summaryrefslogtreecommitdiff
path: root/src/mesa
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa')
-rw-r--r--src/mesa/Makefile4
-rw-r--r--src/mesa/SConscript1
-rw-r--r--src/mesa/drivers/dri/common/dri_util.c1
-rw-r--r--src/mesa/drivers/dri/i965/brw_misc_state.c11
-rw-r--r--src/mesa/drivers/dri/i965/brw_queryobj.c84
-rw-r--r--src/mesa/drivers/dri/i965/brw_state_cache.c3
-rw-r--r--src/mesa/drivers/dri/i965/brw_wm_surface_state.c9
-rw-r--r--src/mesa/drivers/dri/intel/intel_batchbuffer.c15
-rw-r--r--src/mesa/drivers/dri/intel/intel_decode.c27
-rw-r--r--src/mesa/drivers/dri/intel/intel_extensions.c7
-rw-r--r--src/mesa/drivers/dri/intel/intel_tex_copy.c8
-rw-r--r--src/mesa/drivers/dri/r300/compiler/r300_fragprog_emit.c6
-rw-r--r--src/mesa/drivers/dri/r300/compiler/r3xx_vertprog.c2
-rw-r--r--src/mesa/drivers/dri/r300/compiler/r500_fragprog_emit.c8
-rw-r--r--src/mesa/drivers/dri/r300/r300_blit.c14
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_fbo.c8
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_texture.c22
-rw-r--r--src/mesa/drivers/dri/swrast/swrast.c68
-rw-r--r--src/mesa/drivers/fbdev/glfbdev.c8
-rw-r--r--src/mesa/main/compiler.h4
-rw-r--r--src/mesa/main/es_generator.py3
-rw-r--r--src/mesa/main/fbobject.c21
-rw-r--r--src/mesa/main/get.c4
-rw-r--r--src/mesa/main/shaders.c153
-rw-r--r--src/mesa/main/shaders.h239
-rw-r--r--src/mesa/shader/prog_print.c2
-rw-r--r--src/mesa/shader/program_parse.tab.c2
-rw-r--r--src/mesa/shader/program_parse.y2
-rw-r--r--src/mesa/shader/shader_api.c883
-rw-r--r--src/mesa/shader/shader_api.h4
-rw-r--r--src/mesa/shader/slang/slang_emit.c2
-rw-r--r--src/mesa/shader/slang/slang_link.c137
-rw-r--r--src/mesa/shader/uniforms.c937
-rw-r--r--src/mesa/shader/uniforms.h33
-rw-r--r--src/mesa/sources.mak3
-rw-r--r--src/mesa/state_tracker/st_cb_blit.c2
-rw-r--r--src/mesa/state_tracker/st_cb_viewport.c2
-rw-r--r--src/mesa/state_tracker/st_context.c2
-rw-r--r--src/mesa/state_tracker/st_debug.c18
-rw-r--r--src/mesa/state_tracker/st_extensions.c7
-rw-r--r--src/mesa/state_tracker/st_mesa_to_tgsi.c13
-rw-r--r--src/mesa/vbo/vbo_exec.c12
-rw-r--r--src/mesa/vbo/vbo_exec.h3
-rw-r--r--src/mesa/vbo/vbo_exec_array.c99
44 files changed, 1768 insertions, 1125 deletions
diff --git a/src/mesa/Makefile b/src/mesa/Makefile
index 3bb2f39475..4f81768924 100644
--- a/src/mesa/Makefile
+++ b/src/mesa/Makefile
@@ -17,8 +17,8 @@ ES1_OBJ_DIR := objs-es1
ES2_OBJ_DIR := objs-es2
MESA_CPPFLAGS := $(API_DEFINES)
-ES1_CPPFLAGS := -DFEATURE_ES1=1 -D__GL_EXPORTS
-ES2_CPPFLAGS := -DFEATURE_ES2=1 -D__GL_EXPORTS
+ES1_CPPFLAGS := -DFEATURE_ES1=1
+ES2_CPPFLAGS := -DFEATURE_ES2=1
include sources.mak
diff --git a/src/mesa/SConscript b/src/mesa/SConscript
index 3385bf6f39..34b7f4e8b7 100644
--- a/src/mesa/SConscript
+++ b/src/mesa/SConscript
@@ -217,6 +217,7 @@ if env['platform'] != 'winddk':
'shader/programopt.c',
'shader/symbol_table.c',
'shader/shader_api.c',
+ 'shader/uniforms.c',
]
slang_sources = [
diff --git a/src/mesa/drivers/dri/common/dri_util.c b/src/mesa/drivers/dri/common/dri_util.c
index c3d1f2c454..18b9035248 100644
--- a/src/mesa/drivers/dri/common/dri_util.c
+++ b/src/mesa/drivers/dri/common/dri_util.c
@@ -423,6 +423,7 @@ driCreateNewDrawable(__DRIscreen *psp, const __DRIconfig *config,
return NULL;
}
+ pdp->driContextPriv = NULL;
pdp->loaderPrivate = data;
pdp->hHWDrawable = hwDrawable;
pdp->refcount = 1;
diff --git a/src/mesa/drivers/dri/i965/brw_misc_state.c b/src/mesa/drivers/dri/i965/brw_misc_state.c
index 3b3cb5a0e9..35908ee7b6 100644
--- a/src/mesa/drivers/dri/i965/brw_misc_state.c
+++ b/src/mesa/drivers/dri/i965/brw_misc_state.c
@@ -182,6 +182,13 @@ static void upload_pipelined_state_pointers(struct brw_context *brw )
{
struct intel_context *intel = &brw->intel;
+ if (intel->gen == 5) {
+ /* Need to flush before changing clip max threads for errata. */
+ BEGIN_BATCH(1);
+ OUT_BATCH(MI_FLUSH);
+ ADVANCE_BATCH();
+ }
+
BEGIN_BATCH(7);
OUT_BATCH(CMD_PIPELINED_STATE_POINTERS << 16 | (7 - 2));
OUT_RELOC(brw->vs.state_bo, I915_GEM_DOMAIN_INSTRUCTION, 0, 0);
@@ -519,11 +526,11 @@ static void upload_invarient_state( struct brw_context *brw )
BRW_BATCH_STRUCT(brw, &gdo);
}
- intel_batchbuffer_emit_mi_flush(intel->batch);
-
if (intel->gen >= 6) {
int i;
+ intel_batchbuffer_emit_mi_flush(intel->batch);
+
BEGIN_BATCH(3);
OUT_BATCH(CMD_3D_MULTISAMPLE << 16 | (3 - 2));
OUT_BATCH(MS_PIXEL_LOCATION_CENTER |
diff --git a/src/mesa/drivers/dri/i965/brw_queryobj.c b/src/mesa/drivers/dri/i965/brw_queryobj.c
index 3f47a68049..7cb812b521 100644
--- a/src/mesa/drivers/dri/i965/brw_queryobj.c
+++ b/src/mesa/drivers/dri/i965/brw_queryobj.c
@@ -55,11 +55,15 @@ brw_queryobj_get_results(struct brw_query_object *query)
if (query->bo == NULL)
return;
- /* Map and count the pixels from the current query BO */
dri_bo_map(query->bo, GL_FALSE);
results = query->bo->virtual;
- for (i = query->first_index; i <= query->last_index; i++) {
- query->Base.Result += results[i * 2 + 1] - results[i * 2];
+ if (query->Base.Target == GL_TIME_ELAPSED_EXT) {
+ query->Base.Result += 1000 * ((results[1] >> 32) - (results[0] >> 32));
+ } else {
+ /* Map and count the pixels from the current query BO */
+ for (i = query->first_index; i <= query->last_index; i++) {
+ query->Base.Result += results[i * 2 + 1] - results[i * 2];
+ }
}
dri_bo_unmap(query->bo);
@@ -98,14 +102,31 @@ brw_begin_query(GLcontext *ctx, struct gl_query_object *q)
struct intel_context *intel = intel_context(ctx);
struct brw_query_object *query = (struct brw_query_object *)q;
- /* Reset our driver's tracking of query state. */
- dri_bo_unreference(query->bo);
- query->bo = NULL;
- query->first_index = -1;
- query->last_index = -1;
-
- brw->query.obj = query;
- intel->stats_wm++;
+ if (query->Base.Target == GL_TIME_ELAPSED_EXT) {
+ dri_bo_unreference(query->bo);
+ query->bo = drm_intel_bo_alloc(intel->bufmgr, "timer query",
+ 4096, 4096);
+
+ BEGIN_BATCH(4);
+ OUT_BATCH(_3DSTATE_PIPE_CONTROL |
+ PIPE_CONTROL_WRITE_TIMESTAMP);
+ OUT_RELOC(query->bo,
+ I915_GEM_DOMAIN_INSTRUCTION, I915_GEM_DOMAIN_INSTRUCTION,
+ PIPE_CONTROL_GLOBAL_GTT_WRITE |
+ 0);
+ OUT_BATCH(0);
+ OUT_BATCH(0);
+ ADVANCE_BATCH();
+ } else {
+ /* Reset our driver's tracking of query state. */
+ dri_bo_unreference(query->bo);
+ query->bo = NULL;
+ query->first_index = -1;
+ query->last_index = -1;
+
+ brw->query.obj = query;
+ intel->stats_wm++;
+ }
}
/**
@@ -118,21 +139,36 @@ brw_end_query(GLcontext *ctx, struct gl_query_object *q)
struct intel_context *intel = intel_context(ctx);
struct brw_query_object *query = (struct brw_query_object *)q;
- /* Flush the batchbuffer in case it has writes to our query BO.
- * Have later queries write to a new query BO so that further rendering
- * doesn't delay the collection of our results.
- */
- if (query->bo) {
- brw_emit_query_end(brw);
- intel_batchbuffer_flush(intel->batch);
+ if (query->Base.Target == GL_TIME_ELAPSED_EXT) {
+ BEGIN_BATCH(4);
+ OUT_BATCH(_3DSTATE_PIPE_CONTROL |
+ PIPE_CONTROL_WRITE_TIMESTAMP);
+ OUT_RELOC(query->bo,
+ I915_GEM_DOMAIN_INSTRUCTION, I915_GEM_DOMAIN_INSTRUCTION,
+ PIPE_CONTROL_GLOBAL_GTT_WRITE |
+ 8);
+ OUT_BATCH(0);
+ OUT_BATCH(0);
+ ADVANCE_BATCH();
- dri_bo_unreference(brw->query.bo);
- brw->query.bo = NULL;
+ intel_batchbuffer_flush(intel->batch);
+ } else {
+ /* Flush the batchbuffer in case it has writes to our query BO.
+ * Have later queries write to a new query BO so that further rendering
+ * doesn't delay the collection of our results.
+ */
+ if (query->bo) {
+ brw_emit_query_end(brw);
+ intel_batchbuffer_flush(intel->batch);
+
+ dri_bo_unreference(brw->query.bo);
+ brw->query.bo = NULL;
+ }
+
+ brw->query.obj = NULL;
+
+ intel->stats_wm--;
}
-
- brw->query.obj = NULL;
-
- intel->stats_wm--;
}
static void brw_wait_query(GLcontext *ctx, struct gl_query_object *q)
diff --git a/src/mesa/drivers/dri/i965/brw_state_cache.c b/src/mesa/drivers/dri/i965/brw_state_cache.c
index c08cb45b75..c4431b5a32 100644
--- a/src/mesa/drivers/dri/i965/brw_state_cache.c
+++ b/src/mesa/drivers/dri/i965/brw_state_cache.c
@@ -386,11 +386,14 @@ brw_init_non_surface_cache(struct brw_context *brw)
brw_init_cache_id(cache, "CLIP_UNIT", BRW_CLIP_UNIT);
brw_init_cache_id(cache, "CLIP_PROG", BRW_CLIP_PROG);
+ brw_init_cache_id(cache, "CLIP_VP", BRW_CLIP_VP);
brw_init_cache_id(cache, "GS_UNIT", BRW_GS_UNIT);
brw_init_cache_id(cache, "GS_PROG", BRW_GS_PROG);
brw_init_cache_id(cache, "BLEND_STATE", BRW_BLEND_STATE);
+ brw_init_cache_id(cache, "COLOR_CALC_STATE", BRW_COLOR_CALC_STATE);
+ brw_init_cache_id(cache, "DEPTH_STENCIL_STATE", BRW_DEPTH_STENCIL_STATE);
}
diff --git a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c
index e51a1a0e26..feaa2e1f40 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c
@@ -519,13 +519,8 @@ brw_update_renderbuffer_surface(struct brw_context *brw,
_mesa_problem(ctx, "Bad renderbuffer format: %d\n", irb->Base.Format);
}
key.tiling = region->tiling;
- if (brw->intel.intelScreen->driScrnPriv->dri2.enabled) {
- key.width = rb->Width;
- key.height = rb->Height;
- } else {
- key.width = region->width;
- key.height = region->height;
- }
+ key.width = rb->Width;
+ key.height = rb->Height;
key.pitch = region->pitch;
key.cpp = region->cpp;
key.draw_x = region->draw_x;
diff --git a/src/mesa/drivers/dri/intel/intel_batchbuffer.c b/src/mesa/drivers/dri/intel/intel_batchbuffer.c
index ca8e344836..27bd4fe605 100644
--- a/src/mesa/drivers/dri/intel/intel_batchbuffer.c
+++ b/src/mesa/drivers/dri/intel/intel_batchbuffer.c
@@ -55,6 +55,7 @@ intel_batchbuffer_reset(struct intel_batchbuffer *batch)
}
batch->size = intel->maxBatchSize;
batch->ptr = batch->map;
+ batch->reserved_space = BATCH_RESERVED;
batch->dirty_state = ~0;
}
@@ -180,8 +181,6 @@ _intel_batchbuffer_flush(struct intel_batchbuffer *batch, const char *file,
/* Check that we didn't just wrap our batchbuffer at a bad time. */
assert(!intel->no_batch_wrap);
- batch->reserved_space = BATCH_RESERVED;
-
/* TODO: Just pass the relocation list and dma buffer up to the
* kernel.
*/
@@ -275,10 +274,18 @@ intel_batchbuffer_emit_mi_flush(struct intel_batchbuffer *batch)
{
struct intel_context *intel = batch->intel;
- if (intel->gen >= 4) {
+ if (intel->gen >= 6) {
+ BEGIN_BATCH(4);
+ OUT_BATCH(_3DSTATE_PIPE_CONTROL);
+ OUT_BATCH(PIPE_CONTROL_INSTRUCTION_FLUSH |
+ PIPE_CONTROL_WRITE_FLUSH |
+ PIPE_CONTROL_NO_WRITE);
+ OUT_BATCH(0); /* write address */
+ OUT_BATCH(0); /* write data */
+ ADVANCE_BATCH();
+ } else if (intel->gen >= 4) {
BEGIN_BATCH(4);
OUT_BATCH(_3DSTATE_PIPE_CONTROL |
- PIPE_CONTROL_INSTRUCTION_FLUSH |
PIPE_CONTROL_WRITE_FLUSH |
PIPE_CONTROL_NO_WRITE);
OUT_BATCH(0); /* write address */
diff --git a/src/mesa/drivers/dri/intel/intel_decode.c b/src/mesa/drivers/dri/intel/intel_decode.c
index 5293482b35..650010ac9c 100644
--- a/src/mesa/drivers/dri/intel/intel_decode.c
+++ b/src/mesa/drivers/dri/intel/intel_decode.c
@@ -1407,6 +1407,7 @@ decode_3d_965(uint32_t *data, int count, uint32_t hw_offset, int *failures)
{
unsigned int opcode, len;
int i;
+ char *desc1;
struct {
uint32_t opcode;
@@ -1622,6 +1623,32 @@ decode_3d_965(uint32_t *data, int count, uint32_t hw_offset, int *failures)
return len;
+ case 0x7a00:
+ len = (data[0] & 0xff) + 2;
+ if (len != 4)
+ fprintf(out, "Bad count in PIPE_CONTROL\n");
+ if (count < len)
+ BUFFER_FAIL(count, len, "PIPE_CONTROL");
+
+ switch ((data[0] >> 14) & 0x3) {
+ case 0: desc1 = "no write"; break;
+ case 1: desc1 = "qword write"; break;
+ case 2: desc1 = "PS_DEPTH_COUNT write"; break;
+ case 3: desc1 = "TIMESTAMP write"; break;
+ }
+ instr_out(data, hw_offset, 0,
+ "PIPE_CONTROL: %s, %sdepth stall, %sRC write flush, "
+ "%sinst flush, %stexture flush\n",
+ desc1,
+ data[0] & (1 << 13) ? "" : "no ",
+ data[0] & (1 << 12) ? "" : "no ",
+ data[0] & (1 << 11) ? "" : "no ",
+ data[0] & (1 << 9) ? "" : "no ");
+ instr_out(data, hw_offset, 1, "destination address\n");
+ instr_out(data, hw_offset, 2, "immediate dword low\n");
+ instr_out(data, hw_offset, 3, "immediate dword high\n");
+ return len;
+
case 0x7b00:
len = (data[0] & 0xff) + 2;
if (len != 6)
diff --git a/src/mesa/drivers/dri/intel/intel_extensions.c b/src/mesa/drivers/dri/intel/intel_extensions.c
index 9c2083873a..edba1fc2f2 100644
--- a/src/mesa/drivers/dri/intel/intel_extensions.c
+++ b/src/mesa/drivers/dri/intel/intel_extensions.c
@@ -57,6 +57,7 @@
#define need_GL_EXT_provoking_vertex
#define need_GL_EXT_secondary_color
#define need_GL_EXT_stencil_two_side
+#define need_GL_EXT_timer_query
#define need_GL_APPLE_vertex_array_object
#define need_GL_APPLE_object_purgeable
#define need_GL_ATI_separate_stencil
@@ -182,6 +183,9 @@ static const struct dri_extension brw_extensions[] = {
{ NULL, NULL }
};
+static const struct dri_extension ironlake_extensions[] = {
+ { "GL_EXT_timer_query", GL_EXT_timer_query_functions },
+};
static const struct dri_extension arb_oq_extensions[] = {
{ "GL_ARB_occlusion_query", GL_ARB_occlusion_query_functions },
@@ -207,6 +211,9 @@ intelInitExtensions(GLcontext *ctx)
*/
driInitExtensions(ctx, card_extensions, GL_FALSE);
+ if (intel->gen >= 5)
+ driInitExtensions(ctx, ironlake_extensions, GL_FALSE);
+
if (intel->gen >= 4)
driInitExtensions(ctx, brw_extensions, GL_FALSE);
diff --git a/src/mesa/drivers/dri/intel/intel_tex_copy.c b/src/mesa/drivers/dri/intel/intel_tex_copy.c
index 549a4acc7d..ddc2c337c8 100644
--- a/src/mesa/drivers/dri/intel/intel_tex_copy.c
+++ b/src/mesa/drivers/dri/intel/intel_tex_copy.c
@@ -74,6 +74,14 @@ get_teximage_source(struct intel_context *intel, GLenum internalFormat)
return NULL;
case GL_RGBA:
case GL_RGBA8:
+ irb = intel_renderbuffer(intel->ctx.ReadBuffer->_ColorReadBuffer);
+ /* We're required to set alpha to 1.0 in this case, but we can't
+ * do that with the blitter, so fall back. We could use the 3D
+ * engine or do two passes with the blitter, but it doesn't seem
+ * worth it for this case. */
+ if (irb->Base._BaseFormat == GL_RGB)
+ return NULL;
+ return irb->region;
case GL_RGB:
case GL_RGB8:
return intel_readbuf_region(intel);
diff --git a/src/mesa/drivers/dri/r300/compiler/r300_fragprog_emit.c b/src/mesa/drivers/dri/r300/compiler/r300_fragprog_emit.c
index ef56e62396..b27a683c39 100644
--- a/src/mesa/drivers/dri/r300/compiler/r300_fragprog_emit.c
+++ b/src/mesa/drivers/dri/r300/compiler/r300_fragprog_emit.c
@@ -95,7 +95,7 @@ static unsigned int translate_rgb_opcode(struct r300_fragment_program_compiler *
case RC_OPCODE_DP4: return R300_ALU_OUTC_DP4;
case RC_OPCODE_FRC: return R300_ALU_OUTC_FRC;
default:
- error("translate_rgb_opcode(%i): Unknown opcode", opcode);
+ error("translate_rgb_opcode: Unknown opcode %s", rc_get_opcode_info(opcode)->Name);
/* fall through */
case RC_OPCODE_NOP:
/* fall through */
@@ -116,7 +116,7 @@ static unsigned int translate_alpha_opcode(struct r300_fragment_program_compiler
case RC_OPCODE_FRC: return R300_ALU_OUTA_FRC;
case RC_OPCODE_LG2: return R300_ALU_OUTA_LG2;
default:
- error("translate_rgb_opcode(%i): Unknown opcode", opcode);
+ error("translate_rgb_opcode: Unknown opcode %s", rc_get_opcode_info(opcode)->Name);
/* fall through */
case RC_OPCODE_NOP:
/* fall through */
@@ -302,7 +302,7 @@ static int emit_tex(struct r300_emit_state * emit, struct rc_instruction * inst)
case RC_OPCODE_TXB: opcode = R300_TEX_OP_TXB; break;
case RC_OPCODE_TXP: opcode = R300_TEX_OP_TXP; break;
default:
- error("Unknown texture opcode %i", inst->U.I.Opcode);
+ error("Unknown texture opcode %s", rc_get_opcode_info(inst->U.I.Opcode)->Name);
return 0;
}
diff --git a/src/mesa/drivers/dri/r300/compiler/r3xx_vertprog.c b/src/mesa/drivers/dri/r300/compiler/r3xx_vertprog.c
index 4a0b6c02ef..02bef5603f 100644
--- a/src/mesa/drivers/dri/r300/compiler/r3xx_vertprog.c
+++ b/src/mesa/drivers/dri/r300/compiler/r3xx_vertprog.c
@@ -375,7 +375,7 @@ static void translate_vertex_program(struct r300_vertex_program_compiler * compi
case RC_OPCODE_SGE: ei_vector2(compiler->code, VE_SET_GREATER_THAN_EQUAL, vpi, inst); break;
case RC_OPCODE_SLT: ei_vector2(compiler->code, VE_SET_LESS_THAN, vpi, inst); break;
default:
- rc_error(&compiler->Base, "Unknown opcode %i\n", vpi->Opcode);
+ rc_error(&compiler->Base, "Unknown opcode %s\n", rc_get_opcode_info(vpi->Opcode)->Name);
return;
}
diff --git a/src/mesa/drivers/dri/r300/compiler/r500_fragprog_emit.c b/src/mesa/drivers/dri/r300/compiler/r500_fragprog_emit.c
index 10c5e2349e..fb2d8b5a9c 100644
--- a/src/mesa/drivers/dri/r300/compiler/r500_fragprog_emit.c
+++ b/src/mesa/drivers/dri/r300/compiler/r500_fragprog_emit.c
@@ -82,7 +82,7 @@ static unsigned int translate_rgb_op(struct r300_fragment_program_compiler *c, r
case RC_OPCODE_DP4: return R500_ALU_RGBA_OP_DP4;
case RC_OPCODE_FRC: return R500_ALU_RGBA_OP_FRC;
default:
- error("translate_rgb_op(%d): unknown opcode\n", opcode);
+ error("translate_rgb_op: unknown opcode %s\n", rc_get_opcode_info(opcode)->Name);
/* fall through */
case RC_OPCODE_NOP:
/* fall through */
@@ -106,7 +106,7 @@ static unsigned int translate_alpha_op(struct r300_fragment_program_compiler *c,
case RC_OPCODE_FRC: return R500_ALPHA_OP_FRC;
case RC_OPCODE_LG2: return R500_ALPHA_OP_LN2;
default:
- error("translate_alpha_op(%d): unknown opcode\n", opcode);
+ error("translate_alpha_op: unknown opcode %s\n", rc_get_opcode_info(opcode)->Name);
/* fall through */
case RC_OPCODE_NOP:
/* fall through */
@@ -332,7 +332,7 @@ static int emit_tex(struct r300_fragment_program_compiler *c, struct rc_sub_inst
code->inst[ip].inst1 |= R500_TEX_INST_PROJ;
break;
default:
- error("emit_tex can't handle opcode %x\n", inst->Opcode);
+ error("emit_tex can't handle opcode %s\n", rc_get_opcode_info(inst->Opcode)->Name);
}
use_temporary(code, inst->SrcReg[0].Index);
@@ -432,7 +432,7 @@ static void emit_flowcontrol(struct emit_state * s, struct rc_instruction * inst
s->CurrentBranchDepth--;
} else {
- rc_error(s->C, "%s: unknown opcode %i\n", __FUNCTION__, inst->U.I.Opcode);
+ rc_error(s->C, "%s: unknown opcode %s\n", __FUNCTION__, rc_get_opcode_info(inst->U.I.Opcode)->Name);
}
}
diff --git a/src/mesa/drivers/dri/r300/r300_blit.c b/src/mesa/drivers/dri/r300/r300_blit.c
index 6fd41b6f41..d2c25fb9cd 100644
--- a/src/mesa/drivers/dri/r300/r300_blit.c
+++ b/src/mesa/drivers/dri/r300/r300_blit.c
@@ -141,10 +141,11 @@ static void r300_emit_tx_setup(struct r300_context *r300,
unsigned height,
unsigned pitch)
{
+ int is_r500 = r300->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515;
BATCH_LOCALS(&r300->radeon);
- assert(width <= 2048);
- assert(height <= 2048);
+ assert(is_r500 ? width <= 4096 : width <= 2048);
+ assert(is_r500 ? height <= 4096 : height <= 2048);
assert(r300TranslateTexFormat(mesa_format) >= 0);
assert(offset % 32 == 0);
@@ -159,14 +160,17 @@ static void r300_emit_tx_setup(struct r300_context *r300,
(0 << 28));
OUT_BATCH_REGVAL(R300_TX_FILTER1_0, 0);
OUT_BATCH_REGVAL(R300_TX_SIZE_0,
- ((width-1) << R300_TX_WIDTHMASK_SHIFT) |
- ((height-1) << R300_TX_HEIGHTMASK_SHIFT) |
+ (((width - 1) & 0x7ff) << R300_TX_WIDTHMASK_SHIFT) |
+ (((height - 1) & 0x7ff) << R300_TX_HEIGHTMASK_SHIFT) |
(0 << R300_TX_DEPTHMASK_SHIFT) |
(0 << R300_TX_MAX_MIP_LEVEL_SHIFT) |
R300_TX_SIZE_TXPITCH_EN);
OUT_BATCH_REGVAL(R300_TX_FORMAT_0, r300TranslateTexFormat(mesa_format));
- OUT_BATCH_REGVAL(R300_TX_FORMAT2_0, pitch - 1);
+ OUT_BATCH_REGVAL(R300_TX_FORMAT2_0,
+ (pitch - 1) |
+ (is_r500 && width > 2048 ? R500_TXWIDTH_BIT11 : 0) |
+ (is_r500 && height > 2048 ? R500_TXHEIGHT_BIT11 : 0));
OUT_BATCH_REGSEQ(R300_TX_OFFSET_0, 1);
OUT_BATCH_RELOC(0, bo, offset, RADEON_GEM_DOMAIN_GTT|RADEON_GEM_DOMAIN_VRAM, 0, 0);
diff --git a/src/mesa/drivers/dri/radeon/radeon_fbo.c b/src/mesa/drivers/dri/radeon/radeon_fbo.c
index 6398605835..517485091a 100644
--- a/src/mesa/drivers/dri/radeon/radeon_fbo.c
+++ b/src/mesa/drivers/dri/radeon/radeon_fbo.c
@@ -506,9 +506,10 @@ radeon_render_texture(GLcontext * ctx,
ASSERT(newImage);
- if (newImage->Border != 0) {
- /* Fallback on drawing to a texture with a border, which won't have a
- * miptree.
+ radeon_image = (radeon_texture_image *)newImage;
+
+ if (!radeon_image->mt || newImage->Border != 0) {
+ /* Fallback on drawing to a texture without a miptree.
*/
_mesa_reference_renderbuffer(&att->Renderbuffer, NULL);
_mesa_render_texture(ctx, fb, att);
@@ -539,7 +540,6 @@ radeon_render_texture(GLcontext * ctx,
rrb->base.RefCount);
/* point the renderbufer's region to the texture image region */
- radeon_image = (radeon_texture_image *)newImage;
if (rrb->bo != radeon_image->mt->bo) {
if (rrb->bo)
radeon_bo_unref(rrb->bo);
diff --git a/src/mesa/drivers/dri/radeon/radeon_texture.c b/src/mesa/drivers/dri/radeon/radeon_texture.c
index 2b655fbd95..bcac125baf 100644
--- a/src/mesa/drivers/dri/radeon/radeon_texture.c
+++ b/src/mesa/drivers/dri/radeon/radeon_texture.c
@@ -39,6 +39,7 @@
#include "main/texstore.h"
#include "main/teximage.h"
#include "main/texobj.h"
+#include "drivers/common/meta.h"
#include "xmlpool.h" /* for symbolic values of enum-type options */
@@ -294,9 +295,13 @@ void radeonGenerateMipmap(GLcontext* ctx, GLenum target, struct gl_texture_objec
radeon_firevertices(rmesa);
}
- radeon_teximage_map(baseimage, GL_FALSE);
- radeon_generate_mipmap(ctx, target, texObj);
- radeon_teximage_unmap(baseimage);
+ if (_mesa_meta_check_generate_mipmap_fallback(ctx, target, texObj)) {
+ radeon_teximage_map(baseimage, GL_FALSE);
+ radeon_generate_mipmap(ctx, target, texObj);
+ radeon_teximage_unmap(baseimage);
+ } else {
+ _mesa_meta_GenerateMipmap(ctx, target, texObj);
+ }
}
@@ -588,7 +593,12 @@ static int image_matches_texture_obj(struct gl_texture_object *texObj,
if (!baseImage)
return 0;
- if (level < texObj->BaseLevel || level > texObj->MaxLevel)
+ /* Check image level against object BaseLevel, but not MaxLevel. MaxLevel is not
+ * the highest level that can be assigned to the miptree.
+ */
+ const unsigned maxLevel = texObj->BaseLevel + baseImage->MaxLog2;
+ if (level < texObj->BaseLevel || level > maxLevel
+ || level > RADEON_MIPTREE_MAX_TEXTURE_LEVELS)
return 0;
const unsigned levelDiff = level - texObj->BaseLevel;
@@ -610,9 +620,7 @@ static void teximage_assign_miptree(radeonContextPtr rmesa,
radeonTexObj *t = radeon_tex_obj(texObj);
radeon_texture_image* image = get_radeon_texture_image(texImage);
- /* Since miptree holds only images for levels <BaseLevel..MaxLevel>
- * don't allocate the miptree if the teximage won't fit.
- */
+ /* check image for dimension and level compatibility with texture */
if (!image_matches_texture_obj(texObj, texImage, level))
return;
diff --git a/src/mesa/drivers/dri/swrast/swrast.c b/src/mesa/drivers/dri/swrast/swrast.c
index 7fa7e2192f..f3903c2e38 100644
--- a/src/mesa/drivers/dri/swrast/swrast.c
+++ b/src/mesa/drivers/dri/swrast/swrast.c
@@ -47,6 +47,11 @@
#include "drivers/common/meta.h"
#include "utils.h"
+#include "main/teximage.h"
+#include "main/texfetch.h"
+#include "main/texformat.h"
+#include "main/texstate.h"
+
#include "swrast_priv.h"
@@ -54,7 +59,59 @@
* Screen and config-related functions
*/
+static void swrastSetTexBuffer2(__DRIcontext *pDRICtx, GLint target,
+ GLint texture_format, __DRIdrawable *dPriv)
+{
+ struct dri_context *dri_ctx;
+ int x, y, w, h;
+ __DRIscreen *sPriv = dPriv->driScreenPriv;
+ struct gl_texture_unit *texUnit;
+ struct gl_texture_object *texObj;
+ struct gl_texture_image *texImage;
+ uint32_t internalFormat;
+
+ dri_ctx = pDRICtx->driverPrivate;
+
+ internalFormat = (texture_format == __DRI_TEXTURE_FORMAT_RGB ? 3 : 4);
+
+ texUnit = _mesa_get_current_tex_unit(&dri_ctx->Base);
+ texObj = _mesa_select_tex_object(&dri_ctx->Base, texUnit, target);
+ texImage = _mesa_get_tex_image(&dri_ctx->Base, texObj, target, 0);
+
+ _mesa_lock_texture(&dri_ctx->Base, texObj);
+
+ sPriv->swrast_loader->getDrawableInfo(dPriv, &x, &y, &w, &h, dPriv->loaderPrivate);
+
+ _mesa_init_teximage_fields(&dri_ctx->Base, target, texImage,
+ w, h, 1, 0, internalFormat);
+
+ if (texture_format == __DRI_TEXTURE_FORMAT_RGB)
+ texImage->TexFormat = MESA_FORMAT_XRGB8888;
+ else
+ texImage->TexFormat = MESA_FORMAT_ARGB8888;
+
+ _mesa_set_fetch_functions(texImage, 2);
+
+ sPriv->swrast_loader->getImage(dPriv, x, y, w, h, (char *)texImage->Data,
+ dPriv->loaderPrivate);
+
+ _mesa_unlock_texture(&dri_ctx->Base, texObj);
+}
+
+static void swrastSetTexBuffer(__DRIcontext *pDRICtx, GLint target,
+ __DRIdrawable *dPriv)
+{
+ swrastSetTexBuffer2(pDRICtx, target, __DRI_TEXTURE_FORMAT_RGBA, dPriv);
+}
+
+static const __DRItexBufferExtension swrastTexBufferExtension = {
+ { __DRI_TEX_BUFFER, __DRI_TEX_BUFFER_VERSION },
+ swrastSetTexBuffer,
+ swrastSetTexBuffer2,
+};
+
static const __DRIextension *dri_screen_extensions[] = {
+ &swrastTexBufferExtension.base,
NULL
};
@@ -486,6 +543,16 @@ viewport(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h)
swrast_check_and_update_window_size(ctx, read);
}
+static gl_format swrastChooseTextureFormat(GLcontext * ctx,
+ GLint internalFormat,
+ GLenum format,
+ GLenum type)
+{
+ if (internalFormat == GL_RGB)
+ return MESA_FORMAT_XRGB8888;
+ return _mesa_choose_tex_format(ctx, internalFormat, format, type);
+}
+
static void
swrast_init_driver_functions(struct dd_function_table *driver)
{
@@ -493,6 +560,7 @@ swrast_init_driver_functions(struct dd_function_table *driver)
driver->UpdateState = update_state;
driver->GetBufferSize = NULL;
driver->Viewport = viewport;
+ driver->ChooseTextureFormat = swrastChooseTextureFormat;
}
diff --git a/src/mesa/drivers/fbdev/glfbdev.c b/src/mesa/drivers/fbdev/glfbdev.c
index 0ea2796eaa..2ad52d89fc 100644
--- a/src/mesa/drivers/fbdev/glfbdev.c
+++ b/src/mesa/drivers/fbdev/glfbdev.c
@@ -41,8 +41,8 @@
#ifdef USE_GLFBDEV_DRIVER
-#include <linux/fb.h>
#include "GL/glfbdev.h"
+#include <linux/fb.h>
#include "main/glheader.h"
#include "main/buffers.h"
#include "main/context.h"
@@ -216,6 +216,10 @@ viewport(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h)
DST[1] = VALUE[GCOMP]; \
DST[2] = VALUE[RCOMP]; \
DST[3] = VALUE[ACOMP]
+#define STORE_PIXEL_RGB(DST, X, Y, VALUE) \
+ DST[0] = VALUE[BCOMP]; \
+ DST[1] = VALUE[GCOMP]; \
+ DST[2] = VALUE[RCOMP];
#define FETCH_PIXEL(DST, SRC) \
DST[RCOMP] = SRC[2]; \
DST[GCOMP] = SRC[1]; \
@@ -531,10 +535,12 @@ new_glfbdev_renderbuffer(void *bufferStart, const GLFBDevVisualPtr visual)
rb->Base.Width = visual->var.xres;
rb->Base.Height = visual->var.yres;
+ /*
rb->Base.RedBits = visual->var.red.length;
rb->Base.GreenBits = visual->var.green.length;
rb->Base.BlueBits = visual->var.blue.length;
rb->Base.AlphaBits = visual->var.transp.length;
+ */
rb->Base.InternalFormat = pixelFormat;
}
diff --git a/src/mesa/main/compiler.h b/src/mesa/main/compiler.h
index efd8057608..e0507ccf86 100644
--- a/src/mesa/main/compiler.h
+++ b/src/mesa/main/compiler.h
@@ -65,9 +65,7 @@ extern "C" {
typedef unsigned __int8 uint8_t;
typedef __int16 int16_t;
typedef unsigned __int16 uint16_t;
-# ifndef __eglplatform_h_
- typedef __int32 int32_t;
-# endif
+ typedef __int32 int32_t;
typedef unsigned __int32 uint32_t;
typedef __int64 int64_t;
typedef unsigned __int64 uint64_t;
diff --git a/src/mesa/main/es_generator.py b/src/mesa/main/es_generator.py
index a3e089ed58..9a8f5a6f5e 100644
--- a/src/mesa/main/es_generator.py
+++ b/src/mesa/main/es_generator.py
@@ -203,9 +203,6 @@ print """
typedef double GLdouble;
typedef double GLclampd;
-/* This type is normally in glext.h, but needed here */
-typedef char GLchar;
-
/* Mesa error handling requires these */
extern void *_mesa_get_current_context(void);
extern void _mesa_error(void *ctx, GLenum error, const char *fmtString, ... );
diff --git a/src/mesa/main/fbobject.c b/src/mesa/main/fbobject.c
index bf445d2b29..f33e027857 100644
--- a/src/mesa/main/fbobject.c
+++ b/src/mesa/main/fbobject.c
@@ -1015,9 +1015,10 @@ renderbuffer_storage(GLenum target, GLenum internalFormat,
*/
}
+
#if FEATURE_OES_EGL_image
void GLAPIENTRY
-_mesa_EGLImageTargetRenderbufferStorageOES (GLenum target, GLeglImageOES image)
+_mesa_EGLImageTargetRenderbufferStorageOES(GLenum target, GLeglImageOES image)
{
struct gl_renderbuffer *rb;
GET_CURRENT_CONTEXT(ctx);
@@ -1030,13 +1031,15 @@ _mesa_EGLImageTargetRenderbufferStorageOES (GLenum target, GLeglImageOES image)
}
if (target != GL_RENDERBUFFER) {
- _mesa_error(ctx, GL_INVALID_ENUM, "EGLImageTargetRenderbufferStorageOES");
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "EGLImageTargetRenderbufferStorageOES");
return;
}
rb = ctx->CurrentRenderbuffer;
if (!rb) {
- _mesa_error(ctx, GL_INVALID_OPERATION, "EGLImageTargetRenderbufferStorageOES");
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "EGLImageTargetRenderbufferStorageOES");
return;
}
@@ -1046,6 +1049,7 @@ _mesa_EGLImageTargetRenderbufferStorageOES (GLenum target, GLeglImageOES image)
}
#endif
+
/**
* Helper function for _mesa_GetRenderbufferParameterivEXT() and
* _mesa_GetFramebufferAttachmentParameterivEXT()
@@ -1113,6 +1117,10 @@ _mesa_RenderbufferStorageMultisample(GLenum target, GLsizei samples,
renderbuffer_storage(target, internalFormat, width, height, samples);
}
+
+/**
+ * OpenGL ES version of glRenderBufferStorage.
+ */
void GLAPIENTRY
_es_RenderbufferStorageEXT(GLenum target, GLenum internalFormat,
GLsizei width, GLsizei height)
@@ -1130,6 +1138,7 @@ _es_RenderbufferStorageEXT(GLenum target, GLenum internalFormat,
renderbuffer_storage(target, internalFormat, width, height, 0);
}
+
void GLAPIENTRY
_mesa_GetRenderbufferParameterivEXT(GLenum target, GLenum pname, GLint *params)
{
@@ -1802,10 +1811,10 @@ _mesa_FramebufferRenderbufferEXT(GLenum target, GLenum attachment,
rb = NULL;
}
- if (attachment == GL_DEPTH_STENCIL_ATTACHMENT) {
+ if (attachment == GL_DEPTH_STENCIL_ATTACHMENT &&
+ rb && rb->Format != MESA_FORMAT_NONE) {
/* make sure the renderbuffer is a depth/stencil format */
- const GLenum baseFormat =
- _mesa_get_format_base_format(att->Renderbuffer->Format);
+ const GLenum baseFormat = _mesa_get_format_base_format(rb->Format);
if (baseFormat != GL_DEPTH_STENCIL) {
_mesa_error(ctx, GL_INVALID_OPERATION,
"glFramebufferRenderbufferEXT(renderbuffer"
diff --git a/src/mesa/main/get.c b/src/mesa/main/get.c
index 1cb6cffb6a..03f2707f4f 100644
--- a/src/mesa/main/get.c
+++ b/src/mesa/main/get.c
@@ -674,14 +674,14 @@ static const struct value_desc values[] = {
#if FEATURE_ES2
/* Enums unique to OpenGL ES 2.0 */
- { 0, 0, TYPE_API_MASK, API_OPENGLES2_BIT, NO_OFFSET, NO_EXTRA },
+ { 0, 0, TYPE_API_MASK, API_OPENGLES2_BIT, NO_EXTRA },
{ GL_MAX_FRAGMENT_UNIFORM_VECTORS, LOC_CUSTOM, TYPE_INT,
offsetof(GLcontext, Const.FragmentProgram.MaxUniformComponents), NO_EXTRA },
{ GL_MAX_VARYING_VECTORS, LOC_CUSTOM, TYPE_INT,
offsetof(GLcontext, Const.MaxVarying), NO_EXTRA },
{ GL_MAX_VERTEX_UNIFORM_VECTORS, LOC_CUSTOM, TYPE_INT,
offsetof(GLcontext, Const.VertexProgram.MaxUniformComponents), NO_EXTRA },
- { GL_SHADER_COMPILER, CONST(1), NO_EXTRA, NO_EXTRA },
+ { GL_SHADER_COMPILER, CONST(1), NO_EXTRA },
/* OES_get_program_binary */
{ GL_NUM_SHADER_BINARY_FORMATS, CONST(0), NO_EXTRA },
{ GL_SHADER_BINARY_FORMATS, CONST(0), NO_EXTRA },
diff --git a/src/mesa/main/shaders.c b/src/mesa/main/shaders.c
index 917e295fe1..65f1ee3efb 100644
--- a/src/mesa/main/shaders.c
+++ b/src/mesa/main/shaders.c
@@ -49,7 +49,7 @@
-static void GLAPIENTRY
+void GLAPIENTRY
_mesa_AttachObjectARB(GLhandleARB program, GLhandleARB shader)
{
GET_CURRENT_CONTEXT(ctx);
@@ -57,7 +57,7 @@ _mesa_AttachObjectARB(GLhandleARB program, GLhandleARB shader)
}
-static void GLAPIENTRY
+void GLAPIENTRY
_mesa_AttachShader(GLuint program, GLuint shader)
{
GET_CURRENT_CONTEXT(ctx);
@@ -65,7 +65,7 @@ _mesa_AttachShader(GLuint program, GLuint shader)
}
-static void GLAPIENTRY
+void GLAPIENTRY
_mesa_BindAttribLocationARB(GLhandleARB program, GLuint index,
const GLcharARB *name)
{
@@ -74,7 +74,7 @@ _mesa_BindAttribLocationARB(GLhandleARB program, GLuint index,
}
-static void GLAPIENTRY
+void GLAPIENTRY
_mesa_CompileShaderARB(GLhandleARB shaderObj)
{
GET_CURRENT_CONTEXT(ctx);
@@ -82,7 +82,7 @@ _mesa_CompileShaderARB(GLhandleARB shaderObj)
}
-static GLuint GLAPIENTRY
+GLuint GLAPIENTRY
_mesa_CreateShader(GLenum type)
{
GET_CURRENT_CONTEXT(ctx);
@@ -90,7 +90,7 @@ _mesa_CreateShader(GLenum type)
}
-static GLhandleARB GLAPIENTRY
+GLhandleARB GLAPIENTRY
_mesa_CreateShaderObjectARB(GLenum type)
{
GET_CURRENT_CONTEXT(ctx);
@@ -98,7 +98,7 @@ _mesa_CreateShaderObjectARB(GLenum type)
}
-static GLuint GLAPIENTRY
+GLuint GLAPIENTRY
_mesa_CreateProgram(void)
{
GET_CURRENT_CONTEXT(ctx);
@@ -106,7 +106,7 @@ _mesa_CreateProgram(void)
}
-static GLhandleARB GLAPIENTRY
+GLhandleARB GLAPIENTRY
_mesa_CreateProgramObjectARB(void)
{
GET_CURRENT_CONTEXT(ctx);
@@ -114,7 +114,7 @@ _mesa_CreateProgramObjectARB(void)
}
-static void GLAPIENTRY
+void GLAPIENTRY
_mesa_DeleteObjectARB(GLhandleARB obj)
{
if (obj) {
@@ -132,7 +132,7 @@ _mesa_DeleteObjectARB(GLhandleARB obj)
}
-static void GLAPIENTRY
+void GLAPIENTRY
_mesa_DeleteProgram(GLuint name)
{
if (name) {
@@ -142,7 +142,7 @@ _mesa_DeleteProgram(GLuint name)
}
-static void GLAPIENTRY
+void GLAPIENTRY
_mesa_DeleteShader(GLuint name)
{
if (name) {
@@ -152,7 +152,7 @@ _mesa_DeleteShader(GLuint name)
}
-static void GLAPIENTRY
+void GLAPIENTRY
_mesa_DetachObjectARB(GLhandleARB program, GLhandleARB shader)
{
GET_CURRENT_CONTEXT(ctx);
@@ -160,7 +160,7 @@ _mesa_DetachObjectARB(GLhandleARB program, GLhandleARB shader)
}
-static void GLAPIENTRY
+void GLAPIENTRY
_mesa_DetachShader(GLuint program, GLuint shader)
{
GET_CURRENT_CONTEXT(ctx);
@@ -168,7 +168,7 @@ _mesa_DetachShader(GLuint program, GLuint shader)
}
-static void GLAPIENTRY
+void GLAPIENTRY
_mesa_GetActiveAttribARB(GLhandleARB program, GLuint index,
GLsizei maxLength, GLsizei * length, GLint * size,
GLenum * type, GLcharARB * name)
@@ -179,7 +179,7 @@ _mesa_GetActiveAttribARB(GLhandleARB program, GLuint index,
}
-static void GLAPIENTRY
+void GLAPIENTRY
_mesa_GetActiveUniformARB(GLhandleARB program, GLuint index,
GLsizei maxLength, GLsizei * length, GLint * size,
GLenum * type, GLcharARB * name)
@@ -190,7 +190,7 @@ _mesa_GetActiveUniformARB(GLhandleARB program, GLuint index,
}
-static void GLAPIENTRY
+void GLAPIENTRY
_mesa_GetAttachedObjectsARB(GLhandleARB container, GLsizei maxCount,
GLsizei * count, GLhandleARB * obj)
{
@@ -199,7 +199,7 @@ _mesa_GetAttachedObjectsARB(GLhandleARB container, GLsizei maxCount,
}
-static void GLAPIENTRY
+void GLAPIENTRY
_mesa_GetAttachedShaders(GLuint program, GLsizei maxCount,
GLsizei *count, GLuint *obj)
{
@@ -208,7 +208,7 @@ _mesa_GetAttachedShaders(GLuint program, GLsizei maxCount,
}
-static GLint GLAPIENTRY
+GLint GLAPIENTRY
_mesa_GetAttribLocationARB(GLhandleARB program, const GLcharARB * name)
{
GET_CURRENT_CONTEXT(ctx);
@@ -216,7 +216,7 @@ _mesa_GetAttribLocationARB(GLhandleARB program, const GLcharARB * name)
}
-static void GLAPIENTRY
+void GLAPIENTRY
_mesa_GetInfoLogARB(GLhandleARB object, GLsizei maxLength, GLsizei * length,
GLcharARB * infoLog)
{
@@ -234,7 +234,7 @@ _mesa_GetInfoLogARB(GLhandleARB object, GLsizei maxLength, GLsizei * length,
}
-static void GLAPIENTRY
+void GLAPIENTRY
_mesa_GetObjectParameterivARB(GLhandleARB object, GLenum pname, GLint *params)
{
GET_CURRENT_CONTEXT(ctx);
@@ -261,7 +261,7 @@ _mesa_GetObjectParameterivARB(GLhandleARB object, GLenum pname, GLint *params)
}
-static void GLAPIENTRY
+void GLAPIENTRY
_mesa_GetObjectParameterfvARB(GLhandleARB object, GLenum pname,
GLfloat *params)
{
@@ -271,7 +271,7 @@ _mesa_GetObjectParameterfvARB(GLhandleARB object, GLenum pname,
}
-static void GLAPIENTRY
+void GLAPIENTRY
_mesa_GetProgramiv(GLuint program, GLenum pname, GLint *params)
{
GET_CURRENT_CONTEXT(ctx);
@@ -279,7 +279,7 @@ _mesa_GetProgramiv(GLuint program, GLenum pname, GLint *params)
}
-static void GLAPIENTRY
+void GLAPIENTRY
_mesa_GetShaderiv(GLuint shader, GLenum pname, GLint *params)
{
GET_CURRENT_CONTEXT(ctx);
@@ -287,7 +287,7 @@ _mesa_GetShaderiv(GLuint shader, GLenum pname, GLint *params)
}
-static void GLAPIENTRY
+void GLAPIENTRY
_mesa_GetProgramInfoLog(GLuint program, GLsizei bufSize,
GLsizei *length, GLchar *infoLog)
{
@@ -296,7 +296,7 @@ _mesa_GetProgramInfoLog(GLuint program, GLsizei bufSize,
}
-static void GLAPIENTRY
+void GLAPIENTRY
_mesa_GetShaderInfoLog(GLuint shader, GLsizei bufSize,
GLsizei *length, GLchar *infoLog)
{
@@ -305,7 +305,7 @@ _mesa_GetShaderInfoLog(GLuint shader, GLsizei bufSize,
}
-static void GLAPIENTRY
+void GLAPIENTRY
_mesa_GetShaderSourceARB(GLhandleARB shader, GLsizei maxLength,
GLsizei *length, GLcharARB *sourceOut)
{
@@ -314,7 +314,7 @@ _mesa_GetShaderSourceARB(GLhandleARB shader, GLsizei maxLength,
}
-static void GLAPIENTRY
+void GLAPIENTRY
_mesa_GetUniformfvARB(GLhandleARB program, GLint location, GLfloat * params)
{
GET_CURRENT_CONTEXT(ctx);
@@ -322,7 +322,7 @@ _mesa_GetUniformfvARB(GLhandleARB program, GLint location, GLfloat * params)
}
-static void GLAPIENTRY
+void GLAPIENTRY
_mesa_GetUniformivARB(GLhandleARB program, GLint location, GLint * params)
{
GET_CURRENT_CONTEXT(ctx);
@@ -341,7 +341,7 @@ _mesa_GetUniformLocation(GLuint program, const GLcharARB *name)
#endif
-static GLhandleARB GLAPIENTRY
+GLhandleARB GLAPIENTRY
_mesa_GetHandleARB(GLenum pname)
{
GET_CURRENT_CONTEXT(ctx);
@@ -349,7 +349,7 @@ _mesa_GetHandleARB(GLenum pname)
}
-static GLint GLAPIENTRY
+GLint GLAPIENTRY
_mesa_GetUniformLocationARB(GLhandleARB programObj, const GLcharARB *name)
{
GET_CURRENT_CONTEXT(ctx);
@@ -357,7 +357,7 @@ _mesa_GetUniformLocationARB(GLhandleARB programObj, const GLcharARB *name)
}
-static GLboolean GLAPIENTRY
+GLboolean GLAPIENTRY
_mesa_IsProgram(GLuint name)
{
GET_CURRENT_CONTEXT(ctx);
@@ -365,7 +365,7 @@ _mesa_IsProgram(GLuint name)
}
-static GLboolean GLAPIENTRY
+GLboolean GLAPIENTRY
_mesa_IsShader(GLuint name)
{
GET_CURRENT_CONTEXT(ctx);
@@ -373,7 +373,7 @@ _mesa_IsShader(GLuint name)
}
-static void GLAPIENTRY
+void GLAPIENTRY
_mesa_LinkProgramARB(GLhandleARB programObj)
{
GET_CURRENT_CONTEXT(ctx);
@@ -416,7 +416,7 @@ _mesa_read_shader(const char *fname)
* Basically, concatenate the source code strings into one long string
* and pass it to ctx->Driver.ShaderSource().
*/
-static void GLAPIENTRY
+void GLAPIENTRY
_mesa_ShaderSourceARB(GLhandleARB shaderObj, GLsizei count,
const GLcharARB ** string, const GLint * length)
{
@@ -509,14 +509,14 @@ _mesa_ShaderSourceARB(GLhandleARB shaderObj, GLsizei count,
}
-static void GLAPIENTRY
+void GLAPIENTRY
_mesa_Uniform1fARB(GLint location, GLfloat v0)
{
GET_CURRENT_CONTEXT(ctx);
ctx->Driver.Uniform(ctx, location, 1, &v0, GL_FLOAT);
}
-static void GLAPIENTRY
+void GLAPIENTRY
_mesa_Uniform2fARB(GLint location, GLfloat v0, GLfloat v1)
{
GET_CURRENT_CONTEXT(ctx);
@@ -526,7 +526,7 @@ _mesa_Uniform2fARB(GLint location, GLfloat v0, GLfloat v1)
ctx->Driver.Uniform(ctx, location, 1, v, GL_FLOAT_VEC2);
}
-static void GLAPIENTRY
+void GLAPIENTRY
_mesa_Uniform3fARB(GLint location, GLfloat v0, GLfloat v1, GLfloat v2)
{
GET_CURRENT_CONTEXT(ctx);
@@ -537,7 +537,7 @@ _mesa_Uniform3fARB(GLint location, GLfloat v0, GLfloat v1, GLfloat v2)
ctx->Driver.Uniform(ctx, location, 1, v, GL_FLOAT_VEC3);
}
-static void GLAPIENTRY
+void GLAPIENTRY
_mesa_Uniform4fARB(GLint location, GLfloat v0, GLfloat v1, GLfloat v2,
GLfloat v3)
{
@@ -550,14 +550,14 @@ _mesa_Uniform4fARB(GLint location, GLfloat v0, GLfloat v1, GLfloat v2,
ctx->Driver.Uniform(ctx, location, 1, v, GL_FLOAT_VEC4);
}
-static void GLAPIENTRY
+void GLAPIENTRY
_mesa_Uniform1iARB(GLint location, GLint v0)
{
GET_CURRENT_CONTEXT(ctx);
ctx->Driver.Uniform(ctx, location, 1, &v0, GL_INT);
}
-static void GLAPIENTRY
+void GLAPIENTRY
_mesa_Uniform2iARB(GLint location, GLint v0, GLint v1)
{
GET_CURRENT_CONTEXT(ctx);
@@ -567,7 +567,7 @@ _mesa_Uniform2iARB(GLint location, GLint v0, GLint v1)
ctx->Driver.Uniform(ctx, location, 1, v, GL_INT_VEC2);
}
-static void GLAPIENTRY
+void GLAPIENTRY
_mesa_Uniform3iARB(GLint location, GLint v0, GLint v1, GLint v2)
{
GET_CURRENT_CONTEXT(ctx);
@@ -578,7 +578,7 @@ _mesa_Uniform3iARB(GLint location, GLint v0, GLint v1, GLint v2)
ctx->Driver.Uniform(ctx, location, 1, v, GL_INT_VEC3);
}
-static void GLAPIENTRY
+void GLAPIENTRY
_mesa_Uniform4iARB(GLint location, GLint v0, GLint v1, GLint v2, GLint v3)
{
GET_CURRENT_CONTEXT(ctx);
@@ -590,56 +590,56 @@ _mesa_Uniform4iARB(GLint location, GLint v0, GLint v1, GLint v2, GLint v3)
ctx->Driver.Uniform(ctx, location, 1, v, GL_INT_VEC4);
}
-static void GLAPIENTRY
+void GLAPIENTRY
_mesa_Uniform1fvARB(GLint location, GLsizei count, const GLfloat * value)
{
GET_CURRENT_CONTEXT(ctx);
ctx->Driver.Uniform(ctx, location, count, value, GL_FLOAT);
}
-static void GLAPIENTRY
+void GLAPIENTRY
_mesa_Uniform2fvARB(GLint location, GLsizei count, const GLfloat * value)
{
GET_CURRENT_CONTEXT(ctx);
ctx->Driver.Uniform(ctx, location, count, value, GL_FLOAT_VEC2);
}
-static void GLAPIENTRY
+void GLAPIENTRY
_mesa_Uniform3fvARB(GLint location, GLsizei count, const GLfloat * value)
{
GET_CURRENT_CONTEXT(ctx);
ctx->Driver.Uniform(ctx, location, count, value, GL_FLOAT_VEC3);
}
-static void GLAPIENTRY
+void GLAPIENTRY
_mesa_Uniform4fvARB(GLint location, GLsizei count, const GLfloat * value)
{
GET_CURRENT_CONTEXT(ctx);
ctx->Driver.Uniform(ctx, location, count, value, GL_FLOAT_VEC4);
}
-static void GLAPIENTRY
+void GLAPIENTRY
_mesa_Uniform1ivARB(GLint location, GLsizei count, const GLint * value)
{
GET_CURRENT_CONTEXT(ctx);
ctx->Driver.Uniform(ctx, location, count, value, GL_INT);
}
-static void GLAPIENTRY
+void GLAPIENTRY
_mesa_Uniform2ivARB(GLint location, GLsizei count, const GLint * value)
{
GET_CURRENT_CONTEXT(ctx);
ctx->Driver.Uniform(ctx, location, count, value, GL_INT_VEC2);
}
-static void GLAPIENTRY
+void GLAPIENTRY
_mesa_Uniform3ivARB(GLint location, GLsizei count, const GLint * value)
{
GET_CURRENT_CONTEXT(ctx);
ctx->Driver.Uniform(ctx, location, count, value, GL_INT_VEC3);
}
-static void GLAPIENTRY
+void GLAPIENTRY
_mesa_Uniform4ivARB(GLint location, GLsizei count, const GLint * value)
{
GET_CURRENT_CONTEXT(ctx);
@@ -648,14 +648,14 @@ _mesa_Uniform4ivARB(GLint location, GLsizei count, const GLint * value)
/** OpenGL 3.0 GLuint-valued functions **/
-static void GLAPIENTRY
+void GLAPIENTRY
_mesa_Uniform1ui(GLint location, GLuint v0)
{
GET_CURRENT_CONTEXT(ctx);
ctx->Driver.Uniform(ctx, location, 1, &v0, GL_UNSIGNED_INT);
}
-static void GLAPIENTRY
+void GLAPIENTRY
_mesa_Uniform2ui(GLint location, GLuint v0, GLuint v1)
{
GET_CURRENT_CONTEXT(ctx);
@@ -665,7 +665,7 @@ _mesa_Uniform2ui(GLint location, GLuint v0, GLuint v1)
ctx->Driver.Uniform(ctx, location, 1, v, GL_UNSIGNED_INT_VEC2);
}
-static void GLAPIENTRY
+void GLAPIENTRY
_mesa_Uniform3ui(GLint location, GLuint v0, GLuint v1, GLuint v2)
{
GET_CURRENT_CONTEXT(ctx);
@@ -676,7 +676,7 @@ _mesa_Uniform3ui(GLint location, GLuint v0, GLuint v1, GLuint v2)
ctx->Driver.Uniform(ctx, location, 1, v, GL_UNSIGNED_INT_VEC3);
}
-static void GLAPIENTRY
+void GLAPIENTRY
_mesa_Uniform4ui(GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3)
{
GET_CURRENT_CONTEXT(ctx);
@@ -688,28 +688,28 @@ _mesa_Uniform4ui(GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3)
ctx->Driver.Uniform(ctx, location, 1, v, GL_UNSIGNED_INT_VEC4);
}
-static void GLAPIENTRY
+void GLAPIENTRY
_mesa_Uniform1uiv(GLint location, GLsizei count, const GLuint *value)
{
GET_CURRENT_CONTEXT(ctx);
ctx->Driver.Uniform(ctx, location, count, value, GL_UNSIGNED_INT);
}
-static void GLAPIENTRY
+void GLAPIENTRY
_mesa_Uniform2uiv(GLint location, GLsizei count, const GLuint *value)
{
GET_CURRENT_CONTEXT(ctx);
ctx->Driver.Uniform(ctx, location, count, value, GL_UNSIGNED_INT_VEC2);
}
-static void GLAPIENTRY
+void GLAPIENTRY
_mesa_Uniform3uiv(GLint location, GLsizei count, const GLuint *value)
{
GET_CURRENT_CONTEXT(ctx);
ctx->Driver.Uniform(ctx, location, count, value, GL_UNSIGNED_INT_VEC3);
}
-static void GLAPIENTRY
+void GLAPIENTRY
_mesa_Uniform4uiv(GLint location, GLsizei count, const GLuint *value)
{
GET_CURRENT_CONTEXT(ctx);
@@ -718,7 +718,7 @@ _mesa_Uniform4uiv(GLint location, GLsizei count, const GLuint *value)
-static void GLAPIENTRY
+void GLAPIENTRY
_mesa_UniformMatrix2fvARB(GLint location, GLsizei count, GLboolean transpose,
const GLfloat * value)
{
@@ -726,7 +726,7 @@ _mesa_UniformMatrix2fvARB(GLint location, GLsizei count, GLboolean transpose,
ctx->Driver.UniformMatrix(ctx, 2, 2, location, count, transpose, value);
}
-static void GLAPIENTRY
+void GLAPIENTRY
_mesa_UniformMatrix3fvARB(GLint location, GLsizei count, GLboolean transpose,
const GLfloat * value)
{
@@ -734,7 +734,7 @@ _mesa_UniformMatrix3fvARB(GLint location, GLsizei count, GLboolean transpose,
ctx->Driver.UniformMatrix(ctx, 3, 3, location, count, transpose, value);
}
-static void GLAPIENTRY
+void GLAPIENTRY
_mesa_UniformMatrix4fvARB(GLint location, GLsizei count, GLboolean transpose,
const GLfloat * value)
{
@@ -746,7 +746,7 @@ _mesa_UniformMatrix4fvARB(GLint location, GLsizei count, GLboolean transpose,
/**
* Non-square UniformMatrix are OpenGL 2.1
*/
-static void GLAPIENTRY
+void GLAPIENTRY
_mesa_UniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose,
const GLfloat *value)
{
@@ -754,7 +754,7 @@ _mesa_UniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose,
ctx->Driver.UniformMatrix(ctx, 2, 3, location, count, transpose, value);
}
-static void GLAPIENTRY
+void GLAPIENTRY
_mesa_UniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose,
const GLfloat *value)
{
@@ -762,7 +762,7 @@ _mesa_UniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose,
ctx->Driver.UniformMatrix(ctx, 3, 2, location, count, transpose, value);
}
-static void GLAPIENTRY
+void GLAPIENTRY
_mesa_UniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose,
const GLfloat *value)
{
@@ -770,7 +770,7 @@ _mesa_UniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose,
ctx->Driver.UniformMatrix(ctx, 2, 4, location, count, transpose, value);
}
-static void GLAPIENTRY
+void GLAPIENTRY
_mesa_UniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose,
const GLfloat *value)
{
@@ -778,7 +778,7 @@ _mesa_UniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose,
ctx->Driver.UniformMatrix(ctx, 4, 2, location, count, transpose, value);
}
-static void GLAPIENTRY
+void GLAPIENTRY
_mesa_UniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose,
const GLfloat *value)
{
@@ -786,7 +786,7 @@ _mesa_UniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose,
ctx->Driver.UniformMatrix(ctx, 3, 4, location, count, transpose, value);
}
-static void GLAPIENTRY
+void GLAPIENTRY
_mesa_UniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose,
const GLfloat *value)
{
@@ -804,16 +804,16 @@ _mesa_UseProgramObjectARB(GLhandleARB program)
}
-static void GLAPIENTRY
+void GLAPIENTRY
_mesa_ValidateProgramARB(GLhandleARB program)
{
GET_CURRENT_CONTEXT(ctx);
ctx->Driver.ValidateProgram(ctx, program);
}
-#ifdef FEATURE_ES2
+#if FEATURE_ES2
-static void GLAPIENTRY
+void GLAPIENTRY
_mesa_GetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype,
GLint* range, GLint* precision)
{
@@ -822,7 +822,7 @@ _mesa_GetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype,
}
-static void GLAPIENTRY
+void GLAPIENTRY
_mesa_ReleaseShaderCompiler(void)
{
GET_CURRENT_CONTEXT(ctx);
@@ -830,7 +830,7 @@ _mesa_ReleaseShaderCompiler(void)
}
-static void GLAPIENTRY
+void GLAPIENTRY
_mesa_ShaderBinary(GLint n, const GLuint* shaders, GLenum binaryformat,
const void* binary, GLint length)
{
@@ -847,6 +847,7 @@ _mesa_ShaderBinary(GLint n, const GLuint* shaders, GLenum binaryformat,
void
_mesa_init_shader_dispatch(struct _glapi_table *exec)
{
+#if FEATURE_GL
/* GL_ARB_vertex/fragment_shader */
SET_DeleteObjectARB(exec, _mesa_DeleteObjectARB);
SET_GetHandleARB(exec, _mesa_GetHandleARB);
@@ -917,13 +918,6 @@ _mesa_init_shader_dispatch(struct _glapi_table *exec)
SET_GetAttribLocationARB(exec, _mesa_GetAttribLocationARB);
#endif
-#ifdef FEATURE_ES2
- /* XXX finish dispatch */
- (void) _mesa_GetShaderPrecisionFormat;
- (void) _mesa_ReleaseShaderCompiler;
- (void) _mesa_ShaderBinary;
-#endif
-
/* OpenGL 3.0 */
/* XXX finish dispatch */
(void) _mesa_Uniform1ui;
@@ -934,4 +928,5 @@ _mesa_init_shader_dispatch(struct _glapi_table *exec)
(void) _mesa_Uniform2uiv;
(void) _mesa_Uniform3uiv;
(void) _mesa_Uniform4uiv;
+#endif /* FEATURE_GL */
}
diff --git a/src/mesa/main/shaders.h b/src/mesa/main/shaders.h
index 24c381bd52..af65b2d01a 100644
--- a/src/mesa/main/shaders.h
+++ b/src/mesa/main/shaders.h
@@ -30,12 +30,245 @@
#include "glheader.h"
#include "mtypes.h"
+extern void
+_mesa_init_shader_dispatch(struct _glapi_table *exec);
extern void GLAPIENTRY
-_mesa_UseProgramObjectARB(GLhandleARB program);
+_mesa_DeleteObjectARB(GLhandleARB obj);
-extern void
-_mesa_init_shader_dispatch(struct _glapi_table *exec);
+extern GLhandleARB GLAPIENTRY
+_mesa_GetHandleARB(GLenum pname);
+
+extern void GLAPIENTRY
+_mesa_DetachObjectARB (GLhandleARB, GLhandleARB);
+
+extern GLhandleARB GLAPIENTRY
+_mesa_CreateShaderObjectARB (GLenum);
+
+extern void GLAPIENTRY
+_mesa_ShaderSourceARB (GLhandleARB, GLsizei, const GLcharARB* *, const GLint *);
+
+extern void GLAPIENTRY
+_mesa_CompileShaderARB (GLhandleARB);
+
+extern GLhandleARB GLAPIENTRY
+_mesa_CreateProgramObjectARB (void);
+
+extern void GLAPIENTRY
+_mesa_AttachObjectARB (GLhandleARB, GLhandleARB);
+
+extern void GLAPIENTRY
+_mesa_LinkProgramARB (GLhandleARB);
+
+extern void GLAPIENTRY
+_mesa_UseProgramObjectARB (GLhandleARB);
+
+extern void GLAPIENTRY
+_mesa_ValidateProgramARB (GLhandleARB);
+
+extern void GLAPIENTRY
+_mesa_Uniform1fARB (GLint, GLfloat);
+
+extern void GLAPIENTRY
+_mesa_Uniform2fARB (GLint, GLfloat, GLfloat);
+
+extern void GLAPIENTRY
+_mesa_Uniform3fARB (GLint, GLfloat, GLfloat, GLfloat);
+
+extern void GLAPIENTRY
+_mesa_Uniform4fARB (GLint, GLfloat, GLfloat, GLfloat, GLfloat);
+
+extern void GLAPIENTRY
+_mesa_Uniform1iARB (GLint, GLint);
+
+extern void GLAPIENTRY
+_mesa_Uniform2iARB (GLint, GLint, GLint);
+
+extern void GLAPIENTRY
+_mesa_Uniform3iARB (GLint, GLint, GLint, GLint);
+
+extern void GLAPIENTRY
+_mesa_Uniform4iARB (GLint, GLint, GLint, GLint, GLint);
+
+extern void GLAPIENTRY
+_mesa_Uniform1fvARB (GLint, GLsizei, const GLfloat *);
+
+extern void GLAPIENTRY
+_mesa_Uniform2fvARB (GLint, GLsizei, const GLfloat *);
+
+extern void GLAPIENTRY
+_mesa_Uniform3fvARB (GLint, GLsizei, const GLfloat *);
+
+extern void GLAPIENTRY
+_mesa_Uniform4fvARB (GLint, GLsizei, const GLfloat *);
+
+extern void GLAPIENTRY
+_mesa_Uniform1ivARB (GLint, GLsizei, const GLint *);
+
+extern void GLAPIENTRY
+_mesa_Uniform2ivARB (GLint, GLsizei, const GLint *);
+
+extern void GLAPIENTRY
+_mesa_Uniform3ivARB (GLint, GLsizei, const GLint *);
+
+extern void GLAPIENTRY
+_mesa_Uniform4ivARB (GLint, GLsizei, const GLint *);
+
+extern void GLAPIENTRY
+_mesa_Uniform1ui(GLint location, GLuint v0);
+
+extern void GLAPIENTRY
+_mesa_Uniform2ui(GLint location, GLuint v0, GLuint v1);
+
+extern void GLAPIENTRY
+_mesa_Uniform3ui(GLint location, GLuint v0, GLuint v1, GLuint v2);
+
+extern void GLAPIENTRY
+_mesa_Uniform4ui(GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3);
+
+extern void GLAPIENTRY
+_mesa_Uniform1uiv(GLint location, GLsizei count, const GLuint *value);
+
+extern void GLAPIENTRY
+_mesa_Uniform2uiv(GLint location, GLsizei count, const GLuint *value);
+
+extern void GLAPIENTRY
+_mesa_Uniform3uiv(GLint location, GLsizei count, const GLuint *value);
+
+extern void GLAPIENTRY
+_mesa_Uniform4uiv(GLint location, GLsizei count, const GLuint *value);
+
+
+extern void GLAPIENTRY
+_mesa_UniformMatrix2fvARB (GLint, GLsizei, GLboolean, const GLfloat *);
+extern void GLAPIENTRY
+_mesa_UniformMatrix3fvARB (GLint, GLsizei, GLboolean, const GLfloat *);
+
+extern void GLAPIENTRY
+_mesa_UniformMatrix4fvARB (GLint, GLsizei, GLboolean, const GLfloat *);
+
+extern void GLAPIENTRY
+_mesa_GetObjectParameterfvARB (GLhandleARB, GLenum, GLfloat *);
+
+extern void GLAPIENTRY
+_mesa_GetObjectParameterivARB (GLhandleARB, GLenum, GLint *);
+
+extern void GLAPIENTRY
+_mesa_GetInfoLogARB (GLhandleARB, GLsizei, GLsizei *, GLcharARB *);
+
+extern void GLAPIENTRY
+_mesa_GetAttachedObjectsARB (GLhandleARB, GLsizei, GLsizei *, GLhandleARB *);
+
+extern GLint GLAPIENTRY
+_mesa_GetUniformLocationARB (GLhandleARB, const GLcharARB *);
+
+extern void GLAPIENTRY
+_mesa_GetActiveUniformARB (GLhandleARB, GLuint, GLsizei, GLsizei *, GLint *, GLenum *, GLcharARB *);
+
+extern void GLAPIENTRY
+_mesa_GetUniformfvARB (GLhandleARB, GLint, GLfloat *);
+
+extern void GLAPIENTRY
+_mesa_GetUniformivARB (GLhandleARB, GLint, GLint *);
+
+extern void GLAPIENTRY
+_mesa_GetShaderSourceARB (GLhandleARB, GLsizei, GLsizei *, GLcharARB *);
+
+#if FEATURE_ARB_vertex_shader
+
+extern void GLAPIENTRY
+_mesa_BindAttribLocationARB (GLhandleARB, GLuint, const GLcharARB *);
+
+extern void GLAPIENTRY
+_mesa_GetActiveAttribARB (GLhandleARB, GLuint, GLsizei, GLsizei *, GLint *, GLenum *, GLcharARB *);
+
+extern GLint GLAPIENTRY
+_mesa_GetAttribLocationARB (GLhandleARB, const GLcharARB *);
+
+#endif /* FEATURE_ARB_vertex_shader */
+
+
+/* 2.0 */
+extern void GLAPIENTRY
+_mesa_AttachShader(GLuint program, GLuint shader);
+
+extern GLuint GLAPIENTRY
+_mesa_CreateShader(GLenum);
+
+extern GLuint GLAPIENTRY
+_mesa_CreateProgram(void);
+
+extern void GLAPIENTRY
+_mesa_DeleteProgram(GLuint program);
+
+extern void GLAPIENTRY
+_mesa_DeleteShader(GLuint shader);
+
+extern void GLAPIENTRY
+_mesa_DetachShader(GLuint program, GLuint shader);
+
+extern void GLAPIENTRY
+_mesa_GetAttachedShaders(GLuint program, GLsizei maxCount,
+ GLsizei *count, GLuint *obj);
+
+extern void GLAPIENTRY
+_mesa_GetProgramiv(GLuint program, GLenum pname, GLint *params);
+
+extern void GLAPIENTRY
+_mesa_GetProgramInfoLog(GLuint program, GLsizei bufSize,
+ GLsizei *length, GLchar *infoLog);
+
+extern void GLAPIENTRY
+_mesa_GetShaderiv(GLuint shader, GLenum pname, GLint *params);
+
+extern void GLAPIENTRY
+_mesa_GetShaderInfoLog(GLuint shader, GLsizei bufSize,
+ GLsizei *length, GLchar *infoLog);
+
+extern GLboolean GLAPIENTRY
+_mesa_IsProgram(GLuint program);
+
+extern GLboolean GLAPIENTRY
+_mesa_IsShader(GLuint shader);
+
+
+
+/* 2.1 */
+extern void GLAPIENTRY
+_mesa_UniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose,
+ const GLfloat *value);
+
+extern void GLAPIENTRY
+_mesa_UniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose,
+ const GLfloat *value);
+
+extern void GLAPIENTRY
+_mesa_UniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose,
+ const GLfloat *value);
+
+extern void GLAPIENTRY
+_mesa_UniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose,
+ const GLfloat *value);
+
+extern void GLAPIENTRY
+_mesa_UniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose,
+ const GLfloat *value);
+
+extern void GLAPIENTRY
+_mesa_UniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose,
+ const GLfloat *value);
+
+/* GLES 2.0 */
+extern void GLAPIENTRY
+_mesa_GetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype,
+ GLint* range, GLint* precision);
+
+extern void GLAPIENTRY
+_mesa_ReleaseShaderCompiler(void);
+
+extern void GLAPIENTRY
+_mesa_ShaderBinary(GLint n, const GLuint* shaders, GLenum binaryformat,
+ const void* binary, GLint length);
#endif /* SHADERS_H */
diff --git a/src/mesa/shader/prog_print.c b/src/mesa/shader/prog_print.c
index f66c240ce7..05aae83f0c 100644
--- a/src/mesa/shader/prog_print.c
+++ b/src/mesa/shader/prog_print.c
@@ -876,7 +876,7 @@ binary(GLbitfield64 val)
static char buf[80];
GLint i, len = 0;
for (i = 63; i >= 0; --i) {
- if (val & (1ULL << i))
+ if (val & (BITFIELD64_BIT(i)))
buf[len++] = '1';
else if (len > 0 || i == 0)
buf[len++] = '0';
diff --git a/src/mesa/shader/program_parse.tab.c b/src/mesa/shader/program_parse.tab.c
index 99c4b2baa5..7da7226c32 100644
--- a/src/mesa/shader/program_parse.tab.c
+++ b/src/mesa/shader/program_parse.tab.c
@@ -3366,7 +3366,7 @@ yyreduce:
s->param_binding_type = (yyvsp[(3) - (3)].temp_sym).param_binding_type;
s->param_binding_begin = (yyvsp[(3) - (3)].temp_sym).param_binding_begin;
s->param_binding_length = (yyvsp[(3) - (3)].temp_sym).param_binding_length;
- s->param_binding_swizzle = SWIZZLE_XYZW;
+ s->param_binding_swizzle = (yyvsp[(3) - (3)].temp_sym).param_binding_swizzle;
s->param_is_array = 0;
}
;}
diff --git a/src/mesa/shader/program_parse.y b/src/mesa/shader/program_parse.y
index 06c2db7a07..a2f34b863b 100644
--- a/src/mesa/shader/program_parse.y
+++ b/src/mesa/shader/program_parse.y
@@ -1219,7 +1219,7 @@ PARAM_singleStmt: PARAM IDENTIFIER paramSingleInit
s->param_binding_type = $3.param_binding_type;
s->param_binding_begin = $3.param_binding_begin;
s->param_binding_length = $3.param_binding_length;
- s->param_binding_swizzle = SWIZZLE_XYZW;
+ s->param_binding_swizzle = $3.param_binding_swizzle;
s->param_is_array = 0;
}
}
diff --git a/src/mesa/shader/shader_api.c b/src/mesa/shader/shader_api.c
index cebe899265..c414e89825 100644
--- a/src/mesa/shader/shader_api.c
+++ b/src/mesa/shader/shader_api.c
@@ -41,12 +41,11 @@
#include "main/hash.h"
#include "shader/program.h"
#include "shader/prog_parameter.h"
-#include "shader/prog_statevars.h"
#include "shader/prog_uniform.h"
#include "shader/shader_api.h"
+#include "shader/uniforms.h"
#include "shader/slang/slang_compile.h"
#include "shader/slang/slang_link.h"
-#include "main/dispatch.h"
/**
@@ -222,7 +221,7 @@ _mesa_lookup_shader_program(GLcontext *ctx, GLuint name)
/**
* As above, but record an error if program is not found.
*/
-static struct gl_shader_program *
+struct gl_shader_program *
_mesa_lookup_shader_program_err(GLcontext *ctx, GLuint name,
const char *caller)
{
@@ -840,77 +839,6 @@ _mesa_sizeof_glsl_type(GLenum type)
}
-static GLenum
-base_uniform_type(GLenum type)
-{
- switch (type) {
-#if 0 /* not needed, for now */
- case GL_BOOL:
- case GL_BOOL_VEC2:
- case GL_BOOL_VEC3:
- case GL_BOOL_VEC4:
- return GL_BOOL;
-#endif
- case GL_FLOAT:
- case GL_FLOAT_VEC2:
- case GL_FLOAT_VEC3:
- case GL_FLOAT_VEC4:
- return GL_FLOAT;
- case GL_UNSIGNED_INT:
- case GL_UNSIGNED_INT_VEC2:
- case GL_UNSIGNED_INT_VEC3:
- case GL_UNSIGNED_INT_VEC4:
- return GL_UNSIGNED_INT;
- case GL_INT:
- case GL_INT_VEC2:
- case GL_INT_VEC3:
- case GL_INT_VEC4:
- return GL_INT;
- default:
- _mesa_problem(NULL, "Invalid type in base_uniform_type()");
- return GL_FLOAT;
- }
-}
-
-
-static GLboolean
-is_boolean_type(GLenum type)
-{
- switch (type) {
- case GL_BOOL:
- case GL_BOOL_VEC2:
- case GL_BOOL_VEC3:
- case GL_BOOL_VEC4:
- return GL_TRUE;
- default:
- return GL_FALSE;
- }
-}
-
-
-static GLboolean
-is_sampler_type(GLenum type)
-{
- switch (type) {
- case GL_SAMPLER_1D:
- case GL_SAMPLER_2D:
- case GL_SAMPLER_3D:
- case GL_SAMPLER_CUBE:
- case GL_SAMPLER_1D_SHADOW:
- case GL_SAMPLER_2D_SHADOW:
- case GL_SAMPLER_2D_RECT_ARB:
- case GL_SAMPLER_2D_RECT_SHADOW_ARB:
- case GL_SAMPLER_1D_ARRAY_EXT:
- case GL_SAMPLER_2D_ARRAY_EXT:
- case GL_SAMPLER_1D_ARRAY_SHADOW_EXT:
- case GL_SAMPLER_2D_ARRAY_SHADOW_EXT:
- return GL_TRUE;
- default:
- return GL_FALSE;
- }
-}
-
-
static void
_mesa_get_active_attrib(GLcontext *ctx, GLuint program, GLuint index,
GLsizei maxLength, GLsizei *length, GLint *size,
@@ -943,93 +871,6 @@ _mesa_get_active_attrib(GLcontext *ctx, GLuint program, GLuint index,
}
-static struct gl_program_parameter *
-get_uniform_parameter(const struct gl_shader_program *shProg, GLuint index)
-{
- const struct gl_program *prog = NULL;
- GLint progPos;
-
- progPos = shProg->Uniforms->Uniforms[index].VertPos;
- if (progPos >= 0) {
- prog = &shProg->VertexProgram->Base;
- }
- else {
- progPos = shProg->Uniforms->Uniforms[index].FragPos;
- if (progPos >= 0) {
- prog = &shProg->FragmentProgram->Base;
- }
- }
-
- if (!prog || progPos < 0)
- return NULL; /* should never happen */
-
- return &prog->Parameters->Parameters[progPos];
-}
-
-
-/**
- * Called via ctx->Driver.GetActiveUniform().
- */
-static void
-_mesa_get_active_uniform(GLcontext *ctx, GLuint program, GLuint index,
- GLsizei maxLength, GLsizei *length, GLint *size,
- GLenum *type, GLchar *nameOut)
-{
- const struct gl_shader_program *shProg;
- const struct gl_program *prog = NULL;
- const struct gl_program_parameter *param;
- GLint progPos;
-
- shProg = _mesa_lookup_shader_program_err(ctx, program, "glGetActiveUniform");
- if (!shProg)
- return;
-
- if (!shProg->Uniforms || index >= shProg->Uniforms->NumUniforms) {
- _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveUniform(index)");
- return;
- }
-
- progPos = shProg->Uniforms->Uniforms[index].VertPos;
- if (progPos >= 0) {
- prog = &shProg->VertexProgram->Base;
- }
- else {
- progPos = shProg->Uniforms->Uniforms[index].FragPos;
- if (progPos >= 0) {
- prog = &shProg->FragmentProgram->Base;
- }
- }
-
- if (!prog || progPos < 0)
- return; /* should never happen */
-
- ASSERT(progPos < prog->Parameters->NumParameters);
- param = &prog->Parameters->Parameters[progPos];
-
- if (nameOut) {
- _mesa_copy_string(nameOut, maxLength, length, param->Name);
- }
-
- if (size) {
- GLint typeSize = _mesa_sizeof_glsl_type(param->DataType);
- if ((GLint) param->Size > typeSize) {
- /* This is an array.
- * Array elements are placed on vector[4] boundaries so they're
- * a multiple of four floats. We round typeSize up to next multiple
- * of four to get the right size below.
- */
- typeSize = (typeSize + 3) & ~3;
- }
- /* Note that the returned size is in units of the <type>, not bytes */
- *size = param->Size / typeSize;
- }
-
- if (type) {
- *type = param->DataType;
- }
-}
-
-
/**
* Called via ctx->Driver.GetAttachedShaders().
*/
@@ -1050,21 +891,28 @@ _mesa_get_attached_shaders(GLcontext *ctx, GLuint program, GLsizei maxCount,
}
+/** glGetHandleARB() - return ID/name of currently bound shader program */
static GLuint
_mesa_get_handle(GLcontext *ctx, GLenum pname)
{
- GLint handle = 0;
-
if (pname == GL_PROGRAM_OBJECT_ARB) {
- CALL_GetIntegerv(ctx->Exec, (GL_CURRENT_PROGRAM, &handle));
- } else {
+ if (ctx->Shader.CurrentProgram)
+ return ctx->Shader.CurrentProgram->Name;
+ else
+ return 0;
+ }
+ else {
_mesa_error(ctx, GL_INVALID_ENUM, "glGetHandleARB");
+ return 0;
}
-
- return handle;
}
+/**
+ * glGetProgramiv() - get shader program state.
+ * Note that this is for GLSL shader programs, not ARB vertex/fragment
+ * programs (see glGetProgramivARB).
+ */
static void
_mesa_get_programiv(GLcontext *ctx, GLuint program,
GLenum pname, GLint *params)
@@ -1134,6 +982,7 @@ _mesa_get_programiv(GLcontext *ctx, GLuint program,
}
+/** glGetShaderiv() - get GLSL shader state */
static void
_mesa_get_shaderiv(GLcontext *ctx, GLuint name, GLenum pname, GLint *params)
{
@@ -1209,282 +1058,6 @@ _mesa_get_shader_source(GLcontext *ctx, GLuint shader, GLsizei maxLength,
}
-static void
-get_matrix_dims(GLenum type, GLint *rows, GLint *cols)
-{
- switch (type) {
- case GL_FLOAT_MAT2:
- *rows = *cols = 2;
- break;
- case GL_FLOAT_MAT2x3:
- *rows = 3;
- *cols = 2;
- break;
- case GL_FLOAT_MAT2x4:
- *rows = 4;
- *cols = 2;
- break;
- case GL_FLOAT_MAT3:
- *rows = 3;
- *cols = 3;
- break;
- case GL_FLOAT_MAT3x2:
- *rows = 2;
- *cols = 3;
- break;
- case GL_FLOAT_MAT3x4:
- *rows = 4;
- *cols = 3;
- break;
- case GL_FLOAT_MAT4:
- *rows = 4;
- *cols = 4;
- break;
- case GL_FLOAT_MAT4x2:
- *rows = 2;
- *cols = 4;
- break;
- case GL_FLOAT_MAT4x3:
- *rows = 3;
- *cols = 4;
- break;
- default:
- *rows = *cols = 0;
- }
-}
-
-
-/**
- * Determine the number of rows and columns occupied by a uniform
- * according to its datatype. For non-matrix types (such as GL_FLOAT_VEC4),
- * the number of rows = 1 and cols = number of elements in the vector.
- */
-static void
-get_uniform_rows_cols(const struct gl_program_parameter *p,
- GLint *rows, GLint *cols)
-{
- get_matrix_dims(p->DataType, rows, cols);
- if (*rows == 0 && *cols == 0) {
- /* not a matrix type, probably a float or vector */
- if (p->Size <= 4) {
- *rows = 1;
- *cols = p->Size;
- }
- else {
- *rows = p->Size / 4 + 1;
- if (p->Size % 4 == 0)
- *cols = 4;
- else
- *cols = p->Size % 4;
- }
- }
-}
-
-
-/**
- * Helper for get_uniform[fi]v() functions.
- * Given a shader program name and uniform location, return a pointer
- * to the shader program and return the program parameter position.
- */
-static void
-lookup_uniform_parameter(GLcontext *ctx, GLuint program, GLint location,
- struct gl_program **progOut, GLint *paramPosOut)
-{
- struct gl_shader_program *shProg
- = _mesa_lookup_shader_program_err(ctx, program, "glGetUniform[if]v");
- struct gl_program *prog = NULL;
- GLint progPos = -1;
-
- /* if shProg is NULL, we'll have already recorded an error */
-
- if (shProg) {
- if (!shProg->Uniforms ||
- location < 0 ||
- location >= (GLint) shProg->Uniforms->NumUniforms) {
- _mesa_error(ctx, GL_INVALID_OPERATION, "glGetUniformfv(location)");
- }
- else {
- /* OK, find the gl_program and program parameter location */
- progPos = shProg->Uniforms->Uniforms[location].VertPos;
- if (progPos >= 0) {
- prog = &shProg->VertexProgram->Base;
- }
- else {
- progPos = shProg->Uniforms->Uniforms[location].FragPos;
- if (progPos >= 0) {
- prog = &shProg->FragmentProgram->Base;
- }
- }
- }
- }
-
- *progOut = prog;
- *paramPosOut = progPos;
-}
-
-
-/**
- * Called via ctx->Driver.GetUniformfv().
- */
-static void
-_mesa_get_uniformfv(GLcontext *ctx, GLuint program, GLint location,
- GLfloat *params)
-{
- struct gl_program *prog;
- GLint paramPos;
-
- lookup_uniform_parameter(ctx, program, location, &prog, &paramPos);
-
- if (prog) {
- const struct gl_program_parameter *p =
- &prog->Parameters->Parameters[paramPos];
- GLint rows, cols, i, j, k;
-
- get_uniform_rows_cols(p, &rows, &cols);
-
- k = 0;
- for (i = 0; i < rows; i++) {
- for (j = 0; j < cols; j++ ) {
- params[k++] = prog->Parameters->ParameterValues[paramPos+i][j];
- }
- }
- }
-}
-
-
-/**
- * Called via ctx->Driver.GetUniformiv().
- * \sa _mesa_get_uniformfv, only difference is a cast.
- */
-static void
-_mesa_get_uniformiv(GLcontext *ctx, GLuint program, GLint location,
- GLint *params)
-{
- struct gl_program *prog;
- GLint paramPos;
-
- lookup_uniform_parameter(ctx, program, location, &prog, &paramPos);
-
- if (prog) {
- const struct gl_program_parameter *p =
- &prog->Parameters->Parameters[paramPos];
- GLint rows, cols, i, j, k;
-
- get_uniform_rows_cols(p, &rows, &cols);
-
- k = 0;
- for (i = 0; i < rows; i++) {
- for (j = 0; j < cols; j++ ) {
- params[k++] = (GLint) prog->Parameters->ParameterValues[paramPos+i][j];
- }
- }
- }
-}
-
-
-/**
- * The value returned by GetUniformLocation actually encodes two things:
- * 1. the index into the prog->Uniforms[] array for the uniform
- * 2. an offset in the prog->ParameterValues[] array for specifying array
- * elements or structure fields.
- * This function merges those two values.
- */
-static void
-merge_location_offset(GLint *location, GLint offset)
-{
- *location = *location | (offset << 16);
-}
-
-
-/**
- * Seperate the uniform location and parameter offset. See above.
- */
-static void
-split_location_offset(GLint *location, GLint *offset)
-{
- *offset = (*location >> 16);
- *location = *location & 0xffff;
-}
-
-
-/**
- * Called via ctx->Driver.GetUniformLocation().
- *
- * The return value will encode two values, the uniform location and an
- * offset (used for arrays, structs).
- */
-static GLint
-_mesa_get_uniform_location(GLcontext *ctx, GLuint program, const GLchar *name)
-{
- GLint offset = 0, location = -1;
-
- struct gl_shader_program *shProg =
- _mesa_lookup_shader_program_err(ctx, program, "glGetUniformLocation");
-
- if (!shProg)
- return -1;
-
- if (shProg->LinkStatus == GL_FALSE) {
- _mesa_error(ctx, GL_INVALID_OPERATION, "glGetUniformfv(program)");
- return -1;
- }
-
- /* XXX we should return -1 if the uniform was declared, but not
- * actually used.
- */
-
- /* XXX we need to be able to parse uniform names for structs and arrays
- * such as:
- * mymatrix[1]
- * mystruct.field1
- */
-
- {
- /* handle 1-dimension arrays here... */
- char *c = strchr(name, '[');
- if (c) {
- /* truncate name at [ */
- const GLint len = c - name;
- GLchar *newName = malloc(len + 1);
- if (!newName)
- return -1; /* out of mem */
- memcpy(newName, name, len);
- newName[len] = 0;
-
- location = _mesa_lookup_uniform(shProg->Uniforms, newName);
- if (location >= 0) {
- const GLint element = atoi(c + 1);
- if (element > 0) {
- /* get type of the uniform array element */
- struct gl_program_parameter *p;
- p = get_uniform_parameter(shProg, location);
- if (p) {
- GLint rows, cols;
- get_matrix_dims(p->DataType, &rows, &cols);
- if (rows < 1)
- rows = 1;
- offset = element * rows;
- }
- }
- }
-
- free(newName);
- }
- }
-
- if (location < 0) {
- location = _mesa_lookup_uniform(shProg->Uniforms, name);
- }
-
- if (location >= 0) {
- merge_location_offset(&location, offset);
- }
-
- return location;
-}
-
-
-
/**
* Called via ctx->Driver.ShaderSource()
*/
@@ -1692,422 +1265,6 @@ _mesa_update_shader_textures_used(struct gl_program *prog)
/**
- * Check if the type given by userType is allowed to set a uniform of the
- * target type. Generally, equivalence is required, but setting Boolean
- * uniforms can be done with glUniformiv or glUniformfv.
- */
-static GLboolean
-compatible_types(GLenum userType, GLenum targetType)
-{
- if (userType == targetType)
- return GL_TRUE;
-
- if (targetType == GL_BOOL && (userType == GL_FLOAT ||
- userType == GL_UNSIGNED_INT ||
- userType == GL_INT))
- return GL_TRUE;
-
- if (targetType == GL_BOOL_VEC2 && (userType == GL_FLOAT_VEC2 ||
- userType == GL_UNSIGNED_INT_VEC2 ||
- userType == GL_INT_VEC2))
- return GL_TRUE;
-
- if (targetType == GL_BOOL_VEC3 && (userType == GL_FLOAT_VEC3 ||
- userType == GL_UNSIGNED_INT_VEC3 ||
- userType == GL_INT_VEC3))
- return GL_TRUE;
-
- if (targetType == GL_BOOL_VEC4 && (userType == GL_FLOAT_VEC4 ||
- userType == GL_UNSIGNED_INT_VEC4 ||
- userType == GL_INT_VEC4))
- return GL_TRUE;
-
- if (is_sampler_type(targetType) && userType == GL_INT)
- return GL_TRUE;
-
- return GL_FALSE;
-}
-
-
-/**
- * Set the value of a program's uniform variable.
- * \param program the program whose uniform to update
- * \param index the index of the program parameter for the uniform
- * \param offset additional parameter slot offset (for arrays)
- * \param type the incoming datatype of 'values'
- * \param count the number of uniforms to set
- * \param elems number of elements per uniform (1, 2, 3 or 4)
- * \param values the new values, of datatype 'type'
- */
-static void
-set_program_uniform(GLcontext *ctx, struct gl_program *program,
- GLint index, GLint offset,
- GLenum type, GLsizei count, GLint elems,
- const void *values)
-{
- const struct gl_program_parameter *param =
- &program->Parameters->Parameters[index];
-
- assert(offset >= 0);
- assert(elems >= 1);
- assert(elems <= 4);
-
- if (!compatible_types(type, param->DataType)) {
- _mesa_error(ctx, GL_INVALID_OPERATION, "glUniform(type mismatch)");
- return;
- }
-
- if (index + offset > (GLint) program->Parameters->Size) {
- /* out of bounds! */
- return;
- }
-
- if (param->Type == PROGRAM_SAMPLER) {
- /* This controls which texture unit which is used by a sampler */
- GLboolean changed = GL_FALSE;
- GLint i;
-
- /* this should have been caught by the compatible_types() check */
- ASSERT(type == GL_INT);
-
- /* loop over number of samplers to change */
- for (i = 0; i < count; i++) {
- GLuint sampler =
- (GLuint) program->Parameters->ParameterValues[index + offset + i][0];
- GLuint texUnit = ((GLuint *) values)[i];
-
- /* check that the sampler (tex unit index) is legal */
- if (texUnit >= ctx->Const.MaxTextureImageUnits) {
- _mesa_error(ctx, GL_INVALID_VALUE,
- "glUniform1(invalid sampler/tex unit index for '%s')",
- param->Name);
- return;
- }
-
- /* This maps a sampler to a texture unit: */
- if (sampler < MAX_SAMPLERS) {
-#if 0
- printf("Set program %p sampler %d '%s' to unit %u\n",
- program, sampler, param->Name, texUnit);
-#endif
- if (program->SamplerUnits[sampler] != texUnit) {
- program->SamplerUnits[sampler] = texUnit;
- changed = GL_TRUE;
- }
- }
- }
-
- if (changed) {
- /* When a sampler's value changes it usually requires rewriting
- * a GPU program's TEX instructions since there may not be a
- * sampler->texture lookup table. We signal this with the
- * ProgramStringNotify() callback.
- */
- FLUSH_VERTICES(ctx, _NEW_TEXTURE | _NEW_PROGRAM);
- _mesa_update_shader_textures_used(program);
- /* Do we need to care about the return value here?
- * This should not be the first time the driver was notified of
- * this program.
- */
- (void) ctx->Driver.ProgramStringNotify(ctx, program->Target, program);
- }
- }
- else {
- /* ordinary uniform variable */
- const GLboolean isUniformBool = is_boolean_type(param->DataType);
- const GLenum basicType = base_uniform_type(type);
- const GLint slots = (param->Size + 3) / 4;
- const GLint typeSize = _mesa_sizeof_glsl_type(param->DataType);
- GLsizei k, i;
-
- if ((GLint) param->Size > typeSize) {
- /* an array */
- /* we'll ignore extra data below */
- }
- else {
- /* non-array: count must be at most one; count == 0 is handled by the loop below */
- if (count > 1) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glUniform(uniform '%s' is not an array)",
- param->Name);
- return;
- }
- }
-
- /* loop over number of array elements */
- for (k = 0; k < count; k++) {
- GLfloat *uniformVal;
-
- if (offset + k >= slots) {
- /* Extra array data is ignored */
- break;
- }
-
- /* uniformVal (the destination) is always float[4] */
- uniformVal = program->Parameters->ParameterValues[index + offset + k];
-
- if (basicType == GL_INT) {
- /* convert user's ints to floats */
- const GLint *iValues = ((const GLint *) values) + k * elems;
- for (i = 0; i < elems; i++) {
- uniformVal[i] = (GLfloat) iValues[i];
- }
- }
- else if (basicType == GL_UNSIGNED_INT) {
- /* convert user's uints to floats */
- const GLuint *iValues = ((const GLuint *) values) + k * elems;
- for (i = 0; i < elems; i++) {
- uniformVal[i] = (GLfloat) iValues[i];
- }
- }
- else {
- const GLfloat *fValues = ((const GLfloat *) values) + k * elems;
- assert(basicType == GL_FLOAT);
- for (i = 0; i < elems; i++) {
- uniformVal[i] = fValues[i];
- }
- }
-
- /* if the uniform is bool-valued, convert to 1.0 or 0.0 */
- if (isUniformBool) {
- for (i = 0; i < elems; i++) {
- uniformVal[i] = uniformVal[i] ? 1.0f : 0.0f;
- }
- }
- }
- }
-}
-
-
-/**
- * Called via ctx->Driver.Uniform().
- */
-static void
-_mesa_uniform(GLcontext *ctx, GLint location, GLsizei count,
- const GLvoid *values, GLenum type)
-{
- struct gl_shader_program *shProg = ctx->Shader.CurrentProgram;
- struct gl_uniform *uniform;
- GLint elems, offset;
-
- if (!shProg || !shProg->LinkStatus) {
- _mesa_error(ctx, GL_INVALID_OPERATION, "glUniform(program not linked)");
- return;
- }
-
- if (location == -1)
- return; /* The standard specifies this as a no-op */
-
- if (location < -1) {
- _mesa_error(ctx, GL_INVALID_OPERATION, "glUniform(location=%d)",
- location);
- return;
- }
-
- split_location_offset(&location, &offset);
-
- if (location < 0 || location >= (GLint) shProg->Uniforms->NumUniforms) {
- _mesa_error(ctx, GL_INVALID_VALUE, "glUniform(location=%d)", location);
- return;
- }
-
- if (count < 0) {
- _mesa_error(ctx, GL_INVALID_VALUE, "glUniform(count < 0)");
- return;
- }
-
- elems = _mesa_sizeof_glsl_type(type);
-
- FLUSH_VERTICES(ctx, _NEW_PROGRAM_CONSTANTS);
-
- uniform = &shProg->Uniforms->Uniforms[location];
-
- if (ctx->Shader.Flags & GLSL_UNIFORMS) {
- const GLenum basicType = base_uniform_type(type);
- GLint i;
- printf("Mesa: set program %u uniform %s (loc %d) to: ",
- shProg->Name, uniform->Name, location);
- if (basicType == GL_INT) {
- const GLint *v = (const GLint *) values;
- for (i = 0; i < count * elems; i++) {
- printf("%d ", v[i]);
- }
- }
- else if (basicType == GL_UNSIGNED_INT) {
- const GLuint *v = (const GLuint *) values;
- for (i = 0; i < count * elems; i++) {
- printf("%u ", v[i]);
- }
- }
- else {
- const GLfloat *v = (const GLfloat *) values;
- assert(basicType == GL_FLOAT);
- for (i = 0; i < count * elems; i++) {
- printf("%g ", v[i]);
- }
- }
- printf("\n");
- }
-
- /* A uniform var may be used by both a vertex shader and a fragment
- * shader. We may need to update one or both shader's uniform here:
- */
- if (shProg->VertexProgram) {
- /* convert uniform location to program parameter index */
- GLint index = uniform->VertPos;
- if (index >= 0) {
- set_program_uniform(ctx, &shProg->VertexProgram->Base,
- index, offset, type, count, elems, values);
- }
- }
-
- if (shProg->FragmentProgram) {
- /* convert uniform location to program parameter index */
- GLint index = uniform->FragPos;
- if (index >= 0) {
- set_program_uniform(ctx, &shProg->FragmentProgram->Base,
- index, offset, type, count, elems, values);
- }
- }
-
- uniform->Initialized = GL_TRUE;
-}
-
-
-/**
- * Set a matrix-valued program parameter.
- */
-static void
-set_program_uniform_matrix(GLcontext *ctx, struct gl_program *program,
- GLuint index, GLuint offset,
- GLuint count, GLuint rows, GLuint cols,
- GLboolean transpose, const GLfloat *values)
-{
- GLuint mat, row, col;
- GLuint src = 0;
- const struct gl_program_parameter * param = &program->Parameters->Parameters[index];
- const GLuint slots = (param->Size + 3) / 4;
- const GLint typeSize = _mesa_sizeof_glsl_type(param->DataType);
- GLint nr, nc;
-
- /* check that the number of rows, columns is correct */
- get_matrix_dims(param->DataType, &nr, &nc);
- if (rows != nr || cols != nc) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glUniformMatrix(matrix size mismatch)");
- return;
- }
-
- if ((GLint) param->Size <= typeSize) {
- /* non-array: count must be at most one; count == 0 is handled by the loop below */
- if (count > 1) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glUniformMatrix(uniform is not an array)");
- return;
- }
- }
-
- /*
- * Note: the _columns_ of a matrix are stored in program registers, not
- * the rows. So, the loops below look a little funny.
- * XXX could optimize this a bit...
- */
-
- /* loop over matrices */
- for (mat = 0; mat < count; mat++) {
-
- /* each matrix: */
- for (col = 0; col < cols; col++) {
- GLfloat *v;
- if (offset >= slots) {
- /* Ignore writes beyond the end of (the used part of) an array */
- return;
- }
- v = program->Parameters->ParameterValues[index + offset];
- for (row = 0; row < rows; row++) {
- if (transpose) {
- v[row] = values[src + row * cols + col];
- }
- else {
- v[row] = values[src + col * rows + row];
- }
- }
-
- offset++;
- }
-
- src += rows * cols; /* next matrix */
- }
-}
-
-
-/**
- * Called by ctx->Driver.UniformMatrix().
- * Note: cols=2, rows=4 ==> array[2] of vec4
- */
-static void
-_mesa_uniform_matrix(GLcontext *ctx, GLint cols, GLint rows,
- GLint location, GLsizei count,
- GLboolean transpose, const GLfloat *values)
-{
- struct gl_shader_program *shProg = ctx->Shader.CurrentProgram;
- struct gl_uniform *uniform;
- GLint offset;
-
- if (!shProg || !shProg->LinkStatus) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glUniformMatrix(program not linked)");
- return;
- }
-
- if (location == -1)
- return; /* The standard specifies this as a no-op */
-
- if (location < -1) {
- _mesa_error(ctx, GL_INVALID_OPERATION, "glUniformMatrix(location)");
- return;
- }
-
- split_location_offset(&location, &offset);
-
- if (location < 0 || location >= (GLint) shProg->Uniforms->NumUniforms) {
- _mesa_error(ctx, GL_INVALID_VALUE, "glUniformMatrix(location)");
- return;
- }
- if (values == NULL) {
- _mesa_error(ctx, GL_INVALID_VALUE, "glUniformMatrix");
- return;
- }
-
- FLUSH_VERTICES(ctx, _NEW_PROGRAM_CONSTANTS);
-
- uniform = &shProg->Uniforms->Uniforms[location];
-
- if (shProg->VertexProgram) {
- /* convert uniform location to program parameter index */
- GLint index = uniform->VertPos;
- if (index >= 0) {
- set_program_uniform_matrix(ctx, &shProg->VertexProgram->Base,
- index, offset,
- count, rows, cols, transpose, values);
- }
- }
-
- if (shProg->FragmentProgram) {
- /* convert uniform location to program parameter index */
- GLint index = uniform->FragPos;
- if (index >= 0) {
- set_program_uniform_matrix(ctx, &shProg->FragmentProgram->Base,
- index, offset,
- count, rows, cols, transpose, values);
- }
- }
-
- uniform->Initialized = GL_TRUE;
-}
-
-
-/**
* Validate a program's samplers.
* Specifically, check that there aren't two samplers of different types
* pointing to the same texture unit.
@@ -2248,7 +1405,6 @@ _mesa_init_glsl_driver_functions(struct dd_function_table *driver)
driver->DeleteShader = _mesa_delete_shader;
driver->DetachShader = _mesa_detach_shader;
driver->GetActiveAttrib = _mesa_get_active_attrib;
- driver->GetActiveUniform = _mesa_get_active_uniform;
driver->GetAttachedShaders = _mesa_get_attached_shaders;
driver->GetAttribLocation = _mesa_get_attrib_location;
driver->GetHandle = _mesa_get_handle;
@@ -2257,15 +1413,12 @@ _mesa_init_glsl_driver_functions(struct dd_function_table *driver)
driver->GetShaderiv = _mesa_get_shaderiv;
driver->GetShaderInfoLog = _mesa_get_shader_info_log;
driver->GetShaderSource = _mesa_get_shader_source;
- driver->GetUniformfv = _mesa_get_uniformfv;
- driver->GetUniformiv = _mesa_get_uniformiv;
- driver->GetUniformLocation = _mesa_get_uniform_location;
driver->IsProgram = _mesa_is_program;
driver->IsShader = _mesa_is_shader;
driver->LinkProgram = _mesa_link_program;
driver->ShaderSource = _mesa_shader_source;
- driver->Uniform = _mesa_uniform;
- driver->UniformMatrix = _mesa_uniform_matrix;
driver->UseProgram = _mesa_use_program;
driver->ValidateProgram = _mesa_validate_program;
+
+ _mesa_init_uniform_functions(driver);
}
diff --git a/src/mesa/shader/shader_api.h b/src/mesa/shader/shader_api.h
index 597f0b8e75..9743a23ce6 100644
--- a/src/mesa/shader/shader_api.h
+++ b/src/mesa/shader/shader_api.h
@@ -75,6 +75,10 @@ extern struct gl_shader_program *
_mesa_lookup_shader_program(GLcontext *ctx, GLuint name);
+extern struct gl_shader_program *
+_mesa_lookup_shader_program_err(GLcontext *ctx, GLuint name,
+ const char *caller);
+
extern struct gl_shader *
_mesa_new_shader(GLcontext *ctx, GLuint name, GLenum type);
diff --git a/src/mesa/shader/slang/slang_emit.c b/src/mesa/shader/slang/slang_emit.c
index 974c4a3131..4d4c611dfe 100644
--- a/src/mesa/shader/slang/slang_emit.c
+++ b/src/mesa/shader/slang/slang_emit.c
@@ -366,7 +366,7 @@ storage_to_src_reg(struct prog_src_register *src, const slang_ir_storage *st)
st0->File = PROGRAM_TEMPORARY;
}
#endif
- assert(st->File < PROGRAM_UNDEFINED);
+ assert(st->File < PROGRAM_FILE_MAX);
src->File = st->File;
assert(index >= 0);
diff --git a/src/mesa/shader/slang/slang_link.c b/src/mesa/shader/slang/slang_link.c
index 3d4208ce4c..2d003ef9c3 100644
--- a/src/mesa/shader/slang/slang_link.c
+++ b/src/mesa/shader/slang/slang_link.c
@@ -591,6 +591,108 @@ _slang_count_temporaries(struct gl_program *prog)
/**
+ * If an input attribute is indexed with relative addressing we have
+ * to compute a gl_program::InputsRead bitmask which reflects the fact
+ * that any input may be referenced by array element. Ex: gl_TexCoord[i].
+ * This function computes the bitmask of potentially read inputs.
+ */
+static GLbitfield
+get_inputs_read_mask(GLenum target, GLuint index, GLboolean relAddr)
+{
+ GLbitfield mask;
+
+ mask = 1 << index;
+
+ if (relAddr) {
+ if (target == GL_VERTEX_PROGRAM_ARB) {
+ switch (index) {
+ case VERT_ATTRIB_TEX0:
+ mask = ((1U << (VERT_ATTRIB_TEX7 + 1)) - 1)
+ - ((1U << VERT_ATTRIB_TEX0) - 1);
+ break;
+ case VERT_ATTRIB_GENERIC0:
+ /* different code to avoid uint overflow */
+ mask = ~0x0U - ((1U << VERT_ATTRIB_GENERIC0) - 1);
+ break;
+ default:
+ ; /* a non-array input attribute */
+ }
+ }
+ else if (target == GL_FRAGMENT_PROGRAM_ARB) {
+ switch (index) {
+ case FRAG_ATTRIB_TEX0:
+ mask = ((1U << (FRAG_ATTRIB_TEX7 + 1)) - 1)
+ - ((1U << FRAG_ATTRIB_TEX0) - 1);
+ break;
+ case FRAG_ATTRIB_VAR0:
+ mask = ((1U << (FRAG_ATTRIB_VAR0 + MAX_VARYING)) - 1)
+ - ((1U << FRAG_ATTRIB_VAR0) - 1);
+ break;
+ default:
+ ; /* a non-array input attribute */
+ }
+ }
+ else {
+ assert(0 && "bad program target");
+ }
+ }
+ else {
+ }
+
+ return mask;
+}
+
+
+/**
+ * If an output attribute is indexed with relative addressing we have
+ * to compute a gl_program::OutputsWritten bitmask which reflects the fact
+ * that any output may be referenced by array element. Ex: gl_TexCoord[i].
+ * This function computes the bitmask of potentially written outputs.
+ */
+static GLbitfield64
+get_outputs_written_mask(GLenum target, GLuint index, GLboolean relAddr)
+{
+ GLbitfield64 mask;
+
+ mask = BITFIELD64_BIT(index);
+
+ if (relAddr) {
+ if (target == GL_VERTEX_PROGRAM_ARB) {
+ switch (index) {
+ case VERT_RESULT_TEX0:
+ mask = BITFIELD64_RANGE(VERT_RESULT_TEX0,
+ (VERT_RESULT_TEX0
+ + MAX_TEXTURE_COORD_UNITS - 1));
+ break;
+ case VERT_RESULT_VAR0:
+ mask = BITFIELD64_RANGE(VERT_RESULT_VAR0,
+ (VERT_RESULT_VAR0 + MAX_VARYING - 1));
+ break;
+ default:
+ ; /* a non-array output attribute */
+ }
+ }
+ else if (target == GL_FRAGMENT_PROGRAM_ARB) {
+ switch (index) {
+ case FRAG_RESULT_DATA0:
+ mask = BITFIELD64_RANGE(FRAG_RESULT_DATA0,
+ (FRAG_RESULT_DATA0
+ + MAX_DRAW_BUFFERS - 1));
+ break;
+ default:
+ ; /* a non-array output attribute */
+ }
+ }
+ else {
+ assert(0 && "bad program target");
+ }
+ }
+
+ return mask;
+}
+
+
+/**
* Scan program instructions to update the program's InputsRead and
* OutputsWritten fields.
*/
@@ -608,7 +710,9 @@ _slang_update_inputs_outputs(struct gl_program *prog)
const GLuint numSrc = _mesa_num_inst_src_regs(inst->Opcode);
for (j = 0; j < numSrc; j++) {
if (inst->SrcReg[j].File == PROGRAM_INPUT) {
- prog->InputsRead |= 1 << inst->SrcReg[j].Index;
+ prog->InputsRead |= get_inputs_read_mask(prog->Target,
+ inst->SrcReg[j].Index,
+ inst->SrcReg[j].RelAddr);
}
else if (inst->SrcReg[j].File == PROGRAM_ADDRESS) {
maxAddrReg = MAX2(maxAddrReg, (GLuint) (inst->SrcReg[j].Index + 1));
@@ -616,34 +720,9 @@ _slang_update_inputs_outputs(struct gl_program *prog)
}
if (inst->DstReg.File == PROGRAM_OUTPUT) {
- prog->OutputsWritten |= BITFIELD64_BIT(inst->DstReg.Index);
- if (inst->DstReg.RelAddr) {
- /* If the output attribute is indexed with relative addressing
- * we know that it must be a varying or texcoord such as
- * gl_TexCoord[i] = v; In this case, mark all the texcoords
- * or varying outputs as being written. It's not an error if
- * a vertex shader writes varying vars that aren't used by the
- * fragment shader. But it is an error for a fragment shader
- * to use varyings that are not written by the vertex shader.
- */
- if (prog->Target == GL_VERTEX_PROGRAM_ARB) {
- if (inst->DstReg.Index == VERT_RESULT_TEX0) {
- /* mark all texcoord outputs as written */
- const GLbitfield64 mask =
- BITFIELD64_RANGE(VERT_RESULT_TEX0,
- (VERT_RESULT_TEX0
- + MAX_TEXTURE_COORD_UNITS - 1));
- prog->OutputsWritten |= mask;
- }
- else if (inst->DstReg.Index == VERT_RESULT_VAR0) {
- /* mark all generic varying outputs as written */
- const GLbitfield64 mask =
- BITFIELD64_RANGE(VERT_RESULT_VAR0,
- (VERT_RESULT_VAR0 + MAX_VARYING - 1));
- prog->OutputsWritten |= mask;
- }
- }
- }
+ prog->OutputsWritten |= get_outputs_written_mask(prog->Target,
+ inst->DstReg.Index,
+ inst->DstReg.RelAddr);
}
else if (inst->DstReg.File == PROGRAM_ADDRESS) {
maxAddrReg = MAX2(maxAddrReg, inst->DstReg.Index + 1);
diff --git a/src/mesa/shader/uniforms.c b/src/mesa/shader/uniforms.c
new file mode 100644
index 0000000000..b1fb90d020
--- /dev/null
+++ b/src/mesa/shader/uniforms.c
@@ -0,0 +1,937 @@
+/*
+ * Mesa 3-D graphics library
+ *
+ * Copyright (C) 2004-2008 Brian Paul All Rights Reserved.
+ * Copyright (C) 2009-2010 VMware, Inc. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, 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
+ * BRIAN PAUL 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 uniforms.c
+ * Functions related to GLSL uniform variables.
+ * \author Brian Paul
+ */
+
+/**
+ * XXX things to do:
+ * 1. Check that the right error code is generated for all _mesa_error() calls.
+ * 2. Insert FLUSH_VERTICES calls in various places
+ */
+
+
+#include "main/glheader.h"
+#include "main/context.h"
+#include "shader/prog_parameter.h"
+#include "shader/prog_statevars.h"
+#include "shader/prog_uniform.h"
+#include "shader/shader_api.h"
+#include "uniforms.h"
+
+
+
+static GLenum
+base_uniform_type(GLenum type)
+{
+ switch (type) {
+#if 0 /* not needed, for now */
+ case GL_BOOL:
+ case GL_BOOL_VEC2:
+ case GL_BOOL_VEC3:
+ case GL_BOOL_VEC4:
+ return GL_BOOL;
+#endif
+ case GL_FLOAT:
+ case GL_FLOAT_VEC2:
+ case GL_FLOAT_VEC3:
+ case GL_FLOAT_VEC4:
+ return GL_FLOAT;
+ case GL_UNSIGNED_INT:
+ case GL_UNSIGNED_INT_VEC2:
+ case GL_UNSIGNED_INT_VEC3:
+ case GL_UNSIGNED_INT_VEC4:
+ return GL_UNSIGNED_INT;
+ case GL_INT:
+ case GL_INT_VEC2:
+ case GL_INT_VEC3:
+ case GL_INT_VEC4:
+ return GL_INT;
+ default:
+ _mesa_problem(NULL, "Invalid type in base_uniform_type()");
+ return GL_FLOAT;
+ }
+}
+
+
+static GLboolean
+is_boolean_type(GLenum type)
+{
+ switch (type) {
+ case GL_BOOL:
+ case GL_BOOL_VEC2:
+ case GL_BOOL_VEC3:
+ case GL_BOOL_VEC4:
+ return GL_TRUE;
+ default:
+ return GL_FALSE;
+ }
+}
+
+
+static GLboolean
+is_sampler_type(GLenum type)
+{
+ switch (type) {
+ case GL_SAMPLER_1D:
+ case GL_SAMPLER_2D:
+ case GL_SAMPLER_3D:
+ case GL_SAMPLER_CUBE:
+ case GL_SAMPLER_1D_SHADOW:
+ case GL_SAMPLER_2D_SHADOW:
+ case GL_SAMPLER_2D_RECT_ARB:
+ case GL_SAMPLER_2D_RECT_SHADOW_ARB:
+ case GL_SAMPLER_1D_ARRAY_EXT:
+ case GL_SAMPLER_2D_ARRAY_EXT:
+ case GL_SAMPLER_1D_ARRAY_SHADOW_EXT:
+ case GL_SAMPLER_2D_ARRAY_SHADOW_EXT:
+ return GL_TRUE;
+ default:
+ return GL_FALSE;
+ }
+}
+
+
+static struct gl_program_parameter *
+get_uniform_parameter(const struct gl_shader_program *shProg, GLuint index)
+{
+ const struct gl_program *prog = NULL;
+ GLint progPos;
+
+ progPos = shProg->Uniforms->Uniforms[index].VertPos;
+ if (progPos >= 0) {
+ prog = &shProg->VertexProgram->Base;
+ }
+ else {
+ progPos = shProg->Uniforms->Uniforms[index].FragPos;
+ if (progPos >= 0) {
+ prog = &shProg->FragmentProgram->Base;
+ }
+ }
+
+ if (!prog || progPos < 0)
+ return NULL; /* should never happen */
+
+ return &prog->Parameters->Parameters[progPos];
+}
+
+
+/**
+ * Called via ctx->Driver.GetActiveUniform().
+ */
+static void
+_mesa_get_active_uniform(GLcontext *ctx, GLuint program, GLuint index,
+ GLsizei maxLength, GLsizei *length, GLint *size,
+ GLenum *type, GLchar *nameOut)
+{
+ const struct gl_shader_program *shProg;
+ const struct gl_program *prog = NULL;
+ const struct gl_program_parameter *param;
+ GLint progPos;
+
+ shProg = _mesa_lookup_shader_program_err(ctx, program, "glGetActiveUniform");
+ if (!shProg)
+ return;
+
+ if (!shProg->Uniforms || index >= shProg->Uniforms->NumUniforms) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveUniform(index)");
+ return;
+ }
+
+ progPos = shProg->Uniforms->Uniforms[index].VertPos;
+ if (progPos >= 0) {
+ prog = &shProg->VertexProgram->Base;
+ }
+ else {
+ progPos = shProg->Uniforms->Uniforms[index].FragPos;
+ if (progPos >= 0) {
+ prog = &shProg->FragmentProgram->Base;
+ }
+ }
+
+ if (!prog || progPos < 0)
+ return; /* should never happen */
+
+ ASSERT(progPos < prog->Parameters->NumParameters);
+ param = &prog->Parameters->Parameters[progPos];
+
+ if (nameOut) {
+ _mesa_copy_string(nameOut, maxLength, length, param->Name);
+ }
+
+ if (size) {
+ GLint typeSize = _mesa_sizeof_glsl_type(param->DataType);
+ if ((GLint) param->Size > typeSize) {
+ /* This is an array.
+ * Array elements are placed on vector[4] boundaries so they're
+ * a multiple of four floats. We round typeSize up to next multiple
+ * of four to get the right size below.
+ */
+ typeSize = (typeSize + 3) & ~3;
+ }
+ /* Note that the returned size is in units of the <type>, not bytes */
+ *size = param->Size / typeSize;
+ }
+
+ if (type) {
+ *type = param->DataType;
+ }
+}
+
+
+
+static void
+get_matrix_dims(GLenum type, GLint *rows, GLint *cols)
+{
+ switch (type) {
+ case GL_FLOAT_MAT2:
+ *rows = *cols = 2;
+ break;
+ case GL_FLOAT_MAT2x3:
+ *rows = 3;
+ *cols = 2;
+ break;
+ case GL_FLOAT_MAT2x4:
+ *rows = 4;
+ *cols = 2;
+ break;
+ case GL_FLOAT_MAT3:
+ *rows = 3;
+ *cols = 3;
+ break;
+ case GL_FLOAT_MAT3x2:
+ *rows = 2;
+ *cols = 3;
+ break;
+ case GL_FLOAT_MAT3x4:
+ *rows = 4;
+ *cols = 3;
+ break;
+ case GL_FLOAT_MAT4:
+ *rows = 4;
+ *cols = 4;
+ break;
+ case GL_FLOAT_MAT4x2:
+ *rows = 2;
+ *cols = 4;
+ break;
+ case GL_FLOAT_MAT4x3:
+ *rows = 3;
+ *cols = 4;
+ break;
+ default:
+ *rows = *cols = 0;
+ }
+}
+
+
+/**
+ * Determine the number of rows and columns occupied by a uniform
+ * according to its datatype. For non-matrix types (such as GL_FLOAT_VEC4),
+ * the number of rows = 1 and cols = number of elements in the vector.
+ */
+static void
+get_uniform_rows_cols(const struct gl_program_parameter *p,
+ GLint *rows, GLint *cols)
+{
+ get_matrix_dims(p->DataType, rows, cols);
+ if (*rows == 0 && *cols == 0) {
+ /* not a matrix type, probably a float or vector */
+ if (p->Size <= 4) {
+ *rows = 1;
+ *cols = p->Size;
+ }
+ else {
+ *rows = p->Size / 4 + 1;
+ if (p->Size % 4 == 0)
+ *cols = 4;
+ else
+ *cols = p->Size % 4;
+ }
+ }
+}
+
+
+/**
+ * Helper for get_uniform[fi]v() functions.
+ * Given a shader program name and uniform location, return a pointer
+ * to the shader program and return the program parameter position.
+ */
+static void
+lookup_uniform_parameter(GLcontext *ctx, GLuint program, GLint location,
+ struct gl_program **progOut, GLint *paramPosOut)
+{
+ struct gl_shader_program *shProg
+ = _mesa_lookup_shader_program_err(ctx, program, "glGetUniform[if]v");
+ struct gl_program *prog = NULL;
+ GLint progPos = -1;
+
+ /* if shProg is NULL, we'll have already recorded an error */
+
+ if (shProg) {
+ if (!shProg->Uniforms ||
+ location < 0 ||
+ location >= (GLint) shProg->Uniforms->NumUniforms) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glGetUniformfv(location)");
+ }
+ else {
+ /* OK, find the gl_program and program parameter location */
+ progPos = shProg->Uniforms->Uniforms[location].VertPos;
+ if (progPos >= 0) {
+ prog = &shProg->VertexProgram->Base;
+ }
+ else {
+ progPos = shProg->Uniforms->Uniforms[location].FragPos;
+ if (progPos >= 0) {
+ prog = &shProg->FragmentProgram->Base;
+ }
+ }
+ }
+ }
+
+ *progOut = prog;
+ *paramPosOut = progPos;
+}
+
+
+/**
+ * GLGL uniform arrays and structs require special handling.
+ *
+ * The GL_ARB_shader_objects spec says that if you use
+ * glGetUniformLocation to get the location of an array, you CANNOT
+ * access other elements of the array by adding an offset to the
+ * returned location. For example, you must call
+ * glGetUniformLocation("foo[16]") if you want to set the 16th element
+ * of the array with glUniform().
+ *
+ * HOWEVER, some other OpenGL drivers allow accessing array elements
+ * by adding an offset to the returned array location. And some apps
+ * seem to depend on that behaviour.
+ *
+ * Mesa's gl_uniform_list doesn't directly support this since each
+ * entry in the list describes one uniform variable, not one uniform
+ * element. We could insert dummy entries in the list for each array
+ * element after [0] but that causes complications elsewhere.
+ *
+ * We solve this problem by encoding two values in the location that's
+ * returned by glGetUniformLocation():
+ * a) index into gl_uniform_list::Uniforms[] for the uniform
+ * b) an array/field offset (0 for simple types)
+ *
+ * These two values are encoded in the high and low halves of a GLint.
+ * By putting the uniform number in the high part and the offset in the
+ * low part, we can support the unofficial ability to index into arrays
+ * by adding offsets to the location value.
+ */
+static void
+merge_location_offset(GLint *location, GLint offset)
+{
+ *location = (*location << 16) | offset;
+}
+
+
+/**
+ * Separate the uniform location and parameter offset. See above.
+ */
+static void
+split_location_offset(GLint *location, GLint *offset)
+{
+ *offset = *location & 0xffff;
+ *location = *location >> 16;
+}
+
+
+
+/**
+ * Called via ctx->Driver.GetUniformfv().
+ */
+static void
+_mesa_get_uniformfv(GLcontext *ctx, GLuint program, GLint location,
+ GLfloat *params)
+{
+ struct gl_program *prog;
+ GLint paramPos;
+ GLint offset;
+
+ split_location_offset(&location, &offset);
+
+ lookup_uniform_parameter(ctx, program, location, &prog, &paramPos);
+
+ if (prog) {
+ const struct gl_program_parameter *p =
+ &prog->Parameters->Parameters[paramPos];
+ GLint rows, cols, i, j, k;
+
+ get_uniform_rows_cols(p, &rows, &cols);
+
+ k = 0;
+ for (i = 0; i < rows; i++) {
+ for (j = 0; j < cols; j++ ) {
+ params[k++] = prog->Parameters->ParameterValues[paramPos+i][j];
+ }
+ }
+ }
+}
+
+
+/**
+ * Called via ctx->Driver.GetUniformiv().
+ * \sa _mesa_get_uniformfv, only difference is a cast.
+ */
+static void
+_mesa_get_uniformiv(GLcontext *ctx, GLuint program, GLint location,
+ GLint *params)
+{
+ struct gl_program *prog;
+ GLint paramPos;
+ GLint offset;
+
+ split_location_offset(&location, &offset);
+
+ lookup_uniform_parameter(ctx, program, location, &prog, &paramPos);
+
+ if (prog) {
+ const struct gl_program_parameter *p =
+ &prog->Parameters->Parameters[paramPos];
+ GLint rows, cols, i, j, k;
+
+ get_uniform_rows_cols(p, &rows, &cols);
+
+ k = 0;
+ for (i = 0; i < rows; i++) {
+ for (j = 0; j < cols; j++ ) {
+ params[k++] = (GLint) prog->Parameters->ParameterValues[paramPos+i][j];
+ }
+ }
+ }
+}
+
+
+/**
+ * Called via ctx->Driver.GetUniformLocation().
+ *
+ * The return value will encode two values, the uniform location and an
+ * offset (used for arrays, structs).
+ */
+static GLint
+_mesa_get_uniform_location(GLcontext *ctx, GLuint program, const GLchar *name)
+{
+ GLint offset = 0, location = -1;
+
+ struct gl_shader_program *shProg =
+ _mesa_lookup_shader_program_err(ctx, program, "glGetUniformLocation");
+
+ if (!shProg)
+ return -1;
+
+ if (shProg->LinkStatus == GL_FALSE) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glGetUniformfv(program)");
+ return -1;
+ }
+
+ /* XXX we should return -1 if the uniform was declared, but not
+ * actually used.
+ */
+
+ /* XXX we need to be able to parse uniform names for structs and arrays
+ * such as:
+ * mymatrix[1]
+ * mystruct.field1
+ */
+
+ {
+ /* handle 1-dimension arrays here... */
+ char *c = strchr(name, '[');
+ if (c) {
+ /* truncate name at [ */
+ const GLint len = c - name;
+ GLchar *newName = malloc(len + 1);
+ if (!newName)
+ return -1; /* out of mem */
+ memcpy(newName, name, len);
+ newName[len] = 0;
+
+ location = _mesa_lookup_uniform(shProg->Uniforms, newName);
+ if (location >= 0) {
+ const GLint element = atoi(c + 1);
+ if (element > 0) {
+ /* get type of the uniform array element */
+ struct gl_program_parameter *p;
+ p = get_uniform_parameter(shProg, location);
+ if (p) {
+ GLint rows, cols;
+ get_matrix_dims(p->DataType, &rows, &cols);
+ if (rows < 1)
+ rows = 1;
+ offset = element * rows;
+ }
+ }
+ }
+
+ free(newName);
+ }
+ }
+
+ if (location < 0) {
+ location = _mesa_lookup_uniform(shProg->Uniforms, name);
+ }
+
+ if (location >= 0) {
+ merge_location_offset(&location, offset);
+ }
+
+ return location;
+}
+
+
+/**
+ * Check if the type given by userType is allowed to set a uniform of the
+ * target type. Generally, equivalence is required, but setting Boolean
+ * uniforms can be done with glUniformiv or glUniformfv.
+ */
+static GLboolean
+compatible_types(GLenum userType, GLenum targetType)
+{
+ if (userType == targetType)
+ return GL_TRUE;
+
+ if (targetType == GL_BOOL && (userType == GL_FLOAT ||
+ userType == GL_UNSIGNED_INT ||
+ userType == GL_INT))
+ return GL_TRUE;
+
+ if (targetType == GL_BOOL_VEC2 && (userType == GL_FLOAT_VEC2 ||
+ userType == GL_UNSIGNED_INT_VEC2 ||
+ userType == GL_INT_VEC2))
+ return GL_TRUE;
+
+ if (targetType == GL_BOOL_VEC3 && (userType == GL_FLOAT_VEC3 ||
+ userType == GL_UNSIGNED_INT_VEC3 ||
+ userType == GL_INT_VEC3))
+ return GL_TRUE;
+
+ if (targetType == GL_BOOL_VEC4 && (userType == GL_FLOAT_VEC4 ||
+ userType == GL_UNSIGNED_INT_VEC4 ||
+ userType == GL_INT_VEC4))
+ return GL_TRUE;
+
+ if (is_sampler_type(targetType) && userType == GL_INT)
+ return GL_TRUE;
+
+ return GL_FALSE;
+}
+
+
+/**
+ * Set the value of a program's uniform variable.
+ * \param program the program whose uniform to update
+ * \param index the index of the program parameter for the uniform
+ * \param offset additional parameter slot offset (for arrays)
+ * \param type the incoming datatype of 'values'
+ * \param count the number of uniforms to set
+ * \param elems number of elements per uniform (1, 2, 3 or 4)
+ * \param values the new values, of datatype 'type'
+ */
+static void
+set_program_uniform(GLcontext *ctx, struct gl_program *program,
+ GLint index, GLint offset,
+ GLenum type, GLsizei count, GLint elems,
+ const void *values)
+{
+ const struct gl_program_parameter *param =
+ &program->Parameters->Parameters[index];
+
+ assert(offset >= 0);
+ assert(elems >= 1);
+ assert(elems <= 4);
+
+ if (!compatible_types(type, param->DataType)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glUniform(type mismatch)");
+ return;
+ }
+
+ if (index + offset > (GLint) program->Parameters->Size) {
+ /* out of bounds! */
+ return;
+ }
+
+ if (param->Type == PROGRAM_SAMPLER) {
+ /* This controls which texture unit which is used by a sampler */
+ GLboolean changed = GL_FALSE;
+ GLint i;
+
+ /* this should have been caught by the compatible_types() check */
+ ASSERT(type == GL_INT);
+
+ /* loop over number of samplers to change */
+ for (i = 0; i < count; i++) {
+ GLuint sampler =
+ (GLuint) program->Parameters->ParameterValues[index + offset + i][0];
+ GLuint texUnit = ((GLuint *) values)[i];
+
+ /* check that the sampler (tex unit index) is legal */
+ if (texUnit >= ctx->Const.MaxTextureImageUnits) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glUniform1(invalid sampler/tex unit index for '%s')",
+ param->Name);
+ return;
+ }
+
+ /* This maps a sampler to a texture unit: */
+ if (sampler < MAX_SAMPLERS) {
+#if 0
+ printf("Set program %p sampler %d '%s' to unit %u\n",
+ program, sampler, param->Name, texUnit);
+#endif
+ if (program->SamplerUnits[sampler] != texUnit) {
+ program->SamplerUnits[sampler] = texUnit;
+ changed = GL_TRUE;
+ }
+ }
+ }
+
+ if (changed) {
+ /* When a sampler's value changes it usually requires rewriting
+ * a GPU program's TEX instructions since there may not be a
+ * sampler->texture lookup table. We signal this with the
+ * ProgramStringNotify() callback.
+ */
+ FLUSH_VERTICES(ctx, _NEW_TEXTURE | _NEW_PROGRAM);
+ _mesa_update_shader_textures_used(program);
+ /* Do we need to care about the return value here?
+ * This should not be the first time the driver was notified of
+ * this program.
+ */
+ (void) ctx->Driver.ProgramStringNotify(ctx, program->Target, program);
+ }
+ }
+ else {
+ /* ordinary uniform variable */
+ const GLboolean isUniformBool = is_boolean_type(param->DataType);
+ const GLenum basicType = base_uniform_type(type);
+ const GLint slots = (param->Size + 3) / 4;
+ const GLint typeSize = _mesa_sizeof_glsl_type(param->DataType);
+ GLsizei k, i;
+
+ if ((GLint) param->Size > typeSize) {
+ /* an array */
+ /* we'll ignore extra data below */
+ }
+ else {
+ /* non-array: count must be at most one; count == 0 is handled by the loop below */
+ if (count > 1) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glUniform(uniform '%s' is not an array)",
+ param->Name);
+ return;
+ }
+ }
+
+ /* loop over number of array elements */
+ for (k = 0; k < count; k++) {
+ GLfloat *uniformVal;
+
+ if (offset + k >= slots) {
+ /* Extra array data is ignored */
+ break;
+ }
+
+ /* uniformVal (the destination) is always float[4] */
+ uniformVal = program->Parameters->ParameterValues[index + offset + k];
+
+ if (basicType == GL_INT) {
+ /* convert user's ints to floats */
+ const GLint *iValues = ((const GLint *) values) + k * elems;
+ for (i = 0; i < elems; i++) {
+ uniformVal[i] = (GLfloat) iValues[i];
+ }
+ }
+ else if (basicType == GL_UNSIGNED_INT) {
+ /* convert user's uints to floats */
+ const GLuint *iValues = ((const GLuint *) values) + k * elems;
+ for (i = 0; i < elems; i++) {
+ uniformVal[i] = (GLfloat) iValues[i];
+ }
+ }
+ else {
+ const GLfloat *fValues = ((const GLfloat *) values) + k * elems;
+ assert(basicType == GL_FLOAT);
+ for (i = 0; i < elems; i++) {
+ uniformVal[i] = fValues[i];
+ }
+ }
+
+ /* if the uniform is bool-valued, convert to 1.0 or 0.0 */
+ if (isUniformBool) {
+ for (i = 0; i < elems; i++) {
+ uniformVal[i] = uniformVal[i] ? 1.0f : 0.0f;
+ }
+ }
+ }
+ }
+}
+
+
+/**
+ * Called via ctx->Driver.Uniform().
+ */
+static void
+_mesa_uniform(GLcontext *ctx, GLint location, GLsizei count,
+ const GLvoid *values, GLenum type)
+{
+ struct gl_shader_program *shProg = ctx->Shader.CurrentProgram;
+ struct gl_uniform *uniform;
+ GLint elems, offset;
+
+ if (!shProg || !shProg->LinkStatus) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glUniform(program not linked)");
+ return;
+ }
+
+ if (location == -1)
+ return; /* The standard specifies this as a no-op */
+
+ if (location < -1) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glUniform(location=%d)",
+ location);
+ return;
+ }
+
+ split_location_offset(&location, &offset);
+
+ if (location < 0 || location >= (GLint) shProg->Uniforms->NumUniforms) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glUniform(location=%d)", location);
+ return;
+ }
+
+ if (count < 0) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glUniform(count < 0)");
+ return;
+ }
+
+ elems = _mesa_sizeof_glsl_type(type);
+
+ FLUSH_VERTICES(ctx, _NEW_PROGRAM_CONSTANTS);
+
+ uniform = &shProg->Uniforms->Uniforms[location];
+
+ if (ctx->Shader.Flags & GLSL_UNIFORMS) {
+ const GLenum basicType = base_uniform_type(type);
+ GLint i;
+ printf("Mesa: set program %u uniform %s (loc %d) to: ",
+ shProg->Name, uniform->Name, location);
+ if (basicType == GL_INT) {
+ const GLint *v = (const GLint *) values;
+ for (i = 0; i < count * elems; i++) {
+ printf("%d ", v[i]);
+ }
+ }
+ else if (basicType == GL_UNSIGNED_INT) {
+ const GLuint *v = (const GLuint *) values;
+ for (i = 0; i < count * elems; i++) {
+ printf("%u ", v[i]);
+ }
+ }
+ else {
+ const GLfloat *v = (const GLfloat *) values;
+ assert(basicType == GL_FLOAT);
+ for (i = 0; i < count * elems; i++) {
+ printf("%g ", v[i]);
+ }
+ }
+ printf("\n");
+ }
+
+ /* A uniform var may be used by both a vertex shader and a fragment
+ * shader. We may need to update one or both shader's uniform here:
+ */
+ if (shProg->VertexProgram) {
+ /* convert uniform location to program parameter index */
+ GLint index = uniform->VertPos;
+ if (index >= 0) {
+ set_program_uniform(ctx, &shProg->VertexProgram->Base,
+ index, offset, type, count, elems, values);
+ }
+ }
+
+ if (shProg->FragmentProgram) {
+ /* convert uniform location to program parameter index */
+ GLint index = uniform->FragPos;
+ if (index >= 0) {
+ set_program_uniform(ctx, &shProg->FragmentProgram->Base,
+ index, offset, type, count, elems, values);
+ }
+ }
+
+ uniform->Initialized = GL_TRUE;
+}
+
+
+/**
+ * Set a matrix-valued program parameter.
+ */
+static void
+set_program_uniform_matrix(GLcontext *ctx, struct gl_program *program,
+ GLuint index, GLuint offset,
+ GLuint count, GLuint rows, GLuint cols,
+ GLboolean transpose, const GLfloat *values)
+{
+ GLuint mat, row, col;
+ GLuint src = 0;
+ const struct gl_program_parameter * param = &program->Parameters->Parameters[index];
+ const GLuint slots = (param->Size + 3) / 4;
+ const GLint typeSize = _mesa_sizeof_glsl_type(param->DataType);
+ GLint nr, nc;
+
+ /* check that the number of rows, columns is correct */
+ get_matrix_dims(param->DataType, &nr, &nc);
+ if (rows != nr || cols != nc) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glUniformMatrix(matrix size mismatch)");
+ return;
+ }
+
+ if ((GLint) param->Size <= typeSize) {
+ /* non-array: count must be at most one; count == 0 is handled by the loop below */
+ if (count > 1) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glUniformMatrix(uniform is not an array)");
+ return;
+ }
+ }
+
+ /*
+ * Note: the _columns_ of a matrix are stored in program registers, not
+ * the rows. So, the loops below look a little funny.
+ * XXX could optimize this a bit...
+ */
+
+ /* loop over matrices */
+ for (mat = 0; mat < count; mat++) {
+
+ /* each matrix: */
+ for (col = 0; col < cols; col++) {
+ GLfloat *v;
+ if (offset >= slots) {
+ /* Ignore writes beyond the end of (the used part of) an array */
+ return;
+ }
+ v = program->Parameters->ParameterValues[index + offset];
+ for (row = 0; row < rows; row++) {
+ if (transpose) {
+ v[row] = values[src + row * cols + col];
+ }
+ else {
+ v[row] = values[src + col * rows + row];
+ }
+ }
+
+ offset++;
+ }
+
+ src += rows * cols; /* next matrix */
+ }
+}
+
+
+/**
+ * Called by ctx->Driver.UniformMatrix().
+ * Note: cols=2, rows=4 ==> array[2] of vec4
+ */
+static void
+_mesa_uniform_matrix(GLcontext *ctx, GLint cols, GLint rows,
+ GLint location, GLsizei count,
+ GLboolean transpose, const GLfloat *values)
+{
+ struct gl_shader_program *shProg = ctx->Shader.CurrentProgram;
+ struct gl_uniform *uniform;
+ GLint offset;
+
+ if (!shProg || !shProg->LinkStatus) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glUniformMatrix(program not linked)");
+ return;
+ }
+
+ if (location == -1)
+ return; /* The standard specifies this as a no-op */
+
+ if (location < -1) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glUniformMatrix(location)");
+ return;
+ }
+
+ split_location_offset(&location, &offset);
+
+ if (location < 0 || location >= (GLint) shProg->Uniforms->NumUniforms) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glUniformMatrix(location)");
+ return;
+ }
+ if (values == NULL) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glUniformMatrix");
+ return;
+ }
+
+ FLUSH_VERTICES(ctx, _NEW_PROGRAM_CONSTANTS);
+
+ uniform = &shProg->Uniforms->Uniforms[location];
+
+ if (shProg->VertexProgram) {
+ /* convert uniform location to program parameter index */
+ GLint index = uniform->VertPos;
+ if (index >= 0) {
+ set_program_uniform_matrix(ctx, &shProg->VertexProgram->Base,
+ index, offset,
+ count, rows, cols, transpose, values);
+ }
+ }
+
+ if (shProg->FragmentProgram) {
+ /* convert uniform location to program parameter index */
+ GLint index = uniform->FragPos;
+ if (index >= 0) {
+ set_program_uniform_matrix(ctx, &shProg->FragmentProgram->Base,
+ index, offset,
+ count, rows, cols, transpose, values);
+ }
+ }
+
+ uniform->Initialized = GL_TRUE;
+}
+
+
+
+void
+_mesa_init_uniform_functions(struct dd_function_table *driver)
+{
+ driver->GetActiveUniform = _mesa_get_active_uniform;
+ driver->GetUniformfv = _mesa_get_uniformfv;
+ driver->GetUniformiv = _mesa_get_uniformiv;
+ driver->GetUniformLocation = _mesa_get_uniform_location;
+ driver->Uniform = _mesa_uniform;
+ driver->UniformMatrix = _mesa_uniform_matrix;
+}
diff --git a/src/mesa/shader/uniforms.h b/src/mesa/shader/uniforms.h
new file mode 100644
index 0000000000..52984dedad
--- /dev/null
+++ b/src/mesa/shader/uniforms.h
@@ -0,0 +1,33 @@
+/*
+ * Mesa 3-D graphics library
+ *
+ * Copyright (C) 2010 VMware, Inc. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, 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
+ * THE AUTHORS 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 UNIFORMS_H
+#define UNIFORMS_H
+
+
+extern void
+_mesa_init_uniform_functions(struct dd_function_table *driver);
+
+
+#endif /* UNIFORMS_H */
diff --git a/src/mesa/sources.mak b/src/mesa/sources.mak
index c9d8620e35..ddd63cea0b 100644
--- a/src/mesa/sources.mak
+++ b/src/mesa/sources.mak
@@ -247,7 +247,8 @@ SHADER_SOURCES = \
shader/prog_uniform.c \
shader/programopt.c \
shader/symbol_table.c \
- shader/shader_api.c
+ shader/shader_api.c \
+ shader/uniforms.c
SLANG_SOURCES = \
shader/slang/slang_builtin.c \
diff --git a/src/mesa/state_tracker/st_cb_blit.c b/src/mesa/state_tracker/st_cb_blit.c
index d7c086f569..1f73f503f6 100644
--- a/src/mesa/state_tracker/st_cb_blit.c
+++ b/src/mesa/state_tracker/st_cb_blit.c
@@ -33,7 +33,6 @@
#include "main/imports.h"
#include "main/image.h"
#include "main/macros.h"
-#include "shader/program.h"
#include "st_context.h"
#include "st_texture.h"
@@ -41,7 +40,6 @@
#include "st_cb_fbo.h"
#include "util/u_blit.h"
-#include "util/u_inlines.h"
void
diff --git a/src/mesa/state_tracker/st_cb_viewport.c b/src/mesa/state_tracker/st_cb_viewport.c
index d10b0b2531..a1fe45cac4 100644
--- a/src/mesa/state_tracker/st_cb_viewport.c
+++ b/src/mesa/state_tracker/st_cb_viewport.c
@@ -29,11 +29,9 @@
#include "st_context.h"
#include "st_cb_viewport.h"
-#include "pipe/p_context.h"
#include "pipe/p_state.h"
#include "pipe/p_defines.h"
#include "util/u_atomic.h"
-#include "util/u_debug.h"
/**
* Cast wrapper to convert a GLframebuffer to an st_framebuffer.
diff --git a/src/mesa/state_tracker/st_context.c b/src/mesa/state_tracker/st_context.c
index 605a337b55..0bf030e987 100644
--- a/src/mesa/state_tracker/st_context.c
+++ b/src/mesa/state_tracker/st_context.c
@@ -59,8 +59,6 @@
#include "st_program.h"
#include "pipe/p_context.h"
#include "util/u_inlines.h"
-#include "util/u_rect.h"
-#include "util/u_surface.h"
#include "cso_cache/cso_context.h"
diff --git a/src/mesa/state_tracker/st_debug.c b/src/mesa/state_tracker/st_debug.c
index 2da27fc4bd..0b3768341e 100644
--- a/src/mesa/state_tracker/st_debug.c
+++ b/src/mesa/state_tracker/st_debug.c
@@ -45,15 +45,15 @@
int ST_DEBUG = 0;
static const struct debug_named_value st_debug_flags[] = {
- { "mesa", DEBUG_MESA },
- { "tgsi", DEBUG_TGSI },
- { "constants",DEBUG_CONSTANTS },
- { "pipe", DEBUG_PIPE },
- { "tex", DEBUG_TEX },
- { "fallback", DEBUG_FALLBACK },
- { "screen", DEBUG_SCREEN },
- { "query", DEBUG_QUERY },
- {NULL, 0}
+ { "mesa", DEBUG_MESA, NULL },
+ { "tgsi", DEBUG_TGSI, NULL },
+ { "constants",DEBUG_CONSTANTS, NULL },
+ { "pipe", DEBUG_PIPE, NULL },
+ { "tex", DEBUG_TEX, NULL },
+ { "fallback", DEBUG_FALLBACK, NULL },
+ { "screen", DEBUG_SCREEN, NULL },
+ { "query", DEBUG_QUERY, NULL },
+ DEBUG_NAMED_VALUE_END
};
#endif
diff --git a/src/mesa/state_tracker/st_extensions.c b/src/mesa/state_tracker/st_extensions.c
index 810a0635b5..4093eedde9 100644
--- a/src/mesa/state_tracker/st_extensions.c
+++ b/src/mesa/state_tracker/st_extensions.c
@@ -373,6 +373,13 @@ void st_init_extensions(struct st_context *st)
ctx->Extensions.EXT_draw_buffers2 = GL_TRUE;
}
+ /* GL_ARB_half_float_vertex */
+ if (screen->is_format_supported(screen, PIPE_FORMAT_R16G16B16A16_FLOAT,
+ PIPE_BUFFER, 0,
+ PIPE_BIND_VERTEX_BUFFER, 0)) {
+ ctx->Extensions.ARB_half_float_vertex = GL_TRUE;
+ }
+
#if 0 /* not yet */
if (screen->get_param(screen, PIPE_CAP_INDEP_BLEND_FUNC)) {
ctx->Extensions.ARB_draw_buffers_blend = GL_TRUE;
diff --git a/src/mesa/state_tracker/st_mesa_to_tgsi.c b/src/mesa/state_tracker/st_mesa_to_tgsi.c
index 6df6cdfe03..35016d80e6 100644
--- a/src/mesa/state_tracker/st_mesa_to_tgsi.c
+++ b/src/mesa/state_tracker/st_mesa_to_tgsi.c
@@ -319,10 +319,15 @@ translate_src( struct st_translate *t,
if (SrcReg->RelAddr) {
src = ureg_src_indirect( src, ureg_src(t->address[0]));
- /* If SrcReg->Index was negative, it was set to zero in
- * src_register(). Reassign it now.
- */
- src.Index = SrcReg->Index;
+ if (SrcReg->File != PROGRAM_INPUT &&
+ SrcReg->File != PROGRAM_OUTPUT) {
+ /* If SrcReg->Index was negative, it was set to zero in
+ * src_register(). Reassign it now. But don't do this
+ * for input/output regs since they get remapped while
+ * const buffers don't.
+ */
+ src.Index = SrcReg->Index;
+ }
}
return src;
diff --git a/src/mesa/vbo/vbo_exec.c b/src/mesa/vbo/vbo_exec.c
index a057befed0..046fa8105b 100644
--- a/src/mesa/vbo/vbo_exec.c
+++ b/src/mesa/vbo/vbo_exec.c
@@ -30,9 +30,10 @@
#include "main/glheader.h"
#include "main/mtypes.h"
#include "main/vtxfmt.h"
-
#include "vbo_context.h"
+
+
void vbo_exec_init( GLcontext *ctx )
{
struct vbo_exec_context *exec = &vbo_context(ctx)->exec;
@@ -74,7 +75,9 @@ void vbo_exec_destroy( GLcontext *ctx )
vbo_exec_array_destroy( exec );
}
-/* Really want to install these callbacks to a central facility to be
+
+/**
+ * Really want to install these callbacks to a central facility to be
* invoked according to the state flags. That will have to wait for a
* mesa rework:
*/
@@ -87,8 +90,3 @@ void vbo_exec_invalidate_state( GLcontext *ctx, GLuint new_state )
_ae_invalidate_state(ctx, new_state);
}
-
-
-
-
-
diff --git a/src/mesa/vbo/vbo_exec.h b/src/mesa/vbo/vbo_exec.h
index 98c1f363d9..33494f0cea 100644
--- a/src/mesa/vbo/vbo_exec.h
+++ b/src/mesa/vbo/vbo_exec.h
@@ -195,7 +195,4 @@ void vbo_exec_do_EvalCoord2f( struct vbo_exec_context *exec,
void vbo_exec_do_EvalCoord1f( struct vbo_exec_context *exec,
GLfloat u);
-extern GLboolean
-vbo_validate_shaders(GLcontext *ctx);
-
#endif
diff --git a/src/mesa/vbo/vbo_exec_array.c b/src/mesa/vbo/vbo_exec_array.c
index d4dbc8d256..c32a504443 100644
--- a/src/mesa/vbo/vbo_exec_array.c
+++ b/src/mesa/vbo/vbo_exec_array.c
@@ -30,7 +30,6 @@
#include "main/context.h"
#include "main/state.h"
#include "main/api_validate.h"
-#include "main/api_noop.h"
#include "main/varray.h"
#include "main/bufferobj.h"
#include "main/enums.h"
@@ -40,7 +39,8 @@
/**
- * Compute min and max elements for glDraw[Range]Elements() calls.
+ * Compute min and max elements by scanning the index buffer for
+ * glDraw[Range]Elements() calls.
*/
void
vbo_get_minmax_index(GLcontext *ctx,
@@ -112,6 +112,7 @@ vbo_get_minmax_index(GLcontext *ctx,
/**
* Check that element 'j' of the array has reasonable data.
* Map VBO if needed.
+ * For debugging purposes; not normally used.
*/
static void
check_array_data(GLcontext *ctx, struct gl_client_array *array,
@@ -172,6 +173,7 @@ unmap_array_buffer(GLcontext *ctx, struct gl_client_array *array)
/**
* Examine the array's data for NaNs, etc.
+ * For debug purposes; not normally used.
*/
static void
check_draw_elements_data(GLcontext *ctx, GLsizei count, GLenum elemType,
@@ -249,7 +251,7 @@ check_draw_arrays_data(GLcontext *ctx, GLint start, GLsizei count)
/**
- * Print info/data for glDrawArrays().
+ * Print info/data for glDrawArrays(), for debugging.
*/
static void
print_draw_arrays(GLcontext *ctx, struct vbo_exec_context *exec,
@@ -295,6 +297,9 @@ print_draw_arrays(GLcontext *ctx, struct vbo_exec_context *exec,
/**
+ * Bind the VBO executor to the current vertex array object prior
+ * to drawing.
+ *
* Just translate the arrayobj into a sane layout.
*/
static void
@@ -334,6 +339,14 @@ bind_array_obj(GLcontext *ctx)
}
+/**
+ * Set the vbo->exec->inputs[] pointers to point to the enabled
+ * vertex arrays. This depends on the current vertex program/shader
+ * being executed because of whether or not generic vertex arrays
+ * alias the conventional vertex arrays.
+ * For arrays that aren't enabled, we set the input[attrib] pointer
+ * to point at a zero-stride current value "array".
+ */
static void
recalculate_input_bindings(GLcontext *ctx)
{
@@ -453,27 +466,15 @@ recalculate_input_bindings(GLcontext *ctx)
static void
bind_arrays(GLcontext *ctx)
{
-#if 0
- if (ctx->Array.ArrayObj.Name != exec->array.array_obj) {
- bind_array_obj(ctx);
- recalculate_input_bindings(ctx);
- }
- else if (exec->array.program_mode != get_program_mode(ctx) ||
- exec->array.enabled_flags != ctx->Array.ArrayObj->_Enabled) {
- recalculate_input_bindings(ctx);
- }
-#else
bind_array_obj(ctx);
recalculate_input_bindings(ctx);
-#endif
}
-/***********************************************************************
- * API functions.
+/**
+ * Called from glDrawArrays when in immediate mode (not display list mode).
*/
-
static void GLAPIENTRY
vbo_exec_DrawArrays(GLenum mode, GLint start, GLsizei count)
{
@@ -533,6 +534,10 @@ vbo_exec_DrawArrays(GLenum mode, GLint start, GLsizei count)
}
+/**
+ * Called from glDrawArraysInstanced when in immediate mode (not
+ * display list mode).
+ */
static void GLAPIENTRY
vbo_exec_DrawArraysInstanced(GLenum mode, GLint start, GLsizei count,
GLsizei primcount)
@@ -591,6 +596,7 @@ vbo_exec_DrawArraysInstanced(GLenum mode, GLint start, GLsizei count,
/**
* Map GL_ELEMENT_ARRAY_BUFFER and print contents.
+ * For debugging.
*/
static void
dump_element_buffer(GLcontext *ctx, GLenum type)
@@ -645,7 +651,11 @@ dump_element_buffer(GLcontext *ctx, GLenum type)
}
-/* Inner support for both _mesa_DrawElements and _mesa_DrawRangeElements */
+/**
+ * Inner support for both _mesa_DrawElements and _mesa_DrawRangeElements.
+ * Do the rendering for a glDrawElements or glDrawRangeElements call after
+ * we've validated buffer bounds, etc.
+ */
static void
vbo_validated_drawrangeelements(GLcontext *ctx, GLenum mode,
GLboolean index_bounds_valid,
@@ -722,6 +732,10 @@ vbo_validated_drawrangeelements(GLcontext *ctx, GLenum mode,
index_bounds_valid, start, end );
}
+
+/**
+ * Called by glDrawRangeElementsBaseVertex() in immediate mode.
+ */
static void GLAPIENTRY
vbo_exec_DrawRangeElementsBaseVertex(GLenum mode,
GLuint start, GLuint end,
@@ -831,6 +845,9 @@ vbo_exec_DrawRangeElementsBaseVertex(GLenum mode,
}
+/**
+ * Called by glDrawRangeElements() in immediate mode.
+ */
static void GLAPIENTRY
vbo_exec_DrawRangeElements(GLenum mode, GLuint start, GLuint end,
GLsizei count, GLenum type, const GLvoid *indices)
@@ -848,6 +865,9 @@ vbo_exec_DrawRangeElements(GLenum mode, GLuint start, GLuint end,
}
+/**
+ * Called by glDrawElements() in immediate mode.
+ */
static void GLAPIENTRY
vbo_exec_DrawElements(GLenum mode, GLsizei count, GLenum type,
const GLvoid *indices)
@@ -867,6 +887,9 @@ vbo_exec_DrawElements(GLenum mode, GLsizei count, GLenum type,
}
+/**
+ * Called by glDrawElementsBaseVertex() in immediate mode.
+ */
static void GLAPIENTRY
vbo_exec_DrawElementsBaseVertex(GLenum mode, GLsizei count, GLenum type,
const GLvoid *indices, GLint basevertex)
@@ -887,6 +910,9 @@ vbo_exec_DrawElementsBaseVertex(GLenum mode, GLsizei count, GLenum type,
}
+/**
+ * Called by glDrawElementsInstanced() in immediate mode.
+ */
static void GLAPIENTRY
vbo_exec_DrawElementsInstanced(GLenum mode, GLsizei count, GLenum type,
const GLvoid *indices, GLsizei primcount)
@@ -907,7 +933,11 @@ vbo_exec_DrawElementsInstanced(GLenum mode, GLsizei count, GLenum type,
}
-/** Inner support for both _mesa_DrawElements and _mesa_DrawRangeElements */
+/**
+ * Inner support for both _mesa_MultiDrawElements() and
+ * _mesa_MultiDrawRangeElements().
+ * This does the actual rendering after we've checked array indexes, etc.
+ */
static void
vbo_validated_multidrawelements(GLcontext *ctx, GLenum mode,
const GLsizei *count, GLenum type,
@@ -939,7 +969,8 @@ vbo_validated_multidrawelements(GLcontext *ctx, GLenum mode,
}
/* Decide if we can do this all as one set of primitives sharing the
- * same index buffer, or if we have to reset the index pointer per primitive.
+ * same index buffer, or if we have to reset the index pointer per
+ * primitive.
*/
bind_arrays( ctx );
@@ -1089,14 +1120,13 @@ vbo_exec_MultiDrawElementsBaseVertex(GLenum mode,
}
-/***********************************************************************
- * Initialization
+/**
+ * Plug in the immediate-mode vertex array drawing commands into the
+ * givven vbo_exec_context object.
*/
-
void
vbo_exec_array_init( struct vbo_exec_context *exec )
{
-#if 1
exec->vtxfmt.DrawArrays = vbo_exec_DrawArrays;
exec->vtxfmt.DrawElements = vbo_exec_DrawElements;
exec->vtxfmt.DrawRangeElements = vbo_exec_DrawRangeElements;
@@ -1106,15 +1136,6 @@ vbo_exec_array_init( struct vbo_exec_context *exec )
exec->vtxfmt.MultiDrawElementsBaseVertex = vbo_exec_MultiDrawElementsBaseVertex;
exec->vtxfmt.DrawArraysInstanced = vbo_exec_DrawArraysInstanced;
exec->vtxfmt.DrawElementsInstanced = vbo_exec_DrawElementsInstanced;
-#else
- exec->vtxfmt.DrawArrays = _mesa_noop_DrawArrays;
- exec->vtxfmt.DrawElements = _mesa_noop_DrawElements;
- exec->vtxfmt.DrawRangeElements = _mesa_noop_DrawRangeElements;
- exec->vtxfmt.MultiDrawElementsEXT = _mesa_noop_MultiDrawElements;
- exec->vtxfmt.DrawElementsBaseVertex = _mesa_noop_DrawElementsBaseVertex;
- exec->vtxfmt.DrawRangeElementsBaseVertex = _mesa_noop_DrawRangeElementsBaseVertex;
- exec->vtxfmt.MultiDrawElementsBaseVertex = _mesa_noop_MultiDrawElementsBaseVertex;
-#endif
}
@@ -1125,7 +1146,13 @@ vbo_exec_array_destroy( struct vbo_exec_context *exec )
}
-/* This API entrypoint is not ordinarily used */
+
+/**
+ * The following functions are only used for OpenGL ES 1/2 support.
+ * And some aren't even supported (yet) in ES 1/2.
+ */
+
+
void GLAPIENTRY
_mesa_DrawArrays(GLenum mode, GLint first, GLsizei count)
{
@@ -1133,7 +1160,6 @@ _mesa_DrawArrays(GLenum mode, GLint first, GLsizei count)
}
-/* This API entrypoint is not ordinarily used */
void GLAPIENTRY
_mesa_DrawElements(GLenum mode, GLsizei count, GLenum type,
const GLvoid *indices)
@@ -1141,6 +1167,7 @@ _mesa_DrawElements(GLenum mode, GLsizei count, GLenum type,
vbo_exec_DrawElements(mode, count, type, indices);
}
+
void GLAPIENTRY
_mesa_DrawElementsBaseVertex(GLenum mode, GLsizei count, GLenum type,
const GLvoid *indices, GLint basevertex)
@@ -1149,7 +1176,6 @@ _mesa_DrawElementsBaseVertex(GLenum mode, GLsizei count, GLenum type,
}
-/* This API entrypoint is not ordinarily used */
void GLAPIENTRY
_mesa_DrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count,
GLenum type, const GLvoid *indices)
@@ -1168,7 +1194,6 @@ _mesa_DrawRangeElementsBaseVertex(GLenum mode, GLuint start, GLuint end,
}
-/* GL_EXT_multi_draw_arrays */
void GLAPIENTRY
_mesa_MultiDrawElementsEXT(GLenum mode, const GLsizei *count, GLenum type,
const GLvoid **indices, GLsizei primcount)