diff options
Diffstat (limited to 'src/gallium')
193 files changed, 6087 insertions, 3812 deletions
diff --git a/src/gallium/auxiliary/Makefile b/src/gallium/auxiliary/Makefile index dcebab7c0f2..843b72bc38b 100644 --- a/src/gallium/auxiliary/Makefile +++ b/src/gallium/auxiliary/Makefile @@ -149,6 +149,7 @@ C_SOURCES = \ GALLIVM_SOURCES = \ gallivm/lp_bld_arit.c \ + gallivm/lp_bld_assert.c \ gallivm/lp_bld_const.c \ gallivm/lp_bld_conv.c \ gallivm/lp_bld_debug.c \ diff --git a/src/gallium/auxiliary/SConscript b/src/gallium/auxiliary/SConscript index 72a16617db8..1f091987218 100644 --- a/src/gallium/auxiliary/SConscript +++ b/src/gallium/auxiliary/SConscript @@ -34,14 +34,14 @@ env.CodeGenerate( target = 'util/u_format_table.c', script = '#src/gallium/auxiliary/util/u_format_table.py', source = ['#src/gallium/auxiliary/util/u_format.csv'], - command = 'python $SCRIPT $SOURCE > $TARGET' + command = python_cmd + ' $SCRIPT $SOURCE > $TARGET' ) env.CodeGenerate( target = 'util/u_half.c', script = 'util/u_half.py', source = [], - command = 'python $SCRIPT > $TARGET' + command = python_cmd + ' $SCRIPT > $TARGET' ) env.Depends('util/u_format_table.c', [ @@ -198,6 +198,7 @@ source = [ if env['llvm']: source += [ 'gallivm/lp_bld_arit.c', + 'gallivm/lp_bld_assert.c', 'gallivm/lp_bld_const.c', 'gallivm/lp_bld_conv.c', 'gallivm/lp_bld_debug.c', diff --git a/src/gallium/auxiliary/draw/draw_context.c b/src/gallium/auxiliary/draw/draw_context.c index c127f741881..995b675b9a1 100644 --- a/src/gallium/auxiliary/draw/draw_context.c +++ b/src/gallium/auxiliary/draw/draw_context.c @@ -288,12 +288,19 @@ draw_set_mapped_constant_buffer(struct draw_context *draw, shader_type == PIPE_SHADER_GEOMETRY); debug_assert(slot < PIPE_MAX_CONSTANT_BUFFERS); - if (shader_type == PIPE_SHADER_VERTEX) { + switch (shader_type) { + case PIPE_SHADER_VERTEX: draw->pt.user.vs_constants[slot] = buffer; + draw->pt.user.vs_constants_size[slot] = size; draw_vs_set_constants(draw, slot, buffer, size); - } else if (shader_type == PIPE_SHADER_GEOMETRY) { + break; + case PIPE_SHADER_GEOMETRY: draw->pt.user.gs_constants[slot] = buffer; + draw->pt.user.gs_constants_size[slot] = size; draw_gs_set_constants(draw, slot, buffer, size); + break; + default: + assert(0 && "invalid shader type in draw_set_mapped_constant_buffer"); } } diff --git a/src/gallium/auxiliary/draw/draw_decompose_tmp.h b/src/gallium/auxiliary/draw/draw_decompose_tmp.h new file mode 100644 index 00000000000..a52d2b50588 --- /dev/null +++ b/src/gallium/auxiliary/draw/draw_decompose_tmp.h @@ -0,0 +1,425 @@ +/* + * Mesa 3-D graphics library + * Version: 7.9 + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * Copyright (C) 2010 LunarG Inc. + * + * 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, sublicense, + * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS 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. + * + * Authors: + * Keith Whitwell <[email protected]> + * Chia-I Wu <[email protected]> + */ + +/* these macros are optional */ +#ifndef LOCAL_VARS +#define LOCAL_VARS +#endif +#ifndef FUNC_ENTER +#define FUNC_ENTER do {} while (0) +#endif +#ifndef FUNC_EXIT +#define FUNC_EXIT do {} while (0) +#endif +#ifndef LINE_ADJ +#define LINE_ADJ(flags, a0, i0, i1, a1) LINE(flags, i0, i1) +#endif +#ifndef TRIANGLE_ADJ +#define TRIANGLE_ADJ(flags, i0, a0, i1, a1, i2, a2) TRIANGLE(flags, i0, i1, i2) +#endif + +static void +FUNC(FUNC_VARS) +{ + unsigned idx[6], i; + ushort flags; + LOCAL_VARS + + FUNC_ENTER; + + /* prim, count, and last_vertex_last should have been defined */ + if (0) { + debug_printf("%s: prim 0x%x, count %d, last_vertex_last %d\n", + __FUNCTION__, prim, count, last_vertex_last); + } + + switch (prim) { + case PIPE_PRIM_POINTS: + for (i = 0; i < count; i++) { + idx[0] = GET_ELT(i); + POINT(idx[0]); + } + break; + + case PIPE_PRIM_LINES: + flags = DRAW_PIPE_RESET_STIPPLE; + for (i = 0; i + 1 < count; i += 2) { + idx[0] = GET_ELT(i); + idx[1] = GET_ELT(i + 1); + LINE(flags, idx[0], idx[1]); + } + break; + + case PIPE_PRIM_LINE_LOOP: + case PIPE_PRIM_LINE_STRIP: + if (count >= 2) { + flags = DRAW_PIPE_RESET_STIPPLE; + idx[1] = GET_ELT(0); + idx[2] = idx[1]; + + for (i = 1; i < count; i++, flags = 0) { + idx[0] = idx[1]; + idx[1] = GET_ELT(i); + LINE(flags, idx[0], idx[1]); + } + /* close the loop */ + if (prim == PIPE_PRIM_LINE_LOOP) + LINE(flags, idx[1], idx[2]); + } + break; + + case PIPE_PRIM_TRIANGLES: + flags = DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL; + for (i = 0; i + 2 < count; i += 3) { + idx[0] = GET_ELT(i); + idx[1] = GET_ELT(i + 1); + idx[2] = GET_ELT(i + 2); + TRIANGLE(flags, idx[0], idx[1], idx[2]); + } + break; + + case PIPE_PRIM_TRIANGLE_STRIP: + if (count >= 3) { + flags = DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL; + idx[1] = GET_ELT(0); + idx[2] = GET_ELT(1); + + if (last_vertex_last) { + for (i = 0; i + 2 < count; i++) { + idx[0] = idx[1]; + idx[1] = idx[2]; + idx[2] = GET_ELT(i + 2); + /* always emit idx[2] last */ + if (i & 1) + TRIANGLE(flags, idx[1], idx[0], idx[2]); + else + TRIANGLE(flags, idx[0], idx[1], idx[2]); + } + } + else { + for (i = 0; i + 2 < count; i++) { + idx[0] = idx[1]; + idx[1] = idx[2]; + idx[2] = GET_ELT(i + 2); + /* always emit idx[0] first */ + if (i & 1) + TRIANGLE(flags, idx[0], idx[2], idx[1]); + else + TRIANGLE(flags, idx[0], idx[1], idx[2]); + } + } + } + break; + + case PIPE_PRIM_TRIANGLE_FAN: + if (count >= 3) { + flags = DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL; + idx[0] = GET_ELT(0); + idx[2] = GET_ELT(1); + + /* idx[0] is neither the first nor the last vertex */ + if (last_vertex_last) { + for (i = 0; i + 2 < count; i++) { + idx[1] = idx[2]; + idx[2] = GET_ELT(i + 2); + /* always emit idx[2] last */ + TRIANGLE(flags, idx[0], idx[1], idx[2]); + } + } + else { + for (i = 0; i + 2 < count; i++) { + idx[1] = idx[2]; + idx[2] = GET_ELT(i + 2); + /* always emit idx[1] first */ + TRIANGLE(flags, idx[1], idx[2], idx[0]); + } + } + } + break; + + case PIPE_PRIM_QUADS: + if (last_vertex_last) { + for (i = 0; i + 3 < count; i += 4) { + idx[0] = GET_ELT(i); + idx[1] = GET_ELT(i + 1); + idx[2] = GET_ELT(i + 2); + idx[3] = GET_ELT(i + 3); + + flags = DRAW_PIPE_RESET_STIPPLE | + DRAW_PIPE_EDGE_FLAG_0 | + DRAW_PIPE_EDGE_FLAG_2; + /* always emit idx[3] last */ + TRIANGLE(flags, idx[0], idx[1], idx[3]); + + flags = DRAW_PIPE_EDGE_FLAG_0 | + DRAW_PIPE_EDGE_FLAG_1; + TRIANGLE(flags, idx[1], idx[2], idx[3]); + } + } + else { + for (i = 0; i + 3 < count; i += 4) { + idx[0] = GET_ELT(i); + idx[1] = GET_ELT(i + 1); + idx[2] = GET_ELT(i + 2); + idx[3] = GET_ELT(i + 3); + + flags = DRAW_PIPE_RESET_STIPPLE | + DRAW_PIPE_EDGE_FLAG_0 | + DRAW_PIPE_EDGE_FLAG_1; + /* XXX should always emit idx[0] first */ + /* always emit idx[3] first */ + TRIANGLE(flags, idx[3], idx[0], idx[1]); + + flags = DRAW_PIPE_EDGE_FLAG_1 | + DRAW_PIPE_EDGE_FLAG_2; + TRIANGLE(flags, idx[3], idx[1], idx[2]); + } + } + break; + + case PIPE_PRIM_QUAD_STRIP: + if (count >= 4) { + idx[2] = GET_ELT(0); + idx[3] = GET_ELT(1); + + if (last_vertex_last) { + for (i = 0; i + 3 < count; i += 2) { + idx[0] = idx[2]; + idx[1] = idx[3]; + idx[2] = GET_ELT(i + 2); + idx[3] = GET_ELT(i + 3); + + /* always emit idx[3] last */ + flags = DRAW_PIPE_RESET_STIPPLE | + DRAW_PIPE_EDGE_FLAG_0 | + DRAW_PIPE_EDGE_FLAG_2; + TRIANGLE(flags, idx[2], idx[0], idx[3]); + + flags = DRAW_PIPE_EDGE_FLAG_0 | + DRAW_PIPE_EDGE_FLAG_1; + TRIANGLE(flags, idx[0], idx[1], idx[3]); + } + } + else { + for (i = 0; i + 3 < count; i += 2) { + idx[0] = idx[2]; + idx[1] = idx[3]; + idx[2] = GET_ELT(i + 2); + idx[3] = GET_ELT(i + 3); + + flags = DRAW_PIPE_RESET_STIPPLE | + DRAW_PIPE_EDGE_FLAG_0 | + DRAW_PIPE_EDGE_FLAG_1; + /* XXX should always emit idx[0] first */ + /* always emit idx[3] first */ + TRIANGLE(flags, idx[3], idx[2], idx[0]); + + flags = DRAW_PIPE_EDGE_FLAG_1 | + DRAW_PIPE_EDGE_FLAG_2; + TRIANGLE(flags, idx[3], idx[0], idx[1]); + } + } + } + break; + + case PIPE_PRIM_POLYGON: + if (count >= 3) { + ushort edge_next, edge_finish; + + if (last_vertex_last) { + flags = (DRAW_PIPE_RESET_STIPPLE | + DRAW_PIPE_EDGE_FLAG_2 | + DRAW_PIPE_EDGE_FLAG_0); + edge_next = DRAW_PIPE_EDGE_FLAG_0; + edge_finish = DRAW_PIPE_EDGE_FLAG_1; + } + else { + flags = (DRAW_PIPE_RESET_STIPPLE | + DRAW_PIPE_EDGE_FLAG_0 | + DRAW_PIPE_EDGE_FLAG_1); + edge_next = DRAW_PIPE_EDGE_FLAG_1; + edge_finish = DRAW_PIPE_EDGE_FLAG_2; + } + + idx[0] = GET_ELT(0); + idx[2] = GET_ELT(1); + + for (i = 0; i + 2 < count; i++, flags = edge_next) { + idx[1] = idx[2]; + idx[2] = GET_ELT(i + 2); + + if (i + 3 == count) + flags |= edge_finish; + + /* idx[0] is both the first and the last vertex */ + if (last_vertex_last) + TRIANGLE(flags, idx[1], idx[2], idx[0]); + else + TRIANGLE(flags, idx[0], idx[1], idx[2]); + } + } + break; + + case PIPE_PRIM_LINES_ADJACENCY: + flags = DRAW_PIPE_RESET_STIPPLE; + for (i = 0; i + 3 < count; i += 4) { + idx[0] = GET_ELT(i); + idx[1] = GET_ELT(i + 1); + idx[2] = GET_ELT(i + 2); + idx[3] = GET_ELT(i + 3); + LINE_ADJ(flags, idx[0], idx[1], idx[2], idx[3]); + } + break; + + case PIPE_PRIM_LINE_STRIP_ADJACENCY: + if (count >= 4) { + flags = DRAW_PIPE_RESET_STIPPLE; + idx[1] = GET_ELT(0); + idx[2] = GET_ELT(1); + idx[3] = GET_ELT(2); + + for (i = 1; i + 2 < count; i++, flags = 0) { + idx[0] = idx[1]; + idx[1] = idx[2]; + idx[2] = idx[3]; + idx[3] = GET_ELT(i + 2); + LINE_ADJ(flags, idx[0], idx[1], idx[2], idx[3]); + } + } + break; + + case PIPE_PRIM_TRIANGLES_ADJACENCY: + flags = DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL; + for (i = 0; i + 5 < count; i += 6) { + idx[0] = GET_ELT(i); + idx[1] = GET_ELT(i + 1); + idx[2] = GET_ELT(i + 2); + idx[3] = GET_ELT(i + 3); + idx[4] = GET_ELT(i + 4); + idx[5] = GET_ELT(i + 5); + TRIANGLE_ADJ(flags, idx[0], idx[1], idx[2], idx[3], idx[4], idx[5]); + } + break; + + case PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY: + if (count >= 6) { + flags = DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL; + idx[0] = GET_ELT(1); + idx[2] = GET_ELT(0); + idx[4] = GET_ELT(2); + idx[3] = GET_ELT(4); + + /* + * The vertices of the i-th triangle are stored in + * idx[0,2,4] = { 2*i, 2*i+2, 2*i+4 }; + * + * The adjacent vertices are stored in + * idx[1,3,5] = { 2*i-2, 2*i+6, 2*i+3 }. + * + * However, there are two exceptions: + * + * For the first triangle, idx[1] = 1; + * For the last triangle, idx[3] = 2*i+5. + */ + if (last_vertex_last) { + for (i = 0; i + 5 < count; i += 2) { + idx[1] = idx[0]; + + idx[0] = idx[2]; + idx[2] = idx[4]; + idx[4] = idx[3]; + + idx[3] = GET_ELT(i + ((i + 7 < count) ? 6 : 5)); + idx[5] = GET_ELT(i + 3); + + /* + * alternate the first two vertices (idx[0] and idx[2]) and the + * corresponding adjacent vertices (idx[3] and idx[5]) to have + * the correct orientation + */ + if (i & 2) { + TRIANGLE_ADJ(flags, + idx[2], idx[1], idx[0], idx[5], idx[4], idx[3]); + } + else { + TRIANGLE_ADJ(flags, + idx[0], idx[1], idx[2], idx[3], idx[4], idx[5]); + } + } + } + else { + for (i = 0; i + 5 < count; i += 2) { + idx[1] = idx[0]; + + idx[0] = idx[2]; + idx[2] = idx[4]; + idx[4] = idx[3]; + + idx[3] = GET_ELT(i + ((i + 7 < count) ? 6 : 5)); + idx[5] = GET_ELT(i + 3); + + /* + * alternate the last two vertices (idx[2] and idx[4]) and the + * corresponding adjacent vertices (idx[1] and idx[5]) to have + * the correct orientation + */ + if (i & 2) { + TRIANGLE_ADJ(flags, + idx[0], idx[5], idx[4], idx[3], idx[2], idx[1]); + } + else { + TRIANGLE_ADJ(flags, + idx[0], idx[1], idx[2], idx[3], idx[4], idx[5]); + } + } + } + } + break; + + default: + assert(0); + break; + } + + FUNC_EXIT; +} + +#undef LOCAL_VARS +#undef FUNC_ENTER +#undef FUNC_EXIT +#undef LINE_ADJ +#undef TRIANGLE_ADJ + +#undef FUNC +#undef FUNC_VARS +#undef GET_ELT +#undef POINT +#undef LINE +#undef TRIANGLE diff --git a/src/gallium/auxiliary/draw/draw_gs.c b/src/gallium/auxiliary/draw/draw_gs.c index 79a57a67f3e..4a1013e79a5 100644 --- a/src/gallium/auxiliary/draw/draw_gs.c +++ b/src/gallium/auxiliary/draw/draw_gs.c @@ -1,6 +1,6 @@ /************************************************************************** * - * Copyright 2009 VMWare Inc. + * Copyright 2009 VMware, Inc. * All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a @@ -75,7 +75,10 @@ draw_gs_set_constants(struct draw_context *draw, const void *constants, unsigned size) { - /* noop */ + /* noop. added here for symmetry with the VS + * code and in case we'll ever want to allign + * the constants, e.g. when we'll change to a + * different interpreter */ } @@ -370,32 +373,23 @@ static void gs_tri_adj(struct draw_geometry_shader *shader, gs_flush(shader, 1); } -#define TRIANGLE(gs,i0,i1,i2) gs_tri(gs,i0,i1,i2) -#define TRI_ADJ(gs,i0,i1,i2,i3,i4,i5) gs_tri_adj(gs,i0,i1,i2,i3,i4,i5) -#define LINE(gs,i0,i1) gs_line(gs,i0,i1) -#define LINE_ADJ(gs,i0,i1,i2,i3) gs_line_adj(gs,i0,i1,i2,i3) -#define POINT(gs,i0) gs_point(gs,i0) -#define FUNC gs_run -#define LOCAL_VARS +#define FUNC gs_run +#define GET_ELT(idx) (idx) #include "draw_gs_tmp.h" -#define TRIANGLE(gs,i0,i1,i2) gs_tri(gs,elts[i0],elts[i1],elts[i2]) -#define TRI_ADJ(gs,i0,i1,i2,i3,i4,i5) \ - gs_tri_adj(gs,elts[i0],elts[i1],elts[i2],elts[i3], \ - elts[i4],elts[i5]) -#define LINE(gs,i0,i1) gs_line(gs,elts[i0],elts[i1]) -#define LINE_ADJ(gs,i0,i1,i2,i3) gs_line_adj(gs,elts[i0], \ - elts[i1], \ - elts[i2],elts[i3]) -#define POINT(gs,i0) gs_point(gs,elts[i0]) -#define FUNC gs_run_elts -#define LOCAL_VARS \ - const ushort *elts = input_prims->elts; +#define FUNC gs_run_elts +#define LOCAL_VARS const ushort *elts = input_prims->elts; +#define GET_ELT(idx) (elts[idx] & ~DRAW_PIPE_FLAG_MASK) #include "draw_gs_tmp.h" + +/** + * Execute geometry shader using TGSI interpreter. + */ int draw_geometry_shader_run(struct draw_geometry_shader *shader, const void *constants[PIPE_MAX_CONSTANT_BUFFERS], + const unsigned constants_size[PIPE_MAX_CONSTANT_BUFFERS], const struct draw_vertex_info *input_verts, const struct draw_prim_info *input_prim, struct draw_vertex_info *output_verts, @@ -405,7 +399,6 @@ int draw_geometry_shader_run(struct draw_geometry_shader *shader, unsigned input_stride = input_verts->vertex_size; unsigned vertex_size = input_verts->vertex_size; struct tgsi_exec_machine *machine = shader->machine; - unsigned int i; unsigned num_input_verts = input_prim->linear ? input_verts->count : input_prim->count; @@ -447,9 +440,8 @@ int draw_geometry_shader_run(struct draw_geometry_shader *shader, } shader->primitive_lengths = MALLOC(max_out_prims * sizeof(unsigned)); - for (i = 0; i < PIPE_MAX_CONSTANT_BUFFERS; i++) { - machine->Consts[i] = constants[i]; - } + tgsi_exec_set_constant_buffers(machine, PIPE_MAX_CONSTANT_BUFFERS, + constants, constants_size); if (input_prim->linear) gs_run(shader, input_prim, input_verts, diff --git a/src/gallium/auxiliary/draw/draw_gs.h b/src/gallium/auxiliary/draw/draw_gs.h index 2cb634818c2..67bc1aa73ff 100644 --- a/src/gallium/auxiliary/draw/draw_gs.h +++ b/src/gallium/auxiliary/draw/draw_gs.h @@ -1,6 +1,6 @@ /************************************************************************** * - * Copyright 2009 VMWare Inc. + * Copyright 2009 VMware, Inc. * All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a @@ -73,6 +73,7 @@ struct draw_geometry_shader { */ int draw_geometry_shader_run(struct draw_geometry_shader *shader, const void *constants[PIPE_MAX_CONSTANT_BUFFERS], + const unsigned constants_size[PIPE_MAX_CONSTANT_BUFFERS], const struct draw_vertex_info *input_verts, const struct draw_prim_info *input_prim, struct draw_vertex_info *output_verts, diff --git a/src/gallium/auxiliary/draw/draw_gs_tmp.h b/src/gallium/auxiliary/draw/draw_gs_tmp.h index 7a8683cf7c2..4a17af0dea3 100644 --- a/src/gallium/auxiliary/draw/draw_gs_tmp.h +++ b/src/gallium/auxiliary/draw/draw_gs_tmp.h @@ -1,152 +1,34 @@ - -static void FUNC( struct draw_geometry_shader *shader, - const struct draw_prim_info *input_prims, - const struct draw_vertex_info *input_verts, - struct draw_prim_info *output_prims, - struct draw_vertex_info *output_verts) -{ - struct draw_context *draw = shader->draw; - - boolean flatfirst = (draw->rasterizer->flatshade && - draw->rasterizer->flatshade_first); - unsigned i, j; - unsigned count = input_prims->count; - LOCAL_VARS - - if (0) debug_printf("%s %d\n", __FUNCTION__, count); - - debug_assert(input_prims->primitive_count == 1); - - switch (input_prims->prim) { - case PIPE_PRIM_POINTS: - for (i = 0; i < count; i++) { - POINT( shader, i + 0 ); - } - break; - - case PIPE_PRIM_LINES: - for (i = 0; i+1 < count; i += 2) { - LINE( shader , i + 0 , i + 1 ); - } - break; - - case PIPE_PRIM_LINE_LOOP: - if (count >= 2) { - - for (i = 1; i < count; i++) { - LINE( shader, i - 1, i ); - } - - LINE( shader, i - 1, 0 ); - } - break; - - case PIPE_PRIM_LINE_STRIP: - for (i = 1; i < count; i++) { - LINE( shader, i - 1, i ); - } - break; - - case PIPE_PRIM_TRIANGLES: - for (i = 0; i+2 < count; i += 3) { - TRIANGLE( shader, i + 0, i + 1, i + 2 ); - } - break; - - case PIPE_PRIM_TRIANGLE_STRIP: - if (flatfirst) { - for (i = 0; i+2 < count; i++) { - TRIANGLE( shader, - i + 0, - i + 1 + (i&1), - i + 2 - (i&1) ); - } - } - else { - for (i = 0; i+2 < count; i++) { - TRIANGLE( shader, - i + 0 + (i&1), - i + 1 - (i&1), - i + 2 ); - } - } - break; - - case PIPE_PRIM_TRIANGLE_FAN: - if (count >= 3) { - if (flatfirst) { - for (i = 0; i+2 < count; i++) { - TRIANGLE( shader, - i + 1, - i + 2, - 0 ); - } - } - else { - for (i = 0; i+2 < count; i++) { - TRIANGLE( shader, - 0, - i + 1, - i + 2 ); - } - } - } - break; - - case PIPE_PRIM_POLYGON: - { - for (i = 0; i+2 < count; i++) { - - if (flatfirst) { - TRIANGLE( shader, 0, i + 1, i + 2 ); - } - else { - TRIANGLE( shader, i + 1, i + 2, 0 ); - } - } - } - break; - - case PIPE_PRIM_LINES_ADJACENCY: - for (i = 0; i+3 < count; i += 4) { - LINE_ADJ( shader , i + 0 , i + 1, i + 2, i + 3 ); - } - break; - case PIPE_PRIM_LINE_STRIP_ADJACENCY: - for (i = 1; i + 2 < count; i++) { - LINE_ADJ( shader, i - 1, i, i + 1, i + 2 ); - } - break; - - case PIPE_PRIM_TRIANGLES_ADJACENCY: - for (i = 0; i+5 < count; i += 5) { - TRI_ADJ( shader, i + 0, i + 1, i + 2, - i + 3, i + 4, i + 5); - } - break; - case PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY: - for (i = 0, j = 0; i+5 < count; i += 2, ++j) { - TRI_ADJ( shader, - i + 0, - i + 1 + 2*(j&1), - i + 2 + 2*(j&1), - i + 3 - 2*(j&1), - i + 4 - 2*(j&1), - i + 5); - } - break; - - default: - debug_assert(!"Unsupported primitive in geometry shader"); - break; - } -} - - -#undef TRIANGLE -#undef TRI_ADJ -#undef POINT -#undef LINE -#undef LINE_ADJ -#undef FUNC -#undef LOCAL_VARS +#define FUNC_VARS struct draw_geometry_shader *gs, \ + const struct draw_prim_info *input_prims, \ + const struct draw_vertex_info *input_verts, \ + struct draw_prim_info *output_prims, \ + struct draw_vertex_info *output_verts + +#define FUNC_ENTER \ + /* declare more local vars */ \ + struct draw_context *draw = gs->draw; \ + const unsigned prim = input_prims->prim; \ + const unsigned count = input_prims->count; \ + const boolean last_vertex_last = \ + !(draw->rasterizer->flatshade && \ + draw->rasterizer->flatshade_first); \ + do { \ + debug_assert(input_prims->primitive_count == 1); \ + switch (prim) { \ + case PIPE_PRIM_QUADS: \ + case PIPE_PRIM_QUAD_STRIP: \ + case PIPE_PRIM_POLYGON: \ + debug_assert(!"unexpected primitive type in GS"); \ + return; \ + default: \ + break; \ + } \ + } while (0) \ + +#define POINT(i0) gs_point(gs,i0) +#define LINE(flags,i0,i1) gs_line(gs,i0,i1) +#define TRIANGLE(flags,i0,i1,i2) gs_tri(gs,i0,i1,i2) +#define LINE_ADJ(flags,i0,i1,i2,i3) gs_line_adj(gs,i0,i1,i2,i3) +#define TRIANGLE_ADJ(flags,i0,i1,i2,i3,i4,i5) gs_tri_adj(gs,i0,i1,i2,i3,i4,i5) + +#include "draw_decompose_tmp.h" diff --git a/src/gallium/auxiliary/draw/draw_llvm.c b/src/gallium/auxiliary/draw/draw_llvm.c index 19f96c37ab4..de99b00a814 100644 --- a/src/gallium/auxiliary/draw/draw_llvm.c +++ b/src/gallium/auxiliary/draw/draw_llvm.c @@ -37,6 +37,8 @@ #include "gallivm/lp_bld_debug.h" #include "gallivm/lp_bld_tgsi.h" #include "gallivm/lp_bld_printf.h" +#include "gallivm/lp_bld_intr.h" +#include "gallivm/lp_bld_init.h" #include "tgsi/tgsi_exec.h" #include "tgsi/tgsi_dump.h" @@ -793,6 +795,11 @@ draw_llvm_generate(struct draw_llvm *llvm, struct draw_llvm_variant *variant) sampler->destroy(sampler); +#ifdef PIPE_ARCH_X86 + /* Avoid corrupting the FPU stack on 32bit OSes. */ + lp_build_intrinsic(builder, "llvm.x86.mmx.emms", LLVMVoidType(), NULL, 0); +#endif + LLVMBuildRetVoid(builder); LLVMDisposeBuilder(builder); @@ -820,6 +827,7 @@ draw_llvm_generate(struct draw_llvm *llvm, struct draw_llvm_variant *variant) if (gallivm_debug & GALLIVM_DEBUG_ASM) { lp_disassemble(code); } + lp_func_delete_body(variant->function); } @@ -963,6 +971,11 @@ draw_llvm_generate_elts(struct draw_llvm *llvm, struct draw_llvm_variant *varian sampler->destroy(sampler); +#ifdef PIPE_ARCH_X86 + /* Avoid corrupting the FPU stack on 32bit OSes. */ + lp_build_intrinsic(builder, "llvm.x86.mmx.emms", LLVMVoidType(), NULL, 0); +#endif + LLVMBuildRetVoid(builder); LLVMDisposeBuilder(builder); @@ -990,6 +1003,7 @@ draw_llvm_generate_elts(struct draw_llvm *llvm, struct draw_llvm_variant *varian if (gallivm_debug & GALLIVM_DEBUG_ASM) { lp_disassemble(code); } + lp_func_delete_body(variant->function_elts); } void diff --git a/src/gallium/auxiliary/draw/draw_pipe.c b/src/gallium/auxiliary/draw/draw_pipe.c index 8cd75ecf9a3..070ac803c85 100644 --- a/src/gallium/auxiliary/draw/draw_pipe.c +++ b/src/gallium/auxiliary/draw/draw_pipe.c @@ -169,77 +169,40 @@ static void do_triangle( struct draw_context *draw, /* * Set up macros for draw_pt_decompose.h template code. * This code uses vertex indexes / elements. + * + * Flags are needed by the stipple and unfilled stages. When the two stages + * are active, vcache_run_extras is called and the flags are stored in the + * higher bits of i0. Otherwise, flags do not matter. */ -/* emit first quad vertex as first vertex in triangles */ -#define QUAD_FIRST_PV(i0,i1,i2,i3) \ - do_triangle( draw, \ - ( DRAW_PIPE_RESET_STIPPLE | \ - DRAW_PIPE_EDGE_FLAG_0 | \ - DRAW_PIPE_EDGE_FLAG_1 ), \ - verts + stride * (elts[i0] & ~DRAW_PIPE_FLAG_MASK), \ - verts + stride * (elts[i1] & ~DRAW_PIPE_FLAG_MASK), \ - verts + stride * (elts[i2] & ~DRAW_PIPE_FLAG_MASK)); \ - do_triangle( draw, \ - ( DRAW_PIPE_EDGE_FLAG_1 | \ - DRAW_PIPE_EDGE_FLAG_2 ), \ - verts + stride * (elts[i0] & ~DRAW_PIPE_FLAG_MASK), \ - verts + stride * (elts[i2] & ~DRAW_PIPE_FLAG_MASK), \ - verts + stride * (elts[i3] & ~DRAW_PIPE_FLAG_MASK)) - -/* emit last quad vertex as last vertex in triangles */ -#define QUAD_LAST_PV(i0,i1,i2,i3) \ - do_triangle( draw, \ - ( DRAW_PIPE_RESET_STIPPLE | \ - DRAW_PIPE_EDGE_FLAG_0 | \ - DRAW_PIPE_EDGE_FLAG_2 ), \ - verts + stride * (elts[i0] & ~DRAW_PIPE_FLAG_MASK), \ - verts + stride * (elts[i1] & ~DRAW_PIPE_FLAG_MASK), \ - verts + stride * (elts[i3] & ~DRAW_PIPE_FLAG_MASK)); \ - do_triangle( draw, \ - ( DRAW_PIPE_EDGE_FLAG_0 | \ - DRAW_PIPE_EDGE_FLAG_1 ), \ - verts + stride * (elts[i1] & ~DRAW_PIPE_FLAG_MASK), \ - verts + stride * (elts[i2] & ~DRAW_PIPE_FLAG_MASK), \ - verts + stride * (elts[i3] & ~DRAW_PIPE_FLAG_MASK)) - -#define TRIANGLE(flags,i0,i1,i2) \ - do_triangle( draw, \ - elts[i0], /* flags */ \ - verts + stride * (elts[i0] & ~DRAW_PIPE_FLAG_MASK), \ - verts + stride * (elts[i1] & ~DRAW_PIPE_FLAG_MASK), \ - verts + stride * (elts[i2] & ~DRAW_PIPE_FLAG_MASK) ); - -#define LINE(flags,i0,i1) \ - do_line( draw, \ - elts[i0], \ - verts + stride * (elts[i0] & ~DRAW_PIPE_FLAG_MASK), \ - verts + stride * (elts[i1] & ~DRAW_PIPE_FLAG_MASK) ); +#define TRIANGLE(flags,i0,i1,i2) \ + do_triangle( draw, \ + i0, /* flags */ \ + verts + stride * (i0 & ~DRAW_PIPE_FLAG_MASK), \ + verts + stride * (i1), \ + verts + stride * (i2) ) + +#define LINE(flags,i0,i1) \ + do_line( draw, \ + i0, /* flags */ \ + verts + stride * (i0 & ~DRAW_PIPE_FLAG_MASK), \ + verts + stride * (i1) ) #define POINT(i0) \ - do_point( draw, \ - verts + stride * (elts[i0] & ~DRAW_PIPE_FLAG_MASK) ) + do_point( draw, verts + stride * (i0) ) -#define FUNC pipe_run -#define ARGS \ +#define GET_ELT(idx) (elts[idx]) + +#define FUNC pipe_run_elts +#define FUNC_VARS \ struct draw_context *draw, \ unsigned prim, \ struct vertex_header *vertices, \ unsigned stride, \ - const ushort *elts - -#define LOCAL_VARS \ - char *verts = (char *)vertices; \ - boolean flatfirst = (draw->rasterizer->flatshade && \ - draw->rasterizer->flatshade_first); \ - unsigned i; \ - ushort flags - -#define FLUSH + const ushort *elts, \ + unsigned count #include "draw_pt_decompose.h" -#undef ARGS -#undef LOCAL_VARS @@ -269,14 +232,29 @@ void draw_pipeline_run( struct draw_context *draw, i < prim_info->primitive_count; start += prim_info->primitive_lengths[i], i++) { - unsigned count = prim_info->primitive_lengths[i]; - - pipe_run(draw, - prim_info->prim, - vert_info->verts, - vert_info->stride, - prim_info->elts + start, - count); + const unsigned count = prim_info->primitive_lengths[i]; + +#if DEBUG + /* make sure none of the element indexes go outside the vertex buffer */ + { + unsigned max_index = 0x0, i; + /* find the largest element index */ + for (i = 0; i < count; i++) { + unsigned int index = (prim_info->elts[start + i] + & ~DRAW_PIPE_FLAG_MASK); + if (index > max_index) + max_index = index; + } + assert(max_index <= vert_info->count); + } +#endif + + pipe_run_elts(draw, + prim_info->prim, + vert_info->verts, + vert_info->stride, + prim_info->elts + start, + count); } draw->pipeline.verts = NULL; @@ -289,70 +267,30 @@ void draw_pipeline_run( struct draw_context *draw, * This code is for non-indexed (aka linear) rendering (no elts). */ -/* emit first quad vertex as first vertex in triangles */ -#define QUAD_FIRST_PV(i0,i1,i2,i3) \ - do_triangle( draw, \ - ( DRAW_PIPE_RESET_STIPPLE | \ - DRAW_PIPE_EDGE_FLAG_0 | \ - DRAW_PIPE_EDGE_FLAG_1 ), \ - verts + stride * ((i0) & ~DRAW_PIPE_FLAG_MASK), \ - verts + stride * ((i1) & ~DRAW_PIPE_FLAG_MASK), \ - verts + stride * ((i2) & ~DRAW_PIPE_FLAG_MASK)); \ - do_triangle( draw, \ - ( DRAW_PIPE_EDGE_FLAG_1 | \ - DRAW_PIPE_EDGE_FLAG_2 ), \ - verts + stride * ((i0) & ~DRAW_PIPE_FLAG_MASK), \ - verts + stride * ((i2) & ~DRAW_PIPE_FLAG_MASK), \ - verts + stride * ((i3) & ~DRAW_PIPE_FLAG_MASK)) - -/* emit last quad vertex as last vertex in triangles */ -#define QUAD_LAST_PV(i0,i1,i2,i3) \ - do_triangle( draw, \ - ( DRAW_PIPE_RESET_STIPPLE | \ - DRAW_PIPE_EDGE_FLAG_0 | \ - DRAW_PIPE_EDGE_FLAG_2 ), \ - verts + stride * ((i0) & ~DRAW_PIPE_FLAG_MASK), \ - verts + stride * ((i1) & ~DRAW_PIPE_FLAG_MASK), \ - verts + stride * ((i3) & ~DRAW_PIPE_FLAG_MASK)); \ - do_triangle( draw, \ - ( DRAW_PIPE_EDGE_FLAG_0 | \ - DRAW_PIPE_EDGE_FLAG_1 ), \ - verts + stride * ((i1) & ~DRAW_PIPE_FLAG_MASK), \ - verts + stride * ((i2) & ~DRAW_PIPE_FLAG_MASK), \ - verts + stride * ((i3) & ~DRAW_PIPE_FLAG_MASK)) - -#define TRIANGLE(flags,i0,i1,i2) \ - do_triangle( draw, \ - flags, /* flags */ \ - verts + stride * ((i0) & ~DRAW_PIPE_FLAG_MASK), \ - verts + stride * ((i1) & ~DRAW_PIPE_FLAG_MASK), \ - verts + stride * ((i2) & ~DRAW_PIPE_FLAG_MASK)) - -#define LINE(flags,i0,i1) \ - do_line( draw, \ - flags, \ - verts + stride * ((i0) & ~DRAW_PIPE_FLAG_MASK), \ - verts + stride * ((i1) & ~DRAW_PIPE_FLAG_MASK)) +#define TRIANGLE(flags,i0,i1,i2) \ + do_triangle( draw, flags, \ + verts + stride * (i0), \ + verts + stride * (i1), \ + verts + stride * (i2) ) -#define POINT(i0) \ - do_point( draw, \ - verts + stride * ((i0) & ~DRAW_PIPE_FLAG_MASK) ) +#define LINE(flags,i0,i1) \ + do_line( draw, flags, \ + verts + stride * (i0), \ + verts + stride * (i1) ) -#define FUNC pipe_run_linear -#define ARGS \ - struct draw_context *draw, \ - unsigned prim, \ - struct vertex_header *vertices, \ - unsigned stride +#define POINT(i0) \ + do_point( draw, verts + stride * (i0) ) -#define LOCAL_VARS \ - char *verts = (char *)vertices; \ - boolean flatfirst = (draw->rasterizer->flatshade && \ - draw->rasterizer->flatshade_first); \ - unsigned i; \ - ushort flags -#define FLUSH +#define GET_ELT(idx) (idx) + +#define FUNC pipe_run_linear +#define FUNC_VARS \ + struct draw_context *draw, \ + unsigned prim, \ + struct vertex_header *vertices, \ + unsigned stride, \ + unsigned count #include "draw_pt_decompose.h" @@ -378,6 +316,8 @@ void draw_pipeline_run_linear( struct draw_context *draw, draw->pipeline.vertex_stride = vert_info->stride; draw->pipeline.vertex_count = count; + assert(count <= vert_info->count); + pipe_run_linear(draw, prim_info->prim, (struct vertex_header*)verts, diff --git a/src/gallium/auxiliary/draw/draw_pipe_clip.c b/src/gallium/auxiliary/draw/draw_pipe_clip.c index 1cf6ee7a7f9..8a3d499febb 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_clip.c +++ b/src/gallium/auxiliary/draw/draw_pipe_clip.c @@ -68,8 +68,7 @@ struct clip_stage { }; -/* This is a bit confusing: - */ +/** Cast wrapper */ static INLINE struct clip_stage *clip_stage( struct draw_stage *stage ) { return (struct clip_stage *)stage; @@ -81,18 +80,22 @@ static INLINE struct clip_stage *clip_stage( struct draw_stage *stage ) /* All attributes are float[4], so this is easy: */ -static void interp_attr( float *fdst, +static void interp_attr( float dst[4], float t, - const float *fin, - const float *fout ) + const float in[4], + const float out[4] ) { - fdst[0] = LINTERP( t, fout[0], fin[0] ); - fdst[1] = LINTERP( t, fout[1], fin[1] ); - fdst[2] = LINTERP( t, fout[2], fin[2] ); - fdst[3] = LINTERP( t, fout[3], fin[3] ); + dst[0] = LINTERP( t, out[0], in[0] ); + dst[1] = LINTERP( t, out[1], in[1] ); + dst[2] = LINTERP( t, out[2], in[2] ); + dst[3] = LINTERP( t, out[3], in[3] ); } +/** + * Copy front/back, primary/secondary colors from src vertex to dst vertex. + * Used when flat shading. + */ static void copy_colors( struct draw_stage *stage, struct vertex_header *dst, const struct vertex_header *src ) @@ -121,20 +124,17 @@ static void interp( const struct clip_stage *clip, /* Vertex header. */ - { - dst->clipmask = 0; - dst->edgeflag = 0; /* will get overwritten later */ - dst->pad = 0; - dst->vertex_id = UNDEFINED_VERTEX_ID; - } + dst->clipmask = 0; + dst->edgeflag = 0; /* will get overwritten later */ + dst->pad = 0; + dst->vertex_id = UNDEFINED_VERTEX_ID; - /* Clip coordinates: interpolate normally + /* Interpolate the clip-space coords. */ - { - interp_attr(dst->clip, t, in->clip, out->clip); - } + interp_attr(dst->clip, t, in->clip, out->clip); - /* Do the projective divide and insert window coordinates: + /* Do the projective divide and viewport transformation to get + * new window coordinates: */ { const float *pos = dst->clip; diff --git a/src/gallium/auxiliary/draw/draw_private.h b/src/gallium/auxiliary/draw/draw_private.h index 058aeedc17a..397d4bf653c 100644 --- a/src/gallium/auxiliary/draw/draw_private.h +++ b/src/gallium/auxiliary/draw/draw_private.h @@ -163,9 +163,11 @@ struct draw_context /** vertex arrays */ const void *vbuffer[PIPE_MAX_ATTRIBS]; - /** constant buffer (for vertex/geometry shader) */ + /** constant buffers (for vertex/geometry shader) */ const void *vs_constants[PIPE_MAX_CONSTANT_BUFFERS]; + unsigned vs_constants_size[PIPE_MAX_CONSTANT_BUFFERS]; const void *gs_constants[PIPE_MAX_CONSTANT_BUFFERS]; + unsigned gs_constants_size[PIPE_MAX_CONSTANT_BUFFERS]; } user; boolean test_fse; /* enable FSE even though its not correct (eg for softpipe) */ @@ -198,6 +200,7 @@ struct draw_context struct pipe_viewport_state viewport; boolean identity_viewport; + /** Vertex shader state */ struct { struct draw_vertex_shader *vertex_shader; uint num_vs_outputs; /**< convenience, from vertex_shader */ @@ -227,6 +230,7 @@ struct draw_context struct translate_cache *emit_cache; } vs; + /** Geometry shader state */ struct { struct draw_geometry_shader *geometry_shader; uint num_gs_outputs; /**< convenience, from geometry_shader */ @@ -239,6 +243,7 @@ struct draw_context struct tgsi_sampler **samplers; } gs; + /** Stream output (vertex feedback) state */ struct { struct pipe_stream_output_state state; void *buffers[PIPE_MAX_SO_BUFFERS]; diff --git a/src/gallium/auxiliary/draw/draw_pt.c b/src/gallium/auxiliary/draw/draw_pt.c index 92d4113b4c6..248927505da 100644 --- a/src/gallium/auxiliary/draw/draw_pt.c +++ b/src/gallium/auxiliary/draw/draw_pt.c @@ -259,6 +259,12 @@ draw_print_arrays(struct draw_context *draw, uint prim, int start, uint count) for (j = 0; j < draw->pt.nr_vertex_elements; j++) { uint buf = draw->pt.vertex_element[j].vertex_buffer_index; ubyte *ptr = (ubyte *) draw->pt.user.vbuffer[buf]; + + if (draw->pt.vertex_element[j].instance_divisor) { + ii = draw->instance_id / draw->pt.vertex_element[j].instance_divisor; + } + + ptr += draw->pt.vertex_buffer[buf].buffer_offset; ptr += draw->pt.vertex_buffer[buf].stride * ii; ptr += draw->pt.vertex_element[j].src_offset; @@ -341,19 +347,22 @@ draw_arrays_instanced(struct draw_context *draw, unsigned reduced_prim = u_reduced_prim(mode); unsigned instance; + assert(instanceCount > 0); + if (reduced_prim != draw->reduced_prim) { draw_do_flush(draw, DRAW_FLUSH_STATE_CHANGE); draw->reduced_prim = reduced_prim; } if (0) - draw_print_arrays(draw, mode, start, MIN2(count, 20)); - - if (0) { - unsigned int i; debug_printf("draw_arrays(mode=%u start=%u count=%u):\n", mode, start, count); + + if (0) tgsi_dump(draw->vs.vertex_shader->state.tokens, 0); + + if (0) { + unsigned int i; debug_printf("Elements:\n"); for (i = 0; i < draw->pt.nr_vertex_elements; i++) { debug_printf(" %u: src_offset=%u inst_div=%u vbuf=%u format=%s\n", @@ -374,6 +383,9 @@ draw_arrays_instanced(struct draw_context *draw, } } + if (0) + draw_print_arrays(draw, mode, start, MIN2(count, 20)); + for (instance = 0; instance < instanceCount; instance++) { draw->instance_id = instance + startInstance; draw_pt_arrays(draw, mode, start, count); diff --git a/src/gallium/auxiliary/draw/draw_pt_decompose.h b/src/gallium/auxiliary/draw/draw_pt_decompose.h index 52f9593d46e..3127aad7310 100644 --- a/src/gallium/auxiliary/draw/draw_pt_decompose.h +++ b/src/gallium/auxiliary/draw/draw_pt_decompose.h @@ -1,194 +1,7 @@ +#define LOCAL_VARS \ + char *verts = (char *) vertices; \ + const boolean last_vertex_last = \ + !(draw->rasterizer->flatshade && \ + draw->rasterizer->flatshade_first); - -static void FUNC( ARGS, - unsigned count ) -{ - LOCAL_VARS; - - switch (prim) { - case PIPE_PRIM_POINTS: - for (i = 0; i < count; i ++) { - POINT( (i + 0) ); - } - break; - - case PIPE_PRIM_LINES: - for (i = 0; i+1 < count; i += 2) { - LINE( DRAW_PIPE_RESET_STIPPLE, - (i + 0), - (i + 1)); - } - break; - - case PIPE_PRIM_LINE_LOOP: - if (count >= 2) { - flags = DRAW_PIPE_RESET_STIPPLE; - - for (i = 1; i < count; i++, flags = 0) { - LINE( flags, - (i - 1), - (i )); - } - - LINE( flags, - (i - 1), - (0 )); - } - break; - - case PIPE_PRIM_LINE_STRIP: - flags = DRAW_PIPE_RESET_STIPPLE; - for (i = 1; i < count; i++, flags = 0) { - LINE( flags, - (i - 1), - (i )); - } - break; - - case PIPE_PRIM_TRIANGLES: - for (i = 0; i+2 < count; i += 3) { - TRIANGLE( DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL, - (i + 0), - (i + 1), - (i + 2 )); - } - break; - - case PIPE_PRIM_TRIANGLE_STRIP: - if (flatfirst) { - for (i = 0; i+2 < count; i++) { - /* Emit first triangle vertex as first triangle vertex */ - TRIANGLE( DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL, - (i + 0), - (i + 1 + (i&1)), - (i + 2 - (i&1)) ); - } - } - else { - for (i = 0; i+2 < count; i++) { - /* Emit last triangle vertex as last triangle vertex */ - TRIANGLE( DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL, - (i + 0 + (i&1)), - (i + 1 - (i&1)), - (i + 2 )); - } - } - break; - - case PIPE_PRIM_TRIANGLE_FAN: - if (count >= 3) { - if (flatfirst) { - for (i = 0; i+2 < count; i++) { - TRIANGLE( DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL, - (i + 1), - (i + 2), - 0 ); - } - } - else { - for (i = 0; i+2 < count; i++) { - TRIANGLE( DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL, - (0), - (i + 1), - (i + 2 )); - } - } - } - break; - - - case PIPE_PRIM_QUADS: - /* GL quads don't follow provoking vertex convention */ - if (flatfirst) { - for (i = 0; i+3 < count; i += 4) { - /* emit last quad vertex as first triangle vertex */ - QUAD_FIRST_PV( (i + 3), - (i + 0), - (i + 1), - (i + 2) ); - } - } - else { - for (i = 0; i+3 < count; i += 4) { - /* emit last quad vertex as last triangle vertex */ - QUAD_LAST_PV( (i + 0), - (i + 1), - (i + 2), - (i + 3) ); - } - } - break; - - case PIPE_PRIM_QUAD_STRIP: - /* GL quad strips don't follow provoking vertex convention */ - if (flatfirst) { - for (i = 0; i+3 < count; i += 2) { - /* emit last quad vertex as first triangle vertex */ - QUAD_FIRST_PV( (i + 3), - (i + 2), - (i + 0), - (i + 1) ); - - } - } - else { - for (i = 0; i+3 < count; i += 2) { - /* emit last quad vertex as last triangle vertex */ - QUAD_LAST_PV( (i + 2), - (i + 0), - (i + 1), - (i + 3) ); - } - } - break; - - case PIPE_PRIM_POLYGON: - /* GL polygons don't follow provoking vertex convention */ - { - /* These bitflags look a little odd because we submit the - * vertices as (1,2,0) to satisfy flatshade requirements. - */ - const ushort edge_first = DRAW_PIPE_EDGE_FLAG_2; - const ushort edge_middle = DRAW_PIPE_EDGE_FLAG_0; - const ushort edge_last = DRAW_PIPE_EDGE_FLAG_1; - - flags = DRAW_PIPE_RESET_STIPPLE | edge_first | edge_middle; - - for (i = 0; i+2 < count; i++, flags = edge_middle) { - - if (i + 3 == count) - flags |= edge_last; - - if (flatfirst) { - /* emit first polygon vertex as first triangle vertex */ - TRIANGLE( flags, - (0), - (i + 1), - (i + 2) ); - } - else { - /* emit first polygon vertex as last triangle vertex */ - TRIANGLE( flags, - (i + 1), - (i + 2), - (0)); - } - } - } - break; - - default: - assert(0); - break; - } - - FLUSH; -} - - -#undef TRIANGLE -#undef QUAD_FIRST_PV -#undef QUAD_LAST_PV -#undef POINT -#undef LINE -#undef FUNC +#include "draw_decompose_tmp.h" diff --git a/src/gallium/auxiliary/draw/draw_pt_emit.c b/src/gallium/auxiliary/draw/draw_pt_emit.c index 0229bcc7fe1..5568fbb9f88 100644 --- a/src/gallium/auxiliary/draw/draw_pt_emit.c +++ b/src/gallium/auxiliary/draw/draw_pt_emit.c @@ -182,6 +182,7 @@ void draw_pt_emit( struct pt_emit *emit, 0, ~0); + /* fetch/translate vertex attribs to fill hw_verts[] */ translate->run( translate, 0, vertex_count, diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c index 121dfc414a4..5b16c3788e5 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c @@ -176,6 +176,7 @@ static void emit(struct pt_emit *emit, static void draw_vertex_shader_run(struct draw_vertex_shader *vshader, const void *constants[PIPE_MAX_CONSTANT_BUFFERS], + unsigned const_size[PIPE_MAX_CONSTANT_BUFFERS], const struct draw_vertex_info *input_verts, struct draw_vertex_info *output_verts ) { @@ -190,6 +191,7 @@ static void draw_vertex_shader_run(struct draw_vertex_shader *vshader, (const float (*)[4])input_verts->verts->data, ( float (*)[4])output_verts->verts->data, constants, + const_size, input_verts->count, input_verts->vertex_size, input_verts->vertex_size); @@ -236,6 +238,7 @@ static void fetch_pipeline_generic( struct draw_pt_middle_end *middle, if (fpme->opt & PT_SHADE) { draw_vertex_shader_run(vshader, draw->pt.user.vs_constants, + draw->pt.user.vs_constants_size, vert_info, &vs_vert_info); @@ -246,6 +249,7 @@ static void fetch_pipeline_generic( struct draw_pt_middle_end *middle, if ((fpme->opt & PT_SHADE) && gshader) { draw_geometry_shader_run(gshader, draw->pt.user.gs_constants, + draw->pt.user.gs_constants_size, vert_info, prim_info, &gs_vert_info, diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c index bc074df8c2a..4b99bee86a0 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c @@ -1,6 +1,6 @@ /************************************************************************** * - * Copyright 2010 VMWare, Inc. + * Copyright 2010 VMware, Inc. * All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a @@ -254,6 +254,7 @@ llvm_pipeline_generic( struct draw_pt_middle_end *middle, if ((opt & PT_SHADE) && gshader) { draw_geometry_shader_run(gshader, draw->pt.user.gs_constants, + draw->pt.user.gs_constants_size, vert_info, prim_info, &gs_vert_info, diff --git a/src/gallium/auxiliary/draw/draw_pt_so_emit.c b/src/gallium/auxiliary/draw/draw_pt_so_emit.c index 5d82934889b..f7f4f24d354 100644 --- a/src/gallium/auxiliary/draw/draw_pt_so_emit.c +++ b/src/gallium/auxiliary/draw/draw_pt_so_emit.c @@ -218,25 +218,15 @@ static void so_tri(struct pt_so_emit *so, int i0, int i1, int i2) } -#define TRIANGLE(gs,i0,i1,i2) so_tri(so,i0,i1,i2) -#define LINE(gs,i0,i1) so_line(so,i0,i1) -#define POINT(gs,i0) so_point(so,i0) -#define FUNC so_run_linear -#define LOCAL_VARS +#define FUNC so_run_linear +#define GET_ELT(idx) (start + (idx)) #include "draw_so_emit_tmp.h" -#undef LOCAL_VARS -#undef FUNC -#define TRIANGLE(gs,i0,i1,i2) so_tri(gs,elts[i0],elts[i1],elts[i2]) -#define LINE(gs,i0,i1) so_line(gs,elts[i0],elts[i1]) -#define POINT(gs,i0) so_point(gs,elts[i0]) -#define FUNC so_run_elts -#define LOCAL_VARS \ - const ushort *elts = input_prims->elts; +#define FUNC so_run_elts +#define LOCAL_VARS const ushort *elts = input_prims->elts; +#define GET_ELT(idx) (elts[start + (idx)] & ~DRAW_PIPE_FLAG_MASK) #include "draw_so_emit_tmp.h" -#undef LOCAL_VARS -#undef FUNC void draw_pt_so_emit( struct pt_so_emit *emit, diff --git a/src/gallium/auxiliary/draw/draw_pt_vcache.c b/src/gallium/auxiliary/draw/draw_pt_vcache.c index 8ef94c3163c..a848b54f7d2 100644 --- a/src/gallium/auxiliary/draw/draw_pt_vcache.c +++ b/src/gallium/auxiliary/draw/draw_pt_vcache.c @@ -95,7 +95,7 @@ static INLINE void vcache_check_flush( struct vcache_frontend *vcache ) { if (vcache->draw_count + 6 >= DRAW_MAX || - vcache->fetch_count + 4 >= FETCH_MAX) { + vcache->fetch_count + 6 >= FETCH_MAX) { vcache_flush( vcache ); } } @@ -180,59 +180,61 @@ vcache_point( struct vcache_frontend *vcache, } -static INLINE void -vcache_quad( struct vcache_frontend *vcache, - unsigned i0, - unsigned i1, - unsigned i2, - unsigned i3 ) +static INLINE void +vcache_line_adj_flags( struct vcache_frontend *vcache, + unsigned flags, + unsigned a0, unsigned i0, unsigned i1, unsigned a1 ) { - if (vcache->draw->rasterizer->flatshade_first) { - /* pass last quad vertex as first triangle vertex */ - vcache_triangle( vcache, i3, i0, i1 ); - vcache_triangle( vcache, i3, i1, i2 ); - } - else { - /* pass last quad vertex as last triangle vertex */ - vcache_triangle( vcache, i0, i1, i3 ); - vcache_triangle( vcache, i1, i2, i3 ); - } + vcache_elt(vcache, a0, 0); + vcache_elt(vcache, i0, flags); + vcache_elt(vcache, i1, 0); + vcache_elt(vcache, a1, 0); + vcache_check_flush(vcache); } -static INLINE void -vcache_ef_quad( struct vcache_frontend *vcache, - unsigned i0, - unsigned i1, - unsigned i2, - unsigned i3 ) +static INLINE void +vcache_line_adj( struct vcache_frontend *vcache, + unsigned a0, unsigned i0, unsigned i1, unsigned a1 ) { - if (vcache->draw->rasterizer->flatshade_first) { - /* pass last quad vertex as first triangle vertex */ - vcache_triangle_flags( vcache, - ( DRAW_PIPE_RESET_STIPPLE | - DRAW_PIPE_EDGE_FLAG_0 | - DRAW_PIPE_EDGE_FLAG_1 ), - i3, i0, i1 ); - - vcache_triangle_flags( vcache, - ( DRAW_PIPE_EDGE_FLAG_1 | - DRAW_PIPE_EDGE_FLAG_2 ), - i3, i1, i2 ); - } - else { - /* pass last quad vertex as last triangle vertex */ - vcache_triangle_flags( vcache, - ( DRAW_PIPE_RESET_STIPPLE | - DRAW_PIPE_EDGE_FLAG_0 | - DRAW_PIPE_EDGE_FLAG_2 ), - i0, i1, i3 ); - - vcache_triangle_flags( vcache, - ( DRAW_PIPE_EDGE_FLAG_0 | - DRAW_PIPE_EDGE_FLAG_1 ), - i1, i2, i3 ); - } + vcache_elt(vcache, a0, 0); + vcache_elt(vcache, i0, 0); + vcache_elt(vcache, i1, 0); + vcache_elt(vcache, a1, 0); + vcache_check_flush(vcache); +} + + +static INLINE void +vcache_triangle_adj_flags( struct vcache_frontend *vcache, + unsigned flags, + unsigned i0, unsigned a0, + unsigned i1, unsigned a1, + unsigned i2, unsigned a2 ) +{ + vcache_elt(vcache, i0, flags); + vcache_elt(vcache, a0, 0); + vcache_elt(vcache, i1, 0); + vcache_elt(vcache, a1, 0); + vcache_elt(vcache, i2, 0); + vcache_elt(vcache, a2, 0); + vcache_check_flush(vcache); +} + + +static INLINE void +vcache_triangle_adj( struct vcache_frontend *vcache, + unsigned i0, unsigned a0, + unsigned i1, unsigned a1, + unsigned i2, unsigned a2 ) +{ + vcache_elt(vcache, i0, 0); + vcache_elt(vcache, a0, 0); + vcache_elt(vcache, i1, 0); + vcache_elt(vcache, a1, 0); + vcache_elt(vcache, i2, 0); + vcache_elt(vcache, a2, 0); + vcache_check_flush(vcache); } @@ -240,17 +242,23 @@ vcache_ef_quad( struct vcache_frontend *vcache, * this. The two paths aren't too different though - it may be * possible to reunify them. */ -#define TRIANGLE(vc,flags,i0,i1,i2) vcache_triangle_flags(vc,flags,i0,i1,i2) -#define QUAD(vc,i0,i1,i2,i3) vcache_ef_quad(vc,i0,i1,i2,i3) -#define LINE(vc,flags,i0,i1) vcache_line_flags(vc,flags,i0,i1) -#define POINT(vc,i0) vcache_point(vc,i0) +#define TRIANGLE(flags,i0,i1,i2) vcache_triangle_flags(vcache,flags,i0,i1,i2) +#define LINE(flags,i0,i1) vcache_line_flags(vcache,flags,i0,i1) +#define POINT(i0) vcache_point(vcache,i0) +#define LINE_ADJ(flags,a0,i0,i1,a1) \ + vcache_line_adj_flags(vcache,flags,a0,i0,i1,a1) +#define TRIANGLE_ADJ(flags,i0,a0,i1,a1,i2,a2) \ + vcache_triangle_adj_flags(vcache,flags,i0,a0,i1,a1,i2,a2) #define FUNC vcache_run_extras #include "draw_pt_vcache_tmp.h" -#define TRIANGLE(vc,flags,i0,i1,i2) vcache_triangle(vc,i0,i1,i2) -#define QUAD(vc,i0,i1,i2,i3) vcache_quad(vc,i0,i1,i2,i3) -#define LINE(vc,flags,i0,i1) vcache_line(vc,i0,i1) -#define POINT(vc,i0) vcache_point(vc,i0) +#define TRIANGLE(flags,i0,i1,i2) vcache_triangle(vcache,i0,i1,i2) +#define LINE(flags,i0,i1) vcache_line(vcache,i0,i1) +#define POINT(i0) vcache_point(vcache,i0) +#define LINE_ADJ(flags,a0,i0,i1,a1) \ + vcache_line_adj(vcache,a0,i0,i1,a1) +#define TRIANGLE_ADJ(flags,i0,a0,i1,a1,i2,a2) \ + vcache_triangle_adj(vcache,i0,a0,i1,a1,i2,a2) #define FUNC vcache_run #include "draw_pt_vcache_tmp.h" @@ -339,6 +347,25 @@ format_from_get_elt( pt_elt_func get_elt ) #endif +/** + * Check if any vertex attributes use instance divisors. + * Note that instance divisors complicate vertex fetching so we need + * to take the vcache path when they're in use. + */ +static boolean +any_instance_divisors(const struct draw_context *draw) +{ + uint i; + + for (i = 0; i < draw->pt.nr_vertex_elements; i++) { + uint div = draw->pt.vertex_element[i].instance_divisor; + if (div) + return TRUE; + } + return FALSE; +} + + static INLINE void vcache_check_run( struct draw_pt_front_end *frontend, pt_elt_func get_elt, @@ -382,6 +409,9 @@ vcache_check_run( struct draw_pt_front_end *frontend, if (max_index >= (unsigned) DRAW_PIPE_MAX_VERTICES) goto fail; + if (any_instance_divisors(draw)) + goto fail; + fetch_count = max_index + 1 - min_index; if (0) @@ -518,7 +548,18 @@ vcache_prepare( struct draw_pt_front_end *frontend, * which is a separate issue. */ vcache->input_prim = in_prim; - vcache->output_prim = u_reduced_prim(in_prim); + switch (in_prim) { + case PIPE_PRIM_LINES_ADJACENCY: + case PIPE_PRIM_LINE_STRIP_ADJACENCY: + vcache->output_prim = PIPE_PRIM_LINES_ADJACENCY; + break; + case PIPE_PRIM_TRIANGLES_ADJACENCY: + case PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY: + vcache->output_prim = PIPE_PRIM_TRIANGLES_ADJACENCY; + break; + default: + vcache->output_prim = u_reduced_prim(in_prim); + } vcache->middle = middle; vcache->opt = opt; diff --git a/src/gallium/auxiliary/draw/draw_pt_vcache_tmp.h b/src/gallium/auxiliary/draw/draw_pt_vcache_tmp.h index dac68ad4398..1a3748d5f0b 100644 --- a/src/gallium/auxiliary/draw/draw_pt_vcache_tmp.h +++ b/src/gallium/auxiliary/draw/draw_pt_vcache_tmp.h @@ -1,198 +1,19 @@ +#define FUNC_VARS \ + struct draw_pt_front_end *frontend, \ + pt_elt_func get_elt, \ + const void *elts, \ + int elt_bias, \ + unsigned count +#define LOCAL_VARS \ + struct vcache_frontend *vcache = (struct vcache_frontend *) frontend; \ + struct draw_context *draw = vcache->draw; \ + const unsigned prim = vcache->input_prim; \ + const boolean last_vertex_last = !(draw->rasterizer->flatshade && \ + draw->rasterizer->flatshade_first); -static void FUNC( struct draw_pt_front_end *frontend, - pt_elt_func get_elt, - const void *elts, - int elt_bias, - unsigned count ) -{ - struct vcache_frontend *vcache = (struct vcache_frontend *)frontend; - struct draw_context *draw = vcache->draw; +#define GET_ELT(idx) (get_elt(elts, idx) + elt_bias) - boolean flatfirst = (draw->rasterizer->flatshade && - draw->rasterizer->flatshade_first); - unsigned i; - ushort flags; +#define FUNC_EXIT do { vcache_flush(vcache); } while (0) - if (0) debug_printf("%s %d\n", __FUNCTION__, count); - - - switch (vcache->input_prim) { - case PIPE_PRIM_POINTS: - for (i = 0; i < count; i ++) { - POINT( vcache, - get_elt(elts, i + 0) + elt_bias ); - } - break; - - case PIPE_PRIM_LINES: - for (i = 0; i+1 < count; i += 2) { - LINE( vcache, - DRAW_PIPE_RESET_STIPPLE, - get_elt(elts, i + 0) + elt_bias, - get_elt(elts, i + 1) + elt_bias); - } - break; - - case PIPE_PRIM_LINE_LOOP: - if (count >= 2) { - flags = DRAW_PIPE_RESET_STIPPLE; - - for (i = 1; i < count; i++, flags = 0) { - LINE( vcache, - flags, - get_elt(elts, i - 1) + elt_bias, - get_elt(elts, i ) + elt_bias); - } - - LINE( vcache, - flags, - get_elt(elts, i - 1) + elt_bias, - get_elt(elts, 0 ) + elt_bias); - } - break; - - case PIPE_PRIM_LINE_STRIP: - flags = DRAW_PIPE_RESET_STIPPLE; - for (i = 1; i < count; i++, flags = 0) { - LINE( vcache, - flags, - get_elt(elts, i - 1) + elt_bias, - get_elt(elts, i ) + elt_bias); - } - break; - - case PIPE_PRIM_TRIANGLES: - for (i = 0; i+2 < count; i += 3) { - TRIANGLE( vcache, - DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL, - get_elt(elts, i + 0) + elt_bias, - get_elt(elts, i + 1) + elt_bias, - get_elt(elts, i + 2 ) + elt_bias); - } - break; - - case PIPE_PRIM_TRIANGLE_STRIP: - if (flatfirst) { - for (i = 0; i+2 < count; i++) { - TRIANGLE( vcache, - DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL, - get_elt(elts, i + 0) + elt_bias, - get_elt(elts, i + 1 + (i&1)) + elt_bias, - get_elt(elts, i + 2 - (i&1)) + elt_bias); - } - } - else { - for (i = 0; i+2 < count; i++) { - TRIANGLE( vcache, - DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL, - get_elt(elts, i + 0 + (i&1)) + elt_bias, - get_elt(elts, i + 1 - (i&1)) + elt_bias, - get_elt(elts, i + 2 ) + elt_bias); - } - } - break; - - case PIPE_PRIM_TRIANGLE_FAN: - if (count >= 3) { - if (flatfirst) { - for (i = 0; i+2 < count; i++) { - TRIANGLE( vcache, - DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL, - get_elt(elts, i + 1) + elt_bias, - get_elt(elts, i + 2) + elt_bias, - get_elt(elts, 0 ) + elt_bias); - } - } - else { - for (i = 0; i+2 < count; i++) { - TRIANGLE( vcache, - DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL, - get_elt(elts, 0) + elt_bias, - get_elt(elts, i + 1) + elt_bias, - get_elt(elts, i + 2 ) + elt_bias); - } - } - } - break; - - - case PIPE_PRIM_QUADS: - for (i = 0; i+3 < count; i += 4) { - QUAD( vcache, - get_elt(elts, i + 0) + elt_bias, - get_elt(elts, i + 1) + elt_bias, - get_elt(elts, i + 2) + elt_bias, - get_elt(elts, i + 3) + elt_bias ); - } - break; - - case PIPE_PRIM_QUAD_STRIP: - for (i = 0; i+3 < count; i += 2) { - QUAD( vcache, - get_elt(elts, i + 2) + elt_bias, - get_elt(elts, i + 0) + elt_bias, - get_elt(elts, i + 1) + elt_bias, - get_elt(elts, i + 3) + elt_bias ); - } - break; - - case PIPE_PRIM_POLYGON: - { - /* These bitflags look a little odd because we submit the - * vertices as (1,2,0) to satisfy flatshade requirements. - */ - ushort edge_next, edge_finish; - - if (flatfirst) { - flags = (DRAW_PIPE_RESET_STIPPLE | - DRAW_PIPE_EDGE_FLAG_1 | - DRAW_PIPE_EDGE_FLAG_2); - edge_next = DRAW_PIPE_EDGE_FLAG_2; - edge_finish = DRAW_PIPE_EDGE_FLAG_0; - } - else { - flags = (DRAW_PIPE_RESET_STIPPLE | - DRAW_PIPE_EDGE_FLAG_2 | - DRAW_PIPE_EDGE_FLAG_0); - edge_next = DRAW_PIPE_EDGE_FLAG_0; - edge_finish = DRAW_PIPE_EDGE_FLAG_1; - } - - for (i = 0; i+2 < count; i++, flags = edge_next) { - - if (i + 3 == count) - flags |= edge_finish; - - if (flatfirst) { - TRIANGLE( vcache, - flags, - get_elt(elts, 0) + elt_bias, - get_elt(elts, i + 1) + elt_bias, - get_elt(elts, i + 2) + elt_bias ); - } - else { - TRIANGLE( vcache, - flags, - get_elt(elts, i + 1) + elt_bias, - get_elt(elts, i + 2) + elt_bias, - get_elt(elts, 0) + elt_bias); - } - } - } - break; - - default: - assert(0); - break; - } - - vcache_flush( vcache ); -} - - -#undef TRIANGLE -#undef QUAD -#undef POINT -#undef LINE -#undef FUNC +#include "draw_decompose_tmp.h" diff --git a/src/gallium/auxiliary/draw/draw_so_emit_tmp.h b/src/gallium/auxiliary/draw/draw_so_emit_tmp.h index 01212a8e536..6d8937a0b41 100644 --- a/src/gallium/auxiliary/draw/draw_so_emit_tmp.h +++ b/src/gallium/auxiliary/draw/draw_so_emit_tmp.h @@ -1,123 +1,33 @@ - -static void FUNC( struct pt_so_emit *so, - const struct draw_prim_info *input_prims, - const struct draw_vertex_info *input_verts, - unsigned start, - unsigned count) -{ - struct draw_context *draw = so->draw; - - boolean flatfirst = (draw->rasterizer->flatshade && - draw->rasterizer->flatshade_first); - unsigned i; - LOCAL_VARS - - if (0) debug_printf("%s %d\n", __FUNCTION__, count); - - debug_assert(input_prims->primitive_count == 1); - - switch (input_prims->prim) { - case PIPE_PRIM_POINTS: - for (i = 0; i < count; i++) { - POINT( so, start + i + 0 ); - } - break; - - case PIPE_PRIM_LINES: - for (i = 0; i+1 < count; i += 2) { - LINE( so , start + i + 0 , start + i + 1 ); - } - break; - - case PIPE_PRIM_LINE_LOOP: - if (count >= 2) { - - for (i = 1; i < count; i++) { - LINE( so, start + i - 1, start + i ); - } - - LINE( so, start + i - 1, start ); - } - break; - - case PIPE_PRIM_LINE_STRIP: - for (i = 1; i < count; i++) { - LINE( so, start + i - 1, start + i ); - } - break; - - case PIPE_PRIM_TRIANGLES: - for (i = 0; i+2 < count; i += 3) { - TRIANGLE( so, start + i + 0, start + i + 1, start + i + 2 ); - } - break; - - case PIPE_PRIM_TRIANGLE_STRIP: - if (flatfirst) { - for (i = 0; i+2 < count; i++) { - TRIANGLE( so, - start + i + 0, - start + i + 1 + (i&1), - start + i + 2 - (i&1) ); - } - } - else { - for (i = 0; i+2 < count; i++) { - TRIANGLE( so, - start + i + 0 + (i&1), - start + i + 1 - (i&1), - start + i + 2 ); - } - } - break; - - case PIPE_PRIM_TRIANGLE_FAN: - if (count >= 3) { - if (flatfirst) { - for (i = 0; i+2 < count; i++) { - TRIANGLE( so, - start + i + 1, - start + i + 2, - start ); - } - } - else { - for (i = 0; i+2 < count; i++) { - TRIANGLE( so, - start, - start + i + 1, - start + i + 2 ); - } - } - } - break; - - case PIPE_PRIM_POLYGON: - { - /* These bitflags look a little odd because we submit the - * vertices as (1,2,0) to satisfy flatshade requirements. - */ - - for (i = 0; i+2 < count; i++) { - - if (flatfirst) { - TRIANGLE( so, start + 0, start + i + 1, start + i + 2 ); - } - else { - TRIANGLE( so, start + i + 1, start + i + 2, start + 0 ); - } - } - } - break; - - default: - debug_assert(!"Unsupported primitive in stream output"); - break; - } -} - - -#undef TRIANGLE -#undef POINT -#undef LINE -#undef FUNC +#define FUNC_VARS \ + struct pt_so_emit *so, \ + const struct draw_prim_info *input_prims, \ + const struct draw_vertex_info *input_verts, \ + unsigned start, \ + unsigned count + +#define FUNC_ENTER \ + /* declare more local vars */ \ + struct draw_context *draw = so->draw; \ + const unsigned prim = input_prims->prim; \ + const boolean last_vertex_last = \ + !(draw->rasterizer->flatshade && \ + draw->rasterizer->flatshade_first); \ + do { \ + debug_assert(input_prims->primitive_count == 1); \ + switch (prim) { \ + case PIPE_PRIM_LINES_ADJACENCY: \ + case PIPE_PRIM_LINE_STRIP_ADJACENCY: \ + case PIPE_PRIM_TRIANGLES_ADJACENCY: \ + case PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY: \ + debug_assert(!"unexpected primitive type in stream output"); \ + return; \ + default: \ + break; \ + } \ + } while (0) \ + +#define POINT(i0) so_point(so,i0) +#define LINE(flags,i0,i1) so_line(so,i0,i1) +#define TRIANGLE(flags,i0,i1,i2) so_tri(so,i0,i1,i2) + +#include "draw_decompose_tmp.h" diff --git a/src/gallium/auxiliary/draw/draw_vertex.h b/src/gallium/auxiliary/draw/draw_vertex.h index 3af31ffe126..e63cf5f4f98 100644 --- a/src/gallium/auxiliary/draw/draw_vertex.h +++ b/src/gallium/auxiliary/draw/draw_vertex.h @@ -166,7 +166,7 @@ static INLINE enum pipe_format draw_translate_vinfo_format(enum attrib_emit emit } } -static INLINE enum attrib_emit draw_translate_vinfo_size(enum attrib_emit emit) +static INLINE unsigned draw_translate_vinfo_size(enum attrib_emit emit) { switch (emit) { case EMIT_OMIT: diff --git a/src/gallium/auxiliary/draw/draw_vs.c b/src/gallium/auxiliary/draw/draw_vs.c index 57ea63fc060..fb665b08fff 100644 --- a/src/gallium/auxiliary/draw/draw_vs.c +++ b/src/gallium/auxiliary/draw/draw_vs.c @@ -48,18 +48,30 @@ DEBUG_GET_ONCE_BOOL_OPTION(gallium_dump_vs, "GALLIUM_DUMP_VS", FALSE) + +/** + * Set a vertex shader constant buffer. + * \param slot which constant buffer in [0, PIPE_MAX_CONSTANT_BUFFERS-1] + * \param constants the mapped buffer + * \param size size of buffer in bytes + */ void draw_vs_set_constants(struct draw_context *draw, unsigned slot, const void *constants, unsigned size) { - if (((uintptr_t)constants) & 0xf) { + const int alignment = 16; + + /* check if buffer is 16-byte aligned */ + if (((uintptr_t)constants) & (alignment - 1)) { + /* if not, copy the constants into a new, 16-byte aligned buffer */ if (size > draw->vs.const_storage_size[slot]) { if (draw->vs.aligned_constant_storage[slot]) { align_free((void *)draw->vs.aligned_constant_storage[slot]); } - draw->vs.aligned_constant_storage[slot] = align_malloc(size, 16); + draw->vs.aligned_constant_storage[slot] = + align_malloc(size, alignment); } assert(constants); memcpy((void *)draw->vs.aligned_constant_storage[slot], diff --git a/src/gallium/auxiliary/draw/draw_vs.h b/src/gallium/auxiliary/draw/draw_vs.h index a7319945234..f9a038788fb 100644 --- a/src/gallium/auxiliary/draw/draw_vs.h +++ b/src/gallium/auxiliary/draw/draw_vs.h @@ -133,7 +133,8 @@ struct draw_vertex_shader { void (*run_linear)( struct draw_vertex_shader *shader, const float (*input)[4], float (*output)[4], - const void *constants[PIPE_MAX_CONSTANT_BUFFERS], + const void *constants[PIPE_MAX_CONSTANT_BUFFERS], + const unsigned const_size[PIPE_MAX_CONSTANT_BUFFERS], unsigned count, unsigned input_stride, unsigned output_stride ); diff --git a/src/gallium/auxiliary/draw/draw_vs_exec.c b/src/gallium/auxiliary/draw/draw_vs_exec.c index bc34d390dae..dab3eb1ca8e 100644 --- a/src/gallium/auxiliary/draw/draw_vs_exec.c +++ b/src/gallium/auxiliary/draw/draw_vs_exec.c @@ -85,7 +85,8 @@ static void vs_exec_run_linear( struct draw_vertex_shader *shader, const float (*input)[4], float (*output)[4], - const void *constants[PIPE_MAX_CONSTANT_BUFFERS], + const void *constants[PIPE_MAX_CONSTANT_BUFFERS], + const unsigned const_size[PIPE_MAX_CONSTANT_BUFFERS], unsigned count, unsigned input_stride, unsigned output_stride ) @@ -95,9 +96,8 @@ vs_exec_run_linear( struct draw_vertex_shader *shader, unsigned int i, j; unsigned slot; - for (i = 0; i < PIPE_MAX_CONSTANT_BUFFERS; i++) { - machine->Consts[i] = constants[i]; - } + tgsi_exec_set_constant_buffers(machine, PIPE_MAX_CONSTANT_BUFFERS, + constants, const_size); for (i = 0; i < count; i += MAX_TGSI_VERTICES) { unsigned int max_vertices = MIN2(MAX_TGSI_VERTICES, count - i); diff --git a/src/gallium/auxiliary/draw/draw_vs_llvm.c b/src/gallium/auxiliary/draw/draw_vs_llvm.c index 6c13df79132..d13ad24fff0 100644 --- a/src/gallium/auxiliary/draw/draw_vs_llvm.c +++ b/src/gallium/auxiliary/draw/draw_vs_llvm.c @@ -49,6 +49,7 @@ vs_llvm_run_linear( struct draw_vertex_shader *shader, const float (*input)[4], float (*output)[4], const void *constants[PIPE_MAX_CONSTANT_BUFFERS], + const unsigned constants_size[PIPE_MAX_CONSTANT_BUFFERS], unsigned count, unsigned input_stride, unsigned output_stride ) diff --git a/src/gallium/auxiliary/draw/draw_vs_sse.c b/src/gallium/auxiliary/draw/draw_vs_sse.c index 14c95082a9d..0b0c6077c6f 100644 --- a/src/gallium/auxiliary/draw/draw_vs_sse.c +++ b/src/gallium/auxiliary/draw/draw_vs_sse.c @@ -84,6 +84,7 @@ vs_sse_run_linear( struct draw_vertex_shader *base, const float (*input)[4], float (*output)[4], const void *constants[PIPE_MAX_CONSTANT_BUFFERS], + const unsigned const_size[PIPE_MAX_CONSTANT_BUFFERS], unsigned count, unsigned input_stride, unsigned output_stride ) diff --git a/src/gallium/auxiliary/draw/draw_vs_varient.c b/src/gallium/auxiliary/draw/draw_vs_varient.c index 6eb26927f27..eacd1601877 100644 --- a/src/gallium/auxiliary/draw/draw_vs_varient.c +++ b/src/gallium/auxiliary/draw/draw_vs_varient.c @@ -149,7 +149,8 @@ static void PIPE_CDECL vsvg_run_elts( struct draw_vs_varient *varient, vsvg->base.vs->run_linear( vsvg->base.vs, temp_buffer, temp_buffer, - vsvg->base.vs->draw->pt.user.vs_constants, + vsvg->base.vs->draw->pt.user.vs_constants, + vsvg->base.vs->draw->pt.user.vs_constants_size, count, temp_vertex_stride, temp_vertex_stride); @@ -214,7 +215,8 @@ static void PIPE_CDECL vsvg_run_linear( struct draw_vs_varient *varient, vsvg->base.vs->run_linear( vsvg->base.vs, temp_buffer, temp_buffer, - vsvg->base.vs->draw->pt.user.vs_constants, + vsvg->base.vs->draw->pt.user.vs_constants, + vsvg->base.vs->draw->pt.user.vs_constants_size, count, temp_vertex_stride, temp_vertex_stride); diff --git a/src/gallium/auxiliary/gallivm/lp_bld_assert.c b/src/gallium/auxiliary/gallivm/lp_bld_assert.c new file mode 100644 index 00000000000..f2ebd868a8d --- /dev/null +++ b/src/gallium/auxiliary/gallivm/lp_bld_assert.c @@ -0,0 +1,101 @@ +/************************************************************************** + * + * Copyright 2010 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. + * + * 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 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 "util/u_debug.h" +#include "util/u_memory.h" +#include "lp_bld_assert.h" +#include "lp_bld_init.h" +#include "lp_bld_printf.h" + + +/** + * A call to lp_build_assert() will build a function call to this function. + */ +static void +lp_assert(int condition, const char *msg) +{ + if (!condition) { + debug_printf("LLVM assertion '%s' failed!\n", msg); + assert(condition); + } +} + + + +/** + * lp_build_assert. + * + * Build an assertion in LLVM IR by building a function call to the + * lp_assert() function above. + * + * \param condition should be an 'i1' or 'i32' value + * \param msg a string to print if the assertion fails. + */ +LLVMValueRef +lp_build_assert(LLVMBuilderRef builder, LLVMValueRef condition, + const char *msg) +{ + LLVMModuleRef module; + LLVMTypeRef arg_types[2]; + LLVMValueRef msg_string, assert_func, params[2], r; + + module = LLVMGetGlobalParent(LLVMGetBasicBlockParent( + LLVMGetInsertBlock(builder))); + + msg_string = lp_build_const_string_variable(module, msg, strlen(msg) + 1); + + arg_types[0] = LLVMInt32Type(); + arg_types[1] = LLVMPointerType(LLVMInt8Type(), 0); + + /* lookup the lp_assert function */ + assert_func = LLVMGetNamedFunction(module, "lp_assert"); + + /* Create the assertion function if not found */ + if (!assert_func) { + LLVMTypeRef func_type = + LLVMFunctionType(LLVMVoidType(), arg_types, 2, 0); + + assert_func = LLVMAddFunction(module, "lp_assert", func_type); + LLVMSetFunctionCallConv(assert_func, LLVMCCallConv); + LLVMSetLinkage(assert_func, LLVMExternalLinkage); + LLVMAddGlobalMapping(lp_build_engine, assert_func, + func_to_pointer((func_pointer)lp_assert)); + } + assert(assert_func); + + /* build function call param list */ + params[0] = LLVMBuildZExt(builder, condition, arg_types[0], ""); + params[1] = LLVMBuildBitCast(builder, msg_string, arg_types[1], ""); + + /* check arg types */ + assert(LLVMTypeOf(params[0]) == arg_types[0]); + assert(LLVMTypeOf(params[1]) == arg_types[1]); + + r = LLVMBuildCall(builder, assert_func, params, 2, ""); + + return r; +} diff --git a/src/gallium/state_trackers/dri/drm/dri2.h b/src/gallium/auxiliary/gallivm/lp_bld_assert.h index 07adfe4f6c5..ddd879dc2c6 100644 --- a/src/gallium/state_trackers/dri/drm/dri2.h +++ b/src/gallium/auxiliary/gallivm/lp_bld_assert.h @@ -1,6 +1,6 @@ /************************************************************************** * - * Copyright 2009, VMware, Inc. + * Copyright 2010 VMware, Inc. * All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a @@ -25,13 +25,17 @@ * **************************************************************************/ -#ifndef DRI2_H -#define DRI2_H +#ifndef LP_BLD_ASSERT_H +#define LP_BLD_ASSERT_H -#include "dri_drawable.h" -#include "dri_wrapper.h" -const __DRIconfig ** -dri2_init_screen(__DRIscreen * sPriv); +#include "lp_bld.h" + + +LLVMValueRef +lp_build_assert(LLVMBuilderRef builder, LLVMValueRef condition, + const char *msg); + + +#endif -#endif /* DRI2_H */ diff --git a/src/gallium/auxiliary/gallivm/lp_bld_init.c b/src/gallium/auxiliary/gallivm/lp_bld_init.c index 69353dea09e..ef0888079c7 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_init.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_init.c @@ -45,6 +45,8 @@ static const struct debug_named_value lp_bld_debug_flags[] = { { "nopt", GALLIVM_DEBUG_NO_OPT, NULL }, DEBUG_NAMED_VALUE_END }; + +DEBUG_GET_ONCE_FLAGS_OPTION(gallivm_debug, "GALLIVM_DEBUG", lp_bld_debug_flags, 0); #endif @@ -89,7 +91,7 @@ void lp_build_init(void) { #ifdef DEBUG - gallivm_debug = debug_get_flags_option("GALLIVM_DEBUG", lp_bld_debug_flags, 0 ); + gallivm_debug = debug_get_option_gallivm_debug(); #endif lp_set_target_options(); diff --git a/src/gallium/auxiliary/gallivm/lp_bld_init.h b/src/gallium/auxiliary/gallivm/lp_bld_init.h index a32ced9b4c3..f26fdac4663 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_init.h +++ b/src/gallium/auxiliary/gallivm/lp_bld_init.h @@ -44,5 +44,7 @@ extern LLVMPassManagerRef lp_build_pass; void lp_build_init(void); +extern void +lp_func_delete_body(LLVMValueRef func); #endif /* !LP_BLD_INIT_H */ diff --git a/src/gallium/auxiliary/gallivm/lp_bld_logic.c b/src/gallium/auxiliary/gallivm/lp_bld_logic.c index 39854e43b19..ab4ddb81c40 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_logic.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_logic.c @@ -363,9 +363,52 @@ lp_build_cmp(struct lp_build_context *bld, /** + * Return (mask & a) | (~mask & b); + */ +LLVMValueRef +lp_build_select_bitwise(struct lp_build_context *bld, + LLVMValueRef mask, + LLVMValueRef a, + LLVMValueRef b) +{ + struct lp_type type = bld->type; + LLVMValueRef res; + + if (a == b) { + return a; + } + + if(type.floating) { + LLVMTypeRef int_vec_type = lp_build_int_vec_type(type); + a = LLVMBuildBitCast(bld->builder, a, int_vec_type, ""); + b = LLVMBuildBitCast(bld->builder, b, int_vec_type, ""); + } + + a = LLVMBuildAnd(bld->builder, a, mask, ""); + + /* This often gets translated to PANDN, but sometimes the NOT is + * pre-computed and stored in another constant. The best strategy depends + * on available registers, so it is not a big deal -- hopefully LLVM does + * the right decision attending the rest of the program. + */ + b = LLVMBuildAnd(bld->builder, b, LLVMBuildNot(bld->builder, mask, ""), ""); + + res = LLVMBuildOr(bld->builder, a, b, ""); + + if(type.floating) { + LLVMTypeRef vec_type = lp_build_vec_type(type); + res = LLVMBuildBitCast(bld->builder, res, vec_type, ""); + } + + return res; +} + + +/** * Return mask ? a : b; * - * mask is a bitwise mask, composed of 0 or ~0 for each element. + * mask is a bitwise mask, composed of 0 or ~0 for each element. Any other value + * will yield unpredictable results. */ LLVMValueRef lp_build_select(struct lp_build_context *bld, @@ -424,27 +467,7 @@ lp_build_select(struct lp_build_context *bld, } } else { - if(type.floating) { - LLVMTypeRef int_vec_type = lp_build_int_vec_type(type); - a = LLVMBuildBitCast(bld->builder, a, int_vec_type, ""); - b = LLVMBuildBitCast(bld->builder, b, int_vec_type, ""); - } - - a = LLVMBuildAnd(bld->builder, a, mask, ""); - - /* This often gets translated to PANDN, but sometimes the NOT is - * pre-computed and stored in another constant. The best strategy depends - * on available registers, so it is not a big deal -- hopefully LLVM does - * the right decision attending the rest of the program. - */ - b = LLVMBuildAnd(bld->builder, b, LLVMBuildNot(bld->builder, mask, ""), ""); - - res = LLVMBuildOr(bld->builder, a, b, ""); - - if(type.floating) { - LLVMTypeRef vec_type = lp_build_vec_type(type); - res = LLVMBuildBitCast(bld->builder, res, vec_type, ""); - } + res = lp_build_select_bitwise(bld, mask, a, b); } return res; diff --git a/src/gallium/auxiliary/gallivm/lp_bld_logic.h b/src/gallium/auxiliary/gallivm/lp_bld_logic.h index 29f9fc3b205..4e7b4c9938e 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_logic.h +++ b/src/gallium/auxiliary/gallivm/lp_bld_logic.h @@ -63,6 +63,11 @@ lp_build_cmp(struct lp_build_context *bld, LLVMValueRef a, LLVMValueRef b); +LLVMValueRef +lp_build_select_bitwise(struct lp_build_context *bld, + LLVMValueRef mask, + LLVMValueRef a, + LLVMValueRef b); LLVMValueRef lp_build_select(struct lp_build_context *bld, diff --git a/src/gallium/auxiliary/gallivm/lp_bld_misc.cpp b/src/gallium/auxiliary/gallivm/lp_bld_misc.cpp index 5a9488b5f79..6d5410d9701 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_misc.cpp +++ b/src/gallium/auxiliary/gallivm/lp_bld_misc.cpp @@ -39,6 +39,7 @@ #include <llvm/Target/TargetOptions.h> #include <llvm/ExecutionEngine/ExecutionEngine.h> #include <llvm/ExecutionEngine/JITEventListener.h> +#include <llvm/Support/CommandLine.h> #include "pipe/p_config.h" #include "util/u_debug.h" @@ -141,4 +142,35 @@ lp_set_target_options(void) #if 0 llvm::UnsafeFPMath = true; #endif + +#if 0 + /* + * LLVM will generate MMX instructions for vectors <= 64 bits, leading to + * innefficient code, and in 32bit systems, to the corruption of the FPU + * stack given that it expects the user to generate the EMMS instructions. + * + * See also: + * - http://llvm.org/bugs/show_bug.cgi?id=3287 + * - http://l4.me.uk/post/2009/06/07/llvm-wrinkle-3-configuration-what-configuration/ + * + * XXX: Unfortunately this is not working. + */ + static boolean first = FALSE; + if (first) { + static const char* options[] = { + "prog", + "-disable-mmx" + }; + llvm::cl::ParseCommandLineOptions(2, const_cast<char**>(options)); + first = FALSE; + } +#endif +} + + +extern "C" void +lp_func_delete_body(LLVMValueRef FF) +{ + llvm::Function *func = llvm::unwrap<llvm::Function>(FF); + func->deleteBody(); } diff --git a/src/gallium/auxiliary/tgsi/tgsi_exec.c b/src/gallium/auxiliary/tgsi/tgsi_exec.c index 5275faa5e22..298f3d0a8bb 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_exec.c +++ b/src/gallium/auxiliary/tgsi/tgsi_exec.c @@ -557,6 +557,23 @@ print_temp(const struct tgsi_exec_machine *mach, uint index) #endif +void +tgsi_exec_set_constant_buffers(struct tgsi_exec_machine *mach, + unsigned num_bufs, + const void **bufs, + const unsigned *buf_sizes) +{ + unsigned i; + + for (i = 0; i < num_bufs; i++) { + mach->Consts[i] = bufs[i]; + mach->ConstsSize[i] = buf_sizes[i]; + } +} + + + + /** * Check if there's a potential src/dst register data dependency when * using SOA execution. @@ -632,6 +649,10 @@ tgsi_exec_machine_bind_shader( util_init_math(); + if (numSamplers) { + assert(samplers); + } + mach->Tokens = tokens; mach->Samplers = samplers; @@ -1040,6 +1061,8 @@ fetch_src_file_channel(const struct tgsi_exec_machine *mach, { uint i; + assert(swizzle < 4); + switch (file) { case TGSI_FILE_CONSTANT: for (i = 0; i < QUAD_SIZE; i++) { @@ -1049,9 +1072,23 @@ fetch_src_file_channel(const struct tgsi_exec_machine *mach, if (index->i[i] < 0) { chan->u[i] = 0; } else { - const uint *p = (const uint *)mach->Consts[index2D->i[i]]; - - chan->u[i] = p[index->i[i] * 4 + swizzle]; + /* NOTE: copying the const value as a uint instead of float */ + const uint constbuf = index2D->i[i]; + const uint *buf = (const uint *)mach->Consts[constbuf]; + const int pos = index->i[i] * 4 + swizzle; + /* const buffer bounds check */ + if (pos < 0 || pos >= mach->ConstsSize[constbuf]) { + if (0) { + /* Debug: print warning */ + static int count = 0; + if (count++ < 100) + debug_printf("TGSI Exec: const buffer index %d" + " out of bounds\n", pos); + } + chan->u[i] = 0; + } + else + chan->u[i] = buf[pos]; } } break; @@ -1065,9 +1102,10 @@ fetch_src_file_channel(const struct tgsi_exec_machine *mach, index2D->i[i] * TGSI_EXEC_MAX_INPUT_ATTRIBS + index->i[i], index2D->i[i], index->i[i]); }*/ - chan->u[i] = mach->Inputs[index2D->i[i] * - TGSI_EXEC_MAX_INPUT_ATTRIBS + - index->i[i]].xyzw[swizzle].u[i]; + int pos = index2D->i[i] * TGSI_EXEC_MAX_INPUT_ATTRIBS + index->i[i]; + assert(pos >= 0); + assert(pos < Elements(mach->Inputs)); + chan->u[i] = mach->Inputs[pos].xyzw[swizzle].u[i]; } break; @@ -1187,7 +1225,7 @@ fetch_source(const struct tgsi_exec_machine *mach, index2.i[1] = index2.i[2] = index2.i[3] = reg->Indirect.Index; - + assert(reg->Indirect.File == TGSI_FILE_ADDRESS); /* get current value of address register[swizzle] */ swizzle = tgsi_util_get_src_register_swizzle( ®->Indirect, CHAN_X ); fetch_src_file_channel(mach, diff --git a/src/gallium/auxiliary/tgsi/tgsi_exec.h b/src/gallium/auxiliary/tgsi/tgsi_exec.h index ccf80ca6fd9..6dee362d589 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_exec.h +++ b/src/gallium/auxiliary/tgsi/tgsi_exec.h @@ -253,7 +253,10 @@ struct tgsi_exec_machine struct tgsi_sampler **Samplers; unsigned ImmLimit; + const void *Consts[PIPE_MAX_CONSTANT_BUFFERS]; + unsigned ConstsSize[PIPE_MAX_CONSTANT_BUFFERS]; + const struct tgsi_token *Tokens; /**< Declarations, instructions */ unsigned Processor; /**< TGSI_PROCESSOR_x */ @@ -367,6 +370,13 @@ tgsi_set_exec_mask(struct tgsi_exec_machine *mach, } +extern void +tgsi_exec_set_constant_buffers(struct tgsi_exec_machine *mach, + unsigned num_bufs, + const void **bufs, + const unsigned *buf_sizes); + + #if defined __cplusplus } /* extern "C" */ #endif diff --git a/src/gallium/auxiliary/tgsi/tgsi_sanity.c b/src/gallium/auxiliary/tgsi/tgsi_sanity.c index 97148dbe233..9e02040f6c4 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_sanity.c +++ b/src/gallium/auxiliary/tgsi/tgsi_sanity.c @@ -33,6 +33,10 @@ #include "tgsi_info.h" #include "tgsi_iterate.h" + +DEBUG_GET_ONCE_BOOL_OPTION(print_sanity, "TGSI_PRINT_SANITY", TRUE); + + typedef struct { uint file : 28; /* max 2 dimensions */ @@ -54,6 +58,8 @@ struct sanity_check_ctx uint errors; uint warnings; uint implied_array_size; + + boolean print; }; static INLINE unsigned @@ -148,6 +154,9 @@ report_error( { va_list args; + if (!ctx->print) + return; + debug_printf( "Error : " ); va_start( args, format ); _debug_vprintf( format, args ); @@ -164,6 +173,9 @@ report_warning( { va_list args; + if (!ctx->print) + return; + debug_printf( "Warning: " ); va_start( args, format ); _debug_vprintf( format, args ); @@ -539,6 +551,7 @@ tgsi_sanity_check( ctx.errors = 0; ctx.warnings = 0; ctx.implied_array_size = 0; + ctx.print = debug_get_option_print_sanity(); if (!tgsi_iterate_shader( tokens, &ctx.iter )) return FALSE; diff --git a/src/gallium/auxiliary/tgsi/tgsi_sanity.h b/src/gallium/auxiliary/tgsi/tgsi_sanity.h index 52263ff8832..46d8d184190 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_sanity.h +++ b/src/gallium/auxiliary/tgsi/tgsi_sanity.h @@ -35,7 +35,8 @@ extern "C" { #endif /* Check the given token stream for errors and common mistakes. - * Diagnostic messages are printed out to the debug output. + * Diagnostic messages are printed out to the debug output, and is + * controlled by the debug option TGSI_PRINT_SANITY (default true). * Returns TRUE if there are no errors, even though there could be some warnings. */ boolean diff --git a/src/gallium/auxiliary/translate/translate_generic.c b/src/gallium/auxiliary/translate/translate_generic.c index 0e43a512ee8..4d1977229e2 100644 --- a/src/gallium/auxiliary/translate/translate_generic.c +++ b/src/gallium/auxiliary/translate/translate_generic.c @@ -368,23 +368,23 @@ static void PIPE_CDECL generic_run_elts( struct translate *translate, /* loop over vertex attributes (vertex shader inputs) */ for (i = 0; i < count; i++) { - unsigned elt = *elts++; + const unsigned elt = *elts++; for (attr = 0; attr < nr_attrs; attr++) { float data[4]; - const uint8_t *src; - unsigned index; - - char *dst = (vert + - tg->attrib[attr].output_offset); + char *dst = vert + tg->attrib[attr].output_offset; if (tg->attrib[attr].type == TRANSLATE_ELEMENT_NORMAL) { + const uint8_t *src; + unsigned index; + if (tg->attrib[attr].instance_divisor) { index = instance_id / tg->attrib[attr].instance_divisor; } else { index = elt; } + /* clamp to void going out of bounds */ index = MIN2(index, tg->attrib[attr].max_index); src = tg->attrib[attr].input_ptr + @@ -392,11 +392,23 @@ static void PIPE_CDECL generic_run_elts( struct translate *translate, tg->attrib[attr].fetch( data, src, 0, 0 ); + if (0) + debug_printf("Fetch elt attr %d from %p stride %d div %u max %u index %d: " + " %f, %f, %f, %f \n", + attr, + tg->attrib[attr].input_ptr, + tg->attrib[attr].input_stride, + tg->attrib[attr].instance_divisor, + tg->attrib[attr].max_index, + index, + data[0], data[1],data[2], data[3]); } else { data[0] = (float)instance_id; } - if (0) debug_printf("vert %d/%d attr %d: %f %f %f %f\n", - i, elt, attr, data[0], data[1], data[2], data[3]); + + if (0) + debug_printf("vert %d/%d attr %d: %f %f %f %f\n", + i, elt, attr, data[0], data[1], data[2], data[3]); tg->attrib[attr].emit( data, dst ); } @@ -425,29 +437,42 @@ static void PIPE_CDECL generic_run( struct translate *translate, for (attr = 0; attr < nr_attrs; attr++) { float data[4]; - - char *dst = (vert + - tg->attrib[attr].output_offset); + char *dst = vert + tg->attrib[attr].output_offset; if (tg->attrib[attr].type == TRANSLATE_ELEMENT_NORMAL) { const uint8_t *src; + unsigned index; if (tg->attrib[attr].instance_divisor) { - src = tg->attrib[attr].input_ptr + - tg->attrib[attr].input_stride * - (instance_id / tg->attrib[attr].instance_divisor); - } else { - src = tg->attrib[attr].input_ptr + - tg->attrib[attr].input_stride * elt; + index = instance_id / tg->attrib[attr].instance_divisor; } + else { + index = elt; + } + + /* clamp to void going out of bounds */ + index = MIN2(index, tg->attrib[attr].max_index); + + src = tg->attrib[attr].input_ptr + + tg->attrib[attr].input_stride * index; tg->attrib[attr].fetch( data, src, 0, 0 ); + + if (0) + debug_printf("Fetch linear attr %d from %p stride %d index %d: " + " %f, %f, %f, %f \n", + attr, + tg->attrib[attr].input_ptr, + tg->attrib[attr].input_stride, + index, + data[0], data[1],data[2], data[3]); } else { data[0] = (float)instance_id; } - if (0) debug_printf("vert %d attr %d: %f %f %f %f\n", - i, attr, data[0], data[1], data[2], data[3]); + if (0) + debug_printf("vert %d attr %d: %f %f %f %f\n", + i, attr, data[0], data[1], data[2], data[3]); tg->attrib[attr].emit( data, dst ); } diff --git a/src/gallium/auxiliary/util/u_blitter.c b/src/gallium/auxiliary/util/u_blitter.c index 0d94aaae956..b5b86b72142 100644 --- a/src/gallium/auxiliary/util/u_blitter.c +++ b/src/gallium/auxiliary/util/u_blitter.c @@ -87,6 +87,7 @@ struct blitter_context_priv void *dsa_write_depth_keep_stencil; void *dsa_keep_depth_stencil; void *dsa_keep_depth_write_stencil; + void *dsa_flush_depth_stencil; void *velem_state; @@ -156,6 +157,10 @@ struct blitter_context *util_blitter_create(struct pipe_context *pipe) ctx->dsa_keep_depth_stencil = pipe->create_depth_stencil_alpha_state(pipe, &dsa); + dsa.depth.writemask = 1; + ctx->dsa_flush_depth_stencil = + pipe->create_depth_stencil_alpha_state(pipe, &dsa); + dsa.depth.enabled = 1; dsa.depth.writemask = 1; dsa.depth.func = PIPE_FUNC_ALWAYS; @@ -940,3 +945,42 @@ void util_blitter_clear_depth_stencil(struct blitter_context *blitter, UTIL_BLITTER_ATTRIB_NONE, NULL); blitter_restore_CSOs(ctx); } + +/* Clear a region of a depth stencil surface. */ +void util_blitter_flush_depth_stencil(struct blitter_context *blitter, + struct pipe_surface *dstsurf) +{ + struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter; + struct pipe_context *pipe = ctx->base.pipe; + struct pipe_framebuffer_state fb_state; + + assert(dstsurf->texture); + if (!dstsurf->texture) + return; + + /* check the saved state */ + blitter_check_saved_CSOs(ctx); + assert(blitter->saved_fb_state.nr_cbufs != ~0); + + /* bind CSOs */ + pipe->bind_blend_state(pipe, ctx->blend_keep_color); + pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_flush_depth_stencil); + + pipe->bind_rasterizer_state(pipe, ctx->rs_state); + pipe->bind_fs_state(pipe, blitter_get_fs_col(ctx, 0)); + pipe->bind_vs_state(pipe, ctx->vs_col); + pipe->bind_vertex_elements_state(pipe, ctx->velem_state); + + /* set a framebuffer state */ + fb_state.width = dstsurf->width; + fb_state.height = dstsurf->height; + fb_state.nr_cbufs = 0; + fb_state.cbufs[0] = 0; + fb_state.zsbuf = dstsurf; + pipe->set_framebuffer_state(pipe, &fb_state); + + blitter_set_dst_dimensions(ctx, dstsurf->width, dstsurf->height); + blitter->draw_rectangle(blitter, 0, 0, dstsurf->width, dstsurf->height, 0, + UTIL_BLITTER_ATTRIB_NONE, NULL); + blitter_restore_CSOs(ctx); +} diff --git a/src/gallium/auxiliary/util/u_blitter.h b/src/gallium/auxiliary/util/u_blitter.h index ba3f92eca85..f316587dea0 100644 --- a/src/gallium/auxiliary/util/u_blitter.h +++ b/src/gallium/auxiliary/util/u_blitter.h @@ -200,6 +200,8 @@ void util_blitter_clear_depth_stencil(struct blitter_context *blitter, unsigned dstx, unsigned dsty, unsigned width, unsigned height); +void util_blitter_flush_depth_stencil(struct blitter_context *blitter, + struct pipe_surface *dstsurf); /* The functions below should be used to save currently bound constant state * objects inside a driver. The objects are automatically restored at the end * of the util_blitter_{clear, copy_region, fill_region} functions and then diff --git a/src/gallium/auxiliary/util/u_cpu_detect.c b/src/gallium/auxiliary/util/u_cpu_detect.c index 23d33af4e41..6f38d222854 100644 --- a/src/gallium/auxiliary/util/u_cpu_detect.c +++ b/src/gallium/auxiliary/util/u_cpu_detect.c @@ -73,9 +73,15 @@ #endif +DEBUG_GET_ONCE_BOOL_OPTION(dump_cpu, "GALLIUM_DUMP_CPU", TRUE); + + struct util_cpu_caps util_cpu_caps; +#if defined(PIPE_ARCH_X86) || defined(PIPE_ARCH_X86_64) static int has_cpuid(void); +#endif + #if defined(PIPE_ARCH_X86) @@ -497,23 +503,25 @@ util_cpu_detect(void) #endif /* PIPE_ARCH_PPC */ #ifdef DEBUG - debug_printf("util_cpu_caps.arch = %i\n", util_cpu_caps.arch); - debug_printf("util_cpu_caps.nr_cpus = %u\n", util_cpu_caps.nr_cpus); - - debug_printf("util_cpu_caps.x86_cpu_type = %u\n", util_cpu_caps.x86_cpu_type); - debug_printf("util_cpu_caps.cacheline = %u\n", util_cpu_caps.cacheline); - - debug_printf("util_cpu_caps.has_tsc = %u\n", util_cpu_caps.has_tsc); - debug_printf("util_cpu_caps.has_mmx = %u\n", util_cpu_caps.has_mmx); - debug_printf("util_cpu_caps.has_mmx2 = %u\n", util_cpu_caps.has_mmx2); - debug_printf("util_cpu_caps.has_sse = %u\n", util_cpu_caps.has_sse); - debug_printf("util_cpu_caps.has_sse2 = %u\n", util_cpu_caps.has_sse2); - debug_printf("util_cpu_caps.has_sse3 = %u\n", util_cpu_caps.has_sse3); - debug_printf("util_cpu_caps.has_ssse3 = %u\n", util_cpu_caps.has_ssse3); - debug_printf("util_cpu_caps.has_sse4_1 = %u\n", util_cpu_caps.has_sse4_1); - debug_printf("util_cpu_caps.has_3dnow = %u\n", util_cpu_caps.has_3dnow); - debug_printf("util_cpu_caps.has_3dnow_ext = %u\n", util_cpu_caps.has_3dnow_ext); - debug_printf("util_cpu_caps.has_altivec = %u\n", util_cpu_caps.has_altivec); + if (debug_get_option_dump_cpu()) { + debug_printf("util_cpu_caps.arch = %i\n", util_cpu_caps.arch); + debug_printf("util_cpu_caps.nr_cpus = %u\n", util_cpu_caps.nr_cpus); + + debug_printf("util_cpu_caps.x86_cpu_type = %u\n", util_cpu_caps.x86_cpu_type); + debug_printf("util_cpu_caps.cacheline = %u\n", util_cpu_caps.cacheline); + + debug_printf("util_cpu_caps.has_tsc = %u\n", util_cpu_caps.has_tsc); + debug_printf("util_cpu_caps.has_mmx = %u\n", util_cpu_caps.has_mmx); + debug_printf("util_cpu_caps.has_mmx2 = %u\n", util_cpu_caps.has_mmx2); + debug_printf("util_cpu_caps.has_sse = %u\n", util_cpu_caps.has_sse); + debug_printf("util_cpu_caps.has_sse2 = %u\n", util_cpu_caps.has_sse2); + debug_printf("util_cpu_caps.has_sse3 = %u\n", util_cpu_caps.has_sse3); + debug_printf("util_cpu_caps.has_ssse3 = %u\n", util_cpu_caps.has_ssse3); + debug_printf("util_cpu_caps.has_sse4_1 = %u\n", util_cpu_caps.has_sse4_1); + debug_printf("util_cpu_caps.has_3dnow = %u\n", util_cpu_caps.has_3dnow); + debug_printf("util_cpu_caps.has_3dnow_ext = %u\n", util_cpu_caps.has_3dnow_ext); + debug_printf("util_cpu_caps.has_altivec = %u\n", util_cpu_caps.has_altivec); + } #endif util_cpu_detect_initialized = TRUE; diff --git a/src/gallium/auxiliary/util/u_draw.h b/src/gallium/auxiliary/util/u_draw.h new file mode 100644 index 00000000000..2a91ea0f9ae --- /dev/null +++ b/src/gallium/auxiliary/util/u_draw.h @@ -0,0 +1,138 @@ +/************************************************************************** + * + * 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 U_DRAW_H +#define U_DRAW_H + + +#include "pipe/p_compiler.h" +#include "pipe/p_context.h" + + +static INLINE void +util_draw_init_info(struct pipe_draw_info *info) +{ + memset(info, 0, sizeof(*info)); + info->instance_count = 1; + info->max_index = 0xffffffff; +} + + +static INLINE void +util_draw_arrays(struct pipe_context *pipe, uint mode, uint start, uint count) +{ + struct pipe_draw_info info; + + util_draw_init_info(&info); + info.mode = mode; + info.start = start; + info.count = count; + info.min_index = start; + info.max_index = start + count - 1; + + pipe->draw_vbo(pipe, &info); +} + +static INLINE void +util_draw_elements(struct pipe_context *pipe, int index_bias, + uint mode, uint start, uint count) +{ + struct pipe_draw_info info; + + util_draw_init_info(&info); + info.indexed = TRUE; + info.mode = mode; + info.start = start; + info.count = count; + info.index_bias = index_bias; + + pipe->draw_vbo(pipe, &info); +} + +static INLINE void +util_draw_arrays_instanced(struct pipe_context *pipe, + uint mode, uint start, uint count, + uint start_instance, + uint instance_count) +{ + struct pipe_draw_info info; + + util_draw_init_info(&info); + info.mode = mode; + info.start = start; + info.count = count; + info.start_instance = start_instance; + info.instance_count = instance_count; + info.min_index = start; + info.max_index = start + count - 1; + + pipe->draw_vbo(pipe, &info); +} + +static INLINE void +util_draw_elements_instanced(struct pipe_context *pipe, + int index_bias, + uint mode, uint start, uint count, + uint start_instance, + uint instance_count) +{ + struct pipe_draw_info info; + + util_draw_init_info(&info); + info.indexed = TRUE; + info.mode = mode; + info.start = start; + info.count = count; + info.index_bias = index_bias; + info.start_instance = start_instance; + info.instance_count = instance_count; + + pipe->draw_vbo(pipe, &info); +} + +static INLINE void +util_draw_range_elements(struct pipe_context *pipe, + int index_bias, + uint min_index, + uint max_index, + uint mode, uint start, uint count) +{ + struct pipe_draw_info info; + + util_draw_init_info(&info); + info.indexed = TRUE; + info.mode = mode; + info.start = start; + info.count = count; + info.index_bias = index_bias; + info.min_index = min_index; + info.max_index = max_index; + + pipe->draw_vbo(pipe, &info); +} + +#endif diff --git a/src/gallium/auxiliary/util/u_draw_quad.c b/src/gallium/auxiliary/util/u_draw_quad.c index b37b48b5aef..0b6dc5880f3 100644 --- a/src/gallium/auxiliary/util/u_draw_quad.c +++ b/src/gallium/auxiliary/util/u_draw_quad.c @@ -60,7 +60,7 @@ util_draw_vertex_buffer(struct pipe_context *pipe, /* note: vertex elements already set by caller */ /* draw */ - pipe->draw_arrays(pipe, prim_type, 0, num_verts); + util_draw_arrays(pipe, prim_type, 0, num_verts); } diff --git a/src/gallium/auxiliary/util/u_draw_quad.h b/src/gallium/auxiliary/util/u_draw_quad.h index 42eb1844289..52994fe05c3 100644 --- a/src/gallium/auxiliary/util/u_draw_quad.h +++ b/src/gallium/auxiliary/util/u_draw_quad.h @@ -29,12 +29,18 @@ #define U_DRAWQUAD_H +#include "pipe/p_compiler.h" +#include "pipe/p_context.h" + + #ifdef __cplusplus extern "C" { #endif struct pipe_resource; +#include "util/u_draw.h" + extern void util_draw_vertex_buffer(struct pipe_context *pipe, struct pipe_resource *vbuf, uint offset, diff --git a/src/gallium/auxiliary/util/u_format_other.c b/src/gallium/auxiliary/util/u_format_other.c index 723fa8c3bf9..fa42ec37138 100644 --- a/src/gallium/auxiliary/util/u_format_other.c +++ b/src/gallium/auxiliary/util/u_format_other.c @@ -121,6 +121,15 @@ util_format_r1_unorm_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, * A.k.a. D3DFMT_CxV8U8 */ +static uint8_t +r8g8bx_derive(int16_t r, int16_t g) +{ + /* Derive blue from red and green components. + * Apparently, we must always use integers to perform calculations, + * otherwise the results won't match D3D's CxV8U8 definition. + */ + return (uint8_t)sqrtf(0x7f * 0x7f - r * r - g * g) * 0xff / 0x7f; +} void util_format_r8g8bx_snorm_unpack_rgba_float(float *dst_row, unsigned dst_stride, @@ -145,7 +154,7 @@ util_format_r8g8bx_snorm_unpack_rgba_float(float *dst_row, unsigned dst_stride, dst[0] = (float)(r * (1.0f/0x7f)); /* r */ dst[1] = (float)(g * (1.0f/0x7f)); /* g */ - dst[2] = sqrtf(1.0f - dst[0] * dst[0] - dst[1] * dst[1]); /* b */ + dst[2] = r8g8bx_derive(r, g) * (1.0f/0xff); /* b */ dst[3] = 1.0f; /* a */ dst += 4; } @@ -177,7 +186,7 @@ util_format_r8g8bx_snorm_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_strid dst[0] = (uint8_t)(((uint16_t)MAX2(r, 0)) * 0xff / 0x7f); /* r */ dst[1] = (uint8_t)(((uint16_t)MAX2(g, 0)) * 0xff / 0x7f); /* g */ - dst[2] = (uint8_t)sqrtf(0x7f*0x7f - r * r - g * g) * 0xff / 0x7f; /* b */ + dst[2] = r8g8bx_derive(r, g); /* b */ dst[3] = 255; /* a */ dst += 4; } @@ -262,6 +271,6 @@ util_format_r8g8bx_snorm_fetch_rgba_float(float *dst, const uint8_t *src, dst[0] = r * (1.0f/0x7f); /* r */ dst[1] = g * (1.0f/0x7f); /* g */ - dst[2] = sqrtf(1.0f - dst[0] * dst[0] - dst[1] * dst[1]); /* b */ + dst[2] = r8g8bx_derive(r, g) * (1.0f/0xff); /* b */ dst[3] = 1.0f; /* a */ } diff --git a/src/gallium/auxiliary/util/u_pack_color.h b/src/gallium/auxiliary/util/u_pack_color.h index 3ebef9fb749..5f113f742b1 100644 --- a/src/gallium/auxiliary/util/u_pack_color.h +++ b/src/gallium/auxiliary/util/u_pack_color.h @@ -425,6 +425,53 @@ util_pack_color(const float rgba[4], enum pipe_format format, union util_color * } } +/* Integer versions of util_pack_z and util_pack_z_stencil - useful for + * constructing clear masks. + */ +static INLINE uint +util_pack_uint_z(enum pipe_format format, unsigned z) +{ + switch (format) { + case PIPE_FORMAT_Z16_UNORM: + return z & 0xffff; + case PIPE_FORMAT_Z32_UNORM: + case PIPE_FORMAT_Z32_FLOAT: + return z; + case PIPE_FORMAT_Z24_UNORM_S8_USCALED: + case PIPE_FORMAT_Z24X8_UNORM: + return z & 0xffffff; + case PIPE_FORMAT_S8_USCALED_Z24_UNORM: + case PIPE_FORMAT_X8Z24_UNORM: + return (z & 0xffffff) << 8; + case PIPE_FORMAT_S8_USCALED: + return 0; + default: + debug_print_format("gallium: unhandled format in util_pack_z()", format); + assert(0); + return 0; + } +} + +static INLINE uint +util_pack_uint_z_stencil(enum pipe_format format, double z, uint s) +{ + unsigned packed = util_pack_uint_z(format, z); + + s &= 0xff; + + switch (format) { + case PIPE_FORMAT_Z24_UNORM_S8_USCALED: + return packed | (s << 24); + case PIPE_FORMAT_S8_USCALED_Z24_UNORM: + return packed | s; + case PIPE_FORMAT_S8_USCALED: + return packed | s; + default: + return packed; + } +} + + /** * Note: it's assumed that z is in [0,1] diff --git a/src/gallium/auxiliary/util/u_prim.h b/src/gallium/auxiliary/util/u_prim.h index 606b9b5c6b9..3c851f73401 100644 --- a/src/gallium/auxiliary/util/u_prim.h +++ b/src/gallium/auxiliary/util/u_prim.h @@ -108,6 +108,20 @@ static INLINE boolean u_trim_pipe_prim( unsigned pipe_prim, unsigned *nr ) ok = (*nr >= 4); *nr -= (*nr % 2); break; + case PIPE_PRIM_LINES_ADJACENCY: + ok = (*nr >= 4); + *nr -= (*nr % 4); + break; + case PIPE_PRIM_LINE_STRIP_ADJACENCY: + ok = (*nr >= 4); + break; + case PIPE_PRIM_TRIANGLES_ADJACENCY: + ok = (*nr >= 6); + *nr -= (*nr % 5); + break; + case PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY: + ok = (*nr >= 4); + break; default: ok = 0; break; diff --git a/src/gallium/auxiliary/util/u_sse.h b/src/gallium/auxiliary/util/u_sse.h index e2a8491e62c..6145e34aa3f 100644 --- a/src/gallium/auxiliary/util/u_sse.h +++ b/src/gallium/auxiliary/util/u_sse.h @@ -41,7 +41,6 @@ #if defined(PIPE_ARCH_SSE) -#include <xmmintrin.h> #include <emmintrin.h> diff --git a/src/gallium/docs/d3d11ddi.txt b/src/gallium/docs/d3d11ddi.txt index 0954c2926df..f8155c828b1 100644 --- a/src/gallium/docs/d3d11ddi.txt +++ b/src/gallium/docs/d3d11ddi.txt @@ -66,9 +66,6 @@ Unordered access view: view supporting random read/write access (usually from co clear + Gallium supports clearing both render targets and depth/stencil with a single call -draw_range_elements - + Gallium supports indexed draw with explicit range - fence_signalled fence_finish + D3D10/D3D11 don't appear to support explicit fencing; queries can often substitute though, and flushing is supported @@ -271,31 +268,27 @@ Dispatch (D3D11 only) DispatchIndirect (D3D11 only) - Gallium does not support compute shaders -Draw -> draw_arrays +Draw -> draw_vbo ! D3D11 sets primitive modes separately with IaSetTopology: it's not obvious which is better DrawAuto -> draw_auto -DrawIndexed -> draw_elements +DrawIndexed -> draw_vbo ! D3D11 sets primitive modes separately with IaSetTopology: it's not obvious which is better - * may want to add a separate set_index_buffer - - Gallium lacks base vertex for indexed draw calls - + D3D11 lacks draw_range_elements functionality, which is required for OpenGL + + D3D11 lacks explicit range, which is required for OpenGL -DrawIndexedInstanced -> draw_elements_instanced +DrawIndexedInstanced -> draw_vbo ! D3D11 sets primitive modes separately with IaSetTopology: it's not obvious which is better - * may want to add a separate set_index_buffer - - Gallium lacks base vertex for indexed draw calls -DrawIndexedInstancedIndirect (D3D11 only) -> call draw_elements_instanced multiple times in software - # this allows to use an hardware buffer to specify the parameters for multiple draw_elements_instanced calls +DrawIndexedInstancedIndirect (D3D11 only) + # this allows to use an hardware buffer to specify the parameters for multiple draw_vbo calls - Gallium does not support draw call parameter buffers and indirect draw -DrawInstanced -> draw_arrays_instanced +DrawInstanced -> draw_vbo ! D3D11 sets primitive modes separately with IaSetTopology: it's not obvious which is better -DrawInstancedIndirect (D3D11 only) -> call draw_arrays_instanced multiple times in software - # this allows to use an hardware buffer to specify the parameters for multiple draw_arrays_instanced calls +DrawInstancedIndirect (D3D11 only) + # this allows to use an hardware buffer to specify the parameters for multiple draw_vbo calls - Gallium does not support draw call parameter buffers and indirect draws DsSetConstantBuffers (D3D11 only) @@ -332,10 +325,9 @@ HsSetShaderResources (D3D11 only) HsSetShaderWithIfaces (D3D11 only) - Gallium does not support hull shaders -IaSetIndexBuffer - ! Gallium passes this to the draw_elements or draw_elements_instanced calls +IaSetIndexBuffer -> set_index_buffer + Gallium supports 8-bit indices - ! the D3D11 interface allows index-size-unaligned byte offsets into index buffers; it's not clear whether they actually work + # the D3D11 interface allows index-size-unaligned byte offsets into the index buffer; most drivers will abort with an assertion IaSetInputLayout -> bind_vertex_elements_state diff --git a/src/gallium/docs/source/conf.py b/src/gallium/docs/source/conf.py index ccc84405c41..99e665234eb 100644 --- a/src/gallium/docs/source/conf.py +++ b/src/gallium/docs/source/conf.py @@ -38,7 +38,7 @@ master_doc = 'index' # General information about the project. project = u'Gallium' -copyright = u'2009, VMWare, X.org, Nouveau' +copyright = u'2009, VMware, X.org, Nouveau' # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the @@ -176,7 +176,7 @@ htmlhelp_basename = 'Galliumdoc' # (source start file, target name, title, author, documentclass [howto/manual]). latex_documents = [ ('index', 'Gallium.tex', u'Gallium Documentation', - u'VMWare, X.org, Nouveau', 'manual'), + u'VMware, X.org, Nouveau', 'manual'), ] # The name of an image file (relative to this directory) to place at the top of diff --git a/src/gallium/docs/source/context.rst b/src/gallium/docs/source/context.rst index 4e35a4c4082..f241411a002 100644 --- a/src/gallium/docs/source/context.rst +++ b/src/gallium/docs/source/context.rst @@ -45,6 +45,7 @@ buffers, surfaces) are bound to the driver. * ``set_vertex_buffers`` +* ``set_index_buffer`` Non-CSO State ^^^^^^^^^^^^^ @@ -132,50 +133,26 @@ this surface need not be bound to the framebuffer. Drawing ^^^^^^^ -``draw_arrays`` draws a specified primitive. +``draw_vbo`` draws a specified primitive. The primitive mode and other +properties are described by ``pipe_draw_info``. -This command is equivalent to calling ``draw_arrays_instanced`` -with ``startInstance`` set to 0 and ``instanceCount`` set to 1. +The ``mode``, ``start``, and ``count`` fields of ``pipe_draw_info`` specify the +the mode of the primitive and the vertices to be fetched, in the range between +``start`` to ``start``+``count``-1, inclusive. -``draw_elements`` draws a specified primitive using an optional -index buffer. +Every instance with instanceID in the range between ``start_instance`` and +``start_instance``+``instance_count``-1, inclusive, will be drawn. -This command is equivalent to calling ``draw_elements_instanced`` -with ``startInstance`` set to 0 and ``instanceCount`` set to 1. +All vertex indices must fall inside the range given by ``min_index`` and +``max_index``. In case non-indexed draw, ``min_index`` should be set to +``start`` and ``max_index`` should be set to ``start``+``count``-1. -``draw_range_elements`` +``index_bias`` is a value added to every vertex index before fetching vertex +attributes. It does not affect ``min_index`` and ``max_index``. -XXX: this is (probably) a temporary entrypoint, as the range -information should be available from the vertex_buffer state. -Using this to quickly evaluate a specialized path in the draw -module. - -``draw_arrays_instanced`` draws multiple instances of the same primitive. - -This command is equivalent to calling ``draw_elements_instanced`` -with ``indexBuffer`` set to NULL and ``indexSize`` set to 0. - -``draw_elements_instanced`` draws multiple instances of the same primitive -using an optional index buffer. - -For instanceID in the range between ``startInstance`` -and ``startInstance``+``instanceCount``-1, inclusive, draw a primitive -specified by ``mode`` and sequential numbers in the range between ``start`` -and ``start``+``count``-1, inclusive. - -If ``indexBuffer`` is not NULL, it specifies an index buffer with index -byte size of ``indexSize``. The sequential numbers are used to lookup -the index buffer and the resulting indices in turn are used to fetch -vertex attributes. - -If ``indexBuffer`` is NULL, the sequential numbers are used directly -as indices to fetch vertex attributes. - -``indexBias`` is a value which is added to every index read from the index -buffer before fetching vertex attributes. - -``minIndex`` and ``maxIndex`` describe minimum and maximum index contained in -the index buffer. +If there is an index buffer bound, and ``indexed`` field is true, all vertex +indices will be looked up in the index buffer. ``min_index``, ``max_index``, +and ``index_bias`` apply after index lookup. If a given vertex element has ``instance_divisor`` set to 0, it is said it contains per-vertex data and effective vertex attribute address needs diff --git a/src/gallium/docs/source/cso/rasterizer.rst b/src/gallium/docs/source/cso/rasterizer.rst index ad1612f93e3..ee3419ccfca 100644 --- a/src/gallium/docs/source/cso/rasterizer.rst +++ b/src/gallium/docs/source/cso/rasterizer.rst @@ -126,11 +126,15 @@ sprite_coord_enable Specifies if a texture unit has its texture coordinates replaced or not. This is a packed bitfield containing the enable for all texcoords -- if all bits -are zero, point sprites are effectively disabled. If any bit is set, then -point_smooth and point_quad_rasterization are ignored; point smoothing is -disabled and points are always rasterized as quads. If enabled, the four -vertices of the resulting quad will be assigned texture coordinates, -according to sprite_coord_mode. +are zero, point sprites are effectively disabled. + +If any bit is set, then point_smooth MUST be disabled (there are no +round sprites) and point_quad_rasterization MUST be true (sprites are +always rasterized as quads). Any mismatch between these states should +be considered a bug in the state-tracker. + +If enabled, the four vertices of the resulting quad will be assigned +texture coordinates, according to sprite_coord_mode. sprite_coord_mode ^^^^^^^^^^^^^^^^^ @@ -141,20 +145,23 @@ have coordinates (0,0,0,1). For PIPE_SPRITE_COORD_UPPER_LEFT, the upper-left vertex will have coordinates (0,0,0,1). This state is used by :ref:`Draw` to generate texcoords. -.. note:: - - When geometry shaders are available, a special geometry shader could be - used instead of this functionality, to convert incoming points into quads - with the proper texture coordinates. - point_quad_rasterization ^^^^^^^^^^^^^^^^^^^^^^^^ -Determines if points should be rasterized as quads or points. Certain APIs, -like Direct3D, always use quad rasterization for points, regardless of -whether point sprites are enabled or not. If this state is enabled, point -smoothing and antialiasing are disabled. If it is disabled, point sprite -coordinates are not generated. +Determines if points should be rasterized according to quad or point +rasterization rules. + +OpenGL actually has quite different rasterization rules for points and +point sprites - hence this indicates if points should be rasterized as +points or according to point sprite (which decomposes them into quads, +basically) rules. + +Additionally Direct3D will always use quad rasterization rules for +points, regardless of whether point sprites are enabled or not. + +If this state is enabled, point smoothing and antialiasing are +disabled. If it is disabled, point sprite coordinates are not +generated. .. note:: diff --git a/src/gallium/docs/source/distro.rst b/src/gallium/docs/source/distro.rst index 6ba5a056f45..e379ad32719 100644 --- a/src/gallium/docs/source/distro.rst +++ b/src/gallium/docs/source/distro.rst @@ -51,10 +51,10 @@ nVidia nv50 Driver for the nVidia nv50 family of GPUs. -VMWare SVGA +VMware SVGA ^^^^^^^^^^^ -Driver for VMWare virtualized guest operating system graphics processing. +Driver for VMware virtualized guest operating system graphics processing. ATI r300 ^^^^^^^^ diff --git a/src/gallium/drivers/cell/common.h b/src/gallium/drivers/cell/common.h index bbb112fd336..a8cdde34aa7 100644 --- a/src/gallium/drivers/cell/common.h +++ b/src/gallium/drivers/cell/common.h @@ -230,7 +230,7 @@ struct cell_command_rasterizer { opcode_t opcode; /**< CELL_CMD_STATE_RASTERIZER */ struct pipe_rasterizer_state rasterizer; - uint32_t pad[1]; + /*uint32_t pad[1];*/ }; diff --git a/src/gallium/drivers/cell/ppu/cell_context.h b/src/gallium/drivers/cell/ppu/cell_context.h index 07b6eebc69c..d1aee62ba1e 100644 --- a/src/gallium/drivers/cell/ppu/cell_context.h +++ b/src/gallium/drivers/cell/ppu/cell_context.h @@ -132,6 +132,7 @@ struct cell_context struct pipe_viewport_state viewport; struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS]; uint num_vertex_buffers; + struct pipe_index_buffer index_buffer; ubyte *cbuf_map[PIPE_MAX_COLOR_BUFS]; ubyte *zsbuf_map; @@ -154,7 +155,7 @@ struct cell_context struct vertex_info vertex_info; /** Mapped constant buffers */ - void *mapped_constants[PIPE_SHADER_TYPES]; + const void *mapped_constants[PIPE_SHADER_TYPES]; PIPE_ALIGN_VAR(16) struct cell_spu_function_info spu_functions; diff --git a/src/gallium/drivers/cell/ppu/cell_draw_arrays.c b/src/gallium/drivers/cell/ppu/cell_draw_arrays.c index 6a1e4d8a646..4adef5b8c07 100644 --- a/src/gallium/drivers/cell/ppu/cell_draw_arrays.c +++ b/src/gallium/drivers/cell/ppu/cell_draw_arrays.c @@ -56,16 +56,11 @@ * XXX should the element buffer be specified/bound with a separate function? */ static void -cell_draw_range_elements(struct pipe_context *pipe, - struct pipe_resource *indexBuffer, - unsigned indexSize, - int indexBias, - unsigned min_index, - unsigned max_index, - unsigned mode, unsigned start, unsigned count) +cell_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info) { struct cell_context *cell = cell_context(pipe); struct draw_context *draw = cell->draw; + void *mapped_indices = NULL; unsigned i; if (cell->dirty) @@ -83,18 +78,20 @@ cell_draw_range_elements(struct pipe_context *pipe, draw_set_mapped_vertex_buffer(draw, i, buf); } /* Map index buffer, if present */ - if (indexBuffer) { - void *mapped_indexes = cell_resource(indexBuffer)->data; - draw_set_mapped_element_buffer(draw, indexSize, indexBias, mapped_indexes); - } - else { - /* no index/element buffer */ - draw_set_mapped_element_buffer(draw, 0, 0, NULL); + if (info->indexed && cell->index_buffer.buffer) { + mapped_indices = cell_resource(cell->index_buffer.buffer)->data; + mapped_indices += cell->index_buffer.offset; } + draw_set_mapped_element_buffer_range(draw, (mapped_indices) ? + lp->index_buffer.index_size : 0, + info->index_bias, + info->min_index, + info->max_index, + mapped_indices); /* draw! */ - draw_arrays(draw, mode, start, count); + draw_arrays(draw, info->mode, info->start, info->count); /* * unmap vertex/index buffers - will cause draw module to flush @@ -102,7 +99,7 @@ cell_draw_range_elements(struct pipe_context *pipe, for (i = 0; i < cell->num_vertex_buffers; i++) { draw_set_mapped_vertex_buffer(draw, i, NULL); } - if (indexBuffer) { + if (mapped_indices) { draw_set_mapped_element_buffer(draw, 0, 0, NULL); } @@ -115,32 +112,9 @@ cell_draw_range_elements(struct pipe_context *pipe, } -static void -cell_draw_elements(struct pipe_context *pipe, - struct pipe_resource *indexBuffer, - unsigned indexSize, int indexBias, - unsigned mode, unsigned start, unsigned count) -{ - cell_draw_range_elements( pipe, indexBuffer, - indexSize, indexBias, - 0, 0xffffffff, - mode, start, count ); -} - - -static void -cell_draw_arrays(struct pipe_context *pipe, unsigned mode, - unsigned start, unsigned count) -{ - cell_draw_elements(pipe, NULL, 0, 0, mode, start, count); -} - - void cell_init_draw_functions(struct cell_context *cell) { - cell->pipe.draw_arrays = cell_draw_arrays; - cell->pipe.draw_elements = cell_draw_elements; - cell->pipe.draw_range_elements = cell_draw_range_elements; + cell->pipe.draw_vbo = cell_draw_vbo; } diff --git a/src/gallium/drivers/cell/ppu/cell_fence.c b/src/gallium/drivers/cell/ppu/cell_fence.c index 34ca864155b..e7c9fc46d9f 100644 --- a/src/gallium/drivers/cell/ppu/cell_fence.c +++ b/src/gallium/drivers/cell/ppu/cell_fence.c @@ -87,6 +87,7 @@ struct cell_buffer_node }; +#if 0 static void cell_add_buffer_to_list(struct cell_context *cell, struct cell_buffer_list *list, @@ -100,6 +101,7 @@ cell_add_buffer_to_list(struct cell_context *cell, list->head = node; } } +#endif /** @@ -113,7 +115,7 @@ cell_free_fenced_buffers(struct cell_context *cell, struct cell_buffer_list *list) { if (list->head) { - struct pipe_screen *ps = cell->pipe.screen; + /*struct pipe_screen *ps = cell->pipe.screen;*/ struct cell_buffer_node *node; cell_fence_finish(cell, &list->fence); @@ -146,7 +148,7 @@ cell_free_fenced_buffers(struct cell_context *cell, void cell_add_fenced_textures(struct cell_context *cell) { - struct cell_buffer_list *list = &cell->fenced_buffers[cell->cur_batch]; + /*struct cell_buffer_list *list = &cell->fenced_buffers[cell->cur_batch];*/ uint i; for (i = 0; i < cell->num_textures; i++) { diff --git a/src/gallium/drivers/cell/ppu/cell_pipe_state.c b/src/gallium/drivers/cell/ppu/cell_pipe_state.c index 03f84d295b5..223adda48f0 100644 --- a/src/gallium/drivers/cell/ppu/cell_pipe_state.c +++ b/src/gallium/drivers/cell/ppu/cell_pipe_state.c @@ -281,7 +281,7 @@ cell_set_fragment_sampler_views(struct pipe_context *pipe, struct pipe_resource *new_tex = new_view ? new_view->texture : NULL; pipe_sampler_view_reference(&cell->fragment_sampler_views[i], - views[i]); + new_view); pipe_resource_reference((struct pipe_resource **) &cell->texture[i], (struct pipe_resource *) new_tex); diff --git a/src/gallium/drivers/cell/ppu/cell_state_vertex.c b/src/gallium/drivers/cell/ppu/cell_state_vertex.c index 9510ea9ac2b..4e3701cd0ac 100644 --- a/src/gallium/drivers/cell/ppu/cell_state_vertex.c +++ b/src/gallium/drivers/cell/ppu/cell_state_vertex.c @@ -36,7 +36,7 @@ #include "draw/draw_context.h" -void * +static void * cell_create_vertex_elements_state(struct pipe_context *pipe, unsigned count, const struct pipe_vertex_element *attribs) @@ -51,7 +51,7 @@ cell_create_vertex_elements_state(struct pipe_context *pipe, return velems; } -void +static void cell_bind_vertex_elements_state(struct pipe_context *pipe, void *velems) { @@ -66,7 +66,7 @@ cell_bind_vertex_elements_state(struct pipe_context *pipe, draw_set_vertex_elements(cell->draw, cell_velems->count, cell_velems->velem); } -void +static void cell_delete_vertex_elements_state(struct pipe_context *pipe, void *velems) { FREE( velems ); @@ -91,10 +91,26 @@ cell_set_vertex_buffers(struct pipe_context *pipe, } +static void +cell_set_index_buffer(struct pipe_context *pipe, + const struct pipe_index_buffer *ib) +{ + struct cell_context *cell = cell_context(pipe); + + if (ib) + memcpy(&cell->index_buffer, ib, sizeof(cell->index_buffer)); + else + memset(&cell->index_buffer, 0, sizeof(cell->index_buffer)); + + /* TODO make this more like a state */ +} + + void cell_init_vertex_functions(struct cell_context *cell) { cell->pipe.set_vertex_buffers = cell_set_vertex_buffers; + cell->pipe.set_index_buffer = cell_set_index_buffer; cell->pipe.create_vertex_elements_state = cell_create_vertex_elements_state; cell->pipe.bind_vertex_elements_state = cell_bind_vertex_elements_state; cell->pipe.delete_vertex_elements_state = cell_delete_vertex_elements_state; diff --git a/src/gallium/drivers/failover/fo_context.c b/src/gallium/drivers/failover/fo_context.c index 9c9c1bdc452..761a0fce721 100644 --- a/src/gallium/drivers/failover/fo_context.c +++ b/src/gallium/drivers/failover/fo_context.c @@ -50,13 +50,8 @@ void failover_fail_over( struct failover_context *failover ) } -static void failover_draw_elements( struct pipe_context *pipe, - struct pipe_resource *indexResource, - unsigned indexSize, - int indexBias, - unsigned prim, - unsigned start, - unsigned count) +static void failover_draw_vbo( struct pipe_context *pipe, + const struct pipe_draw_info *info) { struct failover_context *failover = failover_context( pipe ); @@ -70,13 +65,7 @@ static void failover_draw_elements( struct pipe_context *pipe, /* Try hardware: */ if (failover->mode == FO_HW) { - failover->hw->draw_elements( failover->hw, - indexResource, - indexSize, - indexBias, - prim, - start, - count ); + failover->hw->draw_vbo( failover->hw, info ); } /* Possibly try software: @@ -88,13 +77,7 @@ static void failover_draw_elements( struct pipe_context *pipe, failover_state_emit( failover ); } - failover->sw->draw_elements( failover->sw, - indexResource, - indexSize, - indexBias, - prim, - start, - count ); + failover->sw->draw_vbo( failover->sw, info ); /* Be ready to switch back to hardware rendering without an * intervening flush. Unlikely to be much performance impact to @@ -104,13 +87,6 @@ static void failover_draw_elements( struct pipe_context *pipe, } } - -static void failover_draw_arrays( struct pipe_context *pipe, - unsigned prim, unsigned start, unsigned count) -{ - failover_draw_elements(pipe, NULL, 0, 0, prim, start, count); -} - static unsigned int failover_is_resource_referenced( struct pipe_context *_pipe, struct pipe_resource *resource, @@ -143,8 +119,7 @@ struct pipe_context *failover_create( struct pipe_context *hw, failover->pipe.get_paramf = hw->get_paramf; #endif - failover->pipe.draw_arrays = failover_draw_arrays; - failover->pipe.draw_elements = failover_draw_elements; + failover->pipe.draw_vbo = failover_draw_vbo; failover->pipe.clear = hw->clear; failover->pipe.clear_render_target = hw->clear_render_target; failover->pipe.clear_depth_stencil = hw->clear_depth_stencil; diff --git a/src/gallium/drivers/failover/fo_context.h b/src/gallium/drivers/failover/fo_context.h index 9d3e0d0dba0..1afa6c9ceed 100644 --- a/src/gallium/drivers/failover/fo_context.h +++ b/src/gallium/drivers/failover/fo_context.h @@ -56,6 +56,7 @@ #define FO_NEW_VERTEX_BUFFER 0x40000 #define FO_NEW_VERTEX_ELEMENT 0x80000 #define FO_NEW_SAMPLE_MASK 0x100000 +#define FO_NEW_INDEX_BUFFER 0x200000 @@ -97,6 +98,7 @@ struct failover_context { struct pipe_scissor_state scissor; struct pipe_viewport_state viewport; struct pipe_vertex_buffer vertex_buffers[PIPE_MAX_ATTRIBS]; + struct pipe_index_buffer index_buffer; uint num_vertex_buffers; diff --git a/src/gallium/drivers/failover/fo_state.c b/src/gallium/drivers/failover/fo_state.c index 12e42379f98..c265f381b67 100644 --- a/src/gallium/drivers/failover/fo_state.c +++ b/src/gallium/drivers/failover/fo_state.c @@ -583,6 +583,23 @@ failover_set_vertex_buffers(struct pipe_context *pipe, } +static void +failover_set_index_buffer(struct pipe_context *pipe, + const struct pipe_index_buffer *ib) +{ + struct failover_context *failover = failover_context(pipe); + + if (ib) + memcpy(&failover->index_buffer, ib, sizeof(failover->index_buffer)); + else + memset(&failover->index_buffer, 0, sizeof(failover->index_buffer)); + + failover->dirty |= FO_NEW_INDEX_BUFFER; + failover->sw->set_index_buffer( failover->sw, ib ); + failover->hw->set_index_buffer( failover->hw, ib ); +} + + void failover_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index, @@ -635,6 +652,7 @@ failover_init_state_functions( struct failover_context *failover ) failover->pipe.set_vertex_sampler_views = failover_set_vertex_sampler_views; failover->pipe.set_viewport_state = failover_set_viewport_state; failover->pipe.set_vertex_buffers = failover_set_vertex_buffers; + failover->pipe.set_index_buffer = failover_set_index_buffer; failover->pipe.set_constant_buffer = failover_set_constant_buffer; failover->pipe.create_sampler_view = failover_create_sampler_view; failover->pipe.sampler_view_destroy = failover_sampler_view_destroy; diff --git a/src/gallium/drivers/failover/fo_state_emit.c b/src/gallium/drivers/failover/fo_state_emit.c index 147f23269ca..7f434ff9d68 100644 --- a/src/gallium/drivers/failover/fo_state_emit.c +++ b/src/gallium/drivers/failover/fo_state_emit.c @@ -135,5 +135,10 @@ failover_state_emit( struct failover_context *failover ) failover->vertex_buffers ); } + if (failover->dirty & FO_NEW_INDEX_BUFFER) { + failover->sw->set_index_buffer( failover->sw, + &failover->index_buffer ); + } + failover->dirty = 0; } diff --git a/src/gallium/drivers/galahad/glhd_context.c b/src/gallium/drivers/galahad/glhd_context.c index ab6f17b3ab8..fe14a287efb 100644 --- a/src/gallium/drivers/galahad/glhd_context.c +++ b/src/gallium/drivers/galahad/glhd_context.c @@ -48,68 +48,13 @@ galahad_destroy(struct pipe_context *_pipe) } static void -galahad_draw_arrays(struct pipe_context *_pipe, - unsigned prim, - unsigned start, - unsigned count) +galahad_draw_vbo(struct pipe_context *_pipe, + const struct pipe_draw_info *info) { struct galahad_context *glhd_pipe = galahad_context(_pipe); struct pipe_context *pipe = glhd_pipe->pipe; - pipe->draw_arrays(pipe, - prim, - start, - count); -} - -static void -galahad_draw_elements(struct pipe_context *_pipe, - struct pipe_resource *_indexResource, - unsigned indexSize, - int indexBias, - unsigned prim, - unsigned start, - unsigned count) -{ - struct galahad_context *glhd_pipe = galahad_context(_pipe); - struct galahad_resource *glhd_resource = galahad_resource(_indexResource); - struct pipe_context *pipe = glhd_pipe->pipe; - struct pipe_resource *indexResource = glhd_resource->resource; - - pipe->draw_elements(pipe, - indexResource, - indexSize, - indexBias, - prim, - start, - count); -} - -static void -galahad_draw_range_elements(struct pipe_context *_pipe, - struct pipe_resource *_indexResource, - unsigned indexSize, - int indexBias, - unsigned minIndex, - unsigned maxIndex, - unsigned mode, - unsigned start, - unsigned count) -{ - struct galahad_context *glhd_pipe = galahad_context(_pipe); - struct galahad_resource *glhd_resource = galahad_resource(_indexResource); - struct pipe_context *pipe = glhd_pipe->pipe; - struct pipe_resource *indexResource = glhd_resource->resource; - - pipe->draw_range_elements(pipe, - indexResource, - indexSize, - indexBias, - minIndex, - maxIndex, - mode, - start, - count); + pipe->draw_vbo(pipe, info); } static struct pipe_query * @@ -650,6 +595,41 @@ galahad_set_vertex_buffers(struct pipe_context *_pipe, num_buffers, buffers); } + +static void +galahad_set_index_buffer(struct pipe_context *_pipe, + const struct pipe_index_buffer *_ib) +{ + struct galahad_context *glhd_pipe = galahad_context(_pipe); + struct pipe_context *pipe = glhd_pipe->pipe; + struct pipe_index_buffer unwrapped_ib, *ib = NULL; + + if (_ib->buffer) { + switch (_ib->index_size) { + case 1: + case 2: + case 4: + break; + default: + glhd_warn("index buffer %p has unrecognized index size %d", + _ib->buffer, _ib->index_size); + break; + } + } + else if (_ib->offset || _ib->index_size) { + glhd_warn("non-indexed state with index offset %d and index size %d", + _ib->offset, _ib->index_size); + } + + if (_ib) { + unwrapped_ib = *_ib; + unwrapped_ib.buffer = galahad_resource_unwrap(_ib->buffer); + ib = &unwrapped_ib; + } + + pipe->set_index_buffer(pipe, ib); +} + static void galahad_resource_copy_region(struct pipe_context *_pipe, struct pipe_resource *_dst, @@ -934,9 +914,7 @@ galahad_context_create(struct pipe_screen *_screen, struct pipe_context *pipe) glhd_pipe->base.draw = NULL; glhd_pipe->base.destroy = galahad_destroy; - glhd_pipe->base.draw_arrays = galahad_draw_arrays; - glhd_pipe->base.draw_elements = galahad_draw_elements; - glhd_pipe->base.draw_range_elements = galahad_draw_range_elements; + glhd_pipe->base.draw_vbo = galahad_draw_vbo; glhd_pipe->base.create_query = galahad_create_query; glhd_pipe->base.destroy_query = galahad_destroy_query; glhd_pipe->base.begin_query = galahad_begin_query; @@ -976,6 +954,7 @@ galahad_context_create(struct pipe_screen *_screen, struct pipe_context *pipe) glhd_pipe->base.set_fragment_sampler_views = galahad_set_fragment_sampler_views; glhd_pipe->base.set_vertex_sampler_views = galahad_set_vertex_sampler_views; glhd_pipe->base.set_vertex_buffers = galahad_set_vertex_buffers; + glhd_pipe->base.set_index_buffer = galahad_set_index_buffer; glhd_pipe->base.resource_copy_region = galahad_resource_copy_region; glhd_pipe->base.clear = galahad_clear; glhd_pipe->base.clear_render_target = galahad_clear_render_target; diff --git a/src/gallium/drivers/i915/i915_context.c b/src/gallium/drivers/i915/i915_context.c index 2af9bdac956..2beb9e3091f 100644 --- a/src/gallium/drivers/i915/i915_context.c +++ b/src/gallium/drivers/i915/i915_context.c @@ -45,16 +45,11 @@ static void -i915_draw_range_elements(struct pipe_context *pipe, - struct pipe_resource *indexBuffer, - unsigned indexSize, - int indexBias, - unsigned min_index, - unsigned max_index, - unsigned prim, unsigned start, unsigned count) +i915_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info) { struct i915_context *i915 = i915_context(pipe); struct draw_context *draw = i915->draw; + void *mapped_indices = NULL; unsigned i; if (i915->dirty) @@ -71,16 +66,18 @@ i915_draw_range_elements(struct pipe_context *pipe, /* * Map index buffer, if present */ - if (indexBuffer) { - void *mapped_indexes = i915_buffer(indexBuffer)->data; - draw_set_mapped_element_buffer_range(draw, indexSize, indexBias, - min_index, - max_index, - mapped_indexes); - } else { - draw_set_mapped_element_buffer(draw, 0, 0, NULL); + if (info->indexed && i915->index_buffer.buffer) { + char *indices = (char *) i915_buffer(i915->index_buffer.buffer)->data; + mapped_indices = (void *) (indices + i915->index_buffer.offset); } + draw_set_mapped_element_buffer_range(draw, (mapped_indices) ? + i915->index_buffer.index_size : 0, + info->index_bias, + info->min_index, + info->max_index, + mapped_indices); + draw_set_mapped_constant_buffer(draw, PIPE_SHADER_VERTEX, 0, i915->current.constants[PIPE_SHADER_VERTEX], @@ -90,7 +87,7 @@ i915_draw_range_elements(struct pipe_context *pipe, /* * Do the drawing */ - draw_arrays(i915->draw, prim, start, count); + draw_arrays(i915->draw, info->mode, info->start, info->count); /* * unmap vertex/index buffers @@ -99,32 +96,11 @@ i915_draw_range_elements(struct pipe_context *pipe, draw_set_mapped_vertex_buffer(draw, i, NULL); } - if (indexBuffer) { + if (mapped_indices) { draw_set_mapped_element_buffer(draw, 0, 0, NULL); } } -static void -i915_draw_elements(struct pipe_context *pipe, - struct pipe_resource *indexBuffer, - unsigned indexSize, int indexBias, - unsigned prim, unsigned start, unsigned count) -{ - i915_draw_range_elements(pipe, indexBuffer, - indexSize, indexBias, - 0, 0xffffffff, - prim, start, count); -} - -static void -i915_draw_arrays(struct pipe_context *pipe, - unsigned prim, unsigned start, unsigned count) -{ - i915_draw_elements(pipe, NULL, 0, 0, prim, start, count); -} - - - /* * Generic context functions @@ -168,9 +144,7 @@ i915_create_context(struct pipe_screen *screen, void *priv) i915->base.clear = i915_clear; - i915->base.draw_arrays = i915_draw_arrays; - i915->base.draw_elements = i915_draw_elements; - i915->base.draw_range_elements = i915_draw_range_elements; + i915->base.draw_vbo = i915_draw_vbo; /* * Create drawing context and plug our rendering stage into it. diff --git a/src/gallium/drivers/i915/i915_context.h b/src/gallium/drivers/i915/i915_context.h index b210cb130d0..3ae61d0ea70 100644 --- a/src/gallium/drivers/i915/i915_context.h +++ b/src/gallium/drivers/i915/i915_context.h @@ -221,6 +221,7 @@ struct i915_context struct pipe_sampler_view *fragment_sampler_views[PIPE_MAX_SAMPLERS]; struct pipe_viewport_state viewport; struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS]; + struct pipe_index_buffer index_buffer; unsigned dirty; diff --git a/src/gallium/drivers/i915/i915_state.c b/src/gallium/drivers/i915/i915_state.c index e767aa9f8f0..385c3b2d2d3 100644 --- a/src/gallium/drivers/i915/i915_state.c +++ b/src/gallium/drivers/i915/i915_state.c @@ -812,6 +812,19 @@ i915_delete_vertex_elements_state(struct pipe_context *pipe, void *velems) FREE( velems ); } +static void i915_set_index_buffer(struct pipe_context *pipe, + const struct pipe_index_buffer *ib) +{ + struct i915_context *i915 = i915_context(pipe); + + if (ib) + memcpy(&i915->index_buffer, ib, sizeof(i915->index_buffer)); + else + memset(&i915->index_buffer, 0, sizeof(i915->index_buffer)); + + /* TODO make this more like a state */ +} + static void i915_set_sample_mask(struct pipe_context *pipe, unsigned sample_mask) @@ -860,4 +873,5 @@ i915_init_state_functions( struct i915_context *i915 ) i915->base.sampler_view_destroy = i915_sampler_view_destroy; i915->base.set_viewport_state = i915_set_viewport_state; i915->base.set_vertex_buffers = i915_set_vertex_buffers; + i915->base.set_index_buffer = i915_set_index_buffer; } diff --git a/src/gallium/drivers/i965/brw_context.h b/src/gallium/drivers/i965/brw_context.h index 94c9c443f05..56d351f97d1 100644 --- a/src/gallium/drivers/i965/brw_context.h +++ b/src/gallium/drivers/i965/brw_context.h @@ -576,6 +576,7 @@ struct brw_context */ struct pipe_resource *index_buffer; unsigned index_size; + unsigned index_offset; /* Updates are signalled by PIPE_NEW_INDEX_RANGE: */ diff --git a/src/gallium/drivers/i965/brw_draw.c b/src/gallium/drivers/i965/brw_draw.c index 4625c2048f9..3ab9024c31e 100644 --- a/src/gallium/drivers/i965/brw_draw.c +++ b/src/gallium/drivers/i965/brw_draw.c @@ -142,7 +142,7 @@ static int brw_emit_prim(struct brw_context *brw, */ static int try_draw_range_elements(struct brw_context *brw, - struct pipe_resource *index_buffer, + boolean indexed, unsigned hw_prim, unsigned start, unsigned count) { @@ -165,7 +165,7 @@ try_draw_range_elements(struct brw_context *brw, if (ret) return ret; - ret = brw_emit_prim(brw, start, count, index_buffer != NULL, hw_prim); + ret = brw_emit_prim(brw, start, count, indexed, hw_prim); if (ret) return ret; @@ -177,91 +177,54 @@ try_draw_range_elements(struct brw_context *brw, static void -brw_draw_range_elements(struct pipe_context *pipe, - struct pipe_resource *index_buffer, - unsigned index_size, int index_bias, - unsigned min_index, - unsigned max_index, - unsigned mode, unsigned start, unsigned count) +brw_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info) { struct brw_context *brw = brw_context(pipe); int ret; uint32_t hw_prim; - hw_prim = brw_set_prim(brw, mode); + hw_prim = brw_set_prim(brw, info->mode); if (BRW_DEBUG & DEBUG_PRIMS) debug_printf("PRIM: %s start %d count %d index_buffer %p\n", - u_prim_name(mode), start, count, (void *)index_buffer); + u_prim_name(info->mode), info->start, info->count, + (void *) brw->curr.index_buffer); - assert(index_bias == 0); + assert(info->index_bias == 0); - /* Potentially trigger upload of new index buffer. - * - * XXX: do we need to go through state validation to achieve this? - * Could just call upload code directly. + /* Potentially trigger upload of new index buffer range. + * XXX: do we really care? */ - if (brw->curr.index_buffer != index_buffer || - brw->curr.index_size != index_size) { - pipe_resource_reference( &brw->curr.index_buffer, index_buffer ); - brw->curr.index_size = index_size; - brw->state.dirty.mesa |= PIPE_NEW_INDEX_BUFFER; - } - - /* XXX: do we really care? - */ - if (brw->curr.min_index != min_index || - brw->curr.max_index != max_index) + if (brw->curr.min_index != info->min_index || + brw->curr.max_index != info->max_index) { - brw->curr.min_index = min_index; - brw->curr.max_index = max_index; + brw->curr.min_index = info->min_index; + brw->curr.max_index = info->max_index; brw->state.dirty.mesa |= PIPE_NEW_INDEX_RANGE; } /* Make a first attempt at drawing: */ - ret = try_draw_range_elements(brw, index_buffer, hw_prim, start, count ); + ret = try_draw_range_elements(brw, info->indexed, + hw_prim, info->start, info->count); /* Otherwise, flush and retry: */ if (ret != 0) { brw_context_flush( brw ); - ret = try_draw_range_elements(brw, index_buffer, hw_prim, start, count ); + ret = try_draw_range_elements(brw, info->indexed, + hw_prim, info->start, info->count); assert(ret == 0); } } -static void -brw_draw_elements(struct pipe_context *pipe, - struct pipe_resource *index_buffer, - unsigned index_size, int index_bias, - unsigned mode, - unsigned start, unsigned count) -{ - brw_draw_range_elements( pipe, index_buffer, - index_size, index_bias, - 0, 0xffffffff, - mode, - start, count ); -} - -static void -brw_draw_arrays(struct pipe_context *pipe, unsigned mode, - unsigned start, unsigned count) -{ - brw_draw_elements(pipe, NULL, 0, 0, mode, start, count); -} - - boolean brw_draw_init( struct brw_context *brw ) { /* Register our drawing function: */ - brw->base.draw_arrays = brw_draw_arrays; - brw->base.draw_elements = brw_draw_elements; - brw->base.draw_range_elements = brw_draw_range_elements; + brw->base.draw_vbo = brw_draw_vbo; /* Create helpers for uploading data in user buffers: */ diff --git a/src/gallium/drivers/i965/brw_draw_upload.c b/src/gallium/drivers/i965/brw_draw_upload.c index 337eee8cd9c..ebeb1e146aa 100644 --- a/src/gallium/drivers/i965/brw_draw_upload.c +++ b/src/gallium/drivers/i965/brw_draw_upload.c @@ -231,7 +231,7 @@ static int brw_prepare_indices(struct brw_context *brw) struct pipe_resource *upload_buf = NULL; struct brw_winsys_buffer *bo = NULL; GLuint offset; - GLuint index_size; + GLuint index_size, index_offset; GLuint ib_size; int ret; @@ -246,13 +246,14 @@ static int brw_prepare_indices(struct brw_context *brw) ib_size = index_buffer->width0; index_size = brw->curr.index_size; + index_offset = brw->curr.index_offset; /* Turn userbuffer into a proper hardware buffer? */ if (brw_buffer_is_user_buffer(index_buffer)) { ret = u_upload_buffer( brw->vb.upload_index, - 0, + index_offset, ib_size, index_buffer, &offset, @@ -269,7 +270,7 @@ static int brw_prepare_indices(struct brw_context *brw) else { bo = brw_buffer(index_buffer)->bo; ib_size = bo->size; - offset = 0; + offset = index_offset; } /* Use CMD_3D_PRIM's start_vertex_offset to avoid re-uploading the diff --git a/src/gallium/drivers/i965/brw_pipe_vertex.c b/src/gallium/drivers/i965/brw_pipe_vertex.c index 4a120a51dad..007239efc40 100644 --- a/src/gallium/drivers/i965/brw_pipe_vertex.c +++ b/src/gallium/drivers/i965/brw_pipe_vertex.c @@ -274,10 +274,41 @@ static void brw_set_vertex_buffers(struct pipe_context *pipe, } +static void brw_set_index_buffer(struct pipe_context *pipe, + const struct pipe_index_buffer *ib) +{ + struct brw_context *brw = brw_context(pipe); + + if (ib) { + if (brw->curr.index_buffer == ib->buffer && + brw->curr.index_offset == ib->offset && + brw->curr.index_size == ib->index_size) + return; + + pipe_resource_reference(&brw->curr.index_buffer, ib->buffer); + brw->curr.index_offset = ib->offset; + brw->curr.index_size = ib->index_size; + } + else { + if (!brw->curr.index_buffer && + !brw->curr.index_offset && + !brw->curr.index_size) + return; + + pipe_resource_reference(&brw->curr.index_buffer, NULL); + brw->curr.index_offset = 0; + brw->curr.index_size = 0; + } + + brw->state.dirty.mesa |= PIPE_NEW_INDEX_BUFFER; +} + + void brw_pipe_vertex_init( struct brw_context *brw ) { brw->base.set_vertex_buffers = brw_set_vertex_buffers; + brw->base.set_index_buffer = brw_set_index_buffer; brw->base.create_vertex_elements_state = brw_create_vertex_elements_state; brw->base.bind_vertex_elements_state = brw_bind_vertex_elements_state; brw->base.delete_vertex_elements_state = brw_delete_vertex_elements_state; diff --git a/src/gallium/drivers/identity/id_context.c b/src/gallium/drivers/identity/id_context.c index 67be895b385..de83c249057 100644 --- a/src/gallium/drivers/identity/id_context.c +++ b/src/gallium/drivers/identity/id_context.c @@ -46,68 +46,13 @@ identity_destroy(struct pipe_context *_pipe) } static void -identity_draw_arrays(struct pipe_context *_pipe, - unsigned prim, - unsigned start, - unsigned count) +identity_draw_vbo(struct pipe_context *_pipe, + const struct pipe_draw_info *info) { struct identity_context *id_pipe = identity_context(_pipe); struct pipe_context *pipe = id_pipe->pipe; - pipe->draw_arrays(pipe, - prim, - start, - count); -} - -static void -identity_draw_elements(struct pipe_context *_pipe, - struct pipe_resource *_indexResource, - unsigned indexSize, - int indexBias, - unsigned prim, - unsigned start, - unsigned count) -{ - struct identity_context *id_pipe = identity_context(_pipe); - struct identity_resource *id_resource = identity_resource(_indexResource); - struct pipe_context *pipe = id_pipe->pipe; - struct pipe_resource *indexResource = id_resource->resource; - - pipe->draw_elements(pipe, - indexResource, - indexSize, - indexBias, - prim, - start, - count); -} - -static void -identity_draw_range_elements(struct pipe_context *_pipe, - struct pipe_resource *_indexResource, - unsigned indexSize, - int indexBias, - unsigned minIndex, - unsigned maxIndex, - unsigned mode, - unsigned start, - unsigned count) -{ - struct identity_context *id_pipe = identity_context(_pipe); - struct identity_resource *id_resource = identity_resource(_indexResource); - struct pipe_context *pipe = id_pipe->pipe; - struct pipe_resource *indexResource = id_resource->resource; - - pipe->draw_range_elements(pipe, - indexResource, - indexSize, - indexBias, - minIndex, - maxIndex, - mode, - start, - count); + pipe->draw_vbo(pipe, info); } static struct pipe_query * @@ -611,6 +556,24 @@ identity_set_vertex_buffers(struct pipe_context *_pipe, num_buffers, buffers); } + +static void +identity_set_index_buffer(struct pipe_context *_pipe, + const struct pipe_index_buffer *_ib) +{ + struct identity_context *id_pipe = identity_context(_pipe); + struct pipe_context *pipe = id_pipe->pipe; + struct pipe_index_buffer unwrapped_ib, *ib = NULL; + + if (_ib) { + unwrapped_ib = *_ib; + unwrapped_ib.buffer = identity_resource_unwrap(_ib->buffer); + ib = &unwrapped_ib; + } + + pipe->set_index_buffer(pipe, ib); +} + static void identity_resource_copy_region(struct pipe_context *_pipe, struct pipe_resource *_dst, @@ -889,9 +852,7 @@ identity_context_create(struct pipe_screen *_screen, struct pipe_context *pipe) id_pipe->base.draw = NULL; id_pipe->base.destroy = identity_destroy; - id_pipe->base.draw_arrays = identity_draw_arrays; - id_pipe->base.draw_elements = identity_draw_elements; - id_pipe->base.draw_range_elements = identity_draw_range_elements; + id_pipe->base.draw_vbo = identity_draw_vbo; id_pipe->base.create_query = identity_create_query; id_pipe->base.destroy_query = identity_destroy_query; id_pipe->base.begin_query = identity_begin_query; @@ -931,6 +892,7 @@ identity_context_create(struct pipe_screen *_screen, struct pipe_context *pipe) id_pipe->base.set_fragment_sampler_views = identity_set_fragment_sampler_views; id_pipe->base.set_vertex_sampler_views = identity_set_vertex_sampler_views; id_pipe->base.set_vertex_buffers = identity_set_vertex_buffers; + id_pipe->base.set_index_buffer = identity_set_index_buffer; id_pipe->base.resource_copy_region = identity_resource_copy_region; id_pipe->base.clear = identity_clear; id_pipe->base.clear_render_target = identity_clear_render_target; diff --git a/src/gallium/drivers/llvmpipe/SConscript b/src/gallium/drivers/llvmpipe/SConscript index fd6ba1561ea..5583fca38e6 100644 --- a/src/gallium/drivers/llvmpipe/SConscript +++ b/src/gallium/drivers/llvmpipe/SConscript @@ -1,3 +1,4 @@ +from sys import executable as python_cmd import distutils.version Import('*') @@ -16,7 +17,7 @@ env.CodeGenerate( target = 'lp_tile_soa.c', script = 'lp_tile_soa.py', source = ['#src/gallium/auxiliary/util/u_format.csv'], - command = 'python $SCRIPT $SOURCE > $TARGET' + command = python_cmd + ' $SCRIPT $SOURCE > $TARGET' ) # XXX: Our dependency scanner only finds depended modules in relative dirs. diff --git a/src/gallium/drivers/llvmpipe/lp_bld_depth.c b/src/gallium/drivers/llvmpipe/lp_bld_depth.c index e05bbe5011a..99a768afd80 100644 --- a/src/gallium/drivers/llvmpipe/lp_bld_depth.c +++ b/src/gallium/drivers/llvmpipe/lp_bld_depth.c @@ -258,16 +258,16 @@ lp_build_stencil_op_single(struct lp_build_context *bld, } if (stencil->writemask != stencilMax) { - /* compute res = (res & mask) | (stencilVals & ~mask) */ - LLVMValueRef mask = lp_build_const_int_vec(type, stencil->writemask); - LLVMValueRef cmask = LLVMBuildNot(bld->builder, mask, "notWritemask"); - LLVMValueRef t1 = LLVMBuildAnd(bld->builder, res, mask, "t1"); - LLVMValueRef t2 = LLVMBuildAnd(bld->builder, stencilVals, cmask, "t2"); - res = LLVMBuildOr(bld->builder, t1, t2, "t1_or_t2"); + /* mask &= stencil->writemask */ + LLVMValueRef writemask = lp_build_const_int_vec(type, stencil->writemask); + mask = LLVMBuildAnd(bld->builder, mask, writemask, ""); + /* res = (res & mask) | (stencilVals & ~mask) */ + res = lp_build_select_bitwise(bld, writemask, res, stencilVals); + } + else { + /* res = mask ? res : stencilVals */ + res = lp_build_select(bld, mask, res, stencilVals); } - - /* only the update the vector elements enabled by 'mask' */ - res = lp_build_select(bld, mask, res, stencilVals); return res; } @@ -662,9 +662,9 @@ lp_build_depth_stencil_test(LLVMBuilderRef builder, } /* Mix the old and new Z buffer values. - * z_dst[i] = zselectmask[i] ? z_src[i] : z_dst[i] + * z_dst[i] = (zselectmask[i] & z_src[i]) | (~zselectmask[i] & z_dst[i]) */ - z_dst = lp_build_select(&bld, zselectmask, z_src, z_dst); + z_dst = lp_build_select_bitwise(&bld, zselectmask, z_src, z_dst); } if (stencil[0].enabled) { diff --git a/src/gallium/drivers/llvmpipe/lp_context.c b/src/gallium/drivers/llvmpipe/lp_context.c index 3db4f12ebb6..28793682edf 100644 --- a/src/gallium/drivers/llvmpipe/lp_context.c +++ b/src/gallium/drivers/llvmpipe/lp_context.c @@ -46,6 +46,10 @@ #include "lp_query.h" #include "lp_setup.h" + +DEBUG_GET_ONCE_BOOL_OPTION(lp_no_rast, "LP_NO_RAST", FALSE); + + static void llvmpipe_destroy( struct pipe_context *pipe ) { struct llvmpipe_context *llvmpipe = llvmpipe_context( pipe ); @@ -130,7 +134,7 @@ llvmpipe_create_context( struct pipe_screen *screen, void *priv ) /* FIXME: devise alternative to draw_texture_samplers */ - if (debug_get_bool_option( "LP_NO_RAST", FALSE )) + if (debug_get_option_lp_no_rast()) llvmpipe->no_rast = TRUE; llvmpipe->setup = lp_setup_create( &llvmpipe->pipe, diff --git a/src/gallium/drivers/llvmpipe/lp_context.h b/src/gallium/drivers/llvmpipe/lp_context.h index b2643ab33cd..50f9091c3ca 100644 --- a/src/gallium/drivers/llvmpipe/lp_context.h +++ b/src/gallium/drivers/llvmpipe/lp_context.h @@ -77,6 +77,7 @@ struct llvmpipe_context { struct pipe_sampler_view *vertex_sampler_views[PIPE_MAX_VERTEX_SAMPLERS]; struct pipe_viewport_state viewport; struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS]; + struct pipe_index_buffer index_buffer; struct { struct llvmpipe_resource *buffer[PIPE_MAX_SO_BUFFERS]; int offset[PIPE_MAX_SO_BUFFERS]; diff --git a/src/gallium/drivers/llvmpipe/lp_draw_arrays.c b/src/gallium/drivers/llvmpipe/lp_draw_arrays.c index 625d0c8a8c9..e73b431cb4d 100644 --- a/src/gallium/drivers/llvmpipe/lp_draw_arrays.c +++ b/src/gallium/drivers/llvmpipe/lp_draw_arrays.c @@ -49,20 +49,11 @@ * the drawing to the 'draw' module. */ static void -llvmpipe_draw_range_elements_instanced(struct pipe_context *pipe, - struct pipe_resource *indexBuffer, - unsigned indexSize, - int indexBias, - unsigned minIndex, - unsigned maxIndex, - unsigned mode, - unsigned start, - unsigned count, - unsigned startInstance, - unsigned instanceCount) +llvmpipe_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info) { struct llvmpipe_context *lp = llvmpipe_context(pipe); struct draw_context *draw = lp->draw; + void *mapped_indices = NULL; unsigned i; if (lp->dirty) @@ -77,27 +68,25 @@ llvmpipe_draw_range_elements_instanced(struct pipe_context *pipe, } /* Map index buffer, if present */ - if (indexBuffer) { - void *mapped_indexes = llvmpipe_resource_data(indexBuffer); - draw_set_mapped_element_buffer_range(draw, - indexSize, - indexBias, - minIndex, - maxIndex, - mapped_indexes); - } - else { - /* no index/element buffer */ - draw_set_mapped_element_buffer_range(draw, 0, 0, start, - start + count - 1, NULL); + if (info->indexed && lp->index_buffer.buffer) { + char *indices = (char *) llvmpipe_resource_data(lp->index_buffer.buffer); + mapped_indices = (void *) (indices + lp->index_buffer.offset); } + + draw_set_mapped_element_buffer_range(draw, (mapped_indices) ? + lp->index_buffer.index_size : 0, + info->index_bias, + info->min_index, + info->max_index, + mapped_indices); + llvmpipe_prepare_vertex_sampling(lp, lp->num_vertex_sampler_views, lp->vertex_sampler_views); /* draw! */ - draw_arrays_instanced(draw, mode, start, count, - startInstance, instanceCount); + draw_arrays_instanced(draw, info->mode, info->start, info->count, + info->start_instance, info->instance_count); /* * unmap vertex/index buffers @@ -105,7 +94,7 @@ llvmpipe_draw_range_elements_instanced(struct pipe_context *pipe, for (i = 0; i < lp->num_vertex_buffers; i++) { draw_set_mapped_vertex_buffer(draw, i, NULL); } - if (indexBuffer) { + if (mapped_indices) { draw_set_mapped_element_buffer(draw, 0, 0, NULL); } llvmpipe_cleanup_vertex_sampling(lp); @@ -119,112 +108,8 @@ llvmpipe_draw_range_elements_instanced(struct pipe_context *pipe, } -static void -llvmpipe_draw_arrays_instanced(struct pipe_context *pipe, - unsigned mode, - unsigned start, - unsigned count, - unsigned startInstance, - unsigned instanceCount) -{ - llvmpipe_draw_range_elements_instanced(pipe, - NULL, /* no indexBuffer */ - 0, 0, /* indexSize, indexBias */ - 0, ~0, /* minIndex, maxIndex */ - mode, - start, - count, - startInstance, - instanceCount); -} - - -static void -llvmpipe_draw_elements_instanced(struct pipe_context *pipe, - struct pipe_resource *indexBuffer, - unsigned indexSize, - int indexBias, - unsigned mode, - unsigned start, - unsigned count, - unsigned startInstance, - unsigned instanceCount) -{ - llvmpipe_draw_range_elements_instanced(pipe, - indexBuffer, - indexSize, indexBias, - 0, ~0, /* minIndex, maxIndex */ - mode, - start, - count, - startInstance, - instanceCount); -} - - -static void -llvmpipe_draw_elements(struct pipe_context *pipe, - struct pipe_resource *indexBuffer, - unsigned indexSize, - int indexBias, - unsigned mode, - unsigned start, - unsigned count) -{ - llvmpipe_draw_range_elements_instanced(pipe, - indexBuffer, - indexSize, indexBias, - 0, 0xffffffff, /* min, maxIndex */ - mode, start, count, - 0, /* startInstance */ - 1); /* instanceCount */ -} - - -static void -llvmpipe_draw_range_elements(struct pipe_context *pipe, - struct pipe_resource *indexBuffer, - unsigned indexSize, - int indexBias, - unsigned min_index, - unsigned max_index, - unsigned mode, - unsigned start, - unsigned count) -{ - llvmpipe_draw_range_elements_instanced(pipe, - indexBuffer, - indexSize, indexBias, - min_index, max_index, - mode, start, count, - 0, /* startInstance */ - 1); /* instanceCount */ -} - - -static void -llvmpipe_draw_arrays(struct pipe_context *pipe, - unsigned mode, - unsigned start, - unsigned count) -{ - llvmpipe_draw_range_elements_instanced(pipe, - NULL, /* indexBuffer */ - 0, /* indexSize */ - 0, /* indexBias */ - 0, ~0, /* min, maxIndex */ - mode, start, count, - 0, /* startInstance */ - 1); /* instanceCount */ -} - - void llvmpipe_init_draw_funcs(struct llvmpipe_context *llvmpipe) { - llvmpipe->pipe.draw_arrays = llvmpipe_draw_arrays; - llvmpipe->pipe.draw_elements = llvmpipe_draw_elements; - llvmpipe->pipe.draw_range_elements = llvmpipe_draw_range_elements; - llvmpipe->pipe.draw_arrays_instanced = llvmpipe_draw_arrays_instanced; - llvmpipe->pipe.draw_elements_instanced = llvmpipe_draw_elements_instanced; + llvmpipe->pipe.draw_vbo = llvmpipe_draw_vbo; } diff --git a/src/gallium/drivers/llvmpipe/lp_rast.c b/src/gallium/drivers/llvmpipe/lp_rast.c index 654f4ea48eb..3215d0f6525 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast.c +++ b/src/gallium/drivers/llvmpipe/lp_rast.c @@ -43,6 +43,12 @@ #include "lp_scene.h" +#ifdef DEBUG +int jit_line = 0; +const struct lp_rast_state *jit_state = NULL; +#endif + + /** * Begin rasterizing a scene. * Called once per scene by one thread. @@ -368,14 +374,15 @@ lp_rast_store_linear_color( struct lp_rasterizer_task *task, for (buf = 0; buf < rast->state.nr_cbufs; buf++) { struct pipe_surface *cbuf = scene->fb.cbufs[buf]; - const unsigned face = cbuf->face, level = cbuf->level; + const unsigned face_slice = cbuf->face + cbuf->zslice; + const unsigned level = cbuf->level; struct llvmpipe_resource *lpt = llvmpipe_resource(cbuf->texture); if (!task->color_tiles[buf]) continue; llvmpipe_unswizzle_cbuf_tile(lpt, - face, + face_slice, level, task->x, task->y, task->color_tiles[buf]); @@ -418,6 +425,7 @@ lp_rast_shade_tile(struct lp_rasterizer_task *task, depth = lp_rast_get_depth_block_pointer(task, tile_x + x, tile_y + y); /* run shader on 4x4 block */ + BEGIN_JIT_CALL(state); variant->jit_function[RAST_WHOLE]( &state->jit_context, tile_x + x, tile_y + y, inputs->facing, @@ -428,6 +436,7 @@ lp_rast_shade_tile(struct lp_rasterizer_task *task, depth, 0xffff, &task->vis_counter); + END_JIT_CALL(); } } } @@ -497,6 +506,7 @@ lp_rast_shade_quads_mask(struct lp_rasterizer_task *task, assert(lp_check_alignment(state->jit_context.blend_color, 16)); /* run shader on 4x4 block */ + BEGIN_JIT_CALL(state); variant->jit_function[RAST_EDGE_TEST](&state->jit_context, x, y, inputs->facing, @@ -507,6 +517,7 @@ lp_rast_shade_quads_mask(struct lp_rasterizer_task *task, depth, mask, &task->vis_counter); + END_JIT_CALL(); } diff --git a/src/gallium/drivers/llvmpipe/lp_rast_priv.h b/src/gallium/drivers/llvmpipe/lp_rast_priv.h index b4a48cfd024..fae7f6d3dc2 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast_priv.h +++ b/src/gallium/drivers/llvmpipe/lp_rast_priv.h @@ -40,6 +40,34 @@ #include "lp_limits.h" +/* If we crash in a jitted function, we can examine jit_line and jit_state + * to get some info. This is not thread-safe, however. + */ +#ifdef DEBUG + +extern int jit_line; +extern const struct lp_rast_state *jit_state; + +#define BEGIN_JIT_CALL(state) \ + do { \ + jit_line = __LINE__; \ + jit_state = state; \ + } while (0) + +#define END_JIT_CALL() \ + do { \ + jit_line = 0; \ + jit_state = NULL; \ + } while (0) + +#else + +#define BEGIN_JIT_CALL(X) +#define END_JIT_CALL() + +#endif + + struct lp_rasterizer; @@ -249,6 +277,7 @@ lp_rast_shade_quads_all( struct lp_rasterizer_task *task, depth = lp_rast_get_depth_block_pointer(task, x, y); /* run shader on 4x4 block */ + BEGIN_JIT_CALL(state); variant->jit_function[RAST_WHOLE]( &state->jit_context, x, y, inputs->facing, @@ -259,6 +288,7 @@ lp_rast_shade_quads_all( struct lp_rasterizer_task *task, depth, 0xffff, &task->vis_counter ); + END_JIT_CALL(); } diff --git a/src/gallium/drivers/llvmpipe/lp_state_fs.c b/src/gallium/drivers/llvmpipe/lp_state_fs.c index 5953d690a41..dbca49a2efa 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_fs.c +++ b/src/gallium/drivers/llvmpipe/lp_state_fs.c @@ -75,6 +75,7 @@ #include "gallivm/lp_bld_type.h" #include "gallivm/lp_bld_const.h" #include "gallivm/lp_bld_conv.h" +#include "gallivm/lp_bld_init.h" #include "gallivm/lp_bld_intr.h" #include "gallivm/lp_bld_logic.h" #include "gallivm/lp_bld_tgsi.h" @@ -676,6 +677,11 @@ generate_fragment(struct llvmpipe_context *lp, color_ptr); } +#ifdef PIPE_ARCH_X86 + /* Avoid corrupting the FPU stack on 32bit OSes. */ + lp_build_intrinsic(builder, "llvm.x86.mmx.emms", LLVMVoidType(), NULL, 0); +#endif + LLVMBuildRetVoid(builder); LLVMDisposeBuilder(builder); @@ -710,6 +716,7 @@ generate_fragment(struct llvmpipe_context *lp, if (gallivm_debug & GALLIVM_DEBUG_ASM) { lp_disassemble(f); } + lp_func_delete_body(function); } } diff --git a/src/gallium/drivers/llvmpipe/lp_state_vertex.c b/src/gallium/drivers/llvmpipe/lp_state_vertex.c index 113f13db018..d86e66b4fb8 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_vertex.c +++ b/src/gallium/drivers/llvmpipe/lp_state_vertex.c @@ -89,6 +89,19 @@ llvmpipe_set_vertex_buffers(struct pipe_context *pipe, } +static void +llvmpipe_set_index_buffer(struct pipe_context *pipe, + const struct pipe_index_buffer *ib) +{ + struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe); + + if (ib) + memcpy(&llvmpipe->index_buffer, ib, sizeof(llvmpipe->index_buffer)); + else + memset(&llvmpipe->index_buffer, 0, sizeof(llvmpipe->index_buffer)); + + /* TODO make this more like a state */ +} void llvmpipe_init_vertex_funcs(struct llvmpipe_context *llvmpipe) @@ -98,4 +111,5 @@ llvmpipe_init_vertex_funcs(struct llvmpipe_context *llvmpipe) llvmpipe->pipe.delete_vertex_elements_state = llvmpipe_delete_vertex_elements_state; llvmpipe->pipe.set_vertex_buffers = llvmpipe_set_vertex_buffers; + llvmpipe->pipe.set_index_buffer = llvmpipe_set_index_buffer; } diff --git a/src/gallium/drivers/llvmpipe/lp_test_blend.c b/src/gallium/drivers/llvmpipe/lp_test_blend.c index 0c955556551..d0389f0cb0b 100644 --- a/src/gallium/drivers/llvmpipe/lp_test_blend.c +++ b/src/gallium/drivers/llvmpipe/lp_test_blend.c @@ -37,6 +37,7 @@ */ +#include "gallivm/lp_bld_init.h" #include "gallivm/lp_bld_type.h" #include "gallivm/lp_bld_debug.h" #include "lp_bld_blend.h" @@ -485,8 +486,7 @@ test_one(unsigned verbose, { LLVMModuleRef module = NULL; LLVMValueRef func = NULL; - LLVMExecutionEngineRef engine = NULL; - LLVMModuleProviderRef provider = NULL; + LLVMExecutionEngineRef engine = lp_build_engine; LLVMPassManagerRef pass = NULL; char *error = NULL; blend_test_ptr_t blend_test_ptr; @@ -510,15 +510,6 @@ test_one(unsigned verbose, } LLVMDisposeMessage(error); - provider = LLVMCreateModuleProviderForExistingModule(module); - if (LLVMCreateJITCompiler(&engine, provider, 1, &error)) { - if(verbose < 1) - dump_blend_type(stderr, blend, mode, type); - fprintf(stderr, "%s\n", error); - LLVMDisposeMessage(error); - abort(); - } - #if 0 pass = LLVMCreatePassManager(); LLVMAddTargetData(LLVMGetExecutionEngineTargetData(engine), pass); @@ -735,7 +726,6 @@ test_one(unsigned verbose, LLVMFreeMachineCodeForFunction(engine, func); - LLVMDisposeExecutionEngine(engine); if(pass) LLVMDisposePassManager(pass); diff --git a/src/gallium/drivers/llvmpipe/lp_test_conv.c b/src/gallium/drivers/llvmpipe/lp_test_conv.c index cf41b40581f..3ba42bf11a6 100644 --- a/src/gallium/drivers/llvmpipe/lp_test_conv.c +++ b/src/gallium/drivers/llvmpipe/lp_test_conv.c @@ -35,6 +35,7 @@ #include "util/u_pointer.h" +#include "gallivm/lp_bld_init.h" #include "gallivm/lp_bld_type.h" #include "gallivm/lp_bld_const.h" #include "gallivm/lp_bld_conv.h" @@ -152,8 +153,7 @@ test_one(unsigned verbose, { LLVMModuleRef module = NULL; LLVMValueRef func = NULL; - LLVMExecutionEngineRef engine = NULL; - LLVMModuleProviderRef provider = NULL; + LLVMExecutionEngineRef engine = lp_build_engine; LLVMPassManagerRef pass = NULL; char *error = NULL; conv_test_ptr_t conv_test_ptr; @@ -203,15 +203,6 @@ test_one(unsigned verbose, } LLVMDisposeMessage(error); - provider = LLVMCreateModuleProviderForExistingModule(module); - if (LLVMCreateJITCompiler(&engine, provider, 1, &error)) { - if(verbose < 1) - dump_conv_types(stderr, src_type, dst_type); - fprintf(stderr, "%s\n", error); - LLVMDisposeMessage(error); - abort(); - } - #if 0 pass = LLVMCreatePassManager(); LLVMAddTargetData(LLVMGetExecutionEngineTargetData(engine), pass); @@ -351,7 +342,6 @@ test_one(unsigned verbose, LLVMFreeMachineCodeForFunction(engine, func); - LLVMDisposeExecutionEngine(engine); if(pass) LLVMDisposePassManager(pass); diff --git a/src/gallium/drivers/llvmpipe/lp_test_printf.c b/src/gallium/drivers/llvmpipe/lp_test_printf.c index 21df83f9d89..4653f30e39d 100644 --- a/src/gallium/drivers/llvmpipe/lp_test_printf.c +++ b/src/gallium/drivers/llvmpipe/lp_test_printf.c @@ -31,6 +31,8 @@ #include "util/u_pointer.h" #include "gallivm/lp_bld.h" +#include "gallivm/lp_bld_init.h" +#include "gallivm/lp_bld_assert.h" #include "gallivm/lp_bld_printf.h" #include <llvm-c/Analysis.h> @@ -74,6 +76,10 @@ add_printf_test(LLVMModuleRef module) lp_build_printf(builder, "hello, world\n"); lp_build_printf(builder, "print 5 6: %d %d\n", LLVMConstInt(LLVMInt32Type(), 5, 0), LLVMConstInt(LLVMInt32Type(), 6, 0)); + + /* Also test lp_build_assert(). This should not fail. */ + lp_build_assert(builder, LLVMConstInt(LLVMInt32Type(), 1, 0), "assert(1)"); + LLVMBuildRetVoid(builder); LLVMDisposeBuilder(builder); return func; @@ -107,11 +113,16 @@ test_printf(unsigned verbose, FILE *fp, const struct printf_test_case *testcase) LLVMDisposeMessage(error); provider = LLVMCreateModuleProviderForExistingModule(module); +#if 0 if (LLVMCreateJITCompiler(&engine, provider, 1, &error)) { fprintf(stderr, "%s\n", error); LLVMDisposeMessage(error); abort(); } +#else + (void) provider; + engine = lp_build_engine; +#endif #if 0 pass = LLVMCreatePassManager(); diff --git a/src/gallium/drivers/llvmpipe/lp_test_round.c b/src/gallium/drivers/llvmpipe/lp_test_round.c index f571a81a4a4..57b0ee57767 100644 --- a/src/gallium/drivers/llvmpipe/lp_test_round.c +++ b/src/gallium/drivers/llvmpipe/lp_test_round.c @@ -31,7 +31,7 @@ #include "util/u_pointer.h" #include "gallivm/lp_bld.h" -#include "gallivm/lp_bld_printf.h" +#include "gallivm/lp_bld_init.h" #include "gallivm/lp_bld_arit.h" #include <llvm-c/Analysis.h> @@ -121,8 +121,7 @@ test_round(unsigned verbose, FILE *fp) { LLVMModuleRef module = NULL; LLVMValueRef test_round = NULL, test_trunc, test_floor, test_ceil; - LLVMExecutionEngineRef engine = NULL; - LLVMModuleProviderRef provider = NULL; + LLVMExecutionEngineRef engine = lp_build_engine; LLVMPassManagerRef pass = NULL; char *error = NULL; test_round_t round_func, trunc_func, floor_func, ceil_func; @@ -145,13 +144,6 @@ test_round(unsigned verbose, FILE *fp) } LLVMDisposeMessage(error); - provider = LLVMCreateModuleProviderForExistingModule(module); - if (LLVMCreateJITCompiler(&engine, provider, 1, &error)) { - fprintf(stderr, "%s\n", error); - LLVMDisposeMessage(error); - abort(); - } - #if 0 pass = LLVMCreatePassManager(); LLVMAddTargetData(LLVMGetExecutionEngineTargetData(engine), pass); diff --git a/src/gallium/drivers/llvmpipe/lp_test_sincos.c b/src/gallium/drivers/llvmpipe/lp_test_sincos.c index 1366ecddcbc..7ab357f162e 100644 --- a/src/gallium/drivers/llvmpipe/lp_test_sincos.c +++ b/src/gallium/drivers/llvmpipe/lp_test_sincos.c @@ -30,8 +30,9 @@ #include <stdio.h> #include "gallivm/lp_bld.h" -#include "gallivm/lp_bld_printf.h" +#include "gallivm/lp_bld_init.h" #include "gallivm/lp_bld_arit.h" +#include "util/u_pointer.h" #include <llvm-c/Analysis.h> #include <llvm-c/ExecutionEngine.h> @@ -101,8 +102,7 @@ test_sincos(unsigned verbose, FILE *fp) { LLVMModuleRef module = NULL; LLVMValueRef test_sin = NULL, test_cos = NULL; - LLVMExecutionEngineRef engine = NULL; - LLVMModuleProviderRef provider = NULL; + LLVMExecutionEngineRef engine = lp_build_engine; LLVMPassManagerRef pass = NULL; char *error = NULL; test_sincos_t sin_func; @@ -122,13 +122,6 @@ test_sincos(unsigned verbose, FILE *fp) } LLVMDisposeMessage(error); - provider = LLVMCreateModuleProviderForExistingModule(module); - if (LLVMCreateJITCompiler(&engine, provider, 1, &error)) { - fprintf(stderr, "%s\n", error); - LLVMDisposeMessage(error); - abort(); - } - #if 0 pass = LLVMCreatePassManager(); LLVMAddTargetData(LLVMGetExecutionEngineTargetData(engine), pass); @@ -144,8 +137,8 @@ test_sincos(unsigned verbose, FILE *fp) (void)pass; #endif - sin_func = (test_sincos_t)LLVMGetPointerToGlobal(engine, test_sin); - cos_func = (test_sincos_t)LLVMGetPointerToGlobal(engine, test_cos); + sin_func = (test_sincos_t) pointer_to_func(LLVMGetPointerToGlobal(engine, test_sin)); + cos_func = (test_sincos_t) pointer_to_func(LLVMGetPointerToGlobal(engine, test_cos)); memset(unpacked, 0, sizeof unpacked); @@ -162,7 +155,6 @@ test_sincos(unsigned verbose, FILE *fp) LLVMFreeMachineCodeForFunction(engine, test_sin); LLVMFreeMachineCodeForFunction(engine, test_cos); - LLVMDisposeExecutionEngine(engine); if(pass) LLVMDisposePassManager(pass); diff --git a/src/gallium/drivers/nv50/nv50_context.c b/src/gallium/drivers/nv50/nv50_context.c index 915a9254025..0874cb5e4ea 100644 --- a/src/gallium/drivers/nv50/nv50_context.c +++ b/src/gallium/drivers/nv50/nv50_context.c @@ -82,10 +82,7 @@ nv50_create(struct pipe_screen *pscreen, void *priv) nv50->pipe.destroy = nv50_destroy; - nv50->pipe.draw_arrays = nv50_draw_arrays; - nv50->pipe.draw_arrays_instanced = nv50_draw_arrays_instanced; - nv50->pipe.draw_elements = nv50_draw_elements; - nv50->pipe.draw_elements_instanced = nv50_draw_elements_instanced; + nv50->pipe.draw_vbo = nv50_draw_vbo; nv50->pipe.clear = nv50_clear; nv50->pipe.flush = nv50_flush; diff --git a/src/gallium/drivers/nv50/nv50_context.h b/src/gallium/drivers/nv50/nv50_context.h index 12c4a93a9bd..d24d6c50ea8 100644 --- a/src/gallium/drivers/nv50/nv50_context.h +++ b/src/gallium/drivers/nv50/nv50_context.h @@ -148,6 +148,7 @@ struct nv50_context { struct pipe_resource *constbuf[PIPE_SHADER_TYPES]; struct pipe_vertex_buffer vtxbuf[PIPE_MAX_ATTRIBS]; unsigned vtxbuf_nr; + struct pipe_index_buffer idxbuf; struct nv50_vtxelt_stateobj *vtxelt; struct nv50_sampler_stateobj *sampler[3][PIPE_MAX_SAMPLERS]; unsigned sampler_nr[3]; @@ -179,24 +180,8 @@ nv50_surface_do_copy(struct nv50_screen *screen, struct pipe_surface *dst, extern struct draw_stage *nv50_draw_render_stage(struct nv50_context *nv50); /* nv50_vbo.c */ -extern void nv50_draw_arrays(struct pipe_context *, unsigned mode, - unsigned start, unsigned count); -extern void nv50_draw_arrays_instanced(struct pipe_context *, unsigned mode, - unsigned start, unsigned count, - unsigned startInstance, - unsigned instanceCount); -extern void nv50_draw_elements(struct pipe_context *pipe, - struct pipe_resource *indexBuffer, - unsigned indexSize, int indexBias, - unsigned mode, unsigned start, - unsigned count); -extern void nv50_draw_elements_instanced(struct pipe_context *pipe, - struct pipe_resource *indexBuffer, - unsigned indexSize, int indexBias, - unsigned mode, unsigned start, - unsigned count, - unsigned startInstance, - unsigned instanceCount); +extern void nv50_draw_vbo(struct pipe_context *pipe, + const struct pipe_draw_info *info); extern void nv50_vtxelt_construct(struct nv50_vtxelt_stateobj *cso); extern struct nouveau_stateobj *nv50_vbo_validate(struct nv50_context *nv50); diff --git a/src/gallium/drivers/nv50/nv50_state.c b/src/gallium/drivers/nv50/nv50_state.c index 42c5a583189..ec0c0ff2838 100644 --- a/src/gallium/drivers/nv50/nv50_state.c +++ b/src/gallium/drivers/nv50/nv50_state.c @@ -742,6 +742,20 @@ nv50_set_vertex_buffers(struct pipe_context *pipe, unsigned count, nv50->dirty |= NV50_NEW_ARRAYS; } +static void +nv50_set_index_buffer(struct pipe_context *pipe, + const struct pipe_index_buffer *ib) +{ + struct nv50_context *nv50 = nv50_context(pipe); + + if (ib) + memcpy(&nv50->idxbuf, ib, sizeof(nv50->idxbuf)); + else + memset(&nv50->idxbuf, 0, sizeof(nv50->idxbuf)); + + /* TODO make this more like a state */ +} + static void * nv50_vtxelts_state_create(struct pipe_context *pipe, unsigned num_elements, @@ -827,5 +841,6 @@ nv50_init_state_functions(struct nv50_context *nv50) nv50->pipe.bind_vertex_elements_state = nv50_vtxelts_state_bind; nv50->pipe.set_vertex_buffers = nv50_set_vertex_buffers; + nv50->pipe.set_index_buffer = nv50_set_index_buffer; } diff --git a/src/gallium/drivers/nv50/nv50_vbo.c b/src/gallium/drivers/nv50/nv50_vbo.c index 864cb09352a..e7f8fe33edf 100644 --- a/src/gallium/drivers/nv50/nv50_vbo.c +++ b/src/gallium/drivers/nv50/nv50_vbo.c @@ -173,7 +173,7 @@ instance_step(struct nv50_context *nv50, struct instance *a) } } -void +static void nv50_draw_arrays_instanced(struct pipe_context *pipe, unsigned mode, unsigned start, unsigned count, unsigned startInstance, unsigned instanceCount) @@ -220,13 +220,6 @@ nv50_draw_arrays_instanced(struct pipe_context *pipe, } } -void -nv50_draw_arrays(struct pipe_context *pipe, unsigned mode, unsigned start, - unsigned count) -{ - nv50_draw_arrays_instanced(pipe, mode, start, count, 0, 1); -} - struct inline_ctx { struct nv50_context *nv50; void *map; @@ -384,7 +377,7 @@ nv50_draw_elements_inline(struct pipe_context *pipe, pipe_buffer_unmap(pipe, indexBuffer, transfer); } -void +static void nv50_draw_elements_instanced(struct pipe_context *pipe, struct pipe_resource *indexBuffer, unsigned indexSize, int indexBias, @@ -464,13 +457,34 @@ nv50_draw_elements_instanced(struct pipe_context *pipe, } void -nv50_draw_elements(struct pipe_context *pipe, - struct pipe_resource *indexBuffer, - unsigned indexSize, int indexBias, - unsigned mode, unsigned start, unsigned count) +nv50_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info) { - nv50_draw_elements_instanced(pipe, indexBuffer, indexSize, indexBias, - mode, start, count, 0, 1); + struct nv50_context *nv50 = nv50_context(pipe); + + if (info->indexed && nv50->idxbuf.buffer) { + unsigned offset; + + assert(nv50->idxbuf.offset % nv50->idxbuf.index_size == 0); + offset = nv50->idxbuf.offset / nv50->idxbuf.index_size; + + nv50_draw_elements_instanced(pipe, + nv50->idxbuf.buffer, + nv50->idxbuf.index_size, + info->index_bias, + info->mode, + info->start + offset, + info->count, + info->start_instance, + info->instance_count); + } + else { + nv50_draw_arrays_instanced(pipe, + info->mode, + info->start, + info->count, + info->start_instance, + info->instance_count); + } } static INLINE boolean diff --git a/src/gallium/drivers/nvfx/nvfx_context.c b/src/gallium/drivers/nvfx/nvfx_context.c index 6d2dc4d5bf6..7218abff22d 100644 --- a/src/gallium/drivers/nvfx/nvfx_context.c +++ b/src/gallium/drivers/nvfx/nvfx_context.c @@ -55,8 +55,7 @@ nvfx_create(struct pipe_screen *pscreen, void *priv) nvfx->pipe.screen = pscreen; nvfx->pipe.priv = priv; nvfx->pipe.destroy = nvfx_destroy; - nvfx->pipe.draw_arrays = nvfx_draw_arrays; - nvfx->pipe.draw_elements = nvfx_draw_elements; + nvfx->pipe.draw_vbo = nvfx_draw_vbo; nvfx->pipe.clear = nvfx_clear; nvfx->pipe.flush = nvfx_flush; diff --git a/src/gallium/drivers/nvfx/nvfx_context.h b/src/gallium/drivers/nvfx/nvfx_context.h index e48f9f3aa88..89f94c10bd1 100644 --- a/src/gallium/drivers/nvfx/nvfx_context.h +++ b/src/gallium/drivers/nvfx/nvfx_context.h @@ -121,7 +121,8 @@ struct nvfx_context { struct pipe_stencil_ref stencil_ref; struct pipe_viewport_state viewport; struct pipe_framebuffer_state framebuffer; - struct pipe_resource *idxbuf; + struct pipe_index_buffer idxbuf; + struct pipe_resource *idxbuf_buffer; unsigned idxbuf_format; struct nvfx_sampler_state *tex_sampler[PIPE_MAX_SAMPLERS]; struct pipe_sampler_view *fragment_sampler_views[PIPE_MAX_SAMPLERS]; @@ -235,13 +236,8 @@ extern void nvfx_init_transfer_functions(struct nvfx_context *nvfx); /* nvfx_vbo.c */ extern boolean nvfx_vbo_validate(struct nvfx_context *nvfx); extern void nvfx_vbo_relocate(struct nvfx_context *nvfx); -extern void nvfx_draw_arrays(struct pipe_context *, unsigned mode, - unsigned start, unsigned count); -extern void nvfx_draw_elements(struct pipe_context *pipe, - struct pipe_resource *indexBuffer, - unsigned indexSize, int indexBias, - unsigned mode, unsigned start, - unsigned count); +extern void nvfx_draw_vbo(struct pipe_context *pipe, + const struct pipe_draw_info *info); /* nvfx_vertprog.c */ extern boolean nvfx_vertprog_validate(struct nvfx_context *nvfx); diff --git a/src/gallium/drivers/nvfx/nvfx_screen.c b/src/gallium/drivers/nvfx/nvfx_screen.c index 80db28a07cb..f2525ccb38f 100644 --- a/src/gallium/drivers/nvfx/nvfx_screen.c +++ b/src/gallium/drivers/nvfx/nvfx_screen.c @@ -131,6 +131,8 @@ nvfx_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param) return screen->is_nv4x ? 1 : 0; case PIPE_CAP_GEOMETRY_SHADER4: return 0; + case PIPE_CAP_DEPTH_CLAMP: + return 0; // TODO: implement depth clamp default: NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param); return 0; diff --git a/src/gallium/drivers/nvfx/nvfx_state.c b/src/gallium/drivers/nvfx/nvfx_state.c index 30322d46d93..cd58e439d71 100644 --- a/src/gallium/drivers/nvfx/nvfx_state.c +++ b/src/gallium/drivers/nvfx/nvfx_state.c @@ -555,6 +555,20 @@ nvfx_set_vertex_buffers(struct pipe_context *pipe, unsigned count, nvfx->draw_dirty |= NVFX_NEW_ARRAYS; } +static void +nvfx_set_index_buffer(struct pipe_context *pipe, + const struct pipe_index_buffer *ib) +{ + struct nvfx_context *nvfx = nvfx_context(pipe); + + if (ib) + memcpy(&nvfx->idxbuf, ib, sizeof(nvfx->idxbuf)); + else + memset(&nvfx->idxbuf, 0, sizeof(nvfx->idxbuf)); + + /* TODO make this more like a state */ +} + static void * nvfx_vtxelts_state_create(struct pipe_context *pipe, unsigned num_elements, @@ -635,4 +649,5 @@ nvfx_init_state_functions(struct nvfx_context *nvfx) nvfx->pipe.bind_vertex_elements_state = nvfx_vtxelts_state_bind; nvfx->pipe.set_vertex_buffers = nvfx_set_vertex_buffers; + nvfx->pipe.set_index_buffer = nvfx_set_index_buffer; } diff --git a/src/gallium/drivers/nvfx/nvfx_vbo.c b/src/gallium/drivers/nvfx/nvfx_vbo.c index 520bae5aed2..4aa37938425 100644 --- a/src/gallium/drivers/nvfx/nvfx_vbo.c +++ b/src/gallium/drivers/nvfx/nvfx_vbo.c @@ -85,7 +85,7 @@ nvfx_vbo_set_idxbuf(struct nvfx_context *nvfx, struct pipe_resource *ib, unsigned type; if (!ib) { - nvfx->idxbuf = NULL; + nvfx->idxbuf_buffer = NULL; nvfx->idxbuf_format = 0xdeadbeef; return FALSE; } @@ -104,10 +104,10 @@ nvfx_vbo_set_idxbuf(struct nvfx_context *nvfx, struct pipe_resource *ib, return FALSE; } - if (ib != nvfx->idxbuf || + if (ib != nvfx->idxbuf_buffer || type != nvfx->idxbuf_format) { nvfx->dirty |= NVFX_NEW_ARRAYS; - nvfx->idxbuf = ib; + nvfx->idxbuf_buffer = ib; nvfx->idxbuf_format = type; } @@ -158,7 +158,7 @@ nvfx_vbo_static_attrib(struct nvfx_context *nvfx, pipe_buffer_unmap(&nvfx->pipe, vb->buffer, transfer); } -void +static void nvfx_draw_arrays(struct pipe_context *pipe, unsigned mode, unsigned start, unsigned count) { @@ -463,7 +463,7 @@ nvfx_draw_elements_vbo(struct pipe_context *pipe, } } -void +static void nvfx_draw_elements(struct pipe_context *pipe, struct pipe_resource *indexBuffer, unsigned indexSize, int indexBias, @@ -491,11 +491,38 @@ nvfx_draw_elements(struct pipe_context *pipe, pipe->flush(pipe, 0, NULL); } +void +nvfx_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info) +{ + struct nvfx_context *nvfx = nvfx_context(pipe); + + if (info->indexed && nvfx->idxbuf.buffer) { + unsigned offset; + + assert(nvfx->idxbuf.offset % nvfx->idxbuf.index_size == 0); + offset = nvfx->idxbuf.offset / nvfx->idxbuf.index_size; + + nvfx_draw_elements(pipe, + nvfx->idxbuf.buffer, + nvfx->idxbuf.index_size, + info->index_bias, + info->mode, + info->start + offset, + info->count); + } + else { + nvfx_draw_arrays(pipe, + info->mode, + info->start, + info->count); + } +} + boolean nvfx_vbo_validate(struct nvfx_context *nvfx) { struct nouveau_channel* chan = nvfx->screen->base.channel; - struct pipe_resource *ib = nvfx->idxbuf; + struct pipe_resource *ib = nvfx->idxbuf_buffer; unsigned ib_format = nvfx->idxbuf_format; int i; int elements = MAX2(nvfx->vtxelt->num_elements, nvfx->hw_vtxelt_nr); @@ -610,10 +637,10 @@ nvfx_vbo_relocate(struct nvfx_context *nvfx) } } - if(nvfx->idxbuf) + if(nvfx->idxbuf_buffer) { unsigned ib_flags = nvfx->screen->index_buffer_reloc_flags | NOUVEAU_BO_RD | NOUVEAU_BO_DUMMY; - struct nouveau_bo* bo = nvfx_resource(nvfx->idxbuf)->bo; + struct nouveau_bo* bo = nvfx_resource(nvfx->idxbuf_buffer)->bo; assert(nvfx->screen->index_buffer_reloc_flags); diff --git a/src/gallium/drivers/nvfx/nvfx_vertprog.c b/src/gallium/drivers/nvfx/nvfx_vertprog.c index 80b98b62d34..24d9846310e 100644 --- a/src/gallium/drivers/nvfx/nvfx_vertprog.c +++ b/src/gallium/drivers/nvfx/nvfx_vertprog.c @@ -299,7 +299,13 @@ nvfx_vp_arith(struct nvfx_context* nvfx, struct nvfx_vpc *vpc, int slot, int op, (3 << NVFX_VP(INST_COND_SWZ_W_SHIFT))); if(!nvfx->is_nv4x) { - hw[1] |= (op << NV30_VP_INST_VEC_OPCODE_SHIFT); + if(slot == 0) + hw[1] |= (op << NV30_VP_INST_VEC_OPCODE_SHIFT); + else + { + hw[0] |= ((op >> 4) << NV30_VP_INST_SCA_OPCODEH_SHIFT); + hw[1] |= ((op & 0xf) << NV30_VP_INST_SCA_OPCODEL_SHIFT); + } // hw[3] |= NVFX_VP(INST_SCA_DEST_TEMP_MASK); // hw[3] |= (mask << NVFX_VP(INST_VEC_WRITEMASK_SHIFT)); diff --git a/src/gallium/drivers/r300/r300_blit.c b/src/gallium/drivers/r300/r300_blit.c index d125196b6dc..6f8d9abfc81 100644 --- a/src/gallium/drivers/r300/r300_blit.c +++ b/src/gallium/drivers/r300/r300_blit.c @@ -22,6 +22,7 @@ #include "r300_context.h" #include "r300_texture.h" +#include "r300_winsys.h" #include "util/u_format.h" #include "util/u_pack_color.h" @@ -81,7 +82,7 @@ static void r300_blitter_end(struct r300_context *r300) } static uint32_t r300_depth_clear_cb_value(enum pipe_format format, - const float* rgba) + const float* rgba) { union util_color uc; util_pack_color(rgba, format, &uc); @@ -98,6 +99,9 @@ static boolean r300_cbzb_clear_allowed(struct r300_context *r300, struct pipe_framebuffer_state *fb = (struct pipe_framebuffer_state*)r300->fb_state.state; + if (r300->z_fastfill) + clear_buffers &= ~(PIPE_CLEAR_DEPTH | PIPE_CLEAR_STENCIL); + /* Only color clear allowed, and only one colorbuffer. */ if (clear_buffers != PIPE_CLEAR_COLOR || fb->nr_cbufs != 1) return FALSE; @@ -105,6 +109,23 @@ static boolean r300_cbzb_clear_allowed(struct r300_context *r300, return r300_surface(fb->cbufs[0])->cbzb_allowed; } +static uint32_t r300_depth_clear_value(enum pipe_format format, + double depth, unsigned stencil) +{ + switch (format) { + case PIPE_FORMAT_Z16_UNORM: + case PIPE_FORMAT_X8Z24_UNORM: + return util_pack_z(format, depth); + + case PIPE_FORMAT_S8_USCALED_Z24_UNORM: + return util_pack_z_stencil(format, depth, stencil); + + default: + assert(0); + return 0; + } +} + /* Clear currently bound buffers. */ static void r300_clear(struct pipe_context* pipe, unsigned buffers, @@ -154,6 +175,22 @@ static void r300_clear(struct pipe_context* pipe, (struct r300_hyperz_state*)r300->hyperz_state.state; uint32_t width = fb->width; uint32_t height = fb->height; + boolean has_hyperz = r300->rws->get_value(r300->rws, R300_CAN_HYPERZ); + uint32_t hyperz_dcv = 0; + + /* Enable fast Z clear. + * The zbuffer must be in micro-tiled mode, otherwise it locks up. */ + if ((buffers & (PIPE_CLEAR_DEPTH|PIPE_CLEAR_STENCIL)) && has_hyperz) { + + hyperz_dcv = hyperz->zb_depthclearvalue = + r300_depth_clear_value(fb->zsbuf->format, depth, stencil); + + r300_mark_fb_state_dirty(r300, R300_CHANGED_ZCLEAR_FLAG); + if (r300->z_compression || r300->z_fastfill) + r300->zmask_clear.dirty = TRUE; + if (r300->hiz_enable) + r300->hiz_clear.dirty = TRUE; + } /* Enable CBZB clear. */ if (r300_cbzb_clear_allowed(r300, buffers)) { @@ -181,6 +218,7 @@ static void r300_clear(struct pipe_context* pipe, /* Disable CBZB clear. */ if (r300->cbzb_clear) { r300->cbzb_clear = FALSE; + hyperz->zb_depthclearvalue = hyperz_dcv; r300_mark_fb_state_dirty(r300, R300_CHANGED_CBZB_FLAG); } @@ -221,6 +259,29 @@ static void r300_clear_depth_stencil(struct pipe_context *pipe, r300_blitter_end(r300); } +/* Clear a region of a depth stencil surface. */ +static void r300_flush_depth_stencil(struct pipe_context *pipe, + struct pipe_resource *dst, + struct pipe_subresource subdst) +{ + struct r300_context *r300 = r300_context(pipe); + struct pipe_surface *dstsurf; + struct r300_texture *tex = r300_texture(dst); + + /* only flush the zmask if we have one attached to this texture */ + if (!tex->zmask_mem[subdst.level]) + return; + + dstsurf = pipe->screen->get_tex_surface(pipe->screen, dst, + subdst.face, subdst.level, 0, + PIPE_BIND_DEPTH_STENCIL); + r300->z_decomp_rd = TRUE; + r300_blitter_begin(r300, R300_CLEAR_SURFACE); + util_blitter_flush_depth_stencil(r300->blitter, dstsurf); + r300_blitter_end(r300); + r300->z_decomp_rd = FALSE; +} + /* Copy a block of pixels from one surface to another using HW. */ static void r300_hw_copy_region(struct pipe_context* pipe, struct pipe_resource *dst, @@ -252,7 +313,7 @@ static void r300_resource_copy_region(struct pipe_context *pipe, { enum pipe_format old_format = dst->format; enum pipe_format new_format = old_format; - + boolean is_depth; if (!pipe->screen->is_format_supported(pipe->screen, old_format, src->target, src->nr_samples, @@ -279,6 +340,10 @@ static void r300_resource_copy_region(struct pipe_context *pipe, } } + is_depth = util_format_get_component_bits(src->format, UTIL_FORMAT_COLORSPACE_ZS, 0) != 0; + if (is_depth) { + r300_flush_depth_stencil(pipe, src, subsrc); + } if (old_format != new_format) { dst->format = new_format; src->format = new_format; diff --git a/src/gallium/drivers/r300/r300_chipset.c b/src/gallium/drivers/r300/r300_chipset.c index 21f3b9d2610..48c24092114 100644 --- a/src/gallium/drivers/r300/r300_chipset.c +++ b/src/gallium/drivers/r300/r300_chipset.c @@ -36,7 +36,7 @@ void r300_parse_chipset(struct r300_capabilities* caps) caps->num_vert_fpus = 2; caps->num_tex_units = 16; caps->has_tcl = debug_get_bool_option("RADEON_NO_TCL", FALSE) ? FALSE : TRUE; - caps->has_hiz = TRUE; + caps->hiz_ram = 0; caps->is_r400 = FALSE; caps->is_r500 = FALSE; caps->high_second_pipe = FALSE; @@ -49,6 +49,8 @@ void r300_parse_chipset(struct r300_capabilities* caps) caps->family = CHIP_FAMILY_R300; caps->high_second_pipe = TRUE; caps->num_vert_fpus = 4; + caps->hiz_ram = R300_HIZ_LIMIT; + caps->zmask_ram = PIPE_ZMASK_SIZE; break; case 0x4145: @@ -61,6 +63,8 @@ void r300_parse_chipset(struct r300_capabilities* caps) caps->family = CHIP_FAMILY_R300; caps->high_second_pipe = TRUE; caps->num_vert_fpus = 4; + caps->hiz_ram = R300_HIZ_LIMIT; + caps->zmask_ram = PIPE_ZMASK_SIZE; break; case 0x4150: @@ -77,8 +81,8 @@ void r300_parse_chipset(struct r300_capabilities* caps) case 0x4E54: case 0x4E56: caps->family = CHIP_FAMILY_RV350; - caps->has_hiz = FALSE; caps->high_second_pipe = TRUE; + caps->zmask_ram = RV3xx_ZMASK_SIZE; break; case 0x4148: @@ -91,12 +95,16 @@ void r300_parse_chipset(struct r300_capabilities* caps) caps->family = CHIP_FAMILY_R350; caps->high_second_pipe = TRUE; caps->num_vert_fpus = 4; + caps->hiz_ram = R300_HIZ_LIMIT; + caps->zmask_ram = PIPE_ZMASK_SIZE; break; case 0x4E4A: caps->family = CHIP_FAMILY_R360; caps->high_second_pipe = TRUE; caps->num_vert_fpus = 4; + caps->hiz_ram = R300_HIZ_LIMIT; + caps->zmask_ram = PIPE_ZMASK_SIZE; break; case 0x5460: @@ -108,8 +116,8 @@ void r300_parse_chipset(struct r300_capabilities* caps) case 0x5B64: case 0x5B65: caps->family = CHIP_FAMILY_RV370; - caps->has_hiz = FALSE; caps->high_second_pipe = TRUE; + caps->zmask_ram = RV3xx_ZMASK_SIZE; break; case 0x3150: @@ -120,6 +128,8 @@ void r300_parse_chipset(struct r300_capabilities* caps) case 0x3E54: caps->family = CHIP_FAMILY_RV380; caps->high_second_pipe = TRUE; + caps->hiz_ram = R300_HIZ_LIMIT; + caps->zmask_ram = RV3xx_ZMASK_SIZE; break; case 0x4A48: @@ -135,6 +145,8 @@ void r300_parse_chipset(struct r300_capabilities* caps) caps->family = CHIP_FAMILY_R420; caps->num_vert_fpus = 6; caps->is_r400 = TRUE; + caps->hiz_ram = R300_HIZ_LIMIT; + caps->zmask_ram = PIPE_ZMASK_SIZE; break; case 0x5548: @@ -149,6 +161,8 @@ void r300_parse_chipset(struct r300_capabilities* caps) caps->family = CHIP_FAMILY_R423; caps->num_vert_fpus = 6; caps->is_r400 = TRUE; + caps->hiz_ram = R300_HIZ_LIMIT; + caps->zmask_ram = PIPE_ZMASK_SIZE; break; case 0x554C: @@ -161,6 +175,8 @@ void r300_parse_chipset(struct r300_capabilities* caps) caps->family = CHIP_FAMILY_R430; caps->num_vert_fpus = 6; caps->is_r400 = TRUE; + caps->hiz_ram = R300_HIZ_LIMIT; + caps->zmask_ram = PIPE_ZMASK_SIZE; break; case 0x5D4C: @@ -172,6 +188,8 @@ void r300_parse_chipset(struct r300_capabilities* caps) caps->family = CHIP_FAMILY_R480; caps->num_vert_fpus = 6; caps->is_r400 = TRUE; + caps->hiz_ram = R300_HIZ_LIMIT; + caps->zmask_ram = PIPE_ZMASK_SIZE; break; case 0x4B48: @@ -182,6 +200,8 @@ void r300_parse_chipset(struct r300_capabilities* caps) caps->family = CHIP_FAMILY_R481; caps->num_vert_fpus = 6; caps->is_r400 = TRUE; + caps->hiz_ram = R300_HIZ_LIMIT; + caps->zmask_ram = PIPE_ZMASK_SIZE; break; case 0x5E4C: @@ -199,34 +219,36 @@ void r300_parse_chipset(struct r300_capabilities* caps) caps->family = CHIP_FAMILY_RV410; caps->num_vert_fpus = 6; caps->is_r400 = TRUE; + caps->hiz_ram = R300_HIZ_LIMIT; + caps->zmask_ram = PIPE_ZMASK_SIZE; break; case 0x5954: case 0x5955: caps->family = CHIP_FAMILY_RS480; - caps->has_hiz = FALSE; caps->has_tcl = FALSE; + caps->zmask_ram = RV3xx_ZMASK_SIZE; break; case 0x5974: case 0x5975: caps->family = CHIP_FAMILY_RS482; - caps->has_hiz = FALSE; caps->has_tcl = FALSE; + caps->zmask_ram = RV3xx_ZMASK_SIZE; break; case 0x5A41: case 0x5A42: caps->family = CHIP_FAMILY_RS400; - caps->has_hiz = FALSE; caps->has_tcl = FALSE; + caps->zmask_ram = RV3xx_ZMASK_SIZE; break; case 0x5A61: case 0x5A62: caps->family = CHIP_FAMILY_RC410; - caps->has_hiz = FALSE; caps->has_tcl = FALSE; + caps->zmask_ram = RV3xx_ZMASK_SIZE; break; case 0x791E: @@ -234,6 +256,8 @@ void r300_parse_chipset(struct r300_capabilities* caps) caps->family = CHIP_FAMILY_RS690; caps->has_tcl = FALSE; caps->is_r400 = TRUE; + caps->hiz_ram = R300_HIZ_LIMIT; + caps->zmask_ram = PIPE_ZMASK_SIZE; break; case 0x793F: @@ -242,6 +266,8 @@ void r300_parse_chipset(struct r300_capabilities* caps) caps->family = CHIP_FAMILY_RS600; caps->has_tcl = FALSE; caps->is_r400 = TRUE; + caps->hiz_ram = R300_HIZ_LIMIT; + caps->zmask_ram = PIPE_ZMASK_SIZE; break; case 0x796C: @@ -251,6 +277,8 @@ void r300_parse_chipset(struct r300_capabilities* caps) caps->family = CHIP_FAMILY_RS740; caps->has_tcl = FALSE; caps->is_r400 = TRUE; + caps->hiz_ram = R300_HIZ_LIMIT; + caps->zmask_ram = PIPE_ZMASK_SIZE; break; case 0x7100: @@ -270,6 +298,8 @@ void r300_parse_chipset(struct r300_capabilities* caps) caps->family = CHIP_FAMILY_R520; caps->num_vert_fpus = 8; caps->is_r500 = TRUE; + caps->hiz_ram = R300_HIZ_LIMIT; + caps->zmask_ram = PIPE_ZMASK_SIZE; break; case 0x7140: @@ -313,6 +343,8 @@ void r300_parse_chipset(struct r300_capabilities* caps) caps->family = CHIP_FAMILY_RV515; caps->num_vert_fpus = 2; caps->is_r500 = TRUE; + caps->hiz_ram = R300_HIZ_LIMIT; + caps->zmask_ram = PIPE_ZMASK_SIZE; break; case 0x71C0: @@ -334,6 +366,8 @@ void r300_parse_chipset(struct r300_capabilities* caps) caps->family = CHIP_FAMILY_RV530; caps->num_vert_fpus = 5; caps->is_r500 = TRUE; + /*caps->hiz_ram = RV530_HIZ_LIMIT;*/ + caps->zmask_ram = PIPE_ZMASK_SIZE; break; case 0x7240: @@ -354,12 +388,16 @@ void r300_parse_chipset(struct r300_capabilities* caps) caps->family = CHIP_FAMILY_R580; caps->num_vert_fpus = 8; caps->is_r500 = TRUE; + caps->hiz_ram = RV530_HIZ_LIMIT; + caps->zmask_ram = PIPE_ZMASK_SIZE; break; case 0x7280: caps->family = CHIP_FAMILY_RV570; caps->num_vert_fpus = 8; caps->is_r500 = TRUE; + caps->hiz_ram = RV530_HIZ_LIMIT; + caps->zmask_ram = PIPE_ZMASK_SIZE; break; case 0x7281: @@ -376,6 +414,8 @@ void r300_parse_chipset(struct r300_capabilities* caps) caps->family = CHIP_FAMILY_RV560; caps->num_vert_fpus = 8; caps->is_r500 = TRUE; + caps->hiz_ram = RV530_HIZ_LIMIT; + caps->zmask_ram = PIPE_ZMASK_SIZE; break; default: diff --git a/src/gallium/drivers/r300/r300_chipset.h b/src/gallium/drivers/r300/r300_chipset.h index 65750f54e71..e7ca642b4f3 100644 --- a/src/gallium/drivers/r300/r300_chipset.h +++ b/src/gallium/drivers/r300/r300_chipset.h @@ -25,6 +25,14 @@ #include "pipe/p_compiler.h" +/* these are sizes in dwords */ +#define R300_HIZ_LIMIT 10240 +#define RV530_HIZ_LIMIT 15360 + +/* rv3xx have only one pipe */ +#define PIPE_ZMASK_SIZE 4096 +#define RV3xx_ZMASK_SIZE 5120 + /* Structure containing all the possible information about a specific Radeon * in the R3xx, R4xx, and R5xx families. */ struct r300_capabilities { @@ -42,8 +50,10 @@ struct r300_capabilities { unsigned num_tex_units; /* Whether or not TCL is physically present */ boolean has_tcl; - /* Some chipsets do not have HiZ RAM. */ - boolean has_hiz; + /* Some chipsets do not have HiZ RAM - other have varying amounts . */ + int hiz_ram; + /* some chipsets have zmask ram per pipe some don't */ + int zmask_ram; /* Whether or not this is RV350 or newer, including all r400 and r500 * chipsets. The differences compared to the oldest r300 chips are: * - Blend LTE/GTE thresholds diff --git a/src/gallium/drivers/r300/r300_context.c b/src/gallium/drivers/r300/r300_context.c index df903590583..e8b6c4f7af8 100644 --- a/src/gallium/drivers/r300/r300_context.c +++ b/src/gallium/drivers/r300/r300_context.c @@ -30,6 +30,7 @@ #include "r300_cb.h" #include "r300_context.h" #include "r300_emit.h" +#include "r300_hyperz.h" #include "r300_screen.h" #include "r300_screen_buffer.h" #include "r300_winsys.h" @@ -114,6 +115,10 @@ static void r300_destroy_context(struct pipe_context* context) u_upload_destroy(r300->upload_vb); u_upload_destroy(r300->upload_ib); + /* setup hyper-z mm */ + if (r300->rws->get_value(r300->rws, R300_CAN_HYPERZ)) + r300_hyperz_destroy_mm(r300); + translate_cache_destroy(r300->tran.translate_cache); r300_release_referenced_objects(r300); @@ -166,6 +171,9 @@ static void r300_setup_atoms(struct r300_context* r300) boolean is_r500 = r300->screen->caps.is_r500; boolean has_tcl = r300->screen->caps.has_tcl; boolean drm_2_3_0 = r300->rws->get_value(r300->rws, R300_VID_DRM_2_3_0); + boolean drm_2_6_0 = r300->rws->get_value(r300->rws, R300_VID_DRM_2_6_0); + boolean has_hyperz = r300->rws->get_value(r300->rws, R300_CAN_HYPERZ); + boolean has_hiz_ram = r300->screen->caps.hiz_ram > 0; /* Create the actual atom list. * @@ -188,8 +196,8 @@ static void r300_setup_atoms(struct r300_context* r300) R300_INIT_ATOM(gpu_flush, 9); R300_INIT_ATOM(aa_state, 4); R300_INIT_ATOM(fb_state, 0); + R300_INIT_ATOM(hyperz_state, is_r500 || (is_rv350 && drm_2_6_0) ? 10 : 8); /* ZB (unpipelined), SC. */ - R300_INIT_ATOM(hyperz_state, 6); R300_INIT_ATOM(ztop_state, 2); /* ZB, FG. */ R300_INIT_ATOM(dsa_state, is_r500 ? 8 : 6); @@ -220,6 +228,13 @@ static void r300_setup_atoms(struct r300_context* r300) /* TX. */ R300_INIT_ATOM(texture_cache_inval, 2); R300_INIT_ATOM(textures_state, 0); + if (has_hyperz) { + /* HiZ Clear */ + if (has_hiz_ram) + R300_INIT_ATOM(hiz_clear, 0); + /* zmask clear */ + R300_INIT_ATOM(zmask_clear, 0); + } /* ZB (unpipelined), SU. */ R300_INIT_ATOM(query_start, 4); @@ -282,8 +297,7 @@ static void r300_init_states(struct pipe_context *pipe) (struct r300_vap_invariant_state*)r300->vap_invariant_state.state; struct r300_invariant_state *invariant = (struct r300_invariant_state*)r300->invariant_state.state; - struct r300_hyperz_state *hyperz = - (struct r300_hyperz_state*)r300->hyperz_state.state; + CB_LOCALS; pipe->set_blend_color(pipe, &bc); @@ -351,10 +365,20 @@ static void r300_init_states(struct pipe_context *pipe) /* Initialize the hyperz state. */ { - BEGIN_CB(&hyperz->cb_begin, r300->hyperz_state.size); + struct r300_hyperz_state *hyperz = + (struct r300_hyperz_state*)r300->hyperz_state.state; + BEGIN_CB(&hyperz->cb_flush_begin, r300->hyperz_state.size); + OUT_CB_REG(R300_ZB_ZCACHE_CTLSTAT, + R300_ZB_ZCACHE_CTLSTAT_ZC_FLUSH_FLUSH_AND_FREE); OUT_CB_REG(R300_ZB_BW_CNTL, 0); OUT_CB_REG(R300_ZB_DEPTHCLEARVALUE, 0); OUT_CB_REG(R300_SC_HYPERZ, R300_SC_HYPERZ_ADJ_2); + + if (r300->screen->caps.is_r500 || + (r300->screen->caps.is_rv350 && + r300->rws->get_value(r300->rws, R300_VID_DRM_2_6_0))) { + OUT_CB_REG(R300_GB_Z_PEQ_CONFIG, 0); + } END_CB; } } @@ -415,6 +439,10 @@ struct pipe_context* r300_create_context(struct pipe_screen* screen, rws->cs_set_flush(r300->cs, r300_flush_cb, r300); + /* setup hyper-z mm */ + if (r300->rws->get_value(r300->rws, R300_CAN_HYPERZ)) + r300_hyperz_init_mm(r300); + r300->upload_ib = u_upload_create(&r300->context, 32 * 1024, 16, PIPE_BIND_INDEX_BUFFER); diff --git a/src/gallium/drivers/r300/r300_context.h b/src/gallium/drivers/r300/r300_context.h index b4256c62786..d86a5c8fc98 100644 --- a/src/gallium/drivers/r300/r300_context.h +++ b/src/gallium/drivers/r300/r300_context.h @@ -106,13 +106,19 @@ struct r300_dsa_state { }; struct r300_hyperz_state { + int current_func; /* -1 after a clear before first op */ + int flush; /* This is actually a command buffer with named dwords. */ + uint32_t cb_flush_begin; + uint32_t zb_zcache_ctlstat; /* R300_ZB_CACHE_CNTL */ uint32_t cb_begin; uint32_t zb_bw_cntl; /* R300_ZB_BW_CNTL */ uint32_t cb_reg1; uint32_t zb_depthclearvalue; /* R300_ZB_DEPTHCLEARVALUE */ uint32_t cb_reg2; uint32_t sc_hyperz; /* R300_SC_HYPERZ */ + uint32_t cb_reg3; + uint32_t gb_z_peq_config; /* R300_GB_Z_PEQ_CONFIG: 0x4028 */ }; struct r300_gpu_flush { @@ -321,6 +327,7 @@ struct r300_surface { /* Whether the CBZB clear is allowed on the surface. */ boolean cbzb_allowed; + }; struct r300_texture_desc { @@ -387,6 +394,10 @@ struct r300_texture { /* All bits should be filled in. */ struct r300_texture_fb_state fb_state; + /* hyper-z memory allocs */ + struct mem_block *hiz_mem[R300_MAX_TEXTURE_LEVELS]; + struct mem_block *zmask_mem[R300_MAX_TEXTURE_LEVELS]; + /* This is the level tiling flags were last time set for. * It's used to prevent redundant tiling-flags changes from happening.*/ unsigned surface_level; @@ -512,6 +523,10 @@ struct r300_context { struct r300_atom texture_cache_inval; /* GPU flush. */ struct r300_atom gpu_flush; + /* HiZ clear */ + struct r300_atom hiz_clear; + /* zmask clear */ + struct r300_atom zmask_clear; /* Invariant state. This must be emitted to get the engine started. */ struct r300_atom invariant_state; @@ -524,6 +539,8 @@ struct r300_context { struct r300_vertex_element_state *velems; bool any_user_vbs; + struct pipe_index_buffer index_buffer; + /* Vertex info for Draw. */ struct vertex_info vertex_info; @@ -547,8 +564,19 @@ struct r300_context { boolean two_sided_color; /* Incompatible vertex buffer layout? (misaligned stride or buffer_offset) */ boolean incompatible_vb_layout; - + /* Whether fast zclear is enabled. */ + boolean z_fastfill; +#define R300_Z_COMPRESS_44 1 +#define RV350_Z_COMPRESS_88 2 + int z_compression; + boolean hiz_enable; boolean cbzb_clear; + boolean z_decomp_rd; + + /* two mem block managers for hiz/zmask ram space */ + struct mem_block *hiz_mm; + struct mem_block *zmask_mm; + /* upload managers */ struct u_upload_mgr *upload_vb; struct u_upload_mgr *upload_ib; @@ -619,7 +647,8 @@ void r300_plug_in_stencil_ref_fallback(struct r300_context *r300); /* r300_state.c */ enum r300_fb_state_change { R300_CHANGED_FB_STATE = 0, - R300_CHANGED_CBZB_FLAG + R300_CHANGED_CBZB_FLAG, + R300_CHANGED_ZCLEAR_FLAG }; void r300_mark_fb_state_dirty(struct r300_context *r300, diff --git a/src/gallium/drivers/r300/r300_debug.c b/src/gallium/drivers/r300/r300_debug.c index 053a64ea6d7..c3e157e99af 100644 --- a/src/gallium/drivers/r300/r300_debug.c +++ b/src/gallium/drivers/r300/r300_debug.c @@ -44,6 +44,7 @@ static const struct debug_named_value debug_options[] = { { "notiling", DBG_NO_TILING, "Disable tiling (for benchmarking)" }, { "noimmd", DBG_NO_IMMD, "Disable immediate mode (for benchmarking)" }, { "stats", DBG_STATS, "Gather statistics" }, + { "hyperz", DBG_HYPERZ, "HyperZ (for debugging)" }, /* must be last */ DEBUG_NAMED_VALUE_END diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c index 36a26a78717..17e180a79ac 100644 --- a/src/gallium/drivers/r300/r300_emit.c +++ b/src/gallium/drivers/r300/r300_emit.c @@ -25,6 +25,7 @@ #include "util/u_format.h" #include "util/u_math.h" +#include "util/u_mm.h" #include "util/u_simple_list.h" #include "r300_context.h" @@ -329,6 +330,7 @@ void r300_emit_fb_state(struct r300_context* r300, unsigned size, void* state) struct pipe_framebuffer_state* fb = (struct pipe_framebuffer_state*)state; struct r300_surface* surf; unsigned i; + boolean has_hyperz = r300->rws->get_value(r300->rws, R300_CAN_HYPERZ); CS_LOCALS(r300); BEGIN_CS(size); @@ -364,6 +366,10 @@ void r300_emit_fb_state(struct r300_context* r300, unsigned size, void* state) OUT_CS_REG_SEQ(R300_ZB_DEPTHPITCH, 1); OUT_CS_RELOC(surf->buffer, surf->cbzb_pitch, 0, surf->domain); + + DBG(r300, DBG_CBZB, + "CBZB clearing cbuf %08x %08x\n", surf->cbzb_format, + surf->cbzb_pitch); } /* Set up a zbuffer. */ else if (fb->zsbuf) { @@ -377,15 +383,32 @@ void r300_emit_fb_state(struct r300_context* r300, unsigned size, void* state) OUT_CS_REG_SEQ(R300_ZB_DEPTHPITCH, 1); OUT_CS_RELOC(surf->buffer, surf->pitch, 0, surf->domain); - /* HiZ RAM. */ - if (r300->screen->caps.has_hiz) { - OUT_CS_REG(R300_ZB_HIZ_OFFSET, 0); - OUT_CS_REG(R300_ZB_HIZ_PITCH, 0); + if (has_hyperz) { + uint32_t surf_pitch; + struct r300_texture *tex; + int level = surf->base.level; + tex = r300_texture(surf->base.texture); + + surf_pitch = surf->pitch & R300_DEPTHPITCH_MASK; + /* HiZ RAM. */ + if (r300->screen->caps.hiz_ram) { + if (tex->hiz_mem[level]) { + OUT_CS_REG(R300_ZB_HIZ_OFFSET, tex->hiz_mem[level]->ofs); + OUT_CS_REG(R300_ZB_HIZ_PITCH, surf_pitch); + } else { + OUT_CS_REG(R300_ZB_HIZ_OFFSET, 0); + OUT_CS_REG(R300_ZB_HIZ_PITCH, 0); + } + } + /* Z Mask RAM. (compressed zbuffer) */ + if (tex->zmask_mem[level]) { + OUT_CS_REG(R300_ZB_ZMASK_OFFSET, tex->zmask_mem[level]->ofs); + OUT_CS_REG(R300_ZB_ZMASK_PITCH, surf_pitch); + } else { + OUT_CS_REG(R300_ZB_ZMASK_OFFSET, 0); + OUT_CS_REG(R300_ZB_ZMASK_PITCH, 0); + } } - - /* Z Mask RAM. (compressed zbuffer) */ - OUT_CS_REG(R300_ZB_ZMASK_OFFSET, 0); - OUT_CS_REG(R300_ZB_ZMASK_PITCH, 0); } END_CS; @@ -394,8 +417,12 @@ void r300_emit_fb_state(struct r300_context* r300, unsigned size, void* state) void r300_emit_hyperz_state(struct r300_context *r300, unsigned size, void *state) { + struct r300_hyperz_state *z = state; CS_LOCALS(r300); - WRITE_CS_TABLE(state, size); + if (z->flush) + WRITE_CS_TABLE(&z->cb_flush_begin, size); + else + WRITE_CS_TABLE(&z->cb_begin, size - 2); } void r300_emit_hyperz_end(struct r300_context *r300) @@ -403,9 +430,11 @@ void r300_emit_hyperz_end(struct r300_context *r300) struct r300_hyperz_state z = *(struct r300_hyperz_state*)r300->hyperz_state.state; + z.flush = 1; z.zb_bw_cntl = 0; z.zb_depthclearvalue = 0; z.sc_hyperz = R300_SC_HYPERZ_ADJ_2; + z.gb_z_peq_config = 0; r300_emit_hyperz_state(r300, r300->hyperz_state.size, &z); } @@ -943,6 +972,101 @@ void r300_emit_viewport_state(struct r300_context* r300, END_CS; } +static void r300_emit_hiz_line_clear(struct r300_context *r300, int start, uint16_t count, uint32_t val) +{ + CS_LOCALS(r300); + BEGIN_CS(4); + OUT_CS_PKT3(R300_PACKET3_3D_CLEAR_HIZ, 2); + OUT_CS(start); + OUT_CS(count); + OUT_CS(val); + END_CS; +} + +static void r300_emit_zmask_line_clear(struct r300_context *r300, int start, uint16_t count, uint32_t val) +{ + CS_LOCALS(r300); + BEGIN_CS(4); + OUT_CS_PKT3(R300_PACKET3_3D_CLEAR_ZMASK, 2); + OUT_CS(start); + OUT_CS(count); + OUT_CS(val); + END_CS; +} + +#define ALIGN_DIVUP(x, y) (((x) + (y) - 1) / (y)) + +void r300_emit_hiz_clear(struct r300_context *r300, unsigned size, void *state) +{ + struct pipe_framebuffer_state *fb = + (struct pipe_framebuffer_state*)r300->fb_state.state; + struct r300_hyperz_state *z = + (struct r300_hyperz_state*)r300->hyperz_state.state; + struct r300_screen* r300screen = r300->screen; + uint32_t stride, offset = 0, height, offset_shift; + struct r300_texture* tex; + int i; + + tex = r300_texture(fb->zsbuf->texture); + stride = tex->desc.stride_in_pixels[fb->zsbuf->level]; + + /* convert from pixels to 4x4 blocks */ + stride = ALIGN_DIVUP(stride, 4); + + stride = ALIGN_DIVUP(stride, r300screen->caps.num_frag_pipes); + /* there are 4 blocks per dwords */ + stride = ALIGN_DIVUP(stride, 4); + + height = ALIGN_DIVUP(fb->zsbuf->height, 4); + + offset_shift = 2; + offset_shift += (r300screen->caps.num_frag_pipes / 2); + + for (i = 0; i < height; i++) { + offset = i * stride; + offset <<= offset_shift; + r300_emit_hiz_line_clear(r300, offset, stride, 0xffffffff); + } + z->current_func = -1; +} + +void r300_emit_zmask_clear(struct r300_context *r300, unsigned size, void *state) +{ + struct pipe_framebuffer_state *fb = + (struct pipe_framebuffer_state*)r300->fb_state.state; + struct r300_screen* r300screen = r300->screen; + uint32_t stride, offset = 0; + struct r300_texture* tex; + uint32_t i, height; + int mult, offset_shift; + + tex = r300_texture(fb->zsbuf->texture); + stride = tex->desc.stride_in_pixels[fb->zsbuf->level]; + + if (r300->z_compression == RV350_Z_COMPRESS_88) + mult = 8; + else + mult = 4; + + height = ALIGN_DIVUP(fb->zsbuf->height, mult); + + offset_shift = 4; + offset_shift += (r300screen->caps.num_frag_pipes / 2); + stride = ALIGN_DIVUP(stride, r300screen->caps.num_frag_pipes); + + /* okay have width in pixels - divide by block width */ + stride = ALIGN_DIVUP(stride, mult); + /* have width in blocks - divide by number of fragment pipes screen width */ + /* 16 blocks per dword */ + stride = ALIGN_DIVUP(stride, 16); + + for (i = 0; i < height; i++) { + offset = i * stride; + offset <<= offset_shift; + r300_emit_zmask_line_clear(r300, offset, stride, 0x0);//0xffffffff); + } +} + void r300_emit_ztop_state(struct r300_context* r300, unsigned size, void* state) { diff --git a/src/gallium/drivers/r300/r300_emit.h b/src/gallium/drivers/r300/r300_emit.h index 5d05039669f..2f2c2f2dcb4 100644 --- a/src/gallium/drivers/r300/r300_emit.h +++ b/src/gallium/drivers/r300/r300_emit.h @@ -112,6 +112,9 @@ void r300_emit_texture_cache_inval(struct r300_context* r300, unsigned size, voi void r300_emit_invariant_state(struct r300_context *r300, unsigned size, void *state); +void r300_emit_hiz_clear(struct r300_context *r300, unsigned size, void *state); +void r300_emit_zmask_clear(struct r300_context *r300, unsigned size, void *state); + unsigned r300_get_num_dirty_dwords(struct r300_context *r300); /* Emit all dirty state. */ diff --git a/src/gallium/drivers/r300/r300_flush.c b/src/gallium/drivers/r300/r300_flush.c index ae7b5759e78..7fed9b5d074 100644 --- a/src/gallium/drivers/r300/r300_flush.c +++ b/src/gallium/drivers/r300/r300_flush.c @@ -43,16 +43,9 @@ static void r300_flush(struct pipe_context* pipe, u_upload_flush(r300->upload_vb); u_upload_flush(r300->upload_ib); - /* We probably need to flush Draw, but we may have been called from - * within Draw. This feels kludgy, but it might be the best thing. - * - * Of course, the best thing is to kill Draw with fire. :3 */ - if (r300->draw && !r300->draw->flushing) { - draw_flush(r300->draw); - } - if (r300->dirty_hw) { - r300_emit_hyperz_end(r300); + if (r300->rws->get_value(r300->rws, R300_CAN_HYPERZ)) + r300_emit_hyperz_end(r300); r300_emit_query_end(r300); r300->flush_counter++; diff --git a/src/gallium/drivers/r300/r300_fs.c b/src/gallium/drivers/r300/r300_fs.c index db5269912e2..87ff49a90c7 100644 --- a/src/gallium/drivers/r300/r300_fs.c +++ b/src/gallium/drivers/r300/r300_fs.c @@ -248,13 +248,18 @@ static void r300_emit_fs_code_to_buffer( shader->cb_code_size = 19 + ((code->inst_end + 1) * 6) + - imm_count * 7; + imm_count * 7 + + code->int_constant_count * 2; NEW_CB(shader->cb_code, shader->cb_code_size); OUT_CB_REG(R500_US_CONFIG, R500_ZERO_TIMES_ANYTHING_EQUALS_ZERO); OUT_CB_REG(R500_US_PIXSIZE, code->max_temp_idx); OUT_CB_REG(R500_US_FC_CTRL, code->us_fc_ctrl); - OUT_CB_REG(R500_US_CODE_RANGE, + for(i = 0; i < code->int_constant_count; i++){ + OUT_CB_REG(R500_US_FC_INT_CONST_0 + (i * 4), + code->int_constants[i]); + } + OUT_CB_REG(R500_US_CODE_RANGE, R500_US_CODE_RANGE_ADDR(0) | R500_US_CODE_RANGE_SIZE(code->inst_end)); OUT_CB_REG(R500_US_CODE_OFFSET, 0); OUT_CB_REG(R500_US_CODE_ADDR, diff --git a/src/gallium/drivers/r300/r300_hyperz.c b/src/gallium/drivers/r300/r300_hyperz.c index e9528956019..10e440ce306 100644 --- a/src/gallium/drivers/r300/r300_hyperz.c +++ b/src/gallium/drivers/r300/r300_hyperz.c @@ -21,25 +21,156 @@ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE * USE OR OTHER DEALINGS IN THE SOFTWARE. */ +#include "util/u_format.h" +#include "util/u_mm.h" #include "r300_context.h" #include "r300_hyperz.h" #include "r300_reg.h" #include "r300_fs.h" +/* + HiZ rules - taken from various docs + 1. HiZ only works on depth values + 2. Cannot HiZ if stencil fail or zfail is !KEEP + 3. on R300/400, HiZ is disabled if depth test is EQUAL + 4. comparison changes without clears usually mean disabling HiZ +*/ /*****************************************************************************/ /* The HyperZ setup */ /*****************************************************************************/ +static bool r300_get_sc_hz_max(struct r300_context *r300) +{ + struct r300_dsa_state *dsa_state = r300->dsa_state.state; + int func = dsa_state->z_stencil_control & 0x7; + int ret = R300_SC_HYPERZ_MIN; + + if (func >= 4 && func <= 7) + ret = R300_SC_HYPERZ_MAX; + return ret; +} + +static bool r300_zfunc_same_direction(int func1, int func2) +{ + /* func1 is less/lessthan */ + if (func1 == 1 || func1 == 2) + if (func2 == 3 || func2 == 4 || func2 == 5) + return FALSE; + + if (func2 == 1 || func2 == 2) + if (func1 == 4 || func1 == 5) + return FALSE; + return TRUE; +} + +static int r300_get_hiz_min(struct r300_context *r300) +{ + struct r300_dsa_state *dsa_state = r300->dsa_state.state; + int func = dsa_state->z_stencil_control & 0x7; + int ret = R300_HIZ_MIN; + + if (func == 1 || func == 2) + ret = R300_HIZ_MAX; + return ret; +} + +static boolean r300_dsa_stencil_op_not_keep(struct pipe_stencil_state *s) +{ + if (s->enabled && (s->fail_op != PIPE_STENCIL_OP_KEEP || + s->zfail_op != PIPE_STENCIL_OP_KEEP)) + return TRUE; + return FALSE; +} + +static boolean r300_can_hiz(struct r300_context *r300) +{ + struct r300_dsa_state *dsa_state = r300->dsa_state.state; + struct pipe_depth_stencil_alpha_state *dsa = &dsa_state->dsa; + struct r300_screen* r300screen = r300->screen; + struct r300_hyperz_state *z = r300->hyperz_state.state; + + /* shader writes depth - no HiZ */ + if (r300_fragment_shader_writes_depth(r300_fs(r300))) /* (5) */ + return FALSE; + + if (r300->query_current) + return FALSE; + /* if stencil fail/zfail op is not KEEP */ + if (r300_dsa_stencil_op_not_keep(&dsa->stencil[0]) || + r300_dsa_stencil_op_not_keep(&dsa->stencil[1])) + return FALSE; + + if (dsa->depth.enabled) { + /* if depth func is EQUAL pre-r500 */ + if (dsa->depth.func == PIPE_FUNC_EQUAL && !r300screen->caps.is_r500) + return FALSE; + /* if depth func is NOTEQUAL */ + if (dsa->depth.func == PIPE_FUNC_NOTEQUAL) + return FALSE; + } + /* depth comparison function - if just cleared save and return okay */ + if (z->current_func == -1) { + int func = dsa_state->z_stencil_control & 0x7; + if (func != 0 && func != 7) + z->current_func = dsa_state->z_stencil_control & 0x7; + } else { + /* simple don't change */ + if (!r300_zfunc_same_direction(z->current_func, (dsa_state->z_stencil_control & 0x7))) { + DBG(r300, DBG_HYPERZ, "z func changed direction - disabling hyper-z %d -> %d\n", z->current_func, dsa_state->z_stencil_control); + return FALSE; + } + } + return TRUE; +} + static void r300_update_hyperz(struct r300_context* r300) { struct r300_hyperz_state *z = (struct r300_hyperz_state*)r300->hyperz_state.state; + z->gb_z_peq_config = 0; z->zb_bw_cntl = 0; z->sc_hyperz = R300_SC_HYPERZ_ADJ_2; + z->flush = 0; - if (r300->cbzb_clear) + if (r300->cbzb_clear) { z->zb_bw_cntl |= R300_ZB_CB_CLEAR_CACHE_LINE_WRITE_ONLY; + return; + } + + /* Zbuffer compression. */ + if (r300->z_compression) { + z->zb_bw_cntl |= R300_RD_COMP_ENABLE; + if (r300->z_decomp_rd == false) + z->zb_bw_cntl |= R300_WR_COMP_ENABLE; + /* RV350 and up optimizations. */ + if (r300->z_compression == RV350_Z_COMPRESS_88) + z->gb_z_peq_config |= R300_GB_Z_PEQ_CONFIG_Z_PEQ_SIZE_8_8; + } + + /* Z fastfill. */ + if (r300->z_fastfill) { + z->zb_bw_cntl |= R300_FAST_FILL_ENABLE; /* | R300_FORCE_COMPRESSED_STENCIL_VALUE_ENABLE;*/ + } + + if (r300->hiz_enable) { + bool can_hiz = r300_can_hiz(r300); + if (can_hiz) { + z->zb_bw_cntl |= R300_HIZ_ENABLE; + z->sc_hyperz |= R300_SC_HYPERZ_ENABLE; + z->sc_hyperz |= r300_get_sc_hz_max(r300); + z->zb_bw_cntl |= r300_get_hiz_min(r300); + } + } + + if (r300->screen->caps.is_r500) { + /* XXX Are these bits really available on RV350? */ + z->zb_bw_cntl |= R500_HIZ_FP_EXP_BITS_3; + z->zb_bw_cntl |= + R500_HIZ_EQUAL_REJECT_ENABLE | + R500_PEQ_PACKING_ENABLE | + R500_COVERED_PTR_MASKING_ENABLE; + } } /*****************************************************************************/ @@ -126,15 +257,115 @@ static void r300_update_ztop(struct r300_context* r300) } else { ztop_state->z_buffer_top = R300_ZTOP_ENABLE; } - if (ztop_state->z_buffer_top != old_ztop) r300->ztop_state.dirty = TRUE; } +#define ALIGN_DIVUP(x, y) (((x) + (y) - 1) / (y)) + +static void r300_update_hiz_clear(struct r300_context *r300) +{ + struct pipe_framebuffer_state *fb = + (struct pipe_framebuffer_state*)r300->fb_state.state; + uint32_t height; + + height = ALIGN_DIVUP(fb->zsbuf->height, 4); + r300->hiz_clear.size = height * 4; +} + +static void r300_update_zmask_clear(struct r300_context *r300) +{ + struct pipe_framebuffer_state *fb = + (struct pipe_framebuffer_state*)r300->fb_state.state; + uint32_t height; + int mult; + + if (r300->z_compression == RV350_Z_COMPRESS_88) + mult = 8; + else + mult = 4; + + height = ALIGN_DIVUP(fb->zsbuf->height, mult); + + r300->zmask_clear.size = height * 4; +} + void r300_update_hyperz_state(struct r300_context* r300) { r300_update_ztop(r300); if (r300->hyperz_state.dirty) { r300_update_hyperz(r300); } + + if (r300->hiz_clear.dirty) { + r300_update_hiz_clear(r300); + } + if (r300->zmask_clear.dirty) { + r300_update_zmask_clear(r300); + } +} + +void r300_hiz_alloc_block(struct r300_context *r300, struct r300_surface *surf) +{ + struct r300_texture *tex; + uint32_t zsize, ndw; + int level = surf->base.level; + + tex = r300_texture(surf->base.texture); + + if (tex->hiz_mem[level]) + return; + + zsize = tex->desc.layer_size_in_bytes[level]; + zsize /= util_format_get_blocksize(tex->desc.b.b.format); + ndw = ALIGN_DIVUP(zsize, 64); + + tex->hiz_mem[level] = u_mmAllocMem(r300->hiz_mm, ndw, 0, 0); + return; +} + +void r300_zmask_alloc_block(struct r300_context *r300, struct r300_surface *surf, int compress) +{ + int bsize = 256; + uint32_t zsize, ndw; + int level = surf->base.level; + struct r300_texture *tex; + + tex = r300_texture(surf->base.texture); + + if (tex->zmask_mem[level]) + return; + + zsize = tex->desc.layer_size_in_bytes[level]; + zsize /= util_format_get_blocksize(tex->desc.b.b.format); + + /* each zmask dword represents 16 4x4 blocks - which is 256 pixels + or 16 8x8 depending on the gb peq flag = 1024 pixels */ + if (compress == RV350_Z_COMPRESS_88) + bsize = 1024; + + ndw = ALIGN_DIVUP(zsize, bsize); + tex->zmask_mem[level] = u_mmAllocMem(r300->zmask_mm, ndw, 0, 0); + return; +} + +void r300_hyperz_init_mm(struct r300_context *r300) +{ + struct r300_screen* r300screen = r300->screen; + int frag_pipes = r300screen->caps.num_frag_pipes; + + if (r300screen->caps.hiz_ram) + r300->hiz_mm = u_mmInit(0, r300screen->caps.hiz_ram * frag_pipes); + + r300->zmask_mm = u_mmInit(0, r300screen->caps.zmask_ram * frag_pipes); +} + +void r300_hyperz_destroy_mm(struct r300_context *r300) +{ + struct r300_screen* r300screen = r300->screen; + + if (r300screen->caps.hiz_ram) + u_mmDestroy(r300->hiz_mm); + + u_mmDestroy(r300->zmask_mm); } diff --git a/src/gallium/drivers/r300/r300_hyperz.h b/src/gallium/drivers/r300/r300_hyperz.h index 3df5053b896..09e1ff6625c 100644 --- a/src/gallium/drivers/r300/r300_hyperz.h +++ b/src/gallium/drivers/r300/r300_hyperz.h @@ -27,4 +27,9 @@ struct r300_context; void r300_update_hyperz_state(struct r300_context* r300); +void r300_hiz_alloc_block(struct r300_context *r300, struct r300_surface *surf); +void r300_zmask_alloc_block(struct r300_context *r300, struct r300_surface *surf, int compress); + +void r300_hyperz_init_mm(struct r300_context *r300); +void r300_hyperz_destroy_mm(struct r300_context *r300); #endif diff --git a/src/gallium/drivers/r300/r300_reg.h b/src/gallium/drivers/r300/r300_reg.h index 2acc1a903e8..99a9d650551 100644 --- a/src/gallium/drivers/r300/r300_reg.h +++ b/src/gallium/drivers/r300/r300_reg.h @@ -3436,6 +3436,7 @@ enum { # define R300_VBPNTR_SIZE1(x) (((x) >> 2) << 16) # define R300_VBPNTR_STRIDE1(x) (((x) >> 2) << 24) +#define R300_PACKET3_3D_CLEAR_ZMASK 0x00003200 #define R300_PACKET3_INDX_BUFFER 0x00003300 # define R300_INDX_BUFFER_DST_SHIFT 0 # define R300_INDX_BUFFER_SKIP_SHIFT 16 diff --git a/src/gallium/drivers/r300/r300_render.c b/src/gallium/drivers/r300/r300_render.c index bae02135da9..910f5f7113e 100644 --- a/src/gallium/drivers/r300/r300_render.c +++ b/src/gallium/drivers/r300/r300_render.c @@ -223,7 +223,8 @@ static void r300_prepare_for_rendering(struct r300_context *r300, /* Emitted in flush. */ end_dwords += 26; /* emit_query_end */ - end_dwords += r300->hyperz_state.size; /* emit_hyperz_end */ + if (r300->rws->get_value(r300->rws, R300_CAN_HYPERZ)) + end_dwords += r300->hyperz_state.size + 2; /* emit_hyperz_end + zcache flush */ cs_dwords += end_dwords; @@ -566,19 +567,6 @@ static void r300_draw_range_elements(struct pipe_context* pipe, } } -/* Simple helpers for context setup. Should probably be moved to util. */ -static void r300_draw_elements(struct pipe_context* pipe, - struct pipe_resource* indexBuffer, - unsigned indexSize, int indexBias, unsigned mode, - unsigned start, unsigned count) -{ - struct r300_context *r300 = r300_context(pipe); - - pipe->draw_range_elements(pipe, indexBuffer, indexSize, indexBias, - 0, r300->vertex_buffer_max_index, - mode, start, count); -} - static void r300_draw_arrays(struct pipe_context* pipe, unsigned mode, unsigned start, unsigned count) { @@ -638,111 +626,104 @@ static void r300_draw_arrays(struct pipe_context* pipe, unsigned mode, } } -/**************************************************************************** - * The rest of this file is for SW TCL rendering only. Please be polite and * - * keep these functions separated so that they are easier to locate. ~C. * - ***************************************************************************/ - -/* SW TCL arrays, using Draw. */ -static void r300_swtcl_draw_arrays(struct pipe_context* pipe, - unsigned mode, - unsigned start, - unsigned count) +static void r300_draw_vbo(struct pipe_context* pipe, + const struct pipe_draw_info *info) { struct r300_context* r300 = r300_context(pipe); - struct pipe_transfer *vb_transfer[PIPE_MAX_ATTRIBS]; - int i; - if (r300->skip_rendering) { - return; + if (info->indexed && r300->index_buffer.buffer) { + unsigned offset; + + assert(r300->index_buffer.offset % r300->index_buffer.index_size == 0); + offset = r300->index_buffer.offset / r300->index_buffer.index_size; + + r300_draw_range_elements(pipe, + r300->index_buffer.buffer, + r300->index_buffer.index_size, + info->index_bias, + info->min_index, + info->max_index, + info->mode, + info->start + offset, + info->count); } - - if (!u_trim_pipe_prim(mode, &count)) { - return; - } - - r300_update_derived_state(r300); - - for (i = 0; i < r300->vertex_buffer_count; i++) { - void* buf = pipe_buffer_map(pipe, - r300->vertex_buffer[i].buffer, - PIPE_TRANSFER_READ, - &vb_transfer[i]); - draw_set_mapped_vertex_buffer(r300->draw, i, buf); - } - - draw_set_mapped_element_buffer(r300->draw, 0, 0, NULL); - - draw_arrays(r300->draw, mode, start, count); - - /* XXX Not sure whether this is the best fix. - * It prevents CS from being rejected and weird assertion failures. */ - draw_flush(r300->draw); - - for (i = 0; i < r300->vertex_buffer_count; i++) { - pipe_buffer_unmap(pipe, r300->vertex_buffer[i].buffer, - vb_transfer[i]); - draw_set_mapped_vertex_buffer(r300->draw, i, NULL); + else { + r300_draw_arrays(pipe, + info->mode, + info->start, + info->count); } } +/**************************************************************************** + * The rest of this file is for SW TCL rendering only. Please be polite and * + * keep these functions separated so that they are easier to locate. ~C. * + ***************************************************************************/ + /* SW TCL elements, using Draw. */ -static void r300_swtcl_draw_range_elements(struct pipe_context* pipe, - struct pipe_resource* indexBuffer, - unsigned indexSize, - int indexBias, - unsigned minIndex, - unsigned maxIndex, - unsigned mode, - unsigned start, - unsigned count) +static void r300_swtcl_draw_vbo(struct pipe_context* pipe, + const struct pipe_draw_info *info) { struct r300_context* r300 = r300_context(pipe); struct pipe_transfer *vb_transfer[PIPE_MAX_ATTRIBS]; - struct pipe_transfer *ib_transfer; + struct pipe_transfer *ib_transfer = NULL; + unsigned count = info->count; int i; - void* indices; + void* indices = NULL; if (r300->skip_rendering) { return; } - if (!u_trim_pipe_prim(mode, &count)) { + if (!u_trim_pipe_prim(info->mode, &count)) { return; } r300_update_derived_state(r300); for (i = 0; i < r300->vertex_buffer_count; i++) { - void* buf = pipe_buffer_map(pipe, - r300->vertex_buffer[i].buffer, - PIPE_TRANSFER_READ, - &vb_transfer[i]); - draw_set_mapped_vertex_buffer(r300->draw, i, buf); + if (r300->vertex_buffer[i].buffer) { + void *buf = pipe_buffer_map(pipe, + r300->vertex_buffer[i].buffer, + PIPE_TRANSFER_READ, + &vb_transfer[i]); + draw_set_mapped_vertex_buffer(r300->draw, i, buf); + } + } + + if (info->indexed && r300->index_buffer.buffer) { + indices = pipe_buffer_map(pipe, r300->index_buffer.buffer, + PIPE_TRANSFER_READ, &ib_transfer); + if (indices) + indices = (void *) ((char *) indices + r300->index_buffer.offset); } - indices = pipe_buffer_map(pipe, indexBuffer, - PIPE_TRANSFER_READ, &ib_transfer); - draw_set_mapped_element_buffer_range(r300->draw, indexSize, indexBias, - minIndex, maxIndex, indices); + draw_set_mapped_element_buffer_range(r300->draw, (indices) ? + r300->index_buffer.index_size : 0, + info->index_bias, + info->min_index, + info->max_index, + indices); - draw_arrays(r300->draw, mode, start, count); + draw_arrays(r300->draw, info->mode, info->start, count); /* XXX Not sure whether this is the best fix. * It prevents CS from being rejected and weird assertion failures. */ draw_flush(r300->draw); for (i = 0; i < r300->vertex_buffer_count; i++) { - pipe_buffer_unmap(pipe, r300->vertex_buffer[i].buffer, - vb_transfer[i]); - draw_set_mapped_vertex_buffer(r300->draw, i, NULL); + if (r300->vertex_buffer[i].buffer) { + pipe_buffer_unmap(pipe, r300->vertex_buffer[i].buffer, + vb_transfer[i]); + draw_set_mapped_vertex_buffer(r300->draw, i, NULL); + } } - pipe_buffer_unmap(pipe, indexBuffer, - ib_transfer); - draw_set_mapped_element_buffer_range(r300->draw, 0, 0, - start, start + count - 1, - NULL); + if (ib_transfer) { + pipe_buffer_unmap(pipe, r300->index_buffer.buffer, ib_transfer); + draw_set_mapped_element_buffer_range(r300->draw, 0, 0, info->start, + info->start + count - 1, NULL); + } } /* Object for rendering using Draw. */ @@ -820,6 +801,8 @@ static void* r300_render_map_vertices(struct vbuf_render* render) PIPE_TRANSFER_WRITE, &r300render->vbo_transfer); + assert(r300render->vbo_ptr); + return ((uint8_t*)r300render->vbo_ptr + r300render->vbo_offset); } @@ -1141,16 +1124,11 @@ static void r300_resource_resolve(struct pipe_context* pipe, void r300_init_render_functions(struct r300_context *r300) { - /* Set generic functions. */ - r300->context.draw_elements = r300_draw_elements; - /* Set draw functions based on presence of HW TCL. */ if (r300->screen->caps.has_tcl) { - r300->context.draw_arrays = r300_draw_arrays; - r300->context.draw_range_elements = r300_draw_range_elements; + r300->context.draw_vbo = r300_draw_vbo; } else { - r300->context.draw_arrays = r300_swtcl_draw_arrays; - r300->context.draw_range_elements = r300_swtcl_draw_range_elements; + r300->context.draw_vbo = r300_swtcl_draw_vbo; } r300->context.resource_resolve = r300_resource_resolve; diff --git a/src/gallium/drivers/r300/r300_render_stencilref.c b/src/gallium/drivers/r300/r300_render_stencilref.c index 9a6b4e12ff1..1f035d64a28 100644 --- a/src/gallium/drivers/r300/r300_render_stencilref.c +++ b/src/gallium/drivers/r300/r300_render_stencilref.c @@ -34,13 +34,8 @@ #include "r300_reg.h" struct r300_stencilref_context { - void (*draw_arrays)(struct pipe_context *pipe, - unsigned mode, unsigned start, unsigned count); - - void (*draw_range_elements)( - struct pipe_context *pipe, struct pipe_resource *indexBuffer, - unsigned indexSize, int indexBias, unsigned minIndex, unsigned maxIndex, - unsigned mode, unsigned start, unsigned count); + void (*draw_vbo)(struct pipe_context *pipe, + const struct pipe_draw_info *info); uint32_t rs_cull_mode; uint32_t zb_stencilrefmask; @@ -105,41 +100,19 @@ static void r300_stencilref_end(struct r300_context *r300) r300->dsa_state.dirty = TRUE; } -static void r300_stencilref_draw_arrays(struct pipe_context *pipe, unsigned mode, - unsigned start, unsigned count) -{ - struct r300_context *r300 = r300_context(pipe); - struct r300_stencilref_context *sr = r300->stencilref_fallback; - - if (!r300_stencilref_needed(r300)) { - sr->draw_arrays(pipe, mode, start, count); - } else { - r300_stencilref_begin(r300); - sr->draw_arrays(pipe, mode, start, count); - r300_stencilref_switch_side(r300); - sr->draw_arrays(pipe, mode, start, count); - r300_stencilref_end(r300); - } -} - -static void r300_stencilref_draw_range_elements( - struct pipe_context *pipe, struct pipe_resource *indexBuffer, - unsigned indexSize, int indexBias, unsigned minIndex, unsigned maxIndex, - unsigned mode, unsigned start, unsigned count) +static void r300_stencilref_draw_vbo(struct pipe_context *pipe, + const struct pipe_draw_info *info) { struct r300_context *r300 = r300_context(pipe); struct r300_stencilref_context *sr = r300->stencilref_fallback; if (!r300_stencilref_needed(r300)) { - sr->draw_range_elements(pipe, indexBuffer, indexSize, indexBias, - minIndex, maxIndex, mode, start, count); + sr->draw_vbo(pipe, info); } else { r300_stencilref_begin(r300); - sr->draw_range_elements(pipe, indexBuffer, indexSize, indexBias, - minIndex, maxIndex, mode, start, count); + sr->draw_vbo(pipe, info); r300_stencilref_switch_side(r300); - sr->draw_range_elements(pipe, indexBuffer, indexSize, indexBias, - minIndex, maxIndex, mode, start, count); + sr->draw_vbo(pipe, info); r300_stencilref_end(r300); } } @@ -148,11 +121,9 @@ void r300_plug_in_stencil_ref_fallback(struct r300_context *r300) { r300->stencilref_fallback = CALLOC_STRUCT(r300_stencilref_context); - /* Save original draw functions. */ - r300->stencilref_fallback->draw_arrays = r300->context.draw_arrays; - r300->stencilref_fallback->draw_range_elements = r300->context.draw_range_elements; + /* Save original draw function. */ + r300->stencilref_fallback->draw_vbo = r300->context.draw_vbo; - /* Override the draw functions. */ - r300->context.draw_arrays = r300_stencilref_draw_arrays; - r300->context.draw_range_elements = r300_stencilref_draw_range_elements; + /* Override the draw function. */ + r300->context.draw_vbo = r300_stencilref_draw_vbo; } diff --git a/src/gallium/drivers/r300/r300_screen.c b/src/gallium/drivers/r300/r300_screen.c index 676430f5fee..6268001054b 100644 --- a/src/gallium/drivers/r300/r300_screen.c +++ b/src/gallium/drivers/r300/r300_screen.c @@ -279,11 +279,14 @@ static boolean r300_is_format_supported(struct pipe_screen* screen, case 3: case 4: case 6: + return FALSE; +#if 0 if (usage != PIPE_BIND_RENDER_TARGET || !util_format_is_rgba8_variant( util_format_description(format))) { return FALSE; } +#endif break; default: return FALSE; diff --git a/src/gallium/drivers/r300/r300_screen.h b/src/gallium/drivers/r300/r300_screen.h index 18745b83a09..13a3320b992 100644 --- a/src/gallium/drivers/r300/r300_screen.h +++ b/src/gallium/drivers/r300/r300_screen.h @@ -91,6 +91,7 @@ r300_winsys_screen(struct pipe_screen *screen) { #define DBG_FB (1 << 9) #define DBG_RS_BLOCK (1 << 10) #define DBG_CBZB (1 << 11) +#define DBG_HYPERZ (1 << 12) /* Features. */ #define DBG_ANISOHQ (1 << 16) #define DBG_NO_TILING (1 << 17) diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c index 3e221f2e02d..1e6b81d7989 100644 --- a/src/gallium/drivers/r300/r300_state.c +++ b/src/gallium/drivers/r300/r300_state.c @@ -25,6 +25,7 @@ #include "util/u_blitter.h" #include "util/u_math.h" +#include "util/u_mm.h" #include "util/u_memory.h" #include "util/u_pack_color.h" @@ -43,6 +44,7 @@ #include "r300_texture.h" #include "r300_vs.h" #include "r300_winsys.h" +#include "r300_hyperz.h" /* r300_state: Functions used to intialize state context by translating * Gallium state objects into semi-native r300 state objects. */ @@ -446,7 +448,6 @@ static void r300_set_clip_state(struct pipe_context* pipe, r300->clip_state.dirty = TRUE; } else { - draw_flush(r300->draw); draw_set_clip_state(r300->draw, state); } } @@ -473,14 +474,14 @@ static void* dsa->dsa = *state; - /* Depth test setup. */ + /* Depth test setup. - separate write mask depth for decomp flush */ + if (state->depth.writemask) { + dsa->z_buffer_control |= R300_Z_WRITE_ENABLE; + } + if (state->depth.enabled) { dsa->z_buffer_control |= R300_Z_ENABLE; - if (state->depth.writemask) { - dsa->z_buffer_control |= R300_Z_WRITE_ENABLE; - } - dsa->z_stencil_control |= (r300_translate_depth_stencil_function(state->depth.func) << R300_Z_FUNC_SHIFT); @@ -593,6 +594,7 @@ static void r300_bind_dsa_state(struct pipe_context* pipe, UPDATE_STATE(state, r300->dsa_state); + r300->hyperz_state.dirty = TRUE; /* Will be updated before the emission. */ r300_dsa_inject_stencilref(r300); } @@ -682,11 +684,13 @@ void r300_mark_fb_state_dirty(struct r300_context *r300, enum r300_fb_state_change change) { struct pipe_framebuffer_state *state = r300->fb_state.state; + boolean has_hyperz = r300->rws->get_value(r300->rws, R300_CAN_HYPERZ); /* What is marked as dirty depends on the enum r300_fb_state_change. */ r300->gpu_flush.dirty = TRUE; r300->fb_state.dirty = TRUE; - r300->hyperz_state.dirty = TRUE; + if (r300->rws->get_value(r300->rws, R300_CAN_HYPERZ)) + r300->hyperz_state.dirty = TRUE; if (change == R300_CHANGED_FB_STATE) { r300->aa_state.dirty = TRUE; @@ -698,8 +702,11 @@ void r300_mark_fb_state_dirty(struct r300_context *r300, if (r300->cbzb_clear) r300->fb_state.size += 10; - else if (state->zsbuf) - r300->fb_state.size += r300->screen->caps.has_hiz ? 18 : 14; + else if (state->zsbuf) { + r300->fb_state.size += 10; + if (has_hyperz) + r300->fb_state.size += r300->screen->caps.hiz_ram ? 8 : 4; + } /* The size of the rest of atoms stays the same. */ } @@ -711,8 +718,10 @@ static void struct r300_context* r300 = r300_context(pipe); struct r300_aa_state *aa = (struct r300_aa_state*)r300->aa_state.state; struct pipe_framebuffer_state *old_state = r300->fb_state.state; + boolean has_hyperz = r300->rws->get_value(r300->rws, R300_CAN_HYPERZ); unsigned max_width, max_height, i; uint32_t zbuffer_bpp = 0; + int blocksize; if (r300->screen->caps.is_r500) { max_width = max_height = 4096; @@ -728,10 +737,6 @@ static void return; } - if (r300->draw) { - draw_flush(r300->draw); - } - /* If nr_cbufs is changed from zero to non-zero or vice versa... */ if (!!old_state->nr_cbufs != !!state->nr_cbufs) { r300->blend_state.dirty = TRUE; @@ -748,20 +753,57 @@ static void r300_mark_fb_state_dirty(r300, R300_CHANGED_FB_STATE); - /* Polygon offset depends on the zbuffer bit depth. */ - if (state->zsbuf && r300->polygon_offset_enabled) { - switch (util_format_get_blocksize(state->zsbuf->texture->format)) { - case 2: - zbuffer_bpp = 16; - break; - case 4: - zbuffer_bpp = 24; - break; + r300->hiz_enable = false; + r300->z_fastfill = false; + r300->z_compression = false; + + if (state->zsbuf) { + blocksize = util_format_get_blocksize(state->zsbuf->texture->format); + switch (blocksize) { + case 2: + zbuffer_bpp = 16; + break; + case 4: + zbuffer_bpp = 24; + break; } + if (has_hyperz) { + struct r300_surface *zs_surf = r300_surface(state->zsbuf); + struct r300_texture *tex; + int compress = r300->screen->caps.is_rv350 ? RV350_Z_COMPRESS_88 : R300_Z_COMPRESS_44; + int level = zs_surf->base.level; + + tex = r300_texture(zs_surf->base.texture); + + /* work out whether we can support hiz on this buffer */ + r300_hiz_alloc_block(r300, zs_surf); + + /* work out whether we can support zmask features on this buffer */ + r300_zmask_alloc_block(r300, zs_surf, compress); + + if (tex->hiz_mem[level]) { + r300->hiz_enable = 1; + } + if (tex->zmask_mem[level]) { + r300->z_fastfill = 1; + /* compression causes hangs on 16-bit */ + if (zbuffer_bpp == 24) + r300->z_compression = compress; + } + DBG(r300, DBG_HYPERZ, + "hyper-z features: hiz: %d @ %08x z-compression: %d z-fastfill: %d @ %08x\n", r300->hiz_enable, + tex->hiz_mem[level] ? tex->hiz_mem[level]->ofs : 0xdeadbeef, + r300->z_compression, r300->z_fastfill, + tex->zmask_mem[level] ? tex->zmask_mem[level]->ofs : 0xdeadbeef); + } + + /* Polygon offset depends on the zbuffer bit depth. */ if (r300->zbuffer_bpp != zbuffer_bpp) { r300->zbuffer_bpp = zbuffer_bpp; - r300->rs_state.dirty = TRUE; + + if (r300->polygon_offset_enabled) + r300->rs_state.dirty = TRUE; } } @@ -1019,7 +1061,7 @@ static void* r300_create_rs_state(struct pipe_context* pipe, for (i = 0; i < 8; i++) { if (state->sprite_coord_enable & (1 << i)) stuffing_enable |= - R300_GB_TEX_STR << (R300_GB_TEX0_SOURCE_SHIFT + (i*2)); + R300_GB_TEX_ST << (R300_GB_TEX0_SOURCE_SHIFT + (i*2)); } point_texcoord_left = 0.0f; @@ -1096,14 +1138,11 @@ static void r300_bind_rs_state(struct pipe_context* pipe, void* state) boolean last_two_sided_color = r300->two_sided_color; if (r300->draw && rs) { - draw_flush(r300->draw); draw_set_rasterizer_state(r300->draw, &rs->rs_draw, state); } if (rs) { - r300->polygon_offset_enabled = (rs->rs.offset_point || - rs->rs.offset_line || - rs->rs.offset_tri); + r300->polygon_offset_enabled = rs->polygon_offset_enable; r300->sprite_coord_enable = rs->rs.sprite_coord_enable; r300->two_sided_color = rs->rs.light_twoside; } else { @@ -1385,7 +1424,6 @@ static void r300_set_viewport_state(struct pipe_context* pipe, r300->viewport = *state; if (r300->draw) { - draw_flush(r300->draw); draw_set_viewport_state(r300->draw, state); viewport->vte_control = R300_VTX_XY_FMT | R300_VTX_Z_FMT; return; @@ -1486,7 +1524,6 @@ static void r300_set_vertex_buffers(struct pipe_context* pipe, } else { /* SW TCL. */ - draw_flush(r300->draw); draw_set_vertex_buffers(r300->draw, count, buffers); } @@ -1505,6 +1542,23 @@ static void r300_set_vertex_buffers(struct pipe_context* pipe, r300->vertex_buffer_count = count; } +static void r300_set_index_buffer(struct pipe_context* pipe, + const struct pipe_index_buffer *ib) +{ + struct r300_context* r300 = r300_context(pipe); + + if (ib) { + pipe_resource_reference(&r300->index_buffer.buffer, ib->buffer); + memcpy(&r300->index_buffer, ib, sizeof(r300->index_buffer)); + } + else { + pipe_resource_reference(&r300->index_buffer.buffer, NULL); + memset(&r300->index_buffer, 0, sizeof(r300->index_buffer)); + } + + /* TODO make this more like a state */ +} + /* Initialize the PSC tables. */ static void r300_vertex_psc(struct r300_vertex_element_state *velems) { @@ -1654,7 +1708,6 @@ static void r300_bind_vertex_elements_state(struct pipe_context *pipe, r300->velems = velems; if (r300->draw) { - draw_flush(r300->draw); draw_set_vertex_elements(r300->draw, velems->count, velems->velem); return; } @@ -1720,7 +1773,6 @@ static void r300_bind_vs_state(struct pipe_context* pipe, void* shader) r300->pvs_flush.dirty = TRUE; } else { - draw_flush(r300->draw); draw_bind_vertex_shader(r300->draw, (struct draw_vertex_shader*)vs->draw_vs); } @@ -1852,6 +1904,7 @@ void r300_init_state_functions(struct r300_context* r300) r300->context.set_viewport_state = r300_set_viewport_state; r300->context.set_vertex_buffers = r300_set_vertex_buffers; + r300->context.set_index_buffer = r300_set_index_buffer; r300->context.create_vertex_elements_state = r300_create_vertex_elements_state; r300->context.bind_vertex_elements_state = r300_bind_vertex_elements_state; diff --git a/src/gallium/drivers/r300/r300_state_derived.c b/src/gallium/drivers/r300/r300_state_derived.c index a85db27064c..f3dad4c2923 100644 --- a/src/gallium/drivers/r300/r300_state_derived.c +++ b/src/gallium/drivers/r300/r300_state_derived.c @@ -35,6 +35,7 @@ #include "r300_state_inlines.h" #include "r300_texture.h" #include "r300_vs.h" +#include "r300_winsys.h" /* r300_state_derived: Various bits of state which are dependent upon * currently bound CSO data. */ @@ -213,19 +214,19 @@ static void r300_rs_tex(struct r300_rs_block* rs, int id, int ptr, enum r300_rs_swizzle swiz) { if (swiz == SWIZ_X001) { - rs->ip[id] |= R300_RS_TEX_PTR(ptr*4) | + rs->ip[id] |= R300_RS_TEX_PTR(ptr) | R300_RS_SEL_S(R300_RS_SEL_C0) | R300_RS_SEL_T(R300_RS_SEL_K0) | R300_RS_SEL_R(R300_RS_SEL_K0) | R300_RS_SEL_Q(R300_RS_SEL_K1); } else if (swiz == SWIZ_XY01) { - rs->ip[id] |= R300_RS_TEX_PTR(ptr*4) | + rs->ip[id] |= R300_RS_TEX_PTR(ptr) | R300_RS_SEL_S(R300_RS_SEL_C0) | R300_RS_SEL_T(R300_RS_SEL_C1) | R300_RS_SEL_R(R300_RS_SEL_K0) | R300_RS_SEL_Q(R300_RS_SEL_K1); } else { - rs->ip[id] |= R300_RS_TEX_PTR(ptr*4) | + rs->ip[id] |= R300_RS_TEX_PTR(ptr) | R300_RS_SEL_S(R300_RS_SEL_C0) | R300_RS_SEL_T(R300_RS_SEL_C1) | R300_RS_SEL_R(R300_RS_SEL_C2) | @@ -261,23 +262,21 @@ static void r500_rs_col_write(struct r300_rs_block* rs, int id, int fp_offset) static void r500_rs_tex(struct r300_rs_block* rs, int id, int ptr, enum r300_rs_swizzle swiz) { - int rs_tex_comp = ptr*4; - if (swiz == SWIZ_X001) { - rs->ip[id] |= R500_RS_SEL_S(rs_tex_comp) | + rs->ip[id] |= R500_RS_SEL_S(ptr) | R500_RS_SEL_T(R500_RS_IP_PTR_K0) | R500_RS_SEL_R(R500_RS_IP_PTR_K0) | R500_RS_SEL_Q(R500_RS_IP_PTR_K1); } else if (swiz == SWIZ_XY01) { - rs->ip[id] |= R500_RS_SEL_S(rs_tex_comp) | - R500_RS_SEL_T(rs_tex_comp + 1) | + rs->ip[id] |= R500_RS_SEL_S(ptr) | + R500_RS_SEL_T(ptr + 1) | R500_RS_SEL_R(R500_RS_IP_PTR_K0) | R500_RS_SEL_Q(R500_RS_IP_PTR_K1); } else { - rs->ip[id] |= R500_RS_SEL_S(rs_tex_comp) | - R500_RS_SEL_T(rs_tex_comp + 1) | - R500_RS_SEL_R(rs_tex_comp + 2) | - R500_RS_SEL_Q(rs_tex_comp + 3); + rs->ip[id] |= R500_RS_SEL_S(ptr) | + R500_RS_SEL_T(ptr + 1) | + R500_RS_SEL_R(ptr + 2) | + R500_RS_SEL_Q(ptr + 3); } rs->inst[id] |= R500_RS_INST_TEX_ID(id); } @@ -305,7 +304,7 @@ static void r300_update_rs_block(struct r300_context *r300) struct r300_shader_semantics *vs_outputs = &vs->outputs; struct r300_shader_semantics *fs_inputs = &r300_fs(r300)->shader->inputs; struct r300_rs_block rs = {0}; - int i, col_count = 0, tex_count = 0, fp_offset = 0, count, loc = 0; + int i, col_count = 0, tex_count = 0, fp_offset = 0, count, loc = 0, tex_ptr = 0; void (*rX00_rs_col)(struct r300_rs_block*, int, int, enum r300_rs_swizzle); void (*rX00_rs_col_write)(struct r300_rs_block*, int, int); void (*rX00_rs_tex)(struct r300_rs_block*, int, int, enum r300_rs_swizzle); @@ -393,8 +392,9 @@ static void r300_update_rs_block(struct r300_context *r300) stream_loc_notcl[loc++] = 6 + tex_count; /* Rasterize it. */ - rX00_rs_tex(&rs, tex_count, tex_count, SWIZ_XYZW); + rX00_rs_tex(&rs, tex_count, tex_ptr, SWIZ_XYZW); tex_count++; + tex_ptr += 4; } } } @@ -412,7 +412,7 @@ static void r300_update_rs_block(struct r300_context *r300) } /* Rasterize it. */ - rX00_rs_tex(&rs, tex_count, tex_count, + rX00_rs_tex(&rs, tex_count, tex_ptr, sprite_coord ? SWIZ_XY01 : SWIZ_XYZW); /* Write it to the FS input register if it's needed by the FS. */ @@ -429,6 +429,7 @@ static void r300_update_rs_block(struct r300_context *r300) i, sprite_coord ? " (sprite coord)" : ""); } tex_count++; + tex_ptr += sprite_coord ? 2 : 4; } else { /* Skip the FS input register, leave it uninitialized. */ /* If we try to set it to (0,0,0,1), it will lock up. */ @@ -449,7 +450,7 @@ static void r300_update_rs_block(struct r300_context *r300) stream_loc_notcl[loc++] = 6 + tex_count; /* Rasterize it. */ - rX00_rs_tex(&rs, tex_count, tex_count, SWIZ_X001); + rX00_rs_tex(&rs, tex_count, tex_ptr, SWIZ_X001); /* Write it to the FS input register if it's needed by the FS. */ if (fs_inputs->fog != ATTR_UNUSED) { @@ -461,6 +462,7 @@ static void r300_update_rs_block(struct r300_context *r300) DBG(r300, DBG_RS, "r300: Rasterized fog unused.\n"); } tex_count++; + tex_ptr += 4; } else { /* Skip the FS input register, leave it uninitialized. */ /* If we try to set it to (0,0,0,1), it will lock up. */ @@ -480,7 +482,7 @@ static void r300_update_rs_block(struct r300_context *r300) stream_loc_notcl[loc++] = 6 + tex_count; /* Rasterize it. */ - rX00_rs_tex(&rs, tex_count, tex_count, SWIZ_XYZW); + rX00_rs_tex(&rs, tex_count, tex_ptr, SWIZ_XYZW); /* Write it to the FS input register. */ rX00_rs_tex_write(&rs, tex_count, fp_offset); @@ -489,6 +491,7 @@ static void r300_update_rs_block(struct r300_context *r300) fp_offset++; tex_count++; + tex_ptr += 4; } /* Invalidate the rest of the no-TCL (GA) stream locations. */ @@ -507,7 +510,7 @@ static void r300_update_rs_block(struct r300_context *r300) DBG(r300, DBG_RS, "r300: --- Rasterizer status ---: colors: %i, " "generics: %i.\n", col_count, tex_count); - rs.count = (tex_count*4) | (col_count << R300_IC_COUNT_SHIFT) | + rs.count = MIN2(tex_ptr, 32) | (col_count << R300_IC_COUNT_SHIFT) | R300_HIRES_EN; count = MAX3(col_count, tex_count, 1); @@ -691,5 +694,6 @@ void r300_update_derived_state(struct r300_context* r300) } } - r300_update_hyperz_state(r300); + if (r300->rws->get_value(r300->rws, R300_CAN_HYPERZ)) + r300_update_hyperz_state(r300); } diff --git a/src/gallium/drivers/r300/r300_texture.c b/src/gallium/drivers/r300/r300_texture.c index fcdca5605e9..da8eadd3b53 100644 --- a/src/gallium/drivers/r300/r300_texture.c +++ b/src/gallium/drivers/r300/r300_texture.c @@ -35,6 +35,7 @@ #include "util/u_format_s3tc.h" #include "util/u_math.h" #include "util/u_memory.h" +#include "util/u_mm.h" #include "pipe/p_screen.h" @@ -645,8 +646,16 @@ static void r300_texture_destroy(struct pipe_screen *screen, { struct r300_texture* tex = (struct r300_texture*)texture; struct r300_winsys_screen *rws = (struct r300_winsys_screen *)texture->screen->winsys; + int i; rws->buffer_reference(rws, &tex->buffer, NULL); + for (i = 0; i < R300_MAX_TEXTURE_LEVELS; i++) { + if (tex->hiz_mem[i]) + u_mmFreeMem(tex->hiz_mem[i]); + if (tex->zmask_mem[i]) + u_mmFreeMem(tex->zmask_mem[i]); + } + FREE(tex); } diff --git a/src/gallium/drivers/r300/r300_texture_desc.c b/src/gallium/drivers/r300/r300_texture_desc.c index 343089bf2c5..5d690e8c332 100644 --- a/src/gallium/drivers/r300/r300_texture_desc.c +++ b/src/gallium/drivers/r300/r300_texture_desc.c @@ -136,13 +136,27 @@ static unsigned r300_texture_get_stride(struct r300_screen *screen, stride = util_format_get_stride(desc->b.b.format, width); - /* Some IGPs need a minimum stride of 64 bytes, hmm... - * This doesn't seem to apply to tiled textures, according to r300c. */ - if (!desc->microtile && !desc->macrotile[level] && + /* Some IGPs need a minimum stride of 64 bytes, hmm... */ + if (!desc->macrotile[level] && (screen->caps.family == CHIP_FAMILY_RS600 || screen->caps.family == CHIP_FAMILY_RS690 || screen->caps.family == CHIP_FAMILY_RS740)) { - return stride < 64 ? 64 : stride; + unsigned min_stride; + + if (desc->microtile) { + unsigned tile_height = + r300_get_pixel_alignment(desc->b.b.format, + desc->b.b.nr_samples, + desc->microtile, + desc->macrotile[level], + DIM_HEIGHT); + + min_stride = 64 / tile_height; + } else { + min_stride = 64; + } + + return stride < min_stride ? min_stride : stride; } /* The alignment to 32 bytes is sort of implied by the layout... */ diff --git a/src/gallium/drivers/r300/r300_winsys.h b/src/gallium/drivers/r300/r300_winsys.h index ff11546a647..187780750fa 100644 --- a/src/gallium/drivers/r300/r300_winsys.h +++ b/src/gallium/drivers/r300/r300_winsys.h @@ -49,6 +49,8 @@ enum r300_value_id { R300_VID_Z_PIPES, R300_VID_SQUARE_TILING_SUPPORT, R300_VID_DRM_2_3_0, + R300_VID_DRM_2_6_0, + R300_CAN_HYPERZ, }; enum r300_reference_domain { /* bitfield */ diff --git a/src/gallium/drivers/r600/Makefile b/src/gallium/drivers/r600/Makefile index 8f1e1366b50..fc94ae71f4a 100644 --- a/src/gallium/drivers/r600/Makefile +++ b/src/gallium/drivers/r600/Makefile @@ -9,6 +9,7 @@ LIBRARY_INCLUDES = \ C_SOURCES = \ r600_buffer.c \ r600_context.c \ + r600_shader.c \ r600_draw.c \ r600_blit.c \ r600_helper.c \ @@ -17,7 +18,6 @@ C_SOURCES = \ r600_screen.c \ r600_state.c \ r600_texture.c \ - r600_shader.c \ r600_asm.c \ r700_asm.c diff --git a/src/gallium/drivers/r600/r600_asm.c b/src/gallium/drivers/r600/r600_asm.c index e678a2fdf2c..f1dc3dc3a96 100644 --- a/src/gallium/drivers/r600/r600_asm.c +++ b/src/gallium/drivers/r600/r600_asm.c @@ -91,6 +91,7 @@ static int r600_bc_add_cf(struct r600_bc *bc) bc->cf_last = cf; bc->ncf++; bc->ndw += 2; + bc->force_add_cf = 0; return 0; } @@ -118,7 +119,9 @@ int r600_bc_add_alu(struct r600_bc *bc, const struct r600_bc_alu *alu) nalu->nliteral = 0; /* cf can contains only alu or only vtx or only tex */ - if (bc->cf_last == NULL || bc->cf_last->inst != (V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU << 3)) { + if (bc->cf_last == NULL || bc->cf_last->inst != (V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU << 3) || + bc->force_add_cf) { + /* at most 128 slots, one add alu can add 4 slots + 4 constant worst case */ r = r600_bc_add_cf(bc); if (r) { free(nalu); @@ -126,6 +129,9 @@ int r600_bc_add_alu(struct r600_bc *bc, const struct r600_bc_alu *alu) } bc->cf_last->inst = V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU << 3; } + if (alu->last && (bc->cf_last->ndw >> 1) >= 124) { + bc->force_add_cf = 1; + } /* number of gpr == the last gpr used in any alu */ for (i = 0; i < 3; i++) { if (alu->src[i].sel >= bc->ngpr && alu->src[i].sel < 128) { @@ -294,6 +300,7 @@ int r600_bc_alu_build(struct r600_bc *bc, struct r600_bc_alu *alu, unsigned id) S_SQ_ALU_WORD0_LAST(alu->last); bc->bytecode[id++] = S_SQ_ALU_WORD1_DST_GPR(alu->dst.sel) | S_SQ_ALU_WORD1_DST_CHAN(alu->dst.chan) | + S_SQ_ALU_WORD1_CLAMP(alu->dst.clamp) | S_SQ_ALU_WORD1_OP3_SRC2_SEL(alu->src[2].sel) | S_SQ_ALU_WORD1_OP3_SRC2_CHAN(alu->src[2].chan) | S_SQ_ALU_WORD1_OP3_SRC2_NEG(alu->src[2].neg) | @@ -309,6 +316,7 @@ int r600_bc_alu_build(struct r600_bc *bc, struct r600_bc_alu *alu, unsigned id) S_SQ_ALU_WORD0_LAST(alu->last); bc->bytecode[id++] = S_SQ_ALU_WORD1_DST_GPR(alu->dst.sel) | S_SQ_ALU_WORD1_DST_CHAN(alu->dst.chan) | + S_SQ_ALU_WORD1_CLAMP(alu->dst.clamp) | S_SQ_ALU_WORD1_OP2_SRC0_ABS(alu->src[0].abs) | S_SQ_ALU_WORD1_OP2_SRC1_ABS(alu->src[1].abs) | S_SQ_ALU_WORD1_OP2_WRITE_MASK(alu->dst.write) | diff --git a/src/gallium/drivers/r600/r600_asm.h b/src/gallium/drivers/r600/r600_asm.h index 88fb957440a..3fd94dbda03 100644 --- a/src/gallium/drivers/r600/r600_asm.h +++ b/src/gallium/drivers/r600/r600_asm.h @@ -127,6 +127,7 @@ struct r600_bc { unsigned ncf; unsigned ngpr; unsigned nresource; + unsigned force_add_cf; u32 *bytecode; }; diff --git a/src/gallium/drivers/r600/r600_blit.c b/src/gallium/drivers/r600/r600_blit.c index 1dcb19babc9..f4eedfe4cb1 100644 --- a/src/gallium/drivers/r600/r600_blit.c +++ b/src/gallium/drivers/r600/r600_blit.c @@ -34,31 +34,37 @@ static void r600_blitter_save_states(struct r600_context *rctx) { - util_blitter_save_blend(rctx->blitter, - rctx->draw->state[R600_BLEND]); - util_blitter_save_depth_stencil_alpha(rctx->blitter, - rctx->draw->state[R600_DSA]); - util_blitter_save_stencil_ref(rctx->blitter, &rctx->stencil_ref); - util_blitter_save_rasterizer(rctx->blitter, - rctx->draw->state[R600_RASTERIZER]); - util_blitter_save_fragment_shader(rctx->blitter, - rctx->ps_shader); - util_blitter_save_vertex_shader(rctx->blitter, - rctx->vs_shader); - util_blitter_save_vertex_elements(rctx->blitter, - rctx->vertex_elements); - util_blitter_save_viewport(rctx->blitter, - &rctx->viewport); + util_blitter_save_blend(rctx->blitter, rctx->blend); + util_blitter_save_depth_stencil_alpha(rctx->blitter, rctx->dsa); + if (rctx->stencil_ref) { + util_blitter_save_stencil_ref(rctx->blitter, + &rctx->stencil_ref->state.stencil_ref); + } + util_blitter_save_rasterizer(rctx->blitter, rctx->rasterizer); + util_blitter_save_fragment_shader(rctx->blitter, rctx->ps_shader); + util_blitter_save_vertex_shader(rctx->blitter, rctx->vs_shader); + util_blitter_save_vertex_elements(rctx->blitter, rctx->vertex_elements); + if (rctx->viewport) { + util_blitter_save_viewport(rctx->blitter, &rctx->viewport->state.viewport); + } /* XXX util_blitter_save_clip(rctx->blitter, &rctx->clip); */ util_blitter_save_vertex_buffers(rctx->blitter, rctx->nvertex_buffer, - rctx->vertex_buffer); + rctx->vertex_buffer); + + /* remove ptr so they don't get deleted */ + rctx->blend = NULL; + rctx->vs_shader = NULL; + rctx->ps_shader = NULL; + rctx->rasterizer = NULL; + rctx->dsa = NULL; + rctx->vertex_elements = NULL; } static void r600_clear(struct pipe_context *ctx, unsigned buffers, const float *rgba, double depth, unsigned stencil) { struct r600_context *rctx = r600_context(ctx); - struct pipe_framebuffer_state *fb = &rctx->fb_state; + struct pipe_framebuffer_state *fb = &rctx->framebuffer->state.framebuffer; r600_blitter_save_states(rctx); util_blitter_clear(rctx->blitter, fb->width, fb->height, @@ -73,9 +79,10 @@ static void r600_clear_render_target(struct pipe_context *pipe, unsigned width, unsigned height) { struct r600_context *rctx = r600_context(pipe); + struct pipe_framebuffer_state *fb = &rctx->framebuffer->state.framebuffer; r600_blitter_save_states(rctx); - util_blitter_save_framebuffer(rctx->blitter, &rctx->fb_state); + util_blitter_save_framebuffer(rctx->blitter, fb); util_blitter_clear_render_target(rctx->blitter, dst, rgba, dstx, dsty, width, height); @@ -90,9 +97,10 @@ static void r600_clear_depth_stencil(struct pipe_context *pipe, unsigned width, unsigned height) { struct r600_context *rctx = r600_context(pipe); + struct pipe_framebuffer_state *fb = &rctx->framebuffer->state.framebuffer; r600_blitter_save_states(rctx); - util_blitter_save_framebuffer(rctx->blitter, &rctx->fb_state); + util_blitter_save_framebuffer(rctx->blitter, fb); util_blitter_clear_depth_stencil(rctx->blitter, dst, clear_flags, depth, stencil, dstx, dsty, width, height); diff --git a/src/gallium/drivers/r600/r600_buffer.c b/src/gallium/drivers/r600/r600_buffer.c index bc6e336ba7b..7829a479c2e 100644 --- a/src/gallium/drivers/r600/r600_buffer.c +++ b/src/gallium/drivers/r600/r600_buffer.c @@ -32,10 +32,11 @@ #include "state_tracker/drm_driver.h" #include "r600_screen.h" #include "r600_context.h" +#include "r600_resource.h" extern struct u_resource_vtbl r600_buffer_vtbl; -static u32 r600_domain_from_usage(unsigned usage) +u32 r600_domain_from_usage(unsigned usage) { u32 domain = RADEON_GEM_DOMAIN_GTT; @@ -63,47 +64,47 @@ struct pipe_resource *r600_buffer_create(struct pipe_screen *screen, const struct pipe_resource *templ) { struct r600_screen *rscreen = r600_screen(screen); - struct r600_buffer *rbuffer; + struct r600_resource *rbuffer; struct radeon_bo *bo; struct pb_desc desc; /* XXX We probably want a different alignment for buffers and textures. */ unsigned alignment = 4096; - rbuffer = CALLOC_STRUCT(r600_buffer); + rbuffer = CALLOC_STRUCT(r600_resource); if (rbuffer == NULL) return NULL; - rbuffer->b.b = *templ; - pipe_reference_init(&rbuffer->b.b.reference, 1); - rbuffer->b.b.screen = screen; - rbuffer->b.vtbl = &r600_buffer_vtbl; + rbuffer->base.b = *templ; + pipe_reference_init(&rbuffer->base.b.reference, 1); + rbuffer->base.b.screen = screen; + rbuffer->base.vtbl = &r600_buffer_vtbl; - if (rbuffer->b.b.bind & PIPE_BIND_CONSTANT_BUFFER) { + if (rbuffer->base.b.bind & PIPE_BIND_CONSTANT_BUFFER) { desc.alignment = alignment; - desc.usage = rbuffer->b.b.bind; - rbuffer->pb = pb_malloc_buffer_create(rbuffer->b.b.width0, + desc.usage = rbuffer->base.b.bind; + rbuffer->pb = pb_malloc_buffer_create(rbuffer->base.b.width0, &desc); if (rbuffer->pb == NULL) { free(rbuffer); return NULL; } - return &rbuffer->b.b; + return &rbuffer->base.b; } - rbuffer->domain = r600_domain_from_usage(rbuffer->b.b.bind); - bo = radeon_bo(rscreen->rw, 0, rbuffer->b.b.width0, alignment, NULL); + rbuffer->domain = r600_domain_from_usage(rbuffer->base.b.bind); + bo = radeon_bo(rscreen->rw, 0, rbuffer->base.b.width0, alignment, NULL); if (bo == NULL) { FREE(rbuffer); return NULL; } rbuffer->bo = bo; - return &rbuffer->b.b; + return &rbuffer->base.b; } struct pipe_resource *r600_user_buffer_create(struct pipe_screen *screen, void *ptr, unsigned bytes, unsigned bind) { - struct r600_buffer *rbuffer; + struct r600_resource *rbuffer; struct r600_screen *rscreen = r600_screen(screen); struct pipe_resource templ; @@ -116,20 +117,20 @@ struct pipe_resource *r600_user_buffer_create(struct pipe_screen *screen, templ.height0 = 1; templ.depth0 = 1; - rbuffer = (struct r600_buffer*)r600_buffer_create(screen, &templ); + rbuffer = (struct r600_resource*)r600_buffer_create(screen, &templ); if (rbuffer == NULL) { return NULL; } radeon_bo_map(rscreen->rw, rbuffer->bo); memcpy(rbuffer->bo->data, ptr, bytes); radeon_bo_unmap(rscreen->rw, rbuffer->bo); - return &rbuffer->b.b; + return &rbuffer->base.b; } static void r600_buffer_destroy(struct pipe_screen *screen, struct pipe_resource *buf) { - struct r600_buffer *rbuffer = (struct r600_buffer*)buf; + struct r600_resource *rbuffer = (struct r600_resource*)buf; struct r600_screen *rscreen = r600_screen(screen); if (rbuffer->pb) { @@ -140,13 +141,14 @@ static void r600_buffer_destroy(struct pipe_screen *screen, if (rbuffer->bo) { radeon_bo_decref(rscreen->rw, rbuffer->bo); } + memset(rbuffer, 0, sizeof(struct r600_resource)); FREE(rbuffer); } static void *r600_buffer_transfer_map(struct pipe_context *pipe, struct pipe_transfer *transfer) { - struct r600_buffer *rbuffer = (struct r600_buffer*)transfer->resource; + struct r600_resource *rbuffer = (struct r600_resource*)transfer->resource; struct r600_screen *rscreen = r600_screen(pipe->screen); int write = 0; @@ -166,9 +168,9 @@ static void *r600_buffer_transfer_map(struct pipe_context *pipe, } static void r600_buffer_transfer_unmap(struct pipe_context *pipe, - struct pipe_transfer *transfer) + struct pipe_transfer *transfer) { - struct r600_buffer *rbuffer = (struct r600_buffer*)transfer->resource; + struct r600_resource *rbuffer = (struct r600_resource*)transfer->resource; struct r600_screen *rscreen = r600_screen(pipe->screen); if (rbuffer->pb) { @@ -188,7 +190,7 @@ unsigned r600_buffer_is_referenced_by_cs(struct pipe_context *context, struct pipe_resource *buf, unsigned face, unsigned level) { - /* XXX */ + /* FIXME */ return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE; } @@ -196,7 +198,7 @@ struct pipe_resource *r600_buffer_from_handle(struct pipe_screen *screen, struct winsys_handle *whandle) { struct radeon *rw = (struct radeon*)screen->winsys; - struct r600_buffer *rbuffer; + struct r600_resource *rbuffer; struct radeon_bo *bo = NULL; bo = radeon_bo(rw, whandle->handle, 0, 0, NULL); @@ -204,18 +206,18 @@ struct pipe_resource *r600_buffer_from_handle(struct pipe_screen *screen, return NULL; } - rbuffer = CALLOC_STRUCT(r600_buffer); + rbuffer = CALLOC_STRUCT(r600_resource); if (rbuffer == NULL) { radeon_bo_decref(rw, bo); return NULL; } - pipe_reference_init(&rbuffer->b.b.reference, 1); - rbuffer->b.b.target = PIPE_BUFFER; - rbuffer->b.b.screen = screen; - rbuffer->b.vtbl = &r600_buffer_vtbl; + pipe_reference_init(&rbuffer->base.b.reference, 1); + rbuffer->base.b.target = PIPE_BUFFER; + rbuffer->base.b.screen = screen; + rbuffer->base.vtbl = &r600_buffer_vtbl; rbuffer->bo = bo; - return &rbuffer->b.b; + return &rbuffer->base.b; } struct u_resource_vtbl r600_buffer_vtbl = diff --git a/src/gallium/drivers/r600/r600_context.c b/src/gallium/drivers/r600/r600_context.c index 05575b57676..ae1780a1d40 100644 --- a/src/gallium/drivers/r600/r600_context.c +++ b/src/gallium/drivers/r600/r600_context.c @@ -29,9 +29,9 @@ #include <util/u_format.h> #include <util/u_memory.h> #include <util/u_blitter.h> -#include "r600_resource.h" #include "r600_screen.h" #include "r600_context.h" +#include "r600_resource.h" #include "r600d.h" static void r600_destroy_context(struct pipe_context *context) @@ -41,7 +41,7 @@ static void r600_destroy_context(struct pipe_context *context) FREE(rctx); } -static void r600_flush(struct pipe_context *ctx, unsigned flags, +void r600_flush(struct pipe_context *ctx, unsigned flags, struct pipe_fence_handle **fence) { struct r600_context *rctx = r600_context(ctx); @@ -55,7 +55,7 @@ static void r600_flush(struct pipe_context *ctx, unsigned flags, */ if (!dc) radeon_ctx_dump_bof(rctx->ctx, "gallium.bof"); -#if 0 +#if 1 radeon_ctx_submit(rctx->ctx); #endif rctx->ctx = radeon_ctx_decref(rctx->ctx); @@ -220,9 +220,9 @@ static void r600_init_config(struct r600_context *rctx) printf("num_gs_stack_entries : %d\n", num_gs_stack_entries); printf("num_es_stack_entries : %d\n", num_es_stack_entries); - rctx->config = radeon_state(rctx->rw, R600_CONFIG_TYPE, R600_CONFIG); + rctx->hw_states.config = radeon_state(rctx->rw, R600_CONFIG_TYPE, R600_CONFIG); - rctx->config->states[R600_CONFIG__SQ_CONFIG] = 0x00000000; + rctx->hw_states.config->states[R600_CONFIG__SQ_CONFIG] = 0x00000000; switch (family) { case CHIP_RV610: case CHIP_RV620: @@ -231,75 +231,75 @@ static void r600_init_config(struct r600_context *rctx) case CHIP_RV710: break; default: - rctx->config->states[R600_CONFIG__SQ_CONFIG] |= S_008C00_VC_ENABLE(1); + rctx->hw_states.config->states[R600_CONFIG__SQ_CONFIG] |= S_008C00_VC_ENABLE(1); break; } - rctx->config->states[R600_CONFIG__SQ_CONFIG] |= S_008C00_DX9_CONSTS(1); - rctx->config->states[R600_CONFIG__SQ_CONFIG] |= S_008C00_ALU_INST_PREFER_VECTOR(1); - rctx->config->states[R600_CONFIG__SQ_CONFIG] |= S_008C00_PS_PRIO(ps_prio); - rctx->config->states[R600_CONFIG__SQ_CONFIG] |= S_008C00_VS_PRIO(vs_prio); - rctx->config->states[R600_CONFIG__SQ_CONFIG] |= S_008C00_GS_PRIO(gs_prio); - rctx->config->states[R600_CONFIG__SQ_CONFIG] |= S_008C00_ES_PRIO(es_prio); + rctx->hw_states.config->states[R600_CONFIG__SQ_CONFIG] |= S_008C00_DX9_CONSTS(1); + rctx->hw_states.config->states[R600_CONFIG__SQ_CONFIG] |= S_008C00_ALU_INST_PREFER_VECTOR(1); + rctx->hw_states.config->states[R600_CONFIG__SQ_CONFIG] |= S_008C00_PS_PRIO(ps_prio); + rctx->hw_states.config->states[R600_CONFIG__SQ_CONFIG] |= S_008C00_VS_PRIO(vs_prio); + rctx->hw_states.config->states[R600_CONFIG__SQ_CONFIG] |= S_008C00_GS_PRIO(gs_prio); + rctx->hw_states.config->states[R600_CONFIG__SQ_CONFIG] |= S_008C00_ES_PRIO(es_prio); - rctx->config->states[R600_CONFIG__SQ_GPR_RESOURCE_MGMT_1] = 0; - rctx->config->states[R600_CONFIG__SQ_GPR_RESOURCE_MGMT_1] |= S_008C04_NUM_PS_GPRS(num_ps_gprs); - rctx->config->states[R600_CONFIG__SQ_GPR_RESOURCE_MGMT_1] |= S_008C04_NUM_VS_GPRS(num_vs_gprs); - rctx->config->states[R600_CONFIG__SQ_GPR_RESOURCE_MGMT_1] |= S_008C04_NUM_CLAUSE_TEMP_GPRS(num_temp_gprs); + rctx->hw_states.config->states[R600_CONFIG__SQ_GPR_RESOURCE_MGMT_1] = 0; + rctx->hw_states.config->states[R600_CONFIG__SQ_GPR_RESOURCE_MGMT_1] |= S_008C04_NUM_PS_GPRS(num_ps_gprs); + rctx->hw_states.config->states[R600_CONFIG__SQ_GPR_RESOURCE_MGMT_1] |= S_008C04_NUM_VS_GPRS(num_vs_gprs); + rctx->hw_states.config->states[R600_CONFIG__SQ_GPR_RESOURCE_MGMT_1] |= S_008C04_NUM_CLAUSE_TEMP_GPRS(num_temp_gprs); - rctx->config->states[R600_CONFIG__SQ_GPR_RESOURCE_MGMT_2] = 0; - rctx->config->states[R600_CONFIG__SQ_GPR_RESOURCE_MGMT_2] |= S_008C08_NUM_GS_GPRS(num_gs_gprs); - rctx->config->states[R600_CONFIG__SQ_GPR_RESOURCE_MGMT_2] |= S_008C08_NUM_GS_GPRS(num_es_gprs); + rctx->hw_states.config->states[R600_CONFIG__SQ_GPR_RESOURCE_MGMT_2] = 0; + rctx->hw_states.config->states[R600_CONFIG__SQ_GPR_RESOURCE_MGMT_2] |= S_008C08_NUM_GS_GPRS(num_gs_gprs); + rctx->hw_states.config->states[R600_CONFIG__SQ_GPR_RESOURCE_MGMT_2] |= S_008C08_NUM_GS_GPRS(num_es_gprs); - rctx->config->states[R600_CONFIG__SQ_THREAD_RESOURCE_MGMT] = 0; - rctx->config->states[R600_CONFIG__SQ_THREAD_RESOURCE_MGMT] |= S_008C0C_NUM_PS_THREADS(num_ps_threads); - rctx->config->states[R600_CONFIG__SQ_THREAD_RESOURCE_MGMT] |= S_008C0C_NUM_VS_THREADS(num_vs_threads); - rctx->config->states[R600_CONFIG__SQ_THREAD_RESOURCE_MGMT] |= S_008C0C_NUM_GS_THREADS(num_gs_threads); - rctx->config->states[R600_CONFIG__SQ_THREAD_RESOURCE_MGMT] |= S_008C0C_NUM_ES_THREADS(num_es_threads); + rctx->hw_states.config->states[R600_CONFIG__SQ_THREAD_RESOURCE_MGMT] = 0; + rctx->hw_states.config->states[R600_CONFIG__SQ_THREAD_RESOURCE_MGMT] |= S_008C0C_NUM_PS_THREADS(num_ps_threads); + rctx->hw_states.config->states[R600_CONFIG__SQ_THREAD_RESOURCE_MGMT] |= S_008C0C_NUM_VS_THREADS(num_vs_threads); + rctx->hw_states.config->states[R600_CONFIG__SQ_THREAD_RESOURCE_MGMT] |= S_008C0C_NUM_GS_THREADS(num_gs_threads); + rctx->hw_states.config->states[R600_CONFIG__SQ_THREAD_RESOURCE_MGMT] |= S_008C0C_NUM_ES_THREADS(num_es_threads); - rctx->config->states[R600_CONFIG__SQ_STACK_RESOURCE_MGMT_1] = 0; - rctx->config->states[R600_CONFIG__SQ_STACK_RESOURCE_MGMT_1] |= S_008C10_NUM_PS_STACK_ENTRIES(num_ps_stack_entries); - rctx->config->states[R600_CONFIG__SQ_STACK_RESOURCE_MGMT_1] |= S_008C10_NUM_VS_STACK_ENTRIES(num_vs_stack_entries); + rctx->hw_states.config->states[R600_CONFIG__SQ_STACK_RESOURCE_MGMT_1] = 0; + rctx->hw_states.config->states[R600_CONFIG__SQ_STACK_RESOURCE_MGMT_1] |= S_008C10_NUM_PS_STACK_ENTRIES(num_ps_stack_entries); + rctx->hw_states.config->states[R600_CONFIG__SQ_STACK_RESOURCE_MGMT_1] |= S_008C10_NUM_VS_STACK_ENTRIES(num_vs_stack_entries); - rctx->config->states[R600_CONFIG__SQ_STACK_RESOURCE_MGMT_2] = 0; - rctx->config->states[R600_CONFIG__SQ_STACK_RESOURCE_MGMT_2] |= S_008C14_NUM_GS_STACK_ENTRIES(num_gs_stack_entries); - rctx->config->states[R600_CONFIG__SQ_STACK_RESOURCE_MGMT_2] |= S_008C14_NUM_ES_STACK_ENTRIES(num_es_stack_entries); + rctx->hw_states.config->states[R600_CONFIG__SQ_STACK_RESOURCE_MGMT_2] = 0; + rctx->hw_states.config->states[R600_CONFIG__SQ_STACK_RESOURCE_MGMT_2] |= S_008C14_NUM_GS_STACK_ENTRIES(num_gs_stack_entries); + rctx->hw_states.config->states[R600_CONFIG__SQ_STACK_RESOURCE_MGMT_2] |= S_008C14_NUM_ES_STACK_ENTRIES(num_es_stack_entries); - rctx->config->states[R600_CONFIG__SQ_DYN_GPR_CNTL_PS_FLUSH_REQ] = 0x00004000; - rctx->config->states[R600_CONFIG__TA_CNTL_AUX] = 0x07000002; - rctx->config->states[R600_CONFIG__VC_ENHANCE] = 0x00000000; - rctx->config->states[R600_CONFIG__DB_DEBUG] = 0x00000000; - rctx->config->states[R600_CONFIG__DB_WATERMARKS] = 0x00420204; - rctx->config->states[R600_CONFIG__SX_MISC] = 0x00000000; - rctx->config->states[R600_CONFIG__SPI_THREAD_GROUPING] = 0x00000001; - rctx->config->states[R600_CONFIG__CB_SHADER_CONTROL] = 0x00000003; - rctx->config->states[R600_CONFIG__SQ_ESGS_RING_ITEMSIZE] = 0x00000000; - rctx->config->states[R600_CONFIG__SQ_GSVS_RING_ITEMSIZE] = 0x00000000; - rctx->config->states[R600_CONFIG__SQ_ESTMP_RING_ITEMSIZE] = 0x00000000; - rctx->config->states[R600_CONFIG__SQ_GSTMP_RING_ITEMSIZE] = 0x00000000; - rctx->config->states[R600_CONFIG__SQ_VSTMP_RING_ITEMSIZE] = 0x00000000; - rctx->config->states[R600_CONFIG__SQ_PSTMP_RING_ITEMSIZE] = 0x00000000; - rctx->config->states[R600_CONFIG__SQ_FBUF_RING_ITEMSIZE] = 0x00000000; - rctx->config->states[R600_CONFIG__SQ_REDUC_RING_ITEMSIZE] = 0x00000000; - rctx->config->states[R600_CONFIG__SQ_GS_VERT_ITEMSIZE] = 0x00000000; - rctx->config->states[R600_CONFIG__VGT_OUTPUT_PATH_CNTL] = 0x00000000; - rctx->config->states[R600_CONFIG__VGT_HOS_CNTL] = 0x00000000; - rctx->config->states[R600_CONFIG__VGT_HOS_MAX_TESS_LEVEL] = 0x00000000; - rctx->config->states[R600_CONFIG__VGT_HOS_MIN_TESS_LEVEL] = 0x00000000; - rctx->config->states[R600_CONFIG__VGT_HOS_REUSE_DEPTH] = 0x00000000; - rctx->config->states[R600_CONFIG__VGT_GROUP_PRIM_TYPE] = 0x00000000; - rctx->config->states[R600_CONFIG__VGT_GROUP_FIRST_DECR] = 0x00000000; - rctx->config->states[R600_CONFIG__VGT_GROUP_DECR] = 0x00000000; - rctx->config->states[R600_CONFIG__VGT_GROUP_VECT_0_CNTL] = 0x00000000; - rctx->config->states[R600_CONFIG__VGT_GROUP_VECT_1_CNTL] = 0x00000000; - rctx->config->states[R600_CONFIG__VGT_GROUP_VECT_0_FMT_CNTL] = 0x00000000; - rctx->config->states[R600_CONFIG__VGT_GROUP_VECT_1_FMT_CNTL] = 0x00000000; - rctx->config->states[R600_CONFIG__VGT_GS_MODE] = 0x00000000; - rctx->config->states[R600_CONFIG__PA_SC_MODE_CNTL] = 0x00514000; - rctx->config->states[R600_CONFIG__VGT_STRMOUT_EN] = 0x00000000; - rctx->config->states[R600_CONFIG__VGT_REUSE_OFF] = 0x00000001; - rctx->config->states[R600_CONFIG__VGT_VTX_CNT_EN] = 0x00000000; - rctx->config->states[R600_CONFIG__VGT_STRMOUT_BUFFER_EN] = 0x00000000; - radeon_state_pm4(rctx->config); + rctx->hw_states.config->states[R600_CONFIG__SQ_DYN_GPR_CNTL_PS_FLUSH_REQ] = 0x00004000; + rctx->hw_states.config->states[R600_CONFIG__TA_CNTL_AUX] = 0x07000002; + rctx->hw_states.config->states[R600_CONFIG__VC_ENHANCE] = 0x00000000; + rctx->hw_states.config->states[R600_CONFIG__DB_DEBUG] = 0x00000000; + rctx->hw_states.config->states[R600_CONFIG__DB_WATERMARKS] = 0x00420204; + rctx->hw_states.config->states[R600_CONFIG__SX_MISC] = 0x00000000; + rctx->hw_states.config->states[R600_CONFIG__SPI_THREAD_GROUPING] = 0x00000001; + rctx->hw_states.config->states[R600_CONFIG__CB_SHADER_CONTROL] = 0x00000003; + rctx->hw_states.config->states[R600_CONFIG__SQ_ESGS_RING_ITEMSIZE] = 0x00000000; + rctx->hw_states.config->states[R600_CONFIG__SQ_GSVS_RING_ITEMSIZE] = 0x00000000; + rctx->hw_states.config->states[R600_CONFIG__SQ_ESTMP_RING_ITEMSIZE] = 0x00000000; + rctx->hw_states.config->states[R600_CONFIG__SQ_GSTMP_RING_ITEMSIZE] = 0x00000000; + rctx->hw_states.config->states[R600_CONFIG__SQ_VSTMP_RING_ITEMSIZE] = 0x00000000; + rctx->hw_states.config->states[R600_CONFIG__SQ_PSTMP_RING_ITEMSIZE] = 0x00000000; + rctx->hw_states.config->states[R600_CONFIG__SQ_FBUF_RING_ITEMSIZE] = 0x00000000; + rctx->hw_states.config->states[R600_CONFIG__SQ_REDUC_RING_ITEMSIZE] = 0x00000000; + rctx->hw_states.config->states[R600_CONFIG__SQ_GS_VERT_ITEMSIZE] = 0x00000000; + rctx->hw_states.config->states[R600_CONFIG__VGT_OUTPUT_PATH_CNTL] = 0x00000000; + rctx->hw_states.config->states[R600_CONFIG__VGT_HOS_CNTL] = 0x00000000; + rctx->hw_states.config->states[R600_CONFIG__VGT_HOS_MAX_TESS_LEVEL] = 0x00000000; + rctx->hw_states.config->states[R600_CONFIG__VGT_HOS_MIN_TESS_LEVEL] = 0x00000000; + rctx->hw_states.config->states[R600_CONFIG__VGT_HOS_REUSE_DEPTH] = 0x00000000; + rctx->hw_states.config->states[R600_CONFIG__VGT_GROUP_PRIM_TYPE] = 0x00000000; + rctx->hw_states.config->states[R600_CONFIG__VGT_GROUP_FIRST_DECR] = 0x00000000; + rctx->hw_states.config->states[R600_CONFIG__VGT_GROUP_DECR] = 0x00000000; + rctx->hw_states.config->states[R600_CONFIG__VGT_GROUP_VECT_0_CNTL] = 0x00000000; + rctx->hw_states.config->states[R600_CONFIG__VGT_GROUP_VECT_1_CNTL] = 0x00000000; + rctx->hw_states.config->states[R600_CONFIG__VGT_GROUP_VECT_0_FMT_CNTL] = 0x00000000; + rctx->hw_states.config->states[R600_CONFIG__VGT_GROUP_VECT_1_FMT_CNTL] = 0x00000000; + rctx->hw_states.config->states[R600_CONFIG__VGT_GS_MODE] = 0x00000000; + rctx->hw_states.config->states[R600_CONFIG__PA_SC_MODE_CNTL] = 0x00514000; + rctx->hw_states.config->states[R600_CONFIG__VGT_STRMOUT_EN] = 0x00000000; + rctx->hw_states.config->states[R600_CONFIG__VGT_REUSE_OFF] = 0x00000001; + rctx->hw_states.config->states[R600_CONFIG__VGT_VTX_CNT_EN] = 0x00000000; + rctx->hw_states.config->states[R600_CONFIG__VGT_STRMOUT_BUFFER_EN] = 0x00000000; + radeon_state_pm4(rctx->hw_states.config); } struct pipe_context *r600_create_context(struct pipe_screen *screen, void *priv) @@ -313,9 +313,7 @@ struct pipe_context *r600_create_context(struct pipe_screen *screen, void *priv) rctx->context.screen = screen; rctx->context.priv = priv; rctx->context.destroy = r600_destroy_context; - rctx->context.draw_arrays = r600_draw_arrays; - rctx->context.draw_elements = r600_draw_elements; - rctx->context.draw_range_elements = r600_draw_range_elements; + rctx->context.draw_vbo = r600_draw_vbo; rctx->context.flush = r600_flush; /* Easy accessing of screen/winsys. */ @@ -333,20 +331,6 @@ struct pipe_context *r600_create_context(struct pipe_screen *screen, void *priv) return NULL; } - rctx->cb_cntl = radeon_state(rscreen->rw, R600_CB_CNTL_TYPE, R600_CB_CNTL); - rctx->cb_cntl->states[R600_CB_CNTL__CB_SHADER_MASK] = 0x0000000F; - rctx->cb_cntl->states[R600_CB_CNTL__CB_TARGET_MASK] = 0x0000000F; - rctx->cb_cntl->states[R600_CB_CNTL__CB_COLOR_CONTROL] = 0x00CC0000; - rctx->cb_cntl->states[R600_CB_CNTL__PA_SC_AA_CONFIG] = 0x00000000; - rctx->cb_cntl->states[R600_CB_CNTL__PA_SC_AA_SAMPLE_LOCS_MCTX] = 0x00000000; - rctx->cb_cntl->states[R600_CB_CNTL__PA_SC_AA_SAMPLE_LOCS_8S_WD1_MCTX] = 0x00000000; - rctx->cb_cntl->states[R600_CB_CNTL__CB_CLRCMP_CONTROL] = 0x01000000; - rctx->cb_cntl->states[R600_CB_CNTL__CB_CLRCMP_SRC] = 0x00000000; - rctx->cb_cntl->states[R600_CB_CNTL__CB_CLRCMP_DST] = 0x000000FF; - rctx->cb_cntl->states[R600_CB_CNTL__CB_CLRCMP_MSK] = 0xFFFFFFFF; - rctx->cb_cntl->states[R600_CB_CNTL__PA_SC_AA_MASK] = 0xFFFFFFFF; - radeon_state_pm4(rctx->cb_cntl); - r600_init_config(rctx); rctx->ctx = radeon_ctx(rscreen->rw); diff --git a/src/gallium/drivers/r600/r600_context.h b/src/gallium/drivers/r600/r600_context.h index 669aaec0b24..431f8951b2a 100644 --- a/src/gallium/drivers/r600/r600_context.h +++ b/src/gallium/drivers/r600/r600_context.h @@ -23,6 +23,7 @@ #ifndef R600_CONTEXT_H #define R600_CONTEXT_H +#include <stdio.h> #include <pipe/p_state.h> #include <pipe/p_context.h> #include <tgsi/tgsi_scan.h> @@ -33,16 +34,74 @@ #include "r600_shader.h" /* XXX move this to a more appropriate place */ -struct r600_vertex_elements_state +union pipe_states { + struct pipe_rasterizer_state rasterizer; + struct pipe_poly_stipple poly_stipple; + struct pipe_scissor_state scissor; + struct pipe_clip_state clip; + struct pipe_shader_state shader; + struct pipe_depth_state depth; + struct pipe_stencil_state stencil; + struct pipe_alpha_state alpha; + struct pipe_depth_stencil_alpha_state dsa; + struct pipe_blend_state blend; + struct pipe_blend_color blend_color; + struct pipe_stencil_ref stencil_ref; + struct pipe_framebuffer_state framebuffer; + struct pipe_sampler_state sampler; + struct pipe_sampler_view sampler_view; + struct pipe_viewport_state viewport; +}; + +enum pipe_state_type { + pipe_rasterizer_type = 1, + pipe_poly_stipple_type, + pipe_scissor_type, + pipe_clip_type, + pipe_shader_type, + pipe_depth_type, + pipe_stencil_type, + pipe_alpha_type, + pipe_dsa_type, + pipe_blend_type, + pipe_stencil_ref_type, + pipe_framebuffer_type, + pipe_sampler_type, + pipe_sampler_view_type, + pipe_viewport_type, + pipe_type_count +}; + +struct r600_context_state { + union pipe_states state; + unsigned refcount; + unsigned type; + struct radeon_state *rstate; + struct r600_shader shader; + struct radeon_bo *bo; +}; + +struct r600_vertex_element { - unsigned count; - struct pipe_vertex_element elements[32]; + unsigned refcount; + unsigned count; + struct pipe_vertex_element elements[32]; }; -struct r600_pipe_shader { - struct r600_shader shader; - struct radeon_bo *bo; - struct radeon_state *state; +struct r600_context_hw_states { + struct radeon_state *rasterizer; + struct radeon_state *scissor; + struct radeon_state *dsa; + struct radeon_state *blend; + struct radeon_state *viewport; + struct radeon_state *cb[7]; + struct radeon_state *config; + struct radeon_state *cb_cntl; + struct radeon_state *db; + unsigned ps_nresource; + unsigned ps_nsampler; + struct radeon_state *ps_resource[160]; + struct radeon_state *ps_sampler[16]; }; struct r600_context { @@ -50,20 +109,39 @@ struct r600_context { struct r600_screen *screen; struct radeon *rw; struct radeon_ctx *ctx; - struct radeon_state *cb_cntl; - struct radeon_state *db; - struct radeon_state *config; - struct r600_pipe_shader *ps_shader; - struct r600_pipe_shader *vs_shader; + struct blitter_context *blitter; + struct radeon_draw *draw; + /* hw states */ + struct r600_context_hw_states hw_states; + /* pipe states */ unsigned flat_shade; + unsigned ps_nsampler; + unsigned vs_nsampler; + unsigned ps_nsampler_view; + unsigned vs_nsampler_view; unsigned nvertex_buffer; - struct r600_vertex_elements_state *vertex_elements; + struct r600_context_state *rasterizer; + struct r600_context_state *poly_stipple; + struct r600_context_state *scissor; + struct r600_context_state *clip; + struct r600_context_state *ps_shader; + struct r600_context_state *vs_shader; + struct r600_context_state *depth; + struct r600_context_state *stencil; + struct r600_context_state *alpha; + struct r600_context_state *dsa; + struct r600_context_state *blend; + struct r600_context_state *stencil_ref; + struct r600_context_state *viewport; + struct r600_context_state *framebuffer; + struct r600_context_state *ps_sampler[PIPE_MAX_ATTRIBS]; + struct r600_context_state *vs_sampler[PIPE_MAX_ATTRIBS]; + struct r600_context_state *ps_sampler_view[PIPE_MAX_ATTRIBS]; + struct r600_context_state *vs_sampler_view[PIPE_MAX_ATTRIBS]; + struct r600_vertex_element *vertex_elements; struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS]; - struct blitter_context *blitter; - struct pipe_stencil_ref stencil_ref; - struct pipe_framebuffer_state fb_state; - struct radeon_draw *draw; - struct pipe_viewport_state viewport; + struct pipe_index_buffer index_buffer; + struct pipe_blend_color blend_color; }; /* Convenience cast wrapper. */ @@ -72,27 +150,27 @@ static INLINE struct r600_context *r600_context(struct pipe_context *pipe) return (struct r600_context*)pipe; } -void r600_draw_arrays(struct pipe_context *ctx, unsigned mode, - unsigned start, unsigned count); -void r600_draw_elements(struct pipe_context *ctx, - struct pipe_resource *index_buffer, - unsigned index_size, int index_bias, unsigned mode, - unsigned start, unsigned count); -void r600_draw_range_elements(struct pipe_context *ctx, - struct pipe_resource *index_buffer, - unsigned index_size, int index_bias, unsigned min_index, - unsigned max_index, unsigned mode, - unsigned start, unsigned count); +struct r600_context_state *r600_context_state(struct r600_context *rctx, unsigned type, const void *state); +struct r600_context_state *r600_context_state_incref(struct r600_context_state *rstate); +struct r600_context_state *r600_context_state_decref(struct r600_context_state *rstate); +void r600_flush(struct pipe_context *ctx, unsigned flags, + struct pipe_fence_handle **fence); + +int r600_context_hw_states(struct r600_context *rctx); + +void r600_draw_vbo(struct pipe_context *ctx, + const struct pipe_draw_info *info); void r600_init_blit_functions(struct r600_context *rctx); void r600_init_state_functions(struct r600_context *rctx); void r600_init_query_functions(struct r600_context* rctx); struct pipe_context *r600_create_context(struct pipe_screen *screen, void *priv); -void r600_pipe_shader_destroy(struct pipe_context *ctx, struct r600_pipe_shader *rpshader); -struct r600_pipe_shader *r600_pipe_shader_create(struct pipe_context *ctx, - const struct tgsi_token *tokens); -int r600_pipe_shader_update(struct pipe_context *ctx, struct r600_pipe_shader *rpshader); +extern int r600_pipe_shader_create(struct pipe_context *ctx, + struct r600_context_state *rstate, + const struct tgsi_token *tokens); +extern int r600_pipe_shader_update(struct pipe_context *ctx, + struct r600_context_state *rstate); #define R600_ERR(fmt, args...) \ fprintf(stderr, "EE %s/%s:%d - "fmt, __FILE__, __func__, __LINE__, ##args) diff --git a/src/gallium/drivers/r600/r600_draw.c b/src/gallium/drivers/r600/r600_draw.c index 724fb6c988e..2420b763188 100644 --- a/src/gallium/drivers/r600/r600_draw.c +++ b/src/gallium/drivers/r600/r600_draw.c @@ -33,7 +33,8 @@ #include <util/u_memory.h> #include "r600_screen.h" #include "r600_context.h" -#include "r600d.h" +#include "r600_resource.h" +#include "r600_state_inlines.h" struct r600_draw { struct pipe_context *ctx; @@ -51,11 +52,15 @@ static int r600_draw_common(struct r600_draw *draw) struct r600_context *rctx = r600_context(draw->ctx); struct r600_screen *rscreen = rctx->screen; struct radeon_state *vs_resource; - struct r600_buffer *rbuffer; + struct r600_resource *rbuffer; unsigned i, j, offset, format, prim; u32 vgt_dma_index_type, vgt_draw_initiator; + struct pipe_vertex_buffer *vertex_buffer; int r; + r = r600_context_hw_states(rctx); + if (r) + return r; switch (draw->index_size) { case 2: vgt_draw_initiator = 0; @@ -83,29 +88,19 @@ static int r600_draw_common(struct r600_draw *draw) r = r600_pipe_shader_update(draw->ctx, rctx->ps_shader); if (r) return r; - r = radeon_draw_set(rctx->draw, rctx->vs_shader->state); - if (r) - return r; - r = radeon_draw_set(rctx->draw, rctx->ps_shader->state); + r = radeon_draw_set(rctx->draw, rctx->vs_shader->rstate); if (r) return r; - r = radeon_draw_set(rctx->draw, rctx->cb_cntl); - if (r) - return r; - r = radeon_draw_set(rctx->draw, rctx->db); - if (r) - return r; - r = radeon_draw_set(rctx->draw, rctx->config); + r = radeon_draw_set(rctx->draw, rctx->ps_shader->rstate); if (r) return r; for (i = 0 ; i < rctx->vertex_elements->count; i++) { j = rctx->vertex_elements->elements[i].vertex_buffer_index; - rbuffer = (struct r600_buffer*)rctx->vertex_buffer[j].buffer; - offset = rctx->vertex_elements->elements[i].src_offset + rctx->vertex_buffer[j].buffer_offset; - r = r600_conv_pipe_format(rctx->vertex_elements->elements[i].src_format, &format); - if (r) - return r; + vertex_buffer = &rctx->vertex_buffer[j]; + rbuffer = (struct r600_resource*)vertex_buffer->buffer; + offset = rctx->vertex_elements->elements[i].src_offset + vertex_buffer->buffer_offset; + format = r600_translate_colorformat(rctx->vertex_elements->elements[i].src_format); vs_resource = radeon_state(rscreen->rw, R600_VS_RESOURCE_TYPE, R600_VS_RESOURCE + i); if (vs_resource == NULL) return -ENOMEM; @@ -113,7 +108,7 @@ static int r600_draw_common(struct r600_draw *draw) vs_resource->nbo = 1; vs_resource->states[R600_PS_RESOURCE__RESOURCE0_WORD0] = offset; vs_resource->states[R600_PS_RESOURCE__RESOURCE0_WORD1] = rbuffer->bo->size - offset; - vs_resource->states[R600_PS_RESOURCE__RESOURCE0_WORD2] = S_038008_STRIDE(rctx->vertex_buffer[j].stride) | + vs_resource->states[R600_PS_RESOURCE__RESOURCE0_WORD2] = S_038008_STRIDE(vertex_buffer->stride) | S_038008_DATA_FORMAT(format); vs_resource->states[R600_PS_RESOURCE__RESOURCE0_WORD3] = 0x00000000; vs_resource->states[R600_PS_RESOURCE__RESOURCE0_WORD4] = 0x00000000; @@ -160,58 +155,39 @@ static int r600_draw_common(struct r600_draw *draw) return r; /* FIXME */ r = radeon_ctx_set_draw_new(rctx->ctx, rctx->draw); + if (r == -EBUSY) { + r600_flush(draw->ctx, 0, NULL); + r = radeon_ctx_set_draw_new(rctx->ctx, rctx->draw); + } if (r) return r; rctx->draw = radeon_draw_duplicate(rctx->draw); return 0; } -void r600_draw_range_elements(struct pipe_context *ctx, - struct pipe_resource *index_buffer, - unsigned index_size, int index_bias, unsigned min_index, - unsigned max_index, unsigned mode, - unsigned start, unsigned count) +void r600_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *info) { + struct r600_context *rctx = r600_context(ctx); struct r600_draw draw; - assert(index_bias == 0); - draw.ctx = ctx; - draw.mode = mode; - draw.start = start; - draw.count = count; - draw.index_size = index_size; - draw.index_buffer = index_buffer; -printf("index_size %d min %d max %d start %d count %d\n", index_size, min_index, max_index, start, count); - r600_draw_common(&draw); -} - -void r600_draw_elements(struct pipe_context *ctx, - struct pipe_resource *index_buffer, - unsigned index_size, int index_bias, unsigned mode, - unsigned start, unsigned count) -{ - struct r600_draw draw; - assert(index_bias == 0); + assert(info->index_bias == 0); draw.ctx = ctx; - draw.mode = mode; - draw.start = start; - draw.count = count; - draw.index_size = index_size; - draw.index_buffer = index_buffer; - r600_draw_common(&draw); -} + draw.mode = info->mode; + draw.start = info->start; + draw.count = info->count; + if (info->indexed && rctx->index_buffer.buffer) { + draw.index_size = rctx->index_buffer.index_size; + draw.index_buffer = rctx->index_buffer.buffer; -void r600_draw_arrays(struct pipe_context *ctx, unsigned mode, - unsigned start, unsigned count) -{ - struct r600_draw draw; - - draw.ctx = ctx; - draw.mode = mode; - draw.start = start; - draw.count = count; - draw.index_size = 0; - draw.index_buffer = NULL; + assert(rctx->index_buffer.offset % + rctx->index_buffer.index_size == 0); + draw.start += rctx->index_buffer.offset / + rctx->index_buffer.index_size; + } + else { + draw.index_size = 0; + draw.index_buffer = NULL; + } r600_draw_common(&draw); } diff --git a/src/gallium/drivers/r600/r600_helper.c b/src/gallium/drivers/r600/r600_helper.c index 7241ab1c175..5e0e0aab570 100644 --- a/src/gallium/drivers/r600/r600_helper.c +++ b/src/gallium/drivers/r600/r600_helper.c @@ -30,97 +30,6 @@ #include "r600_context.h" #include "r600d.h" -int r600_conv_pipe_format(unsigned pformat, unsigned *format) -{ - switch (pformat) { - case PIPE_FORMAT_R32G32B32_FLOAT: - *format = 0x30; - return 0; - case PIPE_FORMAT_R32G32B32A32_FLOAT: - *format = V_0280A0_COLOR_32_32_32_32_FLOAT; - return 0; - case PIPE_FORMAT_A8R8G8B8_UNORM: - case PIPE_FORMAT_X8R8G8B8_UNORM: - case PIPE_FORMAT_B8G8R8A8_UNORM: - case PIPE_FORMAT_B8G8R8X8_UNORM: - case PIPE_FORMAT_R8G8B8A8_UNORM: - case PIPE_FORMAT_R8G8B8X8_UNORM: - case PIPE_FORMAT_R8G8B8A8_USCALED: - case PIPE_FORMAT_R8G8B8A8_SNORM: - case PIPE_FORMAT_R8G8B8A8_SSCALED: - *format = V_0280A0_COLOR_8_8_8_8; - return 0; - case PIPE_FORMAT_R32_FLOAT: - *format = V_0280A0_COLOR_32_FLOAT; - return 0; - case PIPE_FORMAT_R32G32_FLOAT: - *format = V_0280A0_COLOR_32_32_FLOAT; - return 0; - case PIPE_FORMAT_L8_UNORM: - case PIPE_FORMAT_A8_UNORM: - case PIPE_FORMAT_I8_UNORM: - case PIPE_FORMAT_L16_UNORM: - case PIPE_FORMAT_Z16_UNORM: - case PIPE_FORMAT_Z32_UNORM: - case PIPE_FORMAT_Z32_FLOAT: - case PIPE_FORMAT_R64_FLOAT: - case PIPE_FORMAT_R64G64_FLOAT: - case PIPE_FORMAT_R64G64B64_FLOAT: - case PIPE_FORMAT_R64G64B64A64_FLOAT: - case PIPE_FORMAT_R32_UNORM: - case PIPE_FORMAT_R32G32_UNORM: - case PIPE_FORMAT_R32G32B32_UNORM: - case PIPE_FORMAT_R32G32B32A32_UNORM: - case PIPE_FORMAT_R32_USCALED: - case PIPE_FORMAT_R32G32_USCALED: - case PIPE_FORMAT_R32G32B32_USCALED: - case PIPE_FORMAT_R32G32B32A32_USCALED: - case PIPE_FORMAT_R32_SNORM: - case PIPE_FORMAT_R32G32_SNORM: - case PIPE_FORMAT_R32G32B32_SNORM: - case PIPE_FORMAT_R32G32B32A32_SNORM: - case PIPE_FORMAT_R32_SSCALED: - case PIPE_FORMAT_R32G32_SSCALED: - case PIPE_FORMAT_R32G32B32_SSCALED: - case PIPE_FORMAT_R32G32B32A32_SSCALED: - case PIPE_FORMAT_R16_UNORM: - case PIPE_FORMAT_R16G16_UNORM: - case PIPE_FORMAT_R16G16B16_UNORM: - case PIPE_FORMAT_R16G16B16A16_UNORM: - case PIPE_FORMAT_R16_USCALED: - case PIPE_FORMAT_R16G16_USCALED: - case PIPE_FORMAT_R16G16B16_USCALED: - case PIPE_FORMAT_R16G16B16A16_USCALED: - case PIPE_FORMAT_R16_SNORM: - case PIPE_FORMAT_R16G16_SNORM: - case PIPE_FORMAT_R16G16B16_SNORM: - case PIPE_FORMAT_R16G16B16A16_SNORM: - case PIPE_FORMAT_R16_SSCALED: - case PIPE_FORMAT_R16G16_SSCALED: - case PIPE_FORMAT_R16G16B16_SSCALED: - case PIPE_FORMAT_R16G16B16A16_SSCALED: - case PIPE_FORMAT_R8_UNORM: - case PIPE_FORMAT_R8G8_UNORM: - case PIPE_FORMAT_R8G8B8_UNORM: - case PIPE_FORMAT_R8_USCALED: - case PIPE_FORMAT_R8G8_USCALED: - case PIPE_FORMAT_R8G8B8_USCALED: - case PIPE_FORMAT_R8_SNORM: - case PIPE_FORMAT_R8G8_SNORM: - case PIPE_FORMAT_R8G8B8_SNORM: - case PIPE_FORMAT_R8_SSCALED: - case PIPE_FORMAT_R8G8_SSCALED: - case PIPE_FORMAT_R8G8B8_SSCALED: - case PIPE_FORMAT_R32_FIXED: - case PIPE_FORMAT_R32G32_FIXED: - case PIPE_FORMAT_R32G32B32_FIXED: - case PIPE_FORMAT_R32G32B32A32_FIXED: - default: - R600_ERR("unsupported %d\n", pformat); - return -EINVAL; - } -} - int r600_conv_pipe_prim(unsigned pprim, unsigned *prim) { switch (pprim) { diff --git a/src/gallium/drivers/r600/r600_resource.c b/src/gallium/drivers/r600/r600_resource.c index d9aa1df04f0..8dc411ef409 100644 --- a/src/gallium/drivers/r600/r600_resource.c +++ b/src/gallium/drivers/r600/r600_resource.c @@ -24,45 +24,44 @@ #include "r600_context.h" #include "r600_resource.h" #include "r600_screen.h" -#include "r600_texture.h" -static struct pipe_resource * -r600_resource_create(struct pipe_screen *screen, - const struct pipe_resource *templ) +static struct pipe_resource *r600_resource_create(struct pipe_screen *screen, + const struct pipe_resource *templ) { - if (templ->target == PIPE_BUFFER) - return r600_buffer_create(screen, templ); - else - return r600_texture_create(screen, templ); + if (templ->target == PIPE_BUFFER) { + return r600_buffer_create(screen, templ); + } else { + return r600_texture_create(screen, templ); + } } -static struct pipe_resource * -r600_resource_from_handle(struct pipe_screen * screen, - const struct pipe_resource *templ, - struct winsys_handle *whandle) +static struct pipe_resource *r600_resource_from_handle(struct pipe_screen * screen, + const struct pipe_resource *templ, + struct winsys_handle *whandle) { - if (templ->target == PIPE_BUFFER) - return NULL; - else - return r600_texture_from_handle(screen, templ, whandle); + if (templ->target == PIPE_BUFFER) { + return NULL; + } else { + return r600_texture_from_handle(screen, templ, whandle); + } } void r600_init_context_resource_functions(struct r600_context *r600) { - r600->context.get_transfer = u_get_transfer_vtbl; - r600->context.transfer_map = u_transfer_map_vtbl; - r600->context.transfer_flush_region = u_transfer_flush_region_vtbl; - r600->context.transfer_unmap = u_transfer_unmap_vtbl; - r600->context.transfer_destroy = u_transfer_destroy_vtbl; - r600->context.transfer_inline_write = u_transfer_inline_write_vtbl; - r600->context.is_resource_referenced = u_is_resource_referenced_vtbl; + r600->context.get_transfer = u_get_transfer_vtbl; + r600->context.transfer_map = u_transfer_map_vtbl; + r600->context.transfer_flush_region = u_transfer_flush_region_vtbl; + r600->context.transfer_unmap = u_transfer_unmap_vtbl; + r600->context.transfer_destroy = u_transfer_destroy_vtbl; + r600->context.transfer_inline_write = u_transfer_inline_write_vtbl; + r600->context.is_resource_referenced = u_is_resource_referenced_vtbl; } void r600_init_screen_resource_functions(struct r600_screen *r600screen) { - r600screen->screen.resource_create = r600_resource_create; - r600screen->screen.resource_from_handle = r600_resource_from_handle; - r600screen->screen.resource_get_handle = u_resource_get_handle_vtbl; - r600screen->screen.resource_destroy = u_resource_destroy_vtbl; - r600screen->screen.user_buffer_create = r600_user_buffer_create; + r600screen->screen.resource_create = r600_resource_create; + r600screen->screen.resource_from_handle = r600_resource_from_handle; + r600screen->screen.resource_get_handle = u_resource_get_handle_vtbl; + r600screen->screen.resource_destroy = u_resource_destroy_vtbl; + r600screen->screen.user_buffer_create = r600_user_buffer_create; } diff --git a/src/gallium/drivers/r600/r600_resource.h b/src/gallium/drivers/r600/r600_resource.h index 95084a371bd..bb90e76fb78 100644 --- a/src/gallium/drivers/r600/r600_resource.h +++ b/src/gallium/drivers/r600/r600_resource.h @@ -20,14 +20,47 @@ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE * USE OR OTHER DEALINGS IN THE SOFTWARE. */ - #ifndef R600_RESOURCE_H #define R600_RESOURCE_H +#include "util/u_transfer.h" + struct r600_context; struct r600_screen; +/* This gets further specialized into either buffer or texture + * structures. Use the vtbl struct to choose between the two + * underlying implementations. + */ +struct r600_resource { + struct u_resource base; + struct radeon_bo *bo; + u32 domain; + u32 flink; + struct pb_buffer *pb; +}; + +struct r600_resource_texture { + struct r600_resource resource; + unsigned long offset[PIPE_MAX_TEXTURE_LEVELS]; + unsigned long pitch[PIPE_MAX_TEXTURE_LEVELS]; + unsigned long layer_size[PIPE_MAX_TEXTURE_LEVELS]; + unsigned long pitch_override; + unsigned long bpt; + unsigned long size; +}; + void r600_init_context_resource_functions(struct r600_context *r600); void r600_init_screen_resource_functions(struct r600_screen *r600screen); +/* r600_buffer */ +u32 r600_domain_from_usage(unsigned usage); + +/* r600_texture */ +struct pipe_resource *r600_texture_create(struct pipe_screen *screen, + const struct pipe_resource *templ); +struct pipe_resource *r600_texture_from_handle(struct pipe_screen *screen, + const struct pipe_resource *base, + struct winsys_handle *whandle); + #endif diff --git a/src/gallium/drivers/r600/r600_screen.c b/src/gallium/drivers/r600/r600_screen.c index dec6fa8d272..4b87327a7cf 100644 --- a/src/gallium/drivers/r600/r600_screen.c +++ b/src/gallium/drivers/r600/r600_screen.c @@ -24,15 +24,15 @@ * Jerome Glisse * Corbin Simpson */ -#include <util/u_inlines.h> -#include <util/u_format.h> -#include <util/u_memory.h> -#include "r600_resource.h" +#include <stdio.h> +#include "util/u_inlines.h" +#include "util/u_format.h" +#include "util/u_memory.h" #include "r600_screen.h" -#include "r600_texture.h" #include "r600_context.h" #include "r600_public.h" -#include <stdio.h> +#include "r600_resource.h" +#include "r600_state_inlines.h" static const char* r600_get_vendor(struct pipe_screen* pscreen) { @@ -107,7 +107,7 @@ static int r600_get_param(struct pipe_screen* pscreen, enum pipe_cap param) case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER: return 0; default: - debug_printf("r600: unknown param %d\n", param); + R600_ERR("r600: unknown param %d\n", param); return 0; } } @@ -125,7 +125,7 @@ static float r600_get_paramf(struct pipe_screen* pscreen, enum pipe_cap param) case PIPE_CAP_MAX_TEXTURE_LOD_BIAS: return 16.0f; default: - debug_printf("r600: unsupported paramf %d\n", param); + R600_ERR("r600: unsupported paramf %d\n", param); return 0.0f; } } @@ -134,108 +134,51 @@ static boolean r600_is_format_supported(struct pipe_screen* screen, enum pipe_format format, enum pipe_texture_target target, unsigned sample_count, - unsigned bindings, + unsigned usage, unsigned geom_flags) { + unsigned retval = 0; if (target >= PIPE_MAX_TEXTURE_TYPES) { - debug_printf("r600: unsupported texture type %d\n", target); + R600_ERR("r600: unsupported texture type %d\n", target); return FALSE; } - switch (format) { - case PIPE_FORMAT_B4G4R4A4_UNORM: - case PIPE_FORMAT_B5G6R5_UNORM: - case PIPE_FORMAT_B5G5R5A1_UNORM: - case PIPE_FORMAT_A8_UNORM: - case PIPE_FORMAT_L8_UNORM: - case PIPE_FORMAT_A8R8G8B8_SRGB: - case PIPE_FORMAT_R8G8B8A8_SRGB: - case PIPE_FORMAT_DXT1_RGB: - case PIPE_FORMAT_DXT1_RGBA: - case PIPE_FORMAT_DXT3_RGBA: - case PIPE_FORMAT_DXT5_RGBA: - case PIPE_FORMAT_UYVY: - case PIPE_FORMAT_L8_SRGB: - case PIPE_FORMAT_L8A8_SRGB: - case PIPE_FORMAT_L8A8_UNORM: - case PIPE_FORMAT_A8R8G8B8_UNORM: - case PIPE_FORMAT_X8R8G8B8_UNORM: - case PIPE_FORMAT_R8G8B8A8_UNORM: - case PIPE_FORMAT_R8G8B8X8_UNORM: - case PIPE_FORMAT_B8G8R8A8_UNORM: - case PIPE_FORMAT_B8G8R8X8_UNORM: - case PIPE_FORMAT_A8B8G8R8_SRGB: - case PIPE_FORMAT_B8G8R8A8_SRGB: - case PIPE_FORMAT_I8_UNORM: - case PIPE_FORMAT_Z16_UNORM: - case PIPE_FORMAT_X8Z24_UNORM: - case PIPE_FORMAT_S8_USCALED_Z24_UNORM: - case PIPE_FORMAT_Z32_UNORM: - case PIPE_FORMAT_Z24_UNORM_S8_USCALED: - case PIPE_FORMAT_Z24X8_UNORM: - return TRUE; - default: - /* Unknown format... */ - break; - } - return FALSE; -} - -struct pipe_transfer* r600_texture_get_transfer(struct pipe_context *ctx, - struct pipe_resource *texture, - struct pipe_subresource sr, - unsigned usage, - const struct pipe_box *box) -{ - struct r600_texture *rtex = (struct r600_texture*)texture; - struct r600_transfer *trans; - trans = CALLOC_STRUCT(r600_transfer); - if (trans == NULL) - return NULL; - pipe_resource_reference(&trans->transfer.resource, texture); - trans->transfer.sr = sr; - trans->transfer.usage = usage; - trans->transfer.box = *box; - trans->transfer.stride = rtex->stride[sr.level]; - trans->offset = r600_texture_get_offset(rtex, sr.level, box->z, sr.face); - return &trans->transfer; -} - -void r600_texture_transfer_destroy(struct pipe_context *ctx, - struct pipe_transfer *trans) -{ - pipe_resource_reference(&trans->resource, NULL); - FREE(trans); -} + /* Multisample */ + if (sample_count > 1) + return FALSE; -void* r600_texture_transfer_map(struct pipe_context *ctx, - struct pipe_transfer* transfer) -{ - struct r600_transfer *rtransfer = (struct r600_transfer*)transfer; - struct r600_texture *rtex = (struct r600_texture*)transfer->resource; - char *map; - enum pipe_format format = rtex->b.b.format; + if ((usage & PIPE_BIND_SAMPLER_VIEW) && + r600_is_sampler_format_supported(format)) { + retval |= PIPE_BIND_SAMPLER_VIEW; + } - map = pipe_buffer_map(ctx, rtex->buffer, - transfer->usage, - &rtransfer->buffer_transfer); + if ((usage & (PIPE_BIND_RENDER_TARGET | + PIPE_BIND_DISPLAY_TARGET | + PIPE_BIND_SCANOUT | + PIPE_BIND_SHARED)) && + r600_is_colorbuffer_format_supported(format)) { + retval |= usage & + (PIPE_BIND_RENDER_TARGET | + PIPE_BIND_DISPLAY_TARGET | + PIPE_BIND_SCANOUT | + PIPE_BIND_SHARED); + } - if (!map) { - return NULL; + if ((usage & PIPE_BIND_DEPTH_STENCIL) && + r600_is_zs_format_supported(format)) { + retval |= PIPE_BIND_DEPTH_STENCIL; } - return map + rtransfer->offset + - transfer->box.y / util_format_get_blockheight(format) * transfer->stride + - transfer->box.x / util_format_get_blockwidth(format) * util_format_get_blocksize(format); -} + if ((usage & PIPE_BIND_VERTEX_BUFFER) && + r600_is_vertex_format_supported(format)) + retval |= PIPE_BIND_VERTEX_BUFFER; -void r600_texture_transfer_unmap(struct pipe_context *ctx, - struct pipe_transfer* transfer) -{ - struct r600_transfer *rtransfer = (struct r600_transfer*)transfer; - struct r600_texture *rtex = (struct r600_texture*)transfer->resource; + if (usage & PIPE_BIND_TRANSFER_READ) + retval |= PIPE_BIND_TRANSFER_READ; + if (usage & PIPE_BIND_TRANSFER_WRITE) + retval |= PIPE_BIND_TRANSFER_WRITE; - pipe_buffer_unmap(ctx, rtex->buffer, rtransfer->buffer_transfer); + return retval == usage; } static void r600_destroy_screen(struct pipe_screen* pscreen) diff --git a/src/gallium/drivers/r600/r600_screen.h b/src/gallium/drivers/r600/r600_screen.h index 0a0286d96bc..9a452ecfe3f 100644 --- a/src/gallium/drivers/r600/r600_screen.h +++ b/src/gallium/drivers/r600/r600_screen.h @@ -40,14 +40,6 @@ struct r600_transfer { unsigned offset; }; -struct r600_buffer { - struct u_resource b; - struct radeon_bo *bo; - u32 domain; - u32 flink; - struct pb_buffer *pb; -}; - struct r600_screen { struct pipe_screen screen; struct radeon *rw; @@ -88,17 +80,4 @@ void r600_texture_transfer_unmap(struct pipe_context *ctx, int r600_conv_pipe_format(unsigned pformat, unsigned *format); int r600_conv_pipe_prim(unsigned pprim, unsigned *prim); -union r600_float_to_u32_u { - u32 u; - float f; -}; - -static inline u32 r600_float_to_u32(float f) -{ - union r600_float_to_u32_u c; - - c.f = f; - return c.u; -} - #endif diff --git a/src/gallium/drivers/r600/r600_shader.c b/src/gallium/drivers/r600/r600_shader.c index e5e6786fd04..dc8d4cb3151 100644 --- a/src/gallium/drivers/r600/r600_shader.c +++ b/src/gallium/drivers/r600/r600_shader.c @@ -34,6 +34,30 @@ #include <stdio.h> #include <errno.h> + +struct r600_shader_tgsi_instruction; + +struct r600_shader_ctx { + struct tgsi_shader_info info; + struct tgsi_parse_context parse; + const struct tgsi_token *tokens; + unsigned type; + unsigned file_offset[TGSI_FILE_COUNT]; + unsigned temp_reg; + struct r600_shader_tgsi_instruction *inst_info; + struct r600_bc *bc; + struct r600_shader *shader; + u32 value[4]; +}; + +struct r600_shader_tgsi_instruction { + unsigned tgsi_opcode; + unsigned is_op3; + unsigned r600_opcode; + int (*process)(struct r600_shader_ctx *ctx); +}; + +static struct r600_shader_tgsi_instruction r600_shader_tgsi_instruction[]; static int r600_shader_from_tgsi(const struct tgsi_token *tokens, struct r600_shader *shader); static int r600_shader_update(struct pipe_context *ctx, struct r600_shader *shader) @@ -74,96 +98,105 @@ static int r600_shader_update(struct pipe_context *ctx, struct r600_shader *shad return r600_bc_build(&shader->bc); } -struct r600_pipe_shader *r600_pipe_shader_create(struct pipe_context *ctx, - const struct tgsi_token *tokens) +int r600_pipe_shader_create(struct pipe_context *ctx, + struct r600_context_state *rpshader, + const struct tgsi_token *tokens) { struct r600_screen *rscreen = r600_screen(ctx->screen); - struct r600_pipe_shader *rpshader = CALLOC_STRUCT(r600_pipe_shader); int r; fprintf(stderr, "--------------------------------------------------------------\n"); tgsi_dump(tokens, 0); if (rpshader == NULL) - return NULL; + return -ENOMEM; rpshader->shader.family = radeon_get_family(rscreen->rw); r = r600_shader_from_tgsi(tokens, &rpshader->shader); if (r) { R600_ERR("translation from TGSI failed !\n"); - goto out_err; + return r; } r = r600_bc_build(&rpshader->shader.bc); if (r) { R600_ERR("building bytecode failed !\n"); - goto out_err; + return r; } fprintf(stderr, "______________________________________________________________\n"); - return rpshader; -out_err: - free(rpshader); - return NULL; + return 0; } -static int r600_pipe_shader_vs(struct pipe_context *ctx, struct r600_pipe_shader *rpshader) +static int r600_pipe_shader_vs(struct pipe_context *ctx, struct r600_context_state *rpshader) { struct r600_screen *rscreen = r600_screen(ctx->screen); struct r600_shader *rshader = &rpshader->shader; struct radeon_state *state; - unsigned i, j, tmp; + unsigned i, tmp; - rpshader->state = radeon_state_decref(rpshader->state); + rpshader->rstate = radeon_state_decref(rpshader->rstate); state = radeon_state(rscreen->rw, R600_VS_SHADER_TYPE, R600_VS_SHADER); if (state == NULL) return -ENOMEM; for (i = 0; i < 10; i++) { state->states[R600_VS_SHADER__SPI_VS_OUT_ID_0 + i] = 0; } - for (i = 0, j = 0; i < rshader->noutput; i++) { - if (rshader->output[i].name != TGSI_SEMANTIC_POSITION) { - tmp = rshader->output[i].sid << ((j & 3) * 8); - state->states[R600_VS_SHADER__SPI_VS_OUT_ID_0 + j / 4] |= tmp; - j++; - } + /* so far never got proper semantic id from tgsi */ + for (i = 0; i < 32; i++) { + tmp = i << ((i & 3) * 8); + state->states[R600_VS_SHADER__SPI_VS_OUT_ID_0 + i / 4] |= tmp; } state->states[R600_VS_SHADER__SPI_VS_OUT_CONFIG] = S_0286C4_VS_EXPORT_COUNT(rshader->noutput - 2); state->states[R600_VS_SHADER__SQ_PGM_RESOURCES_VS] = S_028868_NUM_GPRS(rshader->bc.ngpr); - rpshader->state = state; - rpshader->state->bo[0] = radeon_bo_incref(rscreen->rw, rpshader->bo); - rpshader->state->bo[1] = radeon_bo_incref(rscreen->rw, rpshader->bo); - rpshader->state->nbo = 2; - rpshader->state->placement[0] = RADEON_GEM_DOMAIN_GTT; + rpshader->rstate = state; + rpshader->rstate->bo[0] = radeon_bo_incref(rscreen->rw, rpshader->bo); + rpshader->rstate->bo[1] = radeon_bo_incref(rscreen->rw, rpshader->bo); + rpshader->rstate->nbo = 2; + rpshader->rstate->placement[0] = RADEON_GEM_DOMAIN_GTT; return radeon_state_pm4(state); } -static int r600_pipe_shader_ps(struct pipe_context *ctx, struct r600_pipe_shader *rpshader) +static int r600_pipe_shader_ps(struct pipe_context *ctx, struct r600_context_state *rpshader) { struct r600_screen *rscreen = r600_screen(ctx->screen); struct r600_shader *rshader = &rpshader->shader; struct radeon_state *state; - unsigned i, tmp; + unsigned i, tmp, exports_ps, num_cout; - rpshader->state = radeon_state_decref(rpshader->state); + rpshader->rstate = radeon_state_decref(rpshader->rstate); state = radeon_state(rscreen->rw, R600_PS_SHADER_TYPE, R600_PS_SHADER); if (state == NULL) return -ENOMEM; for (i = 0; i < rshader->ninput; i++) { - tmp = S_028644_SEMANTIC(rshader->input[i].sid); + tmp = S_028644_SEMANTIC(i); tmp |= S_028644_SEL_CENTROID(1); - tmp |= S_028644_FLAT_SHADE(rshader->flat_shade); + if (rshader->input[i].name == TGSI_SEMANTIC_COLOR || + rshader->input[i].name == TGSI_SEMANTIC_BCOLOR) { + tmp |= S_028644_FLAT_SHADE(rshader->flat_shade); + } state->states[R600_PS_SHADER__SPI_PS_INPUT_CNTL_0 + i] = tmp; } + + exports_ps = 0; + num_cout = 0; + for (i = 0; i < rshader->noutput; i++) { + if (rshader->output[i].name == TGSI_SEMANTIC_POSITION) + exports_ps |= 1; + else if (rshader->output[i].name == TGSI_SEMANTIC_COLOR) { + exports_ps |= (1 << (num_cout+1)); + num_cout++; + } + } state->states[R600_PS_SHADER__SPI_PS_IN_CONTROL_0] = S_0286CC_NUM_INTERP(rshader->ninput) | S_0286CC_PERSP_GRADIENT_ENA(1); state->states[R600_PS_SHADER__SPI_PS_IN_CONTROL_1] = 0x00000000; state->states[R600_PS_SHADER__SQ_PGM_RESOURCES_PS] = S_028868_NUM_GPRS(rshader->bc.ngpr); - state->states[R600_PS_SHADER__SQ_PGM_EXPORTS_PS] = 0x00000002; - rpshader->state = state; - rpshader->state->bo[0] = radeon_bo_incref(rscreen->rw, rpshader->bo); - rpshader->state->nbo = 1; - rpshader->state->placement[0] = RADEON_GEM_DOMAIN_GTT; + state->states[R600_PS_SHADER__SQ_PGM_EXPORTS_PS] = exports_ps; + rpshader->rstate = state; + rpshader->rstate->bo[0] = radeon_bo_incref(rscreen->rw, rpshader->bo); + rpshader->rstate->nbo = 1; + rpshader->rstate->placement[0] = RADEON_GEM_DOMAIN_GTT; return radeon_state_pm4(state); } -static int r600_pipe_shader(struct pipe_context *ctx, struct r600_pipe_shader *rpshader) +static int r600_pipe_shader(struct pipe_context *ctx, struct r600_context_state *rpshader) { struct r600_screen *rscreen = r600_screen(ctx->screen); struct r600_context *rctx = r600_context(ctx); @@ -197,7 +230,7 @@ static int r600_pipe_shader(struct pipe_context *ctx, struct r600_pipe_shader *r return r; } -int r600_pipe_shader_update(struct pipe_context *ctx, struct r600_pipe_shader *rpshader) +int r600_pipe_shader_update(struct pipe_context *ctx, struct r600_context_state *rpshader) { struct r600_context *rctx = r600_context(ctx); int r; @@ -216,29 +249,6 @@ int r600_pipe_shader_update(struct pipe_context *ctx, struct r600_pipe_shader *r return r600_pipe_shader(ctx, rpshader); } -struct r600_shader_tgsi_instruction; - -struct r600_shader_ctx { - struct tgsi_shader_info info; - struct tgsi_parse_context parse; - const struct tgsi_token *tokens; - unsigned type; - unsigned file_offset[TGSI_FILE_COUNT]; - unsigned temp_reg; - struct r600_shader_tgsi_instruction *inst_info; - struct r600_bc *bc; - struct r600_shader *shader; -}; - -struct r600_shader_tgsi_instruction { - unsigned tgsi_opcode; - unsigned is_op3; - unsigned r600_opcode; - int (*process)(struct r600_shader_ctx *ctx); -}; - -static struct r600_shader_tgsi_instruction r600_shader_tgsi_instruction[]; - static int tgsi_is_supported(struct r600_shader_ctx *ctx) { struct tgsi_full_instruction *i = &ctx->parse.FullToken.FullInstruction; @@ -248,10 +258,6 @@ static int tgsi_is_supported(struct r600_shader_ctx *ctx) R600_ERR("too many dst (%d)\n", i->Instruction.NumDstRegs); return -EINVAL; } - if (i->Instruction.Saturate) { - R600_ERR("staturate unsupported\n"); - return -EINVAL; - } if (i->Instruction.Predicate) { R600_ERR("predicate unsupported\n"); return -EINVAL; @@ -289,6 +295,7 @@ static int tgsi_declaration(struct r600_shader_ctx *ctx) i = ctx->shader->ninput++; ctx->shader->input[i].name = d->Semantic.Name; ctx->shader->input[i].sid = d->Semantic.Index; + ctx->shader->input[i].interpolate = d->Declaration.Interpolate; ctx->shader->input[i].gpr = ctx->file_offset[TGSI_FILE_INPUT] + i; if (ctx->type == TGSI_PROCESSOR_VERTEX) { /* turn input into fetch */ @@ -315,6 +322,7 @@ static int tgsi_declaration(struct r600_shader_ctx *ctx) ctx->shader->output[i].name = d->Semantic.Name; ctx->shader->output[i].sid = d->Semantic.Index; ctx->shader->output[i].gpr = ctx->file_offset[TGSI_FILE_OUTPUT] + i; + ctx->shader->output[i].interpolate = d->Declaration.Interpolate; break; case TGSI_FILE_CONSTANT: case TGSI_FILE_TEMPORARY: @@ -334,7 +342,6 @@ int r600_shader_from_tgsi(const struct tgsi_token *tokens, struct r600_shader *s struct r600_bc_output output; unsigned opcode; int i, r = 0, pos0; - u32 value[4]; ctx.bc = &shader->bc; ctx.shader = shader; @@ -380,10 +387,10 @@ int r600_shader_from_tgsi(const struct tgsi_token *tokens, struct r600_shader *s switch (ctx.parse.FullToken.Token.Type) { case TGSI_TOKEN_TYPE_IMMEDIATE: immediate = &ctx.parse.FullToken.FullImmediate; - value[0] = immediate->u[0].Uint; - value[1] = immediate->u[1].Uint; - value[2] = immediate->u[2].Uint; - value[3] = immediate->u[3].Uint; + ctx.value[0] = immediate->u[0].Uint; + ctx.value[1] = immediate->u[1].Uint; + ctx.value[2] = immediate->u[2].Uint; + ctx.value[3] = immediate->u[3].Uint; break; case TGSI_TOKEN_TYPE_DECLARATION: r = tgsi_declaration(&ctx); @@ -399,7 +406,7 @@ int r600_shader_from_tgsi(const struct tgsi_token *tokens, struct r600_shader *s r = ctx.inst_info->process(&ctx); if (r) goto out_err; - r = r600_bc_add_literal(ctx.bc, value); + r = r600_bc_add_literal(ctx.bc, ctx.value); if (r) goto out_err; break; @@ -435,6 +442,9 @@ int r600_shader_from_tgsi(const struct tgsi_token *tokens, struct r600_shader *s if (shader->output[i].name == TGSI_SEMANTIC_COLOR) { output.array_base = 0; output.type = V_SQ_CF_ALLOC_EXPORT_WORD0_SQ_EXPORT_PIXEL; + } else if (shader->output[i].name == TGSI_SEMANTIC_POSITION) { + output.array_base = 61; + output.type = V_SQ_CF_ALLOC_EXPORT_WORD0_SQ_EXPORT_PIXEL; } else { R600_ERR("unsupported fragment output name %d\n", shader->output[i].name); r = -EINVAL; @@ -473,30 +483,14 @@ static int tgsi_end(struct r600_shader_ctx *ctx) static int tgsi_src(struct r600_shader_ctx *ctx, const struct tgsi_full_src_register *tgsi_src, - unsigned swizzle, struct r600_bc_alu_src *r600_src) { + memset(r600_src, 0, sizeof(struct r600_bc_alu_src)); r600_src->sel = tgsi_src->Register.Index; if (tgsi_src->Register.File == TGSI_FILE_IMMEDIATE) { r600_src->sel = 0; } r600_src->sel += ctx->file_offset[tgsi_src->Register.File]; - switch (swizzle) { - case 0: - r600_src->chan = tgsi_src->Register.SwizzleX; - break; - case 1: - r600_src->chan = tgsi_src->Register.SwizzleY; - break; - case 2: - r600_src->chan = tgsi_src->Register.SwizzleZ; - break; - case 3: - r600_src->chan = tgsi_src->Register.SwizzleW; - break; - default: - return -EINVAL; - } return 0; } @@ -505,29 +499,92 @@ static int tgsi_dst(struct r600_shader_ctx *ctx, unsigned swizzle, struct r600_bc_alu_dst *r600_dst) { + struct tgsi_full_instruction *inst = &ctx->parse.FullToken.FullInstruction; + r600_dst->sel = tgsi_dst->Register.Index; r600_dst->sel += ctx->file_offset[tgsi_dst->Register.File]; r600_dst->chan = swizzle; r600_dst->write = 1; + if (inst->Instruction.Saturate) { + r600_dst->clamp = 1; + } + return 0; +} + +static unsigned tgsi_chan(const struct tgsi_full_src_register *tgsi_src, unsigned swizzle) +{ + switch (swizzle) { + case 0: + return tgsi_src->Register.SwizzleX; + case 1: + return tgsi_src->Register.SwizzleY; + case 2: + return tgsi_src->Register.SwizzleZ; + case 3: + return tgsi_src->Register.SwizzleW; + default: + return 0; + } +} + +static int tgsi_split_constant(struct r600_shader_ctx *ctx, struct r600_bc_alu_src r600_src[3]) +{ + struct tgsi_full_instruction *inst = &ctx->parse.FullToken.FullInstruction; + struct r600_bc_alu alu; + int i, j, k, nconst, r; + + for (i = 0, nconst = 0; i < inst->Instruction.NumSrcRegs; i++) { + if (inst->Src[i].Register.File == TGSI_FILE_CONSTANT) { + nconst++; + } + r = tgsi_src(ctx, &inst->Src[i], &r600_src[i]); + if (r) { + return r; + } + } + for (i = 0, j = nconst - 1; i < inst->Instruction.NumSrcRegs; i++) { + if (inst->Src[j].Register.File == TGSI_FILE_CONSTANT && j > 0) { + for (k = 0; k < 4; k++) { + memset(&alu, 0, sizeof(struct r600_bc_alu)); + alu.inst = V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOV; + alu.src[0].sel = r600_src[0].sel; + alu.src[0].chan = k; + alu.dst.sel = ctx->temp_reg + j; + alu.dst.chan = k; + alu.dst.write = 1; + if (k == 3) + alu.last = 1; + r = r600_bc_add_alu(ctx->bc, &alu); + if (r) + return r; + } + r600_src[0].sel = ctx->temp_reg + j; + j--; + } + } return 0; } static int tgsi_op2(struct r600_shader_ctx *ctx) { struct tgsi_full_instruction *inst = &ctx->parse.FullToken.FullInstruction; + struct r600_bc_alu_src r600_src[3]; struct r600_bc_alu alu; int i, j, r; + r = tgsi_split_constant(ctx, r600_src); + if (r) + return r; for (i = 0; i < 4; i++) { memset(&alu, 0, sizeof(struct r600_bc_alu)); if (!(inst->Dst[0].Register.WriteMask & (1 << i))) { alu.inst = V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP; + alu.dst.chan = i; } else { alu.inst = ctx->inst_info->r600_opcode; for (j = 0; j < inst->Instruction.NumSrcRegs; j++) { - r = tgsi_src(ctx, &inst->Src[j], i, &alu.src[j]); - if (r) - return r; + alu.src[j] = r600_src[j]; + alu.src[j].chan = tgsi_chan(&inst->Src[j], i); } r = tgsi_dst(ctx, &inst->Dst[0], i, &alu.dst); if (r) @@ -538,6 +595,9 @@ static int tgsi_op2(struct r600_shader_ctx *ctx) case TGSI_OPCODE_SUB: alu.src[1].neg = 1; break; + case TGSI_OPCODE_ABS: + alu.src[0].abs = 1; + break; default: break; } @@ -551,24 +611,52 @@ static int tgsi_op2(struct r600_shader_ctx *ctx) return 0; } +static int tgsi_kill(struct r600_shader_ctx *ctx) +{ + struct tgsi_full_instruction *inst = &ctx->parse.FullToken.FullInstruction; + struct r600_bc_alu alu; + int i, r; + + for (i = 0; i < 4; i++) { + memset(&alu, 0, sizeof(struct r600_bc_alu)); + alu.inst = ctx->inst_info->r600_opcode; + alu.dst.chan = i; + alu.src[0].sel = 248; + r = tgsi_src(ctx, &inst->Src[0], &alu.src[1]); + if (r) + return r; + alu.src[1].chan = tgsi_chan(&inst->Src[0], i); + if (i == 3) { + alu.last = 1; + } + r = r600_bc_add_alu(ctx->bc, &alu); + if (r) + return r; + } + return 0; +} + static int tgsi_slt(struct r600_shader_ctx *ctx) { struct tgsi_full_instruction *inst = &ctx->parse.FullToken.FullInstruction; + struct r600_bc_alu_src r600_src[3]; struct r600_bc_alu alu; int i, r; + r = tgsi_split_constant(ctx, r600_src); + if (r) + return r; for (i = 0; i < 4; i++) { memset(&alu, 0, sizeof(struct r600_bc_alu)); if (!(inst->Dst[0].Register.WriteMask & (1 << i))) { alu.inst = V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP; + alu.dst.chan = i; } else { alu.inst = ctx->inst_info->r600_opcode; - r = tgsi_src(ctx, &inst->Src[0], i, &alu.src[1]); - if (r) - return r; - r = tgsi_src(ctx, &inst->Src[1], i, &alu.src[0]); - if (r) - return r; + alu.src[1] = r600_src[0]; + alu.src[1].chan = tgsi_chan(&inst->Src[0], i); + alu.src[0] = r600_src[1]; + alu.src[0].chan = tgsi_chan(&inst->Src[1], i); r = tgsi_dst(ctx, &inst->Dst[0], i, &alu.dst); if (r) return r; @@ -587,73 +675,71 @@ static int tgsi_lit(struct r600_shader_ctx *ctx) { struct tgsi_full_instruction *inst = &ctx->parse.FullToken.FullInstruction; struct r600_bc_alu alu; - int r; + /* dst.x, <- 1.0 */ + memset(&alu, 0, sizeof(struct r600_bc_alu)); + alu.inst = V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOV; + alu.src[0].sel = 249; /*1.0*/ + alu.src[0].chan = 0; + r = tgsi_dst(ctx, &inst->Dst[0], 0, &alu.dst); + if (r) + return r; + alu.dst.write = (inst->Dst[0].Register.WriteMask >> 0) & 1; + r = r600_bc_add_alu(ctx->bc, &alu); + if (r) + return r; - if (inst->Dst[0].Register.WriteMask & (1 << 0)) - { - /* dst.x, <- 1.0 */ - memset(&alu, 0, sizeof(struct r600_bc_alu)); - alu.inst = V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOV; - alu.src[0].sel = 249; /*1.0*/ - alu.src[0].chan = 0; - r = tgsi_dst(ctx, &inst->Dst[0], 0, &alu.dst); - if (r) - return r; - if ((inst->Dst[0].Register.WriteMask & 0xe) == 0) - alu.last = 1; - r = r600_bc_add_alu(ctx->bc, &alu); - if (r) - return r; - } - + /* dst.y = max(src.x, 0.0) */ + memset(&alu, 0, sizeof(struct r600_bc_alu)); + alu.inst = V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MAX; + r = tgsi_src(ctx, &inst->Src[0], &alu.src[0]); + if (r) + return r; + alu.src[1].sel = 248; /*0.0*/ + alu.src[1].chan = tgsi_chan(&inst->Src[0], 0); + r = tgsi_dst(ctx, &inst->Dst[0], 1, &alu.dst); + if (r) + return r; + alu.dst.write = (inst->Dst[0].Register.WriteMask >> 1) & 1; + r = r600_bc_add_alu(ctx->bc, &alu); + if (r) + return r; - if (inst->Dst[0].Register.WriteMask & (1 << 1)) - { - /* dst.y = max(src.x, 0.0) */ - memset(&alu, 0, sizeof(struct r600_bc_alu)); - alu.inst = V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MAX; - r = tgsi_src(ctx, &inst->Src[0], 0, &alu.src[0]); - if (r) - return r; - alu.src[1].sel = 248; /*0.0*/ - alu.src[1].chan = 0; - r = tgsi_dst(ctx, &inst->Dst[0], 1, &alu.dst); - if (r) - return r; - if ((inst->Dst[0].Register.WriteMask & 0xa) == 0) - alu.last = 1; - r = r600_bc_add_alu(ctx->bc, &alu); - if (r) - return r; - } + /* dst.z = NOP - fill Z slot */ + memset(&alu, 0, sizeof(struct r600_bc_alu)); + alu.inst = V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP; + alu.dst.chan = 2; + r = r600_bc_add_alu(ctx->bc, &alu); + if (r) + return r; - if (inst->Dst[0].Register.WriteMask & (1 << 3)) - { - /* dst.w, <- 1.0 */ - memset(&alu, 0, sizeof(struct r600_bc_alu)); - alu.inst = V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOV; - alu.src[0].sel = 249; - alu.src[0].chan = 0; - r = tgsi_dst(ctx, &inst->Dst[0], 3, &alu.dst); - if (r) - return r; - if ((inst->Dst[0].Register.WriteMask & 0x4) == 0) - alu.last = 1; - r = r600_bc_add_alu(ctx->bc, &alu); - if (r) - return r; - } + /* dst.w, <- 1.0 */ + memset(&alu, 0, sizeof(struct r600_bc_alu)); + alu.inst = V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOV; + alu.src[0].sel = 249; + alu.src[0].chan = 0; + r = tgsi_dst(ctx, &inst->Dst[0], 3, &alu.dst); + if (r) + return r; + alu.dst.write = (inst->Dst[0].Register.WriteMask >> 3) & 1; + alu.last = 1; + r = r600_bc_add_alu(ctx->bc, &alu); + if (r) + return r; if (inst->Dst[0].Register.WriteMask & (1 << 2)) { + int chan; + int sel; + /* dst.z = log(src.y) */ memset(&alu, 0, sizeof(struct r600_bc_alu)); alu.inst = V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_LOG_CLAMPED; - r = tgsi_src(ctx, &inst->Src[0], 1, &alu.src[0]); + r = tgsi_src(ctx, &inst->Src[0], &alu.src[0]); if (r) return r; + alu.src[0].chan = tgsi_chan(&inst->Src[0], 1); r = tgsi_dst(ctx, &inst->Dst[0], 2, &alu.dst); if (r) return r; @@ -662,20 +748,22 @@ static int tgsi_lit(struct r600_shader_ctx *ctx) if (r) return r; - int chan = alu.dst.chan; - int sel = alu.dst.sel; + chan = alu.dst.chan; + sel = alu.dst.sel; /* tmp.x = amd MUL_LIT(src.w, dst.z, src.x ) */ memset(&alu, 0, sizeof(struct r600_bc_alu)); alu.inst = V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_MUL_LIT; - r = tgsi_src(ctx, &inst->Src[0], 3, &alu.src[0]); + r = tgsi_src(ctx, &inst->Src[0], &alu.src[0]); if (r) - return r; + return r; + alu.src[0].chan = tgsi_chan(&inst->Src[0], 3); alu.src[1].sel = sel; alu.src[1].chan = chan; - r = tgsi_src(ctx, &inst->Src[0], 0, &alu.src[2]); + r = tgsi_src(ctx, &inst->Src[0], &alu.src[2]); if (r) return r; + alu.src[2].chan = tgsi_chan(&inst->Src[0], 0); alu.dst.sel = ctx->temp_reg; alu.dst.chan = 0; alu.dst.write = 1; @@ -712,9 +800,10 @@ static int tgsi_trans(struct r600_shader_ctx *ctx) if (inst->Dst[0].Register.WriteMask & (1 << i)) { alu.inst = ctx->inst_info->r600_opcode; for (j = 0; j < inst->Instruction.NumSrcRegs; j++) { - r = tgsi_src(ctx, &inst->Src[j], i, &alu.src[j]); + r = tgsi_src(ctx, &inst->Src[j], &alu.src[j]); if (r) return r; + alu.src[j].chan = tgsi_chan(&inst->Src[j], i); } r = tgsi_dst(ctx, &inst->Dst[0], i, &alu.dst); if (r) @@ -728,15 +817,58 @@ static int tgsi_trans(struct r600_shader_ctx *ctx) return 0; } +static int tgsi_trans_srcx_replicate(struct r600_shader_ctx *ctx) +{ + struct tgsi_full_instruction *inst = &ctx->parse.FullToken.FullInstruction; + struct r600_bc_alu alu; + int i, j, r; + + memset(&alu, 0, sizeof(struct r600_bc_alu)); + alu.inst = ctx->inst_info->r600_opcode; + for (j = 0; j < inst->Instruction.NumSrcRegs; j++) { + r = tgsi_src(ctx, &inst->Src[j], &alu.src[j]); + if (r) + return r; + alu.src[j].chan = tgsi_chan(&inst->Src[j], 0); + } + alu.dst.sel = ctx->temp_reg; + alu.dst.write = 1; + alu.last = 1; + r = r600_bc_add_alu(ctx->bc, &alu); + if (r) + return r; + /* replicate result */ + for (i = 0; i < 4; i++) { + memset(&alu, 0, sizeof(struct r600_bc_alu)); + alu.src[0].sel = ctx->temp_reg; + alu.inst = V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOV; + alu.dst.chan = i; + r = tgsi_dst(ctx, &inst->Dst[0], i, &alu.dst); + if (r) + return r; + alu.dst.write = (inst->Dst[0].Register.WriteMask >> i) & 1; + if (i == 3) + alu.last = 1; + r = r600_bc_add_alu(ctx->bc, &alu); + if (r) + return r; + } + return 0; +} + static int tgsi_helper_copy(struct r600_shader_ctx *ctx, struct tgsi_full_instruction *inst) { struct r600_bc_alu alu; int i, r; + r = r600_bc_add_literal(ctx->bc, ctx->value); + if (r) + return r; for (i = 0; i < 4; i++) { memset(&alu, 0, sizeof(struct r600_bc_alu)); if (!(inst->Dst[0].Register.WriteMask & (1 << i))) { alu.inst = V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP; + alu.dst.chan = i; } else { alu.inst = V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOV; r = tgsi_dst(ctx, &inst->Dst[0], i, &alu.dst); @@ -758,17 +890,20 @@ static int tgsi_helper_copy(struct r600_shader_ctx *ctx, struct tgsi_full_instru static int tgsi_op3(struct r600_shader_ctx *ctx) { struct tgsi_full_instruction *inst = &ctx->parse.FullToken.FullInstruction; + struct r600_bc_alu_src r600_src[3]; struct r600_bc_alu alu; int i, j, r; + r = tgsi_split_constant(ctx, r600_src); + if (r) + return r; /* do it in 2 step as op3 doesn't support writemask */ for (i = 0; i < 4; i++) { memset(&alu, 0, sizeof(struct r600_bc_alu)); alu.inst = ctx->inst_info->r600_opcode; for (j = 0; j < inst->Instruction.NumSrcRegs; j++) { - r = tgsi_src(ctx, &inst->Src[j], i, &alu.src[j]); - if (r) - return r; + alu.src[j] = r600_src[j]; + alu.src[j].chan = tgsi_chan(&inst->Src[j], i); } alu.dst.sel = ctx->temp_reg; alu.dst.chan = i; @@ -787,16 +922,19 @@ static int tgsi_op3(struct r600_shader_ctx *ctx) static int tgsi_dp(struct r600_shader_ctx *ctx) { struct tgsi_full_instruction *inst = &ctx->parse.FullToken.FullInstruction; + struct r600_bc_alu_src r600_src[3]; struct r600_bc_alu alu; int i, j, r; + r = tgsi_split_constant(ctx, r600_src); + if (r) + return r; for (i = 0; i < 4; i++) { memset(&alu, 0, sizeof(struct r600_bc_alu)); alu.inst = ctx->inst_info->r600_opcode; for (j = 0; j < inst->Instruction.NumSrcRegs; j++) { - r = tgsi_src(ctx, &inst->Src[j], i, &alu.src[j]); - if (r) - return r; + alu.src[j] = r600_src[j]; + alu.src[j].chan = tgsi_chan(&inst->Src[j], i); } alu.dst.sel = ctx->temp_reg; alu.dst.chan = i; @@ -832,13 +970,81 @@ static int tgsi_tex(struct r600_shader_ctx *ctx) { struct tgsi_full_instruction *inst = &ctx->parse.FullToken.FullInstruction; struct r600_bc_tex tex; + struct r600_bc_alu alu; + unsigned src_gpr; + int r; + + src_gpr = ctx->file_offset[inst->Src[0].Register.File] + inst->Src[0].Register.Index; + /* Add perspective divide */ + memset(&alu, 0, sizeof(struct r600_bc_alu)); + alu.inst = V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIP_IEEE; + alu.src[0].sel = src_gpr; + alu.src[0].chan = tgsi_chan(&inst->Src[0], 3); + alu.dst.sel = ctx->temp_reg; + alu.dst.chan = 3; + alu.last = 1; + alu.dst.write = 1; + r = r600_bc_add_alu(ctx->bc, &alu); + if (r) + return r; + + memset(&alu, 0, sizeof(struct r600_bc_alu)); + alu.inst = V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MUL; + alu.src[0].sel = ctx->temp_reg; + alu.src[0].chan = 3; + alu.src[1].sel = src_gpr; + alu.src[1].chan = tgsi_chan(&inst->Src[0], 0); + alu.dst.sel = ctx->temp_reg; + alu.dst.chan = 0; + alu.dst.write = 1; + r = r600_bc_add_alu(ctx->bc, &alu); + if (r) + return r; + memset(&alu, 0, sizeof(struct r600_bc_alu)); + alu.inst = V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MUL; + alu.src[0].sel = ctx->temp_reg; + alu.src[0].chan = 3; + alu.src[1].sel = src_gpr; + alu.src[1].chan = tgsi_chan(&inst->Src[0], 1); + alu.dst.sel = ctx->temp_reg; + alu.dst.chan = 1; + alu.dst.write = 1; + r = r600_bc_add_alu(ctx->bc, &alu); + if (r) + return r; + memset(&alu, 0, sizeof(struct r600_bc_alu)); + alu.inst = V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MUL; + alu.src[0].sel = ctx->temp_reg; + alu.src[0].chan = 3; + alu.src[1].sel = src_gpr; + alu.src[1].chan = tgsi_chan(&inst->Src[0], 2); + alu.dst.sel = ctx->temp_reg; + alu.dst.chan = 2; + alu.dst.write = 1; + r = r600_bc_add_alu(ctx->bc, &alu); + if (r) + return r; + memset(&alu, 0, sizeof(struct r600_bc_alu)); + alu.inst = V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOV; + alu.src[0].sel = 249; + alu.src[0].chan = 0; + alu.dst.sel = ctx->temp_reg; + alu.dst.chan = 3; + alu.last = 1; + alu.dst.write = 1; + r = r600_bc_add_alu(ctx->bc, &alu); + if (r) + return r; + src_gpr = ctx->temp_reg; + + /* TODO use temp if src_gpr is not a temporary reg (File != TEMPORARY) */ memset(&tex, 0, sizeof(struct r600_bc_tex)); tex.inst = ctx->inst_info->r600_opcode; tex.resource_id = ctx->file_offset[inst->Src[1].Register.File] + inst->Src[1].Register.Index; tex.sampler_id = tex.resource_id; - tex.src_gpr = ctx->file_offset[inst->Src[0].Register.File] + inst->Src[0].Register.Index; - tex.dst_gpr = ctx->file_offset[inst->Dst[0].Register.File] + inst->Src[0].Register.Index; + tex.src_gpr = src_gpr; + tex.dst_gpr = ctx->file_offset[inst->Dst[0].Register.File] + inst->Dst[0].Register.Index; tex.dst_sel_x = 0; tex.dst_sel_y = 1; tex.dst_sel_z = 2; @@ -847,15 +1053,101 @@ static int tgsi_tex(struct r600_shader_ctx *ctx) tex.src_sel_y = 1; tex.src_sel_z = 2; tex.src_sel_w = 3; + + if (inst->Texture.Texture != TGSI_TEXTURE_RECT) { + tex.coord_type_x = 1; + tex.coord_type_y = 1; + tex.coord_type_z = 1; + tex.coord_type_w = 1; + } return r600_bc_add_tex(ctx->bc, &tex); } +static int tgsi_lrp(struct r600_shader_ctx *ctx) +{ + struct tgsi_full_instruction *inst = &ctx->parse.FullToken.FullInstruction; + struct r600_bc_alu_src r600_src[3]; + struct r600_bc_alu alu; + unsigned i; + int r; + + r = tgsi_split_constant(ctx, r600_src); + if (r) + return r; + /* 1 - src0 */ + for (i = 0; i < 4; i++) { + memset(&alu, 0, sizeof(struct r600_bc_alu)); + alu.inst = V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_ADD; + alu.src[0].sel = 249; + alu.src[0].chan = 0; + alu.src[1] = r600_src[0]; + alu.src[1].chan = tgsi_chan(&inst->Src[0], i); + alu.src[1].neg = 1; + alu.dst.sel = ctx->temp_reg; + alu.dst.chan = i; + if (i == 3) { + alu.last = 1; + } + alu.dst.write = 1; + r = r600_bc_add_alu(ctx->bc, &alu); + if (r) + return r; + } + r = r600_bc_add_literal(ctx->bc, ctx->value); + if (r) + return r; + + /* (1 - src0) * src2 */ + for (i = 0; i < 4; i++) { + memset(&alu, 0, sizeof(struct r600_bc_alu)); + alu.inst = V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MUL; + alu.src[0].sel = ctx->temp_reg; + alu.src[0].chan = i; + alu.src[1] = r600_src[2]; + alu.src[1].chan = tgsi_chan(&inst->Src[2], i); + alu.dst.sel = ctx->temp_reg; + alu.dst.chan = i; + if (i == 3) { + alu.last = 1; + } + alu.dst.write = 1; + r = r600_bc_add_alu(ctx->bc, &alu); + if (r) + return r; + } + r = r600_bc_add_literal(ctx->bc, ctx->value); + if (r) + return r; + + /* src0 * src1 + (1 - src0) * src2 */ + for (i = 0; i < 4; i++) { + memset(&alu, 0, sizeof(struct r600_bc_alu)); + alu.inst = V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_MULADD; + alu.is_op3 = 1; + alu.src[0] = r600_src[0]; + alu.src[0].chan = tgsi_chan(&inst->Src[0], i); + alu.src[1] = r600_src[1]; + alu.src[1].chan = tgsi_chan(&inst->Src[1], i); + alu.src[2].sel = ctx->temp_reg; + alu.src[2].chan = i; + alu.dst.sel = ctx->temp_reg; + alu.dst.chan = i; + if (i == 3) { + alu.last = 1; + } + r = r600_bc_add_alu(ctx->bc, &alu); + if (r) + return r; + } + return tgsi_helper_copy(ctx, inst); +} + static struct r600_shader_tgsi_instruction r600_shader_tgsi_instruction[] = { {TGSI_OPCODE_ARL, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, {TGSI_OPCODE_MOV, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOV, tgsi_op2}, {TGSI_OPCODE_LIT, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_lit}, - {TGSI_OPCODE_RCP, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, - {TGSI_OPCODE_RSQ, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIPSQRT_IEEE, tgsi_trans}, + {TGSI_OPCODE_RCP, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIP_IEEE, tgsi_trans_srcx_replicate}, + {TGSI_OPCODE_RSQ, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIPSQRT_IEEE, tgsi_trans_srcx_replicate}, {TGSI_OPCODE_EXP, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, {TGSI_OPCODE_LOG, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, {TGSI_OPCODE_MUL, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MUL, tgsi_op2}, @@ -863,13 +1155,13 @@ static struct r600_shader_tgsi_instruction r600_shader_tgsi_instruction[] = { {TGSI_OPCODE_DP3, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_DOT4, tgsi_dp}, {TGSI_OPCODE_DP4, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_DOT4, tgsi_dp}, {TGSI_OPCODE_DST, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, - {TGSI_OPCODE_MIN, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_MIN, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MIN, tgsi_op2}, {TGSI_OPCODE_MAX, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MAX, tgsi_op2}, {TGSI_OPCODE_SLT, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SETGT, tgsi_slt}, {TGSI_OPCODE_SGE, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, {TGSI_OPCODE_MAD, 1, V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_MULADD, tgsi_op3}, {TGSI_OPCODE_SUB, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_ADD, tgsi_op2}, - {TGSI_OPCODE_LRP, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_LRP, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_lrp}, {TGSI_OPCODE_CND, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, /* gap */ {20, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, @@ -881,13 +1173,13 @@ static struct r600_shader_tgsi_instruction r600_shader_tgsi_instruction[] = { {TGSI_OPCODE_CLAMP, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, {TGSI_OPCODE_FLR, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, {TGSI_OPCODE_ROUND, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, - {TGSI_OPCODE_EX2, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_EX2, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_EXP_IEEE, tgsi_trans_srcx_replicate}, {TGSI_OPCODE_LG2, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, {TGSI_OPCODE_POW, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, {TGSI_OPCODE_XPD, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, /* gap */ {32, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, - {TGSI_OPCODE_ABS, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_ABS, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOV, tgsi_op2}, {TGSI_OPCODE_RCC, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, {TGSI_OPCODE_DPH, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, {TGSI_OPCODE_COS, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, @@ -906,7 +1198,7 @@ static struct r600_shader_tgsi_instruction r600_shader_tgsi_instruction[] = { {TGSI_OPCODE_SLE, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, {TGSI_OPCODE_SNE, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, {TGSI_OPCODE_STR, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, - {TGSI_OPCODE_TEX, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_TEX, 0, 0x10, tgsi_tex}, {TGSI_OPCODE_TXD, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, {TGSI_OPCODE_TXP, 0, 0x10, tgsi_tex}, {TGSI_OPCODE_UP2H, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, @@ -975,7 +1267,7 @@ static struct r600_shader_tgsi_instruction r600_shader_tgsi_instruction[] = { {TGSI_OPCODE_CALLNZ, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, {TGSI_OPCODE_IFC, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, {TGSI_OPCODE_BREAKC, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, - {TGSI_OPCODE_KIL, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, /* conditional kill */ + {TGSI_OPCODE_KIL, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLGT, tgsi_kill}, /* conditional kill */ {TGSI_OPCODE_END, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_end}, /* aka HALT */ /* gap */ {118, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, diff --git a/src/gallium/drivers/r600/r600_shader.h b/src/gallium/drivers/r600/r600_shader.h index 23b6a83b9a9..ee0381e8bdd 100644 --- a/src/gallium/drivers/r600/r600_shader.h +++ b/src/gallium/drivers/r600/r600_shader.h @@ -29,6 +29,7 @@ struct r600_shader_io { unsigned name; unsigned gpr; int sid; + unsigned interpolate; }; struct r600_shader { diff --git a/src/gallium/drivers/r600/r600_state.c b/src/gallium/drivers/r600/r600_state.c index 84a13e4ef7a..deb9bf3395a 100644 --- a/src/gallium/drivers/r600/r600_state.c +++ b/src/gallium/drivers/r600/r600_state.c @@ -24,36 +24,600 @@ * Jerome Glisse */ #include <stdio.h> -#include <util/u_inlines.h> -#include <util/u_format.h> -#include <util/u_memory.h> +#include <errno.h> +#include "util/u_inlines.h" +#include "util/u_format.h" +#include "util/u_memory.h" #include "r600_screen.h" -#include "r600_texture.h" #include "r600_context.h" +#include "r600_resource.h" #include "r600d.h" +#include "r600_state_inlines.h" +static void *r600_create_blend_state(struct pipe_context *ctx, + const struct pipe_blend_state *state) +{ + struct r600_context *rctx = r600_context(ctx); + + return r600_context_state(rctx, pipe_blend_type, state); +} + +static void *r600_create_dsa_state(struct pipe_context *ctx, + const struct pipe_depth_stencil_alpha_state *state) +{ + struct r600_context *rctx = r600_context(ctx); + + return r600_context_state(rctx, pipe_dsa_type, state); +} + +static void *r600_create_rs_state(struct pipe_context *ctx, + const struct pipe_rasterizer_state *state) +{ + struct r600_context *rctx = r600_context(ctx); + + return r600_context_state(rctx, pipe_rasterizer_type, state); +} + +static void *r600_create_sampler_state(struct pipe_context *ctx, + const struct pipe_sampler_state *state) +{ + struct r600_context *rctx = r600_context(ctx); + + return r600_context_state(rctx, pipe_sampler_type, state); +} + +static void r600_sampler_view_destroy(struct pipe_context *ctx, + struct pipe_sampler_view *state) +{ + struct r600_context_state *rstate = (struct r600_context_state *)state; + + r600_context_state_decref(rstate); +} + +static struct pipe_sampler_view *r600_create_sampler_view(struct pipe_context *ctx, + struct pipe_resource *texture, + const struct pipe_sampler_view *state) +{ + struct r600_context *rctx = r600_context(ctx); + struct r600_context_state *rstate; + + rstate = r600_context_state(rctx, pipe_sampler_type, state); + pipe_reference(NULL, &texture->reference); + rstate->state.sampler_view.texture = texture; + rstate->state.sampler_view.reference.count = 1; + rstate->state.sampler_view.context = ctx; + return &rstate->state.sampler_view; +} + +static void *r600_create_shader_state(struct pipe_context *ctx, + const struct pipe_shader_state *state) +{ + struct r600_context *rctx = r600_context(ctx); + + return r600_context_state(rctx, pipe_shader_type, state); +} + +static void *r600_create_vertex_elements(struct pipe_context *ctx, + unsigned count, + const struct pipe_vertex_element *elements) +{ + struct r600_vertex_element *v = CALLOC_STRUCT(r600_vertex_element); + + assert(count < 32); + v->count = count; + memcpy(v->elements, elements, count * sizeof(struct pipe_vertex_element)); + v->refcount = 1; + return v; +} + +static void r600_bind_state(struct pipe_context *ctx, void *state) +{ + struct r600_context *rctx = r600_context(ctx); + struct r600_context_state *rstate = (struct r600_context_state *)state; + + if (state == NULL) + return; + switch (rstate->type) { + case pipe_rasterizer_type: + rctx->rasterizer = r600_context_state_decref(rctx->rasterizer); + rctx->rasterizer = r600_context_state_incref(rstate); + break; + case pipe_poly_stipple_type: + rctx->poly_stipple = r600_context_state_decref(rctx->poly_stipple); + rctx->poly_stipple = r600_context_state_incref(rstate); + break; + case pipe_scissor_type: + rctx->scissor = r600_context_state_decref(rctx->scissor); + rctx->scissor = r600_context_state_incref(rstate); + break; + case pipe_clip_type: + rctx->clip = r600_context_state_decref(rctx->clip); + rctx->clip = r600_context_state_incref(rstate); + break; + case pipe_depth_type: + rctx->depth = r600_context_state_decref(rctx->depth); + rctx->depth = r600_context_state_incref(rstate); + break; + case pipe_stencil_type: + rctx->stencil = r600_context_state_decref(rctx->stencil); + rctx->stencil = r600_context_state_incref(rstate); + break; + case pipe_alpha_type: + rctx->alpha = r600_context_state_decref(rctx->alpha); + rctx->alpha = r600_context_state_incref(rstate); + break; + case pipe_dsa_type: + rctx->dsa = r600_context_state_decref(rctx->dsa); + rctx->dsa = r600_context_state_incref(rstate); + break; + case pipe_blend_type: + rctx->blend = r600_context_state_decref(rctx->blend); + rctx->blend = r600_context_state_incref(rstate); + break; + case pipe_framebuffer_type: + rctx->framebuffer = r600_context_state_decref(rctx->framebuffer); + rctx->framebuffer = r600_context_state_incref(rstate); + break; + case pipe_stencil_ref_type: + rctx->stencil_ref = r600_context_state_decref(rctx->stencil_ref); + rctx->stencil_ref = r600_context_state_incref(rstate); + break; + case pipe_viewport_type: + rctx->viewport = r600_context_state_decref(rctx->viewport); + rctx->viewport = r600_context_state_incref(rstate); + break; + case pipe_shader_type: + case pipe_sampler_type: + case pipe_sampler_view_type: + default: + R600_ERR("invalid type %d\n", rstate->type); + return; + } +} + +static void r600_bind_ps_shader(struct pipe_context *ctx, void *state) +{ + struct r600_context *rctx = r600_context(ctx); + struct r600_context_state *rstate = (struct r600_context_state *)state; + + rctx->ps_shader = r600_context_state_decref(rctx->ps_shader); + rctx->ps_shader = r600_context_state_incref(rstate); +} + +static void r600_bind_vs_shader(struct pipe_context *ctx, void *state) +{ + struct r600_context *rctx = r600_context(ctx); + struct r600_context_state *rstate = (struct r600_context_state *)state; + + rctx->vs_shader = r600_context_state_decref(rctx->vs_shader); + rctx->vs_shader = r600_context_state_incref(rstate); +} + +static void r600_delete_vertex_element(struct pipe_context *ctx, void *state) +{ + struct r600_vertex_element *v = (struct r600_vertex_element*)state; + + if (v == NULL) + return; + if (--v->refcount) + return; + free(v); +} + +static void r600_bind_vertex_elements(struct pipe_context *ctx, void *state) +{ + struct r600_context *rctx = r600_context(ctx); + struct r600_vertex_element *v = (struct r600_vertex_element*)state; + + r600_delete_vertex_element(ctx, rctx->vertex_elements); + rctx->vertex_elements = v; + if (v) { + v->refcount++; + } +} + +static void r600_bind_ps_sampler(struct pipe_context *ctx, + unsigned count, void **states) +{ + struct r600_context *rctx = r600_context(ctx); + struct r600_context_state *rstate; + unsigned i; + + for (i = 0; i < rctx->ps_nsampler; i++) { + rctx->ps_sampler[i] = r600_context_state_decref(rctx->ps_sampler[i]); + } + for (i = 0; i < count; i++) { + rstate = (struct r600_context_state *)states[i]; + rctx->ps_sampler[i] = r600_context_state_incref(rstate); + } + rctx->ps_nsampler = count; +} + +static void r600_bind_vs_sampler(struct pipe_context *ctx, + unsigned count, void **states) +{ + struct r600_context *rctx = r600_context(ctx); + struct r600_context_state *rstate; + unsigned i; + + for (i = 0; i < rctx->vs_nsampler; i++) { + rctx->vs_sampler[i] = r600_context_state_decref(rctx->vs_sampler[i]); + } + for (i = 0; i < count; i++) { + rstate = (struct r600_context_state *)states[i]; + rctx->vs_sampler[i] = r600_context_state_incref(rstate); + } + rctx->vs_nsampler = count; +} static void r600_delete_state(struct pipe_context *ctx, void *state) { - struct radeon_state *rstate = state; + struct r600_context_state *rstate = (struct r600_context_state *)state; - radeon_state_decref(rstate); + r600_context_state_decref(rstate); } -static void *r600_create_blend_state(struct pipe_context *ctx, - const struct pipe_blend_state *state) +static void r600_set_blend_color(struct pipe_context *ctx, + const struct pipe_blend_color *color) +{ + struct r600_context *rctx = r600_context(ctx); + + rctx->blend_color = *color; +} + +static void r600_set_clip_state(struct pipe_context *ctx, + const struct pipe_clip_state *state) +{ +} + +static void r600_set_constant_buffer(struct pipe_context *ctx, + uint shader, uint index, + struct pipe_resource *buffer) { struct r600_screen *rscreen = r600_screen(ctx->screen); + struct r600_context *rctx = r600_context(ctx); + unsigned nconstant = 0, i, type, id; struct radeon_state *rstate; + struct pipe_transfer *transfer; + u32 *ptr; + + switch (shader) { + case PIPE_SHADER_VERTEX: + id = R600_VS_CONSTANT; + type = R600_VS_CONSTANT_TYPE; + break; + case PIPE_SHADER_FRAGMENT: + id = R600_PS_CONSTANT; + type = R600_PS_CONSTANT_TYPE; + break; + default: + R600_ERR("unsupported %d\n", shader); + return; + } + if (buffer && buffer->width0 > 0) { + nconstant = buffer->width0 / 16; + ptr = pipe_buffer_map(ctx, buffer, PIPE_TRANSFER_READ, &transfer); + if (ptr == NULL) + return; + for (i = 0; i < nconstant; i++) { + rstate = radeon_state(rscreen->rw, type, id + i); + if (rstate == NULL) + return; + rstate->states[R600_PS_CONSTANT__SQ_ALU_CONSTANT0_0] = ptr[i * 4 + 0]; + rstate->states[R600_PS_CONSTANT__SQ_ALU_CONSTANT1_0] = ptr[i * 4 + 1]; + rstate->states[R600_PS_CONSTANT__SQ_ALU_CONSTANT2_0] = ptr[i * 4 + 2]; + rstate->states[R600_PS_CONSTANT__SQ_ALU_CONSTANT3_0] = ptr[i * 4 + 3]; + if (radeon_state_pm4(rstate)) + return; + if (radeon_draw_set_new(rctx->draw, rstate)) + return; + } + pipe_buffer_unmap(ctx, buffer, transfer); + } +} + +static void r600_set_ps_sampler_view(struct pipe_context *ctx, + unsigned count, + struct pipe_sampler_view **views) +{ + struct r600_context *rctx = r600_context(ctx); + struct r600_context_state *rstate; + unsigned i; + + for (i = 0; i < rctx->ps_nsampler_view; i++) { + rctx->ps_sampler_view[i] = r600_context_state_decref(rctx->ps_sampler_view[i]); + } + for (i = 0; i < count; i++) { + rstate = (struct r600_context_state *)views[i]; + rctx->ps_sampler_view[i] = r600_context_state_incref(rstate); + } + rctx->ps_nsampler_view = count; +} + +static void r600_set_vs_sampler_view(struct pipe_context *ctx, + unsigned count, + struct pipe_sampler_view **views) +{ + struct r600_context *rctx = r600_context(ctx); + struct r600_context_state *rstate; + unsigned i; + + for (i = 0; i < rctx->vs_nsampler_view; i++) { + rctx->vs_sampler_view[i] = r600_context_state_decref(rctx->vs_sampler_view[i]); + } + for (i = 0; i < count; i++) { + rstate = (struct r600_context_state *)views[i]; + rctx->vs_sampler_view[i] = r600_context_state_incref(rstate); + } + rctx->vs_nsampler_view = count; +} + +static void r600_set_framebuffer_state(struct pipe_context *ctx, + const struct pipe_framebuffer_state *state) +{ + struct r600_context *rctx = r600_context(ctx); + struct r600_context_state *rstate; + + rstate = r600_context_state(rctx, pipe_framebuffer_type, state); + r600_bind_state(ctx, rstate); +} + +static void r600_set_polygon_stipple(struct pipe_context *ctx, + const struct pipe_poly_stipple *state) +{ +} + +static void r600_set_sample_mask(struct pipe_context *pipe, unsigned sample_mask) +{ +} + +static void r600_set_scissor_state(struct pipe_context *ctx, + const struct pipe_scissor_state *state) +{ + struct r600_context *rctx = r600_context(ctx); + struct r600_context_state *rstate; + + rstate = r600_context_state(rctx, pipe_scissor_type, state); + r600_bind_state(ctx, rstate); +} + +static void r600_set_stencil_ref(struct pipe_context *ctx, + const struct pipe_stencil_ref *state) +{ + struct r600_context *rctx = r600_context(ctx); + struct r600_context_state *rstate; + + rstate = r600_context_state(rctx, pipe_stencil_ref_type, state); + r600_bind_state(ctx, rstate); +} + +static void r600_set_vertex_buffers(struct pipe_context *ctx, + unsigned count, + const struct pipe_vertex_buffer *buffers) +{ + struct r600_context *rctx = r600_context(ctx); + unsigned i; + + for (i = 0; i < rctx->nvertex_buffer; i++) { + pipe_resource_reference(&rctx->vertex_buffer[i].buffer, NULL); + } + memcpy(rctx->vertex_buffer, buffers, sizeof(struct pipe_vertex_buffer) * count); + for (i = 0; i < count; i++) { + rctx->vertex_buffer[i].buffer = NULL; + pipe_resource_reference(&rctx->vertex_buffer[i].buffer, buffers[i].buffer); + } + rctx->nvertex_buffer = count; +} + +static void r600_set_index_buffer(struct pipe_context *ctx, + const struct pipe_index_buffer *ib) +{ + struct r600_context *rctx = r600_context(ctx); + + if (ib) { + pipe_resource_reference(&rctx->index_buffer.buffer, ib->buffer); + memcpy(&rctx->index_buffer, ib, sizeof(rctx->index_buffer)); + } else { + pipe_resource_reference(&rctx->index_buffer.buffer, NULL); + memset(&rctx->index_buffer, 0, sizeof(rctx->index_buffer)); + } + + /* TODO make this more like a state */ +} + +static void r600_set_viewport_state(struct pipe_context *ctx, + const struct pipe_viewport_state *state) +{ + struct r600_context *rctx = r600_context(ctx); + struct r600_context_state *rstate; + + rstate = r600_context_state(rctx, pipe_viewport_type, state); + r600_bind_state(ctx, rstate); +} + +void r600_init_state_functions(struct r600_context *rctx) +{ + rctx->context.create_blend_state = r600_create_blend_state; + rctx->context.create_depth_stencil_alpha_state = r600_create_dsa_state; + rctx->context.create_fs_state = r600_create_shader_state; + rctx->context.create_rasterizer_state = r600_create_rs_state; + rctx->context.create_sampler_state = r600_create_sampler_state; + rctx->context.create_sampler_view = r600_create_sampler_view; + rctx->context.create_vertex_elements_state = r600_create_vertex_elements; + rctx->context.create_vs_state = r600_create_shader_state; + rctx->context.bind_blend_state = r600_bind_state; + rctx->context.bind_depth_stencil_alpha_state = r600_bind_state; + rctx->context.bind_fragment_sampler_states = r600_bind_ps_sampler; + rctx->context.bind_fs_state = r600_bind_ps_shader; + rctx->context.bind_rasterizer_state = r600_bind_state; + rctx->context.bind_vertex_elements_state = r600_bind_vertex_elements; + rctx->context.bind_vertex_sampler_states = r600_bind_vs_sampler; + rctx->context.bind_vs_state = r600_bind_vs_shader; + rctx->context.delete_blend_state = r600_delete_state; + rctx->context.delete_depth_stencil_alpha_state = r600_delete_state; + rctx->context.delete_fs_state = r600_delete_state; + rctx->context.delete_rasterizer_state = r600_delete_state; + rctx->context.delete_sampler_state = r600_delete_state; + rctx->context.delete_vertex_elements_state = r600_delete_vertex_element; + rctx->context.delete_vs_state = r600_delete_state; + rctx->context.set_blend_color = r600_set_blend_color; + rctx->context.set_clip_state = r600_set_clip_state; + rctx->context.set_constant_buffer = r600_set_constant_buffer; + rctx->context.set_fragment_sampler_views = r600_set_ps_sampler_view; + rctx->context.set_framebuffer_state = r600_set_framebuffer_state; + rctx->context.set_polygon_stipple = r600_set_polygon_stipple; + rctx->context.set_sample_mask = r600_set_sample_mask; + rctx->context.set_scissor_state = r600_set_scissor_state; + rctx->context.set_stencil_ref = r600_set_stencil_ref; + rctx->context.set_vertex_buffers = r600_set_vertex_buffers; + rctx->context.set_index_buffer = r600_set_index_buffer; + rctx->context.set_vertex_sampler_views = r600_set_vs_sampler_view; + rctx->context.set_viewport_state = r600_set_viewport_state; + rctx->context.sampler_view_destroy = r600_sampler_view_destroy; +} + +struct r600_context_state *r600_context_state_incref(struct r600_context_state *rstate) +{ + if (rstate == NULL) + return NULL; + rstate->refcount++; + return rstate; +} + +struct r600_context_state *r600_context_state_decref(struct r600_context_state *rstate) +{ + unsigned i; + + if (rstate == NULL) + return NULL; + if (--rstate->refcount) + return NULL; + switch (rstate->type) { + case pipe_sampler_view_type: + pipe_resource_reference(&rstate->state.sampler_view.texture, NULL); + break; + case pipe_framebuffer_type: + for (i = 0; i < rstate->state.framebuffer.nr_cbufs; i++) { + pipe_surface_reference(&rstate->state.framebuffer.cbufs[i], NULL); + } + pipe_surface_reference(&rstate->state.framebuffer.zsbuf, NULL); + break; + case pipe_viewport_type: + case pipe_depth_type: + case pipe_rasterizer_type: + case pipe_poly_stipple_type: + case pipe_scissor_type: + case pipe_clip_type: + case pipe_stencil_type: + case pipe_alpha_type: + case pipe_dsa_type: + case pipe_blend_type: + case pipe_stencil_ref_type: + case pipe_shader_type: + case pipe_sampler_type: + break; + default: + R600_ERR("invalid type %d\n", rstate->type); + return NULL; + } + radeon_state_decref(rstate->rstate); + FREE(rstate); + return NULL; +} + +struct r600_context_state *r600_context_state(struct r600_context *rctx, unsigned type, const void *state) +{ + struct r600_context_state *rstate = CALLOC_STRUCT(r600_context_state); + const union pipe_states *states = state; + unsigned i; + int r; + + if (rstate == NULL) + return NULL; + rstate->type = type; + rstate->refcount = 1; + + switch (rstate->type) { + case pipe_sampler_view_type: + rstate->state.sampler_view = (*states).sampler_view; + rstate->state.sampler_view.texture = NULL; + break; + case pipe_framebuffer_type: + rstate->state.framebuffer = (*states).framebuffer; + for (i = 0; i < rstate->state.framebuffer.nr_cbufs; i++) { + pipe_surface_reference(&rstate->state.framebuffer.cbufs[i], + (*states).framebuffer.cbufs[i]); + } + pipe_surface_reference(&rstate->state.framebuffer.zsbuf, + (*states).framebuffer.zsbuf); + break; + case pipe_viewport_type: + rstate->state.viewport = (*states).viewport; + break; + case pipe_depth_type: + rstate->state.depth = (*states).depth; + break; + case pipe_rasterizer_type: + rstate->state.rasterizer = (*states).rasterizer; + break; + case pipe_poly_stipple_type: + rstate->state.poly_stipple = (*states).poly_stipple; + break; + case pipe_scissor_type: + rstate->state.scissor = (*states).scissor; + break; + case pipe_clip_type: + rstate->state.clip = (*states).clip; + break; + case pipe_stencil_type: + rstate->state.stencil = (*states).stencil; + break; + case pipe_alpha_type: + rstate->state.alpha = (*states).alpha; + break; + case pipe_dsa_type: + rstate->state.dsa = (*states).dsa; + break; + case pipe_blend_type: + rstate->state.blend = (*states).blend; + break; + case pipe_stencil_ref_type: + rstate->state.stencil_ref = (*states).stencil_ref; + break; + case pipe_shader_type: + rstate->state.shader = (*states).shader; + r = r600_pipe_shader_create(&rctx->context, rstate, rstate->state.shader.tokens); + if (r) { + r600_context_state_decref(rstate); + return NULL; + } + break; + case pipe_sampler_type: + rstate->state.sampler = (*states).sampler; + break; + default: + R600_ERR("invalid type %d\n", rstate->type); + FREE(rstate); + return NULL; + } + return rstate; +} + +static struct radeon_state *r600_blend(struct r600_context *rctx) +{ + struct r600_screen *rscreen = rctx->screen; + struct radeon_state *rstate; + const struct pipe_blend_state *state = &rctx->blend->state.blend; + int i; rstate = radeon_state(rscreen->rw, R600_BLEND_TYPE, R600_BLEND); if (rstate == NULL) return NULL; - rstate->states[R600_BLEND__CB_BLEND_RED] = 0x00000000; - rstate->states[R600_BLEND__CB_BLEND_GREEN] = 0x00000000; - rstate->states[R600_BLEND__CB_BLEND_BLUE] = 0x00000000; - rstate->states[R600_BLEND__CB_BLEND_ALPHA] = 0x00000000; - rstate->states[R600_BLEND__CB_BLEND0_CONTROL] = 0x00010001; + rstate->states[R600_BLEND__CB_BLEND_RED] = fui(rctx->blend_color.color[0]); + rstate->states[R600_BLEND__CB_BLEND_GREEN] = fui(rctx->blend_color.color[1]); + rstate->states[R600_BLEND__CB_BLEND_BLUE] = fui(rctx->blend_color.color[2]); + rstate->states[R600_BLEND__CB_BLEND_ALPHA] = fui(rctx->blend_color.color[3]); + rstate->states[R600_BLEND__CB_BLEND0_CONTROL] = 0x00000000; rstate->states[R600_BLEND__CB_BLEND1_CONTROL] = 0x00000000; rstate->states[R600_BLEND__CB_BLEND2_CONTROL] = 0x00000000; rstate->states[R600_BLEND__CB_BLEND3_CONTROL] = 0x00000000; @@ -62,6 +626,36 @@ static void *r600_create_blend_state(struct pipe_context *ctx, rstate->states[R600_BLEND__CB_BLEND6_CONTROL] = 0x00000000; rstate->states[R600_BLEND__CB_BLEND7_CONTROL] = 0x00000000; rstate->states[R600_BLEND__CB_BLEND_CONTROL] = 0x00000000; + + for (i = 0; i < 8; i++) { + unsigned eqRGB = state->rt[i].rgb_func; + unsigned srcRGB = state->rt[i].rgb_src_factor; + unsigned dstRGB = state->rt[i].rgb_dst_factor; + + unsigned eqA = state->rt[i].alpha_func; + unsigned srcA = state->rt[i].alpha_src_factor; + unsigned dstA = state->rt[i].alpha_dst_factor; + uint32_t bc = 0; + + if (!state->rt[i].blend_enable) + continue; + + bc |= S_028804_COLOR_COMB_FCN(r600_translate_blend_function(eqRGB)); + bc |= S_028804_COLOR_SRCBLEND(r600_translate_blend_factor(srcRGB)); + bc |= S_028804_COLOR_DESTBLEND(r600_translate_blend_factor(dstRGB)); + + if (srcA != srcRGB || dstA != dstRGB || eqA != eqRGB) { + bc |= S_028804_SEPARATE_ALPHA_BLEND(1); + bc |= S_028804_ALPHA_COMB_FCN(r600_translate_blend_function(eqA)); + bc |= S_028804_ALPHA_SRCBLEND(r600_translate_blend_factor(srcA)); + bc |= S_028804_ALPHA_DESTBLEND(r600_translate_blend_factor(dstA)); + } + + rstate->states[R600_BLEND__CB_BLEND0_CONTROL + i] = bc; + if (i == 0) + rstate->states[R600_BLEND__CB_BLEND_CONTROL] = bc; + } + if (radeon_state_pm4(rstate)) { radeon_state_decref(rstate); return NULL; @@ -69,38 +663,25 @@ static void *r600_create_blend_state(struct pipe_context *ctx, return rstate; } -static void r600_bind_blend_state(struct pipe_context *ctx, void *state) -{ - struct r600_context *rctx = r600_context(ctx); - radeon_draw_set(rctx->draw, state); -} - -static void r600_set_blend_color(struct pipe_context *ctx, - const struct pipe_blend_color *color) +static struct radeon_state *r600_cb(struct r600_context *rctx, int cb) { -} - -static void r600_set_clip_state(struct pipe_context *ctx, - const struct pipe_clip_state *state) -{ -} - -static void r600_set_framebuffer_state(struct pipe_context *ctx, - const struct pipe_framebuffer_state *state) -{ - struct r600_screen *rscreen = r600_screen(ctx->screen); - struct r600_context *rctx = r600_context(ctx); - struct r600_texture *rtex; - struct r600_buffer *rbuffer; + struct r600_screen *rscreen = rctx->screen; + struct r600_resource_texture *rtex; + struct r600_resource *rbuffer; struct radeon_state *rstate; - unsigned level = state->cbufs[0]->level; + const struct pipe_framebuffer_state *state = &rctx->framebuffer->state.framebuffer; + unsigned level = state->cbufs[cb]->level; unsigned pitch, slice; + unsigned color_info; + unsigned format, swap, ntype; + const struct util_format_description *desc; + int id = R600_CB0 + cb; - rstate = radeon_state(rscreen->rw, R600_CB0_TYPE, R600_CB0); + rstate = radeon_state(rscreen->rw, R600_CB0_TYPE, id); if (rstate == NULL) - return; - rtex = (struct r600_texture*)state->cbufs[0]->texture; - rbuffer = (struct r600_buffer*)rtex->buffer; + return NULL; + rtex = (struct r600_resource_texture*)state->cbufs[cb]->texture; + rbuffer = &rtex->resource; rstate->bo[0] = radeon_bo_incref(rscreen->rw, rbuffer->bo); rstate->bo[1] = radeon_bo_incref(rscreen->rw, rbuffer->bo); rstate->bo[2] = radeon_bo_incref(rscreen->rw, rbuffer->bo); @@ -108,10 +689,25 @@ static void r600_set_framebuffer_state(struct pipe_context *ctx, rstate->placement[2] = RADEON_GEM_DOMAIN_GTT; rstate->placement[4] = RADEON_GEM_DOMAIN_GTT; rstate->nbo = 3; - pitch = rtex->pitch[level] / 8 - 1; - slice = rtex->pitch[level] * state->cbufs[0]->height / 64 - 1; + pitch = (rtex->pitch[level] / rtex->bpt) / 8 - 1; + slice = (rtex->pitch[level] / rtex->bpt) * state->cbufs[cb]->height / 64 - 1; + + ntype = 0; + desc = util_format_description(rtex->resource.base.b.format); + if (desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB) + ntype = V_0280A0_NUMBER_SRGB; + + format = r600_translate_colorformat(rtex->resource.base.b.format); + swap = r600_translate_colorswap(rtex->resource.base.b.format); + + color_info = S_0280A0_FORMAT(format) | + S_0280A0_COMP_SWAP(swap) | + S_0280A0_BLEND_CLAMP(1) | + S_0280A0_SOURCE_FORMAT(1) | + S_0280A0_NUMBER_TYPE(ntype); + rstate->states[R600_CB0__CB_COLOR0_BASE] = 0x00000000; - rstate->states[R600_CB0__CB_COLOR0_INFO] = 0x08110068; + rstate->states[R600_CB0__CB_COLOR0_INFO] = color_info; rstate->states[R600_CB0__CB_COLOR0_SIZE] = S_028060_PITCH_TILE_MAX(pitch) | S_028060_SLICE_TILE_MAX(slice); rstate->states[R600_CB0__CB_COLOR0_VIEW] = 0x00000000; @@ -120,71 +716,85 @@ static void r600_set_framebuffer_state(struct pipe_context *ctx, rstate->states[R600_CB0__CB_COLOR0_MASK] = 0x00000000; if (radeon_state_pm4(rstate)) { radeon_state_decref(rstate); - return; + return NULL; } - radeon_draw_set_new(rctx->draw, rstate); - rctx->db = radeon_state_decref(rctx->db); - if(state->zsbuf) { - rtex = (struct r600_texture*)state->zsbuf->texture; - rbuffer = (struct r600_buffer*)rtex->buffer; - rctx->db = radeon_state(rscreen->rw, R600_DB_TYPE, R600_DB); - if(rctx->db == NULL) - return; - rctx->db->bo[0] = radeon_bo_incref(rscreen->rw, rbuffer->bo); - rctx->db->nbo = 1; - rctx->db->placement[0] = RADEON_GEM_DOMAIN_VRAM; - level = state->zsbuf->level; - pitch = rtex->pitch[level] / 8 - 1; - slice = rtex->pitch[level] * state->zsbuf->height / 64 - 1; - - rctx->db->states[R600_DB__DB_DEPTH_BASE] = 0x00000000; - rctx->db->states[R600_DB__DB_DEPTH_INFO] = 0x00010006; - rctx->db->states[R600_DB__DB_DEPTH_VIEW] = 0x00000000; - rctx->db->states[R600_DB__DB_PREFETCH_LIMIT] = (state->zsbuf->height / 8) -1; - rctx->db->states[R600_DB__DB_DEPTH_SIZE] = S_028000_PITCH_TILE_MAX(pitch) | - S_028000_SLICE_TILE_MAX(slice); - } else - rctx->db = NULL; - rctx->fb_state = *state; -} - -static void *r600_create_fs_state(struct pipe_context *ctx, - const struct pipe_shader_state *shader) -{ - return r600_pipe_shader_create(ctx, shader->tokens); -} - -static void r600_bind_fs_state(struct pipe_context *ctx, void *state) -{ - struct r600_context *rctx = r600_context(ctx); - - rctx->ps_shader = state; + return rstate; } -static void *r600_create_vs_state(struct pipe_context *ctx, - const struct pipe_shader_state *shader) +static struct radeon_state *r600_db(struct r600_context *rctx) { - return r600_pipe_shader_create(ctx, shader->tokens); -} + struct r600_screen *rscreen = rctx->screen; + struct r600_resource_texture *rtex; + struct r600_resource *rbuffer; + struct radeon_state *rstate; + const struct pipe_framebuffer_state *state = &rctx->framebuffer->state.framebuffer; + unsigned level = state->cbufs[0]->level; + unsigned pitch, slice, format; -static void r600_bind_vs_state(struct pipe_context *ctx, void *state) -{ - struct r600_context *rctx = r600_context(ctx); + if (state->zsbuf == NULL) + return NULL; - rctx->vs_shader = state; -} + rstate = radeon_state(rscreen->rw, R600_DB_TYPE, R600_DB); + if (rstate == NULL) + return NULL; -static void r600_set_polygon_stipple(struct pipe_context *ctx, - const struct pipe_poly_stipple *state) -{ + rtex = (struct r600_resource_texture*)state->zsbuf->texture; + rbuffer = &rtex->resource; + rstate->bo[0] = radeon_bo_incref(rscreen->rw, rbuffer->bo); + rstate->nbo = 1; + rstate->placement[0] = RADEON_GEM_DOMAIN_VRAM; + level = state->zsbuf->level; + pitch = (rtex->pitch[level] / rtex->bpt) / 8 - 1; + slice = (rtex->pitch[level] / rtex->bpt) * state->zsbuf->height / 64 - 1; + format = r600_translate_dbformat(state->zsbuf->texture->format); + rstate->states[R600_DB__DB_DEPTH_BASE] = 0x00000000; + rstate->states[R600_DB__DB_DEPTH_INFO] = 0x00010000 | + S_028010_FORMAT(format); + rstate->states[R600_DB__DB_DEPTH_VIEW] = 0x00000000; + rstate->states[R600_DB__DB_PREFETCH_LIMIT] = (state->zsbuf->height / 8) -1; + rstate->states[R600_DB__DB_DEPTH_SIZE] = S_028000_PITCH_TILE_MAX(pitch) | + S_028000_SLICE_TILE_MAX(slice); + if (radeon_state_pm4(rstate)) { + radeon_state_decref(rstate); + return NULL; + } + return rstate; } -static void *r600_create_rs_state(struct pipe_context *ctx, - const struct pipe_rasterizer_state *state) +static struct radeon_state *r600_rasterizer(struct r600_context *rctx) { - struct r600_screen *rscreen = r600_screen(ctx->screen); - struct r600_context *rctx = r600_context(ctx); + const struct pipe_rasterizer_state *state = &rctx->rasterizer->state.rasterizer; + const struct pipe_framebuffer_state *fb = &rctx->framebuffer->state.framebuffer; + struct r600_screen *rscreen = rctx->screen; struct radeon_state *rstate; + float offset_units = 0, offset_scale = 0; + char depth = 0; + unsigned offset_db_fmt_cntl = 0; + + if (fb->zsbuf) { + offset_units = state->offset_units; + offset_scale = state->offset_scale * 12.0f; + switch (fb->zsbuf->texture->format) { + case PIPE_FORMAT_Z24X8_UNORM: + case PIPE_FORMAT_Z24_UNORM_S8_USCALED: + depth = -24; + offset_units *= 2.0f; + break; + case PIPE_FORMAT_Z32_FLOAT: + depth = -23; + offset_units *= 1.0f; + offset_db_fmt_cntl |= S_028DF8_POLY_OFFSET_DB_IS_FLOAT_FMT(1); + break; + case PIPE_FORMAT_Z16_UNORM: + depth = -16; + offset_units *= 4.0f; + break; + default: + R600_ERR("unsupported %d\n", fb->zsbuf->texture->format); + return NULL; + } + } + offset_db_fmt_cntl |= S_028DF8_POLY_OFFSET_NEG_NUM_DB_BITS(depth); rctx->flat_shade = state->flatshade; rstate = radeon_state(rscreen->rw, R600_RASTERIZER_TYPE, R600_RASTERIZER); @@ -192,7 +802,13 @@ static void *r600_create_rs_state(struct pipe_context *ctx, return NULL; rstate->states[R600_RASTERIZER__SPI_INTERP_CONTROL_0] = 0x00000001; rstate->states[R600_RASTERIZER__PA_CL_CLIP_CNTL] = 0x00000000; - rstate->states[R600_RASTERIZER__PA_SU_SC_MODE_CNTL] = 0x00080000; + rstate->states[R600_RASTERIZER__PA_SU_SC_MODE_CNTL] = 0x00080000 | + S_028814_CULL_FRONT((state->cull_face & PIPE_FACE_FRONT) ? 1 : 0) | + S_028814_CULL_BACK((state->cull_face & PIPE_FACE_BACK) ? 1 : 0) | + S_028814_FACE(!state->front_ccw) | + S_028814_POLY_OFFSET_FRONT_ENABLE(state->offset_tri) | + S_028814_POLY_OFFSET_BACK_ENABLE(state->offset_tri) | + S_028814_POLY_OFFSET_PARA_ENABLE(state->offset_tri); rstate->states[R600_RASTERIZER__PA_CL_VS_OUT_CNTL] = 0x00000000; rstate->states[R600_RASTERIZER__PA_CL_NANINF_CNTL] = 0x00000000; rstate->states[R600_RASTERIZER__PA_SU_POINT_SIZE] = 0x00080008; @@ -205,12 +821,12 @@ static void *r600_create_rs_state(struct pipe_context *ctx, rstate->states[R600_RASTERIZER__PA_CL_GB_VERT_DISC_ADJ] = 0x3F800000; rstate->states[R600_RASTERIZER__PA_CL_GB_HORZ_CLIP_ADJ] = 0x3F800000; rstate->states[R600_RASTERIZER__PA_CL_GB_HORZ_DISC_ADJ] = 0x3F800000; - rstate->states[R600_RASTERIZER__PA_SU_POLY_OFFSET_DB_FMT_CNTL] = 0x00000000; + rstate->states[R600_RASTERIZER__PA_SU_POLY_OFFSET_DB_FMT_CNTL] = offset_db_fmt_cntl; rstate->states[R600_RASTERIZER__PA_SU_POLY_OFFSET_CLAMP] = 0x00000000; - rstate->states[R600_RASTERIZER__PA_SU_POLY_OFFSET_FRONT_SCALE] = 0x00000000; - rstate->states[R600_RASTERIZER__PA_SU_POLY_OFFSET_FRONT_OFFSET] = 0x00000000; - rstate->states[R600_RASTERIZER__PA_SU_POLY_OFFSET_BACK_SCALE] = 0x00000000; - rstate->states[R600_RASTERIZER__PA_SU_POLY_OFFSET_BACK_OFFSET] = 0x00000000; + rstate->states[R600_RASTERIZER__PA_SU_POLY_OFFSET_FRONT_SCALE] = fui(offset_scale); + rstate->states[R600_RASTERIZER__PA_SU_POLY_OFFSET_FRONT_OFFSET] = fui(offset_units); + rstate->states[R600_RASTERIZER__PA_SU_POLY_OFFSET_BACK_SCALE] = fui(offset_scale); + rstate->states[R600_RASTERIZER__PA_SU_POLY_OFFSET_BACK_OFFSET] = fui(offset_units); if (radeon_state_pm4(rstate)) { radeon_state_decref(rstate); return NULL; @@ -218,56 +834,10 @@ static void *r600_create_rs_state(struct pipe_context *ctx, return rstate; } -static void r600_bind_rs_state(struct pipe_context *ctx, void *state) -{ - struct r600_context *rctx = r600_context(ctx); - radeon_draw_set(rctx->draw, state); -} - -static void *r600_create_sampler_state(struct pipe_context *ctx, - const struct pipe_sampler_state *state) -{ - return NULL; -} - -static void r600_bind_sampler_states(struct pipe_context *ctx, - unsigned count, void **states) -{ -} - -static struct pipe_sampler_view *r600_create_sampler_view(struct pipe_context *ctx, - struct pipe_resource *texture, - const struct pipe_sampler_view *templ) -{ - struct pipe_sampler_view *view = CALLOC_STRUCT(pipe_sampler_view); - - *view = *templ; - return view; -} - -static void r600_sampler_view_destroy(struct pipe_context *ctx, - struct pipe_sampler_view *view) +static struct radeon_state *r600_scissor(struct r600_context *rctx) { - FREE(view); -} - -static void r600_set_fragment_sampler_views(struct pipe_context *ctx, - unsigned count, - struct pipe_sampler_view **views) -{ -} - -static void r600_set_vertex_sampler_views(struct pipe_context *ctx, - unsigned count, - struct pipe_sampler_view **views) -{ -} - -static void r600_set_scissor_state(struct pipe_context *ctx, - const struct pipe_scissor_state *state) -{ - struct r600_screen *rscreen = r600_screen(ctx->screen); - struct r600_context *rctx = r600_context(ctx); + const struct pipe_scissor_state *state = &rctx->scissor->state.scissor; + struct r600_screen *rscreen = rctx->screen; struct radeon_state *rstate; u32 tl, br; @@ -275,7 +845,7 @@ static void r600_set_scissor_state(struct pipe_context *ctx, br = S_028244_BR_X(state->maxx) | S_028244_BR_Y(state->maxy); rstate = radeon_state(rscreen->rw, R600_SCISSOR_TYPE, R600_SCISSOR); if (rstate == NULL) - return; + return NULL; rstate->states[R600_SCISSOR__PA_SC_SCREEN_SCISSOR_TL] = tl; rstate->states[R600_SCISSOR__PA_SC_SCREEN_SCISSOR_BR] = br; rstate->states[R600_SCISSOR__PA_SC_WINDOW_OFFSET] = 0x00000000; @@ -297,97 +867,104 @@ static void r600_set_scissor_state(struct pipe_context *ctx, rstate->states[R600_SCISSOR__PA_SC_VPORT_SCISSOR_0_BR] = br; if (radeon_state_pm4(rstate)) { radeon_state_decref(rstate); - return; + return NULL; } - radeon_draw_set_new(rctx->draw, rstate); + return rstate; } -static void r600_set_viewport_state(struct pipe_context *ctx, - const struct pipe_viewport_state *state) +static struct radeon_state *r600_viewport(struct r600_context *rctx) { - struct r600_screen *rscreen = r600_screen(ctx->screen); - struct r600_context *rctx = r600_context(ctx); + const struct pipe_viewport_state *state = &rctx->viewport->state.viewport; + struct r600_screen *rscreen = rctx->screen; struct radeon_state *rstate; rstate = radeon_state(rscreen->rw, R600_VIEWPORT_TYPE, R600_VIEWPORT); if (rstate == NULL) - return; + return NULL; rstate->states[R600_VIEWPORT__PA_SC_VPORT_ZMIN_0] = 0x00000000; rstate->states[R600_VIEWPORT__PA_SC_VPORT_ZMAX_0] = 0x3F800000; - rstate->states[R600_VIEWPORT__PA_CL_VPORT_XSCALE_0] = r600_float_to_u32(state->scale[0]); - rstate->states[R600_VIEWPORT__PA_CL_VPORT_YSCALE_0] = r600_float_to_u32(state->scale[1]); - rstate->states[R600_VIEWPORT__PA_CL_VPORT_ZSCALE_0] = r600_float_to_u32(state->scale[2]); - rstate->states[R600_VIEWPORT__PA_CL_VPORT_XOFFSET_0] = r600_float_to_u32(state->translate[0]); - rstate->states[R600_VIEWPORT__PA_CL_VPORT_YOFFSET_0] = r600_float_to_u32(state->translate[1]); - rstate->states[R600_VIEWPORT__PA_CL_VPORT_ZOFFSET_0] = r600_float_to_u32(state->translate[2]); + rstate->states[R600_VIEWPORT__PA_CL_VPORT_XSCALE_0] = fui(state->scale[0]); + rstate->states[R600_VIEWPORT__PA_CL_VPORT_YSCALE_0] = fui(state->scale[1]); + rstate->states[R600_VIEWPORT__PA_CL_VPORT_ZSCALE_0] = fui(state->scale[2]); + rstate->states[R600_VIEWPORT__PA_CL_VPORT_XOFFSET_0] = fui(state->translate[0]); + rstate->states[R600_VIEWPORT__PA_CL_VPORT_YOFFSET_0] = fui(state->translate[1]); + rstate->states[R600_VIEWPORT__PA_CL_VPORT_ZOFFSET_0] = fui(state->translate[2]); rstate->states[R600_VIEWPORT__PA_CL_VTE_CNTL] = 0x0000043F; if (radeon_state_pm4(rstate)) { radeon_state_decref(rstate); - return; + return NULL; } - radeon_draw_set_new(rctx->draw, rstate); - rctx->viewport = *state; -} - -static void r600_set_vertex_buffers(struct pipe_context *ctx, - unsigned count, - const struct pipe_vertex_buffer *buffers) -{ - struct r600_context *rctx = r600_context(ctx); - - memcpy(rctx->vertex_buffer, buffers, sizeof(struct pipe_vertex_buffer) * count); - rctx->nvertex_buffer = count; + return rstate; } - -static void *r600_create_vertex_elements_state(struct pipe_context *ctx, - unsigned count, - const struct pipe_vertex_element *elements) +static struct radeon_state *r600_dsa(struct r600_context *rctx) { - struct r600_vertex_elements_state *v = CALLOC_STRUCT(r600_vertex_elements_state); + const struct pipe_depth_stencil_alpha_state *state = &rctx->dsa->state.dsa; + const struct pipe_stencil_ref *stencil_ref = &rctx->stencil_ref->state.stencil_ref; + struct r600_screen *rscreen = rctx->screen; + unsigned db_depth_control, alpha_test_control, alpha_ref, db_shader_control; + unsigned stencil_ref_mask, stencil_ref_mask_bf; + struct r600_shader *rshader = &rctx->ps_shader->shader; + struct radeon_state *rstate; + int i; - assert(count < 32); - v->count = count; - memcpy(v->elements, elements, count * sizeof(struct pipe_vertex_element)); - return v; -} + rstate = radeon_state(rscreen->rw, R600_DSA_TYPE, R600_DSA); + if (rstate == NULL) + return NULL; -static void r600_bind_vertex_elements_state(struct pipe_context *ctx, void *state) -{ - struct r600_context *rctx = r600_context(ctx); - struct r600_vertex_elements_state *v = (struct r600_vertex_elements_state*)state; + db_shader_control = 0x210; + for (i = 0; i < rshader->noutput; i++) { + if (rshader->output[i].name == TGSI_SEMANTIC_POSITION) + db_shader_control |= 1; + } + stencil_ref_mask = 0; + stencil_ref_mask_bf = 0; + db_depth_control = S_028800_Z_ENABLE(state->depth.enabled) | + S_028800_Z_WRITE_ENABLE(state->depth.writemask) | + S_028800_ZFUNC(state->depth.func); + /* set stencil enable */ - rctx->vertex_elements = v; -} + if (state->stencil[0].enabled) { + db_depth_control |= S_028800_STENCIL_ENABLE(1); + db_depth_control |= S_028800_STENCILFUNC(r600_translate_ds_func(state->stencil[0].func)); + db_depth_control |= S_028800_STENCILFAIL(r600_translate_stencil_op(state->stencil[0].fail_op)); + db_depth_control |= S_028800_STENCILZPASS(r600_translate_stencil_op(state->stencil[0].zpass_op)); + db_depth_control |= S_028800_STENCILZFAIL(r600_translate_stencil_op(state->stencil[0].zfail_op)); -static void r600_delete_vertex_elements_state(struct pipe_context *ctx, void *state) -{ - FREE(state); -} + stencil_ref_mask = S_028430_STENCILMASK(state->stencil[0].valuemask) | + S_028430_STENCILWRITEMASK(state->stencil[0].writemask); + stencil_ref_mask |= S_028430_STENCILREF(stencil_ref->ref_value[0]); + if (state->stencil[1].enabled) { + db_depth_control |= S_028800_BACKFACE_ENABLE(1); + db_depth_control |= S_028800_STENCILFUNC_BF(r600_translate_ds_func(state->stencil[1].func)); + db_depth_control |= S_028800_STENCILFAIL_BF(r600_translate_stencil_op(state->stencil[1].fail_op)); + db_depth_control |= S_028800_STENCILZPASS_BF(r600_translate_stencil_op(state->stencil[1].zpass_op)); + db_depth_control |= S_028800_STENCILZFAIL_BF(r600_translate_stencil_op(state->stencil[1].zfail_op)); + stencil_ref_mask_bf = S_028434_STENCILMASK_BF(state->stencil[1].valuemask) | + S_028434_STENCILWRITEMASK_BF(state->stencil[1].writemask); + stencil_ref_mask_bf |= S_028430_STENCILREF(stencil_ref->ref_value[1]); + } + } -static void *r600_create_dsa_state(struct pipe_context *ctx, - const struct pipe_depth_stencil_alpha_state *state) -{ - struct r600_screen *rscreen = r600_screen(ctx->screen); - struct radeon_state *rstate; - unsigned db_depth_control; + alpha_test_control = 0; + alpha_ref = 0; + if (state->alpha.enabled) { + alpha_test_control = S_028410_ALPHA_FUNC(state->alpha.func); + alpha_test_control |= S_028410_ALPHA_TEST_ENABLE(1); + alpha_ref = fui(state->alpha.ref_value); + } - rstate = radeon_state(rscreen->rw, R600_DSA_TYPE, R600_DSA); - if (rstate == NULL) - return NULL; - db_depth_control = 0x00700700 | S_028800_Z_ENABLE(state->depth.enabled) | S_028800_Z_WRITE_ENABLE(state->depth.writemask) | S_028800_ZFUNC(state->depth.func); - rstate->states[R600_DSA__DB_STENCIL_CLEAR] = 0x00000000; rstate->states[R600_DSA__DB_DEPTH_CLEAR] = 0x3F800000; - rstate->states[R600_DSA__SX_ALPHA_TEST_CONTROL] = 0x00000000; - rstate->states[R600_DSA__DB_STENCILREFMASK] = 0xFFFFFF00; - rstate->states[R600_DSA__DB_STENCILREFMASK_BF] = 0xFFFFFF00; - rstate->states[R600_DSA__SX_ALPHA_REF] = 0x00000000; + rstate->states[R600_DSA__SX_ALPHA_TEST_CONTROL] = alpha_test_control; + rstate->states[R600_DSA__DB_STENCILREFMASK] = stencil_ref_mask; + rstate->states[R600_DSA__DB_STENCILREFMASK_BF] = stencil_ref_mask_bf; + rstate->states[R600_DSA__SX_ALPHA_REF] = alpha_ref; rstate->states[R600_DSA__SPI_FOG_FUNC_SCALE] = 0x00000000; rstate->states[R600_DSA__SPI_FOG_FUNC_BIAS] = 0x00000000; rstate->states[R600_DSA__SPI_FOG_CNTL] = 0x00000000; rstate->states[R600_DSA__DB_DEPTH_CONTROL] = db_depth_control; - rstate->states[R600_DSA__DB_SHADER_CONTROL] = 0x00000210; + rstate->states[R600_DSA__DB_SHADER_CONTROL] = db_shader_control; rstate->states[R600_DSA__DB_RENDER_CONTROL] = 0x00000060; rstate->states[R600_DSA__DB_RENDER_OVERRIDE] = 0x0000002A; rstate->states[R600_DSA__DB_SRESULTS_COMPARE_STATE1] = 0x00000000; @@ -400,105 +977,381 @@ static void *r600_create_dsa_state(struct pipe_context *ctx, return rstate; } -static void r600_bind_dsa_state(struct pipe_context *ctx, void *state) +static inline unsigned r600_tex_wrap(unsigned wrap) { - struct r600_context *rctx = r600_context(ctx); - radeon_draw_set(rctx->draw, state); + switch (wrap) { + default: + case PIPE_TEX_WRAP_REPEAT: + return V_03C000_SQ_TEX_WRAP; + case PIPE_TEX_WRAP_CLAMP: + return V_03C000_SQ_TEX_CLAMP_LAST_TEXEL; + case PIPE_TEX_WRAP_CLAMP_TO_EDGE: + return V_03C000_SQ_TEX_CLAMP_HALF_BORDER; + case PIPE_TEX_WRAP_CLAMP_TO_BORDER: + return V_03C000_SQ_TEX_CLAMP_BORDER; + case PIPE_TEX_WRAP_MIRROR_REPEAT: + return V_03C000_SQ_TEX_MIRROR; + case PIPE_TEX_WRAP_MIRROR_CLAMP: + return V_03C000_SQ_TEX_MIRROR_ONCE_LAST_TEXEL; + case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE: + return V_03C000_SQ_TEX_MIRROR_ONCE_HALF_BORDER; + case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER: + return V_03C000_SQ_TEX_MIRROR_ONCE_BORDER; + } } -static void r600_set_constant_buffer(struct pipe_context *ctx, - uint shader, uint index, - struct pipe_resource *buffer) +static inline unsigned r600_tex_filter(unsigned filter) { - struct r600_screen *rscreen = r600_screen(ctx->screen); - struct r600_context *rctx = r600_context(ctx); - unsigned nconstant = 0, i, type, id; + switch (filter) { + default: + case PIPE_TEX_FILTER_NEAREST: + return V_03C000_SQ_TEX_XY_FILTER_POINT; + case PIPE_TEX_FILTER_LINEAR: + return V_03C000_SQ_TEX_XY_FILTER_BILINEAR; + } +} + +static inline unsigned r600_tex_mipfilter(unsigned filter) +{ + switch (filter) { + case PIPE_TEX_MIPFILTER_NEAREST: + return V_03C000_SQ_TEX_Z_FILTER_POINT; + case PIPE_TEX_MIPFILTER_LINEAR: + return V_03C000_SQ_TEX_Z_FILTER_LINEAR; + default: + case PIPE_TEX_MIPFILTER_NONE: + return V_03C000_SQ_TEX_Z_FILTER_NONE; + } +} + +static inline unsigned r600_tex_compare(unsigned compare) +{ + switch (compare) { + default: + case PIPE_FUNC_NEVER: + return V_03C000_SQ_TEX_DEPTH_COMPARE_NEVER; + case PIPE_FUNC_LESS: + return V_03C000_SQ_TEX_DEPTH_COMPARE_LESS; + case PIPE_FUNC_EQUAL: + return V_03C000_SQ_TEX_DEPTH_COMPARE_EQUAL; + case PIPE_FUNC_LEQUAL: + return V_03C000_SQ_TEX_DEPTH_COMPARE_LESSEQUAL; + case PIPE_FUNC_GREATER: + return V_03C000_SQ_TEX_DEPTH_COMPARE_GREATER; + case PIPE_FUNC_NOTEQUAL: + return V_03C000_SQ_TEX_DEPTH_COMPARE_NOTEQUAL; + case PIPE_FUNC_GEQUAL: + return V_03C000_SQ_TEX_DEPTH_COMPARE_GREATEREQUAL; + case PIPE_FUNC_ALWAYS: + return V_03C000_SQ_TEX_DEPTH_COMPARE_ALWAYS; + } +} + +static INLINE u32 S_FIXED(float value, u32 frac_bits) +{ + return value * (1 << frac_bits); +} + +static struct radeon_state *r600_sampler(struct r600_context *rctx, + const struct pipe_sampler_state *state, + unsigned id) +{ + struct r600_screen *rscreen = rctx->screen; struct radeon_state *rstate; - struct pipe_transfer *transfer; - u32 *ptr; - switch (shader) { - case PIPE_SHADER_VERTEX: - id = R600_VS_CONSTANT; - type = R600_VS_CONSTANT_TYPE; - break; - case PIPE_SHADER_FRAGMENT: - id = R600_PS_CONSTANT; - type = R600_PS_CONSTANT_TYPE; - break; + rstate = radeon_state(rscreen->rw, R600_PS_SAMPLER_TYPE, id); + if (rstate == NULL) + return NULL; + rstate->states[R600_PS_SAMPLER__SQ_TEX_SAMPLER_WORD0_0] = + S_03C000_CLAMP_X(r600_tex_wrap(state->wrap_s)) | + S_03C000_CLAMP_Y(r600_tex_wrap(state->wrap_t)) | + S_03C000_CLAMP_Z(r600_tex_wrap(state->wrap_r)) | + S_03C000_XY_MAG_FILTER(r600_tex_filter(state->mag_img_filter)) | + S_03C000_XY_MIN_FILTER(r600_tex_filter(state->min_img_filter)) | + S_03C000_MIP_FILTER(r600_tex_mipfilter(state->min_mip_filter)) | + S_03C000_DEPTH_COMPARE_FUNCTION(r600_tex_compare(state->compare_func)); + /* FIXME LOD it depends on texture base level ... */ + rstate->states[R600_PS_SAMPLER__SQ_TEX_SAMPLER_WORD1_0] = + S_03C004_MIN_LOD(S_FIXED(CLAMP(state->min_lod, 0, 15), 6)) | + S_03C004_MAX_LOD(S_FIXED(CLAMP(state->max_lod, 0, 15), 6)) | + S_03C004_LOD_BIAS(S_FIXED(CLAMP(state->lod_bias, -16, 16), 6)); + rstate->states[R600_PS_SAMPLER__SQ_TEX_SAMPLER_WORD2_0] = S_03C008_TYPE(1); + if (radeon_state_pm4(rstate)) { + radeon_state_decref(rstate); + return NULL; + } + return rstate; +} + +static inline unsigned r600_tex_swizzle(unsigned swizzle) +{ + switch (swizzle) { + case PIPE_SWIZZLE_RED: + return V_038010_SQ_SEL_X; + case PIPE_SWIZZLE_GREEN: + return V_038010_SQ_SEL_Y; + case PIPE_SWIZZLE_BLUE: + return V_038010_SQ_SEL_Z; + case PIPE_SWIZZLE_ALPHA: + return V_038010_SQ_SEL_W; + case PIPE_SWIZZLE_ZERO: + return V_038010_SQ_SEL_0; default: - fprintf(stderr, "%s:%d unsupported %d\n", __func__, __LINE__, shader); - return; + case PIPE_SWIZZLE_ONE: + return V_038010_SQ_SEL_1; } - if (buffer && buffer->width0 > 0) { - nconstant = buffer->width0 / 16; - ptr = pipe_buffer_map(ctx, buffer, PIPE_TRANSFER_READ, &transfer); - if (ptr == NULL) - return; - for (i = 0; i < nconstant; i++) { - rstate = radeon_state(rscreen->rw, type, id + i); - if (rstate == NULL) - return; - rstate->states[R600_PS_CONSTANT__SQ_ALU_CONSTANT0_0] = ptr[i * 4 + 0]; - rstate->states[R600_PS_CONSTANT__SQ_ALU_CONSTANT1_0] = ptr[i * 4 + 1]; - rstate->states[R600_PS_CONSTANT__SQ_ALU_CONSTANT2_0] = ptr[i * 4 + 2]; - rstate->states[R600_PS_CONSTANT__SQ_ALU_CONSTANT3_0] = ptr[i * 4 + 3]; - if (radeon_state_pm4(rstate)) - return; - if (radeon_draw_set_new(rctx->draw, rstate)) - return; - } - pipe_buffer_unmap(ctx, buffer, transfer); +} + +static inline unsigned r600_format_type(unsigned format_type) +{ + switch (format_type) { + default: + case UTIL_FORMAT_TYPE_UNSIGNED: + return V_038010_SQ_FORMAT_COMP_UNSIGNED; + case UTIL_FORMAT_TYPE_SIGNED: + return V_038010_SQ_FORMAT_COMP_SIGNED; + case UTIL_FORMAT_TYPE_FIXED: + return V_038010_SQ_FORMAT_COMP_UNSIGNED_BIASED; } } -static void r600_set_stencil_ref(struct pipe_context *ctx, - const struct pipe_stencil_ref *sr) +static inline unsigned r600_tex_dim(unsigned dim) { - struct r600_context *rctx = r600_context(ctx); - rctx->stencil_ref = *sr; + switch (dim) { + default: + case PIPE_TEXTURE_1D: + return V_038000_SQ_TEX_DIM_1D; + case PIPE_TEXTURE_2D: + return V_038000_SQ_TEX_DIM_2D; + case PIPE_TEXTURE_3D: + return V_038000_SQ_TEX_DIM_3D; + case PIPE_TEXTURE_CUBE: + return V_038000_SQ_TEX_DIM_CUBEMAP; + } } -static void r600_set_sample_mask(struct pipe_context *pipe, unsigned sample_mask) +static struct radeon_state *r600_resource(struct r600_context *rctx, + const struct pipe_sampler_view *view, + unsigned id) { + struct r600_screen *rscreen = rctx->screen; + const struct util_format_description *desc; + struct r600_resource_texture *tmp; + struct r600_resource *rbuffer; + struct radeon_state *rstate; + unsigned format; + + format = r600_translate_colorformat(view->texture->format); + if (format == ~0) + return NULL; + desc = util_format_description(view->texture->format); + if (desc == NULL) { + R600_ERR("unknow format %d\n", view->texture->format); + return NULL; + } + rstate = radeon_state(rscreen->rw, R600_PS_RESOURCE_TYPE, id); + if (rstate == NULL) { + return NULL; + } + tmp = (struct r600_resource_texture*)view->texture; + rbuffer = &tmp->resource; + rstate->bo[0] = radeon_bo_incref(rscreen->rw, rbuffer->bo); + rstate->bo[1] = radeon_bo_incref(rscreen->rw, rbuffer->bo); + rstate->nbo = 2; + rstate->placement[0] = RADEON_GEM_DOMAIN_GTT; + rstate->placement[1] = RADEON_GEM_DOMAIN_GTT; + rstate->placement[2] = RADEON_GEM_DOMAIN_GTT; + rstate->placement[3] = RADEON_GEM_DOMAIN_GTT; + + /* FIXME properly handle first level != 0 */ + rstate->states[R600_PS_RESOURCE__RESOURCE0_WORD0] = + S_038000_DIM(r600_tex_dim(view->texture->target)) | + S_038000_PITCH(((tmp->pitch[0] / tmp->bpt) / 8) - 1) | + S_038000_TEX_WIDTH(view->texture->width0 - 1); + rstate->states[R600_PS_RESOURCE__RESOURCE0_WORD1] = + S_038004_TEX_HEIGHT(view->texture->height0 - 1) | + S_038004_TEX_DEPTH(view->texture->depth0 - 1) | + S_038004_DATA_FORMAT(format); + rstate->states[R600_PS_RESOURCE__RESOURCE0_WORD2] = 0; + rstate->states[R600_PS_RESOURCE__RESOURCE0_WORD3] = tmp->offset[1] >> 8; + rstate->states[R600_PS_RESOURCE__RESOURCE0_WORD4] = + S_038010_FORMAT_COMP_X(r600_format_type(UTIL_FORMAT_TYPE_UNSIGNED)) | + S_038010_FORMAT_COMP_Y(r600_format_type(UTIL_FORMAT_TYPE_UNSIGNED)) | + S_038010_FORMAT_COMP_Z(r600_format_type(UTIL_FORMAT_TYPE_UNSIGNED)) | + S_038010_FORMAT_COMP_W(r600_format_type(UTIL_FORMAT_TYPE_UNSIGNED)) | + S_038010_NUM_FORMAT_ALL(V_038010_SQ_NUM_FORMAT_NORM) | + S_038010_SRF_MODE_ALL(V_038010_SFR_MODE_NO_ZERO) | + S_038010_REQUEST_SIZE(1) | + S_038010_DST_SEL_X(r600_tex_swizzle(view->swizzle_b)) | + S_038010_DST_SEL_Y(r600_tex_swizzle(view->swizzle_g)) | + S_038010_DST_SEL_Z(r600_tex_swizzle(view->swizzle_r)) | + S_038010_DST_SEL_W(r600_tex_swizzle(view->swizzle_a)) | + S_038010_FORCE_DEGAMMA(desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB ? 1 : 0) | + S_038010_BASE_LEVEL(view->first_level); + rstate->states[R600_PS_RESOURCE__RESOURCE0_WORD5] = + S_038014_LAST_LEVEL(view->last_level) | + S_038014_BASE_ARRAY(0) | + S_038014_LAST_ARRAY(0); + rstate->states[R600_PS_RESOURCE__RESOURCE0_WORD6] = + S_038018_TYPE(V_038010_SQ_TEX_VTX_VALID_TEXTURE); + if (radeon_state_pm4(rstate)) { + radeon_state_decref(rstate); + return NULL; + } + return rstate; } -void r600_init_state_functions(struct r600_context *rctx) +static struct radeon_state *r600_cb_cntl(struct r600_context *rctx) { - rctx->context.set_sample_mask = r600_set_sample_mask; - rctx->context.create_blend_state = r600_create_blend_state; - rctx->context.bind_blend_state = r600_bind_blend_state; - rctx->context.delete_blend_state = r600_delete_state; - rctx->context.set_blend_color = r600_set_blend_color; - rctx->context.set_clip_state = r600_set_clip_state; - rctx->context.set_constant_buffer = r600_set_constant_buffer; - rctx->context.create_depth_stencil_alpha_state = r600_create_dsa_state; - rctx->context.bind_depth_stencil_alpha_state = r600_bind_dsa_state; - rctx->context.delete_depth_stencil_alpha_state = r600_delete_state; - rctx->context.set_framebuffer_state = r600_set_framebuffer_state; - rctx->context.create_fs_state = r600_create_fs_state; - rctx->context.bind_fs_state = r600_bind_fs_state; - rctx->context.delete_fs_state = r600_delete_state; - rctx->context.set_polygon_stipple = r600_set_polygon_stipple; - rctx->context.create_rasterizer_state = r600_create_rs_state; - rctx->context.bind_rasterizer_state = r600_bind_rs_state; - rctx->context.delete_rasterizer_state = r600_delete_state; - rctx->context.create_sampler_state = r600_create_sampler_state; - rctx->context.bind_fragment_sampler_states = r600_bind_sampler_states; - rctx->context.bind_vertex_sampler_states = r600_bind_sampler_states; - rctx->context.delete_sampler_state = r600_delete_state; - rctx->context.create_sampler_view = r600_create_sampler_view; - rctx->context.sampler_view_destroy = r600_sampler_view_destroy; - rctx->context.set_fragment_sampler_views = r600_set_fragment_sampler_views; - rctx->context.set_vertex_sampler_views = r600_set_vertex_sampler_views; - rctx->context.set_scissor_state = r600_set_scissor_state; - rctx->context.set_viewport_state = r600_set_viewport_state; - rctx->context.set_vertex_buffers = r600_set_vertex_buffers; - rctx->context.create_vertex_elements_state = r600_create_vertex_elements_state; - rctx->context.bind_vertex_elements_state = r600_bind_vertex_elements_state; - rctx->context.delete_vertex_elements_state = r600_delete_vertex_elements_state; - rctx->context.create_vs_state = r600_create_vs_state; - rctx->context.bind_vs_state = r600_bind_vs_state; - rctx->context.delete_vs_state = r600_delete_state; - rctx->context.set_stencil_ref = r600_set_stencil_ref; + struct r600_screen *rscreen = rctx->screen; + struct radeon_state *rstate; + const struct pipe_blend_state *pbs = &rctx->blend->state.blend; + int nr_cbufs = rctx->framebuffer->state.framebuffer.nr_cbufs; + uint32_t color_control, target_mask, shader_mask; + int i; + + target_mask = 0; + shader_mask = 0; + color_control = S_028808_PER_MRT_BLEND(1); + + for (i = 0; i < nr_cbufs; i++) { + shader_mask |= 0xf << i; + } + + if (pbs->logicop_enable) { + color_control |= (pbs->logicop_func) << 16; + } else + color_control |= (0xcc << 16); + + for (i = 0; i < 8; i++) { + if (pbs->rt[i].blend_enable) { + color_control |= S_028808_TARGET_BLEND_ENABLE(1 << i); + } + target_mask |= (pbs->rt[i].colormask << (4 * i)); + + } + rstate = radeon_state(rscreen->rw, R600_CB_CNTL_TYPE, R600_CB_CNTL); + rstate->states[R600_CB_CNTL__CB_SHADER_MASK] = shader_mask; + rstate->states[R600_CB_CNTL__CB_TARGET_MASK] = target_mask; + rstate->states[R600_CB_CNTL__CB_COLOR_CONTROL] = color_control; + rstate->states[R600_CB_CNTL__PA_SC_AA_CONFIG] = 0x00000000; + rstate->states[R600_CB_CNTL__PA_SC_AA_SAMPLE_LOCS_MCTX] = 0x00000000; + rstate->states[R600_CB_CNTL__PA_SC_AA_SAMPLE_LOCS_8S_WD1_MCTX] = 0x00000000; + rstate->states[R600_CB_CNTL__CB_CLRCMP_CONTROL] = 0x01000000; + rstate->states[R600_CB_CNTL__CB_CLRCMP_SRC] = 0x00000000; + rstate->states[R600_CB_CNTL__CB_CLRCMP_DST] = 0x000000FF; + rstate->states[R600_CB_CNTL__CB_CLRCMP_MSK] = 0xFFFFFFFF; + rstate->states[R600_CB_CNTL__PA_SC_AA_MASK] = 0xFFFFFFFF; + if (radeon_state_pm4(rstate)) { + radeon_state_decref(rstate); + return NULL; + } + return rstate; +} + +int r600_context_hw_states(struct r600_context *rctx) +{ + unsigned i; + int r; + int nr_cbufs = rctx->framebuffer->state.framebuffer.nr_cbufs; + + /* free previous TODO determine what need to be updated, what + * doesn't + */ + //radeon_state_decref(rctx->hw_states.config); + rctx->hw_states.cb_cntl = radeon_state_decref(rctx->hw_states.cb_cntl); + rctx->hw_states.db = radeon_state_decref(rctx->hw_states.db); + rctx->hw_states.rasterizer = radeon_state_decref(rctx->hw_states.rasterizer); + rctx->hw_states.scissor = radeon_state_decref(rctx->hw_states.scissor); + rctx->hw_states.dsa = radeon_state_decref(rctx->hw_states.dsa); + rctx->hw_states.blend = radeon_state_decref(rctx->hw_states.blend); + rctx->hw_states.viewport = radeon_state_decref(rctx->hw_states.viewport); + for (i = 0; i < 8; i++) { + rctx->hw_states.cb[i] = radeon_state_decref(rctx->hw_states.cb[i]); + } + for (i = 0; i < rctx->hw_states.ps_nresource; i++) { + radeon_state_decref(rctx->hw_states.ps_resource[i]); + rctx->hw_states.ps_resource[i] = NULL; + } + rctx->hw_states.ps_nresource = 0; + for (i = 0; i < rctx->hw_states.ps_nsampler; i++) { + radeon_state_decref(rctx->hw_states.ps_sampler[i]); + rctx->hw_states.ps_sampler[i] = NULL; + } + rctx->hw_states.ps_nsampler = 0; + + /* build new states */ + rctx->hw_states.rasterizer = r600_rasterizer(rctx); + rctx->hw_states.scissor = r600_scissor(rctx); + rctx->hw_states.dsa = r600_dsa(rctx); + rctx->hw_states.blend = r600_blend(rctx); + rctx->hw_states.viewport = r600_viewport(rctx); + for (i = 0; i < nr_cbufs; i++) { + rctx->hw_states.cb[i] = r600_cb(rctx, i); + } + rctx->hw_states.db = r600_db(rctx); + rctx->hw_states.cb_cntl = r600_cb_cntl(rctx); + + for (i = 0; i < rctx->ps_nsampler; i++) { + if (rctx->ps_sampler[i]) { + rctx->hw_states.ps_sampler[i] = r600_sampler(rctx, + &rctx->ps_sampler[i]->state.sampler, + R600_PS_SAMPLER + i); + } + } + rctx->hw_states.ps_nsampler = rctx->ps_nsampler; + for (i = 0; i < rctx->ps_nsampler_view; i++) { + if (rctx->ps_sampler_view[i]) { + rctx->hw_states.ps_resource[i] = r600_resource(rctx, + &rctx->ps_sampler_view[i]->state.sampler_view, + R600_PS_RESOURCE + i); + } + } + rctx->hw_states.ps_nresource = rctx->ps_nsampler_view; + + /* bind states */ + r = radeon_draw_set(rctx->draw, rctx->hw_states.db); + if (r) + return r; + r = radeon_draw_set(rctx->draw, rctx->hw_states.rasterizer); + if (r) + return r; + r = radeon_draw_set(rctx->draw, rctx->hw_states.scissor); + if (r) + return r; + r = radeon_draw_set(rctx->draw, rctx->hw_states.dsa); + if (r) + return r; + r = radeon_draw_set(rctx->draw, rctx->hw_states.blend); + if (r) + return r; + r = radeon_draw_set(rctx->draw, rctx->hw_states.viewport); + if (r) + return r; + for (i = 0; i < nr_cbufs; i++) { + r = radeon_draw_set(rctx->draw, rctx->hw_states.cb[i]); + if (r) + return r; + } + r = radeon_draw_set(rctx->draw, rctx->hw_states.config); + if (r) + return r; + r = radeon_draw_set(rctx->draw, rctx->hw_states.cb_cntl); + if (r) + return r; + for (i = 0; i < rctx->hw_states.ps_nresource; i++) { + if (rctx->hw_states.ps_resource[i]) { + r = radeon_draw_set(rctx->draw, rctx->hw_states.ps_resource[i]); + if (r) + return r; + } + } + for (i = 0; i < rctx->hw_states.ps_nsampler; i++) { + if (rctx->hw_states.ps_sampler[i]) { + r = radeon_draw_set(rctx->draw, rctx->hw_states.ps_sampler[i]); + if (r) + return r; + } + } + return 0; } diff --git a/src/gallium/drivers/r600/r600_state_inlines.h b/src/gallium/drivers/r600/r600_state_inlines.h new file mode 100644 index 00000000000..8271ad19fba --- /dev/null +++ b/src/gallium/drivers/r600/r600_state_inlines.h @@ -0,0 +1,311 @@ +/* + * Copyright 2010 Red Hat Inc. + * + * 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 R600_STATE_INLINES_H +#define R600_STATE_INLINES_H + +#include "util/u_format.h" +#include "r600d.h" + +static INLINE uint32_t r600_translate_blend_function(int blend_func) +{ + switch (blend_func) { + case PIPE_BLEND_ADD: + return V_028804_COMB_DST_PLUS_SRC; + case PIPE_BLEND_SUBTRACT: + return V_028804_COMB_SRC_MINUS_DST; + case PIPE_BLEND_REVERSE_SUBTRACT: + return V_028804_COMB_DST_MINUS_SRC; + case PIPE_BLEND_MIN: + return V_028804_COMB_MIN_DST_SRC; + case PIPE_BLEND_MAX: + return V_028804_COMB_MAX_DST_SRC; + default: + R600_ERR("Unknown blend function %d\n", blend_func); + assert(0); + break; + } + return 0; +} + +static INLINE uint32_t r600_translate_blend_factor(int blend_fact) +{ + switch (blend_fact) { + case PIPE_BLENDFACTOR_ONE: + return V_028804_BLEND_ONE; + case PIPE_BLENDFACTOR_SRC_COLOR: + return V_028804_BLEND_SRC_COLOR; + case PIPE_BLENDFACTOR_SRC_ALPHA: + return V_028804_BLEND_SRC_ALPHA; + case PIPE_BLENDFACTOR_DST_ALPHA: + return V_028804_BLEND_DST_ALPHA; + case PIPE_BLENDFACTOR_DST_COLOR: + return V_028804_BLEND_DST_COLOR; + case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE: + return V_028804_BLEND_SRC_ALPHA_SATURATE; + case PIPE_BLENDFACTOR_CONST_COLOR: + return V_028804_BLEND_CONST_COLOR; + case PIPE_BLENDFACTOR_CONST_ALPHA: + return V_028804_BLEND_CONST_ALPHA; + case PIPE_BLENDFACTOR_ZERO: + return V_028804_BLEND_ZERO; + case PIPE_BLENDFACTOR_INV_SRC_COLOR: + return V_028804_BLEND_ONE_MINUS_SRC_COLOR; + case PIPE_BLENDFACTOR_INV_SRC_ALPHA: + return V_028804_BLEND_ONE_MINUS_SRC_ALPHA; + case PIPE_BLENDFACTOR_INV_DST_ALPHA: + return V_028804_BLEND_ONE_MINUS_DST_ALPHA; + case PIPE_BLENDFACTOR_INV_DST_COLOR: + return V_028804_BLEND_ONE_MINUS_DST_COLOR; + case PIPE_BLENDFACTOR_INV_CONST_COLOR: + return V_028804_BLEND_ONE_MINUS_CONST_COLOR; + case PIPE_BLENDFACTOR_INV_CONST_ALPHA: + return V_028804_BLEND_ONE_MINUS_CONST_ALPHA; + case PIPE_BLENDFACTOR_SRC1_COLOR: + return V_028804_BLEND_SRC1_COLOR; + case PIPE_BLENDFACTOR_SRC1_ALPHA: + return V_028804_BLEND_SRC1_ALPHA; + case PIPE_BLENDFACTOR_INV_SRC1_COLOR: + return V_028804_BLEND_INV_SRC1_COLOR; + case PIPE_BLENDFACTOR_INV_SRC1_ALPHA: + return V_028804_BLEND_INV_SRC1_ALPHA; + default: + R600_ERR("Bad blend factor %d not supported!\n", blend_fact); + assert(0); + break; + } + return 0; +} + +static INLINE uint32_t r600_translate_stencil_op(int s_op) +{ + switch (s_op) { + case PIPE_STENCIL_OP_KEEP: + return V_028800_STENCIL_KEEP; + case PIPE_STENCIL_OP_ZERO: + return V_028800_STENCIL_ZERO; + case PIPE_STENCIL_OP_REPLACE: + return V_028800_STENCIL_REPLACE; + case PIPE_STENCIL_OP_INCR: + return V_028800_STENCIL_INCR; + case PIPE_STENCIL_OP_DECR: + return V_028800_STENCIL_DECR; + case PIPE_STENCIL_OP_INCR_WRAP: + return V_028800_STENCIL_INVERT; + case PIPE_STENCIL_OP_DECR_WRAP: + return V_028800_STENCIL_DECR_WRAP; + case PIPE_STENCIL_OP_INVERT: + return V_028800_STENCIL_INVERT; + default: + R600_ERR("Unknown stencil op %d", s_op); + assert(0); + break; + } + return 0; +} + +/* translates straight */ +static INLINE uint32_t r600_translate_ds_func(int func) +{ + return func; +} + +static uint32_t r600_translate_dbformat(enum pipe_format format) +{ + switch (format) { + case PIPE_FORMAT_Z16_UNORM: + return V_028010_DEPTH_16; + case PIPE_FORMAT_Z24X8_UNORM: + return V_028010_DEPTH_X8_24; + case PIPE_FORMAT_Z24_UNORM_S8_USCALED: + return V_028010_DEPTH_8_24; + default: + return ~0; + } +} + +static uint32_t r600_translate_colorswap(enum pipe_format format) +{ + switch (format) { + /* 8-bit buffers. */ + case PIPE_FORMAT_A8_UNORM: + case PIPE_FORMAT_I8_UNORM: + case PIPE_FORMAT_L8_UNORM: + case PIPE_FORMAT_R8_UNORM: + case PIPE_FORMAT_R8_SNORM: + return V_0280A0_SWAP_STD; + + /* 16-bit buffers. */ + case PIPE_FORMAT_B5G6R5_UNORM: + return V_0280A0_SWAP_STD_REV; + + case PIPE_FORMAT_B5G5R5A1_UNORM: + case PIPE_FORMAT_B5G5R5X1_UNORM: + return V_0280A0_SWAP_ALT; + + case PIPE_FORMAT_B4G4R4A4_UNORM: + case PIPE_FORMAT_B4G4R4X4_UNORM: + return V_0280A0_SWAP_ALT; + /* 32-bit buffers. */ + + case PIPE_FORMAT_A8B8G8R8_SRGB: + return V_0280A0_SWAP_STD_REV; + case PIPE_FORMAT_B8G8R8A8_SRGB: + return V_0280A0_SWAP_ALT; + + case PIPE_FORMAT_B8G8R8A8_UNORM: + case PIPE_FORMAT_B8G8R8X8_UNORM: + return V_0280A0_SWAP_ALT; + + case PIPE_FORMAT_A8R8G8B8_UNORM: + case PIPE_FORMAT_X8R8G8B8_UNORM: + return V_0280A0_SWAP_ALT_REV; + case PIPE_FORMAT_R8G8B8A8_SNORM: + case PIPE_FORMAT_R8G8B8X8_UNORM: + return V_0280A0_SWAP_STD; + + case PIPE_FORMAT_A8B8G8R8_UNORM: + case PIPE_FORMAT_X8B8G8R8_UNORM: + // case PIPE_FORMAT_R8SG8SB8UX8U_NORM: + return V_0280A0_SWAP_STD_REV; + + case PIPE_FORMAT_Z24X8_UNORM: + case PIPE_FORMAT_Z24_UNORM_S8_USCALED: + return V_0280A0_SWAP_STD; + + case PIPE_FORMAT_R10G10B10A2_UNORM: + case PIPE_FORMAT_R10G10B10X2_SNORM: + case PIPE_FORMAT_B10G10R10A2_UNORM: + case PIPE_FORMAT_R10SG10SB10SA2U_NORM: + return V_0280A0_SWAP_STD_REV; + + /* 64-bit buffers. */ + case PIPE_FORMAT_R16G16B16A16_UNORM: + case PIPE_FORMAT_R16G16B16A16_SNORM: + // return V_0280A0_COLOR_16_16_16_16; + case PIPE_FORMAT_R16G16B16A16_FLOAT: + // return V_0280A0_COLOR_16_16_16_16_FLOAT; + + /* 128-bit buffers. */ + case PIPE_FORMAT_R32G32B32A32_FLOAT: + // return V_0280A0_COLOR_32_32_32_32_FLOAT; + return 0; + default: + R600_ERR("unsupported colorswap format %d\n", format); + return ~0; + } + return ~0; +} + +static INLINE uint32_t r600_translate_colorformat(enum pipe_format format) +{ + switch (format) { + /* 8-bit buffers. */ + case PIPE_FORMAT_A8_UNORM: + case PIPE_FORMAT_I8_UNORM: + case PIPE_FORMAT_L8_UNORM: + case PIPE_FORMAT_R8_UNORM: + case PIPE_FORMAT_R8_SNORM: + return V_0280A0_COLOR_8; + + /* 16-bit buffers. */ + case PIPE_FORMAT_B5G6R5_UNORM: + return V_0280A0_COLOR_5_6_5; + + case PIPE_FORMAT_B5G5R5A1_UNORM: + case PIPE_FORMAT_B5G5R5X1_UNORM: + return V_0280A0_COLOR_1_5_5_5; + + case PIPE_FORMAT_B4G4R4A4_UNORM: + case PIPE_FORMAT_B4G4R4X4_UNORM: + return V_0280A0_COLOR_4_4_4_4; + + /* 32-bit buffers. */ + case PIPE_FORMAT_A8B8G8R8_SRGB: + case PIPE_FORMAT_A8B8G8R8_UNORM: + case PIPE_FORMAT_A8R8G8B8_UNORM: + case PIPE_FORMAT_B8G8R8A8_SRGB: + case PIPE_FORMAT_B8G8R8A8_UNORM: + case PIPE_FORMAT_B8G8R8X8_UNORM: + case PIPE_FORMAT_R8G8B8A8_SNORM: + case PIPE_FORMAT_R8G8B8A8_UNORM: + case PIPE_FORMAT_R8G8B8X8_UNORM: + case PIPE_FORMAT_R8SG8SB8UX8U_NORM: + case PIPE_FORMAT_X8B8G8R8_UNORM: + case PIPE_FORMAT_X8R8G8B8_UNORM: + return V_0280A0_COLOR_8_8_8_8; + + case PIPE_FORMAT_R10G10B10A2_UNORM: + case PIPE_FORMAT_R10G10B10X2_SNORM: + case PIPE_FORMAT_B10G10R10A2_UNORM: + case PIPE_FORMAT_R10SG10SB10SA2U_NORM: + return V_0280A0_COLOR_10_10_10_2; + + case PIPE_FORMAT_Z24X8_UNORM: + case PIPE_FORMAT_Z24_UNORM_S8_USCALED: + return V_0280A0_COLOR_24_8; + + /* 64-bit buffers. */ + case PIPE_FORMAT_R16G16B16A16_UNORM: + case PIPE_FORMAT_R16G16B16A16_SNORM: + return V_0280A0_COLOR_16_16_16_16; + case PIPE_FORMAT_R16G16B16A16_FLOAT: + return V_0280A0_COLOR_16_16_16_16_FLOAT; + case PIPE_FORMAT_R32G32_FLOAT: + return V_0280A0_COLOR_32_32_FLOAT; + + /* 128-bit buffers. */ + case PIPE_FORMAT_R32G32B32_FLOAT: + case PIPE_FORMAT_R32G32B32A32_FLOAT: + return V_0280A0_COLOR_32_32_32_32_FLOAT; + + /* YUV buffers. */ + case PIPE_FORMAT_UYVY: + case PIPE_FORMAT_YUYV: + default: + R600_ERR("unsupported color format %d\n", format); + return ~0; /* Unsupported. */ + } +} + +static INLINE boolean r600_is_sampler_format_supported(enum pipe_format format) +{ + return r600_translate_colorformat(format) != ~0; +} + +static INLINE boolean r600_is_colorbuffer_format_supported(enum pipe_format format) +{ + return r600_translate_colorformat(format) != ~0 && + r600_translate_colorswap(format) != ~0; +} + +static INLINE boolean r600_is_zs_format_supported(enum pipe_format format) +{ + return r600_translate_dbformat(format) != ~0; +} + +static INLINE boolean r600_is_vertex_format_supported(enum pipe_format format) +{ + return r600_translate_colorformat(format) != ~0; +} + +#endif diff --git a/src/gallium/drivers/r600/r600_texture.c b/src/gallium/drivers/r600/r600_texture.c index 903cfad80a8..1bce9113066 100644 --- a/src/gallium/drivers/r600/r600_texture.c +++ b/src/gallium/drivers/r600/r600_texture.c @@ -31,15 +31,18 @@ #include <util/u_memory.h> #include "state_tracker/drm_driver.h" #include "r600_screen.h" -#include "r600_texture.h" +#include "r600_context.h" +#include "r600_resource.h" extern struct u_resource_vtbl r600_texture_vtbl; -unsigned long r600_texture_get_offset(struct r600_texture *rtex, unsigned level, unsigned zslice, unsigned face) +static unsigned long r600_texture_get_offset(struct r600_resource_texture *rtex, + unsigned level, unsigned zslice, + unsigned face) { unsigned long offset = rtex->offset[level]; - switch (rtex->b.b.target) { + switch (rtex->resource.base.b.target) { case PIPE_TEXTURE_3D: assert(face == 0); return offset + zslice * rtex->layer_size[level]; @@ -52,67 +55,68 @@ unsigned long r600_texture_get_offset(struct r600_texture *rtex, unsigned level, } } -static void r600_setup_miptree(struct r600_screen *rscreen, struct r600_texture *rtex) +static void r600_setup_miptree(struct r600_screen *rscreen, struct r600_resource_texture *rtex) { - struct pipe_resource *ptex = &rtex->b.b; - unsigned long w, h, stride, size, layer_size, i, offset; + struct pipe_resource *ptex = &rtex->resource.base.b; + unsigned long w, h, pitch, size, layer_size, i, offset; + rtex->bpt = util_format_get_blocksize(ptex->format); for (i = 0, offset = 0; i <= ptex->last_level; i++) { w = u_minify(ptex->width0, i); h = u_minify(ptex->height0, i); - stride = align(util_format_get_stride(ptex->format, w), 32); - layer_size = stride * h; + pitch = util_format_get_stride(ptex->format, align(w, 64)); + layer_size = pitch * h; if (ptex->target == PIPE_TEXTURE_CUBE) size = layer_size * 6; else size = layer_size * u_minify(ptex->depth0, i); rtex->offset[i] = offset; rtex->layer_size[i] = layer_size; - rtex->pitch[i] = stride / util_format_get_blocksize(ptex->format); - rtex->stride[i] = stride; - offset += align(size, 32); + rtex->pitch[i] = pitch; + offset += size; } rtex->size = offset; } struct pipe_resource *r600_texture_create(struct pipe_screen *screen, - const struct pipe_resource *templ) + const struct pipe_resource *templ) { - struct r600_texture *rtex = CALLOC_STRUCT(r600_texture); + struct r600_resource_texture *rtex; + struct r600_resource *resource; struct r600_screen *rscreen = r600_screen(screen); - struct pipe_resource templ_buf; + rtex = CALLOC_STRUCT(r600_resource_texture); if (!rtex) { return NULL; } - rtex->b.b = *templ; - rtex->b.vtbl = &r600_texture_vtbl; - pipe_reference_init(&rtex->b.b.reference, 1); - rtex->b.b.screen = screen; + resource = &rtex->resource; + resource->base.b = *templ; + resource->base.vtbl = &r600_texture_vtbl; + pipe_reference_init(&resource->base.b.reference, 1); + resource->base.b.screen = screen; r600_setup_miptree(rscreen, rtex); - memset(&templ_buf, 0, sizeof(struct pipe_resource)); - templ_buf.target = PIPE_BUFFER; - templ_buf.format = PIPE_FORMAT_R8_UNORM; - templ_buf.usage = templ->usage; - templ_buf.bind = templ->bind; - templ_buf.width0 = rtex->size; - templ_buf.height0 = 1; - templ_buf.depth0 = 1; - - rtex->buffer = screen->resource_create(screen, &templ_buf); - if (!rtex->buffer) { + /* FIXME alignment 4096 enought ? too much ? */ + resource->domain = r600_domain_from_usage(resource->base.b.bind); + resource->bo = radeon_bo(rscreen->rw, 0, rtex->size, 4096, NULL); + if (resource->bo == NULL) { FREE(rtex); return NULL; } - return &rtex->b.b; + + return &resource->base.b; } static void r600_texture_destroy(struct pipe_screen *screen, struct pipe_resource *ptex) { - struct r600_texture *rtex = (struct r600_texture*)ptex; + struct r600_resource_texture *rtex = (struct r600_resource_texture*)ptex; + struct r600_resource *resource = &rtex->resource; + struct r600_screen *rscreen = r600_screen(screen); + if (resource->bo) { + radeon_bo_decref(rscreen->rw, resource->bo); + } FREE(rtex); } @@ -121,7 +125,7 @@ static struct pipe_surface *r600_get_tex_surface(struct pipe_screen *screen, unsigned face, unsigned level, unsigned zslice, unsigned flags) { - struct r600_texture *rtex = (struct r600_texture*)texture; + struct r600_resource_texture *rtex = (struct r600_resource_texture*)texture; struct pipe_surface *surface = CALLOC_STRUCT(pipe_surface); unsigned long offset; @@ -149,71 +153,115 @@ static void r600_tex_surface_destroy(struct pipe_surface *surface) } struct pipe_resource *r600_texture_from_handle(struct pipe_screen *screen, - const struct pipe_resource *base, + const struct pipe_resource *templ, struct winsys_handle *whandle) { - struct pipe_resource *buffer; - struct r600_texture *rtex; + struct radeon *rw = (struct radeon*)screen->winsys; + struct r600_resource_texture *rtex; + struct r600_resource *resource; + struct radeon_bo *bo = NULL; - buffer = r600_buffer_from_handle(screen, whandle); - if (buffer == NULL) { + bo = radeon_bo(rw, whandle->handle, 0, 0, NULL); + if (bo == NULL) { return NULL; } /* Support only 2D textures without mipmaps */ - if (base->target != PIPE_TEXTURE_2D || base->depth0 != 1 || base->last_level != 0) + if (templ->target != PIPE_TEXTURE_2D || templ->depth0 != 1 || templ->last_level != 0) return NULL; - rtex = CALLOC_STRUCT(r600_texture); + rtex = CALLOC_STRUCT(r600_resource_texture); if (rtex == NULL) return NULL; - /* one ref already taken */ - rtex->buffer = buffer; - - rtex->b.b = *base; - rtex->b.vtbl = &r600_texture_vtbl; - pipe_reference_init(&rtex->b.b.reference, 1); - rtex->b.b.screen = screen; - rtex->stride_override = whandle->stride; - rtex->pitch[0] = whandle->stride / util_format_get_blocksize(base->format); - rtex->stride[0] = whandle->stride; + resource = &rtex->resource; + resource->base.b = *templ; + resource->base.vtbl = &r600_texture_vtbl; + pipe_reference_init(&resource->base.b.reference, 1); + resource->base.b.screen = screen; + resource->bo = bo; + rtex->pitch_override = whandle->stride; + rtex->bpt = util_format_get_blocksize(templ->format); + rtex->pitch[0] = whandle->stride; rtex->offset[0] = 0; - rtex->size = align(rtex->stride[0] * base->height0, 32); + rtex->size = align(rtex->pitch[0] * templ->height0, 64); - return &rtex->b.b; + return &resource->base.b; } -static boolean r600_texture_get_handle(struct pipe_screen* screen, - struct pipe_resource *texture, - struct winsys_handle *whandle) +static unsigned int r600_texture_is_referenced(struct pipe_context *context, + struct pipe_resource *texture, + unsigned face, unsigned level) { - struct r600_screen *rscreen = r600_screen(screen); - struct r600_texture* rtex = (struct r600_texture*)texture; + /* FIXME */ + return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE; +} - if (!rtex) { - return FALSE; - } +struct pipe_transfer* r600_texture_get_transfer(struct pipe_context *ctx, + struct pipe_resource *texture, + struct pipe_subresource sr, + unsigned usage, + const struct pipe_box *box) +{ + struct r600_resource_texture *rtex = (struct r600_resource_texture*)texture; + struct r600_transfer *trans; - whandle->stride = rtex->stride[0]; + trans = CALLOC_STRUCT(r600_transfer); + if (trans == NULL) + return NULL; + pipe_resource_reference(&trans->transfer.resource, texture); + trans->transfer.sr = sr; + trans->transfer.usage = usage; + trans->transfer.box = *box; + trans->transfer.stride = rtex->pitch[sr.level]; + trans->offset = r600_texture_get_offset(rtex, sr.level, box->z, sr.face); + return &trans->transfer; +} - r600_buffer_get_handle(rscreen->rw, rtex->buffer, whandle); +void r600_texture_transfer_destroy(struct pipe_context *ctx, + struct pipe_transfer *trans) +{ + pipe_resource_reference(&trans->resource, NULL); + FREE(trans); +} - return TRUE; +void* r600_texture_transfer_map(struct pipe_context *ctx, + struct pipe_transfer* transfer) +{ + struct r600_transfer *rtransfer = (struct r600_transfer*)transfer; + struct r600_resource *resource; + enum pipe_format format = transfer->resource->format; + struct r600_screen *rscreen = r600_screen(ctx->screen); + char *map; + + r600_flush(ctx, 0, NULL); + + resource = (struct r600_resource *)transfer->resource; + if (radeon_bo_map(rscreen->rw, resource->bo)) { + return NULL; + } + radeon_bo_wait(rscreen->rw, resource->bo); + + map = resource->bo->data; + + return map + rtransfer->offset + + transfer->box.y / util_format_get_blockheight(format) * transfer->stride + + transfer->box.x / util_format_get_blockwidth(format) * util_format_get_blocksize(format); } -static unsigned int r600_texture_is_referenced(struct pipe_context *context, - struct pipe_resource *texture, - unsigned face, unsigned level) +void r600_texture_transfer_unmap(struct pipe_context *ctx, + struct pipe_transfer* transfer) { - struct r600_texture *rtex = (struct r600_texture*)texture; + struct r600_screen *rscreen = r600_screen(ctx->screen); + struct r600_resource *resource; - return r600_buffer_is_referenced_by_cs(context, rtex->buffer, face, level); + resource = (struct r600_resource *)transfer->resource; + radeon_bo_unmap(rscreen->rw, resource->bo); } struct u_resource_vtbl r600_texture_vtbl = { - r600_texture_get_handle, /* get_handle */ + u_default_resource_get_handle, /* get_handle */ r600_texture_destroy, /* resource_destroy */ r600_texture_is_referenced, /* is_resource_referenced */ r600_texture_get_transfer, /* get_transfer */ diff --git a/src/gallium/drivers/r600/r600_texture.h b/src/gallium/drivers/r600/r600_texture.h deleted file mode 100644 index 9bc08d6b040..00000000000 --- a/src/gallium/drivers/r600/r600_texture.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 2010 Jerome Glisse <[email protected]> - * - * 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 R600_TEXTURE_H -#define R600_TEXTURE_H - -#include <pipe/p_state.h> - -struct r600_texture { - struct u_resource b; - unsigned long offset[PIPE_MAX_TEXTURE_LEVELS]; - unsigned long pitch[PIPE_MAX_TEXTURE_LEVELS]; - unsigned long stride[PIPE_MAX_TEXTURE_LEVELS]; - unsigned long layer_size[PIPE_MAX_TEXTURE_LEVELS]; - unsigned long stride_override; - unsigned long size; - struct pipe_resource *buffer; -}; - -struct pipe_resource *r600_texture_create(struct pipe_screen *screen, - const struct pipe_resource *templ); -unsigned long r600_texture_get_offset(struct r600_texture *rtex, unsigned level, unsigned zslice, unsigned face); -struct pipe_resource *r600_texture_from_handle(struct pipe_screen *screen, - const struct pipe_resource *base, - struct winsys_handle *whandle); -void r600_init_screen_texture_functions(struct pipe_screen *screen); - -/* This should be implemented by winsys. */ -boolean r600_buffer_get_handle(struct radeon *rw, - struct pipe_resource *buf, - struct winsys_handle *whandle); - - -#endif diff --git a/src/gallium/drivers/r600/r600d.h b/src/gallium/drivers/r600/r600d.h index 44834984c68..fb71b1e5d1d 100644 --- a/src/gallium/drivers/r600/r600d.h +++ b/src/gallium/drivers/r600/r600d.h @@ -26,6 +26,8 @@ #ifndef R600D_H #define R600D_H +#define R600_TEXEL_PITCH_ALIGNMENT_MASK 0x7 + #define PKT3_NOP 0x10 #define PKT3_INDIRECT_BUFFER_END 0x17 #define PKT3_SET_PREDICATION 0x20 @@ -207,12 +209,24 @@ #define S_0280A0_NUMBER_TYPE(x) (((x) & 0x7) << 12) #define G_0280A0_NUMBER_TYPE(x) (((x) >> 12) & 0x7) #define C_0280A0_NUMBER_TYPE 0xFFFF8FFF +#define V_0280A0_NUMBER_UNORM 0x00000000 +#define V_0280A0_NUMBER_SNORM 0x00000001 +#define V_0280A0_NUMBER_USCALED 0x00000002 +#define V_0280A0_NUMBER_SSCALED 0x00000003 +#define V_0280A0_NUMBER_UINT 0x00000004 +#define V_0280A0_NUMBER_SINT 0x00000005 +#define V_0280A0_NUMBER_SRGB 0x00000006 +#define V_0280A0_NUMBER_FLOAT 0x00000007 #define S_0280A0_READ_SIZE(x) (((x) & 0x1) << 15) #define G_0280A0_READ_SIZE(x) (((x) >> 15) & 0x1) #define C_0280A0_READ_SIZE 0xFFFF7FFF #define S_0280A0_COMP_SWAP(x) (((x) & 0x3) << 16) #define G_0280A0_COMP_SWAP(x) (((x) >> 16) & 0x3) #define C_0280A0_COMP_SWAP 0xFFFCFFFF +#define V_0280A0_SWAP_STD 0x00000000 +#define V_0280A0_SWAP_ALT 0x00000001 +#define V_0280A0_SWAP_STD_REV 0x00000002 +#define V_0280A0_SWAP_ALT_REV 0x00000003 #define S_0280A0_TILE_MODE(x) (((x) & 0x3) << 18) #define G_0280A0_TILE_MODE(x) (((x) >> 18) & 0x3) #define C_0280A0_TILE_MODE 0xFFF3FFFF @@ -247,6 +261,16 @@ #define S_028060_SLICE_TILE_MAX(x) (((x) & 0xFFFFF) << 10) #define G_028060_SLICE_TILE_MAX(x) (((x) >> 10) & 0xFFFFF) #define C_028060_SLICE_TILE_MAX 0xC00003FF +#define R_028410_SX_ALPHA_TEST_CONTROL 0x028410 +#define S_028410_ALPHA_FUNC(x) (((x) & 0x7) << 0) +#define G_028410_ALPHA_FUNC(x) (((x) >> 0) & 0x7) +#define C_028410_ALPHA_FUNC 0xFFFFFFF8 +#define S_028410_ALPHA_TEST_ENABLE(x) (((x) & 0x1) << 3) +#define G_028410_ALPHA_TEST_ENABLE(x) (((x) >> 3) & 0x1) +#define C_028410_ALPHA_TEST_ENABLE 0xFFFFFFF7 +#define S_028410_ALPHA_TEST_BYPASS(x) (((x) & 0x1) << 8) +#define G_028410_ALPHA_TEST_BYPASS(x) (((x) >> 8) & 0x1) +#define C_028410_ALPHA_TEST_BYPASS 0xFFFFFEFF #define R_028800_DB_DEPTH_CONTROL 0x028800 #define S_028800_STENCIL_ENABLE(x) (((x) & 0x1) << 0) #define G_028800_STENCIL_ENABLE(x) (((x) >> 0) & 0x1) @@ -266,9 +290,25 @@ #define S_028800_STENCILFUNC(x) (((x) & 0x7) << 8) #define G_028800_STENCILFUNC(x) (((x) >> 8) & 0x7) #define C_028800_STENCILFUNC 0xFFFFF8FF +#define V_028800_STENCILFUNC_NEVER 0x00000000 +#define V_028800_STENCILFUNC_LESS 0x00000001 +#define V_028800_STENCILFUNC_EQUAL 0x00000002 +#define V_028800_STENCILFUNC_LEQUAL 0x00000003 +#define V_028800_STENCILFUNC_GREATER 0x00000004 +#define V_028800_STENCILFUNC_NOTEQUAL 0x00000005 +#define V_028800_STENCILFUNC_GEQUAL 0x00000006 +#define V_028800_STENCILFUNC_ALWAYS 0x00000007 #define S_028800_STENCILFAIL(x) (((x) & 0x7) << 11) #define G_028800_STENCILFAIL(x) (((x) >> 11) & 0x7) #define C_028800_STENCILFAIL 0xFFFFC7FF +#define V_028800_STENCIL_KEEP 0x00000000 +#define V_028800_STENCIL_ZERO 0x00000001 +#define V_028800_STENCIL_REPLACE 0x00000002 +#define V_028800_STENCIL_INCR 0x00000003 +#define V_028800_STENCIL_DECR 0x00000004 +#define V_028800_STENCIL_INVERT 0x00000005 +#define V_028800_STENCIL_INCR_WRAP 0x00000006 +#define V_028800_STENCIL_DECR_WRAP 0x00000007 #define S_028800_STENCILZPASS(x) (((x) & 0x7) << 14) #define G_028800_STENCILZPASS(x) (((x) >> 14) & 0x7) #define C_028800_STENCILZPASS 0xFFFE3FFF @@ -287,6 +327,31 @@ #define S_028800_STENCILZFAIL_BF(x) (((x) & 0x7) << 29) #define G_028800_STENCILZFAIL_BF(x) (((x) >> 29) & 0x7) #define C_028800_STENCILZFAIL_BF 0x1FFFFFFF +#define R_028808_CB_COLOR_CONTROL 0x028808 +#define S_028808_FOG_ENABLE(x) (((x) & 0x1) << 0) +#define G_028808_FOG_ENABLE(x) (((x) >> 0) & 0x1) +#define C_028808_FOG_ENABLE 0xFFFFFFFE +#define S_028808_MULTIWRITE_ENABLE(x) (((x) & 0x1) << 1) +#define G_028808_MULTIWRITE_ENABLE(x) (((x) >> 1) & 0x1) +#define C_028808_MULTIWRITE_ENABLE 0xFFFFFFFD +#define S_028808_DITHER_ENABLE(x) (((x) & 0x1) << 2) +#define G_028808_DITHER_ENABLE(x) (((x) >> 2) & 0x1) +#define C_028808_DITHER_ENABLE 0xFFFFFFFB +#define S_028808_DEGAMMA_ENABLE(x) (((x) & 0x1) << 3) +#define G_028808_DEGAMMA_ENABLE(x) (((x) >> 3) & 0x1) +#define C_028808_DEGAMMA_ENABLE 0xFFFFFFF7 +#define S_028808_SPECIAL_OP(x) (((x) & 0x7) << 4) +#define G_028808_SPECIAL_OP(x) (((x) >> 4) & 0x7) +#define C_028808_SPECIAL_OP 0xFFFFFF8F +#define S_028808_PER_MRT_BLEND(x) (((x) & 0x1) << 7) +#define G_028808_PER_MRT_BLEND(x) (((x) >> 7) & 0x1) +#define C_028808_PER_MRT_BLEND 0xFFFFFF7F +#define S_028808_TARGET_BLEND_ENABLE(x) (((x) & 0xFF) << 8) +#define G_028808_TARGET_BLEND_ENABLE(x) (((x) >> 8) & 0xFF) +#define C_028808_TARGET_BLEND_ENABLE 0xFFFF00FF +#define S_028808_ROP3(x) (((x) & 0xFF) << 16) +#define G_028808_ROP3(x) (((x) >> 16) & 0xFF) +#define C_028808_ROP3 0xFF00FFFF #define R_028010_DB_DEPTH_INFO 0x028010 #define S_028010_FORMAT(x) (((x) & 0x7) << 0) #define G_028010_FORMAT(x) (((x) >> 0) & 0x7) @@ -314,6 +379,117 @@ #define S_028010_ZRANGE_PRECISION(x) (((x) & 0x1) << 31) #define G_028010_ZRANGE_PRECISION(x) (((x) >> 31) & 0x1) #define C_028010_ZRANGE_PRECISION 0x7FFFFFFF +#define R_028430_DB_STENCILREFMASK 0x028430 +#define S_028430_STENCILREF(x) (((x) & 0xFF) << 0) +#define G_028430_STENCILREF(x) (((x) >> 0) & 0xFF) +#define C_028430_STENCILREF 0xFFFFFF00 +#define S_028430_STENCILMASK(x) (((x) & 0xFF) << 8) +#define G_028430_STENCILMASK(x) (((x) >> 8) & 0xFF) +#define C_028430_STENCILMASK 0xFFFF00FF +#define S_028430_STENCILWRITEMASK(x) (((x) & 0xFF) << 16) +#define G_028430_STENCILWRITEMASK(x) (((x) >> 16) & 0xFF) +#define C_028430_STENCILWRITEMASK 0xFF00FFFF +#define R_028434_DB_STENCILREFMASK_BF 0x028434 +#define S_028434_STENCILREF_BF(x) (((x) & 0xFF) << 0) +#define G_028434_STENCILREF_BF(x) (((x) >> 0) & 0xFF) +#define C_028434_STENCILREF_BF 0xFFFFFF00 +#define S_028434_STENCILMASK_BF(x) (((x) & 0xFF) << 8) +#define G_028434_STENCILMASK_BF(x) (((x) >> 8) & 0xFF) +#define C_028434_STENCILMASK_BF 0xFFFF00FF +#define S_028434_STENCILWRITEMASK_BF(x) (((x) & 0xFF) << 16) +#define G_028434_STENCILWRITEMASK_BF(x) (((x) >> 16) & 0xFF) +#define C_028434_STENCILWRITEMASK_BF 0xFF00FFFF +#define R_028804_CB_BLEND_CONTROL 0x028804 +#define S_028804_COLOR_SRCBLEND(x) (((x) & 0x1F) << 0) +#define G_028804_COLOR_SRCBLEND(x) (((x) >> 0) & 0x1F) +#define C_028804_COLOR_SRCBLEND 0xFFFFFFE0 +#define V_028804_BLEND_ZERO 0x00000000 +#define V_028804_BLEND_ONE 0x00000001 +#define V_028804_BLEND_SRC_COLOR 0x00000002 +#define V_028804_BLEND_ONE_MINUS_SRC_COLOR 0x00000003 +#define V_028804_BLEND_SRC_ALPHA 0x00000004 +#define V_028804_BLEND_ONE_MINUS_SRC_ALPHA 0x00000005 +#define V_028804_BLEND_DST_ALPHA 0x00000006 +#define V_028804_BLEND_ONE_MINUS_DST_ALPHA 0x00000007 +#define V_028804_BLEND_DST_COLOR 0x00000008 +#define V_028804_BLEND_ONE_MINUS_DST_COLOR 0x00000009 +#define V_028804_BLEND_SRC_ALPHA_SATURATE 0x0000000A +#define V_028804_BLEND_BOTH_SRC_ALPHA 0x0000000B +#define V_028804_BLEND_BOTH_INV_SRC_ALPHA 0x0000000C +#define V_028804_BLEND_CONST_COLOR 0x0000000D +#define V_028804_BLEND_ONE_MINUS_CONST_COLOR 0x0000000E +#define V_028804_BLEND_SRC1_COLOR 0x0000000F +#define V_028804_BLEND_INV_SRC1_COLOR 0x00000010 +#define V_028804_BLEND_SRC1_ALPHA 0x00000011 +#define V_028804_BLEND_INV_SRC1_ALPHA 0x00000012 +#define V_028804_BLEND_CONST_ALPHA 0x00000013 +#define V_028804_BLEND_ONE_MINUS_CONST_ALPHA 0x00000014 +#define S_028804_COLOR_COMB_FCN(x) (((x) & 0x7) << 5) +#define G_028804_COLOR_COMB_FCN(x) (((x) >> 5) & 0x7) +#define C_028804_COLOR_COMB_FCN 0xFFFFFF1F +#define V_028804_COMB_DST_PLUS_SRC 0x00000000 +#define V_028804_COMB_SRC_MINUS_DST 0x00000001 +#define V_028804_COMB_MIN_DST_SRC 0x00000002 +#define V_028804_COMB_MAX_DST_SRC 0x00000003 +#define V_028804_COMB_DST_MINUS_SRC 0x00000004 +#define S_028804_COLOR_DESTBLEND(x) (((x) & 0x1F) << 8) +#define G_028804_COLOR_DESTBLEND(x) (((x) >> 8) & 0x1F) +#define C_028804_COLOR_DESTBLEND 0xFFFFE0FF +#define S_028804_OPACITY_WEIGHT(x) (((x) & 0x1) << 13) +#define G_028804_OPACITY_WEIGHT(x) (((x) >> 13) & 0x1) +#define C_028804_OPACITY_WEIGHT 0xFFFFDFFF +#define S_028804_ALPHA_SRCBLEND(x) (((x) & 0x1F) << 16) +#define G_028804_ALPHA_SRCBLEND(x) (((x) >> 16) & 0x1F) +#define C_028804_ALPHA_SRCBLEND 0xFFE0FFFF +#define S_028804_ALPHA_COMB_FCN(x) (((x) & 0x7) << 21) +#define G_028804_ALPHA_COMB_FCN(x) (((x) >> 21) & 0x7) +#define C_028804_ALPHA_COMB_FCN 0xFF1FFFFF +#define S_028804_ALPHA_DESTBLEND(x) (((x) & 0x1F) << 24) +#define G_028804_ALPHA_DESTBLEND(x) (((x) >> 24) & 0x1F) +#define C_028804_ALPHA_DESTBLEND 0xE0FFFFFF +#define S_028804_SEPARATE_ALPHA_BLEND(x) (((x) & 0x1) << 29) +#define G_028804_SEPARATE_ALPHA_BLEND(x) (((x) >> 29) & 0x1) +#define C_028804_SEPARATE_ALPHA_BLEND 0xDFFFFFFF +#define R_028814_PA_SU_SC_MODE_CNTL 0x028814 +#define S_028814_CULL_FRONT(x) (((x) & 0x1) << 0) +#define G_028814_CULL_FRONT(x) (((x) >> 0) & 0x1) +#define C_028814_CULL_FRONT 0xFFFFFFFE +#define S_028814_CULL_BACK(x) (((x) & 0x1) << 1) +#define G_028814_CULL_BACK(x) (((x) >> 1) & 0x1) +#define C_028814_CULL_BACK 0xFFFFFFFD +#define S_028814_FACE(x) (((x) & 0x1) << 2) +#define G_028814_FACE(x) (((x) >> 2) & 0x1) +#define C_028814_FACE 0xFFFFFFFB +#define S_028814_POLY_MODE(x) (((x) & 0x3) << 3) +#define G_028814_POLY_MODE(x) (((x) >> 3) & 0x3) +#define C_028814_POLY_MODE 0xFFFFFFE7 +#define S_028814_POLYMODE_FRONT_PTYPE(x) (((x) & 0x7) << 5) +#define G_028814_POLYMODE_FRONT_PTYPE(x) (((x) >> 5) & 0x7) +#define C_028814_POLYMODE_FRONT_PTYPE 0xFFFFFF1F +#define S_028814_POLYMODE_BACK_PTYPE(x) (((x) & 0x7) << 8) +#define G_028814_POLYMODE_BACK_PTYPE(x) (((x) >> 8) & 0x7) +#define C_028814_POLYMODE_BACK_PTYPE 0xFFFFF8FF +#define S_028814_POLY_OFFSET_FRONT_ENABLE(x) (((x) & 0x1) << 11) +#define G_028814_POLY_OFFSET_FRONT_ENABLE(x) (((x) >> 11) & 0x1) +#define C_028814_POLY_OFFSET_FRONT_ENABLE 0xFFFFF7FF +#define S_028814_POLY_OFFSET_BACK_ENABLE(x) (((x) & 0x1) << 12) +#define G_028814_POLY_OFFSET_BACK_ENABLE(x) (((x) >> 12) & 0x1) +#define C_028814_POLY_OFFSET_BACK_ENABLE 0xFFFFEFFF +#define S_028814_POLY_OFFSET_PARA_ENABLE(x) (((x) & 0x1) << 13) +#define G_028814_POLY_OFFSET_PARA_ENABLE(x) (((x) >> 13) & 0x1) +#define C_028814_POLY_OFFSET_PARA_ENABLE 0xFFFFDFFF +#define S_028814_VTX_WINDOW_OFFSET_ENABLE(x) (((x) & 0x1) << 16) +#define G_028814_VTX_WINDOW_OFFSET_ENABLE(x) (((x) >> 16) & 0x1) +#define C_028814_VTX_WINDOW_OFFSET_ENABLE 0xFFFEFFFF +#define S_028814_PROVOKING_VTX_LAST(x) (((x) & 0x1) << 19) +#define G_028814_PROVOKING_VTX_LAST(x) (((x) >> 19) & 0x1) +#define C_028814_PROVOKING_VTX_LAST 0xFFF7FFFF +#define S_028814_PERSP_CORR_DIS(x) (((x) & 0x1) << 20) +#define G_028814_PERSP_CORR_DIS(x) (((x) >> 20) & 0x1) +#define C_028814_PERSP_CORR_DIS 0xFFEFFFFF +#define S_028814_MULTI_PRIM_IB_ENA(x) (((x) & 0x1) << 21) +#define G_028814_MULTI_PRIM_IB_ENA(x) (((x) >> 21) & 0x1) +#define C_028814_MULTI_PRIM_IB_ENA 0xFFDFFFFF #define R_028000_DB_DEPTH_SIZE 0x028000 #define S_028000_PITCH_TILE_MAX(x) (((x) & 0x3FF) << 0) #define G_028000_PITCH_TILE_MAX(x) (((x) >> 0) & 0x3FF) @@ -400,6 +576,29 @@ #define S_028D10_IGNORE_SC_ZRANGE(x) (((x) & 0x1) << 17) #define G_028D10_IGNORE_SC_ZRANGE(x) (((x) >> 17) & 0x1) #define C_028D10_IGNORE_SC_ZRANGE 0xFFFDFFFF +#define R_028DF8_PA_SU_POLY_OFFSET_DB_FMT_CNTL 0x028DF8 +#define S_028DF8_POLY_OFFSET_NEG_NUM_DB_BITS(x) (((x) & 0xFF) << 0) +#define G_028DF8_POLY_OFFSET_NEG_NUM_DB_BITS(x) (((x) >> 0) & 0xFF) +#define C_028DF8_POLY_OFFSET_NEG_NUM_DB_BITS 0xFFFFFF00 +#define S_028DF8_POLY_OFFSET_DB_IS_FLOAT_FMT(x) (((x) & 0x1) << 8) +#define G_028DF8_POLY_OFFSET_DB_IS_FLOAT_FMT(x) (((x) >> 8) & 0x1) +#define C_028DF8_POLY_OFFSET_DB_IS_FLOAT_FMT 0xFFFFFEFF +#define R_028E00_PA_SU_POLY_OFFSET_FRONT_SCALE 0x028E00 +#define S_028E00_SCALE(x) (((x) & 0xFFFFFFFF) << 0) +#define G_028E00_SCALE(x) (((x) >> 0) & 0xFFFFFFFF) +#define C_028E00_SCALE 0x00000000 +#define R_028E04_PA_SU_POLY_OFFSET_FRONT_OFFSET 0x028E04 +#define S_028E04_OFFSET(x) (((x) & 0xFFFFFFFF) << 0) +#define G_028E04_OFFSET(x) (((x) >> 0) & 0xFFFFFFFF) +#define C_028E04_OFFSET 0x00000000 +#define R_028E08_PA_SU_POLY_OFFSET_BACK_SCALE 0x028E08 +#define S_028E08_SCALE(x) (((x) & 0xFFFFFFFF) << 0) +#define G_028E08_SCALE(x) (((x) >> 0) & 0xFFFFFFFF) +#define C_028E08_SCALE 0x00000000 +#define R_028E0C_PA_SU_POLY_OFFSET_BACK_OFFSET 0x028E0C +#define S_028E0C_OFFSET(x) (((x) & 0xFFFFFFFF) << 0) +#define G_028E0C_OFFSET(x) (((x) >> 0) & 0xFFFFFFFF) +#define C_028E0C_OFFSET 0x00000000 #define R_028A40_VGT_GS_MODE 0x028A40 #define S_028A40_MODE(x) (((x) & 0x3) << 0) #define G_028A40_MODE(x) (((x) >> 0) & 0x3) @@ -574,6 +773,132 @@ #define S_0287F0_USE_OPAQUE(x) (((x) & 0x1) << 6) #define G_0287F0_USE_OPAQUE(x) (((x) >> 6) & 0x1) #define C_0287F0_USE_OPAQUE 0xFFFFFFBF +#define R_038000_SQ_TEX_RESOURCE_WORD0_0 0x038000 +#define S_038000_DIM(x) (((x) & 0x7) << 0) +#define G_038000_DIM(x) (((x) >> 0) & 0x7) +#define C_038000_DIM 0xFFFFFFF8 +#define V_038000_SQ_TEX_DIM_1D 0x00000000 +#define V_038000_SQ_TEX_DIM_2D 0x00000001 +#define V_038000_SQ_TEX_DIM_3D 0x00000002 +#define V_038000_SQ_TEX_DIM_CUBEMAP 0x00000003 +#define V_038000_SQ_TEX_DIM_1D_ARRAY 0x00000004 +#define V_038000_SQ_TEX_DIM_2D_ARRAY 0x00000005 +#define V_038000_SQ_TEX_DIM_2D_MSAA 0x00000006 +#define V_038000_SQ_TEX_DIM_2D_ARRAY_MSAA 0x00000007 +#define S_038000_TILE_MODE(x) (((x) & 0xF) << 3) +#define G_038000_TILE_MODE(x) (((x) >> 3) & 0xF) +#define C_038000_TILE_MODE 0xFFFFFF87 +#define S_038000_TILE_TYPE(x) (((x) & 0x1) << 7) +#define G_038000_TILE_TYPE(x) (((x) >> 7) & 0x1) +#define C_038000_TILE_TYPE 0xFFFFFF7F +#define S_038000_PITCH(x) (((x) & 0x7FF) << 8) +#define G_038000_PITCH(x) (((x) >> 8) & 0x7FF) +#define C_038000_PITCH 0xFFF800FF +#define S_038000_TEX_WIDTH(x) (((x) & 0x1FFF) << 19) +#define G_038000_TEX_WIDTH(x) (((x) >> 19) & 0x1FFF) +#define C_038000_TEX_WIDTH 0x0007FFFF +#define R_038004_SQ_TEX_RESOURCE_WORD1_0 0x038004 +#define S_038004_TEX_HEIGHT(x) (((x) & 0x1FFF) << 0) +#define G_038004_TEX_HEIGHT(x) (((x) >> 0) & 0x1FFF) +#define C_038004_TEX_HEIGHT 0xFFFFE000 +#define S_038004_TEX_DEPTH(x) (((x) & 0x1FFF) << 13) +#define G_038004_TEX_DEPTH(x) (((x) >> 13) & 0x1FFF) +#define C_038004_TEX_DEPTH 0xFC001FFF +#define S_038004_DATA_FORMAT(x) (((x) & 0x3F) << 26) +#define G_038004_DATA_FORMAT(x) (((x) >> 26) & 0x3F) +#define C_038004_DATA_FORMAT 0x03FFFFFF +#define R_038008_SQ_TEX_RESOURCE_WORD2_0 0x038008 +#define S_038008_BASE_ADDRESS(x) (((x) & 0xFFFFFFFF) << 0) +#define G_038008_BASE_ADDRESS(x) (((x) >> 0) & 0xFFFFFFFF) +#define C_038008_BASE_ADDRESS 0x00000000 +#define R_03800C_SQ_TEX_RESOURCE_WORD3_0 0x03800C +#define S_03800C_MIP_ADDRESS(x) (((x) & 0xFFFFFFFF) << 0) +#define G_03800C_MIP_ADDRESS(x) (((x) >> 0) & 0xFFFFFFFF) +#define C_03800C_MIP_ADDRESS 0x00000000 +#define R_038010_SQ_TEX_RESOURCE_WORD4_0 0x038010 +#define S_038010_FORMAT_COMP_X(x) (((x) & 0x3) << 0) +#define G_038010_FORMAT_COMP_X(x) (((x) >> 0) & 0x3) +#define C_038010_FORMAT_COMP_X 0xFFFFFFFC +#define V_038010_SQ_FORMAT_COMP_UNSIGNED 0x00000000 +#define V_038010_SQ_FORMAT_COMP_SIGNED 0x00000001 +#define V_038010_SQ_FORMAT_COMP_UNSIGNED_BIASED 0x00000002 +#define S_038010_FORMAT_COMP_Y(x) (((x) & 0x3) << 2) +#define G_038010_FORMAT_COMP_Y(x) (((x) >> 2) & 0x3) +#define C_038010_FORMAT_COMP_Y 0xFFFFFFF3 +#define S_038010_FORMAT_COMP_Z(x) (((x) & 0x3) << 4) +#define G_038010_FORMAT_COMP_Z(x) (((x) >> 4) & 0x3) +#define C_038010_FORMAT_COMP_Z 0xFFFFFFCF +#define S_038010_FORMAT_COMP_W(x) (((x) & 0x3) << 6) +#define G_038010_FORMAT_COMP_W(x) (((x) >> 6) & 0x3) +#define C_038010_FORMAT_COMP_W 0xFFFFFF3F +#define S_038010_NUM_FORMAT_ALL(x) (((x) & 0x3) << 8) +#define G_038010_NUM_FORMAT_ALL(x) (((x) >> 8) & 0x3) +#define C_038010_NUM_FORMAT_ALL 0xFFFFFCFF +#define V_038010_SQ_NUM_FORMAT_NORM 0x00000000 +#define V_038010_SQ_NUM_FORMAT_INT 0x00000001 +#define V_038010_SQ_NUM_FORMAT_SCALED 0x00000002 +#define S_038010_SRF_MODE_ALL(x) (((x) & 0x1) << 10) +#define G_038010_SRF_MODE_ALL(x) (((x) >> 10) & 0x1) +#define C_038010_SRF_MODE_ALL 0xFFFFFBFF +#define V_038010_SFR_MODE_ZERO_CLAMP_MINUS_ONE 0x00000000 +#define V_038010_SFR_MODE_NO_ZERO 0x00000001 +#define S_038010_FORCE_DEGAMMA(x) (((x) & 0x1) << 11) +#define G_038010_FORCE_DEGAMMA(x) (((x) >> 11) & 0x1) +#define C_038010_FORCE_DEGAMMA 0xFFFFF7FF +#define S_038010_ENDIAN_SWAP(x) (((x) & 0x3) << 12) +#define G_038010_ENDIAN_SWAP(x) (((x) >> 12) & 0x3) +#define C_038010_ENDIAN_SWAP 0xFFFFCFFF +#define S_038010_REQUEST_SIZE(x) (((x) & 0x3) << 14) +#define G_038010_REQUEST_SIZE(x) (((x) >> 14) & 0x3) +#define C_038010_REQUEST_SIZE 0xFFFF3FFF +#define S_038010_DST_SEL_X(x) (((x) & 0x7) << 16) +#define G_038010_DST_SEL_X(x) (((x) >> 16) & 0x7) +#define C_038010_DST_SEL_X 0xFFF8FFFF +#define V_038010_SQ_SEL_X 0x00000000 +#define V_038010_SQ_SEL_Y 0x00000001 +#define V_038010_SQ_SEL_Z 0x00000002 +#define V_038010_SQ_SEL_W 0x00000003 +#define V_038010_SQ_SEL_0 0x00000004 +#define V_038010_SQ_SEL_1 0x00000005 +#define S_038010_DST_SEL_Y(x) (((x) & 0x7) << 19) +#define G_038010_DST_SEL_Y(x) (((x) >> 19) & 0x7) +#define C_038010_DST_SEL_Y 0xFFC7FFFF +#define S_038010_DST_SEL_Z(x) (((x) & 0x7) << 22) +#define G_038010_DST_SEL_Z(x) (((x) >> 22) & 0x7) +#define C_038010_DST_SEL_Z 0xFE3FFFFF +#define S_038010_DST_SEL_W(x) (((x) & 0x7) << 25) +#define G_038010_DST_SEL_W(x) (((x) >> 25) & 0x7) +#define C_038010_DST_SEL_W 0xF1FFFFFF +#define S_038010_BASE_LEVEL(x) (((x) & 0xF) << 28) +#define G_038010_BASE_LEVEL(x) (((x) >> 28) & 0xF) +#define C_038010_BASE_LEVEL 0x0FFFFFFF +#define R_038014_SQ_TEX_RESOURCE_WORD5_0 0x038014 +#define S_038014_LAST_LEVEL(x) (((x) & 0xF) << 0) +#define G_038014_LAST_LEVEL(x) (((x) >> 0) & 0xF) +#define C_038014_LAST_LEVEL 0xFFFFFFF0 +#define S_038014_BASE_ARRAY(x) (((x) & 0x1FFF) << 4) +#define G_038014_BASE_ARRAY(x) (((x) >> 4) & 0x1FFF) +#define C_038014_BASE_ARRAY 0xFFFE000F +#define S_038014_LAST_ARRAY(x) (((x) & 0x1FFF) << 17) +#define G_038014_LAST_ARRAY(x) (((x) >> 17) & 0x1FFF) +#define C_038014_LAST_ARRAY 0xC001FFFF +#define R_038018_SQ_TEX_RESOURCE_WORD6_0 0x038018 +#define S_038018_MPEG_CLAMP(x) (((x) & 0x3) << 0) +#define G_038018_MPEG_CLAMP(x) (((x) >> 0) & 0x3) +#define C_038018_MPEG_CLAMP 0xFFFFFFFC +#define S_038018_PERF_MODULATION(x) (((x) & 0x7) << 5) +#define G_038018_PERF_MODULATION(x) (((x) >> 5) & 0x7) +#define C_038018_PERF_MODULATION 0xFFFFFF1F +#define S_038018_INTERLACED(x) (((x) & 0x1) << 8) +#define G_038018_INTERLACED(x) (((x) >> 8) & 0x1) +#define C_038018_INTERLACED 0xFFFFFEFF +#define S_038018_TYPE(x) (((x) & 0x3) << 30) +#define G_038018_TYPE(x) (((x) >> 30) & 0x3) +#define C_038018_TYPE 0x3FFFFFFF +#define V_038010_SQ_TEX_VTX_INVALID_TEXTURE 0x00000000 +#define V_038010_SQ_TEX_VTX_INVALID_BUFFER 0x00000001 +#define V_038010_SQ_TEX_VTX_VALID_TEXTURE 0x00000002 +#define V_038010_SQ_TEX_VTX_VALID_BUFFER 0x00000003 #define R_038008_SQ_VTX_CONSTANT_WORD2_0 0x038008 #define S_038008_BASE_ADDRESS_HI(x) (((x) & 0xFF) << 0) #define G_038008_BASE_ADDRESS_HI(x) (((x) >> 0) & 0xFF) @@ -633,6 +958,113 @@ #define S_038008_ENDIAN_SWAP(x) (((x) & 0x3) << 30) #define G_038008_ENDIAN_SWAP(x) (((x) >> 30) & 0x3) #define C_038008_ENDIAN_SWAP 0x3FFFFFFF +#define R_03C000_SQ_TEX_SAMPLER_WORD0_0 0x03C000 +#define S_03C000_CLAMP_X(x) (((x) & 0x7) << 0) +#define G_03C000_CLAMP_X(x) (((x) >> 0) & 0x7) +#define C_03C000_CLAMP_X 0xFFFFFFF8 +#define V_03C000_SQ_TEX_WRAP 0x00000000 +#define V_03C000_SQ_TEX_MIRROR 0x00000001 +#define V_03C000_SQ_TEX_CLAMP_LAST_TEXEL 0x00000002 +#define V_03C000_SQ_TEX_MIRROR_ONCE_LAST_TEXEL 0x00000003 +#define V_03C000_SQ_TEX_CLAMP_HALF_BORDER 0x00000004 +#define V_03C000_SQ_TEX_MIRROR_ONCE_HALF_BORDER 0x00000005 +#define V_03C000_SQ_TEX_CLAMP_BORDER 0x00000006 +#define V_03C000_SQ_TEX_MIRROR_ONCE_BORDER 0x00000007 +#define S_03C000_CLAMP_Y(x) (((x) & 0x7) << 3) +#define G_03C000_CLAMP_Y(x) (((x) >> 3) & 0x7) +#define C_03C000_CLAMP_Y 0xFFFFFFC7 +#define S_03C000_CLAMP_Z(x) (((x) & 0x7) << 6) +#define G_03C000_CLAMP_Z(x) (((x) >> 6) & 0x7) +#define C_03C000_CLAMP_Z 0xFFFFFE3F +#define S_03C000_XY_MAG_FILTER(x) (((x) & 0x7) << 9) +#define G_03C000_XY_MAG_FILTER(x) (((x) >> 9) & 0x7) +#define C_03C000_XY_MAG_FILTER 0xFFFFF1FF +#define V_03C000_SQ_TEX_XY_FILTER_POINT 0x00000000 +#define V_03C000_SQ_TEX_XY_FILTER_BILINEAR 0x00000001 +#define V_03C000_SQ_TEX_XY_FILTER_BICUBIC 0x00000002 +#define S_03C000_XY_MIN_FILTER(x) (((x) & 0x7) << 12) +#define G_03C000_XY_MIN_FILTER(x) (((x) >> 12) & 0x7) +#define C_03C000_XY_MIN_FILTER 0xFFFF8FFF +#define S_03C000_Z_FILTER(x) (((x) & 0x3) << 15) +#define G_03C000_Z_FILTER(x) (((x) >> 15) & 0x3) +#define C_03C000_Z_FILTER 0xFFFE7FFF +#define V_03C000_SQ_TEX_Z_FILTER_NONE 0x00000000 +#define V_03C000_SQ_TEX_Z_FILTER_POINT 0x00000001 +#define V_03C000_SQ_TEX_Z_FILTER_LINEAR 0x00000002 +#define S_03C000_MIP_FILTER(x) (((x) & 0x3) << 17) +#define G_03C000_MIP_FILTER(x) (((x) >> 17) & 0x3) +#define C_03C000_MIP_FILTER 0xFFF9FFFF +#define S_03C000_BORDER_COLOR_TYPE(x) (((x) & 0x3) << 22) +#define G_03C000_BORDER_COLOR_TYPE(x) (((x) >> 22) & 0x3) +#define C_03C000_BORDER_COLOR_TYPE 0xFF3FFFFF +#define V_03C000_SQ_TEX_BORDER_COLOR_TRANS_BLACK 0x00000000 +#define V_03C000_SQ_TEX_BORDER_COLOR_OPAQUE_BLACK 0x00000001 +#define V_03C000_SQ_TEX_BORDER_COLOR_OPAQUE_WHITE 0x00000002 +#define V_03C000_SQ_TEX_BORDER_COLOR_REGISTER 0x00000003 +#define S_03C000_POINT_SAMPLING_CLAMP(x) (((x) & 0x1) << 24) +#define G_03C000_POINT_SAMPLING_CLAMP(x) (((x) >> 24) & 0x1) +#define C_03C000_POINT_SAMPLING_CLAMP 0xFEFFFFFF +#define S_03C000_TEX_ARRAY_OVERRIDE(x) (((x) & 0x1) << 25) +#define G_03C000_TEX_ARRAY_OVERRIDE(x) (((x) >> 25) & 0x1) +#define C_03C000_TEX_ARRAY_OVERRIDE 0xFDFFFFFF +#define S_03C000_DEPTH_COMPARE_FUNCTION(x) (((x) & 0x7) << 26) +#define G_03C000_DEPTH_COMPARE_FUNCTION(x) (((x) >> 26) & 0x7) +#define C_03C000_DEPTH_COMPARE_FUNCTION 0xE3FFFFFF +#define V_03C000_SQ_TEX_DEPTH_COMPARE_NEVER 0x00000000 +#define V_03C000_SQ_TEX_DEPTH_COMPARE_LESS 0x00000001 +#define V_03C000_SQ_TEX_DEPTH_COMPARE_EQUAL 0x00000002 +#define V_03C000_SQ_TEX_DEPTH_COMPARE_LESSEQUAL 0x00000003 +#define V_03C000_SQ_TEX_DEPTH_COMPARE_GREATER 0x00000004 +#define V_03C000_SQ_TEX_DEPTH_COMPARE_NOTEQUAL 0x00000005 +#define V_03C000_SQ_TEX_DEPTH_COMPARE_GREATEREQUAL 0x00000006 +#define V_03C000_SQ_TEX_DEPTH_COMPARE_ALWAYS 0x00000007 +#define S_03C000_CHROMA_KEY(x) (((x) & 0x3) << 29) +#define G_03C000_CHROMA_KEY(x) (((x) >> 29) & 0x3) +#define C_03C000_CHROMA_KEY 0x9FFFFFFF +#define V_03C000_SQ_TEX_CHROMA_KEY_DISABLE 0x00000000 +#define V_03C000_SQ_TEX_CHROMA_KEY_KILL 0x00000001 +#define V_03C000_SQ_TEX_CHROMA_KEY_BLEND 0x00000002 +#define S_03C000_LOD_USES_MINOR_AXIS(x) (((x) & 0x1) << 31) +#define G_03C000_LOD_USES_MINOR_AXIS(x) (((x) >> 31) & 0x1) +#define C_03C000_LOD_USES_MINOR_AXIS 0x7FFFFFFF +#define R_03C004_SQ_TEX_SAMPLER_WORD1_0 0x03C004 +#define S_03C004_MIN_LOD(x) (((x) & 0x3FF) << 0) +#define G_03C004_MIN_LOD(x) (((x) >> 0) & 0x3FF) +#define C_03C004_MIN_LOD 0xFFFFFC00 +#define S_03C004_MAX_LOD(x) (((x) & 0x3FF) << 10) +#define G_03C004_MAX_LOD(x) (((x) >> 10) & 0x3FF) +#define C_03C004_MAX_LOD 0xFFF003FF +#define S_03C004_LOD_BIAS(x) (((x) & 0xFFF) << 20) +#define G_03C004_LOD_BIAS(x) (((x) >> 20) & 0xFFF) +#define C_03C004_LOD_BIAS 0x000FFFFF +#define R_03C008_SQ_TEX_SAMPLER_WORD2_0 0x03C008 +#define S_03C008_LOD_BIAS_SEC(x) (((x) & 0xFFF) << 0) +#define G_03C008_LOD_BIAS_SEC(x) (((x) >> 0) & 0xFFF) +#define C_03C008_LOD_BIAS_SEC 0xFFFFF000 +#define S_03C008_MC_COORD_TRUNCATE(x) (((x) & 0x1) << 12) +#define G_03C008_MC_COORD_TRUNCATE(x) (((x) >> 12) & 0x1) +#define C_03C008_MC_COORD_TRUNCATE 0xFFFFEFFF +#define S_03C008_FORCE_DEGAMMA(x) (((x) & 0x1) << 13) +#define G_03C008_FORCE_DEGAMMA(x) (((x) >> 13) & 0x1) +#define C_03C008_FORCE_DEGAMMA 0xFFFFDFFF +#define S_03C008_HIGH_PRECISION_FILTER(x) (((x) & 0x1) << 14) +#define G_03C008_HIGH_PRECISION_FILTER(x) (((x) >> 14) & 0x1) +#define C_03C008_HIGH_PRECISION_FILTER 0xFFFFBFFF +#define S_03C008_PERF_MIP(x) (((x) & 0x7) << 15) +#define G_03C008_PERF_MIP(x) (((x) >> 15) & 0x7) +#define C_03C008_PERF_MIP 0xFFFC7FFF +#define S_03C008_PERF_Z(x) (((x) & 0x3) << 18) +#define G_03C008_PERF_Z(x) (((x) >> 18) & 0x3) +#define C_03C008_PERF_Z 0xFFF3FFFF +#define S_03C008_FETCH_4(x) (((x) & 0x1) << 26) +#define G_03C008_FETCH_4(x) (((x) >> 26) & 0x1) +#define C_03C008_FETCH_4 0xFBFFFFFF +#define S_03C008_SAMPLE_IS_PCF(x) (((x) & 0x1) << 27) +#define G_03C008_SAMPLE_IS_PCF(x) (((x) >> 27) & 0x1) +#define C_03C008_SAMPLE_IS_PCF 0xF7FFFFFF +#define S_03C008_TYPE(x) (((x) & 0x1) << 31) +#define G_03C008_TYPE(x) (((x) >> 31) & 0x1) +#define C_03C008_TYPE 0x7FFFFFFF #define R_008958_VGT_PRIMITIVE_TYPE 0x008958 #define S_008958_PRIM_TYPE(x) (((x) & 0x3F) << 0) #define G_008958_PRIM_TYPE(x) (((x) >> 0) & 0x3F) diff --git a/src/gallium/drivers/r600/r700_asm.c b/src/gallium/drivers/r600/r700_asm.c index 3532ba5b0c6..1ebe20d6ab0 100644 --- a/src/gallium/drivers/r600/r700_asm.c +++ b/src/gallium/drivers/r600/r700_asm.c @@ -25,7 +25,6 @@ #include "util/u_memory.h" #include "r700_sq.h" #include <stdio.h> -#include <errno.h> int r700_bc_alu_build(struct r600_bc *bc, struct r600_bc_alu *alu, unsigned id) { diff --git a/src/gallium/drivers/rbug/rbug_context.c b/src/gallium/drivers/rbug/rbug_context.c index e0dd5cf8c2b..3ffda87520f 100644 --- a/src/gallium/drivers/rbug/rbug_context.c +++ b/src/gallium/drivers/rbug/rbug_context.c @@ -103,10 +103,7 @@ rbug_draw_block_locked(struct rbug_context *rb_pipe, int flag) } static void -rbug_draw_arrays(struct pipe_context *_pipe, - unsigned prim, - unsigned start, - unsigned count) +rbug_draw_vbo(struct pipe_context *_pipe, const struct pipe_draw_info *info) { struct rbug_context *rb_pipe = rbug_context(_pipe); struct pipe_context *pipe = rb_pipe->pipe; @@ -114,72 +111,7 @@ rbug_draw_arrays(struct pipe_context *_pipe, pipe_mutex_lock(rb_pipe->draw_mutex); rbug_draw_block_locked(rb_pipe, RBUG_BLOCK_BEFORE); - pipe->draw_arrays(pipe, - prim, - start, - count); - - rbug_draw_block_locked(rb_pipe, RBUG_BLOCK_AFTER); - pipe_mutex_unlock(rb_pipe->draw_mutex); -} - -static void -rbug_draw_elements(struct pipe_context *_pipe, - struct pipe_resource *_indexResource, - unsigned indexSize, - int indexBias, - unsigned prim, - unsigned start, - unsigned count) -{ - struct rbug_context *rb_pipe = rbug_context(_pipe); - struct rbug_resource *rb_resource = rbug_resource(_indexResource); - struct pipe_context *pipe = rb_pipe->pipe; - struct pipe_resource *indexResource = rb_resource->resource; - - pipe_mutex_lock(rb_pipe->draw_mutex); - rbug_draw_block_locked(rb_pipe, RBUG_BLOCK_BEFORE); - - pipe->draw_elements(pipe, - indexResource, - indexSize, - indexBias, - prim, - start, - count); - - rbug_draw_block_locked(rb_pipe, RBUG_BLOCK_AFTER); - pipe_mutex_unlock(rb_pipe->draw_mutex); -} - -static void -rbug_draw_range_elements(struct pipe_context *_pipe, - struct pipe_resource *_indexResource, - unsigned indexSize, - int indexBias, - unsigned minIndex, - unsigned maxIndex, - unsigned mode, - unsigned start, - unsigned count) -{ - struct rbug_context *rb_pipe = rbug_context(_pipe); - struct rbug_resource *rb_resource = rbug_resource(_indexResource); - struct pipe_context *pipe = rb_pipe->pipe; - struct pipe_resource *indexResource = rb_resource->resource; - - pipe_mutex_lock(rb_pipe->draw_mutex); - rbug_draw_block_locked(rb_pipe, RBUG_BLOCK_BEFORE); - - pipe->draw_range_elements(pipe, - indexResource, - indexSize, - indexBias, - minIndex, - maxIndex, - mode, - start, - count); + pipe->draw_vbo(pipe, info); rbug_draw_block_locked(rb_pipe, RBUG_BLOCK_AFTER); pipe_mutex_unlock(rb_pipe->draw_mutex); @@ -745,6 +677,23 @@ rbug_set_vertex_buffers(struct pipe_context *_pipe, } static void +rbug_set_index_buffer(struct pipe_context *_pipe, + const struct pipe_index_buffer *_ib) +{ + struct rbug_context *rb_pipe = rbug_context(_pipe); + struct pipe_context *pipe = rb_pipe->pipe; + struct pipe_index_buffer unwrapped_ib, *ib = NULL; + + if (_ib) { + unwrapped_ib = *_ib; + unwrapped_ib.buffer = rbug_resource_unwrap(_ib->buffer); + ib = &unwrapped_ib; + } + + pipe->set_index_buffer(pipe, ib); +} + +static void rbug_set_sample_mask(struct pipe_context *_pipe, unsigned sample_mask) { @@ -1040,9 +989,7 @@ rbug_context_create(struct pipe_screen *_screen, struct pipe_context *pipe) rb_pipe->base.draw = NULL; rb_pipe->base.destroy = rbug_destroy; - rb_pipe->base.draw_arrays = rbug_draw_arrays; - rb_pipe->base.draw_elements = rbug_draw_elements; - rb_pipe->base.draw_range_elements = rbug_draw_range_elements; + rb_pipe->base.draw_vbo = rbug_draw_vbo; rb_pipe->base.create_query = rbug_create_query; rb_pipe->base.destroy_query = rbug_destroy_query; rb_pipe->base.begin_query = rbug_begin_query; @@ -1084,6 +1031,7 @@ rbug_context_create(struct pipe_screen *_screen, struct pipe_context *pipe) rb_pipe->base.set_fragment_sampler_views = rbug_set_fragment_sampler_views; rb_pipe->base.set_vertex_sampler_views = rbug_set_vertex_sampler_views; rb_pipe->base.set_vertex_buffers = rbug_set_vertex_buffers; + rb_pipe->base.set_index_buffer = rbug_set_index_buffer; rb_pipe->base.set_sample_mask = rbug_set_sample_mask; rb_pipe->base.resource_copy_region = rbug_resource_copy_region; rb_pipe->base.clear = rbug_clear; diff --git a/src/gallium/drivers/softpipe/sp_context.c b/src/gallium/drivers/softpipe/sp_context.c index 12ef98aac75..a7c9959b3e1 100644 --- a/src/gallium/drivers/softpipe/sp_context.c +++ b/src/gallium/drivers/softpipe/sp_context.c @@ -282,12 +282,9 @@ softpipe_create_context( struct pipe_screen *screen, softpipe->pipe.set_viewport_state = softpipe_set_viewport_state; softpipe->pipe.set_stream_output_buffers = softpipe_set_stream_output_buffers; softpipe->pipe.set_vertex_buffers = softpipe_set_vertex_buffers; + softpipe->pipe.set_index_buffer = softpipe_set_index_buffer; - softpipe->pipe.draw_arrays = softpipe_draw_arrays; - softpipe->pipe.draw_elements = softpipe_draw_elements; - softpipe->pipe.draw_range_elements = softpipe_draw_range_elements; - softpipe->pipe.draw_arrays_instanced = softpipe_draw_arrays_instanced; - softpipe->pipe.draw_elements_instanced = softpipe_draw_elements_instanced; + softpipe->pipe.draw_vbo = softpipe_draw_vbo; softpipe->pipe.draw_stream_output = softpipe_draw_stream_output; softpipe->pipe.clear = softpipe_clear; diff --git a/src/gallium/drivers/softpipe/sp_context.h b/src/gallium/drivers/softpipe/sp_context.h index 53115a827d0..9361a3df09e 100644 --- a/src/gallium/drivers/softpipe/sp_context.h +++ b/src/gallium/drivers/softpipe/sp_context.h @@ -82,6 +82,7 @@ struct softpipe_context { struct pipe_sampler_view *geometry_sampler_views[PIPE_MAX_GEOMETRY_SAMPLERS]; struct pipe_viewport_state viewport; struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS]; + struct pipe_index_buffer index_buffer; struct { struct softpipe_resource *buffer[PIPE_MAX_SO_BUFFERS]; int offset[PIPE_MAX_SO_BUFFERS]; @@ -111,6 +112,7 @@ struct softpipe_context { /** Mapped constant buffers */ const void *mapped_constants[PIPE_SHADER_TYPES][PIPE_MAX_CONSTANT_BUFFERS]; + unsigned const_buffer_size[PIPE_SHADER_TYPES][PIPE_MAX_CONSTANT_BUFFERS]; /** Vertex format */ struct vertex_info vertex_info; diff --git a/src/gallium/drivers/softpipe/sp_draw_arrays.c b/src/gallium/drivers/softpipe/sp_draw_arrays.c index 9e727c93811..386c8acb8ce 100644 --- a/src/gallium/drivers/softpipe/sp_draw_arrays.c +++ b/src/gallium/drivers/softpipe/sp_draw_arrays.c @@ -111,27 +111,19 @@ softpipe_draw_stream_output(struct pipe_context *pipe, unsigned mode) * When the min/max element indexes aren't known, minIndex should be 0 * and maxIndex should be ~0. */ -static void -softpipe_draw_range_elements_instanced(struct pipe_context *pipe, - struct pipe_resource *indexBuffer, - unsigned indexSize, - int indexBias, - unsigned minIndex, - unsigned maxIndex, - unsigned mode, - unsigned start, - unsigned count, - unsigned startInstance, - unsigned instanceCount) +void +softpipe_draw_vbo(struct pipe_context *pipe, + const struct pipe_draw_info *info) { struct softpipe_context *sp = softpipe_context(pipe); struct draw_context *draw = sp->draw; + void *mapped_indices = NULL; unsigned i; if (!softpipe_check_render_cond(sp)) return; - sp->reduced_api_prim = u_reduced_prim(mode); + sp->reduced_api_prim = u_reduced_prim(info->mode); if (sp->dirty) { softpipe_update_derived(sp); @@ -146,31 +138,27 @@ softpipe_draw_range_elements_instanced(struct pipe_context *pipe, } /* Map index buffer, if present */ - if (indexBuffer) { - void *mapped_indexes = softpipe_resource(indexBuffer)->data; - draw_set_mapped_element_buffer_range(draw, - indexSize, - indexBias, - minIndex, - maxIndex, - mapped_indexes); - } else { - /* no index/element buffer */ - draw_set_mapped_element_buffer_range(draw, - 0, 0, - start, - start + count - 1, - NULL); + if (info->indexed && sp->index_buffer.buffer) { + char *indices = (char *) softpipe_resource(sp->index_buffer.buffer)->data; + mapped_indices = (void *) (indices + sp->index_buffer.offset); } + draw_set_mapped_element_buffer_range(draw, (mapped_indices) ? + sp->index_buffer.index_size : 0, + info->index_bias, + info->min_index, + info->max_index, + mapped_indices); + /* draw! */ - draw_arrays_instanced(draw, mode, start, count, startInstance, instanceCount); + draw_arrays_instanced(draw, info->mode, info->start, info->count, + info->start_instance, info->instance_count); /* unmap vertex/index buffers - will cause draw module to flush */ for (i = 0; i < sp->num_vertex_buffers; i++) { draw_set_mapped_vertex_buffer(draw, i, NULL); } - if (indexBuffer) { + if (mapped_indices) { draw_set_mapped_element_buffer(draw, 0, 0, NULL); } @@ -184,109 +172,3 @@ softpipe_draw_range_elements_instanced(struct pipe_context *pipe, /* Note: leave drawing surfaces mapped */ sp->dirty_render_cache = TRUE; } - - -void -softpipe_draw_range_elements(struct pipe_context *pipe, - struct pipe_resource *indexBuffer, - unsigned indexSize, - int indexBias, - unsigned min_index, - unsigned max_index, - unsigned mode, unsigned start, unsigned count) -{ - softpipe_draw_range_elements_instanced(pipe, - indexBuffer, - indexSize, - indexBias, - min_index, - max_index, - mode, - start, - count, - 0, - 1); -} - - -void -softpipe_draw_elements(struct pipe_context *pipe, - struct pipe_resource *indexBuffer, - unsigned indexSize, int indexBias, - unsigned mode, unsigned start, unsigned count) -{ - softpipe_draw_range_elements_instanced(pipe, - indexBuffer, - indexSize, - indexBias, - 0, - 0xffffffff, - mode, - start, - count, - 0, - 1); -} - -void -softpipe_draw_arrays_instanced(struct pipe_context *pipe, - unsigned mode, - unsigned start, - unsigned count, - unsigned startInstance, - unsigned instanceCount) -{ - softpipe_draw_range_elements_instanced(pipe, - NULL, - 0, - 0, - 0, - 0xffffffff, - mode, - start, - count, - startInstance, - instanceCount); -} - -void -softpipe_draw_elements_instanced(struct pipe_context *pipe, - struct pipe_resource *indexBuffer, - unsigned indexSize, - int indexBias, - unsigned mode, - unsigned start, - unsigned count, - unsigned startInstance, - unsigned instanceCount) -{ - softpipe_draw_range_elements_instanced(pipe, - indexBuffer, - indexSize, - indexBias, - 0, - 0xffffffff, - mode, - start, - count, - startInstance, - instanceCount); -} - -void -softpipe_draw_arrays(struct pipe_context *pipe, unsigned mode, - unsigned start, unsigned count) -{ - softpipe_draw_range_elements_instanced(pipe, - NULL, - 0, - 0, - 0, - 0xffffffff, - mode, - start, - count, - 0, - 1); -} - diff --git a/src/gallium/drivers/softpipe/sp_quad_fs.c b/src/gallium/drivers/softpipe/sp_quad_fs.c index d240bcbf3bb..90f4787d599 100644 --- a/src/gallium/drivers/softpipe/sp_quad_fs.c +++ b/src/gallium/drivers/softpipe/sp_quad_fs.c @@ -111,9 +111,10 @@ shade_quads(struct quad_stage *qs, struct tgsi_exec_machine *machine = softpipe->fs_machine; unsigned i, nr_quads = 0; - for (i = 0; i < PIPE_MAX_CONSTANT_BUFFERS; i++) { - machine->Consts[i] = softpipe->mapped_constants[PIPE_SHADER_FRAGMENT][i]; - } + tgsi_exec_set_constant_buffers(machine, PIPE_MAX_CONSTANT_BUFFERS, + softpipe->mapped_constants[PIPE_SHADER_FRAGMENT], + softpipe->const_buffer_size[PIPE_SHADER_FRAGMENT]); + machine->InterpCoefs = quads[0]->coef; for (i = 0; i < nr; i++) { diff --git a/src/gallium/drivers/softpipe/sp_state.h b/src/gallium/drivers/softpipe/sp_state.h index 7d6b86dce04..39d204de8a9 100644 --- a/src/gallium/drivers/softpipe/sp_state.h +++ b/src/gallium/drivers/softpipe/sp_state.h @@ -221,44 +221,16 @@ void softpipe_set_vertex_buffers(struct pipe_context *, unsigned count, const struct pipe_vertex_buffer *); - -void softpipe_update_derived( struct softpipe_context *softpipe ); +void softpipe_set_index_buffer(struct pipe_context *, + const struct pipe_index_buffer *); -void softpipe_draw_arrays(struct pipe_context *pipe, unsigned mode, - unsigned start, unsigned count); - -void softpipe_draw_elements(struct pipe_context *pipe, - struct pipe_resource *indexBuffer, - unsigned indexSize, int indexBias, - unsigned mode, unsigned start, unsigned count); -void -softpipe_draw_range_elements(struct pipe_context *pipe, - struct pipe_resource *indexBuffer, - unsigned indexSize, - int indexBias, - unsigned min_index, - unsigned max_index, - unsigned mode, unsigned start, unsigned count); +void softpipe_update_derived( struct softpipe_context *softpipe ); -void -softpipe_draw_arrays_instanced(struct pipe_context *pipe, - unsigned mode, - unsigned start, - unsigned count, - unsigned startInstance, - unsigned instanceCount); void -softpipe_draw_elements_instanced(struct pipe_context *pipe, - struct pipe_resource *indexBuffer, - unsigned indexSize, - int indexBias, - unsigned mode, - unsigned start, - unsigned count, - unsigned startInstance, - unsigned instanceCount); +softpipe_draw_vbo(struct pipe_context *pipe, + const struct pipe_draw_info *info); void softpipe_draw_stream_output(struct pipe_context *pipe, unsigned mode); diff --git a/src/gallium/drivers/softpipe/sp_state_fs.c b/src/gallium/drivers/softpipe/sp_state_fs.c index 3fbf1f25781..ded242d3dc5 100644 --- a/src/gallium/drivers/softpipe/sp_state_fs.c +++ b/src/gallium/drivers/softpipe/sp_state_fs.c @@ -195,6 +195,8 @@ softpipe_set_constant_buffer(struct pipe_context *pipe, } softpipe->mapped_constants[shader][index] = data; + softpipe->const_buffer_size[shader][index] = size; + softpipe->dirty |= SP_NEW_CONSTANTS; } diff --git a/src/gallium/drivers/softpipe/sp_state_vertex.c b/src/gallium/drivers/softpipe/sp_state_vertex.c index 462f4d2655e..880a7c7cd26 100644 --- a/src/gallium/drivers/softpipe/sp_state_vertex.c +++ b/src/gallium/drivers/softpipe/sp_state_vertex.c @@ -88,3 +88,17 @@ softpipe_set_vertex_buffers(struct pipe_context *pipe, draw_set_vertex_buffers(softpipe->draw, count, buffers); } + +void +softpipe_set_index_buffer(struct pipe_context *pipe, + const struct pipe_index_buffer *ib) +{ + struct softpipe_context *softpipe = softpipe_context(pipe); + + if (ib) + memcpy(&softpipe->index_buffer, ib, sizeof(softpipe->index_buffer)); + else + memset(&softpipe->index_buffer, 0, sizeof(softpipe->index_buffer)); + + /* TODO make this more like a state */ +} diff --git a/src/gallium/drivers/svga/svga_context.h b/src/gallium/drivers/svga/svga_context.h index 9a46de643fd..67a7614c8af 100644 --- a/src/gallium/drivers/svga/svga_context.h +++ b/src/gallium/drivers/svga/svga_context.h @@ -190,6 +190,7 @@ struct svga_state struct svga_vertex_shader *vs; struct pipe_vertex_buffer vb[PIPE_MAX_ATTRIBS]; + struct pipe_index_buffer ib; struct pipe_resource *cb[PIPE_SHADER_TYPES]; struct pipe_framebuffer_state framebuffer; diff --git a/src/gallium/drivers/svga/svga_pipe_draw.c b/src/gallium/drivers/svga/svga_pipe_draw.c index 58e930d9835..de08bc5e562 100644 --- a/src/gallium/drivers/svga/svga_pipe_draw.c +++ b/src/gallium/drivers/svga/svga_pipe_draw.c @@ -227,31 +227,30 @@ svga_draw_range_elements( struct pipe_context *pipe, static void -svga_draw_elements( struct pipe_context *pipe, - struct pipe_resource *index_buffer, - unsigned index_size, int index_bias, - unsigned prim, unsigned start, unsigned count) +svga_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info) { - svga_draw_range_elements( pipe, index_buffer, - index_size, index_bias, - 0, 0xffffffff, - prim, start, count ); -} + struct svga_context *svga = svga_context(pipe); -static void -svga_draw_arrays( struct pipe_context *pipe, - unsigned prim, unsigned start, unsigned count) -{ - svga_draw_range_elements(pipe, NULL, 0, 0, - start, start + count - 1, - prim, - start, count); + if (info->indexed && svga->curr.ib.buffer) { + unsigned offset; + + assert(svga->curr.ib.offset % svga->curr.ib.index_size == 0); + offset = svga->curr.ib.offset / svga->curr.ib.index_size; + + svga_draw_range_elements(pipe, svga->curr.ib.buffer, + svga->curr.ib.index_size, info->index_bias, + info->min_index, info->max_index, + info->mode, info->start + offset, info->count); + } + else { + svga_draw_range_elements(pipe, NULL, 0, 0, + info->min_index, info->max_index, + info->mode, info->start, info->count); + } } void svga_init_draw_functions( struct svga_context *svga ) { - svga->pipe.draw_arrays = svga_draw_arrays; - svga->pipe.draw_elements = svga_draw_elements; - svga->pipe.draw_range_elements = svga_draw_range_elements; + svga->pipe.draw_vbo = svga_draw_vbo; } diff --git a/src/gallium/drivers/svga/svga_pipe_vertex.c b/src/gallium/drivers/svga/svga_pipe_vertex.c index 23808ad08e0..86c79459f3e 100644 --- a/src/gallium/drivers/svga/svga_pipe_vertex.c +++ b/src/gallium/drivers/svga/svga_pipe_vertex.c @@ -66,6 +66,24 @@ static void svga_set_vertex_buffers(struct pipe_context *pipe, } +static void svga_set_index_buffer(struct pipe_context *pipe, + const struct pipe_index_buffer *ib) +{ + struct svga_context *svga = svga_context(pipe); + + if (ib) { + pipe_resource_reference(&svga->curr.ib.buffer, ib->buffer); + memcpy(&svga->curr.ib, ib, sizeof(svga->curr.ib)); + } + else { + pipe_resource_reference(&svga->curr.ib.buffer, NULL); + memset(&svga->curr.ib, 0, sizeof(svga->curr.ib)); + } + + /* TODO make this more like a state */ +} + + static void * svga_create_vertex_elements_state(struct pipe_context *pipe, unsigned count, @@ -109,6 +127,7 @@ void svga_cleanup_vertex_state( struct svga_context *svga ) void svga_init_vertex_functions( struct svga_context *svga ) { svga->pipe.set_vertex_buffers = svga_set_vertex_buffers; + svga->pipe.set_index_buffer = svga_set_index_buffer; svga->pipe.create_vertex_elements_state = svga_create_vertex_elements_state; svga->pipe.bind_vertex_elements_state = svga_bind_vertex_elements_state; svga->pipe.delete_vertex_elements_state = svga_delete_vertex_elements_state; diff --git a/src/gallium/drivers/trace/tr_context.c b/src/gallium/drivers/trace/tr_context.c index 55dd6cf8837..84e5a6a8242 100644 --- a/src/gallium/drivers/trace/tr_context.c +++ b/src/gallium/drivers/trace/tr_context.c @@ -83,85 +83,26 @@ trace_surface_unwrap(struct trace_context *tr_ctx, static INLINE void -trace_context_draw_arrays(struct pipe_context *_pipe, - unsigned mode, unsigned start, unsigned count) +trace_context_draw_vbo(struct pipe_context *_pipe, + const struct pipe_draw_info *info) { struct trace_context *tr_ctx = trace_context(_pipe); struct pipe_context *pipe = tr_ctx->pipe; - trace_dump_call_begin("pipe_context", "draw_arrays"); + trace_dump_call_begin("pipe_context", "draw_vbo"); - trace_dump_arg(ptr, pipe); - trace_dump_arg(uint, mode); - trace_dump_arg(uint, start); - trace_dump_arg(uint, count); - - pipe->draw_arrays(pipe, mode, start, count); - - trace_dump_call_end(); -} - - -static INLINE void -trace_context_draw_elements(struct pipe_context *_pipe, - struct pipe_resource *_indexBuffer, - unsigned indexSize, int indexBias, - unsigned mode, unsigned start, unsigned count) -{ - struct trace_context *tr_ctx = trace_context(_pipe); - struct trace_resource *tr_buf = trace_resource(_indexBuffer); - struct pipe_context *pipe = tr_ctx->pipe; - struct pipe_resource *indexBuffer = tr_buf->resource; - - trace_dump_call_begin("pipe_context", "draw_elements"); - - trace_dump_arg(ptr, pipe); - trace_dump_arg(ptr, indexBuffer); - trace_dump_arg(uint, indexSize); - trace_dump_arg(int, indexBias); - trace_dump_arg(uint, mode); - trace_dump_arg(uint, start); - trace_dump_arg(uint, count); - - pipe->draw_elements(pipe, indexBuffer, indexSize, indexBias, - mode, start, count); - - trace_dump_call_end(); -} - - -static INLINE void -trace_context_draw_range_elements(struct pipe_context *_pipe, - struct pipe_resource *_indexBuffer, - unsigned indexSize, - int indexBias, - unsigned minIndex, - unsigned maxIndex, - unsigned mode, - unsigned start, - unsigned count) -{ - struct trace_context *tr_ctx = trace_context(_pipe); - struct trace_resource *tr_buf = trace_resource(_indexBuffer); - struct pipe_context *pipe = tr_ctx->pipe; - struct pipe_resource *indexBuffer = tr_buf->resource; - - trace_dump_call_begin("pipe_context", "draw_range_elements"); + trace_dump_arg(ptr, pipe); + trace_dump_arg(bool, info->indexed); + trace_dump_arg(uint, info->mode); + trace_dump_arg(uint, info->start); + trace_dump_arg(uint, info->count); + trace_dump_arg(uint, info->start_instance); + trace_dump_arg(uint, info->instance_count); + trace_dump_arg(int, info->index_bias); + trace_dump_arg(uint, info->min_index); + trace_dump_arg(uint, info->max_index); - trace_dump_arg(ptr, pipe); - trace_dump_arg(ptr, indexBuffer); - trace_dump_arg(uint, indexSize); - trace_dump_arg(int, indexBias); - trace_dump_arg(uint, minIndex); - trace_dump_arg(uint, maxIndex); - trace_dump_arg(uint, mode); - trace_dump_arg(uint, start); - trace_dump_arg(uint, count); - - pipe->draw_range_elements(pipe, - indexBuffer, indexSize, indexBias, - minIndex, maxIndex, - mode, start, count); + pipe->draw_vbo(pipe, info); trace_dump_call_end(); } @@ -1045,6 +986,30 @@ trace_context_set_vertex_buffers(struct pipe_context *_pipe, static INLINE void +trace_context_set_index_buffer(struct pipe_context *_pipe, + const struct pipe_index_buffer *_ib) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct pipe_context *pipe = tr_ctx->pipe; + struct pipe_index_buffer unwrapped_ib, *ib = NULL; + + if (_ib) { + unwrapped_ib = *_ib; + unwrapped_ib.buffer = trace_resource_unwrap(tr_ctx, _ib->buffer); + ib = &unwrapped_ib; + } + + trace_dump_call_begin("pipe_context", "set_index_buffer"); + + trace_dump_arg(ptr, pipe); + trace_dump_arg(index_buffer, ib); + + pipe->set_index_buffer(pipe, ib); + + trace_dump_call_end(); +} + +static INLINE void trace_context_resource_copy_region(struct pipe_context *_pipe, struct pipe_resource *dst, struct pipe_subresource subdst, @@ -1433,9 +1398,7 @@ trace_context_create(struct trace_screen *tr_scr, tr_ctx->base.screen = &tr_scr->base; tr_ctx->base.destroy = trace_context_destroy; - tr_ctx->base.draw_arrays = trace_context_draw_arrays; - tr_ctx->base.draw_elements = trace_context_draw_elements; - tr_ctx->base.draw_range_elements = trace_context_draw_range_elements; + tr_ctx->base.draw_vbo = trace_context_draw_vbo; tr_ctx->base.create_query = trace_context_create_query; tr_ctx->base.destroy_query = trace_context_destroy_query; tr_ctx->base.begin_query = trace_context_begin_query; @@ -1477,6 +1440,7 @@ trace_context_create(struct trace_screen *tr_scr, tr_ctx->base.create_sampler_view = trace_create_sampler_view; tr_ctx->base.sampler_view_destroy = trace_sampler_view_destroy; tr_ctx->base.set_vertex_buffers = trace_context_set_vertex_buffers; + tr_ctx->base.set_index_buffer = trace_context_set_index_buffer; tr_ctx->base.resource_copy_region = trace_context_resource_copy_region; tr_ctx->base.clear = trace_context_clear; tr_ctx->base.clear_render_target = trace_context_clear_render_target; diff --git a/src/gallium/drivers/trace/tr_dump_state.c b/src/gallium/drivers/trace/tr_dump_state.c index 1727c2a0206..bd9a9bfaf16 100644 --- a/src/gallium/drivers/trace/tr_dump_state.c +++ b/src/gallium/drivers/trace/tr_dump_state.c @@ -533,6 +533,26 @@ void trace_dump_vertex_buffer(const struct pipe_vertex_buffer *state) } +void trace_dump_index_buffer(const struct pipe_index_buffer *state) +{ + if (!trace_dumping_enabled_locked()) + return; + + if(!state) { + trace_dump_null(); + return; + } + + trace_dump_struct_begin("pipe_index_buffer"); + + trace_dump_member(uint, state, index_size); + trace_dump_member(uint, state, offset); + trace_dump_member(resource_ptr, state, buffer); + + trace_dump_struct_end(); +} + + void trace_dump_vertex_element(const struct pipe_vertex_element *state) { if (!trace_dumping_enabled_locked()) diff --git a/src/gallium/drivers/trace/tr_dump_state.h b/src/gallium/drivers/trace/tr_dump_state.h index e614e8355e3..2e70f4e1c74 100644 --- a/src/gallium/drivers/trace/tr_dump_state.h +++ b/src/gallium/drivers/trace/tr_dump_state.h @@ -75,6 +75,8 @@ void trace_dump_transfer(const struct pipe_transfer *state); void trace_dump_vertex_buffer(const struct pipe_vertex_buffer *state); +void trace_dump_index_buffer(const struct pipe_index_buffer *state); + void trace_dump_vertex_element(const struct pipe_vertex_element *state); diff --git a/src/gallium/include/pipe/p_context.h b/src/gallium/include/pipe/p_context.h index 7ec3d63a3fd..0579962ec69 100644 --- a/src/gallium/include/pipe/p_context.h +++ b/src/gallium/include/pipe/p_context.h @@ -61,46 +61,8 @@ struct pipe_context { * VBO drawing */ /*@{*/ - void (*draw_arrays)( struct pipe_context *pipe, - unsigned mode, unsigned start, unsigned count); - - void (*draw_elements)( struct pipe_context *pipe, - struct pipe_resource *indexBuffer, - unsigned indexSize, - int indexBias, - unsigned mode, unsigned start, unsigned count); - - void (*draw_arrays_instanced)(struct pipe_context *pipe, - unsigned mode, - unsigned start, - unsigned count, - unsigned startInstance, - unsigned instanceCount); - - void (*draw_elements_instanced)(struct pipe_context *pipe, - struct pipe_resource *indexBuffer, - unsigned indexSize, - int indexBias, - unsigned mode, - unsigned start, - unsigned count, - unsigned startInstance, - unsigned instanceCount); - - /* XXX: this is (probably) a temporary entrypoint, as the range - * information should be available from the vertex_buffer state. - * Using this to quickly evaluate a specialized path in the draw - * module. - */ - void (*draw_range_elements)( struct pipe_context *pipe, - struct pipe_resource *indexBuffer, - unsigned indexSize, - int indexBias, - unsigned minIndex, - unsigned maxIndex, - unsigned mode, - unsigned start, - unsigned count); + void (*draw_vbo)( struct pipe_context *pipe, + const struct pipe_draw_info *info ); /** * Draw the stream output buffer at index 0 @@ -249,6 +211,9 @@ struct pipe_context { unsigned num_buffers, const struct pipe_vertex_buffer * ); + void (*set_index_buffer)( struct pipe_context *pipe, + const struct pipe_index_buffer * ); + void (*set_stream_output_buffers)(struct pipe_context *, struct pipe_resource **buffers, int *offsets, /*array of offsets diff --git a/src/gallium/include/pipe/p_state.h b/src/gallium/include/pipe/p_state.h index 301fe2b74f0..0f1a44cde42 100644 --- a/src/gallium/include/pipe/p_state.h +++ b/src/gallium/include/pipe/p_state.h @@ -426,6 +426,41 @@ struct pipe_vertex_element }; +/** + * An index buffer. When an index buffer is bound, all indices to vertices + * will be looked up in the buffer. + */ +struct pipe_index_buffer +{ + unsigned index_size; /**< size of an index, in bytes */ + unsigned offset; /**< offset to start of data in buffer, in bytes */ + struct pipe_resource *buffer; /**< the actual buffer */ +}; + + +/** + * Information to describe a draw_vbo call. + */ +struct pipe_draw_info +{ + boolean indexed; /**< use index buffer */ + + unsigned mode; /**< the mode of the primitive */ + unsigned start; /**< the index of the first vertex */ + unsigned count; /**< number of vertices */ + + unsigned start_instance; /**< first instance id */ + unsigned instance_count; /**< number of instances */ + + /** + * For indexed drawing, these fields apply after index lookup. + */ + int index_bias; /**< a bias to be added to each index */ + unsigned min_index; /**< the min index */ + unsigned max_index; /**< the max index */ +}; + + #ifdef __cplusplus } #endif diff --git a/src/gallium/state_trackers/dri/common/dri1_helper.c b/src/gallium/state_trackers/dri/common/dri1_helper.c deleted file mode 100644 index ad6c7d37504..00000000000 --- a/src/gallium/state_trackers/dri/common/dri1_helper.c +++ /dev/null @@ -1,129 +0,0 @@ -/************************************************************************** - * - * 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. - * - * 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 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. - * - **************************************************************************/ -/* - * Management of pipe objects (surface / pipe / fences) used by DRI1 and DRISW. - * - * Author: Keith Whitwell <[email protected]> - * Author: Jakob Bornecrantz <[email protected]> - */ - -#include "util/u_inlines.h" -#include "pipe/p_context.h" - -#include "dri_screen.h" -#include "dri_context.h" -#include "dri_drawable.h" -#include "dri1_helper.h" - -struct pipe_fence_handle * -dri1_swap_fences_pop_front(struct dri_drawable *draw) -{ - struct pipe_screen *screen = dri_screen(draw->sPriv)->base.screen; - struct pipe_fence_handle *fence = NULL; - - if (draw->cur_fences >= draw->desired_fences) { - screen->fence_reference(screen, &fence, draw->swap_fences[draw->tail]); - screen->fence_reference(screen, &draw->swap_fences[draw->tail++], NULL); - --draw->cur_fences; - draw->tail &= DRI_SWAP_FENCES_MASK; - } - return fence; -} - -void -dri1_swap_fences_push_back(struct dri_drawable *draw, - struct pipe_fence_handle *fence) -{ - struct pipe_screen *screen = dri_screen(draw->sPriv)->base.screen; - - if (!fence) - return; - - if (draw->cur_fences < DRI_SWAP_FENCES_MAX) { - draw->cur_fences++; - screen->fence_reference(screen, &draw->swap_fences[draw->head++], - fence); - draw->head &= DRI_SWAP_FENCES_MASK; - } -} - -void -dri1_swap_fences_clear(struct dri_drawable *drawable) -{ - struct pipe_screen *screen = dri_screen(drawable->sPriv)->base.screen; - struct pipe_fence_handle *fence; - - while (drawable->cur_fences) { - fence = dri1_swap_fences_pop_front(drawable); - screen->fence_reference(screen, &fence, NULL); - } -} - -struct pipe_surface * -dri1_get_pipe_surface(struct dri_drawable *drawable, struct pipe_resource *ptex) -{ - struct pipe_screen *pipe_screen = dri_screen(drawable->sPriv)->base.screen; - struct pipe_surface *psurf = drawable->dri1_surface; - - if (!psurf || psurf->texture != ptex) { - pipe_surface_reference(&drawable->dri1_surface, NULL); - - drawable->dri1_surface = pipe_screen->get_tex_surface(pipe_screen, - ptex, 0, 0, 0, 0/* no bind flag???*/); - - psurf = drawable->dri1_surface; - } - - return psurf; -} - -void -dri1_destroy_pipe_surface(struct dri_drawable *drawable) -{ - pipe_surface_reference(&drawable->dri1_surface, NULL); -} - -struct pipe_context * -dri1_get_pipe_context(struct dri_screen *screen) -{ - struct pipe_context *pipe = screen->dri1_pipe; - - if (!pipe) { - screen->dri1_pipe = - screen->base.screen->context_create(screen->base.screen, NULL); - pipe = screen->dri1_pipe; - } - - return pipe; -} - -void -dri1_destroy_pipe_context(struct dri_screen *screen) -{ - if (screen->dri1_pipe) - screen->dri1_pipe->destroy(screen->dri1_pipe); -} diff --git a/src/gallium/state_trackers/dri/common/dri1_helper.h b/src/gallium/state_trackers/dri/common/dri1_helper.h deleted file mode 100644 index c98adf2df22..00000000000 --- a/src/gallium/state_trackers/dri/common/dri1_helper.h +++ /dev/null @@ -1,61 +0,0 @@ -/************************************************************************** - * - * 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. - * - * 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 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. - * - **************************************************************************/ -/* - * Author: Keith Whitwell <[email protected]> - * Author: Jakob Bornecrantz <[email protected]> - */ - -#ifndef DRI1_HELPER_H -#define DRI1_HELPER_H - -#include "dri_screen.h" -#include "dri_context.h" -#include "dri_drawable.h" - -struct pipe_fence_handle * -dri1_swap_fences_pop_front(struct dri_drawable *draw); - -void -dri1_swap_fences_push_back(struct dri_drawable *draw, - struct pipe_fence_handle *fence); - -void -dri1_swap_fences_clear(struct dri_drawable *drawable); - -struct pipe_surface * -dri1_get_pipe_surface(struct dri_drawable *drawable, struct pipe_resource *ptex); - -void -dri1_destroy_pipe_surface(struct dri_drawable *drawable); - -struct pipe_context * -dri1_get_pipe_context(struct dri_screen *screen); - -void -dri1_destroy_pipe_context(struct dri_screen *screen); - -#endif /* DRI1_HELPER_H */ diff --git a/src/gallium/state_trackers/dri/common/dri_context.h b/src/gallium/state_trackers/dri/common/dri_context.h index b29e8533837..692c49d7cd5 100644 --- a/src/gallium/state_trackers/dri/common/dri_context.h +++ b/src/gallium/state_trackers/dri/common/dri_context.h @@ -60,6 +60,9 @@ struct dri_context /* gallium */ struct st_context_iface *st; + + /* hooks filled in by dri2 & drisw */ + __DRIimage * (*lookup_egl_image)(struct dri_context *ctx, void *handle); }; static INLINE struct dri_context * diff --git a/src/gallium/state_trackers/dri/common/dri_drawable.c b/src/gallium/state_trackers/dri/common/dri_drawable.c index 2bc0faffeff..c67ca2224d0 100644 --- a/src/gallium/state_trackers/dri/common/dri_drawable.c +++ b/src/gallium/state_trackers/dri/common/dri_drawable.c @@ -30,9 +30,7 @@ */ #include "dri_screen.h" -#include "dri_context.h" #include "dri_drawable.h" -#include "dri1_helper.h" #include "pipe/p_screen.h" #include "util/u_format.h" @@ -68,10 +66,10 @@ dri_st_framebuffer_validate(struct st_framebuffer_iface *stfbi, new_stamp = (drawable->texture_stamp != drawable->dPriv->lastStamp); if (new_stamp || new_mask || screen->broken_invalidate) { - if (new_stamp && screen->update_drawable_info) - screen->update_drawable_info(drawable); + if (new_stamp && drawable->update_drawable_info) + drawable->update_drawable_info(drawable); - screen->allocate_textures(drawable, statts, count); + drawable->allocate_textures(drawable, statts, count); /* add existing textures */ for (i = 0; i < ST_ATTACHMENT_COUNT; i++) { @@ -100,10 +98,9 @@ dri_st_framebuffer_flush_front(struct st_framebuffer_iface *stfbi, { struct dri_drawable *drawable = (struct dri_drawable *) stfbi->st_manager_private; - struct dri_screen *screen = dri_screen(drawable->sPriv); /* XXX remove this and just set the correct one on the framebuffer */ - screen->flush_frontbuffer(drawable, statt); + drawable->flush_frontbuffer(drawable, statt); return TRUE; } @@ -138,8 +135,6 @@ dri_create_buffer(__DRIscreen * sPriv, drawable->dPriv = dPriv; dPriv->driverPrivate = (void *)drawable; - drawable->desired_fences = 2; - return GL_TRUE; fail: FREE(drawable); @@ -152,15 +147,11 @@ dri_destroy_buffer(__DRIdrawable * dPriv) struct dri_drawable *drawable = dri_drawable(dPriv); int i; - dri1_swap_fences_clear(drawable); - - dri1_destroy_pipe_surface(drawable); + pipe_surface_reference(&drawable->drisw_surface, NULL); for (i = 0; i < ST_ATTACHMENT_COUNT; i++) pipe_resource_reference(&drawable->textures[i], NULL); - drawable->desired_fences = 0; - FREE(drawable); } diff --git a/src/gallium/state_trackers/dri/common/dri_drawable.h b/src/gallium/state_trackers/dri/common/dri_drawable.h index 5fd650ac88e..3f2e24fc158 100644 --- a/src/gallium/state_trackers/dri/common/dri_drawable.h +++ b/src/gallium/state_trackers/dri/common/dri_drawable.h @@ -33,13 +33,9 @@ #include "state_tracker/st_api.h" struct pipe_surface; -struct pipe_fence_handle; struct st_framebuffer; struct dri_context; -#define DRI_SWAP_FENCES_MAX 8 -#define DRI_SWAP_FENCES_MASK 7 - struct dri_drawable { struct st_framebuffer_iface base; @@ -57,14 +53,18 @@ struct dri_drawable struct pipe_resource *textures[ST_ATTACHMENT_COUNT]; unsigned int texture_mask, texture_stamp; - struct pipe_fence_handle *swap_fences[DRI_SWAP_FENCES_MAX]; - unsigned int head; - unsigned int tail; - unsigned int desired_fences; - unsigned int cur_fences; + /* used only by DRISW */ + struct pipe_surface *drisw_surface; + + /* hooks filled in by dri2 & drisw */ + void (*allocate_textures)(struct dri_drawable *drawable, + const enum st_attachment_type *statts, + unsigned count); + + void (*update_drawable_info)(struct dri_drawable *drawable); - /* used only by DRI1 */ - struct pipe_surface *dri1_surface; + void (*flush_frontbuffer)(struct dri_drawable *drawable, + enum st_attachment_type statt); }; static INLINE struct dri_drawable * diff --git a/src/gallium/state_trackers/dri/common/dri_screen.c b/src/gallium/state_trackers/dri/common/dri_screen.c index 25cad8d46c4..6ad2c7da4d6 100644 --- a/src/gallium/state_trackers/dri/common/dri_screen.c +++ b/src/gallium/state_trackers/dri/common/dri_screen.c @@ -30,20 +30,10 @@ */ #include "utils.h" -#ifndef __NOT_HAVE_DRM_H -#include "vblank.h" -#endif #include "xmlpool.h" #include "dri_screen.h" #include "dri_context.h" -#include "dri_drawable.h" -#include "dri1_helper.h" -#ifndef __NOT_HAVE_DRM_H -#include "dri2.h" -#else -#include "drisw.h" -#endif #include "util/u_inlines.h" #include "pipe/p_screen.h" @@ -303,11 +293,10 @@ dri_get_egl_image(struct st_manager *smapi, { struct dri_context *ctx = (struct dri_context *)stctxi->st_manager_private; - struct dri_screen *screen = dri_screen(ctx->sPriv); __DRIimage *img = NULL; - if (screen->lookup_egl_image) { - img = screen->lookup_egl_image(ctx, egl_image); + if (ctx->lookup_egl_image) { + img = ctx->lookup_egl_image(ctx, egl_image); } if (!img) @@ -355,8 +344,6 @@ dri_destroy_option_cache(struct dri_screen * screen) void dri_destroy_screen_helper(struct dri_screen * screen) { - dri1_destroy_pipe_context(screen); - if (screen->st_api && screen->st_api->destroy) screen->st_api->destroy(screen->st_api); @@ -366,7 +353,7 @@ dri_destroy_screen_helper(struct dri_screen * screen) dri_destroy_option_cache(screen); } -static void +void dri_destroy_screen(__DRIscreen * sPriv) { struct dri_screen *screen = dri_screen(sPriv); @@ -402,38 +389,4 @@ dri_init_screen_helper(struct dri_screen *screen, return dri_fill_in_modes(screen, pixel_bits); } -/** - * DRI driver virtual function table. - * - * DRI versions differ in their implementation of init_screen and swap_buffers. - */ -const struct __DriverAPIRec driDriverAPI = { - .DestroyScreen = dri_destroy_screen, - .CreateContext = dri_create_context, - .DestroyContext = dri_destroy_context, - .CreateBuffer = dri_create_buffer, - .DestroyBuffer = dri_destroy_buffer, - .MakeCurrent = dri_make_current, - .UnbindContext = dri_unbind_context, - -#ifndef __NOT_HAVE_DRM_H - - .GetSwapInfo = NULL, - .GetDrawableMSC = NULL, - .WaitForMSC = NULL, - .InitScreen2 = dri2_init_screen, - - .InitScreen = NULL, - .SwapBuffers = NULL, - .CopySubBuffer = NULL, - -#else - - .InitScreen = drisw_init_screen, - .SwapBuffers = drisw_swap_buffers, - -#endif - -}; - /* vim: set sw=3 ts=8 sts=3 expandtab: */ diff --git a/src/gallium/state_trackers/dri/common/dri_screen.h b/src/gallium/state_trackers/dri/common/dri_screen.h index 087ae8d2a4a..53ccce145ba 100644 --- a/src/gallium/state_trackers/dri/common/dri_screen.h +++ b/src/gallium/state_trackers/dri/common/dri_screen.h @@ -64,22 +64,10 @@ struct dri_screen int fd; drmLock *drmLock; - /* hooks filled in by dri1, dri2 & drisw */ - __DRIimage * (*lookup_egl_image)(struct dri_context *ctx, void *handle); - void (*allocate_textures)(struct dri_drawable *drawable, - const enum st_attachment_type *statts, - unsigned count); - void (*update_drawable_info)(struct dri_drawable *drawable); - void (*flush_frontbuffer)(struct dri_drawable *drawable, - enum st_attachment_type statt); - /* gallium */ boolean d_depth_bits_last; boolean sd_depth_bits_last; boolean auto_fake_front; - - /* used only by DRI1 */ - struct pipe_context *dri1_pipe; }; /** cast wrapper */ @@ -132,6 +120,9 @@ dri_init_screen_helper(struct dri_screen *screen, void dri_destroy_screen_helper(struct dri_screen * screen); +void +dri_destroy_screen(__DRIscreen * sPriv); + #endif /* vim: set sw=3 ts=8 sts=3 expandtab: */ diff --git a/src/gallium/state_trackers/dri/drm/Makefile b/src/gallium/state_trackers/dri/drm/Makefile index 94fa61fec73..c717b2bdeb5 100644 --- a/src/gallium/state_trackers/dri/drm/Makefile +++ b/src/gallium/state_trackers/dri/drm/Makefile @@ -17,7 +17,6 @@ C_SOURCES = \ dri_context.c \ dri_screen.c \ dri_drawable.c \ - dri1_helper.c \ dri2.c # $(TOP)/src/mesa/drivers/dri/common/utils.c \ diff --git a/src/gallium/state_trackers/dri/drm/SConscript b/src/gallium/state_trackers/dri/drm/SConscript index 0c279d22366..2a0af65f9bd 100644 --- a/src/gallium/state_trackers/dri/drm/SConscript +++ b/src/gallium/state_trackers/dri/drm/SConscript @@ -21,7 +21,6 @@ if env['dri']: source = [ 'dri_context.c', 'dri_drawable.c', 'dri_screen.c', - 'dri1_helper.c', 'dri2.c', ] ) diff --git a/src/gallium/state_trackers/dri/drm/dri1_helper.c b/src/gallium/state_trackers/dri/drm/dri1_helper.c deleted file mode 120000 index c45ebf5c102..00000000000 --- a/src/gallium/state_trackers/dri/drm/dri1_helper.c +++ /dev/null @@ -1 +0,0 @@ -../common/dri1_helper.c
\ No newline at end of file diff --git a/src/gallium/state_trackers/dri/drm/dri2.c b/src/gallium/state_trackers/dri/drm/dri2.c index 5c6573fa69b..1fb89963371 100644 --- a/src/gallium/state_trackers/dri/drm/dri2.c +++ b/src/gallium/state_trackers/dri/drm/dri2.c @@ -38,9 +38,6 @@ #include "dri_screen.h" #include "dri_context.h" #include "dri_drawable.h" -#include "dri2.h" - -#include "GL/internal/dri_interface.h" /** * DRI2 flush extension. @@ -354,7 +351,8 @@ dri2_allocate_textures(struct dri_drawable *drawable, unsigned num_buffers = count; buffers = dri2_drawable_get_buffers(drawable, statts, &num_buffers); - dri2_drawable_process_buffers(drawable, buffers, num_buffers); + if (buffers) + dri2_drawable_process_buffers(drawable, buffers, num_buffers); } static void @@ -497,7 +495,7 @@ static const __DRIextension *dri_screen_extensions[] = { * * Returns the __GLcontextModes supported by this driver. */ -const __DRIconfig ** +static const __DRIconfig ** dri2_init_screen(__DRIscreen * sPriv) { const __DRIconfig **configs; @@ -510,9 +508,6 @@ dri2_init_screen(__DRIscreen * sPriv) screen->sPriv = sPriv; screen->fd = sPriv->fd; - screen->lookup_egl_image = dri2_lookup_egl_image; - screen->allocate_textures = dri2_allocate_textures; - screen->flush_frontbuffer = dri2_flush_frontbuffer; sPriv->private = (void *)screen; sPriv->extensions = dri_screen_extensions; @@ -534,6 +529,64 @@ fail: return NULL; } +static boolean +dri2_create_context(gl_api api, const __GLcontextModes * visual, + __DRIcontext * cPriv, void *sharedContextPrivate) +{ + struct dri_context *ctx = NULL; + + if (!dri_create_context(api, visual, cPriv, sharedContextPrivate)) + return FALSE; + + ctx = cPriv->driverPrivate; + + ctx->lookup_egl_image = dri2_lookup_egl_image; + + return TRUE; +} + +static boolean +dri2_create_buffer(__DRIscreen * sPriv, + __DRIdrawable * dPriv, + const __GLcontextModes * visual, boolean isPixmap) +{ + struct dri_drawable *drawable = NULL; + + if (!dri_create_buffer(sPriv, dPriv, visual, isPixmap)) + return FALSE; + + drawable = dPriv->driverPrivate; + + drawable->allocate_textures = dri2_allocate_textures; + drawable->flush_frontbuffer = dri2_flush_frontbuffer; + + return TRUE; +} + +/** + * DRI driver virtual function table. + * + * DRI versions differ in their implementation of init_screen and swap_buffers. + */ +const struct __DriverAPIRec driDriverAPI = { + .InitScreen = NULL, + .InitScreen2 = dri2_init_screen, + .DestroyScreen = dri_destroy_screen, + .CreateContext = dri2_create_context, + .DestroyContext = dri_destroy_context, + .CreateBuffer = dri2_create_buffer, + .DestroyBuffer = dri_destroy_buffer, + .MakeCurrent = dri_make_current, + .UnbindContext = dri_unbind_context, + + .GetSwapInfo = NULL, + .GetDrawableMSC = NULL, + .WaitForMSC = NULL, + + .SwapBuffers = NULL, + .CopySubBuffer = NULL, +}; + /* This is the table of extensions that the loader will dlsym() for. */ PUBLIC const __DRIextension *__driDriverExtensions[] = { &driCoreExtension.base, diff --git a/src/gallium/state_trackers/dri/sw/Makefile b/src/gallium/state_trackers/dri/sw/Makefile index a1dadeba5e6..33bc0ed9c94 100644 --- a/src/gallium/state_trackers/dri/sw/Makefile +++ b/src/gallium/state_trackers/dri/sw/Makefile @@ -20,7 +20,6 @@ C_SOURCES = \ dri_context.c \ dri_screen.c \ dri_drawable.c \ - dri1_helper.c \ drisw.c include ../../../Makefile.template diff --git a/src/gallium/state_trackers/dri/sw/SConscript b/src/gallium/state_trackers/dri/sw/SConscript index 0c5194d6edc..d2eb66668e0 100644 --- a/src/gallium/state_trackers/dri/sw/SConscript +++ b/src/gallium/state_trackers/dri/sw/SConscript @@ -21,7 +21,6 @@ if env['dri']: source = [ 'dri_context.c', 'dri_drawable.c', 'dri_screen.c', - 'dri1_helper.c', 'drisw.c', ] ) diff --git a/src/gallium/state_trackers/dri/sw/dri1_helper.c b/src/gallium/state_trackers/dri/sw/dri1_helper.c deleted file mode 120000 index c45ebf5c102..00000000000 --- a/src/gallium/state_trackers/dri/sw/dri1_helper.c +++ /dev/null @@ -1 +0,0 @@ -../common/dri1_helper.c
\ No newline at end of file diff --git a/src/gallium/state_trackers/dri/sw/drisw.c b/src/gallium/state_trackers/dri/sw/drisw.c index 23e99aa0add..ae96f1b20e2 100644 --- a/src/gallium/state_trackers/dri/sw/drisw.c +++ b/src/gallium/state_trackers/dri/sw/drisw.c @@ -43,9 +43,9 @@ #include "dri_screen.h" #include "dri_context.h" #include "dri_drawable.h" -#include "dri1_helper.h" -#include "drisw.h" +DEBUG_GET_ONCE_BOOL_OPTION(swrast_no_present, "SWRAST_NO_PRESENT", FALSE); +static boolean swrast_no_present = FALSE; static INLINE void get_drawable_info(__DRIdrawable *dPriv, int *w, int *h) @@ -87,6 +87,24 @@ drisw_put_image(struct dri_drawable *drawable, put_image(dPriv, data, width, height); } +static struct pipe_surface * +drisw_get_pipe_surface(struct dri_drawable *drawable, struct pipe_resource *ptex) +{ + struct pipe_screen *pipe_screen = dri_screen(drawable->sPriv)->base.screen; + struct pipe_surface *psurf = drawable->drisw_surface; + + if (!psurf || psurf->texture != ptex) { + pipe_surface_reference(&drawable->drisw_surface, NULL); + + drawable->drisw_surface = pipe_screen->get_tex_surface(pipe_screen, + ptex, 0, 0, 0, 0/* no bind flag???*/); + + psurf = drawable->drisw_surface; + } + + return psurf; +} + static INLINE void drisw_present_texture(__DRIdrawable *dPriv, struct pipe_resource *ptex) @@ -95,7 +113,10 @@ drisw_present_texture(__DRIdrawable *dPriv, struct dri_screen *screen = dri_screen(drawable->sPriv); struct pipe_surface *psurf; - psurf = dri1_get_pipe_surface(drawable, ptex); + if (swrast_no_present) + return; + + psurf = drisw_get_pipe_surface(drawable, ptex); if (!psurf) return; @@ -128,7 +149,7 @@ drisw_copy_to_front(__DRIdrawable * dPriv, * Backend functions for st_framebuffer interface and swap_buffers. */ -void +static void drisw_swap_buffers(__DRIdrawable *dPriv) { struct dri_context *ctx = dri_get_current(dPriv->driScreenPriv); @@ -170,10 +191,6 @@ drisw_flush_frontbuffer(struct dri_drawable *drawable, * During fixed-size operation, the function keeps allocating new attachments * as they are requested. Unused attachments are not removed, not until the * framebuffer is resized or destroyed. - * - * It should be possible for DRI1 and DRISW to share this function, but it - * seems a better seperation and safer for each DRI version to provide its own - * function. */ static void drisw_allocate_textures(struct dri_drawable *drawable, @@ -215,7 +232,8 @@ drisw_allocate_textures(struct dri_drawable *drawable, dri_drawable_get_format(drawable, statts[i], &format, &bind); - if (statts[i] != ST_ATTACHMENT_DEPTH_STENCIL) + /* if we don't do any present, no need for display targets */ + if (statts[i] != ST_ATTACHMENT_DEPTH_STENCIL && !swrast_no_present) bind |= PIPE_BIND_DISPLAY_TARGET; if (format == PIPE_FORMAT_NONE) @@ -244,7 +262,7 @@ static struct drisw_loader_funcs drisw_lf = { .put_image = drisw_put_image }; -const __DRIconfig ** +static const __DRIconfig ** drisw_init_screen(__DRIscreen * sPriv) { const __DRIconfig **configs; @@ -257,9 +275,8 @@ drisw_init_screen(__DRIscreen * sPriv) screen->sPriv = sPriv; screen->fd = -1; - screen->allocate_textures = drisw_allocate_textures; - screen->update_drawable_info = drisw_update_drawable_info; - screen->flush_frontbuffer = drisw_flush_frontbuffer; + + swrast_no_present = debug_get_option_swrast_no_present(); sPriv->private = (void *)screen; sPriv->extensions = drisw_screen_extensions; @@ -278,6 +295,43 @@ fail: return NULL; } +static boolean +drisw_create_buffer(__DRIscreen * sPriv, + __DRIdrawable * dPriv, + const __GLcontextModes * visual, boolean isPixmap) +{ + struct dri_drawable *drawable = NULL; + + if (!dri_create_buffer(sPriv, dPriv, visual, isPixmap)) + return FALSE; + + drawable = dPriv->driverPrivate; + + drawable->allocate_textures = drisw_allocate_textures; + drawable->update_drawable_info = drisw_update_drawable_info; + drawable->flush_frontbuffer = drisw_flush_frontbuffer; + + return TRUE; +} + +/** + * DRI driver virtual function table. + * + * DRI versions differ in their implementation of init_screen and swap_buffers. + */ +const struct __DriverAPIRec driDriverAPI = { + .InitScreen = drisw_init_screen, + .DestroyScreen = dri_destroy_screen, + .CreateContext = dri_create_context, + .DestroyContext = dri_destroy_context, + .CreateBuffer = drisw_create_buffer, + .DestroyBuffer = dri_destroy_buffer, + .MakeCurrent = dri_make_current, + .UnbindContext = dri_unbind_context, + + .SwapBuffers = drisw_swap_buffers, +}; + /* This is the table of extensions that the loader will dlsym() for. */ PUBLIC const __DRIextension *__driDriverExtensions[] = { &driCoreExtension.base, diff --git a/src/gallium/state_trackers/dri/sw/drisw.h b/src/gallium/state_trackers/dri/sw/drisw.h deleted file mode 100644 index 6c6c891f356..00000000000 --- a/src/gallium/state_trackers/dri/sw/drisw.h +++ /dev/null @@ -1,43 +0,0 @@ -/************************************************************************** - * - * Copyright 2009, VMware, Inc. - * All Rights Reserved. - * Copyright 2010 George Sapountzis <[email protected]> - * - * 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 VMWARE 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 DRISW_H -#define DRISW_H - -#include "dri_context.h" -#include "dri_drawable.h" - -#include "state_tracker/st_api.h" -#include "dri_wrapper.h" - -const __DRIconfig ** -drisw_init_screen(__DRIscreen * sPriv); - -void drisw_swap_buffers(__DRIdrawable * dPriv); - -#endif /* DRISW_H */ diff --git a/src/gallium/state_trackers/egl/common/egl_g3d.c b/src/gallium/state_trackers/egl/common/egl_g3d.c index b6321e6b437..56d575ffe08 100644 --- a/src/gallium/state_trackers/egl/common/egl_g3d.c +++ b/src/gallium/state_trackers/egl/common/egl_g3d.c @@ -434,9 +434,11 @@ egl_g3d_free_config(void *conf) static void egl_g3d_free_screen(void *scr) { +#ifdef EGL_MESA_screen_surface struct egl_g3d_screen *gscr = egl_g3d_screen((_EGLScreen *) scr); FREE(gscr->native_modes); FREE(gscr); +#endif } static EGLBoolean diff --git a/src/gallium/state_trackers/egl/common/egl_g3d.h b/src/gallium/state_trackers/egl/common/egl_g3d.h index ed2b0409bb9..f33dc91cf90 100644 --- a/src/gallium/state_trackers/egl/common/egl_g3d.h +++ b/src/gallium/state_trackers/egl/common/egl_g3d.h @@ -95,15 +95,19 @@ struct egl_g3d_image { unsigned zslice; }; +/* standard typecasts */ +_EGL_DRIVER_STANDARD_TYPECASTS(egl_g3d) +_EGL_DRIVER_TYPECAST(egl_g3d_image, _EGLImage, obj) + +#ifdef EGL_MESA_screen_surface + struct egl_g3d_screen { _EGLScreen base; const struct native_connector *native; const struct native_mode **native_modes; }; - -/* standard typecasts */ -_EGL_DRIVER_STANDARD_TYPECASTS(egl_g3d) _EGL_DRIVER_TYPECAST(egl_g3d_screen, _EGLScreen, obj) -_EGL_DRIVER_TYPECAST(egl_g3d_image, _EGLImage, obj) + +#endif /* EGL_MESA_screen_surface */ #endif /* _EGL_G3D_H_ */ diff --git a/src/gallium/state_trackers/egl/x11/glxinit.c b/src/gallium/state_trackers/egl/x11/glxinit.c index 809a0987e55..57c6aaff864 100644 --- a/src/gallium/state_trackers/egl/x11/glxinit.c +++ b/src/gallium/state_trackers/egl/x11/glxinit.c @@ -10,10 +10,16 @@ #include <assert.h> #include <X11/Xlib.h> #include <X11/Xproto.h> +#include <X11/Xlibint.h> #include <X11/extensions/Xext.h> #include <X11/extensions/extutil.h> #include <sys/time.h> +#include "GL/glxproto.h" +#include "GL/glxtokens.h" +#include "GL/gl.h" /* for GL types needed by __GLcontextModes */ +#include "GL/internal/glcore.h" /* for __GLcontextModes */ + #include "glxinit.h" #ifdef GLX_DIRECT_RENDERING @@ -55,9 +61,9 @@ static /* const */ XExtensionHooks __glXExtensionHooks = { NULL, /* error_string */ }; -XEXT_GENERATE_FIND_DISPLAY(__glXFindDisplay, __glXExtensionInfo, - __glXExtensionName, &__glXExtensionHooks, - __GLX_NUMBER_EVENTS, NULL) +static XEXT_GENERATE_FIND_DISPLAY(__glXFindDisplay, __glXExtensionInfo, + __glXExtensionName, &__glXExtensionHooks, + __GLX_NUMBER_EVENTS, NULL) static GLint _gl_convert_from_x_visual_type(int visualType) @@ -73,6 +79,17 @@ _gl_convert_from_x_visual_type(int visualType) ? glx_visual_types[visualType] : GLX_NONE; } +static void +_gl_context_modes_destroy(__GLcontextModes * modes) +{ + while (modes != NULL) { + __GLcontextModes *const next = modes->next; + + Xfree(modes); + modes = next; + } +} + static __GLcontextModes * _gl_context_modes_create(unsigned count, size_t minimum_size) { @@ -116,18 +133,7 @@ _gl_context_modes_create(unsigned count, size_t minimum_size) return base; } -_X_HIDDEN void -_gl_context_modes_destroy(__GLcontextModes * modes) -{ - while (modes != NULL) { - __GLcontextModes *const next = modes->next; - - Xfree(modes); - modes = next; - } -} - -_X_HIDDEN char * +static char * __glXQueryServerString(Display * dpy, int opcode, CARD32 screen, CARD32 name) { xGLXGenericGetStringReq *req; @@ -194,10 +200,6 @@ FreeScreenConfigs(__GLXdisplayPrivate * priv) _gl_context_modes_destroy(psc->configs); psc->configs = NULL; /* NOTE: just for paranoia */ } - if (psc->visuals) { - _gl_context_modes_destroy(psc->visuals); - psc->visuals = NULL; /* NOTE: just for paranoia */ - } Xfree((char *) psc->serverGLXexts); } XFree((char *) priv->screenConfigs); @@ -215,14 +217,8 @@ __glXFreeDisplayPrivate(XExtData * extension) priv = (__GLXdisplayPrivate *) extension->private_data; FreeScreenConfigs(priv); - if (priv->serverGLXvendor) { - Xfree((char *) priv->serverGLXvendor); - priv->serverGLXvendor = 0x0; /* to protect against double free's */ - } - if (priv->serverGLXversion) { + if (priv->serverGLXversion) Xfree((char *) priv->serverGLXversion); - priv->serverGLXversion = 0x0; /* to protect against double free's */ - } Xfree((char *) priv); return 0; @@ -234,6 +230,10 @@ __glXFreeDisplayPrivate(XExtData * extension) ** Query the version of the GLX extension. This procedure works even if ** the client extension is not completely set up. */ + +#define GLX_MAJOR_VERSION 1 /* current version numbers */ +#define GLX_MINOR_VERSION 4 + static Bool QueryVersion(Display * dpy, int opcode, int *major, int *minor) { @@ -263,7 +263,13 @@ QueryVersion(Display * dpy, int opcode, int *major, int *minor) return GL_TRUE; } -_X_HIDDEN void +#define __GLX_MIN_CONFIG_PROPS 18 +#define __GLX_MAX_CONFIG_PROPS 500 +#define __GLX_EXT_CONFIG_PROPS 10 +#define __GLX_TOTAL_CONFIG (__GLX_MIN_CONFIG_PROPS + \ + 2 * __GLX_EXT_CONFIG_PROPS) + +static void __glXInitializeVisualConfigFromTags(__GLcontextModes * config, int count, const INT32 * bp, Bool tagged_only, Bool fbconfig_style_tags) @@ -506,35 +512,6 @@ createConfigsFromProperties(Display * dpy, int nvisuals, int nprops, } static GLboolean -getVisualConfigs(__GLXscreenConfigs *psc, - __GLXdisplayPrivate *priv, int screen) -{ - xGLXGetVisualConfigsReq *req; - xGLXGetVisualConfigsReply reply; - Display *dpy = priv->dpy; - - LockDisplay(dpy); - - psc->visuals = NULL; - GetReq(GLXGetVisualConfigs, req); - req->reqType = priv->majorOpcode; - req->glxCode = X_GLXGetVisualConfigs; - req->screen = screen; - - if (!_XReply(dpy, (xReply *) & reply, 0, False)) - goto out; - - psc->visuals = createConfigsFromProperties(dpy, - reply.numVisuals, - reply.numProps, - screen, GL_FALSE); - - out: - UnlockDisplay(dpy); - return psc->visuals != NULL; -} - -static GLboolean getFBConfigs(__GLXscreenConfigs *psc, __GLXdisplayPrivate *priv, int screen) { xGLXGetFBConfigsReq *fb_req; @@ -581,32 +558,6 @@ getFBConfigs(__GLXscreenConfigs *psc, __GLXdisplayPrivate *priv, int screen) return psc->configs != NULL; } -_X_HIDDEN Bool -glx_screen_init(__GLXscreenConfigs *psc, - int screen, __GLXdisplayPrivate * priv) -{ - /* Initialize per screen dynamic client GLX extensions */ - psc->ext_list_first_time = GL_TRUE; - psc->scr = screen; - psc->dpy = priv->dpy; - - getVisualConfigs(psc, priv, screen); - getFBConfigs(psc, priv, screen); - - return GL_TRUE; -} - -static __GLXscreenConfigs * -createIndirectScreen() -{ - __GLXscreenConfigs *psc; - - psc = Xmalloc(sizeof *psc); - memset(psc, 0, sizeof *psc); - - return psc; -} - static GLboolean AllocAndFetchScreenConfigs(Display * dpy, __GLXdisplayPrivate * priv) { @@ -630,10 +581,10 @@ AllocAndFetchScreenConfigs(Display * dpy, __GLXdisplayPrivate * priv) } for (i = 0; i < screens; i++) { - psc = createIndirectScreen(); + psc = Xcalloc(1, sizeof *psc); if (!psc) return GL_FALSE; - glx_screen_init(psc, i, priv); + getFBConfigs(psc, priv, i); priv->screenConfigs[i] = psc; } @@ -682,13 +633,8 @@ __glXInitialize(Display * dpy) ** structures from the server. */ dpyPriv->majorOpcode = info->codes->major_opcode; - dpyPriv->majorVersion = major; - dpyPriv->minorVersion = minor; dpyPriv->dpy = dpy; - dpyPriv->serverGLXvendor = NULL; - dpyPriv->serverGLXversion = NULL; - if (!AllocAndFetchScreenConfigs(dpy, dpyPriv)) { Xfree(dpyPriv); Xfree(private); diff --git a/src/gallium/state_trackers/egl/x11/glxinit.h b/src/gallium/state_trackers/egl/x11/glxinit.h index 1cc7c460fe2..4078aef2fee 100644 --- a/src/gallium/state_trackers/egl/x11/glxinit.h +++ b/src/gallium/state_trackers/egl/x11/glxinit.h @@ -2,10 +2,21 @@ #define GLXINIT_INCLUDED #include <X11/Xlib.h> -#include "glxclient.h" +#include <GL/gl.h> -/* this is used by DRI loaders */ -extern void -_gl_context_modes_destroy(__GLcontextModes * modes); +typedef struct { + __GLcontextModes *configs; + char *serverGLXexts; +} __GLXscreenConfigs; + +typedef struct { + Display *dpy; + __GLXscreenConfigs **screenConfigs; + char *serverGLXversion; + int majorOpcode; + struct x11_screen *xscr; +} __GLXdisplayPrivate; + +extern __GLXdisplayPrivate *__glXInitialize(Display * dpy); #endif /* GLXINIT_INCLUDED */ diff --git a/src/gallium/state_trackers/egl/x11/x11_screen.c b/src/gallium/state_trackers/egl/x11/x11_screen.c index bc6482ab15d..c07ebb7ef6c 100644 --- a/src/gallium/state_trackers/egl/x11/x11_screen.c +++ b/src/gallium/state_trackers/egl/x11/x11_screen.c @@ -39,11 +39,6 @@ #include "glxinit.h" struct x11_screen { -#ifdef GLX_DIRECT_RENDERING - /* dummy base class */ - struct __GLXDRIdisplayRec base; -#endif - Display *dpy; int number; @@ -108,7 +103,7 @@ x11_screen_destroy(struct x11_screen *xscr) #ifdef GLX_DIRECT_RENDERING /* xscr->glx_dpy will be destroyed with the X display */ if (xscr->glx_dpy) - xscr->glx_dpy->dri2Display = NULL; + xscr->glx_dpy->xscr = NULL; #endif if (xscr->visuals) @@ -231,17 +226,6 @@ x11_screen_get_glx_configs(struct x11_screen *xscr) } /** - * Return the GLX visuals. - */ -const __GLcontextModes * -x11_screen_get_glx_visuals(struct x11_screen *xscr) -{ - return (x11_screen_init_glx(xscr)) - ? xscr->glx_dpy->screenConfigs[xscr->number]->visuals - : NULL; -} - -/** * Probe the screen for the DRI2 driver name. */ const char * @@ -306,14 +290,14 @@ x11_screen_enable_dri2(struct x11_screen *xscr, close(fd); return -1; } - if (xscr->glx_dpy->dri2Display) { + if (xscr->glx_dpy->xscr) { _eglLog(_EGL_WARNING, "display is already managed by another x11 screen"); close(fd); return -1; } - xscr->glx_dpy->dri2Display = (__GLXDRIdisplay *) xscr; + xscr->glx_dpy->xscr = xscr; xscr->dri_invalidate_buffers = invalidate_buffers; xscr->dri_user_data = user_data; @@ -428,6 +412,9 @@ x11_context_modes_count(const __GLcontextModes *modes) return count; } +extern void +dri2InvalidateBuffers(Display *dpy, XID drawable); + /** * This is called from src/glx/dri2.c. */ @@ -437,8 +424,8 @@ dri2InvalidateBuffers(Display *dpy, XID drawable) __GLXdisplayPrivate *priv = __glXInitialize(dpy); struct x11_screen *xscr = NULL; - if (priv && priv->dri2Display) - xscr = (struct x11_screen *) priv->dri2Display; + if (priv && priv->xscr) + xscr = priv->xscr; if (!xscr || !xscr->dri_invalidate_buffers) return; diff --git a/src/gallium/state_trackers/python/p_context.i b/src/gallium/state_trackers/python/p_context.i index cf0144b5dc6..40c4603fb9d 100644 --- a/src/gallium/state_trackers/python/p_context.i +++ b/src/gallium/state_trackers/python/p_context.i @@ -289,6 +289,20 @@ struct st_context { $self->vertex_buffers); } + void set_index_buffer(unsigned index_size, + unsigned offset, + struct pipe_resource *buffer) + { + struct pipe_index_buffer ib; + + memset(&ib, 0, sizeof(ib)); + ib.index_size = index_size; + ib.offset = offset; + ib.buffer = buffer; + + $self->pipe->set_index_buffer($self->pipe, &ib); + } + void set_vertex_element(unsigned index, const struct pipe_vertex_element *element) { @@ -308,29 +322,12 @@ struct st_context { */ void draw_arrays(unsigned mode, unsigned start, unsigned count) { - $self->pipe->draw_arrays($self->pipe, mode, start, count); - } - - void draw_elements( struct pipe_resource *indexBuffer, - unsigned indexSize, int indexBias, - unsigned mode, unsigned start, unsigned count) - { - $self->pipe->draw_elements($self->pipe, - indexBuffer, - indexSize, - indexBias, - mode, start, count); + util_draw_arrays($self->pipe, mode, start, count); } - void draw_range_elements( struct pipe_resource *indexBuffer, - unsigned indexSize, int indexBias, - unsigned minIndex, unsigned maxIndex, - unsigned mode, unsigned start, unsigned count) + void draw_vbo(const struct pipe_draw_info *info) { - $self->pipe->draw_range_elements($self->pipe, - indexBuffer, indexSize, indexBias, - minIndex, maxIndex, - mode, start, count); + $self->pipe->draw_vbo($self->pipe, info); } void draw_vertices(unsigned prim, @@ -382,7 +379,7 @@ struct st_context { pipe->set_vertex_buffers(pipe, 1, &vbuffer); /* draw */ - pipe->draw_arrays(pipe, prim, 0, num_verts); + util_draw_arrays(pipe, prim, 0, num_verts); cso_restore_vertex_elements($self->cso); diff --git a/src/gallium/state_trackers/vega/polygon.c b/src/gallium/state_trackers/vega/polygon.c index e9c8f031373..bc94170eb96 100644 --- a/src/gallium/state_trackers/vega/polygon.c +++ b/src/gallium/state_trackers/vega/polygon.c @@ -301,8 +301,7 @@ static void draw_polygon(struct vg_context *ctx, cso_set_vertex_elements(ctx->cso_context, 1, &velement); /* draw */ - pipe->draw_arrays(pipe, PIPE_PRIM_TRIANGLE_FAN, - 0, poly->num_verts); + util_draw_arrays(pipe, PIPE_PRIM_TRIANGLE_FAN, 0, (uint) poly->num_verts); } void polygon_fill(struct polygon *poly, struct vg_context *ctx) diff --git a/src/gallium/targets/egl/st_GL.c b/src/gallium/targets/egl/st_GL.c index 676300b0cc1..17b7bf9d481 100644 --- a/src/gallium/targets/egl/st_GL.c +++ b/src/gallium/targets/egl/st_GL.c @@ -1,4 +1,5 @@ #include "state_tracker/st_gl_api.h" +#include "state_tracker/st_api.h" #if FEATURE_GL PUBLIC struct st_api * diff --git a/src/gallium/tests/graw/SConscript b/src/gallium/tests/graw/SConscript index 61121732e38..7e39ec21a41 100644 --- a/src/gallium/tests/graw/SConscript +++ b/src/gallium/tests/graw/SConscript @@ -11,6 +11,9 @@ env = env.Clone() env.Prepend(LIBPATH = [graw.dir]) env.Prepend(LIBS = ['graw'] + gallium) +if platform == 'sunos5': + env.Append(LIBS = ['m']) + progs = [ 'clear', 'tri', diff --git a/src/gallium/tests/graw/fs-test.c b/src/gallium/tests/graw/fs-test.c index dea087357d6..53fbb744d86 100644 --- a/src/gallium/tests/graw/fs-test.c +++ b/src/gallium/tests/graw/fs-test.c @@ -13,6 +13,7 @@ #include "util/u_debug.h" /* debug_dump_surface_bmp() */ #include "util/u_inlines.h" #include "util/u_memory.h" /* Offset() */ +#include "util/u_draw_quad.h" #include "util/u_box.h" static const char *filename = NULL; @@ -275,7 +276,7 @@ static void draw( void ) float clear_color[4] = {.1,.3,.5,0}; ctx->clear(ctx, PIPE_CLEAR_COLOR, clear_color, 0, 0); - ctx->draw_arrays(ctx, PIPE_PRIM_TRIANGLES, 0, 3); + util_draw_arrays(ctx, PIPE_PRIM_TRIANGLES, 0, 3); ctx->flush(ctx, PIPE_FLUSH_RENDER_CACHE, NULL); #if 0 diff --git a/src/gallium/tests/graw/gs-test.c b/src/gallium/tests/graw/gs-test.c index 3087d446fca..62714900bd9 100644 --- a/src/gallium/tests/graw/gs-test.c +++ b/src/gallium/tests/graw/gs-test.c @@ -13,6 +13,7 @@ #include "util/u_debug.h" /* debug_dump_surface_bmp() */ #include "util/u_inlines.h" #include "util/u_memory.h" /* Offset() */ +#include "util/u_draw_quad.h" #include "util/u_box.h" static const char *filename = NULL; @@ -336,9 +337,9 @@ static void draw( void ) ctx->clear(ctx, PIPE_CLEAR_COLOR, clear_color, 0, 0); if (draw_strip) - ctx->draw_arrays(ctx, PIPE_PRIM_TRIANGLE_STRIP, 0, 4); + util_draw_arrays(ctx, PIPE_PRIM_TRIANGLE_STRIP, 0, 4); else - ctx->draw_arrays(ctx, PIPE_PRIM_TRIANGLES, 0, 3); + util_draw_arrays(ctx, PIPE_PRIM_TRIANGLES, 0, 3); ctx->flush(ctx, PIPE_FLUSH_RENDER_CACHE, NULL); diff --git a/src/gallium/tests/graw/quad-tex.c b/src/gallium/tests/graw/quad-tex.c index 6a0a2ba2950..c50ef12ab5a 100644 --- a/src/gallium/tests/graw/quad-tex.c +++ b/src/gallium/tests/graw/quad-tex.c @@ -12,6 +12,7 @@ #include "util/u_debug.h" /* debug_dump_surface_bmp() */ #include "util/u_inlines.h" #include "util/u_memory.h" /* Offset() */ +#include "util/u_draw_quad.h" #include "util/u_box.h" enum pipe_format formats[] = { @@ -146,7 +147,7 @@ static void draw( void ) float clear_color[4] = {.5,.5,.5,1}; ctx->clear(ctx, PIPE_CLEAR_COLOR, clear_color, 0, 0); - ctx->draw_arrays(ctx, PIPE_PRIM_QUADS, 0, 4); + util_draw_arrays(ctx, PIPE_PRIM_QUADS, 0, 4); ctx->flush(ctx, PIPE_FLUSH_RENDER_CACHE, NULL); #if 0 diff --git a/src/gallium/tests/graw/tri-gs.c b/src/gallium/tests/graw/tri-gs.c index d187505f8d4..152ae408eb0 100644 --- a/src/gallium/tests/graw/tri-gs.c +++ b/src/gallium/tests/graw/tri-gs.c @@ -10,6 +10,7 @@ #include "util/u_debug.h" /* debug_dump_surface_bmp() */ #include "util/u_memory.h" /* Offset() */ +#include "util/u_draw_quad.h" enum pipe_format formats[] = { PIPE_FORMAT_R8G8B8A8_UNORM, @@ -161,7 +162,7 @@ static void draw( void ) float clear_color[4] = {1,0,1,1}; ctx->clear(ctx, PIPE_CLEAR_COLOR, clear_color, 0, 0); - ctx->draw_arrays(ctx, PIPE_PRIM_TRIANGLES, 0, 3); + util_draw_arrays(ctx, PIPE_PRIM_TRIANGLES, 0, 3); ctx->flush(ctx, PIPE_FLUSH_RENDER_CACHE, NULL); screen->flush_frontbuffer(screen, surf, window); diff --git a/src/gallium/tests/graw/tri-instanced.c b/src/gallium/tests/graw/tri-instanced.c index 30e205f1434..8859f745fdb 100644 --- a/src/gallium/tests/graw/tri-instanced.c +++ b/src/gallium/tests/graw/tri-instanced.c @@ -13,6 +13,7 @@ #include "util/u_debug.h" /* debug_dump_surface_bmp() */ #include "util/u_memory.h" /* Offset() */ +#include "util/u_draw_quad.h" enum pipe_format formats[] = { @@ -27,7 +28,6 @@ static const int HEIGHT = 300; static struct pipe_screen *screen = NULL; static struct pipe_context *ctx = NULL; static struct pipe_surface *surf = NULL; -static struct pipe_resource *indexBuffer = NULL; static void *window = NULL; struct vertex { @@ -105,6 +105,7 @@ static void set_vertices( void ) { struct pipe_vertex_element ve[3]; struct pipe_vertex_buffer vbuf[2]; + struct pipe_index_buffer ibuf; void *handle; memset(ve, 0, sizeof ve); @@ -151,11 +152,14 @@ static void set_vertices( void ) ctx->set_vertex_buffers(ctx, 2, vbuf); /* index data */ - indexBuffer = screen->user_buffer_create(screen, + ibuf.buffer = screen->user_buffer_create(screen, indices, sizeof(indices), PIPE_BIND_VERTEX_BUFFER); + ibuf.offset = 0; + ibuf.index_size = 2; + ctx->set_index_buffer(ctx, &ibuf); } @@ -195,18 +199,19 @@ static void set_fragment_shader( void ) static void draw( void ) { float clear_color[4] = {1,0,1,1}; + struct pipe_draw_info info; ctx->clear(ctx, PIPE_CLEAR_COLOR, clear_color, 0, 0); + util_draw_init_info(&info); + info.indexed = (draw_elements != 0); + info.mode = PIPE_PRIM_TRIANGLES; + info.start = 0; + info.count = 3; /* draw NUM_INST triangles */ - if (draw_elements) - ctx->draw_elements_instanced(ctx, indexBuffer, 2, - 0, /* indexBias */ - PIPE_PRIM_TRIANGLES, - 0, 3, /* start, count */ - 0, NUM_INST); /* startInst, instCount */ - else - ctx->draw_arrays_instanced(ctx, PIPE_PRIM_TRIANGLES, 0, 3, 0, NUM_INST); + info.instance_count = NUM_INST; + + ctx->draw_vbo(ctx, &info); ctx->flush(ctx, PIPE_FLUSH_RENDER_CACHE, NULL); diff --git a/src/gallium/tests/graw/tri.c b/src/gallium/tests/graw/tri.c index 80377f526d6..4dbd2c062a5 100644 --- a/src/gallium/tests/graw/tri.c +++ b/src/gallium/tests/graw/tri.c @@ -10,6 +10,7 @@ #include "util/u_debug.h" /* debug_dump_surface_bmp() */ #include "util/u_memory.h" /* Offset() */ +#include "util/u_draw_quad.h" enum pipe_format formats[] = { PIPE_FORMAT_R8G8B8A8_UNORM, @@ -134,7 +135,7 @@ static void draw( void ) float clear_color[4] = {1,0,1,1}; ctx->clear(ctx, PIPE_CLEAR_COLOR, clear_color, 0, 0); - ctx->draw_arrays(ctx, PIPE_PRIM_TRIANGLES, 0, 3); + util_draw_arrays(ctx, PIPE_PRIM_TRIANGLES, 0, 3); ctx->flush(ctx, PIPE_FLUSH_RENDER_CACHE, NULL); #if 0 diff --git a/src/gallium/tests/graw/vs-test.c b/src/gallium/tests/graw/vs-test.c index 7f93db42c0d..e1cd814bf72 100644 --- a/src/gallium/tests/graw/vs-test.c +++ b/src/gallium/tests/graw/vs-test.c @@ -14,6 +14,7 @@ #include "util/u_debug.h" /* debug_dump_surface_bmp() */ #include "util/u_inlines.h" #include "util/u_memory.h" /* Offset() */ +#include "util/u_draw_quad.h" #include "util/u_box.h" static const char *filename = NULL; @@ -226,7 +227,7 @@ static void draw( void ) float clear_color[4] = {.1,.3,.5,0}; ctx->clear(ctx, PIPE_CLEAR_COLOR, clear_color, 0, 0); - ctx->draw_arrays(ctx, PIPE_PRIM_POINTS, 0, Elements(vertices)); + util_draw_arrays(ctx, PIPE_PRIM_POINTS, 0, Elements(vertices)); ctx->flush(ctx, PIPE_FLUSH_RENDER_CACHE, NULL); #if 0 diff --git a/src/gallium/tests/unit/SConscript b/src/gallium/tests/unit/SConscript index 8a9f3504c75..a200123f446 100644 --- a/src/gallium/tests/unit/SConscript +++ b/src/gallium/tests/unit/SConscript @@ -4,6 +4,9 @@ env = env.Clone() env.Prepend(LIBS = [gallium]) +if platform == 'sunos5': + env.Append(LIBS = ['m']) + progs = [ 'pipe_barrier_test', 'u_cache_test', diff --git a/src/gallium/winsys/r600/drm/r600_drm.c b/src/gallium/winsys/r600/drm/r600_drm.c index 3d87a994c15..9520792f54d 100644 --- a/src/gallium/winsys/r600/drm/r600_drm.c +++ b/src/gallium/winsys/r600/drm/r600_drm.c @@ -30,7 +30,7 @@ #include "util/u_debug.h" #include "radeon_priv.h" #include "r600_screen.h" -#include "r600_texture.h" +#include "r600_resource.h" #include "r600_public.h" #include "r600_drm_public.h" #include "state_tracker/drm_driver.h" @@ -45,7 +45,7 @@ boolean r600_buffer_get_handle(struct radeon *rw, struct winsys_handle *whandle) { struct drm_gem_flink flink; - struct r600_buffer* rbuffer = (struct r600_buffer*)buf; + struct r600_resource* rbuffer = (struct r600_buffer*)buf; if (whandle->type == DRM_API_HANDLE_TYPE_SHARED) { if (!rbuffer->flink) { diff --git a/src/gallium/winsys/radeon/drm/radeon_drm.c b/src/gallium/winsys/radeon/drm/radeon_drm.c index e9a276362f3..ecaf096dea2 100644 --- a/src/gallium/winsys/radeon/drm/radeon_drm.c +++ b/src/gallium/winsys/radeon/drm/radeon_drm.c @@ -103,6 +103,10 @@ static void do_ioctls(int fd, struct radeon_libdrm_winsys* winsys) winsys->drm_2_3_0 = version->version_major > 2 || version->version_minor >= 3; + winsys->drm_2_6_0 = version->version_major > 2 || + (version->version_major == 2 && + version->version_minor >= 6); + info.request = RADEON_INFO_DEVICE_ID; retval = drmCommandWriteRead(fd, DRM_RADEON_INFO, &info, sizeof(info)); if (retval) { @@ -130,6 +134,16 @@ static void do_ioctls(int fd, struct radeon_libdrm_winsys* winsys) } winsys->z_pipes = target; + winsys->hyperz = FALSE; +#ifndef RADEON_INFO_WANT_HYPERZ +#define RADEON_INFO_WANT_HYPERZ 7 +#endif + info.request = RADEON_INFO_WANT_HYPERZ; + retval = drmCommandWriteRead(fd, DRM_RADEON_INFO, &info, sizeof(info)); + if (!retval && target == 1) { + winsys->hyperz = TRUE; + } + retval = drmCommandWriteRead(fd, DRM_RADEON_GEM_INFO, &gem_info, sizeof(gem_info)); if (retval) { @@ -142,12 +156,14 @@ static void do_ioctls(int fd, struct radeon_libdrm_winsys* winsys) debug_printf("radeon: Successfully grabbed chipset info from kernel!\n" "radeon: DRM version: %d.%d.%d ID: 0x%04x GB: %d Z: %d\n" - "radeon: GART size: %d MB VRAM size: %d MB\n", + "radeon: GART size: %d MB VRAM size: %d MB\n" + "radeon: HyperZ: %s\n", version->version_major, version->version_minor, version->version_patchlevel, winsys->pci_id, winsys->gb_pipes, winsys->z_pipes, winsys->gart_size / 1024 / 1024, - winsys->vram_size / 1024 / 1024); + winsys->vram_size / 1024 / 1024, + winsys->hyperz ? "YES" : "NO"); drmFreeVersion(version); } diff --git a/src/gallium/winsys/radeon/drm/radeon_r300.c b/src/gallium/winsys/radeon/drm/radeon_r300.c index 55445040671..58400986421 100644 --- a/src/gallium/winsys/radeon/drm/radeon_r300.c +++ b/src/gallium/winsys/radeon/drm/radeon_r300.c @@ -211,6 +211,10 @@ static uint32_t radeon_get_value(struct r300_winsys_screen *rws, return ws->squaretiling; case R300_VID_DRM_2_3_0: return ws->drm_2_3_0; + case R300_VID_DRM_2_6_0: + return ws->drm_2_6_0; + case R300_CAN_HYPERZ: + return ws->hyperz; } return 0; } diff --git a/src/gallium/winsys/radeon/drm/radeon_winsys.h b/src/gallium/winsys/radeon/drm/radeon_winsys.h index 533b7b2e2d2..6f4aa4bce30 100644 --- a/src/gallium/winsys/radeon/drm/radeon_winsys.h +++ b/src/gallium/winsys/radeon/drm/radeon_winsys.h @@ -65,6 +65,15 @@ struct radeon_libdrm_winsys { */ boolean drm_2_3_0; + /* DRM 2.6.0 + * - Hyper-Z + * - GB_Z_PEQ_CONFIG allowed on rv350->r4xx, we should initialize it + */ + boolean drm_2_6_0; + + /* hyperz user */ + boolean hyperz; + /* DRM FD */ int fd; |