summaryrefslogtreecommitdiff
path: root/src/mesa
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa')
-rw-r--r--src/mesa/SConscript1
-rw-r--r--src/mesa/main/teximage.c23
-rw-r--r--src/mesa/shader/arbprogparse.c5
-rw-r--r--src/mesa/sources1
-rw-r--r--src/mesa/state_tracker/st_atom_blend.c52
-rw-r--r--src/mesa/state_tracker/st_atom_depth.c60
-rw-r--r--src/mesa/state_tracker/st_atom_rasterizer.c108
-rw-r--r--src/mesa/state_tracker/st_atom_sampler.c60
-rw-r--r--src/mesa/state_tracker/st_atom_shader.c28
-rw-r--r--src/mesa/state_tracker/st_atom_texture.c15
-rw-r--r--src/mesa/state_tracker/st_cb_accum.c1
-rw-r--r--src/mesa/state_tracker/st_cb_clear.c56
-rw-r--r--src/mesa/state_tracker/st_cb_drawpixels.c69
-rw-r--r--src/mesa/state_tracker/st_cb_program.c5
-rw-r--r--src/mesa/state_tracker/st_cb_texture.c3
-rw-r--r--src/mesa/state_tracker/st_context.c9
-rw-r--r--src/mesa/state_tracker/st_context.h22
-rw-r--r--src/mesa/state_tracker/st_debug.c6
-rw-r--r--src/mesa/state_tracker/st_draw.c13
-rw-r--r--src/mesa/state_tracker/st_gen_mipmap.c41
-rw-r--r--src/mesa/state_tracker/st_mesa_to_tgsi.c8
-rw-r--r--src/mesa/state_tracker/st_mesa_to_tgsi.h2
-rw-r--r--src/mesa/state_tracker/st_program.c59
-rw-r--r--src/mesa/state_tracker/st_program.h22
-rw-r--r--src/mesa/vbo/vbo_exec_api.c11
25 files changed, 358 insertions, 322 deletions
diff --git a/src/mesa/SConscript b/src/mesa/SConscript
index a77c3de6c7..678e4ad0e8 100644
--- a/src/mesa/SConscript
+++ b/src/mesa/SConscript
@@ -161,6 +161,7 @@ STATETRACKER_SOURCES = [
'state_tracker/st_extensions.c',
'state_tracker/st_format.c',
'state_tracker/st_framebuffer.c',
+ 'state_tracker/st_gen_mipmap.c',
'state_tracker/st_mesa_to_tgsi.c',
'state_tracker/st_program.c',
'state_tracker/st_texture.c',
diff --git a/src/mesa/main/teximage.c b/src/mesa/main/teximage.c
index 5c96be9216..f15e404527 100644
--- a/src/mesa/main/teximage.c
+++ b/src/mesa/main/teximage.c
@@ -1214,19 +1214,30 @@ _mesa_init_teximage_fields(GLcontext *ctx, GLenum target,
img->Width = width;
img->Height = height;
img->Depth = depth;
+
img->Width2 = width - 2 * border; /* == 1 << img->WidthLog2; */
- img->Height2 = height - 2 * border; /* == 1 << img->HeightLog2; */
- img->Depth2 = depth - 2 * border; /* == 1 << img->DepthLog2; */
img->WidthLog2 = logbase2(img->Width2);
- if (height == 1) /* 1-D texture */
+
+ if (height == 1) { /* 1-D texture */
+ img->Height2 = 1;
img->HeightLog2 = 0;
- else
+ }
+ else {
+ img->Height2 = height - 2 * border; /* == 1 << img->HeightLog2; */
img->HeightLog2 = logbase2(img->Height2);
- if (depth == 1) /* 2-D texture */
+ }
+
+ if (depth == 1) { /* 2-D texture */
+ img->Depth2 = 1;
img->DepthLog2 = 0;
- else
+ }
+ else {
+ img->Depth2 = depth - 2 * border; /* == 1 << img->DepthLog2; */
img->DepthLog2 = logbase2(img->Depth2);
+ }
+
img->MaxLog2 = MAX2(img->WidthLog2, img->HeightLog2);
+
img->IsCompressed = GL_FALSE;
img->CompressedSize = 0;
diff --git a/src/mesa/shader/arbprogparse.c b/src/mesa/shader/arbprogparse.c
index b6b3c88b14..e385b9d997 100644
--- a/src/mesa/shader/arbprogparse.c
+++ b/src/mesa/shader/arbprogparse.c
@@ -3910,8 +3910,11 @@ _mesa_parse_arb_fragment_program(GLcontext* ctx, GLenum target,
program->Base.NumNativeTexIndirections = ap.Base.NumTexIndirections;
program->Base.InputsRead = ap.Base.InputsRead;
program->Base.OutputsWritten = ap.Base.OutputsWritten;
- for (i = 0; i < MAX_TEXTURE_IMAGE_UNITS; i++)
+ for (i = 0; i < MAX_TEXTURE_IMAGE_UNITS; i++) {
program->Base.TexturesUsed[i] = ap.TexturesUsed[i];
+ if (ap.TexturesUsed[i])
+ program->Base.SamplersUsed |= (1 << i);
+ }
program->Base.ShadowSamplers = ap.ShadowSamplers;
program->FogOption = ap.FogOption;
program->UsesKill = ap.UsesKill;
diff --git a/src/mesa/sources b/src/mesa/sources
index f0bf7b31fb..e3d5f22849 100644
--- a/src/mesa/sources
+++ b/src/mesa/sources
@@ -184,7 +184,6 @@ STATETRACKER_SOURCES = \
state_tracker/st_cb_readpixels.c \
state_tracker/st_cb_strings.c \
state_tracker/st_cb_texture.c \
- state_tracker/st_cache.c \
state_tracker/st_context.c \
state_tracker/st_debug.c \
state_tracker/st_draw.c \
diff --git a/src/mesa/state_tracker/st_atom_blend.c b/src/mesa/state_tracker/st_atom_blend.c
index 2a9d209153..6c13fc8141 100644
--- a/src/mesa/state_tracker/st_atom_blend.c
+++ b/src/mesa/state_tracker/st_atom_blend.c
@@ -33,11 +33,11 @@
#include "st_context.h"
-#include "st_cache.h"
#include "st_atom.h"
#include "pipe/p_context.h"
#include "pipe/p_defines.h"
+#include "cso_cache/cso_context.h"
/**
@@ -155,44 +155,43 @@ translate_logicop(GLenum logicop)
static void
update_blend( struct st_context *st )
{
- struct pipe_blend_state blend;
- const struct cso_blend *cso;
+ struct pipe_blend_state *blend = &st->state.blend;
- memset(&blend, 0, sizeof(blend));
+ memset(blend, 0, sizeof(*blend));
if (st->ctx->Color.ColorLogicOpEnabled ||
(st->ctx->Color.BlendEnabled &&
st->ctx->Color.BlendEquationRGB == GL_LOGIC_OP)) {
/* logicop enabled */
- blend.logicop_enable = 1;
- blend.logicop_func = translate_logicop(st->ctx->Color.LogicOp);
+ blend->logicop_enable = 1;
+ blend->logicop_func = translate_logicop(st->ctx->Color.LogicOp);
}
else if (st->ctx->Color.BlendEnabled) {
/* blending enabled */
- blend.blend_enable = 1;
+ blend->blend_enable = 1;
- blend.rgb_func = translate_blend(st->ctx->Color.BlendEquationRGB);
+ blend->rgb_func = translate_blend(st->ctx->Color.BlendEquationRGB);
if (st->ctx->Color.BlendEquationRGB == GL_MIN ||
st->ctx->Color.BlendEquationRGB == GL_MAX) {
/* Min/max are special */
- blend.rgb_src_factor = PIPE_BLENDFACTOR_ONE;
- blend.rgb_dst_factor = PIPE_BLENDFACTOR_ONE;
+ blend->rgb_src_factor = PIPE_BLENDFACTOR_ONE;
+ blend->rgb_dst_factor = PIPE_BLENDFACTOR_ONE;
}
else {
- blend.rgb_src_factor = translate_blend(st->ctx->Color.BlendSrcRGB);
- blend.rgb_dst_factor = translate_blend(st->ctx->Color.BlendDstRGB);
+ blend->rgb_src_factor = translate_blend(st->ctx->Color.BlendSrcRGB);
+ blend->rgb_dst_factor = translate_blend(st->ctx->Color.BlendDstRGB);
}
- blend.alpha_func = translate_blend(st->ctx->Color.BlendEquationA);
+ blend->alpha_func = translate_blend(st->ctx->Color.BlendEquationA);
if (st->ctx->Color.BlendEquationA == GL_MIN ||
st->ctx->Color.BlendEquationA == GL_MAX) {
/* Min/max are special */
- blend.alpha_src_factor = PIPE_BLENDFACTOR_ONE;
- blend.alpha_dst_factor = PIPE_BLENDFACTOR_ONE;
+ blend->alpha_src_factor = PIPE_BLENDFACTOR_ONE;
+ blend->alpha_dst_factor = PIPE_BLENDFACTOR_ONE;
}
else {
- blend.alpha_src_factor = translate_blend(st->ctx->Color.BlendSrcA);
- blend.alpha_dst_factor = translate_blend(st->ctx->Color.BlendDstA);
+ blend->alpha_src_factor = translate_blend(st->ctx->Color.BlendSrcA);
+ blend->alpha_dst_factor = translate_blend(st->ctx->Color.BlendDstA);
}
}
else {
@@ -201,25 +200,18 @@ update_blend( struct st_context *st )
/* Colormask - maybe reverse these bits? */
if (st->ctx->Color.ColorMask[0])
- blend.colormask |= PIPE_MASK_R;
+ blend->colormask |= PIPE_MASK_R;
if (st->ctx->Color.ColorMask[1])
- blend.colormask |= PIPE_MASK_G;
+ blend->colormask |= PIPE_MASK_G;
if (st->ctx->Color.ColorMask[2])
- blend.colormask |= PIPE_MASK_B;
+ blend->colormask |= PIPE_MASK_B;
if (st->ctx->Color.ColorMask[3])
- blend.colormask |= PIPE_MASK_A;
+ blend->colormask |= PIPE_MASK_A;
if (st->ctx->Color.DitherFlag)
- blend.dither = 1;
+ blend->dither = 1;
- cso = st_cached_blend_state(st, &blend);
-
- if (st->state.blend != cso) {
- /* state has changed */
- st->state.blend = cso;
- /* bind new state */
- st->pipe->bind_blend_state(st->pipe, cso->data);
- }
+ cso_set_blend(st->cso_context, blend);
if (memcmp(st->ctx->Color.BlendColor, &st->state.blend_color, 4 * sizeof(GLfloat)) != 0) {
/* state has changed */
diff --git a/src/mesa/state_tracker/st_atom_depth.c b/src/mesa/state_tracker/st_atom_depth.c
index 7aecdbfbcc..827ad3b548 100644
--- a/src/mesa/state_tracker/st_atom_depth.c
+++ b/src/mesa/state_tracker/st_atom_depth.c
@@ -34,10 +34,10 @@
#include "st_context.h"
-#include "st_cache.h"
#include "st_atom.h"
#include "pipe/p_context.h"
#include "pipe/p_defines.h"
+#include "cso_cache/cso_context.h"
/**
@@ -93,53 +93,47 @@ gl_stencil_op_to_pipe(GLenum func)
static void
update_depth_stencil_alpha(struct st_context *st)
{
- struct pipe_depth_stencil_alpha_state depth_stencil;
- const struct cso_depth_stencil_alpha *cso;
+ struct pipe_depth_stencil_alpha_state *dsa = &st->state.depth_stencil;
- memset(&depth_stencil, 0, sizeof(depth_stencil));
+ memset(dsa, 0, sizeof(*dsa));
- depth_stencil.depth.enabled = st->ctx->Depth.Test;
- depth_stencil.depth.writemask = st->ctx->Depth.Mask;
- depth_stencil.depth.func = st_compare_func_to_pipe(st->ctx->Depth.Func);
+ dsa->depth.enabled = st->ctx->Depth.Test;
+ dsa->depth.writemask = st->ctx->Depth.Mask;
+ dsa->depth.func = st_compare_func_to_pipe(st->ctx->Depth.Func);
if (st->ctx->Query.CurrentOcclusionObject &&
st->ctx->Query.CurrentOcclusionObject->Active)
- depth_stencil.depth.occlusion_count = 1;
+ dsa->depth.occlusion_count = 1;
if (st->ctx->Stencil.Enabled) {
- depth_stencil.stencil[0].enabled = 1;
- depth_stencil.stencil[0].func = st_compare_func_to_pipe(st->ctx->Stencil.Function[0]);
- depth_stencil.stencil[0].fail_op = gl_stencil_op_to_pipe(st->ctx->Stencil.FailFunc[0]);
- depth_stencil.stencil[0].zfail_op = gl_stencil_op_to_pipe(st->ctx->Stencil.ZFailFunc[0]);
- depth_stencil.stencil[0].zpass_op = gl_stencil_op_to_pipe(st->ctx->Stencil.ZPassFunc[0]);
- depth_stencil.stencil[0].ref_value = st->ctx->Stencil.Ref[0] & 0xff;
- depth_stencil.stencil[0].value_mask = st->ctx->Stencil.ValueMask[0] & 0xff;
- depth_stencil.stencil[0].write_mask = st->ctx->Stencil.WriteMask[0] & 0xff;
+ dsa->stencil[0].enabled = 1;
+ dsa->stencil[0].func = st_compare_func_to_pipe(st->ctx->Stencil.Function[0]);
+ dsa->stencil[0].fail_op = gl_stencil_op_to_pipe(st->ctx->Stencil.FailFunc[0]);
+ dsa->stencil[0].zfail_op = gl_stencil_op_to_pipe(st->ctx->Stencil.ZFailFunc[0]);
+ dsa->stencil[0].zpass_op = gl_stencil_op_to_pipe(st->ctx->Stencil.ZPassFunc[0]);
+ dsa->stencil[0].ref_value = st->ctx->Stencil.Ref[0] & 0xff;
+ dsa->stencil[0].value_mask = st->ctx->Stencil.ValueMask[0] & 0xff;
+ dsa->stencil[0].write_mask = st->ctx->Stencil.WriteMask[0] & 0xff;
if (st->ctx->Stencil.TestTwoSide) {
- depth_stencil.stencil[1].enabled = 1;
- depth_stencil.stencil[1].func = st_compare_func_to_pipe(st->ctx->Stencil.Function[1]);
- depth_stencil.stencil[1].fail_op = gl_stencil_op_to_pipe(st->ctx->Stencil.FailFunc[1]);
- depth_stencil.stencil[1].zfail_op = gl_stencil_op_to_pipe(st->ctx->Stencil.ZFailFunc[1]);
- depth_stencil.stencil[1].zpass_op = gl_stencil_op_to_pipe(st->ctx->Stencil.ZPassFunc[1]);
- depth_stencil.stencil[1].ref_value = st->ctx->Stencil.Ref[1] & 0xff;
- depth_stencil.stencil[1].value_mask = st->ctx->Stencil.ValueMask[1] & 0xff;
- depth_stencil.stencil[1].write_mask = st->ctx->Stencil.WriteMask[1] & 0xff;
+ dsa->stencil[1].enabled = 1;
+ dsa->stencil[1].func = st_compare_func_to_pipe(st->ctx->Stencil.Function[1]);
+ dsa->stencil[1].fail_op = gl_stencil_op_to_pipe(st->ctx->Stencil.FailFunc[1]);
+ dsa->stencil[1].zfail_op = gl_stencil_op_to_pipe(st->ctx->Stencil.ZFailFunc[1]);
+ dsa->stencil[1].zpass_op = gl_stencil_op_to_pipe(st->ctx->Stencil.ZPassFunc[1]);
+ dsa->stencil[1].ref_value = st->ctx->Stencil.Ref[1] & 0xff;
+ dsa->stencil[1].value_mask = st->ctx->Stencil.ValueMask[1] & 0xff;
+ dsa->stencil[1].write_mask = st->ctx->Stencil.WriteMask[1] & 0xff;
}
}
if (st->ctx->Color.AlphaEnabled) {
- depth_stencil.alpha.enabled = 1;
- depth_stencil.alpha.func = st_compare_func_to_pipe(st->ctx->Color.AlphaFunc);
- depth_stencil.alpha.ref = st->ctx->Color.AlphaRef;
+ dsa->alpha.enabled = 1;
+ dsa->alpha.func = st_compare_func_to_pipe(st->ctx->Color.AlphaFunc);
+ dsa->alpha.ref = st->ctx->Color.AlphaRef;
}
- cso = st_cached_depth_stencil_alpha_state(st, &depth_stencil);
- if (st->state.depth_stencil != cso) {
- /* state has changed */
- st->state.depth_stencil = cso;
- st->pipe->bind_depth_stencil_alpha_state(st->pipe, cso->data); /* bind new state */
- }
+ cso_set_depth_stencil_alpha(st->cso_context, dsa);
}
diff --git a/src/mesa/state_tracker/st_atom_rasterizer.c b/src/mesa/state_tracker/st_atom_rasterizer.c
index 229839d8b2..77cef9236b 100644
--- a/src/mesa/state_tracker/st_atom_rasterizer.c
+++ b/src/mesa/state_tracker/st_atom_rasterizer.c
@@ -32,10 +32,11 @@
#include "main/macros.h"
#include "st_context.h"
-#include "st_cache.h"
+#include "st_atom.h"
#include "pipe/p_context.h"
#include "pipe/p_defines.h"
-#include "st_atom.h"
+#include "cso_cache/cso_context.h"
+
static GLuint translate_fill( GLenum mode )
{
@@ -72,22 +73,21 @@ static GLboolean get_offset_flag( GLuint fill_mode,
static void update_raster_state( struct st_context *st )
{
GLcontext *ctx = st->ctx;
- struct pipe_rasterizer_state raster;
- const struct cso_rasterizer *cso;
+ struct pipe_rasterizer_state *raster = &st->state.rasterizer;
const struct gl_vertex_program *vertProg = ctx->VertexProgram._Current;
uint i;
- memset(&raster, 0, sizeof(raster));
+ memset(raster, 0, sizeof(*raster));
- raster.origin_lower_left = 1; /* Always true for OpenGL */
+ raster->origin_lower_left = 1; /* Always true for OpenGL */
/* _NEW_POLYGON, _NEW_BUFFERS
*/
{
if (ctx->Polygon.FrontFace == GL_CCW)
- raster.front_winding = PIPE_WINDING_CCW;
+ raster->front_winding = PIPE_WINDING_CCW;
else
- raster.front_winding = PIPE_WINDING_CW;
+ raster->front_winding = PIPE_WINDING_CW;
/* XXX
* I think the intention here is that user-created framebuffer objects
@@ -96,13 +96,13 @@ static void update_raster_state( struct st_context *st )
* But this is an implementation/driver-specific artifact - remove...
*/
if (ctx->DrawBuffer && ctx->DrawBuffer->Name != 0)
- raster.front_winding ^= PIPE_WINDING_BOTH;
+ raster->front_winding ^= PIPE_WINDING_BOTH;
}
/* _NEW_LIGHT
*/
if (ctx->Light.ShadeModel == GL_FLAT)
- raster.flatshade = 1;
+ raster->flatshade = 1;
/* _NEW_LIGHT | _NEW_PROGRAM
*
@@ -113,28 +113,28 @@ static void update_raster_state( struct st_context *st )
if (ctx->VertexProgram._Current) {
if (ctx->VertexProgram._Enabled) {
/* user-defined program */
- raster.light_twoside = ctx->VertexProgram.TwoSideEnabled;
+ raster->light_twoside = ctx->VertexProgram.TwoSideEnabled;
}
else {
/* TNL-generated program */
- raster.light_twoside = ctx->Light.Enabled && ctx->Light.Model.TwoSide;
+ raster->light_twoside = ctx->Light.Enabled && ctx->Light.Model.TwoSide;
}
}
else if (ctx->Light.Enabled && ctx->Light.Model.TwoSide) {
- raster.light_twoside = 1;
+ raster->light_twoside = 1;
}
/* _NEW_POLYGON
*/
if (ctx->Polygon.CullFlag) {
if (ctx->Polygon.CullFaceMode == GL_FRONT_AND_BACK) {
- raster.cull_mode = PIPE_WINDING_BOTH;
+ raster->cull_mode = PIPE_WINDING_BOTH;
}
else if (ctx->Polygon.CullFaceMode == GL_FRONT) {
- raster.cull_mode = raster.front_winding;
+ raster->cull_mode = raster->front_winding;
}
else {
- raster.cull_mode = raster.front_winding ^ PIPE_WINDING_BOTH;
+ raster->cull_mode = raster->front_winding ^ PIPE_WINDING_BOTH;
}
}
@@ -144,23 +144,23 @@ static void update_raster_state( struct st_context *st )
GLuint fill_front = translate_fill( ctx->Polygon.FrontMode );
GLuint fill_back = translate_fill( ctx->Polygon.BackMode );
- if (raster.front_winding == PIPE_WINDING_CW) {
- raster.fill_cw = fill_front;
- raster.fill_ccw = fill_back;
+ if (raster->front_winding == PIPE_WINDING_CW) {
+ raster->fill_cw = fill_front;
+ raster->fill_ccw = fill_back;
}
else {
- raster.fill_cw = fill_back;
- raster.fill_ccw = fill_front;
+ raster->fill_cw = fill_back;
+ raster->fill_ccw = fill_front;
}
/* Simplify when culling is active:
*/
- if (raster.cull_mode & PIPE_WINDING_CW) {
- raster.fill_cw = raster.fill_ccw;
+ if (raster->cull_mode & PIPE_WINDING_CW) {
+ raster->fill_cw = raster->fill_ccw;
}
- if (raster.cull_mode & PIPE_WINDING_CCW) {
- raster.fill_ccw = raster.fill_cw;
+ if (raster->cull_mode & PIPE_WINDING_CCW) {
+ raster->fill_ccw = raster->fill_cw;
}
}
@@ -168,95 +168,91 @@ static void update_raster_state( struct st_context *st )
*/
if (ctx->Polygon.OffsetUnits != 0.0 ||
ctx->Polygon.OffsetFactor != 0.0) {
- raster.offset_cw = get_offset_flag( raster.fill_cw, &ctx->Polygon );
- raster.offset_ccw = get_offset_flag( raster.fill_ccw, &ctx->Polygon );
- raster.offset_units = ctx->Polygon.OffsetUnits;
- raster.offset_scale = ctx->Polygon.OffsetFactor;
+ raster->offset_cw = get_offset_flag( raster->fill_cw, &ctx->Polygon );
+ raster->offset_ccw = get_offset_flag( raster->fill_ccw, &ctx->Polygon );
+ raster->offset_units = ctx->Polygon.OffsetUnits;
+ raster->offset_scale = ctx->Polygon.OffsetFactor;
}
if (ctx->Polygon.SmoothFlag)
- raster.poly_smooth = 1;
+ raster->poly_smooth = 1;
if (ctx->Polygon.StippleFlag)
- raster.poly_stipple_enable = 1;
+ raster->poly_stipple_enable = 1;
/* _NEW_BUFFERS, _NEW_POLYGON
*/
- if (raster.fill_cw != PIPE_POLYGON_MODE_FILL ||
- raster.fill_ccw != PIPE_POLYGON_MODE_FILL)
+ if (raster->fill_cw != PIPE_POLYGON_MODE_FILL ||
+ raster->fill_ccw != PIPE_POLYGON_MODE_FILL)
{
GLfloat mrd = (ctx->DrawBuffer ?
ctx->DrawBuffer->_MRD :
1.0);
- raster.offset_units = ctx->Polygon.OffsetFactor * mrd;
- raster.offset_scale = (ctx->Polygon.OffsetUnits * mrd *
+ raster->offset_units = ctx->Polygon.OffsetFactor * mrd;
+ raster->offset_scale = (ctx->Polygon.OffsetUnits * mrd *
st->polygon_offset_scale);
}
/* _NEW_POINT
*/
- raster.point_size = ctx->Point.Size;
- raster.point_smooth = ctx->Point.SmoothFlag;
- raster.point_sprite = ctx->Point.PointSprite;
+ raster->point_size = ctx->Point.Size;
+ raster->point_smooth = ctx->Point.SmoothFlag;
+ raster->point_sprite = ctx->Point.PointSprite;
for (i = 0; i < MAX_TEXTURE_COORD_UNITS; i++) {
if (ctx->Point.CoordReplace[i]) {
if (ctx->Point.SpriteOrigin == GL_UPPER_LEFT)
- raster.sprite_coord_mode[i] = PIPE_SPRITE_COORD_UPPER_LEFT;
+ raster->sprite_coord_mode[i] = PIPE_SPRITE_COORD_UPPER_LEFT;
else
- raster.sprite_coord_mode[i] = PIPE_SPRITE_COORD_LOWER_LEFT;
+ raster->sprite_coord_mode[i] = PIPE_SPRITE_COORD_LOWER_LEFT;
}
else {
- raster.sprite_coord_mode[i] = PIPE_SPRITE_COORD_NONE;
+ raster->sprite_coord_mode[i] = PIPE_SPRITE_COORD_NONE;
}
}
if (vertProg) {
if (vertProg->Base.Id == 0) {
if (vertProg->Base.OutputsWritten & (1 << VERT_RESULT_PSIZ)) {
/* generated program which emits point size */
- raster.point_size_per_vertex = TRUE;
+ raster->point_size_per_vertex = TRUE;
}
}
else if (ctx->VertexProgram.PointSizeEnabled) {
/* user-defined program and GL_VERTEX_PROGRAM_POINT_SIZE set */
- raster.point_size_per_vertex = ctx->VertexProgram.PointSizeEnabled;
+ raster->point_size_per_vertex = ctx->VertexProgram.PointSizeEnabled;
}
}
/* _NEW_LINE
*/
- raster.line_smooth = ctx->Line.SmoothFlag;
+ raster->line_smooth = ctx->Line.SmoothFlag;
if (ctx->Line.SmoothFlag) {
- raster.line_width = CLAMP(ctx->Line.Width,
+ raster->line_width = CLAMP(ctx->Line.Width,
ctx->Const.MinLineWidthAA,
ctx->Const.MaxLineWidthAA);
}
else {
- raster.line_width = CLAMP(ctx->Line.Width,
+ raster->line_width = CLAMP(ctx->Line.Width,
ctx->Const.MinLineWidth,
ctx->Const.MaxLineWidth);
}
- raster.line_stipple_enable = ctx->Line.StippleFlag;
- raster.line_stipple_pattern = ctx->Line.StipplePattern;
+ raster->line_stipple_enable = ctx->Line.StippleFlag;
+ raster->line_stipple_pattern = ctx->Line.StipplePattern;
/* GL stipple factor is in [1,256], remap to [0, 255] here */
- raster.line_stipple_factor = ctx->Line.StippleFactor - 1;
+ raster->line_stipple_factor = ctx->Line.StippleFactor - 1;
/* _NEW_MULTISAMPLE */
if (ctx->Multisample.Enabled)
- raster.multisample = 1;
+ raster->multisample = 1;
/* _NEW_SCISSOR */
if (ctx->Scissor.Enabled)
- raster.scissor = 1;
+ raster->scissor = 1;
- cso = st_cached_rasterizer_state(st, &raster);
- if (st->state.rasterizer != cso) {
- st->state.rasterizer = cso;
- st->pipe->bind_rasterizer_state(st->pipe, cso->data);
- }
+ cso_set_rasterizer(st->cso_context, raster);
}
const struct st_tracked_state st_update_rasterizer = {
diff --git a/src/mesa/state_tracker/st_atom_sampler.c b/src/mesa/state_tracker/st_atom_sampler.c
index 92263cb688..5787a7492c 100644
--- a/src/mesa/state_tracker/st_atom_sampler.c
+++ b/src/mesa/state_tracker/st_atom_sampler.c
@@ -33,11 +33,11 @@
#include "st_context.h"
-#include "st_cache.h"
#include "st_atom.h"
#include "st_program.h"
#include "pipe/p_context.h"
#include "pipe/p_defines.h"
+#include "cso_cache/cso_context.h"
/**
@@ -120,12 +120,13 @@ update_samplers(struct st_context *st)
const struct st_fragment_program *fs = st->fp;
GLuint su;
+ st->state.num_samplers = 0;
+
/* loop over sampler units (aka tex image units) */
for (su = 0; su < st->ctx->Const.MaxTextureImageUnits; su++) {
- struct pipe_sampler_state sampler;
- const struct cso_sampler *cso;
+ struct pipe_sampler_state *sampler = st->state.samplers + su;
- memset(&sampler, 0, sizeof(sampler));
+ memset(sampler, 0, sizeof(*sampler));
if (fs->Base.Base.SamplersUsed & (1 << su)) {
GLuint texUnit = fs->Base.Base.SamplerUnits[su];
@@ -134,51 +135,56 @@ update_samplers(struct st_context *st)
assert(texobj);
- sampler.wrap_s = gl_wrap_to_sp(texobj->WrapS);
- sampler.wrap_t = gl_wrap_to_sp(texobj->WrapT);
- sampler.wrap_r = gl_wrap_to_sp(texobj->WrapR);
+ sampler->wrap_s = gl_wrap_to_sp(texobj->WrapS);
+ sampler->wrap_t = gl_wrap_to_sp(texobj->WrapT);
+ sampler->wrap_r = gl_wrap_to_sp(texobj->WrapR);
- sampler.min_img_filter = gl_filter_to_img_filter(texobj->MinFilter);
- sampler.min_mip_filter = gl_filter_to_mip_filter(texobj->MinFilter);
- sampler.mag_img_filter = gl_filter_to_img_filter(texobj->MagFilter);
+ sampler->min_img_filter = gl_filter_to_img_filter(texobj->MinFilter);
+ sampler->min_mip_filter = gl_filter_to_mip_filter(texobj->MinFilter);
+ sampler->mag_img_filter = gl_filter_to_img_filter(texobj->MagFilter);
if (texobj->Target != GL_TEXTURE_RECTANGLE_ARB)
- sampler.normalized_coords = 1;
+ sampler->normalized_coords = 1;
- sampler.lod_bias = st->ctx->Texture.Unit[su].LodBias;
+ sampler->lod_bias = st->ctx->Texture.Unit[su].LodBias;
#if 1
- sampler.min_lod = (texobj->MinLod) < 0.0 ? 0.0 : texobj->MinLod;
- sampler.max_lod = texobj->MaxLod;
+ sampler->min_lod = (texobj->MinLod) < 0.0 ? 0.0 : texobj->MinLod;
+ sampler->max_lod = texobj->MaxLod;
#else
/* min/max lod should really be as follows (untested).
* Also, calculate_first_last_level() needs to be overhauled
* since today's hardware had real support for LOD clamping.
*/
- sampler.min_lod = MAX2(texobj->BaseLevel, texobj->MinLod);
- sampler.max_lod = MIN2(texobj->MaxLevel, texobj->MaxLod);
+ sampler->min_lod = MAX2(texobj->BaseLevel, texobj->MinLod);
+ sampler->max_lod = MIN2(texobj->MaxLevel, texobj->MaxLod);
#endif
- sampler.max_anisotropy = texobj->MaxAnisotropy;
+ sampler->max_anisotropy = texobj->MaxAnisotropy;
+ if (sampler->max_anisotropy > 1.0) {
+ sampler->min_img_filter = PIPE_TEX_FILTER_ANISO;
+ sampler->mag_img_filter = PIPE_TEX_FILTER_ANISO;
+ }
/* only care about ARB_shadow, not SGI shadow */
if (texobj->CompareMode == GL_COMPARE_R_TO_TEXTURE) {
- sampler.compare = 1;
- sampler.compare_mode = PIPE_TEX_COMPARE_R_TO_TEXTURE;
- sampler.compare_func
+ sampler->compare = 1;
+ sampler->compare_mode = PIPE_TEX_COMPARE_R_TO_TEXTURE;
+ sampler->compare_func
= st_compare_func_to_pipe(texobj->CompareFunc);
}
- /* XXX more sampler state here */
- }
+ st->state.num_samplers = su + 1;
- cso = st_cached_sampler_state(st, &sampler);
+ /* XXX more sampler state here */
- if (cso != st->state.sampler[su]) {
- /* state has changed */
- st->state.sampler[su] = cso;
- st->pipe->bind_sampler_state(st->pipe, su, cso->data);
+ cso_single_sampler(st->cso_context, su, sampler);
+ }
+ else {
+ cso_single_sampler(st->cso_context, su, NULL);
}
}
+
+ cso_single_sampler_done(st->cso_context);
}
diff --git a/src/mesa/state_tracker/st_atom_shader.c b/src/mesa/state_tracker/st_atom_shader.c
index 10c131d554..0726688493 100644
--- a/src/mesa/state_tracker/st_atom_shader.c
+++ b/src/mesa/state_tracker/st_atom_shader.c
@@ -43,10 +43,9 @@
#include "pipe/p_context.h"
#include "pipe/p_shader_tokens.h"
-#include "cso_cache/cso_cache.h"
+#include "cso_cache/cso_context.h"
#include "st_context.h"
-#include "st_cache.h"
#include "st_atom.h"
#include "st_program.h"
#include "st_atom_shader.h"
@@ -70,9 +69,6 @@ struct translated_vertex_program
/** Maps VERT_RESULT_x to slot */
GLuint output_to_slot[VERT_RESULT_MAX];
- /** The program in TGSI format */
- struct tgsi_token tokens[ST_MAX_SHADER_TOKENS];
-
/** Pointer to the translated vertex program */
struct st_vertex_program *vp;
@@ -158,7 +154,7 @@ find_translated_vp(struct st_context *st,
/*
* Translate fragment program if needed.
*/
- if (!stfp->cso) {
+ if (!stfp->state.tokens) {
GLuint inAttr, numIn = 0;
for (inAttr = 0; inAttr < FRAG_ATTRIB_MAX; inAttr++) {
@@ -175,11 +171,7 @@ find_translated_vp(struct st_context *st,
assert(stfp->Base.Base.NumInstructions > 1);
- (void) st_translate_fragment_program(st, stfp,
- stfp->input_to_slot,
- stfp->tokens,
- ST_MAX_SHADER_TOKENS);
- assert(stfp->cso);
+ st_translate_fragment_program(st, stfp, stfp->input_to_slot);
}
@@ -261,12 +253,8 @@ find_translated_vp(struct st_context *st,
assert(stvp->Base.Base.NumInstructions > 1);
- st_translate_vertex_program(st, stvp,
- xvp->output_to_slot,
- xvp->tokens,
- ST_MAX_SHADER_TOKENS);
+ st_translate_vertex_program(st, stvp, xvp->output_to_slot);
- assert(stvp->cso);
xvp->vp = stvp;
/* translated VP is up to date now */
@@ -296,12 +284,10 @@ update_linkage( struct st_context *st )
xvp = find_translated_vp(st, stvp, stfp);
st->vp = stvp;
- st->state.vs = xvp->vp;
- st->pipe->bind_vs_state(st->pipe, st->state.vs->cso->data);
-
st->fp = stfp;
- st->state.fs = stfp->cso;
- st->pipe->bind_fs_state(st->pipe, st->state.fs->data);
+
+ st->pipe->bind_vs_state(st->pipe, stvp->driver_shader);
+ st->pipe->bind_fs_state(st->pipe, stfp->driver_shader);
st->vertex_result_to_slot = xvp->output_to_slot;
}
diff --git a/src/mesa/state_tracker/st_atom_texture.c b/src/mesa/state_tracker/st_atom_texture.c
index 697d2cdfb4..e53a897637 100644
--- a/src/mesa/state_tracker/st_atom_texture.c
+++ b/src/mesa/state_tracker/st_atom_texture.c
@@ -37,6 +37,7 @@
#include "st_texture.h"
#include "st_cb_texture.h"
#include "pipe/p_context.h"
+#include "pipe/p_inlines.h"
/**
@@ -51,6 +52,8 @@ update_textures(struct st_context *st)
struct gl_fragment_program *fprog = st->ctx->FragmentProgram._Current;
GLuint unit;
+ st->state.num_textures = 0;
+
for (unit = 0; unit < st->ctx->Const.MaxTextureCoordUnits; unit++) {
const GLuint su = fprog->Base.SamplerUnits[unit];
struct gl_texture_object *texObj = st->ctx->Texture.Unit[su]._Current;
@@ -62,6 +65,8 @@ update_textures(struct st_context *st)
retval = st_finalize_texture(st->ctx, st->pipe, texObj, &flush);
/* XXX retval indicates whether there's a texture border */
+
+ st->state.num_textures = unit + 1;
}
/* XXX: need to ensure that textures are unbound/removed from
@@ -70,18 +75,16 @@ update_textures(struct st_context *st)
*/
pt = st_get_stobj_texture(stObj);
-
- if (st->state.sampler_texture[unit] != pt) {
- st->state.sampler_texture[unit] = pt;
- st->pipe->set_sampler_texture(st->pipe, unit, pt);
- }
+ pipe_texture_reference(&st->state.sampler_texture[unit], pt);
if (stObj && stObj->dirtyData) {
st->pipe->texture_update(st->pipe, pt);
stObj->dirtyData = GL_FALSE;
}
-
}
+
+ st->pipe->set_sampler_textures(st->pipe, st->state.num_textures,
+ st->state.sampler_texture);
}
diff --git a/src/mesa/state_tracker/st_cb_accum.c b/src/mesa/state_tracker/st_cb_accum.c
index 663c4f205d..f1fddc4e02 100644
--- a/src/mesa/state_tracker/st_cb_accum.c
+++ b/src/mesa/state_tracker/st_cb_accum.c
@@ -35,7 +35,6 @@
#include "main/macros.h"
#include "st_context.h"
-#include "st_cache.h"
#include "st_cb_accum.h"
#include "st_cb_fbo.h"
#include "st_draw.h"
diff --git a/src/mesa/state_tracker/st_cb_clear.c b/src/mesa/state_tracker/st_cb_clear.c
index e712fd84cd..cc8a136292 100644
--- a/src/mesa/state_tracker/st_cb_clear.c
+++ b/src/mesa/state_tracker/st_cb_clear.c
@@ -35,7 +35,6 @@
#include "main/macros.h"
#include "shader/prog_instruction.h"
#include "st_atom.h"
-#include "st_cache.h"
#include "st_context.h"
#include "st_cb_accum.h"
#include "st_cb_clear.h"
@@ -50,6 +49,8 @@
#include "pipe/p_defines.h"
#include "pipe/p_winsys.h"
+#include "cso_cache/cso_context.h"
+
@@ -157,8 +158,7 @@ make_frag_shader(struct st_context *st)
p->OutputsWritten = (1 << FRAG_RESULT_COLR);
stfp = (struct st_fragment_program *) p;
- st_translate_fragment_program(st, stfp, NULL,
- stfp->tokens, ST_MAX_SHADER_TOKENS);
+ st_translate_fragment_program(st, stfp, NULL);
return stfp;
}
@@ -206,9 +206,10 @@ make_vertex_shader(struct st_context *st)
(1 << VERT_RESULT_HPOS));
stvp = (struct st_vertex_program *) p;
- st_translate_vertex_program(st, stvp, NULL,
- stvp->tokens, ST_MAX_SHADER_TOKENS);
+ st_translate_vertex_program(st, stvp, NULL);
+#if 0
assert(stvp->cso);
+#endif
return stvp;
}
@@ -284,7 +285,6 @@ clear_with_quad(GLcontext *ctx,
/* blend state: RGBA masking */
{
struct pipe_blend_state blend;
- const struct cso_blend *cso;
memset(&blend, 0, sizeof(blend));
if (color) {
if (ctx->Color.ColorMask[0])
@@ -298,14 +298,12 @@ clear_with_quad(GLcontext *ctx,
if (st->ctx->Color.DitherFlag)
blend.dither = 1;
}
- cso = st_cached_blend_state(st, &blend);
- pipe->bind_blend_state(pipe, cso->data);
+ cso_set_blend(st->cso_context, &blend);
}
/* depth_stencil state: always pass/set to ref value */
{
struct pipe_depth_stencil_alpha_state depth_stencil;
- const struct cso_depth_stencil_alpha *cso;
memset(&depth_stencil, 0, sizeof(depth_stencil));
if (depth) {
depth_stencil.depth.enabled = 1;
@@ -323,14 +321,13 @@ clear_with_quad(GLcontext *ctx,
depth_stencil.stencil[0].value_mask = 0xff;
depth_stencil.stencil[0].write_mask = ctx->Stencil.WriteMask[0] & 0xff;
}
- cso = st_cached_depth_stencil_alpha_state(st, &depth_stencil);
- pipe->bind_depth_stencil_alpha_state(pipe, cso->data);
+
+ cso_set_depth_stencil_alpha(st->cso_context, &depth_stencil);
}
/* rasterizer state: nothing */
{
struct pipe_rasterizer_state raster;
- const struct cso_rasterizer *cso;
memset(&raster, 0, sizeof(raster));
#if 0
/* don't do per-pixel scissor; we'll just draw a PIPE_PRIM_QUAD
@@ -339,8 +336,7 @@ clear_with_quad(GLcontext *ctx,
if (ctx->Scissor.Enabled)
raster.scissor = 1;
#endif
- cso = st_cached_rasterizer_state(st, &raster);
- pipe->bind_rasterizer_state(pipe, cso->data);
+ cso_set_rasterizer(st->cso_context, &raster);
}
/* fragment shader state: color pass-through program */
@@ -349,7 +345,7 @@ clear_with_quad(GLcontext *ctx,
if (!stfp) {
stfp = make_frag_shader(st);
}
- pipe->bind_fs_state(pipe, stfp->cso->data);
+ pipe->bind_fs_state(pipe, stfp->driver_shader);
}
/* vertex shader state: color/position pass-through */
@@ -358,7 +354,7 @@ clear_with_quad(GLcontext *ctx,
if (!stvp) {
stvp = make_vertex_shader(st);
}
- pipe->bind_vs_state(pipe, stvp->cso->data);
+ pipe->bind_vs_state(pipe, stvp->driver_shader);
}
/* viewport state: viewport matching window dims */
@@ -380,16 +376,19 @@ clear_with_quad(GLcontext *ctx,
/* draw quad matching scissor rect (XXX verify coord round-off) */
draw_quad(ctx, x0, y0, x1, y1, ctx->Depth.Clear, ctx->Color.ClearColor);
+#if 0
+ /* Can't depend on old state objects still existing -- may have
+ * been deleted to make room in the hash, etc. (Should get
+ * fixed...)
+ */
+ st_invalidate_state(ctx, _NEW_COLOR | _NEW_DEPTH | _NEW_STENCIL);
+#else
/* Restore pipe state */
- pipe->bind_blend_state(pipe, st->state.blend->data);
- pipe->bind_depth_stencil_alpha_state(pipe, st->state.depth_stencil->data);
- pipe->bind_fs_state(pipe, st->state.fs->data);
- pipe->bind_vs_state(pipe, st->state.vs->cso->data);
- pipe->bind_rasterizer_state(pipe, st->state.rasterizer->data);
+ cso_set_rasterizer(st->cso_context, &st->state.rasterizer);
+ pipe->bind_fs_state(pipe, st->fp->driver_shader);
+ pipe->bind_vs_state(pipe, st->vp->driver_shader);
+#endif
pipe->set_viewport_state(pipe, &st->state.viewport);
- /* OR:
- st_invalidate_state(ctx, _NEW_COLOR | _NEW_DEPTH | _NEW_STENCIL);
- */
}
@@ -545,6 +544,15 @@ clear_stencil_buffer(GLcontext *ctx, struct gl_renderbuffer *rb)
/* simple clear of whole buffer */
GLuint clearValue = ctx->Stencil.Clear;
+
+ switch (strb->surface->format) {
+ case PIPE_FORMAT_S8Z24_UNORM:
+ clearValue <<= 24;
+ break;
+ default:
+ ; /* no-op, stencil value is in least significant bits */
+ }
+
ctx->st->pipe->clear(ctx->st->pipe, strb->surface, clearValue);
}
}
diff --git a/src/mesa/state_tracker/st_cb_drawpixels.c b/src/mesa/state_tracker/st_cb_drawpixels.c
index 65c9fda9cb..18ec9645c4 100644
--- a/src/mesa/state_tracker/st_cb_drawpixels.c
+++ b/src/mesa/state_tracker/st_cb_drawpixels.c
@@ -41,7 +41,6 @@
#include "st_context.h"
#include "st_atom.h"
#include "st_atom_constbuf.h"
-#include "st_cache.h"
#include "st_draw.h"
#include "st_program.h"
#include "st_cb_drawpixels.h"
@@ -58,6 +57,7 @@
#include "pipe/p_winsys.h"
#include "util/p_tile.h"
#include "shader/prog_instruction.h"
+#include "cso_cache/cso_context.h"
/**
@@ -159,8 +159,7 @@ make_bitmap_fragment_program(GLcontext *ctx)
stfp = (struct st_fragment_program *) p;
stfp->Base.UsesKill = GL_TRUE;
- st_translate_fragment_program(ctx->st, stfp, NULL,
- stfp->tokens, ST_MAX_SHADER_TOKENS);
+ st_translate_fragment_program(ctx->st, stfp, NULL);
return stfp;
}
@@ -204,8 +203,7 @@ combined_bitmap_fragment_program(GLcontext *ctx)
#endif
/* translate to TGSI tokens */
- st_translate_fragment_program(st, stfp, NULL,
- stfp->tokens, ST_MAX_SHADER_TOKENS);
+ st_translate_fragment_program(st, stfp, NULL);
/* save new program, update serial numbers */
st->bitmap.user_prog_sn = st->fp->serialNo;
@@ -266,8 +264,7 @@ combined_drawpix_fragment_program(GLcontext *ctx)
#endif
/* translate to TGSI tokens */
- st_translate_fragment_program(st, stfp, NULL,
- stfp->tokens, ST_MAX_SHADER_TOKENS);
+ st_translate_fragment_program(st, stfp, NULL);
/* save new program, update serial numbers */
st->pixel_xfer.xfer_prog_sn = st->pixel_xfer.program->serialNo;
@@ -343,8 +340,7 @@ make_fragment_shader_z(struct st_context *st)
p->OutputsWritten = (1 << FRAG_RESULT_COLR) | (1 << FRAG_RESULT_DEPR);
stfp = (struct st_fragment_program *) p;
- st_translate_fragment_program(st, stfp, NULL,
- stfp->tokens, ST_MAX_SHADER_TOKENS);
+ st_translate_fragment_program(st, stfp, NULL);
return stfp;
}
@@ -421,8 +417,7 @@ st_make_passthrough_vertex_shader(struct st_context *st, GLboolean passColor)
}
stvp = (struct st_vertex_program *) p;
- st_translate_vertex_program(st, stvp, NULL,
- stvp->tokens, ST_MAX_SHADER_TOKENS);
+ st_translate_vertex_program(st, stvp, NULL);
progs[passColor] = stvp;
@@ -641,8 +636,9 @@ draw_textured_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z,
const GLfloat *color,
GLboolean invertTex)
{
- const GLuint unit = 0;
+ struct st_context *st = ctx->st;
struct pipe_context *pipe = ctx->st->pipe;
+ struct cso_context *cso = ctx->st->cso_context;
GLfloat x0, y0, x1, y1;
GLuint maxSize;
@@ -657,24 +653,23 @@ draw_textured_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z,
/* setup state: just scissor */
{
struct pipe_rasterizer_state setup;
- const struct cso_rasterizer *cso;
memset(&setup, 0, sizeof(setup));
if (ctx->Scissor.Enabled)
setup.scissor = 1;
- cso = st_cached_rasterizer_state(ctx->st, &setup);
- pipe->bind_rasterizer_state(pipe, cso->data);
+
+ cso_set_rasterizer(cso, &setup);
}
/* fragment shader state: TEX lookup program */
- pipe->bind_fs_state(pipe, stfp->cso->data);
+ pipe->bind_fs_state(pipe, stfp->driver_shader);
/* vertex shader state: position + texcoord pass-through */
- pipe->bind_vs_state(pipe, stvp->cso->data);
+ pipe->bind_vs_state(pipe, stvp->driver_shader);
+
/* texture sampling state: */
{
struct pipe_sampler_state sampler;
- const struct cso_sampler *cso;
memset(&sampler, 0, sizeof(sampler));
sampler.wrap_s = PIPE_TEX_WRAP_CLAMP;
sampler.wrap_t = PIPE_TEX_WRAP_CLAMP;
@@ -683,8 +678,9 @@ draw_textured_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z,
sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NONE;
sampler.mag_img_filter = PIPE_TEX_FILTER_NEAREST;
sampler.normalized_coords = 1;
- cso = st_cached_sampler_state(ctx->st, &sampler);
- pipe->bind_sampler_state(pipe, unit, cso->data);
+
+ cso_single_sampler(cso, 0, &sampler);
+ cso_single_sampler_done(cso);
}
/* viewport state: viewport matching window dims */
@@ -705,7 +701,7 @@ draw_textured_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z,
/* texture state: */
{
- pipe->set_sampler_texture(pipe, unit, pt);
+ pipe->set_sampler_textures(pipe, 1, &pt);
}
/* Compute window coords (y=0=bottom) with pixel zoom.
@@ -724,12 +720,25 @@ draw_textured_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z,
draw_quad(ctx, x0, y0, z, x1, y1, invertTex);
/* restore GL state */
- pipe->bind_rasterizer_state(pipe, ctx->st->state.rasterizer->data);
- pipe->bind_fs_state(pipe, ctx->st->state.fs->data);
- pipe->bind_vs_state(pipe, ctx->st->state.vs->cso->data);
- pipe->set_sampler_texture(pipe, unit, ctx->st->state.sampler_texture[unit]);
- pipe->bind_sampler_state(pipe, unit, ctx->st->state.sampler[unit]->data);
+ pipe->set_sampler_textures(pipe, ctx->st->state.num_textures,
+ ctx->st->state.sampler_texture);
+
pipe->set_viewport_state(pipe, &ctx->st->state.viewport);
+
+#if 0
+ /* Can't depend on old state objects still existing -- may have
+ * been deleted to make room in the hash, etc. (Should get
+ * fixed...)
+ */
+ st_invalidate_state(ctx, _NEW_COLOR | _NEW_TEXTURE);
+#else
+ /* restore state */
+ pipe->bind_fs_state(pipe, st->fp->driver_shader);
+ pipe->bind_vs_state(pipe, st->vp->driver_shader);
+ cso_set_rasterizer(cso, &st->state.rasterizer);
+ cso_set_samplers(cso, PIPE_MAX_SAMPLERS,
+ (const struct pipe_sampler_state **) st->state.sampler_list);
+#endif
}
@@ -797,10 +806,10 @@ compatible_formats(GLenum format, GLenum type, enum pipe_format pipeFormat)
static GLboolean
any_fragment_ops(const struct st_context *st)
{
- if (st->state.depth_stencil->state.alpha.enabled ||
- st->state.blend->state.blend_enable ||
- st->state.blend->state.logicop_enable ||
- st->state.depth_stencil->state.depth.enabled)
+ if (st->state.depth_stencil.alpha.enabled ||
+ st->state.depth_stencil.depth.enabled ||
+ st->state.blend.blend_enable ||
+ st->state.blend.logicop_enable)
/* XXX more checks */
return GL_TRUE;
else
diff --git a/src/mesa/state_tracker/st_cb_program.c b/src/mesa/state_tracker/st_cb_program.c
index 61d4f4c41c..4dc76f19b1 100644
--- a/src/mesa/state_tracker/st_cb_program.c
+++ b/src/mesa/state_tracker/st_cb_program.c
@@ -168,11 +168,13 @@ static void st_program_string_notify( GLcontext *ctx,
stfp->serialNo++;
+#if 0
if (stfp->cso) {
/* free the TGSI code */
// cso_delete(stfp->vs);
stfp->cso = NULL;
}
+#endif
stfp->param_state = stfp->Base.Base.Parameters->StateFlags;
@@ -184,13 +186,14 @@ static void st_program_string_notify( GLcontext *ctx,
stvp->serialNo++;
+#if 0
if (stvp->cso) {
/* free the CSO data */
st->pipe->delete_vs_state(st->pipe, stvp->cso->data);
FREE((void *) stvp->cso);
stvp->cso = NULL;
}
-
+#endif
if (stvp->draw_shader) {
draw_delete_vertex_shader(st->draw, stvp->draw_shader);
stvp->draw_shader = NULL;
diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c
index 1ba3173312..d4731c7737 100644
--- a/src/mesa/state_tracker/st_cb_texture.c
+++ b/src/mesa/state_tracker/st_cb_texture.c
@@ -529,7 +529,8 @@ st_TexImage(GLcontext * ctx,
texImage->RowStride = postConvWidth;
}
- assert(texImage->RowStride == postConvWidth);
+ /* we'll set RowStride elsewhere when the texture is a "mapped" state */
+ /*assert(texImage->RowStride == postConvWidth);*/
}
/* Release the reference to a potentially orphaned buffer.
diff --git a/src/mesa/state_tracker/st_context.c b/src/mesa/state_tracker/st_context.c
index 09e389f9dc..5458ab420e 100644
--- a/src/mesa/state_tracker/st_context.c
+++ b/src/mesa/state_tracker/st_context.c
@@ -56,6 +56,7 @@
#include "pipe/p_inlines.h"
#include "draw/draw_context.h"
#include "cso_cache/cso_cache.h"
+#include "cso_cache/cso_context.h"
/**
@@ -78,6 +79,7 @@ void st_invalidate_state(GLcontext * ctx, GLuint new_state)
static struct st_context *
st_create_context_priv( GLcontext *ctx, struct pipe_context *pipe )
{
+ uint i;
struct st_context *st = CALLOC_STRUCT( st_context );
ctx->st = st;
@@ -93,12 +95,15 @@ st_create_context_priv( GLcontext *ctx, struct pipe_context *pipe )
st->dirty.mesa = ~0;
st->dirty.st = ~0;
- st->cache = cso_cache_create();
+ st->cso_context = cso_create_context(pipe);
st_init_atoms( st );
st_init_draw( st );
st_init_generate_mipmap(st);
+ for (i = 0; i < PIPE_MAX_SAMPLERS; i++)
+ st->state.sampler_list[i] = &st->state.samplers[i];
+
/* we want all vertex data to be placed in buffer objects */
vbo_use_buffer_objects(ctx);
@@ -149,7 +154,7 @@ static void st_destroy_context_priv( struct st_context *st )
_vbo_DestroyContext(st->ctx);
- cso_cache_delete( st->cache );
+ cso_destroy_context(st->cso_context);
_mesa_delete_program_cache(st->ctx, st->pixel_xfer.cache);
diff --git a/src/mesa/state_tracker/st_context.h b/src/mesa/state_tracker/st_context.h
index 1fbf9721e7..e81aebba3d 100644
--- a/src/mesa/state_tracker/st_context.h
+++ b/src/mesa/state_tracker/st_context.h
@@ -74,14 +74,11 @@ struct st_context
* Other state is just parameter values.
*/
struct {
- const struct cso_alpha_test *alpha_test;
- const struct cso_blend *blend;
- const struct cso_sampler *sampler[PIPE_MAX_SAMPLERS];
- const struct cso_depth_stencil_alpha *depth_stencil;
- const struct cso_rasterizer *rasterizer;
- const struct cso_fragment_shader *fs;
- struct st_vertex_program *vs;
-
+ struct pipe_blend_state blend;
+ struct pipe_depth_stencil_alpha_state depth_stencil;
+ struct pipe_rasterizer_state rasterizer;
+ struct pipe_sampler_state samplers[PIPE_MAX_SAMPLERS];
+ struct pipe_sampler_state *sampler_list[PIPE_MAX_SAMPLERS];
struct pipe_blend_color blend_color;
struct pipe_clip_state clip;
struct pipe_constant_buffer constants[2];
@@ -90,6 +87,9 @@ struct st_context
struct pipe_poly_stipple poly_stipple;
struct pipe_scissor_state scissor;
struct pipe_viewport_state viewport;
+
+ GLuint num_samplers;
+ GLuint num_textures;
} state;
struct {
@@ -148,6 +148,10 @@ struct st_context
/** For gen/render mipmap feature */
struct {
+ struct pipe_blend_state blend;
+ struct pipe_depth_stencil_alpha_state depthstencil;
+ struct pipe_rasterizer_state rasterizer;
+
void *blend_cso;
void *depthstencil_cso;
void *rasterizer_cso;
@@ -155,7 +159,7 @@ struct st_context
struct st_vertex_program *stvp;
} gen_mipmap;
- struct cso_cache *cache;
+ struct cso_context *cso_context;
};
diff --git a/src/mesa/state_tracker/st_debug.c b/src/mesa/state_tracker/st_debug.c
index 5888bcb98a..9c13010da8 100644
--- a/src/mesa/state_tracker/st_debug.c
+++ b/src/mesa/state_tracker/st_debug.c
@@ -53,15 +53,15 @@ st_print_current(void)
int i;
printf("Vertex Transform Inputs:\n");
- for (i = 0; i < st->state.vs->cso->state.num_inputs; i++) {
+ for (i = 0; i < st->vp->state.num_inputs; i++) {
printf(" Slot %d: VERT_ATTRIB_%d\n", i, st->vp->index_to_input[i]);
}
- tgsi_dump( st->state.vs->cso->state.tokens, 0 );
+ tgsi_dump( st->vp->state.tokens, 0 );
if (st->vp->Base.Base.Parameters)
_mesa_print_parameter_list(st->vp->Base.Base.Parameters);
- tgsi_dump( st->state.fs->state.tokens, 0 );
+ tgsi_dump( st->fp->state.tokens, 0 );
if (st->fp->Base.Base.Parameters)
_mesa_print_parameter_list(st->fp->Base.Base.Parameters);
}
diff --git a/src/mesa/state_tracker/st_draw.c b/src/mesa/state_tracker/st_draw.c
index 1c0fa8c6aa..98504e46c1 100644
--- a/src/mesa/state_tracker/st_draw.c
+++ b/src/mesa/state_tracker/st_draw.c
@@ -36,7 +36,6 @@
#include "vbo/vbo.h"
#include "st_atom.h"
-#include "st_cache.h"
#include "st_context.h"
#include "st_cb_bufferobjects.h"
#include "st_draw.h"
@@ -219,7 +218,7 @@ st_draw_vbo(GLcontext *ctx,
/* must get these after state validation! */
vp = ctx->st->vp;
- vs = &ctx->st->state.vs->cso->state;
+ vs = &ctx->st->vp->state;
/* loop over TGSI shader inputs to determine vertex buffer
* and attribute info
@@ -481,10 +480,10 @@ st_feedback_draw_vbo(GLcontext *ctx,
/* must get these after state validation! */
vp = ctx->st->vp;
- vs = &ctx->st->state.vs->cso->state;
+ vs = &st->vp->state;
- if (!st->state.vs->draw_shader) {
- st->state.vs->draw_shader = draw_create_vertex_shader(draw, vs);
+ if (!st->vp->draw_shader) {
+ st->vp->draw_shader = draw_create_vertex_shader(draw, vs);
}
/*
@@ -496,8 +495,8 @@ st_feedback_draw_vbo(GLcontext *ctx,
assert(draw);
draw_set_viewport_state(draw, &st->state.viewport);
draw_set_clip_state(draw, &st->state.clip);
- draw_set_rasterizer_state(draw, &st->state.rasterizer->state);
- draw_bind_vertex_shader(draw, st->state.vs->draw_shader);
+ draw_set_rasterizer_state(draw, &st->state.rasterizer);
+ draw_bind_vertex_shader(draw, st->vp->draw_shader);
set_feedback_vertex_format(ctx);
/* loop over TGSI shader inputs to determine vertex buffer
diff --git a/src/mesa/state_tracker/st_gen_mipmap.c b/src/mesa/state_tracker/st_gen_mipmap.c
index 841d77abbc..9c4e1032ef 100644
--- a/src/mesa/state_tracker/st_gen_mipmap.c
+++ b/src/mesa/state_tracker/st_gen_mipmap.c
@@ -38,6 +38,7 @@
#include "pipe/p_inlines.h"
#include "pipe/p_winsys.h"
#include "cso_cache/cso_cache.h"
+#include "cso_cache/cso_context.h"
#include "st_context.h"
#include "st_draw.h"
@@ -89,8 +90,7 @@ make_tex_fragment_program(GLcontext *ctx)
stfp = (struct st_fragment_program *) p;
- st_translate_fragment_program(ctx->st, stfp, NULL,
- stfp->tokens, ST_MAX_SHADER_TOKENS);
+ st_translate_fragment_program(ctx->st, stfp, NULL);
return stfp;
}
@@ -118,6 +118,7 @@ st_init_generate_mipmap(struct st_context *st)
blend.rgb_dst_factor = PIPE_BLENDFACTOR_ZERO;
blend.alpha_dst_factor = PIPE_BLENDFACTOR_ZERO;
blend.colormask = PIPE_MASK_RGBA;
+ st->gen_mipmap.blend = blend;
st->gen_mipmap.blend_cso = pipe->create_blend_state(pipe, &blend);
memset(&depthstencil, 0, sizeof(depthstencil));
@@ -257,14 +258,14 @@ st_render_mipmap(struct st_context *st,
sampler.normalized_coords = 1;
- /* bind CSOs */
- pipe->bind_blend_state(pipe, st->gen_mipmap.blend_cso);
- pipe->bind_depth_stencil_alpha_state(pipe, st->gen_mipmap.depthstencil_cso);
- pipe->bind_rasterizer_state(pipe, st->gen_mipmap.rasterizer_cso);
+ /* bind state */
+ cso_set_blend(st->cso_context, &st->gen_mipmap.blend);
+ cso_set_depth_stencil_alpha(st->cso_context, &st->gen_mipmap.depthstencil);
+ cso_set_rasterizer(st->cso_context, &st->gen_mipmap.rasterizer);
/* bind shaders */
- pipe->bind_fs_state(pipe, st->gen_mipmap.stfp->cso->data);
- pipe->bind_vs_state(pipe, st->gen_mipmap.stvp->cso->data);
+ pipe->bind_fs_state(pipe, st->gen_mipmap.stfp->driver_shader);
+ pipe->bind_vs_state(pipe, st->gen_mipmap.stvp->driver_shader);
/*
* XXX for small mipmap levels, it may be faster to use the software
@@ -284,7 +285,7 @@ st_render_mipmap(struct st_context *st,
*/
sampler.min_lod = sampler.max_lod = srcLevel;
sampler_cso = pipe->create_sampler_state(pipe, &sampler);
- pipe->bind_sampler_state(pipe, 0, sampler_cso);
+ pipe->bind_sampler_states(pipe, 1, &sampler_cso);
simple_viewport(pipe, pt->width[dstLevel], pt->height[dstLevel]);
@@ -293,7 +294,7 @@ st_render_mipmap(struct st_context *st,
* the right mipmap level.
*/
/*pt->first_level = srcLevel;*/
- pipe->set_sampler_texture(pipe, 0, pt);
+ pipe->set_sampler_textures(pipe, 1, &pt);
draw_quad(st->ctx);
@@ -304,16 +305,18 @@ st_render_mipmap(struct st_context *st,
/*pt->first_level = first_level_save;*/
/* restore pipe state */
- if (st->state.rasterizer)
- pipe->bind_rasterizer_state(pipe, st->state.rasterizer->data);
- if (st->state.fs)
- pipe->bind_fs_state(pipe, st->state.fs->data);
- if (st->state.vs)
- pipe->bind_vs_state(pipe, st->state.vs->cso->data);
- if (st->state.sampler[0])
- pipe->bind_sampler_state(pipe, 0, st->state.sampler[0]->data);
- pipe->set_sampler_texture(pipe, 0, st->state.sampler_texture[0]);
+#if 0
+ cso_set_rasterizer(st->cso_context, &st->state.rasterizer);
+ cso_set_samplers(st->cso_context, st->state.samplers_list);
+ pipe->bind_fs_state(pipe, st->fp->shader_program);
+ pipe->bind_vs_state(pipe, st->vp->shader_program);
+ pipe->set_sampler_textures(pipe, st->state.num_textures,
+ st->state.sampler_texture);
pipe->set_viewport_state(pipe, &st->state.viewport);
+#else
+ /* XXX is this sufficient? */
+ st_invalidate_state(st->ctx, _NEW_COLOR | _NEW_TEXTURE);
+#endif
return TRUE;
}
diff --git a/src/mesa/state_tracker/st_mesa_to_tgsi.c b/src/mesa/state_tracker/st_mesa_to_tgsi.c
index 97206752af..f3cfda0bfb 100644
--- a/src/mesa/state_tracker/st_mesa_to_tgsi.c
+++ b/src/mesa/state_tracker/st_mesa_to_tgsi.c
@@ -513,10 +513,9 @@ compile_instruction(
case OPCODE_TXP:
/* texture lookup with divide by Q component */
/* convert to TEX w/ special flag for division */
- fullinst->Instruction.Opcode = TGSI_OPCODE_TEX;
+ fullinst->Instruction.Opcode = TGSI_OPCODE_TXP;
fullinst->Instruction.NumSrcRegs = 2;
fullinst->InstructionExtTexture.Texture = map_texture_target( inst->TexSrcTarget );
- fullinst->FullSrcRegisters[0].SrcRegisterExtSwz.ExtDivide = TGSI_EXTSWIZZLE_W;
fullinst->FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_SAMPLER;
fullinst->FullSrcRegisters[1].SrcRegister.Index = inst->TexSrcUnit;
break;
@@ -683,8 +682,9 @@ find_temporaries(const struct gl_program *program,
* \param tokens array to store translated tokens in
* \param maxTokens size of the tokens array
*
+ * \return number of tokens placed in 'tokens' buffer, or zero if error
*/
-GLboolean
+GLuint
tgsi_translate_mesa_program(
uint procType,
const struct gl_program *program,
@@ -918,6 +918,6 @@ tgsi_translate_mesa_program(
maxTokens - ti );
}
- return GL_TRUE;
+ return ti;
}
diff --git a/src/mesa/state_tracker/st_mesa_to_tgsi.h b/src/mesa/state_tracker/st_mesa_to_tgsi.h
index 3ababf1339..63fc855b53 100644
--- a/src/mesa/state_tracker/st_mesa_to_tgsi.h
+++ b/src/mesa/state_tracker/st_mesa_to_tgsi.h
@@ -39,7 +39,7 @@ extern "C" {
struct tgsi_token;
struct gl_program;
-GLboolean
+GLuint
tgsi_translate_mesa_program(
uint procType,
const struct gl_program *program,
diff --git a/src/mesa/state_tracker/st_program.c b/src/mesa/state_tracker/st_program.c
index aa252c845a..0f8784e132 100644
--- a/src/mesa/state_tracker/st_program.c
+++ b/src/mesa/state_tracker/st_program.c
@@ -42,15 +42,29 @@
#include "tgsi/util/tgsi_dump.h"
#include "st_context.h"
-#include "st_cache.h"
#include "st_atom.h"
#include "st_program.h"
#include "st_mesa_to_tgsi.h"
+#include "cso_cache/cso_context.h"
#define TGSI_DEBUG 0
+/** XXX we should use the version of this from p_util.h but including
+ * that header causes symbol collisions.
+ */
+static INLINE void *
+mem_dup(const void *src, uint size)
+{
+ void *dup = MALLOC(size);
+ if (dup)
+ memcpy(dup, src, size);
+ return dup;
+}
+
+
+
/**
* Translate a Mesa vertex shader into a TGSI shader.
* \param outputMapping to map vertex program output registers to TGSI
@@ -61,15 +75,15 @@
void
st_translate_vertex_program(struct st_context *st,
struct st_vertex_program *stvp,
- const GLuint outputMapping[],
- struct tgsi_token *tokensOut,
- GLuint maxTokens)
+ const GLuint outputMapping[])
{
+ struct pipe_context *pipe = st->pipe;
+ struct tgsi_token tokens[ST_MAX_SHADER_TOKENS];
GLuint defaultOutputMapping[VERT_RESULT_MAX];
struct pipe_shader_state vs;
- const struct cso_vertex_shader *cso;
GLuint attr, i;
GLuint num_generic = 0;
+ GLuint num_tokens;
memset(&vs, 0, sizeof(vs));
@@ -240,7 +254,7 @@ st_translate_vertex_program(struct st_context *st,
/* XXX: fix static allocation of tokens:
*/
- tgsi_translate_mesa_program( TGSI_PROCESSOR_VERTEX,
+ num_tokens = tgsi_translate_mesa_program( TGSI_PROCESSOR_VERTEX,
&stvp->Base.Base,
/* inputs */
vs.num_inputs,
@@ -252,20 +266,21 @@ st_translate_vertex_program(struct st_context *st,
vs.num_outputs,
outputMapping,
vs.output_semantic_name,
- vs.output_semantic_index,
+ vs.output_semantic_index,
/* tokenized result */
- tokensOut, maxTokens);
+ tokens, ST_MAX_SHADER_TOKENS);
- vs.tokens = tokensOut;
+ vs.tokens = (struct tgsi_token *)
+ mem_dup(tokens, num_tokens * sizeof(tokens[0]));
- cso = st_cached_vs_state(st, &vs);
- stvp->cso = cso;
+ stvp->state = vs; /* struct copy */
+ stvp->driver_shader = pipe->create_vs_state(pipe, &vs);
if (0)
_mesa_print_program(&stvp->Base.Base);
if (TGSI_DEBUG)
- tgsi_dump( tokensOut, 0 );
+ tgsi_dump( vs.tokens, 0 );
}
@@ -280,10 +295,10 @@ st_translate_vertex_program(struct st_context *st,
const struct cso_fragment_shader *
st_translate_fragment_program(struct st_context *st,
struct st_fragment_program *stfp,
- const GLuint inputMapping[],
- struct tgsi_token *tokensOut,
- GLuint maxTokens)
+ const GLuint inputMapping[])
{
+ struct pipe_context *pipe = st->pipe;
+ struct tgsi_token tokens[ST_MAX_SHADER_TOKENS];
GLuint outputMapping[FRAG_RESULT_MAX];
GLuint defaultInputMapping[FRAG_ATTRIB_MAX];
struct pipe_shader_state fs;
@@ -293,6 +308,7 @@ st_translate_fragment_program(struct st_context *st,
const GLbitfield inputsRead = stfp->Base.Base.InputsRead;
GLuint vslot = 0;
GLuint num_generic = 0;
+ GLuint num_tokens;
memset(&fs, 0, sizeof(fs));
@@ -401,7 +417,7 @@ st_translate_fragment_program(struct st_context *st,
/* XXX: fix static allocation of tokens:
*/
- tgsi_translate_mesa_program( TGSI_PROCESSOR_FRAGMENT,
+ num_tokens = tgsi_translate_mesa_program( TGSI_PROCESSOR_FRAGMENT,
&stfp->Base.Base,
/* inputs */
fs.num_inputs,
@@ -415,18 +431,19 @@ st_translate_fragment_program(struct st_context *st,
fs.output_semantic_name,
fs.output_semantic_index,
/* tokenized result */
- tokensOut, maxTokens);
+ tokens, ST_MAX_SHADER_TOKENS);
- fs.tokens = tokensOut;
+ fs.tokens = (struct tgsi_token *)
+ mem_dup(tokens, num_tokens * sizeof(tokens[0]));
- cso = st_cached_fs_state(st, &fs);
- stfp->cso = cso;
+ stfp->state = fs; /* struct copy */
+ stfp->driver_shader = pipe->create_fs_state(pipe, &fs);
if (0)
_mesa_print_program(&stfp->Base.Base);
if (TGSI_DEBUG)
- tgsi_dump( tokensOut, 0/*TGSI_DUMP_VERBOSE*/ );
+ tgsi_dump( fs.tokens, 0/*TGSI_DUMP_VERBOSE*/ );
return cso;
}
diff --git a/src/mesa/state_tracker/st_program.h b/src/mesa/state_tracker/st_program.h
index 31558af6ce..78786dcbb6 100644
--- a/src/mesa/state_tracker/st_program.h
+++ b/src/mesa/state_tracker/st_program.h
@@ -60,11 +60,8 @@ struct st_fragment_program
/** map FP input back to VP output */
GLuint input_map[PIPE_MAX_SHADER_INPUTS];
- /** The program in TGSI format */
- struct tgsi_token tokens[ST_MAX_SHADER_TOKENS];
-
- /** Pointer to the corresponding cached shader */
- const struct cso_fragment_shader *cso;
+ struct pipe_shader_state state;
+ struct pipe_shader_state *driver_shader;
GLuint param_state;
@@ -88,11 +85,8 @@ struct st_vertex_program
/** maps a TGSI input index back to a Mesa VERT_ATTRIB_x */
GLuint index_to_input[PIPE_MAX_SHADER_INPUTS];
- /** The program in TGSI format */
- struct tgsi_token tokens[ST_MAX_SHADER_TOKENS];
-
- /** Pointer to the corresponding cached shader */
- const struct cso_vertex_shader *cso;
+ struct pipe_shader_state state;
+ struct pipe_shader_state *driver_shader;
/** For using our private draw module (glRasterPos) */
struct draw_vertex_shader *draw_shader;
@@ -122,16 +116,12 @@ st_vertex_program( struct gl_vertex_program *vp )
extern const struct cso_fragment_shader *
st_translate_fragment_program(struct st_context *st,
struct st_fragment_program *fp,
- const GLuint inputMapping[],
- struct tgsi_token *tokens,
- GLuint maxTokens);
+ const GLuint inputMapping[]);
extern void
st_translate_vertex_program(struct st_context *st,
struct st_vertex_program *vp,
- const GLuint vert_output_to_slot[],
- struct tgsi_token *tokens,
- GLuint maxTokens);
+ const GLuint vert_output_to_slot[]);
#endif
diff --git a/src/mesa/vbo/vbo_exec_api.c b/src/mesa/vbo/vbo_exec_api.c
index b7f4d8a307..35dc0e768f 100644
--- a/src/mesa/vbo/vbo_exec_api.c
+++ b/src/mesa/vbo/vbo_exec_api.c
@@ -309,16 +309,23 @@ static void vbo_exec_fixup_vertex( GLcontext *ctx,
GLuint attr, GLuint sz )
{
struct vbo_exec_context *exec = &vbo_context(ctx)->exec;
+ static const GLfloat id[4] = { 0, 0, 0, 1 };
int i;
- if (sz > exec->vtx.attrsz[attr]) {
+ if (exec->vtx.prim_count == 0) {
+ GLfloat *current = (GLfloat *)vbo_context(ctx)->currval[attr].Ptr;
+ exec->vtx.attrptr[attr] = current;
+ memcpy(current, id, sizeof(id));
+ ctx->Driver.NeedFlush |= FLUSH_UPDATE_CURRENT;
+ return;
+ }
+ else if (sz > exec->vtx.attrsz[attr]) {
/* New size is larger. Need to flush existing vertices and get
* an enlarged vertex format.
*/
vbo_exec_wrap_upgrade_vertex( exec, attr, sz );
}
else if (sz < exec->vtx.active_sz[attr]) {
- static const GLfloat id[4] = { 0, 0, 0, 1 };
/* New size is smaller - just need to fill in some
* zeros. Don't need to flush or wrap.