diff options
Diffstat (limited to 'src/mesa/state_tracker')
-rw-r--r-- | src/mesa/state_tracker/st_atom_blend.c | 61 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_atom_clip.c | 7 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_atom_pixeltransfer.c | 2 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_atom_sampler.c | 152 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_atom_scissor.c | 17 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_atom_stipple.c | 11 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_atom_texture.c | 30 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_cb_drawpixels.c | 10 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_cb_texture.c | 7 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_cb_viewport.c | 15 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_context.h | 6 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_draw.c | 82 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_format.c | 122 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_format.h | 3 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_manager.c | 163 |
15 files changed, 423 insertions, 265 deletions
diff --git a/src/mesa/state_tracker/st_atom_blend.c b/src/mesa/state_tracker/st_atom_blend.c index d1844e1066f..4c9a2b95ac3 100644 --- a/src/mesa/state_tracker/st_atom_blend.c +++ b/src/mesa/state_tracker/st_atom_blend.c @@ -156,7 +156,7 @@ translate_logicop(GLenum logicop) * Figure out if colormasks are different per rt. */ static GLboolean -colormask_per_rt(struct gl_context *ctx) +colormask_per_rt(const struct gl_context *ctx) { /* a bit suboptimal have to compare lots of values */ unsigned i; @@ -172,7 +172,7 @@ colormask_per_rt(struct gl_context *ctx) * Figure out if blend enables/state are different per rt. */ static GLboolean -blend_per_rt(struct gl_context *ctx) +blend_per_rt(const struct gl_context *ctx) { if (ctx->Color.BlendEnabled && (ctx->Color.BlendEnabled != ((1 << ctx->Const.MaxDrawBuffers) - 1))) { @@ -190,13 +190,14 @@ static void update_blend( struct st_context *st ) { struct pipe_blend_state *blend = &st->state.blend; + const struct gl_context *ctx = st->ctx; unsigned num_state = 1; unsigned i, j; memset(blend, 0, sizeof(*blend)); - if (blend_per_rt(st->ctx) || colormask_per_rt(st->ctx)) { - num_state = st->ctx->Const.MaxDrawBuffers; + if (blend_per_rt(ctx) || colormask_per_rt(ctx)) { + num_state = ctx->Const.MaxDrawBuffers; blend->independent_blend_enable = 1; } /* Note it is impossible to correctly deal with EXT_blend_logic_op and @@ -205,52 +206,52 @@ update_blend( struct st_context *st ) and separate alpha/rgb logicop/blend support respectively. Neither possible in gallium nor most hardware. Assume these combinations don't happen. */ - if (st->ctx->Color.ColorLogicOpEnabled || - (st->ctx->Color.BlendEnabled && - st->ctx->Color.Blend[0].EquationRGB == GL_LOGIC_OP)) { + if (ctx->Color.ColorLogicOpEnabled || + (ctx->Color.BlendEnabled && + ctx->Color.Blend[0].EquationRGB == GL_LOGIC_OP)) { /* logicop enabled */ blend->logicop_enable = 1; - blend->logicop_func = translate_logicop(st->ctx->Color.LogicOp); + blend->logicop_func = translate_logicop(ctx->Color.LogicOp); } - else if (st->ctx->Color.BlendEnabled) { + else if (ctx->Color.BlendEnabled) { /* blending enabled */ for (i = 0, j = 0; i < num_state; i++) { - blend->rt[i].blend_enable = (st->ctx->Color.BlendEnabled >> i) & 0x1; + blend->rt[i].blend_enable = (ctx->Color.BlendEnabled >> i) & 0x1; - if (st->ctx->Extensions.ARB_draw_buffers_blend) + if (ctx->Extensions.ARB_draw_buffers_blend) j = i; blend->rt[i].rgb_func = - translate_blend(st->ctx->Color.Blend[j].EquationRGB); + translate_blend(ctx->Color.Blend[j].EquationRGB); - if (st->ctx->Color.Blend[i].EquationRGB == GL_MIN || - st->ctx->Color.Blend[i].EquationRGB == GL_MAX) { + if (ctx->Color.Blend[i].EquationRGB == GL_MIN || + ctx->Color.Blend[i].EquationRGB == GL_MAX) { /* Min/max are special */ blend->rt[i].rgb_src_factor = PIPE_BLENDFACTOR_ONE; blend->rt[i].rgb_dst_factor = PIPE_BLENDFACTOR_ONE; } else { blend->rt[i].rgb_src_factor = - translate_blend(st->ctx->Color.Blend[j].SrcRGB); + translate_blend(ctx->Color.Blend[j].SrcRGB); blend->rt[i].rgb_dst_factor = - translate_blend(st->ctx->Color.Blend[j].DstRGB); + translate_blend(ctx->Color.Blend[j].DstRGB); } blend->rt[i].alpha_func = - translate_blend(st->ctx->Color.Blend[j].EquationA); + translate_blend(ctx->Color.Blend[j].EquationA); - if (st->ctx->Color.Blend[i].EquationA == GL_MIN || - st->ctx->Color.Blend[i].EquationA == GL_MAX) { + if (ctx->Color.Blend[i].EquationA == GL_MIN || + ctx->Color.Blend[i].EquationA == GL_MAX) { /* Min/max are special */ blend->rt[i].alpha_src_factor = PIPE_BLENDFACTOR_ONE; blend->rt[i].alpha_dst_factor = PIPE_BLENDFACTOR_ONE; } else { blend->rt[i].alpha_src_factor = - translate_blend(st->ctx->Color.Blend[j].SrcA); + translate_blend(ctx->Color.Blend[j].SrcA); blend->rt[i].alpha_dst_factor = - translate_blend(st->ctx->Color.Blend[j].DstA); + translate_blend(ctx->Color.Blend[j].DstA); } } } @@ -260,25 +261,25 @@ update_blend( struct st_context *st ) /* Colormask - maybe reverse these bits? */ for (i = 0; i < num_state; i++) { - if (st->ctx->Color.ColorMask[i][0]) + if (ctx->Color.ColorMask[i][0]) blend->rt[i].colormask |= PIPE_MASK_R; - if (st->ctx->Color.ColorMask[i][1]) + if (ctx->Color.ColorMask[i][1]) blend->rt[i].colormask |= PIPE_MASK_G; - if (st->ctx->Color.ColorMask[i][2]) + if (ctx->Color.ColorMask[i][2]) blend->rt[i].colormask |= PIPE_MASK_B; - if (st->ctx->Color.ColorMask[i][3]) + if (ctx->Color.ColorMask[i][3]) blend->rt[i].colormask |= PIPE_MASK_A; } - if (st->ctx->Color.DitherFlag) + if (ctx->Color.DitherFlag) blend->dither = 1; - if (st->ctx->Multisample.Enabled) { + if (ctx->Multisample.Enabled) { /* unlike in gallium/d3d10 these operations are only performed if msaa is enabled */ - if (st->ctx->Multisample.SampleAlphaToCoverage) + if (ctx->Multisample.SampleAlphaToCoverage) blend->alpha_to_coverage = 1; - if (st->ctx->Multisample.SampleAlphaToOne) + if (ctx->Multisample.SampleAlphaToOne) blend->alpha_to_one = 1; } @@ -286,7 +287,7 @@ update_blend( struct st_context *st ) { struct pipe_blend_color bc; - COPY_4FV(bc.color, st->ctx->Color.BlendColorUnclamped); + COPY_4FV(bc.color, ctx->Color.BlendColorUnclamped); cso_set_blend_color(st->cso_context, &bc); } } diff --git a/src/mesa/state_tracker/st_atom_clip.c b/src/mesa/state_tracker/st_atom_clip.c index 16f7aaae6f4..1330db843a6 100644 --- a/src/mesa/state_tracker/st_atom_clip.c +++ b/src/mesa/state_tracker/st_atom_clip.c @@ -43,20 +43,21 @@ static void update_clip( struct st_context *st ) { struct pipe_clip_state clip; + const struct gl_context *ctx = st->ctx; GLuint i; memset(&clip, 0, sizeof(clip)); for (i = 0; i < PIPE_MAX_CLIP_PLANES; i++) { - if (st->ctx->Transform.ClipPlanesEnabled & (1 << i)) { + if (ctx->Transform.ClipPlanesEnabled & (1 << i)) { memcpy(clip.ucp[clip.nr], - st->ctx->Transform._ClipUserPlane[i], + ctx->Transform._ClipUserPlane[i], sizeof(clip.ucp[0])); clip.nr++; } } - clip.depth_clamp = st->ctx->Transform.DepthClamp != GL_FALSE; + clip.depth_clamp = ctx->Transform.DepthClamp != GL_FALSE; if (memcmp(&clip, &st->state.clip, sizeof(clip)) != 0) { st->state.clip = clip; diff --git a/src/mesa/state_tracker/st_atom_pixeltransfer.c b/src/mesa/state_tracker/st_atom_pixeltransfer.c index 95b706cb96c..1f833d28212 100644 --- a/src/mesa/state_tracker/st_atom_pixeltransfer.c +++ b/src/mesa/state_tracker/st_atom_pixeltransfer.c @@ -94,7 +94,7 @@ create_color_map_texture(struct gl_context *ctx) const uint texSize = 256; /* simple, and usually perfect */ /* find an RGBA texture format */ - format = st_choose_format(pipe->screen, GL_RGBA, + format = st_choose_format(pipe->screen, GL_RGBA, GL_NONE, GL_NONE, PIPE_TEXTURE_2D, 0, PIPE_BIND_SAMPLER_VIEW); /* create texture for color map/table */ diff --git a/src/mesa/state_tracker/st_atom_sampler.c b/src/mesa/state_tracker/st_atom_sampler.c index 06024ad2657..731338f9beb 100644 --- a/src/mesa/state_tracker/st_atom_sampler.c +++ b/src/mesa/state_tracker/st_atom_sampler.c @@ -120,87 +120,91 @@ gl_filter_to_img_filter(GLenum filter) } } -static void convert_sampler(struct st_context *st, - struct pipe_sampler_state *sampler, - GLuint texUnit) + +static void +convert_sampler(struct st_context *st, + struct pipe_sampler_state *sampler, + GLuint texUnit) { - struct gl_texture_object *texobj; - struct gl_sampler_object *msamp; - - texobj = st->ctx->Texture.Unit[texUnit]._Current; - if (!texobj) { - texobj = st_get_default_texture(st); - } - - msamp = _mesa_get_samplerobj(st->ctx, texUnit); - - memset(sampler, 0, sizeof(*sampler)); - sampler->wrap_s = gl_wrap_xlate(msamp->WrapS); - sampler->wrap_t = gl_wrap_xlate(msamp->WrapT); - sampler->wrap_r = gl_wrap_xlate(msamp->WrapR); - - sampler->min_img_filter = gl_filter_to_img_filter(msamp->MinFilter); - sampler->min_mip_filter = gl_filter_to_mip_filter(msamp->MinFilter); - sampler->mag_img_filter = gl_filter_to_img_filter(msamp->MagFilter); - - if (texobj->Target != GL_TEXTURE_RECTANGLE_ARB) - sampler->normalized_coords = 1; - - sampler->lod_bias = st->ctx->Texture.Unit[texUnit].LodBias + - msamp->LodBias; - - sampler->min_lod = CLAMP(msamp->MinLod, - 0.0f, - (GLfloat) texobj->MaxLevel - texobj->BaseLevel); - sampler->max_lod = MIN2((GLfloat) texobj->MaxLevel - texobj->BaseLevel, - msamp->MaxLod); - if (sampler->max_lod < sampler->min_lod) { - /* The GL spec doesn't seem to specify what to do in this case. - * Swap the values. - */ - float tmp = sampler->max_lod; - sampler->max_lod = sampler->min_lod; - sampler->min_lod = tmp; - assert(sampler->min_lod <= sampler->max_lod); - } - - if (msamp->BorderColor.ui[0] || - msamp->BorderColor.ui[1] || - msamp->BorderColor.ui[2] || - msamp->BorderColor.ui[3]) { - struct gl_texture_image *teximg; - - teximg = texobj->Image[0][texobj->BaseLevel]; - - st_translate_color(msamp->BorderColor.f, - teximg ? teximg->_BaseFormat : GL_RGBA, - sampler->border_color); - } - - sampler->max_anisotropy = (msamp->MaxAnisotropy == 1.0 ? - 0 : (GLuint) msamp->MaxAnisotropy); - - /* only care about ARB_shadow, not SGI shadow */ - if (msamp->CompareMode == GL_COMPARE_R_TO_TEXTURE) { - sampler->compare_mode = PIPE_TEX_COMPARE_R_TO_TEXTURE; - sampler->compare_func - = st_compare_func_to_pipe(msamp->CompareFunc); - } - - sampler->seamless_cube_map = - st->ctx->Texture.CubeMapSeamless || msamp->CubeMapSeamless; + struct gl_texture_object *texobj; + struct gl_context *ctx = st->ctx; + struct gl_sampler_object *msamp; + + texobj = ctx->Texture.Unit[texUnit]._Current; + if (!texobj) { + texobj = st_get_default_texture(st); + } + + msamp = _mesa_get_samplerobj(ctx, texUnit); + + memset(sampler, 0, sizeof(*sampler)); + sampler->wrap_s = gl_wrap_xlate(msamp->WrapS); + sampler->wrap_t = gl_wrap_xlate(msamp->WrapT); + sampler->wrap_r = gl_wrap_xlate(msamp->WrapR); + + sampler->min_img_filter = gl_filter_to_img_filter(msamp->MinFilter); + sampler->min_mip_filter = gl_filter_to_mip_filter(msamp->MinFilter); + sampler->mag_img_filter = gl_filter_to_img_filter(msamp->MagFilter); + + if (texobj->Target != GL_TEXTURE_RECTANGLE_ARB) + sampler->normalized_coords = 1; + + sampler->lod_bias = ctx->Texture.Unit[texUnit].LodBias + msamp->LodBias; + + sampler->min_lod = CLAMP(msamp->MinLod, + 0.0f, + (GLfloat) texobj->MaxLevel - texobj->BaseLevel); + sampler->max_lod = MIN2((GLfloat) texobj->MaxLevel - texobj->BaseLevel, + msamp->MaxLod); + if (sampler->max_lod < sampler->min_lod) { + /* The GL spec doesn't seem to specify what to do in this case. + * Swap the values. + */ + float tmp = sampler->max_lod; + sampler->max_lod = sampler->min_lod; + sampler->min_lod = tmp; + assert(sampler->min_lod <= sampler->max_lod); + } + + if (msamp->BorderColor.ui[0] || + msamp->BorderColor.ui[1] || + msamp->BorderColor.ui[2] || + msamp->BorderColor.ui[3]) { + struct gl_texture_image *teximg; + + teximg = texobj->Image[0][texobj->BaseLevel]; + + st_translate_color(msamp->BorderColor.f, + teximg ? teximg->_BaseFormat : GL_RGBA, + sampler->border_color); + } + + sampler->max_anisotropy = (msamp->MaxAnisotropy == 1.0 ? + 0 : (GLuint) msamp->MaxAnisotropy); + + /* only care about ARB_shadow, not SGI shadow */ + if (msamp->CompareMode == GL_COMPARE_R_TO_TEXTURE) { + sampler->compare_mode = PIPE_TEX_COMPARE_R_TO_TEXTURE; + sampler->compare_func + = st_compare_func_to_pipe(msamp->CompareFunc); + } + + sampler->seamless_cube_map = + ctx->Texture.CubeMapSeamless || msamp->CubeMapSeamless; } + static void update_vertex_samplers(struct st_context *st) { - struct gl_vertex_program *vprog = st->ctx->VertexProgram._Current; + const struct gl_context *ctx = st->ctx; + struct gl_vertex_program *vprog = ctx->VertexProgram._Current; GLuint su; st->state.num_vertex_samplers = 0; /* loop over sampler units (aka tex image units) */ - for (su = 0; su < st->ctx->Const.MaxVertexTextureImageUnits; su++) { + for (su = 0; su < ctx->Const.MaxVertexTextureImageUnits; su++) { struct pipe_sampler_state *sampler = st->state.vertex_samplers + su; if (vprog->Base.SamplersUsed & (1 << su)) { @@ -220,16 +224,18 @@ update_vertex_samplers(struct st_context *st) cso_single_vertex_sampler_done(st->cso_context); } + static void update_fragment_samplers(struct st_context *st) { - struct gl_fragment_program *fprog = st->ctx->FragmentProgram._Current; + const struct gl_context *ctx = st->ctx; + struct gl_fragment_program *fprog = ctx->FragmentProgram._Current; GLuint su; st->state.num_samplers = 0; /* loop over sampler units (aka tex image units) */ - for (su = 0; su < st->ctx->Const.MaxTextureImageUnits; su++) { + for (su = 0; su < ctx->Const.MaxTextureImageUnits; su++) { struct pipe_sampler_state *sampler = st->state.samplers + su; @@ -254,6 +260,7 @@ update_fragment_samplers(struct st_context *st) cso_single_sampler_done(st->cso_context); } + static void update_samplers(struct st_context *st) { @@ -261,6 +268,7 @@ update_samplers(struct st_context *st) update_vertex_samplers(st); } + const struct st_tracked_state st_update_sampler = { "st_update_sampler", /* name */ { /* dirty */ diff --git a/src/mesa/state_tracker/st_atom_scissor.c b/src/mesa/state_tracker/st_atom_scissor.c index 56b1383ae39..eb13877787b 100644 --- a/src/mesa/state_tracker/st_atom_scissor.c +++ b/src/mesa/state_tracker/st_atom_scissor.c @@ -44,7 +44,8 @@ static void update_scissor( struct st_context *st ) { struct pipe_scissor_state scissor; - const struct gl_framebuffer *fb = st->ctx->DrawBuffer; + const struct gl_context *ctx = st->ctx; + const struct gl_framebuffer *fb = ctx->DrawBuffer; GLint miny, maxy; scissor.minx = 0; @@ -52,15 +53,15 @@ update_scissor( struct st_context *st ) scissor.maxx = fb->Width; scissor.maxy = fb->Height; - if (st->ctx->Scissor.Enabled) { + if (ctx->Scissor.Enabled) { /* need to be careful here with xmax or ymax < 0 */ - GLint xmax = MAX2(0, st->ctx->Scissor.X + st->ctx->Scissor.Width); - GLint ymax = MAX2(0, st->ctx->Scissor.Y + st->ctx->Scissor.Height); + GLint xmax = MAX2(0, ctx->Scissor.X + ctx->Scissor.Width); + GLint ymax = MAX2(0, ctx->Scissor.Y + ctx->Scissor.Height); - if (st->ctx->Scissor.X > (GLint)scissor.minx) - scissor.minx = st->ctx->Scissor.X; - if (st->ctx->Scissor.Y > (GLint)scissor.miny) - scissor.miny = st->ctx->Scissor.Y; + if (ctx->Scissor.X > (GLint)scissor.minx) + scissor.minx = ctx->Scissor.X; + if (ctx->Scissor.Y > (GLint)scissor.miny) + scissor.miny = ctx->Scissor.Y; if (xmax < (GLint) scissor.maxx) scissor.maxx = xmax; diff --git a/src/mesa/state_tracker/st_atom_stipple.c b/src/mesa/state_tracker/st_atom_stipple.c index ecdd9f06f6a..b3e0dc7f1b0 100644 --- a/src/mesa/state_tracker/st_atom_stipple.c +++ b/src/mesa/state_tracker/st_atom_stipple.c @@ -64,17 +64,18 @@ invert_stipple(GLuint dest[32], const GLuint src[32], GLuint winHeight) static void update_stipple( struct st_context *st ) { + const struct gl_context *ctx = st->ctx; const GLuint sz = sizeof(st->state.poly_stipple); - assert(sz == sizeof(st->ctx->PolygonStipple)); + assert(sz == sizeof(ctx->PolygonStipple)); - if (memcmp(st->state.poly_stipple, st->ctx->PolygonStipple, sz)) { + if (memcmp(st->state.poly_stipple, ctx->PolygonStipple, sz)) { /* state has changed */ struct pipe_poly_stipple newStipple; - memcpy(st->state.poly_stipple, st->ctx->PolygonStipple, sz); + memcpy(st->state.poly_stipple, ctx->PolygonStipple, sz); - invert_stipple(newStipple.stipple, st->ctx->PolygonStipple, - st->ctx->DrawBuffer->Height); + invert_stipple(newStipple.stipple, ctx->PolygonStipple, + ctx->DrawBuffer->Height); st->pipe->set_polygon_stipple(st->pipe, &newStipple); } diff --git a/src/mesa/state_tracker/st_atom_texture.c b/src/mesa/state_tracker/st_atom_texture.c index 072eb977ebb..800a9f1f0e0 100644 --- a/src/mesa/state_tracker/st_atom_texture.c +++ b/src/mesa/state_tracker/st_atom_texture.c @@ -187,15 +187,16 @@ update_single_texture(struct st_context *st, struct pipe_sampler_view **sampler_ GLuint texUnit) { struct pipe_context *pipe = st->pipe; + struct gl_context *ctx = st->ctx; const struct gl_sampler_object *samp; struct gl_texture_object *texObj; struct st_texture_object *stObj; enum pipe_format st_view_format; GLboolean retval; - samp = _mesa_get_samplerobj(st->ctx, texUnit); + samp = _mesa_get_samplerobj(ctx, texUnit); - texObj = st->ctx->Texture.Unit[texUnit]._Current; + texObj = ctx->Texture.Unit[texUnit]._Current; if (!texObj) { texObj = st_get_default_texture(st); @@ -203,7 +204,7 @@ update_single_texture(struct st_context *st, struct pipe_sampler_view **sampler_ } stObj = st_texture_object(texObj); - retval = st_finalize_texture(st->ctx, st->pipe, texObj); + retval = st_finalize_texture(ctx, st->pipe, texObj); if (!retval) { /* out of mem */ return GL_FALSE; @@ -253,13 +254,14 @@ update_single_texture(struct st_context *st, struct pipe_sampler_view **sampler_ static void update_vertex_textures(struct st_context *st) { - struct gl_vertex_program *vprog = st->ctx->VertexProgram._Current; + const struct gl_context *ctx = st->ctx; + struct gl_vertex_program *vprog = ctx->VertexProgram._Current; GLuint su; st->state.num_vertex_textures = 0; /* loop over sampler units (aka tex image units) */ - for (su = 0; su < st->ctx->Const.MaxTextureImageUnits; su++) { + for (su = 0; su < ctx->Const.MaxTextureImageUnits; su++) { struct pipe_sampler_view *sampler_view = NULL; if (vprog->Base.SamplersUsed & (1 << su)) { GLboolean retval; @@ -277,9 +279,9 @@ update_vertex_textures(struct st_context *st) pipe_sampler_view_reference(&st->state.sampler_vertex_views[su], sampler_view); } - if (st->ctx->Const.MaxVertexTextureImageUnits > 0) { + if (ctx->Const.MaxVertexTextureImageUnits > 0) { GLuint numUnits = MIN2(st->state.num_vertex_textures, - st->ctx->Const.MaxVertexTextureImageUnits); + ctx->Const.MaxVertexTextureImageUnits); cso_set_vertex_sampler_views(st->cso_context, numUnits, st->state.sampler_vertex_views); @@ -289,13 +291,14 @@ update_vertex_textures(struct st_context *st) static void update_fragment_textures(struct st_context *st) { - struct gl_fragment_program *fprog = st->ctx->FragmentProgram._Current; + const struct gl_context *ctx = st->ctx; + struct gl_fragment_program *fprog = ctx->FragmentProgram._Current; GLuint su; st->state.num_textures = 0; /* loop over sampler units (aka tex image units) */ - for (su = 0; su < st->ctx->Const.MaxTextureImageUnits; su++) { + for (su = 0; su < ctx->Const.MaxTextureImageUnits; su++) { struct pipe_sampler_view *sampler_view = NULL; if (fprog->Base.SamplersUsed & (1 << su)) { GLboolean retval; @@ -338,22 +341,23 @@ const struct st_tracked_state st_update_vertex_texture = { static void finalize_textures(struct st_context *st) { - struct gl_fragment_program *fprog = st->ctx->FragmentProgram._Current; + struct gl_context *ctx = st->ctx; + struct gl_fragment_program *fprog = ctx->FragmentProgram._Current; const GLboolean prev_missing_textures = st->missing_textures; GLuint su; st->missing_textures = GL_FALSE; - for (su = 0; su < st->ctx->Const.MaxTextureCoordUnits; su++) { + for (su = 0; su < ctx->Const.MaxTextureCoordUnits; su++) { if (fprog->Base.SamplersUsed & (1 << su)) { const GLuint texUnit = fprog->Base.SamplerUnits[su]; struct gl_texture_object *texObj - = st->ctx->Texture.Unit[texUnit]._Current; + = ctx->Texture.Unit[texUnit]._Current; if (texObj) { GLboolean retval; - retval = st_finalize_texture(st->ctx, st->pipe, texObj); + retval = st_finalize_texture(ctx, st->pipe, texObj); if (!retval) { /* out of mem */ st->missing_textures = GL_TRUE; diff --git a/src/mesa/state_tracker/st_cb_drawpixels.c b/src/mesa/state_tracker/st_cb_drawpixels.c index 965fbcd1d9e..d61d7ac22be 100644 --- a/src/mesa/state_tracker/st_cb_drawpixels.c +++ b/src/mesa/state_tracker/st_cb_drawpixels.c @@ -989,8 +989,9 @@ st_DrawPixels(struct gl_context *ctx, GLint x, GLint y, /* can we write to stencil if not fallback */ if (!pipe->screen->get_param(pipe->screen, PIPE_CAP_SHADER_STENCIL_EXPORT)) goto stencil_fallback; - + tex_format = st_choose_format(st->pipe->screen, base_format(format), + GL_NONE, GL_NONE, PIPE_TEXTURE_2D, 0, PIPE_BIND_SAMPLER_VIEW); if (tex_format == PIPE_FORMAT_Z24_UNORM_S8_USCALED) @@ -1399,13 +1400,14 @@ st_CopyPixels(struct gl_context *ctx, GLint srcx, GLint srcy, /* srcFormat can't be used as a texture format */ if (type == GL_DEPTH) { texFormat = st_choose_format(screen, GL_DEPTH_COMPONENT, - st->internal_target, sample_count, - PIPE_BIND_DEPTH_STENCIL); + GL_NONE, GL_NONE, st->internal_target, + sample_count, PIPE_BIND_DEPTH_STENCIL); assert(texFormat != PIPE_FORMAT_NONE); } else { /* default color format */ - texFormat = st_choose_format(screen, GL_RGBA, st->internal_target, + texFormat = st_choose_format(screen, GL_RGBA, + GL_NONE, GL_NONE, st->internal_target, sample_count, PIPE_BIND_SAMPLER_VIEW); assert(texFormat != PIPE_FORMAT_NONE); } diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c index 88f62902b25..6907cfc03cf 100644 --- a/src/mesa/state_tracker/st_cb_texture.c +++ b/src/mesa/state_tracker/st_cb_texture.c @@ -842,7 +842,7 @@ decompress_with_blit(struct gl_context * ctx, GLenum target, GLint level, else { /* format translation via floats */ GLuint row; - enum pipe_format format = util_format_linear(dst_texture->format); + enum pipe_format pformat = util_format_linear(dst_texture->format); for (row = 0; row < height; row++) { const GLbitfield transferOps = 0x0; /* bypassed for glGetTexImage() */ GLfloat rgba[4 * MAX_WIDTH]; @@ -854,7 +854,7 @@ decompress_with_blit(struct gl_context * ctx, GLenum target, GLint level, /* get float[4] rgba row from surface */ pipe_get_tile_rgba_format(pipe, tex_xfer, 0, row, width, 1, - format, rgba); + pformat, rgba); _mesa_pack_rgba_span_float(ctx, width, (GLfloat (*)[4]) rgba, format, type, dest, &ctx->Pack, transferOps); @@ -1241,7 +1241,8 @@ fallback_copy_texsubimage(struct gl_context *ctx, GLenum target, GLint level, src_trans = pipe_get_transfer(pipe, strb->texture, - 0, 0, + strb->rtt_level, + strb->rtt_face + strb->rtt_slice, PIPE_TRANSFER_READ, srcX, srcY, width, height); diff --git a/src/mesa/state_tracker/st_cb_viewport.c b/src/mesa/state_tracker/st_cb_viewport.c index 049755e45c0..d4742eb897d 100644 --- a/src/mesa/state_tracker/st_cb_viewport.c +++ b/src/mesa/state_tracker/st_cb_viewport.c @@ -56,13 +56,20 @@ static void st_viewport(struct gl_context * ctx, GLint x, GLint y, if (!st->invalidate_on_gl_viewport) return; + /* + * Normally we'd want the state tracker manager to mark the drawables + * invalid only when needed. This will force the state tracker manager + * to revalidate the drawable, rather than just update the context with + * the latest cached drawable info. + */ + stdraw = st_ws_framebuffer(st->ctx->DrawBuffer); stread = st_ws_framebuffer(st->ctx->ReadBuffer); - if (stdraw) - p_atomic_set(&stdraw->revalidate, TRUE); - if (stread && stread != stdraw) - p_atomic_set(&stread->revalidate, TRUE); + if (stdraw && stdraw->iface) + stdraw->iface_stamp = p_atomic_read(&stdraw->iface->stamp) - 1; + if (stread && stread != stdraw && stread->iface) + stread->iface_stamp = p_atomic_read(&stread->iface->stamp) - 1; } void st_init_viewport_functions(struct dd_function_table *functions) diff --git a/src/mesa/state_tracker/st_context.h b/src/mesa/state_tracker/st_context.h index ff207039d78..0a322022149 100644 --- a/src/mesa/state_tracker/st_context.h +++ b/src/mesa/state_tracker/st_context.h @@ -204,6 +204,9 @@ struct st_context /* Active render condition. */ struct pipe_query *render_condition; unsigned condition_mode; + + int32_t draw_stamp; + int32_t read_stamp; }; @@ -227,7 +230,8 @@ struct st_framebuffer struct st_framebuffer_iface *iface; enum st_attachment_type statts[ST_ATTACHMENT_COUNT]; unsigned num_statts; - int32_t revalidate; + int32_t stamp; + int32_t iface_stamp; }; diff --git a/src/mesa/state_tracker/st_draw.c b/src/mesa/state_tracker/st_draw.c index 56955d357b1..5040c6fa5ab 100644 --- a/src/mesa/state_tracker/st_draw.c +++ b/src/mesa/state_tracker/st_draw.c @@ -33,7 +33,7 @@ * * We basically convert the VBO's vertex attribute/array information into * Gallium vertex state, bind the vertex buffer objects and call - * pipe->draw_elements(), pipe->draw_range_elements() or pipe->draw_arrays(). + * pipe->draw_vbo(). * * Authors: * Keith Whitwell <[email protected]> @@ -233,11 +233,26 @@ st_pipe_vertex_format(GLenum type, GLuint size, GLenum format, } +/** + * This is very similar to vbo_all_varyings_in_vbos() but we test + * the stride. See bug 38626. + */ +static GLboolean +all_varyings_in_vbos(const struct gl_client_array *arrays[]) +{ + GLuint i; + + for (i = 0; i < VERT_ATTRIB_MAX; i++) + if (arrays[i]->StrideB && !_mesa_is_bufferobj(arrays[i]->BufferObj)) + return GL_FALSE; + + return GL_TRUE; +} + /** * Examine the active arrays to determine if we have interleaved * vertex arrays all living in one VBO, or all living in user space. - * \param userSpace returns whether the arrays are in user space. */ static GLboolean is_interleaved_arrays(const struct st_vertex_program *vp, @@ -247,8 +262,8 @@ is_interleaved_arrays(const struct st_vertex_program *vp, GLuint attr; const struct gl_buffer_object *firstBufObj = NULL; GLint firstStride = -1; - const GLubyte *client_addr = NULL; - GLboolean user_memory = GL_FALSE; + const GLubyte *firstPtr = NULL; + GLboolean userSpaceBuffer = GL_FALSE; for (attr = 0; attr < vpv->num_inputs; attr++) { const GLuint mesaAttr = vp->index_to_input[attr]; @@ -256,37 +271,26 @@ is_interleaved_arrays(const struct st_vertex_program *vp, const struct gl_buffer_object *bufObj = array->BufferObj; const GLsizei stride = array->StrideB; /* in bytes */ - if (firstStride < 0) { + if (attr == 0) { + /* save info about the first array */ firstStride = stride; - user_memory = !bufObj || !bufObj->Name; - } - else if (firstStride != stride) { - return GL_FALSE; - } - - if (!bufObj || !bufObj->Name) { - /* Try to detect if the client-space arrays are - * "close" to each other. - */ - if (!user_memory) { - return GL_FALSE; - } - if (!client_addr) { - client_addr = array->Ptr; - } - else if (abs(array->Ptr - client_addr) > firstStride) { - /* arrays start too far apart */ - return GL_FALSE; - } - } - else if (!firstBufObj) { - if (user_memory) { - return GL_FALSE; - } + firstPtr = array->Ptr; firstBufObj = bufObj; + userSpaceBuffer = !bufObj || !bufObj->Name; } - else if (bufObj != firstBufObj) { - return GL_FALSE; + else { + /* check if other arrays interleave with the first, in same buffer */ + if (stride != firstStride) + return GL_FALSE; /* strides don't match */ + + if (bufObj != firstBufObj) + return GL_FALSE; /* arrays in different VBOs */ + + if (abs(array->Ptr - firstPtr) > firstStride) + return GL_FALSE; /* arrays start too far apart */ + + if ((!bufObj || !_mesa_is_bufferobj(bufObj)) != userSpaceBuffer) + return GL_FALSE; /* mix of VBO and user-space arrays */ } } @@ -510,6 +514,7 @@ setup_index_buffer(struct gl_context *ctx, } } + /** * Prior to drawing, check that any uniforms referenced by the * current shader have been set. If a uniform has not been set, @@ -556,8 +561,8 @@ translate_prim(const struct gl_context *ctx, unsigned prim) assert(GL_TRIANGLE_STRIP_ADJACENCY == PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY); /* Avoid quadstrips if it's easy to do so: - * Note: it's imporant to do the correct trimming if we change the prim type! - * We do that wherever this function is called. + * Note: it's important to do the correct trimming if we change the + * prim type! We do that wherever this function is called. */ if (prim == GL_QUAD_STRIP && ctx->Light.ShadeModel != GL_FLAT && @@ -650,7 +655,8 @@ st_draw_vbo(struct gl_context *ctx, struct pipe_draw_info info; unsigned i, num_instances = 1; GLboolean new_array = - st->dirty.st && (st->dirty.mesa & (_NEW_ARRAY | _NEW_PROGRAM)) != 0; + st->dirty.st && + (st->dirty.mesa & (_NEW_ARRAY | _NEW_PROGRAM | _NEW_BUFFER_OBJECT)) != 0; /* Mesa core state should have been validated already */ assert(ctx->NewState == 0x0); @@ -658,7 +664,7 @@ st_draw_vbo(struct gl_context *ctx, if (ib) { /* Gallium probably doesn't want this in some cases. */ if (!index_bounds_valid) - if (!vbo_all_varyings_in_vbos(arrays)) + if (!all_varyings_in_vbos(arrays)) vbo_get_minmax_index(ctx, prims, ib, &min_index, &max_index); for (i = 0; i < nr_prims; i++) { @@ -738,8 +744,8 @@ st_draw_vbo(struct gl_context *ctx, } } - info.primitive_restart = st->ctx->Array.PrimitiveRestart; - info.restart_index = st->ctx->Array.RestartIndex; + info.primitive_restart = ctx->Array.PrimitiveRestart; + info.restart_index = ctx->Array.RestartIndex; /* do actual drawing */ for (i = 0; i < nr_prims; i++) { diff --git a/src/mesa/state_tracker/st_format.c b/src/mesa/state_tracker/st_format.c index 35835712547..fa5d8f5050a 100644 --- a/src/mesa/state_tracker/st_format.c +++ b/src/mesa/state_tracker/st_format.c @@ -608,7 +608,7 @@ struct format_mapping * Multiple GL enums might map to multiple pipe_formats. * The first pipe format in the list that's supported is the one that's chosen. */ -static struct format_mapping format_map[] = { +static const struct format_mapping format_map[] = { /* Basic RGB, RGBA formats */ { { GL_RGB10, GL_RGB10_A2, 0 }, @@ -616,7 +616,7 @@ static struct format_mapping format_map[] = { }, { { 4, GL_RGBA, GL_RGBA8, 0 }, - { DEFAULT_RGBA_FORMATS, 0 } + { PIPE_FORMAT_R8G8B8A8_UNORM, DEFAULT_RGBA_FORMATS } }, { { GL_BGRA, 0 }, @@ -624,7 +624,7 @@ static struct format_mapping format_map[] = { }, { { 3, GL_RGB, GL_RGB8, 0 }, - { DEFAULT_RGB_FORMATS, 0 } + { DEFAULT_RGB_FORMATS } }, { { GL_RGB12, GL_RGB16, GL_RGBA12, GL_RGBA16, 0 }, @@ -1108,7 +1108,7 @@ static struct format_mapping format_map[] = { * Return first supported format from the given list. */ static enum pipe_format -find_supported_format(struct pipe_screen *screen, +find_supported_format(struct pipe_screen *screen, const enum pipe_format formats[], enum pipe_texture_target target, unsigned sample_count, @@ -1124,6 +1124,91 @@ find_supported_format(struct pipe_screen *screen, return PIPE_FORMAT_NONE; } +struct exact_format_mapping +{ + GLenum format; + GLenum type; + enum pipe_format pformat; +}; + +static const struct exact_format_mapping rgba8888_tbl[] = +{ + { GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, PIPE_FORMAT_A8B8G8R8_UNORM }, + { GL_ABGR_EXT, GL_UNSIGNED_INT_8_8_8_8_REV, PIPE_FORMAT_A8B8G8R8_UNORM }, + { GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, PIPE_FORMAT_R8G8B8A8_UNORM }, + { GL_ABGR_EXT, GL_UNSIGNED_INT_8_8_8_8, PIPE_FORMAT_R8G8B8A8_UNORM }, + { GL_BGRA, GL_UNSIGNED_INT_8_8_8_8, PIPE_FORMAT_A8R8G8B8_UNORM }, + { GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, PIPE_FORMAT_B8G8R8A8_UNORM }, + { GL_RGBA, GL_UNSIGNED_BYTE, PIPE_FORMAT_R8G8B8A8_UNORM }, + { GL_ABGR_EXT, GL_UNSIGNED_BYTE, PIPE_FORMAT_A8B8G8R8_UNORM }, + { GL_BGRA, GL_UNSIGNED_BYTE, PIPE_FORMAT_B8G8R8A8_UNORM }, + { 0, 0, 0 } +}; + +static const struct exact_format_mapping rgbx8888_tbl[] = +{ + { GL_BGRA, GL_UNSIGNED_INT_8_8_8_8, PIPE_FORMAT_X8R8G8B8_UNORM }, + { GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, PIPE_FORMAT_B8G8R8X8_UNORM }, + { GL_BGRA, GL_UNSIGNED_BYTE, PIPE_FORMAT_B8G8R8X8_UNORM }, + /* No Mesa formats for these Gallium formats: + { GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, PIPE_FORMAT_X8B8G8R8_UNORM }, + { GL_ABGR_EXT, GL_UNSIGNED_INT_8_8_8_8_REV, PIPE_FORMAT_X8B8G8R8_UNORM }, + { GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, PIPE_FORMAT_R8G8B8X8_UNORM }, + { GL_ABGR_EXT, GL_UNSIGNED_INT_8_8_8_8, PIPE_FORMAT_R8G8B8X8_UNORM }, + { GL_RGBA, GL_UNSIGNED_BYTE, PIPE_FORMAT_R8G8B8X8_UNORM }, + { GL_ABGR_EXT, GL_UNSIGNED_BYTE, PIPE_FORMAT_X8B8G8R8_UNORM }, + */ + { 0, 0, 0 } +}; + +static const struct exact_format_mapping rgba1010102_tbl[] = +{ + { GL_BGRA, GL_UNSIGNED_INT_2_10_10_10_REV, PIPE_FORMAT_B10G10R10A2_UNORM }, + /* No Mesa formats for these Gallium formats: + { GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, PIPE_FORMAT_R10G10B10A2_UNORM }, + { GL_ABGR_EXT, GL_UNSIGNED_INT_10_10_10_2, PIPE_FORMAT_R10G10B10A2_UNORM }, + { GL_ABGR_EXT, GL_UNSIGNED_INT, PIPE_FORMAT_R10G10B10A2_UNORM }, + */ + { 0, 0, 0 } +}; + +/** + * If there is an exact pipe_format match for {internalFormat, format, type} + * return that, otherwise return PIPE_FORMAT_NONE so we can do fuzzy matching. + */ +static enum pipe_format +find_exact_format(GLint internalFormat, GLenum format, GLenum type) +{ + uint i; + const struct exact_format_mapping* tbl; + + if (format == GL_NONE || type == GL_NONE) + return PIPE_FORMAT_NONE; + + switch (internalFormat) { + case 4: + case GL_RGBA: + case GL_RGBA8: + tbl = rgba8888_tbl; + break; + case 3: + case GL_RGB: + case GL_RGB8: + tbl = rgbx8888_tbl; + break; + case GL_RGB10_A2: + tbl = rgba1010102_tbl; + break; + default: + return PIPE_FORMAT_NONE; + } + + for (i = 0; tbl[i].format; i++) + if (tbl[i].format == format && tbl[i].type == type) + return tbl[i].pformat; + + return PIPE_FORMAT_NONE; +} /** * Given an OpenGL internalFormat value for a texture or surface, return @@ -1140,11 +1225,13 @@ find_supported_format(struct pipe_screen *screen, */ enum pipe_format st_choose_format(struct pipe_screen *screen, GLenum internalFormat, + GLenum format, GLenum type, enum pipe_texture_target target, unsigned sample_count, unsigned bindings) { GET_CURRENT_CONTEXT(ctx); /* XXX this should be a function parameter */ int i, j; + enum pipe_format pf; /* can't render to compressed formats at this time */ if (_mesa_is_compressed_format(ctx, internalFormat) @@ -1152,6 +1239,13 @@ st_choose_format(struct pipe_screen *screen, GLenum internalFormat, return PIPE_FORMAT_NONE; } + /* search for exact matches */ + pf = find_exact_format(internalFormat, format, type); + if (pf != PIPE_FORMAT_NONE && + screen->is_format_supported(screen, pf, + target, sample_count, bindings)) + return pf; + /* search table for internalFormat */ for (i = 0; i < Elements(format_map); i++) { const struct format_mapping *mapping = &format_map[i]; @@ -1183,14 +1277,11 @@ st_choose_renderbuffer_format(struct pipe_screen *screen, usage = PIPE_BIND_DEPTH_STENCIL; else usage = PIPE_BIND_RENDER_TARGET; - return st_choose_format(screen, internalFormat, PIPE_TEXTURE_2D, + return st_choose_format(screen, internalFormat, GL_NONE, GL_NONE, PIPE_TEXTURE_2D, sample_count, usage); } -/** - * Called via ctx->Driver.chooseTextureFormat(). - */ gl_format st_ChooseTextureFormat_renderable(struct gl_context *ctx, GLint internalFormat, GLenum format, GLenum type, GLboolean renderable) @@ -1206,20 +1297,19 @@ st_ChooseTextureFormat_renderable(struct gl_context *ctx, GLint internalFormat, * that in advance. Specify potential render target flags now. */ bindings = PIPE_BIND_SAMPLER_VIEW; - if (renderable == GL_TRUE) { - if (_mesa_is_depth_format(internalFormat) || - _mesa_is_depth_or_stencil_format(internalFormat)) + if (renderable) { + if (_mesa_is_depth_or_stencil_format(internalFormat)) bindings |= PIPE_BIND_DEPTH_STENCIL; - else + else bindings |= PIPE_BIND_RENDER_TARGET; } - pFormat = st_choose_format(screen, internalFormat, + pFormat = st_choose_format(screen, internalFormat, format, type, PIPE_TEXTURE_2D, 0, bindings); if (pFormat == PIPE_FORMAT_NONE) { /* try choosing format again, this time without render target bindings */ - pFormat = st_choose_format(screen, internalFormat, + pFormat = st_choose_format(screen, internalFormat, format, type, PIPE_TEXTURE_2D, 0, PIPE_BIND_SAMPLER_VIEW); } @@ -1231,6 +1321,10 @@ st_ChooseTextureFormat_renderable(struct gl_context *ctx, GLint internalFormat, return st_pipe_format_to_mesa_format(pFormat); } + +/** + * Called via ctx->Driver.ChooseTextureFormat(). + */ gl_format st_ChooseTextureFormat(struct gl_context *ctx, GLint internalFormat, GLenum format, GLenum type) diff --git a/src/mesa/state_tracker/st_format.h b/src/mesa/state_tracker/st_format.h index 0fb570f6ee4..1c1f5965f66 100644 --- a/src/mesa/state_tracker/st_format.h +++ b/src/mesa/state_tracker/st_format.h @@ -52,8 +52,9 @@ st_pipe_format_to_mesa_format(enum pipe_format pipeFormat); extern enum pipe_format st_choose_format(struct pipe_screen *screen, GLenum internalFormat, + GLenum format, GLenum type, enum pipe_texture_target target, unsigned sample_count, - unsigned tex_usage); + unsigned bindings); extern enum pipe_format st_choose_renderbuffer_format(struct pipe_screen *screen, diff --git a/src/mesa/state_tracker/st_manager.c b/src/mesa/state_tracker/st_manager.c index a68544ddac7..a8c4b5c3f49 100644 --- a/src/mesa/state_tracker/st_manager.c +++ b/src/mesa/state_tracker/st_manager.c @@ -139,23 +139,64 @@ buffer_index_to_attachment(gl_buffer_index index) } /** + * Make sure a context picks up the latest cached state of the + * drawables it binds to. + */ +static void +st_context_validate(struct st_context *st, + struct st_framebuffer *stdraw, + struct st_framebuffer *stread) +{ + if (stdraw && stdraw->stamp != st->draw_stamp) { + st->dirty.st |= ST_NEW_FRAMEBUFFER; + _mesa_resize_framebuffer(st->ctx, &stdraw->Base, + stdraw->Base.Width, + stdraw->Base.Height); + st->draw_stamp = stdraw->stamp; + } + + if (stread && stread->stamp != st->read_stamp) { + if (stread != stdraw) { + st->dirty.st |= ST_NEW_FRAMEBUFFER; + _mesa_resize_framebuffer(st->ctx, &stread->Base, + stread->Base.Width, + stread->Base.Height); + } + st->read_stamp = stread->stamp; + } +} + +/** * Validate a framebuffer to make sure up-to-date pipe_textures are used. + * The context we need to pass in is s dummy context needed only to be + * able to get a pipe context to create pipe surfaces, and to have a + * context to call _mesa_resize_framebuffer(): + * (That should probably be rethought, since those surfaces become + * drawable state, not context state, and can be freed by another pipe + * context). */ static void -st_framebuffer_validate(struct st_framebuffer *stfb, struct st_context *st) +st_framebuffer_validate(struct st_framebuffer *stfb, + struct st_context *st) { - struct pipe_context *pipe = st->pipe; struct pipe_resource *textures[ST_ATTACHMENT_COUNT]; uint width, height; unsigned i; boolean changed = FALSE; + int32_t new_stamp = p_atomic_read(&stfb->iface->stamp); - if (!p_atomic_read(&stfb->revalidate)) + if (stfb->iface_stamp == new_stamp) return; /* validate the fb */ - if (!stfb->iface->validate(stfb->iface, stfb->statts, stfb->num_statts, textures)) - return; + do { + if (!stfb->iface->validate(stfb->iface, stfb->statts, + stfb->num_statts, textures)) + return; + + stfb->iface_stamp = new_stamp; + new_stamp = p_atomic_read(&stfb->iface->stamp); + } while(stfb->iface_stamp != new_stamp); width = stfb->Base.Width; height = stfb->Base.Height; @@ -184,7 +225,7 @@ st_framebuffer_validate(struct st_framebuffer *stfb, struct st_context *st) memset(&surf_tmpl, 0, sizeof(surf_tmpl)); u_surface_default_template(&surf_tmpl, textures[i], PIPE_BIND_RENDER_TARGET); - ps = pipe->create_surface(pipe, textures[i], &surf_tmpl); + ps = st->pipe->create_surface(st->pipe, textures[i], &surf_tmpl); if (ps) { pipe_surface_reference(&strb->surface, ps); pipe_resource_reference(&strb->texture, ps->texture); @@ -204,14 +245,9 @@ st_framebuffer_validate(struct st_framebuffer *stfb, struct st_context *st) } if (changed) { - st->dirty.st |= ST_NEW_FRAMEBUFFER; + ++stfb->stamp; _mesa_resize_framebuffer(st->ctx, &stfb->Base, width, height); - - assert(stfb->Base.Width == width); - assert(stfb->Base.Height == height); } - - p_atomic_set(&stfb->revalidate, FALSE); } /** @@ -236,8 +272,7 @@ st_framebuffer_update_attachments(struct st_framebuffer *stfb) st_visual_have_buffers(stfb->iface->visual, 1 << statt)) stfb->statts[stfb->num_statts++] = statt; } - - p_atomic_set(&stfb->revalidate, TRUE); + stfb->stamp++; } /** @@ -443,6 +478,7 @@ st_framebuffer_create(struct st_framebuffer_iface *stfbi) &stfb->Base._ColorReadBufferIndex); stfb->iface = stfbi; + stfb->iface_stamp = p_atomic_read(&stfbi->stamp) - 1; /* add the color buffer */ idx = stfb->Base._ColorDrawBufferIndexes[0]; @@ -454,6 +490,7 @@ st_framebuffer_create(struct st_framebuffer_iface *stfbi) st_framebuffer_add_renderbuffer(stfb, BUFFER_DEPTH); st_framebuffer_add_renderbuffer(stfb, BUFFER_ACCUM); + stfb->stamp = 0; st_framebuffer_update_attachments(stfb); stfb->Base.Initialized = GL_TRUE; @@ -473,31 +510,6 @@ st_framebuffer_reference(struct st_framebuffer **ptr, } static void -st_context_notify_invalid_framebuffer(struct st_context_iface *stctxi, - struct st_framebuffer_iface *stfbi) -{ - struct st_context *st = (struct st_context *) stctxi; - struct st_framebuffer *stfb; - - /* either draw or read winsys fb */ - stfb = st_ws_framebuffer(st->ctx->WinSysDrawBuffer); - if (!stfb || stfb->iface != stfbi) - stfb = st_ws_framebuffer(st->ctx->WinSysReadBuffer); - - if (stfb && stfb->iface == stfbi) { - p_atomic_set(&stfb->revalidate, TRUE); - } - else { - /* This function is probably getting called when we've detected a - * change in a window's size but the currently bound context is - * not bound to that window. - * If the st_framebuffer_iface structure had a pointer to the - * corresponding st_framebuffer we'd be able to handle this. - */ - } -} - -static void st_context_flush(struct st_context_iface *stctxi, unsigned flags, struct pipe_fence_handle **fence) { @@ -696,8 +708,6 @@ st_api_create_context(struct st_api *stapi, struct st_manager *smapi, smapi->get_param(smapi, ST_MANAGER_BROKEN_INVALIDATE); st->iface.destroy = st_context_destroy; - st->iface.notify_invalid_framebuffer = - st_context_notify_invalid_framebuffer; st->iface.flush = st_context_flush; st->iface.teximage = st_context_teximage; st->iface.copy = st_context_copy; @@ -707,38 +717,58 @@ st_api_create_context(struct st_api *stapi, struct st_manager *smapi, return &st->iface; } +static struct st_context_iface * +st_api_get_current(struct st_api *stapi) +{ + GET_CURRENT_CONTEXT(ctx); + struct st_context *st = (ctx) ? ctx->st : NULL; + + return (st) ? &st->iface : NULL; +} + +static struct st_framebuffer * +st_framebuffer_reuse_or_create(struct gl_framebuffer *fb, + struct st_framebuffer_iface *stfbi) +{ + struct st_framebuffer *cur = st_ws_framebuffer(fb), *stfb = NULL; + + if (cur && cur->iface == stfbi) { + /* reuse the current stfb */ + st_framebuffer_reference(&stfb, cur); + } + else { + /* create a new one */ + stfb = st_framebuffer_create(stfbi); + } + + return stfb; +} + static boolean st_api_make_current(struct st_api *stapi, struct st_context_iface *stctxi, struct st_framebuffer_iface *stdrawi, struct st_framebuffer_iface *streadi) { struct st_context *st = (struct st_context *) stctxi; - struct st_framebuffer *stdraw, *stread, *stfb; + struct st_framebuffer *stdraw, *stread; boolean ret; _glapi_check_multithread(); if (st) { - /* reuse/create the draw fb */ - stfb = st_ws_framebuffer(st->ctx->WinSysDrawBuffer); - if (stfb && stfb->iface == stdrawi) { - stdraw = NULL; - st_framebuffer_reference(&stdraw, stfb); + /* reuse or create the draw fb */ + stdraw = st_framebuffer_reuse_or_create(st->ctx->WinSysDrawBuffer, + stdrawi); + if (streadi != stdrawi) { + /* do the same for the read fb */ + stread = st_framebuffer_reuse_or_create(st->ctx->WinSysReadBuffer, + streadi); } else { - stdraw = st_framebuffer_create(stdrawi); - } - - /* reuse/create the read fb */ - stfb = st_ws_framebuffer(st->ctx->WinSysReadBuffer); - if (!stfb || stfb->iface != streadi) - stfb = stdraw; - if (stfb && stfb->iface == streadi) { stread = NULL; - st_framebuffer_reference(&stread, stfb); - } - else { - stread = st_framebuffer_create(streadi); + /* reuse the draw fb for the read fb */ + if (stdraw) + st_framebuffer_reference(&stread, stdraw); } if (stdraw && stread) { @@ -757,6 +787,10 @@ st_api_make_current(struct st_api *stapi, struct st_context_iface *stctxi, } ret = _mesa_make_current(st->ctx, &stdraw->Base, &stread->Base); + + st->draw_stamp = stdraw->stamp - 1; + st->read_stamp = stread->stamp - 1; + st_context_validate(st, stdraw, stread); } else { struct gl_framebuffer *incomplete = _mesa_get_incomplete_framebuffer(); @@ -773,15 +807,6 @@ st_api_make_current(struct st_api *stapi, struct st_context_iface *stctxi, return ret; } -static struct st_context_iface * -st_api_get_current(struct st_api *stapi) -{ - GET_CURRENT_CONTEXT(ctx); - struct st_context *st = (ctx) ? ctx->st : NULL; - - return (st) ? &st->iface : NULL; -} - static st_proc_t st_api_get_proc_address(struct st_api *stapi, const char *procname) { @@ -857,6 +882,8 @@ st_manager_validate_framebuffers(struct st_context *st) st_framebuffer_validate(stdraw, st); if (stread && stread != stdraw) st_framebuffer_validate(stread, st); + + st_context_validate(st, stdraw, stread); } /** |