diff options
Diffstat (limited to 'src/mesa')
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, ¶mPos); - - 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, ¶mPos); - - 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, ¶mPos); + + 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, ¶mPos); + + 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) |