diff options
author | Brian Paul <[email protected]> | 2008-11-05 15:58:09 -0700 |
---|---|---|
committer | Brian Paul <[email protected]> | 2008-11-05 15:58:09 -0700 |
commit | 80a718a63bf2fa817e346f0f5731ee9ef2e0e68b (patch) | |
tree | 4a1bdb03ae8b8482b9a15e56c9604fcc34e95b0e /src/mesa | |
parent | 7115b79b77e541f3eb81db00f6f0c34a0f224feb (diff) | |
parent | de14fdd63f26a2e6fc55fad92c08966f269601a6 (diff) |
Merge commit 'origin/gallium-0.1' into gallium-0.2
Conflicts:
src/gallium/auxiliary/rtasm/rtasm_execmem.c
src/mesa/shader/slang/slang_emit.c
src/mesa/shader/slang/slang_log.c
src/mesa/state_tracker/st_atom_framebuffer.c
Diffstat (limited to 'src/mesa')
-rw-r--r-- | src/mesa/main/texenvprogram.c | 12 | ||||
-rw-r--r-- | src/mesa/shader/prog_uniform.c | 1 | ||||
-rw-r--r-- | src/mesa/shader/prog_uniform.h | 1 | ||||
-rw-r--r-- | src/mesa/shader/shader_api.c | 21 | ||||
-rw-r--r-- | src/mesa/shader/slang/slang_codegen.c | 2 | ||||
-rw-r--r-- | src/mesa/shader/slang/slang_emit.c | 109 | ||||
-rw-r--r-- | src/mesa/shader/slang/slang_log.c | 2 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_atom_framebuffer.c | 10 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_cb_clear.c | 26 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_draw.c | 30 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_framebuffer.c | 3 |
11 files changed, 185 insertions, 32 deletions
diff --git a/src/mesa/main/texenvprogram.c b/src/mesa/main/texenvprogram.c index 2c7df7b8d9a..237ddaa6838 100644 --- a/src/mesa/main/texenvprogram.c +++ b/src/mesa/main/texenvprogram.c @@ -233,6 +233,12 @@ static GLbitfield get_fp_input_mask( GLcontext *ctx ) /* Fixed function logic */ GLbitfield varying_inputs = ctx->varying_vp_inputs; + /* These get generated in the setup routine regardless of the + * vertex program: + */ + if (ctx->Point.PointSprite) + varying_inputs |= FRAG_BITS_TEX_ANY; + /* First look at what values may be computed by the generated * vertex program: */ @@ -260,6 +266,12 @@ static GLbitfield get_fp_input_mask( GLcontext *ctx ) /* calculate from vp->outputs */ GLbitfield vp_outputs = ctx->VertexProgram._Current->Base.OutputsWritten; + /* These get generated in the setup routine regardless of the + * vertex program: + */ + if (ctx->Point.PointSprite) + vp_outputs |= FRAG_BITS_TEX_ANY; + if (vp_outputs & (1 << VERT_RESULT_COL0)) fp_inputs |= FRAG_BIT_COL0; if (vp_outputs & (1 << VERT_RESULT_COL1)) fp_inputs |= FRAG_BIT_COL1; diff --git a/src/mesa/shader/prog_uniform.c b/src/mesa/shader/prog_uniform.c index 25d7c0997bc..11f2e3e561c 100644 --- a/src/mesa/shader/prog_uniform.c +++ b/src/mesa/shader/prog_uniform.c @@ -87,6 +87,7 @@ _mesa_append_uniform(struct gl_uniform_list *list, list->Uniforms[oldNum].Name = _mesa_strdup(name); list->Uniforms[oldNum].VertPos = -1; list->Uniforms[oldNum].FragPos = -1; + list->Uniforms[oldNum].Initialized = GL_FALSE; index = oldNum; list->NumUniforms++; } diff --git a/src/mesa/shader/prog_uniform.h b/src/mesa/shader/prog_uniform.h index 735de28705a..deea7329912 100644 --- a/src/mesa/shader/prog_uniform.h +++ b/src/mesa/shader/prog_uniform.h @@ -50,6 +50,7 @@ struct gl_uniform const char *Name; /**< Null-terminated string */ GLint VertPos; GLint FragPos; + GLboolean Initialized; /**< For debug. Has this uniform been set? */ #if 0 GLenum DataType; /**< GL_FLOAT, GL_FLOAT_VEC2, etc */ GLuint Size; /**< Number of components (1..4) */ diff --git a/src/mesa/shader/shader_api.c b/src/mesa/shader/shader_api.c index 266ecc4ef21..7f020fe5d3c 100644 --- a/src/mesa/shader/shader_api.c +++ b/src/mesa/shader/shader_api.c @@ -1512,10 +1512,12 @@ set_program_uniform(GLcontext *ctx, struct gl_program *program, GLenum type, GLsizei count, GLint elems, const void *values) { + struct gl_program_parameter *param = + &program->Parameters->Parameters[index]; + assert(offset >= 0); - if (!compatible_types(type, - program->Parameters->Parameters[index].DataType)) { + if (!compatible_types(type, param->DataType)) { _mesa_error(ctx, GL_INVALID_OPERATION, "glUniform(type mismatch)"); return; } @@ -1525,7 +1527,7 @@ set_program_uniform(GLcontext *ctx, struct gl_program *program, return; } - if (program->Parameters->Parameters[index].Type == PROGRAM_SAMPLER) { + if (param->Type == PROGRAM_SAMPLER) { /* This controls which texture unit which is used by a sampler */ GLuint texUnit, sampler; @@ -1556,9 +1558,9 @@ set_program_uniform(GLcontext *ctx, struct gl_program *program, else { /* ordinary uniform variable */ GLsizei k, i; - GLint slots = (program->Parameters->Parameters[index].Size + 3) / 4; + GLint slots = (param->Size + 3) / 4; - if (count * elems > (GLint) program->Parameters->Parameters[index].Size) { + if (count * elems > (GLint) param->Size) { _mesa_error(ctx, GL_INVALID_OPERATION, "glUniform(count too large)"); return; } @@ -1567,7 +1569,8 @@ set_program_uniform(GLcontext *ctx, struct gl_program *program, count = slots; for (k = 0; k < count; k++) { - GLfloat *uniformVal = program->Parameters->ParameterValues[index + offset + k]; + GLfloat *uniformVal = + program->Parameters->ParameterValues[index + offset + k]; if (is_integer_type(type)) { const GLint *iValues = ((const GLint *) values) + k * elems; for (i = 0; i < elems; i++) { @@ -1582,7 +1585,7 @@ set_program_uniform(GLcontext *ctx, struct gl_program *program, } /* if the uniform is bool-valued, convert to 1.0 or 0.0 */ - if (is_boolean_type(program->Parameters->Parameters[index].DataType)) { + if (is_boolean_type(param->DataType)) { for (i = 0; i < elems; i++) { uniformVal[i] = uniformVal[i] ? 1.0f : 0.0f; } @@ -1666,6 +1669,8 @@ _mesa_uniform(GLcontext *ctx, GLint location, GLsizei count, index, offset, type, count, elems, values); } } + + shProg->Uniforms->Uniforms[location].Initialized = GL_TRUE; } @@ -1776,6 +1781,8 @@ _mesa_uniform_matrix(GLcontext *ctx, GLint cols, GLint rows, count, rows, cols, transpose, values); } } + + shProg->Uniforms->Uniforms[location].Initialized = GL_TRUE; } diff --git a/src/mesa/shader/slang/slang_codegen.c b/src/mesa/shader/slang/slang_codegen.c index e7b2bad8c24..d83e3b01e6b 100644 --- a/src/mesa/shader/slang/slang_codegen.c +++ b/src/mesa/shader/slang/slang_codegen.c @@ -3253,7 +3253,7 @@ _slang_gen_array_element(slang_assemble_ctx * A, slang_operation *oper) index = _slang_gen_operation(A, &oper->children[1]); if (array && index) { /* bounds check */ - GLint constIndex = 0; + GLint constIndex = -1; if (index->Opcode == IR_FLOAT) { constIndex = (int) index->Value[0]; if (constIndex < 0 || constIndex >= arrayLen) { diff --git a/src/mesa/shader/slang/slang_emit.c b/src/mesa/shader/slang/slang_emit.c index 6ab06864b90..672ec4bd606 100644 --- a/src/mesa/shader/slang/slang_emit.c +++ b/src/mesa/shader/slang/slang_emit.c @@ -330,6 +330,17 @@ constant_to_src_reg(struct prog_src_register *src, GLfloat val, } +static void +address_to_dst_reg(struct prog_dst_register *dst, GLuint index) +{ + assert(index == 0); /* only one address reg at this time */ + dst->File = PROGRAM_ADDRESS; + dst->Index = index; + dst->WriteMask = WRITEMASK_X; +} + + + /** * Add new instruction at end of given program. * \param prog the program to append instruction onto @@ -614,6 +625,7 @@ emit_arith(slang_emit_info *emitInfo, slang_ir_node *n) /* result storage */ alloc_node_storage(emitInfo, n, -1); + assert(n->Store->Index >= 0); if (n->Store->Size == 2) n->Writemask = WRITEMASK_XY; @@ -1546,6 +1558,60 @@ emit_swizzle(slang_emit_info *emitInfo, slang_ir_node *n) /** + * Move a block registers from src to dst (or move a single register). + * \param size size of block, in floats (<=4 means one register) + */ +static struct prog_instruction * +move_block(slang_emit_info *emitInfo, + GLuint size, GLboolean relAddr, + const slang_ir_storage *dst, + const slang_ir_storage *src) +{ + struct prog_instruction *inst; + + if (size > 4) { + /* move matrix/struct etc (block of registers) */ + slang_ir_storage dstStore = *dst; + slang_ir_storage srcStore = *src; + //GLint size = srcStore.Size; + /*ASSERT(n->Children[0]->Writemask == WRITEMASK_XYZW); + ASSERT(n->Children[1]->Store->Swizzle == SWIZZLE_NOOP); + */ + dstStore.Size = 4; + srcStore.Size = 4; + while (size >= 4) { + inst = new_instruction(emitInfo, OPCODE_MOV); + inst->Comment = _mesa_strdup("IR_COPY block"); + storage_to_dst_reg(&inst->DstReg, &dstStore, WRITEMASK_XYZW); + storage_to_src_reg(&inst->SrcReg[0], &srcStore); + inst->SrcReg[0].RelAddr = relAddr; + srcStore.Index++; + dstStore.Index++; + size -= 4; + } + } + else { + /* single register move */ + GLuint writemask; + if (size == 1) { + GLuint comp = GET_SWZ(src->Swizzle, 0); + assert(comp < 4); + writemask = WRITEMASK_X << comp; + } + else { + writemask = WRITEMASK_XYZW; + } + inst = new_instruction(emitInfo, OPCODE_MOV); + storage_to_dst_reg(&inst->DstReg, dst, writemask); + storage_to_src_reg(&inst->SrcReg[0], src); + inst->SrcReg[0].RelAddr = relAddr; + } + return inst; +} + + + +/** * Dereference array element. Just resolve storage for the array * element represented by this node. */ @@ -1587,24 +1653,47 @@ emit_array_element(slang_emit_info *emitInfo, slang_ir_node *n) else { /* Variable array index */ struct prog_instruction *inst; - slang_ir_storage dstStore = *n->Store; /* do codegen for array index expression */ emit(emitInfo, n->Children[1]); - inst = new_instruction(emitInfo, OPCODE_ARL); + /* allocate temp storage for the array element */ + assert(n->Store->Index < 0); + n->Store->File = PROGRAM_TEMPORARY; + n->Store->Parent = NULL; + alloc_node_storage(emitInfo, n, -1); + + if (n->Store->Size > 4) { + /* need to multiply the index by the element size */ + GLint elemSize = (n->Store->Size + 3) / 4; + slang_ir_storage indexTemp; - if (dstStore.Size > 4) - dstStore.Size = 4; /* only emit one instruction */ + /* allocate 1 float indexTemp */ + alloc_local_temp(emitInfo, &indexTemp, 1); + + /* MUL temp, index, elemSize */ + inst = new_instruction(emitInfo, OPCODE_MUL); + storage_to_dst_reg(&inst->DstReg, &indexTemp, WRITEMASK_X); + storage_to_src_reg(&inst->SrcReg[0], n->Children[1]->Store); + constant_to_src_reg(&inst->SrcReg[1], elemSize, emitInfo); - storage_to_dst_reg(&inst->DstReg, &dstStore, n->Writemask); - storage_to_src_reg(&inst->SrcReg[0], n->Children[1]->Store); + /* load ADDR[0].X = temp */ + inst = new_instruction(emitInfo, OPCODE_ARL); + storage_to_src_reg(&inst->SrcReg[0], &indexTemp); + address_to_dst_reg(&inst->DstReg, 0); - inst->DstReg.File = PROGRAM_ADDRESS; - inst->DstReg.Index = 0; /* always address register [0] */ - inst->Comment = _mesa_strdup("ARL ADDR"); + _slang_free_temp(emitInfo->vt, &indexTemp); + } + else { + /* simply load address reg w/ array index */ + inst = new_instruction(emitInfo, OPCODE_ARL); + storage_to_src_reg(&inst->SrcReg[0], n->Children[1]->Store); + address_to_dst_reg(&inst->DstReg, 0); + } - n->Store->RelAddr = GL_TRUE; + /* copy from array element to temp storage */ + move_block(emitInfo, n->Store->Size, GL_TRUE, + n->Store, n->Children[0]->Store); } /* if array element size is one, make sure we only access X */ diff --git a/src/mesa/shader/slang/slang_log.c b/src/mesa/shader/slang/slang_log.c index dc838c72ade..25f696f67ea 100644 --- a/src/mesa/shader/slang/slang_log.c +++ b/src/mesa/shader/slang/slang_log.c @@ -89,7 +89,7 @@ slang_info_log_message(slang_info_log * log, const char *prefix, slang_string_concat(log->text, "\n"); if (MESA_VERBOSE & VERBOSE_GLSL) { - _mesa_printf("Mesa: GLSL %s\n", log->text); + _mesa_printf("Mesa: GLSL %s", log->text); } return 1; diff --git a/src/mesa/state_tracker/st_atom_framebuffer.c b/src/mesa/state_tracker/st_atom_framebuffer.c index b4f42c6f93f..ca1a719a9ac 100644 --- a/src/mesa/state_tracker/st_atom_framebuffer.c +++ b/src/mesa/state_tracker/st_atom_framebuffer.c @@ -116,10 +116,11 @@ update_framebuffer_state( struct st_context *st ) /* rendering to a GL texture, may have to update surface */ update_renderbuffer_surface(st, strb); } - - assert(strb->surface); - framebuffer->cbufs[framebuffer->num_cbufs] = strb->surface; - framebuffer->num_cbufs++; + + if (strb->surface) { + framebuffer->cbufs[framebuffer->num_cbufs] = strb->surface; + framebuffer->num_cbufs++; + } } strb = st_renderbuffer(fb->Attachment[BUFFER_DEPTH].Renderbuffer); @@ -130,7 +131,6 @@ update_framebuffer_state( struct st_context *st ) update_renderbuffer_surface(st, strb); } - assert(strb->surface); framebuffer->zsbuf = strb->surface; } else { diff --git a/src/mesa/state_tracker/st_cb_clear.c b/src/mesa/state_tracker/st_cb_clear.c index ee282e8e20c..1412a3761f1 100644 --- a/src/mesa/state_tracker/st_cb_clear.c +++ b/src/mesa/state_tracker/st_cb_clear.c @@ -406,13 +406,17 @@ check_clear_stencil_with_quad(GLcontext *ctx, struct gl_renderbuffer *rb) static void clear_color_buffer(GLcontext *ctx, struct gl_renderbuffer *rb) { + struct st_renderbuffer *strb = st_renderbuffer(rb); + + if (!strb->surface) + return; + if (check_clear_color_with_quad( ctx, rb )) { /* masking or scissoring */ clear_with_quad(ctx, GL_TRUE, GL_FALSE, GL_FALSE); } else { /* clear whole buffer w/out masking */ - struct st_renderbuffer *strb = st_renderbuffer(rb); uint clearValue; /* NOTE: we always pass the clear color as PIPE_FORMAT_A8R8G8B8_UNORM * at this time! @@ -426,13 +430,16 @@ clear_color_buffer(GLcontext *ctx, struct gl_renderbuffer *rb) static void clear_depth_buffer(GLcontext *ctx, struct gl_renderbuffer *rb) { + struct st_renderbuffer *strb = st_renderbuffer(rb); + + if (!strb->surface) + return; + if (check_clear_depth_with_quad(ctx, rb)) { /* scissoring or we have a combined depth/stencil buffer */ clear_with_quad(ctx, GL_FALSE, GL_TRUE, GL_FALSE); } else { - struct st_renderbuffer *strb = st_renderbuffer(rb); - /* simple clear of whole buffer */ uint clearValue = util_pack_z(strb->surface->format, ctx->Depth.Clear); ctx->st->pipe->clear(ctx->st->pipe, strb->surface, clearValue); @@ -443,13 +450,16 @@ clear_depth_buffer(GLcontext *ctx, struct gl_renderbuffer *rb) static void clear_stencil_buffer(GLcontext *ctx, struct gl_renderbuffer *rb) { + struct st_renderbuffer *strb = st_renderbuffer(rb); + + if (!strb->surface) + return; + if (check_clear_stencil_with_quad(ctx, rb)) { /* masking or scissoring or combined depth/stencil buffer */ clear_with_quad(ctx, GL_FALSE, GL_FALSE, GL_TRUE); } else { - struct st_renderbuffer *strb = st_renderbuffer(rb); - /* simple clear of whole buffer */ GLuint clearValue = ctx->Stencil.Clear; @@ -469,14 +479,16 @@ clear_stencil_buffer(GLcontext *ctx, struct gl_renderbuffer *rb) static void clear_depth_stencil_buffer(GLcontext *ctx, struct gl_renderbuffer *rb) { + struct st_renderbuffer *strb = st_renderbuffer(rb); + + if (!strb->surface) + return; if (check_clear_depth_stencil_with_quad(ctx, rb)) { /* masking or scissoring */ clear_with_quad(ctx, GL_FALSE, GL_TRUE, GL_TRUE); } else { - struct st_renderbuffer *strb = st_renderbuffer(rb); - /* clear whole buffer w/out masking */ GLuint clearValue = util_pack_z(strb->surface->format, ctx->Depth.Clear); diff --git a/src/mesa/state_tracker/st_draw.c b/src/mesa/state_tracker/st_draw.c index 61949a93884..7cf06da43cc 100644 --- a/src/mesa/state_tracker/st_draw.c +++ b/src/mesa/state_tracker/st_draw.c @@ -33,6 +33,7 @@ #include "main/imports.h" #include "main/image.h" #include "main/macros.h" +#include "shader/prog_uniform.h" #include "vbo/vbo.h" @@ -483,6 +484,28 @@ setup_non_interleaved_attribs(GLcontext *ctx, +/** + * Prior to drawing, check that any uniforms referenced by the + * current shader have been set. If a uniform has not been set, + * issue a warning. + */ +static void +check_uniforms(GLcontext *ctx) +{ + const struct gl_shader_program *shProg = ctx->Shader.CurrentProgram; + if (shProg && shProg->LinkStatus) { + GLuint i; + for (i = 0; i < shProg->Uniforms->NumUniforms; i++) { + const struct gl_uniform *u = &shProg->Uniforms->Uniforms[i]; + if (!u->Initialized) { + _mesa_warning(ctx, + "Using shader with uninitialized uniform: %s", + u->Name); + } + } + } +} + /** * This function gets plugged into the VBO module and is called when @@ -516,6 +539,10 @@ st_draw_vbo(GLcontext *ctx, vp = ctx->st->vp; vs = &ctx->st->vp->state; + if (MESA_VERBOSE & VERBOSE_GLSL) { + check_uniforms(ctx); + } + /* * Setup the vbuffer[] and velements[] arrays. */ @@ -557,6 +584,9 @@ st_draw_vbo(GLcontext *ctx, pipe->set_vertex_buffers(pipe, num_vbuffers, vbuffer); pipe->set_vertex_elements(pipe, num_velements, velements); + if (num_vbuffers == 0 || num_velements == 0) + return; + /* do actual drawing */ if (ib) { /* indexed primitive */ diff --git a/src/mesa/state_tracker/st_framebuffer.c b/src/mesa/state_tracker/st_framebuffer.c index fe9900d92ca..6fd731d209d 100644 --- a/src/mesa/state_tracker/st_framebuffer.c +++ b/src/mesa/state_tracker/st_framebuffer.c @@ -291,7 +291,8 @@ st_notify_swapbuffers_complete(struct st_framebuffer *stfb) for (i = 0; i < BUFFER_COUNT; i++) { if (stfb->Base.Attachment[i].Renderbuffer) { strb = st_renderbuffer(stfb->Base.Attachment[i].Renderbuffer); - strb->surface->status = PIPE_SURFACE_STATUS_UNDEFINED; + if (strb->surface) + strb->surface->status = PIPE_SURFACE_STATUS_UNDEFINED; } } } |