summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorBen Skeggs <[email protected]>2008-05-14 18:13:36 +1000
committerBen Skeggs <[email protected]>2008-05-14 18:13:36 +1000
commitbc1696862c9ffa8d8f2c11d3120310e82f2e9327 (patch)
treea212a92776a05fb1ef09d1ea1864d9cc1e315440 /src
parent666ac923f016b1b231c5a8847cbe084321f697ca (diff)
parent19f15277d1871b62902031f9fa9aabf2f1bc7c40 (diff)
Merge remote branch 'upstream/gallium-0.1' into nouveau-gallium-0.1
Diffstat (limited to 'src')
-rw-r--r--src/gallium/auxiliary/cso_cache/cso_context.c2
-rw-r--r--src/gallium/auxiliary/draw/draw_pipe_vbuf.c20
-rw-r--r--src/gallium/auxiliary/draw/draw_pt_emit.c10
-rw-r--r--src/gallium/auxiliary/draw/draw_pt_fetch.c5
-rw-r--r--src/gallium/auxiliary/draw/draw_pt_fetch_emit.c3
-rw-r--r--src/gallium/auxiliary/gallivm/instructions.cpp30
-rw-r--r--src/gallium/auxiliary/gallivm/storage.cpp16
-rw-r--r--src/gallium/auxiliary/gallivm/storagesoa.cpp8
-rw-r--r--src/gallium/auxiliary/translate/translate.h26
-rw-r--r--src/gallium/drivers/softpipe/sp_quad_fs.c15
-rw-r--r--src/gallium/drivers/softpipe/sp_setup.c86
-rw-r--r--src/gallium/winsys/xlib/fakeglx.c9
-rw-r--r--src/gallium/winsys/xlib/xm_api.c3
-rwxr-xr-xsrc/mesa/main/context.c42
-rw-r--r--src/mesa/main/ffvertex_prog.c43
-rw-r--r--src/mesa/main/imports.c36
-rw-r--r--src/mesa/main/mtypes.h4
-rw-r--r--src/mesa/main/state.c32
-rw-r--r--src/mesa/shader/prog_cache.c5
-rw-r--r--src/mesa/shader/program.c103
-rw-r--r--src/mesa/shader/program.h22
-rw-r--r--src/mesa/shader/shader_api.c6
-rw-r--r--src/mesa/shader/slang/slang_link.c12
-rw-r--r--src/mesa/state_tracker/st_atom.h28
-rw-r--r--src/mesa/state_tracker/st_atom_shader.c7
-rw-r--r--src/mesa/state_tracker/st_cb_texture.c2
-rw-r--r--src/mesa/state_tracker/st_context.c3
-rw-r--r--src/mesa/state_tracker/st_program.h24
28 files changed, 365 insertions, 237 deletions
diff --git a/src/gallium/auxiliary/cso_cache/cso_context.c b/src/gallium/auxiliary/cso_cache/cso_context.c
index eef898f4865..a1a3a9efaf3 100644
--- a/src/gallium/auxiliary/cso_cache/cso_context.c
+++ b/src/gallium/auxiliary/cso_cache/cso_context.c
@@ -84,7 +84,7 @@ static boolean delete_blend_state(struct cso_context *ctx, void *state)
{
struct cso_blend *cso = (struct cso_blend *)state;
- if (ctx->blend == state)
+ if (ctx->blend == cso->data)
return FALSE;
if (cso->delete_state)
diff --git a/src/gallium/auxiliary/draw/draw_pipe_vbuf.c b/src/gallium/auxiliary/draw/draw_pipe_vbuf.c
index 2a19e6916af..86a7d1c7303 100644
--- a/src/gallium/auxiliary/draw/draw_pipe_vbuf.c
+++ b/src/gallium/auxiliary/draw/draw_pipe_vbuf.c
@@ -42,6 +42,7 @@
#include "draw_vertex.h"
#include "draw_pipe.h"
#include "translate/translate.h"
+#include "translate/translate_cache.h"
/**
@@ -75,6 +76,8 @@ struct vbuf_stage {
/* Cache point size somewhere it's address won't change:
*/
float point_size;
+
+ struct translate_cache *cache;
};
@@ -220,7 +223,6 @@ vbuf_set_prim( struct vbuf_stage *vbuf, uint prim )
/* Translate from pipeline vertices to hw vertices.
*/
dst_offset = 0;
- memset(&hw_key, 0, sizeof(hw_key));
for (i = 0; i < vbuf->vinfo->num_attribs; i++) {
unsigned emit_sz = 0;
@@ -277,12 +279,10 @@ vbuf_set_prim( struct vbuf_stage *vbuf, uint prim )
/* Don't bother with caching at this stage:
*/
if (!vbuf->translate ||
- memcmp(&vbuf->translate->key, &hw_key, sizeof(hw_key)) != 0)
+ translate_key_compare(&vbuf->translate->key, &hw_key) != 0)
{
- if (vbuf->translate)
- vbuf->translate->release(vbuf->translate);
-
- vbuf->translate = translate_create( &hw_key );
+ translate_key_sanitize(&hw_key);
+ vbuf->translate = translate_cache_find(vbuf->cache, &hw_key);
vbuf->translate->set_buffer(vbuf->translate, 1, &vbuf->point_size, 0);
}
@@ -433,6 +433,9 @@ static void vbuf_destroy( struct draw_stage *stage )
if (vbuf->render)
vbuf->render->destroy( vbuf->render );
+ if (vbuf->cache)
+ translate_cache_destroy(vbuf->cache);
+
FREE( stage );
}
@@ -463,6 +466,11 @@ struct draw_stage *draw_vbuf_stage( struct draw_context *draw,
16 );
if (!vbuf->indices)
goto fail;
+
+ vbuf->cache = translate_cache_create();
+ if (!vbuf->cache)
+ goto fail;
+
vbuf->vertices = NULL;
vbuf->vertex_ptr = vbuf->vertices;
diff --git a/src/gallium/auxiliary/draw/draw_pt_emit.c b/src/gallium/auxiliary/draw/draw_pt_emit.c
index f9ac16786ef..ce3a153f647 100644
--- a/src/gallium/auxiliary/draw/draw_pt_emit.c
+++ b/src/gallium/auxiliary/draw/draw_pt_emit.c
@@ -58,8 +58,6 @@ void draw_pt_emit_prepare( struct pt_emit *emit,
return;
}
- memset(&hw_key, 0, sizeof(hw_key));
-
/* Must do this after set_primitive() above:
*/
vinfo = draw->render->get_vertex_info(draw->render);
@@ -122,8 +120,9 @@ void draw_pt_emit_prepare( struct pt_emit *emit,
hw_key.output_stride = vinfo->size * 4;
if (!emit->translate ||
- memcmp(&emit->translate->key, &hw_key, sizeof(hw_key)) != 0)
+ translate_key_compare(&emit->translate->key, &hw_key) != 0)
{
+ translate_key_sanitize(&hw_key);
emit->translate = translate_cache_find(emit->cache, &hw_key);
}
}
@@ -147,7 +146,7 @@ void draw_pt_emit( struct pt_emit *emit,
hw_verts = render->allocate_vertices(render,
(ushort)translate->key.output_stride,
- (ushort)count);
+ (ushort)vertex_count);
if (!hw_verts) {
assert(0);
return;
@@ -197,7 +196,8 @@ struct pt_emit *draw_pt_emit_create( struct draw_context *draw )
void draw_pt_emit_destroy( struct pt_emit *emit )
{
- translate_cache_destroy(emit->cache);
+ if (emit->cache)
+ translate_cache_destroy(emit->cache);
FREE(emit);
}
diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch.c b/src/gallium/auxiliary/draw/draw_pt_fetch.c
index 1f765b73adf..100117a9aef 100644
--- a/src/gallium/auxiliary/draw/draw_pt_fetch.c
+++ b/src/gallium/auxiliary/draw/draw_pt_fetch.c
@@ -65,8 +65,6 @@ void draw_pt_fetch_prepare( struct pt_fetch *fetch,
fetch->vertex_size = vertex_size;
- memset(&key, 0, sizeof(key));
-
/* Always emit/leave space for a vertex header.
*
* It's worth considering whether the vertex headers should contain
@@ -110,8 +108,9 @@ void draw_pt_fetch_prepare( struct pt_fetch *fetch,
if (!fetch->translate ||
- memcmp(&fetch->translate->key, &key, sizeof(key)) != 0)
+ translate_key_compare(&fetch->translate->key, &key) != 0)
{
+ translate_key_sanitize(&key);
fetch->translate = translate_cache_find(fetch->cache, &key);
{
diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c b/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c
index a4de341df8e..b7b970a297f 100644
--- a/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c
+++ b/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c
@@ -174,8 +174,9 @@ static void fetch_emit_prepare( struct draw_pt_middle_end *middle,
/* Don't bother with caching at this stage:
*/
if (!feme->translate ||
- memcmp(&feme->translate->key, &key, sizeof(key)) != 0)
+ translate_key_compare(&feme->translate->key, &key) != 0)
{
+ translate_key_sanitize(&key);
feme->translate = translate_cache_find(feme->cache,
&key);
diff --git a/src/gallium/auxiliary/gallivm/instructions.cpp b/src/gallium/auxiliary/gallivm/instructions.cpp
index 95a670edafc..1a98491b82a 100644
--- a/src/gallium/auxiliary/gallivm/instructions.cpp
+++ b/src/gallium/auxiliary/gallivm/instructions.cpp
@@ -166,10 +166,9 @@ llvm::Value * Instructions::rsq(llvm::Value *in1)
Value *abs = callFAbs(x);
Value *sqrt = callFSqrt(abs);
- Value *rsqrt = m_builder.CreateFDiv(ConstantFP::get(Type::FloatTy,
- APFloat(1.f)),
- sqrt,
- name("rsqrt"));
+ Value *rsqrt = m_builder.CreateFDiv(ConstantFP::get(APFloat(1.f)),
+ sqrt,
+ name("rsqrt"));
return vectorFromVals(rsqrt, rsqrt, rsqrt, rsqrt);
}
@@ -278,9 +277,8 @@ llvm::Value * Instructions::rcp(llvm::Value *in1)
Value *x1 = m_builder.CreateExtractElement(in1,
m_storage->constantInt(0),
name("x1"));
- Value *res = m_builder.CreateFDiv(ConstantFP::get(Type::FloatTy,
- APFloat(1.f)),
- x1, name("rcp"));
+ Value *res = m_builder.CreateFDiv(ConstantFP::get(APFloat(1.f)),
+ x1, name("rcp"));
return vectorFromVals(res, res, res, res);
}
@@ -319,13 +317,13 @@ llvm::Value * Instructions::dst(llvm::Value *in1, llvm::Value *in2)
m_storage->constantInt(3),
name("w"));
Value *ry = m_builder.CreateMul(y1, y2, name("tyuy"));
- return vectorFromVals(ConstantFP::get(Type::FloatTy, APFloat(1.f)),
+ return vectorFromVals(ConstantFP::get(APFloat(1.f)),
ry, z, w);
}
llvm::Value * Instructions::ex2(llvm::Value *in)
{
- llvm::Value *val = callPow(ConstantFP::get(Type::FloatTy, APFloat(2.f)),
+ llvm::Value *val = callPow(ConstantFP::get(APFloat(2.f)),
m_builder.CreateExtractElement(
in, m_storage->constantInt(0),
name("x1")));
@@ -526,7 +524,7 @@ llvm::Function * Instructions::declarePrintf()
llvm::Value * Instructions::sgt(llvm::Value *in1, llvm::Value *in2)
{
- Constant *const1f = ConstantFP::get(Type::FloatTy, APFloat(1.000000e+00f));
+ Constant *const1f = ConstantFP::get(APFloat(1.000000e+00f));
Constant *const0f = Constant::getNullValue(Type::FloatTy);
std::vector<llvm::Value*> vec1 = extractVector(in1);
@@ -547,7 +545,7 @@ llvm::Value * Instructions::sgt(llvm::Value *in1, llvm::Value *in2)
}
llvm::Value * Instructions::sge(llvm::Value *in1, llvm::Value *in2)
{
- Constant *const1f = ConstantFP::get(Type::FloatTy, APFloat(1.000000e+00f));
+ Constant *const1f = ConstantFP::get(APFloat(1.000000e+00f));
Constant *const0f = Constant::getNullValue(Type::FloatTy);
std::vector<llvm::Value*> vec1 = extractVector(in1);
@@ -571,7 +569,7 @@ llvm::Value * Instructions::sge(llvm::Value *in1, llvm::Value *in2)
llvm::Value * Instructions::slt(llvm::Value *in1, llvm::Value *in2)
{
- Constant *const1f = ConstantFP::get(Type::FloatTy, APFloat(1.000000e+00f));
+ Constant *const1f = ConstantFP::get(APFloat(1.000000e+00f));
Constant *const0f = Constant::getNullValue(Type::FloatTy);
std::vector<llvm::Value*> vec1 = extractVector(in1);
@@ -814,10 +812,10 @@ llvm::Function * Instructions::findFunction(int label)
llvm::Value * Instructions::constVector(float x, float y, float z, float w)
{
std::vector<Constant*> vec(4);
- vec[0] = ConstantFP::get(Type::FloatTy, APFloat(x));
- vec[1] = ConstantFP::get(Type::FloatTy, APFloat(y));
- vec[2] = ConstantFP::get(Type::FloatTy, APFloat(z));
- vec[3] = ConstantFP::get(Type::FloatTy, APFloat(w));
+ vec[0] = ConstantFP::get(APFloat(x));
+ vec[1] = ConstantFP::get(APFloat(y));
+ vec[2] = ConstantFP::get(APFloat(z));
+ vec[3] = ConstantFP::get(APFloat(w));
return ConstantVector::get(m_floatVecType, vec);
}
diff --git a/src/gallium/auxiliary/gallivm/storage.cpp b/src/gallium/auxiliary/gallivm/storage.cpp
index 9d9fd123604..6f373f6dd5e 100644
--- a/src/gallium/auxiliary/gallivm/storage.cpp
+++ b/src/gallium/auxiliary/gallivm/storage.cpp
@@ -69,10 +69,10 @@ llvm::Constant *Storage::shuffleMask(int vec)
{
if (!m_extSwizzleVec) {
std::vector<Constant*> elems;
- elems.push_back(ConstantFP::get(Type::FloatTy, APFloat(0.f)));
- elems.push_back(ConstantFP::get(Type::FloatTy, APFloat(1.f)));
- elems.push_back(ConstantFP::get(Type::FloatTy, APFloat(0.f)));
- elems.push_back(ConstantFP::get(Type::FloatTy, APFloat(1.f)));
+ elems.push_back(ConstantFP::get(APFloat(0.f)));
+ elems.push_back(ConstantFP::get(APFloat(1.f)));
+ elems.push_back(ConstantFP::get(APFloat(0.f)));
+ elems.push_back(ConstantFP::get(APFloat(1.f)));
m_extSwizzleVec = ConstantVector::get(m_floatVecType, elems);
}
@@ -295,10 +295,10 @@ llvm::Value * Storage::immediateElement(int idx)
void Storage::addImmediate(float *val)
{
std::vector<Constant*> vec(4);
- vec[0] = ConstantFP::get(Type::FloatTy, APFloat(val[0]));
- vec[1] = ConstantFP::get(Type::FloatTy, APFloat(val[1]));
- vec[2] = ConstantFP::get(Type::FloatTy, APFloat(val[2]));
- vec[3] = ConstantFP::get(Type::FloatTy, APFloat(val[3]));
+ vec[0] = ConstantFP::get(APFloat(val[0]));
+ vec[1] = ConstantFP::get(APFloat(val[1]));
+ vec[2] = ConstantFP::get(APFloat(val[2]));
+ vec[3] = ConstantFP::get(APFloat(val[3]));
m_immediates.push_back(ConstantVector::get(m_floatVecType, vec));
}
diff --git a/src/gallium/auxiliary/gallivm/storagesoa.cpp b/src/gallium/auxiliary/gallivm/storagesoa.cpp
index 0e6e68c9d70..78d754371f0 100644
--- a/src/gallium/auxiliary/gallivm/storagesoa.cpp
+++ b/src/gallium/auxiliary/gallivm/storagesoa.cpp
@@ -264,10 +264,10 @@ llvm::Constant * StorageSoa::createConstGlobalVector(const std::vector<float> &v
{
VectorType *vectorType = VectorType::get(Type::FloatTy, 4);
std::vector<Constant*> immValues;
- ConstantFP *constx = ConstantFP::get(Type::FloatTy, APFloat(vec[0]));
- ConstantFP *consty = ConstantFP::get(Type::FloatTy, APFloat(vec[1]));
- ConstantFP *constz = ConstantFP::get(Type::FloatTy, APFloat(vec[2]));
- ConstantFP *constw = ConstantFP::get(Type::FloatTy, APFloat(vec[3]));
+ ConstantFP *constx = ConstantFP::get(APFloat(vec[0]));
+ ConstantFP *consty = ConstantFP::get(APFloat(vec[1]));
+ ConstantFP *constz = ConstantFP::get(APFloat(vec[2]));
+ ConstantFP *constw = ConstantFP::get(APFloat(vec[3]));
immValues.push_back(constx);
immValues.push_back(consty);
immValues.push_back(constz);
diff --git a/src/gallium/auxiliary/translate/translate.h b/src/gallium/auxiliary/translate/translate.h
index 6c15d7e4dc7..b8210af50cf 100644
--- a/src/gallium/auxiliary/translate/translate.h
+++ b/src/gallium/auxiliary/translate/translate.h
@@ -47,10 +47,9 @@
struct translate_element
{
enum pipe_format input_format;
- unsigned input_buffer;
- unsigned input_offset;
-
enum pipe_format output_format;
+ unsigned input_buffer;
+ unsigned input_offset; /* can't really reduce the size of these */
unsigned output_offset;
};
@@ -96,6 +95,27 @@ struct translate *translate_lookup_or_create( struct translate_context *tctx,
struct translate *translate_create( const struct translate_key *key );
+static INLINE int translate_keysize( const struct translate_key *key )
+{
+ return 2 * sizeof(int) + key->nr_elements * sizeof(struct translate_element);
+}
+
+static INLINE int translate_key_compare( const struct translate_key *a,
+ const struct translate_key *b )
+{
+ int keysize = translate_keysize(a);
+ return memcmp(a, b, keysize);
+}
+
+
+static INLINE void translate_key_sanitize( struct translate_key *a )
+{
+ int keysize = translate_keysize(a);
+ char *ptr = (char *)a;
+ memset(ptr + keysize, 0, sizeof(*a) - keysize);
+}
+
+
/*******************************************************************************
* Private:
*/
diff --git a/src/gallium/drivers/softpipe/sp_quad_fs.c b/src/gallium/drivers/softpipe/sp_quad_fs.c
index 625d0f9b489..8c88c192f8f 100644
--- a/src/gallium/drivers/softpipe/sp_quad_fs.c
+++ b/src/gallium/drivers/softpipe/sp_quad_fs.c
@@ -53,7 +53,6 @@ struct quad_shade_stage
struct tgsi_sampler samplers[PIPE_MAX_SAMPLERS];
struct tgsi_exec_machine machine;
struct tgsi_exec_vector *inputs, *outputs;
- int colorOutSlot, depthOutSlot;
};
@@ -156,20 +155,6 @@ static void shade_begin(struct quad_stage *qs)
qss->samplers[i].texture = softpipe->texture[i];
}
- /* find output slots for depth, color */
- qss->colorOutSlot = -1;
- qss->depthOutSlot = -1;
- for (i = 0; i < qss->stage.softpipe->fs->info.num_outputs; i++) {
- switch (qss->stage.softpipe->fs->info.output_semantic_name[i]) {
- case TGSI_SEMANTIC_POSITION:
- qss->depthOutSlot = i;
- break;
- case TGSI_SEMANTIC_COLOR:
- qss->colorOutSlot = i;
- break;
- }
- }
-
softpipe->fs->prepare( softpipe->fs,
&qss->machine,
qss->samplers );
diff --git a/src/gallium/drivers/softpipe/sp_setup.c b/src/gallium/drivers/softpipe/sp_setup.c
index df7be01fcd5..543d86a5cb9 100644
--- a/src/gallium/drivers/softpipe/sp_setup.c
+++ b/src/gallium/drivers/softpipe/sp_setup.c
@@ -209,77 +209,76 @@ static INLINE int block( int x )
/**
- * Compute mask which indicates which pixels in the 2x2 quad are actually inside
- * the triangle's bounds.
- *
- * this is pretty nasty... may need to rework flush_spans again to
- * fix it, if possible.
- */
-static unsigned calculate_mask( struct setup_context *setup, int x )
-{
- unsigned mask = 0x0;
-
- if (x >= setup->span.left[0] && x < setup->span.right[0])
- mask |= MASK_TOP_LEFT;
-
- if (x >= setup->span.left[1] && x < setup->span.right[1])
- mask |= MASK_BOTTOM_LEFT;
-
- if (x+1 >= setup->span.left[0] && x+1 < setup->span.right[0])
- mask |= MASK_TOP_RIGHT;
-
- if (x+1 >= setup->span.left[1] && x+1 < setup->span.right[1])
- mask |= MASK_BOTTOM_RIGHT;
-
- return mask;
-}
-
-
-/**
* Render a horizontal span of quads
*/
static void flush_spans( struct setup_context *setup )
{
+ const int xleft0 = setup->span.left[0];
+ const int xleft1 = setup->span.left[1];
+ const int xright0 = setup->span.right[0];
+ const int xright1 = setup->span.right[1];
int minleft, maxright;
int x;
switch (setup->span.y_flags) {
case 0x3:
/* both odd and even lines written (both quad rows) */
- minleft = MIN2(setup->span.left[0], setup->span.left[1]);
- maxright = MAX2(setup->span.right[0], setup->span.right[1]);
+ minleft = block(MIN2(xleft0, xleft1));
+ maxright = block(MAX2(xright0, xright1));
+ for (x = minleft; x <= maxright; x += 2) {
+ /* determine which of the four pixels is inside the span bounds */
+ uint mask = 0x0;
+ if (x >= xleft0 && x < xright0)
+ mask |= MASK_TOP_LEFT;
+ if (x >= xleft1 && x < xright1)
+ mask |= MASK_BOTTOM_LEFT;
+ if (x+1 >= xleft0 && x+1 < xright0)
+ mask |= MASK_TOP_RIGHT;
+ if (x+1 >= xleft1 && x+1 < xright1)
+ mask |= MASK_BOTTOM_RIGHT;
+ emit_quad( setup, x, setup->span.y, mask );
+ }
break;
case 0x1:
/* only even line written (quad top row) */
- minleft = setup->span.left[0];
- maxright = setup->span.right[0];
+ minleft = block(xleft0);
+ maxright = block(xright0);
+ for (x = minleft; x <= maxright; x += 2) {
+ uint mask = 0x0;
+ if (x >= xleft0 && x < xright0)
+ mask |= MASK_TOP_LEFT;
+ if (x+1 >= xleft0 && x+1 < xright0)
+ mask |= MASK_TOP_RIGHT;
+ emit_quad( setup, x, setup->span.y, mask );
+ }
break;
case 0x2:
/* only odd line written (quad bottom row) */
- minleft = setup->span.left[1];
- maxright = setup->span.right[1];
+ minleft = block(xleft1);
+ maxright = block(xright1);
+ for (x = minleft; x <= maxright; x += 2) {
+ uint mask = 0x0;
+ if (x >= xleft1 && x < xright1)
+ mask |= MASK_BOTTOM_LEFT;
+ if (x+1 >= xleft1 && x+1 < xright1)
+ mask |= MASK_BOTTOM_RIGHT;
+ emit_quad( setup, x, setup->span.y, mask );
+ }
break;
default:
return;
}
- /* XXX this loop could be moved into the above switch cases and
- * calculate_mask() could be simplified a bit...
- */
- for (x = block(minleft); x <= block(maxright); x += 2) {
- emit_quad( setup, x, setup->span.y,
- calculate_mask( setup, x ) );
- }
-
setup->span.y = 0;
setup->span.y_flags = 0;
setup->span.right[0] = 0;
setup->span.right[1] = 0;
}
+
#if DEBUG_VERTS
static void print_vertex(const struct setup_context *setup,
const float (*v)[4])
@@ -717,7 +716,7 @@ void setup_tri( struct setup_context *setup,
const float (*v1)[4],
const float (*v2)[4] )
{
- float det = calc_det(v0, v1, v2);
+ float det;
#if DEBUG_VERTS
debug_printf("Setup triangle:\n");
@@ -728,7 +727,8 @@ void setup_tri( struct setup_context *setup,
if (setup->softpipe->no_rast)
return;
-
+
+ det = calc_det(v0, v1, v2);
/*
debug_printf("%s\n", __FUNCTION__ );
*/
diff --git a/src/gallium/winsys/xlib/fakeglx.c b/src/gallium/winsys/xlib/fakeglx.c
index ec77e81fedb..2c0075e9345 100644
--- a/src/gallium/winsys/xlib/fakeglx.c
+++ b/src/gallium/winsys/xlib/fakeglx.c
@@ -1689,6 +1689,15 @@ static void
Fake_glXSwapBuffers( Display *dpy, GLXDrawable drawable )
{
XMesaBuffer buffer = XMesaFindBuffer( dpy, drawable );
+ static boolean firsttime = 1, no_rast = 0;
+
+ if (firsttime) {
+ no_rast = getenv("SP_NO_RAST") != NULL;
+ firsttime = 0;
+ }
+
+ if (no_rast)
+ return;
if (buffer) {
XMesaSwapBuffers(buffer);
diff --git a/src/gallium/winsys/xlib/xm_api.c b/src/gallium/winsys/xlib/xm_api.c
index 0c248344b15..26b722f3439 100644
--- a/src/gallium/winsys/xlib/xm_api.c
+++ b/src/gallium/winsys/xlib/xm_api.c
@@ -110,6 +110,9 @@ int xmesa_check_for_xshm( XMesaDisplay *display )
int major, minor, ignore;
Bool pixmaps;
+ if (getenv("SP_NO_RAST"))
+ return 0;
+
if (getenv("MESA_NOSHM")) {
return 0;
}
diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c
index 7b8d9341701..893c79f28ca 100755
--- a/src/mesa/main/context.c
+++ b/src/mesa/main/context.c
@@ -150,8 +150,6 @@ int MESA_DEBUG_FLAGS = 0;
/* ubyte -> float conversion */
GLfloat _mesa_ubyte_to_float_color_tab[256];
-static void
-free_shared_state( GLcontext *ctx, struct gl_shared_state *ss );
/**
@@ -423,12 +421,14 @@ alloc_shared_state( GLcontext *ctx )
#endif
#if FEATURE_ARB_vertex_program
- ss->DefaultVertexProgram = ctx->Driver.NewProgram(ctx, GL_VERTEX_PROGRAM_ARB, 0);
+ ss->DefaultVertexProgram = (struct gl_vertex_program *)
+ ctx->Driver.NewProgram(ctx, GL_VERTEX_PROGRAM_ARB, 0);
if (!ss->DefaultVertexProgram)
goto cleanup;
#endif
#if FEATURE_ARB_fragment_program
- ss->DefaultFragmentProgram = ctx->Driver.NewProgram(ctx, GL_FRAGMENT_PROGRAM_ARB, 0);
+ ss->DefaultFragmentProgram = (struct gl_fragment_program *)
+ ctx->Driver.NewProgram(ctx, GL_FRAGMENT_PROGRAM_ARB, 0);
if (!ss->DefaultFragmentProgram)
goto cleanup;
#endif
@@ -513,12 +513,10 @@ alloc_shared_state( GLcontext *ctx )
_mesa_DeleteHashTable(ss->Programs);
#endif
#if FEATURE_ARB_vertex_program
- if (ss->DefaultVertexProgram)
- ctx->Driver.DeleteProgram(ctx, ss->DefaultVertexProgram);
+ _mesa_reference_vertprog(ctx, &ss->DefaultVertexProgram, NULL);
#endif
#if FEATURE_ARB_fragment_program
- if (ss->DefaultFragmentProgram)
- ctx->Driver.DeleteProgram(ctx, ss->DefaultFragmentProgram);
+ _mesa_reference_fragprog(ctx, &ss->DefaultFragmentProgram, NULL);
#endif
#if FEATURE_ATI_fragment_shader
if (ss->DefaultFragmentShader)
@@ -633,6 +631,21 @@ delete_arrayobj_cb(GLuint id, void *data, void *userData)
}
/**
+ * Callback for freeing shader program data. Call it before delete_shader_cb
+ * to avoid memory access error.
+ */
+static void
+free_shader_program_data_cb(GLuint id, void *data, void *userData)
+{
+ GLcontext *ctx = (GLcontext *) userData;
+ struct gl_shader_program *shProg = (struct gl_shader_program *) data;
+
+ if (shProg->Type == GL_SHADER_PROGRAM_MESA) {
+ _mesa_free_shader_program_data(ctx, shProg);
+ }
+}
+
+/**
* Callback for deleting shader and shader programs objects.
* Called by _mesa_HashDeleteAll().
*/
@@ -695,10 +708,10 @@ free_shared_state( GLcontext *ctx, struct gl_shared_state *ss )
_mesa_DeleteHashTable(ss->Programs);
#endif
#if FEATURE_ARB_vertex_program
- ctx->Driver.DeleteProgram(ctx, ss->DefaultVertexProgram);
+ _mesa_reference_vertprog(ctx, &ss->DefaultVertexProgram, NULL);
#endif
#if FEATURE_ARB_fragment_program
- ctx->Driver.DeleteProgram(ctx, ss->DefaultFragmentProgram);
+ _mesa_reference_fragprog(ctx, &ss->DefaultFragmentProgram, NULL);
#endif
#if FEATURE_ATI_fragment_shader
@@ -716,6 +729,7 @@ free_shared_state( GLcontext *ctx, struct gl_shared_state *ss )
_mesa_DeleteHashTable(ss->ArrayObjects);
#if FEATURE_ARB_shader_objects
+ _mesa_HashWalk(ss->ShaderObjects, free_shader_program_data_cb, ctx);
_mesa_HashDeleteAll(ss->ShaderObjects, delete_shader_cb, ctx);
_mesa_DeleteHashTable(ss->ShaderObjects);
#endif
@@ -1190,6 +1204,14 @@ _mesa_free_context_data( GLcontext *ctx )
_mesa_unreference_framebuffer(&ctx->ReadBuffer);
}
+ _mesa_reference_vertprog(ctx, &ctx->VertexProgram.Current, NULL);
+ _mesa_reference_vertprog(ctx, &ctx->VertexProgram._Current, NULL);
+ _mesa_reference_vertprog(ctx, &ctx->VertexProgram._TnlProgram, NULL);
+
+ _mesa_reference_fragprog(ctx, &ctx->FragmentProgram.Current, NULL);
+ _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current, NULL);
+ _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._TexEnvProgram, NULL);
+
_mesa_free_lighting_data( ctx );
_mesa_free_eval_data( ctx );
_mesa_free_texture_data( ctx );
diff --git a/src/mesa/main/ffvertex_prog.c b/src/mesa/main/ffvertex_prog.c
index f648d081c0e..810af9e33e6 100644
--- a/src/mesa/main/ffvertex_prog.c
+++ b/src/mesa/main/ffvertex_prog.c
@@ -946,35 +946,33 @@ static void build_lighting( struct tnl_program *p )
_bfc1 = _bfc0;
}
-
/* If no lights, still need to emit the scenecolor.
*/
- {
- struct ureg res0 = register_output( p, VERT_RESULT_COL0 );
- emit_op1(p, OPCODE_MOV, res0, 0, _col0);
- }
+ {
+ struct ureg res0 = register_output( p, VERT_RESULT_COL0 );
+ emit_op1(p, OPCODE_MOV, res0, 0, _col0);
+ }
- if (separate) {
- struct ureg res1 = register_output( p, VERT_RESULT_COL1 );
- emit_op1(p, OPCODE_MOV, res1, 0, _col1);
- }
+ if (separate) {
+ struct ureg res1 = register_output( p, VERT_RESULT_COL1 );
+ emit_op1(p, OPCODE_MOV, res1, 0, _col1);
+ }
- if (twoside) {
- struct ureg res0 = register_output( p, VERT_RESULT_BFC0 );
- emit_op1(p, OPCODE_MOV, res0, 0, _bfc0);
- }
+ if (twoside) {
+ struct ureg res0 = register_output( p, VERT_RESULT_BFC0 );
+ emit_op1(p, OPCODE_MOV, res0, 0, _bfc0);
+ }
- if (twoside && separate) {
- struct ureg res1 = register_output( p, VERT_RESULT_BFC1 );
- emit_op1(p, OPCODE_MOV, res1, 0, _bfc1);
- }
+ if (twoside && separate) {
+ struct ureg res1 = register_output( p, VERT_RESULT_BFC1 );
+ emit_op1(p, OPCODE_MOV, res1, 0, _bfc1);
+ }
if (nr_lights == 0) {
release_temps(p);
return;
}
-
for (i = 0; i < MAX_LIGHTS; i++) {
if (p->state->unit[i].light_enabled) {
struct ureg half = undef;
@@ -1006,7 +1004,7 @@ static void build_lighting( struct tnl_program *p )
VPpli = get_temp(p);
half = get_temp(p);
- /* Calulate VPpli vector
+ /* Calculate VPpli vector
*/
emit_op2(p, OPCODE_SUB, VPpli, 0, Ppli, V);
@@ -1017,15 +1015,13 @@ static void build_lighting( struct tnl_program *p )
emit_op1(p, OPCODE_RSQ, dist, 0, dist);
emit_op2(p, OPCODE_MUL, VPpli, 0, VPpli, dist);
-
- /* Calculate attenuation:
+ /* Calculate attenuation:
*/
if (!p->state->unit[i].light_spotcutoff_is_180 ||
p->state->unit[i].light_attenuated) {
att = calculate_light_attenuation(p, i, VPpli, dist);
}
-
-
+
/* Calculate viewer direction, or use infinite viewer:
*/
if (p->state->light_local_viewer) {
@@ -1047,7 +1043,6 @@ static void build_lighting( struct tnl_program *p )
emit_op2(p, OPCODE_DP3, dots, WRITEMASK_X, normal, VPpli);
emit_op2(p, OPCODE_DP3, dots, WRITEMASK_Y, normal, half);
-
/* Front face lighting:
*/
{
diff --git a/src/mesa/main/imports.c b/src/mesa/main/imports.c
index d8d35af15e2..d798f80e253 100644
--- a/src/mesa/main/imports.c
+++ b/src/mesa/main/imports.c
@@ -542,26 +542,24 @@ int
_mesa_ffs(int i)
{
#if (defined(_WIN32) && !defined(__MINGW32__) ) || defined(__IBMC__) || defined(__IBMCPP__)
- register int bit = 0;
- if (i != 0) {
- if ((i & 0xffff) == 0) {
- bit += 16;
- i >>= 16;
- }
- if ((i & 0xff) == 0) {
- bit += 8;
- i >>= 8;
- }
- if ((i & 0xf) == 0) {
- bit += 4;
- i >>= 4;
- }
- while ((i & 1) == 0) {
- bit++;
- i >>= 1;
- }
+ register int bit = 1;
+ if ((i & 0xffff) == 0) {
+ bit += 16;
+ i >>= 16;
+ }
+ if ((i & 0xff) == 0) {
+ bit += 8;
+ i >>= 8;
+ }
+ if ((i & 0xf) == 0) {
+ bit += 4;
+ i >>= 4;
+ }
+ if ((i & 0x3) == 0) {
+ bit += 2;
+ i >>= 2;
}
- return bit;
+ return (i) ? (bit + ((i + 1) & 0x01)) : 0;
#else
return ffs(i);
#endif
diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
index 50b22d25bf3..463142fe395 100644
--- a/src/mesa/main/mtypes.h
+++ b/src/mesa/main/mtypes.h
@@ -2203,10 +2203,10 @@ struct gl_shared_state
/*@{*/
struct _mesa_HashTable *Programs; /**< All vertex/fragment programs */
#if FEATURE_ARB_vertex_program
- struct gl_program *DefaultVertexProgram;
+ struct gl_vertex_program *DefaultVertexProgram;
#endif
#if FEATURE_ARB_fragment_program
- struct gl_program *DefaultFragmentProgram;
+ struct gl_fragment_program *DefaultFragmentProgram;
#endif
/*@}*/
diff --git a/src/mesa/main/state.c b/src/mesa/main/state.c
index 0b1c56fdd5f..90379a17726 100644
--- a/src/mesa/main/state.c
+++ b/src/mesa/main/state.c
@@ -982,16 +982,20 @@ update_program(GLcontext *ctx)
#endif
if (shProg && shProg->LinkStatus && shProg->FragmentProgram) {
/* user-defined fragment shader */
- ctx->FragmentProgram._Current = shProg->FragmentProgram;
+ _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current,
+ shProg->FragmentProgram);
}
else if (ctx->FragmentProgram._Enabled) {
/* use user-defined fragment program */
- ctx->FragmentProgram._Current = ctx->FragmentProgram.Current;
+ _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current,
+ ctx->FragmentProgram.Current);
}
else if (ctx->FragmentProgram._MaintainTexEnvProgram) {
/* fragment program generated from fixed-function state */
- ctx->FragmentProgram._Current = _mesa_get_fixed_func_fragment_program(ctx);
- ctx->FragmentProgram._TexEnvProgram = ctx->FragmentProgram._Current;
+ _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current,
+ _mesa_get_fixed_func_fragment_program(ctx));
+ _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._TexEnvProgram,
+ ctx->FragmentProgram._Current);
/* XXX get rid of this confusing stuff someday? */
ctx->FragmentProgram._Active = ctx->FragmentProgram._Enabled;
@@ -1000,7 +1004,7 @@ update_program(GLcontext *ctx)
}
else {
/* no fragment program */
- ctx->FragmentProgram._Current = NULL;
+ _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current, NULL);
}
if (ctx->FragmentProgram._Current != prevFP && ctx->Driver.BindProgram) {
@@ -1013,29 +1017,33 @@ update_program(GLcontext *ctx)
**/
#if 1
/* XXX get rid of this someday? */
- ctx->VertexProgram._TnlProgram = NULL;
+ _mesa_reference_vertprog(ctx, &ctx->VertexProgram._TnlProgram, NULL);
#endif
if (shProg && shProg->LinkStatus && shProg->VertexProgram) {
/* user-defined vertex shader */
- ctx->VertexProgram._Current = shProg->VertexProgram;
+ _mesa_reference_vertprog(ctx, &ctx->VertexProgram._Current,
+ shProg->VertexProgram);
}
else if (ctx->VertexProgram._Enabled) {
/* use user-defined vertex program */
- ctx->VertexProgram._Current = ctx->VertexProgram.Current;
+ _mesa_reference_vertprog(ctx, &ctx->VertexProgram._Current,
+ ctx->VertexProgram.Current);
}
else if (ctx->VertexProgram._MaintainTnlProgram) {
/* vertex program generated from fixed-function state */
- ctx->VertexProgram._Current = _mesa_get_fixed_func_vertex_program(ctx);
- ctx->VertexProgram._TnlProgram = ctx->VertexProgram._Current;
+ _mesa_reference_vertprog(ctx, &ctx->VertexProgram._Current,
+ _mesa_get_fixed_func_vertex_program(ctx));
+ _mesa_reference_vertprog(ctx, &ctx->VertexProgram._TnlProgram,
+ ctx->VertexProgram._Current);
}
else {
/* no vertex program / used fixed-function code */
- ctx->VertexProgram._Current = NULL;
+ _mesa_reference_vertprog(ctx, &ctx->VertexProgram._Current, NULL);
}
if (ctx->VertexProgram._Current != prevVP && ctx->Driver.BindProgram) {
ctx->Driver.BindProgram(ctx, GL_VERTEX_PROGRAM_ARB,
- (struct gl_program *) ctx->VertexProgram._Current);
+ (struct gl_program *) ctx->VertexProgram._Current);
}
}
diff --git a/src/mesa/shader/prog_cache.c b/src/mesa/shader/prog_cache.c
index dd0241ef24e..36a25377c55 100644
--- a/src/mesa/shader/prog_cache.c
+++ b/src/mesa/shader/prog_cache.c
@@ -30,6 +30,7 @@
#include "main/mtypes.h"
#include "main/imports.h"
#include "shader/prog_cache.h"
+#include "shader/program.h"
struct cache_item
@@ -109,7 +110,7 @@ clear_cache(GLcontext *ctx, struct gl_program_cache *cache)
for (c = cache->items[i]; c; c = next) {
next = c->next;
_mesa_free(c->key);
- ctx->Driver.DeleteProgram(ctx, c->program);
+ _mesa_reference_program(ctx, &c->program, NULL);
_mesa_free(c);
}
cache->items[i] = NULL;
@@ -177,7 +178,7 @@ _mesa_program_cache_insert(GLcontext *ctx,
c->key = _mesa_malloc(keysize);
memcpy(c->key, key, keysize);
- c->program = program;
+ c->program = program; /* no refcount change */
if (cache->n_items > cache->size * 1.5) {
if (cache->size < 1000)
diff --git a/src/mesa/shader/program.c b/src/mesa/shader/program.c
index 0ed7f833d20..9a23c5d7d31 100644
--- a/src/mesa/shader/program.c
+++ b/src/mesa/shader/program.c
@@ -60,9 +60,9 @@ _mesa_init_program(GLcontext *ctx)
ctx->VertexProgram.Enabled = GL_FALSE;
ctx->VertexProgram.PointSizeEnabled = GL_FALSE;
ctx->VertexProgram.TwoSideEnabled = GL_FALSE;
- ctx->VertexProgram.Current = (struct gl_vertex_program *) ctx->Shared->DefaultVertexProgram;
+ _mesa_reference_vertprog(ctx, &ctx->VertexProgram.Current,
+ ctx->Shared->DefaultVertexProgram);
assert(ctx->VertexProgram.Current);
- ctx->VertexProgram.Current->Base.RefCount++;
for (i = 0; i < MAX_NV_VERTEX_PROGRAM_PARAMS / 4; i++) {
ctx->VertexProgram.TrackMatrix[i] = GL_NONE;
ctx->VertexProgram.TrackMatrixTransform[i] = GL_IDENTITY_NV;
@@ -72,9 +72,9 @@ _mesa_init_program(GLcontext *ctx)
#if FEATURE_NV_fragment_program || FEATURE_ARB_fragment_program
ctx->FragmentProgram.Enabled = GL_FALSE;
- ctx->FragmentProgram.Current = (struct gl_fragment_program *) ctx->Shared->DefaultFragmentProgram;
+ _mesa_reference_fragprog(ctx, &ctx->FragmentProgram.Current,
+ ctx->Shared->DefaultFragmentProgram);
assert(ctx->FragmentProgram.Current);
- ctx->FragmentProgram.Current->Base.RefCount++;
ctx->FragmentProgram.Cache = _mesa_new_program_cache();
#endif
@@ -96,19 +96,11 @@ void
_mesa_free_program_data(GLcontext *ctx)
{
#if FEATURE_NV_vertex_program || FEATURE_ARB_vertex_program
- if (ctx->VertexProgram.Current) {
- ctx->VertexProgram.Current->Base.RefCount--;
- if (ctx->VertexProgram.Current->Base.RefCount <= 0)
- ctx->Driver.DeleteProgram(ctx, &(ctx->VertexProgram.Current->Base));
- }
+ _mesa_reference_vertprog(ctx, &ctx->VertexProgram.Current, NULL);
_mesa_delete_program_cache(ctx, ctx->VertexProgram.Cache);
#endif
#if FEATURE_NV_fragment_program || FEATURE_ARB_fragment_program
- if (ctx->FragmentProgram.Current) {
- ctx->FragmentProgram.Current->Base.RefCount--;
- if (ctx->FragmentProgram.Current->Base.RefCount <= 0)
- ctx->Driver.DeleteProgram(ctx, &(ctx->FragmentProgram.Current->Base));
- }
+ _mesa_reference_fragprog(ctx, &ctx->FragmentProgram.Current, NULL);
_mesa_delete_program_cache(ctx, ctx->FragmentProgram.Cache);
#endif
/* XXX probably move this stuff */
@@ -326,6 +318,59 @@ _mesa_lookup_program(GLcontext *ctx, GLuint id)
/**
+ * Reference counting for vertex/fragment programs
+ */
+void
+_mesa_reference_program(GLcontext *ctx,
+ struct gl_program **ptr,
+ struct gl_program *prog)
+{
+ assert(ptr);
+ if (*ptr && prog) {
+ /* sanity check */
+ ASSERT((*ptr)->Target == prog->Target);
+ }
+ if (*ptr == prog) {
+ return; /* no change */
+ }
+ if (*ptr) {
+ GLboolean deleteFlag;
+
+ /*_glthread_LOCK_MUTEX((*ptr)->Mutex);*/
+#if 0
+ printf("Program %p %u 0x%x Refcount-- to %d\n",
+ *ptr, (*ptr)->Id, (*ptr)->Target, (*ptr)->RefCount - 1);
+#endif
+ ASSERT((*ptr)->RefCount > 0);
+ (*ptr)->RefCount--;
+
+ deleteFlag = ((*ptr)->RefCount == 0);
+ /*_glthread_UNLOCK_MUTEX((*ptr)->Mutex);*/
+
+ if (deleteFlag) {
+ ASSERT(ctx);
+ ctx->Driver.DeleteProgram(ctx, *ptr);
+ }
+
+ *ptr = NULL;
+ }
+
+ assert(!*ptr);
+ if (prog) {
+ /*_glthread_LOCK_MUTEX(prog->Mutex);*/
+ prog->RefCount++;
+#if 0
+ printf("Program %p %u 0x%x Refcount++ to %d\n",
+ prog, prog->Id, prog->Target, prog->RefCount);
+#endif
+ /*_glthread_UNLOCK_MUTEX(prog->Mutex);*/
+ }
+
+ *ptr = prog;
+}
+
+
+/**
* Return a copy of a program.
* XXX Problem here if the program object is actually OO-derivation
* made by a device driver.
@@ -340,8 +385,9 @@ _mesa_clone_program(GLcontext *ctx, const struct gl_program *prog)
return NULL;
assert(clone->Target == prog->Target);
+ assert(clone->RefCount == 1);
+
clone->String = (GLubyte *) _mesa_strdup((char *) prog->String);
- clone->RefCount = 1;
clone->Format = prog->Format;
clone->Instructions = _mesa_alloc_instructions(prog->NumInstructions);
if (!clone->Instructions) {
@@ -704,9 +750,9 @@ _mesa_BindProgram(GLenum target, GLuint id)
/* Bind a default program */
newProg = NULL;
if (target == GL_VERTEX_PROGRAM_ARB) /* == GL_VERTEX_PROGRAM_NV */
- newProg = ctx->Shared->DefaultVertexProgram;
+ newProg = &ctx->Shared->DefaultVertexProgram->Base;
else
- newProg = ctx->Shared->DefaultFragmentProgram;
+ newProg = &ctx->Shared->DefaultFragmentProgram->Base;
}
else {
/* Bind a user program */
@@ -734,26 +780,16 @@ _mesa_BindProgram(GLenum target, GLuint id)
return;
}
- /* unbind/delete oldProg */
- if (curProg->Id != 0) {
- /* decrement refcount on previously bound fragment program */
- curProg->RefCount--;
- /* and delete if refcount goes below one */
- if (curProg->RefCount <= 0) {
- /* the program ID was already removed from the hash table */
- ctx->Driver.DeleteProgram(ctx, curProg);
- }
- }
-
/* bind newProg */
if (target == GL_VERTEX_PROGRAM_ARB) { /* == GL_VERTEX_PROGRAM_NV */
- ctx->VertexProgram.Current = (struct gl_vertex_program *) newProg;
+ _mesa_reference_vertprog(ctx, &ctx->VertexProgram.Current,
+ (struct gl_vertex_program *) newProg);
}
else if (target == GL_FRAGMENT_PROGRAM_NV ||
target == GL_FRAGMENT_PROGRAM_ARB) {
- ctx->FragmentProgram.Current = (struct gl_fragment_program *) newProg;
+ _mesa_reference_fragprog(ctx, &ctx->FragmentProgram.Current,
+ (struct gl_fragment_program *) newProg);
}
- newProg->RefCount++;
/* Never null pointers */
ASSERT(ctx->VertexProgram.Current);
@@ -811,10 +847,7 @@ _mesa_DeletePrograms(GLsizei n, const GLuint *ids)
}
/* The ID is immediately available for re-use now */
_mesa_HashRemove(ctx->Shared->Programs, ids[i]);
- prog->RefCount--;
- if (prog->RefCount <= 0) {
- ctx->Driver.DeleteProgram(ctx, prog);
- }
+ _mesa_reference_program(ctx, &prog, NULL);
}
}
}
diff --git a/src/mesa/shader/program.h b/src/mesa/shader/program.h
index 414a57d39cc..08fe576afc1 100644
--- a/src/mesa/shader/program.h
+++ b/src/mesa/shader/program.h
@@ -83,6 +83,28 @@ _mesa_delete_program(GLcontext *ctx, struct gl_program *prog);
extern struct gl_program *
_mesa_lookup_program(GLcontext *ctx, GLuint id);
+extern void
+_mesa_reference_program(GLcontext *ctx,
+ struct gl_program **ptr,
+ struct gl_program *prog);
+
+static INLINE void
+_mesa_reference_vertprog(GLcontext *ctx,
+ struct gl_vertex_program **ptr,
+ struct gl_vertex_program *prog)
+{
+ _mesa_reference_program(ctx, (struct gl_program **) ptr,
+ (struct gl_program *) prog);
+}
+
+static INLINE void
+_mesa_reference_fragprog(GLcontext *ctx,
+ struct gl_fragment_program **ptr,
+ struct gl_fragment_program *prog)
+{
+ _mesa_reference_program(ctx, (struct gl_program **) ptr,
+ (struct gl_program *) prog);
+}
extern struct gl_program *
_mesa_clone_program(GLcontext *ctx, const struct gl_program *prog);
diff --git a/src/mesa/shader/shader_api.c b/src/mesa/shader/shader_api.c
index 9c419c9903f..f12fa28d97b 100644
--- a/src/mesa/shader/shader_api.c
+++ b/src/mesa/shader/shader_api.c
@@ -80,8 +80,7 @@ _mesa_clear_shader_program_data(GLcontext *ctx,
* original/unlinked program.
*/
shProg->VertexProgram->Base.Parameters = NULL;
- ctx->Driver.DeleteProgram(ctx, &shProg->VertexProgram->Base);
- shProg->VertexProgram = NULL;
+ _mesa_reference_vertprog(ctx, &shProg->VertexProgram, NULL);
}
if (shProg->FragmentProgram) {
@@ -89,8 +88,7 @@ _mesa_clear_shader_program_data(GLcontext *ctx,
* original/unlinked program.
*/
shProg->FragmentProgram->Base.Parameters = NULL;
- ctx->Driver.DeleteProgram(ctx, &shProg->FragmentProgram->Base);
- shProg->FragmentProgram = NULL;
+ _mesa_reference_fragprog(ctx, &shProg->FragmentProgram, NULL);
}
if (shProg->Uniforms) {
diff --git a/src/mesa/shader/slang/slang_link.c b/src/mesa/shader/slang/slang_link.c
index addff204218..ae581553dc7 100644
--- a/src/mesa/shader/slang/slang_link.c
+++ b/src/mesa/shader/slang/slang_link.c
@@ -410,19 +410,19 @@ _slang_link(GLcontext *ctx,
* changing src/dst registers after merging the uniforms and varying vars.
*/
if (vertProg) {
- shProg->VertexProgram
- = vertex_program(_mesa_clone_program(ctx, &vertProg->Base));
+ _mesa_reference_vertprog(ctx, &shProg->VertexProgram,
+ vertex_program(_mesa_clone_program(ctx, &vertProg->Base)));
}
else {
- shProg->VertexProgram = NULL;
+ _mesa_reference_vertprog(ctx, &shProg->VertexProgram, NULL);
}
if (fragProg) {
- shProg->FragmentProgram
- = fragment_program(_mesa_clone_program(ctx, &fragProg->Base));
+ _mesa_reference_fragprog(ctx, &shProg->FragmentProgram,
+ fragment_program(_mesa_clone_program(ctx, &fragProg->Base)));
}
else {
- shProg->FragmentProgram = NULL;
+ _mesa_reference_fragprog(ctx, &shProg->FragmentProgram, NULL);
}
/* link varying vars */
diff --git a/src/mesa/state_tracker/st_atom.h b/src/mesa/state_tracker/st_atom.h
index 3a63e2dec03..c6c6eba8121 100644
--- a/src/mesa/state_tracker/st_atom.h
+++ b/src/mesa/state_tracker/st_atom.h
@@ -44,20 +44,20 @@ void st_destroy_atoms( struct st_context *st );
void st_validate_state( struct st_context *st );
-const struct st_tracked_state st_update_framebuffer;
-const struct st_tracked_state st_update_clip;
-const struct st_tracked_state st_update_depth_stencil_alpha;
-const struct st_tracked_state st_update_shader;
-const struct st_tracked_state st_update_rasterizer;
-const struct st_tracked_state st_update_polygon_stipple;
-const struct st_tracked_state st_update_viewport;
-const struct st_tracked_state st_update_scissor;
-const struct st_tracked_state st_update_blend;
-const struct st_tracked_state st_update_sampler;
-const struct st_tracked_state st_update_texture;
-const struct st_tracked_state st_update_fs_constants;
-const struct st_tracked_state st_update_vs_constants;
-const struct st_tracked_state st_update_pixel_transfer;
+extern const struct st_tracked_state st_update_framebuffer;
+extern const struct st_tracked_state st_update_clip;
+extern const struct st_tracked_state st_update_depth_stencil_alpha;
+extern const struct st_tracked_state st_update_shader;
+extern const struct st_tracked_state st_update_rasterizer;
+extern const struct st_tracked_state st_update_polygon_stipple;
+extern const struct st_tracked_state st_update_viewport;
+extern const struct st_tracked_state st_update_scissor;
+extern const struct st_tracked_state st_update_blend;
+extern const struct st_tracked_state st_update_sampler;
+extern const struct st_tracked_state st_update_texture;
+extern const struct st_tracked_state st_update_fs_constants;
+extern const struct st_tracked_state st_update_vs_constants;
+extern const struct st_tracked_state st_update_pixel_transfer;
uint st_compare_func_to_pipe(GLenum func);
diff --git a/src/mesa/state_tracker/st_atom_shader.c b/src/mesa/state_tracker/st_atom_shader.c
index 652500f52a2..7745591afba 100644
--- a/src/mesa/state_tracker/st_atom_shader.c
+++ b/src/mesa/state_tracker/st_atom_shader.c
@@ -39,6 +39,7 @@
#include "main/imports.h"
#include "main/mtypes.h"
+#include "shader/program.h"
#include "pipe/p_context.h"
#include "pipe/p_shader_tokens.h"
@@ -264,14 +265,16 @@ update_linkage( struct st_context *st )
*/
assert(st->ctx->VertexProgram._Current);
stvp = st_vertex_program(st->ctx->VertexProgram._Current);
+ assert(stvp->Base.Base.Target == GL_VERTEX_PROGRAM_ARB);
assert(st->ctx->FragmentProgram._Current);
stfp = st_fragment_program(st->ctx->FragmentProgram._Current);
+ assert(stfp->Base.Base.Target == GL_FRAGMENT_PROGRAM_ARB);
xvp = find_translated_vp(st, stvp, stfp);
- st->vp = stvp;
- st->fp = stfp;
+ st_reference_vertprog(st, &st->vp, stvp);
+ st_reference_fragprog(st, &st->fp, stfp);
cso_set_vertex_shader_handle(st->cso_context, stvp->driver_shader);
cso_set_fragment_shader_handle(st->cso_context, stfp->driver_shader);
diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c
index 02ef961e4d3..866683c23e9 100644
--- a/src/mesa/state_tracker/st_cb_texture.c
+++ b/src/mesa/state_tracker/st_cb_texture.c
@@ -1366,7 +1366,7 @@ calculate_first_last_level(struct st_texture_object *stObj)
}
else {
firstLevel = 0;
- lastLevel = MIN2(tObj->MaxLevel, tObj->Image[0][0]->WidthLog2);
+ lastLevel = MIN2(tObj->MaxLevel, tObj->Image[0][tObj->BaseLevel]->WidthLog2);
}
break;
case GL_TEXTURE_RECTANGLE_NV:
diff --git a/src/mesa/state_tracker/st_context.c b/src/mesa/state_tracker/st_context.c
index c900064f2b8..8db55a179f8 100644
--- a/src/mesa/state_tracker/st_context.c
+++ b/src/mesa/state_tracker/st_context.c
@@ -158,6 +158,9 @@ static void st_destroy_context_priv( struct st_context *st )
{
uint i;
+ st_reference_fragprog(st, &st->fp, NULL);
+ st_reference_vertprog(st, &st->vp, NULL);
+
draw_destroy(st->draw);
st_destroy_atoms( st );
st_destroy_draw( st );
diff --git a/src/mesa/state_tracker/st_program.h b/src/mesa/state_tracker/st_program.h
index d8f26da2eeb..bf07a50789e 100644
--- a/src/mesa/state_tracker/st_program.h
+++ b/src/mesa/state_tracker/st_program.h
@@ -34,7 +34,8 @@
#ifndef ST_PROGRAM_H
#define ST_PROGRAM_H
-#include "mtypes.h"
+#include "main/mtypes.h"
+#include "shader/program.h"
#include "pipe/p_shader_tokens.h"
@@ -115,6 +116,27 @@ st_vertex_program( struct gl_vertex_program *vp )
}
+static INLINE void
+st_reference_vertprog(struct st_context *st,
+ struct st_vertex_program **ptr,
+ struct st_vertex_program *prog)
+{
+ _mesa_reference_program(st->ctx,
+ (struct gl_program **) ptr,
+ (struct gl_program *) prog);
+}
+
+static INLINE void
+st_reference_fragprog(struct st_context *st,
+ struct st_fragment_program **ptr,
+ struct st_fragment_program *prog)
+{
+ _mesa_reference_program(st->ctx,
+ (struct gl_program **) ptr,
+ (struct gl_program *) prog);
+}
+
+
extern void
st_translate_fragment_program(struct st_context *st,
struct st_fragment_program *fp,