diff options
Diffstat (limited to 'src/mesa/state_tracker')
39 files changed, 390 insertions, 290 deletions
diff --git a/src/mesa/state_tracker/st_api.c b/src/mesa/state_tracker/st_api.c deleted file mode 100644 index fc0e9a23164..00000000000 --- a/src/mesa/state_tracker/st_api.c +++ /dev/null @@ -1,33 +0,0 @@ -/************************************************************************** - * - * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - - -/** - * Just a global symbol for EGL to look for to identify the supported - * graphics API. - */ -int st_api_OpenGL = 1; diff --git a/src/mesa/state_tracker/st_atom_blend.c b/src/mesa/state_tracker/st_atom_blend.c index 43e62c29f3e..1511b88dd1f 100644 --- a/src/mesa/state_tracker/st_atom_blend.c +++ b/src/mesa/state_tracker/st_atom_blend.c @@ -152,14 +152,54 @@ translate_logicop(GLenum logicop) } } +/** + * Figure out if colormasks are different per rt. + */ +static GLboolean +colormask_per_rt(GLcontext *ctx) +{ + /* a bit suboptimal have to compare lots of values */ + unsigned i; + for (i = 1; i < ctx->Const.MaxDrawBuffers; i++) { + if (memcmp(ctx->Color.ColorMask[0], ctx->Color.ColorMask[i], 4)) { + return GL_TRUE; + } + } + return GL_FALSE; +} + +/** + * Figure out if blend enables are different per rt. + */ +static GLboolean +blend_per_rt(GLcontext *ctx) +{ + if (ctx->Color.BlendEnabled && + (ctx->Color.BlendEnabled != ((1 << ctx->Const.MaxDrawBuffers) - 1))) { + return GL_TRUE; + } + return GL_FALSE; +} static void update_blend( struct st_context *st ) { struct pipe_blend_state *blend = &st->state.blend; + unsigned num_state = 1; + unsigned i; memset(blend, 0, sizeof(*blend)); + if (blend_per_rt(st->ctx) || colormask_per_rt(st->ctx)) { + num_state = st->ctx->Const.MaxDrawBuffers; + blend->independent_blend_enable = 1; + } + /* Note it is impossible to correctly deal with EXT_blend_logic_op and + EXT_draw_buffers2/EXT_blend_equation_separate at the same time. + These combinations would require support for per-rt logicop enables + 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.BlendEquationRGB == GL_LOGIC_OP)) { @@ -169,30 +209,33 @@ update_blend( struct st_context *st ) } else if (st->ctx->Color.BlendEnabled) { /* blending enabled */ - blend->blend_enable = 1; - - 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; - } - else { - blend->rgb_src_factor = translate_blend(st->ctx->Color.BlendSrcRGB); - blend->rgb_dst_factor = translate_blend(st->ctx->Color.BlendDstRGB); - } + for (i = 0; i < num_state; i++) { - 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; - } - else { - blend->alpha_src_factor = translate_blend(st->ctx->Color.BlendSrcA); - blend->alpha_dst_factor = translate_blend(st->ctx->Color.BlendDstA); + blend->rt[i].blend_enable = (st->ctx->Color.BlendEnabled >> i) & 0x1; + + blend->rt[i].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->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.BlendSrcRGB); + blend->rt[i].rgb_dst_factor = translate_blend(st->ctx->Color.BlendDstRGB); + } + + blend->rt[i].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->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.BlendSrcA); + blend->rt[i].alpha_dst_factor = translate_blend(st->ctx->Color.BlendDstA); + } } } else { @@ -200,14 +243,16 @@ update_blend( struct st_context *st ) } /* Colormask - maybe reverse these bits? */ - if (st->ctx->Color.ColorMask[0][0]) - blend->colormask |= PIPE_MASK_R; - if (st->ctx->Color.ColorMask[0][1]) - blend->colormask |= PIPE_MASK_G; - if (st->ctx->Color.ColorMask[0][2]) - blend->colormask |= PIPE_MASK_B; - if (st->ctx->Color.ColorMask[0][3]) - blend->colormask |= PIPE_MASK_A; + for (i = 0; i < num_state; i++) { + if (st->ctx->Color.ColorMask[i][0]) + blend->rt[i].colormask |= PIPE_MASK_R; + if (st->ctx->Color.ColorMask[i][1]) + blend->rt[i].colormask |= PIPE_MASK_G; + if (st->ctx->Color.ColorMask[i][2]) + blend->rt[i].colormask |= PIPE_MASK_B; + if (st->ctx->Color.ColorMask[i][3]) + blend->rt[i].colormask |= PIPE_MASK_A; + } if (st->ctx->Color.DitherFlag) blend->dither = 1; diff --git a/src/mesa/state_tracker/st_atom_constbuf.c b/src/mesa/state_tracker/st_atom_constbuf.c index 77153889b68..d975cd66f7d 100644 --- a/src/mesa/state_tracker/st_atom_constbuf.c +++ b/src/mesa/state_tracker/st_atom_constbuf.c @@ -37,7 +37,7 @@ #include "pipe/p_context.h" #include "pipe/p_defines.h" -#include "pipe/p_inlines.h" +#include "util/u_inlines.h" #include "st_debug.h" #include "st_context.h" @@ -57,7 +57,7 @@ void st_upload_constants( struct st_context *st, unsigned shader_type) { struct pipe_context *pipe = st->pipe; - struct pipe_constant_buffer *cbuf = &st->state.constants[shader_type]; + struct pipe_buffer **cbuf = &st->state.constants[shader_type]; assert(shader_type == PIPE_SHADER_VERTEX || shader_type == PIPE_SHADER_FRAGMENT); @@ -71,8 +71,8 @@ void st_upload_constants( struct st_context *st, /* We always need to get a new buffer, to keep the drivers simple and * avoid gratuitous rendering synchronization. */ - pipe_buffer_reference(&cbuf->buffer, NULL ); - cbuf->buffer = pipe_buffer_create(pipe->screen, 16, + pipe_buffer_reference(cbuf, NULL ); + *cbuf = pipe_buffer_create(pipe->screen, 16, PIPE_BUFFER_USAGE_CONSTANT, paramBytes ); @@ -84,12 +84,12 @@ void st_upload_constants( struct st_context *st, } /* load Mesa constants into the constant buffer */ - if (cbuf->buffer) - st_no_flush_pipe_buffer_write(st, cbuf->buffer, + if (cbuf) + st_no_flush_pipe_buffer_write(st, *cbuf, 0, paramBytes, params->ParameterValues); - st->pipe->set_constant_buffer(st->pipe, shader_type, 0, cbuf); + st->pipe->set_constant_buffer(st->pipe, shader_type, 0, *cbuf); } else { st->constants.tracked_state[shader_type].dirty.mesa = 0x0; diff --git a/src/mesa/state_tracker/st_atom_framebuffer.c b/src/mesa/state_tracker/st_atom_framebuffer.c index 8ca4335e330..fba7bfe2cea 100644 --- a/src/mesa/state_tracker/st_atom_framebuffer.c +++ b/src/mesa/state_tracker/st_atom_framebuffer.c @@ -37,10 +37,10 @@ #include "st_public.h" #include "st_texture.h" #include "pipe/p_context.h" -#include "pipe/p_inlines.h" #include "cso_cache/cso_context.h" #include "util/u_rect.h" #include "util/u_math.h" +#include "util/u_inlines.h" diff --git a/src/mesa/state_tracker/st_atom_pixeltransfer.c b/src/mesa/state_tracker/st_atom_pixeltransfer.c index 6a5854e9ba5..0b2e3f53812 100644 --- a/src/mesa/state_tracker/st_atom_pixeltransfer.c +++ b/src/mesa/state_tracker/st_atom_pixeltransfer.c @@ -43,7 +43,6 @@ #include "st_context.h" #include "st_format.h" -#include "st_program.h" #include "st_texture.h" #include "st_inlines.h" diff --git a/src/mesa/state_tracker/st_atom_sampler.c b/src/mesa/state_tracker/st_atom_sampler.c index 7b84a86ba48..9d63f1c6ab6 100644 --- a/src/mesa/state_tracker/st_atom_sampler.c +++ b/src/mesa/state_tracker/st_atom_sampler.c @@ -37,7 +37,6 @@ #include "st_context.h" #include "st_cb_texture.h" #include "st_atom.h" -#include "st_program.h" #include "pipe/p_context.h" #include "pipe/p_defines.h" diff --git a/src/mesa/state_tracker/st_atom_scissor.c b/src/mesa/state_tracker/st_atom_scissor.c index 3fd59e1945c..5e0c51cff0a 100644 --- a/src/mesa/state_tracker/st_atom_scissor.c +++ b/src/mesa/state_tracker/st_atom_scissor.c @@ -31,6 +31,7 @@ */ +#include "main/macros.h" #include "st_context.h" #include "pipe/p_context.h" #include "st_atom.h" @@ -52,15 +53,19 @@ update_scissor( struct st_context *st ) scissor.maxy = fb->Height; if (st->ctx->Scissor.Enabled) { - if ((GLuint)st->ctx->Scissor.X > scissor.minx) + /* 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); + + if (st->ctx->Scissor.X > (GLint)scissor.minx) scissor.minx = st->ctx->Scissor.X; - if ((GLuint)st->ctx->Scissor.Y > scissor.miny) + if (st->ctx->Scissor.Y > (GLint)scissor.miny) scissor.miny = st->ctx->Scissor.Y; - if ((GLuint)st->ctx->Scissor.X + st->ctx->Scissor.Width < scissor.maxx) - scissor.maxx = st->ctx->Scissor.X + st->ctx->Scissor.Width; - if ((GLuint)st->ctx->Scissor.Y + st->ctx->Scissor.Height < scissor.maxy) - scissor.maxy = st->ctx->Scissor.Y + st->ctx->Scissor.Height; + if (xmax < (GLint) scissor.maxx) + scissor.maxx = xmax; + if (ymax < (GLint) scissor.maxy) + scissor.maxy = ymax; /* check for null space */ if (scissor.minx >= scissor.maxx || scissor.miny >= scissor.maxy) diff --git a/src/mesa/state_tracker/st_atom_shader.c b/src/mesa/state_tracker/st_atom_shader.c index 46c8cbb3098..ea16719ba0e 100644 --- a/src/mesa/state_tracker/st_atom_shader.c +++ b/src/mesa/state_tracker/st_atom_shader.c @@ -35,11 +35,8 @@ * Brian Paul */ - - #include "main/imports.h" #include "main/mtypes.h" -#include "main/macros.h" #include "shader/program.h" #include "pipe/p_context.h" @@ -52,40 +49,20 @@ #include "st_context.h" #include "st_atom.h" #include "st_program.h" -#include "st_atom_shader.h" -#include "st_mesa_to_tgsi.h" - - -/* +/** * Translate fragment program if needed. */ static void translate_fp(struct st_context *st, struct st_fragment_program *stfp) { - const GLbitfield fragInputsRead = stfp->Base.Base.InputsRead; - if (!stfp->state.tokens) { - GLuint inAttr, numIn = 0; - - for (inAttr = 0; inAttr < FRAG_ATTRIB_MAX; inAttr++) { - if (fragInputsRead & (1 << inAttr)) { - stfp->input_to_slot[inAttr] = numIn; - numIn++; - } - else { - stfp->input_to_slot[inAttr] = -1; - } - } - - stfp->num_input_slots = numIn; + assert(stfp->Base.Base.NumInstructions > 0); - assert(stfp->Base.Base.NumInstructions > 1); - - st_translate_fragment_program(st, stfp, stfp->input_to_slot); + st_translate_fragment_program(st, stfp); } } @@ -155,8 +132,10 @@ find_translated_vp(struct st_context *st, } - - +/** + * Return pointer to a pass-through fragment shader. + * This shader is used when a texture is missing/incomplete. + */ static void * get_passthrough_fs(struct st_context *st) { @@ -168,6 +147,11 @@ get_passthrough_fs(struct st_context *st) return st->passthrough_fs; } + +/** + * Update fragment program state/atom. This involves translating the + * Mesa fragment program into a gallium fragment program and binding it. + */ static void update_fp( struct st_context *st ) { @@ -191,6 +175,7 @@ update_fp( struct st_context *st ) } } + const struct st_tracked_state st_update_fp = { "st_update_fp", /* name */ { /* dirty */ @@ -202,7 +187,10 @@ const struct st_tracked_state st_update_fp = { - +/** + * Update vertex program state/atom. This involves translating the + * Mesa vertex program into a gallium fragment program and binding it. + */ static void update_vp( struct st_context *st ) { diff --git a/src/mesa/state_tracker/st_atom_texture.c b/src/mesa/state_tracker/st_atom_texture.c index 0b68447d212..57b71c1e7b0 100644 --- a/src/mesa/state_tracker/st_atom_texture.c +++ b/src/mesa/state_tracker/st_atom_texture.c @@ -39,6 +39,7 @@ #include "st_texture.h" #include "st_cb_texture.h" #include "pipe/p_context.h" +#include "util/u_inlines.h" #include "cso_cache/cso_context.h" diff --git a/src/mesa/state_tracker/st_atom_viewport.c b/src/mesa/state_tracker/st_atom_viewport.c index 27ec2eb0331..0b6c34ca2cb 100644 --- a/src/mesa/state_tracker/st_atom_viewport.c +++ b/src/mesa/state_tracker/st_atom_viewport.c @@ -27,7 +27,6 @@ #include "main/context.h" -#include "main/colormac.h" #include "st_context.h" #include "st_atom.h" #include "pipe/p_context.h" @@ -62,9 +61,9 @@ update_viewport( struct st_context *st ) GLfloat x = (GLfloat)ctx->Viewport.X; GLfloat y = (GLfloat)ctx->Viewport.Y; GLfloat z = ctx->Viewport.Near; - GLfloat half_width = (GLfloat)ctx->Viewport.Width / 2.0f; - GLfloat half_height = (GLfloat)ctx->Viewport.Height / 2.0f; - GLfloat half_depth = (GLfloat)(ctx->Viewport.Far - ctx->Viewport.Near) / 2.0f; + GLfloat half_width = (GLfloat)ctx->Viewport.Width * 0.5f; + GLfloat half_height = (GLfloat)ctx->Viewport.Height * 0.5f; + GLfloat half_depth = (GLfloat)(ctx->Viewport.Far - ctx->Viewport.Near) * 0.5f; st->state.viewport.scale[0] = half_width; st->state.viewport.scale[1] = half_height * yScale; diff --git a/src/mesa/state_tracker/st_cb_accum.c b/src/mesa/state_tracker/st_cb_accum.c index da7b97d3253..1be72e729e4 100644 --- a/src/mesa/state_tracker/st_cb_accum.c +++ b/src/mesa/state_tracker/st_cb_accum.c @@ -38,14 +38,12 @@ #include "st_context.h" #include "st_cb_accum.h" #include "st_cb_fbo.h" -#include "st_draw.h" #include "st_public.h" -#include "st_format.h" #include "st_texture.h" #include "st_inlines.h" #include "pipe/p_context.h" #include "pipe/p_defines.h" -#include "pipe/p_inlines.h" +#include "util/u_inlines.h" #include "util/u_tile.h" diff --git a/src/mesa/state_tracker/st_cb_bitmap.c b/src/mesa/state_tracker/st_cb_bitmap.c index 1bdeaccda3e..85420a950f4 100644 --- a/src/mesa/state_tracker/st_cb_bitmap.c +++ b/src/mesa/state_tracker/st_cb_bitmap.c @@ -34,9 +34,7 @@ #include "main/image.h" #include "main/bufferobj.h" #include "main/macros.h" -#include "main/texformat.h" #include "shader/program.h" -#include "shader/prog_parameter.h" #include "shader/prog_print.h" #include "st_context.h" @@ -44,15 +42,12 @@ #include "st_atom_constbuf.h" #include "st_program.h" #include "st_cb_bitmap.h" -#include "st_cb_program.h" -#include "st_mesa_to_tgsi.h" #include "st_texture.h" #include "st_inlines.h" #include "pipe/p_context.h" #include "pipe/p_defines.h" -#include "pipe/p_inlines.h" -#include "util/u_tile.h" +#include "util/u_inlines.h" #include "util/u_draw_quad.h" #include "util/u_simple_shaders.h" #include "shader/prog_instruction.h" @@ -226,7 +221,7 @@ combined_bitmap_fragment_program(GLcontext *ctx) #endif /* translate to TGSI tokens */ - st_translate_fragment_program(st, stfp->bitmap_program, NULL); + st_translate_fragment_program(st, stfp->bitmap_program); } return stfp->bitmap_program; @@ -386,11 +381,11 @@ setup_bitmap_vertex_data(struct st_context *st, } /* put vertex data into vbuf */ - st_no_flush_pipe_buffer_write(st, - st->bitmap.vbuf, - st->bitmap.vbuf_slot * sizeof st->bitmap.vertices, - sizeof st->bitmap.vertices, - st->bitmap.vertices); + st_no_flush_pipe_buffer_write_nooverlap(st, + st->bitmap.vbuf, + st->bitmap.vbuf_slot * sizeof st->bitmap.vertices, + sizeof st->bitmap.vertices, + st->bitmap.vertices); return st->bitmap.vbuf_slot++ * sizeof st->bitmap.vertices; } diff --git a/src/mesa/state_tracker/st_cb_blit.c b/src/mesa/state_tracker/st_cb_blit.c index 563615ed0d1..36e03018d9f 100644 --- a/src/mesa/state_tracker/st_cb_blit.c +++ b/src/mesa/state_tracker/st_cb_blit.c @@ -33,20 +33,15 @@ #include "main/imports.h" #include "main/image.h" #include "main/macros.h" -#include "main/texformat.h" #include "shader/program.h" -#include "shader/prog_parameter.h" -#include "shader/prog_print.h" #include "st_context.h" #include "st_texture.h" -#include "st_program.h" #include "st_cb_blit.h" #include "st_cb_fbo.h" #include "util/u_blit.h" - -#include "cso_cache/cso_context.h" +#include "util/u_inlines.h" void diff --git a/src/mesa/state_tracker/st_cb_bufferobjects.c b/src/mesa/state_tracker/st_cb_bufferobjects.c index 0102d8a6f7d..f1b4f11c050 100644 --- a/src/mesa/state_tracker/st_cb_bufferobjects.c +++ b/src/mesa/state_tracker/st_cb_bufferobjects.c @@ -42,7 +42,7 @@ #include "pipe/p_context.h" #include "pipe/p_defines.h" -#include "pipe/p_inlines.h" +#include "util/u_inlines.h" /** @@ -75,6 +75,8 @@ st_bufferobj_free(GLcontext *ctx, struct gl_buffer_object *obj) { struct st_buffer_object *st_obj = st_buffer_object(obj); + assert(obj->RefCount == 0); + if (st_obj->buffer) pipe_buffer_reference(&st_obj->buffer, NULL); diff --git a/src/mesa/state_tracker/st_cb_clear.c b/src/mesa/state_tracker/st_cb_clear.c index 192d765f453..0c7bcb85973 100644 --- a/src/mesa/state_tracker/st_cb_clear.c +++ b/src/mesa/state_tracker/st_cb_clear.c @@ -42,18 +42,15 @@ #include "st_cb_accum.h" #include "st_cb_clear.h" #include "st_cb_fbo.h" -#include "st_draw.h" #include "st_program.h" #include "st_public.h" -#include "st_mesa_to_tgsi.h" #include "st_inlines.h" #include "pipe/p_context.h" -#include "pipe/p_inlines.h" +#include "util/u_inlines.h" #include "pipe/p_state.h" #include "pipe/p_defines.h" #include "util/u_format.h" -#include "util/u_pack_color.h" #include "util/u_simple_shaders.h" #include "util/u_draw_quad.h" @@ -166,10 +163,10 @@ draw_quad(GLcontext *ctx, } /* put vertex data into vbuf */ - st_no_flush_pipe_buffer_write(st, st->clear.vbuf, - st->clear.vbuf_slot * sizeof(st->clear.vertices), - sizeof(st->clear.vertices), - st->clear.vertices); + st_no_flush_pipe_buffer_write_nooverlap(st, st->clear.vbuf, + st->clear.vbuf_slot * sizeof(st->clear.vertices), + sizeof(st->clear.vertices), + st->clear.vertices); /* draw */ util_draw_vertex_buffer(pipe, @@ -227,19 +224,19 @@ clear_with_quad(GLcontext *ctx, { struct pipe_blend_state blend; memset(&blend, 0, sizeof(blend)); - blend.rgb_src_factor = PIPE_BLENDFACTOR_ONE; - blend.alpha_src_factor = PIPE_BLENDFACTOR_ONE; - blend.rgb_dst_factor = PIPE_BLENDFACTOR_ZERO; - blend.alpha_dst_factor = PIPE_BLENDFACTOR_ZERO; + blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE; + blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE; + blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO; + blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO; if (color) { if (ctx->Color.ColorMask[0][0]) - blend.colormask |= PIPE_MASK_R; + blend.rt[0].colormask |= PIPE_MASK_R; if (ctx->Color.ColorMask[0][1]) - blend.colormask |= PIPE_MASK_G; + blend.rt[0].colormask |= PIPE_MASK_G; if (ctx->Color.ColorMask[0][2]) - blend.colormask |= PIPE_MASK_B; + blend.rt[0].colormask |= PIPE_MASK_B; if (ctx->Color.ColorMask[0][3]) - blend.colormask |= PIPE_MASK_A; + blend.rt[0].colormask |= PIPE_MASK_A; if (st->ctx->Color.DitherFlag) blend.dither = 1; } diff --git a/src/mesa/state_tracker/st_cb_condrender.c b/src/mesa/state_tracker/st_cb_condrender.c index 780b40c2065..8483b93bd85 100644 --- a/src/mesa/state_tracker/st_cb_condrender.c +++ b/src/mesa/state_tracker/st_cb_condrender.c @@ -69,6 +69,7 @@ st_BeginConditionalRender(GLcontext *ctx, struct gl_query_object *q, break; default: assert(0 && "bad mode in st_BeginConditionalRender"); + m = PIPE_RENDER_COND_WAIT; } pipe->render_condition(pipe, stq->pq, m); diff --git a/src/mesa/state_tracker/st_cb_drawpixels.c b/src/mesa/state_tracker/st_cb_drawpixels.c index 7c664267d4e..2a084ca5779 100644 --- a/src/mesa/state_tracker/st_cb_drawpixels.c +++ b/src/mesa/state_tracker/st_cb_drawpixels.c @@ -36,30 +36,24 @@ #include "main/macros.h" #include "main/texformat.h" #include "main/texstore.h" -#include "main/state.h" #include "shader/program.h" -#include "shader/prog_parameter.h" #include "shader/prog_print.h" #include "st_debug.h" #include "st_context.h" #include "st_atom.h" #include "st_atom_constbuf.h" -#include "st_draw.h" #include "st_program.h" #include "st_cb_drawpixels.h" #include "st_cb_readpixels.h" #include "st_cb_fbo.h" -#include "st_cb_texture.h" -#include "st_draw.h" #include "st_format.h" -#include "st_mesa_to_tgsi.h" #include "st_texture.h" #include "st_inlines.h" #include "pipe/p_context.h" #include "pipe/p_defines.h" -#include "pipe/p_inlines.h" +#include "util/u_inlines.h" #include "tgsi/tgsi_ureg.h" #include "util/u_tile.h" #include "util/u_draw_quad.h" @@ -146,7 +140,7 @@ combined_drawpix_fragment_program(GLcontext *ctx) #endif /* translate to TGSI tokens */ - st_translate_fragment_program(st, stfp, NULL); + st_translate_fragment_program(st, stfp); /* save new program, update serial numbers */ st->pixel_xfer.xfer_prog_sn = st->pixel_xfer.program->serialNo; @@ -227,7 +221,7 @@ make_fragment_shader_z(struct st_context *st) p->SamplersUsed = 0x1; /* sampler 0 (bit 0) is used */ st->drawpix.z_shader = (struct st_fragment_program *) p; - st_translate_fragment_program(st, st->drawpix.z_shader, NULL); + st_translate_fragment_program(st, st->drawpix.z_shader); return st->drawpix.z_shader; } @@ -1138,6 +1132,8 @@ st_destroy_drawpix(struct st_context *st) { st_reference_fragprog(st, &st->drawpix.z_shader, NULL); st_reference_fragprog(st, &st->pixel_xfer.combined_prog, NULL); - st_reference_vertprog(st, &st->drawpix.vert_shaders[0], NULL); - st_reference_vertprog(st, &st->drawpix.vert_shaders[1], NULL); + if (st->drawpix.vert_shaders[0]) + free(st->drawpix.vert_shaders[0]); + if (st->drawpix.vert_shaders[1]) + free(st->drawpix.vert_shaders[1]); } diff --git a/src/mesa/state_tracker/st_cb_fbo.c b/src/mesa/state_tracker/st_cb_fbo.c index 45ce34a85f7..9f2fe7420d4 100644 --- a/src/mesa/state_tracker/st_cb_fbo.c +++ b/src/mesa/state_tracker/st_cb_fbo.c @@ -44,13 +44,13 @@ #include "pipe/p_screen.h" #include "st_context.h" #include "st_cb_fbo.h" -#include "st_cb_texture.h" #include "st_format.h" #include "st_public.h" #include "st_texture.h" #include "util/u_format.h" #include "util/u_rect.h" +#include "util/u_inlines.h" /** diff --git a/src/mesa/state_tracker/st_cb_feedback.c b/src/mesa/state_tracker/st_cb_feedback.c index 93f71452192..edf26473d45 100644 --- a/src/mesa/state_tracker/st_cb_feedback.c +++ b/src/mesa/state_tracker/st_cb_feedback.c @@ -40,19 +40,15 @@ #include "main/imports.h" #include "main/context.h" #include "main/feedback.h" -#include "main/macros.h" #include "vbo/vbo.h" #include "st_context.h" -#include "st_atom.h" #include "st_draw.h" #include "st_cb_feedback.h" -#include "st_cb_bufferobjects.h" #include "pipe/p_context.h" #include "pipe/p_defines.h" -#include "cso_cache/cso_cache.h" #include "draw/draw_context.h" #include "draw/draw_pipe.h" diff --git a/src/mesa/state_tracker/st_cb_program.c b/src/mesa/state_tracker/st_cb_program.c index 8c276f8128e..82ef5572e1d 100644 --- a/src/mesa/state_tracker/st_cb_program.c +++ b/src/mesa/state_tracker/st_cb_program.c @@ -36,7 +36,6 @@ #include "shader/prog_instruction.h" #include "shader/prog_parameter.h" #include "shader/program.h" -#include "shader/programopt.h" #include "shader/shader_api.h" #include "cso_cache/cso_context.h" @@ -44,7 +43,6 @@ #include "st_context.h" #include "st_program.h" -#include "st_atom_shader.h" #include "st_mesa_to_tgsi.h" #include "st_cb_program.h" @@ -179,9 +177,9 @@ static GLboolean st_is_program_native( GLcontext *ctx, } -static void st_program_string_notify( GLcontext *ctx, - GLenum target, - struct gl_program *prog ) +static GLboolean st_program_string_notify( GLcontext *ctx, + GLenum target, + struct gl_program *prog ) { struct st_context *st = st_context(ctx); @@ -213,6 +211,9 @@ static void st_program_string_notify( GLcontext *ctx, if (st->vp == stvp) st->dirty.st |= ST_NEW_VERTEX_PROGRAM; } + + /* XXX check if program is legal, within limits */ + return GL_TRUE; } diff --git a/src/mesa/state_tracker/st_cb_queryobj.c b/src/mesa/state_tracker/st_cb_queryobj.c index 10629e92254..2281d10e999 100644 --- a/src/mesa/state_tracker/st_cb_queryobj.c +++ b/src/mesa/state_tracker/st_cb_queryobj.c @@ -41,7 +41,6 @@ #include "pipe/p_defines.h" #include "st_context.h" #include "st_cb_queryobj.h" -#include "st_public.h" static struct gl_query_object * diff --git a/src/mesa/state_tracker/st_cb_rasterpos.c b/src/mesa/state_tracker/st_cb_rasterpos.c index d82b2a2035f..42a1377809a 100644 --- a/src/mesa/state_tracker/st_cb_rasterpos.c +++ b/src/mesa/state_tracker/st_cb_rasterpos.c @@ -47,7 +47,6 @@ #include "st_draw.h" #include "draw/draw_context.h" #include "draw/draw_pipe.h" -#include "shader/prog_instruction.h" #include "vbo/vbo.h" diff --git a/src/mesa/state_tracker/st_cb_readpixels.c b/src/mesa/state_tracker/st_cb_readpixels.c index 6fa7bb64f2e..6b1fdf3ecd0 100644 --- a/src/mesa/state_tracker/st_cb_readpixels.c +++ b/src/mesa/state_tracker/st_cb_readpixels.c @@ -40,15 +40,13 @@ #include "pipe/p_context.h" #include "pipe/p_defines.h" -#include "pipe/p_inlines.h" +#include "util/u_inlines.h" #include "util/u_tile.h" #include "st_debug.h" #include "st_context.h" -#include "st_cb_bitmap.h" #include "st_cb_readpixels.h" #include "st_cb_fbo.h" -#include "st_format.h" #include "st_public.h" #include "st_texture.h" #include "st_inlines.h" diff --git a/src/mesa/state_tracker/st_cb_strings.c b/src/mesa/state_tracker/st_cb_strings.c index bb931f17c4e..0fcb427f30a 100644 --- a/src/mesa/state_tracker/st_cb_strings.c +++ b/src/mesa/state_tracker/st_cb_strings.c @@ -33,13 +33,13 @@ #include "main/glheader.h" #include "main/macros.h" -#include "main/version.h" #include "pipe/p_context.h" #include "pipe/p_screen.h" +#include "util/u_string.h" #include "st_context.h" #include "st_cb_strings.h" -#define ST_VERSION_STRING "0.3" +#define ST_VERSION_STRING "0.4" static const GLubyte * st_get_string(GLcontext * ctx, GLenum name) diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c index f01053cdacc..13f050900a6 100644 --- a/src/mesa/state_tracker/st_cb_texture.c +++ b/src/mesa/state_tracker/st_cb_texture.c @@ -31,15 +31,14 @@ #include "main/convolve.h" #endif #include "main/enums.h" +#include "main/fbobject.h" #include "main/formats.h" #include "main/image.h" #include "main/imports.h" #include "main/macros.h" #include "main/mipmap.h" -#include "main/pixel.h" #include "main/texcompress.h" #include "main/texfetch.h" -#include "main/texformat.h" #include "main/texgetimage.h" #include "main/teximage.h" #include "main/texobj.h" @@ -58,7 +57,7 @@ #include "pipe/p_context.h" #include "pipe/p_defines.h" -#include "pipe/p_inlines.h" +#include "util/u_inlines.h" #include "pipe/p_shader_tokens.h" #include "util/u_tile.h" #include "util/u_blit.h" @@ -544,22 +543,15 @@ st_TexImage(GLcontext * ctx, _mesa_align_free(texImage->Data); } - if (width == 0 || height == 0 || depth == 0) { - /* stop after freeing old image */ - return; - } - - /* If this is the only mipmap level in the texture, could call - * bmBufferData with NULL data to free the old block and avoid - * waiting on any outstanding fences. + /* + * See if the new image is somehow incompatible with the existing + * mipmap. If so, free the old mipmap. */ if (stObj->pt) { if (stObj->teximage_realloc || level > (GLint) stObj->pt->last_level || - (stObj->pt->last_level == level && - stObj->pt->target != PIPE_TEXTURE_CUBE && - !st_texture_match_image(stObj->pt, &stImage->base, - stImage->face, stImage->level))) { + !st_texture_match_image(stObj->pt, &stImage->base, + stImage->face, stImage->level)) { DBG("release it\n"); pipe_texture_reference(&stObj->pt, NULL); assert(!stObj->pt); @@ -567,6 +559,11 @@ st_TexImage(GLcontext * ctx, } } + if (width == 0 || height == 0 || depth == 0) { + /* stop after freeing old image */ + return; + } + if (!stObj->pt) { guess_and_alloc_texture(ctx->st, stObj, stImage); if (!stObj->pt) { @@ -687,9 +684,11 @@ st_TexImage(GLcontext * ctx, { char *dst = texImage->Data; const char *src = pixels; - int i; + GLuint i, bw, bh, lines; + _mesa_get_format_block_size(texImage->TexFormat, &bw, &bh); + lines = (height + bh - 1) / bh; - for(i = 0; i < height; ++i) + for(i = 0; i < lines; ++i) { memcpy(dst, src, srcImageStride); dst += dstRowStride; @@ -1368,33 +1367,64 @@ fallback_copy_texsubimage(GLcontext *ctx, GLenum target, GLint level, } + +/** + * If the format of the src renderbuffer and the format of the dest + * texture are compatible (in terms of blitting), return a TGSI writemask + * to be used during the blit. + * If the src/dest are incompatible, return 0. + */ static unsigned -compatible_src_dst_formats(const struct gl_renderbuffer *src, +compatible_src_dst_formats(GLcontext *ctx, + const struct gl_renderbuffer *src, const struct gl_texture_image *dst) { - const GLenum srcFormat = _mesa_get_format_base_format(src->Format); - const GLenum dstLogicalFormat = _mesa_get_format_base_format(dst->TexFormat); + /* Get logical base formats for the src and dest. + * That is, use the user-requested formats and not the actual, device- + * chosen formats. + * For example, the user may have requested an A8 texture but the + * driver may actually be using an RGBA texture format. When we + * copy/blit to that texture, we only want to copy the Alpha channel + * and not the RGB channels. + * + * Similarly, when the src FBO was created an RGB format may have been + * requested but the driver actually chose an RGBA format. In that case, + * we don't want to copy the undefined Alpha channel to the dest texture + * (it should be 1.0). + */ + const GLenum srcFormat = _mesa_base_fbo_format(ctx, src->InternalFormat); + const GLenum dstFormat = _mesa_base_tex_format(ctx, dst->InternalFormat); - if (srcFormat == dstLogicalFormat) { + /** + * XXX when we have red-only and red/green renderbuffers we'll need + * to add more cases here (or implement a general-purpose routine that + * queries the existance of the R,G,B,A channels in the src and dest). + */ + if (srcFormat == dstFormat) { /* This is the same as matching_base_formats, which should * always pass, as it did previously. */ return TGSI_WRITEMASK_XYZW; } - else if (srcFormat == GL_RGBA && - dstLogicalFormat == GL_RGB) { - /* Add a single special case to cope with RGBA->RGB transfers, - * setting A to 1.0 to cope with situations where the RGB - * destination is actually stored as RGBA. + else if (srcFormat == GL_RGB && dstFormat == GL_RGBA) { + /* Make sure that A in the dest is 1. The actual src format + * may be RGBA and have undefined A values. + */ + return TGSI_WRITEMASK_XYZ; + } + else if (srcFormat == GL_RGBA && dstFormat == GL_RGB) { + /* Make sure that A in the dest is 1. The actual dst format + * may be RGBA and will need A=1 to provide proper alpha values + * when sampled later. */ - return TGSI_WRITEMASK_XYZ; /* A ==> 1.0 */ + return TGSI_WRITEMASK_XYZ; } else { if (ST_DEBUG & DEBUG_FALLBACK) debug_printf("%s failed for src %s, dst %s\n", __FUNCTION__, _mesa_lookup_enum_by_nr(srcFormat), - _mesa_lookup_enum_by_nr(dstLogicalFormat)); + _mesa_lookup_enum_by_nr(dstFormat)); /* Otherwise fail. */ @@ -1505,7 +1535,7 @@ st_copy_texsubimage(GLcontext *ctx, matching_base_formats = (_mesa_get_format_base_format(strb->Base.Format) == _mesa_get_format_base_format(texImage->TexFormat)); - format_writemask = compatible_src_dst_formats(&strb->Base, texImage); + format_writemask = compatible_src_dst_formats(ctx, &strb->Base, texImage); if (ctx->_ImageTransferState == 0x0) { diff --git a/src/mesa/state_tracker/st_cb_viewport.c b/src/mesa/state_tracker/st_cb_viewport.c index ab11c5b4fe0..b29191abef6 100644 --- a/src/mesa/state_tracker/st_cb_viewport.c +++ b/src/mesa/state_tracker/st_cb_viewport.c @@ -27,14 +27,11 @@ #include "main/glheader.h" #include "st_context.h" -#include "st_public.h" #include "st_cb_viewport.h" #include "pipe/p_context.h" -#include "pipe/p_inlines.h" #include "pipe/p_state.h" #include "pipe/p_defines.h" -#include "pipe/internal/p_winsys_screen.h" static void st_viewport(GLcontext * ctx, GLint x, GLint y, diff --git a/src/mesa/state_tracker/st_context.c b/src/mesa/state_tracker/st_context.c index e4f18c842ca..8f6a0c2423b 100644 --- a/src/mesa/state_tracker/st_context.c +++ b/src/mesa/state_tracker/st_context.c @@ -27,11 +27,6 @@ #include "main/imports.h" #include "main/context.h" -#include "main/extensions.h" -#include "main/matrix.h" -#include "main/buffers.h" -#include "main/scissor.h" -#include "main/viewport.h" #include "vbo/vbo.h" #include "shader/shader_api.h" #include "glapi/glapi.h" @@ -48,7 +43,7 @@ #include "st_cb_drawpixels.h" #include "st_cb_rasterpos.h" #endif -#ifdef FEATURE_OES_draw_texture +#if FEATURE_OES_draw_texture #include "st_cb_drawtex.h" #endif #include "st_cb_fbo.h" @@ -68,8 +63,8 @@ #include "st_gen_mipmap.h" #include "st_program.h" #include "pipe/p_context.h" +#include "util/u_inlines.h" #include "draw/draw_context.h" -#include "cso_cache/cso_cache.h" #include "cso_cache/cso_context.h" @@ -209,7 +204,7 @@ static void st_destroy_context_priv( struct st_context *st ) st_destroy_bitmap(st); st_destroy_drawpix(st); #endif -#ifdef FEATURE_OES_draw_texture +#if FEATURE_OES_draw_texture st_destroy_drawtex(st); #endif @@ -218,8 +213,8 @@ static void st_destroy_context_priv( struct st_context *st ) } for (i = 0; i < Elements(st->state.constants); i++) { - if (st->state.constants[i].buffer) { - pipe_buffer_reference(&st->state.constants[i].buffer, NULL); + if (st->state.constants[i]) { + pipe_buffer_reference(&st->state.constants[i], NULL); } } @@ -330,6 +325,11 @@ void st_init_driver_functions(struct dd_function_table *functions) st_init_drawpixels_functions(functions); st_init_rasterpos_functions(functions); #endif + +#if FEATURE_OES_draw_texture + st_init_drawtex_functions(functions); +#endif + st_init_fbo_functions(functions); #if FEATURE_feedback st_init_feedback_functions(functions); diff --git a/src/mesa/state_tracker/st_context.h b/src/mesa/state_tracker/st_context.h index 831909a3f8f..50e98d7146a 100644 --- a/src/mesa/state_tracker/st_context.h +++ b/src/mesa/state_tracker/st_context.h @@ -92,7 +92,7 @@ struct st_context struct pipe_sampler_state samplers[PIPE_MAX_SAMPLERS]; struct pipe_sampler_state *sampler_list[PIPE_MAX_SAMPLERS]; struct pipe_clip_state clip; - struct pipe_constant_buffer constants[2]; + struct pipe_buffer *constants[2]; struct pipe_framebuffer_state framebuffer; struct pipe_texture *sampler_texture[PIPE_MAX_SAMPLERS]; struct pipe_scissor_state scissor; @@ -159,7 +159,7 @@ struct st_context /** for glDraw/CopyPixels */ struct { struct st_fragment_program *z_shader; - struct st_vertex_program *vert_shaders[2]; + void *vert_shaders[2]; /**< ureg shaders */ } drawpix; /** for glClear */ diff --git a/src/mesa/state_tracker/st_draw.c b/src/mesa/state_tracker/st_draw.c index e54f21be600..e1dcb154c1b 100644 --- a/src/mesa/state_tracker/st_draw.c +++ b/src/mesa/state_tracker/st_draw.c @@ -55,7 +55,7 @@ #include "pipe/p_context.h" #include "pipe/p_defines.h" -#include "pipe/p_inlines.h" +#include "util/u_inlines.h" static GLuint double_types[4] = { @@ -365,6 +365,7 @@ setup_interleaved_attribs(GLcontext *ctx, velements[attr].src_offset = (unsigned) (arrays[mesaAttr]->Ptr - offset0); + velements[attr].instance_divisor = 0; velements[attr].vertex_buffer_index = 0; velements[attr].nr_components = arrays[mesaAttr]->Size; velements[attr].src_format = @@ -454,6 +455,7 @@ setup_non_interleaved_attribs(GLcontext *ctx, /* common-case setup */ vbuffer[attr].stride = stride; /* in bytes */ vbuffer[attr].max_index = max_index; + velements[attr].instance_divisor = 0; velements[attr].vertex_buffer_index = attr; velements[attr].nr_components = arrays[mesaAttr]->Size; velements[attr].src_format @@ -522,7 +524,6 @@ st_draw_vbo(GLcontext *ctx, struct pipe_context *pipe = ctx->st->pipe; const struct st_vertex_program *vp; const struct st_vp_varient *vpv; - const struct pipe_shader_state *vs; struct pipe_vertex_buffer vbuffer[PIPE_MAX_SHADER_INPUTS]; GLuint attr; struct pipe_vertex_element velements[PIPE_MAX_ATTRIBS]; @@ -530,6 +531,9 @@ st_draw_vbo(GLcontext *ctx, GLboolean userSpace = GL_FALSE; GLboolean vertDataEdgeFlags; + /* Mesa core state should have been validated already */ + assert(ctx->NewState == 0x0); + /* Gallium probably doesn't want this in some cases. */ if (!index_bounds_valid) if (!vbo_all_varyings_in_vbos(arrays)) @@ -550,7 +554,6 @@ st_draw_vbo(GLcontext *ctx, /* must get these after state validation! */ vp = ctx->st->vp; vpv = ctx->st->vp_varient; - vs = &vpv->state; #if 0 if (MESA_VERBOSE & VERBOSE_GLSL) { diff --git a/src/mesa/state_tracker/st_draw_feedback.c b/src/mesa/state_tracker/st_draw_feedback.c index cfc0caac983..75ad1a97cf2 100644 --- a/src/mesa/state_tracker/st_draw_feedback.c +++ b/src/mesa/state_tracker/st_draw_feedback.c @@ -28,7 +28,6 @@ #include "main/imports.h" #include "main/image.h" #include "main/macros.h" -#include "shader/prog_uniform.h" #include "vbo/vbo.h" @@ -40,7 +39,7 @@ #include "pipe/p_context.h" #include "pipe/p_defines.h" -#include "pipe/p_inlines.h" +#include "util/u_inlines.h" #include "draw/draw_private.h" #include "draw/draw_context.h" @@ -177,6 +176,7 @@ st_feedback_draw_vbo(GLcontext *ctx, /* common-case setup */ vbuffers[attr].stride = arrays[mesaAttr]->StrideB; /* in bytes */ vbuffers[attr].max_index = max_index; + velements[attr].instance_divisor = 0; velements[attr].vertex_buffer_index = attr; velements[attr].nr_components = arrays[mesaAttr]->Size; velements[attr].src_format = @@ -239,11 +239,11 @@ st_feedback_draw_vbo(GLcontext *ctx, /* map constant buffers */ mapped_constants = pipe_buffer_map(pipe->screen, - st->state.constants[PIPE_SHADER_VERTEX].buffer, + st->state.constants[PIPE_SHADER_VERTEX], PIPE_BUFFER_USAGE_CPU_READ); - draw_set_mapped_constant_buffer(st->draw, PIPE_SHADER_VERTEX, + draw_set_mapped_constant_buffer(st->draw, PIPE_SHADER_VERTEX, 0, mapped_constants, - st->state.constants[PIPE_SHADER_VERTEX].buffer->size); + st->state.constants[PIPE_SHADER_VERTEX]->size); /* draw here */ @@ -253,7 +253,7 @@ st_feedback_draw_vbo(GLcontext *ctx, /* unmap constant buffers */ - pipe_buffer_unmap(pipe->screen, st->state.constants[PIPE_SHADER_VERTEX].buffer); + pipe_buffer_unmap(pipe->screen, st->state.constants[PIPE_SHADER_VERTEX]); /* * unmap vertex/index buffers diff --git a/src/mesa/state_tracker/st_extensions.c b/src/mesa/state_tracker/st_extensions.c index cf31a0c06ed..d5f58546613 100644 --- a/src/mesa/state_tracker/st_extensions.c +++ b/src/mesa/state_tracker/st_extensions.c @@ -28,7 +28,6 @@ #include "main/imports.h" #include "main/context.h" -#include "main/extensions.h" #include "main/macros.h" #include "pipe/p_context.h" @@ -157,6 +156,7 @@ void st_init_extensions(struct st_context *st) * Extensions that are supported by all Gallium drivers: */ ctx->Extensions.ARB_copy_buffer = GL_TRUE; + ctx->Extensions.ARB_fragment_coord_conventions = GL_TRUE; ctx->Extensions.ARB_fragment_program = GL_TRUE; ctx->Extensions.ARB_map_buffer_range = GL_TRUE; ctx->Extensions.ARB_multisample = GL_TRUE; @@ -177,6 +177,7 @@ void st_init_extensions(struct st_context *st) ctx->Extensions.EXT_blend_subtract = GL_TRUE; ctx->Extensions.EXT_framebuffer_blit = GL_TRUE; ctx->Extensions.EXT_framebuffer_object = GL_TRUE; + ctx->Extensions.EXT_framebuffer_multisample = GL_TRUE; ctx->Extensions.EXT_fog_coord = GL_TRUE; ctx->Extensions.EXT_multi_draw_arrays = GL_TRUE; ctx->Extensions.EXT_pixel_buffer_object = GL_TRUE; @@ -196,6 +197,10 @@ void st_init_extensions(struct st_context *st) ctx->Extensions.NV_texgen_reflection = GL_TRUE; ctx->Extensions.NV_texture_env_combine4 = GL_TRUE; +#if FEATURE_OES_draw_texture + ctx->Extensions.OES_draw_texture = GL_TRUE; +#endif + ctx->Extensions.SGI_color_matrix = GL_TRUE; ctx->Extensions.SGIS_generate_mipmap = GL_TRUE; @@ -319,4 +324,14 @@ void st_init_extensions(struct st_context *st) if (st->pipe->render_condition) { ctx->Extensions.NV_conditional_render = GL_TRUE; } + + if (screen->get_param(screen, PIPE_CAP_INDEP_BLEND_ENABLE)) { + ctx->Extensions.EXT_draw_buffers2 = GL_TRUE; + } + +#if 0 /* not yet */ + if (screen->get_param(screen, PIPE_CAP_INDEP_BLEND_FUNC)) { + ctx->Extensions.ARB_draw_buffers_blend = GL_TRUE; + } +#endif } diff --git a/src/mesa/state_tracker/st_format.c b/src/mesa/state_tracker/st_format.c index d00b67a279e..3ffc2aee2a2 100644 --- a/src/mesa/state_tracker/st_format.c +++ b/src/mesa/state_tracker/st_format.c @@ -35,7 +35,6 @@ #include "main/imports.h" #include "main/context.h" #include "main/texstore.h" -#include "main/texformat.h" #include "main/enums.h" #include "main/macros.h" @@ -288,6 +287,8 @@ st_pipe_format_to_mesa_format(enum pipe_format pipeFormat) return MESA_FORMAT_XRGB8888; case PIPE_FORMAT_B8G8R8A8_UNORM: return MESA_FORMAT_ARGB8888_REV; + case PIPE_FORMAT_B8G8R8X8_UNORM: + return MESA_FORMAT_XRGB8888_REV; case PIPE_FORMAT_A1R5G5B5_UNORM: return MESA_FORMAT_ARGB1555; case PIPE_FORMAT_A4R4G4B4_UNORM: diff --git a/src/mesa/state_tracker/st_framebuffer.c b/src/mesa/state_tracker/st_framebuffer.c index a5d1ae3b034..4e225a123c8 100644 --- a/src/mesa/state_tracker/st_framebuffer.c +++ b/src/mesa/state_tracker/st_framebuffer.c @@ -30,15 +30,12 @@ #include "main/buffers.h" #include "main/context.h" #include "main/framebuffer.h" -#include "main/matrix.h" #include "main/renderbuffer.h" -#include "main/scissor.h" -#include "main/viewport.h" #include "st_context.h" #include "st_cb_fbo.h" #include "st_public.h" #include "pipe/p_defines.h" -#include "pipe/p_context.h" +#include "util/u_inlines.h" struct st_framebuffer * @@ -57,7 +54,7 @@ st_create_framebuffer( const __GLcontextModes *visual, if (visual->sampleBuffers) samples = visual->samples; - _mesa_initialize_framebuffer(&stfb->Base, visual); + _mesa_initialize_window_framebuffer(&stfb->Base, visual); if (visual->doubleBufferMode) { struct gl_renderbuffer *rb diff --git a/src/mesa/state_tracker/st_gen_mipmap.c b/src/mesa/state_tracker/st_gen_mipmap.c index 2c283d464ae..f67d7b4cb5c 100644 --- a/src/mesa/state_tracker/st_gen_mipmap.c +++ b/src/mesa/state_tracker/st_gen_mipmap.c @@ -36,7 +36,7 @@ #include "pipe/p_context.h" #include "pipe/p_defines.h" -#include "pipe/p_inlines.h" +#include "util/u_inlines.h" #include "util/u_format.h" #include "util/u_gen_mipmap.h" #include "util/u_math.h" @@ -46,9 +46,7 @@ #include "st_debug.h" #include "st_context.h" -#include "st_draw.h" #include "st_gen_mipmap.h" -#include "st_program.h" #include "st_texture.h" #include "st_cb_texture.h" #include "st_inlines.h" diff --git a/src/mesa/state_tracker/st_inlines.h b/src/mesa/state_tracker/st_inlines.h index a41cfeb96f7..e105870bc75 100644 --- a/src/mesa/state_tracker/st_inlines.h +++ b/src/mesa/state_tracker/st_inlines.h @@ -36,7 +36,7 @@ #include "pipe/p_context.h" #include "pipe/p_screen.h" #include "pipe/p_defines.h" -#include "pipe/p_inlines.h" +#include "util/u_inlines.h" #include "pipe/p_state.h" #include "st_context.h" @@ -126,6 +126,16 @@ st_no_flush_pipe_buffer_write(struct st_context *st, } static INLINE void +st_no_flush_pipe_buffer_write_nooverlap(struct st_context *st, + struct pipe_buffer *buf, + unsigned int offset, + unsigned int size, + const void * data) +{ + pipe_buffer_write_nooverlap(st->pipe->screen, buf, offset, size, data); +} + +static INLINE void st_cond_flush_pipe_buffer_read(struct st_context *st, struct pipe_buffer *buf, unsigned int offset, diff --git a/src/mesa/state_tracker/st_mesa_to_tgsi.c b/src/mesa/state_tracker/st_mesa_to_tgsi.c index 4830a8f383a..537a6a86482 100644 --- a/src/mesa/state_tracker/st_mesa_to_tgsi.c +++ b/src/mesa/state_tracker/st_mesa_to_tgsi.c @@ -34,11 +34,12 @@ #include "pipe/p_compiler.h" #include "pipe/p_shader_tokens.h" #include "pipe/p_state.h" +#include "pipe/p_context.h" #include "tgsi/tgsi_ureg.h" #include "st_mesa_to_tgsi.h" +#include "st_context.h" #include "shader/prog_instruction.h" #include "shader/prog_parameter.h" -#include "shader/prog_print.h" #include "util/u_debug.h" #include "util/u_math.h" #include "util/u_memory.h" @@ -48,6 +49,10 @@ struct label { unsigned token; }; + +/** + * Intermediate state used during shader translation. + */ struct st_translate { struct ureg_program *ureg; @@ -178,13 +183,13 @@ src_register( struct st_translate *t, t->temps[index] = ureg_DECL_temporary( t->ureg ); return ureg_src(t->temps[index]); - case PROGRAM_STATE_VAR: case PROGRAM_NAMED_PARAM: case PROGRAM_ENV_PARAM: case PROGRAM_LOCAL_PARAM: case PROGRAM_UNIFORM: ASSERT(index >= 0); return t->constants[index]; + case PROGRAM_STATE_VAR: case PROGRAM_CONSTANT: /* ie, immediate */ if (index < 0) return ureg_DECL_constant( t->ureg, 0 ); @@ -667,6 +672,22 @@ compile_instruction( } } +/** + * Emit the TGSI instructions to adjust the WPOS pixel center convention + */ +static void +emit_adjusted_wpos( struct st_translate *t, + const struct gl_program *program, GLfloat value) +{ + struct ureg_program *ureg = t->ureg; + struct ureg_dst wpos_temp = ureg_DECL_temporary(ureg); + struct ureg_src wpos_input = t->inputs[t->inputMapping[FRAG_ATTRIB_WPOS]]; + + ureg_ADD(ureg, ureg_writemask(wpos_temp, TGSI_WRITEMASK_X | TGSI_WRITEMASK_Y), + wpos_input, ureg_imm1f(ureg, value)); + + t->inputs[t->inputMapping[FRAG_ATTRIB_WPOS]] = ureg_src(wpos_temp); +} /** * Emit the TGSI instructions for inverting the WPOS y coordinate. @@ -692,12 +713,17 @@ emit_inverted_wpos( struct st_translate *t, winSizeState); struct ureg_src winsize = ureg_DECL_constant( ureg, winHeightConst ); - struct ureg_dst wpos_temp = ureg_DECL_temporary( ureg ); + struct ureg_dst wpos_temp; struct ureg_src wpos_input = t->inputs[t->inputMapping[FRAG_ATTRIB_WPOS]]; /* MOV wpos_temp, input[wpos] */ - ureg_MOV( ureg, wpos_temp, wpos_input ); + if (wpos_input.File == TGSI_FILE_TEMPORARY) + wpos_temp = ureg_dst(wpos_input); + else { + wpos_temp = ureg_DECL_temporary( ureg ); + ureg_MOV( ureg, wpos_temp, wpos_input ); + } /* SUB wpos_temp.y, winsize_const, wpos_input */ @@ -736,6 +762,7 @@ emit_face_var( struct st_translate *t, t->inputs[t->inputMapping[FRAG_ATTRIB_FACE]] = ureg_src(face_temp); } + static void emit_edgeflags( struct st_translate *t, const struct gl_program *program ) @@ -747,6 +774,7 @@ emit_edgeflags( struct st_translate *t, ureg_MOV( ureg, edge_dst, edge_src ); } + /** * Translate Mesa program to TGSI format. * \param program the program to translate @@ -764,7 +792,7 @@ emit_edgeflags( struct st_translate *t, * \param outputSemanticIndex the semantic index (ex: which texcoord) for * each output * - * \return array of translated tokens, caller's responsibility to free + * \return PIPE_OK or PIPE_ERROR_OUT_OF_MEMORY */ enum pipe_error st_translate_mesa_program( @@ -785,6 +813,7 @@ st_translate_mesa_program( { struct st_translate translate, *t; unsigned i; + enum pipe_error ret = PIPE_OK; t = &translate; memset(t, 0, sizeof *t); @@ -802,18 +831,72 @@ st_translate_mesa_program( * Declare input attributes. */ if (procType == TGSI_PROCESSOR_FRAGMENT) { + struct gl_fragment_program* fp = (struct gl_fragment_program*)program; for (i = 0; i < numInputs; i++) { - t->inputs[i] = ureg_DECL_fs_input(ureg, - inputSemanticName[i], - inputSemanticIndex[i], - interpMode[i]); + if (program->InputFlags[0] & PROG_PARAM_BIT_CYL_WRAP) { + t->inputs[i] = ureg_DECL_fs_input_cyl(ureg, + inputSemanticName[i], + inputSemanticIndex[i], + interpMode[i], + TGSI_CYLINDRICAL_WRAP_X); + } + else { + t->inputs[i] = ureg_DECL_fs_input(ureg, + inputSemanticName[i], + inputSemanticIndex[i], + interpMode[i]); + } } if (program->InputsRead & FRAG_BIT_WPOS) { /* Must do this after setting up t->inputs, and before * emitting constant references, below: */ - emit_inverted_wpos( t, program ); + struct pipe_screen* pscreen = st_context(ctx)->pipe->screen; + boolean invert = FALSE; + + if (fp->OriginUpperLeft) { + if (pscreen->get_param(pscreen, PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT)) { + } + else if (pscreen->get_param(pscreen, PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT)) { + ureg_property_fs_coord_origin(ureg, TGSI_FS_COORD_ORIGIN_LOWER_LEFT); + invert = TRUE; + } + else + assert(0); + } + else { + if (pscreen->get_param(pscreen, PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT)) + ureg_property_fs_coord_origin(ureg, TGSI_FS_COORD_ORIGIN_LOWER_LEFT); + else if (pscreen->get_param(pscreen, PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT)) + invert = TRUE; + else + assert(0); + } + + if (fp->PixelCenterInteger) { + if (pscreen->get_param(pscreen, PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER)) + ureg_property_fs_coord_pixel_center(ureg, TGSI_FS_COORD_PIXEL_CENTER_INTEGER); + else if (pscreen->get_param(pscreen, PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER)) + emit_adjusted_wpos(t, program, invert ? 0.5f : -0.5f); + else + assert(0); + } + else { + if (pscreen->get_param(pscreen, PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER)) { + } + else if (pscreen->get_param(pscreen, PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER)) { + ureg_property_fs_coord_pixel_center(ureg, TGSI_FS_COORD_PIXEL_CENTER_INTEGER); + emit_adjusted_wpos(t, program, invert ? -0.5f : 0.5f); + } + else + assert(0); + } + + /* we invert after adjustment so that we avoid the MOV to temporary, + * and reuse the adjustment ADD instead */ + if (invert) + emit_inverted_wpos(t, program); } if (program->InputsRead & FRAG_BIT_FACE) { @@ -888,8 +971,10 @@ st_translate_mesa_program( t->constants = CALLOC( program->Parameters->NumParameters, sizeof t->constants[0] ); - if (t->constants == NULL) + if (t->constants == NULL) { + ret = PIPE_ERROR_OUT_OF_MEMORY; goto out; + } for (i = 0; i < program->Parameters->NumParameters; i++) { switch (program->Parameters->Parameters[i].Type) { @@ -956,8 +1041,6 @@ st_translate_mesa_program( t->insn[t->labels[i].branch_target] ); } - return PIPE_OK; - out: FREE(t->insn); FREE(t->labels); @@ -967,7 +1050,7 @@ out: debug_printf("%s: translate error flag set\n", __FUNCTION__); } - return PIPE_ERROR_OUT_OF_MEMORY; + return ret; } diff --git a/src/mesa/state_tracker/st_program.c b/src/mesa/state_tracker/st_program.c index 6a869fae904..21ad6fef2b4 100644 --- a/src/mesa/state_tracker/st_program.c +++ b/src/mesa/state_tracker/st_program.c @@ -44,7 +44,6 @@ #include "st_debug.h" #include "st_context.h" -#include "st_atom.h" #include "st_program.h" #include "st_mesa_to_tgsi.h" #include "cso_cache/cso_context.h" @@ -270,24 +269,20 @@ fail: /** * Translate a Mesa fragment shader into a TGSI shader. - * \param inputMapping to map fragment program input registers to TGSI - * input slots * \return pointer to cached pipe_shader object. */ void st_translate_fragment_program(struct st_context *st, - struct st_fragment_program *stfp, - const GLuint inputMapping[]) + struct st_fragment_program *stfp ) { struct pipe_context *pipe = st->pipe; GLuint outputMapping[FRAG_RESULT_MAX]; - GLuint defaultInputMapping[FRAG_ATTRIB_MAX]; + GLuint inputMapping[FRAG_ATTRIB_MAX]; GLuint interpMode[16]; /* XXX size? */ GLuint attr; enum pipe_error error; const GLbitfield inputsRead = stfp->Base.Base.InputsRead; struct ureg_program *ureg; - GLuint vslot = 0; uint fs_num_inputs = 0; @@ -295,24 +290,14 @@ st_translate_fragment_program(struct st_context *st, ubyte fs_output_semantic_index[PIPE_MAX_SHADER_OUTPUTS]; uint fs_num_outputs = 0; - /* which vertex output goes to the first fragment input: */ - if (inputsRead & FRAG_BIT_WPOS) - vslot = 0; - else - vslot = 1; - /* * Convert Mesa program inputs to TGSI input register semantics. */ for (attr = 0; attr < FRAG_ATTRIB_MAX; attr++) { if (inputsRead & (1 << attr)) { - const GLuint slot = fs_num_inputs; - - defaultInputMapping[attr] = slot; + const GLuint slot = fs_num_inputs++; - stfp->input_map[slot] = vslot++; - - fs_num_inputs++; + inputMapping[attr] = slot; switch (attr) { case FRAG_ATTRIB_WPOS: @@ -340,6 +325,16 @@ st_translate_fragment_program(struct st_context *st, stfp->input_semantic_index[slot] = 0; interpMode[slot] = TGSI_INTERPOLATE_CONSTANT; break; + case FRAG_ATTRIB_PNTC: + /* This is a hack. We really need a new semantic label for + * point coord. The draw module needs to know which fragment + * shader input is the point coord attribute so that it can set + * up the right vertex attribute values. + */ + stfp->input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC; + stfp->input_semantic_index[slot] = 0; + interpMode[slot] = TGSI_INTERPOLATE_PERSPECTIVE; + break; /* In most cases, there is nothing special about these * inputs, so adopt a convention to use the generic @@ -364,7 +359,6 @@ st_translate_fragment_program(struct st_context *st, case FRAG_ATTRIB_TEX5: case FRAG_ATTRIB_TEX6: case FRAG_ATTRIB_TEX7: - case FRAG_ATTRIB_PNTC: case FRAG_ATTRIB_VAR0: default: /* Actually, let's try and zero-base this just for @@ -377,6 +371,9 @@ st_translate_fragment_program(struct st_context *st, break; } } + else { + inputMapping[attr] = -1; + } } /* @@ -418,9 +415,6 @@ st_translate_fragment_program(struct st_context *st, } } - if (!inputMapping) - inputMapping = defaultInputMapping; - ureg = ureg_create( TGSI_PROCESSOR_FRAGMENT ); if (ureg == NULL) return; diff --git a/src/mesa/state_tracker/st_program.h b/src/mesa/state_tracker/st_program.h index 6b9a9226df5..d9822e50f55 100644 --- a/src/mesa/state_tracker/st_program.h +++ b/src/mesa/state_tracker/st_program.h @@ -52,12 +52,6 @@ struct st_fragment_program struct gl_fragment_program Base; GLuint serialNo; - GLuint input_to_slot[FRAG_ATTRIB_MAX]; /**< Maps FRAG_ATTRIB_x to slot */ - GLuint num_input_slots; - - /** map FP input back to VP output */ - GLuint input_map[PIPE_MAX_SHADER_INPUTS]; - ubyte input_semantic_name[PIPE_MAX_SHADER_INPUTS]; ubyte input_semantic_index[PIPE_MAX_SHADER_INPUTS]; @@ -171,8 +165,7 @@ st_reference_fragprog(struct st_context *st, extern void st_translate_fragment_program(struct st_context *st, - struct st_fragment_program *fp, - const GLuint inputMapping[]); + struct st_fragment_program *fp); /* Called after program string change, discard all previous diff --git a/src/mesa/state_tracker/st_texture.c b/src/mesa/state_tracker/st_texture.c index 8a3e4cd3ac3..5a45c4358a9 100644 --- a/src/mesa/state_tracker/st_texture.c +++ b/src/mesa/state_tracker/st_texture.c @@ -35,14 +35,13 @@ #include "main/texfetch.h" #include "main/teximage.h" #include "main/texobj.h" -#include "main/texstore.h" #undef Elements /* fix re-defined macro warning */ #include "pipe/p_state.h" #include "pipe/p_context.h" #include "pipe/p_defines.h" -#include "pipe/p_inlines.h" +#include "util/u_inlines.h" #include "util/u_format.h" #include "util/u_rect.h" #include "util/u_math.h" |