summaryrefslogtreecommitdiffstats
path: root/src/mesa
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa')
-rw-r--r--src/mesa/main/texenvprogram.c12
-rw-r--r--src/mesa/shader/prog_uniform.c1
-rw-r--r--src/mesa/shader/prog_uniform.h1
-rw-r--r--src/mesa/shader/shader_api.c21
-rw-r--r--src/mesa/shader/slang/slang_codegen.c2
-rw-r--r--src/mesa/shader/slang/slang_emit.c109
-rw-r--r--src/mesa/shader/slang/slang_log.c2
-rw-r--r--src/mesa/state_tracker/st_atom_framebuffer.c10
-rw-r--r--src/mesa/state_tracker/st_cb_clear.c26
-rw-r--r--src/mesa/state_tracker/st_draw.c30
-rw-r--r--src/mesa/state_tracker/st_framebuffer.c3
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;
}
}
}