diff options
Diffstat (limited to 'src/gallium')
77 files changed, 2086 insertions, 1831 deletions
diff --git a/src/gallium/auxiliary/draw/draw_vs_exec.c b/src/gallium/auxiliary/draw/draw_vs_exec.c index dbbc33fffa..f2368dde5c 100644 --- a/src/gallium/auxiliary/draw/draw_vs_exec.c +++ b/src/gallium/auxiliary/draw/draw_vs_exec.c @@ -114,6 +114,12 @@ vs_exec_run_linear( struct draw_vertex_shader *shader,  #endif           for (slot = 0; slot < shader->info.num_inputs; slot++) { +#if 0 +            assert(!util_is_inf_or_nan(input[slot][0])); +            assert(!util_is_inf_or_nan(input[slot][1])); +            assert(!util_is_inf_or_nan(input[slot][2])); +            assert(!util_is_inf_or_nan(input[slot][3])); +#endif              machine->Inputs[slot].xyzw[0].f[j] = input[slot][0];              machine->Inputs[slot].xyzw[1].f[j] = input[slot][1];              machine->Inputs[slot].xyzw[2].f[j] = input[slot][2]; diff --git a/src/gallium/auxiliary/trace/trace_drm.h b/src/gallium/auxiliary/trace/trace_drm.h new file mode 100644 index 0000000000..892bd9860c --- /dev/null +++ b/src/gallium/auxiliary/trace/trace_drm.h @@ -0,0 +1,165 @@ +/* + * Copyright 2009 Jakob Bornecrantz <jakob@vmware.com> + *                Corbin Simpson <MostAwesomeDude@gmail.com> + * + * 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 + * on 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 + * THE AUTHOR(S) AND/OR THEIR 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. */ + +#ifndef TRACE_DRM_H +#define TRACE_DRM_H + +#include "state_tracker/drm_api.h" + +#include "trace/tr_buffer.h" +#include "trace/tr_context.h" +#include "trace/tr_screen.h" +#include "trace/tr_texture.h" + +struct drm_api hooks; + +static struct pipe_screen * +trace_drm_create_screen(int fd, struct drm_create_screen_arg *arg) +{ +	struct pipe_screen *screen; + +	if (arg && arg->mode != DRM_CREATE_NORMAL) +		return NULL; + +	screen = hooks.create_screen(fd, arg); + +	return trace_screen_create(screen); +}; + +static struct pipe_context * +trace_drm_create_context(struct pipe_screen *_screen) +{ +	struct pipe_screen *screen; +	struct pipe_context *pipe; + +	if (trace_enabled()) +		screen = trace_screen(_screen)->screen; +	else +		screen = _screen; + +	pipe = hooks.create_context(screen); + +	if (trace_enabled()) +		pipe = trace_context_create(_screen, pipe); + +	return pipe; +}; + +static boolean +trace_drm_buffer_from_texture(struct pipe_texture *_texture, +                              struct pipe_buffer **_buffer, +                              unsigned *stride) +{ +	struct pipe_texture *texture; +	struct pipe_buffer *buffer = NULL; +	boolean result; + +	if (trace_enabled()) +		texture = trace_texture(_texture)->texture; +	else +		texture = _texture; + +	result = hooks.buffer_from_texture(texture, &buffer, stride); + +	if (result && _buffer) +		buffer = trace_buffer_create(trace_screen(texture->screen), buffer); + +	if (_buffer) +		*_buffer = buffer; +	else +		pipe_buffer_reference(&buffer, NULL); + +	return result; +} + +static struct pipe_buffer * +trace_drm_buffer_from_handle(struct pipe_screen *_screen, +                             const char *name, +                             unsigned handle) +{ +	struct pipe_screen *screen; +	struct pipe_buffer *result; + +	if (trace_enabled()) +		screen = trace_screen(_screen)->screen; +	else +		screen = _screen; + +	result = hooks.buffer_from_handle(screen, name, handle); + +	if (trace_enabled()) +		result = trace_buffer_create(trace_screen(_screen), result); + +	return result; +} + +static boolean +trace_drm_handle_from_buffer(struct pipe_screen *_screen, +                             struct pipe_buffer *_buffer, +                             unsigned *handle) +{ +	struct pipe_screen *screen; +	struct pipe_buffer *buffer; + +	if (trace_enabled()) { +		screen = trace_screen(_screen)->screen; +		buffer = trace_buffer(_buffer)->buffer; +	} else { +		screen = _screen; +		buffer = _buffer; +	} + +	return hooks.handle_from_buffer(screen, buffer, handle); +} + +static boolean +trace_drm_global_handle_from_buffer(struct pipe_screen *_screen, +                                    struct pipe_buffer *_buffer, +                                    unsigned *handle) +{ +	struct pipe_screen *screen; +	struct pipe_buffer *buffer; + +	if (trace_enabled()) { +		screen = trace_screen(_screen)->screen; +		buffer = trace_buffer(_buffer)->buffer; +	} else { +		screen = _screen; +		buffer = _buffer; +	} + +	return hooks.global_handle_from_buffer(screen, buffer, handle); +} + +struct drm_api drm_api_hooks = +{ +	.create_screen = trace_drm_create_screen, +	.create_context = trace_drm_create_context, + +	.buffer_from_texture = trace_drm_buffer_from_texture, +	.buffer_from_handle = trace_drm_buffer_from_handle, +	.handle_from_buffer = trace_drm_handle_from_buffer, +	.global_handle_from_buffer = trace_drm_global_handle_from_buffer, +}; + +#endif /* TRACE_DRM_H */ diff --git a/src/gallium/drivers/cell/spu/spu_render.c b/src/gallium/drivers/cell/spu/spu_render.c index 7c225e2f27..5ffb7073ab 100644 --- a/src/gallium/drivers/cell/spu/spu_render.c +++ b/src/gallium/drivers/cell/spu/spu_render.c @@ -32,6 +32,7 @@  #include "spu_main.h"  #include "spu_render.h" +#include "spu_shuffle.h"  #include "spu_tri.h"  #include "spu_tile.h"  #include "cell/common.h" @@ -267,15 +268,75 @@ cmd_render(const struct cell_command_render *render, uint *pos_incr)        uint drawn = 0; -      /* loop over tris */ -      for (j = 0; j < render->num_indexes; j += 3) { -         const float *v0, *v1, *v2; +      const qword vertex_sizes = (qword)spu_splats(vertex_size); +      const qword verticess = (qword)spu_splats((uint)vertices); -         v0 = (const float *) (vertices + indexes[j+0] * vertex_size); -         v1 = (const float *) (vertices + indexes[j+1] * vertex_size); -         v2 = (const float *) (vertices + indexes[j+2] * vertex_size); +      ASSERT_ALIGN16(&indexes[0]); -         drawn += tri_draw(v0, v1, v2, tx, ty); +      const uint num_indexes = render->num_indexes; + +      /* loop over tris +	   * &indexes[0] will be 16 byte aligned.  This loop is heavily unrolled +	   * avoiding variable rotates when extracting vertex indices. +	   */ +      for (j = 0; j < num_indexes; j += 24) { +         /* Load three vectors, containing 24 ushort indices */ +         const qword* lower_qword = (qword*)&indexes[j]; +         const qword indices0 = lower_qword[0]; +         const qword indices1 = lower_qword[1]; +         const qword indices2 = lower_qword[2]; + +         /* stores three indices for each tri n in slots 0, 1 and 2 of vsn */ +		 /* Straightforward rotates for these */ +         qword vs0 = indices0; +         qword vs1 = si_shlqbyi(indices0, 6); +         qword vs3 = si_shlqbyi(indices1, 2); +         qword vs4 = si_shlqbyi(indices1, 8); +         qword vs6 = si_shlqbyi(indices2, 4); +         qword vs7 = si_shlqbyi(indices2, 10); + +         /* For tri 2 and 5, the three indices are split across two machine +		  * words - rotate and combine */ +         const qword tmp2a = si_shlqbyi(indices0, 12); +         const qword tmp2b = si_rotqmbyi(indices1, 12|16); +         qword vs2 = si_selb(tmp2a, tmp2b, si_fsmh(si_from_uint(0x20))); + +         const qword tmp5a = si_shlqbyi(indices1, 14); +         const qword tmp5b = si_rotqmbyi(indices2, 14|16); +         qword vs5 = si_selb(tmp5a, tmp5b, si_fsmh(si_from_uint(0x60))); + +         /* unpack indices from halfword slots to word slots */ +         vs0 = si_shufb(vs0, vs0, SHUFB8(0,A,0,B,0,C,0,0)); +         vs1 = si_shufb(vs1, vs1, SHUFB8(0,A,0,B,0,C,0,0)); +         vs2 = si_shufb(vs2, vs2, SHUFB8(0,A,0,B,0,C,0,0)); +         vs3 = si_shufb(vs3, vs3, SHUFB8(0,A,0,B,0,C,0,0)); +         vs4 = si_shufb(vs4, vs4, SHUFB8(0,A,0,B,0,C,0,0)); +         vs5 = si_shufb(vs5, vs5, SHUFB8(0,A,0,B,0,C,0,0)); +         vs6 = si_shufb(vs6, vs6, SHUFB8(0,A,0,B,0,C,0,0)); +         vs7 = si_shufb(vs7, vs7, SHUFB8(0,A,0,B,0,C,0,0)); + +         /* Calculate address of vertex in vertices[] */ +         vs0 = si_mpya(vs0, vertex_sizes, verticess); +         vs1 = si_mpya(vs1, vertex_sizes, verticess); +         vs2 = si_mpya(vs2, vertex_sizes, verticess); +         vs3 = si_mpya(vs3, vertex_sizes, verticess); +         vs4 = si_mpya(vs4, vertex_sizes, verticess); +         vs5 = si_mpya(vs5, vertex_sizes, verticess); +         vs6 = si_mpya(vs6, vertex_sizes, verticess); +         vs7 = si_mpya(vs7, vertex_sizes, verticess); + +         /* Select the appropriate call based on the number of vertices  +		  * remaining */ +         switch(num_indexes - j) { +            default: drawn += tri_draw(vs7, tx, ty); +            case 21: drawn += tri_draw(vs6, tx, ty); +            case 18: drawn += tri_draw(vs5, tx, ty); +            case 15: drawn += tri_draw(vs4, tx, ty); +            case 12: drawn += tri_draw(vs3, tx, ty); +            case 9:  drawn += tri_draw(vs2, tx, ty); +            case 6:  drawn += tri_draw(vs1, tx, ty); +            case 3:  drawn += tri_draw(vs0, tx, ty); +         }        }        //printf("SPU %u: drew %u of %u\n", spu.init.id, drawn, render->num_indexes/3); diff --git a/src/gallium/drivers/cell/spu/spu_tri.c b/src/gallium/drivers/cell/spu/spu_tri.c index d727268475..58be001be4 100644 --- a/src/gallium/drivers/cell/spu/spu_tri.c +++ b/src/gallium/drivers/cell/spu/spu_tri.c @@ -133,7 +133,15 @@ struct setup_stage {     uint tx, ty;  /**< position of current tile (x, y) */ -   int cliprect_minx, cliprect_maxx, cliprect_miny, cliprect_maxy; +   union { +      struct { +         int cliprect_minx; +         int cliprect_miny; +         int cliprect_maxx; +         int cliprect_maxy; +      }; +      qword cliprect; +   };     struct interp_coef coef[PIPE_MAX_SHADER_INPUTS]; @@ -432,6 +440,41 @@ print_vertex(const struct vertex_header *v)  }  #endif +/* Returns the minimum of each slot of two vec_float4s as qwords. + * i.e. return[n] = min(q0[n],q1[n]); + */ +static qword +minfq(qword q0, qword q1) +{ +   const qword q0q1m = si_fcgt(q0, q1); +   return si_selb(q0, q1, q0q1m); +} + +/* Returns the minimum of each slot of three vec_float4s as qwords. + * i.e. return[n] = min(q0[n],q1[n],q2[n]); + */ +static qword +min3fq(qword q0, qword q1, qword q2) +{ +   return minfq(minfq(q0, q1), q2); +} + +/* Returns the maximum of each slot of two vec_float4s as qwords. + * i.e. return[n] = min(q0[n],q1[n],q2[n]); + */ +static qword +maxfq(qword q0, qword q1) { +   const qword q0q1m = si_fcgt(q0, q1); +   return si_selb(q1, q0, q0q1m); +} + +/* Returns the maximum of each slot of three vec_float4s as qwords. + * i.e. return[n] = min(q0[n],q1[n],q2[n]); + */ +static qword +max3fq(qword q0, qword q1, qword q2) { +   return maxfq(maxfq(q0, q1), q2); +}  /**   * Sort vertices from top to bottom. @@ -440,9 +483,7 @@ print_vertex(const struct vertex_header *v)   * \return  FALSE if tri is totally outside tile, TRUE otherwise   */  static boolean -setup_sort_vertices(const struct vertex_header *v0, -                    const struct vertex_header *v1, -                    const struct vertex_header *v2) +setup_sort_vertices(const qword vs)  {     float area, sign; @@ -455,57 +496,57 @@ setup_sort_vertices(const struct vertex_header *v0,     }  #endif -   /* determine bottom to top order of vertices */     { +      /* Load the float values for various processing... */ +      const qword f0 = (qword)(((const struct vertex_header*)si_to_ptr(vs))->data[0]); +      const qword f1 = (qword)(((const struct vertex_header*)si_to_ptr(si_rotqbyi(vs, 4)))->data[0]); +      const qword f2 = (qword)(((const struct vertex_header*)si_to_ptr(si_rotqbyi(vs, 8)))->data[0]); + +      /* Check if triangle is completely outside the tile bounds +       * Find the min and max x and y positions of the three poits */ +      const qword minf = min3fq(f0, f1, f2); +      const qword maxf = max3fq(f0, f1, f2); + +      /* Compare min and max against cliprect vals */ +      const qword maxsmins = si_shufb(maxf, minf, SHUFB4(A,B,a,b)); +      const qword outside = si_fcgt(maxsmins, si_csflt(setup.cliprect, 0)); + +      /* Use a little magic to work out of the tri is visible or not */ +      if(si_to_uint(si_xori(si_gb(outside), 0xc))) return FALSE; + +      /* determine bottom to top order of vertices */        /* A table of shuffle patterns for putting vertex_header pointers into           correct order.  Quite magical. */ -      const vec_uchar16 sort_order_patterns[] = { -         SHUFFLE4(A,B,C,C), -         SHUFFLE4(C,A,B,C), -         SHUFFLE4(A,C,B,C), -         SHUFFLE4(B,C,A,C), -         SHUFFLE4(B,A,C,C), -         SHUFFLE4(C,B,A,C) }; - -      /* The vertex_header pointers, packed for easy shuffling later */ -      const vec_uint4 vs = {(unsigned)v0, (unsigned)v1, (unsigned)v2}; +      const qword sort_order_patterns[] = { +         SHUFB4(A,B,C,C), +         SHUFB4(C,A,B,C), +         SHUFB4(A,C,B,C), +         SHUFB4(B,C,A,C), +         SHUFB4(B,A,C,C), +         SHUFB4(C,B,A,C) };        /* Collate y values into two vectors for comparison.           Using only one shuffle constant! ;) */ -      const vec_float4 y_02_ = spu_shuffle(v0->data[0], v2->data[0], SHUFFLE4(0,B,b,C)); -      const vec_float4 y_10_ = spu_shuffle(v1->data[0], v0->data[0], SHUFFLE4(0,B,b,C)); -      const vec_float4 y_012 = spu_shuffle(y_02_, v1->data[0], SHUFFLE4(0,B,b,C)); -      const vec_float4 y_120 = spu_shuffle(y_10_, v2->data[0], SHUFFLE4(0,B,b,C)); +      const qword y_02_ = si_shufb(f0, f2, SHUFB4(0,B,b,C)); +      const qword y_10_ = si_shufb(f1, f0, SHUFB4(0,B,b,C)); +      const qword y_012 = si_shufb(y_02_, f1, SHUFB4(0,B,b,C)); +      const qword y_120 = si_shufb(y_10_, f2, SHUFB4(0,B,b,C));        /* Perform comparison: {y0,y1,y2} > {y1,y2,y0} */ -      const vec_uint4 compare = spu_cmpgt(y_012, y_120); +      const qword compare = si_fcgt(y_012, y_120);        /* Compress the result of the comparison into 4 bits */ -      const vec_uint4 gather = spu_gather(compare); +      const qword gather = si_gb(compare);        /* Subtract one to attain the index into the LUT.  Magical. */ -      const unsigned int index = spu_extract(gather, 0) - 1; +      const unsigned int index = si_to_uint(gather) - 1;        /* Load the appropriate pattern and construct the desired vector. */ -      setup.vertex_headers = (qword)spu_shuffle(vs, vs, sort_order_patterns[index]); +      setup.vertex_headers = si_shufb(vs, vs, sort_order_patterns[index]);        /* Using the result of the comparison, set sign.           Very magical. */ -      sign = ((si_to_uint(si_cntb((qword)gather)) == 2) ? 1.0f : -1.0f); +      sign = ((si_to_uint(si_cntb(gather)) == 2) ? 1.0f : -1.0f);     } -   /* Check if triangle is completely outside the tile bounds */ -   if (spu_extract(setup.vmin->data[0], 1) > setup.cliprect_maxy) -      return FALSE; -   if (spu_extract(setup.vmax->data[0], 1) < setup.cliprect_miny) -      return FALSE; -   if (spu_extract(setup.vmin->data[0], 0) < setup.cliprect_minx && -       spu_extract(setup.vmid->data[0], 0) < setup.cliprect_minx && -       spu_extract(setup.vmax->data[0], 0) < setup.cliprect_minx) -      return FALSE; -   if (spu_extract(setup.vmin->data[0], 0) > setup.cliprect_maxx && -       spu_extract(setup.vmid->data[0], 0) > setup.cliprect_maxx && -       spu_extract(setup.vmax->data[0], 0) > setup.cliprect_maxx) -      return FALSE; -     setup.ebot.ds = spu_sub(setup.vmid->data[0], setup.vmin->data[0]);     setup.emaj.ds = spu_sub(setup.vmax->data[0], setup.vmin->data[0]);     setup.etop.ds = spu_sub(setup.vmax->data[0], setup.vmid->data[0]); @@ -761,21 +802,19 @@ subtriangle(struct edge *eleft, struct edge *eright, unsigned lines)   * The tile data should have already been fetched.   */  boolean -tri_draw(const float *v0, const float *v1, const float *v2, +tri_draw(const qword vs,           uint tx, uint ty)  {     setup.tx = tx;     setup.ty = ty;     /* set clipping bounds to tile bounds */ -   setup.cliprect_minx = tx * TILE_SIZE; -   setup.cliprect_miny = ty * TILE_SIZE; -   setup.cliprect_maxx = (tx + 1) * TILE_SIZE; -   setup.cliprect_maxy = (ty + 1) * TILE_SIZE; +   const qword clipbase = (qword)((vec_uint4){tx, ty}); +   const qword clipmin = si_mpyui(clipbase, TILE_SIZE); +   const qword clipmax = si_ai(clipmin, TILE_SIZE); +   setup.cliprect = si_shufb(clipmin, clipmax, SHUFB4(A,B,a,b)); -   if (!setup_sort_vertices((struct vertex_header *) v0, -                            (struct vertex_header *) v1, -                            (struct vertex_header *) v2)) { +   if(!setup_sort_vertices(vs)) {        return FALSE; /* totally clipped */     } diff --git a/src/gallium/drivers/cell/spu/spu_tri.h b/src/gallium/drivers/cell/spu/spu_tri.h index aa694dd7c9..82e3b19ad7 100644 --- a/src/gallium/drivers/cell/spu/spu_tri.h +++ b/src/gallium/drivers/cell/spu/spu_tri.h @@ -31,7 +31,7 @@  extern boolean -tri_draw(const float *v0, const float *v1, const float *v2, uint tx, uint ty); +tri_draw(const qword vs, uint tx, uint ty);  #endif /* SPU_TRI_H */ diff --git a/src/gallium/drivers/nv04/nv04_miptree.c b/src/gallium/drivers/nv04/nv04_miptree.c index 4da833c25e..93f752faec 100644 --- a/src/gallium/drivers/nv04/nv04_miptree.c +++ b/src/gallium/drivers/nv04/nv04_miptree.c @@ -31,7 +31,8 @@ nv04_miptree_layout(struct nv04_miptree *nv04mt)  	for (l = 0; l <= pt->last_level; l++) { -		nv04mt->level[l].image_offset = offset; +		nv04mt->level[l].image_offset =  +			CALLOC(nr_faces, sizeof(unsigned));  		offset += nv04mt->level[l].pitch * pt->height[l];  	} diff --git a/src/gallium/drivers/nv04/nv04_state.h b/src/gallium/drivers/nv04/nv04_state.h index 0d51439e3f..399f750dbe 100644 --- a/src/gallium/drivers/nv04/nv04_state.h +++ b/src/gallium/drivers/nv04/nv04_state.h @@ -37,7 +37,7 @@ struct nv04_miptree {  	struct {  		uint pitch; -		uint image_offset; +		uint *image_offset;  	} level[PIPE_MAX_TEXTURE_LEVELS];  }; diff --git a/src/gallium/drivers/r300/r300_chipset.c b/src/gallium/drivers/r300/r300_chipset.c index 9d95ad918c..00fae8d26f 100644 --- a/src/gallium/drivers/r300/r300_chipset.c +++ b/src/gallium/drivers/r300/r300_chipset.c @@ -34,7 +34,6 @@ void r300_parse_chipset(struct r300_capabilities* caps)      caps->is_r500 = FALSE;      caps->num_vert_fpus = 4; -      /* Note: These are not ordered by PCI ID. I leave that task to GCC,       * which will perform the ordering while collating jump tables. Instead,       * I've tried to group them according to capabilities and age. */ @@ -150,6 +149,7 @@ void r300_parse_chipset(struct r300_capabilities* caps)              caps->num_vert_fpus = 6;              break; +        case 0x4B48:          case 0x4B49:          case 0x4B4A:          case 0x4B4B: @@ -349,7 +349,4 @@ void r300_parse_chipset(struct r300_capabilities* caps)                  caps->pci_id);              break;      } - -    /* XXX SW TCL is broken so no forcing it off right now -    caps->has_tcl = FALSE; */  } diff --git a/src/gallium/drivers/r300/r300_chipset.h b/src/gallium/drivers/r300/r300_chipset.h index 21eebeae60..5b2e1f0568 100644 --- a/src/gallium/drivers/r300/r300_chipset.h +++ b/src/gallium/drivers/r300/r300_chipset.h @@ -34,8 +34,6 @@ struct r300_capabilities {      int family;      /* The number of vertex floating-point units */      int num_vert_fpus; -    /* The number of fragment pipes */ -    int num_frag_pipes;      /* Whether or not TCL is physically present */      boolean has_tcl;      /* Whether or not this is an RV515 or newer; R500s have many differences diff --git a/src/gallium/drivers/r300/r300_context.c b/src/gallium/drivers/r300/r300_context.c index 6bdf544a05..21c0fe2b80 100644 --- a/src/gallium/drivers/r300/r300_context.c +++ b/src/gallium/drivers/r300/r300_context.c @@ -34,10 +34,6 @@ static boolean r300_draw_range_elements(struct pipe_context* pipe,      struct r300_context* r300 = r300_context(pipe);      int i; -    if (r300->dirty_state) { -        r300_emit_dirty_state(r300); -    } -      for (i = 0; i < r300->vertex_buffer_count; i++) {          void* buf = pipe_buffer_map(pipe->screen,                                      r300->vertex_buffers[i].buffer, @@ -133,7 +129,6 @@ struct pipe_context* r300_create_context(struct pipe_screen* screen,      if (!r300)          return NULL; -    /* XXX this could be refactored now? */      r300->winsys = r300_winsys;      r300->context.winsys = (struct pipe_winsys*)r300_winsys; @@ -150,8 +145,15 @@ struct pipe_context* r300_create_context(struct pipe_screen* screen,      r300->context.is_texture_referenced = r300_is_texture_referenced;      r300->context.is_buffer_referenced = r300_is_buffer_referenced; +    /* Create a Draw. This is used for vert collation and SW TCL. */      r300->draw = draw_create(); +    /* Enable our renderer. */      draw_set_rasterize_stage(r300->draw, r300_draw_stage(r300)); +    /* Tell Draw that we can always do non-UCP clipping. */ +    draw_set_driver_clipping(r300->draw, TRUE); +    /* Force Draw to never do viewport transform, since (again) we can do +     * transform in hardware, always. */ +    draw_set_viewport_state(r300->draw, &r300_viewport_identity);      r300->blend_color_state = CALLOC_STRUCT(r300_blend_color_state);      r300->rs_block = CALLOC_STRUCT(r300_rs_block); diff --git a/src/gallium/drivers/r300/r300_context.h b/src/gallium/drivers/r300/r300_context.h index 6f62998b35..a9dd041e08 100644 --- a/src/gallium/drivers/r300/r300_context.h +++ b/src/gallium/drivers/r300/r300_context.h @@ -63,6 +63,11 @@ struct r300_rs_state {      /* Draw-specific rasterizer state */      struct pipe_rasterizer_state rs; +    /* Whether or not to enable the VTE. This is referenced at the very +     * last moment during emission of VTE state, to decide whether or not +     * the VTE should be used for transformation. */ +    boolean enable_vte; +      uint32_t vap_control_status;    /* R300_VAP_CNTL_STATUS: 0x2140 */      uint32_t point_size;            /* R300_GA_POINT_SIZE: 0x421c */      uint32_t point_minmax;          /* R300_GA_POINT_MINMAX: 0x4230 */ @@ -136,11 +141,11 @@ struct r300_viewport_state {  struct r300_constant_buffer {      /* Buffer of constants */      /* XXX first number should be raised */ -    float constants[8][4]; +    float constants[32][4];      /* Number of user-defined constants */ -    int user_count; +    unsigned user_count;      /* Total number of constants */ -    int count; +    unsigned count;  };  struct r3xx_fragment_shader { @@ -153,6 +158,10 @@ struct r3xx_fragment_shader {      /* Pixel stack size */      int stack_size; + +    /* Are there immediates in this shader? +     * If not, we can heavily optimize recompilation. */ +    boolean uses_imms;  };  struct r300_fragment_shader { @@ -243,6 +252,10 @@ struct r300_vertex_shader {      /* Has this shader been translated yet? */      boolean translated; +    /* Are there immediates in this shader? +     * If not, we can heavily optimize recompilation. */ +    boolean uses_imms; +      /* Number of used instructions */      int instruction_count; @@ -255,6 +268,11 @@ struct r300_vertex_shader {      } instructions[128]; /*< XXX magic number */  }; +static struct pipe_viewport_state r300_viewport_identity = { +    .scale = {1.0, 1.0, 1.0, 1.0}, +    .translate = {0.0, 0.0, 0.0, 0.0}, +}; +  struct r300_context {      /* Parent class */      struct pipe_context context; @@ -264,6 +282,11 @@ struct r300_context {      /* Draw module. Used mostly for SW TCL. */      struct draw_context* draw; +    /* Vertex buffer for rendering. */ +    struct pipe_buffer* vbo; +    /* Offset into the VBO. */ +    size_t vbo_offset; +      /* Various CSO state objects. */      /* Blend state. */      struct r300_blend_state* blend_state; @@ -289,7 +312,7 @@ struct r300_context {      /* Texture states. */      struct r300_texture* textures[8];      int texture_count; -    /* Vertex buffers. */ +    /* Vertex buffers for Gallium. */      struct pipe_vertex_buffer vertex_buffers[PIPE_MAX_ATTRIBS];      int vertex_buffer_count;      /* Vertex information. */ diff --git a/src/gallium/drivers/r300/r300_cs.h b/src/gallium/drivers/r300/r300_cs.h index 82a3942248..2abf04d27e 100644 --- a/src/gallium/drivers/r300/r300_cs.h +++ b/src/gallium/drivers/r300/r300_cs.h @@ -93,8 +93,9 @@  } while (0)  #define OUT_CS_RELOC(bo, offset, rd, wd, flags) do { \ -    debug_printf("r300: writing relocation for buffer %p, offset %d\n", \ -        bo, offset); \ +    debug_printf("r300: writing relocation for buffer %p, offset %d, " \ +            "domains (%d, %d, %d)\n", \ +        bo, offset, rd, wd, flags); \      assert(bo); \      OUT_CS(offset); \      cs_winsys->write_cs_reloc(cs_winsys, bo, rd, wd, flags); \ diff --git a/src/gallium/drivers/r300/r300_debug.c b/src/gallium/drivers/r300/r300_debug.c index dd63136c9d..ffc93eb591 100644 --- a/src/gallium/drivers/r300/r300_debug.c +++ b/src/gallium/drivers/r300/r300_debug.c @@ -30,81 +30,6 @@ static void r300_dump_fs(struct r300_fragment_shader* fs)      }  } -static char* r500_fs_swiz[] = { -    " R", -    " G", -    " B", -    " A", -    " 0", -    ".5", -    " 1", -    " U", -}; - -static char* r500_fs_op_rgb[] = { -    "MAD", -    "DP3", -    "DP4", -    "D2A", -    "MIN", -    "MAX", -    "---", -    "CND", -    "CMP", -    "FRC", -    "SOP", -    "MDH", -    "MDV", -}; - -static char* r500_fs_op_alpha[] = { -    "MAD", -    " DP", -    "MIN", -    "MAX", -    "---", -    "CND", -    "CMP", -    "FRC", -    "EX2", -    "LN2", -    "RCP", -    "RSQ", -    "SIN", -    "COS", -    "MDH", -    "MDV", -}; - -static char* r500_fs_mask[] = { -    "NONE", -    "R   ", -    " G  ", -    "RG  ", -    "  B ", -    "R B ", -    " GB ", -    "RGB ", -    "   A", -    "R  A", -    " G A", -    "RG A", -    "  BA", -    "R BA", -    " GBA", -    "RGBA", -}; - -static char* r500_fs_tex[] = { -    "    NOP", -    "     LD", -    "TEXKILL", -    "   PROJ", -    "LODBIAS", -    "    LOD", -    "   DXDY", -}; -  void r500_fs_dump(struct r500_fragment_shader* fs)  {      int i; @@ -225,12 +150,27 @@ void r500_fs_dump(struct r500_fragment_shader* fs)      }  } +static void r300_vs_op_dump(uint32_t op) +{ +    if (op & 0x80) { +        if (op & 0x1) { +            debug_printf("PVS_MACRO_OP_2CLK_M2X_ADD\n"); +        } else { +            debug_printf("   PVS_MACRO_OP_2CLK_MADD\n"); +        } +    } else if (op & 0x40) { +        debug_printf("%s\n", r300_vs_me_ops[op & 0x1f]); +    } else { +        debug_printf("%s\n", r300_vs_ve_ops[op & 0x1f]); +    } +} +  void r300_vs_dump(struct r300_vertex_shader* vs)  {      int i;      for (i = 0; i < vs->instruction_count; i++) { -        debug_printf("inst0: 0x%x\n", vs->instructions[i].inst0); +        r300_vs_op_dump(vs->instructions[i].inst0);          debug_printf("inst1: 0x%x\n", vs->instructions[i].inst1);          debug_printf("inst2: 0x%x\n", vs->instructions[i].inst2);          debug_printf("inst3: 0x%x\n", vs->instructions[i].inst3); diff --git a/src/gallium/drivers/r300/r300_debug.h b/src/gallium/drivers/r300/r300_debug.h index a1f873656d..6306594099 100644 --- a/src/gallium/drivers/r300/r300_debug.h +++ b/src/gallium/drivers/r300/r300_debug.h @@ -27,6 +27,152 @@  #include "r300_state_shader.h"  #include "r300_state_tcl.h" +static char* r500_fs_swiz[] = { +    " R", +    " G", +    " B", +    " A", +    " 0", +    ".5", +    " 1", +    " U", +}; + +static char* r500_fs_op_rgb[] = { +    "MAD", +    "DP3", +    "DP4", +    "D2A", +    "MIN", +    "MAX", +    "---", +    "CND", +    "CMP", +    "FRC", +    "SOP", +    "MDH", +    "MDV", +}; + +static char* r500_fs_op_alpha[] = { +    "MAD", +    " DP", +    "MIN", +    "MAX", +    "---", +    "CND", +    "CMP", +    "FRC", +    "EX2", +    "LN2", +    "RCP", +    "RSQ", +    "SIN", +    "COS", +    "MDH", +    "MDV", +}; + +static char* r500_fs_mask[] = { +    "NONE", +    "R   ", +    " G  ", +    "RG  ", +    "  B ", +    "R B ", +    " GB ", +    "RGB ", +    "   A", +    "R  A", +    " G A", +    "RG A", +    "  BA", +    "R BA", +    " GBA", +    "RGBA", +}; + +static char* r500_fs_tex[] = { +    "    NOP", +    "     LD", +    "TEXKILL", +    "   PROJ", +    "LODBIAS", +    "    LOD", +    "   DXDY", +}; + +static char* r300_vs_ve_ops[] = { +    /* R300 vector ops */ +    "                 VE_NO_OP", +    "           VE_DOT_PRODUCT", +    "              VE_MULTIPLY", +    "                   VE_ADD", +    "          VE_MULTIPLY_ADD", +    "       VE_DISTANCE_FACTOR", +    "              VE_FRACTION", +    "               VE_MAXIMUM", +    "               VE_MINIMUM", +    "VE_SET_GREATER_THAN_EQUAL", +    "         VE_SET_LESS_THAN", +    "        VE_MULTIPLYX2_ADD", +    "        VE_MULTIPLY_CLAMP", +    "            VE_FLT2FIX_DX", +    "        VE_FLT2FIX_DX_RND", +    /* R500 vector ops */ +    "      VE_PRED_SET_EQ_PUSH", +    "      VE_PRED_SET_GT_PUSH", +    "     VE_PRED_SET_GTE_PUSH", +    "     VE_PRED_SET_NEQ_PUSH", +    "         VE_COND_WRITE_EQ", +    "         VE_COND_WRITE_GT", +    "        VE_COND_WRITE_GTE", +    "        VE_COND_WRITE_NEQ", +    "      VE_SET_GREATER_THAN", +    "             VE_SET_EQUAL", +    "         VE_SET_NOT_EQUAL", +    "               (reserved)", +    "               (reserved)", +    "               (reserved)", +}; + +static char* r300_vs_me_ops[] = { +    /* R300 math ops */ +    "                 ME_NO_OP", +    "          ME_EXP_BASE2_DX", +    "          ME_LOG_BASE2_DX", +    "          ME_EXP_BASEE_FF", +    "        ME_LIGHT_COEFF_DX", +    "         ME_POWER_FUNC_FF", +    "              ME_RECIP_DX", +    "              ME_RECIP_FF", +    "         ME_RECIP_SQRT_DX", +    "         ME_RECIP_SQRT_FF", +    "              ME_MULTIPLY", +    "     ME_EXP_BASE2_FULL_DX", +    "     ME_LOG_BASE2_FULL_DX", +    " ME_POWER_FUNC_FF_CLAMP_B", +    "ME_POWER_FUNC_FF_CLAMP_B1", +    "ME_POWER_FUNC_FF_CLAMP_01", +    "                   ME_SIN", +    "                   ME_COS", +    /* R500 math ops */ +    "        ME_LOG_BASE2_IEEE", +    "            ME_RECIP_IEEE", +    "       ME_RECIP_SQRT_IEEE", +    "           ME_PRED_SET_EQ", +    "           ME_PRED_SET_GT", +    "          ME_PRED_SET_GTE", +    "          ME_PRED_SET_NEQ", +    "          ME_PRED_SET_CLR", +    "          ME_PRED_SET_INV", +    "          ME_PRED_SET_POP", +    "      ME_PRED_SET_RESTORE", +    "               (reserved)", +    "               (reserved)", +    "               (reserved)", +}; +  void r500_fs_dump(struct r500_fragment_shader* fs);  void r300_vs_dump(struct r300_vertex_shader* vs); diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c index 01bac5f759..5e4b179505 100644 --- a/src/gallium/drivers/r300/r300_emit.c +++ b/src/gallium/drivers/r300/r300_emit.c @@ -163,6 +163,7 @@ void r300_emit_fb_state(struct r300_context* r300,      BEGIN_CS((8 * fb->nr_cbufs) + (fb->zsbuf ? 8 : 0) + 4);      for (i = 0; i < fb->nr_cbufs; i++) {          tex = (struct r300_texture*)fb->cbufs[i]->texture; +        assert(tex && tex->buffer && "cbuf is marked, but NULL!");          pixpitch = tex->stride / tex->tex.block.size;          OUT_CS_REG_SEQ(R300_RB3D_COLOROFFSET0 + (4 * i), 1); @@ -177,7 +178,8 @@ void r300_emit_fb_state(struct r300_context* r300,      if (fb->zsbuf) {          tex = (struct r300_texture*)fb->zsbuf->texture; -        pixpitch = (tex->stride / tex->tex.block.size); +        assert(tex && tex->buffer && "zsbuf is marked, but NULL!"); +        pixpitch = tex->stride / tex->tex.block.size;          OUT_CS_REG_SEQ(R300_ZB_DEPTHOFFSET, 1);          OUT_CS_RELOC(tex->buffer, 0, 0, RADEON_GEM_DOMAIN_VRAM, 0); @@ -234,7 +236,7 @@ void r300_emit_rs_block_state(struct r300_context* r300,      }      for (i = 0; i < 8; i++) {          OUT_CS(rs->ip[i]); -        debug_printf("ip %d: 0x%08x\n", i, rs->ip[i]); +        /* debug_printf("ip %d: 0x%08x\n", i, rs->ip[i]); */      }      OUT_CS_REG_SEQ(R300_RS_COUNT, 2); @@ -248,11 +250,11 @@ void r300_emit_rs_block_state(struct r300_context* r300,      }      for (i = 0; i < 8; i++) {          OUT_CS(rs->inst[i]); -        debug_printf("inst %d: 0x%08x\n", i, rs->inst[i]); +        /* debug_printf("inst %d: 0x%08x\n", i, rs->inst[i]); */      } -    debug_printf("count: 0x%08x inst_count: 0x%08x\n", rs->count, -            rs->inst_count); +    /* debug_printf("count: 0x%08x inst_count: 0x%08x\n", rs->count, +     *        rs->inst_count); */      END_CS;  } @@ -296,6 +298,30 @@ void r300_emit_texture(struct r300_context* r300,      END_CS;  } +void r300_emit_vertex_buffer(struct r300_context* r300) +{ +    CS_LOCALS(r300); + +    debug_printf("r300: Preparing vertex buffer %p for render, " +            "vertex size %d\n", r300->vbo, +            r300->vertex_info.vinfo.size); +    /* Set the pointer to our vertex buffer. The emitted values are this: +     * PACKET3 [3D_LOAD_VBPNTR] +     * COUNT   [1] +     * FORMAT  [size | stride << 8] +     * OFFSET  [offset into BO] +     * VBPNTR  [relocated BO] +     */ +    BEGIN_CS(7); +    OUT_CS_PKT3(R300_PACKET3_3D_LOAD_VBPNTR, 3); +    OUT_CS(1); +    OUT_CS(r300->vertex_info.vinfo.size | +            (r300->vertex_info.vinfo.size << 8)); +    OUT_CS(r300->vbo_offset); +    OUT_CS_RELOC(r300->vbo, 0, RADEON_GEM_DOMAIN_GTT, 0, 0); +    END_CS; +} +  void r300_emit_vertex_format_state(struct r300_context* r300)  {      int i; @@ -310,22 +336,22 @@ void r300_emit_vertex_format_state(struct r300_context* r300)      OUT_CS_REG_SEQ(R300_VAP_OUTPUT_VTX_FMT_0, 2);      OUT_CS(r300->vertex_info.vinfo.hwfmt[2]);      OUT_CS(r300->vertex_info.vinfo.hwfmt[3]); -    for (i = 0; i < 4; i++) { -        debug_printf("hwfmt%d: 0x%08x\n", i, -                r300->vertex_info.vinfo.hwfmt[i]); -    } +    /* for (i = 0; i < 4; i++) { +     *    debug_printf("hwfmt%d: 0x%08x\n", i, +     *            r300->vertex_info.vinfo.hwfmt[i]); +     * } */      OUT_CS_REG_SEQ(R300_VAP_PROG_STREAM_CNTL_0, 8);      for (i = 0; i < 8; i++) {          OUT_CS(r300->vertex_info.vap_prog_stream_cntl[i]); -        debug_printf("prog_stream_cntl%d: 0x%08x\n", i, -                r300->vertex_info.vap_prog_stream_cntl[i]); +        /* debug_printf("prog_stream_cntl%d: 0x%08x\n", i, +         *        r300->vertex_info.vap_prog_stream_cntl[i]); */      }      OUT_CS_REG_SEQ(R300_VAP_PROG_STREAM_CNTL_EXT_0, 8);      for (i = 0; i < 8; i++) {          OUT_CS(r300->vertex_info.vap_prog_stream_cntl_ext[i]); -        debug_printf("prog_stream_cntl_ext%d: 0x%08x\n", i, -                r300->vertex_info.vap_prog_stream_cntl_ext[i]); +        /* debug_printf("prog_stream_cntl_ext%d: 0x%08x\n", i, +         *        r300->vertex_info.vap_prog_stream_cntl_ext[i]); */      }      END_CS;  } @@ -403,7 +429,11 @@ void r300_emit_viewport_state(struct r300_context* r300,      OUT_CS_32F(viewport->zscale);      OUT_CS_32F(viewport->zoffset); -    OUT_CS_REG(R300_VAP_VTE_CNTL, viewport->vte_control); +    if (r300->rs_state->enable_vte) { +        OUT_CS_REG(R300_VAP_VTE_CNTL, viewport->vte_control); +    } else { +        OUT_CS_REG(R300_VAP_VTE_CNTL, 0); +    }      END_CS;  } @@ -421,23 +451,54 @@ void r300_flush_textures(struct r300_context* r300)  void r300_emit_dirty_state(struct r300_context* r300)  {      struct r300_screen* r300screen = r300_screen(r300->context.screen); -    int i; -    int dirty_tex = 0; +    struct r300_texture* tex; +    int i, dirty_tex = 0; +    boolean invalid = FALSE; -    if (!(r300->dirty_hw)) { +    if (!(r300->dirty_state)) {          return;      }      r300_update_derived_state(r300);      /* XXX check size */ -    struct r300_texture* fb_tex = -        (struct r300_texture*)r300->framebuffer_state.cbufs[0]; -    r300->winsys->add_buffer(r300->winsys, fb_tex->buffer, -            0, RADEON_GEM_DOMAIN_VRAM); +validate: +    /* Color buffers... */ +    for (i = 0; i < r300->framebuffer_state.nr_cbufs; i++) { +        tex = (struct r300_texture*)r300->framebuffer_state.cbufs[i]->texture; +        assert(tex && tex->buffer && "cbuf is marked, but NULL!"); +        r300->winsys->add_buffer(r300->winsys, tex->buffer, +                0, RADEON_GEM_DOMAIN_VRAM); +    } +    /* ...depth buffer... */ +    if (r300->framebuffer_state.zsbuf) { +        tex = (struct r300_texture*)r300->framebuffer_state.zsbuf->texture; +        assert(tex && tex->buffer && "zsbuf is marked, but NULL!"); +        r300->winsys->add_buffer(r300->winsys, tex->buffer, +                0, RADEON_GEM_DOMAIN_VRAM); +    } +    /* ...textures... */ +    for (i = 0; i < r300->texture_count; i++) { +        tex = r300->textures[i]; +        assert(tex && tex->buffer && "texture is marked, but NULL!"); +        r300->winsys->add_buffer(r300->winsys, tex->buffer, +                RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0); +    } +    /* ...and vertex buffer. */ +    if (r300->vbo) { +        r300->winsys->add_buffer(r300->winsys, r300->vbo, +                RADEON_GEM_DOMAIN_GTT, 0); +    } else { +        debug_printf("No VBO while emitting dirty state!\n"); +    }      if (r300->winsys->validate(r300->winsys)) { -        /* XXX */          r300->context.flush(&r300->context, 0, NULL); +        if (invalid) { +            /* Well, hell. */ +            exit(1); +        } +        invalid = TRUE; +        goto validate;      }      if (r300->dirty_state & R300_NEW_BLEND) { @@ -519,4 +580,9 @@ void r300_emit_dirty_state(struct r300_context* r300)          r300_emit_vertex_format_state(r300);          r300->dirty_state &= ~R300_NEW_VERTEX_FORMAT;      } + +    /* Finally, emit the VBO. */ +    r300_emit_vertex_buffer(r300); + +    r300->dirty_hw++;  } diff --git a/src/gallium/drivers/r300/r300_emit.h b/src/gallium/drivers/r300/r300_emit.h index 31dbc7ab85..36e14f69f7 100644 --- a/src/gallium/drivers/r300/r300_emit.h +++ b/src/gallium/drivers/r300/r300_emit.h @@ -62,6 +62,8 @@ void r300_emit_scissor_state(struct r300_context* r300,  void r300_emit_texture(struct r300_context* r300,                         struct r300_texture* tex, unsigned offset); +void r300_emit_vertex_buffer(struct r300_context* r300); +  void r300_emit_vertex_format_state(struct r300_context* r300);  void r300_emit_vertex_shader(struct r300_context* r300, diff --git a/src/gallium/drivers/r300/r300_reg.h b/src/gallium/drivers/r300/r300_reg.h index 660816e1da..920584a59e 100644 --- a/src/gallium/drivers/r300/r300_reg.h +++ b/src/gallium/drivers/r300/r300_reg.h @@ -3040,6 +3040,7 @@ enum {  #   define R500_INST_RGB_WMASK_R			(1 << 11)  #   define R500_INST_RGB_WMASK_G			(1 << 12)  #   define R500_INST_RGB_WMASK_B			(1 << 13) +#   define R500_INST_RGB_WMASK_RGB			(7 << 11)  #   define R500_INST_ALPHA_WMASK			(1 << 14)  #   define R500_INST_RGB_OMASK_R			(1 << 15)  #   define R500_INST_RGB_OMASK_G			(1 << 16) diff --git a/src/gallium/drivers/r300/r300_render.c b/src/gallium/drivers/r300/r300_render.c index cbd84d7c56..29b66cee7e 100644 --- a/src/gallium/drivers/r300/r300_render.c +++ b/src/gallium/drivers/r300/r300_render.c @@ -180,27 +180,10 @@ static void prepare_render(struct r300_render* render, unsigned count)      CS_LOCALS(r300); -    /* Make sure that all possible state is emitted. */ -    r300_emit_dirty_state(r300); +    r300->vbo = render->vbo; +    r300->vbo_offset = render->vbo_offset; -    debug_printf("r300: Preparing vertex buffer %p for render, " -            "vertex size %d, vertex count %d\n", render->vbo, -            r300->vertex_info.vinfo.size, count); -    /* Set the pointer to our vertex buffer. The emitted values are this: -     * PACKET3 [3D_LOAD_VBPNTR] -     * COUNT   [1] -     * FORMAT  [size | stride << 8] -     * OFFSET  [0] -     * VBPNTR  [relocated BO] -     */ -    BEGIN_CS(7); -    OUT_CS_PKT3(R300_PACKET3_3D_LOAD_VBPNTR, 3); -    OUT_CS(1); -    OUT_CS(r300->vertex_info.vinfo.size | -            (r300->vertex_info.vinfo.size << 8)); -    OUT_CS(render->vbo_offset); -    OUT_CS_RELOC(render->vbo, 0, RADEON_GEM_DOMAIN_GTT, 0, 0); -    END_CS; +    r300_emit_dirty_state(r300);  }  static void r300_render_draw_arrays(struct vbuf_render* render, diff --git a/src/gallium/drivers/r300/r300_screen.c b/src/gallium/drivers/r300/r300_screen.c index d2c5998c26..a6f1efe356 100644 --- a/src/gallium/drivers/r300/r300_screen.c +++ b/src/gallium/drivers/r300/r300_screen.c @@ -87,23 +87,25 @@ static int r300_get_param(struct pipe_screen* pscreen, int param)              } else {                  return 0;              } -            return 0;          case PIPE_CAP_GLSL: -            /* IN THEORY */ -            return 0; +            if (r300screen->caps->is_r500) { +                return 1; +            } else { +                return 0; +            }          case PIPE_CAP_S3TC:              /* IN THEORY */              return 0;          case PIPE_CAP_ANISOTROPIC_FILTER: -            /* IN THEORY */ -            return 0; +            return 1;          case PIPE_CAP_POINT_SPRITE:              /* IN THEORY */              return 0;          case PIPE_CAP_MAX_RENDER_TARGETS:              return 4;          case PIPE_CAP_OCCLUSION_QUERY: -            return 1; +            /* IN THEORY */ +            return 0;          case PIPE_CAP_TEXTURE_SHADOW_MAP:              /* IN THEORY */              return 0; @@ -152,17 +154,20 @@ static int r300_get_param(struct pipe_screen* pscreen, int param)  static float r300_get_paramf(struct pipe_screen* pscreen, int param)  { +    struct r300_screen* r300screen = r300_screen(pscreen); +      switch (param) {          case PIPE_CAP_MAX_LINE_WIDTH:          case PIPE_CAP_MAX_LINE_WIDTH_AA: -            /* XXX this is the biggest thing that will fit in that register. -            * Perhaps the actual rendering limits are less? */ -            return 10922.0f;          case PIPE_CAP_MAX_POINT_WIDTH:          case PIPE_CAP_MAX_POINT_WIDTH_AA: -            /* XXX this is the biggest thing that will fit in that register. -             * Perhaps the actual rendering limits are less? */ -            return 10922.0f; +            /* The maximum dimensions of the colorbuffer are our practical +             * rendering limits. 2048 pixels should be enough for anybody. */ +            if (r300screen->caps->is_r500) { +                return 4096.0f; +            } else { +                return 2048.0f; +            }          case PIPE_CAP_MAX_TEXTURE_ANISOTROPY:              return 16.0f;          case PIPE_CAP_MAX_TEXTURE_LOD_BIAS: @@ -230,9 +235,16 @@ static boolean r300_is_format_supported(struct pipe_screen* pscreen,          case PIPE_TEXTURE_2D:              return check_tex_2d_format(format,                  r300_screen(pscreen)->caps->is_r500); +        case PIPE_TEXTURE_1D: +        case PIPE_TEXTURE_3D: +        case PIPE_TEXTURE_CUBE: +            debug_printf("r300: Implementation error: Unsupported format " +                    "target: %d\n", target); +            break;          default: -            debug_printf("r300: Warning: Got unknown format target: %d\n", -                format); +            debug_printf("r300: Fatal: This is not a format target: %d\n", +                target); +            assert(0);              break;      } @@ -337,7 +349,6 @@ struct pipe_screen* r300_create_screen(struct r300_winsys* r300_winsys)          return NULL;      caps->pci_id = r300_winsys->pci_id; -    caps->num_frag_pipes = r300_winsys->gb_pipes;      r300_parse_chipset(caps); diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c index 184a23c9e6..0461ffd681 100644 --- a/src/gallium/drivers/r300/r300_state.c +++ b/src/gallium/drivers/r300/r300_state.c @@ -62,8 +62,6 @@ static void* r300_create_blend_state(struct pipe_context* pipe,      }      /* PIPE_LOGICOP_* don't need to be translated, fortunately. */ -    /* XXX are logicops still allowed if blending's disabled? -     * Does Gallium take care of it for us? */      if (state->logicop_enable) {          blend->rop = R300_RB3D_ROPCNTL_ROP_ENABLE |                  (state->logicop_func) << R300_RB3D_ROPCNTL_ROP_SHIFT; @@ -121,7 +119,7 @@ static void r300_set_clip_state(struct pipe_context* pipe,                                  const struct pipe_clip_state* state)  {      struct r300_context* r300 = r300_context(pipe); -    /* XXX Draw */ +    /* XXX add HW TCL clipping setup */      draw_flush(r300->draw);      draw_set_clip_state(r300->draw, state);  } @@ -153,10 +151,12 @@ static void      /* If the number of constants have changed, invalidate the shader. */      if (r300->shader_constants[shader].user_count != i) { -        if (shader == PIPE_SHADER_FRAGMENT && r300->fs) { +        if (shader == PIPE_SHADER_FRAGMENT && r300->fs && +                r300->fs->uses_imms) {              r300->fs->translated = FALSE;              r300_translate_fragment_shader(r300, r300->fs); -        } else if (shader == PIPE_SHADER_VERTEX && r300->vs) { +        } else if (shader == PIPE_SHADER_VERTEX && r300->vs && +                r300->vs->uses_imms) {              r300->vs->translated = FALSE;              r300_translate_vertex_shader(r300, r300->vs);          } @@ -257,6 +257,7 @@ static void r300_set_edgeflags(struct pipe_context* pipe,                                 const unsigned* bitfield)  {      /* XXX you know it's bad when i915 has this blank too */ +    /* XXX and even worse, I have no idea WTF the bitfield is */  }  static void @@ -289,6 +290,7 @@ static void* r300_create_fs_state(struct pipe_context* pipe,      /* Copy state directly into shader. */      fs->state = *shader; +    fs->state.tokens = tgsi_dup_tokens(shader->tokens);      tgsi_scan_shader(shader->tokens, &fs->info); @@ -317,13 +319,15 @@ static void r300_bind_fs_state(struct pipe_context* pipe, void* shader)  /* Delete fragment shader state. */  static void r300_delete_fs_state(struct pipe_context* pipe, void* shader)  { +    struct r3xx_fragment_shader* fs = (struct r3xx_fragment_shader*)shader; +    FREE(fs->state.tokens);      FREE(shader);  }  static void r300_set_polygon_stipple(struct pipe_context* pipe,                                       const struct pipe_poly_stipple* state)  { -    /* XXX */ +    /* XXX no idea how to set this up, but not terribly important */  }  /* Create a new rasterizer state based on the CSO rasterizer state. @@ -341,6 +345,8 @@ static void* r300_create_rs_state(struct pipe_context* pipe,      /* Copy rasterizer state for Draw. */      rs->rs = *state; +    rs->enable_vte = !state->bypass_vs_clip_and_viewport; +      /* If bypassing TCL, or if no TCL engine is present, turn off the HW TCL.       * Else, enable HW TCL and force Draw's TCL off. */      if (state->bypass_vs_clip_and_viewport || @@ -555,40 +561,35 @@ static void r300_set_viewport_state(struct pipe_context* pipe,  {      struct r300_context* r300 = r300_context(pipe); -    draw_flush(r300->draw); - -    if (r300_screen(r300->context.screen)->caps->has_tcl) { -        /* Do the transform in HW. */ -        r300->viewport_state->vte_control = R300_VTX_W0_FMT; +    /* Do the transform in HW. */ +    r300->viewport_state->vte_control = R300_VTX_W0_FMT; -        if (state->scale[0] != 1.0f) { -            r300->viewport_state->xscale = state->scale[0]; -            r300->viewport_state->vte_control |= R300_VPORT_X_SCALE_ENA; -        } -        if (state->scale[1] != 1.0f) { -            r300->viewport_state->yscale = state->scale[1]; -            r300->viewport_state->vte_control |= R300_VPORT_Y_SCALE_ENA; -        } -        if (state->scale[2] != 1.0f) { -            r300->viewport_state->zscale = state->scale[2]; -            r300->viewport_state->vte_control |= R300_VPORT_Z_SCALE_ENA; -        } -        if (state->translate[0] != 0.0f) { -            r300->viewport_state->xoffset = state->translate[0]; -            r300->viewport_state->vte_control |= R300_VPORT_X_OFFSET_ENA; -        } -        if (state->translate[1] != 0.0f) { -            r300->viewport_state->yoffset = state->translate[1]; -            r300->viewport_state->vte_control |= R300_VPORT_Y_OFFSET_ENA; -        } -        if (state->translate[2] != 0.0f) { -            r300->viewport_state->zoffset = state->translate[2]; -            r300->viewport_state->vte_control |= R300_VPORT_Z_OFFSET_ENA; -        } -    } else { -        r300->viewport_state->vte_control = 0; -        /* Have Draw do the actual transform. */ -        draw_set_viewport_state(r300->draw, state); +    if (state->scale[0] != 1.0f) { +        assert(state->scale[0] != 0.0f); +        r300->viewport_state->xscale = state->scale[0]; +        r300->viewport_state->vte_control |= R300_VPORT_X_SCALE_ENA; +    } +    if (state->scale[1] != 1.0f) { +        assert(state->scale[1] != 0.0f); +        r300->viewport_state->yscale = state->scale[1]; +        r300->viewport_state->vte_control |= R300_VPORT_Y_SCALE_ENA; +    } +    if (state->scale[2] != 1.0f) { +        assert(state->scale[2] != 0.0f); +        r300->viewport_state->zscale = state->scale[2]; +        r300->viewport_state->vte_control |= R300_VPORT_Z_SCALE_ENA; +    } +    if (state->translate[0] != 0.0f) { +        r300->viewport_state->xoffset = state->translate[0]; +        r300->viewport_state->vte_control |= R300_VPORT_X_OFFSET_ENA; +    } +    if (state->translate[1] != 0.0f) { +        r300->viewport_state->yoffset = state->translate[1]; +        r300->viewport_state->vte_control |= R300_VPORT_Y_OFFSET_ENA; +    } +    if (state->translate[2] != 0.0f) { +        r300->viewport_state->zoffset = state->translate[2]; +        r300->viewport_state->vte_control |= R300_VPORT_Z_OFFSET_ENA;      }      r300->dirty_state |= R300_NEW_VIEWPORT; @@ -628,6 +629,7 @@ static void* r300_create_vs_state(struct pipe_context* pipe,          struct r300_vertex_shader* vs = CALLOC_STRUCT(r300_vertex_shader);          /* Copy state directly into shader. */          vs->state = *shader; +        vs->state.tokens = tgsi_dup_tokens(shader->tokens);          tgsi_scan_shader(shader->tokens, &vs->info); @@ -673,6 +675,7 @@ static void r300_delete_vs_state(struct pipe_context* pipe, void* shader)          struct r300_vertex_shader* vs = (struct r300_vertex_shader*)shader;          draw_delete_vertex_shader(r300->draw, vs->draw); +        FREE(vs->state.tokens);          FREE(shader);      } else {          draw_delete_vertex_shader(r300->draw, diff --git a/src/gallium/drivers/r300/r300_state_derived.c b/src/gallium/drivers/r300/r300_state_derived.c index c4c9784a00..7ae339cf97 100644 --- a/src/gallium/drivers/r300/r300_state_derived.c +++ b/src/gallium/drivers/r300/r300_state_derived.c @@ -64,6 +64,7 @@ static void r300_vs_tab_routes(struct r300_context* r300,                      break;                  case TGSI_SEMANTIC_FOG:                      fog = TRUE; +                    /* Fall through */                  case TGSI_SEMANTIC_GENERIC:                      texs++;                      break; @@ -103,6 +104,9 @@ static void r300_vs_tab_routes(struct r300_context* r300,          }      } +    /* XXX magic */ +    assert(texs <= 8); +      /* Do the actual vertex_info setup.       *       * vertex_info has four uints of hardware-specific data in it. @@ -140,17 +144,21 @@ static void r300_vs_tab_routes(struct r300_context* r300,          vinfo->hwfmt[2] |= (R300_VAP_OUTPUT_VTX_FMT_0__COLOR_0_PRESENT << i);      } -    for (i = 0; i < texs; i++) { +    /* Init i right here, increment it if fog is enabled. +     * This gets around a double-increment problem. */ +    i = 0; + +    if (fog) { +        i++;          draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE, -            draw_find_vs_output(r300->draw, TGSI_SEMANTIC_GENERIC, i)); +            draw_find_vs_output(r300->draw, TGSI_SEMANTIC_FOG, 0));          vinfo->hwfmt[1] |= (R300_INPUT_CNTL_TC0 << i);          vinfo->hwfmt[3] |= (4 << (3 * i));      } -    if (fog) { -        i++; +    for (i; i < texs; i++) {          draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE, -            draw_find_vs_output(r300->draw, TGSI_SEMANTIC_FOG, 0)); +            draw_find_vs_output(r300->draw, TGSI_SEMANTIC_GENERIC, i));          vinfo->hwfmt[1] |= (R300_INPUT_CNTL_TC0 << i);          vinfo->hwfmt[3] |= (4 << (3 * i));      } @@ -162,26 +170,40 @@ static void r300_vs_tab_routes(struct r300_context* r300,  static void r300_vertex_psc(struct r300_context* r300,                              struct r300_vertex_format* vformat)  { +    struct r300_screen* r300screen = r300_screen(r300->context.screen);      struct vertex_info* vinfo = &vformat->vinfo;      int* tab = vformat->vs_tab;      uint32_t temp; -    int i; +    int i, attrib_count; -    debug_printf("r300: attrib count: %d\n", vinfo->num_attribs); -    for (i = 0; i < vinfo->num_attribs; i++) { -        debug_printf("r300: attrib: offset %d, interp %d, size %d," -               " tab %d\n", vinfo->attrib[i].src_index, -               vinfo->attrib[i].interp_mode, vinfo->attrib[i].emit, -               tab[i]); +    /* Vertex shaders have no semantics on their inputs, +     * so PSC should just route stuff based on their info, +     * and not on attrib information. */ +    if (r300screen->caps->has_tcl) { +        attrib_count = r300->vs->info.num_inputs; +        debug_printf("r300: routing %d attribs in psc for vs\n", +                attrib_count); +    } else { +        attrib_count = vinfo->num_attribs; +        debug_printf("r300: attrib count: %d\n", attrib_count); +        for (i = 0; i < attrib_count; i++) { +            debug_printf("r300: attrib: offset %d, interp %d, size %d," +                   " tab %d\n", vinfo->attrib[i].src_index, +                   vinfo->attrib[i].interp_mode, vinfo->attrib[i].emit, +                   tab[i]); +        }      } -    for (i = 0; i < vinfo->num_attribs; i++) { +    for (i = 0; i < attrib_count; i++) {          /* Make sure we have a proper destination for our attribute */          assert(tab[i] != -1);          /* Add the attribute to the PSC table. */ -        temp = translate_vertex_data_type(vinfo->attrib[i].emit) | -            (tab[i] << R300_DST_VEC_LOC_SHIFT); +        temp = r300screen->caps->has_tcl ? +            R300_DATA_TYPE_FLOAT_4 : +            translate_vertex_data_type(vinfo->attrib[i].emit); +        temp |= tab[i] << R300_DST_VEC_LOC_SHIFT; +          if (i & 1) {              vformat->vap_prog_stream_cntl[i >> 1] &= 0x0000ffff;              vformat->vap_prog_stream_cntl[i >> 1] |= temp << 16; @@ -206,7 +228,6 @@ static void r300_vertex_psc(struct r300_context* r300,  /* Update the vertex format. */  static void r300_update_vertex_format(struct r300_context* r300)  { -    struct r300_screen* r300screen = r300_screen(r300->context.screen);      struct r300_vertex_format vformat;      int i; diff --git a/src/gallium/drivers/r300/r300_state_inlines.h b/src/gallium/drivers/r300/r300_state_inlines.h index 91b93fc367..22c8e199ae 100644 --- a/src/gallium/drivers/r300/r300_state_inlines.h +++ b/src/gallium/drivers/r300/r300_state_inlines.h @@ -353,25 +353,6 @@ static INLINE uint32_t r300_translate_out_fmt(enum pipe_format format)  /* Non-CSO state. (For now.) */ -static INLINE uint32_t r300_translate_gb_pipes(int pipe_count) -{ -    switch (pipe_count) { -        case 1: -            return R300_GB_TILE_PIPE_COUNT_RV300; -            break; -        case 2: -            return R300_GB_TILE_PIPE_COUNT_R300; -            break; -        case 3: -            return R300_GB_TILE_PIPE_COUNT_R420_3P; -            break; -        case 4: -            return R300_GB_TILE_PIPE_COUNT_R420; -            break; -    } -    return 0; -} -  static INLINE uint32_t translate_vertex_data_type(int type) {      switch (type) {          case EMIT_1F: diff --git a/src/gallium/drivers/r300/r300_state_invariant.c b/src/gallium/drivers/r300/r300_state_invariant.c index 8bd9b41bd7..9dde662802 100644 --- a/src/gallium/drivers/r300/r300_state_invariant.c +++ b/src/gallium/drivers/r300/r300_state_invariant.c @@ -34,36 +34,19 @@ void r300_emit_invariant_state(struct r300_context* r300)      struct r300_capabilities* caps = r300_screen(r300->context.screen)->caps;      CS_LOCALS(r300); -    BEGIN_CS(30 + (caps->has_tcl ? 2: 0)); +    BEGIN_CS(26 + (caps->has_tcl ? 2: 0));      /*** Graphics Backend (GB) ***/      /* Various GB enables */      OUT_CS_REG(R300_GB_ENABLE, 0x0);      /* Subpixel multisampling for AA */      OUT_CS_REG(R300_GB_MSPOS0, 0x66666666); -    OUT_CS_REG(R300_GB_MSPOS1, 0x66666666); -    /* GB tile config and pipe setup */ -    OUT_CS_REG(R300_GB_TILE_CONFIG, R300_GB_TILE_DISABLE | -        r300_translate_gb_pipes(caps->num_frag_pipes)); +    OUT_CS_REG(R300_GB_MSPOS1, 0x6666666);      /* Source of fog depth */      OUT_CS_REG(R300_GB_SELECT, R300_GB_FOG_SELECT_1_1_W);      /* AA enable */      OUT_CS_REG(R300_GB_AA_CONFIG, 0x0); -    /*** Geometry Assembly (GA) ***/ -    /* GA errata fixes. */ -    if (caps->is_r500) { -        OUT_CS_REG(R300_GA_ENHANCE, -                R300_GA_ENHANCE_DEADLOCK_CNTL_PREVENT_TCL | -                R300_GA_ENHANCE_FASTSYNC_CNTL_ENABLE | -                R500_GA_ENHANCE_REG_READWRITE_ENABLE | -                R500_GA_ENHANCE_REG_NOSTALL_ENABLE); -    } else { -        OUT_CS_REG(R300_GA_ENHANCE, -                R300_GA_ENHANCE_DEADLOCK_CNTL_PREVENT_TCL | -                R300_GA_ENHANCE_FASTSYNC_CNTL_ENABLE); -    } -      /*** Fog (FG) ***/      OUT_CS_REG(R300_FG_FOG_BLEND, 0x0);      OUT_CS_REG(R300_FG_FOG_COLOR_R, 0x0); @@ -86,7 +69,7 @@ void r300_emit_invariant_state(struct r300_context* r300)      END_CS;      /* XXX unsorted stuff from surface_fill */ -    BEGIN_CS(79 + (caps->has_tcl ? 7 : 0)); +    BEGIN_CS(77 + (caps->has_tcl ? 7 : 0));      /* Flush PVS. */      OUT_CS_REG(R300_VAP_PVS_STATE_FLUSH_REG, 0x0); @@ -113,11 +96,14 @@ void r300_emit_invariant_state(struct r300_context* r300)      OUT_CS_32F(0.0);      OUT_CS_REG_SEQ(R300_GA_POINT_S1, 1);      OUT_CS_32F(1.0); +    /* XXX line tex stuffing */ +    OUT_CS_REG_SEQ(R300_GA_LINE_S0, 1); +    OUT_CS_32F(0.0); +    OUT_CS_REG_SEQ(R300_GA_LINE_S1, 1); +    OUT_CS_32F(1.0);      OUT_CS_REG(R300_GA_TRIANGLE_STIPPLE, 0x5 |          (0x5 << R300_GA_TRIANGLE_STIPPLE_Y_SHIFT_SHIFT));      /* XXX this big chunk should be refactored into rs_state */ -    OUT_CS_REG(R300_GA_LINE_S0, 0x00000000); -    OUT_CS_REG(R300_GA_LINE_S1, 0x3F800000);      OUT_CS_REG(R300_GA_SOLID_RG, 0x00000000);      OUT_CS_REG(R300_GA_SOLID_BA, 0x00000000);      OUT_CS_REG(R300_GA_POLY_MODE, 0x00000000); @@ -144,8 +130,6 @@ void r300_emit_invariant_state(struct r300_context* r300)      OUT_CS_REG(R300_VAP_VTX_STATE_CNTL, 0x1);      OUT_CS_REG(R300_VAP_VSM_VTX_ASSM, 0x405);      OUT_CS_REG(R300_SE_VTE_CNTL, 0x0000043F); -    /* Vertex size. */ -    OUT_CS_REG(R300_VAP_VTX_SIZE, 0x8);      /* XXX */      OUT_CS_REG(R300_SC_CLIP_RULE, 0xaaaa); diff --git a/src/gallium/drivers/r300/r300_state_shader.c b/src/gallium/drivers/r300/r300_state_shader.c index 1b02239ee7..cc7f6a7c4b 100644 --- a/src/gallium/drivers/r300/r300_state_shader.c +++ b/src/gallium/drivers/r300/r300_state_shader.c @@ -22,24 +22,6 @@  #include "r300_state_shader.h" -static void r300_copy_passthrough_shader(struct r300_fragment_shader* fs) -{ -    struct r300_fragment_shader* pt = &r300_passthrough_fragment_shader; -    fs->shader.stack_size = pt->shader.stack_size; -    fs->alu_instruction_count = pt->alu_instruction_count; -    fs->tex_instruction_count = pt->tex_instruction_count; -    fs->indirections = pt->indirections; -    fs->instructions[0] = pt->instructions[0]; -} - -static void r500_copy_passthrough_shader(struct r500_fragment_shader* fs) -{ -    struct r500_fragment_shader* pt = &r500_passthrough_fragment_shader; -    fs->shader.stack_size = pt->shader.stack_size; -    fs->instruction_count = pt->instruction_count; -    fs->instructions[0] = pt->instructions[0]; -} -  static void r300_fs_declare(struct r300_fs_asm* assembler,                              struct tgsi_full_declaration* decl)  { @@ -49,6 +31,7 @@ static void r300_fs_declare(struct r300_fs_asm* assembler,                  case TGSI_SEMANTIC_COLOR:                      assembler->color_count++;                      break; +                case TGSI_SEMANTIC_FOG:                  case TGSI_SEMANTIC_GENERIC:                      assembler->tex_count++;                      break; @@ -59,6 +42,12 @@ static void r300_fs_declare(struct r300_fs_asm* assembler,              }              break;          case TGSI_FILE_OUTPUT: +            /* Depth write. Mark the position of the output so we can +             * identify it later. */ +            if (decl->Semantic.SemanticName == TGSI_SEMANTIC_POSITION) { +                assembler->depth_output = decl->DeclarationRange.First; +            } +            break;          case TGSI_FILE_CONSTANT:              break;          case TGSI_FILE_TEMPORARY: @@ -120,6 +109,14 @@ static INLINE unsigned r300_fs_dst(struct r300_fs_asm* assembler,      return 0;  } +static INLINE boolean r300_fs_is_depr(struct r300_fs_asm* assembler, +                                      struct tgsi_dst_register* dst) +{ +    return (assembler->writes_depth && +            (dst->File == TGSI_FILE_OUTPUT) && +            (dst->Index == assembler->depth_output)); +} +  static INLINE unsigned r500_fix_swiz(unsigned s)  {      /* For historical reasons, the swizzle values x, y, z, w, and 0 are @@ -194,11 +191,17 @@ static INLINE uint32_t r300_alpha_op(unsigned op)  static INLINE uint32_t r500_rgba_op(unsigned op)  {      switch (op) { +        case TGSI_OPCODE_COS:          case TGSI_OPCODE_EX2:          case TGSI_OPCODE_LG2:          case TGSI_OPCODE_RCP:          case TGSI_OPCODE_RSQ: +        case TGSI_OPCODE_SIN:              return R500_ALU_RGBA_OP_SOP; +        case TGSI_OPCODE_DDX: +            return R500_ALU_RGBA_OP_MDH; +        case TGSI_OPCODE_DDY: +            return R500_ALU_RGBA_OP_MDV;          case TGSI_OPCODE_FRC:              return R500_ALU_RGBA_OP_FRC;          case TGSI_OPCODE_DP3: @@ -224,6 +227,8 @@ static INLINE uint32_t r500_rgba_op(unsigned op)  static INLINE uint32_t r500_alpha_op(unsigned op)  {      switch (op) { +        case TGSI_OPCODE_COS: +            return R500_ALPHA_OP_COS;          case TGSI_OPCODE_EX2:              return R500_ALPHA_OP_EX2;          case TGSI_OPCODE_LG2: @@ -234,6 +239,12 @@ static INLINE uint32_t r500_alpha_op(unsigned op)              return R500_ALPHA_OP_RSQ;          case TGSI_OPCODE_FRC:              return R500_ALPHA_OP_FRC; +        case TGSI_OPCODE_SIN: +            return R500_ALPHA_OP_SIN; +        case TGSI_OPCODE_DDX: +            return R500_ALPHA_OP_MDH; +        case TGSI_OPCODE_DDY: +            return R500_ALPHA_OP_MDV;          case TGSI_OPCODE_DP3:          case TGSI_OPCODE_DP4:          case TGSI_OPCODE_DPH: @@ -295,38 +306,34 @@ static INLINE void r300_emit_maths(struct r300_fragment_shader* fs,  }  /* Setup an ALU operation. */ -static INLINE void r500_emit_alu(struct r500_fragment_shader* fs, -                                 struct r300_fs_asm* assembler, -                                 struct tgsi_full_dst_register* dst) +static INLINE void r500_emit_maths(struct r500_fragment_shader* fs, +                                   struct r300_fs_asm* assembler, +                                   struct tgsi_full_src_register* src, +                                   struct tgsi_full_dst_register* dst, +                                   unsigned op, +                                   unsigned count)  {      int i = fs->instruction_count;      if (dst->DstRegister.File == TGSI_FILE_OUTPUT) { -        fs->instructions[i].inst0 = R500_INST_TYPE_OUT | -        R500_ALU_OMASK(dst->DstRegister.WriteMask); +        fs->instructions[i].inst0 = R500_INST_TYPE_OUT; +        if (r300_fs_is_depr(assembler, dst)) { +            fs->instructions[i].inst4 = R500_W_OMASK; +        } else { +            fs->instructions[i].inst0 |= +                R500_ALU_OMASK(dst->DstRegister.WriteMask); +        }      } else {          fs->instructions[i].inst0 = R500_INST_TYPE_ALU | -        R500_ALU_WMASK(dst->DstRegister.WriteMask); +            R500_ALU_WMASK(dst->DstRegister.WriteMask);      }      fs->instructions[i].inst0 |= R500_INST_TEX_SEM_WAIT; -    fs->instructions[i].inst4 = +    fs->instructions[i].inst4 |=          R500_ALPHA_ADDRD(r300_fs_dst(assembler, &dst->DstRegister));      fs->instructions[i].inst5 =          R500_ALU_RGBA_ADDRD(r300_fs_dst(assembler, &dst->DstRegister)); -} - -static INLINE void r500_emit_maths(struct r500_fragment_shader* fs, -                                   struct r300_fs_asm* assembler, -                                   struct tgsi_full_src_register* src, -                                   struct tgsi_full_dst_register* dst, -                                   unsigned op, -                                   unsigned count) -{ -    int i = fs->instruction_count; - -    r500_emit_alu(fs, assembler, dst);      switch (count) {          case 3: @@ -348,8 +355,8 @@ static INLINE void r500_emit_maths(struct r500_fragment_shader* fs,                  R500_ALU_RGB_SEL_B_SRC1 |                  R500_SWIZ_RGB_B(r500_rgb_swiz(&src[1]));              fs->instructions[i].inst4 |= -                R500_SWIZ_ALPHA_B(r500_alpha_swiz(&src[1])) | -                R500_ALPHA_SEL_B_SRC1; +                R500_ALPHA_SEL_B_SRC1 | +                R500_SWIZ_ALPHA_B(r500_alpha_swiz(&src[1]));          case 1:          case 0:          default: @@ -361,8 +368,8 @@ static INLINE void r500_emit_maths(struct r500_fragment_shader* fs,                  R500_ALU_RGB_SEL_A_SRC0 |                  R500_SWIZ_RGB_A(r500_rgb_swiz(&src[0]));              fs->instructions[i].inst4 |= -                R500_SWIZ_ALPHA_A(r500_alpha_swiz(&src[0])) | -                R500_ALPHA_SEL_A_SRC0; +                R500_ALPHA_SEL_A_SRC0 | +                R500_SWIZ_ALPHA_A(r500_alpha_swiz(&src[0]));              break;      } @@ -441,6 +448,9 @@ static void r500_fs_instruction(struct r500_fragment_shader* fs,       * AMD/ATI names for opcodes, please, as it facilitates using the       * documentation. */      switch (inst->Instruction.Opcode) { +        /* XXX trig needs extra prep */ +        case TGSI_OPCODE_COS: +        case TGSI_OPCODE_SIN:          /* The simple scalar ops. */          case TGSI_OPCODE_EX2:          case TGSI_OPCODE_LG2: @@ -452,6 +462,8 @@ static void r500_fs_instruction(struct r500_fragment_shader* fs,              inst->FullSrcRegisters[0].SrcRegister.SwizzleW =                  inst->FullSrcRegisters[0].SrcRegister.SwizzleX;              /* Fall through */ +        case TGSI_OPCODE_DDX: +        case TGSI_OPCODE_DDY:          case TGSI_OPCODE_FRC:              r500_emit_maths(fs, assembler, inst->FullSrcRegisters,                      &inst->FullDstRegisters[0], inst->Instruction.Opcode, 1); @@ -527,6 +539,60 @@ static void r500_fs_instruction(struct r500_fragment_shader* fs,                      &inst->FullDstRegisters[0], inst->Instruction.Opcode, 3);              break; +        /* The compound and hybrid insts. */ +        case TGSI_OPCODE_LRP: +            /* LRP DST A, B, C -> MAD TMP -A, C, C; MAD DST A, B, TMP */ +            inst->FullSrcRegisters[3] = inst->FullSrcRegisters[1]; +            inst->FullSrcRegisters[1] = inst->FullSrcRegisters[2]; +            inst->FullSrcRegisters[0].SrcRegister.Negate = +                !(inst->FullSrcRegisters[0].SrcRegister.Negate); +            inst->FullDstRegisters[1] = inst->FullDstRegisters[0]; +            inst->FullDstRegisters[0].DstRegister.Index = +                assembler->temp_count; +            inst->FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; +            r500_emit_maths(fs, assembler, inst->FullSrcRegisters, +                    &inst->FullDstRegisters[0], TGSI_OPCODE_MAD, 3); +            inst->FullSrcRegisters[2].SrcRegister.Index = +                assembler->temp_count; +            inst->FullSrcRegisters[2].SrcRegister.File = TGSI_FILE_TEMPORARY; +            inst->FullSrcRegisters[2].SrcRegister.SwizzleX = TGSI_SWIZZLE_X; +            inst->FullSrcRegisters[2].SrcRegister.SwizzleY = TGSI_SWIZZLE_Y; +            inst->FullSrcRegisters[2].SrcRegister.SwizzleZ = TGSI_SWIZZLE_Z; +            inst->FullSrcRegisters[2].SrcRegister.SwizzleW = TGSI_SWIZZLE_W; +            inst->FullSrcRegisters[1] = inst->FullSrcRegisters[3]; +            inst->FullSrcRegisters[0].SrcRegister.Negate = +                !(inst->FullSrcRegisters[0].SrcRegister.Negate); +            inst->FullDstRegisters[0] = inst->FullDstRegisters[1]; +            r500_emit_maths(fs, assembler, inst->FullSrcRegisters, +                    &inst->FullDstRegisters[0], TGSI_OPCODE_MAD, 3); +            break; +        case TGSI_OPCODE_POW: +            /* POW DST A, B -> LG2 TMP A; MUL TMP TMP, B; EX2 DST TMP */ +            inst->FullSrcRegisters[0].SrcRegisterExtSwz.ExtSwizzleW = +                inst->FullSrcRegisters[0].SrcRegisterExtSwz.ExtSwizzleX; +            inst->FullSrcRegisters[0].SrcRegister.SwizzleW = +                inst->FullSrcRegisters[0].SrcRegister.SwizzleX; +            inst->FullDstRegisters[1] = inst->FullDstRegisters[0]; +            inst->FullDstRegisters[0].DstRegister.Index = +                assembler->temp_count; +            inst->FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; +            r500_emit_maths(fs, assembler, inst->FullSrcRegisters, +                    &inst->FullDstRegisters[0], TGSI_OPCODE_LG2, 1); +            inst->FullSrcRegisters[0].SrcRegister.Index = +                assembler->temp_count; +            inst->FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; +            inst->FullSrcRegisters[0].SrcRegister.SwizzleX = TGSI_SWIZZLE_X; +            inst->FullSrcRegisters[0].SrcRegister.SwizzleY = TGSI_SWIZZLE_Y; +            inst->FullSrcRegisters[0].SrcRegister.SwizzleZ = TGSI_SWIZZLE_Z; +            inst->FullSrcRegisters[0].SrcRegister.SwizzleW = TGSI_SWIZZLE_W; +            inst->FullSrcRegisters[2] = r500_constant_zero; +            r500_emit_maths(fs, assembler, inst->FullSrcRegisters, +                    &inst->FullDstRegisters[0], TGSI_OPCODE_MUL, 3); +            inst->FullDstRegisters[0] = inst->FullDstRegisters[1]; +            r500_emit_maths(fs, assembler, inst->FullSrcRegisters, +                    &inst->FullDstRegisters[0], TGSI_OPCODE_EX2, 1); +            break; +          /* The texture instruction set. */          case TGSI_OPCODE_KIL:          case TGSI_OPCODE_TEX: @@ -555,7 +621,7 @@ static void r500_fs_instruction(struct r500_fragment_shader* fs,  static void r300_fs_finalize(struct r3xx_fragment_shader* fs,                               struct r300_fs_asm* assembler)  { -    fs->stack_size = assembler->temp_count + assembler->temp_offset; +    fs->stack_size = assembler->temp_count + assembler->temp_offset + 1;  }  static void r500_fs_finalize(struct r500_fragment_shader* fs, @@ -581,6 +647,8 @@ void r300_translate_fragment_shader(struct r300_context* r300,      }      /* Setup starting offset for immediates. */      assembler->imm_offset = consts->user_count; +    /* Enable depth writes, if needed. */ +    assembler->writes_depth = fs->info.writes_z;      /* Make sure we start at the beginning of the shader. */      if (is_r500) { @@ -630,6 +698,7 @@ void r300_translate_fragment_shader(struct r300_context* r300,              assembler->tex_count + assembler->color_count);      consts->count = consts->user_count + assembler->imm_count; +    fs->uses_imms = assembler->imm_count;      debug_printf("r300: fs: %d total constants, "              "%d from user and %d from immediates\n", consts->count,              consts->user_count, assembler->imm_count); diff --git a/src/gallium/drivers/r300/r300_state_shader.h b/src/gallium/drivers/r300/r300_state_shader.h index 185fdd90f0..b6087404ce 100644 --- a/src/gallium/drivers/r300/r300_state_shader.h +++ b/src/gallium/drivers/r300/r300_state_shader.h @@ -57,6 +57,7 @@  #define R500_TEX_WMASK(x) ((x) << 11)  #define R500_ALU_WMASK(x) ((x) << 11)  #define R500_ALU_OMASK(x) ((x) << 15) +#define R500_W_OMASK (1 << 31)  /* TGSI constants. TGSI is like XML: If it can't solve your problems, you're   * not using enough of it. */ @@ -99,20 +100,17 @@ struct r300_fs_asm {      unsigned imm_offset;      /* Number of immediate constants. */      unsigned imm_count; +    /* Are depth writes enabled? */ +    boolean writes_depth; +    /* Depth write offset. This is the TGSI output that corresponds to +     * depth writes. */ +    unsigned depth_output;  };  void r300_translate_fragment_shader(struct r300_context* r300,                             struct r3xx_fragment_shader* fs);  static struct r300_fragment_shader r300_passthrough_fragment_shader = { -    /* XXX This is the emission code. TODO: decode -    OUT_CS_REG(R300_US_CONFIG, 0); -    OUT_CS_REG(R300_US_CODE_OFFSET, 0x0); -    OUT_CS_REG(R300_US_CODE_ADDR_0, 0x0); -    OUT_CS_REG(R300_US_CODE_ADDR_1, 0x0); -    OUT_CS_REG(R300_US_CODE_ADDR_2, 0x0); -    OUT_CS_REG(R300_US_CODE_ADDR_3, 0x400000); -*/      .alu_instruction_count = 1,      .tex_instruction_count = 0,      .indirections = 0, @@ -159,14 +157,6 @@ static struct r500_fragment_shader r500_passthrough_fragment_shader = {  };  static struct r300_fragment_shader r300_texture_fragment_shader = { -    /* XXX This is the emission code. TODO: decode -    OUT_CS_REG(R300_US_CONFIG, 0); -    OUT_CS_REG(R300_US_CODE_OFFSET, 0x0); -    OUT_CS_REG(R300_US_CODE_ADDR_0, 0x0); -    OUT_CS_REG(R300_US_CODE_ADDR_1, 0x0); -    OUT_CS_REG(R300_US_CODE_ADDR_2, 0x0); -    OUT_CS_REG(R300_US_CODE_ADDR_3, 0x400000); -*/      .alu_instruction_count = 1,      .tex_instruction_count = 0,      .indirections = 0, @@ -191,7 +181,7 @@ static struct r500_fragment_shader r500_texture_fragment_shader = {      .instruction_count = 2,      .instructions[0].inst0 = R500_INST_TYPE_TEX |          R500_INST_TEX_SEM_WAIT | -        R500_INST_RGB_OMASK_RGB | R500_INST_ALPHA_OMASK | +        R500_INST_RGB_WMASK_RGB | R500_INST_ALPHA_WMASK |          R500_INST_RGB_CLAMP | R500_INST_ALPHA_CLAMP,      .instructions[0].inst1 = R500_TEX_ID(0) | R500_TEX_INST_LD |          R500_TEX_SEM_ACQUIRE | R500_TEX_IGNORE_UNCOVERED, diff --git a/src/gallium/drivers/r300/r300_state_tcl.c b/src/gallium/drivers/r300/r300_state_tcl.c index d84912de48..32e61bc1d7 100644 --- a/src/gallium/drivers/r300/r300_state_tcl.c +++ b/src/gallium/drivers/r300/r300_state_tcl.c @@ -71,16 +71,13 @@ static INLINE unsigned r300_vs_src_type(struct r300_vs_asm* assembler,  {      switch (src->File) {          case TGSI_FILE_NULL: -            /* Probably a zero or one swizzle */ -            return R300_PVS_SRC_REG_INPUT; -            break;          case TGSI_FILE_INPUT: +            /* Probably a zero or one swizzle */              return R300_PVS_SRC_REG_INPUT; -            break;          case TGSI_FILE_TEMPORARY:              return R300_PVS_SRC_REG_TEMPORARY; -            break;          case TGSI_FILE_CONSTANT: +        case TGSI_FILE_IMMEDIATE:              return R300_PVS_SRC_REG_CONSTANT;          default:              debug_printf("r300: vs: Unimplemented src type %d\n", src->File); @@ -89,16 +86,32 @@ static INLINE unsigned r300_vs_src_type(struct r300_vs_asm* assembler,      return 0;  } +static INLINE unsigned r300_vs_src(struct r300_vs_asm* assembler, +                                   struct tgsi_src_register* src) +{ +    switch (src->File) { +        case TGSI_FILE_NULL: +        case TGSI_FILE_INPUT: +        case TGSI_FILE_TEMPORARY: +        case TGSI_FILE_CONSTANT: +            return src->Index; +        case TGSI_FILE_IMMEDIATE: +            return src->Index + assembler->imm_offset; +        default: +            debug_printf("r300: vs: Unimplemented src type %d\n", src->File); +            break; +    } +    return 0; +} +  static INLINE unsigned r300_vs_dst_type(struct r300_vs_asm* assembler,                                          struct tgsi_dst_register* dst)  {      switch (dst->File) {          case TGSI_FILE_TEMPORARY:              return R300_PVS_DST_REG_TEMPORARY; -            break;          case TGSI_FILE_OUTPUT:              return R300_PVS_DST_REG_OUT; -            break;          default:              debug_printf("r300: vs: Unimplemented dst type %d\n", dst->File);              break; @@ -112,10 +125,8 @@ static INLINE unsigned r300_vs_dst(struct r300_vs_asm* assembler,      switch (dst->File) {          case TGSI_FILE_TEMPORARY:              return dst->Index; -            break;          case TGSI_FILE_OUTPUT:              return assembler->tab[dst->Index]; -            break;          default:              debug_printf("r300: vs: Unimplemented dst %d\n", dst->File);              break; @@ -135,6 +146,12 @@ static uint32_t r300_vs_op(unsigned op)          case TGSI_OPCODE_MOV:          case TGSI_OPCODE_SWZ:              return R300_VE_ADD; +        case TGSI_OPCODE_MAX: +            return R300_VE_MAXIMUM; +        case TGSI_OPCODE_SLT: +            return R300_VE_SET_LESS_THAN; +        case TGSI_OPCODE_RSQ: +            return R300_PVS_DST_MATH_INST | R300_ME_RECIP_DX;          case TGSI_OPCODE_MAD:              return R300_PVS_DST_MACRO_INST | R300_PVS_MACRO_OP_2CLK_MADD;          default: @@ -158,39 +175,62 @@ static uint32_t r300_vs_swiz(struct tgsi_full_src_register* reg)      }  } +/* XXX icky icky icky icky */ +static uint32_t r300_vs_scalar_swiz(struct tgsi_full_src_register* reg) +{ +    if (reg->SrcRegister.Extended) { +        return reg->SrcRegisterExtSwz.ExtSwizzleX | +            (reg->SrcRegisterExtSwz.ExtSwizzleX << 3) | +            (reg->SrcRegisterExtSwz.ExtSwizzleX << 6) | +            (reg->SrcRegisterExtSwz.ExtSwizzleX << 9); +    } else { +        return reg->SrcRegister.SwizzleX | +            (reg->SrcRegister.SwizzleX << 3) | +            (reg->SrcRegister.SwizzleX << 6) | +            (reg->SrcRegister.SwizzleX << 9); +    } +} + +/* XXX scalar stupidity */  static void r300_vs_emit_inst(struct r300_vertex_shader* vs,                                struct r300_vs_asm* assembler,                                struct tgsi_full_src_register* src,                                struct tgsi_full_dst_register* dst,                                unsigned op, -                              unsigned count) +                              unsigned count, +                              boolean is_scalar)  {      int i = vs->instruction_count;      vs->instructions[i].inst0 = R300_PVS_DST_OPCODE(r300_vs_op(op)) |          R300_PVS_DST_REG_TYPE(r300_vs_dst_type(assembler, &dst->DstRegister)) |          R300_PVS_DST_OFFSET(r300_vs_dst(assembler, &dst->DstRegister)) | -        R300_PVS_DST_WE_XYZW; +        R300_PVS_DST_WE(dst->DstRegister.WriteMask);      switch (count) {          case 3:              vs->instructions[i].inst3 =                  R300_PVS_SRC_REG_TYPE(r300_vs_src_type(assembler,                              &src[2].SrcRegister)) | -                R300_PVS_SRC_OFFSET(src[2].SrcRegister.Index) | +                R300_PVS_SRC_OFFSET(r300_vs_src(assembler, +                            &src[2].SrcRegister)) |                  R300_PVS_SRC_SWIZZLE(r300_vs_swiz(&src[2]));              /* Fall through */          case 2:              vs->instructions[i].inst2 =                  R300_PVS_SRC_REG_TYPE(r300_vs_src_type(assembler,                              &src[1].SrcRegister)) | -                R300_PVS_SRC_OFFSET(src[1].SrcRegister.Index) | +                R300_PVS_SRC_OFFSET(r300_vs_src(assembler, +                            &src[1].SrcRegister)) |                  R300_PVS_SRC_SWIZZLE(r300_vs_swiz(&src[1]));              /* Fall through */          case 1:              vs->instructions[i].inst1 =                  R300_PVS_SRC_REG_TYPE(r300_vs_src_type(assembler,                              &src[0].SrcRegister)) | -                R300_PVS_SRC_OFFSET(src[0].SrcRegister.Index) | -                R300_PVS_SRC_SWIZZLE(r300_vs_swiz(&src[0])); +                R300_PVS_SRC_OFFSET(r300_vs_src(assembler, +                            &src[0].SrcRegister)) | +                /* XXX the icky, it burns */ +                R300_PVS_SRC_SWIZZLE(is_scalar ? r300_vs_scalar_swiz(&src[0]) +                        : r300_vs_swiz(&src[0]));              break;      }      vs->instruction_count++; @@ -201,11 +241,18 @@ static void r300_vs_instruction(struct r300_vertex_shader* vs,                                  struct tgsi_full_instruction* inst)  {      switch (inst->Instruction.Opcode) { +        case TGSI_OPCODE_RSQ: +            r300_vs_emit_inst(vs, assembler, inst->FullSrcRegisters, +                    &inst->FullDstRegisters[0], inst->Instruction.Opcode, +                    1, TRUE); +            break;          case TGSI_OPCODE_ADD:          case TGSI_OPCODE_MUL: +        case TGSI_OPCODE_MAX: +        case TGSI_OPCODE_SLT:              r300_vs_emit_inst(vs, assembler, inst->FullSrcRegisters,                      &inst->FullDstRegisters[0], inst->Instruction.Opcode, -                    2); +                    2, FALSE);              break;          case TGSI_OPCODE_DP3:              /* Set alpha swizzle to zero for src0 and src1 */ @@ -235,19 +282,19 @@ static void r300_vs_instruction(struct r300_vertex_shader* vs,          case TGSI_OPCODE_DP4:              r300_vs_emit_inst(vs, assembler, inst->FullSrcRegisters,                      &inst->FullDstRegisters[0], inst->Instruction.Opcode, -                    2); +                    2, FALSE);              break;          case TGSI_OPCODE_MOV:          case TGSI_OPCODE_SWZ:              inst->FullSrcRegisters[1] = r300_constant_zero;              r300_vs_emit_inst(vs, assembler, inst->FullSrcRegisters,                      &inst->FullDstRegisters[0], inst->Instruction.Opcode, -                    2); +                    2, FALSE);              break;          case TGSI_OPCODE_MAD:              r300_vs_emit_inst(vs, assembler, inst->FullSrcRegisters,                      &inst->FullDstRegisters[0], inst->Instruction.Opcode, -                    3); +                    3, FALSE);              break;          case TGSI_OPCODE_END:              break; @@ -278,6 +325,8 @@ static void r300_vs_init(struct r300_vertex_shader* vs,                  break;          }      } + +    vs->instruction_count = 0;  }  void r300_translate_vertex_shader(struct r300_context* r300, @@ -337,6 +386,7 @@ void r300_translate_vertex_shader(struct r300_context* r300,              assembler->tex_count + assembler->color_count);      consts->count = consts->user_count + assembler->imm_count; +    vs->uses_imms = assembler->imm_count;      debug_printf("r300: vs: %d total constants, "              "%d from user and %d from immediates\n", consts->count,              consts->user_count, assembler->imm_count); diff --git a/src/gallium/drivers/r300/r300_state_tcl.h b/src/gallium/drivers/r300/r300_state_tcl.h index e2e1357d43..d5d425e9d6 100644 --- a/src/gallium/drivers/r300/r300_state_tcl.h +++ b/src/gallium/drivers/r300/r300_state_tcl.h @@ -35,6 +35,10 @@  #   define R300_VE_DOT_PRODUCT            1  #   define R300_VE_MULTIPLY               2  #   define R300_VE_ADD                    3 +#   define R300_VE_MAXIMUM                7 +#   define R300_VE_SET_LESS_THAN          10 +#define R300_PVS_DST_MATH_INST     (1 << 6) +#   define R300_ME_RECIP_DX               6  #define R300_PVS_DST_MACRO_INST    (1 << 7)  #   define R300_PVS_MACRO_OP_2CLK_MADD    0  #define R300_PVS_DST_REG_TYPE(x) ((x) << 8) diff --git a/src/gallium/drivers/r300/r300_surface.c b/src/gallium/drivers/r300/r300_surface.c index 4dd5b8af99..7711e8f569 100644 --- a/src/gallium/drivers/r300/r300_surface.c +++ b/src/gallium/drivers/r300/r300_surface.c @@ -23,30 +23,36 @@  #include "r300_surface.h" -static void r300_surface_setup(struct pipe_context* pipe, -                               struct pipe_surface* dest, +static void r300_surface_setup(struct r300_context* r300, +                               struct r300_texture* dest,                                 unsigned x, unsigned y,                                 unsigned w, unsigned h)  { -    struct r300_context* r300 = r300_context(pipe); -    struct r300_capabilities* caps = r300_screen(pipe->screen)->caps; -    struct r300_texture* tex = (struct r300_texture*)dest->texture; -    unsigned pixpitch = tex->stride / tex->tex.block.size; +    struct r300_capabilities* caps = r300_screen(r300->context.screen)->caps; +    unsigned pixpitch = dest->stride / dest->tex.block.size;      CS_LOCALS(r300); -    /* Make sure our target BO is okay. */ -    r300->winsys->add_buffer(r300->winsys, tex->buffer, -            0, RADEON_GEM_DOMAIN_VRAM); -    if (r300->winsys->validate(r300->winsys)) { -        r300->context.flush(&r300->context, 0, NULL); -    } -      r300_emit_blend_state(r300, &blend_clear_state);      r300_emit_blend_color_state(r300, &blend_color_clear_state);      r300_emit_dsa_state(r300, &dsa_clear_state);      r300_emit_rs_state(r300, &rs_clear_state); -    BEGIN_CS(15); +    BEGIN_CS(24); + +    /* Viewport setup */ +    OUT_CS_REG_SEQ(R300_SE_VPORT_XSCALE, 6); +    OUT_CS_32F((float)w); +    OUT_CS_32F((float)x); +    OUT_CS_32F((float)h); +    OUT_CS_32F((float)y); +    OUT_CS_32F(1.0); +    OUT_CS_32F(0.0); + +    OUT_CS_REG(R300_VAP_VTE_CNTL, R300_VPORT_X_SCALE_ENA | +            R300_VPORT_X_OFFSET_ENA | +            R300_VPORT_Y_SCALE_ENA | +            R300_VPORT_Y_OFFSET_ENA | +            R300_VTX_XY_FMT | R300_VTX_Z_FMT);      /* Pixel scissors. */      OUT_CS_REG_SEQ(R300_SC_SCISSORS_TL, 2); @@ -71,9 +77,9 @@ static void r300_surface_setup(struct pipe_context* pipe,      /* Setup colorbuffer. */      OUT_CS_REG_SEQ(R300_RB3D_COLOROFFSET0, 1); -    OUT_CS_RELOC(tex->buffer, 0, 0, RADEON_GEM_DOMAIN_VRAM, 0); +    OUT_CS_RELOC(dest->buffer, 0, 0, RADEON_GEM_DOMAIN_VRAM, 0);      OUT_CS_REG(R300_RB3D_COLORPITCH0, pixpitch | -        r300_translate_colorformat(tex->tex.format)); +        r300_translate_colorformat(dest->tex.format));      OUT_CS_REG(RB3D_COLOR_CHANNEL_MASK, 0xf);      END_CS; @@ -93,6 +99,7 @@ static void r300_surface_fill(struct pipe_context* pipe,      struct r300_capabilities* caps = r300_screen(pipe->screen)->caps;      struct r300_texture* tex = (struct r300_texture*)dest->texture;      unsigned pixpitch = tex->stride / tex->tex.block.size; +    boolean invalid = FALSE;      CS_LOCALS(r300);      a = (float)((color >> 24) & 0xff) / 255.0f; @@ -105,12 +112,26 @@ static void r300_surface_fill(struct pipe_context* pipe,      /* Fallback? */      if (FALSE) { +fallback:          debug_printf("r300: Falling back on surface clear...");          util_surface_fill(pipe, dest, x, y, w, h, color);          return;      } -    r300_surface_setup(r300, dest, x, y, w, h); +    /* Make sure our target BO is okay. */ +validate: +    r300->winsys->add_buffer(r300->winsys, tex->buffer, +            0, RADEON_GEM_DOMAIN_VRAM); +    if (r300->winsys->validate(r300->winsys)) { +        r300->context.flush(&r300->context, 0, NULL); +        if (invalid) { +            goto fallback; +        } +        invalid = TRUE; +        goto validate; +    } + +    r300_surface_setup(r300, tex, x, y, w, h);      /* Vertex shader setup */      if (caps->has_tcl) { @@ -134,7 +155,7 @@ static void r300_surface_fill(struct pipe_context* pipe,          r300_emit_rs_block_state(r300, &r300_rs_block_clear_state);      } -    BEGIN_CS(31); +    BEGIN_CS(26);      /* VAP stream control, mapping from input memory to PVS/RS memory */      if (caps->has_tcl) { @@ -161,27 +182,21 @@ static void r300_surface_fill(struct pipe_context* pipe,      /* Disable textures */      OUT_CS_REG(R300_TX_ENABLE, 0x0); -    /* Viewport setup */ -    OUT_CS_REG_SEQ(R300_SE_VPORT_XSCALE, 6); -    OUT_CS_32F(1.0); -    OUT_CS_32F((float)x); -    OUT_CS_32F(1.0); -    OUT_CS_32F((float)y); -    OUT_CS_32F(1.0); -    OUT_CS_32F(0.0); -      /* The size of the point we're about to draw, in sixths of pixels */      OUT_CS_REG(R300_GA_POINT_SIZE, -        ((h * 6) & R300_POINTSIZE_Y_MASK) | +        ((h * 6)  & R300_POINTSIZE_Y_MASK) |          ((w * 6) << R300_POINTSIZE_X_SHIFT)); +    /* Vertex size. */ +    OUT_CS_REG(R300_VAP_VTX_SIZE, 0x8); +      /* Packet3 with our point vertex */      OUT_CS_PKT3(R200_3D_DRAW_IMMD_2, 8);      OUT_CS(R300_PRIM_TYPE_POINT | R300_PRIM_WALK_RING |              (1 << R300_PRIM_NUM_VERTICES_SHIFT));      /* Position */ -    OUT_CS_32F(w / 2.0); -    OUT_CS_32F(h / 2.0); +    OUT_CS_32F(0.5); +    OUT_CS_32F(0.5);      OUT_CS_32F(1.0);      OUT_CS_32F(1.0);      /* Color */ @@ -190,11 +205,7 @@ static void r300_surface_fill(struct pipe_context* pipe,      OUT_CS_32F(b);      OUT_CS_32F(a); -    /* XXX figure out why this is 0xA and not 0x2 */      OUT_CS_REG(R300_RB3D_DSTCACHE_CTLSTAT, 0xA); -    /* XXX OUT_CS_REG(R300_ZB_ZCACHE_CTLSTAT, -        R300_ZB_ZCACHE_CTLSTAT_ZC_FLUSH_FLUSH_AND_FREE | -        R300_ZB_ZCACHE_CTLSTAT_ZC_FREE_FREE); */      END_CS; @@ -213,6 +224,7 @@ static void r300_surface_copy(struct pipe_context* pipe,      struct r300_texture* srctex = (struct r300_texture*)src->texture;      struct r300_texture* desttex = (struct r300_texture*)dest->texture;      unsigned pixpitch = srctex->stride / srctex->tex.block.size; +    boolean invalid = FALSE;      CS_LOCALS(r300);      debug_printf("r300: Copying surface %p at (%d,%d) to %p at (%d, %d)," @@ -222,18 +234,42 @@ static void r300_surface_copy(struct pipe_context* pipe,      if ((srctex == desttex) &&              ((destx < srcx + w) || (srcx < destx + w)) &&              ((desty < srcy + h) || (srcy < desty + h))) { +fallback:          debug_printf("r300: Falling back on surface_copy\n");          util_surface_copy(pipe, FALSE, dest, destx, desty, src,                  srcx, srcy, w, h);      } +    /* Add our target BOs to the list. */ +validate: +    r300->winsys->add_buffer(r300->winsys, srctex->buffer, +            RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0); +    r300->winsys->add_buffer(r300->winsys, desttex->buffer, +            0, RADEON_GEM_DOMAIN_VRAM); +    if (r300->winsys->validate(r300->winsys)) { +        r300->context.flush(&r300->context, 0, NULL); +        if (invalid) { +            goto fallback; +        } +        invalid = TRUE; +        goto validate; +    } + +    r300_surface_setup(r300, desttex, destx, desty, w, h); + +    /* Setup the texture. */      r300_emit_sampler(r300, &r300_sampler_copy_state, 0);      r300_emit_texture(r300, srctex, 0); -    r300_flush_textures(r300); + +    /* Flush and enable. */ +    BEGIN_CS(4); +    OUT_CS_REG(R300_TX_INVALTAGS, 0); +    OUT_CS_REG(R300_TX_ENABLE, 0x1); +    END_CS;      /* Vertex shader setup */      if (caps->has_tcl) { -        r300_emit_vertex_shader(r300, &r300_texture_vertex_shader); +        r300_emit_vertex_shader(r300, &r300_passthrough_vertex_shader);      } else {          BEGIN_CS(4);          OUT_CS_REG(R300_VAP_CNTL_STATUS, R300_VAP_TCL_BYPASS); @@ -253,6 +289,7 @@ static void r300_surface_copy(struct pipe_context* pipe,          r300_emit_rs_block_state(r300, &r300_rs_block_copy_state);      } +    BEGIN_CS(30);      /* VAP stream control, mapping from input memory to PVS/RS memory */      if (caps->has_tcl) {          OUT_CS_REG(R300_VAP_PROG_STREAM_CNTL_0, @@ -275,33 +312,38 @@ static void r300_surface_copy(struct pipe_context* pipe,      /* Two components of texture 0 */      OUT_CS_REG(R300_VAP_OUTPUT_VTX_FMT_1, 0x2); +    /* Vertex size. */ +    OUT_CS_REG(R300_VAP_VTX_SIZE, 0x4); +      /* Packet3 with our texcoords */ -    OUT_CS_PKT3(R200_3D_DRAW_IMMD_2, 8); +    OUT_CS_PKT3(R200_3D_DRAW_IMMD_2, 16);      OUT_CS(R300_PRIM_TYPE_QUADS | R300_PRIM_WALK_RING |              (4 << R300_PRIM_NUM_VERTICES_SHIFT));      /* (x    , y    ) */ -    OUT_CS_32F((float)destx); -    OUT_CS_32F((float)desty); -    OUT_CS_32F((float)srcx); -    OUT_CS_32F((float)srcy); +    OUT_CS_32F((float)(destx / dest->width)); +    OUT_CS_32F((float)(desty / dest->height)); +    OUT_CS_32F((float)(srcx  / dest->width)); +    OUT_CS_32F((float)(srcy  / dest->height));      /* (x    , y + h) */ -    OUT_CS_32F((float)destx); -    OUT_CS_32F((float)(desty + h)); -    OUT_CS_32F((float)srcx); -    OUT_CS_32F((float)(srcy + h)); +    OUT_CS_32F((float)(destx / dest->width)); +    OUT_CS_32F((float)((desty + h) / dest->height)); +    OUT_CS_32F((float)(srcx  / dest->width)); +    OUT_CS_32F((float)((srcy  + h) / dest->height));      /* (x + w, y + h) */ -    OUT_CS_32F((float)(destx + w)); -    OUT_CS_32F((float)(desty + h)); -    OUT_CS_32F((float)(srcx + w)); -    OUT_CS_32F((float)(srcy + h)); +    OUT_CS_32F((float)((destx + w) / dest->width)); +    OUT_CS_32F((float)((desty + h) / dest->height)); +    OUT_CS_32F((float)((srcx  + w) / dest->width)); +    OUT_CS_32F((float)((srcy  + h) / dest->height));      /* (x + w, y    ) */ -    OUT_CS_32F((float)(destx + w)); -    OUT_CS_32F((float)desty); -    OUT_CS_32F((float)(srcx + w)); -    OUT_CS_32F((float)srcy); +    OUT_CS_32F((float)((destx + w) / dest->width)); +    OUT_CS_32F((float)(desty / dest->height)); +    OUT_CS_32F((float)((srcx  + w) / dest->width)); +    OUT_CS_32F((float)(srcy  / dest->height));      OUT_CS_REG(R300_RB3D_DSTCACHE_CTLSTAT, 0xA); +    END_CS; +      r300->dirty_hw++;  } diff --git a/src/gallium/drivers/r300/r300_surface.h b/src/gallium/drivers/r300/r300_surface.h index 894def07aa..9a4c39f58b 100644 --- a/src/gallium/drivers/r300/r300_surface.h +++ b/src/gallium/drivers/r300/r300_surface.h @@ -101,7 +101,7 @@ static struct r300_rs_block r300_rs_block_copy_state = {          R500_RS_SEL_Q(R300_RS_SEL_K1),      .inst[0] = R300_RS_INST_COL_CN_WRITE,      .count = R300_IT_COUNT(2) | R300_IC_COUNT(0) | R300_HIRES_EN, -    .inst_count = R300_RS_TX_OFFSET(6), +    .inst_count = R300_RS_TX_OFFSET(0),  };  static struct r300_rs_block r500_rs_block_copy_state = { @@ -111,7 +111,7 @@ static struct r300_rs_block r500_rs_block_copy_state = {          R500_RS_SEL_Q(R500_RS_IP_PTR_K1),      .inst[0] = R500_RS_INST_TEX_CN_WRITE,      .count = R300_IT_COUNT(2) | R300_IC_COUNT(0) | R300_HIRES_EN, -    .inst_count = R300_RS_TX_OFFSET(6), +    .inst_count = R300_RS_TX_OFFSET(0),  };  static struct r300_sampler_state r300_sampler_copy_state = { diff --git a/src/gallium/drivers/r300/r300_texture.c b/src/gallium/drivers/r300/r300_texture.c index fe91f4e184..5ea9f56247 100644 --- a/src/gallium/drivers/r300/r300_texture.c +++ b/src/gallium/drivers/r300/r300_texture.c @@ -86,8 +86,6 @@ static struct pipe_texture*      r300_texture_create(struct pipe_screen* screen,                          const struct pipe_texture* template)  { -    /* XXX struct r300_screen* r300screen = r300_screen(screen); */ -      struct r300_texture* tex = CALLOC_STRUCT(r300_texture);      if (!tex) { diff --git a/src/gallium/drivers/r300/r300_winsys.h b/src/gallium/drivers/r300/r300_winsys.h index a833bb0399..a5ced8041c 100644 --- a/src/gallium/drivers/r300/r300_winsys.h +++ b/src/gallium/drivers/r300/r300_winsys.h @@ -45,9 +45,6 @@ struct r300_winsys {      /* PCI ID */      uint32_t pci_id; -    /* GB pipe count */ -    uint32_t gb_pipes; -      /* GART size. */      uint32_t gart_size; diff --git a/src/gallium/drivers/softpipe/sp_context.h b/src/gallium/drivers/softpipe/sp_context.h index 59d6df8f2d..b89a7292e5 100644 --- a/src/gallium/drivers/softpipe/sp_context.h +++ b/src/gallium/drivers/softpipe/sp_context.h @@ -92,6 +92,7 @@ struct softpipe_context {      * queries.      */     uint64_t occlusion_count; +   unsigned active_query_count;     /** Mapped vertex buffers */     ubyte *mapped_vbuffer[PIPE_MAX_ATTRIBS]; diff --git a/src/gallium/drivers/softpipe/sp_quad_pipe.c b/src/gallium/drivers/softpipe/sp_quad_pipe.c index 892ef87ee9..b5f69b7426 100644 --- a/src/gallium/drivers/softpipe/sp_quad_pipe.c +++ b/src/gallium/drivers/softpipe/sp_quad_pipe.c @@ -80,7 +80,7 @@ sp_build_quad_pipeline(struct softpipe_context *sp)           sp_push_quad_first( sp, sp->quad[i].blend, i );        } -      if (sp->depth_stencil->depth.occlusion_count) { +      if (sp->active_query_count) {           sp_push_quad_first( sp, sp->quad[i].occlusion, i );        } diff --git a/src/gallium/drivers/softpipe/sp_query.c b/src/gallium/drivers/softpipe/sp_query.c index 93dab236d6..379cf4ad06 100644 --- a/src/gallium/drivers/softpipe/sp_query.c +++ b/src/gallium/drivers/softpipe/sp_query.c @@ -34,6 +34,7 @@  #include "util/u_memory.h"  #include "sp_context.h"  #include "sp_query.h" +#include "sp_state.h"  struct softpipe_query {     uint64_t start; @@ -69,6 +70,8 @@ softpipe_begin_query(struct pipe_context *pipe, struct pipe_query *q)     struct softpipe_query *sq = softpipe_query(q);     sq->start = softpipe->occlusion_count; +   softpipe->active_query_count++; +   softpipe->dirty |= SP_NEW_QUERY;  } @@ -78,7 +81,9 @@ softpipe_end_query(struct pipe_context *pipe, struct pipe_query *q)     struct softpipe_context *softpipe = softpipe_context( pipe );     struct softpipe_query *sq = softpipe_query(q); +   softpipe->active_query_count--;     sq->end = softpipe->occlusion_count; +   softpipe->dirty |= SP_NEW_QUERY;  } diff --git a/src/gallium/drivers/trace/Makefile b/src/gallium/drivers/trace/Makefile index e087db169a..ecb69fb996 100644 --- a/src/gallium/drivers/trace/Makefile +++ b/src/gallium/drivers/trace/Makefile @@ -7,6 +7,7 @@ C_SOURCES = \  	tr_buffer.c \  	tr_context.c \  	tr_dump.c \ +	tr_dump_state.c \  	tr_screen.c \  	tr_state.c \  	tr_texture.c diff --git a/src/gallium/drivers/trace/SConscript b/src/gallium/drivers/trace/SConscript index 4215215d1a..9b5af0d86f 100644 --- a/src/gallium/drivers/trace/SConscript +++ b/src/gallium/drivers/trace/SConscript @@ -8,6 +8,7 @@ trace = env.ConvenienceLibrary(          'tr_buffer.c',          'tr_context.c',          'tr_dump.c', +        'tr_dump_state.c',          'tr_screen.c',          'tr_state.c',          'tr_texture.c', diff --git a/src/gallium/drivers/trace/tr_context.c b/src/gallium/drivers/trace/tr_context.c index 47280459a7..2ad5ca4998 100644 --- a/src/gallium/drivers/trace/tr_context.c +++ b/src/gallium/drivers/trace/tr_context.c @@ -31,11 +31,11 @@  #include "pipe/p_screen.h"  #include "tr_dump.h" +#include "tr_dump_state.h"  #include "tr_state.h"  #include "tr_buffer.h"  #include "tr_screen.h"  #include "tr_texture.h" -#include "tr_context.h"  static INLINE struct pipe_buffer * @@ -121,6 +121,9 @@ trace_context_draw_arrays(struct pipe_context *_pipe,     struct pipe_context *pipe = tr_ctx->pipe;     boolean result; +   if (tr_ctx->curr.fs->disabled || tr_ctx->curr.vs->disabled) +      return 0; +     trace_dump_call_begin("pipe_context", "draw_arrays");     trace_dump_arg(ptr, pipe); @@ -150,6 +153,9 @@ trace_context_draw_elements(struct pipe_context *_pipe,     struct pipe_buffer *indexBuffer = tr_buf->buffer;     boolean result; +   if (tr_ctx->curr.fs->disabled || tr_ctx->curr.vs->disabled) +      return 0; +     trace_screen_user_buffer_update(_pipe->screen, indexBuffer);     trace_dump_call_begin("pipe_context", "draw_elements"); @@ -187,6 +193,9 @@ trace_context_draw_range_elements(struct pipe_context *_pipe,     struct pipe_buffer *indexBuffer = tr_buf->buffer;     boolean result; +   if (tr_ctx->curr.fs->disabled || tr_ctx->curr.vs->disabled) +      return 0; +     trace_screen_user_buffer_update(_pipe->screen, indexBuffer);     trace_dump_call_begin("pipe_context", "draw_range_elements"); @@ -573,23 +582,32 @@ trace_context_create_fs_state(struct pipe_context *_pipe,     trace_dump_call_end(); +   result = trace_shader_create(tr_ctx, state, result, TRACE_SHADER_FRAGMENT); +     return result;  }  static INLINE void  trace_context_bind_fs_state(struct pipe_context *_pipe, -                            void *state) +                            void *_state)  {     struct trace_context *tr_ctx = trace_context(_pipe); +   struct trace_shader *tr_shdr = trace_shader(_state);     struct pipe_context *pipe = tr_ctx->pipe; +   void *state = tr_shdr ? tr_shdr->state : NULL;     trace_dump_call_begin("pipe_context", "bind_fs_state");     trace_dump_arg(ptr, pipe);     trace_dump_arg(ptr, state); -   pipe->bind_fs_state(pipe, state);; +   tr_ctx->curr.fs = tr_shdr; + +   if (tr_shdr && tr_shdr->replaced) +      state = tr_shdr->replaced; + +   pipe->bind_fs_state(pipe, state);     trace_dump_call_end();  } @@ -597,19 +615,23 @@ trace_context_bind_fs_state(struct pipe_context *_pipe,  static INLINE void  trace_context_delete_fs_state(struct pipe_context *_pipe, -                              void *state) +                              void *_state)  {     struct trace_context *tr_ctx = trace_context(_pipe); +   struct trace_shader *tr_shdr = trace_shader(_state);     struct pipe_context *pipe = tr_ctx->pipe; +   void *state = tr_shdr->state;     trace_dump_call_begin("pipe_context", "delete_fs_state");     trace_dump_arg(ptr, pipe);     trace_dump_arg(ptr, state); -   pipe->delete_fs_state(pipe, state);; +   pipe->delete_fs_state(pipe, state);     trace_dump_call_end(); + +   trace_shader_destroy(tr_ctx, tr_shdr);  } @@ -626,28 +648,37 @@ trace_context_create_vs_state(struct pipe_context *_pipe,     trace_dump_arg(ptr, pipe);     trace_dump_arg(shader_state, state); -   result = pipe->create_vs_state(pipe, state);; +   result = pipe->create_vs_state(pipe, state);     trace_dump_ret(ptr, result);     trace_dump_call_end(); +   result = trace_shader_create(tr_ctx, state, result, TRACE_SHADER_VERTEX); +     return result;  }  static INLINE void  trace_context_bind_vs_state(struct pipe_context *_pipe, -                            void *state) +                            void *_state)  {     struct trace_context *tr_ctx = trace_context(_pipe); +   struct trace_shader *tr_shdr = trace_shader(_state);     struct pipe_context *pipe = tr_ctx->pipe; +   void *state = tr_shdr ? tr_shdr->state : NULL;     trace_dump_call_begin("pipe_context", "bind_vs_state");     trace_dump_arg(ptr, pipe);     trace_dump_arg(ptr, state); +   tr_ctx->curr.vs = tr_shdr; + +   if (tr_shdr && tr_shdr->replaced) +      state = tr_shdr->replaced; +     pipe->bind_vs_state(pipe, state);;     trace_dump_call_end(); @@ -656,10 +687,12 @@ trace_context_bind_vs_state(struct pipe_context *_pipe,  static INLINE void  trace_context_delete_vs_state(struct pipe_context *_pipe, -                              void *state) +                              void *_state)  {     struct trace_context *tr_ctx = trace_context(_pipe); +   struct trace_shader *tr_shdr = trace_shader(_state);     struct pipe_context *pipe = tr_ctx->pipe; +   void *state = tr_shdr->state;     trace_dump_call_begin("pipe_context", "delete_vs_state"); @@ -669,6 +702,8 @@ trace_context_delete_vs_state(struct pipe_context *_pipe,     pipe->delete_vs_state(pipe, state);;     trace_dump_call_end(); + +   trace_shader_destroy(tr_ctx, tr_shdr);  } @@ -1089,7 +1124,7 @@ trace_context_create(struct pipe_screen *_screen,     if(!pipe)        goto error1; -   if(!trace_dump_trace_enabled()) +   if(!trace_enabled())        goto error1;     tr_scr = trace_screen(_screen); @@ -1099,6 +1134,9 @@ trace_context_create(struct pipe_screen *_screen,     if(!tr_ctx)        goto error1; +   pipe_mutex_init(tr_ctx->list_mutex); +   make_empty_list(&tr_ctx->shaders); +     tr_ctx->base.winsys = _screen->winsys;     tr_ctx->base.screen = _screen;     tr_ctx->base.destroy = trace_context_destroy; diff --git a/src/gallium/drivers/trace/tr_context.h b/src/gallium/drivers/trace/tr_context.h index 2512a0a232..86827f97b2 100644 --- a/src/gallium/drivers/trace/tr_context.h +++ b/src/gallium/drivers/trace/tr_context.h @@ -33,6 +33,7 @@  #include "util/u_debug.h"  #include "pipe/p_context.h" +#include "tr_screen.h"  #ifdef __cplusplus  extern "C" { @@ -45,7 +46,19 @@ struct trace_context     struct pipe_context *pipe; +   /* current state */ +   struct { +      struct trace_shader *fs; +      struct trace_shader *vs; +   } curr; + +   /* for list on screen */     struct tr_list list; + +   /* list of state objects */ +   pipe_mutex list_mutex; +   unsigned num_shaders; +   struct tr_list shaders;  }; diff --git a/src/gallium/drivers/trace/tr_dump_state.c b/src/gallium/drivers/trace/tr_dump_state.c new file mode 100644 index 0000000000..23a2473b57 --- /dev/null +++ b/src/gallium/drivers/trace/tr_dump_state.c @@ -0,0 +1,490 @@ +/************************************************************************** + * + * 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. + * + **************************************************************************/ + + +#include "pipe/p_compiler.h" +#include "util/u_memory.h" +#include "tgsi/tgsi_dump.h" + +#include "tr_dump.h" +#include "tr_dump_state.h" + + +void trace_dump_format(enum pipe_format format) +{ +   trace_dump_enum(pf_name(format) ); +} + + +void trace_dump_block(const struct pipe_format_block *block) +{ +   trace_dump_struct_begin("pipe_format_block"); +   trace_dump_member(uint, block, size); +   trace_dump_member(uint, block, width); +   trace_dump_member(uint, block, height); +   trace_dump_struct_end(); +} + + +static void trace_dump_reference(const struct pipe_reference *reference) +{ +   trace_dump_struct_begin("pipe_reference"); +   trace_dump_member(int, &reference->count, count); +   trace_dump_struct_end(); +} + + +void trace_dump_template(const struct pipe_texture *templat) +{ +   if(!templat) { +      trace_dump_null(); +      return; +   } + +   trace_dump_struct_begin("pipe_texture"); + +   trace_dump_member(int, templat, target); +   trace_dump_member(format, templat, format); + +   trace_dump_member_begin("width"); +   trace_dump_array(uint, templat->width, 1); +   trace_dump_member_end(); + +   trace_dump_member_begin("height"); +   trace_dump_array(uint, templat->height, 1); +   trace_dump_member_end(); + +   trace_dump_member_begin("depth"); +   trace_dump_array(uint, templat->depth, 1); +   trace_dump_member_end(); + +   trace_dump_member_begin("block"); +   trace_dump_block(&templat->block); +   trace_dump_member_end(); + +   trace_dump_member(uint, templat, last_level); +   trace_dump_member(uint, templat, tex_usage); + +   trace_dump_struct_end(); +} + + +void trace_dump_rasterizer_state(const struct pipe_rasterizer_state *state) +{ +   if(!state) { +      trace_dump_null(); +      return; +   } + +   trace_dump_struct_begin("pipe_rasterizer_state"); + +   trace_dump_member(bool, state, flatshade); +   trace_dump_member(bool, state, light_twoside); +   trace_dump_member(uint, state, front_winding); +   trace_dump_member(uint, state, cull_mode); +   trace_dump_member(uint, state, fill_cw); +   trace_dump_member(uint, state, fill_ccw); +   trace_dump_member(bool, state, offset_cw); +   trace_dump_member(bool, state, offset_ccw); +   trace_dump_member(bool, state, scissor); +   trace_dump_member(bool, state, poly_smooth); +   trace_dump_member(bool, state, poly_stipple_enable); +   trace_dump_member(bool, state, point_smooth); +   trace_dump_member(bool, state, point_sprite); +   trace_dump_member(bool, state, point_size_per_vertex); +   trace_dump_member(bool, state, multisample); +   trace_dump_member(bool, state, line_smooth); +   trace_dump_member(bool, state, line_stipple_enable); +   trace_dump_member(uint, state, line_stipple_factor); +   trace_dump_member(uint, state, line_stipple_pattern); +   trace_dump_member(bool, state, line_last_pixel); +   trace_dump_member(bool, state, bypass_vs_clip_and_viewport); +   trace_dump_member(bool, state, flatshade_first); +   trace_dump_member(bool, state, gl_rasterization_rules); + +   trace_dump_member(float, state, line_width); +   trace_dump_member(float, state, point_size); +   trace_dump_member(float, state, point_size_min); +   trace_dump_member(float, state, point_size_max); +   trace_dump_member(float, state, offset_units); +   trace_dump_member(float, state, offset_scale); + +   trace_dump_member_array(uint, state, sprite_coord_mode); + +   trace_dump_struct_end(); +} + + +void trace_dump_poly_stipple(const struct pipe_poly_stipple *state) +{ +   if(!state) { +      trace_dump_null(); +      return; +   } + +   trace_dump_struct_begin("pipe_poly_stipple"); + +   trace_dump_member_begin("stipple"); +   trace_dump_array(uint, +                    state->stipple, +                    Elements(state->stipple)); +   trace_dump_member_end(); + +   trace_dump_struct_end(); +} + + +void trace_dump_viewport_state(const struct pipe_viewport_state *state) +{ +   if(!state) { +      trace_dump_null(); +      return; +   } + +   trace_dump_struct_begin("pipe_viewport_state"); + +   trace_dump_member_array(float, state, scale); +   trace_dump_member_array(float, state, translate); + +   trace_dump_struct_end(); +} + + +void trace_dump_scissor_state(const struct pipe_scissor_state *state) +{ +   if(!state) { +      trace_dump_null(); +      return; +   } + +   trace_dump_struct_begin("pipe_scissor_state"); + +   trace_dump_member(uint, state, minx); +   trace_dump_member(uint, state, miny); +   trace_dump_member(uint, state, maxx); +   trace_dump_member(uint, state, maxy); + +   trace_dump_struct_end(); +} + + +void trace_dump_clip_state(const struct pipe_clip_state *state) +{ +   unsigned i; + +   if(!state) { +      trace_dump_null(); +      return; +   } + +   trace_dump_struct_begin("pipe_clip_state"); + +   trace_dump_member_begin("ucp"); +   trace_dump_array_begin(); +   for(i = 0; i < PIPE_MAX_CLIP_PLANES; ++i) { +      trace_dump_elem_begin(); +      trace_dump_array(float, state->ucp[i], 4); +      trace_dump_elem_end(); +   } +   trace_dump_array_end(); +   trace_dump_member_end(); + +   trace_dump_member(uint, state, nr); + +   trace_dump_struct_end(); +} + + +void trace_dump_constant_buffer(const struct pipe_constant_buffer *state) +{ +   if(!state) { +      trace_dump_null(); +      return; +   } + +   trace_dump_struct_begin("pipe_constant_buffer"); + +   trace_dump_member(buffer_ptr, state, buffer); + +   trace_dump_struct_end(); +} + + +void trace_dump_shader_state(const struct pipe_shader_state *state) +{ +   static char str[8192]; + +   if(!state) { +      trace_dump_null(); +      return; +   } + +   tgsi_dump_str(state->tokens, 0, str, sizeof(str)); + +   trace_dump_struct_begin("pipe_shader_state"); + +   trace_dump_member_begin("tokens"); +   trace_dump_string(str); +   trace_dump_member_end(); + +   trace_dump_struct_end(); +} + + +void trace_dump_depth_stencil_alpha_state(const struct pipe_depth_stencil_alpha_state *state) +{ +   unsigned i; + +   if(!state) { +      trace_dump_null(); +      return; +   } + +   trace_dump_struct_begin("pipe_depth_stencil_alpha_state"); + +   trace_dump_member_begin("depth"); +   trace_dump_struct_begin("pipe_depth_state"); +   trace_dump_member(bool, &state->depth, enabled); +   trace_dump_member(bool, &state->depth, writemask); +   trace_dump_member(uint, &state->depth, func); +   trace_dump_struct_end(); +   trace_dump_member_end(); + +   trace_dump_member_begin("stencil"); +   trace_dump_array_begin(); +   for(i = 0; i < Elements(state->stencil); ++i) { +      trace_dump_elem_begin(); +      trace_dump_struct_begin("pipe_stencil_state"); +      trace_dump_member(bool, &state->stencil[i], enabled); +      trace_dump_member(uint, &state->stencil[i], func); +      trace_dump_member(uint, &state->stencil[i], fail_op); +      trace_dump_member(uint, &state->stencil[i], zpass_op); +      trace_dump_member(uint, &state->stencil[i], zfail_op); +      trace_dump_member(uint, &state->stencil[i], ref_value); +      trace_dump_member(uint, &state->stencil[i], valuemask); +      trace_dump_member(uint, &state->stencil[i], writemask); +      trace_dump_struct_end(); +      trace_dump_elem_end(); +   } +   trace_dump_array_end(); +   trace_dump_member_end(); + +   trace_dump_member_begin("alpha"); +   trace_dump_struct_begin("pipe_alpha_state"); +   trace_dump_member(bool, &state->alpha, enabled); +   trace_dump_member(uint, &state->alpha, func); +   trace_dump_member(float, &state->alpha, ref_value); +   trace_dump_struct_end(); +   trace_dump_member_end(); + +   trace_dump_struct_end(); +} + + +void trace_dump_blend_state(const struct pipe_blend_state *state) +{ +   if(!state) { +      trace_dump_null(); +      return; +   } + +   trace_dump_struct_begin("pipe_blend_state"); + +   trace_dump_member(bool, state, blend_enable); + +   trace_dump_member(uint, state, rgb_func); +   trace_dump_member(uint, state, rgb_src_factor); +   trace_dump_member(uint, state, rgb_dst_factor); + +   trace_dump_member(uint, state, alpha_func); +   trace_dump_member(uint, state, alpha_src_factor); +   trace_dump_member(uint, state, alpha_dst_factor); + +   trace_dump_member(bool, state, logicop_enable); +   trace_dump_member(uint, state, logicop_func); + +   trace_dump_member(uint, state, colormask); +   trace_dump_member(bool, state, dither); + +   trace_dump_struct_end(); +} + + +void trace_dump_blend_color(const struct pipe_blend_color *state) +{ +   if(!state) { +      trace_dump_null(); +      return; +   } + +   trace_dump_struct_begin("pipe_blend_color"); + +   trace_dump_member_array(float, state, color); + +   trace_dump_struct_end(); +} + + +void trace_dump_framebuffer_state(const struct pipe_framebuffer_state *state) +{ +   trace_dump_struct_begin("pipe_framebuffer_state"); + +   trace_dump_member(uint, state, width); +   trace_dump_member(uint, state, height); +   trace_dump_member(uint, state, nr_cbufs); +   trace_dump_member_array(ptr, state, cbufs); +   trace_dump_member(ptr, state, zsbuf); + +   trace_dump_struct_end(); +} + + +void trace_dump_sampler_state(const struct pipe_sampler_state *state) +{ +   if(!state) { +      trace_dump_null(); +      return; +   } + +   trace_dump_struct_begin("pipe_sampler_state"); + +   trace_dump_member(uint, state, wrap_s); +   trace_dump_member(uint, state, wrap_t); +   trace_dump_member(uint, state, wrap_r); +   trace_dump_member(uint, state, min_img_filter); +   trace_dump_member(uint, state, min_mip_filter); +   trace_dump_member(uint, state, mag_img_filter); +   trace_dump_member(bool, state, compare_mode); +   trace_dump_member(uint, state, compare_func); +   trace_dump_member(bool, state, normalized_coords); +   trace_dump_member(uint, state, prefilter); +   trace_dump_member(float, state, shadow_ambient); +   trace_dump_member(float, state, lod_bias); +   trace_dump_member(float, state, min_lod); +   trace_dump_member(float, state, max_lod); +   trace_dump_member_array(float, state, border_color); +   trace_dump_member(float, state, max_anisotropy); + +   trace_dump_struct_end(); +} + + +void trace_dump_surface(const struct pipe_surface *state) +{ +   if(!state) { +      trace_dump_null(); +      return; +   } + +   trace_dump_struct_begin("pipe_surface"); + +   trace_dump_reference(&state->reference); + +   trace_dump_member(format, state, format); +   trace_dump_member(uint, state, width); +   trace_dump_member(uint, state, height); + +   trace_dump_member(uint, state, layout); +   trace_dump_member(uint, state, offset); +   trace_dump_member(uint, state, usage); + +   trace_dump_member(ptr, state, texture); +   trace_dump_member(uint, state, face); +   trace_dump_member(uint, state, level); +   trace_dump_member(uint, state, zslice); + +   trace_dump_struct_end(); +} + + +void trace_dump_transfer(const struct pipe_transfer *state) +{ +   if(!state) { +      trace_dump_null(); +      return; +   } + +   trace_dump_struct_begin("pipe_transfer"); + +   trace_dump_member(format, state, format); +   trace_dump_member(uint, state, width); +   trace_dump_member(uint, state, height); + +   trace_dump_member_begin("block"); +   trace_dump_block(&state->block); +   trace_dump_member_end(); + +   trace_dump_member(uint, state, nblocksx); +   trace_dump_member(uint, state, nblocksy); +   trace_dump_member(uint, state, stride); +   trace_dump_member(uint, state, usage); + +   trace_dump_member(ptr, state, texture); +   trace_dump_member(uint, state, face); +   trace_dump_member(uint, state, level); +   trace_dump_member(uint, state, zslice); + +   trace_dump_struct_end(); +} + + +void trace_dump_vertex_buffer(const struct pipe_vertex_buffer *state) +{ +   if(!state) { +      trace_dump_null(); +      return; +   } + +   trace_dump_struct_begin("pipe_vertex_buffer"); + +   trace_dump_member(uint, state, stride); +   trace_dump_member(uint, state, max_index); +   trace_dump_member(uint, state, buffer_offset); +   trace_dump_member(buffer_ptr, state, buffer); + +   trace_dump_struct_end(); +} + + +void trace_dump_vertex_element(const struct pipe_vertex_element *state) +{ +   if(!state) { +      trace_dump_null(); +      return; +   } + +   trace_dump_struct_begin("pipe_vertex_element"); + +   trace_dump_member(uint, state, src_offset); + +   trace_dump_member(uint, state, vertex_buffer_index); +   trace_dump_member(uint, state, nr_components); + +   trace_dump_member(format, state, src_format); + +   trace_dump_struct_end(); +} diff --git a/src/gallium/drivers/trace/tr_dump_state.h b/src/gallium/drivers/trace/tr_dump_state.h new file mode 100644 index 0000000000..05b821adb6 --- /dev/null +++ b/src/gallium/drivers/trace/tr_dump_state.h @@ -0,0 +1,78 @@ +/************************************************************************** + * + * 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. + * + **************************************************************************/ + +#ifndef TR_DUMP_STATE_H_ +#define TR_DUMP_STATE_H_ + +#include "pipe/p_format.h" +#include "pipe/p_state.h" +#include "pipe/p_shader_tokens.h" + + +void trace_dump_format(enum pipe_format format); + +void trace_dump_block(const struct pipe_format_block *block); + +void trace_dump_template(const struct pipe_texture *templat); + + +void trace_dump_rasterizer_state(const struct pipe_rasterizer_state *state); + +void trace_dump_poly_stipple(const struct pipe_poly_stipple *state); + +void trace_dump_viewport_state(const struct pipe_viewport_state *state); + +void trace_dump_scissor_state(const struct pipe_scissor_state *state); + +void trace_dump_clip_state(const struct pipe_clip_state *state); + +void trace_dump_constant_buffer(const struct pipe_constant_buffer *state); + +void trace_dump_token(const struct tgsi_token *token); + +void trace_dump_shader_state(const struct pipe_shader_state *state); + +void trace_dump_depth_stencil_alpha_state(const struct pipe_depth_stencil_alpha_state *state); + +void trace_dump_blend_state(const struct pipe_blend_state *state); + +void trace_dump_blend_color(const struct pipe_blend_color *state); + +void trace_dump_framebuffer_state(const struct pipe_framebuffer_state *state); + +void trace_dump_sampler_state(const struct pipe_sampler_state *state); + +void trace_dump_surface(const struct pipe_surface *state); + +void trace_dump_transfer(const struct pipe_transfer *state); + +void trace_dump_vertex_buffer(const struct pipe_vertex_buffer *state); + +void trace_dump_vertex_element(const struct pipe_vertex_element *state); + + +#endif /* TR_STATE_H */ diff --git a/src/gallium/drivers/trace/tr_screen.c b/src/gallium/drivers/trace/tr_screen.c index 12a8535342..bc14248eeb 100644 --- a/src/gallium/drivers/trace/tr_screen.c +++ b/src/gallium/drivers/trace/tr_screen.c @@ -30,13 +30,15 @@  #include "tr_buffer.h"  #include "tr_dump.h" -#include "tr_state.h" +#include "tr_dump_state.h"  #include "tr_texture.h"  #include "tr_screen.h"  #include "pipe/p_inlines.h" +static boolean trace = FALSE; +  static const char *  trace_screen_get_name(struct pipe_screen *_screen)  { @@ -212,10 +214,12 @@ static struct pipe_texture *  trace_screen_texture_blanket(struct pipe_screen *_screen,                               const struct pipe_texture *templat,                               const unsigned *ppitch, -                             struct pipe_buffer *buffer) +                             struct pipe_buffer *_buffer)  {     struct trace_screen *tr_scr = trace_screen(_screen); +   struct trace_buffer *tr_buf = trace_buffer(_buffer);     struct pipe_screen *screen = tr_scr->screen; +   struct pipe_buffer *buffer = tr_buf->buffer;     unsigned pitch = *ppitch;     struct pipe_texture *result; @@ -818,16 +822,20 @@ trace_screen_destroy(struct pipe_screen *_screen)     struct pipe_screen *screen = tr_scr->screen;     trace_dump_call_begin("pipe_screen", "destroy"); -     trace_dump_arg(ptr, screen); +   trace_dump_call_end(); +   trace_dump_trace_end();     screen->destroy(screen); -   trace_dump_call_end(); +   FREE(tr_scr); +} -   trace_dump_trace_end(); -   FREE(tr_scr); +boolean +trace_enabled(void) +{ +   return trace;  } @@ -842,10 +850,13 @@ trace_screen_create(struct pipe_screen *screen)     trace_dump_init(); -   if(!trace_dump_trace_begin()) -      goto error1; +   if(trace_dump_trace_begin()) { +      trace_dumping_start(); +      trace = TRUE; +   } -   trace_dumping_start(); +   if (!trace) +      goto error1;     trace_dump_call_begin("", "pipe_screen_create"); diff --git a/src/gallium/drivers/trace/tr_screen.h b/src/gallium/drivers/trace/tr_screen.h index 59f254166d..7fae182985 100644 --- a/src/gallium/drivers/trace/tr_screen.h +++ b/src/gallium/drivers/trace/tr_screen.h @@ -71,6 +71,13 @@ struct trace_screen  }; +/* + * tr_screen.c + */ + +boolean +trace_enabled(void); +  struct trace_screen *  trace_screen(struct pipe_screen *screen); diff --git a/src/gallium/drivers/trace/tr_state.c b/src/gallium/drivers/trace/tr_state.c index a9570c1aeb..d8c11640bf 100644 --- a/src/gallium/drivers/trace/tr_state.c +++ b/src/gallium/drivers/trace/tr_state.c @@ -1,491 +1,66 @@ -/************************************************************************** - * - * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. +/* + * Copyright 2009 VMware, Inc.   * 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. + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * on 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 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. + * 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 + * VMWARE AND/OR THEIR 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. + */ -#include "pipe/p_compiler.h" -#include "util/u_memory.h" -#include "tgsi/tgsi_dump.h" - -#include "tr_dump.h"  #include "tr_state.h" +#include "util/u_memory.h" +#include "util/u_simple_list.h" -void trace_dump_format(enum pipe_format format) -{ -   trace_dump_enum(pf_name(format) ); -} - - -void trace_dump_block(const struct pipe_format_block *block) -{ -   trace_dump_struct_begin("pipe_format_block"); -   trace_dump_member(uint, block, size); -   trace_dump_member(uint, block, width); -   trace_dump_member(uint, block, height); -   trace_dump_struct_end(); -} - - -static void trace_dump_reference(const struct pipe_reference *reference) -{ -   trace_dump_struct_begin("pipe_reference"); -   trace_dump_member(int, &reference->count, count); -   trace_dump_struct_end(); -} - - -void trace_dump_template(const struct pipe_texture *templat) -{ -   if(!templat) { -      trace_dump_null(); -      return; -   } - -   trace_dump_struct_begin("pipe_texture"); - -   trace_dump_member(int, templat, target); -   trace_dump_member(format, templat, format); - -   trace_dump_member_begin("width"); -   trace_dump_array(uint, templat->width, 1); -   trace_dump_member_end(); - -   trace_dump_member_begin("height"); -   trace_dump_array(uint, templat->height, 1); -   trace_dump_member_end(); - -   trace_dump_member_begin("depth"); -   trace_dump_array(uint, templat->depth, 1); -   trace_dump_member_end(); - -   trace_dump_member_begin("block"); -   trace_dump_block(&templat->block); -   trace_dump_member_end(); - -   trace_dump_member(uint, templat, last_level); -   trace_dump_member(uint, templat, tex_usage); - -   trace_dump_struct_end(); -} - - -void trace_dump_rasterizer_state(const struct pipe_rasterizer_state *state) -{ -   if(!state) { -      trace_dump_null(); -      return; -   } - -   trace_dump_struct_begin("pipe_rasterizer_state"); - -   trace_dump_member(bool, state, flatshade); -   trace_dump_member(bool, state, light_twoside); -   trace_dump_member(uint, state, front_winding); -   trace_dump_member(uint, state, cull_mode); -   trace_dump_member(uint, state, fill_cw); -   trace_dump_member(uint, state, fill_ccw); -   trace_dump_member(bool, state, offset_cw); -   trace_dump_member(bool, state, offset_ccw); -   trace_dump_member(bool, state, scissor); -   trace_dump_member(bool, state, poly_smooth); -   trace_dump_member(bool, state, poly_stipple_enable); -   trace_dump_member(bool, state, point_smooth); -   trace_dump_member(bool, state, point_sprite); -   trace_dump_member(bool, state, point_size_per_vertex); -   trace_dump_member(bool, state, multisample); -   trace_dump_member(bool, state, line_smooth); -   trace_dump_member(bool, state, line_stipple_enable); -   trace_dump_member(uint, state, line_stipple_factor); -   trace_dump_member(uint, state, line_stipple_pattern); -   trace_dump_member(bool, state, line_last_pixel); -   trace_dump_member(bool, state, bypass_vs_clip_and_viewport); -   trace_dump_member(bool, state, flatshade_first); -   trace_dump_member(bool, state, gl_rasterization_rules); - -   trace_dump_member(float, state, line_width); -   trace_dump_member(float, state, point_size); -   trace_dump_member(float, state, point_size_min); -   trace_dump_member(float, state, point_size_max); -   trace_dump_member(float, state, offset_units); -   trace_dump_member(float, state, offset_scale); - -   trace_dump_member_array(uint, state, sprite_coord_mode); - -   trace_dump_struct_end(); -} - - -void trace_dump_poly_stipple(const struct pipe_poly_stipple *state) -{ -   if(!state) { -      trace_dump_null(); -      return; -   } - -   trace_dump_struct_begin("pipe_poly_stipple"); - -   trace_dump_member_begin("stipple"); -   trace_dump_array(uint, -                    state->stipple, -                    Elements(state->stipple)); -   trace_dump_member_end(); - -   trace_dump_struct_end(); -} - - -void trace_dump_viewport_state(const struct pipe_viewport_state *state) -{ -   if(!state) { -      trace_dump_null(); -      return; -   } - -   trace_dump_struct_begin("pipe_viewport_state"); - -   trace_dump_member_array(float, state, scale); -   trace_dump_member_array(float, state, translate); - -   trace_dump_struct_end(); -} - - -void trace_dump_scissor_state(const struct pipe_scissor_state *state) -{ -   if(!state) { -      trace_dump_null(); -      return; -   } - -   trace_dump_struct_begin("pipe_scissor_state"); - -   trace_dump_member(uint, state, minx); -   trace_dump_member(uint, state, miny); -   trace_dump_member(uint, state, maxx); -   trace_dump_member(uint, state, maxy); - -   trace_dump_struct_end(); -} - - -void trace_dump_clip_state(const struct pipe_clip_state *state) -{ -   unsigned i; - -   if(!state) { -      trace_dump_null(); -      return; -   } - -   trace_dump_struct_begin("pipe_clip_state"); - -   trace_dump_member_begin("ucp"); -   trace_dump_array_begin(); -   for(i = 0; i < PIPE_MAX_CLIP_PLANES; ++i) { -      trace_dump_elem_begin(); -      trace_dump_array(float, state->ucp[i], 4); -      trace_dump_elem_end(); -   } -   trace_dump_array_end(); -   trace_dump_member_end(); - -   trace_dump_member(uint, state, nr); - -   trace_dump_struct_end(); -} - - -void trace_dump_constant_buffer(const struct pipe_constant_buffer *state) -{ -   if(!state) { -      trace_dump_null(); -      return; -   } - -   trace_dump_struct_begin("pipe_constant_buffer"); - -   trace_dump_member(buffer_ptr, state, buffer); - -   trace_dump_struct_end(); -} - - -void trace_dump_shader_state(const struct pipe_shader_state *state) -{ -   static char str[8192]; - -   if(!state) { -      trace_dump_null(); -      return; -   } - -   tgsi_dump_str(state->tokens, 0, str, sizeof(str)); - -   trace_dump_struct_begin("pipe_shader_state"); - -   trace_dump_member_begin("tokens"); -   trace_dump_string(str); -   trace_dump_member_end(); - -   trace_dump_struct_end(); -} - - -void trace_dump_depth_stencil_alpha_state(const struct pipe_depth_stencil_alpha_state *state) -{ -   unsigned i; - -   if(!state) { -      trace_dump_null(); -      return; -   } - -   trace_dump_struct_begin("pipe_depth_stencil_alpha_state"); - -   trace_dump_member_begin("depth"); -   trace_dump_struct_begin("pipe_depth_state"); -   trace_dump_member(bool, &state->depth, enabled); -   trace_dump_member(bool, &state->depth, writemask); -   trace_dump_member(uint, &state->depth, func); -   trace_dump_member(bool, &state->depth, occlusion_count); -   trace_dump_struct_end(); -   trace_dump_member_end(); - -   trace_dump_member_begin("stencil"); -   trace_dump_array_begin(); -   for(i = 0; i < Elements(state->stencil); ++i) { -      trace_dump_elem_begin(); -      trace_dump_struct_begin("pipe_stencil_state"); -      trace_dump_member(bool, &state->stencil[i], enabled); -      trace_dump_member(uint, &state->stencil[i], func); -      trace_dump_member(uint, &state->stencil[i], fail_op); -      trace_dump_member(uint, &state->stencil[i], zpass_op); -      trace_dump_member(uint, &state->stencil[i], zfail_op); -      trace_dump_member(uint, &state->stencil[i], ref_value); -      trace_dump_member(uint, &state->stencil[i], valuemask); -      trace_dump_member(uint, &state->stencil[i], writemask); -      trace_dump_struct_end(); -      trace_dump_elem_end(); -   } -   trace_dump_array_end(); -   trace_dump_member_end(); - -   trace_dump_member_begin("alpha"); -   trace_dump_struct_begin("pipe_alpha_state"); -   trace_dump_member(bool, &state->alpha, enabled); -   trace_dump_member(uint, &state->alpha, func); -   trace_dump_member(float, &state->alpha, ref_value); -   trace_dump_struct_end(); -   trace_dump_member_end(); - -   trace_dump_struct_end(); -} - - -void trace_dump_blend_state(const struct pipe_blend_state *state) -{ -   if(!state) { -      trace_dump_null(); -      return; -   } - -   trace_dump_struct_begin("pipe_blend_state"); - -   trace_dump_member(bool, state, blend_enable); - -   trace_dump_member(uint, state, rgb_func); -   trace_dump_member(uint, state, rgb_src_factor); -   trace_dump_member(uint, state, rgb_dst_factor); - -   trace_dump_member(uint, state, alpha_func); -   trace_dump_member(uint, state, alpha_src_factor); -   trace_dump_member(uint, state, alpha_dst_factor); - -   trace_dump_member(bool, state, logicop_enable); -   trace_dump_member(uint, state, logicop_func); - -   trace_dump_member(uint, state, colormask); -   trace_dump_member(bool, state, dither); - -   trace_dump_struct_end(); -} - - -void trace_dump_blend_color(const struct pipe_blend_color *state) -{ -   if(!state) { -      trace_dump_null(); -      return; -   } - -   trace_dump_struct_begin("pipe_blend_color"); - -   trace_dump_member_array(float, state, color); - -   trace_dump_struct_end(); -} - - -void trace_dump_framebuffer_state(const struct pipe_framebuffer_state *state) -{ -   trace_dump_struct_begin("pipe_framebuffer_state"); - -   trace_dump_member(uint, state, width); -   trace_dump_member(uint, state, height); -   trace_dump_member(uint, state, nr_cbufs); -   trace_dump_member_array(ptr, state, cbufs); -   trace_dump_member(ptr, state, zsbuf); - -   trace_dump_struct_end(); -} - - -void trace_dump_sampler_state(const struct pipe_sampler_state *state) -{ -   if(!state) { -      trace_dump_null(); -      return; -   } - -   trace_dump_struct_begin("pipe_sampler_state"); - -   trace_dump_member(uint, state, wrap_s); -   trace_dump_member(uint, state, wrap_t); -   trace_dump_member(uint, state, wrap_r); -   trace_dump_member(uint, state, min_img_filter); -   trace_dump_member(uint, state, min_mip_filter); -   trace_dump_member(uint, state, mag_img_filter); -   trace_dump_member(bool, state, compare_mode); -   trace_dump_member(uint, state, compare_func); -   trace_dump_member(bool, state, normalized_coords); -   trace_dump_member(uint, state, prefilter); -   trace_dump_member(float, state, shadow_ambient); -   trace_dump_member(float, state, lod_bias); -   trace_dump_member(float, state, min_lod); -   trace_dump_member(float, state, max_lod); -   trace_dump_member_array(float, state, border_color); -   trace_dump_member(float, state, max_anisotropy); - -   trace_dump_struct_end(); -} - - -void trace_dump_surface(const struct pipe_surface *state) -{ -   if(!state) { -      trace_dump_null(); -      return; -   } - -   trace_dump_struct_begin("pipe_surface"); - -   trace_dump_reference(&state->reference); - -   trace_dump_member(format, state, format); -   trace_dump_member(uint, state, width); -   trace_dump_member(uint, state, height); - -   trace_dump_member(uint, state, layout); -   trace_dump_member(uint, state, offset); -   trace_dump_member(uint, state, usage); - -   trace_dump_member(ptr, state, texture); -   trace_dump_member(uint, state, face); -   trace_dump_member(uint, state, level); -   trace_dump_member(uint, state, zslice); - -   trace_dump_struct_end(); -} - +#include "tgsi/tgsi_parse.h" -void trace_dump_transfer(const struct pipe_transfer *state) +struct trace_shader * trace_shader_create(struct trace_context *tr_ctx, +                                          const struct pipe_shader_state *state, +                                          void *result, +                                          enum trace_shader_type type)  { -   if(!state) { -      trace_dump_null(); -      return; -   } +   struct trace_shader *tr_shdr = CALLOC_STRUCT(trace_shader); -   trace_dump_struct_begin("pipe_transfer"); +   tr_shdr->state = result; +   tr_shdr->type = type; +   tr_shdr->tokens = tgsi_dup_tokens(state->tokens); -   trace_dump_member(format, state, format); -   trace_dump_member(uint, state, width); -   trace_dump_member(uint, state, height); +   /* works on context as well */ +   trace_screen_add_to_list(tr_ctx, shaders, tr_shdr); -   trace_dump_member_begin("block"); -   trace_dump_block(&state->block); -   trace_dump_member_end(); - -   trace_dump_member(uint, state, nblocksx); -   trace_dump_member(uint, state, nblocksy); -   trace_dump_member(uint, state, stride); -   trace_dump_member(uint, state, usage); - -   trace_dump_member(ptr, state, texture); -   trace_dump_member(uint, state, face); -   trace_dump_member(uint, state, level); -   trace_dump_member(uint, state, zslice); - -   trace_dump_struct_end(); +   return tr_shdr;  } - -void trace_dump_vertex_buffer(const struct pipe_vertex_buffer *state) +void trace_shader_destroy(struct trace_context *tr_ctx, +                          struct trace_shader *tr_shdr)  { -   if(!state) { -      trace_dump_null(); -      return; -   } +   trace_screen_remove_from_list(tr_ctx, shaders, tr_shdr); -   trace_dump_struct_begin("pipe_vertex_buffer"); - -   trace_dump_member(uint, state, stride); -   trace_dump_member(uint, state, max_index); -   trace_dump_member(uint, state, buffer_offset); -   trace_dump_member(buffer_ptr, state, buffer); - -   trace_dump_struct_end(); -} - - -void trace_dump_vertex_element(const struct pipe_vertex_element *state) -{ -   if(!state) { -      trace_dump_null(); -      return; +   if (tr_shdr->replaced) { +      if (tr_shdr->type == TRACE_SHADER_FRAGMENT) +         tr_ctx->pipe->delete_fs_state(tr_ctx->pipe, tr_shdr->replaced); +      else if (tr_shdr->type == TRACE_SHADER_VERTEX) +         tr_ctx->pipe->delete_vs_state(tr_ctx->pipe, tr_shdr->replaced); +      else +         assert(0);     } -   trace_dump_struct_begin("pipe_vertex_element"); - -   trace_dump_member(uint, state, src_offset); - -   trace_dump_member(uint, state, vertex_buffer_index); -   trace_dump_member(uint, state, nr_components); - -   trace_dump_member(format, state, src_format); - -   trace_dump_struct_end(); +   FREE(tr_shdr->replaced_tokens); +   FREE(tr_shdr->tokens); +   FREE(tr_shdr);  } diff --git a/src/gallium/drivers/trace/tr_state.h b/src/gallium/drivers/trace/tr_state.h index 513ed0ac98..1c16042ee5 100644 --- a/src/gallium/drivers/trace/tr_state.h +++ b/src/gallium/drivers/trace/tr_state.h @@ -1,78 +1,68 @@ -/************************************************************************** - * - * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. +/* + * Copyright 2009 VMware, Inc.   * 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. + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * on 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 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. + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software.   * - **************************************************************************/ - -#ifndef TR_STATE_H -#define TR_STATE_H - -#include "pipe/p_format.h" -#include "pipe/p_state.h" -#include "pipe/p_shader_tokens.h" - - -void trace_dump_format(enum pipe_format format); - -void trace_dump_block(const struct pipe_format_block *block); - -void trace_dump_template(const struct pipe_texture *templat); - - -void trace_dump_rasterizer_state(const struct pipe_rasterizer_state *state); - -void trace_dump_poly_stipple(const struct pipe_poly_stipple *state); - -void trace_dump_viewport_state(const struct pipe_viewport_state *state); - -void trace_dump_scissor_state(const struct pipe_scissor_state *state); - -void trace_dump_clip_state(const struct pipe_clip_state *state); + * 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 + * VMWARE AND/OR THEIR 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. + */ -void trace_dump_constant_buffer(const struct pipe_constant_buffer *state); +#ifndef TR_STATE_H_ +#define TR_STATE_H_ -void trace_dump_token(const struct tgsi_token *token); +#include "tr_context.h" -void trace_dump_shader_state(const struct pipe_shader_state *state); +struct tgsi_token; -void trace_dump_depth_stencil_alpha_state(const struct pipe_depth_stencil_alpha_state *state); +enum trace_shader_type { +   TRACE_SHADER_FRAGMENT = 0, +   TRACE_SHADER_VERTEX   = 1, +   TRACE_SHADER_GEOMETRY = 2, +}; -void trace_dump_blend_state(const struct pipe_blend_state *state); +struct trace_shader +{ +   struct tr_list list; -void trace_dump_blend_color(const struct pipe_blend_color *state); +   enum trace_shader_type type; -void trace_dump_framebuffer_state(const struct pipe_framebuffer_state *state); +   void *state; +   void *replaced; -void trace_dump_sampler_state(const struct pipe_sampler_state *state); +   struct tgsi_token *tokens; +   struct tgsi_token *replaced_tokens; -void trace_dump_surface(const struct pipe_surface *state); +   boolean disabled; +}; -void trace_dump_transfer(const struct pipe_transfer *state); -void trace_dump_vertex_buffer(const struct pipe_vertex_buffer *state); +static INLINE struct trace_shader * +trace_shader(void *state) +{ +   return (struct trace_shader *)state; +} -void trace_dump_vertex_element(const struct pipe_vertex_element *state); +struct trace_shader * trace_shader_create(struct trace_context *tr_ctx, +                                          const struct pipe_shader_state *state, +                                          void *result, +                                          enum trace_shader_type type); +void trace_shader_destroy(struct trace_context *tr_ctx, +                          struct trace_shader *tr_shdr); -#endif /* TR_STATE_H */ +#endif diff --git a/src/gallium/include/pipe/p_defines.h b/src/gallium/include/pipe/p_defines.h index 82e23c413c..47c24f3086 100644 --- a/src/gallium/include/pipe/p_defines.h +++ b/src/gallium/include/pipe/p_defines.h @@ -132,6 +132,7 @@ enum pipe_texture_target {  #define PIPE_TEX_FACE_NEG_Y 3  #define PIPE_TEX_FACE_POS_Z 4  #define PIPE_TEX_FACE_NEG_Z 5 +#define PIPE_TEX_FACE_MAX   6  #define PIPE_TEX_WRAP_REPEAT                   0  #define PIPE_TEX_WRAP_CLAMP                    1 @@ -158,14 +159,6 @@ enum pipe_texture_target {  #define PIPE_TEX_COMPARE_NONE          0  #define PIPE_TEX_COMPARE_R_TO_TEXTURE  1 -#define PIPE_TEX_FACE_POS_X   0 -#define PIPE_TEX_FACE_NEG_X   1 -#define PIPE_TEX_FACE_POS_Y   2 -#define PIPE_TEX_FACE_NEG_Y   3 -#define PIPE_TEX_FACE_POS_Z   4 -#define PIPE_TEX_FACE_NEG_Z   5 -#define PIPE_TEX_FACE_MAX     6 -  #define PIPE_TEXTURE_USAGE_RENDER_TARGET   0x1  #define PIPE_TEXTURE_USAGE_DISPLAY_TARGET  0x2 /* ie a backbuffer */  #define PIPE_TEXTURE_USAGE_PRIMARY         0x4 /* ie a frontbuffer */ diff --git a/src/gallium/state_trackers/dri/dri_drawable.c b/src/gallium/state_trackers/dri/dri_drawable.c index 15a2088df5..865cc8d0b6 100644 --- a/src/gallium/state_trackers/dri/dri_drawable.c +++ b/src/gallium/state_trackers/dri/dri_drawable.c @@ -138,6 +138,18 @@ dri_get_buffers(__DRIdrawablePrivate * dPriv)     dri_drawable->pBackClipRects[0].x2 = dri_drawable->w;     dri_drawable->pBackClipRects[0].y2 = dri_drawable->h; +   if (drawable->old_num == count && +       drawable->old_w == dri_drawable->w && +       drawable->old_h == dri_drawable->h && +       memcmp(drawable->old, buffers, sizeof(__DRIbuffer) * count) == 0) { +       return; +   } else { +      drawable->old_num = count; +      drawable->old_w = dri_drawable->w; +      drawable->old_h = dri_drawable->h; +      memcpy(drawable->old, buffers, sizeof(__DRIbuffer) * count); +   } +     for (i = 0; i < count; i++) {        enum pipe_format format = 0;        int index = 0; diff --git a/src/gallium/state_trackers/dri/dri_drawable.h b/src/gallium/state_trackers/dri/dri_drawable.h index 78a66624aa..0f654d804a 100644 --- a/src/gallium/state_trackers/dri/dri_drawable.h +++ b/src/gallium/state_trackers/dri/dri_drawable.h @@ -46,6 +46,11 @@ struct dri_drawable     unsigned attachments[8];     unsigned num_attachments; +   __DRIbuffer old[8]; +   unsigned old_num; +   unsigned old_w; +   unsigned old_h; +     /* gallium */     struct st_framebuffer *stfb;     struct pipe_fence_handle *swap_fences[DRI_SWAP_FENCES_MAX]; diff --git a/src/gallium/state_trackers/dri/dri_extensions.c b/src/gallium/state_trackers/dri/dri_extensions.c index 0c59d42d5c..2f48162526 100644 --- a/src/gallium/state_trackers/dri/dri_extensions.c +++ b/src/gallium/state_trackers/dri/dri_extensions.c @@ -36,9 +36,11 @@  #define need_GL_ARB_multisample  #define need_GL_ARB_occlusion_query  #define need_GL_ARB_point_parameters +#define need_GL_ARB_shader_objects  #define need_GL_ARB_texture_compression  #define need_GL_ARB_vertex_buffer_object  #define need_GL_ARB_vertex_program +#define need_GL_ARB_vertex_shader  #define need_GL_ARB_window_pos  #define need_GL_EXT_blend_color  #define need_GL_EXT_blend_equation_separate @@ -50,16 +52,23 @@  #define need_GL_EXT_multi_draw_arrays  #define need_GL_EXT_secondary_color  #define need_GL_NV_vertex_program +#define need_GL_VERSION_2_0 +#define need_GL_VERSION_2_1  #include "extension_helper.h"  /**   * Extension strings exported by the driver.   */  const struct dri_extension card_extensions[] = { +   {"GL_ARB_fragment_shader", NULL},     {"GL_ARB_multisample", GL_ARB_multisample_functions},     {"GL_ARB_multitexture", NULL},     {"GL_ARB_occlusion_query", GL_ARB_occlusion_query_functions}, +   {"GL_ARB_pixel_buffer_object", NULL},     {"GL_ARB_point_parameters", GL_ARB_point_parameters_functions}, +   {"GL_ARB_shading_language_100", GL_VERSION_2_0_functions }, +   {"GL_ARB_shading_language_120", GL_VERSION_2_1_functions }, +   {"GL_ARB_shader_objects", GL_ARB_shader_objects_functions},     {"GL_ARB_texture_border_clamp", NULL},     {"GL_ARB_texture_compression", GL_ARB_texture_compression_functions},     {"GL_ARB_texture_cube_map", NULL}, @@ -69,7 +78,7 @@ const struct dri_extension card_extensions[] = {     {"GL_ARB_texture_mirrored_repeat", NULL},     {"GL_ARB_texture_rectangle", NULL},     {"GL_ARB_vertex_buffer_object", GL_ARB_vertex_buffer_object_functions}, -   {"GL_ARB_pixel_buffer_object", NULL}, +   {"GL_ARB_vertex_shader", GL_ARB_vertex_shader_functions},     {"GL_ARB_vertex_program", GL_ARB_vertex_program_functions},     {"GL_ARB_window_pos", GL_ARB_window_pos_functions},     {"GL_EXT_blend_color", GL_EXT_blend_color_functions}, diff --git a/src/gallium/state_trackers/egl/Makefile b/src/gallium/state_trackers/egl/Makefile index 692a3c8b76..e825aa718b 100644 --- a/src/gallium/state_trackers/egl/Makefile +++ b/src/gallium/state_trackers/egl/Makefile @@ -1,29 +1,19 @@ -TARGET     = libegldrm.a -CFILES     = $(wildcard ./*.c) -OBJECTS    = $(patsubst ./%.c,./%.o,$(CFILES)) -GALLIUMDIR = ../.. -TOP        = ../../../.. +TOP = ../../../.. +include $(TOP)/configs/current -include ${TOP}/configs/current +LIBNAME = egldrm -CFLAGS := \ -          -I${GALLIUMDIR}/include \ -          -I${GALLIUMDIR}/auxiliary \ -          -I${TOP}/src/mesa/drivers/dri/common \ -          -I${TOP}/src/mesa \ -          -I$(TOP)/include \ -          -I$(TOP)/src/egl/main \ -          ${LIBDRM_CFLAGS} \ -          ${CFLAGS} +LIBRARY_INCLUDES = \ +	-I$(TOP)/src/gallium/include \ +	-I$(TOP)/src/gallium/auxiliary \ +	-I$(TOP)/src/mesa/drivers/dri/common \ +	-I$(TOP)/src/mesa \ +	-I$(TOP)/include \ +	-I$(TOP)/src/egl/main \ +	$(shell pkg-config --cflags-only-I libdrm) -############################################# -.PHONY	= all clean +C_SOURCES = $(wildcard ./*.c) -all: ${TARGET} -${TARGET}: ${OBJECTS} -	ar rcs $@ $^ - -clean: -	rm -rf ${OBJECTS} ${TARGET} +include ../../Makefile.template diff --git a/src/gallium/state_trackers/glx/xlib/fakeglx.c b/src/gallium/state_trackers/glx/xlib/fakeglx.c index 65e7048188..85e7ecfb9e 100644 --- a/src/gallium/state_trackers/glx/xlib/fakeglx.c +++ b/src/gallium/state_trackers/glx/xlib/fakeglx.c @@ -97,6 +97,9 @@ struct fake_glx_context { +#define DEFAULT_DIRECT GL_TRUE + +  /**********************************************************************/  /***                       GLX Visual Code                          ***/  /**********************************************************************/ @@ -1059,7 +1062,7 @@ Fake_glXCreateContext( Display *dpy, XVisualInfo *visinfo,        return NULL;     } -   glxCtx->glxContext.isDirect = GL_FALSE; +   glxCtx->glxContext.isDirect = DEFAULT_DIRECT;     glxCtx->glxContext.currentDpy = dpy;     glxCtx->glxContext.xid = (XID) glxCtx;  /* self pointer */ @@ -1296,9 +1299,9 @@ Fake_glXDestroyContext( Display *dpy, GLXContext ctx )  static Bool  Fake_glXIsDirect( Display *dpy, GLXContext ctx )  { -   (void) dpy; +   struct fake_glx_context *glxCtx = (struct fake_glx_context *) ctx;     (void) ctx; -   return False; +   return glxCtx->glxContext.isDirect;  } @@ -2055,7 +2058,7 @@ Fake_glXCreateNewContext( Display *dpy, GLXFBConfig config,        return NULL;     } -   glxCtx->glxContext.isDirect = GL_FALSE; +   glxCtx->glxContext.isDirect = DEFAULT_DIRECT;     glxCtx->glxContext.currentDpy = dpy;     glxCtx->glxContext.xid = (XID) glxCtx;  /* self pointer */ @@ -2277,7 +2280,7 @@ Fake_glXCreateContextWithConfigSGIX(Display *dpy, GLXFBConfigSGIX config, int re        return NULL;     } -   glxCtx->glxContext.isDirect = GL_FALSE; +   glxCtx->glxContext.isDirect = DEFAULT_DIRECT;     glxCtx->glxContext.currentDpy = dpy;     glxCtx->glxContext.xid = (XID) glxCtx;  /* self pointer */ diff --git a/src/gallium/state_trackers/glx/xlib/xm_api.c b/src/gallium/state_trackers/glx/xlib/xm_api.c index a3d1651653..79c2230588 100644 --- a/src/gallium/state_trackers/glx/xlib/xm_api.c +++ b/src/gallium/state_trackers/glx/xlib/xm_api.c @@ -1100,26 +1100,19 @@ XMesaContext XMesaGetCurrentContext( void ) - - - -/* - * Copy the back buffer to the front buffer.  If there's no back buffer - * this is a no-op. +/** + * Swap front and back color buffers and have winsys display front buffer. + * If there's no front color buffer no swap actually occurs.   */  PUBLIC  void XMesaSwapBuffers( XMesaBuffer b )  { -   struct pipe_surface *surf; +   struct pipe_surface *frontLeftSurf; -   /* If we're swapping the buffer associated with the current context -    * we have to flush any pending rendering commands first. -    */ -   st_notify_swapbuffers(b->stfb); +   st_swapbuffers(b->stfb, &frontLeftSurf, NULL); -   st_get_framebuffer_surface(b->stfb, ST_SURFACE_BACK_LEFT, &surf); -   if (surf) { -      driver.display_surface(b, surf); +   if (frontLeftSurf) { +      driver.display_surface(b, frontLeftSurf);     }     xmesa_check_and_update_buffer_size(NULL, b); diff --git a/src/gallium/winsys/drm/intel/SConscript b/src/gallium/winsys/drm/intel/SConscript new file mode 100644 index 0000000000..50d7b75ed6 --- /dev/null +++ b/src/gallium/winsys/drm/intel/SConscript @@ -0,0 +1,7 @@ +Import('*') + +SConscript(['gem/SConscript',]) + +if 'mesa' in env['statetrackers']: + +    SConscript(['dri/SConscript']) diff --git a/src/gallium/winsys/drm/intel/dri/Makefile b/src/gallium/winsys/drm/intel/dri/Makefile index ac0891a646..de39e759d8 100644 --- a/src/gallium/winsys/drm/intel/dri/Makefile +++ b/src/gallium/winsys/drm/intel/dri/Makefile @@ -6,6 +6,7 @@ LIBNAME = i915_dri.so  PIPE_DRIVERS = \  	$(TOP)/src/gallium/state_trackers/dri/libdridrm.a \  	$(TOP)/src/gallium/winsys/drm/intel/gem/libinteldrm.a \ +	$(TOP)/src/gallium/drivers/trace/libtrace.a \  	$(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \  	$(TOP)/src/gallium/drivers/i915simple/libi915simple.a diff --git a/src/gallium/winsys/drm/intel/dri/SConscript b/src/gallium/winsys/drm/intel/dri/SConscript new file mode 100644 index 0000000000..e14e96e32f --- /dev/null +++ b/src/gallium/winsys/drm/intel/dri/SConscript @@ -0,0 +1,16 @@ +Import('*') + +env = drienv.Clone() + +drivers = [ +    softpipe, +    i915simple, +    trace, +    inteldrm +] + +env.SharedLibrary( +    target ='i915_dri.so', +    source = COMMON_GALLIUM_SOURCES, +    LIBS = drivers + mesa + auxiliaries + env['LIBS'], +) diff --git a/src/gallium/winsys/drm/intel/gem/SConscript b/src/gallium/winsys/drm/intel/gem/SConscript new file mode 100644 index 0000000000..ea8a2e55f6 --- /dev/null +++ b/src/gallium/winsys/drm/intel/gem/SConscript @@ -0,0 +1,17 @@ +Import('*') + +env = drienv.Clone() + +inteldrm_sources = [ +    'intel_be_api.c', +    'intel_be_batchbuffer.c', +    'intel_be_context.c', +    'intel_be_device.c', +] + +inteldrm = env.ConvenienceLibrary( +    target ='inteldrm', +    source = inteldrm_sources, +) + +Export('inteldrm') diff --git a/src/gallium/winsys/drm/intel/gem/intel_be_api.c b/src/gallium/winsys/drm/intel/gem/intel_be_api.c index f4ef7c2d88..a74be13bf7 100644 --- a/src/gallium/winsys/drm/intel/gem/intel_be_api.c +++ b/src/gallium/winsys/drm/intel/gem/intel_be_api.c @@ -2,7 +2,13 @@  #include "intel_be_api.h"  #include "i915simple/i915_winsys.h" +#ifdef DEBUG +#include "trace/trace_drm.h" + +struct drm_api hooks = +#else  struct drm_api drm_api_hooks = +#endif  {  	/* intel_be_context.c */  	.create_context = intel_be_create_context, diff --git a/src/gallium/winsys/drm/nouveau/Makefile b/src/gallium/winsys/drm/nouveau/Makefile index f8c8135854..6c9cbef26d 100644 --- a/src/gallium/winsys/drm/nouveau/Makefile +++ b/src/gallium/winsys/drm/nouveau/Makefile @@ -2,7 +2,7 @@  TOP = ../../../../..  include $(TOP)/configs/current -SUBDIRS = drm dri dri2 +SUBDIRS = drm $(GALLIUM_STATE_TRACKERS_DIRS)  default install clean:  	@for dir in $(SUBDIRS) ; do \ diff --git a/src/gallium/winsys/drm/nouveau/dri/Makefile b/src/gallium/winsys/drm/nouveau/dri/Makefile index f7db6201fe..024ab150cb 100644 --- a/src/gallium/winsys/drm/nouveau/dri/Makefile +++ b/src/gallium/winsys/drm/nouveau/dri/Makefile @@ -3,9 +3,8 @@ include $(TOP)/configs/current  LIBNAME = nouveau_dri.so -MINIGLX_SOURCES = -  PIPE_DRIVERS = \ +	$(TOP)/src/gallium/state_trackers/dri/libdridrm.a \  	$(TOP)/src/gallium/winsys/drm/nouveau/drm/libnouveaudrm.a \  	$(TOP)/src/gallium/drivers/nv04/libnv04.a \  	$(TOP)/src/gallium/drivers/nv10/libnv10.a \ @@ -13,22 +12,15 @@ PIPE_DRIVERS = \  	$(TOP)/src/gallium/drivers/nv30/libnv30.a \  	$(TOP)/src/gallium/drivers/nv40/libnv40.a \  	$(TOP)/src/gallium/drivers/nv50/libnv50.a -	 -DRIVER_SOURCES = \ -	nouveau_context.c \ -	nouveau_screen.c \ -	nouveau_swapbuffers.c \ -	nouveau_lock.c + +DRIVER_SOURCES =  C_SOURCES = \  	$(COMMON_GALLIUM_SOURCES) \  	$(DRIVER_SOURCES) -ASM_SOURCES =  +include ../../Makefile.template -DRIVER_DEFINES = $(shell pkg-config libdrm_nouveau --cflags)  DRI_LIB_DEPS += $(shell pkg-config libdrm_nouveau --libs) -include ../../Makefile.template -  symlinks: diff --git a/src/gallium/winsys/drm/nouveau/dri/nouveau_context.c b/src/gallium/winsys/drm/nouveau/dri/nouveau_context.c deleted file mode 100644 index deb6ffcff1..0000000000 --- a/src/gallium/winsys/drm/nouveau/dri/nouveau_context.c +++ /dev/null @@ -1,118 +0,0 @@ -#include <main/glheader.h> -#include <glapi/glthread.h> -#include <GL/internal/glcore.h> -#include <utils.h> - -#include <state_tracker/st_public.h> -#include <state_tracker/st_context.h> -#include <state_tracker/drm_api.h> -#include <pipe/p_defines.h> -#include <pipe/p_context.h> -#include <pipe/p_screen.h> - -#include "nouveau_context.h" -#include "nouveau_screen.h" - -#include "nouveau_drmif.h" - -GLboolean -nouveau_context_create(const __GLcontextModes *glVis, -		       __DRIcontextPrivate *driContextPriv, -		       void *sharedContextPrivate) -{ -	__DRIscreenPrivate *driScrnPriv = driContextPriv->driScreenPriv; -	struct nouveau_screen  *nv_screen = driScrnPriv->private; -	struct nouveau_context *nv; -	struct pipe_context *pipe; -	struct st_context *st_share = NULL; - -	if (sharedContextPrivate) -		st_share = ((struct nouveau_context *)sharedContextPrivate)->st; - -	nv = CALLOC_STRUCT(nouveau_context); -	if (!nv) -		return GL_FALSE; - -	{ -		struct nouveau_device_priv *nvdev = -			nouveau_device(nv_screen->device); - -		nvdev->ctx  = driContextPriv->hHWContext; -		nvdev->lock = (drmLock *)&driScrnPriv->pSAREA->lock; -	} - -	pipe = drm_api_hooks.create_context(nv_screen->pscreen); -	if (!pipe) { -		FREE(nv); -		return GL_FALSE; -	} -	pipe->priv = nv; - -	driContextPriv->driverPrivate = nv; -	nv->dri_screen = driScrnPriv; - -	driParseConfigFiles(&nv->dri_option_cache, &nv_screen->option_cache, -			    nv->dri_screen->myNum, "nouveau"); - -	nv->st = st_create_context(pipe, glVis, st_share); -	return GL_TRUE; -} - -void -nouveau_context_destroy(__DRIcontextPrivate *driContextPriv) -{ -	struct nouveau_context *nv = driContextPriv->driverPrivate; - -	assert(nv); - -	st_finish(nv->st); -	st_destroy_context(nv->st); - -	FREE(nv); -} - -GLboolean -nouveau_context_bind(__DRIcontextPrivate *driContextPriv, -		     __DRIdrawablePrivate *driDrawPriv, -		     __DRIdrawablePrivate *driReadPriv) -{ -	struct nouveau_context *nv; -	struct nouveau_framebuffer *draw, *read; - -	if (!driContextPriv) { -		st_make_current(NULL, NULL, NULL); -		return GL_TRUE; -	} - -	nv = driContextPriv->driverPrivate; -	draw = driDrawPriv->driverPrivate; -	read = driReadPriv->driverPrivate; - -	st_make_current(nv->st, draw->stfb, read->stfb); - -	if ((nv->dri_drawable != driDrawPriv) || -	    (nv->last_stamp != driDrawPriv->lastStamp)) { -		nv->dri_drawable = driDrawPriv; -		st_resize_framebuffer(draw->stfb, driDrawPriv->w, -				      driDrawPriv->h); -		nv->last_stamp = driDrawPriv->lastStamp; -	} - -	if (driDrawPriv != driReadPriv) { -		st_resize_framebuffer(read->stfb, driReadPriv->w, -				      driReadPriv->h); -	} - -	return GL_TRUE; -} - -GLboolean -nouveau_context_unbind(__DRIcontextPrivate *driContextPriv) -{ -	struct nouveau_context *nv = driContextPriv->driverPrivate; -	(void)nv; - -	st_flush(nv->st, 0, NULL); -	return GL_TRUE; -} - diff --git a/src/gallium/winsys/drm/nouveau/dri/nouveau_context.h b/src/gallium/winsys/drm/nouveau/dri/nouveau_context.h deleted file mode 100644 index 2779b092e6..0000000000 --- a/src/gallium/winsys/drm/nouveau/dri/nouveau_context.h +++ /dev/null @@ -1,53 +0,0 @@ -#ifndef __NOUVEAU_CONTEXT_DRI_H__ -#define __NOUVEAU_CONTEXT_DRI_H__ - -#include <dri_util.h> -#include <xmlconfig.h> - -#include "nouveau/nouveau_winsys.h" - -#define NOUVEAU_ERR(fmt, args...) debug_printf("%s: "fmt, __func__, ##args) - -struct nouveau_framebuffer { -	struct st_framebuffer *stfb; -}; - -struct nouveau_context { -	struct st_context *st; - -	/* DRI stuff */ -	__DRIscreenPrivate    *dri_screen; -	__DRIdrawablePrivate  *dri_drawable; -	unsigned int           last_stamp; -	driOptionCache         dri_option_cache; -	drm_context_t          drm_context; -	drmLock                drm_lock; -	int                    locked; -}; - -extern GLboolean nouveau_context_create(const __GLcontextModes *, -					__DRIcontextPrivate *, void *); -extern void nouveau_context_destroy(__DRIcontextPrivate *); -extern GLboolean nouveau_context_bind(__DRIcontextPrivate *, -				      __DRIdrawablePrivate *draw, -				      __DRIdrawablePrivate *read); -extern GLboolean nouveau_context_unbind(__DRIcontextPrivate *); - -extern void nouveau_contended_lock(struct nouveau_context *nv); -extern void LOCK_HARDWARE(struct nouveau_context *nv); -extern void UNLOCK_HARDWARE(struct nouveau_context *nv); - -#ifdef DEBUG -extern int __nouveau_debug; - -#define DEBUG_BO (1 << 0) - -#define DBG(flag, ...) do {                   \ -	if (__nouveau_debug & (DEBUG_##flag)) \ -		NOUVEAU_ERR(__VA_ARGS__);     \ -} while(0) -#else -#define DBG(flag, ...) -#endif - -#endif diff --git a/src/gallium/winsys/drm/nouveau/dri/nouveau_lock.c b/src/gallium/winsys/drm/nouveau/dri/nouveau_lock.c deleted file mode 100644 index 92f5bd09c9..0000000000 --- a/src/gallium/winsys/drm/nouveau/dri/nouveau_lock.c +++ /dev/null @@ -1,73 +0,0 @@ -/************************************************************************** - *  - * Copyright 2003 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. - *  - **************************************************************************/ - -#include <pipe/p_thread.h> -#include "nouveau_context.h" -#include "nouveau_screen.h" -#include "nouveau_drmif.h" - -pipe_static_mutex(lockMutex); - -/* Lock the hardware and validate our state. - */ -void -LOCK_HARDWARE(struct nouveau_context *nv) -{ -	struct nouveau_screen *nv_screen = nv->dri_screen->private; -	struct nouveau_device *dev = nv_screen->device; -	struct nouveau_device_priv *nvdev = nouveau_device(dev); -	char __ret=0; - -	assert(!nv->locked); -	pipe_mutex_lock(lockMutex); - -	DRM_CAS(nvdev->lock, nvdev->ctx, -		(DRM_LOCK_HELD | nvdev->ctx), __ret); - -	if (__ret) { -		drmGetLock(nvdev->fd, nvdev->ctx, 0); -		nouveau_contended_lock(nv); -	} -	nv->locked = 1; -} - -/* Unlock the hardware using the global current context  - */ -void -UNLOCK_HARDWARE(struct nouveau_context *nv) -{ -	struct nouveau_screen *nv_screen = nv->dri_screen->private; -	struct nouveau_device *dev = nv_screen->device; -	struct nouveau_device_priv *nvdev = nouveau_device(dev); - -	assert(nv->locked); -	nv->locked = 0; - -	DRM_UNLOCK(nvdev->fd, nvdev->lock, nvdev->ctx); - -	pipe_mutex_unlock(lockMutex); -}  diff --git a/src/gallium/winsys/drm/nouveau/dri/nouveau_screen.c b/src/gallium/winsys/drm/nouveau/dri/nouveau_screen.c deleted file mode 100644 index 4e9b76a909..0000000000 --- a/src/gallium/winsys/drm/nouveau/dri/nouveau_screen.c +++ /dev/null @@ -1,330 +0,0 @@ -#include <utils.h> -#include <vblank.h> -#include <xmlpool.h> - -#include <pipe/p_context.h> -#include <state_tracker/st_public.h> -#include <state_tracker/st_cb_fbo.h> -#include <state_tracker/drm_api.h> - -#include "nouveau_context.h" -#include "nouveau_screen.h" -#include "nouveau_swapbuffers.h" -#include "nouveau_dri.h" - -#include "nouveau_drm.h" -#include "nouveau_drmif.h" - -#if NOUVEAU_DRM_HEADER_PATCHLEVEL != 12 -#error nouveau_drm.h version does not match expected version -#endif - -/* Extension stuff, enabling of extensions handled by Gallium's GL state - * tracker.  But, we still need to define the entry points we want. - */ -#define need_GL_ARB_fragment_program -#define need_GL_ARB_multisample -#define need_GL_ARB_occlusion_query -#define need_GL_ARB_point_parameters -#define need_GL_ARB_shader_objects -#define need_GL_ARB_texture_compression -#define need_GL_ARB_vertex_program -#define need_GL_ARB_vertex_shader -#define need_GL_ARB_vertex_buffer_object -#define need_GL_EXT_compiled_vertex_array -#define need_GL_EXT_fog_coord -#define need_GL_EXT_secondary_color -#define need_GL_EXT_framebuffer_object -#define need_GL_VERSION_2_0 -#define need_GL_VERSION_2_1 -#include "extension_helper.h" - -const struct dri_extension card_extensions[] = -{ -	{ "GL_ARB_multisample", GL_ARB_multisample_functions }, -	{ "GL_ARB_occlusion_query", GL_ARB_occlusion_query_functions }, -	{ "GL_ARB_point_parameters", GL_ARB_point_parameters_functions }, -	{ "GL_ARB_shader_objects", GL_ARB_shader_objects_functions }, -	{ "GL_ARB_shading_language_100", GL_VERSION_2_0_functions }, -	{ "GL_ARB_shading_language_120", GL_VERSION_2_1_functions }, -	{ "GL_ARB_texture_compression", GL_ARB_texture_compression_functions }, -	{ "GL_ARB_vertex_program", GL_ARB_vertex_program_functions }, -	{ "GL_ARB_vertex_shader", GL_ARB_vertex_shader_functions }, -	{ "GL_ARB_vertex_buffer_object", GL_ARB_vertex_buffer_object_functions }, -	{ "GL_EXT_compiled_vertex_array", GL_EXT_compiled_vertex_array_functions }, -	{ "GL_EXT_fog_coord", GL_EXT_fog_coord_functions }, -	{ "GL_EXT_framebuffer_object", GL_EXT_framebuffer_object_functions }, -	{ "GL_EXT_secondary_color", GL_EXT_secondary_color_functions }, -	{ NULL, 0 } -}; - -PUBLIC const char __driConfigOptions[] = -DRI_CONF_BEGIN -DRI_CONF_END; -static const GLuint __driNConfigOptions = 0; - -extern const struct dri_extension common_extensions[]; -extern const struct dri_extension nv40_extensions[]; - -static GLboolean -nouveau_create_buffer(__DRIscreenPrivate * driScrnPriv, -		      __DRIdrawablePrivate * driDrawPriv, -		      const __GLcontextModes *glVis, GLboolean pixmapBuffer) -{ -	struct nouveau_framebuffer *nvfb; -	enum pipe_format colour, depth, stencil; - -	if (pixmapBuffer) -		return GL_FALSE; - -	nvfb = CALLOC_STRUCT(nouveau_framebuffer); -	if (!nvfb) -		return GL_FALSE; - -	if (glVis->redBits == 5) -		colour = PIPE_FORMAT_R5G6B5_UNORM; -	else -		colour = PIPE_FORMAT_A8R8G8B8_UNORM; - -	if (glVis->depthBits == 16) -		depth = PIPE_FORMAT_Z16_UNORM; -	else if (glVis->depthBits == 24) -		depth = PIPE_FORMAT_Z24S8_UNORM; -	else -		depth = PIPE_FORMAT_NONE; - -	if (glVis->stencilBits == 8) -		stencil = PIPE_FORMAT_Z24S8_UNORM; -	else -		stencil = PIPE_FORMAT_NONE; - -	nvfb->stfb = st_create_framebuffer(glVis, colour, depth, stencil, -					   driDrawPriv->w, driDrawPriv->h, -					   (void*)nvfb); -	if (!nvfb->stfb) { -		free(nvfb); -		return  GL_FALSE; -	} - -	driDrawPriv->driverPrivate = (void *)nvfb; -	return GL_TRUE; -} - -static void -nouveau_destroy_buffer(__DRIdrawablePrivate * driDrawPriv) -{ -	struct nouveau_framebuffer *nvfb; -	 -	nvfb = (struct nouveau_framebuffer *)driDrawPriv->driverPrivate; -	st_unreference_framebuffer(nvfb->stfb); -	free(nvfb); -} - -static __DRIconfig ** -nouveau_fill_in_modes(__DRIscreenPrivate *psp, -		      unsigned pixel_bits, unsigned depth_bits, -		      unsigned stencil_bits, GLboolean have_back_buffer) -{ -	__DRIconfig **configs; -	unsigned depth_buffer_factor; -	unsigned back_buffer_factor; -	GLenum fb_format; -	GLenum fb_type; - -	static const GLenum back_buffer_modes[] = { -		GLX_NONE, GLX_SWAP_UNDEFINED_OML, -	}; - -	uint8_t depth_bits_array[3]; -	uint8_t stencil_bits_array[3]; -	uint8_t msaa_samples_array[1]; - -	depth_bits_array[0] = 0; -	depth_bits_array[1] = depth_bits; -	depth_bits_array[2] = depth_bits; - -	/* Just like with the accumulation buffer, always provide some modes -	 * with a stencil buffer.  It will be a sw fallback, but some apps won't -	 * care about that. -	 */ -	stencil_bits_array[0] = 0; -	stencil_bits_array[1] = 0; -	if (depth_bits == 24) -		stencil_bits_array[1] = (stencil_bits == 0) ? 8 : stencil_bits; -	stencil_bits_array[2] = (stencil_bits == 0) ? 8 : stencil_bits; - -	msaa_samples_array[0] = 0; - -	depth_buffer_factor = -		((depth_bits != 0) || (stencil_bits != 0)) ? 3 : 1; -	back_buffer_factor = (have_back_buffer) ? 3 : 1; - -	if (pixel_bits == 16) { -		fb_format = GL_RGB; -		fb_type = GL_UNSIGNED_SHORT_5_6_5; -	} -	else { -		fb_format = GL_BGRA; -		fb_type = GL_UNSIGNED_INT_8_8_8_8_REV; -	} - -	configs = driCreateConfigs(fb_format, fb_type, -				   depth_bits_array, stencil_bits_array, -				   depth_buffer_factor, back_buffer_modes, -				   back_buffer_factor, msaa_samples_array, 1); -	if (configs == NULL) { -	 fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", -			 __func__, __LINE__); -		return NULL; -	} - -	return configs; -} - -static struct pipe_surface * -dri_surface_from_handle(struct pipe_screen *screen, -                        unsigned handle, -                        enum pipe_format format, -                        unsigned width, -                        unsigned height, -                        unsigned pitch) -{ -   struct pipe_surface *surface = NULL; -   struct pipe_texture *texture = NULL; -   struct pipe_texture templat; -   struct pipe_buffer *buf = NULL; - -   buf = drm_api_hooks.buffer_from_handle(screen, "front buffer", handle); -   if (!buf) -      return NULL; - -   memset(&templat, 0, sizeof(templat)); -   templat.tex_usage = PIPE_TEXTURE_USAGE_PRIMARY | -                       NOUVEAU_TEXTURE_USAGE_LINEAR; -   templat.target = PIPE_TEXTURE_2D; -   templat.last_level = 0; -   templat.depth[0] = 1; -   templat.format = format; -   templat.width[0] = width; -   templat.height[0] = height; -   pf_get_block(templat.format, &templat.block); - -   texture = screen->texture_blanket(screen, -                                     &templat, -                                     &pitch, -                                     buf); - -   /* we don't need the buffer from this point on */ -   pipe_buffer_reference(&buf, NULL); - -   if (!texture) -      return NULL; - -   surface = screen->get_tex_surface(screen, texture, 0, 0, 0, -                                     PIPE_BUFFER_USAGE_GPU_READ | -                                     PIPE_BUFFER_USAGE_GPU_WRITE); - -   /* we don't need the texture from this point on */ -   pipe_texture_reference(&texture, NULL); -   return surface; -} - -static const __DRIconfig ** -nouveau_screen_create(__DRIscreenPrivate *psp) -{ -	struct nouveau_dri *nv_dri = psp->pDevPriv; -	struct nouveau_screen *nv_screen; -	static const __DRIversion ddx_expected = -		{ 0, 0, NOUVEAU_DRM_HEADER_PATCHLEVEL }; -	static const __DRIversion dri_expected = { 4, 0, 0 }; -	static const __DRIversion drm_expected = -		{ 0, 0, NOUVEAU_DRM_HEADER_PATCHLEVEL }; - -	if (!driCheckDriDdxDrmVersions2("nouveau", -					&psp->dri_version, &dri_expected, -					&psp->ddx_version, &ddx_expected, -					&psp->drm_version, &drm_expected)) { -		return NULL; -	} - -	if (drm_expected.patch != psp->drm_version.patch) { -		fprintf(stderr, "Incompatible DRM patch level.\n" -				"Expected: %d\n" "Current : %d\n", -			drm_expected.patch, psp->drm_version.patch); -		return NULL; -	} - -	driInitExtensions(NULL, card_extensions, GL_FALSE); - -	if (psp->devPrivSize != sizeof(struct nouveau_dri)) { -		NOUVEAU_ERR("DRI struct mismatch between DDX/DRI\n"); -		return NULL; -	} - -	nv_screen = CALLOC_STRUCT(nouveau_screen); -	if (!nv_screen) -		return NULL; - -	nouveau_device_open_existing(&nv_screen->device, 0, psp->fd, 0); - -	nv_screen->pscreen = drm_api_hooks.create_screen(psp->fd, NULL); -	if (!nv_screen->pscreen) { -		FREE(nv_screen); -		return NULL; -	} -	nv_screen->pscreen->flush_frontbuffer = nouveau_flush_frontbuffer; - -	{ -		enum pipe_format format; - -		if (nv_dri->bpp == 16) -			format = PIPE_FORMAT_R5G6B5_UNORM; -		else -			format = PIPE_FORMAT_A8R8G8B8_UNORM; - -		nv_screen->fb = dri_surface_from_handle(nv_screen->pscreen, -							nv_dri->front_offset, -							format, -							nv_dri->width, -							nv_dri->height, -							nv_dri->front_pitch * -							nv_dri->bpp / 8); -	} -						 -	driParseOptionInfo(&nv_screen->option_cache, -			   __driConfigOptions, __driNConfigOptions); - -	nv_screen->driScrnPriv = psp; -	psp->private = (void *)nv_screen; - -	return (const __DRIconfig **) -		nouveau_fill_in_modes(psp, nv_dri->bpp, -				      (nv_dri->bpp == 16) ? 16 : 24, -				      (nv_dri->bpp == 16) ? 0 : 8, 1); -} - -static void -nouveau_screen_destroy(__DRIscreenPrivate *driScrnPriv) -{ -	struct nouveau_screen *nv_screen = driScrnPriv->private; - -	driScrnPriv->private = NULL; -	FREE(nv_screen); -} - -const struct __DriverAPIRec -driDriverAPI = { -	.InitScreen	= nouveau_screen_create, -	.DestroyScreen	= nouveau_screen_destroy, -	.CreateContext	= nouveau_context_create, -	.DestroyContext	= nouveau_context_destroy, -	.CreateBuffer	= nouveau_create_buffer, -	.DestroyBuffer	= nouveau_destroy_buffer, -	.SwapBuffers	= nouveau_swap_buffers, -	.MakeCurrent	= nouveau_context_bind, -	.UnbindContext	= nouveau_context_unbind, -	.CopySubBuffer	= nouveau_copy_sub_buffer, - -	.InitScreen2	= NULL, /* one day, I promise! */ -}; - diff --git a/src/gallium/winsys/drm/nouveau/dri/nouveau_screen.h b/src/gallium/winsys/drm/nouveau/dri/nouveau_screen.h deleted file mode 100644 index ac078f3c63..0000000000 --- a/src/gallium/winsys/drm/nouveau/dri/nouveau_screen.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef __NOUVEAU_SCREEN_DRI_H__ -#define __NOUVEAU_SCREEN_DRI_H__ - -#include "xmlconfig.h" - -struct nouveau_screen { -	__DRIscreenPrivate *driScrnPriv; -	driOptionCache      option_cache; - -	struct nouveau_device *device; - -	struct pipe_screen *pscreen; -	struct pipe_surface *fb; -}; - -#endif diff --git a/src/gallium/winsys/drm/nouveau/dri/nouveau_swapbuffers.c b/src/gallium/winsys/drm/nouveau/dri/nouveau_swapbuffers.c deleted file mode 100644 index 9c841a0b2d..0000000000 --- a/src/gallium/winsys/drm/nouveau/dri/nouveau_swapbuffers.c +++ /dev/null @@ -1,115 +0,0 @@ -#include <main/glheader.h> -#include <glapi/glthread.h> -#include <GL/internal/glcore.h> - -#include <pipe/p_context.h> -#include <state_tracker/st_public.h> -#include <state_tracker/st_context.h> -#include <state_tracker/st_cb_fbo.h> - -#include "nouveau_context.h" -#include "nouveau_screen.h" -#include "nouveau_swapbuffers.h" - -#include "nouveau_pushbuf.h" - -void -nouveau_copy_buffer(__DRIdrawablePrivate *dPriv, struct pipe_surface *surf, -		    const drm_clip_rect_t *rect) -{ -	struct nouveau_context *nv = dPriv->driContextPriv->driverPrivate; -	struct nouveau_screen *nv_screen = nv->dri_screen->private; -	struct pipe_context *pipe = nv->st->pipe; -	drm_clip_rect_t *pbox; -	int nbox, i; - -	LOCK_HARDWARE(nv); -	if (!dPriv->numClipRects) { -		UNLOCK_HARDWARE(nv); -		return; -	} -	pbox = dPriv->pClipRects; -	nbox = dPriv->numClipRects; - -	for (i = 0; i < nbox; i++, pbox++) { -		int sx, sy, dx, dy, w, h; - -		sx = pbox->x1 - dPriv->x; -		sy = pbox->y1 - dPriv->y; -		dx = pbox->x1; -		dy = pbox->y1; -		w  = pbox->x2 - pbox->x1; -		h  = pbox->y2 - pbox->y1; - -		pipe->surface_copy(pipe, nv_screen->fb, dx, dy, surf, -				   sx, sy, w, h); -	} - -	pipe->flush(pipe, 0, NULL); -	UNLOCK_HARDWARE(nv); - -	if (nv->last_stamp != dPriv->lastStamp) { -		struct nouveau_framebuffer *nvfb = dPriv->driverPrivate; -		st_resize_framebuffer(nvfb->stfb, dPriv->w, dPriv->h); -		nv->last_stamp = dPriv->lastStamp; -	} -} - -void -nouveau_copy_sub_buffer(__DRIdrawablePrivate *dPriv, int x, int y, int w, int h) -{ -	struct nouveau_framebuffer *nvfb = dPriv->driverPrivate; -	struct pipe_surface *surf; - -	st_get_framebuffer_surface(nvfb->stfb, ST_SURFACE_BACK_LEFT, &surf); -	if (surf) { -		drm_clip_rect_t rect; -		rect.x1 = x; -		rect.y1 = y; -		rect.x2 = x + w; -		rect.y2 = y + h; - -		st_notify_swapbuffers(nvfb->stfb); -		nouveau_copy_buffer(dPriv, surf, &rect); -	} -} - -void -nouveau_swap_buffers(__DRIdrawablePrivate *dPriv) -{ -	struct nouveau_framebuffer *nvfb = dPriv->driverPrivate; -	struct pipe_surface *surf; - -	st_get_framebuffer_surface(nvfb->stfb, ST_SURFACE_BACK_LEFT, &surf); -	if (surf) { -		st_notify_swapbuffers(nvfb->stfb); -		nouveau_copy_buffer(dPriv, surf, NULL); -	} -} - -void -nouveau_flush_frontbuffer(struct pipe_screen *pscreen, struct pipe_surface *ps, -			  void *context_private) -{ -	struct nouveau_context *nv = context_private; -	__DRIdrawablePrivate *dPriv = nv->dri_drawable; - -	nouveau_copy_buffer(dPriv, ps, NULL); -} - -void -nouveau_contended_lock(struct nouveau_context *nv) -{ -	struct nouveau_context *nv_sub = (struct nouveau_context*)nv; -	__DRIdrawablePrivate *dPriv = nv_sub->dri_drawable; -	__DRIscreenPrivate *sPriv = nv_sub->dri_screen; - -	/* If the window moved, may need to set a new cliprect now. -	 * -	 * NOTE: This releases and regains the hw lock, so all state -	 * checking must be done *after* this call: -	 */ -	if (dPriv) -		DRI_VALIDATE_DRAWABLE_INFO(sPriv, dPriv); -} - diff --git a/src/gallium/winsys/drm/nouveau/dri/nouveau_swapbuffers.h b/src/gallium/winsys/drm/nouveau/dri/nouveau_swapbuffers.h deleted file mode 100644 index 4ca9cc2283..0000000000 --- a/src/gallium/winsys/drm/nouveau/dri/nouveau_swapbuffers.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef __NOUVEAU_SWAPBUFFERS_H__ -#define __NOUVEAU_SWAPBUFFERS_H__ - -void nouveau_copy_buffer(__DRIdrawablePrivate *, struct pipe_surface *, -			 const drm_clip_rect_t *); -void nouveau_copy_sub_buffer(__DRIdrawablePrivate *, int x, int y, int w, int h); -void nouveau_swap_buffers(__DRIdrawablePrivate *); -void nouveau_flush_frontbuffer(struct pipe_screen *, struct pipe_surface *, -			       void *context_private); - -#endif diff --git a/src/gallium/winsys/drm/nouveau/dri2/Makefile b/src/gallium/winsys/drm/nouveau/dri2/Makefile deleted file mode 100644 index 377a80d518..0000000000 --- a/src/gallium/winsys/drm/nouveau/dri2/Makefile +++ /dev/null @@ -1,26 +0,0 @@ -TOP = ../../../../../.. -include $(TOP)/configs/current - -LIBNAME = nouveau_dri2.so - -PIPE_DRIVERS = \ -	$(TOP)/src/gallium/state_trackers/dri/libdridrm.a \ -	$(TOP)/src/gallium/winsys/drm/nouveau/drm/libnouveaudrm.a \ -	$(TOP)/src/gallium/drivers/nv04/libnv04.a \ -	$(TOP)/src/gallium/drivers/nv10/libnv10.a \ -	$(TOP)/src/gallium/drivers/nv20/libnv20.a \ -	$(TOP)/src/gallium/drivers/nv30/libnv30.a \ -	$(TOP)/src/gallium/drivers/nv40/libnv40.a \ -	$(TOP)/src/gallium/drivers/nv50/libnv50.a - -DRIVER_SOURCES = - -C_SOURCES = \ -	$(COMMON_GALLIUM_SOURCES) \ -	$(DRIVER_SOURCES) - -include ../../Makefile.template - -DRI_LIB_DEPS += $(shell pkg-config libdrm_nouveau --libs) - -symlinks: diff --git a/src/gallium/winsys/drm/nouveau/dri/nouveau_dri.h b/src/gallium/winsys/drm/nouveau/drm/nouveau_dri.h index 1207c2d609..1207c2d609 100644 --- a/src/gallium/winsys/drm/nouveau/dri/nouveau_dri.h +++ b/src/gallium/winsys/drm/nouveau/drm/nouveau_dri.h diff --git a/src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.c b/src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.c index a558fda140..b355a1391d 100644 --- a/src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.c +++ b/src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.c @@ -7,9 +7,68 @@  #include "nouveau_channel.h"  #include "nouveau_bo.h" +static struct pipe_surface * +dri_surface_from_handle(struct pipe_screen *screen, +                        unsigned handle, +                        enum pipe_format format, +                        unsigned width, +                        unsigned height, +                        unsigned pitch) +{ +   struct pipe_surface *surface = NULL; +   struct pipe_texture *texture = NULL; +   struct pipe_texture templat; +   struct pipe_buffer *buf = NULL; + +   buf = drm_api_hooks.buffer_from_handle(screen, "front buffer", handle); +   if (!buf) +      return NULL; + +   memset(&templat, 0, sizeof(templat)); +   templat.tex_usage = PIPE_TEXTURE_USAGE_PRIMARY | +                       NOUVEAU_TEXTURE_USAGE_LINEAR; +   templat.target = PIPE_TEXTURE_2D; +   templat.last_level = 0; +   templat.depth[0] = 1; +   templat.format = format; +   templat.width[0] = width; +   templat.height[0] = height; +   pf_get_block(templat.format, &templat.block); + +   texture = screen->texture_blanket(screen, +                                     &templat, +                                     &pitch, +                                     buf); + +   /* we don't need the buffer from this point on */ +   pipe_buffer_reference(&buf, NULL); + +   if (!texture) +      return NULL; + +   surface = screen->get_tex_surface(screen, texture, 0, 0, 0, +                                     PIPE_BUFFER_USAGE_GPU_READ | +                                     PIPE_BUFFER_USAGE_GPU_WRITE); + +   /* we don't need the texture from this point on */ +   pipe_texture_reference(&texture, NULL); +   return surface; +} + +static struct pipe_surface * +nouveau_dri1_front_surface(struct pipe_context *pipe) +{ +	return nouveau_screen(pipe->screen)->front; +} + +static struct dri1_api nouveau_dri1_api = { +	nouveau_dri1_front_surface, +}; +  static struct pipe_screen *  nouveau_drm_create_screen(int fd, struct drm_create_screen_arg *arg)  { +	struct dri1_create_screen_arg *dri1 = (void *)arg;  	struct pipe_winsys *ws;  	struct nouveau_winsys *nvws;  	struct nouveau_device *dev = NULL; @@ -67,6 +126,33 @@ nouveau_drm_create_screen(int fd, struct drm_create_screen_arg *arg)  		return NULL;  	} +	if (arg->mode == DRM_CREATE_DRI1) { +		struct nouveau_pipe_winsys *nvpws = nouveau_pipe_winsys(ws); +		struct nouveau_dri *nvdri = dri1->ddx_info; +		enum pipe_format format; + +		if (nvdri->bpp == 16) +			format = PIPE_FORMAT_R5G6B5_UNORM; +		else +			format = PIPE_FORMAT_A8R8G8B8_UNORM; + +		nvpws->front = dri_surface_from_handle(nvpws->pscreen, +						       nvdri->front_offset, +						       format, +						       nvdri->width, +						       nvdri->height, +						       nvdri->front_pitch * +						       (nvdri->bpp / 8)); +		if (!nvpws->front) { +			debug_printf("%s: error referencing front buffer\n", +				     __func__); +			ws->destroy(ws); +			return NULL; +		} + +		dri1->api = &nouveau_dri1_api; +	} +  	return nouveau_pipe_winsys(ws)->pscreen;  } diff --git a/src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.h b/src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.h index 2782c83c0e..cc237bfc13 100644 --- a/src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.h +++ b/src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.h @@ -1,5 +1,7 @@  #ifndef __NOUVEAU_DRM_API_H__  #define __NOUVEAU_DRM_API_H__  #include "state_tracker/drm_api.h" +#include "state_tracker/dri1_api.h" +#include "nouveau_dri.h"  #endif diff --git a/src/gallium/winsys/drm/nouveau/drm/nouveau_winsys_pipe.h b/src/gallium/winsys/drm/nouveau/drm/nouveau_winsys_pipe.h index 10e1e269e8..ec10f1e00c 100644 --- a/src/gallium/winsys/drm/nouveau/drm/nouveau_winsys_pipe.h +++ b/src/gallium/winsys/drm/nouveau/drm/nouveau_winsys_pipe.h @@ -29,6 +29,8 @@ struct nouveau_pipe_winsys {  	unsigned nr_pctx;  	struct pipe_context **pctx; + +	struct pipe_surface *front;  };  static INLINE struct nouveau_pipe_winsys * diff --git a/src/gallium/winsys/drm/radeon/core/radeon_buffer.c b/src/gallium/winsys/drm/radeon/core/radeon_buffer.c index a15487352b..0d0fdc5bd8 100644 --- a/src/gallium/winsys/drm/radeon/core/radeon_buffer.c +++ b/src/gallium/winsys/drm/radeon/core/radeon_buffer.c @@ -93,6 +93,29 @@ static struct pipe_buffer *radeon_buffer_user_create(struct pipe_winsys *ws,      return &radeon_buffer->base;  } +static struct pipe_buffer *radeon_surface_buffer_create(struct pipe_winsys *ws, +                                                        unsigned width, +                                                        unsigned height, +                                                        enum pipe_format format, +                                                        unsigned usage, +                                                        unsigned *stride) +{ +    struct pipe_format_block block; +    unsigned nblocksx, nblocksy, size; + +    pf_get_block(format, &block); + +    nblocksx = pf_get_nblocksx(&block, width); +    nblocksy = pf_get_nblocksy(&block, height); + +    /* Radeons enjoy things in multiples of 32. */ +    /* XXX this can be 32 when POT */ +    *stride = (nblocksx * block.size + 63) & ~63; +    size = *stride * nblocksy; + +    return radeon_buffer_create(ws, 64, usage, size); +} +  static void radeon_buffer_del(struct pipe_buffer *buffer)  {      struct radeon_pipe_buffer *radeon_buffer = @@ -180,10 +203,11 @@ struct radeon_winsys* radeon_pipe_winsys(int fd)      radeon_ws->base.flush_frontbuffer = radeon_flush_frontbuffer;      radeon_ws->base.buffer_create = radeon_buffer_create; -    radeon_ws->base.buffer_destroy = radeon_buffer_del;      radeon_ws->base.user_buffer_create = radeon_buffer_user_create; +    radeon_ws->base.surface_buffer_create = radeon_surface_buffer_create;      radeon_ws->base.buffer_map = radeon_buffer_map;      radeon_ws->base.buffer_unmap = radeon_buffer_unmap; +    radeon_ws->base.buffer_destroy = radeon_buffer_del;      radeon_ws->base.fence_reference = radeon_fence_reference;      radeon_ws->base.fence_signalled = radeon_fence_signalled; diff --git a/src/gallium/winsys/drm/radeon/core/radeon_drm.c b/src/gallium/winsys/drm/radeon/core/radeon_drm.c index 428d3f65a1..5406d2bbea 100644 --- a/src/gallium/winsys/drm/radeon/core/radeon_drm.c +++ b/src/gallium/winsys/drm/radeon/core/radeon_drm.c @@ -30,6 +30,10 @@  #include "radeon_drm.h" +#ifdef DEBUG +#include "trace/trace_drm.h" +#endif +  /* Create a pipe_screen. */  struct pipe_screen* radeon_create_screen(int drmFB,  					 struct drm_create_screen_arg *arg) @@ -112,7 +116,11 @@ boolean radeon_global_handle_from_buffer(struct pipe_screen* screen,      return TRUE;  } +#ifdef DEBUG +struct drm_api hooks = { +#else  struct drm_api drm_api_hooks = { +#endif      .create_screen = radeon_create_screen,      .create_context = radeon_create_context,      /* XXX fix this */ diff --git a/src/gallium/winsys/drm/radeon/core/radeon_r300.c b/src/gallium/winsys/drm/radeon/core/radeon_r300.c index da233203d7..995bf6aa22 100644 --- a/src/gallium/winsys/drm/radeon/core/radeon_r300.c +++ b/src/gallium/winsys/drm/radeon/core/radeon_r300.c @@ -35,24 +35,24 @@ static void radeon_r300_add_buffer(struct r300_winsys* winsys,      /* Check to see if this BO is already in line for validation;       * find a slot for it otherwise. */ -    for (i = 0; i < RADEON_MAX_BOS; i++) { +    assert(priv->bo_count <= RADEON_MAX_BOS); +    for (i = 0; i < priv->bo_count; i++) {          if (sc[i].bo == bo) { -            return; -        } else if (sc[i].bo == NULL) { -            sc[i].bo = bo; -            sc[i].read_domains = rd; -            sc[i].write_domain = wd; -            priv->bo_count = i + 1; +            sc[i].read_domains |= rd; +            sc[i].write_domain |= wd;              return;          }      } -    assert(FALSE && "Oh God too many BOs!"); +    sc[priv->bo_count].bo = bo; +    sc[priv->bo_count].read_domains = rd; +    sc[priv->bo_count].write_domain = wd; +    priv->bo_count++;  }  static boolean radeon_r300_validate(struct r300_winsys* winsys)  { -    int retval; +    int retval, i;      struct radeon_winsys_priv* priv =          (struct radeon_winsys_priv*)winsys->radeon_winsys;      struct radeon_cs_space_check* sc = priv->sc; @@ -62,12 +62,23 @@ static boolean radeon_r300_validate(struct r300_winsys* winsys)      if (retval == RADEON_CS_SPACE_OP_TO_BIG) {          /* We might as well HCF, since this is not going to fit in the card,           * period. */ +        /* XXX just drop it on the floor instead */  	exit(1);      } else if (retval == RADEON_CS_SPACE_FLUSH) {          /* We must flush before more rendering can commence. */          return TRUE;      } +    /* XXX should probably be its own function */ +    for (i = 0; i < priv->bo_count; i++) { +        if (sc[i].read_domains && sc[i].write_domain) { +            /* Cute, cute. We need to flush first. */ +            debug_printf("radeon: BO %p can't be read and written; " +                    "requesting flush.\n", sc[i].bo); +            return TRUE; +        } +    } +      /* Things are fine, we can proceed as normal. */      return FALSE;  } @@ -108,9 +119,15 @@ static void radeon_r300_write_cs_reloc(struct r300_winsys* winsys,  {      struct radeon_winsys_priv* priv =          (struct radeon_winsys_priv*)winsys->radeon_winsys; +    int retval = 0; -    radeon_cs_write_reloc(priv->cs, +    retval = radeon_cs_write_reloc(priv->cs,              ((struct radeon_pipe_buffer*)pbuffer)->bo, rd, wd, flags); + +    if (retval) { +        debug_printf("radeon: Relocation of %p (%d, %d, %d) failed!\n", +                pbuffer, rd, wd, flags); +    }  }  static void radeon_r300_end_cs(struct r300_winsys* winsys, @@ -128,57 +145,63 @@ static void radeon_r300_flush_cs(struct r300_winsys* winsys)  {      struct radeon_winsys_priv* priv =          (struct radeon_winsys_priv*)winsys->radeon_winsys; -    int retval = 0; +    struct radeon_cs_space_check* sc = priv->sc; +    int retval = 1; +    /* Emit the CS. */      retval = radeon_cs_emit(priv->cs);      if (retval) {          debug_printf("radeon: Bad CS, dumping...\n");          radeon_cs_print(priv->cs, stderr);      }      radeon_cs_erase(priv->cs); + +    /* Clean out BOs. */ +    memset(sc, 0, sizeof(struct radeon_cs_space_check) * RADEON_MAX_BOS); +    priv->bo_count = 0;  }  /* Helper function to do the ioctls needed for setup and init. */  static void do_ioctls(struct r300_winsys* winsys, int fd)  { -    struct drm_radeon_gem_info info; -    drm_radeon_getparam_t gp; -    int target; +    struct drm_radeon_gem_info gem_info = {0}; +    drm_radeon_getparam_t gp = {0}; +    struct drm_radeon_info info = {0}; +    int target = 0;      int retval; +    info.value = ⌖      gp.value = ⌖ -    /* First, get the number of pixel pipes */ -    gp.param = RADEON_PARAM_NUM_GB_PIPES; -    retval = drmCommandWriteRead(fd, DRM_RADEON_GETPARAM, &gp, sizeof(gp)); +    /* First, get PCI ID */ +    info.request = RADEON_INFO_DEVICE_ID; +    retval = drmCommandWriteRead(fd, DRM_RADEON_INFO, &info, sizeof(info));      if (retval) { -        fprintf(stderr, "%s: Failed to get GB pipe count, error number %d\n", +        fprintf(stderr, "%s: New ioctl for PCI ID failed " +                "(error number %d), trying classic ioctl...\n",                  __FUNCTION__, retval); -        exit(1); -    } -    winsys->gb_pipes = target; - -    /* Then, get PCI ID */ -    gp.param = RADEON_PARAM_DEVICE_ID; -    retval = drmCommandWriteRead(fd, DRM_RADEON_GETPARAM, &gp, sizeof(gp)); -    if (retval) { -        fprintf(stderr, "%s: Failed to get PCI ID, error number %d\n", -                __FUNCTION__, retval); -        exit(1); +        gp.param = RADEON_PARAM_DEVICE_ID; +        retval = drmCommandWriteRead(fd, DRM_RADEON_GETPARAM, &gp, +                sizeof(gp)); +        if (retval) { +            fprintf(stderr, "%s: Failed to get PCI ID, " +                    "error number %d\n", __FUNCTION__, retval); +            exit(1); +        }      }      winsys->pci_id = target; -    /* Finally, retrieve MM info */ +    /* Then, retrieve MM info */      retval = drmCommandWriteRead(fd, DRM_RADEON_GEM_INFO, -            &info, sizeof(info)); +            &gem_info, sizeof(gem_info));      if (retval) {          fprintf(stderr, "%s: Failed to get MM info, error number %d\n",                  __FUNCTION__, retval);          exit(1);      } -    winsys->gart_size = info.gart_size; +    winsys->gart_size = gem_info.gart_size;      /* XXX */ -    winsys->vram_size = info.vram_visible; +    winsys->vram_size = gem_info.vram_visible;  }  struct r300_winsys* diff --git a/src/gallium/winsys/drm/radeon/core/radeon_r300.h b/src/gallium/winsys/drm/radeon/core/radeon_r300.h index 5c373cd084..a2e0e58248 100644 --- a/src/gallium/winsys/drm/radeon/core/radeon_r300.h +++ b/src/gallium/winsys/drm/radeon/core/radeon_r300.h @@ -31,5 +31,18 @@  #include "radeon_buffer.h" +/* protect us from bonghits */ +#ifndef RADEON_INFO_DEVICE_ID +#define RADEON_INFO_DEVICE_ID 0 +#endif +#ifndef DRM_RADEON_INFO +#define DRM_RADEON_INFO 0x1 +struct drm_radeon_info { +	uint32_t		request; +	uint32_t		pad; +	uint64_t		value; +}; +#endif +  struct r300_winsys*  radeon_create_r300_winsys(int fd, struct radeon_winsys* old_winsys); diff --git a/src/gallium/winsys/drm/radeon/dri/Makefile b/src/gallium/winsys/drm/radeon/dri/Makefile index c218ee9d01..a9889444de 100644 --- a/src/gallium/winsys/drm/radeon/dri/Makefile +++ b/src/gallium/winsys/drm/radeon/dri/Makefile @@ -10,6 +10,7 @@ PIPE_DRIVERS = \  	$(TOP)/src/gallium/state_trackers/dri/libdridrm.a \  	$(TOP)/src/gallium/winsys/drm/radeon/core/libradeonwinsys.a \  	$(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \ +	$(TOP)/src/gallium/drivers/trace/libtrace.a \  	$(TOP)/src/gallium/drivers/r300/libr300.a  C_SOURCES = \ diff --git a/src/gallium/winsys/drm/radeon/egl/Makefile b/src/gallium/winsys/drm/radeon/egl/Makefile index d989b3aa93..6a1448d1b9 100644 --- a/src/gallium/winsys/drm/radeon/egl/Makefile +++ b/src/gallium/winsys/drm/radeon/egl/Makefile @@ -8,6 +8,7 @@ PIPE_DRIVERS = \  	$(TOP)/src/gallium/state_trackers/egl/libegldrm.a \  	$(GALLIUMDIR)/winsys/drm/radeon/core/libradeonwinsys.a \  	$(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \ +	$(TOP)/src/gallium/drivers/trace/libtrace.a \  	$(TOP)/src/gallium/drivers/r300/libr300.a  DRIVER_SOURCES = diff --git a/src/gallium/winsys/egl_xlib/egl_xlib.c b/src/gallium/winsys/egl_xlib/egl_xlib.c index b52f427e4a..c10e3c00ff 100644 --- a/src/gallium/winsys/egl_xlib/egl_xlib.c +++ b/src/gallium/winsys/egl_xlib/egl_xlib.c @@ -588,7 +588,9 @@ find_supported_apis(void)     EGLint mask = 0;     void *handle; -   handle = dlopen(NULL, 0); +   handle = dlopen(NULL, RTLD_LAZY | RTLD_LOCAL); +   if(!handle) +      return mask;     if (dlsym(handle, "st_api_OpenGL_ES1"))        mask |= EGL_OPENGL_ES_BIT;  | 
