summaryrefslogtreecommitdiffstats
path: root/src/gallium
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium')
-rw-r--r--src/gallium/Makefile.template4
-rw-r--r--src/gallium/auxiliary/draw/draw_pipe.c78
-rw-r--r--src/gallium/auxiliary/draw/draw_pipe_pstipple.c5
-rw-r--r--src/gallium/auxiliary/draw/draw_pipe_wide_point.c48
-rw-r--r--src/gallium/auxiliary/draw/draw_vs_aos.c17
-rw-r--r--src/gallium/auxiliary/draw/draw_vs_llvm.c2
-rw-r--r--src/gallium/auxiliary/gallivm/instructionssoa.cpp4
-rw-r--r--src/gallium/auxiliary/gallivm/tgsitollvm.cpp84
-rw-r--r--src/gallium/auxiliary/tgsi/Makefile1
-rw-r--r--src/gallium/auxiliary/tgsi/SConscript1
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi-instruction-set.txt28
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_build.c23
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_build.h2
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_dump.c13
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_dump_c.c8
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_exec.c67
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_info.c258
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_info.h7
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_opcode_tmp.h173
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_parse.c13
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_parse.h6
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_ppc.c25
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_sanity.c29
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_sse2.c55
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_text.c18
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_ureg.c797
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_ureg.h439
-rw-r--r--src/gallium/auxiliary/util/u_blit.c82
-rw-r--r--src/gallium/auxiliary/util/u_debug.c2
-rw-r--r--src/gallium/auxiliary/util/u_gen_mipmap.c4
-rw-r--r--src/gallium/auxiliary/util/u_math.h75
-rw-r--r--src/gallium/auxiliary/util/u_memory.h8
-rw-r--r--src/gallium/auxiliary/util/u_mm.c22
-rw-r--r--src/gallium/auxiliary/util/u_mm.h2
-rw-r--r--src/gallium/auxiliary/util/u_simple_screen.c3
-rw-r--r--src/gallium/auxiliary/util/u_simple_shaders.c318
-rw-r--r--src/gallium/auxiliary/util/u_surface.h17
-rw-r--r--src/gallium/auxiliary/util/u_tile.c2
-rw-r--r--src/gallium/auxiliary/util/u_time.c12
-rw-r--r--src/gallium/auxiliary/util/u_time.h6
-rw-r--r--src/gallium/auxiliary/util/u_timed_winsys.c3
-rw-r--r--src/gallium/drivers/cell/ppu/cell_gen_fp.c8
-rw-r--r--src/gallium/drivers/cell/ppu/cell_texture.c13
-rw-r--r--src/gallium/drivers/cell/spu/spu_exec.c46
-rw-r--r--src/gallium/drivers/i915simple/i915_batch.h4
-rw-r--r--src/gallium/drivers/i915simple/i915_context.c16
-rw-r--r--src/gallium/drivers/i915simple/i915_fpc_translate.c3
-rw-r--r--src/gallium/drivers/i915simple/i915_screen.c2
-rw-r--r--src/gallium/drivers/i915simple/i915_texture.c30
-rw-r--r--src/gallium/drivers/i915simple/i915_winsys.h1
-rw-r--r--src/gallium/drivers/i965simple/brw_tex_layout.c5
-rw-r--r--src/gallium/drivers/i965simple/brw_vs_emit.c8
-rw-r--r--src/gallium/drivers/i965simple/brw_wm_glsl.c6
-rw-r--r--src/gallium/drivers/identity/id_context.c2
-rw-r--r--src/gallium/drivers/identity/id_drm.c4
-rw-r--r--src/gallium/drivers/identity/id_screen.c2
-rw-r--r--src/gallium/drivers/nouveau/nouveau_screen.c9
-rw-r--r--src/gallium/drivers/nv04/nv04_surface_2d.c102
-rw-r--r--src/gallium/drivers/nv20/nv20_vertprog.c8
-rw-r--r--src/gallium/drivers/nv30/nv30_fragprog.c8
-rw-r--r--src/gallium/drivers/nv30/nv30_screen.c2
-rw-r--r--src/gallium/drivers/nv30/nv30_vertprog.c8
-rw-r--r--src/gallium/drivers/nv40/nv40_fragprog.c8
-rw-r--r--src/gallium/drivers/nv40/nv40_vertprog.c8
-rw-r--r--src/gallium/drivers/nv50/nv50_context.c18
-rw-r--r--src/gallium/drivers/nv50/nv50_context.h1
-rw-r--r--src/gallium/drivers/nv50/nv50_miptree.c28
-rw-r--r--src/gallium/drivers/nv50/nv50_program.c46
-rw-r--r--src/gallium/drivers/nv50/nv50_query.c12
-rw-r--r--src/gallium/drivers/nv50/nv50_screen.c55
-rw-r--r--src/gallium/drivers/nv50/nv50_state.c19
-rw-r--r--src/gallium/drivers/nv50/nv50_state_validate.c91
-rw-r--r--src/gallium/drivers/nv50/nv50_surface.c12
-rw-r--r--src/gallium/drivers/nv50/nv50_tex.c31
-rw-r--r--src/gallium/drivers/nv50/nv50_texture.h71
-rw-r--r--src/gallium/drivers/nv50/nv50_transfer.c76
-rw-r--r--src/gallium/drivers/nv50/nv50_vbo.c87
-rw-r--r--src/gallium/drivers/r300/Makefile19
-rw-r--r--src/gallium/drivers/r300/r300_context.c2
-rw-r--r--src/gallium/drivers/r300/r300_context.h91
-rw-r--r--src/gallium/drivers/r300/r300_debug.c198
-rw-r--r--src/gallium/drivers/r300/r300_debug.h211
-rw-r--r--src/gallium/drivers/r300/r300_emit.c265
-rw-r--r--src/gallium/drivers/r300/r300_emit.h17
-rw-r--r--src/gallium/drivers/r300/r300_fs.c164
-rw-r--r--src/gallium/drivers/r300/r300_fs.h15
-rw-r--r--src/gallium/drivers/r300/r300_fs_inlines.h158
-rw-r--r--src/gallium/drivers/r300/r300_screen.c7
-rw-r--r--src/gallium/drivers/r300/r300_state.c29
-rw-r--r--src/gallium/drivers/r300/r300_state_derived.c3
-rw-r--r--src/gallium/drivers/r300/r300_state_invariant.c11
-rw-r--r--src/gallium/drivers/r300/r300_surface.c38
-rw-r--r--src/gallium/drivers/r300/r300_texture.c22
-rw-r--r--src/gallium/drivers/r300/r300_tgsi_to_rc.c337
-rw-r--r--src/gallium/drivers/r300/r300_tgsi_to_rc.h41
-rw-r--r--src/gallium/drivers/r300/r300_vs.c520
-rw-r--r--src/gallium/drivers/r300/r300_vs.h137
-rw-r--r--src/gallium/drivers/r300/r3xx_fs.c100
-rw-r--r--src/gallium/drivers/r300/r3xx_fs.h50
-rw-r--r--src/gallium/drivers/r300/r5xx_fs.c540
-rw-r--r--src/gallium/drivers/r300/r5xx_fs.h106
-rw-r--r--src/gallium/drivers/softpipe/sp_texture.c21
-rw-r--r--src/gallium/drivers/trace/tr_drm.c6
-rw-r--r--src/gallium/drivers/trace/tr_screen.c3
-rw-r--r--src/gallium/include/pipe/internal/p_winsys_screen.h1
-rw-r--r--src/gallium/include/pipe/p_defines.h6
-rw-r--r--src/gallium/include/pipe/p_screen.h1
-rw-r--r--src/gallium/include/pipe/p_shader_tokens.h191
-rw-r--r--src/gallium/state_trackers/dri/dri_context.c8
-rw-r--r--src/gallium/state_trackers/dri/dri_drawable.c24
-rw-r--r--src/gallium/state_trackers/dri/dri_drawable.h6
-rw-r--r--src/gallium/state_trackers/dri/dri_screen.c7
-rw-r--r--src/gallium/state_trackers/dri/dri_screen.h6
-rw-r--r--src/gallium/state_trackers/egl/egl_context.c2
-rw-r--r--src/gallium/state_trackers/egl/egl_surface.c6
-rw-r--r--src/gallium/state_trackers/glx/xlib/Makefile9
-rw-r--r--src/gallium/state_trackers/glx/xlib/SConscript7
-rw-r--r--src/gallium/state_trackers/glx/xlib/fakeglx.h41
-rw-r--r--src/gallium/state_trackers/glx/xlib/glx_api.c (renamed from src/gallium/state_trackers/glx/xlib/fakeglx.c)672
-rw-r--r--src/gallium/state_trackers/glx/xlib/glx_getproc.c214
-rw-r--r--src/gallium/state_trackers/glx/xlib/glx_usefont.c (renamed from src/gallium/state_trackers/glx/xlib/fakeglx_fonts.c)22
-rw-r--r--src/gallium/state_trackers/glx/xlib/glxapi.c1254
-rw-r--r--src/gallium/state_trackers/glx/xlib/glxapi.h213
-rw-r--r--src/gallium/state_trackers/glx/xlib/xm_api.h2
-rw-r--r--src/gallium/state_trackers/vega/asm_filters.h4
-rw-r--r--src/gallium/state_trackers/vega/vg_tracker.c14
-rw-r--r--src/gallium/state_trackers/vega/vg_tracker.h7
-rw-r--r--src/gallium/state_trackers/xorg/xorg_dri2.c77
-rw-r--r--src/gallium/state_trackers/xorg/xorg_driver.c33
-rw-r--r--src/gallium/state_trackers/xorg/xorg_exa.c52
-rw-r--r--src/gallium/state_trackers/xorg/xorg_exa.h2
-rw-r--r--src/gallium/state_trackers/xorg/xorg_tracker.h9
-rw-r--r--src/gallium/winsys/drm/Makefile.template4
-rw-r--r--src/gallium/winsys/drm/intel/dri/SConscript5
-rw-r--r--src/gallium/winsys/drm/intel/egl/Makefile1
-rw-r--r--src/gallium/winsys/drm/intel/gem/intel_be_batchbuffer.c43
-rw-r--r--src/gallium/winsys/drm/intel/gem/intel_be_context.c2
-rw-r--r--src/gallium/winsys/drm/intel/gem/intel_be_device.c83
-rw-r--r--src/gallium/winsys/drm/intel/gem/intel_be_device.h5
-rw-r--r--src/gallium/winsys/drm/intel/xorg/Makefile1
-rw-r--r--src/gallium/winsys/drm/radeon/core/radeon_buffer.c1
-rw-r--r--src/gallium/winsys/drm/radeon/core/radeon_buffer.h5
-rw-r--r--src/gallium/winsys/drm/radeon/core/radeon_drm.c4
-rw-r--r--src/gallium/winsys/drm/radeon/core/radeon_drm.h8
-rw-r--r--src/gallium/winsys/drm/radeon/core/radeon_r300.c78
-rw-r--r--src/gallium/winsys/drm/radeon/core/radeon_r300.h18
-rw-r--r--src/gallium/winsys/egl_xlib/egl_xlib.c195
-rw-r--r--src/gallium/winsys/egl_xlib/sw_winsys.c1
-rw-r--r--src/gallium/winsys/xlib/xlib_brw_screen.c1
-rw-r--r--src/gallium/winsys/xlib/xlib_softpipe.c1
150 files changed, 4790 insertions, 5278 deletions
diff --git a/src/gallium/Makefile.template b/src/gallium/Makefile.template
index 98487d43bd6..2e3da436cd7 100644
--- a/src/gallium/Makefile.template
+++ b/src/gallium/Makefile.template
@@ -31,8 +31,8 @@ INCLUDES = \
default: depend lib$(LIBNAME).a
-lib$(LIBNAME).a: $(OBJECTS) Makefile $(TOP)/src/gallium/Makefile.template
- $(MKLIB) -o $(LIBNAME) -static $(OBJECTS)
+lib$(LIBNAME).a: $(OBJECTS) $(EXTRA_OBJECTS) Makefile $(TOP)/src/gallium/Makefile.template
+ $(MKLIB) -o $(LIBNAME) -static $(OBJECTS) $(EXTRA_OBJECTS)
depend: $(C_SOURCES) $(CPP_SOURCES) $(ASM_SOURCES) $(SYMLINKS)
rm -f depend
diff --git a/src/gallium/auxiliary/draw/draw_pipe.c b/src/gallium/auxiliary/draw/draw_pipe.c
index 2e3f5b2fc07..1c6d657297c 100644
--- a/src/gallium/auxiliary/draw/draw_pipe.c
+++ b/src/gallium/auxiliary/draw/draw_pipe.c
@@ -158,6 +158,60 @@ static void do_triangle( struct draw_context *draw,
+#define QUAD(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], \
+ verts + stride * elts[i1], \
+ verts + stride * elts[i3]); \
+ do_triangle( draw, \
+ ( DRAW_PIPE_EDGE_FLAG_0 | \
+ DRAW_PIPE_EDGE_FLAG_1 ), \
+ verts + stride * elts[i1], \
+ verts + stride * elts[i2], \
+ verts + stride * elts[i3])
+
+#define TRIANGLE(flags,i0,i1,i2) \
+ do_triangle( draw, \
+ elts[i0], /* flags */ \
+ verts + stride * (elts[i0] & ~DRAW_PIPE_FLAG_MASK), \
+ verts + stride * elts[i1], \
+ verts + stride * elts[i2])
+
+#define LINE(flags,i0,i1) \
+ do_line( draw, \
+ elts[i0], \
+ verts + stride * (elts[i0] & ~DRAW_PIPE_FLAG_MASK), \
+ verts + stride * elts[i1])
+
+#define POINT(i0) \
+ do_point( draw, \
+ verts + stride * elts[i0] )
+
+#define FUNC pipe_run
+#define ARGS \
+ 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
+
+#include "draw_pt_decompose.h"
+#undef ARGS
+#undef LOCAL_VARS
+
+
/* Code to run the pipeline on a fairly arbitary collection of vertices.
*
@@ -178,34 +232,12 @@ void draw_pipeline_run( struct draw_context *draw,
unsigned count )
{
char *verts = (char *)vertices;
- unsigned i;
draw->pipeline.verts = verts;
draw->pipeline.vertex_stride = stride;
draw->pipeline.vertex_count = vertex_count;
- switch (prim) {
- case PIPE_PRIM_POINTS:
- for (i = 0; i < count; i++)
- do_point( draw,
- verts + stride * elts[i] );
- break;
- case PIPE_PRIM_LINES:
- for (i = 0; i+1 < count; i += 2)
- do_line( draw,
- elts[i+0], /* flags */
- verts + stride * (elts[i+0] & ~DRAW_PIPE_FLAG_MASK),
- verts + stride * elts[i+1]);
- break;
- case PIPE_PRIM_TRIANGLES:
- for (i = 0; i+2 < count; i += 3)
- do_triangle( draw,
- elts[i+0], /* flags */
- verts + stride * (elts[i+0] & ~DRAW_PIPE_FLAG_MASK),
- verts + stride * elts[i+1],
- verts + stride * elts[i+2]);
- break;
- }
+ pipe_run(draw, prim, vertices, stride, elts, count);
draw->pipeline.verts = NULL;
draw->pipeline.vertex_count = 0;
diff --git a/src/gallium/auxiliary/draw/draw_pipe_pstipple.c b/src/gallium/auxiliary/draw/draw_pipe_pstipple.c
index 30a6d2919d9..283502cdf3e 100644
--- a/src/gallium/auxiliary/draw/draw_pipe_pstipple.c
+++ b/src/gallium/auxiliary/draw/draw_pipe_pstipple.c
@@ -256,7 +256,10 @@ pstip_transform_inst(struct tgsi_transform_context *ctx,
uint size = 4;
immed = tgsi_default_full_immediate();
immed.Immediate.NrTokens = 1 + size; /* one for the token itself */
- immed.u.Pointer = (void *) value;
+ immed.u[0].Float = value[0];
+ immed.u[1].Float = value[1];
+ immed.u[2].Float = value[2];
+ immed.u[3].Float = value[3];
ctx->emit_immediate(ctx, &immed);
}
diff --git a/src/gallium/auxiliary/draw/draw_pipe_wide_point.c b/src/gallium/auxiliary/draw/draw_pipe_wide_point.c
index 014d8c7346d..7d76a7dbf39 100644
--- a/src/gallium/auxiliary/draw/draw_pipe_wide_point.c
+++ b/src/gallium/auxiliary/draw/draw_pipe_wide_point.c
@@ -28,6 +28,30 @@
/* Authors: Keith Whitwell <[email protected]>
*/
+/**
+ * Notes on wide points and sprite mode:
+ *
+ * In wide point/sprite mode we effectively need to convert each incoming
+ * vertex into four outgoing vertices specifying the corners of a quad.
+ * Since we don't (yet) have geometry shaders, we have to handle this here
+ * in the draw module.
+ *
+ * For sprites, it also means that this is where we have to handle texcoords
+ * for the vertices of the quad. OpenGL's GL_COORD_REPLACE state specifies
+ * if/how enabled texcoords are automatically generated for sprites. We pass
+ * that info through gallium in the pipe_rasterizer_state::sprite_coord_mode
+ * array.
+ *
+ * Additionally, GLSL's gl_PointCoord fragment attribute has to be handled
+ * here as well. This is basically an additional texture/generic attribute
+ * that varies .x from 0 to 1 horizontally across the point and varies .y
+ * vertically from 0 to 1 down the sprite.
+ *
+ * With geometry shaders, the state tracker could create a GS to do
+ * most/all of this.
+ */
+
+
#include "util/u_math.h"
#include "util/u_memory.h"
#include "pipe/p_defines.h"
@@ -52,7 +76,7 @@ struct widepoint_stage {
int psize_slot;
- int point_coord_fs_input; /**< input for pointcoord (and fog) */
+ int point_coord_fs_input; /**< input for pointcoord */
};
@@ -64,8 +88,6 @@ widepoint_stage( struct draw_stage *stage )
}
-
-
/**
* Set the vertex texcoords for sprite mode.
* Coords may be left untouched or set to a right-side-up or upside-down
@@ -89,10 +111,12 @@ static void set_texcoords(const struct widepoint_stage *wide,
}
if (wide->point_coord_fs_input >= 0) {
- /* put gl_PointCoord into extra vertex output's zw components */
- uint k = wide->stage.draw->extra_vp_outputs.slot;
- v->data[k][2] = tc[0];
- v->data[k][3] = tc[1];
+ /* put gl_PointCoord into the extra vertex slot */
+ uint slot = wide->stage.draw->extra_vp_outputs.slot;
+ v->data[slot][0] = tc[0];
+ v->data[slot][1] = tc[1];
+ v->data[slot][2] = 0.0F;
+ v->data[slot][3] = 1.0F;
}
}
@@ -182,10 +206,10 @@ static void widepoint_point( struct draw_stage *stage,
static int
-find_fog_input_attrib(struct draw_context *draw)
+find_pntc_input_attrib(struct draw_context *draw)
{
- /* Scan the fragment program's input decls to find the fogcoord
- * attribute. The z/w components will store the point coord.
+ /* Scan the fragment program's input decls to find the pointcoord
+ * attribute. The xy components will store the point coord.
*/
return 0; /* XXX fix this */
}
@@ -229,8 +253,8 @@ static void widepoint_first_point( struct draw_stage *stage,
}
wide->num_texcoords = j;
- /* find fragment shader PointCoord/Fog input */
- wide->point_coord_fs_input = find_fog_input_attrib(draw);
+ /* find fragment shader PointCoord input */
+ wide->point_coord_fs_input = find_pntc_input_attrib(draw);
/* setup extra vp output (point coord implemented as a texcoord) */
draw->extra_vp_outputs.semantic_name = TGSI_SEMANTIC_GENERIC;
diff --git a/src/gallium/auxiliary/draw/draw_vs_aos.c b/src/gallium/auxiliary/draw/draw_vs_aos.c
index 9e37a26c1e2..62e04a65f30 100644
--- a/src/gallium/auxiliary/draw/draw_vs_aos.c
+++ b/src/gallium/auxiliary/draw/draw_vs_aos.c
@@ -1758,24 +1758,24 @@ emit_instruction( struct aos_compilation *cp,
case TGSI_OPCODE_SUB:
return emit_SUB(cp, inst);
- case TGSI_OPCODE_LERP:
+ case TGSI_OPCODE_LRP:
// return emit_LERP(cp, inst);
return FALSE;
- case TGSI_OPCODE_FRAC:
+ case TGSI_OPCODE_FRC:
return emit_FRC(cp, inst);
case TGSI_OPCODE_CLAMP:
// return emit_CLAMP(cp, inst);
return FALSE;
- case TGSI_OPCODE_FLOOR:
+ case TGSI_OPCODE_FLR:
return emit_FLR(cp, inst);
case TGSI_OPCODE_ROUND:
return emit_RND(cp, inst);
- case TGSI_OPCODE_EXPBASE2:
+ case TGSI_OPCODE_EX2:
#if FAST_MATH
return emit_EXPBASE2(cp, inst);
#elif 0
@@ -1787,13 +1787,13 @@ emit_instruction( struct aos_compilation *cp,
return FALSE;
#endif
- case TGSI_OPCODE_LOGBASE2:
+ case TGSI_OPCODE_LG2:
return emit_LG2(cp, inst);
- case TGSI_OPCODE_POWER:
+ case TGSI_OPCODE_POW:
return emit_POW(cp, inst);
- case TGSI_OPCODE_CROSSPRODUCT:
+ case TGSI_OPCODE_XPD:
return emit_XPD(cp, inst);
case TGSI_OPCODE_ABS:
@@ -1891,8 +1891,9 @@ static boolean note_immediate( struct aos_compilation *cp,
unsigned pos = cp->num_immediates++;
unsigned j;
+ assert( imm->Immediate.NrTokens <= 4 + 1 );
for (j = 0; j < imm->Immediate.NrTokens - 1; j++) {
- cp->vaos->machine->immediate[pos][j] = imm->u.ImmediateFloat32[j].Float;
+ cp->vaos->machine->immediate[pos][j] = imm->u[j].Float;
}
return TRUE;
diff --git a/src/gallium/auxiliary/draw/draw_vs_llvm.c b/src/gallium/auxiliary/draw/draw_vs_llvm.c
index 727977bc3af..b3535c0e48e 100644
--- a/src/gallium/auxiliary/draw/draw_vs_llvm.c
+++ b/src/gallium/auxiliary/draw/draw_vs_llvm.c
@@ -119,7 +119,7 @@ draw_create_vs_llvm(struct draw_context *draw,
vs->base.create_varient = draw_vs_varient_generic;
vs->base.run_linear = vs_llvm_run_linear;
vs->base.delete = vs_llvm_delete;
- vs->machine = &draw->vs.machine;
+ vs->machine = draw->vs.machine;
{
struct gallivm_ir *ir = gallivm_ir_new(GALLIVM_VS);
diff --git a/src/gallium/auxiliary/gallivm/instructionssoa.cpp b/src/gallium/auxiliary/gallivm/instructionssoa.cpp
index 2d2af3085e6..721b7d2d833 100644
--- a/src/gallium/auxiliary/gallivm/instructionssoa.cpp
+++ b/src/gallium/auxiliary/gallivm/instructionssoa.cpp
@@ -128,7 +128,7 @@ void InstructionsSoa::createFunctionMap()
m_functionsMap[TGSI_OPCODE_DP4] = "dp4";
m_functionsMap[TGSI_OPCODE_MIN] = "min";
m_functionsMap[TGSI_OPCODE_MAX] = "max";
- m_functionsMap[TGSI_OPCODE_POWER] = "pow";
+ m_functionsMap[TGSI_OPCODE_POW] = "pow";
m_functionsMap[TGSI_OPCODE_LIT] = "lit";
m_functionsMap[TGSI_OPCODE_RSQ] = "rsq";
m_functionsMap[TGSI_OPCODE_SLT] = "slt";
@@ -311,7 +311,7 @@ std::vector<llvm::Value*> InstructionsSoa::mul(const std::vector<llvm::Value*> i
std::vector<llvm::Value*> InstructionsSoa::pow(const std::vector<llvm::Value*> in1,
const std::vector<llvm::Value*> in2)
{
- llvm::Function *func = function(TGSI_OPCODE_POWER);
+ llvm::Function *func = function(TGSI_OPCODE_POW);
return callBuiltin(func, in1, in2);
}
diff --git a/src/gallium/auxiliary/gallivm/tgsitollvm.cpp b/src/gallium/auxiliary/gallivm/tgsitollvm.cpp
index 5b08200d142..bf84401e112 100644
--- a/src/gallium/auxiliary/gallivm/tgsitollvm.cpp
+++ b/src/gallium/auxiliary/gallivm/tgsitollvm.cpp
@@ -160,10 +160,11 @@ translate_immediate(Storage *storage,
{
float vec[4];
int i;
+ assert( imm->Immediate.NrTokens <= 4 + 1 );
for (i = 0; i < imm->Immediate.NrTokens - 1; ++i) {
switch (imm->Immediate.DataType) {
case TGSI_IMM_FLOAT32:
- vec[i] = imm->u.ImmediateFloat32[i].Float;
+ vec[i] = imm->u[i].Float;
break;
default:
assert(0);
@@ -179,10 +180,11 @@ translate_immediateir(StorageSoa *storage,
{
float vec[4];
int i;
+ assert( imm->Immediate.NrTokens <= 4 + 1 );
for (i = 0; i < imm->Immediate.NrTokens - 1; ++i) {
switch (imm->Immediate.DataType) {
case TGSI_IMM_FLOAT32:
- vec[i] = imm->u.ImmediateFloat32[i].Float;
+ vec[i] = imm->u[i].Float;
break;
default:
assert(0);
@@ -336,7 +338,7 @@ translate_instruction(llvm::Module *module,
out = instr->sub(inputs[0], inputs[1]);
}
break;
- case TGSI_OPCODE_LERP: {
+ case TGSI_OPCODE_LRP: {
out = instr->lerp(inputs[0], inputs[1], inputs[2]);
}
break;
@@ -348,17 +350,11 @@ translate_instruction(llvm::Module *module,
out = instr->cnd0(inputs[0], inputs[1], inputs[2]);
}
break;
- case TGSI_OPCODE_DOT2ADD: {
+ case TGSI_OPCODE_DP2A: {
out = instr->dot2add(inputs[0], inputs[1], inputs[2]);
}
break;
- case TGSI_OPCODE_INDEX:
- break;
- case TGSI_OPCODE_NEGATE: {
- out = instr->neg(inputs[0]);
- }
- break;
- case TGSI_OPCODE_FRAC: {
+ case TGSI_OPCODE_FRC: {
out = instr->frc(inputs[0]);
}
break;
@@ -366,30 +362,28 @@ translate_instruction(llvm::Module *module,
out = instr->clamp(inputs[0]);
}
break;
- case TGSI_OPCODE_FLOOR: {
+ case TGSI_OPCODE_FLR: {
out = instr->floor(inputs[0]);
}
break;
case TGSI_OPCODE_ROUND:
break;
- case TGSI_OPCODE_EXPBASE2: {
+ case TGSI_OPCODE_EX2: {
out = instr->ex2(inputs[0]);
}
break;
- case TGSI_OPCODE_LOGBASE2: {
+ case TGSI_OPCODE_LG2: {
out = instr->lg2(inputs[0]);
}
break;
- case TGSI_OPCODE_POWER: {
+ case TGSI_OPCODE_POW: {
out = instr->pow(inputs[0], inputs[1]);
}
break;
- case TGSI_OPCODE_CROSSPRODUCT: {
+ case TGSI_OPCODE_XPD: {
out = instr->cross(inputs[0], inputs[1]);
}
break;
- case TGSI_OPCODE_MULTIPLYMATRIX:
- break;
case TGSI_OPCODE_ABS: {
out = instr->abs(inputs[0]);
}
@@ -522,7 +516,7 @@ translate_instruction(llvm::Module *module,
return; //just update the state
}
break;
- case TGSI_OPCODE_LOOP:
+ case TGSI_OPCODE_BGNFOR:
break;
case TGSI_OPCODE_REP:
break;
@@ -538,7 +532,7 @@ translate_instruction(llvm::Module *module,
return; //just update the state
}
break;
- case TGSI_OPCODE_ENDLOOP:
+ case TGSI_OPCODE_ENDFOR:
break;
case TGSI_OPCODE_ENDREP:
break;
@@ -580,7 +574,7 @@ translate_instruction(llvm::Module *module,
break;
case TGSI_OPCODE_ENDPRIM:
break;
- case TGSI_OPCODE_BGNLOOP2: {
+ case TGSI_OPCODE_BGNLOOP: {
instr->beginLoop();
storage->setCurrentBlock(instr->currentBlock());
return;
@@ -593,7 +587,7 @@ translate_instruction(llvm::Module *module,
return;
}
break;
- case TGSI_OPCODE_ENDLOOP2: {
+ case TGSI_OPCODE_ENDLOOP: {
instr->endLoop();
storage->setCurrentBlock(instr->currentBlock());
return;
@@ -617,14 +611,6 @@ translate_instruction(llvm::Module *module,
break;
case TGSI_OPCODE_NOP:
break;
- case TGSI_OPCODE_M4X3:
- break;
- case TGSI_OPCODE_M3X4:
- break;
- case TGSI_OPCODE_M3X3:
- break;
- case TGSI_OPCODE_M3X2:
- break;
case TGSI_OPCODE_CALLNZ:
break;
case TGSI_OPCODE_IFC:
@@ -778,44 +764,38 @@ translate_instructionir(llvm::Module *module,
out = instr->sub(inputs[0], inputs[1]);
}
break;
- case TGSI_OPCODE_LERP: {
+ case TGSI_OPCODE_LRP: {
}
break;
case TGSI_OPCODE_CND:
break;
case TGSI_OPCODE_CND0:
break;
- case TGSI_OPCODE_DOT2ADD:
+ case TGSI_OPCODE_DP2A:
break;
- case TGSI_OPCODE_INDEX:
- break;
- case TGSI_OPCODE_NEGATE:
- break;
- case TGSI_OPCODE_FRAC: {
+ case TGSI_OPCODE_FRC: {
}
break;
case TGSI_OPCODE_CLAMP:
break;
- case TGSI_OPCODE_FLOOR: {
+ case TGSI_OPCODE_FLR: {
}
break;
case TGSI_OPCODE_ROUND:
break;
- case TGSI_OPCODE_EXPBASE2: {
+ case TGSI_OPCODE_EX2: {
}
break;
- case TGSI_OPCODE_LOGBASE2: {
+ case TGSI_OPCODE_LG2: {
}
break;
- case TGSI_OPCODE_POWER: {
+ case TGSI_OPCODE_POW: {
out = instr->pow(inputs[0], inputs[1]);
}
break;
- case TGSI_OPCODE_CROSSPRODUCT: {
+ case TGSI_OPCODE_XPD: {
}
break;
- case TGSI_OPCODE_MULTIPLYMATRIX:
- break;
case TGSI_OPCODE_ABS: {
out = instr->abs(inputs[0]);
}
@@ -910,7 +890,7 @@ translate_instructionir(llvm::Module *module,
case TGSI_OPCODE_IF: {
}
break;
- case TGSI_OPCODE_LOOP:
+ case TGSI_OPCODE_BGNFOR:
break;
case TGSI_OPCODE_REP:
break;
@@ -920,7 +900,7 @@ translate_instructionir(llvm::Module *module,
case TGSI_OPCODE_ENDIF: {
}
break;
- case TGSI_OPCODE_ENDLOOP:
+ case TGSI_OPCODE_ENDFOR:
break;
case TGSI_OPCODE_ENDREP:
break;
@@ -961,13 +941,13 @@ translate_instructionir(llvm::Module *module,
break;
case TGSI_OPCODE_ENDPRIM:
break;
- case TGSI_OPCODE_BGNLOOP2: {
+ case TGSI_OPCODE_BGNLOOP: {
}
break;
case TGSI_OPCODE_BGNSUB: {
}
break;
- case TGSI_OPCODE_ENDLOOP2: {
+ case TGSI_OPCODE_ENDLOOP: {
}
break;
case TGSI_OPCODE_ENDSUB: {
@@ -983,14 +963,6 @@ translate_instructionir(llvm::Module *module,
break;
case TGSI_OPCODE_NOP:
break;
- case TGSI_OPCODE_M4X3:
- break;
- case TGSI_OPCODE_M3X4:
- break;
- case TGSI_OPCODE_M3X3:
- break;
- case TGSI_OPCODE_M3X2:
- break;
case TGSI_OPCODE_NRM4:
break;
case TGSI_OPCODE_CALLNZ:
diff --git a/src/gallium/auxiliary/tgsi/Makefile b/src/gallium/auxiliary/tgsi/Makefile
index b4900e8dbaa..5f0a580b096 100644
--- a/src/gallium/auxiliary/tgsi/Makefile
+++ b/src/gallium/auxiliary/tgsi/Makefile
@@ -16,6 +16,7 @@ C_SOURCES = \
tgsi_sse2.c \
tgsi_text.c \
tgsi_transform.c \
+ tgsi_ureg.c \
tgsi_util.c
include ../../Makefile.template
diff --git a/src/gallium/auxiliary/tgsi/SConscript b/src/gallium/auxiliary/tgsi/SConscript
index 8200cce42f5..b6bc2924f06 100644
--- a/src/gallium/auxiliary/tgsi/SConscript
+++ b/src/gallium/auxiliary/tgsi/SConscript
@@ -16,6 +16,7 @@ tgsi = env.ConvenienceLibrary(
'tgsi_sse2.c',
'tgsi_text.c',
'tgsi_transform.c',
+ 'tgsi_ureg.c',
'tgsi_util.c',
])
diff --git a/src/gallium/auxiliary/tgsi/tgsi-instruction-set.txt b/src/gallium/auxiliary/tgsi/tgsi-instruction-set.txt
index a3f4947c734..802ec371189 100644
--- a/src/gallium/auxiliary/tgsi/tgsi-instruction-set.txt
+++ b/src/gallium/auxiliary/tgsi/tgsi-instruction-set.txt
@@ -665,9 +665,18 @@ TGSI Instruction Specification
TBD
-1.9.8 LOOP - Loop
+1.9.8 BGNFOR - Begin a For-Loop
- TBD
+ dst.x = floor(src.x)
+ dst.y = floor(src.y)
+ dst.z = floor(src.z)
+
+ if (dst.y <= 0)
+ pc = [matching ENDFOR] + 1
+ endif
+
+ Note: The destination must be a loop register.
+ The source must be a constant register.
1.9.9 REP - Repeat
@@ -685,9 +694,16 @@ TGSI Instruction Specification
TBD
-1.9.12 ENDLOOP - End Loop
+1.9.12 ENDFOR - End a For-Loop
- TBD
+ dst.x = dst.x + dst.z
+ dst.y = dst.y - 1.0
+
+ if (dst.y > 0)
+ pc = [matching BGNFOR instruction] + 1
+ endif
+
+ Note: The destination must be a loop register.
1.9.13 ENDREP - End Repeat
@@ -840,7 +856,7 @@ TGSI Instruction Specification
----------
-1.13.1 BGNLOOP2 - Begin Loop
+1.13.1 BGNLOOP - Begin a Loop
TBD
@@ -850,7 +866,7 @@ TGSI Instruction Specification
TBD
-1.13.3 ENDLOOP2 - End Loop
+1.13.3 ENDLOOP - End a Loop
TBD
diff --git a/src/gallium/auxiliary/tgsi/tgsi_build.c b/src/gallium/auxiliary/tgsi/tgsi_build.c
index d272533d63c..010d501c601 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_build.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_build.c
@@ -335,7 +335,10 @@ tgsi_default_full_immediate( void )
struct tgsi_full_immediate fullimm;
fullimm.Immediate = tgsi_default_immediate();
- fullimm.u.Pointer = (void *) 0;
+ fullimm.u[0].Float = 0.0f;
+ fullimm.u[1].Float = 0.0f;
+ fullimm.u[2].Float = 0.0f;
+ fullimm.u[3].Float = 0.0f;
return fullimm;
}
@@ -352,19 +355,19 @@ immediate_grow(
header_bodysize_grow( header );
}
-struct tgsi_immediate_float32
+union tgsi_immediate_data
tgsi_build_immediate_float32(
float value,
struct tgsi_immediate *immediate,
struct tgsi_header *header )
{
- struct tgsi_immediate_float32 immediate_float32;
+ union tgsi_immediate_data immediate_data;
- immediate_float32.Float = value;
+ immediate_data.Float = value;
immediate_grow( immediate, header );
- return immediate_float32;
+ return immediate_data;
}
unsigned
@@ -384,16 +387,18 @@ tgsi_build_full_immediate(
*immediate = tgsi_build_immediate( header );
+ assert( full_imm->Immediate.NrTokens <= 4 + 1 );
+
for( i = 0; i < full_imm->Immediate.NrTokens - 1; i++ ) {
- struct tgsi_immediate_float32 *if32;
+ union tgsi_immediate_data *data;
if( maxsize <= size )
return 0;
- if32 = (struct tgsi_immediate_float32 *) &tokens[size];
+ data = (union tgsi_immediate_data *) &tokens[size];
size++;
- *if32 = tgsi_build_immediate_float32(
- full_imm->u.ImmediateFloat32[i].Float,
+ *data = tgsi_build_immediate_float32(
+ full_imm->u[i].Float,
immediate,
header );
}
diff --git a/src/gallium/auxiliary/tgsi/tgsi_build.h b/src/gallium/auxiliary/tgsi/tgsi_build.h
index 9a3a077cf2b..17d977b0597 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_build.h
+++ b/src/gallium/auxiliary/tgsi/tgsi_build.h
@@ -119,7 +119,7 @@ tgsi_build_immediate(
struct tgsi_full_immediate
tgsi_default_full_immediate( void );
-struct tgsi_immediate_float32
+union tgsi_immediate_data
tgsi_build_immediate_float32(
float value,
struct tgsi_immediate *immediate,
diff --git a/src/gallium/auxiliary/tgsi/tgsi_dump.c b/src/gallium/auxiliary/tgsi/tgsi_dump.c
index a6994ecd48b..f36b1114a95 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_dump.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_dump.c
@@ -82,7 +82,7 @@ static const char *processor_type_names[] =
"GEOM"
};
-static const char *file_names[] =
+static const char *file_names[TGSI_FILE_COUNT] =
{
"NULL",
"CONST",
@@ -91,7 +91,8 @@ static const char *file_names[] =
"TEMP",
"SAMP",
"ADDR",
- "IMM"
+ "IMM",
+ "LOOP"
};
static const char *interpolate_names[] =
@@ -295,10 +296,12 @@ iter_immediate(
ENM( imm->Immediate.DataType, immediate_type_names );
TXT( " { " );
+
+ assert( imm->Immediate.NrTokens <= 4 + 1 );
for (i = 0; i < imm->Immediate.NrTokens - 1; i++) {
switch (imm->Immediate.DataType) {
case TGSI_IMM_FLOAT32:
- FLT( imm->u.ImmediateFloat32[i].Float );
+ FLT( imm->u[i].Float );
break;
default:
assert( 0 );
@@ -470,8 +473,8 @@ iter_instruction(
switch (inst->Instruction.Opcode) {
case TGSI_OPCODE_IF:
case TGSI_OPCODE_ELSE:
- case TGSI_OPCODE_BGNLOOP2:
- case TGSI_OPCODE_ENDLOOP2:
+ case TGSI_OPCODE_BGNLOOP:
+ case TGSI_OPCODE_ENDLOOP:
case TGSI_OPCODE_CAL:
TXT( " :" );
UID( inst->InstructionExtLabel.Label );
diff --git a/src/gallium/auxiliary/tgsi/tgsi_dump_c.c b/src/gallium/auxiliary/tgsi/tgsi_dump_c.c
index 3dc61c48ca3..4a9c02b1413 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_dump_c.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_dump_c.c
@@ -69,7 +69,7 @@ static const char *TGSI_TOKEN_TYPES[] =
"TOKEN_TYPE_INSTRUCTION"
};
-static const char *TGSI_FILES[] =
+static const char *TGSI_FILES[TGSI_FILE_COUNT] =
{
"FILE_NULL",
"FILE_CONSTANT",
@@ -78,7 +78,8 @@ static const char *TGSI_FILES[] =
"FILE_TEMPORARY",
"FILE_SAMPLER",
"FILE_ADDRESS",
- "FILE_IMMEDIATE"
+ "FILE_IMMEDIATE",
+ "FILE_LOOP"
};
static const char *TGSI_INTERPOLATES[] =
@@ -283,12 +284,13 @@ dump_immediate_verbose(
UIX( imm->Immediate.Padding );
}
+ assert( imm->Immediate.NrTokens <= 4 + 1 );
for( i = 0; i < imm->Immediate.NrTokens - 1; i++ ) {
EOL();
switch( imm->Immediate.DataType ) {
case TGSI_IMM_FLOAT32:
TXT( "\nFloat: " );
- FLT( imm->u.ImmediateFloat32[i].Float );
+ FLT( imm->u[i].Float );
break;
default:
diff --git a/src/gallium/auxiliary/tgsi/tgsi_exec.c b/src/gallium/auxiliary/tgsi/tgsi_exec.c
index fe571a86bca..951ecfd5528 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_exec.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_exec.c
@@ -301,14 +301,14 @@ tgsi_exec_machine_bind_shader(
case TGSI_TOKEN_TYPE_IMMEDIATE:
{
uint size = parse.FullToken.FullImmediate.Immediate.NrTokens - 1;
- assert( size % 4 == 0 );
- assert( mach->ImmLimit + size / 4 <= TGSI_EXEC_NUM_IMMEDIATES );
+ assert( size <= 4 );
+ assert( mach->ImmLimit + 1 <= TGSI_EXEC_NUM_IMMEDIATES );
for( i = 0; i < size; i++ ) {
- mach->Imms[mach->ImmLimit + i / 4][i % 4] =
- parse.FullToken.FullImmediate.u.ImmediateFloat32[i].Float;
+ mach->Imms[mach->ImmLimit][i] =
+ parse.FullToken.FullImmediate.u[i].Float;
}
- mach->ImmLimit += size / 4;
+ mach->ImmLimit += 1;
}
break;
@@ -375,15 +375,9 @@ tgsi_exec_machine_create( void )
if (!mach)
goto fail;
- mach->Addrs = &mach->Temps[TGSI_EXEC_TEMP_ADDR];
+ memset(mach, 0, sizeof(*mach));
- mach->Samplers = NULL;
- mach->Consts = NULL;
- mach->Tokens = NULL;
- mach->Primitives = NULL;
- mach->InterpCoefs = NULL;
- mach->Instructions = NULL;
- mach->Declarations = NULL;
+ mach->Addrs = &mach->Temps[TGSI_EXEC_TEMP_ADDR];
/* Setup constants. */
for( i = 0; i < 4; i++ ) {
@@ -2020,8 +2014,7 @@ exec_instruction(
switch (inst->Instruction.Opcode) {
case TGSI_OPCODE_ARL:
- case TGSI_OPCODE_FLOOR:
- /* TGSI_OPCODE_FLR */
+ case TGSI_OPCODE_FLR:
FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
FETCH( &r[0], 0, chan_index );
micro_flr( &r[0], &r[0] );
@@ -2290,8 +2283,7 @@ exec_instruction(
}
break;
- case TGSI_OPCODE_LERP:
- /* TGSI_OPCODE_LRP */
+ case TGSI_OPCODE_LRP:
FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
FETCH(&r[0], 0, chan_index);
FETCH(&r[1], 1, chan_index);
@@ -2325,8 +2317,7 @@ exec_instruction(
}
break;
- case TGSI_OPCODE_DOT2ADD:
- /* TGSI_OPCODE_DP2A */
+ case TGSI_OPCODE_DP2A:
FETCH( &r[0], 0, CHAN_X );
FETCH( &r[1], 1, CHAN_X );
micro_mul( &r[0], &r[0], &r[1] );
@@ -2344,18 +2335,7 @@ exec_instruction(
}
break;
- case TGSI_OPCODE_INDEX:
- /* XXX: considered for removal */
- assert (0);
- break;
-
- case TGSI_OPCODE_NEGATE:
- /* XXX: considered for removal */
- assert (0);
- break;
-
- case TGSI_OPCODE_FRAC:
- /* TGSI_OPCODE_FRC */
+ case TGSI_OPCODE_FRC:
FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
FETCH( &r[0], 0, chan_index );
micro_frc( &r[0], &r[0] );
@@ -2383,8 +2363,7 @@ exec_instruction(
}
break;
- case TGSI_OPCODE_EXPBASE2:
- /* TGSI_OPCODE_EX2 */
+ case TGSI_OPCODE_EX2:
FETCH(&r[0], 0, CHAN_X);
#if FAST_MATH
@@ -2398,8 +2377,7 @@ exec_instruction(
}
break;
- case TGSI_OPCODE_LOGBASE2:
- /* TGSI_OPCODE_LG2 */
+ case TGSI_OPCODE_LG2:
FETCH( &r[0], 0, CHAN_X );
micro_lg2( &r[0], &r[0] );
FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
@@ -2407,8 +2385,7 @@ exec_instruction(
}
break;
- case TGSI_OPCODE_POWER:
- /* TGSI_OPCODE_POW */
+ case TGSI_OPCODE_POW:
FETCH(&r[0], 0, CHAN_X);
FETCH(&r[1], 1, CHAN_X);
@@ -2419,8 +2396,7 @@ exec_instruction(
}
break;
- case TGSI_OPCODE_CROSSPRODUCT:
- /* TGSI_OPCODE_XPD */
+ case TGSI_OPCODE_XPD:
FETCH(&r[0], 0, CHAN_Y);
FETCH(&r[1], 1, CHAN_Z);
@@ -2462,11 +2438,6 @@ exec_instruction(
}
break;
- case TGSI_OPCODE_MULTIPLYMATRIX:
- /* XXX: considered for removal */
- assert (0);
- break;
-
case TGSI_OPCODE_ABS:
FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
FETCH(&r[0], 0, chan_index);
@@ -3110,9 +3081,9 @@ exec_instruction(
mach->Primitives[mach->Temps[TEMP_PRIMITIVE_I].xyzw[TEMP_PRIMITIVE_C].u[0]] = 0;
break;
- case TGSI_OPCODE_LOOP:
+ case TGSI_OPCODE_BGNFOR:
/* fall-through (for now) */
- case TGSI_OPCODE_BGNLOOP2:
+ case TGSI_OPCODE_BGNLOOP:
/* push LoopMask and ContMasks */
assert(mach->LoopStackTop < TGSI_EXEC_MAX_LOOP_NESTING);
mach->LoopStack[mach->LoopStackTop++] = mach->LoopMask;
@@ -3120,9 +3091,9 @@ exec_instruction(
mach->ContStack[mach->ContStackTop++] = mach->ContMask;
break;
- case TGSI_OPCODE_ENDLOOP:
+ case TGSI_OPCODE_ENDFOR:
/* fall-through (for now at least) */
- case TGSI_OPCODE_ENDLOOP2:
+ case TGSI_OPCODE_ENDLOOP:
/* Restore ContMask, but don't pop */
assert(mach->ContStackTop > 0);
mach->ContMask = mach->ContStack[mach->ContStackTop - 1];
diff --git a/src/gallium/auxiliary/tgsi/tgsi_info.c b/src/gallium/auxiliary/tgsi/tgsi_info.c
index 37f2b66d1f6..ccf4b205ffb 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_info.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_info.c
@@ -26,136 +26,156 @@
**************************************************************************/
#include "util/u_debug.h"
+#include "util/u_memory.h"
#include "tgsi_info.h"
static const struct tgsi_opcode_info opcode_info[TGSI_OPCODE_LAST] =
{
- { 1, 1, 0, 0, "ARL", NULL, NULL },
- { 1, 1, 0, 0, "MOV", NULL, NULL },
- { 1, 1, 0, 0, "LIT", NULL, NULL },
- { 1, 1, 0, 0, "RCP", "RECIP", NULL },
- { 1, 1, 0, 0, "RSQ", "RECIPSQRT", NULL },
- { 1, 1, 0, 0, "EXP", "EXPP", NULL },
- { 1, 1, 0, 0, "LOG", NULL, NULL },
- { 1, 2, 0, 0, "MUL", NULL, NULL },
- { 1, 2, 0, 0, "ADD", NULL, NULL },
- { 1, 2, 0, 0, "DP3", "DOT3", NULL },
- { 1, 2, 0, 0, "DP4", "DOT4", NULL },
- { 1, 2, 0, 0, "DST", NULL, NULL },
- { 1, 2, 0, 0, "MIN", NULL, NULL },
- { 1, 2, 0, 0, "MAX", NULL, NULL },
- { 1, 2, 0, 0, "SLT", "SETLT", NULL },
- { 1, 2, 0, 0, "SGE", "SETGE", NULL },
- { 1, 3, 0, 0, "MAD", "MADD", NULL },
- { 1, 2, 0, 0, "SUB", NULL, NULL },
- { 1, 3, 0, 0, "LRP", "LERP", NULL },
- { 1, 3, 0, 0, "CND", NULL, NULL },
- { 1, 3, 0, 0, "CND0", NULL, NULL },
- { 1, 3, 0, 0, "DP2A", "DP2ADD", "DOT2ADD" },
- { 1, 2, 0, 0, "INDEX", NULL, NULL },
- { 1, 1, 0, 0, "NEGATE", NULL, NULL },
- { 1, 1, 0, 0, "FRC", "FRAC", NULL },
- { 1, 3, 0, 0, "CLAMP", NULL, NULL },
- { 1, 1, 0, 0, "FLR", "FLOOR", NULL },
- { 1, 1, 0, 0, "ROUND", NULL, NULL },
- { 1, 1, 0, 0, "EX2", "EXPBASE2", NULL },
- { 1, 1, 0, 0, "LG2", "LOGBASE2", "LOGP" },
- { 1, 2, 0, 0, "POW", "POWER", NULL },
- { 1, 2, 0, 0, "XPD", "CRS", "CROSSPRODUCT" },
- { 1, 2, 0, 0, "M4X4", "MULTIPLYMATRIX", NULL },
- { 1, 1, 0, 0, "ABS", NULL, NULL },
- { 1, 1, 0, 0, "RCC", NULL, NULL },
- { 1, 2, 0, 0, "DPH", NULL, NULL },
- { 1, 1, 0, 0, "COS", NULL, NULL },
- { 1, 1, 0, 0, "DDX", "DSX", NULL },
- { 1, 1, 0, 0, "DDY", "DSY", NULL },
- { 0, 0, 0, 0, "KILP", NULL, NULL },
- { 1, 1, 0, 0, "PK2H", NULL, NULL },
- { 1, 1, 0, 0, "PK2US", NULL, NULL },
- { 1, 1, 0, 0, "PK4B", NULL, NULL },
- { 1, 1, 0, 0, "PK4UB", NULL, NULL },
- { 1, 2, 0, 0, "RFL", NULL, NULL },
- { 1, 2, 0, 0, "SEQ", NULL, NULL },
- { 1, 2, 0, 0, "SFL", NULL, NULL },
- { 1, 2, 0, 0, "SGT", NULL, NULL },
- { 1, 1, 0, 0, "SIN", NULL, NULL },
- { 1, 2, 0, 0, "SLE", NULL, NULL },
- { 1, 2, 0, 0, "SNE", NULL, NULL },
- { 1, 2, 0, 0, "STR", NULL, NULL },
- { 1, 2, 1, 0, "TEX", "TEXLD", NULL },
- { 1, 4, 1, 0, "TXD", "TEXLDD", NULL },
- { 1, 2, 1, 0, "TXP", NULL, NULL },
- { 1, 1, 0, 0, "UP2H", NULL, NULL },
- { 1, 1, 0, 0, "UP2US", NULL, NULL },
- { 1, 1, 0, 0, "UP4B", NULL, NULL },
- { 1, 1, 0, 0, "UP4UB", NULL, NULL },
- { 1, 3, 0, 0, "X2D", NULL, NULL },
- { 1, 1, 0, 0, "ARA", NULL, NULL },
- { 1, 1, 0, 0, "ARR", "MOVA", NULL },
- { 0, 1, 0, 0, "BRA", NULL, NULL },
- { 0, 0, 0, 1, "CAL", "CALL", NULL },
- { 0, 0, 0, 0, "RET", NULL, NULL },
- { 1, 1, 0, 0, "SGN", "SSG", NULL },
- { 1, 3, 0, 0, "CMP", NULL, NULL },
- { 1, 1, 0, 0, "SCS", "SINCOS", NULL },
- { 1, 2, 1, 0, "TXB", "TEXLDB", NULL },
- { 1, 1, 0, 0, "NRM", NULL, NULL },
- { 1, 2, 0, 0, "DIV", NULL, NULL },
- { 1, 2, 0, 0, "DP2", NULL, NULL },
- { 1, 2, 1, 0, "TXL", NULL, NULL },
- { 0, 0, 0, 0, "BRK", "BREAK", NULL },
- { 0, 1, 0, 1, "IF", NULL, NULL },
- { 0, 0, 0, 0, "LOOP", NULL, NULL },
- { 0, 1, 0, 0, "REP", NULL, NULL },
- { 0, 0, 0, 1, "ELSE", NULL, NULL },
- { 0, 0, 0, 0, "ENDIF", NULL, NULL },
- { 0, 0, 0, 0, "ENDLOOP", NULL, NULL },
- { 0, 0, 0, 0, "ENDREP", NULL, NULL },
- { 0, 1, 0, 0, "PUSHA", NULL, NULL },
- { 1, 0, 0, 0, "POPA", NULL, NULL },
- { 1, 1, 0, 0, "CEIL", NULL, NULL },
- { 1, 1, 0, 0, "I2F", NULL, NULL },
- { 1, 1, 0, 0, "NOT", NULL, NULL },
- { 1, 1, 0, 0, "INT", "TRUNC", NULL },
- { 1, 2, 0, 0, "SHL", NULL, NULL },
- { 1, 2, 0, 0, "SHR", NULL, NULL },
- { 1, 2, 0, 0, "AND", NULL, NULL },
- { 1, 2, 0, 0, "OR", NULL, NULL },
- { 1, 2, 0, 0, "MOD", NULL, NULL },
- { 1, 2, 0, 0, "XOR", NULL, NULL },
- { 1, 3, 0, 0, "SAD", NULL, NULL },
- { 1, 2, 1, 0, "TXF", NULL, NULL },
- { 1, 2, 1, 0, "TXQ", NULL, NULL },
- { 0, 0, 0, 0, "CONT", NULL, NULL },
- { 0, 0, 0, 0, "EMIT", NULL, NULL },
- { 0, 0, 0, 0, "ENDPRIM", NULL, NULL },
- { 0, 0, 0, 1, "BGNLOOP2", NULL, NULL },
- { 0, 0, 0, 0, "BGNSUB", NULL, NULL },
- { 0, 0, 0, 1, "ENDLOOP2", NULL, NULL },
- { 0, 0, 0, 0, "ENDSUB", NULL, NULL },
- { 1, 1, 0, 0, "NOISE1", NULL, NULL },
- { 1, 1, 0, 0, "NOISE2", NULL, NULL },
- { 1, 1, 0, 0, "NOISE3", NULL, NULL },
- { 1, 1, 0, 0, "NOISE4", NULL, NULL },
- { 0, 0, 0, 0, "NOP", NULL, NULL },
- { 1, 2, 0, 0, "M4X3", NULL, NULL },
- { 1, 2, 0, 0, "M3X4", NULL, NULL },
- { 1, 2, 0, 0, "M3X3", NULL, NULL },
- { 1, 2, 0, 0, "M3X2", NULL, NULL },
- { 1, 1, 0, 0, "NRM4", NULL, NULL },
- { 0, 1, 0, 0, "CALLNZ", NULL, NULL },
- { 0, 1, 0, 0, "IFC", NULL, NULL },
- { 0, 1, 0, 0, "BREAKC", NULL, NULL },
- { 0, 1, 0, 0, "KIL", "TEXKILL", NULL },
- { 0, 0, 0, 0, "END", NULL, NULL },
- { 1, 1, 0, 0, "SWZ", NULL, NULL }
+ { 1, 1, 0, 0, "ARL", TGSI_OPCODE_ARL },
+ { 1, 1, 0, 0, "MOV", TGSI_OPCODE_MOV },
+ { 1, 1, 0, 0, "LIT", TGSI_OPCODE_LIT },
+ { 1, 1, 0, 0, "RCP", TGSI_OPCODE_RCP },
+ { 1, 1, 0, 0, "RSQ", TGSI_OPCODE_RSQ },
+ { 1, 1, 0, 0, "EXP", TGSI_OPCODE_EXP },
+ { 1, 1, 0, 0, "LOG", TGSI_OPCODE_LOG },
+ { 1, 2, 0, 0, "MUL", TGSI_OPCODE_MUL },
+ { 1, 2, 0, 0, "ADD", TGSI_OPCODE_ADD },
+ { 1, 2, 0, 0, "DP3", TGSI_OPCODE_DP3 },
+ { 1, 2, 0, 0, "DP4", TGSI_OPCODE_DP4 },
+ { 1, 2, 0, 0, "DST", TGSI_OPCODE_DST },
+ { 1, 2, 0, 0, "MIN", TGSI_OPCODE_MIN },
+ { 1, 2, 0, 0, "MAX", TGSI_OPCODE_MAX },
+ { 1, 2, 0, 0, "SLT", TGSI_OPCODE_SLT },
+ { 1, 2, 0, 0, "SGE", TGSI_OPCODE_SGE },
+ { 1, 3, 0, 0, "MAD", TGSI_OPCODE_MAD },
+ { 1, 2, 0, 0, "SUB", TGSI_OPCODE_SUB },
+ { 1, 3, 0, 0, "LRP", TGSI_OPCODE_LRP },
+ { 1, 3, 0, 0, "CND", TGSI_OPCODE_CND },
+ { 1, 3, 0, 0, "CND0", TGSI_OPCODE_CND0 },
+ { 1, 3, 0, 0, "DP2A", TGSI_OPCODE_DP2A },
+ { 0, 0, 0, 0, "", 22 }, /* removed */
+ { 0, 0, 0, 0, "", 23 }, /* removed */
+ { 1, 1, 0, 0, "FRC", TGSI_OPCODE_FRC },
+ { 1, 3, 0, 0, "CLAMP", TGSI_OPCODE_CLAMP },
+ { 1, 1, 0, 0, "FLR", TGSI_OPCODE_FLR },
+ { 1, 1, 0, 0, "ROUND", TGSI_OPCODE_ROUND },
+ { 1, 1, 0, 0, "EX2", TGSI_OPCODE_EX2 },
+ { 1, 1, 0, 0, "LG2", TGSI_OPCODE_LG2 },
+ { 1, 2, 0, 0, "POW", TGSI_OPCODE_POW },
+ { 1, 2, 0, 0, "XPD", TGSI_OPCODE_XPD },
+ { 0, 0, 0, 0, "", 32 }, /* removed */
+ { 1, 1, 0, 0, "ABS", TGSI_OPCODE_ABS },
+ { 1, 1, 0, 0, "RCC", TGSI_OPCODE_RCC },
+ { 1, 2, 0, 0, "DPH", TGSI_OPCODE_DPH },
+ { 1, 1, 0, 0, "COS", TGSI_OPCODE_COS },
+ { 1, 1, 0, 0, "DDX", TGSI_OPCODE_DDX },
+ { 1, 1, 0, 0, "DDY", TGSI_OPCODE_DDY },
+ { 0, 0, 0, 0, "KILP", TGSI_OPCODE_KILP },
+ { 1, 1, 0, 0, "PK2H", TGSI_OPCODE_PK2H },
+ { 1, 1, 0, 0, "PK2US", TGSI_OPCODE_PK2US },
+ { 1, 1, 0, 0, "PK4B", TGSI_OPCODE_PK4B },
+ { 1, 1, 0, 0, "PK4UB", TGSI_OPCODE_PK4UB },
+ { 1, 2, 0, 0, "RFL", TGSI_OPCODE_RFL },
+ { 1, 2, 0, 0, "SEQ", TGSI_OPCODE_SEQ },
+ { 1, 2, 0, 0, "SFL", TGSI_OPCODE_SFL },
+ { 1, 2, 0, 0, "SGT", TGSI_OPCODE_SGT },
+ { 1, 1, 0, 0, "SIN", TGSI_OPCODE_SIN },
+ { 1, 2, 0, 0, "SLE", TGSI_OPCODE_SLE },
+ { 1, 2, 0, 0, "SNE", TGSI_OPCODE_SNE },
+ { 1, 2, 0, 0, "STR", TGSI_OPCODE_STR },
+ { 1, 2, 1, 0, "TEX", TGSI_OPCODE_TEX },
+ { 1, 4, 1, 0, "TXD", TGSI_OPCODE_TXD },
+ { 1, 2, 1, 0, "TXP", TGSI_OPCODE_TXP },
+ { 1, 1, 0, 0, "UP2H", TGSI_OPCODE_UP2H },
+ { 1, 1, 0, 0, "UP2US", TGSI_OPCODE_UP2US },
+ { 1, 1, 0, 0, "UP4B", TGSI_OPCODE_UP4B },
+ { 1, 1, 0, 0, "UP4UB", TGSI_OPCODE_UP4UB },
+ { 1, 3, 0, 0, "X2D", TGSI_OPCODE_X2D },
+ { 1, 1, 0, 0, "ARA", TGSI_OPCODE_ARA },
+ { 1, 1, 0, 0, "ARR", TGSI_OPCODE_ARR },
+ { 0, 1, 0, 0, "BRA", TGSI_OPCODE_BRA },
+ { 0, 0, 0, 1, "CAL", TGSI_OPCODE_CAL },
+ { 0, 0, 0, 0, "RET", TGSI_OPCODE_RET },
+ { 1, 1, 0, 0, "SSG", TGSI_OPCODE_SSG },
+ { 1, 3, 0, 0, "CMP", TGSI_OPCODE_CMP },
+ { 1, 1, 0, 0, "SCS", TGSI_OPCODE_SCS },
+ { 1, 2, 1, 0, "TXB", TGSI_OPCODE_TXB },
+ { 1, 1, 0, 0, "NRM", TGSI_OPCODE_NRM },
+ { 1, 2, 0, 0, "DIV", TGSI_OPCODE_DIV },
+ { 1, 2, 0, 0, "DP2", TGSI_OPCODE_DP2 },
+ { 1, 2, 1, 0, "TXL", TGSI_OPCODE_TXL },
+ { 0, 0, 0, 0, "BRK", TGSI_OPCODE_BRK },
+ { 0, 1, 0, 1, "IF", TGSI_OPCODE_IF },
+ { 1, 1, 0, 0, "BGNFOR", TGSI_OPCODE_BGNFOR },
+ { 0, 1, 0, 0, "REP", TGSI_OPCODE_REP },
+ { 0, 0, 0, 1, "ELSE", TGSI_OPCODE_ELSE },
+ { 0, 0, 0, 0, "ENDIF", TGSI_OPCODE_ENDIF },
+ { 1, 0, 0, 0, "ENDFOR", TGSI_OPCODE_ENDFOR },
+ { 0, 0, 0, 0, "ENDREP", TGSI_OPCODE_ENDREP },
+ { 0, 1, 0, 0, "PUSHA", TGSI_OPCODE_PUSHA },
+ { 1, 0, 0, 0, "POPA", TGSI_OPCODE_POPA },
+ { 1, 1, 0, 0, "CEIL", TGSI_OPCODE_CEIL },
+ { 1, 1, 0, 0, "I2F", TGSI_OPCODE_I2F },
+ { 1, 1, 0, 0, "NOT", TGSI_OPCODE_NOT },
+ { 1, 1, 0, 0, "TRUNC", TGSI_OPCODE_TRUNC },
+ { 1, 2, 0, 0, "SHL", TGSI_OPCODE_SHL },
+ { 1, 2, 0, 0, "SHR", TGSI_OPCODE_SHR },
+ { 1, 2, 0, 0, "AND", TGSI_OPCODE_AND },
+ { 1, 2, 0, 0, "OR", TGSI_OPCODE_OR },
+ { 1, 2, 0, 0, "MOD", TGSI_OPCODE_MOD },
+ { 1, 2, 0, 0, "XOR", TGSI_OPCODE_XOR },
+ { 1, 3, 0, 0, "SAD", TGSI_OPCODE_SAD },
+ { 1, 2, 1, 0, "TXF", TGSI_OPCODE_TXF },
+ { 1, 2, 1, 0, "TXQ", TGSI_OPCODE_TXQ },
+ { 0, 0, 0, 0, "CONT", TGSI_OPCODE_CONT },
+ { 0, 0, 0, 0, "EMIT", TGSI_OPCODE_EMIT },
+ { 0, 0, 0, 0, "ENDPRIM", TGSI_OPCODE_ENDPRIM },
+ { 0, 0, 0, 1, "BGNLOOP", TGSI_OPCODE_BGNLOOP },
+ { 0, 0, 0, 0, "BGNSUB", TGSI_OPCODE_BGNSUB },
+ { 0, 0, 0, 1, "ENDLOOP", TGSI_OPCODE_ENDLOOP },
+ { 0, 0, 0, 0, "ENDSUB", TGSI_OPCODE_ENDSUB },
+ { 1, 1, 0, 0, "NOISE1", TGSI_OPCODE_NOISE1 },
+ { 1, 1, 0, 0, "NOISE2", TGSI_OPCODE_NOISE2 },
+ { 1, 1, 0, 0, "NOISE3", TGSI_OPCODE_NOISE3 },
+ { 1, 1, 0, 0, "NOISE4", TGSI_OPCODE_NOISE4 },
+ { 0, 0, 0, 0, "NOP", TGSI_OPCODE_NOP },
+ { 0, 0, 0, 0, "", 108 }, /* removed */
+ { 0, 0, 0, 0, "", 109 }, /* removed */
+ { 0, 0, 0, 0, "", 110 }, /* removed */
+ { 0, 0, 0, 0, "", 111 }, /* removed */
+ { 1, 1, 0, 0, "NRM4", TGSI_OPCODE_NRM4 },
+ { 0, 1, 0, 0, "CALLNZ", TGSI_OPCODE_CALLNZ },
+ { 0, 1, 0, 0, "IFC", TGSI_OPCODE_IFC },
+ { 0, 1, 0, 0, "BREAKC", TGSI_OPCODE_BREAKC },
+ { 0, 1, 0, 0, "KIL", TGSI_OPCODE_KIL },
+ { 0, 0, 0, 0, "END", TGSI_OPCODE_END },
+ { 1, 1, 0, 0, "SWZ", TGSI_OPCODE_SWZ }
};
const struct tgsi_opcode_info *
tgsi_get_opcode_info( uint opcode )
{
+ static boolean firsttime = 1;
+
+ if (firsttime) {
+ unsigned i;
+ firsttime = 0;
+ for (i = 0; i < Elements(opcode_info); i++)
+ assert(opcode_info[i].opcode == i);
+ }
+
if (opcode < TGSI_OPCODE_LAST)
return &opcode_info[opcode];
+
assert( 0 );
return NULL;
}
+
+
+const char *
+tgsi_get_opcode_name( uint opcode )
+{
+ const struct tgsi_opcode_info *info = tgsi_get_opcode_info(opcode);
+ return info->mnemonic;
+}
+
diff --git a/src/gallium/auxiliary/tgsi/tgsi_info.h b/src/gallium/auxiliary/tgsi/tgsi_info.h
index 077e25acd7f..b2375c69710 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_info.h
+++ b/src/gallium/auxiliary/tgsi/tgsi_info.h
@@ -41,13 +41,16 @@ struct tgsi_opcode_info
boolean is_tex;
boolean is_branch;
const char *mnemonic;
- const char *alt_mnemonic1;
- const char *alt_mnemonic2;
+ uint opcode;
};
const struct tgsi_opcode_info *
tgsi_get_opcode_info( uint opcode );
+const char *
+tgsi_get_opcode_name( uint opcode );
+
+
#if defined __cplusplus
}
#endif
diff --git a/src/gallium/auxiliary/tgsi/tgsi_opcode_tmp.h b/src/gallium/auxiliary/tgsi/tgsi_opcode_tmp.h
new file mode 100644
index 00000000000..ed594a3e2c7
--- /dev/null
+++ b/src/gallium/auxiliary/tgsi/tgsi_opcode_tmp.h
@@ -0,0 +1,173 @@
+/**************************************************************************
+ *
+ * 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 OP12_TEX
+#define OP12_TEX(a) OP12(a)
+#endif
+
+#ifndef OP14_TEX
+#define OP14_TEX(a) OP14(a)
+#endif
+
+#ifndef OP00_LBL
+#define OP00_LBL(a) OP00(a)
+#endif
+
+#ifndef OP01_LBL
+#define OP01_LBL(a) OP01(a)
+#endif
+
+OP11(ARL)
+OP11(MOV)
+OP11(LIT)
+OP11(RCP)
+OP11(RSQ)
+OP11(EXP)
+OP11(LOG)
+OP12(MUL)
+OP12(ADD)
+OP12(DP3)
+OP12(DP4)
+OP12(DST)
+OP12(MIN)
+OP12(MAX)
+OP12(SLT)
+OP12(SGE)
+OP13(MAD)
+OP12(SUB)
+OP13(LRP)
+OP13(CND)
+OP13(CND0)
+OP13(DP2A)
+OP11(FRC)
+OP13(CLAMP)
+OP11(FLR)
+OP11(ROUND)
+OP11(EX2)
+OP11(LG2)
+OP12(POW)
+OP12(XPD)
+OP11(ABS)
+OP11(RCC)
+OP12(DPH)
+OP11(COS)
+OP11(DDX)
+OP11(DDY)
+OP00(KILP)
+OP11(PK2H)
+OP11(PK2US)
+OP11(PK4B)
+OP11(PK4UB)
+OP12(RFL)
+OP12(SEQ)
+OP12(SFL)
+OP12(SGT)
+OP11(SIN)
+OP12(SLE)
+OP12(SNE)
+OP12(STR)
+OP12_TEX(TEX)
+OP14_TEX(TXD)
+OP12_TEX(TXP)
+OP11(UP2H)
+OP11(UP2US)
+OP11(UP4B)
+OP11(UP4UB)
+OP13(X2D)
+OP11(ARA)
+OP11(ARR)
+OP01(BRA)
+OP00_LBL(CAL)
+OP00(RET)
+OP11(SSG)
+OP13(CMP)
+OP11(SCS)
+OP12_TEX(TXB)
+OP11(NRM)
+OP12(DIV)
+OP12(DP2)
+OP12_TEX(TXL)
+OP00(BRK)
+OP01_LBL(IF)
+OP11(BGNFOR)
+OP01(REP)
+OP00_LBL(ELSE)
+OP00(ENDIF)
+OP10(ENDFOR)
+OP00(ENDREP)
+OP01(PUSHA)
+OP10(POPA)
+OP11(CEIL)
+OP11(I2F)
+OP11(NOT)
+OP11(TRUNC)
+OP12(SHL)
+OP12(SHR)
+OP12(AND)
+OP12(OR)
+OP12(MOD)
+OP12(XOR)
+OP13(SAD)
+OP12_TEX(TXF)
+OP12_TEX(TXQ)
+OP00(CONT)
+OP00(EMIT)
+OP00(ENDPRIM)
+OP00_LBL(BGNLOOP)
+OP00(BGNSUB)
+OP00_LBL(ENDLOOP)
+OP00(ENDSUB)
+OP11(NOISE1)
+OP11(NOISE2)
+OP11(NOISE3)
+OP11(NOISE4)
+OP00(NOP)
+OP11(NRM4)
+OP01(CALLNZ)
+OP01(IFC)
+OP01(BREAKC)
+OP01(KIL)
+OP00(END)
+OP11(SWZ)
+
+
+#undef OP00
+#undef OP01
+#undef OP10
+#undef OP11
+#undef OP12
+#undef OP13
+
+#ifdef OP14
+#undef OP14
+#endif
+
+#undef OP00_LBL
+#undef OP01_LBL
+
+#undef OP12_TEX
+#undef OP14_TEX
+
diff --git a/src/gallium/auxiliary/tgsi/tgsi_parse.c b/src/gallium/auxiliary/tgsi/tgsi_parse.c
index 7f2cfb7988f..4870f82b6bd 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_parse.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_parse.c
@@ -42,9 +42,6 @@ void
tgsi_full_token_free(
union tgsi_full_token *full_token )
{
- if( full_token->Token.Type == TGSI_TOKEN_TYPE_IMMEDIATE ) {
- FREE( (void *) full_token->FullImmediate.u.Pointer );
- }
}
unsigned
@@ -156,14 +153,8 @@ tgsi_parse_token(
case TGSI_IMM_FLOAT32:
{
uint imm_count = imm->Immediate.NrTokens - 1;
- struct tgsi_immediate_float32 *data;
-
- data = (struct tgsi_immediate_float32 *) MALLOC(sizeof(struct tgsi_immediate_float32) * imm_count);
- if (data) {
- for (i = 0; i < imm_count; i++) {
- next_token(ctx, &data[i]);
- }
- imm->u.ImmediateFloat32 = data;
+ for (i = 0; i < imm_count; i++) {
+ next_token(ctx, &imm->u[i]);
}
}
break;
diff --git a/src/gallium/auxiliary/tgsi/tgsi_parse.h b/src/gallium/auxiliary/tgsi/tgsi_parse.h
index a289e26e3ac..1035bda1a87 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_parse.h
+++ b/src/gallium/auxiliary/tgsi/tgsi_parse.h
@@ -73,11 +73,7 @@ struct tgsi_full_declaration
struct tgsi_full_immediate
{
struct tgsi_immediate Immediate;
- union
- {
- const void *Pointer;
- const struct tgsi_immediate_float32 *ImmediateFloat32;
- } u;
+ union tgsi_immediate_data u[4];
};
#define TGSI_FULL_MAX_DST_REGISTERS 2
diff --git a/src/gallium/auxiliary/tgsi/tgsi_ppc.c b/src/gallium/auxiliary/tgsi/tgsi_ppc.c
index 0c64ae57131..2d6ad12ffbd 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_ppc.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_ppc.c
@@ -38,6 +38,7 @@
#include "util/u_math.h"
#include "util/u_memory.h"
#include "util/u_sse.h"
+#include "tgsi/tgsi_info.h"
#include "tgsi/tgsi_parse.h"
#include "tgsi/tgsi_util.h"
#include "tgsi_dump.h"
@@ -619,17 +620,17 @@ emit_unaryop(struct gen_context *gen, struct tgsi_full_instruction *inst)
ppc_vandc(gen->f, v1, v0, bit31_vec); /* v1 = v0 & ~bit31 */
}
break;
- case TGSI_OPCODE_FLOOR:
+ case TGSI_OPCODE_FLR:
ppc_vrfim(gen->f, v1, v0); /* v1 = floor(v0) */
break;
- case TGSI_OPCODE_FRAC:
+ case TGSI_OPCODE_FRC:
ppc_vrfim(gen->f, v1, v0); /* tmp = floor(v0) */
ppc_vsubfp(gen->f, v1, v0, v1); /* v1 = v0 - v1 */
break;
- case TGSI_OPCODE_EXPBASE2:
+ case TGSI_OPCODE_EX2:
ppc_vexptefp(gen->f, v1, v0); /* v1 = 2^v0 */
break;
- case TGSI_OPCODE_LOGBASE2:
+ case TGSI_OPCODE_LG2:
/* XXX this may be broken! */
ppc_vlogefp(gen->f, v1, v0); /* v1 = log2(v0) */
break;
@@ -1111,10 +1112,10 @@ emit_instruction(struct gen_context *gen,
case TGSI_OPCODE_MOV:
case TGSI_OPCODE_SWZ:
case TGSI_OPCODE_ABS:
- case TGSI_OPCODE_FLOOR:
- case TGSI_OPCODE_FRAC:
- case TGSI_OPCODE_EXPBASE2:
- case TGSI_OPCODE_LOGBASE2:
+ case TGSI_OPCODE_FLR:
+ case TGSI_OPCODE_FRC:
+ case TGSI_OPCODE_EX2:
+ case TGSI_OPCODE_LG2:
emit_unaryop(gen, inst);
break;
case TGSI_OPCODE_RSQ:
@@ -1317,8 +1318,10 @@ tgsi_emit_ppc(const struct tgsi_token *tokens,
ok = emit_instruction(&gen, &parse.FullToken.FullInstruction);
if (!ok) {
- debug_printf("failed to translate tgsi opcode %d to PPC (%s)\n",
- parse.FullToken.FullInstruction.Instruction.Opcode,
+ uint opcode = parse.FullToken.FullInstruction.Instruction.Opcode;
+ debug_printf("failed to translate tgsi opcode %d (%s) to PPC (%s)\n",
+ opcode,
+ tgsi_get_opcode_name(opcode),
parse.FullHeader.Processor.Processor == TGSI_PROCESSOR_VERTEX ?
"vertex shader" : "fragment shader");
}
@@ -1333,7 +1336,7 @@ tgsi_emit_ppc(const struct tgsi_token *tokens,
assert(num_immediates < TGSI_EXEC_NUM_IMMEDIATES);
for (i = 0; i < size; i++) {
immediates[num_immediates][i] =
- parse.FullToken.FullImmediate.u.ImmediateFloat32[i].Float;
+ parse.FullToken.FullImmediate.u[i].Float;
}
num_immediates++;
}
diff --git a/src/gallium/auxiliary/tgsi/tgsi_sanity.c b/src/gallium/auxiliary/tgsi/tgsi_sanity.c
index 6f1f5c2b4b0..4fe8553c423 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_sanity.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_sanity.c
@@ -131,7 +131,7 @@ is_register_used(
return (ctx->regs_used[file][index / BITS_IN_REG_FLAG] & (1 << (index % BITS_IN_REG_FLAG))) ? TRUE : FALSE;
}
-static const char *file_names[] =
+static const char *file_names[TGSI_FILE_COUNT] =
{
"NULL",
"CONST",
@@ -140,7 +140,8 @@ static const char *file_names[] =
"TEMP",
"SAMP",
"ADDR",
- "IMM"
+ "IMM",
+ "LOOP"
};
static boolean
@@ -234,9 +235,29 @@ iter_instruction(
index,
"indirect",
FALSE );
- if (file != TGSI_FILE_ADDRESS || index != 0)
- report_warning( ctx, "Indirect register not ADDR[0]" );
+ if (!(file == TGSI_FILE_ADDRESS || file == TGSI_FILE_LOOP) || index != 0) {
+ report_warning(ctx, "Indirect register neither ADDR[0] nor LOOP[0]");
+ }
+ }
+ }
+
+ switch (inst->Instruction.Opcode) {
+ case TGSI_OPCODE_BGNFOR:
+ case TGSI_OPCODE_ENDFOR:
+ if (inst->FullDstRegisters[0].DstRegister.File != TGSI_FILE_LOOP ||
+ inst->FullDstRegisters[0].DstRegister.Index != 0) {
+ report_error(ctx, "Destination register must be LOOP[0]");
+ }
+ break;
+ }
+
+ switch (inst->Instruction.Opcode) {
+ case TGSI_OPCODE_BGNFOR:
+ if (inst->FullSrcRegisters[0].SrcRegister.File != TGSI_FILE_CONSTANT &&
+ inst->FullSrcRegisters[0].SrcRegister.File != TGSI_FILE_IMMEDIATE) {
+ report_error(ctx, "Source register file must be either CONST or IMM");
}
+ break;
}
ctx->num_instructions++;
diff --git a/src/gallium/auxiliary/tgsi/tgsi_sse2.c b/src/gallium/auxiliary/tgsi/tgsi_sse2.c
index 4c3343d26c3..cfec5cfc019 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_sse2.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_sse2.c
@@ -36,6 +36,7 @@
#if defined(PIPE_ARCH_SSE)
#include "util/u_sse.h"
#endif
+#include "tgsi/tgsi_info.h"
#include "tgsi/tgsi_parse.h"
#include "tgsi/tgsi_util.h"
#include "tgsi_exec.h"
@@ -1467,15 +1468,15 @@ emit_tex( struct x86_function *func,
switch (inst->InstructionExtTexture.Texture) {
case TGSI_TEXTURE_1D:
- case TGSI_TEXTURE_SHADOW1D:
count = 1;
break;
case TGSI_TEXTURE_2D:
case TGSI_TEXTURE_RECT:
- case TGSI_TEXTURE_SHADOW2D:
- case TGSI_TEXTURE_SHADOWRECT:
count = 2;
break;
+ case TGSI_TEXTURE_SHADOW1D:
+ case TGSI_TEXTURE_SHADOW2D:
+ case TGSI_TEXTURE_SHADOWRECT:
case TGSI_TEXTURE_3D:
case TGSI_TEXTURE_CUBE:
count = 3;
@@ -2064,8 +2065,7 @@ emit_instruction(
}
break;
- case TGSI_OPCODE_LERP:
- /* TGSI_OPCODE_LRP */
+ case TGSI_OPCODE_LRP:
FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) {
FETCH( func, *inst, 0, 0, chan_index );
FETCH( func, *inst, 1, 1, chan_index );
@@ -2085,8 +2085,7 @@ emit_instruction(
return 0;
break;
- case TGSI_OPCODE_DOT2ADD:
- /* TGSI_OPCODE_DP2A */
+ case TGSI_OPCODE_DP2A:
FETCH( func, *inst, 0, 0, CHAN_X ); /* xmm0 = src[0].x */
FETCH( func, *inst, 1, 1, CHAN_X ); /* xmm1 = src[1].x */
emit_mul( func, 0, 1 ); /* xmm0 = xmm0 * xmm1 */
@@ -2101,16 +2100,7 @@ emit_instruction(
}
break;
- case TGSI_OPCODE_INDEX:
- return 0;
- break;
-
- case TGSI_OPCODE_NEGATE:
- return 0;
- break;
-
- case TGSI_OPCODE_FRAC:
- /* TGSI_OPCODE_FRC */
+ case TGSI_OPCODE_FRC:
FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) {
FETCH( func, *inst, 0, 0, chan_index );
emit_frc( func, 0, 0 );
@@ -2122,8 +2112,7 @@ emit_instruction(
return 0;
break;
- case TGSI_OPCODE_FLOOR:
- /* TGSI_OPCODE_FLR */
+ case TGSI_OPCODE_FLR:
FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) {
FETCH( func, *inst, 0, 0, chan_index );
emit_flr( func, 0, 0 );
@@ -2139,8 +2128,7 @@ emit_instruction(
}
break;
- case TGSI_OPCODE_EXPBASE2:
- /* TGSI_OPCODE_EX2 */
+ case TGSI_OPCODE_EX2:
FETCH( func, *inst, 0, 0, CHAN_X );
emit_ex2( func, 0, 0 );
FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) {
@@ -2148,8 +2136,7 @@ emit_instruction(
}
break;
- case TGSI_OPCODE_LOGBASE2:
- /* TGSI_OPCODE_LG2 */
+ case TGSI_OPCODE_LG2:
FETCH( func, *inst, 0, 0, CHAN_X );
emit_lg2( func, 0, 0 );
FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) {
@@ -2157,8 +2144,7 @@ emit_instruction(
}
break;
- case TGSI_OPCODE_POWER:
- /* TGSI_OPCODE_POW */
+ case TGSI_OPCODE_POW:
FETCH( func, *inst, 0, 0, CHAN_X );
FETCH( func, *inst, 1, 1, CHAN_X );
emit_pow( func, 0, 0, 0, 1 );
@@ -2167,8 +2153,7 @@ emit_instruction(
}
break;
- case TGSI_OPCODE_CROSSPRODUCT:
- /* TGSI_OPCODE_XPD */
+ case TGSI_OPCODE_XPD:
if( IS_DST0_CHANNEL_ENABLED( *inst, CHAN_X ) ||
IS_DST0_CHANNEL_ENABLED( *inst, CHAN_Y ) ) {
FETCH( func, *inst, 1, 1, CHAN_Z );
@@ -2214,10 +2199,6 @@ emit_instruction(
}
break;
- case TGSI_OPCODE_MULTIPLYMATRIX:
- return 0;
- break;
-
case TGSI_OPCODE_ABS:
FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) {
FETCH( func, *inst, 0, 0, chan_index );
@@ -2551,7 +2532,7 @@ emit_instruction(
return 0;
break;
- case TGSI_OPCODE_LOOP:
+ case TGSI_OPCODE_BGNFOR:
return 0;
break;
@@ -2567,7 +2548,7 @@ emit_instruction(
return 0;
break;
- case TGSI_OPCODE_ENDLOOP:
+ case TGSI_OPCODE_ENDFOR:
return 0;
break;
@@ -2937,8 +2918,10 @@ tgsi_emit_sse2(
&parse.FullToken.FullInstruction );
if (!ok) {
- debug_printf("failed to translate tgsi opcode %d to SSE (%s)\n",
- parse.FullToken.FullInstruction.Instruction.Opcode,
+ uint opcode = parse.FullToken.FullInstruction.Instruction.Opcode;
+ debug_printf("failed to translate tgsi opcode %d (%s) to SSE (%s)\n",
+ opcode,
+ tgsi_get_opcode_name(opcode),
parse.FullHeader.Processor.Processor == TGSI_PROCESSOR_VERTEX ?
"vertex shader" : "fragment shader");
}
@@ -2953,7 +2936,7 @@ tgsi_emit_sse2(
assert(num_immediates < TGSI_EXEC_NUM_IMMEDIATES);
for( i = 0; i < size; i++ ) {
immediates[num_immediates][i] =
- parse.FullToken.FullImmediate.u.ImmediateFloat32[i].Float;
+ parse.FullToken.FullImmediate.u[i].Float;
}
#if 0
debug_printf("SSE FS immediate[%d] = %f %f %f %f\n",
diff --git a/src/gallium/auxiliary/tgsi/tgsi_text.c b/src/gallium/auxiliary/tgsi/tgsi_text.c
index a76bbc91400..d438450b1e4 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_text.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_text.c
@@ -231,7 +231,8 @@ static const char *file_names[TGSI_FILE_COUNT] =
"TEMP",
"SAMP",
"ADDR",
- "IMM"
+ "IMM",
+ "LOOP"
};
static boolean
@@ -789,16 +790,6 @@ match_inst_mnemonic(const char **pcur,
if (str_match_no_case(pcur, info->mnemonic)) {
return TRUE;
}
- if (info->alt_mnemonic1) {
- if (str_match_no_case(pcur, info->alt_mnemonic1)) {
- return TRUE;
- }
- if (info->alt_mnemonic2) {
- if (str_match_no_case(pcur, info->alt_mnemonic2)) {
- return TRUE;
- }
- }
- }
return FALSE;
}
@@ -1091,7 +1082,10 @@ static boolean parse_immediate( struct translate_ctx *ctx )
imm = tgsi_default_full_immediate();
imm.Immediate.NrTokens += 4;
imm.Immediate.DataType = TGSI_IMM_FLOAT32;
- imm.u.Pointer = values;
+ imm.u[0].Float = values[0];
+ imm.u[1].Float = values[1];
+ imm.u[2].Float = values[2];
+ imm.u[3].Float = values[3];
advance = tgsi_build_full_immediate(
&imm,
diff --git a/src/gallium/auxiliary/tgsi/tgsi_ureg.c b/src/gallium/auxiliary/tgsi/tgsi_ureg.c
new file mode 100644
index 00000000000..ba84a82b2b0
--- /dev/null
+++ b/src/gallium/auxiliary/tgsi/tgsi_ureg.c
@@ -0,0 +1,797 @@
+/**************************************************************************
+ *
+ * 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, INC AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+
+#include "pipe/p_context.h"
+#include "pipe/p_state.h"
+#include "tgsi/tgsi_ureg.h"
+#include "tgsi/tgsi_dump.h"
+#include "util/u_memory.h"
+
+union tgsi_any_token {
+ struct tgsi_version version;
+ struct tgsi_header header;
+ struct tgsi_processor processor;
+ struct tgsi_token token;
+ struct tgsi_declaration decl;
+ struct tgsi_declaration_range decl_range;
+ struct tgsi_declaration_semantic decl_semantic;
+ struct tgsi_immediate imm;
+ union tgsi_immediate_data imm_data;
+ struct tgsi_instruction insn;
+ struct tgsi_instruction_ext_nv insn_ext_nv;
+ struct tgsi_instruction_ext_label insn_ext_label;
+ struct tgsi_instruction_ext_texture insn_ext_texture;
+ struct tgsi_instruction_ext_predicate insn_ext_predicate;
+ struct tgsi_src_register src;
+ struct tgsi_src_register_ext_swz src_ext_swz;
+ struct tgsi_src_register_ext_mod src_ext_mod;
+ struct tgsi_dimension dim;
+ struct tgsi_dst_register dst;
+ struct tgsi_dst_register_ext_concode dst_ext_code;
+ struct tgsi_dst_register_ext_modulate dst_ext_mod;
+ struct tgsi_dst_register_ext_predicate dst_ext_pred;
+ unsigned value;
+};
+
+
+struct ureg_tokens {
+ union tgsi_any_token *tokens;
+ unsigned size;
+ unsigned order;
+ unsigned count;
+};
+
+#define UREG_MAX_INPUT PIPE_MAX_ATTRIBS
+#define UREG_MAX_OUTPUT PIPE_MAX_ATTRIBS
+#define UREG_MAX_IMMEDIATE 32
+#define UREG_MAX_TEMP 256
+
+#define DOMAIN_DECL 0
+#define DOMAIN_INSN 1
+
+struct ureg_program
+{
+ unsigned processor;
+ struct pipe_context *pipe;
+
+ struct {
+ unsigned semantic_name;
+ unsigned semantic_index;
+ unsigned interp;
+ } input[UREG_MAX_INPUT];
+ unsigned nr_inputs;
+
+ struct {
+ unsigned semantic_name;
+ unsigned semantic_index;
+ } output[UREG_MAX_OUTPUT];
+ unsigned nr_outputs;
+
+ struct {
+ float v[4];
+ unsigned nr;
+ } immediate[UREG_MAX_IMMEDIATE];
+ unsigned nr_immediates;
+
+ unsigned temps_active[UREG_MAX_TEMP / 32];
+ unsigned nr_temps;
+
+ unsigned nr_constants;
+ unsigned nr_samplers;
+
+ struct ureg_tokens domain[2];
+};
+
+static union tgsi_any_token error_tokens[32];
+
+static void tokens_error( struct ureg_tokens *tokens )
+{
+ tokens->tokens = error_tokens;
+ tokens->size = Elements(error_tokens);
+ tokens->count = 0;
+}
+
+
+static void tokens_expand( struct ureg_tokens *tokens,
+ unsigned count )
+{
+ unsigned old_size = tokens->size * sizeof(unsigned);
+
+ if (tokens->tokens == error_tokens)
+ goto fail;
+
+ while (tokens->count + count > tokens->size) {
+ tokens->size = (1 << ++tokens->order);
+ }
+
+ tokens->tokens = REALLOC(tokens->tokens,
+ old_size,
+ tokens->size * sizeof(unsigned));
+ if (tokens->tokens == NULL)
+ goto fail;
+
+ return;
+
+fail:
+ tokens_error(tokens);
+}
+
+static void set_bad( struct ureg_program *ureg )
+{
+ tokens_error(&ureg->domain[0]);
+}
+
+
+
+static union tgsi_any_token *get_tokens( struct ureg_program *ureg,
+ unsigned domain,
+ unsigned count )
+{
+ struct ureg_tokens *tokens = &ureg->domain[domain];
+ union tgsi_any_token *result;
+
+ if (tokens->count + count > tokens->size)
+ tokens_expand(tokens, count);
+
+ result = &tokens->tokens[tokens->count];
+ tokens->count += count;
+ return result;
+}
+
+
+static union tgsi_any_token *retrieve_token( struct ureg_program *ureg,
+ unsigned domain,
+ unsigned nr )
+{
+ if (ureg->domain[domain].tokens == error_tokens)
+ return &error_tokens[0];
+
+ return &ureg->domain[domain].tokens[nr];
+}
+
+
+
+static INLINE struct ureg_dst
+ureg_dst_register( unsigned file,
+ unsigned index )
+{
+ struct ureg_dst dst;
+
+ dst.File = file;
+ dst.WriteMask = TGSI_WRITEMASK_XYZW;
+ dst.Indirect = 0;
+ dst.Saturate = 0;
+ dst.Index = index;
+ dst.Pad1 = 0;
+ dst.Pad2 = 0;
+
+ return dst;
+}
+
+static INLINE struct ureg_src
+ureg_src_register( unsigned file,
+ unsigned index )
+{
+ struct ureg_src src;
+
+ src.File = file;
+ src.SwizzleX = TGSI_SWIZZLE_X;
+ src.SwizzleY = TGSI_SWIZZLE_Y;
+ src.SwizzleZ = TGSI_SWIZZLE_Z;
+ src.SwizzleW = TGSI_SWIZZLE_W;
+ src.Pad = 0;
+ src.Indirect = 0;
+ src.Absolute = 0;
+ src.Index = index;
+ src.Negate = 0;
+
+ return src;
+}
+
+
+
+
+static struct ureg_src
+ureg_DECL_input( struct ureg_program *ureg,
+ unsigned name,
+ unsigned index,
+ unsigned interp_mode )
+{
+ unsigned i;
+
+ for (i = 0; i < ureg->nr_inputs; i++) {
+ if (ureg->input[i].semantic_name == name &&
+ ureg->input[i].semantic_index == index)
+ goto out;
+ }
+
+ if (ureg->nr_inputs < UREG_MAX_INPUT) {
+ ureg->input[i].semantic_name = name;
+ ureg->input[i].semantic_index = index;
+ ureg->input[i].interp = interp_mode;
+ ureg->nr_inputs++;
+ }
+ else {
+ set_bad( ureg );
+ }
+
+out:
+ return ureg_src_register( TGSI_FILE_INPUT, i );
+}
+
+
+
+struct ureg_src
+ureg_DECL_fs_input( struct ureg_program *ureg,
+ unsigned name,
+ unsigned index,
+ unsigned interp )
+{
+ return ureg_DECL_input( ureg, name, index, interp );
+}
+
+
+struct ureg_src
+ureg_DECL_vs_input( struct ureg_program *ureg,
+ unsigned name,
+ unsigned index )
+{
+ return ureg_DECL_input( ureg, name, index, TGSI_INTERPOLATE_CONSTANT );
+}
+
+
+struct ureg_dst
+ureg_DECL_output( struct ureg_program *ureg,
+ unsigned name,
+ unsigned index )
+{
+ unsigned i;
+
+ for (i = 0; i < ureg->nr_outputs; i++) {
+ if (ureg->output[i].semantic_name == name &&
+ ureg->output[i].semantic_index == index)
+ goto out;
+ }
+
+ if (ureg->nr_outputs < UREG_MAX_OUTPUT) {
+ ureg->output[i].semantic_name = name;
+ ureg->output[i].semantic_index = index;
+ ureg->nr_outputs++;
+ }
+ else {
+ set_bad( ureg );
+ }
+
+out:
+ return ureg_dst_register( TGSI_FILE_OUTPUT, i );
+}
+
+
+/* Returns a new constant register. Keep track of which have been
+ * referred to so that we can emit decls later.
+ *
+ * There is nothing in this code to bind this constant to any tracked
+ * value or manage any constant_buffer contents -- that's the
+ * resposibility of the calling code.
+ */
+struct ureg_src ureg_DECL_constant(struct ureg_program *ureg )
+{
+ return ureg_src_register( TGSI_FILE_TEMPORARY, ureg->nr_constants++ );
+}
+
+
+/* Allocate a new temporary. Temporaries greater than UREG_MAX_TEMP
+ * are legal, but will not be released.
+ */
+struct ureg_dst ureg_DECL_temporary( struct ureg_program *ureg )
+{
+ unsigned i;
+
+ for (i = 0; i < UREG_MAX_TEMP; i += 32) {
+ int bit = ffs(~ureg->temps_active[i/32]);
+ if (bit != 0) {
+ i += bit - 1;
+ goto out;
+ }
+ }
+
+ /* No reusable temps, so allocate a new one:
+ */
+ i = ureg->nr_temps++;
+
+out:
+ if (i < UREG_MAX_TEMP)
+ ureg->temps_active[i/32] |= 1 << (i % 32);
+
+ if (i >= ureg->nr_temps)
+ ureg->nr_temps = i + 1;
+
+ return ureg_dst_register( TGSI_FILE_TEMPORARY, i );
+}
+
+
+void ureg_release_temporary( struct ureg_program *ureg,
+ struct ureg_dst tmp )
+{
+ if (tmp.Index < UREG_MAX_TEMP)
+ ureg->temps_active[tmp.Index/32] &= ~(1 << (tmp.Index % 32));
+}
+
+
+/* Allocate a new sampler.
+ */
+struct ureg_src ureg_DECL_sampler( struct ureg_program *ureg )
+{
+ return ureg_src_register( TGSI_FILE_SAMPLER, ureg->nr_samplers++ );
+}
+
+
+
+
+static int match_or_expand_immediate( const float *v,
+ unsigned nr,
+ float *v2,
+ unsigned *nr2,
+ unsigned *swizzle )
+{
+ unsigned i, j;
+
+ for (i = 0; i < nr; i++) {
+ boolean found = FALSE;
+
+ for (j = 0; j < *nr2 && !found; j++) {
+ if (v[i] == v2[j]) {
+ *swizzle |= j << (i * 2);
+ found = TRUE;
+ }
+ }
+
+ if (!found) {
+ if (*nr2 >= 4)
+ return FALSE;
+
+ v2[*nr2] = v[i];
+ *swizzle |= *nr2 << (i * 2);
+ (*nr2)++;
+ }
+ }
+
+ return TRUE;
+}
+
+
+
+
+struct ureg_src ureg_DECL_immediate( struct ureg_program *ureg,
+ const float *v,
+ unsigned nr )
+{
+ unsigned i;
+ unsigned swizzle;
+
+ /* Could do a first pass where we examine all existing immediates
+ * without expanding.
+ */
+
+ for (i = 0; i < ureg->nr_immediates; i++) {
+ if (match_or_expand_immediate( v,
+ nr,
+ ureg->immediate[i].v,
+ &ureg->immediate[i].nr,
+ &swizzle ))
+ goto out;
+ }
+
+ if (ureg->nr_immediates < UREG_MAX_IMMEDIATE) {
+ i = ureg->nr_immediates++;
+ if (match_or_expand_immediate( v,
+ nr,
+ ureg->immediate[i].v,
+ &ureg->immediate[i].nr,
+ &swizzle ))
+ goto out;
+ }
+
+ set_bad( ureg );
+
+out:
+ return ureg_swizzle( ureg_src_register( TGSI_FILE_IMMEDIATE, i ),
+ (swizzle >> 0) & 0x3,
+ (swizzle >> 2) & 0x3,
+ (swizzle >> 4) & 0x3,
+ (swizzle >> 6) & 0x3);
+}
+
+
+void
+ureg_emit_src( struct ureg_program *ureg,
+ struct ureg_src src )
+{
+ unsigned size = (1 +
+ (src.Absolute ? 1 : 0) +
+ (src.Indirect ? 1 : 0));
+
+ union tgsi_any_token *out = get_tokens( ureg, DOMAIN_INSN, size );
+ unsigned n = 0;
+
+ out[n].value = 0;
+ out[n].src.File = src.File;
+ out[n].src.SwizzleX = src.SwizzleX;
+ out[n].src.SwizzleY = src.SwizzleY;
+ out[n].src.SwizzleZ = src.SwizzleZ;
+ out[n].src.SwizzleW = src.SwizzleW;
+ out[n].src.Indirect = src.Indirect;
+ out[n].src.Index = src.Index;
+ n++;
+
+ if (src.Absolute) {
+ out[n].value = 0;
+ out[n].src_ext_mod.Absolute = 1;
+ n++;
+ }
+
+ if (src.Indirect) {
+ out[n].value = 0;
+ out[n].src.File = TGSI_FILE_ADDRESS;
+ out[n].src.SwizzleX = TGSI_SWIZZLE_X;
+ out[n].src.SwizzleY = TGSI_SWIZZLE_X;
+ out[n].src.SwizzleZ = TGSI_SWIZZLE_X;
+ out[n].src.SwizzleW = TGSI_SWIZZLE_X;
+ out[n].src.Indirect = 0;
+ out[n].src.Index = 0;
+ n++;
+ }
+
+ assert(n == size);
+}
+
+
+void
+ureg_emit_dst( struct ureg_program *ureg,
+ struct ureg_dst dst )
+{
+ unsigned size = (1 +
+ (dst.Indirect ? 1 : 0));
+
+ union tgsi_any_token *out = get_tokens( ureg, DOMAIN_INSN, size );
+ unsigned n = 0;
+
+ out[n].value = 0;
+ out[n].dst.File = dst.File;
+ out[n].dst.WriteMask = dst.WriteMask;
+ out[n].dst.Indirect = dst.Indirect;
+ out[n].dst.Index = dst.Index;
+ n++;
+
+ if (dst.Indirect) {
+ out[n].value = 0;
+ out[n].src.File = TGSI_FILE_ADDRESS;
+ out[n].src.SwizzleX = TGSI_SWIZZLE_X;
+ out[n].src.SwizzleY = TGSI_SWIZZLE_X;
+ out[n].src.SwizzleZ = TGSI_SWIZZLE_X;
+ out[n].src.SwizzleW = TGSI_SWIZZLE_X;
+ out[n].src.Indirect = 0;
+ out[n].src.Index = 0;
+ n++;
+ }
+
+ assert(n == size);
+}
+
+
+
+unsigned
+ureg_emit_insn(struct ureg_program *ureg,
+ unsigned opcode,
+ boolean saturate,
+ unsigned num_dst,
+ unsigned num_src )
+{
+ union tgsi_any_token *out;
+
+ out = get_tokens( ureg, DOMAIN_INSN, 1 );
+ out[0].value = 0;
+ out[0].insn.Type = TGSI_TOKEN_TYPE_INSTRUCTION;
+ out[0].insn.NrTokens = 0;
+ out[0].insn.Opcode = opcode;
+ out[0].insn.Saturate = saturate;
+ out[0].insn.NrTokens = 0;
+ out[0].insn.NumDstRegs = num_dst;
+ out[0].insn.NumSrcRegs = num_src;
+ out[0].insn.Padding = 0;
+ out[0].insn.Extended = 0;
+
+ return ureg->domain[DOMAIN_INSN].count - 1;
+}
+
+
+void
+ureg_emit_label(struct ureg_program *ureg,
+ unsigned insn_token,
+ unsigned *label_token )
+{
+ union tgsi_any_token *out, *insn;
+
+ out = get_tokens( ureg, DOMAIN_INSN, 1 );
+ insn = retrieve_token( ureg, DOMAIN_INSN, insn_token );
+
+ insn->insn.Extended = 1;
+
+ out[0].value = 0;
+ out[0].insn_ext_label.Type = TGSI_INSTRUCTION_EXT_TYPE_LABEL;
+}
+
+
+void
+ureg_emit_texture(struct ureg_program *ureg,
+ unsigned insn_token,
+ unsigned target )
+{
+ union tgsi_any_token *out, *insn;
+
+ out = get_tokens( ureg, DOMAIN_INSN, 1 );
+ insn = retrieve_token( ureg, DOMAIN_INSN, insn_token );
+
+ insn->insn.Extended = 1;
+
+ out[0].value = 0;
+ out[0].insn_ext_texture.Type = TGSI_INSTRUCTION_EXT_TYPE_TEXTURE;
+ out[0].insn_ext_texture.Texture = target;
+}
+
+
+void
+ureg_fixup_insn_size(struct ureg_program *ureg,
+ unsigned insn )
+{
+ union tgsi_any_token *out = retrieve_token( ureg, DOMAIN_INSN, insn );
+
+ out->insn.NrTokens = ureg->domain[DOMAIN_INSN].count - insn - 1;
+}
+
+
+
+
+
+static void emit_decl( struct ureg_program *ureg,
+ unsigned file,
+ unsigned index,
+ unsigned semantic_name,
+ unsigned semantic_index,
+ unsigned interp )
+{
+ union tgsi_any_token *out = get_tokens( ureg, DOMAIN_DECL, 3 );
+
+ out[0].value = 0;
+ out[0].decl.Type = TGSI_TOKEN_TYPE_DECLARATION;
+ out[0].decl.NrTokens = 3;
+ out[0].decl.File = file;
+ out[0].decl.UsageMask = TGSI_WRITEMASK_XYZW; /* FIXME! */
+ out[0].decl.Interpolate = interp;
+ out[0].decl.Semantic = 1;
+
+ out[1].value = 0;
+ out[1].decl_range.First =
+ out[1].decl_range.Last = index;
+
+ out[2].value = 0;
+ out[2].decl_semantic.SemanticName = semantic_name;
+ out[2].decl_semantic.SemanticIndex = semantic_index;
+
+}
+
+
+static void emit_decl_range( struct ureg_program *ureg,
+ unsigned file,
+ unsigned first,
+ unsigned count )
+{
+ union tgsi_any_token *out = get_tokens( ureg, DOMAIN_DECL, 2 );
+
+ out[0].value = 0;
+ out[0].decl.Type = TGSI_TOKEN_TYPE_DECLARATION;
+ out[0].decl.NrTokens = 2;
+ out[0].decl.File = file;
+ out[0].decl.UsageMask = 0xf;
+ out[0].decl.Interpolate = TGSI_INTERPOLATE_CONSTANT;
+ out[0].decl.Semantic = 0;
+
+ out[1].value = 0;
+ out[1].decl_range.First = first;
+ out[1].decl_range.Last = first + count - 1;
+}
+
+static void emit_immediate( struct ureg_program *ureg,
+ const float *v )
+{
+ union tgsi_any_token *out = get_tokens( ureg, DOMAIN_DECL, 5 );
+
+ out[0].value = 0;
+ out[0].imm.Type = TGSI_TOKEN_TYPE_IMMEDIATE;
+ out[0].imm.NrTokens = 5;
+ out[0].imm.DataType = TGSI_IMM_FLOAT32;
+ out[0].imm.Padding = 0;
+ out[0].imm.Extended = 0;
+
+ out[1].imm_data.Float = v[0];
+ out[2].imm_data.Float = v[1];
+ out[3].imm_data.Float = v[2];
+ out[4].imm_data.Float = v[3];
+}
+
+
+
+
+static void emit_decls( struct ureg_program *ureg )
+{
+ unsigned i;
+
+ for (i = 0; i < ureg->nr_inputs; i++) {
+ emit_decl( ureg,
+ TGSI_FILE_INPUT,
+ i,
+ ureg->input[i].semantic_name,
+ ureg->input[i].semantic_index,
+ ureg->input[i].interp );
+ }
+
+ for (i = 0; i < ureg->nr_outputs; i++) {
+ emit_decl( ureg,
+ TGSI_FILE_OUTPUT,
+ i,
+ ureg->output[i].semantic_name,
+ ureg->output[i].semantic_index,
+ TGSI_INTERPOLATE_CONSTANT );
+ }
+
+ if (ureg->nr_samplers) {
+ emit_decl_range( ureg,
+ TGSI_FILE_SAMPLER,
+ 0, ureg->nr_samplers );
+ }
+
+ if (ureg->nr_constants) {
+ emit_decl_range( ureg,
+ TGSI_FILE_CONSTANT,
+ 0, ureg->nr_constants );
+ }
+
+ if (ureg->nr_temps) {
+ emit_decl_range( ureg,
+ TGSI_FILE_TEMPORARY,
+ 0, ureg->nr_temps );
+ }
+
+ for (i = 0; i < ureg->nr_immediates; i++) {
+ emit_immediate( ureg,
+ ureg->immediate[i].v );
+ }
+}
+
+/* Append the instruction tokens onto the declarations to build a
+ * contiguous stream suitable to send to the driver.
+ */
+static void copy_instructions( struct ureg_program *ureg )
+{
+ unsigned nr_tokens = ureg->domain[DOMAIN_INSN].count;
+ union tgsi_any_token *out = get_tokens( ureg,
+ DOMAIN_DECL,
+ nr_tokens );
+
+ memcpy(out,
+ ureg->domain[DOMAIN_INSN].tokens,
+ nr_tokens * sizeof out[0] );
+}
+
+
+static void
+fixup_header_size(struct ureg_program *ureg,
+ unsigned insn )
+{
+ union tgsi_any_token *out = retrieve_token( ureg, DOMAIN_DECL, 1 );
+
+ out->header.BodySize = ureg->domain[DOMAIN_DECL].count - 3;
+}
+
+
+static void
+emit_header( struct ureg_program *ureg )
+{
+ union tgsi_any_token *out = get_tokens( ureg, DOMAIN_DECL, 3 );
+
+ out[0].version.MajorVersion = 1;
+ out[0].version.MinorVersion = 1;
+ out[0].version.Padding = 0;
+
+ out[1].header.HeaderSize = 2;
+ out[1].header.BodySize = 0;
+
+ out[2].processor.Processor = ureg->processor;
+ out[2].processor.Padding = 0;
+}
+
+
+void *ureg_create_shader( struct ureg_program *ureg )
+{
+ struct pipe_shader_state state;
+ unsigned insn;
+
+ emit_header( ureg );
+ emit_decls( ureg );
+ copy_instructions( ureg );
+ fixup_header_size( ureg, insn );
+
+ if (ureg->domain[0].tokens == error_tokens ||
+ ureg->domain[1].tokens == error_tokens) {
+ debug_printf("%s: error in generated shader\n", __FUNCTION__);
+ assert(0);
+ return NULL;
+ }
+
+ state.tokens = (const struct tgsi_token *)ureg->domain[DOMAIN_DECL].tokens;
+
+ if (0) {
+ debug_printf("%s: emitted shader %d tokens:\n", __FUNCTION__,
+ ureg->domain[DOMAIN_DECL].count);
+ tgsi_dump( state.tokens, 0 );
+ }
+
+ if (ureg->processor == TGSI_PROCESSOR_VERTEX)
+ return ureg->pipe->create_vs_state( ureg->pipe, &state );
+ else
+ return ureg->pipe->create_fs_state( ureg->pipe, &state );
+}
+
+
+
+
+struct ureg_program *ureg_create( struct pipe_context *pipe,
+ unsigned processor )
+{
+ struct ureg_program *ureg = CALLOC_STRUCT( ureg_program );
+ if (ureg == NULL)
+ return NULL;
+
+ ureg->pipe = pipe;
+ ureg->processor = processor;
+ return ureg;
+}
+
+
+void ureg_destroy( struct ureg_program *ureg )
+{
+ unsigned i;
+
+ for (i = 0; i < Elements(ureg->domain); i++) {
+ if (ureg->domain[i].tokens &&
+ ureg->domain[i].tokens != error_tokens)
+ FREE(ureg->domain[i].tokens);
+ }
+
+ FREE(ureg);
+}
diff --git a/src/gallium/auxiliary/tgsi/tgsi_ureg.h b/src/gallium/auxiliary/tgsi/tgsi_ureg.h
new file mode 100644
index 00000000000..0a976fd63b7
--- /dev/null
+++ b/src/gallium/auxiliary/tgsi/tgsi_ureg.h
@@ -0,0 +1,439 @@
+/**************************************************************************
+ *
+ * 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, INC 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 TGSI_UREG_H
+#define TGSI_UREG_H
+
+#include "pipe/p_compiler.h"
+#include "pipe/p_shader_tokens.h"
+
+struct ureg_program;
+
+/* Almost a tgsi_src_register, but we need to pull in the Absolute
+ * flag from the _ext token. Indirect flag always implies ADDR[0].
+ */
+struct ureg_src
+{
+ unsigned File : 4; /* TGSI_FILE_ */
+ unsigned SwizzleX : 2; /* TGSI_SWIZZLE_ */
+ unsigned SwizzleY : 2; /* TGSI_SWIZZLE_ */
+ unsigned SwizzleZ : 2; /* TGSI_SWIZZLE_ */
+ unsigned SwizzleW : 2; /* TGSI_SWIZZLE_ */
+ unsigned Pad : 1; /* BOOL */
+ unsigned Indirect : 1; /* BOOL */
+ unsigned Absolute : 1; /* BOOL */
+ int Index : 16; /* SINT */
+ unsigned Negate : 1; /* BOOL */
+};
+
+/* Very similar to a tgsi_dst_register, removing unsupported fields
+ * and adding a Saturate flag. It's easier to push saturate into the
+ * destination register than to try and create a _SAT varient of each
+ * instruction function.
+ */
+struct ureg_dst
+{
+ unsigned File : 4; /* TGSI_FILE_ */
+ unsigned WriteMask : 4; /* TGSI_WRITEMASK_ */
+ unsigned Indirect : 1; /* BOOL */
+ unsigned Saturate : 1; /* BOOL */
+ int Index : 16; /* SINT */
+ unsigned Pad1 : 5;
+ unsigned Pad2 : 1; /* BOOL */
+};
+
+struct pipe_context;
+
+struct ureg_program *
+ureg_create( struct pipe_context *pipe,
+ unsigned processor );
+
+void *
+ureg_create_shader( struct ureg_program * );
+
+void
+ureg_destroy( struct ureg_program * );
+
+
+/***********************************************************************
+ * Convenience routine:
+ */
+static INLINE void *ureg_create_shader_and_destroy( struct ureg_program *p )
+{
+ void *result = ureg_create_shader( p );
+ ureg_destroy( p );
+ return result;
+}
+
+
+
+/***********************************************************************
+ * Build shader declarations:
+ */
+
+struct ureg_src
+ureg_DECL_fs_input( struct ureg_program *,
+ unsigned semantic_name,
+ unsigned semantic_index,
+ unsigned interp_mode );
+
+struct ureg_src
+ureg_DECL_vs_input( struct ureg_program *,
+ unsigned semantic_name,
+ unsigned semantic_index );
+
+struct ureg_dst
+ureg_DECL_output( struct ureg_program *,
+ unsigned semantic_name,
+ unsigned semantic_index );
+
+struct ureg_src
+ureg_DECL_immediate( struct ureg_program *,
+ const float *v,
+ unsigned nr );
+
+struct ureg_src
+ureg_DECL_constant( struct ureg_program * );
+
+struct ureg_dst
+ureg_DECL_temporary( struct ureg_program * );
+
+void
+ureg_release_temporary( struct ureg_program *ureg,
+ struct ureg_dst tmp );
+
+struct ureg_src
+ureg_DECL_sampler( struct ureg_program * );
+
+
+static INLINE struct ureg_src
+ureg_DECL_immediate4f( struct ureg_program *ureg,
+ float a, float b,
+ float c, float d)
+{
+ float v[4];
+ v[0] = a;
+ v[1] = b;
+ v[2] = c;
+ v[3] = d;
+ return ureg_DECL_immediate( ureg, v, 4 );
+}
+
+static INLINE struct ureg_src
+ureg_DECL_immediate3f( struct ureg_program *ureg,
+ float a, float b,
+ float c)
+{
+ float v[3];
+ v[0] = a;
+ v[1] = b;
+ v[2] = c;
+ return ureg_DECL_immediate( ureg, v, 3 );
+}
+
+static INLINE struct ureg_src
+ureg_DECL_immediate2f( struct ureg_program *ureg,
+ float a, float b)
+{
+ float v[2];
+ v[0] = a;
+ v[1] = b;
+ return ureg_DECL_immediate( ureg, v, 2 );
+}
+
+static INLINE struct ureg_src
+ureg_DECL_immediate1f( struct ureg_program *ureg,
+ float a)
+{
+ float v[1];
+ v[0] = a;
+ return ureg_DECL_immediate( ureg, v, 1 );
+}
+
+/***********************************************************************
+ * Internal instruction helpers, don't call these directly:
+ */
+
+unsigned
+ureg_emit_insn(struct ureg_program *ureg,
+ unsigned opcode,
+ boolean saturate,
+ unsigned num_dst,
+ unsigned num_src );
+
+void
+ureg_emit_label(struct ureg_program *ureg,
+ unsigned insn_token,
+ unsigned *label_token );
+
+void
+ureg_emit_texture(struct ureg_program *ureg,
+ unsigned insn_token,
+ unsigned target );
+
+void
+ureg_emit_dst( struct ureg_program *ureg,
+ struct ureg_dst dst );
+
+void
+ureg_emit_src( struct ureg_program *ureg,
+ struct ureg_src src );
+
+void
+ureg_fixup_insn_size(struct ureg_program *ureg,
+ unsigned insn );
+
+
+#define OP00( op ) \
+static INLINE void ureg_##op( struct ureg_program *ureg ) \
+{ \
+ unsigned opcode = TGSI_OPCODE_##op; \
+ unsigned insn = ureg_emit_insn( ureg, opcode, FALSE, 0, 0 ); \
+ ureg_fixup_insn_size( ureg, insn ); \
+}
+
+#define OP01( op ) \
+static INLINE void ureg_##op( struct ureg_program *ureg, \
+ struct ureg_src src ) \
+{ \
+ unsigned opcode = TGSI_OPCODE_##op; \
+ unsigned insn = ureg_emit_insn( ureg, opcode, FALSE, 0, 1 ); \
+ ureg_emit_src( ureg, src ); \
+ ureg_fixup_insn_size( ureg, insn ); \
+}
+
+#define OP00_LBL( op ) \
+static INLINE void ureg_##op( struct ureg_program *ureg, \
+ unsigned *label_token ) \
+{ \
+ unsigned opcode = TGSI_OPCODE_##op; \
+ unsigned insn = ureg_emit_insn( ureg, opcode, FALSE, 0, 0 ); \
+ ureg_emit_label( ureg, insn, label_token ); \
+ ureg_fixup_insn_size( ureg, insn ); \
+}
+
+#define OP01_LBL( op ) \
+static INLINE void ureg_##op( struct ureg_program *ureg, \
+ struct ureg_src src, \
+ unsigned *label_token ) \
+{ \
+ unsigned opcode = TGSI_OPCODE_##op; \
+ unsigned insn = ureg_emit_insn( ureg, opcode, FALSE, 0, 1 ); \
+ ureg_emit_label( ureg, insn, label_token ); \
+ ureg_emit_src( ureg, src ); \
+ ureg_fixup_insn_size( ureg, insn ); \
+}
+
+#define OP10( op ) \
+static INLINE void ureg_##op( struct ureg_program *ureg, \
+ struct ureg_dst dst ) \
+{ \
+ unsigned opcode = TGSI_OPCODE_##op; \
+ unsigned insn = ureg_emit_insn( ureg, opcode, dst.Saturate, 1, 0 ); \
+ ureg_emit_dst( ureg, dst ); \
+ ureg_fixup_insn_size( ureg, insn ); \
+}
+
+
+#define OP11( op ) \
+static INLINE void ureg_##op( struct ureg_program *ureg, \
+ struct ureg_dst dst, \
+ struct ureg_src src ) \
+{ \
+ unsigned opcode = TGSI_OPCODE_##op; \
+ unsigned insn = ureg_emit_insn( ureg, opcode, dst.Saturate, 1, 1 ); \
+ ureg_emit_dst( ureg, dst ); \
+ ureg_emit_src( ureg, src ); \
+ ureg_fixup_insn_size( ureg, insn ); \
+}
+
+#define OP12( op ) \
+static INLINE void ureg_##op( struct ureg_program *ureg, \
+ struct ureg_dst dst, \
+ struct ureg_src src0, \
+ struct ureg_src src1 ) \
+{ \
+ unsigned opcode = TGSI_OPCODE_##op; \
+ unsigned insn = ureg_emit_insn( ureg, opcode, dst.Saturate, 1, 2 ); \
+ ureg_emit_dst( ureg, dst ); \
+ ureg_emit_src( ureg, src0 ); \
+ ureg_emit_src( ureg, src1 ); \
+ ureg_fixup_insn_size( ureg, insn ); \
+}
+
+#define OP12_TEX( op ) \
+static INLINE void ureg_##op( struct ureg_program *ureg, \
+ struct ureg_dst dst, \
+ unsigned target, \
+ struct ureg_src src0, \
+ struct ureg_src src1 ) \
+{ \
+ unsigned opcode = TGSI_OPCODE_##op; \
+ unsigned insn = ureg_emit_insn( ureg, opcode, dst.Saturate, 1, 2 ); \
+ ureg_emit_texture( ureg, insn, target ); \
+ ureg_emit_dst( ureg, dst ); \
+ ureg_emit_src( ureg, src0 ); \
+ ureg_emit_src( ureg, src1 ); \
+ ureg_fixup_insn_size( ureg, insn ); \
+}
+
+#define OP13( op ) \
+static INLINE void ureg_##op( struct ureg_program *ureg, \
+ struct ureg_dst dst, \
+ struct ureg_src src0, \
+ struct ureg_src src1, \
+ struct ureg_src src2 ) \
+{ \
+ unsigned opcode = TGSI_OPCODE_##op; \
+ unsigned insn = ureg_emit_insn( ureg, opcode, dst.Saturate, 1, 3 ); \
+ ureg_emit_dst( ureg, dst ); \
+ ureg_emit_src( ureg, src0 ); \
+ ureg_emit_src( ureg, src1 ); \
+ ureg_emit_src( ureg, src2 ); \
+ ureg_fixup_insn_size( ureg, insn ); \
+}
+
+#define OP14_TEX( op ) \
+static INLINE void ureg_##op( struct ureg_program *ureg, \
+ struct ureg_dst dst, \
+ unsigned target, \
+ struct ureg_src src0, \
+ struct ureg_src src1, \
+ struct ureg_src src2, \
+ struct ureg_src src3 ) \
+{ \
+ unsigned opcode = TGSI_OPCODE_##op; \
+ unsigned insn = ureg_emit_insn( ureg, opcode, dst.Saturate, 1, 4 ); \
+ ureg_emit_texture( ureg, insn, target ); \
+ ureg_emit_dst( ureg, dst ); \
+ ureg_emit_src( ureg, src0 ); \
+ ureg_emit_src( ureg, src1 ); \
+ ureg_emit_src( ureg, src2 ); \
+ ureg_emit_src( ureg, src3 ); \
+ ureg_fixup_insn_size( ureg, insn ); \
+}
+
+
+/* Use a template include to generate a correctly-typed ureg_OP()
+ * function for each TGSI opcode:
+ */
+#include "tgsi_opcode_tmp.h"
+
+
+/***********************************************************************
+ * Inline helpers for manipulating register structs:
+ */
+static INLINE struct ureg_src
+ureg_negate( struct ureg_src reg )
+{
+ reg.Negate ^= 1;
+ return reg;
+}
+
+static INLINE struct ureg_src
+ureg_abs( struct ureg_src reg )
+{
+ reg.Absolute = 1;
+ reg.Negate = 0;
+ return reg;
+}
+
+static INLINE struct ureg_src
+ureg_swizzle( struct ureg_src reg,
+ int x, int y, int z, int w )
+{
+ unsigned swz = ( (reg.SwizzleX << 0) |
+ (reg.SwizzleY << 2) |
+ (reg.SwizzleZ << 4) |
+ (reg.SwizzleW << 6));
+
+ reg.SwizzleX = (swz >> (x*2)) & 0x3;
+ reg.SwizzleY = (swz >> (y*2)) & 0x3;
+ reg.SwizzleZ = (swz >> (z*2)) & 0x3;
+ reg.SwizzleW = (swz >> (w*2)) & 0x3;
+ return reg;
+}
+
+static INLINE struct ureg_src
+ureg_scalar( struct ureg_src reg, int x )
+{
+ return ureg_swizzle(reg, x, x, x, x);
+}
+
+static INLINE struct ureg_dst
+ureg_writemask( struct ureg_dst reg,
+ unsigned writemask )
+{
+ reg.WriteMask &= writemask;
+ return reg;
+}
+
+static INLINE struct ureg_dst
+ureg_saturate( struct ureg_dst reg )
+{
+ reg.Saturate = 1;
+ return reg;
+}
+
+static INLINE struct ureg_dst
+ureg_dst( struct ureg_src src )
+{
+ struct ureg_dst dst;
+
+ dst.File = src.File;
+ dst.WriteMask = TGSI_WRITEMASK_XYZW;
+ dst.Indirect = src.Indirect;
+ dst.Saturate = 0;
+ dst.Index = src.Index;
+ dst.Pad1 = 0;
+ dst.Pad2 = 0;
+
+ return dst;
+}
+
+static INLINE struct ureg_src
+ureg_src( struct ureg_dst dst )
+{
+ struct ureg_src src;
+
+ src.File = dst.File;
+ src.SwizzleX = TGSI_SWIZZLE_X;
+ src.SwizzleY = TGSI_SWIZZLE_Y;
+ src.SwizzleZ = TGSI_SWIZZLE_Z;
+ src.SwizzleW = TGSI_SWIZZLE_W;
+ src.Pad = 0;
+ src.Indirect = dst.Indirect;
+ src.Absolute = 0;
+ src.Index = dst.Index;
+ src.Negate = 0;
+
+ return src;
+}
+
+
+
+#endif
diff --git a/src/gallium/auxiliary/util/u_blit.c b/src/gallium/auxiliary/util/u_blit.c
index 414cf910254..cda6dbd46d7 100644
--- a/src/gallium/auxiliary/util/u_blit.c
+++ b/src/gallium/auxiliary/util/u_blit.c
@@ -45,6 +45,7 @@
#include "util/u_math.h"
#include "util/u_memory.h"
#include "util/u_simple_shaders.h"
+#include "util/u_surface.h"
#include "cso_cache/cso_context.h"
@@ -155,7 +156,11 @@ util_destroy_blit(struct blit_state *ctx)
}
-static unsigned get_next_slot( struct blit_state *ctx )
+/**
+ * Get offset of next free slot in vertex buffer for quad vertices.
+ */
+static unsigned
+get_next_slot( struct blit_state *ctx )
{
const unsigned max_slots = 4096 / sizeof ctx->vertices;
@@ -173,7 +178,6 @@ static unsigned get_next_slot( struct blit_state *ctx )
}
-
/**
* Setup vertex data for the textured quad we'll draw.
* Note: y=0=top
@@ -260,9 +264,38 @@ setup_vertex_data_tex(struct blit_state *ctx,
return offset;
}
+
+
+/**
+ * \return TRUE if two regions overlap, FALSE otherwise
+ */
+static boolean
+regions_overlap(int srcX0, int srcY0,
+ int srcX1, int srcY1,
+ int dstX0, int dstY0,
+ int dstX1, int dstY1)
+{
+ if (MAX2(srcX0, srcX1) < MIN2(dstX0, dstX1))
+ return FALSE; /* src completely left of dst */
+
+ if (MAX2(dstX0, dstX1) < MIN2(srcX0, srcX1))
+ return FALSE; /* dst completely left of src */
+
+ if (MAX2(srcY0, srcY1) < MIN2(dstY0, dstY1))
+ return FALSE; /* src completely above dst */
+
+ if (MAX2(dstY0, dstY1) < MIN2(srcY0, srcY1))
+ return FALSE; /* dst completely above src */
+
+ return TRUE; /* some overlap */
+}
+
+
/**
* Copy pixel block from src surface to dst surface.
* Overlapping regions are acceptable.
+ * Flipping and stretching are supported.
+ * XXX what about clipping???
* XXX need some control over blitting Z and/or stencil.
*/
void
@@ -285,10 +318,41 @@ util_blit_pixels(struct blit_state *ctx,
const int srcLeft = MIN2(srcX0, srcX1);
const int srcTop = MIN2(srcY0, srcY1);
unsigned offset;
+ boolean overlap;
assert(filter == PIPE_TEX_MIPFILTER_NEAREST ||
filter == PIPE_TEX_MIPFILTER_LINEAR);
+ assert(screen->is_format_supported(screen, src->format, PIPE_TEXTURE_2D,
+ PIPE_TEXTURE_USAGE_SAMPLER, 0));
+ assert(screen->is_format_supported(screen, dst->format, PIPE_TEXTURE_2D,
+ PIPE_TEXTURE_USAGE_RENDER_TARGET, 0));
+
+ /* do the regions overlap? */
+ overlap = util_same_surface(src, dst) &&
+ regions_overlap(srcX0, srcY0, srcX1, srcY1,
+ dstX0, dstY0, dstX1, dstY1);
+
+ /*
+ * Check for simple case: no format conversion, no flipping, no stretching,
+ * no overlapping.
+ * Filter mode should not matter since there's no stretching.
+ */
+ if (dst->format == src->format &&
+ srcX0 < srcX1 &&
+ dstX0 < dstX1 &&
+ srcY0 < srcY1 &&
+ dstY0 < dstY1 &&
+ (dstX1 - dstX0) == (srcX1 - srcX0) &&
+ (dstY1 - dstY0) == (srcY1 - srcY0) &&
+ !overlap) {
+ pipe->surface_copy(pipe,
+ dst, dstX0, dstY0, /* dest */
+ src, srcX0, srcY0, /* src */
+ srcW, srcH); /* size */
+ return;
+ }
+
if (srcLeft != srcX0) {
/* left-right flip */
int tmp = dstX0;
@@ -303,20 +367,6 @@ util_blit_pixels(struct blit_state *ctx,
dstY1 = tmp;
}
- assert(screen->is_format_supported(screen, src->format, PIPE_TEXTURE_2D,
- PIPE_TEXTURE_USAGE_SAMPLER, 0));
- assert(screen->is_format_supported(screen, dst->format, PIPE_TEXTURE_2D,
- PIPE_TEXTURE_USAGE_SAMPLER, 0));
-
- if(dst->format == src->format && (dstX1 - dstX0) == srcW && (dstY1 - dstY0) == srcH) {
- /* FIXME: this will most surely fail for overlapping rectangles */
- pipe->surface_copy(pipe,
- dst, dstX0, dstY0, /* dest */
- src, srcX0, srcY0, /* src */
- srcW, srcH); /* size */
- return;
- }
-
assert(screen->is_format_supported(screen, dst->format, PIPE_TEXTURE_2D,
PIPE_TEXTURE_USAGE_RENDER_TARGET, 0));
diff --git a/src/gallium/auxiliary/util/u_debug.c b/src/gallium/auxiliary/util/u_debug.c
index a5ca0b72bd7..96d400c839b 100644
--- a/src/gallium/auxiliary/util/u_debug.c
+++ b/src/gallium/auxiliary/util/u_debug.c
@@ -143,11 +143,9 @@ void _debug_vprintf(const char *format, va_list ap)
#elif defined(PIPE_SUBSYSTEM_WINDOWS_MINIPORT)
/* TODO */
#else /* !PIPE_SUBSYSTEM_WINDOWS */
-#ifdef DEBUG
fflush(stdout);
vfprintf(stderr, format, ap);
#endif
-#endif
}
diff --git a/src/gallium/auxiliary/util/u_gen_mipmap.c b/src/gallium/auxiliary/util/u_gen_mipmap.c
index ca797486a0e..edc37561ab1 100644
--- a/src/gallium/auxiliary/util/u_gen_mipmap.c
+++ b/src/gallium/auxiliary/util/u_gen_mipmap.c
@@ -46,10 +46,6 @@
#include "util/u_gen_mipmap.h"
#include "util/u_simple_shaders.h"
-#include "tgsi/tgsi_build.h"
-#include "tgsi/tgsi_dump.h"
-#include "tgsi/tgsi_parse.h"
-
#include "cso_cache/cso_context.h"
diff --git a/src/gallium/auxiliary/util/u_math.h b/src/gallium/auxiliary/util/u_math.h
index e5003af01d8..57410e78b02 100644
--- a/src/gallium/auxiliary/util/u_math.h
+++ b/src/gallium/auxiliary/util/u_math.h
@@ -53,11 +53,11 @@ __inline double ceil(double val)
{
double ceil_val;
- if((val - (long) val) == 0) {
+ if ((val - (long) val) == 0) {
ceil_val = val;
}
else {
- if(val > 0) {
+ if (val > 0) {
ceil_val = (long) val + 1;
}
else {
@@ -73,11 +73,11 @@ __inline double floor(double val)
{
double floor_val;
- if((val - (long) val) == 0) {
+ if ((val - (long) val) == 0) {
floor_val = val;
}
else {
- if(val > 0) {
+ if (val > 0) {
floor_val = (long) val;
}
else {
@@ -189,7 +189,10 @@ static INLINE double log2( double x )
extern float pow2_table[POW2_TABLE_SIZE];
-
+/**
+ * Initialize math module. This should be called before using any
+ * other functions in this module.
+ */
extern void
util_init_math(void);
@@ -216,23 +219,24 @@ util_fast_exp2(float x)
int32_t ipart;
float fpart, mpart;
union fi epart;
-
+
if(x > 129.00000f)
return 3.402823466e+38f;
-
- if(x < -126.99999f)
+
+ if (x < -126.99999f)
return 0.0f;
ipart = (int32_t) x;
fpart = x - (float) ipart;
-
+
/* same as
* epart.f = (float) (1 << ipart)
- * but faster and without integer overflow for ipart > 31 */
+ * but faster and without integer overflow for ipart > 31
+ */
epart.i = (ipart + 127 ) << 23;
-
+
mpart = pow2_table[POW2_TABLE_OFFSET + (int)(fpart * POW2_TABLE_SCALE)];
-
+
return epart.f * mpart;
}
@@ -254,6 +258,9 @@ util_fast_exp(float x)
extern float log2_table[LOG2_TABLE_SIZE];
+/**
+ * Fast approximation to log2(x).
+ */
static INLINE float
util_fast_log2(float x)
{
@@ -267,6 +274,9 @@ util_fast_log2(float x)
}
+/**
+ * Fast approximation to x^y.
+ */
static INLINE float
util_fast_pow(float x, float y)
{
@@ -274,7 +284,6 @@ util_fast_pow(float x, float y)
}
-
/**
* Floor(x), returned as int.
*/
@@ -284,8 +293,8 @@ util_ifloor(float f)
int ai, bi;
double af, bf;
union fi u;
- af = (3 << 22) + 0.5 + (double)f;
- bf = (3 << 22) + 0.5 - (double)f;
+ af = (3 << 22) + 0.5 + (double) f;
+ bf = (3 << 22) + 0.5 - (double) f;
u.f = (float) af; ai = u.i;
u.f = (float) bf; bi = u.i;
return (ai - bi) >> 1;
@@ -305,9 +314,9 @@ util_iround(float f)
#elif defined(PIPE_CC_MSVC) && defined(PIPE_ARCH_X86)
int r;
_asm {
- fld f
- fistp r
- }
+ fld f
+ fistp r
+ }
return r;
#else
if (f >= 0.0f)
@@ -340,7 +349,7 @@ static INLINE
unsigned long ffs( unsigned long u )
{
unsigned long i;
- if(_BitScanForward(&i, u))
+ if (_BitScanForward(&i, u))
return i + 1;
else
return 0;
@@ -351,7 +360,7 @@ unsigned ffs( unsigned u )
{
unsigned i;
- if( u == 0 ) {
+ if (u == 0) {
return 0;
}
@@ -378,7 +387,10 @@ fui( float f )
}
-
+/**
+ * Convert ubyte to float in [0, 1].
+ * XXX a 256-entry lookup table would be slightly faster.
+ */
static INLINE float
ubyte_to_float(ubyte ub)
{
@@ -409,7 +421,23 @@ float_to_ubyte(float f)
}
+/**
+ * Calc log base 2
+ */
+static INLINE unsigned
+util_logbase2(unsigned n)
+{
+ unsigned log2 = 0;
+ while (n >>= 1)
+ ++log2;
+ return log2;
+}
+
+/**
+ * Clamp X to [MIN, MAX].
+ * This is a macro to allow float, int, uint, etc. types.
+ */
#define CLAMP( X, MIN, MAX ) ( (X)<(MIN) ? (MIN) : ((X)>(MAX) ? (MAX) : (X)) )
#define MIN2( A, B ) ( (A)<(B) ? (A) : (B) )
@@ -422,6 +450,11 @@ align(int value, int alignment)
return (value + alignment - 1) & ~(alignment - 1);
}
+static INLINE unsigned
+minify(unsigned value)
+{
+ return MAX2(1, value >> 1);
+}
#ifndef COPY_4V
#define COPY_4V( DST, SRC ) \
diff --git a/src/gallium/auxiliary/util/u_memory.h b/src/gallium/auxiliary/util/u_memory.h
index 0b18d043adb..c3f8c918338 100644
--- a/src/gallium/auxiliary/util/u_memory.h
+++ b/src/gallium/auxiliary/util/u_memory.h
@@ -100,8 +100,14 @@ ExFreePool(void *P);
#define MALLOC( SIZE ) malloc( SIZE )
#define CALLOC( COUNT, SIZE ) calloc( COUNT, SIZE )
#define FREE( PTR ) free( PTR )
-#define REALLOC( OLDPTR, OLDSIZE, NEWSIZE ) realloc( OLDPTR, NEWSIZE )
+static INLINE void *
+_REALLOC( void *old_ptr, unsigned old_size, unsigned new_size )
+{
+ (void) old_size;
+ return realloc(old_ptr, new_size);
+}
+#define REALLOC( a, b, c ) _REALLOC( a, b, c )
#endif
diff --git a/src/gallium/auxiliary/util/u_mm.c b/src/gallium/auxiliary/util/u_mm.c
index 151a480d34d..4b75d4ba1d0 100644
--- a/src/gallium/auxiliary/util/u_mm.c
+++ b/src/gallium/auxiliary/util/u_mm.c
@@ -33,30 +33,32 @@
void
u_mmDumpMemInfo(const struct mem_block *heap)
{
- debug_printf("Memory heap %p:\n", (void *)heap);
+ debug_printf("Memory heap %p:\n", (void *) heap);
if (heap == 0) {
debug_printf(" heap == 0\n");
- } else {
+ }
+ else {
const struct mem_block *p;
- for(p = heap->next; p != heap; p = p->next) {
- debug_printf(" Offset:%08x, Size:%08x, %c%c\n",p->ofs,p->size,
- p->free ? 'F':'.',
- p->reserved ? 'R':'.');
+ for (p = heap->next; p != heap; p = p->next) {
+ debug_printf(" Offset:%08x, Size:%08x, %c%c\n", p->ofs, p->size,
+ p->free ? 'F':'.',
+ p->reserved ? 'R':'.');
}
debug_printf("\nFree list:\n");
- for(p = heap->next_free; p != heap; p = p->next_free) {
- debug_printf(" FREE Offset:%08x, Size:%08x, %c%c\n",p->ofs,p->size,
- p->free ? 'F':'.',
- p->reserved ? 'R':'.');
+ for (p = heap->next_free; p != heap; p = p->next_free) {
+ debug_printf(" FREE Offset:%08x, Size:%08x, %c%c\n", p->ofs, p->size,
+ p->free ? 'F':'.',
+ p->reserved ? 'R':'.');
}
}
debug_printf("End of memory blocks\n");
}
+
struct mem_block *
u_mmInit(int ofs, int size)
{
diff --git a/src/gallium/auxiliary/util/u_mm.h b/src/gallium/auxiliary/util/u_mm.h
index ce20e487635..6b158aae6e4 100644
--- a/src/gallium/auxiliary/util/u_mm.h
+++ b/src/gallium/auxiliary/util/u_mm.h
@@ -84,7 +84,7 @@ extern struct mem_block *u_mmFindBlock(struct mem_block *heap, int start);
extern void u_mmDestroy(struct mem_block *mmInit);
/**
- * For debuging purpose.
+ * For debugging purposes.
*/
extern void u_mmDumpMemInfo(const struct mem_block *mmInit);
diff --git a/src/gallium/auxiliary/util/u_simple_screen.c b/src/gallium/auxiliary/util/u_simple_screen.c
index 8114b53cd0d..f01296b40fc 100644
--- a/src/gallium/auxiliary/util/u_simple_screen.c
+++ b/src/gallium/auxiliary/util/u_simple_screen.c
@@ -65,12 +65,13 @@ pass_surface_buffer_create(struct pipe_screen *screen,
unsigned width, unsigned height,
enum pipe_format format,
unsigned usage,
+ unsigned tex_usage,
unsigned *stride)
{
struct pipe_buffer *buffer =
screen->winsys->surface_buffer_create(screen->winsys,
width, height,
- format, usage, stride);
+ format, usage, tex_usage, stride);
buffer->screen = screen;
diff --git a/src/gallium/auxiliary/util/u_simple_shaders.c b/src/gallium/auxiliary/util/u_simple_shaders.c
index e519c354d25..1152d62e73e 100644
--- a/src/gallium/auxiliary/util/u_simple_shaders.c
+++ b/src/gallium/auxiliary/util/u_simple_shaders.c
@@ -42,9 +42,7 @@
#include "util/u_memory.h"
#include "util/u_simple_shaders.h"
-#include "tgsi/tgsi_build.h"
-#include "tgsi/tgsi_dump.h"
-#include "tgsi/tgsi_parse.h"
+#include "tgsi/tgsi_ureg.h"
@@ -58,93 +56,31 @@ util_make_vertex_passthrough_shader(struct pipe_context *pipe,
const uint *semantic_indexes)
{
- struct pipe_shader_state shader;
- struct tgsi_token tokens[100];
- struct tgsi_header *header;
- struct tgsi_processor *processor;
- struct tgsi_full_declaration decl;
- struct tgsi_full_instruction inst;
- const uint procType = TGSI_PROCESSOR_VERTEX;
- uint ti, i;
+ struct ureg_program *ureg;
+ uint i;
- /* shader header
- */
- *(struct tgsi_version *) &tokens[0] = tgsi_build_version();
+ ureg = ureg_create( pipe, TGSI_PROCESSOR_VERTEX );
+ if (ureg == NULL)
+ return NULL;
- header = (struct tgsi_header *) &tokens[1];
- *header = tgsi_build_header();
-
- processor = (struct tgsi_processor *) &tokens[2];
- *processor = tgsi_build_processor( procType, header );
-
- ti = 3;
-
- /* declare inputs */
- for (i = 0; i < num_attribs; i++) {
- decl = tgsi_default_full_declaration();
- decl.Declaration.File = TGSI_FILE_INPUT;
-
- decl.Declaration.Semantic = 1;
- decl.Semantic.SemanticName = semantic_names[i];
- decl.Semantic.SemanticIndex = semantic_indexes[i];
-
- decl.DeclarationRange.First =
- decl.DeclarationRange.Last = i;
- ti += tgsi_build_full_declaration(&decl,
- &tokens[ti],
- header,
- Elements(tokens) - ti);
- }
-
- /* declare outputs */
for (i = 0; i < num_attribs; i++) {
- decl = tgsi_default_full_declaration();
- decl.Declaration.File = TGSI_FILE_OUTPUT;
- decl.Declaration.Semantic = 1;
- decl.Semantic.SemanticName = semantic_names[i];
- decl.Semantic.SemanticIndex = semantic_indexes[i];
- decl.DeclarationRange.First =
- decl.DeclarationRange.Last = i;
- ti += tgsi_build_full_declaration(&decl,
- &tokens[ti],
- header,
- Elements(tokens) - ti);
+ struct ureg_src src;
+ struct ureg_dst dst;
+
+ src = ureg_DECL_vs_input( ureg,
+ semantic_names[i],
+ semantic_indexes[i]);
+
+ dst = ureg_DECL_output( ureg,
+ semantic_names[i],
+ semantic_indexes[i]);
+
+ ureg_MOV( ureg, dst, src );
}
- /* emit MOV instructions */
- for (i = 0; i < num_attribs; i++) {
- /* MOVE out[i], in[i]; */
- inst = tgsi_default_full_instruction();
- inst.Instruction.Opcode = TGSI_OPCODE_MOV;
- inst.Instruction.NumDstRegs = 1;
- inst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_OUTPUT;
- inst.FullDstRegisters[0].DstRegister.Index = i;
- inst.Instruction.NumSrcRegs = 1;
- inst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_INPUT;
- inst.FullSrcRegisters[0].SrcRegister.Index = i;
- ti += tgsi_build_full_instruction(&inst,
- &tokens[ti],
- header,
- Elements(tokens) - ti );
- }
-
- /* END instruction */
- inst = tgsi_default_full_instruction();
- inst.Instruction.Opcode = TGSI_OPCODE_END;
- inst.Instruction.NumDstRegs = 0;
- inst.Instruction.NumSrcRegs = 0;
- ti += tgsi_build_full_instruction(&inst,
- &tokens[ti],
- header,
- Elements(tokens) - ti );
-
-#if 0 /*debug*/
- tgsi_dump(tokens, 0);
-#endif
-
- shader.tokens = tokens;
+ ureg_END( ureg );
- return pipe->create_vs_state(pipe, &shader);
+ return ureg_create_shader_and_destroy( ureg );
}
@@ -158,99 +94,29 @@ util_make_vertex_passthrough_shader(struct pipe_context *pipe,
void *
util_make_fragment_tex_shader(struct pipe_context *pipe)
{
- struct pipe_shader_state shader;
- struct tgsi_token tokens[100];
- struct tgsi_header *header;
- struct tgsi_processor *processor;
- struct tgsi_full_declaration decl;
- struct tgsi_full_instruction inst;
- const uint procType = TGSI_PROCESSOR_FRAGMENT;
- uint ti;
-
- /* shader header
- */
- *(struct tgsi_version *) &tokens[0] = tgsi_build_version();
-
- header = (struct tgsi_header *) &tokens[1];
- *header = tgsi_build_header();
-
- processor = (struct tgsi_processor *) &tokens[2];
- *processor = tgsi_build_processor( procType, header );
-
- ti = 3;
-
- /* declare TEX[0] input */
- decl = tgsi_default_full_declaration();
- decl.Declaration.File = TGSI_FILE_INPUT;
- /* XXX this could be linear... */
- decl.Declaration.Interpolate = TGSI_INTERPOLATE_PERSPECTIVE;
- decl.Declaration.Semantic = 1;
- decl.Semantic.SemanticName = TGSI_SEMANTIC_GENERIC;
- decl.Semantic.SemanticIndex = 0;
- decl.DeclarationRange.First =
- decl.DeclarationRange.Last = 0;
- ti += tgsi_build_full_declaration(&decl,
- &tokens[ti],
- header,
- Elements(tokens) - ti);
-
- /* declare color[0] output */
- decl = tgsi_default_full_declaration();
- decl.Declaration.File = TGSI_FILE_OUTPUT;
- decl.Declaration.Semantic = 1;
- decl.Semantic.SemanticName = TGSI_SEMANTIC_COLOR;
- decl.Semantic.SemanticIndex = 0;
- decl.DeclarationRange.First =
- decl.DeclarationRange.Last = 0;
- ti += tgsi_build_full_declaration(&decl,
- &tokens[ti],
- header,
- Elements(tokens) - ti);
-
- /* declare sampler */
- decl = tgsi_default_full_declaration();
- decl.Declaration.File = TGSI_FILE_SAMPLER;
- decl.DeclarationRange.First =
- decl.DeclarationRange.Last = 0;
- ti += tgsi_build_full_declaration(&decl,
- &tokens[ti],
- header,
- Elements(tokens) - ti);
-
- /* TEX instruction */
- inst = tgsi_default_full_instruction();
- inst.Instruction.Opcode = TGSI_OPCODE_TEX;
- inst.Instruction.NumDstRegs = 1;
- inst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_OUTPUT;
- inst.FullDstRegisters[0].DstRegister.Index = 0;
- inst.Instruction.NumSrcRegs = 2;
- inst.InstructionExtTexture.Texture = TGSI_TEXTURE_2D;
- inst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_INPUT;
- inst.FullSrcRegisters[0].SrcRegister.Index = 0;
- inst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_SAMPLER;
- inst.FullSrcRegisters[1].SrcRegister.Index = 0;
- ti += tgsi_build_full_instruction(&inst,
- &tokens[ti],
- header,
- Elements(tokens) - ti );
-
- /* END instruction */
- inst = tgsi_default_full_instruction();
- inst.Instruction.Opcode = TGSI_OPCODE_END;
- inst.Instruction.NumDstRegs = 0;
- inst.Instruction.NumSrcRegs = 0;
- ti += tgsi_build_full_instruction(&inst,
- &tokens[ti],
- header,
- Elements(tokens) - ti );
-
-#if 0 /*debug*/
- tgsi_dump(tokens, 0);
-#endif
-
- shader.tokens = tokens;
-
- return pipe->create_fs_state(pipe, &shader);
+ struct ureg_program *ureg;
+ struct ureg_src sampler;
+ struct ureg_src tex;
+ struct ureg_dst out;
+
+ ureg = ureg_create( pipe, TGSI_PROCESSOR_FRAGMENT );
+ if (ureg == NULL)
+ return NULL;
+
+ sampler = ureg_DECL_sampler( ureg );
+
+ tex = ureg_DECL_fs_input( ureg,
+ TGSI_SEMANTIC_GENERIC, 0,
+ TGSI_INTERPOLATE_PERSPECTIVE );
+
+ out = ureg_DECL_output( ureg,
+ TGSI_SEMANTIC_COLOR,
+ 0 );
+
+ ureg_TEX( ureg, out, TGSI_TEXTURE_2D, tex, sampler );
+ ureg_END( ureg );
+
+ return ureg_create_shader_and_destroy( ureg );
}
@@ -263,87 +129,23 @@ util_make_fragment_tex_shader(struct pipe_context *pipe)
void *
util_make_fragment_passthrough_shader(struct pipe_context *pipe)
{
- struct pipe_shader_state shader;
- struct tgsi_token tokens[40];
- struct tgsi_header *header;
- struct tgsi_processor *processor;
- struct tgsi_full_declaration decl;
- struct tgsi_full_instruction inst;
- const uint procType = TGSI_PROCESSOR_FRAGMENT;
- uint ti;
-
- /* shader header
- */
- *(struct tgsi_version *) &tokens[0] = tgsi_build_version();
-
- header = (struct tgsi_header *) &tokens[1];
- *header = tgsi_build_header();
-
- processor = (struct tgsi_processor *) &tokens[2];
- *processor = tgsi_build_processor( procType, header );
-
- ti = 3;
-
- /* declare input */
- decl = tgsi_default_full_declaration();
- decl.Declaration.File = TGSI_FILE_INPUT;
- decl.Declaration.Semantic = 1;
- decl.Semantic.SemanticName = TGSI_SEMANTIC_COLOR;
- decl.Semantic.SemanticIndex = 0;
- decl.DeclarationRange.First =
- decl.DeclarationRange.Last = 0;
- ti += tgsi_build_full_declaration(&decl,
- &tokens[ti],
- header,
- Elements(tokens) - ti);
-
- /* declare output */
- decl = tgsi_default_full_declaration();
- decl.Declaration.File = TGSI_FILE_OUTPUT;
- decl.Declaration.Semantic = 1;
- decl.Semantic.SemanticName = TGSI_SEMANTIC_COLOR;
- decl.Semantic.SemanticIndex = 0;
- decl.DeclarationRange.First =
- decl.DeclarationRange.Last = 0;
- ti += tgsi_build_full_declaration(&decl,
- &tokens[ti],
- header,
- Elements(tokens) - ti);
-
-
- /* MOVE out[0], in[0]; */
- inst = tgsi_default_full_instruction();
- inst.Instruction.Opcode = TGSI_OPCODE_MOV;
- inst.Instruction.NumDstRegs = 1;
- inst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_OUTPUT;
- inst.FullDstRegisters[0].DstRegister.Index = 0;
- inst.Instruction.NumSrcRegs = 1;
- inst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_INPUT;
- inst.FullSrcRegisters[0].SrcRegister.Index = 0;
- ti += tgsi_build_full_instruction(&inst,
- &tokens[ti],
- header,
- Elements(tokens) - ti );
-
- /* END instruction */
- inst = tgsi_default_full_instruction();
- inst.Instruction.Opcode = TGSI_OPCODE_END;
- inst.Instruction.NumDstRegs = 0;
- inst.Instruction.NumSrcRegs = 0;
- ti += tgsi_build_full_instruction(&inst,
- &tokens[ti],
- header,
- Elements(tokens) - ti );
-
- assert(ti < Elements(tokens));
-
-#if 0 /*debug*/
- tgsi_dump(tokens, 0);
-#endif
-
- shader.tokens = tokens;
-
- return pipe->create_fs_state(pipe, &shader);
+ struct ureg_program *ureg;
+ struct ureg_src src;
+ struct ureg_dst dst;
+
+ ureg = ureg_create( pipe, TGSI_PROCESSOR_FRAGMENT );
+ if (ureg == NULL)
+ return NULL;
+
+ src = ureg_DECL_fs_input( ureg, TGSI_SEMANTIC_COLOR, 0,
+ TGSI_INTERPOLATE_PERSPECTIVE );
+
+ dst = ureg_DECL_output( ureg, TGSI_SEMANTIC_COLOR, 0 );
+
+ ureg_MOV( ureg, dst, src );
+ ureg_END( ureg );
+
+ return ureg_create_shader_and_destroy( ureg );
}
diff --git a/src/gallium/auxiliary/util/u_surface.h b/src/gallium/auxiliary/util/u_surface.h
index a5b73cfc20a..ce84ed7ad06 100644
--- a/src/gallium/auxiliary/util/u_surface.h
+++ b/src/gallium/auxiliary/util/u_surface.h
@@ -37,6 +37,23 @@ struct pipe_texture;
struct pipe_surface;
+/**
+ * Are s1 and s2 the same surface?
+ * Surfaces are basically views into textures so check if the two surfaces
+ * name the same part of the same texture.
+ */
+static INLINE boolean
+util_same_surface(const struct pipe_surface *s1, const struct pipe_surface *s2)
+{
+ return (s1->texture == s2->texture &&
+ s1->face == s2->face &&
+ s1->level == s2->level &&
+ s1->zslice == s2->zslice);
+}
+
+
+
+
extern boolean
util_create_rgba_surface(struct pipe_screen *screen,
uint width, uint height,
diff --git a/src/gallium/auxiliary/util/u_tile.c b/src/gallium/auxiliary/util/u_tile.c
index a0c8ed88f74..422bc76003a 100644
--- a/src/gallium/auxiliary/util/u_tile.c
+++ b/src/gallium/auxiliary/util/u_tile.c
@@ -153,7 +153,7 @@ a8r8g8b8_put_tile_rgba(unsigned *dst,
}
-/*** PIPE_FORMAT_A8R8G8B8_UNORM ***/
+/*** PIPE_FORMAT_X8R8G8B8_UNORM ***/
static void
x8r8g8b8_get_tile_rgba(const unsigned *src,
diff --git a/src/gallium/auxiliary/util/u_time.c b/src/gallium/auxiliary/util/u_time.c
index 5268cbf79ce..c16cdd0b226 100644
--- a/src/gallium/auxiliary/util/u_time.c
+++ b/src/gallium/auxiliary/util/u_time.c
@@ -35,7 +35,7 @@
#include "pipe/p_config.h"
-#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS)
+#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_APPLE)
#include <sys/time.h>
#elif defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY)
#include <windows.h>
@@ -77,7 +77,7 @@ util_time_get_frequency(void)
void
util_time_get(struct util_time *t)
{
-#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS)
+#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_APPLE)
gettimeofday(&t->tv, NULL);
#elif defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY)
LONGLONG temp;
@@ -102,7 +102,7 @@ util_time_add(const struct util_time *t1,
int64_t usecs,
struct util_time *t2)
{
-#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS)
+#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_APPLE)
t2->tv.tv_sec = t1->tv.tv_sec + usecs / 1000000;
t2->tv.tv_usec = t1->tv.tv_usec + usecs % 1000000;
#elif defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY) || defined(PIPE_SUBSYSTEM_WINDOWS_USER) || defined(PIPE_SUBSYSTEM_WINDOWS_CE)
@@ -124,7 +124,7 @@ int64_t
util_time_diff(const struct util_time *t1,
const struct util_time *t2)
{
-#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS)
+#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_APPLE)
return (t2->tv.tv_usec - t1->tv.tv_usec) +
(t2->tv.tv_sec - t1->tv.tv_sec)*1000000;
#elif defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY) || defined(PIPE_SUBSYSTEM_WINDOWS_USER) || defined(PIPE_SUBSYSTEM_WINDOWS_CE)
@@ -144,7 +144,7 @@ util_time_micros( void )
util_time_get(&t1);
-#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS)
+#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_APPLE)
return t1.tv.tv_usec + t1.tv.tv_sec*1000000LL;
#elif defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY) || defined(PIPE_SUBSYSTEM_WINDOWS_USER) || defined(PIPE_SUBSYSTEM_WINDOWS_CE)
util_time_get_frequency();
@@ -166,7 +166,7 @@ static INLINE int
util_time_compare(const struct util_time *t1,
const struct util_time *t2)
{
-#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS)
+#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_APPLE)
if (t1->tv.tv_sec < t2->tv.tv_sec)
return -1;
else if(t1->tv.tv_sec > t2->tv.tv_sec)
diff --git a/src/gallium/auxiliary/util/u_time.h b/src/gallium/auxiliary/util/u_time.h
index 6bca6077a2a..7a5c54d9b23 100644
--- a/src/gallium/auxiliary/util/u_time.h
+++ b/src/gallium/auxiliary/util/u_time.h
@@ -38,7 +38,7 @@
#include "pipe/p_config.h"
-#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS)
+#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_APPLE)
#include <time.h> /* timeval */
#include <unistd.h> /* usleep */
#endif
@@ -58,7 +58,7 @@ extern "C" {
*/
struct util_time
{
-#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS)
+#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_APPLE)
struct timeval tv;
#else
int64_t counter;
@@ -89,7 +89,7 @@ util_time_timeout(const struct util_time *start,
const struct util_time *end,
const struct util_time *curr);
-#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS)
+#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_APPLE)
#define util_time_sleep usleep
#else
void
diff --git a/src/gallium/auxiliary/util/u_timed_winsys.c b/src/gallium/auxiliary/util/u_timed_winsys.c
index 77b2a3a1c87..178acdca4df 100644
--- a/src/gallium/auxiliary/util/u_timed_winsys.c
+++ b/src/gallium/auxiliary/util/u_timed_winsys.c
@@ -212,13 +212,14 @@ timed_surface_buffer_create(struct pipe_winsys *winsys,
unsigned width, unsigned height,
enum pipe_format format,
unsigned usage,
+ unsigned tex_usage,
unsigned *stride)
{
struct pipe_winsys *backend = timed_winsys(winsys)->backend;
uint64_t start = time_start();
struct pipe_buffer *ret = backend->surface_buffer_create( backend, width, height,
- format, usage, stride );
+ format, usage, tex_usage, stride );
time_finish(winsys, start, 7, __FUNCTION__);
diff --git a/src/gallium/drivers/cell/ppu/cell_gen_fp.c b/src/gallium/drivers/cell/ppu/cell_gen_fp.c
index 5a889a6119d..58a8b5d0b0f 100644
--- a/src/gallium/drivers/cell/ppu/cell_gen_fp.c
+++ b/src/gallium/drivers/cell/ppu/cell_gen_fp.c
@@ -1834,9 +1834,9 @@ emit_instruction(struct codegen *gen,
case TGSI_OPCODE_ENDIF:
return emit_ENDIF(gen, inst);
- case TGSI_OPCODE_BGNLOOP2:
+ case TGSI_OPCODE_BGNLOOP:
return emit_BGNLOOP(gen, inst);
- case TGSI_OPCODE_ENDLOOP2:
+ case TGSI_OPCODE_ENDLOOP:
return emit_ENDLOOP(gen, inst);
case TGSI_OPCODE_BRK:
return emit_BRK(gen, inst);
@@ -1875,9 +1875,9 @@ emit_immediate(struct codegen *gen, const struct tgsi_full_immediate *immed)
assert(gen->num_imm < MAX_TEMPS);
for (ch = 0; ch < 4; ch++) {
- float val = immed->u.ImmediateFloat32[ch].Float;
+ float val = immed->u[ch].Float;
- if (ch > 0 && val == immed->u.ImmediateFloat32[ch - 1].Float) {
+ if (ch > 0 && val == immed->u[ch - 1].Float) {
/* re-use previous register */
gen->imm_regs[gen->num_imm][ch] = gen->imm_regs[gen->num_imm][ch - 1];
}
diff --git a/src/gallium/drivers/cell/ppu/cell_texture.c b/src/gallium/drivers/cell/ppu/cell_texture.c
index e26594448f0..6a63a0e6ced 100644
--- a/src/gallium/drivers/cell/ppu/cell_texture.c
+++ b/src/gallium/drivers/cell/ppu/cell_texture.c
@@ -44,13 +44,6 @@
-static unsigned
-minify(unsigned d)
-{
- return MAX2(1, d>>1);
-}
-
-
static void
cell_texture_layout(struct cell_texture *ct)
{
@@ -424,7 +417,8 @@ cell_transfer_map(struct pipe_screen *screen, struct pipe_transfer *transfer)
if (!ctrans->map)
return NULL; /* out of memory */
- if (transfer->usage & PIPE_TRANSFER_READ) {
+ if (transfer->usage == PIPE_TRANSFER_READ ||
+ transfer->usage == PIPE_TRANSFER_READ_WRITE) {
/* need to untwiddle the texture to make a linear version */
const uint bpp = pf_get_size(ct->base.format);
if (bpp == 4) {
@@ -465,7 +459,8 @@ cell_transfer_unmap(struct pipe_screen *screen,
PIPE_BUFFER_USAGE_CPU_READ);
}
- if (transfer->usage & PIPE_TRANSFER_WRITE) {
+ if (transfer->usage == PIPE_TRANSFER_WRITE ||
+ transfer->usage == PIPE_TRANSFER_READ_WRITE) {
/* The user wrote new texture data into the mapped buffer.
* We need to convert the new linear data into the twiddled/tiled format.
*/
diff --git a/src/gallium/drivers/cell/spu/spu_exec.c b/src/gallium/drivers/cell/spu/spu_exec.c
index e27df2dfb38..6db9501128c 100644
--- a/src/gallium/drivers/cell/spu/spu_exec.c
+++ b/src/gallium/drivers/cell/spu/spu_exec.c
@@ -952,7 +952,6 @@ exec_instruction(
break;
case TGSI_OPCODE_RCP:
- /* TGSI_OPCODE_RECIP */
FETCH( &r[0], 0, CHAN_X );
r[0].q = micro_div(mach->Temps[TEMP_1_I].xyzw[TEMP_1_C].q, r[0].q);
FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
@@ -961,7 +960,6 @@ exec_instruction(
break;
case TGSI_OPCODE_RSQ:
- /* TGSI_OPCODE_RECIPSQRT */
FETCH( &r[0], 0, CHAN_X );
r[0].q = micro_sqrt(r[0].q);
r[0].q = micro_div(mach->Temps[TEMP_1_I].xyzw[TEMP_1_C].q, r[0].q);
@@ -1115,7 +1113,6 @@ exec_instruction(
break;
case TGSI_OPCODE_MAD:
- /* TGSI_OPCODE_MADD */
FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
FETCH( &r[0], 0, chan_index );
FETCH( &r[1], 1, chan_index );
@@ -1136,8 +1133,7 @@ exec_instruction(
}
break;
- case TGSI_OPCODE_LERP:
- /* TGSI_OPCODE_LRP */
+ case TGSI_OPCODE_LRP:
FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
FETCH(&r[0], 0, chan_index);
FETCH(&r[1], 1, chan_index);
@@ -1158,21 +1154,11 @@ exec_instruction(
ASSERT (0);
break;
- case TGSI_OPCODE_DOT2ADD:
- /* TGSI_OPCODE_DP2A */
+ case TGSI_OPCODE_DP2A:
ASSERT (0);
break;
- case TGSI_OPCODE_INDEX:
- ASSERT (0);
- break;
-
- case TGSI_OPCODE_NEGATE:
- ASSERT (0);
- break;
-
- case TGSI_OPCODE_FRAC:
- /* TGSI_OPCODE_FRC */
+ case TGSI_OPCODE_FRC:
FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
FETCH( &r[0], 0, chan_index );
r[0].q = micro_frc(r[0].q);
@@ -1184,8 +1170,7 @@ exec_instruction(
ASSERT (0);
break;
- case TGSI_OPCODE_FLOOR:
- /* TGSI_OPCODE_FLR */
+ case TGSI_OPCODE_FLR:
FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
FETCH( &r[0], 0, chan_index );
r[0].q = micro_flr(r[0].q);
@@ -1201,8 +1186,7 @@ exec_instruction(
}
break;
- case TGSI_OPCODE_EXPBASE2:
- /* TGSI_OPCODE_EX2 */
+ case TGSI_OPCODE_EX2:
FETCH(&r[0], 0, CHAN_X);
r[0].q = micro_pow(mach->Temps[TEMP_2_I].xyzw[TEMP_2_C].q, r[0].q);
@@ -1212,8 +1196,7 @@ exec_instruction(
}
break;
- case TGSI_OPCODE_LOGBASE2:
- /* TGSI_OPCODE_LG2 */
+ case TGSI_OPCODE_LG2:
FETCH( &r[0], 0, CHAN_X );
r[0].q = micro_lg2(r[0].q);
FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
@@ -1221,8 +1204,7 @@ exec_instruction(
}
break;
- case TGSI_OPCODE_POWER:
- /* TGSI_OPCODE_POW */
+ case TGSI_OPCODE_POW:
FETCH(&r[0], 0, CHAN_X);
FETCH(&r[1], 1, CHAN_X);
@@ -1233,7 +1215,7 @@ exec_instruction(
}
break;
- case TGSI_OPCODE_CROSSPRODUCT:
+ case TGSI_OPCODE_XPD:
/* TGSI_OPCODE_XPD */
FETCH(&r[0], 0, CHAN_Y);
FETCH(&r[1], 1, CHAN_Z);
@@ -1275,10 +1257,6 @@ exec_instruction(
}
break;
- case TGSI_OPCODE_MULTIPLYMATRIX:
- ASSERT (0);
- break;
-
case TGSI_OPCODE_ABS:
FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
FETCH(&r[0], 0, chan_index);
@@ -1780,9 +1758,9 @@ exec_instruction(
mach->Primitives[mach->Temps[TEMP_PRIMITIVE_I].xyzw[TEMP_PRIMITIVE_C].u[0]] = 0;
break;
- case TGSI_OPCODE_LOOP:
+ case TGSI_OPCODE_BGNFOR:
/* fall-through (for now) */
- case TGSI_OPCODE_BGNLOOP2:
+ case TGSI_OPCODE_BGNLOOP:
/* push LoopMask and ContMasks */
ASSERT(mach->LoopStackTop < TGSI_EXEC_MAX_LOOP_NESTING);
mach->LoopStack[mach->LoopStackTop++] = mach->LoopMask;
@@ -1790,9 +1768,9 @@ exec_instruction(
mach->ContStack[mach->ContStackTop++] = mach->ContMask;
break;
- case TGSI_OPCODE_ENDLOOP:
+ case TGSI_OPCODE_ENDFOR:
/* fall-through (for now at least) */
- case TGSI_OPCODE_ENDLOOP2:
+ case TGSI_OPCODE_ENDLOOP:
/* Restore ContMask, but don't pop */
ASSERT(mach->ContStackTop > 0);
mach->ContMask = mach->ContStack[mach->ContStackTop - 1];
diff --git a/src/gallium/drivers/i915simple/i915_batch.h b/src/gallium/drivers/i915simple/i915_batch.h
index a433cf054de..c6e68ea38a2 100644
--- a/src/gallium/drivers/i915simple/i915_batch.h
+++ b/src/gallium/drivers/i915simple/i915_batch.h
@@ -50,8 +50,8 @@ i915_batchbuffer_check( struct i915_batchbuffer *batch,
size_t dwords,
size_t relocs )
{
- /** TODO JB: Check relocs */
- return dwords * 4 <= batch->size - (batch->ptr - batch->map);
+ return dwords * 4 <= batch->size - (batch->ptr - batch->map) &&
+ relocs <= (batch->max_relocs - batch->relocs);
}
static INLINE size_t
diff --git a/src/gallium/drivers/i915simple/i915_context.c b/src/gallium/drivers/i915simple/i915_context.c
index ccf9bb31fb0..bf69c8e9f53 100644
--- a/src/gallium/drivers/i915simple/i915_context.c
+++ b/src/gallium/drivers/i915simple/i915_context.c
@@ -142,10 +142,14 @@ i915_is_texture_referenced( struct pipe_context *pipe,
unsigned face, unsigned level)
{
/**
- * FIXME: Optimize.
+ * FIXME: Return the corrent result. We can't alays return referenced
+ * since it causes a double flush within the vbo module.
*/
-
+#if 0
return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE;
+#else
+ return 0;
+#endif
}
static unsigned int
@@ -153,10 +157,14 @@ i915_is_buffer_referenced( struct pipe_context *pipe,
struct pipe_buffer *buf)
{
/**
- * FIXME: Optimize.
+ * FIXME: Return the corrent result. We can't alays return referenced
+ * since it causes a double flush within the vbo module.
*/
-
+#if 0
return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE;
+#else
+ return 0;
+#endif
}
diff --git a/src/gallium/drivers/i915simple/i915_fpc_translate.c b/src/gallium/drivers/i915simple/i915_fpc_translate.c
index 961c1bf2134..89504ced276 100644
--- a/src/gallium/drivers/i915simple/i915_fpc_translate.c
+++ b/src/gallium/drivers/i915simple/i915_fpc_translate.c
@@ -975,8 +975,9 @@ i915_translate_instructions(struct i915_fp_compile *p,
= &parse.FullToken.FullImmediate;
const uint pos = p->num_immediates++;
uint j;
+ assert( imm->Immediate.NrTokens <= 4 + 1 );
for (j = 0; j < imm->Immediate.NrTokens - 1; j++) {
- p->immediates[pos][j] = imm->u.ImmediateFloat32[j].Float;
+ p->immediates[pos][j] = imm->u[j].Float;
}
}
break;
diff --git a/src/gallium/drivers/i915simple/i915_screen.c b/src/gallium/drivers/i915simple/i915_screen.c
index f4aa8e60d81..a3de38d5860 100644
--- a/src/gallium/drivers/i915simple/i915_screen.c
+++ b/src/gallium/drivers/i915simple/i915_screen.c
@@ -232,6 +232,8 @@ i915_get_tex_transfer(struct pipe_screen *screen,
if (trans) {
pipe_texture_reference(&trans->base.texture, texture);
trans->base.format = trans->base.format;
+ trans->base.x = x;
+ trans->base.y = y;
trans->base.width = w;
trans->base.height = h;
trans->base.block = texture->block;
diff --git a/src/gallium/drivers/i915simple/i915_texture.c b/src/gallium/drivers/i915simple/i915_texture.c
index ca8e87af8d1..03f0e14e7c8 100644
--- a/src/gallium/drivers/i915simple/i915_texture.c
+++ b/src/gallium/drivers/i915simple/i915_texture.c
@@ -72,11 +72,6 @@ static const int step_offsets[6][2] = {
{-1, 1}
};
-static unsigned minify( unsigned d )
-{
- return MAX2(1, d>>1);
-}
-
static unsigned
power_of_two(unsigned x)
{
@@ -160,10 +155,10 @@ i915_miptree_set_image_offset(struct i915_texture *tex,
/**
- * Special case to deal with display targets.
+ * Special case to deal with scanout textures.
*/
static boolean
-i915_displaytarget_layout(struct i915_texture *tex)
+i915_scanout_layout(struct i915_texture *tex)
{
struct pipe_texture *pt = &tex->base;
@@ -177,9 +172,13 @@ i915_displaytarget_layout(struct i915_texture *tex)
i915_miptree_set_image_offset( tex, 0, 0, 0, 0 );
if (tex->base.width[0] >= 128) {
+#if 0
tex->stride = power_of_two(tex->base.nblocksx[0] * pt->block.size);
+#else
+ tex->stride = 2048 * 4; /* TODO fix when backend is smarter */
+#endif
tex->total_nblocksy = round_up(tex->base.nblocksy[0], 8);
-#if 0 /* used for tiled display targets */
+#if 0 /* used for tiled textures */
tex->tiled = 1;
#endif
} else {
@@ -209,9 +208,9 @@ i945_miptree_layout_2d( struct i915_texture *tex )
unsigned nblocksx = pt->nblocksx[0];
unsigned nblocksy = pt->nblocksy[0];
- /* used for tiled display targets */
- if (0)
- if (i915_displaytarget_layout(tex))
+ /* used for scanouts that need special layouts */
+ if (tex->base.tex_usage & PIPE_TEXTURE_USAGE_PRIMARY)
+ if (i915_scanout_layout(tex))
return;
tex->stride = round_up(pt->nblocksx[0] * pt->block.size, 4);
@@ -584,6 +583,7 @@ i915_texture_create(struct pipe_screen *screen,
struct i915_screen *i915screen = i915_screen(screen);
struct i915_texture *tex = CALLOC_STRUCT(i915_texture);
size_t tex_size;
+ unsigned buf_usage = 0;
if (!tex)
return NULL;
@@ -605,9 +605,11 @@ i915_texture_create(struct pipe_screen *screen,
tex_size = tex->stride * tex->total_nblocksy;
- tex->buffer = screen->buffer_create(screen, 64,
- PIPE_BUFFER_USAGE_PIXEL,
- tex_size);
+ buf_usage = PIPE_BUFFER_USAGE_PIXEL;
+ if (templat->tex_usage & PIPE_TEXTURE_USAGE_PRIMARY)
+ buf_usage |= I915_BUFFER_USAGE_SCANOUT;
+
+ tex->buffer = screen->buffer_create(screen, 64, buf_usage, tex_size);
if (!tex->buffer)
goto fail;
diff --git a/src/gallium/drivers/i915simple/i915_winsys.h b/src/gallium/drivers/i915simple/i915_winsys.h
index ff5b34f193a..711db91c367 100644
--- a/src/gallium/drivers/i915simple/i915_winsys.h
+++ b/src/gallium/drivers/i915simple/i915_winsys.h
@@ -109,6 +109,7 @@ struct i915_winsys {
#define I915_BUFFER_ACCESS_READ 0x2
#define I915_BUFFER_USAGE_LIT_VERTEX (PIPE_BUFFER_USAGE_CUSTOM << 0)
+#define I915_BUFFER_USAGE_SCANOUT (PIPE_BUFFER_USAGE_CUSTOM << 1)
/**
diff --git a/src/gallium/drivers/i965simple/brw_tex_layout.c b/src/gallium/drivers/i965simple/brw_tex_layout.c
index 8aea8c05581..998ffaeac4a 100644
--- a/src/gallium/drivers/i965simple/brw_tex_layout.c
+++ b/src/gallium/drivers/i965simple/brw_tex_layout.c
@@ -65,11 +65,6 @@ unsigned intel_compressed_alignment(unsigned internalFormat)
}
#endif
-static unsigned minify( unsigned d )
-{
- return MAX2(1, d>>1);
-}
-
static void intel_miptree_set_image_offset(struct brw_texture *tex,
unsigned level,
diff --git a/src/gallium/drivers/i965simple/brw_vs_emit.c b/src/gallium/drivers/i965simple/brw_vs_emit.c
index e03d6534821..3ee82d95b3a 100644
--- a/src/gallium/drivers/i965simple/brw_vs_emit.c
+++ b/src/gallium/drivers/i965simple/brw_vs_emit.c
@@ -1294,10 +1294,10 @@ void brw_vs_emit(struct brw_vs_compile *c)
case TGSI_TOKEN_TYPE_IMMEDIATE: {
struct tgsi_full_immediate *imm = &parse.FullToken.FullImmediate;
assert(imm->Immediate.NrTokens == 4 + 1);
- c->prog_data.imm_buf[c->prog_data.num_imm][0] = imm->u.ImmediateFloat32[0].Float;
- c->prog_data.imm_buf[c->prog_data.num_imm][1] = imm->u.ImmediateFloat32[1].Float;
- c->prog_data.imm_buf[c->prog_data.num_imm][2] = imm->u.ImmediateFloat32[2].Float;
- c->prog_data.imm_buf[c->prog_data.num_imm][3] = imm->u.ImmediateFloat32[3].Float;
+ c->prog_data.imm_buf[c->prog_data.num_imm][0] = imm->u[0].Float;
+ c->prog_data.imm_buf[c->prog_data.num_imm][1] = imm->u[1].Float;
+ c->prog_data.imm_buf[c->prog_data.num_imm][2] = imm->u[2].Float;
+ c->prog_data.imm_buf[c->prog_data.num_imm][3] = imm->u[3].Float;
c->prog_data.num_imm++;
}
break;
diff --git a/src/gallium/drivers/i965simple/brw_wm_glsl.c b/src/gallium/drivers/i965simple/brw_wm_glsl.c
index ab6410aa607..db759639328 100644
--- a/src/gallium/drivers/i965simple/brw_wm_glsl.c
+++ b/src/gallium/drivers/i965simple/brw_wm_glsl.c
@@ -947,7 +947,7 @@ static void brw_wm_emit_instruction( struct brw_wm_compile *c,
#endif
break;
- case TGSI_OPCODE_LOOP:
+ case TGSI_OPCODE_BGNFOR:
c->loop_inst[c->loop_insn++] = brw_DO(p, BRW_EXECUTE_8);
break;
case TGSI_OPCODE_BRK:
@@ -958,11 +958,11 @@ static void brw_wm_emit_instruction( struct brw_wm_compile *c,
brw_CONT(p);
brw_set_predicate_control(p, BRW_PREDICATE_NONE);
break;
- case TGSI_OPCODE_ENDLOOP:
+ case TGSI_OPCODE_ENDFOR:
c->loop_insn--;
c->inst0 = c->inst1 = brw_WHILE(p, c->loop_inst[c->loop_insn]);
/* patch all the BREAK instructions from
- last BEGINLOOP */
+ last BGNFOR */
while (c->inst0 > c->loop_inst[c->loop_insn]) {
c->inst0--;
if (c->inst0->header.opcode == BRW_OPCODE_BREAK) {
diff --git a/src/gallium/drivers/identity/id_context.c b/src/gallium/drivers/identity/id_context.c
index a500ec60454..4e700089e33 100644
--- a/src/gallium/drivers/identity/id_context.c
+++ b/src/gallium/drivers/identity/id_context.c
@@ -501,7 +501,7 @@ identity_set_sampler_textures(struct pipe_context *_pipe,
pipe->set_sampler_textures(pipe,
num_textures,
- _textures);
+ textures);
}
static void
diff --git a/src/gallium/drivers/identity/id_drm.c b/src/gallium/drivers/identity/id_drm.c
index 555220f8531..e5342ac06e3 100644
--- a/src/gallium/drivers/identity/id_drm.c
+++ b/src/gallium/drivers/identity/id_drm.c
@@ -60,7 +60,7 @@ identity_drm_create_screen(struct drm_api *_api, int fd,
screen = api->create_screen(api, fd, arg);
return identity_screen_create(screen);
-};
+}
static struct pipe_context *
identity_drm_create_context(struct drm_api *_api,
@@ -77,7 +77,7 @@ identity_drm_create_context(struct drm_api *_api,
pipe = identity_context_create(_screen, pipe);
return pipe;
-};
+}
static boolean
identity_drm_buffer_from_texture(struct drm_api *_api,
diff --git a/src/gallium/drivers/identity/id_screen.c b/src/gallium/drivers/identity/id_screen.c
index 259f1be36e7..26439637d08 100644
--- a/src/gallium/drivers/identity/id_screen.c
+++ b/src/gallium/drivers/identity/id_screen.c
@@ -289,6 +289,7 @@ identity_screen_surface_buffer_create(struct pipe_screen *_screen,
unsigned height,
enum pipe_format format,
unsigned usage,
+ unsigned tex_usage,
unsigned *stride)
{
struct identity_screen *id_screen = identity_screen(_screen);
@@ -300,6 +301,7 @@ identity_screen_surface_buffer_create(struct pipe_screen *_screen,
height,
format,
usage,
+ tex_usage,
stride);
if (result)
diff --git a/src/gallium/drivers/nouveau/nouveau_screen.c b/src/gallium/drivers/nouveau/nouveau_screen.c
index 832366e6462..e4cf91c005c 100644
--- a/src/gallium/drivers/nouveau/nouveau_screen.c
+++ b/src/gallium/drivers/nouveau/nouveau_screen.c
@@ -4,6 +4,8 @@
#include <util/u_memory.h>
+#include <errno.h>
+
#include "nouveau/nouveau_bo.h"
#include "nouveau_winsys.h"
#include "nouveau_screen.h"
@@ -141,12 +143,13 @@ nouveau_screen_bo_map_range(struct pipe_screen *pscreen, struct pipe_buffer *pb,
unsigned offset, unsigned length, unsigned usage)
{
struct nouveau_bo *bo = nouveau_bo(pb);
+ uint32_t flags = nouveau_screen_map_flags(usage);
int ret;
- ret = nouveau_bo_map_range(bo, offset, length,
- nouveau_screen_map_flags(usage));
+ ret = nouveau_bo_map_range(bo, offset, length, flags);
if (ret) {
- debug_printf("map_range failed: %d\n", ret);
+ if (!(flags & NOUVEAU_BO_NOWAIT) || ret != -EBUSY)
+ debug_printf("map_range failed: %d\n", ret);
return NULL;
}
diff --git a/src/gallium/drivers/nv04/nv04_surface_2d.c b/src/gallium/drivers/nv04/nv04_surface_2d.c
index f315cf54f05..bbbcb54c467 100644
--- a/src/gallium/drivers/nv04/nv04_surface_2d.c
+++ b/src/gallium/drivers/nv04/nv04_surface_2d.c
@@ -110,10 +110,10 @@ nv04_surface_copy_swizzle(struct nv04_surface_2d *ctx,
unsigned cx;
unsigned cy;
- /* POT or GTFO */
- assert(!(w & (w - 1)) && !(h & (h - 1)));
+#if 0
/* That's the way she likes it */
assert(src_pitch == ((struct nv04_surface *)dst)->pitch);
+#endif
BEGIN_RING(chan, swzsurf, NV04_SWIZZLED_SURFACE_DMA_IMAGE, 1);
OUT_RELOCo(chan, dst_bo,
@@ -133,7 +133,7 @@ nv04_surface_copy_swizzle(struct nv04_surface_2d *ctx,
for (cy = 0; cy < h; cy += sub_h) {
for (cx = 0; cx < w; cx += sub_w) {
BEGIN_RING(chan, swzsurf, NV04_SWIZZLED_SURFACE_OFFSET, 1);
- OUT_RELOCl(chan, dst_bo, dst->offset + nv04_swizzle_bits(cx, cy) *
+ OUT_RELOCl(chan, dst_bo, dst->offset + nv04_swizzle_bits(cx+dx, cy+dy) *
dst->texture->block.size, NOUVEAU_BO_GART |
NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
@@ -153,8 +153,8 @@ nv04_surface_copy_swizzle(struct nv04_surface_2d *ctx,
OUT_RING (chan, src_pitch |
NV04_SCALED_IMAGE_FROM_MEMORY_FORMAT_ORIGIN_CENTER |
NV04_SCALED_IMAGE_FROM_MEMORY_FORMAT_FILTER_POINT_SAMPLE);
- OUT_RELOCl(chan, src_bo, src->offset + cy * src_pitch +
- cx * src->texture->block.size, NOUVEAU_BO_GART |
+ OUT_RELOCl(chan, src_bo, src->offset + (cy+sy) * src_pitch +
+ (cx+sx) * src->texture->block.size, NOUVEAU_BO_GART |
NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
OUT_RING (chan, 0);
}
@@ -210,6 +210,43 @@ nv04_surface_copy_m2mf(struct nv04_surface_2d *ctx,
}
static int
+nv04_surface_copy_m2mf_swizzle(struct nv04_surface_2d *ctx,
+ struct pipe_surface *dst, int dx, int dy,
+ struct pipe_surface *src, int sx, int sy)
+{
+ struct nouveau_channel *chan = ctx->m2mf->channel;
+ struct nouveau_grobj *m2mf = ctx->m2mf;
+ struct nouveau_bo *src_bo = nouveau_bo(ctx->buf(src));
+ struct nouveau_bo *dst_bo = nouveau_bo(ctx->buf(dst));
+ unsigned src_pitch = ((struct nv04_surface *)src)->pitch;
+ unsigned dst_pitch = ((struct nv04_surface *)dst)->pitch;
+ unsigned dst_offset = dst->offset + nv04_swizzle_bits(dx, dy) *
+ dst->texture->block.size;
+ unsigned src_offset = src->offset + sy * src_pitch +
+ sx * src->texture->block.size;
+
+ BEGIN_RING(chan, m2mf, NV04_MEMORY_TO_MEMORY_FORMAT_DMA_BUFFER_IN, 2);
+ OUT_RELOCo(chan, src_bo,
+ NOUVEAU_BO_GART | NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
+ OUT_RELOCo(chan, dst_bo,
+ NOUVEAU_BO_GART | NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
+
+ BEGIN_RING(chan, m2mf, NV04_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN, 8);
+ OUT_RELOCl(chan, src_bo, src_offset,
+ NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD);
+ OUT_RELOCl(chan, dst_bo, dst_offset,
+ NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_WR);
+ OUT_RING (chan, src_pitch);
+ OUT_RING (chan, dst_pitch);
+ OUT_RING (chan, 1 * src->texture->block.size);
+ OUT_RING (chan, 1);
+ OUT_RING (chan, 0x0101);
+ OUT_RING (chan, 0);
+
+ return 0;
+}
+
+static int
nv04_surface_copy_blit(struct nv04_surface_2d *ctx, struct pipe_surface *dst,
int dx, int dy, struct pipe_surface *src, int sx, int sy,
int w, int h)
@@ -258,8 +295,59 @@ nv04_surface_copy(struct nv04_surface_2d *ctx, struct pipe_surface *dst,
assert(src->format == dst->format);
/* Setup transfer to swizzle the texture to vram if needed */
- if (src_linear && !dst_linear && w > 1 && h > 1) {
- nv04_surface_copy_swizzle(ctx, dst, dx, dy, src, sx, sy, w, h);
+ if (src_linear && !dst_linear) {
+ int x,y;
+
+ if ((w>1) && (h>1)) {
+ int potWidth = 1<<log2i(w);
+ int potHeight = 1<<log2i(h);
+ int remainWidth = w-potWidth;
+ int remainHeight = h-potHeight;
+ int squareDim = (potWidth>potHeight ? potHeight : potWidth);
+
+ /* top left is always POT, but we can only swizzle squares */
+ for (y=0; y<potHeight; y+=squareDim) {
+ for (x=0; x<potWidth; x+= squareDim) {
+ nv04_surface_copy_swizzle(ctx, dst, dx+x, dy+y,
+ src, sx+x, sy+y,
+ squareDim, squareDim);
+ }
+ }
+
+ /* top right */
+ if (remainWidth>0) {
+ nv04_surface_copy(ctx, dst, dx+potWidth, dy,
+ src, sx+potWidth, sy,
+ remainWidth, potHeight);
+ }
+
+ /* bottom left */
+ if (remainHeight>0) {
+ nv04_surface_copy(ctx, dst, dx, dy+potHeight,
+ src, sx, sy+potHeight,
+ potWidth, remainHeight);
+ }
+
+ /* bottom right */
+ if ((remainWidth>0) && (remainHeight>0)) {
+ nv04_surface_copy(ctx, dst, dx+potWidth, dy+potHeight,
+ src, sx+potWidth, sy+potHeight,
+ remainWidth, remainHeight);
+ }
+ } else if (w==1) {
+ /* We have a column to copy to a swizzled texture */
+ for (y=0; y<h; y++) {
+ nv04_surface_copy_m2mf_swizzle(ctx, dst, dx, dy+y,
+ src, sx, sy+y);
+ }
+ } else if (h==1) {
+ /* We have a row to copy to a swizzled texture */
+ for (x=0; x<w; x++) {
+ nv04_surface_copy_m2mf_swizzle(ctx, dst, dx+x, dy,
+ src, sx+x, sy);
+ }
+ }
+
return;
}
diff --git a/src/gallium/drivers/nv20/nv20_vertprog.c b/src/gallium/drivers/nv20/nv20_vertprog.c
index c1e588902b2..388245ecb04 100644
--- a/src/gallium/drivers/nv20/nv20_vertprog.c
+++ b/src/gallium/drivers/nv20/nv20_vertprog.c
@@ -617,10 +617,10 @@ nv20_vertprog_translate(struct nv20_context *nv20,
assert(imm->Immediate.NrTokens == 4 + 1);
vpc->imm[vpc->nr_imm++] =
constant(vpc, -1,
- imm->u.ImmediateFloat32[0].Float,
- imm->u.ImmediateFloat32[1].Float,
- imm->u.ImmediateFloat32[2].Float,
- imm->u.ImmediateFloat32[3].Float);
+ imm->u[0].Float,
+ imm->u[1].Float,
+ imm->u[2].Float,
+ imm->u[3].Float);
}
break;
case TGSI_TOKEN_TYPE_INSTRUCTION:
diff --git a/src/gallium/drivers/nv30/nv30_fragprog.c b/src/gallium/drivers/nv30/nv30_fragprog.c
index 1d1c556fb11..a48ba9782b3 100644
--- a/src/gallium/drivers/nv30/nv30_fragprog.c
+++ b/src/gallium/drivers/nv30/nv30_fragprog.c
@@ -704,10 +704,10 @@ nv30_fragprog_prepare(struct nv30_fpc *fpc)
assert(imm->Immediate.DataType == TGSI_IMM_FLOAT32);
assert(fpc->nr_imm < MAX_IMM);
- vals[0] = imm->u.ImmediateFloat32[0].Float;
- vals[1] = imm->u.ImmediateFloat32[1].Float;
- vals[2] = imm->u.ImmediateFloat32[2].Float;
- vals[3] = imm->u.ImmediateFloat32[3].Float;
+ vals[0] = imm->u[0].Float;
+ vals[1] = imm->u[1].Float;
+ vals[2] = imm->u[2].Float;
+ vals[3] = imm->u[3].Float;
fpc->imm[fpc->nr_imm++] = constant(fpc, -1, vals);
}
break;
diff --git a/src/gallium/drivers/nv30/nv30_screen.c b/src/gallium/drivers/nv30/nv30_screen.c
index c8b40784b05..f8285e4455f 100644
--- a/src/gallium/drivers/nv30/nv30_screen.c
+++ b/src/gallium/drivers/nv30/nv30_screen.c
@@ -95,7 +95,7 @@ nv30_screen_surface_format_supported(struct pipe_screen *pscreen,
}
} else
if (tex_usage & PIPE_TEXTURE_USAGE_DEPTH_STENCIL) {
- switch (tex_usage) {
+ switch (format) {
case PIPE_FORMAT_Z24S8_UNORM:
case PIPE_FORMAT_Z24X8_UNORM:
case PIPE_FORMAT_Z16_UNORM:
diff --git a/src/gallium/drivers/nv30/nv30_vertprog.c b/src/gallium/drivers/nv30/nv30_vertprog.c
index c7514efcfea..14a5c0260d0 100644
--- a/src/gallium/drivers/nv30/nv30_vertprog.c
+++ b/src/gallium/drivers/nv30/nv30_vertprog.c
@@ -617,10 +617,10 @@ nv30_vertprog_translate(struct nv30_context *nv30,
assert(imm->Immediate.NrTokens == 4 + 1);
vpc->imm[vpc->nr_imm++] =
constant(vpc, -1,
- imm->u.ImmediateFloat32[0].Float,
- imm->u.ImmediateFloat32[1].Float,
- imm->u.ImmediateFloat32[2].Float,
- imm->u.ImmediateFloat32[3].Float);
+ imm->u[0].Float,
+ imm->u[1].Float,
+ imm->u[2].Float,
+ imm->u[3].Float);
}
break;
case TGSI_TOKEN_TYPE_INSTRUCTION:
diff --git a/src/gallium/drivers/nv40/nv40_fragprog.c b/src/gallium/drivers/nv40/nv40_fragprog.c
index 680976da56b..32d9ed1a7f8 100644
--- a/src/gallium/drivers/nv40/nv40_fragprog.c
+++ b/src/gallium/drivers/nv40/nv40_fragprog.c
@@ -790,10 +790,10 @@ nv40_fragprog_prepare(struct nv40_fpc *fpc)
assert(imm->Immediate.DataType == TGSI_IMM_FLOAT32);
assert(fpc->nr_imm < MAX_IMM);
- vals[0] = imm->u.ImmediateFloat32[0].Float;
- vals[1] = imm->u.ImmediateFloat32[1].Float;
- vals[2] = imm->u.ImmediateFloat32[2].Float;
- vals[3] = imm->u.ImmediateFloat32[3].Float;
+ vals[0] = imm->u[0].Float;
+ vals[1] = imm->u[1].Float;
+ vals[2] = imm->u[2].Float;
+ vals[3] = imm->u[3].Float;
fpc->imm[fpc->nr_imm++] = constant(fpc, -1, vals);
}
break;
diff --git a/src/gallium/drivers/nv40/nv40_vertprog.c b/src/gallium/drivers/nv40/nv40_vertprog.c
index e75e8d3f424..0382dbba8f6 100644
--- a/src/gallium/drivers/nv40/nv40_vertprog.c
+++ b/src/gallium/drivers/nv40/nv40_vertprog.c
@@ -788,10 +788,10 @@ nv40_vertprog_translate(struct nv40_context *nv40,
assert(imm->Immediate.NrTokens == 4 + 1);
vpc->imm[vpc->nr_imm++] =
constant(vpc, -1,
- imm->u.ImmediateFloat32[0].Float,
- imm->u.ImmediateFloat32[1].Float,
- imm->u.ImmediateFloat32[2].Float,
- imm->u.ImmediateFloat32[3].Float);
+ imm->u[0].Float,
+ imm->u[1].Float,
+ imm->u[2].Float,
+ imm->u[3].Float);
}
break;
case TGSI_TOKEN_TYPE_INSTRUCTION:
diff --git a/src/gallium/drivers/nv50/nv50_context.c b/src/gallium/drivers/nv50/nv50_context.c
index e02afc4be99..6e8f4f9750d 100644
--- a/src/gallium/drivers/nv50/nv50_context.c
+++ b/src/gallium/drivers/nv50/nv50_context.c
@@ -31,15 +31,23 @@ static void
nv50_flush(struct pipe_context *pipe, unsigned flags,
struct pipe_fence_handle **fence)
{
- struct nv50_context *nv50 = (struct nv50_context *)pipe;
-
- FIRE_RING(nv50->screen->base.channel);
+ struct nv50_context *nv50 = nv50_context(pipe);
+ struct nouveau_channel *chan = nv50->screen->base.channel;
+ struct nouveau_grobj *eng2d = nv50->screen->eng2d;
+
+ /* We need this in the ddx for reliable composite, not sure what we're
+ * actually flushing. We generate all our own flushes with flags = 0. */
+ WAIT_RING(chan, 3);
+ BEGIN_RING(chan, eng2d, 0x0110, 1);
+ OUT_RING (chan, 0);
+
+ FIRE_RING(chan);
}
static void
nv50_destroy(struct pipe_context *pipe)
{
- struct nv50_context *nv50 = (struct nv50_context *)pipe;
+ struct nv50_context *nv50 = nv50_context(pipe);
draw_destroy(nv50->draw);
FREE(nv50);
@@ -112,5 +120,3 @@ nv50_create(struct pipe_screen *pscreen, unsigned pctx_id)
return &nv50->pipe;
}
-
-
diff --git a/src/gallium/drivers/nv50/nv50_context.h b/src/gallium/drivers/nv50/nv50_context.h
index 9b8cc4d37d0..5cbc2c8f823 100644
--- a/src/gallium/drivers/nv50/nv50_context.h
+++ b/src/gallium/drivers/nv50/nv50_context.h
@@ -71,6 +71,7 @@ struct nv50_sampler_stateobj {
struct nv50_miptree_level {
int *image_offset;
unsigned pitch;
+ unsigned tile_mode;
};
struct nv50_miptree {
diff --git a/src/gallium/drivers/nv50/nv50_miptree.c b/src/gallium/drivers/nv50/nv50_miptree.c
index 22465e02274..dd1b0303bd5 100644
--- a/src/gallium/drivers/nv50/nv50_miptree.c
+++ b/src/gallium/drivers/nv50/nv50_miptree.c
@@ -42,9 +42,14 @@ nv50_miptree_create(struct pipe_screen *pscreen, const struct pipe_texture *tmp)
mt->base.screen = pscreen;
switch (pt->format) {
- case PIPE_FORMAT_Z24X8_UNORM:
+ case PIPE_FORMAT_Z32_FLOAT:
+ tile_flags = 0x4800;
+ break;
case PIPE_FORMAT_Z24S8_UNORM:
- case PIPE_FORMAT_Z16_UNORM:
+ tile_flags = 0x1800;
+ break;
+ case PIPE_FORMAT_X8Z24_UNORM:
+ case PIPE_FORMAT_S8Z24_UNORM:
tile_flags = 0x2800;
break;
default:
@@ -82,20 +87,27 @@ nv50_miptree_create(struct pipe_screen *pscreen, const struct pipe_texture *tmp)
lvl->image_offset = CALLOC(mt->image_nr, sizeof(int));
lvl->pitch = align(pt->width[l] * pt->block.size, 64);
+ lvl->tile_mode = tile_mode;
width = MAX2(1, width >> 1);
height = MAX2(1, height >> 1);
depth = MAX2(1, depth >> 1);
+
+ if (tile_mode && height <= (tile_h >> 1)) {
+ tile_mode--;
+ tile_h >>= 1;
+ }
}
for (i = 0; i < mt->image_nr; i++) {
for (l = 0; l <= pt->last_level; l++) {
struct nv50_miptree_level *lvl = &mt->level[l];
int size;
+ tile_h = 1 << (lvl->tile_mode + 2);
size = align(pt->width[l], 8) * pt->block.size;
size = align(size, 64);
- size *= align(pt->height[l], tile_h) * pt->block.size;
+ size *= align(pt->height[l], tile_h);
lvl->image_offset[i] = mt->total_size;
@@ -104,12 +116,12 @@ nv50_miptree_create(struct pipe_screen *pscreen, const struct pipe_texture *tmp)
}
ret = nouveau_bo_new_tile(dev, NOUVEAU_BO_VRAM, 256, mt->total_size,
- tile_mode, tile_flags, &mt->bo);
+ mt->level[0].tile_mode, tile_flags, &mt->bo);
if (ret) {
FREE(mt);
return NULL;
}
-
+
return &mt->base;
}
@@ -146,7 +158,7 @@ nv50_miptree_destroy(struct pipe_texture *pt)
struct nv50_miptree *mt = nv50_miptree(pt);
nouveau_bo_ref(NULL, &mt->bo);
- FREE(mt);
+ FREE(mt);
}
static struct pipe_surface *
@@ -189,8 +201,8 @@ nv50_miptree_surface_del(struct pipe_surface *ps)
{
struct nv50_surface *s = nv50_surface(ps);
- pipe_texture_reference(&ps->texture, NULL);
- FREE(s);
+ pipe_texture_reference(&ps->texture, NULL);
+ FREE(s);
}
void
diff --git a/src/gallium/drivers/nv50/nv50_program.c b/src/gallium/drivers/nv50/nv50_program.c
index 5f7d06dbecb..289c3485e08 100644
--- a/src/gallium/drivers/nv50/nv50_program.c
+++ b/src/gallium/drivers/nv50/nv50_program.c
@@ -251,7 +251,7 @@ alloc_temp4(struct nv50_pc *pc, struct nv50_reg *dst[4], int idx)
if (pc->r_temp[idx] || pc->r_temp[idx + 1] ||
pc->r_temp[idx + 2] || pc->r_temp[idx + 3])
- return alloc_temp4(pc, dst, idx + 1);
+ return alloc_temp4(pc, dst, idx + 4);
for (i = 0; i < 4; i++) {
dst[i] = CALLOC_STRUCT(nv50_reg);
@@ -296,7 +296,7 @@ kill_temp_temp(struct nv50_pc *pc)
static int
ctor_immd(struct nv50_pc *pc, float x, float y, float z, float w)
{
- pc->immd_buf = REALLOC(pc->immd_buf, (pc->immd_nr * r * sizeof(float)),
+ pc->immd_buf = REALLOC(pc->immd_buf, (pc->immd_nr * 4 * sizeof(float)),
(pc->immd_nr + 1) * 4 * sizeof(float));
pc->immd_buf[(pc->immd_nr * 4) + 0] = x;
pc->immd_buf[(pc->immd_nr * 4) + 1] = y;
@@ -1014,6 +1014,7 @@ emit_tex(struct nv50_pc *pc, struct nv50_reg **dst, unsigned mask,
break;
}
+ /* some cards need t[0]'s hw index to be a multiple of 4 */
alloc_temp4(pc, t, 0);
if (proj) {
@@ -1809,10 +1810,10 @@ nv50_program_tx_prep(struct nv50_pc *pc)
const struct tgsi_full_immediate *imm =
&p.FullToken.FullImmediate;
- ctor_immd(pc, imm->u.ImmediateFloat32[0].Float,
- imm->u.ImmediateFloat32[1].Float,
- imm->u.ImmediateFloat32[2].Float,
- imm->u.ImmediateFloat32[3].Float);
+ ctor_immd(pc, imm->u[0].Float,
+ imm->u[1].Float,
+ imm->u[2].Float,
+ imm->u[3].Float);
}
break;
case TGSI_TOKEN_TYPE_DECLARATION:
@@ -2221,9 +2222,9 @@ nv50_program_upload_data(struct nv50_context *nv50, float *map,
while (count) {
unsigned nr = count > 2047 ? 2047 : count;
- BEGIN_RING(chan, tesla, 0x00000f00, 1);
+ BEGIN_RING(chan, tesla, NV50TCL_CB_ADDR, 1);
OUT_RING (chan, (cbuf << 0) | (start << 8));
- BEGIN_RING(chan, tesla, 0x40000f04, nr);
+ BEGIN_RING(chan, tesla, NV50TCL_CB_DATA(0) | 0x40000000, nr);
OUT_RINGp (chan, map, nr);
map += nr;
@@ -2345,7 +2346,7 @@ nv50_program_validate_code(struct nv50_context *nv50, struct nv50_program *p)
}
so = so_new(4,2);
- so_method(so, nv50->screen->tesla, 0x1280, 3);
+ so_method(so, nv50->screen->tesla, NV50TCL_CB_DEF_ADDRESS_HIGH, 3);
so_reloc (so, p->bo, 0, flags | NOUVEAU_BO_HIGH, 0, 0);
so_reloc (so, p->bo, 0, flags | NOUVEAU_BO_LOW, 0, 0);
so_data (so, (NV50_CB_PUPLOAD << 16) | 0x0800); //(p->exec_size * 4));
@@ -2364,9 +2365,9 @@ nv50_program_validate_code(struct nv50_context *nv50, struct nv50_program *p)
continue;
}
- BEGIN_RING(chan, tesla, 0x0f00, 1);
+ BEGIN_RING(chan, tesla, NV50TCL_CB_ADDR, 1);
OUT_RING (chan, (start << 8) | NV50_CB_PUPLOAD);
- BEGIN_RING(chan, tesla, 0x40000f04, nr);
+ BEGIN_RING(chan, tesla, NV50TCL_CB_DATA(0) | 0x40000000, nr);
OUT_RINGp (chan, up + start, nr);
start += nr;
@@ -2399,15 +2400,15 @@ nv50_vertprog_validate(struct nv50_context *nv50)
NOUVEAU_BO_HIGH, 0, 0);
so_reloc (so, p->bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD |
NOUVEAU_BO_LOW, 0, 0);
- so_method(so, tesla, 0x1650, 2);
+ so_method(so, tesla, NV50TCL_VP_ATTR_EN_0, 2);
so_data (so, p->cfg.vp.attr[0]);
so_data (so, p->cfg.vp.attr[1]);
- so_method(so, tesla, 0x16b8, 1);
+ so_method(so, tesla, NV50TCL_VP_REG_ALLOC_RESULT, 1);
so_data (so, p->cfg.high_result);
- so_method(so, tesla, 0x16ac, 2);
+ so_method(so, tesla, NV50TCL_VP_RESULT_MAP_SIZE, 2);
so_data (so, p->cfg.high_result); //8);
so_data (so, p->cfg.high_temp);
- so_method(so, tesla, 0x140c, 1);
+ so_method(so, tesla, NV50TCL_VP_START_ID, 1);
so_data (so, 0); /* program start offset */
so_ref(so, &nv50->state.vertprog);
so_ref(NULL, &so);
@@ -2436,24 +2437,24 @@ nv50_fragprog_validate(struct nv50_context *nv50)
NOUVEAU_BO_HIGH, 0, 0);
so_reloc (so, p->bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD |
NOUVEAU_BO_LOW, 0, 0);
- so_method(so, tesla, 0x1904, 4);
+ so_method(so, tesla, NV50TCL_MAP_SEMANTIC_0, 4);
so_data (so, p->cfg.fp.regs[0]); /* 0x01000404 / 0x00040404 */
so_data (so, 0x00000004);
so_data (so, 0x00000000);
so_data (so, 0x00000000);
- so_method(so, tesla, 0x16bc, p->cfg.fp.high_map);
+ so_method(so, tesla, NV50TCL_VP_RESULT_MAP(0), p->cfg.fp.high_map);
for (i = 0; i < p->cfg.fp.high_map; i++)
so_data(so, p->cfg.fp.map[i]);
- so_method(so, tesla, 0x1988, 2);
+ so_method(so, tesla, NV50TCL_FP_INTERPOLANT_CTRL, 2);
so_data (so, p->cfg.fp.regs[1]); /* 0x08040404 / 0x0f000401 */
so_data (so, p->cfg.high_temp);
- so_method(so, tesla, 0x1298, 1);
+ so_method(so, tesla, NV50TCL_FP_RESULT_COUNT, 1);
so_data (so, p->cfg.high_result);
- so_method(so, tesla, 0x19a8, 1);
+ so_method(so, tesla, NV50TCL_FP_CTRL_UNK19A8, 1);
so_data (so, p->cfg.fp.regs[2]);
- so_method(so, tesla, 0x196c, 1);
+ so_method(so, tesla, NV50TCL_FP_CTRL_UNK196C, 1);
so_data (so, p->cfg.fp.regs[3]);
- so_method(so, tesla, 0x1414, 1);
+ so_method(so, tesla, NV50TCL_FP_START_ID, 1);
so_data (so, 0); /* program start offset */
so_ref(so, &nv50->state.fragprog);
so_ref(NULL, &so);
@@ -2478,4 +2479,3 @@ nv50_program_destroy(struct nv50_context *nv50, struct nv50_program *p)
p->translated = 0;
}
-
diff --git a/src/gallium/drivers/nv50/nv50_query.c b/src/gallium/drivers/nv50/nv50_query.c
index 940e04365f2..5305c93d59a 100644
--- a/src/gallium/drivers/nv50/nv50_query.c
+++ b/src/gallium/drivers/nv50/nv50_query.c
@@ -94,7 +94,7 @@ nv50_query_end(struct pipe_context *pipe, struct pipe_query *pq)
struct nv50_query *q = nv50_query(pq);
WAIT_RING (chan, 5);
- BEGIN_RING(chan, tesla, 0x1b00, 4);
+ BEGIN_RING(chan, tesla, NV50TCL_QUERY_ADDRESS_HIGH, 4);
OUT_RELOCh(chan, q->bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
OUT_RELOCl(chan, q->bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
OUT_RING (chan, 0x00000000);
@@ -107,13 +107,13 @@ nv50_query_result(struct pipe_context *pipe, struct pipe_query *pq,
boolean wait, uint64_t *result)
{
struct nv50_query *q = nv50_query(pq);
-
- /*XXX: Want to be able to return FALSE here instead of blocking
- * until the result is available..
- */
+ int ret;
if (!q->ready) {
- nouveau_bo_map(q->bo, NOUVEAU_BO_RD);
+ ret = nouveau_bo_map(q->bo, NOUVEAU_BO_RD |
+ wait ? 0 : NOUVEAU_BO_NOWAIT);
+ if (ret)
+ return false;
q->result = ((uint32_t *)q->bo->map)[1];
q->ready = TRUE;
nouveau_bo_unmap(q->bo);
diff --git a/src/gallium/drivers/nv50/nv50_screen.c b/src/gallium/drivers/nv50/nv50_screen.c
index ce8f906b15f..c7f80a22037 100644
--- a/src/gallium/drivers/nv50/nv50_screen.c
+++ b/src/gallium/drivers/nv50/nv50_screen.c
@@ -44,9 +44,10 @@ nv50_screen_is_format_supported(struct pipe_screen *pscreen,
} else
if (tex_usage & PIPE_TEXTURE_USAGE_DEPTH_STENCIL) {
switch (format) {
+ case PIPE_FORMAT_Z32_FLOAT:
case PIPE_FORMAT_Z24S8_UNORM:
- case PIPE_FORMAT_Z24X8_UNORM:
- case PIPE_FORMAT_Z16_UNORM:
+ case PIPE_FORMAT_X8Z24_UNORM:
+ case PIPE_FORMAT_S8Z24_UNORM:
return TRUE;
default:
break;
@@ -188,7 +189,8 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev)
nv50_transfer_init_screen_functions(pscreen);
/* DMA engine object */
- ret = nouveau_grobj_alloc(chan, 0xbeef5039, 0x5039, &screen->m2mf);
+ ret = nouveau_grobj_alloc(chan, 0xbeef5039,
+ NV50_MEMORY_TO_MEMORY_FORMAT, &screen->m2mf);
if (ret) {
NOUVEAU_ERR("Error creating M2MF object: %d\n", ret);
nv50_screen_destroy(pscreen);
@@ -197,7 +199,7 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev)
BIND_RING(chan, screen->m2mf, 1);
/* 2D object */
- ret = nouveau_grobj_alloc(chan, 0xbeef502d, 0x502d, &screen->eng2d);
+ ret = nouveau_grobj_alloc(chan, 0xbeef502d, NV50_2D, &screen->eng2d);
if (ret) {
NOUVEAU_ERR("Error creating 2D object: %d\n", ret);
nv50_screen_destroy(pscreen);
@@ -208,14 +210,15 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev)
/* 3D object */
switch (chipset & 0xf0) {
case 0x50:
- tesla_class = 0x5097;
+ tesla_class = NV50TCL;
break;
case 0x80:
case 0x90:
- tesla_class = 0x8297;
+ /* this stupid name should be corrected. */
+ tesla_class = NV54TCL;
break;
case 0xa0:
- tesla_class = 0x8397;
+ tesla_class = NVA0TCL;
break;
default:
NOUVEAU_ERR("Not a known NV50 chipset: NV%02x\n", chipset);
@@ -229,7 +232,8 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev)
return NULL;
}
- ret = nouveau_grobj_alloc(chan, 0xbeef5097, tesla_class, &screen->tesla);
+ ret = nouveau_grobj_alloc(chan, 0xbeef5097, tesla_class,
+ &screen->tesla);
if (ret) {
NOUVEAU_ERR("Error creating 3D object: %d\n", ret);
nv50_screen_destroy(pscreen);
@@ -247,7 +251,7 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev)
/* Static M2MF init */
so = so_new(32, 0);
- so_method(so, screen->m2mf, 0x0180, 3);
+ so_method(so, screen->m2mf, NV04_MEMORY_TO_MEMORY_FORMAT_DMA_NOTIFY, 3);
so_data (so, screen->sync->handle);
so_data (so, chan->vram->handle);
so_data (so, chan->vram->handle);
@@ -290,9 +294,10 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev)
so_method(so, screen->tesla, 0x13bc, 1);
so_data (so, 0x54);
+ /* origin is top left (set to 1 for bottom left) */
so_method(so, screen->tesla, 0x13ac, 1);
- so_data (so, 1);
- so_method(so, screen->tesla, 0x16b8, 1);
+ so_data (so, 0);
+ so_method(so, screen->tesla, NV50TCL_VP_REG_ALLOC_RESULT, 1);
so_data (so, 8);
/* constant buffers for immediates and VP/FP parameters */
@@ -330,33 +335,33 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev)
so_data (so, 0x000BBNP1);
*/
- so_method(so, screen->tesla, 0x1280, 3);
+ so_method(so, screen->tesla, NV50TCL_CB_DEF_ADDRESS_HIGH, 3);
so_reloc (so, screen->constbuf_misc[0], 0, NOUVEAU_BO_VRAM |
NOUVEAU_BO_RD | NOUVEAU_BO_HIGH, 0, 0);
so_reloc (so, screen->constbuf_misc[0], 0, NOUVEAU_BO_VRAM |
NOUVEAU_BO_RD | NOUVEAU_BO_LOW, 0, 0);
so_data (so, (NV50_CB_PMISC << 16) | 0x00000800);
- so_method(so, screen->tesla, 0x1694, 1);
+ so_method(so, screen->tesla, NV50TCL_SET_PROGRAM_CB, 1);
so_data (so, 0x00000001 | (NV50_CB_PMISC << 12));
- so_method(so, screen->tesla, 0x1694, 1);
+ so_method(so, screen->tesla, NV50TCL_SET_PROGRAM_CB, 1);
so_data (so, 0x00000031 | (NV50_CB_PMISC << 12));
- so_method(so, screen->tesla, 0x1280, 3);
+ so_method(so, screen->tesla, NV50TCL_CB_DEF_ADDRESS_HIGH, 3);
so_reloc (so, screen->constbuf_parm[0], 0, NOUVEAU_BO_VRAM |
NOUVEAU_BO_RD | NOUVEAU_BO_HIGH, 0, 0);
so_reloc (so, screen->constbuf_parm[0], 0, NOUVEAU_BO_VRAM |
NOUVEAU_BO_RD | NOUVEAU_BO_LOW, 0, 0);
so_data (so, (NV50_CB_PVP << 16) | 0x00000800);
- so_method(so, screen->tesla, 0x1694, 1);
+ so_method(so, screen->tesla, NV50TCL_SET_PROGRAM_CB, 1);
so_data (so, 0x00000101 | (NV50_CB_PVP << 12));
- so_method(so, screen->tesla, 0x1280, 3);
+ so_method(so, screen->tesla, NV50TCL_CB_DEF_ADDRESS_HIGH, 3);
so_reloc (so, screen->constbuf_parm[1], 0, NOUVEAU_BO_VRAM |
NOUVEAU_BO_RD | NOUVEAU_BO_HIGH, 0, 0);
so_reloc (so, screen->constbuf_parm[1], 0, NOUVEAU_BO_VRAM |
NOUVEAU_BO_RD | NOUVEAU_BO_LOW, 0, 0);
so_data (so, (NV50_CB_PFP << 16) | 0x00000800);
- so_method(so, screen->tesla, 0x1694, 1);
+ so_method(so, screen->tesla, NV50TCL_SET_PROGRAM_CB, 1);
so_data (so, 0x00000131 | (NV50_CB_PFP << 12));
/* Texture sampler/image unit setup - we abuse the constant buffer
@@ -370,13 +375,13 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev)
return NULL;
}
- so_method(so, screen->tesla, 0x1280, 3);
+ so_method(so, screen->tesla, NV50TCL_CB_DEF_ADDRESS_HIGH, 3);
so_reloc (so, screen->tic, 0, NOUVEAU_BO_VRAM |
NOUVEAU_BO_RD | NOUVEAU_BO_HIGH, 0, 0);
so_reloc (so, screen->tic, 0, NOUVEAU_BO_VRAM |
NOUVEAU_BO_RD | NOUVEAU_BO_LOW, 0, 0);
so_data (so, (NV50_CB_TIC << 16) | 0x0800);
- so_method(so, screen->tesla, 0x1574, 3);
+ so_method(so, screen->tesla, NV50TCL_TIC_ADDRESS_HIGH, 3);
so_reloc (so, screen->tic, 0, NOUVEAU_BO_VRAM |
NOUVEAU_BO_RD | NOUVEAU_BO_HIGH, 0, 0);
so_reloc (so, screen->tic, 0, NOUVEAU_BO_VRAM |
@@ -389,13 +394,13 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev)
return NULL;
}
- so_method(so, screen->tesla, 0x1280, 3);
+ so_method(so, screen->tesla, NV50TCL_CB_DEF_ADDRESS_HIGH, 3);
so_reloc (so, screen->tsc, 0, NOUVEAU_BO_VRAM |
NOUVEAU_BO_RD | NOUVEAU_BO_HIGH, 0, 0);
so_reloc (so, screen->tsc, 0, NOUVEAU_BO_VRAM |
NOUVEAU_BO_RD | NOUVEAU_BO_LOW, 0, 0);
so_data (so, (NV50_CB_TSC << 16) | 0x0800);
- so_method(so, screen->tesla, 0x155c, 3);
+ so_method(so, screen->tesla, NV50TCL_TSC_ADDRESS_HIGH, 3);
so_reloc (so, screen->tsc, 0, NOUVEAU_BO_VRAM |
NOUVEAU_BO_RD | NOUVEAU_BO_HIGH, 0, 0);
so_reloc (so, screen->tsc, 0, NOUVEAU_BO_VRAM |
@@ -405,7 +410,7 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev)
/* Vertex array limits - max them out */
for (i = 0; i < 16; i++) {
- so_method(so, screen->tesla, 0x1080 + (i * 8), 2);
+ so_method(so, screen->tesla, NV50TCL_UNK1080_OFFSET_HIGH(i), 2);
so_data (so, 0x000000ff);
so_data (so, 0xffffffff);
}
@@ -417,6 +422,10 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev)
so_method(so, screen->tesla, 0x1234, 1);
so_data (so, 1);
+ /* activate first scissor rectangle */
+ so_method(so, screen->tesla, NV50TCL_SCISSOR_ENABLE, 1);
+ so_data (so, 1);
+
so_emit(chan, so);
so_ref (so, &screen->static_init);
so_ref (NULL, &so);
diff --git a/src/gallium/drivers/nv50/nv50_state.c b/src/gallium/drivers/nv50/nv50_state.c
index 116866a8e78..ef4154d3036 100644
--- a/src/gallium/drivers/nv50/nv50_state.c
+++ b/src/gallium/drivers/nv50/nv50_state.c
@@ -205,11 +205,16 @@ nv50_sampler_state_create(struct pipe_context *pipe,
}
limit = CLAMP(cso->lod_bias, -16.0, 15.0);
- tsc[1] |= ((int)(limit * 256.0) & 0x1fff) << 11;
+ tsc[1] |= ((int)(limit * 256.0) & 0x1fff) << 12;
tsc[2] |= ((int)CLAMP(cso->max_lod, 0.0, 15.0) << 20) |
((int)CLAMP(cso->min_lod, 0.0, 15.0) << 8);
+ tsc[4] = fui(cso->border_color[0]);
+ tsc[5] = fui(cso->border_color[1]);
+ tsc[6] = fui(cso->border_color[2]);
+ tsc[7] = fui(cso->border_color[3]);
+
sso->normalized = cso->normalized_coords;
return (void *)sso;
}
@@ -404,35 +409,35 @@ nv50_depth_stencil_alpha_state_create(struct pipe_context *pipe,
so_data (so, 0);
}
- /*XXX: yes, I know they're backwards.. header needs fixing */
+ /* XXX: keep hex values until header is updated (names reversed) */
if (cso->stencil[0].enabled) {
- so_method(so, tesla, NV50TCL_STENCIL_BACK_ENABLE, 5);
+ so_method(so, tesla, 0x1380, 8);
so_data (so, 1);
so_data (so, nvgl_stencil_op(cso->stencil[0].fail_op));
so_data (so, nvgl_stencil_op(cso->stencil[0].zfail_op));
so_data (so, nvgl_stencil_op(cso->stencil[0].zpass_op));
so_data (so, nvgl_comparison_op(cso->stencil[0].func));
- so_method(so, tesla, NV50TCL_STENCIL_BACK_FUNC_REF, 3);
so_data (so, cso->stencil[0].ref_value);
so_data (so, cso->stencil[0].writemask);
so_data (so, cso->stencil[0].valuemask);
} else {
- so_method(so, tesla, NV50TCL_STENCIL_BACK_ENABLE, 1);
+ so_method(so, tesla, 0x1380, 1);
so_data (so, 0);
}
if (cso->stencil[1].enabled) {
- so_method(so, tesla, NV50TCL_STENCIL_FRONT_ENABLE, 8);
+ so_method(so, tesla, 0x1594, 5);
so_data (so, 1);
so_data (so, nvgl_stencil_op(cso->stencil[1].fail_op));
so_data (so, nvgl_stencil_op(cso->stencil[1].zfail_op));
so_data (so, nvgl_stencil_op(cso->stencil[1].zpass_op));
so_data (so, nvgl_comparison_op(cso->stencil[1].func));
+ so_method(so, tesla, 0x0f54, 3);
so_data (so, cso->stencil[1].ref_value);
so_data (so, cso->stencil[1].writemask);
so_data (so, cso->stencil[1].valuemask);
} else {
- so_method(so, tesla, NV50TCL_STENCIL_FRONT_ENABLE, 1);
+ so_method(so, tesla, 0x1594, 1);
so_data (so, 0);
}
diff --git a/src/gallium/drivers/nv50/nv50_state_validate.c b/src/gallium/drivers/nv50/nv50_state_validate.c
index d313e9de4fe..a879df2e6e2 100644
--- a/src/gallium/drivers/nv50/nv50_state_validate.c
+++ b/src/gallium/drivers/nv50/nv50_state_validate.c
@@ -55,15 +55,15 @@ nv50_state_validate_fb(struct nv50_context *nv50)
NOUVEAU_BO_LOW | NOUVEAU_BO_RDWR, 0, 0);
switch (fb->cbufs[i]->format) {
case PIPE_FORMAT_A8R8G8B8_UNORM:
- so_data(so, 0xcf);
+ so_data(so, NV50TCL_RT_FORMAT_A8R8G8B8_UNORM);
break;
case PIPE_FORMAT_R5G6B5_UNORM:
- so_data(so, 0xe8);
+ so_data(so, NV50TCL_RT_FORMAT_R5G6B5_UNORM);
break;
default:
NOUVEAU_ERR("AIIII unknown format %s\n",
pf_name(fb->cbufs[i]->format));
- so_data(so, 0xe6);
+ so_data(so, NV50TCL_RT_FORMAT_X8R8G8B8_UNORM);
break;
}
so_data(so, bo->tile_mode << 4);
@@ -92,17 +92,22 @@ nv50_state_validate_fb(struct nv50_context *nv50)
so_reloc (so, bo, fb->zsbuf->offset, NOUVEAU_BO_VRAM |
NOUVEAU_BO_LOW | NOUVEAU_BO_RDWR, 0, 0);
switch (fb->zsbuf->format) {
+ case PIPE_FORMAT_Z32_FLOAT:
+ so_data(so, NV50TCL_ZETA_FORMAT_Z32_FLOAT);
+ break;
case PIPE_FORMAT_Z24S8_UNORM:
- case PIPE_FORMAT_Z24X8_UNORM:
- so_data(so, 0x16);
+ so_data(so, NV50TCL_ZETA_FORMAT_Z24S8_UNORM);
+ break;
+ case PIPE_FORMAT_X8Z24_UNORM:
+ so_data(so, NV50TCL_ZETA_FORMAT_X8Z24_UNORM);
break;
- case PIPE_FORMAT_Z16_UNORM:
- so_data(so, 0x15);
+ case PIPE_FORMAT_S8Z24_UNORM:
+ so_data(so, NV50TCL_ZETA_FORMAT_S8Z24_UNORM);
break;
default:
NOUVEAU_ERR("AIIII unknown format %s\n",
pf_name(fb->zsbuf->format));
- so_data(so, 0x16);
+ so_data(so, NV50TCL_ZETA_FORMAT_S8Z24_UNORM);
break;
}
so_data(so, bo->tile_mode << 4);
@@ -110,7 +115,7 @@ nv50_state_validate_fb(struct nv50_context *nv50)
so_method(so, tesla, 0x1538, 1);
so_data (so, 1);
- so_method(so, tesla, 0x1228, 3);
+ so_method(so, tesla, NV50TCL_ZETA_HORIZ, 3);
so_data (so, fb->zsbuf->width);
so_data (so, fb->zsbuf->height);
so_data (so, 0x00010001);
@@ -119,12 +124,18 @@ nv50_state_validate_fb(struct nv50_context *nv50)
so_method(so, tesla, NV50TCL_VIEWPORT_HORIZ, 2);
so_data (so, w << 16);
so_data (so, h << 16);
- so_method(so, tesla, 0x0e04, 2);
+ /* set window lower left corner */
+ so_method(so, tesla, NV50TCL_WINDOW_LEFT, 2);
+ so_data (so, 0);
+ so_data (so, 0);
+ /* set screen scissor rectangle */
+ so_method(so, tesla, NV50TCL_SCREEN_SCISSOR_HORIZ, 2);
so_data (so, w << 16);
so_data (so, h << 16);
- so_method(so, tesla, 0xdf8, 2);
- so_data (so, 0);
- so_data (so, h);
+
+ /* we set scissors to framebuffer size when they're 'turned off' */
+ nv50->dirty |= NV50_NEW_SCISSOR;
+ so_ref(NULL, &nv50->state.scissor);
so_ref(so, &nv50->state.fb);
so_ref(NULL, &so);
@@ -137,7 +148,32 @@ nv50_state_emit(struct nv50_context *nv50)
struct nouveau_channel *chan = screen->base.channel;
if (nv50->pctx_id != screen->cur_pctx) {
- nv50->state.dirty |= 0xffffffff;
+ if (nv50->state.fb)
+ nv50->state.dirty |= NV50_NEW_FRAMEBUFFER;
+ if (nv50->state.blend)
+ nv50->state.dirty |= NV50_NEW_BLEND;
+ if (nv50->state.zsa)
+ nv50->state.dirty |= NV50_NEW_ZSA;
+ if (nv50->state.vertprog)
+ nv50->state.dirty |= NV50_NEW_VERTPROG;
+ if (nv50->state.fragprog)
+ nv50->state.dirty |= NV50_NEW_FRAGPROG;
+ if (nv50->state.rast)
+ nv50->state.dirty |= NV50_NEW_RASTERIZER;
+ if (nv50->state.blend_colour)
+ nv50->state.dirty |= NV50_NEW_BLEND_COLOUR;
+ if (nv50->state.stipple)
+ nv50->state.dirty |= NV50_NEW_STIPPLE;
+ if (nv50->state.scissor)
+ nv50->state.dirty |= NV50_NEW_SCISSOR;
+ if (nv50->state.viewport)
+ nv50->state.dirty |= NV50_NEW_VIEWPORT;
+ if (nv50->state.tsc_upload)
+ nv50->state.dirty |= NV50_NEW_SAMPLER;
+ if (nv50->state.tic_upload)
+ nv50->state.dirty |= NV50_NEW_TEXTURE;
+ if (nv50->state.vtxfmt && nv50->state.vtxbuf)
+ nv50->state.dirty |= NV50_NEW_ARRAYS;
screen->cur_pctx = nv50->pctx_id;
}
@@ -233,13 +269,13 @@ nv50_state_validate(struct nv50_context *nv50)
nv50->state.scissor_enabled = rast->scissor;
so = so_new(3, 0);
- so_method(so, tesla, 0x0ff4, 2);
+ so_method(so, tesla, NV50TCL_SCISSOR_HORIZ, 2);
if (nv50->state.scissor_enabled) {
- so_data(so, ((s->maxx - s->minx) << 16) | s->minx);
- so_data(so, ((s->maxy - s->miny) << 16) | s->miny);
+ so_data(so, (s->maxx << 16) | s->minx);
+ so_data(so, (s->maxy << 16) | s->miny);
} else {
- so_data(so, (8192 << 16));
- so_data(so, (8192 << 16));
+ so_data(so, (nv50->framebuffer.width << 16));
+ so_data(so, (nv50->framebuffer.height << 16));
}
so_ref(so, &nv50->state.scissor);
so_ref(NULL, &so);
@@ -263,20 +299,22 @@ scissor_uptodate:
so = so_new(12, 0);
if (!bypass) {
- so_method(so, tesla, NV50TCL_VIEWPORT_UNK1(0), 3);
+ so_method(so, tesla, NV50TCL_VIEWPORT_TRANSLATE(0), 3);
so_data (so, fui(nv50->viewport.translate[0]));
so_data (so, fui(nv50->viewport.translate[1]));
so_data (so, fui(nv50->viewport.translate[2]));
- so_method(so, tesla, NV50TCL_VIEWPORT_UNK0(0), 3);
+ so_method(so, tesla, NV50TCL_VIEWPORT_SCALE(0), 3);
so_data (so, fui(nv50->viewport.scale[0]));
- so_data (so, fui(-nv50->viewport.scale[1]));
+ so_data (so, fui(nv50->viewport.scale[1]));
so_data (so, fui(nv50->viewport.scale[2]));
- so_method(so, tesla, 0x192c, 1);
+
+ so_method(so, tesla, NV50TCL_VIEWPORT_TRANSFORM_EN, 1);
so_data (so, 1);
+ /* no idea what 0f90 does */
so_method(so, tesla, 0x0f90, 1);
so_data (so, 0);
} else {
- so_method(so, tesla, 0x192c, 1);
+ so_method(so, tesla, NV50TCL_VIEWPORT_TRANSFORM_EN, 1);
so_data (so, 0);
so_method(so, tesla, 0x0f90, 1);
so_data (so, 1);
@@ -292,9 +330,10 @@ viewport_uptodate:
int i;
so = so_new(nv50->sampler_nr * 8 + 3, 0);
- so_method(so, tesla, 0x0f00, 1);
+ so_method(so, tesla, NV50TCL_CB_ADDR, 1);
so_data (so, NV50_CB_TSC);
- so_method(so, tesla, 0x40000f04, nv50->sampler_nr * 8);
+ so_method(so, tesla, NV50TCL_CB_DATA(0) | 0x40000000,
+ nv50->sampler_nr * 8);
for (i = 0; i < nv50->sampler_nr; i++)
so_datap (so, nv50->sampler[i]->tsc, 8);
so_ref(so, &nv50->state.tsc_upload);
diff --git a/src/gallium/drivers/nv50/nv50_surface.c b/src/gallium/drivers/nv50/nv50_surface.c
index 3da9d6e7285..edaf4b055a1 100644
--- a/src/gallium/drivers/nv50/nv50_surface.c
+++ b/src/gallium/drivers/nv50/nv50_surface.c
@@ -35,13 +35,13 @@ nv50_format(enum pipe_format format)
{
switch (format) {
case PIPE_FORMAT_A8R8G8B8_UNORM:
- return NV50_2D_DST_FORMAT_32BPP;
+ return NV50_2D_DST_FORMAT_A8R8G8B8_UNORM;
case PIPE_FORMAT_X8R8G8B8_UNORM:
- return NV50_2D_DST_FORMAT_24BPP;
+ return NV50_2D_DST_FORMAT_X8R8G8B8_UNORM;
case PIPE_FORMAT_R5G6B5_UNORM:
- return NV50_2D_DST_FORMAT_16BPP;
+ return NV50_2D_DST_FORMAT_R5G6B5_UNORM;
case PIPE_FORMAT_A8_UNORM:
- return NV50_2D_DST_FORMAT_8BPP;
+ return NV50_2D_DST_FORMAT_R8_UNORM;
default:
return -1;
}
@@ -144,7 +144,7 @@ nv50_surface_copy(struct pipe_context *pipe,
struct pipe_surface *src, unsigned srcx, unsigned srcy,
unsigned width, unsigned height)
{
- struct nv50_context *nv50 = (struct nv50_context *)pipe;
+ struct nv50_context *nv50 = nv50_context(pipe);
struct nv50_screen *screen = nv50->screen;
assert(src->format == dest->format);
@@ -158,7 +158,7 @@ nv50_surface_fill(struct pipe_context *pipe, struct pipe_surface *dest,
unsigned destx, unsigned desty, unsigned width,
unsigned height, unsigned value)
{
- struct nv50_context *nv50 = (struct nv50_context *)pipe;
+ struct nv50_context *nv50 = nv50_context(pipe);
struct nv50_screen *screen = nv50->screen;
struct nouveau_channel *chan = screen->eng2d->channel;
struct nouveau_grobj *eng2d = screen->eng2d;
diff --git a/src/gallium/drivers/nv50/nv50_tex.c b/src/gallium/drivers/nv50/nv50_tex.c
index ff40c2ad81b..14c68b96e14 100644
--- a/src/gallium/drivers/nv50/nv50_tex.c
+++ b/src/gallium/drivers/nv50/nv50_tex.c
@@ -32,30 +32,30 @@ nv50_tex_construct(struct nv50_context *nv50, struct nouveau_stateobj *so,
switch (mt->base.format) {
case PIPE_FORMAT_A8R8G8B8_UNORM:
so_data(so, NV50TIC_0_0_MAPA_C3 | NV50TIC_0_0_TYPEA_UNORM |
- NV50TIC_0_0_MAPR_C0 | NV50TIC_0_0_TYPER_UNORM |
+ NV50TIC_0_0_MAPR_C2 | NV50TIC_0_0_TYPER_UNORM |
NV50TIC_0_0_MAPG_C1 | NV50TIC_0_0_TYPEG_UNORM |
- NV50TIC_0_0_MAPB_C2 | NV50TIC_0_0_TYPEB_UNORM |
+ NV50TIC_0_0_MAPB_C0 | NV50TIC_0_0_TYPEB_UNORM |
NV50TIC_0_0_FMT_8_8_8_8);
break;
case PIPE_FORMAT_A1R5G5B5_UNORM:
so_data(so, NV50TIC_0_0_MAPA_C3 | NV50TIC_0_0_TYPEA_UNORM |
- NV50TIC_0_0_MAPR_C0 | NV50TIC_0_0_TYPER_UNORM |
+ NV50TIC_0_0_MAPR_C2 | NV50TIC_0_0_TYPER_UNORM |
NV50TIC_0_0_MAPG_C1 | NV50TIC_0_0_TYPEG_UNORM |
- NV50TIC_0_0_MAPB_C2 | NV50TIC_0_0_TYPEB_UNORM |
+ NV50TIC_0_0_MAPB_C0 | NV50TIC_0_0_TYPEB_UNORM |
NV50TIC_0_0_FMT_1_5_5_5);
break;
case PIPE_FORMAT_A4R4G4B4_UNORM:
so_data(so, NV50TIC_0_0_MAPA_C3 | NV50TIC_0_0_TYPEA_UNORM |
- NV50TIC_0_0_MAPR_C0 | NV50TIC_0_0_TYPER_UNORM |
+ NV50TIC_0_0_MAPR_C2 | NV50TIC_0_0_TYPER_UNORM |
NV50TIC_0_0_MAPG_C1 | NV50TIC_0_0_TYPEG_UNORM |
- NV50TIC_0_0_MAPB_C2 | NV50TIC_0_0_TYPEB_UNORM |
+ NV50TIC_0_0_MAPB_C0 | NV50TIC_0_0_TYPEB_UNORM |
NV50TIC_0_0_FMT_4_4_4_4);
break;
case PIPE_FORMAT_R5G6B5_UNORM:
so_data(so, NV50TIC_0_0_MAPA_ONE | NV50TIC_0_0_TYPEA_UNORM |
- NV50TIC_0_0_MAPR_C0 | NV50TIC_0_0_TYPER_UNORM |
+ NV50TIC_0_0_MAPR_C2 | NV50TIC_0_0_TYPER_UNORM |
NV50TIC_0_0_MAPG_C1 | NV50TIC_0_0_TYPEG_UNORM |
- NV50TIC_0_0_MAPB_C2 | NV50TIC_0_0_TYPEB_UNORM |
+ NV50TIC_0_0_MAPB_C0 | NV50TIC_0_0_TYPEB_UNORM |
NV50TIC_0_0_FMT_5_6_5);
break;
case PIPE_FORMAT_L8_UNORM:
@@ -145,25 +145,28 @@ nv50_tex_validate(struct nv50_context *nv50)
push += MAX2(nv50->miptree_nr, nv50->state.miptree_nr) * 2;
so = so_new(push, nv50->miptree_nr * 2);
- so_method(so, tesla, 0x0f00, 1);
+ so_method(so, tesla, NV50TCL_CB_ADDR, 1);
so_data (so, NV50_CB_TIC);
for (unit = 0; unit < nv50->miptree_nr; unit++) {
struct nv50_miptree *mt = nv50->miptree[unit];
- so_method(so, tesla, 0x40000f04, 8);
+ so_method(so, tesla, NV50TCL_CB_DATA(0) | 0x40000000, 8);
if (nv50_tex_construct(nv50, so, mt, unit)) {
NOUVEAU_ERR("failed tex validate\n");
so_ref(NULL, &so);
return;
}
- so_method(so, tesla, 0x1458, 1);
- so_data (so, (unit << 9) | (unit << 1) | 1);
+ so_method(so, tesla, NV50TCL_SET_SAMPLER_TEX, 1);
+ so_data (so, (unit << NV50TCL_SET_SAMPLER_TEX_TIC_SHIFT) |
+ (unit << NV50TCL_SET_SAMPLER_TEX_SAMPLER_SHIFT) |
+ NV50TCL_SET_SAMPLER_TEX_VALID);
}
for (; unit < nv50->state.miptree_nr; unit++) {
- so_method(so, tesla, 0x1458, 1);
- so_data (so, (unit << 1) | 0);
+ so_method(so, tesla, NV50TCL_SET_SAMPLER_TEX, 1);
+ so_data (so,
+ (unit << NV50TCL_SET_SAMPLER_TEX_SAMPLER_SHIFT) | 0);
}
so_ref(so, &nv50->state.tic_upload);
diff --git a/src/gallium/drivers/nv50/nv50_texture.h b/src/gallium/drivers/nv50/nv50_texture.h
index aca622c73b1..207fb039f70 100644
--- a/src/gallium/drivers/nv50/nv50_texture.h
+++ b/src/gallium/drivers/nv50/nv50_texture.h
@@ -14,13 +14,13 @@
#define NV50TIC_0_0_MAPA_C2 0x20000000
#define NV50TIC_0_0_MAPA_C3 0x28000000
#define NV50TIC_0_0_MAPA_ONE 0x38000000
-#define NV50TIC_0_0_MAPR_MASK 0x07000000
-#define NV50TIC_0_0_MAPR_ZERO 0x00000000
-#define NV50TIC_0_0_MAPR_C0 0x02000000
-#define NV50TIC_0_0_MAPR_C1 0x03000000
-#define NV50TIC_0_0_MAPR_C2 0x04000000
-#define NV50TIC_0_0_MAPR_C3 0x05000000
-#define NV50TIC_0_0_MAPR_ONE 0x07000000
+#define NV50TIC_0_0_MAPB_MASK 0x07000000
+#define NV50TIC_0_0_MAPB_ZERO 0x00000000
+#define NV50TIC_0_0_MAPB_C0 0x02000000
+#define NV50TIC_0_0_MAPB_C1 0x03000000
+#define NV50TIC_0_0_MAPB_C2 0x04000000
+#define NV50TIC_0_0_MAPB_C3 0x05000000
+#define NV50TIC_0_0_MAPB_ONE 0x07000000
#define NV50TIC_0_0_MAPG_MASK 0x00e00000
#define NV50TIC_0_0_MAPG_ZERO 0x00000000
#define NV50TIC_0_0_MAPG_C0 0x00400000
@@ -28,31 +28,49 @@
#define NV50TIC_0_0_MAPG_C2 0x00800000
#define NV50TIC_0_0_MAPG_C3 0x00a00000
#define NV50TIC_0_0_MAPG_ONE 0x00e00000
-#define NV50TIC_0_0_MAPB_MASK 0x001c0000
-#define NV50TIC_0_0_MAPB_ZERO 0x00000000
-#define NV50TIC_0_0_MAPB_C0 0x00080000
-#define NV50TIC_0_0_MAPB_C1 0x000c0000
-#define NV50TIC_0_0_MAPB_C2 0x00100000
-#define NV50TIC_0_0_MAPB_C3 0x00140000
-#define NV50TIC_0_0_MAPB_ONE 0x001c0000
+#define NV50TIC_0_0_MAPR_MASK 0x001c0000
+#define NV50TIC_0_0_MAPR_ZERO 0x00000000
+#define NV50TIC_0_0_MAPR_C0 0x00080000
+#define NV50TIC_0_0_MAPR_C1 0x000c0000
+#define NV50TIC_0_0_MAPR_C2 0x00100000
+#define NV50TIC_0_0_MAPR_C3 0x00140000
+#define NV50TIC_0_0_MAPR_ONE 0x001c0000
#define NV50TIC_0_0_TYPEA_MASK 0x00038000
#define NV50TIC_0_0_TYPEA_UNORM 0x00010000
-#define NV50TIC_0_0_TYPER_MASK 0x00007000
-#define NV50TIC_0_0_TYPER_UNORM 0x00002000
+#define NV50TIC_0_0_TYPEA_SNORM 0x00008000
+#define NV50TIC_0_0_TYPEA_FLOAT 0x00038000
+#define NV50TIC_0_0_TYPEB_MASK 0x00007000
+#define NV50TIC_0_0_TYPEB_UNORM 0x00002000
+#define NV50TIC_0_0_TYPEB_SNORM 0x00001000
+#define NV50TIC_0_0_TYPEB_FLOAT 0x00007000
#define NV50TIC_0_0_TYPEG_MASK 0x00000e00
#define NV50TIC_0_0_TYPEG_UNORM 0x00000400
-#define NV50TIC_0_0_TYPEB_MASK 0x000001c0
-#define NV50TIC_0_0_TYPEB_UNORM 0x00000080
-#define NV50TIC_0_0_FMT_MASK 0x0000003c
+#define NV50TIC_0_0_TYPEG_SNORM 0x00000200
+#define NV50TIC_0_0_TYPEG_FLOAT 0x00000e00
+#define NV50TIC_0_0_TYPER_MASK 0x000001c0
+#define NV50TIC_0_0_TYPER_UNORM 0x00000080
+#define NV50TIC_0_0_TYPER_SNORM 0x00000040
+#define NV50TIC_0_0_TYPER_FLOAT 0x000001c0
+#define NV50TIC_0_0_FMT_MASK 0x0000003f
+#define NV50TIC_0_0_FMT_32_32_32_32 0x00000001
+#define NV50TIC_0_0_FMT_16_16_16_16 0x00000003
+#define NV50TIC_0_0_FMT_32_32 0x00000004
#define NV50TIC_0_0_FMT_8_8_8_8 0x00000008
+#define NV50TIC_0_0_FMT_2_10_10_10 0x00000009
+#define NV50TIC_0_0_FMT_32 0x0000000f
#define NV50TIC_0_0_FMT_4_4_4_4 0x00000012
-#define NV50TIC_0_0_FMT_1_5_5_5 0x00000013
+/* #define NV50TIC_0_0_FMT_1_5_5_5 0x00000013 */
+#define NV50TIC_0_0_FMT_1_5_5_5 0x00000014
#define NV50TIC_0_0_FMT_5_6_5 0x00000015
#define NV50TIC_0_0_FMT_8_8 0x00000018
+#define NV50TIC_0_0_FMT_16 0x0000001b
#define NV50TIC_0_0_FMT_8 0x0000001d
+#define NV50TIC_0_0_FMT_10_11_11 0x00000021
#define NV50TIC_0_0_FMT_DXT1 0x00000024
#define NV50TIC_0_0_FMT_DXT3 0x00000025
#define NV50TIC_0_0_FMT_DXT5 0x00000026
+#define NV50TIC_0_0_FMT_RGTC1 0x00000027
+#define NV50TIC_0_0_FMT_RGTC2 0x00000028
#define NV50TIC_0_1_OFFSET_LOW_MASK 0xffffffff
#define NV50TIC_0_1_OFFSET_LOW_SHIFT 0
@@ -102,6 +120,7 @@
#define NV50TSC_1_0_WRAPR_MIRROR_CLAMP_TO_EDGE 0x00000140
#define NV50TSC_1_0_WRAPR_MIRROR_CLAMP_TO_BORDER 0x00000180
#define NV50TSC_1_0_WRAPR_MIRROR_CLAMP 0x000001c0
+#define NV50TSC_1_0_MAX_ANISOTROPY_MASK 0x00700000
#define NV50TSC_1_1_MAGF_MASK 0x00000003
#define NV50TSC_1_1_MAGF_NEAREST 0x00000001
@@ -113,17 +132,19 @@
#define NV50TSC_1_1_MIPF_NONE 0x00000040
#define NV50TSC_1_1_MIPF_NEAREST 0x00000080
#define NV50TSC_1_1_MIPF_LINEAR 0x000000c0
+#define NV50TSC_1_1_LOD_BIAS_MASK 0x01fff000
-#define NV50TSC_1_2_UNKNOWN_MASK 0xffffffff
+#define NV50TSC_1_2_MIN_LOD_MASK 0x00000f00
+#define NV50TSC_1_2_MAX_LOD_MASK 0x00f00000
#define NV50TSC_1_3_UNKNOWN_MASK 0xffffffff
-#define NV50TSC_1_4_UNKNOWN_MASK 0xffffffff
+#define NV50TSC_1_4_BORDER_COLOR_RED_MASK 0xffffffff
-#define NV50TSC_1_5_UNKNOWN_MASK 0xffffffff
+#define NV50TSC_1_5_BORDER_COLOR_GREEN_MASK 0xffffffff
-#define NV50TSC_1_6_UNKNOWN_MASK 0xffffffff
+#define NV50TSC_1_6_BORDER_COLOR_BLUE_MASK 0xffffffff
-#define NV50TSC_1_7_UNKNOWN_MASK 0xffffffff
+#define NV50TSC_1_7_BORDER_COLOR_ALPHA_MASK 0xffffffff
#endif
diff --git a/src/gallium/drivers/nv50/nv50_transfer.c b/src/gallium/drivers/nv50/nv50_transfer.c
index d0b7f0bef43..d2b5e4d75d4 100644
--- a/src/gallium/drivers/nv50/nv50_transfer.c
+++ b/src/gallium/drivers/nv50/nv50_transfer.c
@@ -8,6 +8,7 @@ struct nv50_transfer {
struct pipe_transfer base;
struct nouveau_bo *bo;
unsigned level_offset;
+ unsigned level_tiling;
int level_pitch;
int level_width;
int level_height;
@@ -16,11 +17,14 @@ struct nv50_transfer {
};
static void
-nv50_transfer_rect_m2mf(struct pipe_screen *pscreen, struct nouveau_bo *src_bo,
- unsigned src_offset, int src_pitch, int sx, int sy,
- int sw, int sh, struct nouveau_bo *dst_bo,
- unsigned dst_offset, int dst_pitch, int dx, int dy,
- int dw, int dh, int cpp, int width, int height,
+nv50_transfer_rect_m2mf(struct pipe_screen *pscreen,
+ struct nouveau_bo *src_bo, unsigned src_offset,
+ int src_pitch, unsigned src_tile_mode,
+ int sx, int sy, int sw, int sh,
+ struct nouveau_bo *dst_bo, unsigned dst_offset,
+ int dst_pitch, unsigned dst_tile_mode,
+ int dx, int dy, int dw, int dh,
+ int cpp, int width, int height,
unsigned src_reloc, unsigned dst_reloc)
{
struct nv50_screen *screen = nv50_screen(pscreen);
@@ -33,15 +37,18 @@ nv50_transfer_rect_m2mf(struct pipe_screen *pscreen, struct nouveau_bo *src_bo,
WAIT_RING (chan, 14);
if (!src_bo->tile_flags) {
- BEGIN_RING(chan, m2mf, 0x0200, 1);
+ BEGIN_RING(chan, m2mf,
+ NV50_MEMORY_TO_MEMORY_FORMAT_LINEAR_IN, 1);
OUT_RING (chan, 1);
- BEGIN_RING(chan, m2mf, 0x0314, 1);
+ BEGIN_RING(chan, m2mf,
+ NV50_MEMORY_TO_MEMORY_FORMAT_PITCH_IN, 1);
OUT_RING (chan, src_pitch);
src_offset += (sy * src_pitch) + (sx * cpp);
} else {
- BEGIN_RING(chan, m2mf, 0x0200, 6);
+ BEGIN_RING(chan, m2mf,
+ NV50_MEMORY_TO_MEMORY_FORMAT_LINEAR_IN, 6);
OUT_RING (chan, 0);
- OUT_RING (chan, src_bo->tile_mode << 4);
+ OUT_RING (chan, src_tile_mode << 4);
OUT_RING (chan, sw * cpp);
OUT_RING (chan, sh);
OUT_RING (chan, 1);
@@ -49,15 +56,18 @@ nv50_transfer_rect_m2mf(struct pipe_screen *pscreen, struct nouveau_bo *src_bo,
}
if (!dst_bo->tile_flags) {
- BEGIN_RING(chan, m2mf, 0x021c, 1);
+ BEGIN_RING(chan, m2mf,
+ NV50_MEMORY_TO_MEMORY_FORMAT_LINEAR_OUT, 1);
OUT_RING (chan, 1);
- BEGIN_RING(chan, m2mf, 0x0318, 1);
+ BEGIN_RING(chan, m2mf,
+ NV50_MEMORY_TO_MEMORY_FORMAT_PITCH_OUT, 1);
OUT_RING (chan, dst_pitch);
dst_offset += (dy * dst_pitch) + (dx * cpp);
} else {
- BEGIN_RING(chan, m2mf, 0x021c, 6);
+ BEGIN_RING(chan, m2mf,
+ NV50_MEMORY_TO_MEMORY_FORMAT_LINEAR_OUT, 6);
OUT_RING (chan, 0);
- OUT_RING (chan, dst_bo->tile_mode << 4);
+ OUT_RING (chan, dst_tile_mode << 4);
OUT_RING (chan, dw * cpp);
OUT_RING (chan, dh);
OUT_RING (chan, 1);
@@ -68,25 +78,30 @@ nv50_transfer_rect_m2mf(struct pipe_screen *pscreen, struct nouveau_bo *src_bo,
int line_count = height > 2047 ? 2047 : height;
WAIT_RING (chan, 15);
- BEGIN_RING(chan, m2mf, 0x0238, 2);
+ BEGIN_RING(chan, m2mf,
+ NV50_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN_HIGH, 2);
OUT_RELOCh(chan, src_bo, src_offset, src_reloc);
OUT_RELOCh(chan, dst_bo, dst_offset, dst_reloc);
- BEGIN_RING(chan, m2mf, 0x030c, 2);
+ BEGIN_RING(chan, m2mf,
+ NV50_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN, 2);
OUT_RELOCl(chan, src_bo, src_offset, src_reloc);
OUT_RELOCl(chan, dst_bo, dst_offset, dst_reloc);
if (src_bo->tile_flags) {
- BEGIN_RING(chan, m2mf, 0x0218, 1);
- OUT_RING (chan, (dy << 16) | sx);
+ BEGIN_RING(chan, m2mf,
+ NV50_MEMORY_TO_MEMORY_FORMAT_TILING_POSITION_IN, 1);
+ OUT_RING (chan, (sy << 16) | sx);
} else {
src_offset += (line_count * src_pitch);
}
if (dst_bo->tile_flags) {
- BEGIN_RING(chan, m2mf, 0x0234, 1);
- OUT_RING (chan, (sy << 16) | dx);
+ BEGIN_RING(chan, m2mf,
+ NV50_MEMORY_TO_MEMORY_FORMAT_TILING_POSITION_OUT, 1);
+ OUT_RING (chan, (dy << 16) | dx);
} else {
dst_offset += (line_count * dst_pitch);
}
- BEGIN_RING(chan, m2mf, 0x031c, 4);
+ BEGIN_RING(chan, m2mf,
+ NV50_MEMORY_TO_MEMORY_FORMAT_LINE_LENGTH_IN, 4);
OUT_RING (chan, width * cpp);
OUT_RING (chan, line_count);
OUT_RING (chan, 0x00000101);
@@ -136,6 +151,7 @@ nv50_transfer_new(struct pipe_screen *pscreen, struct pipe_texture *pt,
tx->level_width = mt->base.width[level];
tx->level_height = mt->base.height[level];
tx->level_offset = lvl->image_offset[image];
+ tx->level_tiling = lvl->tile_mode;
tx->level_x = x;
tx->level_y = y;
ret = nouveau_bo_new(dev, NOUVEAU_BO_GART | NOUVEAU_BO_MAP, 0,
@@ -147,9 +163,11 @@ nv50_transfer_new(struct pipe_screen *pscreen, struct pipe_texture *pt,
if (usage != PIPE_TRANSFER_WRITE) {
nv50_transfer_rect_m2mf(pscreen, mt->bo, tx->level_offset,
- tx->level_pitch, x, y, tx->level_width,
- tx->level_height, tx->bo, 0,
- tx->base.stride, 0, 0,
+ tx->level_pitch, tx->level_tiling,
+ x, y,
+ tx->level_width, tx->level_height,
+ tx->bo, 0, tx->base.stride,
+ tx->bo->tile_mode, 0, 0,
tx->base.width, tx->base.height,
tx->base.block.size, w, h,
NOUVEAU_BO_VRAM | NOUVEAU_BO_GART,
@@ -168,12 +186,14 @@ nv50_transfer_del(struct pipe_transfer *ptx)
if (ptx->usage != PIPE_TRANSFER_READ) {
struct pipe_screen *pscreen = ptx->texture->screen;
nv50_transfer_rect_m2mf(pscreen, tx->bo, 0, tx->base.stride,
- 0, 0, tx->base.width, tx->base.height,
- mt->bo, tx->level_offset,
- tx->level_pitch, tx->level_x,
- tx->level_y, tx->level_width,
- tx->level_height, tx->base.block.size,
+ tx->bo->tile_mode, 0, 0,
tx->base.width, tx->base.height,
+ mt->bo, tx->level_offset,
+ tx->level_pitch, tx->level_tiling,
+ tx->level_x, tx->level_y,
+ tx->level_width, tx->level_height,
+ tx->base.block.size, tx->base.width,
+ tx->base.height,
NOUVEAU_BO_GART, NOUVEAU_BO_VRAM |
NOUVEAU_BO_GART);
}
diff --git a/src/gallium/drivers/nv50/nv50_vbo.c b/src/gallium/drivers/nv50/nv50_vbo.c
index f81929f2387..17283f3f418 100644
--- a/src/gallium/drivers/nv50/nv50_vbo.c
+++ b/src/gallium/drivers/nv50/nv50_vbo.c
@@ -49,6 +49,57 @@ nv50_prim(unsigned mode)
return NV50TCL_VERTEX_BEGIN_POINTS;
}
+static INLINE unsigned
+nv50_vtxeltfmt(unsigned pf)
+{
+ static const uint8_t vtxelt_32[4] = { 0x90, 0x20, 0x10, 0x08 };
+ static const uint8_t vtxelt_16[4] = { 0xd8, 0x78, 0x28, 0x18 };
+ static const uint8_t vtxelt_08[4] = { 0xe8, 0xc0, 0x98, 0x50 };
+
+ unsigned nf, c = 0;
+
+ switch (pf_type(pf)) {
+ case PIPE_FORMAT_TYPE_FLOAT:
+ nf = NV50TCL_VERTEX_ARRAY_ATTRIB_TYPE_FLOAT; break;
+ case PIPE_FORMAT_TYPE_UNORM:
+ nf = NV50TCL_VERTEX_ARRAY_ATTRIB_TYPE_UNORM; break;
+ case PIPE_FORMAT_TYPE_SNORM:
+ nf = NV50TCL_VERTEX_ARRAY_ATTRIB_TYPE_SNORM; break;
+ case PIPE_FORMAT_TYPE_USCALED:
+ nf = NV50TCL_VERTEX_ARRAY_ATTRIB_TYPE_USCALED; break;
+ case PIPE_FORMAT_TYPE_SSCALED:
+ nf = NV50TCL_VERTEX_ARRAY_ATTRIB_TYPE_SSCALED; break;
+ default:
+ NOUVEAU_ERR("invalid vbo type %d\n",pf_type(pf));
+ assert(0);
+ nf = NV50TCL_VERTEX_ARRAY_ATTRIB_TYPE_FLOAT;
+ break;
+ }
+
+ if (pf_size_y(pf)) c++;
+ if (pf_size_z(pf)) c++;
+ if (pf_size_w(pf)) c++;
+
+ if (pf_exp2(pf) == 3) {
+ switch (pf_size_x(pf)) {
+ case 1: return (nf | (vtxelt_08[c] << 16));
+ case 2: return (nf | (vtxelt_16[c] << 16));
+ case 4: return (nf | (vtxelt_32[c] << 16));
+ default:
+ break;
+ }
+ } else
+ if (pf_exp2(pf) == 6 && pf_size_x(pf) == 1) {
+ NOUVEAU_ERR("unsupported vbo component size 64\n");
+ assert(0);
+ return (nf | 0x08000000);
+ }
+
+ NOUVEAU_ERR("invalid vbo format %s\n",pf_name(pf));
+ assert(0);
+ return (nf | 0x08000000);
+}
+
boolean
nv50_draw_arrays(struct pipe_context *pipe, unsigned mode, unsigned start,
unsigned count)
@@ -139,7 +190,7 @@ nv50_draw_elements_inline_u16(struct nv50_context *nv50, uint16_t *map,
}
static INLINE void
-nv50_draw_elements_inline_u32(struct nv50_context *nv50, uint8_t *map,
+nv50_draw_elements_inline_u32(struct nv50_context *nv50, uint32_t *map,
unsigned start, unsigned count)
{
struct nouveau_channel *chan = nv50->screen->tesla->channel;
@@ -208,9 +259,14 @@ nv50_vbo_validate(struct nv50_context *nv50)
struct nouveau_stateobj *vtxbuf, *vtxfmt;
int i;
+ /* don't validate if Gallium took away our buffers */
+ if (nv50->vtxbuf_nr == 0)
+ return;
+
vtxbuf = so_new(nv50->vtxelt_nr * 4, nv50->vtxelt_nr * 2);
vtxfmt = so_new(nv50->vtxelt_nr + 1, 0);
- so_method(vtxfmt, tesla, 0x1ac0, nv50->vtxelt_nr);
+ so_method(vtxfmt, tesla, NV50TCL_VERTEX_ARRAY_ATTRIB(0),
+ nv50->vtxelt_nr);
for (i = 0; i < nv50->vtxelt_nr; i++) {
struct pipe_vertex_element *ve = &nv50->vtxelt[i];
@@ -218,32 +274,9 @@ nv50_vbo_validate(struct nv50_context *nv50)
&nv50->vtxbuf[ve->vertex_buffer_index];
struct nouveau_bo *bo = nouveau_bo(vb->buffer);
- switch (ve->src_format) {
- case PIPE_FORMAT_R32G32B32A32_FLOAT:
- so_data(vtxfmt, 0x7e080000 | i);
- break;
- case PIPE_FORMAT_R32G32B32_FLOAT:
- so_data(vtxfmt, 0x7e100000 | i);
- break;
- case PIPE_FORMAT_R32G32_FLOAT:
- so_data(vtxfmt, 0x7e200000 | i);
- break;
- case PIPE_FORMAT_R32_FLOAT:
- so_data(vtxfmt, 0x7e900000 | i);
- break;
- case PIPE_FORMAT_R8G8B8A8_UNORM:
- so_data(vtxfmt, 0x24500000 | i);
- break;
- default:
- {
- NOUVEAU_ERR("invalid vbo format %s\n",
- pf_name(ve->src_format));
- assert(0);
- return;
- }
- }
+ so_data(vtxfmt, nv50_vtxeltfmt(ve->src_format) | i);
- so_method(vtxbuf, tesla, 0x900 + (i * 16), 3);
+ so_method(vtxbuf, tesla, NV50TCL_VERTEX_ARRAY_FORMAT(i), 3);
so_data (vtxbuf, 0x20000000 | vb->stride);
so_reloc (vtxbuf, bo, vb->buffer_offset +
ve->src_offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_GART |
diff --git a/src/gallium/drivers/r300/Makefile b/src/gallium/drivers/r300/Makefile
index faceec9842f..d7a2c8c462c 100644
--- a/src/gallium/drivers/r300/Makefile
+++ b/src/gallium/drivers/r300/Makefile
@@ -9,7 +9,6 @@ C_SOURCES = \
r300_chipset.c \
r300_clear.c \
r300_context.c \
- r300_debug.c \
r300_emit.c \
r300_flush.c \
r300_fs.c \
@@ -21,6 +20,22 @@ C_SOURCES = \
r300_state_invariant.c \
r300_vs.c \
r300_surface.c \
- r300_texture.c
+ r300_texture.c \
+ r300_tgsi_to_rc.c
+
+LIBRARY_INCLUDES = \
+ -I$(TOP)/src/mesa/drivers/dri/r300/compiler \
+ -I$(TOP)/src/mesa \
+ -I$(TOP)/include
+
+COMPILER_ARCHIVE = $(TOP)/src/mesa/drivers/dri/r300/compiler/libr300compiler.a
+
+EXTRA_OBJECTS = \
+ $(COMPILER_ARCHIVE)
include ../../Makefile.template
+
+.PHONY : $(COMPILER_ARCHIVE)
+
+$(COMPILER_ARCHIVE):
+ cd $(TOP)/src/mesa/drivers/dri/r300/compiler; make
diff --git a/src/gallium/drivers/r300/r300_context.c b/src/gallium/drivers/r300/r300_context.c
index 233a32b53c5..c8510bc63e4 100644
--- a/src/gallium/drivers/r300/r300_context.c
+++ b/src/gallium/drivers/r300/r300_context.c
@@ -52,7 +52,7 @@ static boolean r300_draw_range_elements(struct pipe_context* pipe,
draw_set_mapped_constant_buffer(r300->draw,
r300->shader_constants[PIPE_SHADER_VERTEX].constants,
- r300->shader_constants[PIPE_SHADER_VERTEX].user_count *
+ r300->shader_constants[PIPE_SHADER_VERTEX].count *
(sizeof(float) * 4));
draw_arrays(r300->draw, mode, start, count);
diff --git a/src/gallium/drivers/r300/r300_context.h b/src/gallium/drivers/r300/r300_context.h
index d891fd6265f..fc8a4498933 100644
--- a/src/gallium/drivers/r300/r300_context.h
+++ b/src/gallium/drivers/r300/r300_context.h
@@ -34,6 +34,9 @@
#include "r300_screen.h"
#include "r300_winsys.h"
+struct r300_fragment_shader;
+struct r300_vertex_shader;
+
struct r300_blend_state {
uint32_t blend_control; /* R300_RB3D_CBLEND: 0x4e04 */
uint32_t alpha_blend_control; /* R300_RB3D_ABLEND: 0x4e08 */
@@ -143,71 +146,10 @@ struct r300_constant_buffer {
/* Buffer of constants */
/* XXX first number should be raised */
float constants[32][4];
- /* Number of user-defined constants */
- unsigned user_count;
/* Total number of constants */
unsigned count;
};
-struct r300_fragment_shader {
- /* Parent class */
- struct pipe_shader_state state;
- struct tgsi_shader_info info;
-
- /* Has this shader been translated yet? */
- boolean translated;
-
- /* Pixel stack size */
- int stack_size;
-
- /* Are there immediates in this shader?
- * If not, we can heavily optimize recompilation. */
- boolean uses_imms;
-};
-
-struct r3xx_fragment_shader {
- /* Parent class */
- struct r300_fragment_shader shader;
-
- /* Number of ALU instructions */
- int alu_instruction_count;
-
- /* Number of texture instructions */
- int tex_instruction_count;
-
- /* Number of texture indirections */
- int indirections;
-
- /* Indirection node offsets */
- int alu_offset[4];
-
- /* Machine instructions */
- struct {
- uint32_t alu_rgb_inst;
- uint32_t alu_rgb_addr;
- uint32_t alu_alpha_inst;
- uint32_t alu_alpha_addr;
- } instructions[64]; /* XXX magic num */
-};
-
-struct r5xx_fragment_shader {
- /* Parent class */
- struct r300_fragment_shader shader;
-
- /* Number of used instructions */
- int instruction_count;
-
- /* Machine instructions */
- struct {
- uint32_t inst0;
- uint32_t inst1;
- uint32_t inst2;
- uint32_t inst3;
- uint32_t inst4;
- uint32_t inst5;
- } instructions[256]; /*< XXX magic number */
-};
-
struct r300_texture {
/* Parent class */
struct pipe_texture tex;
@@ -242,33 +184,6 @@ struct r300_vertex_format {
int fs_tab[16];
};
-struct r300_vertex_shader {
- /* Parent class */
- struct pipe_shader_state state;
- struct tgsi_shader_info info;
-
- /* Fallback shader, because Draw has issues */
- struct draw_vertex_shader* draw;
-
- /* Has this shader been translated yet? */
- boolean translated;
-
- /* Are there immediates in this shader?
- * If not, we can heavily optimize recompilation. */
- boolean uses_imms;
-
- /* Number of used instructions */
- int instruction_count;
-
- /* Machine instructions */
- struct {
- uint32_t inst0;
- uint32_t inst1;
- uint32_t inst2;
- uint32_t inst3;
- } instructions[128]; /*< XXX magic number */
-};
-
static struct pipe_viewport_state r300_viewport_identity = {
.scale = {1.0, 1.0, 1.0, 1.0},
.translate = {0.0, 0.0, 0.0, 0.0},
diff --git a/src/gallium/drivers/r300/r300_debug.c b/src/gallium/drivers/r300/r300_debug.c
deleted file mode 100644
index c83e8526cf7..00000000000
--- a/src/gallium/drivers/r300/r300_debug.c
+++ /dev/null
@@ -1,198 +0,0 @@
-/*
- * Copyright 2009 Corbin Simpson <[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. */
-
-#include "r300_debug.h"
-
-void r3xx_dump_fs(struct r3xx_fragment_shader* fs)
-{
- int i;
-
- for (i = 0; i < fs->alu_instruction_count; i++) {
- }
-}
-
-void r5xx_fs_dump(struct r5xx_fragment_shader* fs)
-{
- int i;
- uint32_t inst;
-
- for (i = 0; i < fs->instruction_count; i++) {
- inst = fs->instructions[i].inst0;
- debug_printf("%d: 0: CMN_INST 0x%08x:", i, inst);
- switch (inst & 0x3) {
- case R500_INST_TYPE_ALU:
- debug_printf("ALU ");
- break;
- case R500_INST_TYPE_OUT:
- debug_printf("OUT ");
- break;
- case R500_INST_TYPE_FC:
- debug_printf("FC ");
- break;
- case R500_INST_TYPE_TEX:
- debug_printf("TEX ");
- break;
- }
- debug_printf("%s %s %s %s ",
- inst & R500_INST_TEX_SEM_WAIT ? "TEX_WAIT" : "",
- inst & R500_INST_LAST ? "LAST" : "",
- inst & R500_INST_NOP ? "NOP" : "",
- inst & R500_INST_ALU_WAIT ? "ALU_WAIT" : "");
- debug_printf("wmask: %s omask: %s\n",
- r5xx_fs_mask[(inst >> 11) & 0xf],
- r5xx_fs_mask[(inst >> 15) & 0xf]);
- switch (inst & 0x3) {
- case R500_INST_TYPE_ALU:
- case R500_INST_TYPE_OUT:
- inst = fs->instructions[i].inst1;
- debug_printf(" 1: RGB_ADDR 0x%08x:", inst);
- debug_printf("Addr0: %d%c, Addr1: %d%c, "
- "Addr2: %d%c, srcp:%d\n",
- inst & 0xff, (inst & (1 << 8)) ? 'c' : 't',
- (inst >> 10) & 0xff, (inst & (1 << 18)) ? 'c' : 't',
- (inst >> 20) & 0xff, (inst & (1 << 28)) ? 'c' : 't',
- (inst >> 30));
-
- inst = fs->instructions[i].inst2;
- debug_printf(" 2: ALPHA_ADDR 0x%08x:", inst);
- debug_printf("Addr0: %d%c, Addr1: %d%c, "
- "Addr2: %d%c, srcp:%d\n",
- inst & 0xff, (inst & (1 << 8)) ? 'c' : 't',
- (inst >> 10) & 0xff, (inst & (1 << 18)) ? 'c' : 't',
- (inst >> 20) & 0xff, (inst & (1 << 28)) ? 'c' : 't',
- (inst >> 30));
-
- inst = fs->instructions[i].inst3;
- debug_printf(" 3: RGB_INST 0x%08x:", inst);
- debug_printf("rgb_A_src:%d %s/%s/%s %d "
- "rgb_B_src:%d %s/%s/%s %d\n",
- inst & 0x3, r5xx_fs_swiz[(inst >> 2) & 0x7],
- r5xx_fs_swiz[(inst >> 5) & 0x7],
- r5xx_fs_swiz[(inst >> 8) & 0x7],
- (inst >> 11) & 0x3, (inst >> 13) & 0x3,
- r5xx_fs_swiz[(inst >> 15) & 0x7],
- r5xx_fs_swiz[(inst >> 18) & 0x7],
- r5xx_fs_swiz[(inst >> 21) & 0x7],
- (inst >> 24) & 0x3);
-
- inst = fs->instructions[i].inst4;
- debug_printf(" 4: ALPHA_INST 0x%08x:", inst);
- debug_printf("%s dest:%d%s alp_A_src:%d %s %d "
- "alp_B_src:%d %s %d w:%d\n",
- r5xx_fs_op_alpha[inst & 0xf], (inst >> 4) & 0x7f,
- inst & (1<<11) ? "(rel)":"", (inst >> 12) & 0x3,
- r5xx_fs_swiz[(inst >> 14) & 0x7], (inst >> 17) & 0x3,
- (inst >> 19) & 0x3, r5xx_fs_swiz[(inst >> 21) & 0x7],
- (inst >> 24) & 0x3, (inst >> 31) & 0x1);
-
- inst = fs->instructions[i].inst5;
- debug_printf(" 5: RGBA_INST 0x%08x:", inst);
- debug_printf("%s dest:%d%s rgb_C_src:%d %s/%s/%s %d "
- "alp_C_src:%d %s %d\n",
- r5xx_fs_op_rgb[inst & 0xf], (inst >> 4) & 0x7f,
- inst & (1 << 11) ? "(rel)":"", (inst >> 12) & 0x3,
- r5xx_fs_swiz[(inst >> 14) & 0x7],
- r5xx_fs_swiz[(inst >> 17) & 0x7],
- r5xx_fs_swiz[(inst >> 20) & 0x7],
- (inst >> 23) & 0x3, (inst >> 25) & 0x3,
- r5xx_fs_swiz[(inst >> 27) & 0x7], (inst >> 30) & 0x3);
- break;
- case R500_INST_TYPE_FC:
- /* XXX don't even bother yet */
- break;
- case R500_INST_TYPE_TEX:
- inst = fs->instructions[i].inst1;
- debug_printf(" 1: TEX_INST 0x%08x: id: %d "
- "op:%s, %s, %s %s\n",
- inst, (inst >> 16) & 0xf,
- r5xx_fs_tex[(inst >> 22) & 0x7],
- (inst & (1 << 25)) ? "ACQ" : "",
- (inst & (1 << 26)) ? "IGNUNC" : "",
- (inst & (1 << 27)) ? "UNSCALED" : "SCALED");
-
- inst = fs->instructions[i].inst2;
- debug_printf(" 2: TEX_ADDR 0x%08x: "
- "src: %d%s %s/%s/%s/%s dst: %d%s %s/%s/%s/%s\n",
- inst, inst & 0x7f, inst & (1 << 7) ? "(rel)" : "",
- r5xx_fs_swiz[(inst >> 8) & 0x3],
- r5xx_fs_swiz[(inst >> 10) & 0x3],
- r5xx_fs_swiz[(inst >> 12) & 0x3],
- r5xx_fs_swiz[(inst >> 14) & 0x3],
- (inst >> 16) & 0x7f, inst & (1 << 23) ? "(rel)" : "",
- r5xx_fs_swiz[(inst >> 24) & 0x3],
- r5xx_fs_swiz[(inst >> 26) & 0x3],
- r5xx_fs_swiz[(inst >> 28) & 0x3],
- r5xx_fs_swiz[(inst >> 30) & 0x3]);
-
- inst = fs->instructions[i].inst3;
- debug_printf(" 3: TEX_DXDY 0x%08x\n", inst);
- break;
- }
- }
-}
-
-static void r300_vs_op_dump(uint32_t op)
-{
- debug_printf(" dst: %d%s op: ",
- (op >> 13) & 0x7f, r300_vs_dst_debug[(op >> 8) & 0x7]);
- if (op & 0x80) {
- if (op & 0x1) {
- debug_printf("PVS_MACRO_OP_2CLK_M2X_ADD\n");
- } else {
- debug_printf(" PVS_MACRO_OP_2CLK_MADD\n");
- }
- } else if (op & 0x40) {
- debug_printf("%s\n", r300_vs_me_ops[op & 0x1f]);
- } else {
- debug_printf("%s\n", r300_vs_ve_ops[op & 0x1f]);
- }
-}
-
-void r300_vs_src_dump(uint32_t src)
-{
- debug_printf(" reg: %d%s swiz: %s%s/%s%s/%s%s/%s%s\n",
- (src >> 5) & 0x7f, r300_vs_src_debug[src & 0x3],
- src & (1 << 25) ? "-" : " ",
- r300_vs_swiz_debug[(src >> 13) & 0x7],
- src & (1 << 26) ? "-" : " ",
- r300_vs_swiz_debug[(src >> 16) & 0x7],
- src & (1 << 27) ? "-" : " ",
- r300_vs_swiz_debug[(src >> 19) & 0x7],
- src & (1 << 28) ? "-" : " ",
- r300_vs_swiz_debug[(src >> 22) & 0x7]);
-}
-
-void r300_vs_dump(struct r300_vertex_shader* vs)
-{
- int i;
-
- for (i = 0; i < vs->instruction_count; i++) {
- debug_printf("%d: op: 0x%08x", i, vs->instructions[i].inst0);
- r300_vs_op_dump(vs->instructions[i].inst0);
- debug_printf(" src0: 0x%08x", vs->instructions[i].inst1);
- r300_vs_src_dump(vs->instructions[i].inst1);
- debug_printf(" src1: 0x%08x", vs->instructions[i].inst2);
- r300_vs_src_dump(vs->instructions[i].inst2);
- debug_printf(" src2: 0x%08x", vs->instructions[i].inst3);
- r300_vs_src_dump(vs->instructions[i].inst3);
- }
-}
diff --git a/src/gallium/drivers/r300/r300_debug.h b/src/gallium/drivers/r300/r300_debug.h
deleted file mode 100644
index 6b58c1e2501..00000000000
--- a/src/gallium/drivers/r300/r300_debug.h
+++ /dev/null
@@ -1,211 +0,0 @@
-/*
- * Copyright 2009 Corbin Simpson <[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 R300_DEBUG_H
-#define R300_DEBUG_H
-
-#include "r300_reg.h"
-#include "r300_fs.h"
-#include "r300_vs.h"
-
-static char* r5xx_fs_swiz[] = {
- " R",
- " G",
- " B",
- " A",
- " 0",
- ".5",
- " 1",
- " U",
-};
-
-static char* r5xx_fs_op_rgb[] = {
- "MAD",
- "DP3",
- "DP4",
- "D2A",
- "MIN",
- "MAX",
- "---",
- "CND",
- "CMP",
- "FRC",
- "SOP",
- "MDH",
- "MDV",
-};
-
-static char* r5xx_fs_op_alpha[] = {
- "MAD",
- " DP",
- "MIN",
- "MAX",
- "---",
- "CND",
- "CMP",
- "FRC",
- "EX2",
- "LN2",
- "RCP",
- "RSQ",
- "SIN",
- "COS",
- "MDH",
- "MDV",
-};
-
-static char* r5xx_fs_mask[] = {
- "NONE",
- "R ",
- " G ",
- "RG ",
- " B ",
- "R B ",
- " GB ",
- "RGB ",
- " A",
- "R A",
- " G A",
- "RG A",
- " BA",
- "R BA",
- " GBA",
- "RGBA",
-};
-
-static char* r5xx_fs_tex[] = {
- " NOP",
- " LD",
- "TEXKILL",
- " PROJ",
- "LODBIAS",
- " LOD",
- " DXDY",
-};
-
-static char* r300_vs_ve_ops[] = {
- /* R300 vector ops */
- " VE_NO_OP",
- " VE_DOT_PRODUCT",
- " VE_MULTIPLY",
- " VE_ADD",
- " VE_MULTIPLY_ADD",
- " VE_DISTANCE_FACTOR",
- " VE_FRACTION",
- " VE_MAXIMUM",
- " VE_MINIMUM",
- "VE_SET_GREATER_THAN_EQUAL",
- " VE_SET_LESS_THAN",
- " VE_MULTIPLYX2_ADD",
- " VE_MULTIPLY_CLAMP",
- " VE_FLT2FIX_DX",
- " VE_FLT2FIX_DX_RND",
- /* R500 vector ops */
- " VE_PRED_SET_EQ_PUSH",
- " VE_PRED_SET_GT_PUSH",
- " VE_PRED_SET_GTE_PUSH",
- " VE_PRED_SET_NEQ_PUSH",
- " VE_COND_WRITE_EQ",
- " VE_COND_WRITE_GT",
- " VE_COND_WRITE_GTE",
- " VE_COND_WRITE_NEQ",
- " VE_SET_GREATER_THAN",
- " VE_SET_EQUAL",
- " VE_SET_NOT_EQUAL",
- " (reserved)",
- " (reserved)",
- " (reserved)",
-};
-
-static char* r300_vs_me_ops[] = {
- /* R300 math ops */
- " ME_NO_OP",
- " ME_EXP_BASE2_DX",
- " ME_LOG_BASE2_DX",
- " ME_EXP_BASEE_FF",
- " ME_LIGHT_COEFF_DX",
- " ME_POWER_FUNC_FF",
- " ME_RECIP_DX",
- " ME_RECIP_FF",
- " ME_RECIP_SQRT_DX",
- " ME_RECIP_SQRT_FF",
- " ME_MULTIPLY",
- " ME_EXP_BASE2_FULL_DX",
- " ME_LOG_BASE2_FULL_DX",
- " ME_POWER_FUNC_FF_CLAMP_B",
- "ME_POWER_FUNC_FF_CLAMP_B1",
- "ME_POWER_FUNC_FF_CLAMP_01",
- " ME_SIN",
- " ME_COS",
- /* R500 math ops */
- " ME_LOG_BASE2_IEEE",
- " ME_RECIP_IEEE",
- " ME_RECIP_SQRT_IEEE",
- " ME_PRED_SET_EQ",
- " ME_PRED_SET_GT",
- " ME_PRED_SET_GTE",
- " ME_PRED_SET_NEQ",
- " ME_PRED_SET_CLR",
- " ME_PRED_SET_INV",
- " ME_PRED_SET_POP",
- " ME_PRED_SET_RESTORE",
- " (reserved)",
- " (reserved)",
- " (reserved)",
-};
-
-/* XXX refactor to avoid clashing symbols */
-static char* r300_vs_src_debug[] = {
- "t",
- "i",
- "c",
- "a",
-};
-
-static char* r300_vs_dst_debug[] = {
- "t",
- "a0",
- "o",
- "ox",
- "a",
- "i",
- "u",
- "u",
-};
-
-static char* r300_vs_swiz_debug[] = {
- "X",
- "Y",
- "Z",
- "W",
- "0",
- "1",
- "U",
- "U",
-};
-
-void r5xx_fs_dump(struct r5xx_fragment_shader* fs);
-void r3xx_dump_fs(struct r3xx_fragment_shader* fs);
-
-void r300_vs_dump(struct r300_vertex_shader* vs);
-
-#endif /* R300_DEBUG_H */
diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c
index 7ba56cdc1d2..53256fc6dd3 100644
--- a/src/gallium/drivers/r300/r300_emit.c
+++ b/src/gallium/drivers/r300/r300_emit.c
@@ -24,6 +24,9 @@
#include "r300_emit.h"
+#include "r300_fs.h"
+#include "r300_vs.h"
+
void r300_emit_blend_state(struct r300_context* r300,
struct r300_blend_state* blend)
{
@@ -109,73 +112,158 @@ void r300_emit_dsa_state(struct r300_context* r300,
END_CS;
}
-void r300_emit_fragment_shader(struct r300_context* r300,
- struct r3xx_fragment_shader* fs)
+static const float * get_shader_constant(
+ struct r300_context * r300,
+ struct rc_constant * constant,
+ struct r300_constant_buffer * externals)
+{
+ static const float zero[4] = { 0.0, 0.0, 0.0, 0.0 };
+ switch(constant->Type) {
+ case RC_CONSTANT_EXTERNAL:
+ return externals->constants[constant->u.External];
+
+ case RC_CONSTANT_IMMEDIATE:
+ return constant->u.Immediate;
+
+ default:
+ debug_printf("r300: Implementation error: Unhandled constant type %i\n",
+ constant->Type);
+ return zero;
+ }
+}
+
+/* Convert a normal single-precision float into the 7.16 format
+ * used by the R300 fragment shader.
+ */
+static uint32_t pack_float24(float f)
{
+ union {
+ float fl;
+ uint32_t u;
+ } u;
+ float mantissa;
+ int exponent;
+ uint32_t float24 = 0;
+
+ if (f == 0.0)
+ return 0;
+
+ u.fl = f;
+
+ mantissa = frexpf(f, &exponent);
+
+ /* Handle -ve */
+ if (mantissa < 0) {
+ float24 |= (1 << 23);
+ mantissa = mantissa * -1.0;
+ }
+ /* Handle exponent, bias of 63 */
+ exponent += 62;
+ float24 |= (exponent << 16);
+ /* Kill 7 LSB of mantissa */
+ float24 |= (u.u & 0x7FFFFF) >> 7;
+
+ return float24;
+}
+
+void r300_emit_fragment_program_code(struct r300_context* r300,
+ struct rX00_fragment_program_code* generic_code,
+ struct r300_constant_buffer* externals)
+{
+ struct r300_fragment_program_code * code = &generic_code->code.r300;
+ struct rc_constant_list * constants = &generic_code->constants;
int i;
CS_LOCALS(r300);
- BEGIN_CS(22);
-
- OUT_CS_REG(R300_US_CONFIG, fs->indirections);
- OUT_CS_REG(R300_US_PIXSIZE, fs->shader.stack_size);
- /* XXX figure out exactly how big the sizes are on this reg */
- OUT_CS_REG(R300_US_CODE_OFFSET, 0x40);
- /* XXX figure these ones out a bit better kthnx */
- OUT_CS_REG(R300_US_CODE_ADDR_0, 0x0);
- OUT_CS_REG(R300_US_CODE_ADDR_1, 0x0);
- OUT_CS_REG(R300_US_CODE_ADDR_2, 0x0);
- OUT_CS_REG(R300_US_CODE_ADDR_3, 0x40 | R300_RGBA_OUT);
-
- for (i = 0; i < fs->alu_instruction_count; i++) {
- OUT_CS_REG(R300_US_ALU_RGB_INST_0 + (4 * i),
- fs->instructions[i].alu_rgb_inst);
- OUT_CS_REG(R300_US_ALU_RGB_ADDR_0 + (4 * i),
- fs->instructions[i].alu_rgb_addr);
- OUT_CS_REG(R300_US_ALU_ALPHA_INST_0 + (4 * i),
- fs->instructions[i].alu_alpha_inst);
- OUT_CS_REG(R300_US_ALU_ALPHA_ADDR_0 + (4 * i),
- fs->instructions[i].alu_alpha_addr);
+ BEGIN_CS(15 +
+ code->alu.length * 4 +
+ (code->tex.length ? (1 + code->tex.length) : 0) +
+ (constants->Count ? (1 + constants->Count * 4) : 0));
+
+ OUT_CS_REG(R300_US_CONFIG, code->config);
+ OUT_CS_REG(R300_US_PIXSIZE, code->pixsize);
+ OUT_CS_REG(R300_US_CODE_OFFSET, code->code_offset);
+
+ OUT_CS_REG_SEQ(R300_US_CODE_ADDR_0, 4);
+ for(i = 0; i < 4; ++i)
+ OUT_CS(code->code_addr[i]);
+
+ OUT_CS_REG_SEQ(R300_US_ALU_RGB_INST_0, code->alu.length);
+ for (i = 0; i < code->alu.length; i++)
+ OUT_CS(code->alu.inst[i].rgb_inst);
+
+ OUT_CS_REG_SEQ(R300_US_ALU_RGB_ADDR_0, code->alu.length);
+ for (i = 0; i < code->alu.length; i++)
+ OUT_CS(code->alu.inst[i].rgb_addr);
+
+ OUT_CS_REG_SEQ(R300_US_ALU_ALPHA_INST_0, code->alu.length);
+ for (i = 0; i < code->alu.length; i++)
+ OUT_CS(code->alu.inst[i].alpha_inst);
+
+ OUT_CS_REG_SEQ(R300_US_ALU_ALPHA_ADDR_0, code->alu.length);
+ for (i = 0; i < code->alu.length; i++)
+ OUT_CS(code->alu.inst[i].alpha_addr);
+
+ if (code->tex.length) {
+ OUT_CS_REG_SEQ(R300_US_TEX_INST_0, code->tex.length);
+ for(i = 0; i < code->tex.length; ++i)
+ OUT_CS(code->tex.inst[i]);
+ }
+
+ if (constants->Count) {
+ OUT_CS_ONE_REG(R300_PFS_PARAM_0_X, constants->Count * 4);
+ for(i = 0; i < constants->Count; ++i) {
+ const float * data = get_shader_constant(r300, &constants->Constants[i], externals);
+ OUT_CS(pack_float24(data[0]));
+ OUT_CS(pack_float24(data[1]));
+ OUT_CS(pack_float24(data[2]));
+ OUT_CS(pack_float24(data[3]));
+ }
}
END_CS;
}
-void r500_emit_fragment_shader(struct r300_context* r300,
- struct r5xx_fragment_shader* fs)
+void r500_emit_fragment_program_code(struct r300_context* r300,
+ struct rX00_fragment_program_code* generic_code,
+ struct r300_constant_buffer* externals)
{
+ struct r500_fragment_program_code * code = &generic_code->code.r500;
+ struct rc_constant_list * constants = &generic_code->constants;
int i;
- struct r300_constant_buffer* constants =
- &r300->shader_constants[PIPE_SHADER_FRAGMENT];
CS_LOCALS(r300);
- BEGIN_CS(9 + (fs->instruction_count * 6) + (constants->count ? 3 : 0) +
- (constants->count * 4));
- OUT_CS_REG(R500_US_CONFIG, R500_ZERO_TIMES_ANYTHING_EQUALS_ZERO);
- OUT_CS_REG(R500_US_PIXSIZE, fs->shader.stack_size);
- OUT_CS_REG(R500_US_CODE_ADDR, R500_US_CODE_START_ADDR(0) |
- R500_US_CODE_END_ADDR(fs->instruction_count));
+ BEGIN_CS(13 +
+ ((code->inst_end + 1) * 6) +
+ (constants->Count ? (3 + (constants->Count * 4)) : 0));
+ OUT_CS_REG(R500_US_CONFIG, 0);
+ OUT_CS_REG(R500_US_PIXSIZE, code->max_temp_idx);
+ OUT_CS_REG(R500_US_CODE_RANGE,
+ R500_US_CODE_RANGE_ADDR(0) | R500_US_CODE_RANGE_SIZE(code->inst_end));
+ OUT_CS_REG(R500_US_CODE_OFFSET, 0);
+ OUT_CS_REG(R500_US_CODE_ADDR,
+ R500_US_CODE_START_ADDR(0) | R500_US_CODE_END_ADDR(code->inst_end));
OUT_CS_REG(R500_GA_US_VECTOR_INDEX, R500_GA_US_VECTOR_INDEX_TYPE_INSTR);
- OUT_CS_ONE_REG(R500_GA_US_VECTOR_DATA, fs->instruction_count * 6);
- for (i = 0; i < fs->instruction_count; i++) {
- OUT_CS(fs->instructions[i].inst0);
- OUT_CS(fs->instructions[i].inst1);
- OUT_CS(fs->instructions[i].inst2);
- OUT_CS(fs->instructions[i].inst3);
- OUT_CS(fs->instructions[i].inst4);
- OUT_CS(fs->instructions[i].inst5);
- }
-
- if (constants->count) {
- OUT_CS_REG(R500_GA_US_VECTOR_INDEX,
- R500_GA_US_VECTOR_INDEX_TYPE_CONST);
- OUT_CS_ONE_REG(R500_GA_US_VECTOR_DATA, constants->count * 4);
- for (i = 0; i < constants->count; i++) {
- OUT_CS_32F(constants->constants[i][0]);
- OUT_CS_32F(constants->constants[i][1]);
- OUT_CS_32F(constants->constants[i][2]);
- OUT_CS_32F(constants->constants[i][3]);
+ OUT_CS_ONE_REG(R500_GA_US_VECTOR_DATA, (code->inst_end + 1) * 6);
+ for (i = 0; i <= code->inst_end; i++) {
+ OUT_CS(code->inst[i].inst0);
+ OUT_CS(code->inst[i].inst1);
+ OUT_CS(code->inst[i].inst2);
+ OUT_CS(code->inst[i].inst3);
+ OUT_CS(code->inst[i].inst4);
+ OUT_CS(code->inst[i].inst5);
+ }
+
+ if (constants->Count) {
+ OUT_CS_REG(R500_GA_US_VECTOR_INDEX, R500_GA_US_VECTOR_INDEX_TYPE_CONST);
+ OUT_CS_ONE_REG(R500_GA_US_VECTOR_DATA, constants->Count * 4);
+ for (i = 0; i < constants->Count; i++) {
+ const float * data = get_shader_constant(r300, &constants->Constants[i], externals);
+ OUT_CS_32F(data[0]);
+ OUT_CS_32F(data[1]);
+ OUT_CS_32F(data[2]);
+ OUT_CS_32F(data[3]);
}
}
@@ -190,7 +278,7 @@ void r300_emit_fb_state(struct r300_context* r300,
int i;
CS_LOCALS(r300);
- BEGIN_CS((8 * fb->nr_cbufs) + (fb->zsbuf ? 8 : 0) + 4);
+ BEGIN_CS((10 * fb->nr_cbufs) + (fb->zsbuf ? 10 : 0) + 4);
for (i = 0; i < fb->nr_cbufs; i++) {
tex = (struct r300_texture*)fb->cbufs[i]->texture;
assert(tex && tex->buffer && "cbuf is marked, but NULL!");
@@ -199,8 +287,10 @@ void r300_emit_fb_state(struct r300_context* r300,
OUT_CS_REG_SEQ(R300_RB3D_COLOROFFSET0 + (4 * i), 1);
OUT_CS_RELOC(tex->buffer, 0, 0, RADEON_GEM_DOMAIN_VRAM, 0);
- OUT_CS_REG(R300_RB3D_COLORPITCH0 + (4 * i), pixpitch |
- r300_translate_colorformat(tex->tex.format));
+ OUT_CS_REG_SEQ(R300_RB3D_COLORPITCH0 + (4 * i), 1);
+ OUT_CS_RELOC(tex->buffer, pixpitch |
+ r300_translate_colorformat(tex->tex.format), 0,
+ RADEON_GEM_DOMAIN_VRAM, 0);
OUT_CS_REG(R300_US_OUT_FMT_0 + (4 * i),
r300_translate_out_fmt(fb->cbufs[i]->format));
@@ -216,7 +306,8 @@ void r300_emit_fb_state(struct r300_context* r300,
OUT_CS_REG(R300_ZB_FORMAT, r300_translate_zsformat(tex->tex.format));
- OUT_CS_REG(R300_ZB_DEPTHPITCH, pixpitch);
+ OUT_CS_REG_SEQ(R300_ZB_DEPTHPITCH, 1);
+ OUT_CS_RELOC(tex->buffer, pixpitch, 0, RADEON_GEM_DOMAIN_VRAM, 0);
}
OUT_CS_REG(R300_RB3D_DSTCACHE_CTLSTAT,
@@ -380,13 +471,13 @@ void r300_emit_vertex_format_state(struct r300_context* r300)
END_CS;
}
-void r300_emit_vertex_shader(struct r300_context* r300,
- struct r300_vertex_shader* vs)
+void r300_emit_vertex_program_code(struct r300_context* r300,
+ struct r300_vertex_program_code* code,
+ struct r300_constant_buffer* constants)
{
int i;
struct r300_screen* r300screen = r300_screen(r300->context.screen);
- struct r300_constant_buffer* constants =
- &r300->shader_constants[PIPE_SHADER_VERTEX];
+ unsigned instruction_count = code->length / 4;
CS_LOCALS(r300);
if (!r300screen->caps->has_tcl) {
@@ -395,10 +486,10 @@ void r300_emit_vertex_shader(struct r300_context* r300,
return;
}
- if (constants->count) {
- BEGIN_CS(14 + (vs->instruction_count * 4) + (constants->count * 4));
+ if (code->constants.Count) {
+ BEGIN_CS(14 + code->length + (code->constants.Count * 4));
} else {
- BEGIN_CS(11 + (vs->instruction_count * 4));
+ BEGIN_CS(11 + code->length);
}
/* R300_VAP_PVS_CODE_CNTL_0
@@ -408,30 +499,27 @@ void r300_emit_vertex_shader(struct r300_context* r300,
* XXX these could be optimized to select better values... */
OUT_CS_REG_SEQ(R300_VAP_PVS_CODE_CNTL_0, 3);
OUT_CS(R300_PVS_FIRST_INST(0) |
- R300_PVS_XYZW_VALID_INST(vs->instruction_count - 1) |
- R300_PVS_LAST_INST(vs->instruction_count - 1));
- OUT_CS(R300_PVS_MAX_CONST_ADDR(constants->count - 1));
- OUT_CS(vs->instruction_count - 1);
+ R300_PVS_XYZW_VALID_INST(instruction_count - 1) |
+ R300_PVS_LAST_INST(instruction_count - 1));
+ OUT_CS(R300_PVS_MAX_CONST_ADDR(code->constants.Count - 1));
+ OUT_CS(instruction_count - 1);
OUT_CS_REG(R300_VAP_PVS_VECTOR_INDX_REG, 0);
- OUT_CS_ONE_REG(R300_VAP_PVS_UPLOAD_DATA, vs->instruction_count * 4);
- for (i = 0; i < vs->instruction_count; i++) {
- OUT_CS(vs->instructions[i].inst0);
- OUT_CS(vs->instructions[i].inst1);
- OUT_CS(vs->instructions[i].inst2);
- OUT_CS(vs->instructions[i].inst3);
- }
+ OUT_CS_ONE_REG(R300_VAP_PVS_UPLOAD_DATA, code->length);
+ for (i = 0; i < code->length; i++)
+ OUT_CS(code->body.d[i]);
- if (constants->count) {
+ if (code->constants.Count) {
OUT_CS_REG(R300_VAP_PVS_VECTOR_INDX_REG,
(r300screen->caps->is_r500 ?
R500_PVS_CONST_START : R300_PVS_CONST_START));
- OUT_CS_ONE_REG(R300_VAP_PVS_UPLOAD_DATA, constants->count * 4);
- for (i = 0; i < constants->count; i++) {
- OUT_CS_32F(constants->constants[i][0]);
- OUT_CS_32F(constants->constants[i][1]);
- OUT_CS_32F(constants->constants[i][2]);
- OUT_CS_32F(constants->constants[i][3]);
+ OUT_CS_ONE_REG(R300_VAP_PVS_UPLOAD_DATA, code->constants.Count * 4);
+ for (i = 0; i < code->constants.Count; i++) {
+ const float * data = get_shader_constant(r300, &code->constants.Constants[i], constants);
+ OUT_CS_32F(data[0]);
+ OUT_CS_32F(data[1]);
+ OUT_CS_32F(data[2]);
+ OUT_CS_32F(data[3]);
}
}
@@ -443,6 +531,12 @@ void r300_emit_vertex_shader(struct r300_context* r300,
END_CS;
}
+void r300_emit_vertex_shader(struct r300_context* r300,
+ struct r300_vertex_shader* vs)
+{
+ r300_emit_vertex_program_code(r300, &vs->code, &r300->shader_constants[PIPE_SHADER_VERTEX]);
+}
+
void r300_emit_viewport_state(struct r300_context* r300,
struct r300_viewport_state* viewport)
{
@@ -531,10 +625,11 @@ validate:
} else {
debug_printf("No VBO while emitting dirty state!\n");
}
- if (r300->winsys->validate(r300->winsys)) {
+ if (!r300->winsys->validate(r300->winsys)) {
r300->context.flush(&r300->context, 0, NULL);
if (invalid) {
/* Well, hell. */
+ debug_printf("r300: Stuck in validation loop, gonna quit now.");
exit(1);
}
invalid = TRUE;
@@ -563,11 +658,9 @@ validate:
if (r300->dirty_state & R300_NEW_FRAGMENT_SHADER) {
if (r300screen->caps->is_r500) {
- r500_emit_fragment_shader(r300,
- (struct r5xx_fragment_shader*)r300->fs);
+ r500_emit_fragment_program_code(r300, &r300->fs->code, &r300->shader_constants[PIPE_SHADER_FRAGMENT]);
} else {
- r300_emit_fragment_shader(r300,
- (struct r3xx_fragment_shader*)r300->fs);
+ r300_emit_fragment_program_code(r300, &r300->fs->code, &r300->shader_constants[PIPE_SHADER_FRAGMENT]);
}
r300->dirty_state &= ~R300_NEW_FRAGMENT_SHADER;
}
diff --git a/src/gallium/drivers/r300/r300_emit.h b/src/gallium/drivers/r300/r300_emit.h
index fda26f39481..350691d592d 100644
--- a/src/gallium/drivers/r300/r300_emit.h
+++ b/src/gallium/drivers/r300/r300_emit.h
@@ -30,6 +30,9 @@
#include "r300_screen.h"
#include "r300_state_inlines.h"
+struct rX00_fragment_program_code;
+struct r300_vertex_program_code;
+
void r300_emit_blend_state(struct r300_context* r300,
struct r300_blend_state* blend);
@@ -42,11 +45,13 @@ void r300_emit_clip_state(struct r300_context* r300,
void r300_emit_dsa_state(struct r300_context* r300,
struct r300_dsa_state* dsa);
-void r300_emit_fragment_shader(struct r300_context* r300,
- struct r3xx_fragment_shader* fs);
+void r300_emit_fragment_program_code(struct r300_context* r300,
+ struct rX00_fragment_program_code* generic_code,
+ struct r300_constant_buffer* externals);
-void r500_emit_fragment_shader(struct r300_context* r300,
- struct r5xx_fragment_shader* fs);
+void r500_emit_fragment_program_code(struct r300_context* r300,
+ struct rX00_fragment_program_code* generic_code,
+ struct r300_constant_buffer* externals);
void r300_emit_fb_state(struct r300_context* r300,
struct pipe_framebuffer_state* fb);
@@ -68,6 +73,10 @@ void r300_emit_vertex_buffer(struct r300_context* r300);
void r300_emit_vertex_format_state(struct r300_context* r300);
+void r300_emit_vertex_program_code(struct r300_context* r300,
+ struct r300_vertex_program_code* code,
+ struct r300_constant_buffer* constants);
+
void r300_emit_vertex_shader(struct r300_context* r300,
struct r300_vertex_shader* vs);
diff --git a/src/gallium/drivers/r300/r300_fs.c b/src/gallium/drivers/r300/r300_fs.c
index 4b304306d0f..36463b9a2eb 100644
--- a/src/gallium/drivers/r300/r300_fs.c
+++ b/src/gallium/drivers/r300/r300_fs.c
@@ -23,87 +23,115 @@
#include "r300_fs.h"
-void r300_translate_fragment_shader(struct r300_context* r300,
- struct r300_fragment_shader* fs)
+#include "r300_tgsi_to_rc.h"
+
+#include "radeon_compiler.h"
+
+static void find_output_registers(struct r300_fragment_program_compiler * compiler,
+ struct r300_fragment_shader * fs)
{
- struct tgsi_parse_context parser;
- int i;
- boolean is_r500 = r300_screen(r300->context.screen)->caps->is_r500;
- struct r300_constant_buffer* consts =
- &r300->shader_constants[PIPE_SHADER_FRAGMENT];
+ unsigned i;
- struct r300_fs_asm* assembler = CALLOC_STRUCT(r300_fs_asm);
- if (assembler == NULL) {
- return;
- }
- /* Setup starting offset for immediates. */
- assembler->imm_offset = consts->user_count;
- /* Enable depth writes, if needed. */
- assembler->writes_depth = fs->info.writes_z;
-
- /* Make sure we start at the beginning of the shader. */
- if (is_r500) {
- ((struct r5xx_fragment_shader*)fs)->instruction_count = 0;
- }
+ /* Mark the outputs as not present initially */
+ compiler->OutputColor = fs->info.num_outputs;
+ compiler->OutputDepth = fs->info.num_outputs;
- tgsi_parse_init(&parser, fs->state.tokens);
+ /* Now see where they really are. */
+ for(i = 0; i < fs->info.num_outputs; ++i) {
+ switch(fs->info.output_semantic_name[i]) {
+ case TGSI_SEMANTIC_COLOR:
+ compiler->OutputColor = i;
+ break;
+ case TGSI_SEMANTIC_POSITION:
+ compiler->OutputDepth = i;
+ break;
+ }
+ }
+}
- while (!tgsi_parse_end_of_tokens(&parser)) {
- tgsi_parse_token(&parser);
+static void allocate_hardware_inputs(
+ struct r300_fragment_program_compiler * c,
+ void (*allocate)(void * data, unsigned input, unsigned hwreg),
+ void * mydata)
+{
+ struct tgsi_shader_info* info = &((struct r300_fragment_shader*)c->UserData)->info;
+ int total_colors = 0;
+ int colors = 0;
+ int total_generic = 0;
+ int generic = 0;
+ int i;
- /* This is seriously the lamest way to create fragment programs ever.
- * I blame TGSI. */
- switch (parser.FullToken.Token.Type) {
- case TGSI_TOKEN_TYPE_DECLARATION:
- /* Allocated registers sitting at the beginning
- * of the program. */
- r300_fs_declare(assembler, &parser.FullToken.FullDeclaration);
+ for (i = 0; i < info->num_inputs; i++) {
+ switch (info->input_semantic_name[i]) {
+ case TGSI_SEMANTIC_COLOR:
+ total_colors++;
break;
- case TGSI_TOKEN_TYPE_IMMEDIATE:
- debug_printf("r300: Emitting immediate to constant buffer, "
- "position %d\n",
- assembler->imm_offset + assembler->imm_count);
- /* I am not amused by the length of these. */
- for (i = 0; i < 4; i++) {
- consts->constants[assembler->imm_offset +
- assembler->imm_count][i] =
- parser.FullToken.FullImmediate.u.ImmediateFloat32[i]
- .Float;
- }
- assembler->imm_count++;
+ case TGSI_SEMANTIC_FOG:
+ case TGSI_SEMANTIC_GENERIC:
+ total_generic++;
break;
- case TGSI_TOKEN_TYPE_INSTRUCTION:
- if (is_r500) {
- r5xx_fs_instruction((struct r5xx_fragment_shader*)fs,
- assembler, &parser.FullToken.FullInstruction);
- } else {
- r3xx_fs_instruction((struct r3xx_fragment_shader*)fs,
- assembler, &parser.FullToken.FullInstruction);
- }
+ }
+ }
+
+ for(i = 0; i < info->num_inputs; i++) {
+ switch (info->input_semantic_name[i]) {
+ case TGSI_SEMANTIC_COLOR:
+ allocate(mydata, i, colors);
+ colors++;
+ break;
+ case TGSI_SEMANTIC_FOG:
+ case TGSI_SEMANTIC_GENERIC:
+ allocate(mydata, i, total_colors + generic);
+ generic++;
break;
}
}
+}
+
+void r300_translate_fragment_shader(struct r300_context* r300,
+ struct r300_fragment_shader* fs)
+{
+ struct r300_fragment_program_compiler compiler;
+ struct tgsi_to_rc ttr;
+
+ memset(&compiler, 0, sizeof(compiler));
+ rc_init(&compiler.Base);
+ compiler.Base.Debug = 1;
+
+ compiler.code = &fs->code;
+ compiler.is_r500 = r300_screen(r300->context.screen)->caps->is_r500;
+ compiler.AllocateHwInputs = &allocate_hardware_inputs;
+ compiler.UserData = fs;
+
+ /* TODO: Program compilation depends on texture compare modes,
+ * which are sampler state. Therefore, programs need to be recompiled
+ * depending on this state as in the classic Mesa driver.
+ *
+ * This is not yet handled correctly.
+ */
- debug_printf("r300: fs: %d texs and %d colors, first free reg is %d\n",
- assembler->tex_count, assembler->color_count,
- assembler->tex_count + assembler->color_count);
-
- consts->count = consts->user_count + assembler->imm_count;
- fs->uses_imms = assembler->imm_count;
- debug_printf("r300: fs: %d total constants, "
- "%d from user and %d from immediates\n", consts->count,
- consts->user_count, assembler->imm_count);
- r3xx_fs_finalize(fs, assembler);
- if (is_r500) {
- r5xx_fs_finalize((struct r5xx_fragment_shader*)fs, assembler);
+ find_output_registers(&compiler, fs);
+
+ if (compiler.Base.Debug) {
+ debug_printf("r300: Initial fragment program\n");
+ tgsi_dump(fs->state.tokens, 0);
}
- tgsi_dump(fs->state.tokens, 0);
- /* XXX finish r300 dumper too */
- if (is_r500) {
- r5xx_fs_dump((struct r5xx_fragment_shader*)fs);
+ /* Translate TGSI to our internal representation */
+ ttr.compiler = &compiler.Base;
+ ttr.info = &fs->info;
+
+ r300_tgsi_to_rc(&ttr, fs->state.tokens);
+
+ /* Invoke the compiler */
+ r3xx_compile_fragment_program(&compiler);
+ if (compiler.Base.Error) {
+ /* Todo: Fail gracefully */
+ fprintf(stderr, "r300 FP: Compiler error\n");
+ abort();
}
- tgsi_parse_free(&parser);
- FREE(assembler);
+ /* And, finally... */
+ rc_destroy(&compiler.Base);
+ fs->translated = TRUE;
}
diff --git a/src/gallium/drivers/r300/r300_fs.h b/src/gallium/drivers/r300/r300_fs.h
index 18deb7a05e4..9fab7894024 100644
--- a/src/gallium/drivers/r300/r300_fs.h
+++ b/src/gallium/drivers/r300/r300_fs.h
@@ -30,6 +30,21 @@
#include "r3xx_fs.h"
#include "r5xx_fs.h"
+#include "radeon_code.h"
+
+struct r300_fragment_shader {
+ /* Parent class */
+ struct pipe_shader_state state;
+ struct tgsi_shader_info info;
+
+ /* Has this shader been translated yet? */
+ boolean translated;
+
+ /* Compiled code */
+ struct rX00_fragment_program_code code;
+};
+
+
void r300_translate_fragment_shader(struct r300_context* r300,
struct r300_fragment_shader* fs);
diff --git a/src/gallium/drivers/r300/r300_fs_inlines.h b/src/gallium/drivers/r300/r300_fs_inlines.h
deleted file mode 100644
index be4be9465e6..00000000000
--- a/src/gallium/drivers/r300/r300_fs_inlines.h
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
- * Copyright 2008 Corbin Simpson <[email protected]>
- * Joakim Sindholt <[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 R300_FS_INLINES_H
-#define R300_FS_INLINES_H
-
-#include "tgsi/tgsi_parse.h"
-
-#include "r300_context.h"
-#include "r300_debug.h"
-#include "r300_reg.h"
-#include "r300_screen.h"
-#include "r300_shader_inlines.h"
-
-/* Temporary struct used to hold assembly state while putting together
- * fragment programs. */
-struct r300_fs_asm {
- /* Pipe context. */
- struct r300_context* r300;
- /* Number of colors. */
- unsigned color_count;
- /* Number of texcoords. */
- unsigned tex_count;
- /* Offset for temporary registers. Inputs and temporaries have no
- * distinguishing markings, so inputs start at 0 and the first usable
- * temporary register is after all inputs. */
- unsigned temp_offset;
- /* Number of requested temporary registers. */
- unsigned temp_count;
- /* Offset for immediate constants. Neither R300 nor R500 can do four
- * inline constants per source, so instead we copy immediates into the
- * constant buffer. */
- unsigned imm_offset;
- /* Number of immediate constants. */
- unsigned imm_count;
- /* Are depth writes enabled? */
- boolean writes_depth;
- /* Depth write offset. This is the TGSI output that corresponds to
- * depth writes. */
- unsigned depth_output;
-};
-
-static INLINE void r300_fs_declare(struct r300_fs_asm* assembler,
- struct tgsi_full_declaration* decl)
-{
- switch (decl->Declaration.File) {
- case TGSI_FILE_INPUT:
- switch (decl->Semantic.SemanticName) {
- case TGSI_SEMANTIC_COLOR:
- assembler->color_count++;
- break;
- case TGSI_SEMANTIC_FOG:
- case TGSI_SEMANTIC_GENERIC:
- assembler->tex_count++;
- break;
- default:
- debug_printf("r300: fs: Bad semantic declaration %d\n",
- decl->Semantic.SemanticName);
- break;
- }
- break;
- case TGSI_FILE_OUTPUT:
- /* Depth write. Mark the position of the output so we can
- * identify it later. */
- if (decl->Semantic.SemanticName == TGSI_SEMANTIC_POSITION) {
- assembler->depth_output = decl->DeclarationRange.First;
- }
- break;
- case TGSI_FILE_CONSTANT:
- break;
- case TGSI_FILE_TEMPORARY:
- assembler->temp_count++;
- break;
- default:
- debug_printf("r300: fs: Bad file %d\n", decl->Declaration.File);
- break;
- }
-
- assembler->temp_offset = assembler->color_count + assembler->tex_count;
-}
-
-static INLINE unsigned r300_fs_src(struct r300_fs_asm* assembler,
- struct tgsi_src_register* src)
-{
- switch (src->File) {
- case TGSI_FILE_NULL:
- return 0;
- case TGSI_FILE_INPUT:
- /* XXX may be wrong */
- return src->Index;
- break;
- case TGSI_FILE_TEMPORARY:
- return src->Index + assembler->temp_offset;
- break;
- case TGSI_FILE_IMMEDIATE:
- return (src->Index + assembler->imm_offset) | (1 << 8);
- break;
- case TGSI_FILE_CONSTANT:
- /* XXX magic */
- return src->Index | (1 << 8);
- break;
- default:
- debug_printf("r300: fs: Unimplemented src %d\n", src->File);
- break;
- }
- return 0;
-}
-
-static INLINE unsigned r300_fs_dst(struct r300_fs_asm* assembler,
- struct tgsi_dst_register* dst)
-{
- switch (dst->File) {
- case TGSI_FILE_NULL:
- /* This happens during KIL instructions. */
- return 0;
- break;
- case TGSI_FILE_OUTPUT:
- return 0;
- break;
- case TGSI_FILE_TEMPORARY:
- return dst->Index + assembler->temp_offset;
- break;
- default:
- debug_printf("r300: fs: Unimplemented dst %d\n", dst->File);
- break;
- }
- return 0;
-}
-
-static INLINE boolean r300_fs_is_depr(struct r300_fs_asm* assembler,
- struct tgsi_dst_register* dst)
-{
- return (assembler->writes_depth &&
- (dst->File == TGSI_FILE_OUTPUT) &&
- (dst->Index == assembler->depth_output));
-}
-
-#endif /* R300_FS_INLINES_H */
diff --git a/src/gallium/drivers/r300/r300_screen.c b/src/gallium/drivers/r300/r300_screen.c
index da1d5ffe2fd..96a73046217 100644
--- a/src/gallium/drivers/r300/r300_screen.c
+++ b/src/gallium/drivers/r300/r300_screen.c
@@ -147,6 +147,8 @@ static int r300_get_param(struct pipe_screen* pscreen, int param)
case PIPE_CAP_TGSI_CONT_SUPPORTED:
/* XXX */
return 0;
+ case PIPE_CAP_BLEND_EQUATION_SEPARATE:
+ return 1;
default:
debug_printf("r300: Implementation error: Bad param %d\n",
param);
@@ -320,13 +322,14 @@ r300_get_tex_transfer(struct pipe_screen *screen,
trans = CALLOC_STRUCT(r300_transfer);
if (trans) {
pipe_texture_reference(&trans->transfer.texture, texture);
- trans->transfer.format = trans->transfer.format;
+ trans->transfer.format = texture->format;
trans->transfer.width = w;
trans->transfer.height = h;
trans->transfer.block = texture->block;
trans->transfer.nblocksx = texture->nblocksx[level];
trans->transfer.nblocksy = texture->nblocksy[level];
- trans->transfer.stride = tex->stride;
+ trans->transfer.stride = align(pf_get_stride(&trans->transfer.block,
+ texture->width[level]), 32);
trans->transfer.usage = usage;
trans->offset = offset;
}
diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c
index 68da0aa4cbb..a02fb34b2a7 100644
--- a/src/gallium/drivers/r300/r300_state.c
+++ b/src/gallium/drivers/r300/r300_state.c
@@ -32,6 +32,7 @@
#include "r300_reg.h"
#include "r300_state_inlines.h"
#include "r300_fs.h"
+#include "r300_vs.h"
/* r300_state: Functions used to intialize state context by translating
* Gallium state objects into semi-native r300 state objects. */
@@ -137,7 +138,6 @@ static void
const struct pipe_constant_buffer* buffer)
{
struct r300_context* r300 = r300_context(pipe);
- int i = r300->shader_constants[shader].user_count;
/* This entire chunk of code seems ever-so-slightly baked.
* It's as if I've got pipe_buffer* matryoshkas... */
@@ -148,26 +148,13 @@ static void
map, buffer->buffer->size);
pipe->winsys->buffer_unmap(pipe->winsys, buffer->buffer);
- r300->shader_constants[shader].user_count =
+ r300->shader_constants[shader].count =
buffer->buffer->size / (sizeof(float) * 4);
} else {
- r300->shader_constants[shader].user_count = 0;
+ r300->shader_constants[shader].count = 0;
}
r300->dirty_state |= R300_NEW_CONSTANTS;
-
- /* If the number of constants have changed, invalidate the shader. */
- if (r300->shader_constants[shader].user_count != i) {
- if (shader == PIPE_SHADER_FRAGMENT && r300->fs &&
- r300->fs->uses_imms) {
- r300->fs->translated = FALSE;
- r300_translate_fragment_shader(r300, r300->fs);
- } else if (shader == PIPE_SHADER_VERTEX && r300->vs &&
- r300->vs->uses_imms) {
- r300->vs->translated = FALSE;
- r300_translate_vertex_shader(r300, r300->vs);
- }
- }
}
/* Create a new depth, stencil, and alpha state based on the CSO dsa state.
@@ -284,14 +271,9 @@ static void
static void* r300_create_fs_state(struct pipe_context* pipe,
const struct pipe_shader_state* shader)
{
- struct r300_context* r300 = r300_context(pipe);
struct r300_fragment_shader* fs = NULL;
- if (r300_screen(r300->context.screen)->caps->is_r500) {
- fs = (struct r300_fragment_shader*)CALLOC_STRUCT(r5xx_fragment_shader);
- } else {
- fs = (struct r300_fragment_shader*)CALLOC_STRUCT(r3xx_fragment_shader);
- }
+ fs = (struct r300_fragment_shader*)CALLOC_STRUCT(r300_fragment_shader);
/* Copy state directly into shader. */
fs->state = *shader;
@@ -315,7 +297,6 @@ static void r300_bind_fs_state(struct pipe_context* pipe, void* shader)
r300_translate_fragment_shader(r300, fs);
}
- fs->translated = TRUE;
r300->fs = fs;
r300->dirty_state |= R300_NEW_FRAGMENT_SHADER;
@@ -325,6 +306,7 @@ static void r300_bind_fs_state(struct pipe_context* pipe, void* shader)
static void r300_delete_fs_state(struct pipe_context* pipe, void* shader)
{
struct r300_fragment_shader* fs = (struct r300_fragment_shader*)shader;
+ rc_constants_destroy(&fs->code.constants);
FREE(fs->state.tokens);
FREE(shader);
}
@@ -688,6 +670,7 @@ static void r300_delete_vs_state(struct pipe_context* pipe, void* shader)
if (r300_screen(pipe->screen)->caps->has_tcl) {
struct r300_vertex_shader* vs = (struct r300_vertex_shader*)shader;
+ rc_constants_destroy(&vs->code.constants);
draw_delete_vertex_shader(r300->draw, vs->draw);
FREE(vs->state.tokens);
FREE(shader);
diff --git a/src/gallium/drivers/r300/r300_state_derived.c b/src/gallium/drivers/r300/r300_state_derived.c
index 2477b30822b..ea670f41fb5 100644
--- a/src/gallium/drivers/r300/r300_state_derived.c
+++ b/src/gallium/drivers/r300/r300_state_derived.c
@@ -22,6 +22,9 @@
#include "r300_state_derived.h"
+#include "r300_fs.h"
+#include "r300_vs.h"
+
/* r300_state_derived: Various bits of state which are dependent upon
* currently bound CSO data. */
diff --git a/src/gallium/drivers/r300/r300_state_invariant.c b/src/gallium/drivers/r300/r300_state_invariant.c
index 430129d5bd2..1e92374a4e9 100644
--- a/src/gallium/drivers/r300/r300_state_invariant.c
+++ b/src/gallium/drivers/r300/r300_state_invariant.c
@@ -34,7 +34,7 @@ void r300_emit_invariant_state(struct r300_context* r300)
struct r300_capabilities* caps = r300_screen(r300->context.screen)->caps;
CS_LOCALS(r300);
- BEGIN_CS(22 + (caps->has_tcl ? 2: 0));
+ BEGIN_CS(24 + (caps->has_tcl ? 2: 0));
/*** Graphics Backend (GB) ***/
/* Various GB enables */
@@ -56,6 +56,7 @@ void r300_emit_invariant_state(struct r300_context* r300)
OUT_CS_REG(R300_FG_FOG_COLOR_G, 0x0);
OUT_CS_REG(R300_FG_FOG_COLOR_B, 0x0);
OUT_CS_REG(R300_FG_DEPTH_SRC, 0x0);
+ OUT_CS_REG(R300_US_W_FMT, 0x0);
/*** VAP ***/
/* Max and min vertex index clamp. */
@@ -72,7 +73,7 @@ void r300_emit_invariant_state(struct r300_context* r300)
END_CS;
/* XXX unsorted stuff from surface_fill */
- BEGIN_CS(71 + (caps->has_tcl ? 5 : 0) + (caps->is_r500 ? 4 : 0));
+ BEGIN_CS(64 + (caps->has_tcl ? 5 : 0) + (caps->is_r500 ? 4 : 0));
/* Flush PVS. */
OUT_CS_REG(R300_VAP_PVS_STATE_FLUSH_REG, 0x0);
@@ -132,11 +133,5 @@ void r300_emit_invariant_state(struct r300_context* r300)
/* XXX */
OUT_CS_REG(R300_SC_CLIP_RULE, 0xaaaa);
- OUT_CS_REG_SEQ(R300_US_OUT_FMT_0, 4);
- OUT_CS(R300_C0_SEL_B | R300_C1_SEL_G | R300_C2_SEL_R | R300_C3_SEL_A);
- OUT_CS(R300_US_OUT_FMT_UNUSED);
- OUT_CS(R300_US_OUT_FMT_UNUSED);
- OUT_CS(R300_US_OUT_FMT_UNUSED);
- OUT_CS_REG(R300_US_W_FMT, R300_W_FMT_W0);
END_CS;
}
diff --git a/src/gallium/drivers/r300/r300_surface.c b/src/gallium/drivers/r300/r300_surface.c
index fdabe4d9cfe..a093f839454 100644
--- a/src/gallium/drivers/r300/r300_surface.c
+++ b/src/gallium/drivers/r300/r300_surface.c
@@ -37,7 +37,7 @@ static void r300_surface_setup(struct r300_context* r300,
r300_emit_dsa_state(r300, &dsa_clear_state);
r300_emit_rs_state(r300, &rs_clear_state);
- BEGIN_CS(24);
+ BEGIN_CS(26);
/* Viewport setup */
OUT_CS_REG_SEQ(R300_SE_VPORT_XSCALE, 6);
@@ -78,8 +78,10 @@ static void r300_surface_setup(struct r300_context* r300,
/* Setup colorbuffer. */
OUT_CS_REG_SEQ(R300_RB3D_COLOROFFSET0, 1);
OUT_CS_RELOC(dest->buffer, 0, 0, RADEON_GEM_DOMAIN_VRAM, 0);
- OUT_CS_REG(R300_RB3D_COLORPITCH0, pixpitch |
- r300_translate_colorformat(dest->tex.format));
+ OUT_CS_REG_SEQ(R300_RB3D_COLORPITCH0, 1);
+ OUT_CS_RELOC(dest->buffer, pixpitch |
+ r300_translate_colorformat(dest->tex.format), 0,
+ RADEON_GEM_DOMAIN_VRAM, 0);
OUT_CS_REG(RB3D_COLOR_CHANNEL_MASK, 0xf);
END_CS;
@@ -125,9 +127,10 @@ validate:
r300->context.flush(&r300->context, 0, NULL);
goto validate;
}
- if (r300->winsys->validate(r300->winsys)) {
+ if (!r300->winsys->validate(r300->winsys)) {
r300->context.flush(&r300->context, 0, NULL);
if (invalid) {
+ debug_printf("r300: Stuck in validation loop, gonna fallback.");
goto fallback;
}
invalid = TRUE;
@@ -138,10 +141,14 @@ validate:
/* Vertex shader setup */
if (caps->has_tcl) {
- r300_emit_vertex_shader(r300, &r300_passthrough_vertex_shader);
+ r300_emit_vertex_program_code(r300, &r300_passthrough_vertex_shader, 0);
} else {
BEGIN_CS(4);
- OUT_CS_REG(R300_VAP_CNTL_STATUS, R300_VAP_TCL_BYPASS);
+ OUT_CS_REG(R300_VAP_CNTL_STATUS,
+#ifdef PIPE_ARCH_BIG_ENDIAN
+ R300_VC_32BIT_SWAP |
+#endif
+ R300_VAP_TCL_BYPASS);
OUT_CS_REG(R300_VAP_CNTL, R300_PVS_NUM_SLOTS(5) |
R300_PVS_NUM_CNTLRS(5) |
R300_PVS_NUM_FPUS(caps->num_vert_fpus) |
@@ -151,10 +158,10 @@ validate:
/* Fragment shader setup */
if (caps->is_r500) {
- r500_emit_fragment_shader(r300, &r5xx_passthrough_fragment_shader);
+ r500_emit_fragment_program_code(r300, &r5xx_passthrough_fragment_shader, 0);
r300_emit_rs_block_state(r300, &r5xx_rs_block_clear_state);
} else {
- r300_emit_fragment_shader(r300, &r3xx_passthrough_fragment_shader);
+ r300_emit_fragment_program_code(r300, &r3xx_passthrough_fragment_shader, 0);
r300_emit_rs_block_state(r300, &r3xx_rs_block_clear_state);
}
@@ -256,9 +263,10 @@ validate:
r300->context.flush(&r300->context, 0, NULL);
goto validate;
}
- if (r300->winsys->validate(r300->winsys)) {
+ if (!r300->winsys->validate(r300->winsys)) {
r300->context.flush(&r300->context, 0, NULL);
if (invalid) {
+ debug_printf("r300: Stuck in validation loop, gonna fallback.");
goto fallback;
}
invalid = TRUE;
@@ -275,10 +283,14 @@ validate:
/* Vertex shader setup */
if (caps->has_tcl) {
- r300_emit_vertex_shader(r300, &r300_passthrough_vertex_shader);
+ r300_emit_vertex_program_code(r300, &r300_passthrough_vertex_shader, 0);
} else {
BEGIN_CS(4);
- OUT_CS_REG(R300_VAP_CNTL_STATUS, R300_VAP_TCL_BYPASS);
+ OUT_CS_REG(R300_VAP_CNTL_STATUS,
+#ifdef PIPE_ARCH_BIG_ENDIAN
+ R300_VC_32BIT_SWAP |
+#endif
+ R300_VAP_TCL_BYPASS);
OUT_CS_REG(R300_VAP_CNTL, R300_PVS_NUM_SLOTS(5) |
R300_PVS_NUM_CNTLRS(5) |
R300_PVS_NUM_FPUS(caps->num_vert_fpus) |
@@ -288,10 +300,10 @@ validate:
/* Fragment shader setup */
if (caps->is_r500) {
- r500_emit_fragment_shader(r300, &r5xx_texture_fragment_shader);
+ r500_emit_fragment_program_code(r300, &r5xx_texture_fragment_shader, 0);
r300_emit_rs_block_state(r300, &r5xx_rs_block_copy_state);
} else {
- r300_emit_fragment_shader(r300, &r3xx_texture_fragment_shader);
+ r300_emit_fragment_program_code(r300, &r3xx_texture_fragment_shader, 0);
r300_emit_rs_block_state(r300, &r3xx_rs_block_copy_state);
}
diff --git a/src/gallium/drivers/r300/r300_texture.c b/src/gallium/drivers/r300/r300_texture.c
index 11c7858d422..590052509cc 100644
--- a/src/gallium/drivers/r300/r300_texture.c
+++ b/src/gallium/drivers/r300/r300_texture.c
@@ -22,13 +22,6 @@
#include "r300_texture.h"
-/* XXX maths need to go to util */
-
-static int minify(int i)
-{
- return MAX2(1, i >> 1);
-}
-
static void r300_setup_texture_state(struct r300_texture* tex,
unsigned width,
unsigned height,
@@ -55,6 +48,9 @@ static void r300_setup_texture_state(struct r300_texture* tex,
if (height > 2048) {
state->format2 |= R500_TXHEIGHT_BIT11;
}
+
+ debug_printf("r300: Set texture state (%dx%d, pitch %d, %d levels)\n",
+ width, height, pitch, levels);
}
static void r300_setup_miptree(struct r300_texture* tex)
@@ -71,19 +67,23 @@ static void r300_setup_miptree(struct r300_texture* tex)
}
base->nblocksx[i] = pf_get_nblocksx(&base->block, base->width[i]);
- base->nblocksy[i] = pf_get_nblocksy(&base->block, base->width[i]);
+ base->nblocksy[i] = pf_get_nblocksy(&base->block, base->height[i]);
/* Radeons enjoy things in multiples of 64.
*
* XXX
* POT, uncompressed, unmippmapped textures can be aligned to 32,
* instead of 64. */
- stride = align(base->nblocksx[i] * base->block.size, 64);
+ stride = align(pf_get_stride(&base->block, base->width[i]), 32);
size = stride * base->nblocksy[i] * base->depth[i];
- tex->offset[i] = align(tex->size, 64);
+ tex->offset[i] = align(tex->size, 32);
tex->size = tex->offset[i] + size;
+ debug_printf("r300: Texture miptree: Level %d "
+ "(%dx%dx%d px, pitch %d bytes)\n",
+ i, base->width[i], base->height[i], base->depth[i],
+ stride);
/* Save stride of first level to the texture. */
if (i == 0) {
tex->stride = stride;
@@ -111,7 +111,7 @@ static struct pipe_texture*
r300_setup_texture_state(tex, template->width[0], template->height[0],
template->width[0], template->last_level);
- tex->buffer = screen->buffer_create(screen, 64,
+ tex->buffer = screen->buffer_create(screen, 1024,
PIPE_BUFFER_USAGE_PIXEL,
tex->size);
diff --git a/src/gallium/drivers/r300/r300_tgsi_to_rc.c b/src/gallium/drivers/r300/r300_tgsi_to_rc.c
new file mode 100644
index 00000000000..3adbb715f37
--- /dev/null
+++ b/src/gallium/drivers/r300/r300_tgsi_to_rc.c
@@ -0,0 +1,337 @@
+/*
+ * Copyright 2009 Nicolai Hähnle <[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 COPYRIGHT HOLDER(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. */
+
+#include "r300_tgsi_to_rc.h"
+
+#include "radeon_compiler.h"
+#include "radeon_program.h"
+
+#include "tgsi/tgsi_parse.h"
+#include "tgsi/tgsi_scan.h"
+#include "tgsi/tgsi_util.h"
+
+
+static unsigned translate_opcode(unsigned opcode)
+{
+ switch(opcode) {
+ case TGSI_OPCODE_ARL: return OPCODE_ARL;
+ case TGSI_OPCODE_MOV: return OPCODE_MOV;
+ case TGSI_OPCODE_LIT: return OPCODE_LIT;
+ case TGSI_OPCODE_RCP: return OPCODE_RCP;
+ case TGSI_OPCODE_RSQ: return OPCODE_RSQ;
+ case TGSI_OPCODE_EXP: return OPCODE_EXP;
+ case TGSI_OPCODE_LOG: return OPCODE_LOG;
+ case TGSI_OPCODE_MUL: return OPCODE_MUL;
+ case TGSI_OPCODE_ADD: return OPCODE_ADD;
+ case TGSI_OPCODE_DP3: return OPCODE_DP3;
+ case TGSI_OPCODE_DP4: return OPCODE_DP4;
+ case TGSI_OPCODE_DST: return OPCODE_DST;
+ case TGSI_OPCODE_MIN: return OPCODE_MIN;
+ case TGSI_OPCODE_MAX: return OPCODE_MAX;
+ case TGSI_OPCODE_SLT: return OPCODE_SLT;
+ case TGSI_OPCODE_SGE: return OPCODE_SGE;
+ case TGSI_OPCODE_MAD: return OPCODE_MAD;
+ case TGSI_OPCODE_SUB: return OPCODE_SUB;
+ case TGSI_OPCODE_LRP: return OPCODE_LRP;
+ /* case TGSI_OPCODE_CND: return OPCODE_CND; */
+ /* case TGSI_OPCODE_CND0: return OPCODE_CND0; */
+ case TGSI_OPCODE_DP2A: return OPCODE_DP2A;
+ /* gap */
+ case TGSI_OPCODE_FRC: return OPCODE_FRC;
+ /* case TGSI_OPCODE_CLAMP: return OPCODE_CLAMP; */
+ case TGSI_OPCODE_FLR: return OPCODE_FLR;
+ /* case TGSI_OPCODE_ROUND: return OPCODE_ROUND; */
+ case TGSI_OPCODE_EX2: return OPCODE_EX2;
+ case TGSI_OPCODE_LG2: return OPCODE_LG2;
+ case TGSI_OPCODE_POW: return OPCODE_POW;
+ case TGSI_OPCODE_XPD: return OPCODE_XPD;
+ /* gap */
+ case TGSI_OPCODE_ABS: return OPCODE_ABS;
+ case TGSI_OPCODE_RCC: return OPCODE_RCC;
+ case TGSI_OPCODE_DPH: return OPCODE_DPH;
+ case TGSI_OPCODE_COS: return OPCODE_COS;
+ case TGSI_OPCODE_DDX: return OPCODE_DDX;
+ case TGSI_OPCODE_DDY: return OPCODE_DDY;
+ /* case TGSI_OPCODE_KILP: return OPCODE_KILP; */
+ case TGSI_OPCODE_PK2H: return OPCODE_PK2H;
+ case TGSI_OPCODE_PK2US: return OPCODE_PK2US;
+ case TGSI_OPCODE_PK4B: return OPCODE_PK4B;
+ case TGSI_OPCODE_PK4UB: return OPCODE_PK4UB;
+ case TGSI_OPCODE_RFL: return OPCODE_RFL;
+ case TGSI_OPCODE_SEQ: return OPCODE_SEQ;
+ case TGSI_OPCODE_SFL: return OPCODE_SFL;
+ case TGSI_OPCODE_SGT: return OPCODE_SGT;
+ case TGSI_OPCODE_SIN: return OPCODE_SIN;
+ case TGSI_OPCODE_SLE: return OPCODE_SLE;
+ case TGSI_OPCODE_SNE: return OPCODE_SNE;
+ case TGSI_OPCODE_STR: return OPCODE_STR;
+ case TGSI_OPCODE_TEX: return OPCODE_TEX;
+ case TGSI_OPCODE_TXD: return OPCODE_TXD;
+ case TGSI_OPCODE_TXP: return OPCODE_TXP;
+ case TGSI_OPCODE_UP2H: return OPCODE_UP2H;
+ case TGSI_OPCODE_UP2US: return OPCODE_UP2US;
+ case TGSI_OPCODE_UP4B: return OPCODE_UP4B;
+ case TGSI_OPCODE_UP4UB: return OPCODE_UP4UB;
+ case TGSI_OPCODE_X2D: return OPCODE_X2D;
+ case TGSI_OPCODE_ARA: return OPCODE_ARA;
+ case TGSI_OPCODE_ARR: return OPCODE_ARR;
+ case TGSI_OPCODE_BRA: return OPCODE_BRA;
+ case TGSI_OPCODE_CAL: return OPCODE_CAL;
+ case TGSI_OPCODE_RET: return OPCODE_RET;
+ case TGSI_OPCODE_SSG: return OPCODE_SSG;
+ case TGSI_OPCODE_CMP: return OPCODE_CMP;
+ case TGSI_OPCODE_SCS: return OPCODE_SCS;
+ case TGSI_OPCODE_TXB: return OPCODE_TXB;
+ /* case TGSI_OPCODE_NRM: return OPCODE_NRM; */
+ /* case TGSI_OPCODE_DIV: return OPCODE_DIV; */
+ case TGSI_OPCODE_DP2: return OPCODE_DP2;
+ case TGSI_OPCODE_TXL: return OPCODE_TXL;
+ case TGSI_OPCODE_BRK: return OPCODE_BRK;
+ case TGSI_OPCODE_IF: return OPCODE_IF;
+ /* case TGSI_OPCODE_LOOP: return OPCODE_LOOP; */
+ /* case TGSI_OPCODE_REP: return OPCODE_REP; */
+ case TGSI_OPCODE_ELSE: return OPCODE_ELSE;
+ case TGSI_OPCODE_ENDIF: return OPCODE_ENDIF;
+ case TGSI_OPCODE_ENDLOOP: return OPCODE_ENDLOOP;
+ /* case TGSI_OPCODE_ENDREP: return OPCODE_ENDREP; */
+ case TGSI_OPCODE_PUSHA: return OPCODE_PUSHA;
+ case TGSI_OPCODE_POPA: return OPCODE_POPA;
+ /* case TGSI_OPCODE_CEIL: return OPCODE_CEIL; */
+ /* case TGSI_OPCODE_I2F: return OPCODE_I2F; */
+ case TGSI_OPCODE_NOT: return OPCODE_NOT;
+ case TGSI_OPCODE_TRUNC: return OPCODE_TRUNC;
+ /* case TGSI_OPCODE_SHL: return OPCODE_SHL; */
+ /* case TGSI_OPCODE_SHR: return OPCODE_SHR; */
+ case TGSI_OPCODE_AND: return OPCODE_AND;
+ case TGSI_OPCODE_OR: return OPCODE_OR;
+ /* case TGSI_OPCODE_MOD: return OPCODE_MOD; */
+ case TGSI_OPCODE_XOR: return OPCODE_XOR;
+ /* case TGSI_OPCODE_SAD: return OPCODE_SAD; */
+ /* case TGSI_OPCODE_TXF: return OPCODE_TXF; */
+ /* case TGSI_OPCODE_TXQ: return OPCODE_TXQ; */
+ case TGSI_OPCODE_CONT: return OPCODE_CONT;
+ /* case TGSI_OPCODE_EMIT: return OPCODE_EMIT; */
+ /* case TGSI_OPCODE_ENDPRIM: return OPCODE_ENDPRIM; */
+ /* case TGSI_OPCODE_BGNLOOP2: return OPCODE_BGNLOOP2; */
+ case TGSI_OPCODE_BGNSUB: return OPCODE_BGNSUB;
+ /* case TGSI_OPCODE_ENDLOOP2: return OPCODE_ENDLOOP2; */
+ case TGSI_OPCODE_ENDSUB: return OPCODE_ENDSUB;
+ case TGSI_OPCODE_NOISE1: return OPCODE_NOISE1;
+ case TGSI_OPCODE_NOISE2: return OPCODE_NOISE2;
+ case TGSI_OPCODE_NOISE3: return OPCODE_NOISE3;
+ case TGSI_OPCODE_NOISE4: return OPCODE_NOISE4;
+ case TGSI_OPCODE_NOP: return OPCODE_NOP;
+ /* gap */
+ case TGSI_OPCODE_NRM4: return OPCODE_NRM4;
+ /* case TGSI_OPCODE_CALLNZ: return OPCODE_CALLNZ; */
+ /* case TGSI_OPCODE_IFC: return OPCODE_IFC; */
+ /* case TGSI_OPCODE_BREAKC: return OPCODE_BREAKC; */
+ case TGSI_OPCODE_KIL: return OPCODE_KIL;
+ case TGSI_OPCODE_END: return OPCODE_END;
+ case TGSI_OPCODE_SWZ: return OPCODE_SWZ;
+ }
+
+ fprintf(stderr, "Unknown opcode: %i\n", opcode);
+ abort();
+}
+
+static unsigned translate_saturate(unsigned saturate)
+{
+ switch(saturate) {
+ case TGSI_SAT_NONE: return SATURATE_OFF;
+ case TGSI_SAT_ZERO_ONE: return SATURATE_ZERO_ONE;
+ case TGSI_SAT_MINUS_PLUS_ONE: return SATURATE_PLUS_MINUS_ONE;
+ }
+
+ fprintf(stderr, "Unknown saturate mode: %i\n", saturate);
+ abort();
+}
+
+static unsigned translate_register_file(unsigned file)
+{
+ switch(file) {
+ case TGSI_FILE_CONSTANT: return PROGRAM_CONSTANT;
+ case TGSI_FILE_IMMEDIATE: return PROGRAM_CONSTANT;
+ case TGSI_FILE_INPUT: return PROGRAM_INPUT;
+ case TGSI_FILE_OUTPUT: return PROGRAM_OUTPUT;
+ case TGSI_FILE_TEMPORARY: return PROGRAM_TEMPORARY;
+ case TGSI_FILE_ADDRESS: return PROGRAM_ADDRESS;
+ }
+
+ fprintf(stderr, "Unhandled register file: %i\n", file);
+ abort();
+}
+
+static int translate_register_index(
+ struct tgsi_to_rc * ttr,
+ unsigned file,
+ int index)
+{
+ if (file == TGSI_FILE_IMMEDIATE)
+ return ttr->immediate_offset + index;
+
+ return index;
+}
+
+static void transform_dstreg(
+ struct tgsi_to_rc * ttr,
+ struct prog_dst_register * dst,
+ struct tgsi_full_dst_register * src)
+{
+ dst->File = translate_register_file(src->DstRegister.File);
+ dst->Index = translate_register_index(ttr, src->DstRegister.File, src->DstRegister.Index);
+ dst->WriteMask = src->DstRegister.WriteMask;
+ dst->RelAddr = src->DstRegister.Indirect;
+}
+
+static void transform_srcreg(
+ struct tgsi_to_rc * ttr,
+ struct prog_src_register * dst,
+ struct tgsi_full_src_register * src)
+{
+ dst->File = translate_register_file(src->SrcRegister.File);
+ dst->Index = translate_register_index(ttr, src->SrcRegister.File, src->SrcRegister.Index);
+ dst->RelAddr = src->SrcRegister.Indirect;
+ dst->Swizzle = tgsi_util_get_full_src_register_extswizzle(src, 0);
+ dst->Swizzle |= tgsi_util_get_full_src_register_extswizzle(src, 1) << 3;
+ dst->Swizzle |= tgsi_util_get_full_src_register_extswizzle(src, 2) << 6;
+ dst->Swizzle |= tgsi_util_get_full_src_register_extswizzle(src, 3) << 9;
+ dst->Abs = src->SrcRegisterExtMod.Absolute;
+ dst->Negate =
+ src->SrcRegisterExtSwz.NegateX |
+ (src->SrcRegisterExtSwz.NegateY << 1) |
+ (src->SrcRegisterExtSwz.NegateZ << 2) |
+ (src->SrcRegisterExtSwz.NegateW << 3);
+ dst->Negate ^= src->SrcRegister.Negate ? NEGATE_XYZW : 0;
+}
+
+static void transform_texture(struct rc_instruction * dst, struct tgsi_instruction_ext_texture src)
+{
+ switch(src.Texture) {
+ case TGSI_TEXTURE_1D:
+ dst->I.TexSrcTarget = TEXTURE_1D_INDEX;
+ break;
+ case TGSI_TEXTURE_2D:
+ dst->I.TexSrcTarget = TEXTURE_2D_INDEX;
+ break;
+ case TGSI_TEXTURE_3D:
+ dst->I.TexSrcTarget = TEXTURE_3D_INDEX;
+ break;
+ case TGSI_TEXTURE_CUBE:
+ dst->I.TexSrcTarget = TEXTURE_CUBE_INDEX;
+ break;
+ case TGSI_TEXTURE_RECT:
+ dst->I.TexSrcTarget = TEXTURE_RECT_INDEX;
+ break;
+ case TGSI_TEXTURE_SHADOW1D:
+ dst->I.TexSrcTarget = TEXTURE_1D_INDEX;
+ dst->I.TexShadow = 1;
+ break;
+ case TGSI_TEXTURE_SHADOW2D:
+ dst->I.TexSrcTarget = TEXTURE_2D_INDEX;
+ dst->I.TexShadow = 1;
+ break;
+ case TGSI_TEXTURE_SHADOWRECT:
+ dst->I.TexSrcTarget = TEXTURE_RECT_INDEX;
+ dst->I.TexShadow = 1;
+ break;
+ }
+}
+
+static void transform_instruction(struct tgsi_to_rc * ttr, struct tgsi_full_instruction * src)
+{
+ if (src->Instruction.Opcode == TGSI_OPCODE_END)
+ return;
+
+ struct rc_instruction * dst = rc_insert_new_instruction(ttr->compiler, ttr->compiler->Program.Instructions.Prev);
+ int i;
+
+ dst->I.Opcode = translate_opcode(src->Instruction.Opcode);
+ dst->I.SaturateMode = translate_saturate(src->Instruction.Saturate);
+
+ if (src->Instruction.NumDstRegs)
+ transform_dstreg(ttr, &dst->I.DstReg, &src->FullDstRegisters[0]);
+
+ for(i = 0; i < src->Instruction.NumSrcRegs; ++i) {
+ if (src->FullSrcRegisters[i].SrcRegister.File == TGSI_FILE_SAMPLER)
+ dst->I.TexSrcUnit = src->FullSrcRegisters[i].SrcRegister.Index;
+ else
+ transform_srcreg(ttr, &dst->I.SrcReg[i], &src->FullSrcRegisters[i]);
+ }
+
+ /* Texturing. */
+ transform_texture(dst, src->InstructionExtTexture);
+}
+
+static void handle_immediate(struct tgsi_to_rc * ttr, struct tgsi_full_immediate * imm)
+{
+ struct rc_constant constant;
+ int i;
+
+ constant.Type = RC_CONSTANT_IMMEDIATE;
+ constant.Size = 4;
+ for(i = 0; i < 4; ++i)
+ constant.u.Immediate[i] = imm->u[i].Float;
+ rc_constants_add(&ttr->compiler->Program.Constants, &constant);
+}
+
+void r300_tgsi_to_rc(struct tgsi_to_rc * ttr, const struct tgsi_token * tokens)
+{
+ struct tgsi_parse_context parser;
+ int i;
+
+ /* Allocate constants placeholders.
+ *
+ * Note: What if declared constants are not contiguous? */
+ for(i = 0; i <= ttr->info->file_max[TGSI_FILE_CONSTANT]; ++i) {
+ struct rc_constant constant;
+ memset(&constant, 0, sizeof(constant));
+ constant.Type = RC_CONSTANT_EXTERNAL;
+ constant.Size = 4;
+ constant.u.External = i;
+ rc_constants_add(&ttr->compiler->Program.Constants, &constant);
+ }
+
+ ttr->immediate_offset = ttr->compiler->Program.Constants.Count;
+
+ tgsi_parse_init(&parser, tokens);
+
+ while (!tgsi_parse_end_of_tokens(&parser)) {
+ tgsi_parse_token(&parser);
+
+ switch (parser.FullToken.Token.Type) {
+ case TGSI_TOKEN_TYPE_DECLARATION:
+ break;
+ case TGSI_TOKEN_TYPE_IMMEDIATE:
+ handle_immediate(ttr, &parser.FullToken.FullImmediate);
+ break;
+ case TGSI_TOKEN_TYPE_INSTRUCTION:
+ transform_instruction(ttr, &parser.FullToken.FullInstruction);
+ break;
+ }
+ }
+
+ tgsi_parse_free(&parser);
+
+ rc_calculate_inputs_outputs(ttr->compiler);
+}
+
diff --git a/src/gallium/drivers/r300/r300_tgsi_to_rc.h b/src/gallium/drivers/r300/r300_tgsi_to_rc.h
new file mode 100644
index 00000000000..93e90ec6d2c
--- /dev/null
+++ b/src/gallium/drivers/r300/r300_tgsi_to_rc.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2009 Nicolai Hähnle <[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 COPYRIGHT HOLDER(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 R300_TGSI_TO_RC_H
+#define R300_TGSI_TO_RC_H
+
+struct radeon_compiler;
+
+struct tgsi_full_declaration;
+struct tgsi_shader_info;
+struct tgsi_token;
+
+struct tgsi_to_rc {
+ struct radeon_compiler * compiler;
+ const struct tgsi_shader_info * info;
+
+ int immediate_offset;
+};
+
+void r300_tgsi_to_rc(struct tgsi_to_rc * ttr, const struct tgsi_token * tokens);
+
+#endif /* R300_TGSI_TO_RC_H */
diff --git a/src/gallium/drivers/r300/r300_vs.c b/src/gallium/drivers/r300/r300_vs.c
index f87435f9f07..2cb903bba2f 100644
--- a/src/gallium/drivers/r300/r300_vs.c
+++ b/src/gallium/drivers/r300/r300_vs.c
@@ -22,391 +22,213 @@
#include "r300_vs.h"
-static void r300_vs_declare(struct r300_vs_asm* assembler,
- struct tgsi_full_declaration* decl)
-{
- switch (decl->Declaration.File) {
- case TGSI_FILE_INPUT:
- break;
- case TGSI_FILE_OUTPUT:
- switch (decl->Semantic.SemanticName) {
- case TGSI_SEMANTIC_POSITION:
- assembler->tab[decl->DeclarationRange.First] = 0;
- break;
- case TGSI_SEMANTIC_COLOR:
- assembler->tab[decl->DeclarationRange.First] =
- (assembler->point_size ? 1 : 0) +
- assembler->out_colors;
- break;
- case TGSI_SEMANTIC_FOG:
- case TGSI_SEMANTIC_GENERIC:
- /* XXX multiple? */
- assembler->tab[decl->DeclarationRange.First] =
- (assembler->point_size ? 1 : 0) +
- assembler->out_colors +
- assembler->out_texcoords;
- break;
- case TGSI_SEMANTIC_PSIZE:
- assembler->tab[decl->DeclarationRange.First] = 1;
- break;
- default:
- debug_printf("r300: vs: Bad semantic declaration %d\n",
- decl->Semantic.SemanticName);
- break;
- }
- break;
- case TGSI_FILE_CONSTANT:
- break;
- case TGSI_FILE_TEMPORARY:
- assembler->temp_count++;
- break;
- default:
- debug_printf("r300: vs: Bad file %d\n", decl->Declaration.File);
- break;
- }
-}
+#include "r300_context.h"
+#include "r300_tgsi_to_rc.h"
-static INLINE unsigned r300_vs_src_type(struct r300_vs_asm* assembler,
- struct tgsi_src_register* src)
-{
- switch (src->File) {
- case TGSI_FILE_NULL:
- case TGSI_FILE_INPUT:
- /* Probably a zero or one swizzle */
- return R300_PVS_SRC_REG_INPUT;
- case TGSI_FILE_TEMPORARY:
- return R300_PVS_SRC_REG_TEMPORARY;
- case TGSI_FILE_CONSTANT:
- case TGSI_FILE_IMMEDIATE:
- return R300_PVS_SRC_REG_CONSTANT;
- default:
- debug_printf("r300: vs: Unimplemented src type %d\n", src->File);
- break;
- }
- return 0;
-}
+#include "tgsi/tgsi_dump.h"
+#include "tgsi/tgsi_parse.h"
-static INLINE unsigned r300_vs_src(struct r300_vs_asm* assembler,
- struct tgsi_src_register* src)
-{
- switch (src->File) {
- case TGSI_FILE_NULL:
- case TGSI_FILE_INPUT:
- case TGSI_FILE_TEMPORARY:
- case TGSI_FILE_CONSTANT:
- return src->Index;
- case TGSI_FILE_IMMEDIATE:
- return src->Index + assembler->imm_offset;
- default:
- debug_printf("r300: vs: Unimplemented src type %d\n", src->File);
- break;
- }
- return 0;
-}
+#include "radeon_compiler.h"
-static INLINE unsigned r300_vs_dst_type(struct r300_vs_asm* assembler,
- struct tgsi_dst_register* dst)
-{
- switch (dst->File) {
- case TGSI_FILE_TEMPORARY:
- return R300_PVS_DST_REG_TEMPORARY;
- case TGSI_FILE_OUTPUT:
- return R300_PVS_DST_REG_OUT;
- default:
- debug_printf("r300: vs: Unimplemented dst type %d\n", dst->File);
- break;
- }
- return 0;
-}
-static INLINE unsigned r300_vs_dst(struct r300_vs_asm* assembler,
- struct tgsi_dst_register* dst)
+static void set_vertex_inputs_outputs(struct r300_vertex_program_compiler * c)
{
- switch (dst->File) {
- case TGSI_FILE_TEMPORARY:
- return dst->Index;
- case TGSI_FILE_OUTPUT:
- return assembler->tab[dst->Index];
- default:
- debug_printf("r300: vs: Unimplemented dst %d\n", dst->File);
- break;
- }
- return 0;
-}
+ struct r300_vertex_shader * vs = c->UserData;
+ struct tgsi_shader_info* info = &vs->info;
+ boolean pointsize = false;
+ int out_colors = 0;
+ int colors = 0;
+ int out_generic = 0;
+ int generic = 0;
+ int i;
-static uint32_t r300_vs_op(unsigned op)
-{
- switch (op) {
- case TGSI_OPCODE_DP3:
- case TGSI_OPCODE_DP4:
- return R300_VE_DOT_PRODUCT;
- case TGSI_OPCODE_MUL:
- return R300_VE_MULTIPLY;
- case TGSI_OPCODE_ADD:
- case TGSI_OPCODE_MOV:
- case TGSI_OPCODE_SUB:
- case TGSI_OPCODE_SWZ:
- return R300_VE_ADD;
- case TGSI_OPCODE_MAX:
- return R300_VE_MAXIMUM;
- case TGSI_OPCODE_SLT:
- return R300_VE_SET_LESS_THAN;
- case TGSI_OPCODE_RSQ:
- return R300_PVS_DST_MATH_INST | R300_ME_RECIP_DX;
- case TGSI_OPCODE_MAD:
- return R300_PVS_DST_MACRO_INST | R300_PVS_MACRO_OP_2CLK_MADD;
- default:
- break;
- }
- return 0;
-}
+ /* Fill in the input mapping */
+ for (i = 0; i < info->num_inputs; i++)
+ c->code->inputs[i] = i;
-static uint32_t r300_vs_swiz(struct tgsi_full_src_register* reg)
-{
- if (reg->SrcRegister.Extended) {
- return (reg->SrcRegister.Negate ? (0xf << 12) : 0) |
- reg->SrcRegisterExtSwz.ExtSwizzleX |
- (reg->SrcRegisterExtSwz.ExtSwizzleY << 3) |
- (reg->SrcRegisterExtSwz.ExtSwizzleZ << 6) |
- (reg->SrcRegisterExtSwz.ExtSwizzleW << 9);
- } else {
- return (reg->SrcRegister.Negate ? (0xf << 12) : 0) |
- reg->SrcRegister.SwizzleX |
- (reg->SrcRegister.SwizzleY << 3) |
- (reg->SrcRegister.SwizzleZ << 6) |
- (reg->SrcRegister.SwizzleW << 9);
+ /* Fill in the output mapping */
+ for (i = 0; i < info->num_outputs; i++) {
+ switch (info->output_semantic_name[i]) {
+ case TGSI_SEMANTIC_PSIZE:
+ pointsize = true;
+ break;
+ case TGSI_SEMANTIC_COLOR:
+ out_colors++;
+ break;
+ case TGSI_SEMANTIC_FOG:
+ case TGSI_SEMANTIC_GENERIC:
+ out_generic++;
+ break;
+ }
}
-}
-/* XXX icky icky icky icky */
-static uint32_t r300_vs_scalar_swiz(struct tgsi_full_src_register* reg)
-{
- if (reg->SrcRegister.Extended) {
- return (reg->SrcRegister.Negate ? (0xf << 12) : 0) |
- reg->SrcRegisterExtSwz.ExtSwizzleX |
- (reg->SrcRegisterExtSwz.ExtSwizzleX << 3) |
- (reg->SrcRegisterExtSwz.ExtSwizzleX << 6) |
- (reg->SrcRegisterExtSwz.ExtSwizzleX << 9);
- } else {
- return (reg->SrcRegister.Negate ? (0xf << 12) : 0) |
- reg->SrcRegister.SwizzleX |
- (reg->SrcRegister.SwizzleX << 3) |
- (reg->SrcRegister.SwizzleX << 6) |
- (reg->SrcRegister.SwizzleX << 9);
- }
-}
+ struct tgsi_parse_context parser;
-/* XXX scalar stupidity */
-static void r300_vs_emit_inst(struct r300_vertex_shader* vs,
- struct r300_vs_asm* assembler,
- struct tgsi_full_src_register* src,
- struct tgsi_full_dst_register* dst,
- unsigned op,
- unsigned count,
- boolean is_scalar)
-{
- int i = vs->instruction_count;
- vs->instructions[i].inst0 = R300_PVS_DST_OPCODE(r300_vs_op(op)) |
- R300_PVS_DST_REG_TYPE(r300_vs_dst_type(assembler, &dst->DstRegister)) |
- R300_PVS_DST_OFFSET(r300_vs_dst(assembler, &dst->DstRegister)) |
- R300_PVS_DST_WE(dst->DstRegister.WriteMask);
- switch (count) {
- case 3:
- vs->instructions[i].inst3 =
- R300_PVS_SRC_REG_TYPE(r300_vs_src_type(assembler,
- &src[2].SrcRegister)) |
- R300_PVS_SRC_OFFSET(r300_vs_src(assembler,
- &src[2].SrcRegister)) |
- R300_PVS_SRC_SWIZZLE(r300_vs_swiz(&src[2]));
- /* Fall through */
- case 2:
- vs->instructions[i].inst2 =
- R300_PVS_SRC_REG_TYPE(r300_vs_src_type(assembler,
- &src[1].SrcRegister)) |
- R300_PVS_SRC_OFFSET(r300_vs_src(assembler,
- &src[1].SrcRegister)) |
- R300_PVS_SRC_SWIZZLE(r300_vs_swiz(&src[1]));
- /* Fall through */
- case 1:
- vs->instructions[i].inst1 =
- R300_PVS_SRC_REG_TYPE(r300_vs_src_type(assembler,
- &src[0].SrcRegister)) |
- R300_PVS_SRC_OFFSET(r300_vs_src(assembler,
- &src[0].SrcRegister)) |
- /* XXX the icky, it burns */
- R300_PVS_SRC_SWIZZLE(is_scalar ? r300_vs_scalar_swiz(&src[0])
- : r300_vs_swiz(&src[0]));
- break;
- }
- vs->instruction_count++;
-}
+ tgsi_parse_init(&parser, vs->state.tokens);
-static void r300_vs_instruction(struct r300_vertex_shader* vs,
- struct r300_vs_asm* assembler,
- struct tgsi_full_instruction* inst)
-{
- switch (inst->Instruction.Opcode) {
- case TGSI_OPCODE_RSQ:
- r300_vs_emit_inst(vs, assembler, inst->FullSrcRegisters,
- &inst->FullDstRegisters[0], inst->Instruction.Opcode,
- 1, TRUE);
- break;
- case TGSI_OPCODE_SUB:
- inst->FullSrcRegisters[1].SrcRegister.Negate =
- !inst->FullSrcRegisters[1].SrcRegister.Negate;
- /* Fall through */
- case TGSI_OPCODE_ADD:
- case TGSI_OPCODE_MUL:
- case TGSI_OPCODE_MAX:
- case TGSI_OPCODE_SLT:
- r300_vs_emit_inst(vs, assembler, inst->FullSrcRegisters,
- &inst->FullDstRegisters[0], inst->Instruction.Opcode,
- 2, FALSE);
- break;
- case TGSI_OPCODE_DP3:
- /* Set alpha swizzle to zero for src0 and src1 */
- if (!inst->FullSrcRegisters[0].SrcRegister.Extended) {
- inst->FullSrcRegisters[0].SrcRegister.Extended = TRUE;
- inst->FullSrcRegisters[0].SrcRegisterExtSwz.ExtSwizzleX =
- inst->FullSrcRegisters[0].SrcRegister.SwizzleX;
- inst->FullSrcRegisters[0].SrcRegisterExtSwz.ExtSwizzleY =
- inst->FullSrcRegisters[0].SrcRegister.SwizzleY;
- inst->FullSrcRegisters[0].SrcRegisterExtSwz.ExtSwizzleZ =
- inst->FullSrcRegisters[0].SrcRegister.SwizzleZ;
- }
- inst->FullSrcRegisters[0].SrcRegisterExtSwz.ExtSwizzleW =
- TGSI_EXTSWIZZLE_ZERO;
- if (!inst->FullSrcRegisters[1].SrcRegister.Extended) {
- inst->FullSrcRegisters[1].SrcRegister.Extended = TRUE;
- inst->FullSrcRegisters[1].SrcRegisterExtSwz.ExtSwizzleX =
- inst->FullSrcRegisters[1].SrcRegister.SwizzleX;
- inst->FullSrcRegisters[1].SrcRegisterExtSwz.ExtSwizzleY =
- inst->FullSrcRegisters[1].SrcRegister.SwizzleY;
- inst->FullSrcRegisters[1].SrcRegisterExtSwz.ExtSwizzleZ =
- inst->FullSrcRegisters[1].SrcRegister.SwizzleZ;
- }
- inst->FullSrcRegisters[1].SrcRegisterExtSwz.ExtSwizzleW =
- TGSI_EXTSWIZZLE_ZERO;
- /* Fall through */
- case TGSI_OPCODE_DP4:
- r300_vs_emit_inst(vs, assembler, inst->FullSrcRegisters,
- &inst->FullDstRegisters[0], inst->Instruction.Opcode,
- 2, FALSE);
- break;
- case TGSI_OPCODE_MOV:
- case TGSI_OPCODE_SWZ:
- inst->FullSrcRegisters[1] = r300_constant_zero;
- r300_vs_emit_inst(vs, assembler, inst->FullSrcRegisters,
- &inst->FullDstRegisters[0], inst->Instruction.Opcode,
- 2, FALSE);
- break;
- case TGSI_OPCODE_MAD:
- r300_vs_emit_inst(vs, assembler, inst->FullSrcRegisters,
- &inst->FullDstRegisters[0], inst->Instruction.Opcode,
- 3, FALSE);
- break;
- case TGSI_OPCODE_END:
- break;
- default:
- debug_printf("r300: vs: Bad opcode %d\n",
- inst->Instruction.Opcode);
- break;
- }
-}
+ while (!tgsi_parse_end_of_tokens(&parser)) {
+ tgsi_parse_token(&parser);
-static void r300_vs_init(struct r300_vertex_shader* vs,
- struct r300_vs_asm* assembler)
-{
- struct tgsi_shader_info* info = &vs->info;
- int i;
+ if (parser.FullToken.Token.Type != TGSI_TOKEN_TYPE_DECLARATION)
+ continue;
- for (i = 0; i < info->num_outputs; i++) {
- switch (info->output_semantic_name[i]) {
+ struct tgsi_full_declaration * decl = &parser.FullToken.FullDeclaration;
+
+ if (decl->Declaration.File != TGSI_FILE_OUTPUT)
+ continue;
+
+ switch (decl->Semantic.SemanticName) {
+ case TGSI_SEMANTIC_POSITION:
+ c->code->outputs[decl->DeclarationRange.First] = 0;
+ break;
case TGSI_SEMANTIC_PSIZE:
- assembler->point_size = TRUE;
+ c->code->outputs[decl->DeclarationRange.First] = 1;
break;
case TGSI_SEMANTIC_COLOR:
- assembler->out_colors++;
+ c->code->outputs[decl->DeclarationRange.First] = 1 +
+ (pointsize ? 1 : 0) +
+ colors++;
break;
case TGSI_SEMANTIC_FOG:
case TGSI_SEMANTIC_GENERIC:
- assembler->out_texcoords++;
+ c->code->outputs[decl->DeclarationRange.First] = 1 +
+ (pointsize ? 1 : 0) +
+ out_colors +
+ generic++;
+ break;
+ default:
+ debug_printf("r300: vs: Bad semantic declaration %d\n",
+ decl->Semantic.SemanticName);
break;
}
}
- vs->instruction_count = 0;
+ tgsi_parse_free(&parser);
}
+
void r300_translate_vertex_shader(struct r300_context* r300,
struct r300_vertex_shader* vs)
{
- struct tgsi_parse_context parser;
- int i;
- struct r300_constant_buffer* consts =
- &r300->shader_constants[PIPE_SHADER_VERTEX];
+ struct r300_vertex_program_compiler compiler;
+ struct tgsi_to_rc ttr;
- struct r300_vs_asm* assembler = CALLOC_STRUCT(r300_vs_asm);
- if (assembler == NULL) {
- return;
- }
+ /* Setup the compiler */
+ rc_init(&compiler.Base);
- /* Init assembler. */
- r300_vs_init(vs, assembler);
+ compiler.Base.Debug = 1;
+ compiler.code = &vs->code;
+ compiler.UserData = vs;
- /* Setup starting offset for immediates. */
- assembler->imm_offset = consts->user_count;
+ if (compiler.Base.Debug) {
+ debug_printf("r300: Initial vertex program\n");
+ tgsi_dump(vs->state.tokens, 0);
+ }
- tgsi_parse_init(&parser, vs->state.tokens);
+ /* Translate TGSI to our internal representation */
+ ttr.compiler = &compiler.Base;
+ ttr.info = &vs->info;
- while (!tgsi_parse_end_of_tokens(&parser)) {
- tgsi_parse_token(&parser);
+ r300_tgsi_to_rc(&ttr, vs->state.tokens);
- /* This is seriously the lamest way to create fragment programs ever.
- * I blame TGSI. */
- switch (parser.FullToken.Token.Type) {
- case TGSI_TOKEN_TYPE_DECLARATION:
- /* Allocated registers sitting at the beginning
- * of the program. */
- r300_vs_declare(assembler, &parser.FullToken.FullDeclaration);
- break;
- case TGSI_TOKEN_TYPE_IMMEDIATE:
- debug_printf("r300: Emitting immediate to constant buffer, "
- "position %d\n",
- assembler->imm_offset + assembler->imm_count);
- /* I am not amused by the length of these. */
- for (i = 0; i < 4; i++) {
- consts->constants[assembler->imm_offset +
- assembler->imm_count][i] =
- parser.FullToken.FullImmediate.u.ImmediateFloat32[i]
- .Float;
- }
- assembler->imm_count++;
- break;
- case TGSI_TOKEN_TYPE_INSTRUCTION:
- r300_vs_instruction(vs, assembler,
- &parser.FullToken.FullInstruction);
- break;
- }
- }
+ compiler.RequiredOutputs = ~(~0 << vs->info.num_outputs);
+ compiler.SetHwInputOutput = &set_vertex_inputs_outputs;
- debug_printf("r300: vs: %d texs and %d colors, first free reg is %d\n",
- assembler->tex_count, assembler->color_count,
- assembler->tex_count + assembler->color_count);
+ /* Invoke the compiler */
+ r3xx_compile_vertex_program(&compiler);
+ if (compiler.Base.Error) {
+ /* Todo: Fail gracefully */
+ fprintf(stderr, "r300 VP: Compiler error\n");
+ abort();
+ }
- consts->count = consts->user_count + assembler->imm_count;
- vs->uses_imms = assembler->imm_count;
- debug_printf("r300: vs: %d total constants, "
- "%d from user and %d from immediates\n", consts->count,
- consts->user_count, assembler->imm_count);
+ /* And, finally... */
+ rc_destroy(&compiler.Base);
+ vs->translated = TRUE;
+}
- debug_printf("r300: vs: tab: %d %d %d %d\n", assembler->tab[0],
- assembler->tab[1], assembler->tab[2], assembler->tab[3]);
- tgsi_dump(vs->state.tokens, 0);
- /* XXX finish r300 vertex shader dumper */
- r300_vs_dump(vs);
+/* XXX get these to r300_reg */
+#define R300_PVS_DST_OPCODE(x) ((x) << 0)
+# define R300_VE_DOT_PRODUCT 1
+# define R300_VE_MULTIPLY 2
+# define R300_VE_ADD 3
+# define R300_VE_MAXIMUM 7
+# define R300_VE_SET_LESS_THAN 10
+#define R300_PVS_DST_MATH_INST (1 << 6)
+# define R300_ME_RECIP_DX 6
+#define R300_PVS_DST_MACRO_INST (1 << 7)
+# define R300_PVS_MACRO_OP_2CLK_MADD 0
+#define R300_PVS_DST_REG_TYPE(x) ((x) << 8)
+# define R300_PVS_DST_REG_TEMPORARY 0
+# define R300_PVS_DST_REG_A0 1
+# define R300_PVS_DST_REG_OUT 2
+# define R300_PVS_DST_REG_OUT_REPL_X 3
+# define R300_PVS_DST_REG_ALT_TEMPORARY 4
+# define R300_PVS_DST_REG_INPUT 5
+#define R300_PVS_DST_OFFSET(x) ((x) << 13)
+#define R300_PVS_DST_WE(x) ((x) << 20)
+#define R300_PVS_DST_WE_XYZW (0xf << 20)
+
+#define R300_PVS_SRC_REG_TYPE(x) ((x) << 0)
+# define R300_PVS_SRC_REG_TEMPORARY 0
+# define R300_PVS_SRC_REG_INPUT 1
+# define R300_PVS_SRC_REG_CONSTANT 2
+# define R300_PVS_SRC_REG_ALT_TEMPORARY 3
+#define R300_PVS_SRC_OFFSET(x) ((x) << 5)
+#define R300_PVS_SRC_SWIZZLE(x) ((x) << 13)
+# define R300_PVS_SRC_SELECT_X 0
+# define R300_PVS_SRC_SELECT_Y 1
+# define R300_PVS_SRC_SELECT_Z 2
+# define R300_PVS_SRC_SELECT_W 3
+# define R300_PVS_SRC_SELECT_FORCE_0 4
+# define R300_PVS_SRC_SELECT_FORCE_1 5
+# define R300_PVS_SRC_SWIZZLE_XYZW \
+ ((R300_PVS_SRC_SELECT_X | (R300_PVS_SRC_SELECT_Y << 3) | \
+ (R300_PVS_SRC_SELECT_Z << 6) | (R300_PVS_SRC_SELECT_W << 9)) << 13)
+# define R300_PVS_SRC_SWIZZLE_ZERO \
+ ((R300_PVS_SRC_SELECT_FORCE_0 | (R300_PVS_SRC_SELECT_FORCE_0 << 3) | \
+ (R300_PVS_SRC_SELECT_FORCE_0 << 6) | \
+ (R300_PVS_SRC_SELECT_FORCE_0 << 9)) << 13)
+# define R300_PVS_SRC_SWIZZLE_ONE \
+ ((R300_PVS_SRC_SELECT_FORCE_1 | (R300_PVS_SRC_SELECT_FORCE_1 << 3) | \
+ (R300_PVS_SRC_SELECT_FORCE_1 << 6) | \
+ (R300_PVS_SRC_SELECT_FORCE_1 << 9)) << 13)
+#define R300_PVS_MODIFIER_X (1 << 25)
+#define R300_PVS_MODIFIER_Y (1 << 26)
+#define R300_PVS_MODIFIER_Z (1 << 27)
+#define R300_PVS_MODIFIER_W (1 << 28)
+#define R300_PVS_NEGATE_XYZW \
+ (R300_PVS_MODIFIER_X | R300_PVS_MODIFIER_Y | \
+ R300_PVS_MODIFIER_Z | R300_PVS_MODIFIER_W)
+
+struct r300_vertex_program_code r300_passthrough_vertex_shader = {
+ .length = 8, /* two instructions */
+
+ /* MOV out[0], in[0] */
+ .body.d[0] = R300_PVS_DST_OPCODE(R300_VE_ADD) |
+ R300_PVS_DST_REG_TYPE(R300_PVS_DST_REG_OUT) |
+ R300_PVS_DST_OFFSET(0) | R300_PVS_DST_WE_XYZW,
+ .body.d[1] = R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) |
+ R300_PVS_SRC_OFFSET(0) | R300_PVS_SRC_SWIZZLE_XYZW,
+ .body.d[2] = R300_PVS_SRC_SWIZZLE_ZERO,
+ .body.d[3] = 0x0,
+
+ /* MOV out[1], in[1] */
+ .body.d[4] = R300_PVS_DST_OPCODE(R300_VE_ADD) |
+ R300_PVS_DST_REG_TYPE(R300_PVS_DST_REG_OUT) |
+ R300_PVS_DST_OFFSET(1) | R300_PVS_DST_WE_XYZW,
+ .body.d[5] = R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) |
+ R300_PVS_SRC_OFFSET(1) | R300_PVS_SRC_SWIZZLE_XYZW,
+ .body.d[6] = R300_PVS_SRC_SWIZZLE_ZERO,
+ .body.d[7] = 0x0,
+
+ .inputs[0] = 0,
+ .inputs[1] = 1,
+ .outputs[0] = 0,
+ .outputs[1] = 1,
+
+ .InputsRead = 3,
+ .OutputsWritten = 3
+};
- tgsi_parse_free(&parser);
- FREE(assembler);
-}
diff --git a/src/gallium/drivers/r300/r300_vs.h b/src/gallium/drivers/r300/r300_vs.h
index 165d7178122..2a4ce315e32 100644
--- a/src/gallium/drivers/r300/r300_vs.h
+++ b/src/gallium/drivers/r300/r300_vs.h
@@ -23,134 +23,31 @@
#ifndef R300_VS_H
#define R300_VS_H
-#include "tgsi/tgsi_parse.h"
-#include "tgsi/tgsi_dump.h"
+#include "pipe/p_state.h"
+#include "tgsi/tgsi_scan.h"
-#include "r300_context.h"
-#include "r300_debug.h"
-#include "r300_reg.h"
-#include "r300_screen.h"
-#include "r300_shader_inlines.h"
+#include "radeon_code.h"
-/* XXX get these to r300_reg */
-#define R300_PVS_DST_OPCODE(x) ((x) << 0)
-# define R300_VE_DOT_PRODUCT 1
-# define R300_VE_MULTIPLY 2
-# define R300_VE_ADD 3
-# define R300_VE_MAXIMUM 7
-# define R300_VE_SET_LESS_THAN 10
-#define R300_PVS_DST_MATH_INST (1 << 6)
-# define R300_ME_RECIP_DX 6
-#define R300_PVS_DST_MACRO_INST (1 << 7)
-# define R300_PVS_MACRO_OP_2CLK_MADD 0
-#define R300_PVS_DST_REG_TYPE(x) ((x) << 8)
-# define R300_PVS_DST_REG_TEMPORARY 0
-# define R300_PVS_DST_REG_A0 1
-# define R300_PVS_DST_REG_OUT 2
-# define R300_PVS_DST_REG_OUT_REPL_X 3
-# define R300_PVS_DST_REG_ALT_TEMPORARY 4
-# define R300_PVS_DST_REG_INPUT 5
-#define R300_PVS_DST_OFFSET(x) ((x) << 13)
-#define R300_PVS_DST_WE(x) ((x) << 20)
-#define R300_PVS_DST_WE_XYZW (0xf << 20)
+struct r300_context;
-#define R300_PVS_SRC_REG_TYPE(x) ((x) << 0)
-# define R300_PVS_SRC_REG_TEMPORARY 0
-# define R300_PVS_SRC_REG_INPUT 1
-# define R300_PVS_SRC_REG_CONSTANT 2
-# define R300_PVS_SRC_REG_ALT_TEMPORARY 3
-#define R300_PVS_SRC_OFFSET(x) ((x) << 5)
-#define R300_PVS_SRC_SWIZZLE(x) ((x) << 13)
-# define R300_PVS_SRC_SELECT_X 0
-# define R300_PVS_SRC_SELECT_Y 1
-# define R300_PVS_SRC_SELECT_Z 2
-# define R300_PVS_SRC_SELECT_W 3
-# define R300_PVS_SRC_SELECT_FORCE_0 4
-# define R300_PVS_SRC_SELECT_FORCE_1 5
-# define R300_PVS_SRC_SWIZZLE_XYZW \
- ((R300_PVS_SRC_SELECT_X | (R300_PVS_SRC_SELECT_Y << 3) | \
- (R300_PVS_SRC_SELECT_Z << 6) | (R300_PVS_SRC_SELECT_W << 9)) << 13)
-# define R300_PVS_SRC_SWIZZLE_ZERO \
- ((R300_PVS_SRC_SELECT_FORCE_0 | (R300_PVS_SRC_SELECT_FORCE_0 << 3) | \
- (R300_PVS_SRC_SELECT_FORCE_0 << 6) | \
- (R300_PVS_SRC_SELECT_FORCE_0 << 9)) << 13)
-# define R300_PVS_SRC_SWIZZLE_ONE \
- ((R300_PVS_SRC_SELECT_FORCE_1 | (R300_PVS_SRC_SELECT_FORCE_1 << 3) | \
- (R300_PVS_SRC_SELECT_FORCE_1 << 6) | \
- (R300_PVS_SRC_SELECT_FORCE_1 << 9)) << 13)
-#define R300_PVS_MODIFIER_X (1 << 25)
-#define R300_PVS_MODIFIER_Y (1 << 26)
-#define R300_PVS_MODIFIER_Z (1 << 27)
-#define R300_PVS_MODIFIER_W (1 << 28)
-#define R300_PVS_NEGATE_XYZW \
- (R300_PVS_MODIFIER_X | R300_PVS_MODIFIER_Y | \
- R300_PVS_MODIFIER_Z | R300_PVS_MODIFIER_W)
+struct r300_vertex_shader {
+ /* Parent class */
+ struct pipe_shader_state state;
+ struct tgsi_shader_info info;
-/* Temporary struct used to hold assembly state while putting together
- * fragment programs. */
-struct r300_vs_asm {
- /* Pipe context. */
- struct r300_context* r300;
- /* Number of colors. */
- unsigned color_count;
- /* Number of texcoords. */
- unsigned tex_count;
- /* Number of requested temporary registers. */
- unsigned temp_count;
- /* Offset for immediate constants. Neither R300 nor R500 can do four
- * inline constants per source, so instead we copy immediates into the
- * constant buffer. */
- unsigned imm_offset;
- /* Number of immediate constants. */
- unsigned imm_count;
- /* Number of colors to write. */
- unsigned out_colors;
- /* Number of texcoords to write. */
- unsigned out_texcoords;
- /* Whether to emit point size. */
- boolean point_size;
- /* Tab of declared outputs to OVM outputs. */
- unsigned tab[16];
-};
+ /* Fallback shader, because Draw has issues */
+ struct draw_vertex_shader* draw;
-static struct r300_vertex_shader r300_passthrough_vertex_shader = {
- /* XXX translate these back into normal instructions */
- .instruction_count = 2,
- .instructions[0].inst0 = R300_PVS_DST_OPCODE(R300_VE_ADD) |
- R300_PVS_DST_REG_TYPE(R300_PVS_DST_REG_OUT) |
- R300_PVS_DST_OFFSET(0) | R300_PVS_DST_WE_XYZW,
- .instructions[0].inst1 = R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) |
- R300_PVS_SRC_OFFSET(0) | R300_PVS_SRC_SWIZZLE_XYZW,
- .instructions[0].inst2 = R300_PVS_SRC_SWIZZLE_ZERO,
- .instructions[0].inst3 = 0x0,
- .instructions[1].inst0 = R300_PVS_DST_OPCODE(R300_VE_ADD) |
- R300_PVS_DST_REG_TYPE(R300_PVS_DST_REG_OUT) |
- R300_PVS_DST_OFFSET(1) | R300_PVS_DST_WE_XYZW,
- .instructions[1].inst1 = R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) |
- R300_PVS_SRC_OFFSET(1) | R300_PVS_SRC_SWIZZLE_XYZW,
- .instructions[1].inst2 = R300_PVS_SRC_SWIZZLE_ZERO,
- .instructions[1].inst3 = 0x0,
-};
+ /* Has this shader been translated yet? */
+ boolean translated;
-static struct r300_vertex_shader r300_texture_vertex_shader = {
- /* XXX translate these back into normal instructions */
- .instruction_count = 2,
- .instructions[0].inst0 = R300_PVS_DST_OPCODE(R300_VE_ADD) |
- R300_PVS_DST_REG_TYPE(R300_PVS_DST_REG_OUT) |
- R300_PVS_DST_OFFSET(0) | R300_PVS_DST_WE_XYZW,
- .instructions[0].inst1 = R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) |
- R300_PVS_SRC_OFFSET(0) | R300_PVS_SRC_SWIZZLE_XYZW,
- .instructions[0].inst2 = R300_PVS_SRC_SWIZZLE_ZERO,
- .instructions[0].inst3 = 0x0,
- .instructions[1].inst0 = R300_PVS_DST_OPCODE(R300_VE_ADD) |
- R300_PVS_DST_REG_TYPE(R300_PVS_DST_REG_OUT) |
- R300_PVS_DST_OFFSET(1) | R300_PVS_DST_WE_XYZW,
- .instructions[1].inst1 = R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) |
- R300_PVS_SRC_OFFSET(1) | R300_PVS_SRC_SWIZZLE_XYZW,
- .instructions[1].inst2 = R300_PVS_SRC_SWIZZLE_ZERO,
- .instructions[1].inst3 = 0x0,
+ /* Machine code (if translated) */
+ struct r300_vertex_program_code code;
};
+
+extern struct r300_vertex_program_code r300_passthrough_vertex_shader;
+
void r300_translate_vertex_shader(struct r300_context* r300,
struct r300_vertex_shader* vs);
diff --git a/src/gallium/drivers/r300/r3xx_fs.c b/src/gallium/drivers/r300/r3xx_fs.c
index 6e05d769773..c1c1194d58e 100644
--- a/src/gallium/drivers/r300/r3xx_fs.c
+++ b/src/gallium/drivers/r300/r3xx_fs.c
@@ -23,74 +23,52 @@
#include "r3xx_fs.h"
-static INLINE uint32_t r3xx_rgb_op(unsigned op)
-{
- switch (op) {
- case TGSI_OPCODE_MOV:
- return R300_ALU_OUTC_CMP;
- default:
- return 0;
- }
-}
+#include "r300_reg.h"
-static INLINE uint32_t r3xx_alpha_op(unsigned op)
-{
- switch (op) {
- case TGSI_OPCODE_MOV:
- return R300_ALU_OUTA_CMP;
- default:
- return 0;
- }
-}
+struct rX00_fragment_program_code r3xx_passthrough_fragment_shader = {
+ .code.r300.alu.length = 1,
+ .code.r300.tex.length = 0,
-static INLINE void r3xx_emit_maths(struct r3xx_fragment_shader* fs,
- struct r300_fs_asm* assembler,
- struct tgsi_full_src_register* src,
- struct tgsi_full_dst_register* dst,
- unsigned op,
- unsigned count)
-{
- int i = fs->alu_instruction_count;
+ .code.r300.config = 0,
+ .code.r300.pixsize = 0,
+ .code.r300.code_offset = 0,
+ .code.r300.code_addr[3] = R300_RGBA_OUT,
- fs->instructions[i].alu_rgb_inst = R300_RGB_SWIZA(R300_ALU_ARGC_SRC0C_XYZ) |
+ .code.r300.alu.inst[0].rgb_inst = R300_RGB_SWIZA(R300_ALU_ARGC_SRC0C_XYZ) |
R300_RGB_SWIZB(R300_ALU_ARGC_SRC0C_XYZ) |
R300_RGB_SWIZC(R300_ALU_ARGC_ZERO) |
- r3xx_rgb_op(op);
- fs->instructions[i].alu_rgb_addr = R300_RGB_ADDR0(0) | R300_RGB_ADDR1(0) |
- R300_RGB_ADDR2(0) | R300_ALU_DSTC_OUTPUT_XYZ;
- fs->instructions[i].alu_alpha_inst = R300_ALPHA_SWIZA(R300_ALU_ARGA_SRC0A) |
+ R300_ALU_OUTC_CMP,
+ .code.r300.alu.inst[0].rgb_addr = R300_RGB_ADDR0(0) | R300_RGB_ADDR1(0) |
+ R300_RGB_ADDR2(0) | R300_ALU_DSTC_OUTPUT_XYZ,
+ .code.r300.alu.inst[0].alpha_inst = R300_ALPHA_SWIZA(R300_ALU_ARGA_SRC0A) |
R300_ALPHA_SWIZB(R300_ALU_ARGA_SRC0A) |
R300_ALPHA_SWIZC(R300_ALU_ARGA_ZERO) |
- r3xx_alpha_op(op);
- fs->instructions[i].alu_alpha_addr = R300_ALPHA_ADDR0(0) |
- R300_ALPHA_ADDR1(0) | R300_ALPHA_ADDR2(0) | R300_ALU_DSTA_OUTPUT;
+ R300_ALU_OUTA_CMP,
+ .code.r300.alu.inst[0].alpha_addr = R300_ALPHA_ADDR0(0) |
+ R300_ALPHA_ADDR1(0) | R300_ALPHA_ADDR2(0) | R300_ALU_DSTA_OUTPUT,
+};
- fs->alu_instruction_count++;
-}
+struct rX00_fragment_program_code r3xx_texture_fragment_shader = {
+ .code.r300.alu.length = 1,
+ .code.r300.tex.length = 1,
-void r3xx_fs_finalize(struct r300_fragment_shader* fs,
- struct r300_fs_asm* assembler)
-{
- fs->stack_size = assembler->temp_count + assembler->temp_offset + 1;
-}
+ .code.r300.config = R300_PFS_CNTL_FIRST_NODE_HAS_TEX,
+ .code.r300.pixsize = 0,
+ .code.r300.code_offset = 0,
+ .code.r300.code_addr[3] = R300_RGBA_OUT,
-void r3xx_fs_instruction(struct r3xx_fragment_shader* fs,
- struct r300_fs_asm* assembler,
- struct tgsi_full_instruction* inst)
-{
- switch (inst->Instruction.Opcode) {
- case TGSI_OPCODE_MOV:
- /* src0 -> src1 and src2 forced to zero */
- inst->FullSrcRegisters[1] = inst->FullSrcRegisters[0];
- inst->FullSrcRegisters[2] = r300_constant_zero;
- r3xx_emit_maths(fs, assembler, inst->FullSrcRegisters,
- &inst->FullDstRegisters[0], inst->Instruction.Opcode, 3);
- break;
- case TGSI_OPCODE_END:
- break;
- default:
- debug_printf("r300: fs: Bad opcode %d\n",
- inst->Instruction.Opcode);
- break;
- }
-}
+ .code.r300.tex.inst[0] = R300_TEX_OP_LD << R300_TEX_INST_SHIFT,
+
+ .code.r300.alu.inst[0].rgb_inst = R300_RGB_SWIZA(R300_ALU_ARGC_SRC0C_XYZ) |
+ R300_RGB_SWIZB(R300_ALU_ARGC_SRC0C_XYZ) |
+ R300_RGB_SWIZC(R300_ALU_ARGC_ZERO) |
+ R300_ALU_OUTC_CMP,
+ .code.r300.alu.inst[0].rgb_addr = R300_RGB_ADDR0(0) | R300_RGB_ADDR1(0) |
+ R300_RGB_ADDR2(0) | R300_ALU_DSTC_OUTPUT_XYZ,
+ .code.r300.alu.inst[0].alpha_inst = R300_ALPHA_SWIZA(R300_ALU_ARGA_SRC0A) |
+ R300_ALPHA_SWIZB(R300_ALU_ARGA_SRC0A) |
+ R300_ALPHA_SWIZC(R300_ALU_ARGA_ZERO) |
+ R300_ALU_OUTA_CMP,
+ .code.r300.alu.inst[0].alpha_addr = R300_ALPHA_ADDR0(0) |
+ R300_ALPHA_ADDR1(0) | R300_ALPHA_ADDR2(0) | R300_ALU_DSTA_OUTPUT,
+};
diff --git a/src/gallium/drivers/r300/r3xx_fs.h b/src/gallium/drivers/r300/r3xx_fs.h
index 3da39ec2526..51cd245724d 100644
--- a/src/gallium/drivers/r300/r3xx_fs.h
+++ b/src/gallium/drivers/r300/r3xx_fs.h
@@ -24,53 +24,9 @@
#ifndef R3XX_FS_H
#define R3XX_FS_H
-#include "r300_fs_inlines.h"
+#include "radeon_code.h"
-static struct r3xx_fragment_shader r3xx_passthrough_fragment_shader = {
- .alu_instruction_count = 1,
- .tex_instruction_count = 0,
- .indirections = 0,
- .shader.stack_size = 1,
-
- .instructions[0].alu_rgb_inst = R300_RGB_SWIZA(R300_ALU_ARGC_SRC0C_XYZ) |
- R300_RGB_SWIZB(R300_ALU_ARGC_SRC0C_XYZ) |
- R300_RGB_SWIZC(R300_ALU_ARGC_ZERO) |
- R300_ALU_OUTC_CMP,
- .instructions[0].alu_rgb_addr = R300_RGB_ADDR0(0) | R300_RGB_ADDR1(0) |
- R300_RGB_ADDR2(0) | R300_ALU_DSTC_OUTPUT_XYZ,
- .instructions[0].alu_alpha_inst = R300_ALPHA_SWIZA(R300_ALU_ARGA_SRC0A) |
- R300_ALPHA_SWIZB(R300_ALU_ARGA_SRC0A) |
- R300_ALPHA_SWIZC(R300_ALU_ARGA_ZERO) |
- R300_ALU_OUTA_CMP,
- .instructions[0].alu_alpha_addr = R300_ALPHA_ADDR0(0) |
- R300_ALPHA_ADDR1(0) | R300_ALPHA_ADDR2(0) | R300_ALU_DSTA_OUTPUT,
-};
-
-static struct r3xx_fragment_shader r3xx_texture_fragment_shader = {
- .alu_instruction_count = 1,
- .tex_instruction_count = 0,
- .indirections = 0,
- .shader.stack_size = 1,
-
- .instructions[0].alu_rgb_inst = R300_RGB_SWIZA(R300_ALU_ARGC_SRC0C_XYZ) |
- R300_RGB_SWIZB(R300_ALU_ARGC_SRC0C_XYZ) |
- R300_RGB_SWIZC(R300_ALU_ARGC_ZERO) |
- R300_ALU_OUTC_CMP,
- .instructions[0].alu_rgb_addr = R300_RGB_ADDR0(0) | R300_RGB_ADDR1(0) |
- R300_RGB_ADDR2(0) | R300_ALU_DSTC_OUTPUT_XYZ,
- .instructions[0].alu_alpha_inst = R300_ALPHA_SWIZA(R300_ALU_ARGA_SRC0A) |
- R300_ALPHA_SWIZB(R300_ALU_ARGA_SRC0A) |
- R300_ALPHA_SWIZC(R300_ALU_ARGA_ZERO) |
- R300_ALU_OUTA_CMP,
- .instructions[0].alu_alpha_addr = R300_ALPHA_ADDR0(0) |
- R300_ALPHA_ADDR1(0) | R300_ALPHA_ADDR2(0) | R300_ALU_DSTA_OUTPUT,
-};
-
-void r3xx_fs_finalize(struct r300_fragment_shader* fs,
- struct r300_fs_asm* assembler);
-
-void r3xx_fs_instruction(struct r3xx_fragment_shader* fs,
- struct r300_fs_asm* assembler,
- struct tgsi_full_instruction* inst);
+struct rX00_fragment_program_code r3xx_passthrough_fragment_shader;
+struct rX00_fragment_program_code r3xx_texture_fragment_shader;
#endif /* R3XX_FS_H */
diff --git a/src/gallium/drivers/r300/r5xx_fs.c b/src/gallium/drivers/r300/r5xx_fs.c
index 99d826278ce..f072deab0d9 100644
--- a/src/gallium/drivers/r300/r5xx_fs.c
+++ b/src/gallium/drivers/r300/r5xx_fs.c
@@ -23,445 +23,103 @@
#include "r5xx_fs.h"
-static INLINE unsigned r5xx_fix_swiz(unsigned s)
-{
- /* For historical reasons, the swizzle values x, y, z, w, and 0 are
- * equivalent to the actual machine code, but 1 is not. Thus, we just
- * adjust it a bit... */
- if (s == TGSI_EXTSWIZZLE_ONE) {
- return R500_SWIZZLE_ONE;
- } else {
- return s;
- }
-}
-
-static uint32_t r5xx_rgba_swiz(struct tgsi_full_src_register* reg)
-{
- if (reg->SrcRegister.Extended) {
- return r5xx_fix_swiz(reg->SrcRegisterExtSwz.ExtSwizzleX) |
- (r5xx_fix_swiz(reg->SrcRegisterExtSwz.ExtSwizzleY) << 3) |
- (r5xx_fix_swiz(reg->SrcRegisterExtSwz.ExtSwizzleZ) << 6) |
- (r5xx_fix_swiz(reg->SrcRegisterExtSwz.ExtSwizzleW) << 9);
- } else {
- return reg->SrcRegister.SwizzleX |
- (reg->SrcRegister.SwizzleY << 3) |
- (reg->SrcRegister.SwizzleZ << 6) |
- (reg->SrcRegister.SwizzleW << 9);
- }
-}
-
-static uint32_t r5xx_strq_swiz(struct tgsi_full_src_register* reg)
-{
- return reg->SrcRegister.SwizzleX |
- (reg->SrcRegister.SwizzleY << 2) |
- (reg->SrcRegister.SwizzleZ << 4) |
- (reg->SrcRegister.SwizzleW << 6);
-}
-
-static INLINE uint32_t r5xx_rgb_swiz(struct tgsi_full_src_register* reg)
-{
- /* Only the first 9 bits... */
- return (r5xx_rgba_swiz(reg) & 0x1ff) |
- (reg->SrcRegister.Negate ? (1 << 9) : 0) |
- (reg->SrcRegisterExtMod.Absolute ? (1 << 10) : 0);
-}
-
-static INLINE uint32_t r5xx_alpha_swiz(struct tgsi_full_src_register* reg)
-{
- /* Only the last 3 bits... */
- return (r5xx_rgba_swiz(reg) >> 9) |
- (reg->SrcRegister.Negate ? (1 << 9) : 0) |
- (reg->SrcRegisterExtMod.Absolute ? (1 << 10) : 0);
-}
-
-static INLINE uint32_t r5xx_rgba_op(unsigned op)
-{
- switch (op) {
- case TGSI_OPCODE_COS:
- case TGSI_OPCODE_EX2:
- case TGSI_OPCODE_LG2:
- case TGSI_OPCODE_RCP:
- case TGSI_OPCODE_RSQ:
- case TGSI_OPCODE_SIN:
- return R500_ALU_RGBA_OP_SOP;
- case TGSI_OPCODE_DDX:
- return R500_ALU_RGBA_OP_MDH;
- case TGSI_OPCODE_DDY:
- return R500_ALU_RGBA_OP_MDV;
- case TGSI_OPCODE_FRC:
- return R500_ALU_RGBA_OP_FRC;
- case TGSI_OPCODE_DP3:
- return R500_ALU_RGBA_OP_DP3;
- case TGSI_OPCODE_DP4:
- case TGSI_OPCODE_DPH:
- return R500_ALU_RGBA_OP_DP4;
- case TGSI_OPCODE_ABS:
- case TGSI_OPCODE_CMP:
- case TGSI_OPCODE_MOV:
- case TGSI_OPCODE_SWZ:
- return R500_ALU_RGBA_OP_CMP;
- case TGSI_OPCODE_ADD:
- case TGSI_OPCODE_MAD:
- case TGSI_OPCODE_MUL:
- case TGSI_OPCODE_SUB:
- return R500_ALU_RGBA_OP_MAD;
- default:
- return 0;
- }
-}
-
-static INLINE uint32_t r5xx_alpha_op(unsigned op)
-{
- switch (op) {
- case TGSI_OPCODE_COS:
- return R500_ALPHA_OP_COS;
- case TGSI_OPCODE_EX2:
- return R500_ALPHA_OP_EX2;
- case TGSI_OPCODE_LG2:
- return R500_ALPHA_OP_LN2;
- case TGSI_OPCODE_RCP:
- return R500_ALPHA_OP_RCP;
- case TGSI_OPCODE_RSQ:
- return R500_ALPHA_OP_RSQ;
- case TGSI_OPCODE_FRC:
- return R500_ALPHA_OP_FRC;
- case TGSI_OPCODE_SIN:
- return R500_ALPHA_OP_SIN;
- case TGSI_OPCODE_DDX:
- return R500_ALPHA_OP_MDH;
- case TGSI_OPCODE_DDY:
- return R500_ALPHA_OP_MDV;
- case TGSI_OPCODE_DP3:
- case TGSI_OPCODE_DP4:
- case TGSI_OPCODE_DPH:
- return R500_ALPHA_OP_DP;
- case TGSI_OPCODE_ABS:
- case TGSI_OPCODE_CMP:
- case TGSI_OPCODE_MOV:
- case TGSI_OPCODE_SWZ:
- return R500_ALPHA_OP_CMP;
- case TGSI_OPCODE_ADD:
- case TGSI_OPCODE_MAD:
- case TGSI_OPCODE_MUL:
- case TGSI_OPCODE_SUB:
- return R500_ALPHA_OP_MAD;
- default:
- return 0;
- }
-}
-
-static INLINE uint32_t r5xx_tex_op(unsigned op)
-{
- switch (op) {
- case TGSI_OPCODE_KIL:
- return R500_TEX_INST_TEXKILL;
- case TGSI_OPCODE_TEX:
- return R500_TEX_INST_LD;
- case TGSI_OPCODE_TXB:
- return R500_TEX_INST_LODBIAS;
- case TGSI_OPCODE_TXP:
- return R500_TEX_INST_PROJ;
- default:
- return 0;
- }
-}
-
-/* Setup an ALU operation. */
-static INLINE void r5xx_emit_maths(struct r5xx_fragment_shader* fs,
- struct r300_fs_asm* assembler,
- struct tgsi_full_src_register* src,
- struct tgsi_full_dst_register* dst,
- unsigned op,
- unsigned count)
-{
- int i = fs->instruction_count;
-
- if (dst->DstRegister.File == TGSI_FILE_OUTPUT) {
- fs->instructions[i].inst0 = R500_INST_TYPE_OUT;
- if (r300_fs_is_depr(assembler, dst)) {
- fs->instructions[i].inst4 = R500_W_OMASK;
- } else {
- fs->instructions[i].inst0 |=
- R500_ALU_OMASK(dst->DstRegister.WriteMask);
- }
- } else {
- fs->instructions[i].inst0 = R500_INST_TYPE_ALU |
- R500_ALU_WMASK(dst->DstRegister.WriteMask);
- }
-
- fs->instructions[i].inst0 |= R500_INST_TEX_SEM_WAIT;
-
- fs->instructions[i].inst4 |=
- R500_ALPHA_ADDRD(r300_fs_dst(assembler, &dst->DstRegister));
- fs->instructions[i].inst5 =
- R500_ALU_RGBA_ADDRD(r300_fs_dst(assembler, &dst->DstRegister));
-
- switch (count) {
- case 3:
- fs->instructions[i].inst1 =
- R500_RGB_ADDR2(r300_fs_src(assembler, &src[2].SrcRegister));
- fs->instructions[i].inst2 =
- R500_ALPHA_ADDR2(r300_fs_src(assembler, &src[2].SrcRegister));
- fs->instructions[i].inst5 |=
- R500_ALU_RGBA_SEL_C_SRC2 |
- R500_SWIZ_RGBA_C(r5xx_rgb_swiz(&src[2])) |
- R500_ALU_RGBA_ALPHA_SEL_C_SRC2 |
- R500_SWIZ_ALPHA_C(r5xx_alpha_swiz(&src[2]));
- case 2:
- fs->instructions[i].inst1 |=
- R500_RGB_ADDR1(r300_fs_src(assembler, &src[1].SrcRegister));
- fs->instructions[i].inst2 |=
- R500_ALPHA_ADDR1(r300_fs_src(assembler, &src[1].SrcRegister));
- fs->instructions[i].inst3 =
- R500_ALU_RGB_SEL_B_SRC1 |
- R500_SWIZ_RGB_B(r5xx_rgb_swiz(&src[1]));
- fs->instructions[i].inst4 |=
- R500_ALPHA_SEL_B_SRC1 |
- R500_SWIZ_ALPHA_B(r5xx_alpha_swiz(&src[1]));
- case 1:
- case 0:
- default:
- fs->instructions[i].inst1 |=
- R500_RGB_ADDR0(r300_fs_src(assembler, &src[0].SrcRegister));
- fs->instructions[i].inst2 |=
- R500_ALPHA_ADDR0(r300_fs_src(assembler, &src[0].SrcRegister));
- fs->instructions[i].inst3 |=
- R500_ALU_RGB_SEL_A_SRC0 |
- R500_SWIZ_RGB_A(r5xx_rgb_swiz(&src[0]));
- fs->instructions[i].inst4 |=
- R500_ALPHA_SEL_A_SRC0 |
- R500_SWIZ_ALPHA_A(r5xx_alpha_swiz(&src[0]));
- break;
- }
-
- fs->instructions[i].inst4 |= r5xx_alpha_op(op);
- fs->instructions[i].inst5 |= r5xx_rgba_op(op);
-
- fs->instruction_count++;
-}
-
-static INLINE void r5xx_emit_tex(struct r5xx_fragment_shader* fs,
- struct r300_fs_asm* assembler,
- struct tgsi_full_src_register* src,
- struct tgsi_full_dst_register* dst,
- uint32_t op)
-{
- int i = fs->instruction_count;
-
- fs->instructions[i].inst0 = R500_INST_TYPE_TEX |
- R500_TEX_WMASK(dst->DstRegister.WriteMask) |
- R500_INST_TEX_SEM_WAIT;
- fs->instructions[i].inst1 = R500_TEX_ID(0) |
- R500_TEX_SEM_ACQUIRE | //R500_TEX_IGNORE_UNCOVERED |
- r5xx_tex_op(op);
- fs->instructions[i].inst2 =
- R500_TEX_SRC_ADDR(r300_fs_src(assembler, &src->SrcRegister)) |
- R500_SWIZ_TEX_STRQ(r5xx_strq_swiz(src)) |
- R500_TEX_DST_ADDR(r300_fs_dst(assembler, &dst->DstRegister)) |
+#include "r300_reg.h"
+
+/* XXX this all should find its way back to r300_reg */
+/* Swizzle tools */
+#define R500_SWIZZLE_ZERO 4
+#define R500_SWIZZLE_HALF 5
+#define R500_SWIZZLE_ONE 6
+#define R500_SWIZ_RGB_ZERO ((4 << 0) | (4 << 3) | (4 << 6))
+#define R500_SWIZ_RGB_ONE ((6 << 0) | (6 << 3) | (6 << 6))
+#define R500_SWIZ_RGB_RGB ((0 << 0) | (1 << 3) | (2 << 6))
+#define R500_SWIZ_MOD_NEG 1
+#define R500_SWIZ_MOD_ABS 2
+#define R500_SWIZ_MOD_NEG_ABS 3
+/* Swizzles for inst2 */
+#define R500_SWIZ_TEX_STRQ(x) ((x) << 8)
+#define R500_SWIZ_TEX_RGBA(x) ((x) << 24)
+/* Swizzles for inst3 */
+#define R500_SWIZ_RGB_A(x) ((x) << 2)
+#define R500_SWIZ_RGB_B(x) ((x) << 15)
+/* Swizzles for inst4 */
+#define R500_SWIZ_ALPHA_A(x) ((x) << 14)
+#define R500_SWIZ_ALPHA_B(x) ((x) << 21)
+/* Swizzle for inst5 */
+#define R500_SWIZ_RGBA_C(x) ((x) << 14)
+#define R500_SWIZ_ALPHA_C(x) ((x) << 27)
+/* Writemasks */
+#define R500_TEX_WMASK(x) ((x) << 11)
+#define R500_ALU_WMASK(x) ((x) << 11)
+#define R500_ALU_OMASK(x) ((x) << 15)
+#define R500_W_OMASK (1 << 31)
+
+struct rX00_fragment_program_code r5xx_passthrough_fragment_shader = {
+ .code.r500.max_temp_idx = 0,
+ .code.r500.inst_end = 0,
+
+ .code.r500.inst[0].inst0 = R500_INST_TYPE_OUT |
+ R500_INST_TEX_SEM_WAIT | R500_INST_LAST |
+ R500_INST_RGB_OMASK_RGB | R500_INST_ALPHA_OMASK |
+ R500_INST_RGB_CLAMP | R500_INST_ALPHA_CLAMP,
+ .code.r500.inst[0].inst1 =
+ R500_RGB_ADDR0(0) | R500_RGB_ADDR1(0) | R500_RGB_ADDR1_CONST |
+ R500_RGB_ADDR2(0) | R500_RGB_ADDR2_CONST,
+ .code.r500.inst[0].inst2 =
+ R500_ALPHA_ADDR0(0) | R500_ALPHA_ADDR1(0) | R500_ALPHA_ADDR1_CONST |
+ R500_ALPHA_ADDR2(0) | R500_ALPHA_ADDR2_CONST,
+ .code.r500.inst[0].inst3 =
+ R500_ALU_RGB_SEL_A_SRC0 | R500_ALU_RGB_R_SWIZ_A_R |
+ R500_ALU_RGB_G_SWIZ_A_G | R500_ALU_RGB_B_SWIZ_A_B |
+ R500_ALU_RGB_SEL_B_SRC0 | R500_ALU_RGB_R_SWIZ_B_R |
+ R500_ALU_RGB_B_SWIZ_B_G | R500_ALU_RGB_G_SWIZ_B_B,
+ .code.r500.inst[0].inst4 =
+ R500_ALPHA_OP_CMP | R500_ALPHA_SWIZ_A_A | R500_ALPHA_SWIZ_B_A,
+ .code.r500.inst[0].inst5 =
+ R500_ALU_RGBA_OP_CMP | R500_ALU_RGBA_R_SWIZ_0 |
+ R500_ALU_RGBA_G_SWIZ_0 | R500_ALU_RGBA_B_SWIZ_0 |
+ R500_ALU_RGBA_A_SWIZ_0,
+};
+
+struct rX00_fragment_program_code r5xx_texture_fragment_shader = {
+ .code.r500.max_temp_idx = 0,
+ .code.r500.inst_end = 1,
+
+ .code.r500.inst[0].inst0 = R500_INST_TYPE_TEX |
+ R500_INST_TEX_SEM_WAIT |
+ R500_INST_RGB_WMASK_RGB | R500_INST_ALPHA_WMASK |
+ R500_INST_RGB_CLAMP | R500_INST_ALPHA_CLAMP,
+ .code.r500.inst[0].inst1 = R500_TEX_ID(0) | R500_TEX_INST_LD |
+ R500_TEX_SEM_ACQUIRE | R500_TEX_IGNORE_UNCOVERED,
+ .code.r500.inst[0].inst2 = R500_TEX_SRC_ADDR(0) |
+ R500_TEX_SRC_S_SWIZ_R | R500_TEX_SRC_T_SWIZ_G |
+ R500_TEX_SRC_R_SWIZ_B | R500_TEX_SRC_Q_SWIZ_A |
+ R500_TEX_DST_ADDR(0) |
R500_TEX_DST_R_SWIZ_R | R500_TEX_DST_G_SWIZ_G |
- R500_TEX_DST_B_SWIZ_B | R500_TEX_DST_A_SWIZ_A;
-
- if (dst->DstRegister.File == TGSI_FILE_OUTPUT) {
- fs->instructions[i].inst2 |=
- R500_TEX_DST_ADDR(assembler->temp_count +
- assembler->temp_offset);
-
- fs->instruction_count++;
-
- /* Setup and emit a MOV. */
- src[0].SrcRegister.Index = assembler->temp_count;
- src[0].SrcRegister.File = TGSI_FILE_TEMPORARY;
-
- src[1] = src[0];
- src[2] = r300_constant_zero;
- r5xx_emit_maths(fs, assembler, src, dst, TGSI_OPCODE_MOV, 3);
- } else {
- fs->instruction_count++;
- }
-}
-
-void r5xx_fs_finalize(struct r5xx_fragment_shader* fs,
- struct r300_fs_asm* assembler)
-{
- /* XXX should this just go with OPCODE_END? */
- fs->instructions[fs->instruction_count - 1].inst0 |=
- R500_INST_LAST;
-}
-
-void r5xx_fs_instruction(struct r5xx_fragment_shader* fs,
- struct r300_fs_asm* assembler,
- struct tgsi_full_instruction* inst)
-{
- /* Switch between opcodes. When possible, prefer using the official
- * AMD/ATI names for opcodes, please, as it facilitates using the
- * documentation. */
- switch (inst->Instruction.Opcode) {
- /* XXX trig needs extra prep */
- case TGSI_OPCODE_COS:
- case TGSI_OPCODE_SIN:
- /* The simple scalar ops. */
- case TGSI_OPCODE_EX2:
- case TGSI_OPCODE_LG2:
- case TGSI_OPCODE_RCP:
- case TGSI_OPCODE_RSQ:
- /* Copy red swizzle to alpha for src0 */
- inst->FullSrcRegisters[0].SrcRegisterExtSwz.ExtSwizzleW =
- inst->FullSrcRegisters[0].SrcRegisterExtSwz.ExtSwizzleX;
- inst->FullSrcRegisters[0].SrcRegister.SwizzleW =
- inst->FullSrcRegisters[0].SrcRegister.SwizzleX;
- /* Fall through */
- case TGSI_OPCODE_DDX:
- case TGSI_OPCODE_DDY:
- case TGSI_OPCODE_FRC:
- r5xx_emit_maths(fs, assembler, inst->FullSrcRegisters,
- &inst->FullDstRegisters[0], inst->Instruction.Opcode, 1);
- break;
-
- /* The dot products. */
- case TGSI_OPCODE_DPH:
- /* Set alpha swizzle to one for src0 */
- if (!inst->FullSrcRegisters[0].SrcRegister.Extended) {
- inst->FullSrcRegisters[0].SrcRegister.Extended = TRUE;
- inst->FullSrcRegisters[0].SrcRegisterExtSwz.ExtSwizzleX =
- inst->FullSrcRegisters[0].SrcRegister.SwizzleX;
- inst->FullSrcRegisters[0].SrcRegisterExtSwz.ExtSwizzleY =
- inst->FullSrcRegisters[0].SrcRegister.SwizzleY;
- inst->FullSrcRegisters[0].SrcRegisterExtSwz.ExtSwizzleZ =
- inst->FullSrcRegisters[0].SrcRegister.SwizzleZ;
- }
- inst->FullSrcRegisters[0].SrcRegisterExtSwz.ExtSwizzleW =
- TGSI_EXTSWIZZLE_ONE;
- /* Fall through */
- case TGSI_OPCODE_DP3:
- case TGSI_OPCODE_DP4:
- r5xx_emit_maths(fs, assembler, inst->FullSrcRegisters,
- &inst->FullDstRegisters[0], inst->Instruction.Opcode, 2);
- break;
-
- /* Simple three-source operations. */
- case TGSI_OPCODE_CMP:
- /* Swap src0 and src2 */
- inst->FullSrcRegisters[3] = inst->FullSrcRegisters[2];
- inst->FullSrcRegisters[2] = inst->FullSrcRegisters[0];
- inst->FullSrcRegisters[0] = inst->FullSrcRegisters[3];
- r5xx_emit_maths(fs, assembler, inst->FullSrcRegisters,
- &inst->FullDstRegisters[0], inst->Instruction.Opcode, 3);
- break;
-
- /* The MAD variants. */
- case TGSI_OPCODE_SUB:
- /* Just like ADD, but flip the negation on src1 first */
- inst->FullSrcRegisters[1].SrcRegister.Negate =
- !inst->FullSrcRegisters[1].SrcRegister.Negate;
- /* Fall through */
- case TGSI_OPCODE_ADD:
- /* Force src0 to one, move all registers over */
- inst->FullSrcRegisters[2] = inst->FullSrcRegisters[1];
- inst->FullSrcRegisters[1] = inst->FullSrcRegisters[0];
- inst->FullSrcRegisters[0] = r300_constant_one;
- r5xx_emit_maths(fs, assembler, inst->FullSrcRegisters,
- &inst->FullDstRegisters[0], inst->Instruction.Opcode, 3);
- break;
- case TGSI_OPCODE_MUL:
- /* Force our src2 to zero */
- inst->FullSrcRegisters[2] = r300_constant_zero;
- r5xx_emit_maths(fs, assembler, inst->FullSrcRegisters,
- &inst->FullDstRegisters[0], inst->Instruction.Opcode, 3);
- break;
- case TGSI_OPCODE_MAD:
- r5xx_emit_maths(fs, assembler, inst->FullSrcRegisters,
- &inst->FullDstRegisters[0], inst->Instruction.Opcode, 3);
- break;
-
- /* The MOV variants. */
- case TGSI_OPCODE_ABS:
- /* Set absolute value modifiers. */
- inst->FullSrcRegisters[0].SrcRegisterExtMod.Absolute = TRUE;
- /* Fall through */
- case TGSI_OPCODE_MOV:
- case TGSI_OPCODE_SWZ:
- /* src0 -> src1 and src2 forced to zero */
- inst->FullSrcRegisters[1] = inst->FullSrcRegisters[0];
- inst->FullSrcRegisters[2] = r300_constant_zero;
- r5xx_emit_maths(fs, assembler, inst->FullSrcRegisters,
- &inst->FullDstRegisters[0], inst->Instruction.Opcode, 3);
- break;
-
- /* The compound and hybrid insts. */
- case TGSI_OPCODE_LRP:
- /* LRP DST A, B, C -> MAD TMP -A, C, C; MAD DST A, B, TMP */
- inst->FullSrcRegisters[3] = inst->FullSrcRegisters[1];
- inst->FullSrcRegisters[1] = inst->FullSrcRegisters[2];
- inst->FullSrcRegisters[0].SrcRegister.Negate =
- !(inst->FullSrcRegisters[0].SrcRegister.Negate);
- inst->FullDstRegisters[1] = inst->FullDstRegisters[0];
- inst->FullDstRegisters[0].DstRegister.Index =
- assembler->temp_count;
- inst->FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY;
- r5xx_emit_maths(fs, assembler, inst->FullSrcRegisters,
- &inst->FullDstRegisters[0], TGSI_OPCODE_MAD, 3);
- inst->FullSrcRegisters[2].SrcRegister.Index =
- assembler->temp_count;
- inst->FullSrcRegisters[2].SrcRegister.File = TGSI_FILE_TEMPORARY;
- inst->FullSrcRegisters[2].SrcRegister.SwizzleX = TGSI_SWIZZLE_X;
- inst->FullSrcRegisters[2].SrcRegister.SwizzleY = TGSI_SWIZZLE_Y;
- inst->FullSrcRegisters[2].SrcRegister.SwizzleZ = TGSI_SWIZZLE_Z;
- inst->FullSrcRegisters[2].SrcRegister.SwizzleW = TGSI_SWIZZLE_W;
- inst->FullSrcRegisters[1] = inst->FullSrcRegisters[3];
- inst->FullSrcRegisters[0].SrcRegister.Negate =
- !(inst->FullSrcRegisters[0].SrcRegister.Negate);
- inst->FullDstRegisters[0] = inst->FullDstRegisters[1];
- r5xx_emit_maths(fs, assembler, inst->FullSrcRegisters,
- &inst->FullDstRegisters[0], TGSI_OPCODE_MAD, 3);
- break;
- case TGSI_OPCODE_POW:
- /* POW DST A, B -> LG2 TMP A; MUL TMP TMP, B; EX2 DST TMP */
- inst->FullSrcRegisters[0].SrcRegisterExtSwz.ExtSwizzleW =
- inst->FullSrcRegisters[0].SrcRegisterExtSwz.ExtSwizzleX;
- inst->FullSrcRegisters[0].SrcRegister.SwizzleW =
- inst->FullSrcRegisters[0].SrcRegister.SwizzleX;
- inst->FullDstRegisters[1] = inst->FullDstRegisters[0];
- inst->FullDstRegisters[0].DstRegister.Index =
- assembler->temp_count;
- inst->FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY;
- r5xx_emit_maths(fs, assembler, inst->FullSrcRegisters,
- &inst->FullDstRegisters[0], TGSI_OPCODE_LG2, 1);
- inst->FullSrcRegisters[0].SrcRegister.Index =
- assembler->temp_count;
- inst->FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY;
- inst->FullSrcRegisters[0].SrcRegister.SwizzleX = TGSI_SWIZZLE_X;
- inst->FullSrcRegisters[0].SrcRegister.SwizzleY = TGSI_SWIZZLE_Y;
- inst->FullSrcRegisters[0].SrcRegister.SwizzleZ = TGSI_SWIZZLE_Z;
- inst->FullSrcRegisters[0].SrcRegister.SwizzleW = TGSI_SWIZZLE_W;
- inst->FullSrcRegisters[2] = r300_constant_zero;
- r5xx_emit_maths(fs, assembler, inst->FullSrcRegisters,
- &inst->FullDstRegisters[0], TGSI_OPCODE_MUL, 3);
- inst->FullDstRegisters[0] = inst->FullDstRegisters[1];
- r5xx_emit_maths(fs, assembler, inst->FullSrcRegisters,
- &inst->FullDstRegisters[0], TGSI_OPCODE_EX2, 1);
- break;
-
- /* The texture instruction set. */
- case TGSI_OPCODE_KIL:
- case TGSI_OPCODE_TEX:
- case TGSI_OPCODE_TXB:
- case TGSI_OPCODE_TXP:
- r5xx_emit_tex(fs, assembler, &inst->FullSrcRegisters[0],
- &inst->FullDstRegisters[0], inst->Instruction.Opcode);
- break;
-
- /* This is the end. My only friend, the end. */
- case TGSI_OPCODE_END:
- break;
- default:
- debug_printf("r300: fs: Bad opcode %d\n",
- inst->Instruction.Opcode);
- break;
- }
-
- /* Clamp, if saturation flags are set. */
- if (inst->Instruction.Saturate == TGSI_SAT_ZERO_ONE) {
- fs->instructions[fs->instruction_count - 1].inst0 |=
- R500_INST_RGB_CLAMP | R500_INST_ALPHA_CLAMP;
- }
-}
+ R500_TEX_DST_B_SWIZ_B | R500_TEX_DST_A_SWIZ_A,
+ .code.r500.inst[0].inst3 = 0x0,
+ .code.r500.inst[0].inst4 = 0x0,
+ .code.r500.inst[0].inst5 = 0x0,
+
+ .code.r500.inst[1].inst0 = R500_INST_TYPE_OUT |
+ R500_INST_TEX_SEM_WAIT | R500_INST_LAST |
+ R500_INST_RGB_OMASK_RGB | R500_INST_ALPHA_OMASK |
+ R500_INST_RGB_CLAMP | R500_INST_ALPHA_CLAMP,
+ .code.r500.inst[1].inst1 =
+ R500_RGB_ADDR0(0) | R500_RGB_ADDR1(0) | R500_RGB_ADDR1_CONST |
+ R500_RGB_ADDR2(0) | R500_RGB_ADDR2_CONST,
+ .code.r500.inst[1].inst2 =
+ R500_ALPHA_ADDR0(0) | R500_ALPHA_ADDR1(0) | R500_ALPHA_ADDR1_CONST |
+ R500_ALPHA_ADDR2(0) | R500_ALPHA_ADDR2_CONST,
+ .code.r500.inst[1].inst3 =
+ R500_ALU_RGB_SEL_A_SRC0 | R500_ALU_RGB_R_SWIZ_A_R |
+ R500_ALU_RGB_G_SWIZ_A_G | R500_ALU_RGB_B_SWIZ_A_B |
+ R500_ALU_RGB_SEL_B_SRC0 | R500_ALU_RGB_R_SWIZ_B_R |
+ R500_ALU_RGB_B_SWIZ_B_G | R500_ALU_RGB_G_SWIZ_B_B,
+ .code.r500.inst[1].inst4 =
+ R500_ALPHA_OP_CMP | R500_ALPHA_SWIZ_A_A | R500_ALPHA_SWIZ_B_A,
+ .code.r500.inst[1].inst5 =
+ R500_ALU_RGBA_OP_CMP | R500_ALU_RGBA_R_SWIZ_0 |
+ R500_ALU_RGBA_G_SWIZ_0 | R500_ALU_RGBA_B_SWIZ_0 |
+ R500_ALU_RGBA_A_SWIZ_0,
+};
diff --git a/src/gallium/drivers/r300/r5xx_fs.h b/src/gallium/drivers/r300/r5xx_fs.h
index 629e587be4d..a4addde32b2 100644
--- a/src/gallium/drivers/r300/r5xx_fs.h
+++ b/src/gallium/drivers/r300/r5xx_fs.h
@@ -24,109 +24,9 @@
#ifndef R5XX_FS_H
#define R5XX_FS_H
-#include "r300_fs_inlines.h"
+#include "radeon_code.h"
-/* XXX this all should find its way back to r300_reg */
-/* Swizzle tools */
-#define R500_SWIZZLE_ZERO 4
-#define R500_SWIZZLE_HALF 5
-#define R500_SWIZZLE_ONE 6
-#define R500_SWIZ_RGB_ZERO ((4 << 0) | (4 << 3) | (4 << 6))
-#define R500_SWIZ_RGB_ONE ((6 << 0) | (6 << 3) | (6 << 6))
-#define R500_SWIZ_RGB_RGB ((0 << 0) | (1 << 3) | (2 << 6))
-#define R500_SWIZ_MOD_NEG 1
-#define R500_SWIZ_MOD_ABS 2
-#define R500_SWIZ_MOD_NEG_ABS 3
-/* Swizzles for inst2 */
-#define R500_SWIZ_TEX_STRQ(x) ((x) << 8)
-#define R500_SWIZ_TEX_RGBA(x) ((x) << 24)
-/* Swizzles for inst3 */
-#define R500_SWIZ_RGB_A(x) ((x) << 2)
-#define R500_SWIZ_RGB_B(x) ((x) << 15)
-/* Swizzles for inst4 */
-#define R500_SWIZ_ALPHA_A(x) ((x) << 14)
-#define R500_SWIZ_ALPHA_B(x) ((x) << 21)
-/* Swizzle for inst5 */
-#define R500_SWIZ_RGBA_C(x) ((x) << 14)
-#define R500_SWIZ_ALPHA_C(x) ((x) << 27)
-/* Writemasks */
-#define R500_TEX_WMASK(x) ((x) << 11)
-#define R500_ALU_WMASK(x) ((x) << 11)
-#define R500_ALU_OMASK(x) ((x) << 15)
-#define R500_W_OMASK (1 << 31)
-
-static struct r5xx_fragment_shader r5xx_passthrough_fragment_shader = {
- .shader.stack_size = 0,
- .instruction_count = 1,
- .instructions[0].inst0 = R500_INST_TYPE_OUT |
- R500_INST_TEX_SEM_WAIT | R500_INST_LAST |
- R500_INST_RGB_OMASK_RGB | R500_INST_ALPHA_OMASK |
- R500_INST_RGB_CLAMP | R500_INST_ALPHA_CLAMP,
- .instructions[0].inst1 =
- R500_RGB_ADDR0(0) | R500_RGB_ADDR1(0) | R500_RGB_ADDR1_CONST |
- R500_RGB_ADDR2(0) | R500_RGB_ADDR2_CONST,
- .instructions[0].inst2 =
- R500_ALPHA_ADDR0(0) | R500_ALPHA_ADDR1(0) | R500_ALPHA_ADDR1_CONST |
- R500_ALPHA_ADDR2(0) | R500_ALPHA_ADDR2_CONST,
- .instructions[0].inst3 =
- R500_ALU_RGB_SEL_A_SRC0 | R500_ALU_RGB_R_SWIZ_A_R |
- R500_ALU_RGB_G_SWIZ_A_G | R500_ALU_RGB_B_SWIZ_A_B |
- R500_ALU_RGB_SEL_B_SRC0 | R500_ALU_RGB_R_SWIZ_B_R |
- R500_ALU_RGB_B_SWIZ_B_G | R500_ALU_RGB_G_SWIZ_B_B,
- .instructions[0].inst4 =
- R500_ALPHA_OP_CMP | R500_ALPHA_SWIZ_A_A | R500_ALPHA_SWIZ_B_A,
- .instructions[0].inst5 =
- R500_ALU_RGBA_OP_CMP | R500_ALU_RGBA_R_SWIZ_0 |
- R500_ALU_RGBA_G_SWIZ_0 | R500_ALU_RGBA_B_SWIZ_0 |
- R500_ALU_RGBA_A_SWIZ_0,
-};
-
-static struct r5xx_fragment_shader r5xx_texture_fragment_shader = {
- .shader.stack_size = 1,
- .instruction_count = 2,
- .instructions[0].inst0 = R500_INST_TYPE_TEX |
- R500_INST_TEX_SEM_WAIT |
- R500_INST_RGB_WMASK_RGB | R500_INST_ALPHA_WMASK |
- R500_INST_RGB_CLAMP | R500_INST_ALPHA_CLAMP,
- .instructions[0].inst1 = R500_TEX_ID(0) | R500_TEX_INST_LD |
- R500_TEX_SEM_ACQUIRE | R500_TEX_IGNORE_UNCOVERED,
- .instructions[0].inst2 = R500_TEX_SRC_ADDR(0) |
- R500_TEX_SRC_S_SWIZ_R | R500_TEX_SRC_T_SWIZ_G |
- R500_TEX_SRC_R_SWIZ_B | R500_TEX_SRC_Q_SWIZ_A |
- R500_TEX_DST_ADDR(0) |
- R500_TEX_DST_R_SWIZ_R | R500_TEX_DST_G_SWIZ_G |
- R500_TEX_DST_B_SWIZ_B | R500_TEX_DST_A_SWIZ_A,
- .instructions[0].inst3 = 0x0,
- .instructions[0].inst4 = 0x0,
- .instructions[0].inst5 = 0x0,
- .instructions[1].inst0 = R500_INST_TYPE_OUT |
- R500_INST_TEX_SEM_WAIT | R500_INST_LAST |
- R500_INST_RGB_OMASK_RGB | R500_INST_ALPHA_OMASK |
- R500_INST_RGB_CLAMP | R500_INST_ALPHA_CLAMP,
- .instructions[1].inst1 =
- R500_RGB_ADDR0(0) | R500_RGB_ADDR1(0) | R500_RGB_ADDR1_CONST |
- R500_RGB_ADDR2(0) | R500_RGB_ADDR2_CONST,
- .instructions[1].inst2 =
- R500_ALPHA_ADDR0(0) | R500_ALPHA_ADDR1(0) | R500_ALPHA_ADDR1_CONST |
- R500_ALPHA_ADDR2(0) | R500_ALPHA_ADDR2_CONST,
- .instructions[1].inst3 =
- R500_ALU_RGB_SEL_A_SRC0 | R500_ALU_RGB_R_SWIZ_A_R |
- R500_ALU_RGB_G_SWIZ_A_G | R500_ALU_RGB_B_SWIZ_A_B |
- R500_ALU_RGB_SEL_B_SRC0 | R500_ALU_RGB_R_SWIZ_B_R |
- R500_ALU_RGB_B_SWIZ_B_G | R500_ALU_RGB_G_SWIZ_B_B,
- .instructions[1].inst4 =
- R500_ALPHA_OP_CMP | R500_ALPHA_SWIZ_A_A | R500_ALPHA_SWIZ_B_A,
- .instructions[1].inst5 =
- R500_ALU_RGBA_OP_CMP | R500_ALU_RGBA_R_SWIZ_0 |
- R500_ALU_RGBA_G_SWIZ_0 | R500_ALU_RGBA_B_SWIZ_0 |
- R500_ALU_RGBA_A_SWIZ_0,
-};
-
-void r5xx_fs_finalize(struct r5xx_fragment_shader* fs,
- struct r300_fs_asm* assembler);
-
-void r5xx_fs_instruction(struct r5xx_fragment_shader* fs,
- struct r300_fs_asm* assembler,
- struct tgsi_full_instruction* inst);
+struct rX00_fragment_program_code r5xx_passthrough_fragment_shader;
+struct rX00_fragment_program_code r5xx_texture_fragment_shader;
#endif /* R5XX_FS_H */
diff --git a/src/gallium/drivers/softpipe/sp_texture.c b/src/gallium/drivers/softpipe/sp_texture.c
index 7a533dad9f0..70f09324311 100644
--- a/src/gallium/drivers/softpipe/sp_texture.c
+++ b/src/gallium/drivers/softpipe/sp_texture.c
@@ -48,11 +48,6 @@
/* Simple, maximally packed layout.
*/
-static unsigned minify( unsigned d )
-{
- return MAX2(1, d>>1);
-}
-
/* Conventional allocation path for non-display textures:
*/
@@ -100,6 +95,7 @@ softpipe_displaytarget_layout(struct pipe_screen *screen,
{
unsigned usage = (PIPE_BUFFER_USAGE_CPU_READ_WRITE |
PIPE_BUFFER_USAGE_GPU_READ_WRITE);
+ unsigned tex_usage = spt->base.tex_usage;
spt->base.nblocksx[0] = pf_get_nblocksx(&spt->base.block, spt->base.width[0]);
spt->base.nblocksy[0] = pf_get_nblocksy(&spt->base.block, spt->base.height[0]);
@@ -109,6 +105,7 @@ softpipe_displaytarget_layout(struct pipe_screen *screen,
spt->base.height[0],
spt->base.format,
usage,
+ tex_usage,
&spt->stride[0]);
return spt->buffer != NULL;
@@ -130,7 +127,8 @@ softpipe_texture_create(struct pipe_screen *screen,
pipe_reference_init(&spt->base.reference, 1);
spt->base.screen = screen;
- if (spt->base.tex_usage & PIPE_TEXTURE_USAGE_DISPLAY_TARGET) {
+ if (spt->base.tex_usage & (PIPE_TEXTURE_USAGE_DISPLAY_TARGET |
+ PIPE_TEXTURE_USAGE_PRIMARY)) {
if (!softpipe_displaytarget_layout(screen, spt))
goto fail;
}
@@ -224,12 +222,6 @@ softpipe_get_tex_surface(struct pipe_screen *screen,
if (ps->usage & PIPE_BUFFER_USAGE_GPU_READ)
ps->usage |= PIPE_BUFFER_USAGE_CPU_READ;
- if (ps->usage & (PIPE_BUFFER_USAGE_CPU_WRITE |
- PIPE_BUFFER_USAGE_GPU_WRITE)) {
- /* Mark the surface as dirty. The tile cache will look for this. */
- spt->modified = TRUE;
- }
-
ps->face = face;
ps->level = level;
ps->zslice = zslice;
@@ -376,6 +368,11 @@ softpipe_transfer_unmap(struct pipe_screen *screen,
spt = softpipe_texture(transfer->texture);
pipe_buffer_unmap( screen, spt->buffer );
+
+ if (transfer->usage != PIPE_TRANSFER_READ) {
+ /* Mark the texture as dirty to expire the tile caches. */
+ spt->modified = TRUE;
+ }
}
diff --git a/src/gallium/drivers/trace/tr_drm.c b/src/gallium/drivers/trace/tr_drm.c
index 98ac75e3fa3..93c569c73a8 100644
--- a/src/gallium/drivers/trace/tr_drm.c
+++ b/src/gallium/drivers/trace/tr_drm.c
@@ -63,7 +63,7 @@ trace_drm_create_screen(struct drm_api *_api, int fd,
screen = api->create_screen(api, fd, arg);
return trace_screen_create(screen);
-};
+}
static struct pipe_context *
trace_drm_create_context(struct drm_api *_api,
@@ -82,7 +82,7 @@ trace_drm_create_context(struct drm_api *_api,
pipe = trace_context_create(_screen, pipe);
return pipe;
-};
+}
static boolean
trace_drm_buffer_from_texture(struct drm_api *_api,
@@ -102,7 +102,7 @@ trace_drm_buffer_from_texture(struct drm_api *_api,
result = api->buffer_from_texture(api, texture, &buffer, stride);
if (result && _buffer)
- buffer = trace_buffer_create(trace_screen(texture->screen), buffer);
+ buffer = trace_buffer_create(trace_screen(_texture->screen), buffer);
if (_buffer)
*_buffer = buffer;
diff --git a/src/gallium/drivers/trace/tr_screen.c b/src/gallium/drivers/trace/tr_screen.c
index 5b1e26a52d7..26f1c04594f 100644
--- a/src/gallium/drivers/trace/tr_screen.c
+++ b/src/gallium/drivers/trace/tr_screen.c
@@ -462,6 +462,7 @@ trace_screen_surface_buffer_create(struct pipe_screen *_screen,
unsigned width, unsigned height,
enum pipe_format format,
unsigned usage,
+ unsigned tex_usage,
unsigned *pstride)
{
struct trace_screen *tr_scr = trace_screen(_screen);
@@ -476,11 +477,13 @@ trace_screen_surface_buffer_create(struct pipe_screen *_screen,
trace_dump_arg(uint, height);
trace_dump_arg(format, format);
trace_dump_arg(uint, usage);
+ trace_dump_arg(uint, tex_usage);
result = screen->surface_buffer_create(screen,
width, height,
format,
usage,
+ tex_usage,
pstride);
stride = *pstride;
diff --git a/src/gallium/include/pipe/internal/p_winsys_screen.h b/src/gallium/include/pipe/internal/p_winsys_screen.h
index f4a29e63c7e..a1542dada70 100644
--- a/src/gallium/include/pipe/internal/p_winsys_screen.h
+++ b/src/gallium/include/pipe/internal/p_winsys_screen.h
@@ -140,6 +140,7 @@ struct pipe_winsys
unsigned width, unsigned height,
enum pipe_format format,
unsigned usage,
+ unsigned tex_usage,
unsigned *stride);
diff --git a/src/gallium/include/pipe/p_defines.h b/src/gallium/include/pipe/p_defines.h
index bc4bc707591..b01ab6d137c 100644
--- a/src/gallium/include/pipe/p_defines.h
+++ b/src/gallium/include/pipe/p_defines.h
@@ -191,9 +191,9 @@ enum pipe_texture_target {
* Transfer object usage flags
*/
enum pipe_transfer_usage {
- PIPE_TRANSFER_READ,
- PIPE_TRANSFER_WRITE,
- PIPE_TRANSFER_READ_WRITE /**< Read/modify/write */
+ PIPE_TRANSFER_READ = (1 << 0),
+ PIPE_TRANSFER_WRITE = (1 << 1),
+ PIPE_TRANSFER_READ_WRITE = PIPE_TRANSFER_READ | PIPE_TRANSFER_WRITE /**< Read/modify/write */
};
diff --git a/src/gallium/include/pipe/p_screen.h b/src/gallium/include/pipe/p_screen.h
index 6cbdd759434..3f30c52a169 100644
--- a/src/gallium/include/pipe/p_screen.h
+++ b/src/gallium/include/pipe/p_screen.h
@@ -194,6 +194,7 @@ struct pipe_screen {
unsigned width, unsigned height,
enum pipe_format format,
unsigned usage,
+ unsigned tex_usage,
unsigned *stride);
diff --git a/src/gallium/include/pipe/p_shader_tokens.h b/src/gallium/include/pipe/p_shader_tokens.h
index b00cfe3423c..f0ba4fb308c 100644
--- a/src/gallium/include/pipe/p_shader_tokens.h
+++ b/src/gallium/include/pipe/p_shader_tokens.h
@@ -78,6 +78,7 @@ enum tgsi_file_type {
TGSI_FILE_SAMPLER =5,
TGSI_FILE_ADDRESS =6,
TGSI_FILE_IMMEDIATE =7,
+ TGSI_FILE_LOOP =8,
TGSI_FILE_COUNT /**< how many TGSI_FILE_ types */
};
@@ -152,13 +153,16 @@ struct tgsi_immediate
unsigned Extended : 1; /**< BOOL */
};
-struct tgsi_immediate_float32
+union tgsi_immediate_data
{
float Float;
};
-/*
- * GL_NV_vertex_program
+/* TGSI opcodes.
+ *
+ * For more information on semantics of opcodes and
+ * which APIs are known to use which opcodes, see
+ * auxiliary/tgsi/tgsi-instruction-set.txt
*/
#define TGSI_OPCODE_ARL 0
#define TGSI_OPCODE_MOV 1
@@ -177,62 +181,32 @@ struct tgsi_immediate_float32
#define TGSI_OPCODE_SLT 14
#define TGSI_OPCODE_SGE 15
#define TGSI_OPCODE_MAD 16
-
-/*
- * GL_ATI_fragment_shader
- */
#define TGSI_OPCODE_SUB 17
-#define TGSI_OPCODE_DOT3 TGSI_OPCODE_DP3
-#define TGSI_OPCODE_DOT4 TGSI_OPCODE_DP4
-#define TGSI_OPCODE_LERP 18
+#define TGSI_OPCODE_LRP 18
#define TGSI_OPCODE_CND 19
#define TGSI_OPCODE_CND0 20
-#define TGSI_OPCODE_DOT2ADD 21
-
-/*
- * GL_EXT_vertex_shader
- */
-#define TGSI_OPCODE_INDEX 22 /* considered for removal */
-#define TGSI_OPCODE_NEGATE 23 /* considered for removal */
-#define TGSI_OPCODE_MADD TGSI_OPCODE_MAD
-#define TGSI_OPCODE_FRAC 24
-#define TGSI_OPCODE_SETGE TGSI_OPCODE_SGE
-#define TGSI_OPCODE_SETLT TGSI_OPCODE_SLT
+#define TGSI_OPCODE_DP2A 21
+ /* gap */
+#define TGSI_OPCODE_FRC 24
#define TGSI_OPCODE_CLAMP 25
-#define TGSI_OPCODE_FLOOR 26
+#define TGSI_OPCODE_FLR 26
#define TGSI_OPCODE_ROUND 27
-#define TGSI_OPCODE_EXPBASE2 28
-#define TGSI_OPCODE_LOGBASE2 29
-#define TGSI_OPCODE_POWER 30
-#define TGSI_OPCODE_RECIP TGSI_OPCODE_RCP
-#define TGSI_OPCODE_RECIPSQRT TGSI_OPCODE_RSQ
-#define TGSI_OPCODE_CROSSPRODUCT 31
-#define TGSI_OPCODE_MULTIPLYMATRIX 32 /* considered for removal */
-
-/*
- * GL_NV_vertex_program1_1
- */
+#define TGSI_OPCODE_EX2 28
+#define TGSI_OPCODE_LG2 29
+#define TGSI_OPCODE_POW 30
+#define TGSI_OPCODE_XPD 31
+ /* gap */
#define TGSI_OPCODE_ABS 33
#define TGSI_OPCODE_RCC 34
#define TGSI_OPCODE_DPH 35
-
-/*
- * GL_NV_fragment_program
- */
#define TGSI_OPCODE_COS 36
#define TGSI_OPCODE_DDX 37
#define TGSI_OPCODE_DDY 38
-#define TGSI_OPCODE_EX2 TGSI_OPCODE_EXPBASE2
-#define TGSI_OPCODE_FLR TGSI_OPCODE_FLOOR
-#define TGSI_OPCODE_FRC TGSI_OPCODE_FRAC
#define TGSI_OPCODE_KILP 39 /* predicated kill */
-#define TGSI_OPCODE_LG2 TGSI_OPCODE_LOGBASE2
-#define TGSI_OPCODE_LRP TGSI_OPCODE_LERP
#define TGSI_OPCODE_PK2H 40
#define TGSI_OPCODE_PK2US 41
#define TGSI_OPCODE_PK4B 42
#define TGSI_OPCODE_PK4UB 43
-#define TGSI_OPCODE_POW TGSI_OPCODE_POWER
#define TGSI_OPCODE_RFL 44
#define TGSI_OPCODE_SEQ 45
#define TGSI_OPCODE_SFL 46
@@ -249,66 +223,29 @@ struct tgsi_immediate_float32
#define TGSI_OPCODE_UP4B 57
#define TGSI_OPCODE_UP4UB 58
#define TGSI_OPCODE_X2D 59
-
-/*
- * GL_NV_vertex_program2
- */
#define TGSI_OPCODE_ARA 60
#define TGSI_OPCODE_ARR 61
#define TGSI_OPCODE_BRA 62
#define TGSI_OPCODE_CAL 63
#define TGSI_OPCODE_RET 64
-#define TGSI_OPCODE_SSG 65
-
-/*
- * GL_ARB_vertex_program
- */
-#define TGSI_OPCODE_SWZ 118
-#define TGSI_OPCODE_XPD TGSI_OPCODE_CROSSPRODUCT
-
-/*
- * GL_ARB_fragment_program
- */
+#define TGSI_OPCODE_SSG 65 /* SGN */
#define TGSI_OPCODE_CMP 66
-#define TGSI_OPCODE_KIL 116 /* conditional kill */
#define TGSI_OPCODE_SCS 67
#define TGSI_OPCODE_TXB 68
-
-/*
- * GL_NV_fragment_program_option
- */
-/* No new opcode */
-
-/*
- * GL_NV_fragment_program2
- */
#define TGSI_OPCODE_NRM 69
#define TGSI_OPCODE_DIV 70
#define TGSI_OPCODE_DP2 71
-#define TGSI_OPCODE_DP2A TGSI_OPCODE_DOT2ADD
#define TGSI_OPCODE_TXL 72
#define TGSI_OPCODE_BRK 73
#define TGSI_OPCODE_IF 74
-#define TGSI_OPCODE_LOOP 75
+#define TGSI_OPCODE_BGNFOR 75
#define TGSI_OPCODE_REP 76
#define TGSI_OPCODE_ELSE 77
#define TGSI_OPCODE_ENDIF 78
-#define TGSI_OPCODE_ENDLOOP 79
+#define TGSI_OPCODE_ENDFOR 79
#define TGSI_OPCODE_ENDREP 80
-
-/*
- * GL_NV_vertex_program2_option
- */
-
-/*
- * GL_NV_vertex_program3
- */
#define TGSI_OPCODE_PUSHA 81
#define TGSI_OPCODE_POPA 82
-
-/*
- * GL_NV_gpu_program4
- */
#define TGSI_OPCODE_CEIL 83
#define TGSI_OPCODE_I2F 84
#define TGSI_OPCODE_NOT 85
@@ -323,103 +260,25 @@ struct tgsi_immediate_float32
#define TGSI_OPCODE_TXF 94
#define TGSI_OPCODE_TXQ 95
#define TGSI_OPCODE_CONT 96
-
-/*
- * GL_NV_vertex_program4
- */
-/* Same as GL_NV_gpu_program4 */
-
-/*
- * GL_NV_fragment_program4
- */
-/* Same as GL_NV_gpu_program4 */
-
-/*
- * GL_NV_geometry_program4
- */
-/* Same as GL_NV_gpu_program4 */
#define TGSI_OPCODE_EMIT 97
#define TGSI_OPCODE_ENDPRIM 98
-
-/*
- * GLSL
- */
-#define TGSI_OPCODE_BGNLOOP2 99
+#define TGSI_OPCODE_BGNLOOP 99
#define TGSI_OPCODE_BGNSUB 100
-#define TGSI_OPCODE_ENDLOOP2 101
+#define TGSI_OPCODE_ENDLOOP 101
#define TGSI_OPCODE_ENDSUB 102
-#define TGSI_OPCODE_INT TGSI_OPCODE_TRUNC
#define TGSI_OPCODE_NOISE1 103
#define TGSI_OPCODE_NOISE2 104
#define TGSI_OPCODE_NOISE3 105
#define TGSI_OPCODE_NOISE4 106
#define TGSI_OPCODE_NOP 107
-
-/*
- * ps_1_1
- */
-#define TGSI_OPCODE_TEXKILL TGSI_OPCODE_KIL
-
-/*
- * ps_1_2
- */
-/* CMP - use TGSI_OPCODE_CND0 */
-
-/*
- * ps_1_3
- */
-/* CMP - use TGSI_OPCODE_CND0 */
-
-/*
- * ps_1_4
- */
-#define TGSI_OPCODE_TEXLD TGSI_OPCODE_TEX
-
-/*
- * ps_2_0
- */
-#define TGSI_OPCODE_M4X4 TGSI_OPCODE_MULTIPLYMATRIX
-#define TGSI_OPCODE_M4X3 108
-#define TGSI_OPCODE_M3X4 109
-#define TGSI_OPCODE_M3X3 110
-#define TGSI_OPCODE_M3X2 111
-#define TGSI_OPCODE_CRS TGSI_OPCODE_XPD
+ /* gap */
#define TGSI_OPCODE_NRM4 112
-#define TGSI_OPCODE_SINCOS TGSI_OPCODE_SCS
-#define TGSI_OPCODE_TEXLDB TGSI_OPCODE_TXB
-#define TGSI_OPCODE_DP2ADD TGSI_OPCODE_DP2A
-
-/*
- * ps_2_x
- */
-#define TGSI_OPCODE_CALL TGSI_OPCODE_CAL
#define TGSI_OPCODE_CALLNZ 113
#define TGSI_OPCODE_IFC 114
-#define TGSI_OPCODE_BREAK TGSI_OPCODE_BRK
#define TGSI_OPCODE_BREAKC 115
-#define TGSI_OPCODE_DSX TGSI_OPCODE_DDX
-#define TGSI_OPCODE_DSY TGSI_OPCODE_DDY
-#define TGSI_OPCODE_TEXLDD TGSI_OPCODE_TXD
-
-/*
- * vs_1_1
- */
-#define TGSI_OPCODE_EXPP TGSI_OPCODE_EXP
-#define TGSI_OPCODE_LOGP TGSI_OPCODE_LG2
-
-/*
- * vs_2_0
- */
-#define TGSI_OPCODE_SGN TGSI_OPCODE_SSG
-#define TGSI_OPCODE_MOVA TGSI_OPCODE_ARR
-/* EXPP - use TGSI_OPCODE_EX2 */
-
-/*
- * vs_2_x
- */
-
+#define TGSI_OPCODE_KIL 116 /* conditional kill */
#define TGSI_OPCODE_END 117 /* aka HALT */
-
+#define TGSI_OPCODE_SWZ 118
#define TGSI_OPCODE_LAST 119
#define TGSI_SAT_NONE 0 /* do not saturate */
diff --git a/src/gallium/state_trackers/dri/dri_context.c b/src/gallium/state_trackers/dri/dri_context.c
index 6c617197eca..830e511fefd 100644
--- a/src/gallium/state_trackers/dri/dri_context.c
+++ b/src/gallium/state_trackers/dri/dri_context.c
@@ -109,9 +109,6 @@ dri_destroy_context(__DRIcontextPrivate * cPriv)
*/
st_flush(ctx->st, 0, NULL);
- if (screen->dummyContext == ctx)
- screen->dummyContext = NULL;
-
/* Also frees ctx->pipe?
*/
st_destroy_context(ctx->st);
@@ -153,11 +150,6 @@ dri_make_current(__DRIcontextPrivate * cPriv,
++ctx->bind_count;
- /* This is for situations in which we need a rendering context but
- * there may not be any currently bound.
- */
- screen->dummyContext = ctx;
-
if (ctx->dPriv != driDrawPriv) {
ctx->dPriv = driDrawPriv;
ctx->d_stamp = driDrawPriv->lastStamp - 1;
diff --git a/src/gallium/state_trackers/dri/dri_drawable.c b/src/gallium/state_trackers/dri/dri_drawable.c
index 1d91fbb89fb..0a952f7b284 100644
--- a/src/gallium/state_trackers/dri/dri_drawable.c
+++ b/src/gallium/state_trackers/dri/dri_drawable.c
@@ -204,6 +204,30 @@ dri_get_buffers(__DRIdrawablePrivate * dPriv)
st_resize_framebuffer(drawable->stfb, dri_drawable->w, dri_drawable->h);
}
+/**
+ * These are used for GLX_EXT_texture_from_pixmap
+ */
+void dri2_set_tex_buffer2(__DRIcontext *pDRICtx, GLint target,
+ GLint format, __DRIdrawable *dPriv)
+{
+ struct dri_drawable *drawable = dri_drawable(dPriv);
+ struct pipe_surface *ps;
+
+ dri_get_buffers(drawable->dPriv);
+ st_get_framebuffer_surface(drawable->stfb, ST_SURFACE_FRONT_LEFT, &ps);
+
+ st_bind_texture_surface(ps, target == GL_TEXTURE_2D ? ST_TEXTURE_2D :
+ ST_TEXTURE_RECT, 0,
+ format == GLX_TEXTURE_FORMAT_RGBA_EXT ?
+ PIPE_FORMAT_R8G8B8A8_UNORM : PIPE_FORMAT_R8G8B8X8_UNORM);
+}
+
+void dri2_set_tex_buffer(__DRIcontext *pDRICtx, GLint target,
+ __DRIdrawable *dPriv)
+{
+ dri2_set_tex_buffer2(pDRICtx, target, GLX_TEXTURE_FORMAT_RGBA_EXT, dPriv);
+}
+
void
dri_flush_frontbuffer(struct pipe_screen *screen,
struct pipe_surface *surf, void *context_private)
diff --git a/src/gallium/state_trackers/dri/dri_drawable.h b/src/gallium/state_trackers/dri/dri_drawable.h
index 2fbd5f1eb7c..dfd0b8766d2 100644
--- a/src/gallium/state_trackers/dri/dri_drawable.h
+++ b/src/gallium/state_trackers/dri/dri_drawable.h
@@ -91,6 +91,12 @@ void dri_get_buffers(__DRIdrawablePrivate * dPriv);
void dri_destroy_buffer(__DRIdrawablePrivate * dPriv);
+void dri2_set_tex_buffer2(__DRIcontext *pDRICtx, GLint target,
+ GLint glx_texture_format, __DRIdrawable *dPriv);
+
+void dri2_set_tex_buffer(__DRIcontext *pDRICtx, GLint target,
+ __DRIdrawable *dPriv);
+
void
dri1_update_drawables(struct dri_context *ctx,
struct dri_drawable *draw, struct dri_drawable *read);
diff --git a/src/gallium/state_trackers/dri/dri_screen.c b/src/gallium/state_trackers/dri/dri_screen.c
index 5f78b7264af..25555128f93 100644
--- a/src/gallium/state_trackers/dri/dri_screen.c
+++ b/src/gallium/state_trackers/dri/dri_screen.c
@@ -57,12 +57,19 @@ PUBLIC const char __driConfigOptions[] =
const uint __driNConfigOptions = 3;
+static const __DRItexBufferExtension dri2TexBufferExtension = {
+ { __DRI_TEX_BUFFER, __DRI_TEX_BUFFER_VERSION },
+ dri2_set_tex_buffer,
+ dri2_set_tex_buffer2,
+};
+
static const __DRIextension *dri_screen_extensions[] = {
&driReadDrawableExtension,
&driCopySubBufferExtension.base,
&driSwapControlExtension.base,
&driFrameTrackingExtension.base,
&driMediaStreamCounterExtension.base,
+ &dri2TexBufferExtension.base,
NULL
};
diff --git a/src/gallium/state_trackers/dri/dri_screen.h b/src/gallium/state_trackers/dri/dri_screen.h
index f3335bb09f9..f6c56d0f0c5 100644
--- a/src/gallium/state_trackers/dri/dri_screen.h
+++ b/src/gallium/state_trackers/dri/dri_screen.h
@@ -49,12 +49,6 @@ struct dri_screen
*/
driOptionCache optionCache;
- /**
- * Temporary(?) context to use for SwapBuffers or other situations in
- * which we need a rendering context, but none is currently bound.
- */
- struct dri_context *dummyContext;
-
/* drm */
int fd;
drmLock *drmLock;
diff --git a/src/gallium/state_trackers/egl/egl_context.c b/src/gallium/state_trackers/egl/egl_context.c
index e2da2180f71..2c8f51cf388 100644
--- a/src/gallium/state_trackers/egl/egl_context.c
+++ b/src/gallium/state_trackers/egl/egl_context.c
@@ -148,7 +148,7 @@ drm_destroy_context(_EGLDriver *drv, EGLDisplay dpy, EGLContext context)
{
struct drm_context *c = lookup_drm_context(context);
_eglUnlinkContext(&c->base);
- if (!c->base.IsBound) {
+ if (!_eglIsContextBound(&c->base)) {
st_destroy_context(c->st);
c->pipe->destroy(c->pipe);
free(c);
diff --git a/src/gallium/state_trackers/egl/egl_surface.c b/src/gallium/state_trackers/egl/egl_surface.c
index 86f2ea97e54..d4cd2d3c743 100644
--- a/src/gallium/state_trackers/egl/egl_surface.c
+++ b/src/gallium/state_trackers/egl/egl_surface.c
@@ -98,8 +98,8 @@ drm_create_texture(_EGLDriver *drv,
goto err_buf;
memset(&templat, 0, sizeof(templat));
- templat.tex_usage |= PIPE_TEXTURE_USAGE_DISPLAY_TARGET;
- templat.tex_usage |= PIPE_TEXTURE_USAGE_RENDER_TARGET;
+ templat.tex_usage = PIPE_TEXTURE_USAGE_RENDER_TARGET;
+ templat.tex_usage |= PIPE_TEXTURE_USAGE_PRIMARY;
templat.target = PIPE_TEXTURE_2D;
templat.last_level = 0;
templat.depth[0] = 1;
@@ -366,7 +366,7 @@ drm_destroy_surface(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface)
struct drm_surface *surf = lookup_drm_surface(surface);
_eglUnlinkSurface(&surf->base);
- if (!surf->base.IsBound) {
+ if (!_eglIsSurfaceBound(&surf->base)) {
if (surf->screen)
drm_takedown_shown_screen(drv, surf->screen);
st_unreference_framebuffer(surf->stfb);
diff --git a/src/gallium/state_trackers/glx/xlib/Makefile b/src/gallium/state_trackers/glx/xlib/Makefile
index 6d10b090aa0..7b2adc62c34 100644
--- a/src/gallium/state_trackers/glx/xlib/Makefile
+++ b/src/gallium/state_trackers/glx/xlib/Makefile
@@ -5,13 +5,12 @@ LIBNAME = xlib
LIBRARY_INCLUDES = \
-I$(TOP)/include \
- -I$(TOP)/src/mesa \
- -I$(TOP)/src/mesa/main
+ -I$(TOP)/src/mesa
C_SOURCES = \
- glxapi.c \
- fakeglx.c \
- fakeglx_fonts.c \
+ glx_api.c \
+ glx_getproc.c \
+ glx_usefont.c \
xm_api.c
include ../../../Makefile.template
diff --git a/src/gallium/state_trackers/glx/xlib/SConscript b/src/gallium/state_trackers/glx/xlib/SConscript
index 0dbe3413972..04a44c30671 100644
--- a/src/gallium/state_trackers/glx/xlib/SConscript
+++ b/src/gallium/state_trackers/glx/xlib/SConscript
@@ -18,9 +18,10 @@ if env['platform'] == 'linux' \
st_xlib = env.ConvenienceLibrary(
target = 'st_xlib',
- source = [ 'glxapi.c',
- 'fakeglx.c',
- 'fakeglx_fonts.c',
+ source = [
+ 'glx_api.c',
+ 'glx_getproc.c',
+ 'glx_usefont.c',
'xm_api.c',
]
)
diff --git a/src/gallium/state_trackers/glx/xlib/fakeglx.h b/src/gallium/state_trackers/glx/xlib/fakeglx.h
deleted file mode 100644
index e5fd960072e..00000000000
--- a/src/gallium/state_trackers/glx/xlib/fakeglx.h
+++ /dev/null
@@ -1,41 +0,0 @@
-
-/*
- * Mesa 3-D graphics library
- * Version: 3.5
- *
- * Copyright (C) 1999-2000 Brian Paul 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, 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
- * BRIAN PAUL 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 FAKEGLX_H
-#define FAKEGLX_H
-
-
-#include <X11/Xlib.h>
-
-struct _glxapi_table;
-
-extern struct _glxapi_table *_mesa_GetGLXDispatchTable(void);
-
-extern void Fake_glXUseXFont( Font font, int first, int count, int listbase );
-
-
-#endif
-
diff --git a/src/gallium/state_trackers/glx/xlib/fakeglx.c b/src/gallium/state_trackers/glx/xlib/glx_api.c
index 23777c76f6c..96490dbedaa 100644
--- a/src/gallium/state_trackers/glx/xlib/fakeglx.c
+++ b/src/gallium/state_trackers/glx/xlib/glx_api.c
@@ -1,8 +1,9 @@
/*
* Mesa 3-D graphics library
- * Version: 7.1
+ * Version: 7.6
*
* Copyright (C) 1999-2007 Brian Paul All Rights Reserved.
+ * Copyright (C) 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"),
@@ -23,31 +24,21 @@
*/
-/*
- * This is an emulation of the GLX API which allows Mesa/GLX-based programs
- * to run on X servers which do not have the real GLX extension.
- *
- * Thanks to the contributors:
- *
- * Initial version: Philip Brown ([email protected])
- * Better glXGetConfig() support: Armin Liebchen ([email protected])
- * Further visual-handling refinements: Wolfram Gloger
- *
- * Notes:
- * Don't be fooled, stereo isn't supported yet.
+/**
+ * "Fake" GLX API implemented in terms of the XMesa*() functions.
*/
-#include "glxapi.h"
+#define GLX_GLXEXT_PROTOTYPES
+#include "GL/glx.h"
+
#include "xm_api.h"
-#include "context.h"
-#include "config.h"
-#include "macros.h"
-#include "imports.h"
-#include "version.h"
-#include "fakeglx.h"
+#include "main/context.h"
+#include "main/config.h"
+#include "main/macros.h"
+#include "main/imports.h"
+#include "main/version.h"
#include "state_tracker/st_context.h"
#include "state_tracker/st_public.h"
@@ -80,24 +71,55 @@
"GLX_SGIX_fbconfig " \
"GLX_SGIX_pbuffer "
-/*
- * Our fake GLX context will contain a "real" GLX context and an XMesa context.
- *
- * Note that a pointer to a __GLXcontext is a pointer to a fake_glx_context,
- * and vice versa.
- *
- * We really just need this structure in order to make the libGL functions
- * glXGetCurrentContext(), glXGetCurrentDrawable() and glXGetCurrentDisplay()
- * work correctly.
+#define DEFAULT_DIRECT GL_TRUE
+
+
+
+/**
+ * The GLXContext typedef is defined as a pointer to this structure.
*/
-struct fake_glx_context {
- __GLXcontext glxContext; /* this MUST be first! */
+struct __GLXcontextRec
+{
+ Display *currentDpy;
+ GLboolean isDirect;
+ GLXDrawable currentDrawable;
+ GLXDrawable currentReadable;
+ XID xid;
+
XMesaContext xmesaContext;
};
-#define DEFAULT_DIRECT GL_TRUE
+static pipe_tsd ContextTSD;
+
+/** Set current context for calling thread */
+static void
+SetCurrentContext(GLXContext c)
+{
+ pipe_tsd_set(&ContextTSD, c);
+}
+
+/** Get current context for calling thread */
+static GLXContext
+GetCurrentContext(void)
+{
+ return pipe_tsd_get(&ContextTSD);
+}
+
+
+
+/**********************************************************************/
+/*** Debug helper code ***/
+/**********************************************************************/
+
+extern void _kw_ungrab_all( Display *dpy );
+void _kw_ungrab_all( Display *dpy )
+{
+ XUngrabPointer( dpy, CurrentTime );
+ XUngrabKeyboard( dpy, CurrentTime );
+}
+
/**********************************************************************/
@@ -366,10 +388,6 @@ find_glx_visual( Display *dpy, XVisualInfo *vinfo )
}
-
-
-
-
/**
* Try to get an X visual which matches the given arguments.
*/
@@ -418,7 +436,6 @@ get_visual( Display *dpy, int scr, unsigned int depth, int xclass )
}
-
/*
* Retrieve the value of the given environment variable and find
* the X visual which matches it.
@@ -1002,8 +1019,8 @@ choose_visual( Display *dpy, int screen, const int *list, GLboolean fbConfig )
}
-static XVisualInfo *
-Fake_glXChooseVisual( Display *dpy, int screen, int *list )
+XVisualInfo *
+glXChooseVisual( Display *dpy, int screen, int *list )
{
XMesaVisual xmvis;
@@ -1024,18 +1041,18 @@ Fake_glXChooseVisual( Display *dpy, int screen, int *list )
}
-static GLXContext
-Fake_glXCreateContext( Display *dpy, XVisualInfo *visinfo,
- GLXContext share_list, Bool direct )
+GLXContext
+glXCreateContext( Display *dpy, XVisualInfo *visinfo,
+ GLXContext share_list, Bool direct )
{
XMesaVisual xmvis;
- struct fake_glx_context *glxCtx;
- struct fake_glx_context *shareCtx = (struct fake_glx_context *) share_list;
+ GLXContext glxCtx;
+ GLXContext shareCtx = share_list;
if (!dpy || !visinfo)
return 0;
- glxCtx = CALLOC_STRUCT(fake_glx_context);
+ glxCtx = CALLOC_STRUCT(__GLXcontextRec);
if (!glxCtx)
return 0;
@@ -1062,13 +1079,11 @@ Fake_glXCreateContext( Display *dpy, XVisualInfo *visinfo,
return NULL;
}
- glxCtx->glxContext.isDirect = DEFAULT_DIRECT;
- glxCtx->glxContext.currentDpy = dpy;
- glxCtx->glxContext.xid = (XID) glxCtx; /* self pointer */
-
- assert((void *) glxCtx == (void *) &(glxCtx->glxContext));
+ glxCtx->isDirect = DEFAULT_DIRECT;
+ glxCtx->currentDpy = dpy;
+ glxCtx->xid = (XID) glxCtx; /* self pointer */
- return (GLXContext) glxCtx;
+ return glxCtx;
}
@@ -1081,11 +1096,11 @@ static XMesaBuffer MakeCurrent_PrevReadBuffer = 0;
/* GLX 1.3 and later */
-static Bool
-Fake_glXMakeContextCurrent( Display *dpy, GLXDrawable draw,
- GLXDrawable read, GLXContext ctx )
+Bool
+glXMakeContextCurrent( Display *dpy, GLXDrawable draw,
+ GLXDrawable read, GLXContext ctx )
{
- struct fake_glx_context *glxCtx = (struct fake_glx_context *) ctx;
+ GLXContext glxCtx = ctx;
static boolean firsttime = 1, no_rast = 0;
if (firsttime) {
@@ -1093,7 +1108,6 @@ Fake_glXMakeContextCurrent( Display *dpy, GLXDrawable draw,
firsttime = 0;
}
-
if (ctx && draw && read) {
XMesaBuffer drawBuffer, readBuffer;
XMesaContext xmctx = glxCtx->xmesaContext;
@@ -1148,9 +1162,10 @@ Fake_glXMakeContextCurrent( Display *dpy, GLXDrawable draw,
/* Now make current! */
if (XMesaMakeCurrent2(xmctx, drawBuffer, readBuffer)) {
- ((__GLXcontext *) ctx)->currentDpy = dpy;
- ((__GLXcontext *) ctx)->currentDrawable = draw;
- ((__GLXcontext *) ctx)->currentReadable = read;
+ ctx->currentDpy = dpy;
+ ctx->currentDrawable = draw;
+ ctx->currentReadable = read;
+ SetCurrentContext(ctx);
return True;
}
else {
@@ -1165,6 +1180,7 @@ Fake_glXMakeContextCurrent( Display *dpy, GLXDrawable draw,
MakeCurrent_PrevReadable = 0;
MakeCurrent_PrevDrawBuffer = 0;
MakeCurrent_PrevReadBuffer = 0;
+ SetCurrentContext(NULL);
return True;
}
else {
@@ -1176,15 +1192,61 @@ Fake_glXMakeContextCurrent( Display *dpy, GLXDrawable draw,
}
-static Bool
-Fake_glXMakeCurrent( Display *dpy, GLXDrawable drawable, GLXContext ctx )
+Bool
+glXMakeCurrent( Display *dpy, GLXDrawable drawable, GLXContext ctx )
{
- return Fake_glXMakeContextCurrent( dpy, drawable, drawable, ctx );
+ return glXMakeContextCurrent( dpy, drawable, drawable, ctx );
}
-static GLXPixmap
-Fake_glXCreateGLXPixmap( Display *dpy, XVisualInfo *visinfo, Pixmap pixmap )
+GLXContext
+glXGetCurrentContext(void)
+{
+ return GetCurrentContext();
+}
+
+
+Display *
+glXGetCurrentDisplay(void)
+{
+ GLXContext glxCtx = glXGetCurrentContext();
+
+ return glxCtx ? glxCtx->currentDpy : NULL;
+}
+
+
+Display *
+glXGetCurrentDisplayEXT(void)
+{
+ return glXGetCurrentDisplay();
+}
+
+
+GLXDrawable
+glXGetCurrentDrawable(void)
+{
+ GLXContext gc = glXGetCurrentContext();
+ return gc ? gc->currentDrawable : 0;
+}
+
+
+GLXDrawable
+glXGetCurrentReadDrawable(void)
+{
+ GLXContext gc = glXGetCurrentContext();
+ return gc ? gc->currentReadable : 0;
+}
+
+
+GLXDrawable
+glXGetCurrentReadDrawableSGI(void)
+{
+ return glXGetCurrentReadDrawable();
+}
+
+
+GLXPixmap
+glXCreateGLXPixmap( Display *dpy, XVisualInfo *visinfo, Pixmap pixmap )
{
XMesaVisual v;
XMesaBuffer b;
@@ -1208,9 +1270,9 @@ Fake_glXCreateGLXPixmap( Display *dpy, XVisualInfo *visinfo, Pixmap pixmap )
/*** GLX_MESA_pixmap_colormap ***/
-static GLXPixmap
-Fake_glXCreateGLXPixmapMESA( Display *dpy, XVisualInfo *visinfo,
- Pixmap pixmap, Colormap cmap )
+GLXPixmap
+glXCreateGLXPixmapMESA( Display *dpy, XVisualInfo *visinfo,
+ Pixmap pixmap, Colormap cmap )
{
XMesaVisual v;
XMesaBuffer b;
@@ -1232,8 +1294,8 @@ Fake_glXCreateGLXPixmapMESA( Display *dpy, XVisualInfo *visinfo,
}
-static void
-Fake_glXDestroyGLXPixmap( Display *dpy, GLXPixmap pixmap )
+void
+glXDestroyGLXPixmap( Display *dpy, GLXPixmap pixmap )
{
XMesaBuffer b = XMesaFindBuffer(dpy, pixmap);
if (b) {
@@ -1245,12 +1307,12 @@ Fake_glXDestroyGLXPixmap( Display *dpy, GLXPixmap pixmap )
}
-static void
-Fake_glXCopyContext( Display *dpy, GLXContext src, GLXContext dst,
- unsigned long mask )
+void
+glXCopyContext( Display *dpy, GLXContext src, GLXContext dst,
+ unsigned long mask )
{
- struct fake_glx_context *fakeSrc = (struct fake_glx_context *) src;
- struct fake_glx_context *fakeDst = (struct fake_glx_context *) dst;
+ GLXContext fakeSrc = src;
+ GLXContext fakeDst = dst;
XMesaContext xm_src = fakeSrc->xmesaContext;
XMesaContext xm_dst = fakeDst->xmesaContext;
(void) dpy;
@@ -1261,8 +1323,8 @@ Fake_glXCopyContext( Display *dpy, GLXContext src, GLXContext dst,
}
-static Bool
-Fake_glXQueryExtension( Display *dpy, int *errorb, int *event )
+Bool
+glXQueryExtension( Display *dpy, int *errorb, int *event )
{
/* Mesa's GLX isn't really an X extension but we try to act like one. */
(void) dpy;
@@ -1272,18 +1334,10 @@ Fake_glXQueryExtension( Display *dpy, int *errorb, int *event )
}
-extern void _kw_ungrab_all( Display *dpy );
-void _kw_ungrab_all( Display *dpy )
-{
- XUngrabPointer( dpy, CurrentTime );
- XUngrabKeyboard( dpy, CurrentTime );
-}
-
-
-static void
-Fake_glXDestroyContext( Display *dpy, GLXContext ctx )
+void
+glXDestroyContext( Display *dpy, GLXContext ctx )
{
- struct fake_glx_context *glxCtx = (struct fake_glx_context *) ctx;
+ GLXContext glxCtx = ctx;
(void) dpy;
MakeCurrent_PrevContext = 0;
MakeCurrent_PrevDrawable = 0;
@@ -1296,18 +1350,18 @@ Fake_glXDestroyContext( Display *dpy, GLXContext ctx )
}
-static Bool
-Fake_glXIsDirect( Display *dpy, GLXContext ctx )
+Bool
+glXIsDirect( Display *dpy, GLXContext ctx )
{
- struct fake_glx_context *glxCtx = (struct fake_glx_context *) ctx;
+ GLXContext glxCtx = ctx;
(void) ctx;
- return glxCtx->glxContext.isDirect;
+ return glxCtx->isDirect;
}
-static void
-Fake_glXSwapBuffers( Display *dpy, GLXDrawable drawable )
+void
+glXSwapBuffers( Display *dpy, GLXDrawable drawable )
{
XMesaBuffer buffer = XMesaFindBuffer( dpy, drawable );
static boolean firsttime = 1, no_rast = 0;
@@ -1333,8 +1387,8 @@ Fake_glXSwapBuffers( Display *dpy, GLXDrawable drawable )
/*** GLX_MESA_copy_sub_buffer ***/
-static void
-Fake_glXCopySubBufferMESA( Display *dpy, GLXDrawable drawable,
+void
+glXCopySubBufferMESA( Display *dpy, GLXDrawable drawable,
int x, int y, int width, int height )
{
XMesaBuffer buffer = XMesaFindBuffer( dpy, drawable );
@@ -1347,8 +1401,8 @@ Fake_glXCopySubBufferMESA( Display *dpy, GLXDrawable drawable,
}
-static Bool
-Fake_glXQueryVersion( Display *dpy, int *maj, int *min )
+Bool
+glXQueryVersion( Display *dpy, int *maj, int *min )
{
(void) dpy;
/* Return GLX version, not Mesa version */
@@ -1564,8 +1618,8 @@ get_config( XMesaVisual xmvis, int attrib, int *value, GLboolean fbconfig )
}
-static int
-Fake_glXGetConfig( Display *dpy, XVisualInfo *visinfo,
+int
+glXGetConfig( Display *dpy, XVisualInfo *visinfo,
int attrib, int *value )
{
XMesaVisual xmvis;
@@ -1594,8 +1648,8 @@ Fake_glXGetConfig( Display *dpy, XVisualInfo *visinfo,
}
-static void
-Fake_glXWaitGL( void )
+void
+glXWaitGL( void )
{
XMesaContext xmesa = XMesaGetCurrentContext();
XMesaFlush( xmesa );
@@ -1603,8 +1657,8 @@ Fake_glXWaitGL( void )
-static void
-Fake_glXWaitX( void )
+void
+glXWaitX( void )
{
XMesaContext xmesa = XMesaGetCurrentContext();
XMesaFlush( xmesa );
@@ -1620,8 +1674,8 @@ get_extensions( void )
/* GLX 1.1 and later */
-static const char *
-Fake_glXQueryExtensionsString( Display *dpy, int screen )
+const char *
+glXQueryExtensionsString( Display *dpy, int screen )
{
(void) dpy;
(void) screen;
@@ -1631,8 +1685,8 @@ Fake_glXQueryExtensionsString( Display *dpy, int screen )
/* GLX 1.1 and later */
-static const char *
-Fake_glXQueryServerString( Display *dpy, int screen, int name )
+const char *
+glXQueryServerString( Display *dpy, int screen, int name )
{
static char version[1000];
_mesa_sprintf(version, "%d.%d %s",
@@ -1656,8 +1710,8 @@ Fake_glXQueryServerString( Display *dpy, int screen, int name )
/* GLX 1.1 and later */
-static const char *
-Fake_glXGetClientString( Display *dpy, int name )
+const char *
+glXGetClientString( Display *dpy, int name )
{
static char version[1000];
_mesa_sprintf(version, "%d.%d %s", CLIENT_MAJOR_VERSION,
@@ -1684,8 +1738,8 @@ Fake_glXGetClientString( Display *dpy, int name )
*/
-static int
-Fake_glXGetFBConfigAttrib( Display *dpy, GLXFBConfig config,
+int
+glXGetFBConfigAttrib( Display *dpy, GLXFBConfig config,
int attribute, int *value )
{
XMesaVisual v = (XMesaVisual) config;
@@ -1699,8 +1753,8 @@ Fake_glXGetFBConfigAttrib( Display *dpy, GLXFBConfig config,
}
-static GLXFBConfig *
-Fake_glXGetFBConfigs( Display *dpy, int screen, int *nelements )
+GLXFBConfig *
+glXGetFBConfigs( Display *dpy, int screen, int *nelements )
{
XVisualInfo *visuals, visTemplate;
const long visMask = VisualScreenMask;
@@ -1725,15 +1779,15 @@ Fake_glXGetFBConfigs( Display *dpy, int screen, int *nelements )
}
-static GLXFBConfig *
-Fake_glXChooseFBConfig( Display *dpy, int screen,
+GLXFBConfig *
+glXChooseFBConfig( Display *dpy, int screen,
const int *attribList, int *nitems )
{
XMesaVisual xmvis;
if (!attribList || !attribList[0]) {
/* return list of all configs (per GLX_SGIX_fbconfig spec) */
- return Fake_glXGetFBConfigs(dpy, screen, nitems);
+ return glXGetFBConfigs(dpy, screen, nitems);
}
xmvis = choose_visual(dpy, screen, attribList, GL_TRUE);
@@ -1754,8 +1808,8 @@ Fake_glXChooseFBConfig( Display *dpy, int screen,
}
-static XVisualInfo *
-Fake_glXGetVisualFromFBConfig( Display *dpy, GLXFBConfig config )
+XVisualInfo *
+glXGetVisualFromFBConfig( Display *dpy, GLXFBConfig config )
{
if (dpy && config) {
XMesaVisual xmvis = (XMesaVisual) config;
@@ -1776,8 +1830,8 @@ Fake_glXGetVisualFromFBConfig( Display *dpy, GLXFBConfig config )
}
-static GLXWindow
-Fake_glXCreateWindow( Display *dpy, GLXFBConfig config, Window win,
+GLXWindow
+glXCreateWindow( Display *dpy, GLXFBConfig config, Window win,
const int *attribList )
{
XMesaVisual xmvis = (XMesaVisual) config;
@@ -1796,8 +1850,8 @@ Fake_glXCreateWindow( Display *dpy, GLXFBConfig config, Window win,
}
-static void
-Fake_glXDestroyWindow( Display *dpy, GLXWindow window )
+void
+glXDestroyWindow( Display *dpy, GLXWindow window )
{
XMesaBuffer b = XMesaFindBuffer(dpy, (Drawable) window);
if (b)
@@ -1807,8 +1861,8 @@ Fake_glXDestroyWindow( Display *dpy, GLXWindow window )
/* XXX untested */
-static GLXPixmap
-Fake_glXCreatePixmap( Display *dpy, GLXFBConfig config, Pixmap pixmap,
+GLXPixmap
+glXCreatePixmap( Display *dpy, GLXFBConfig config, Pixmap pixmap,
const int *attribList )
{
XMesaVisual v = (XMesaVisual) config;
@@ -1917,8 +1971,8 @@ Fake_glXCreatePixmap( Display *dpy, GLXFBConfig config, Pixmap pixmap,
}
-static void
-Fake_glXDestroyPixmap( Display *dpy, GLXPixmap pixmap )
+void
+glXDestroyPixmap( Display *dpy, GLXPixmap pixmap )
{
XMesaBuffer b = XMesaFindBuffer(dpy, (Drawable)pixmap);
if (b)
@@ -1927,8 +1981,8 @@ Fake_glXDestroyPixmap( Display *dpy, GLXPixmap pixmap )
}
-static GLXPbuffer
-Fake_glXCreatePbuffer( Display *dpy, GLXFBConfig config,
+GLXPbuffer
+glXCreatePbuffer( Display *dpy, GLXFBConfig config,
const int *attribList )
{
XMesaVisual xmvis = (XMesaVisual) config;
@@ -1980,8 +2034,8 @@ Fake_glXCreatePbuffer( Display *dpy, GLXFBConfig config,
}
-static void
-Fake_glXDestroyPbuffer( Display *dpy, GLXPbuffer pbuf )
+void
+glXDestroyPbuffer( Display *dpy, GLXPbuffer pbuf )
{
XMesaBuffer b = XMesaFindBuffer(dpy, pbuf);
if (b) {
@@ -1990,8 +2044,8 @@ Fake_glXDestroyPbuffer( Display *dpy, GLXPbuffer pbuf )
}
-static void
-Fake_glXQueryDrawable( Display *dpy, GLXDrawable draw, int attribute,
+void
+glXQueryDrawable( Display *dpy, GLXDrawable draw, int attribute,
unsigned int *value )
{
XMesaBuffer xmbuf = XMesaFindBuffer(dpy, draw);
@@ -2032,19 +2086,19 @@ Fake_glXQueryDrawable( Display *dpy, GLXDrawable draw, int attribute,
}
-static GLXContext
-Fake_glXCreateNewContext( Display *dpy, GLXFBConfig config,
+GLXContext
+glXCreateNewContext( Display *dpy, GLXFBConfig config,
int renderType, GLXContext shareList, Bool direct )
{
- struct fake_glx_context *glxCtx;
- struct fake_glx_context *shareCtx = (struct fake_glx_context *) shareList;
+ GLXContext glxCtx;
+ GLXContext shareCtx = shareList;
XMesaVisual xmvis = (XMesaVisual) config;
if (!dpy || !config ||
(renderType != GLX_RGBA_TYPE && renderType != GLX_COLOR_INDEX_TYPE))
return 0;
- glxCtx = CALLOC_STRUCT(fake_glx_context);
+ glxCtx = CALLOC_STRUCT(__GLXcontextRec);
if (!glxCtx)
return 0;
@@ -2058,20 +2112,18 @@ Fake_glXCreateNewContext( Display *dpy, GLXFBConfig config,
return NULL;
}
- glxCtx->glxContext.isDirect = DEFAULT_DIRECT;
- glxCtx->glxContext.currentDpy = dpy;
- glxCtx->glxContext.xid = (XID) glxCtx; /* self pointer */
-
- assert((void *) glxCtx == (void *) &(glxCtx->glxContext));
+ glxCtx->isDirect = DEFAULT_DIRECT;
+ glxCtx->currentDpy = dpy;
+ glxCtx->xid = (XID) glxCtx; /* self pointer */
- return (GLXContext) glxCtx;
+ return glxCtx;
}
-static int
-Fake_glXQueryContext( Display *dpy, GLXContext ctx, int attribute, int *value )
+int
+glXQueryContext( Display *dpy, GLXContext ctx, int attribute, int *value )
{
- struct fake_glx_context *glxCtx = (struct fake_glx_context *) ctx;
+ GLXContext glxCtx = ctx;
XMesaContext xmctx = glxCtx->xmesaContext;
(void) dpy;
@@ -2097,8 +2149,8 @@ Fake_glXQueryContext( Display *dpy, GLXContext ctx, int attribute, int *value )
}
-static void
-Fake_glXSelectEvent( Display *dpy, GLXDrawable drawable, unsigned long mask )
+void
+glXSelectEvent( Display *dpy, GLXDrawable drawable, unsigned long mask )
{
XMesaBuffer xmbuf = XMesaFindBuffer(dpy, drawable);
if (xmbuf)
@@ -2106,8 +2158,8 @@ Fake_glXSelectEvent( Display *dpy, GLXDrawable drawable, unsigned long mask )
}
-static void
-Fake_glXGetSelectedEvent( Display *dpy, GLXDrawable drawable,
+void
+glXGetSelectedEvent( Display *dpy, GLXDrawable drawable,
unsigned long *mask )
{
XMesaBuffer xmbuf = XMesaFindBuffer(dpy, drawable);
@@ -2121,8 +2173,8 @@ Fake_glXGetSelectedEvent( Display *dpy, GLXDrawable drawable,
/*** GLX_SGI_swap_control ***/
-static int
-Fake_glXSwapIntervalSGI(int interval)
+int
+glXSwapIntervalSGI(int interval)
{
(void) interval;
return 0;
@@ -2134,16 +2186,16 @@ Fake_glXSwapIntervalSGI(int interval)
static unsigned int FrameCounter = 0;
-static int
-Fake_glXGetVideoSyncSGI(unsigned int *count)
+int
+glXGetVideoSyncSGI(unsigned int *count)
{
/* this is a bogus implementation */
*count = FrameCounter++;
return 0;
}
-static int
-Fake_glXWaitVideoSyncSGI(int divisor, int remainder, unsigned int *count)
+int
+glXWaitVideoSyncSGI(int divisor, int remainder, unsigned int *count)
{
if (divisor <= 0 || remainder < 0)
return GLX_BAD_VALUE;
@@ -2159,15 +2211,15 @@ Fake_glXWaitVideoSyncSGI(int divisor, int remainder, unsigned int *count)
/*** GLX_SGI_make_current_read ***/
-static Bool
-Fake_glXMakeCurrentReadSGI(Display *dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx)
+Bool
+glXMakeCurrentReadSGI(Display *dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx)
{
- return Fake_glXMakeContextCurrent( dpy, draw, read, ctx );
+ return glXMakeContextCurrent( dpy, draw, read, ctx );
}
/* not used
static GLXDrawable
-Fake_glXGetCurrentReadDrawableSGI(void)
+glXGetCurrentReadDrawableSGI(void)
{
return 0;
}
@@ -2177,8 +2229,8 @@ Fake_glXGetCurrentReadDrawableSGI(void)
/*** GLX_SGIX_video_source ***/
#if defined(_VL_H)
-static GLXVideoSourceSGIX
-Fake_glXCreateGLXVideoSourceSGIX(Display *dpy, int screen, VLServer server, VLPath path, int nodeClass, VLNode drainNode)
+GLXVideoSourceSGIX
+glXCreateGLXVideoSourceSGIX(Display *dpy, int screen, VLServer server, VLPath path, int nodeClass, VLNode drainNode)
{
(void) dpy;
(void) screen;
@@ -2189,8 +2241,8 @@ Fake_glXCreateGLXVideoSourceSGIX(Display *dpy, int screen, VLServer server, VLPa
return 0;
}
-static void
-Fake_glXDestroyGLXVideoSourceSGIX(Display *dpy, GLXVideoSourceSGIX src)
+void
+glXDestroyGLXVideoSourceSGIX(Display *dpy, GLXVideoSourceSGIX src)
{
(void) dpy;
(void) src;
@@ -2201,30 +2253,30 @@ Fake_glXDestroyGLXVideoSourceSGIX(Display *dpy, GLXVideoSourceSGIX src)
/*** GLX_EXT_import_context ***/
-static void
-Fake_glXFreeContextEXT(Display *dpy, GLXContext context)
+void
+glXFreeContextEXT(Display *dpy, GLXContext context)
{
(void) dpy;
(void) context;
}
-static GLXContextID
-Fake_glXGetContextIDEXT(const GLXContext context)
+GLXContextID
+glXGetContextIDEXT(const GLXContext context)
{
(void) context;
return 0;
}
-static GLXContext
-Fake_glXImportContextEXT(Display *dpy, GLXContextID contextID)
+GLXContext
+glXImportContextEXT(Display *dpy, GLXContextID contextID)
{
(void) dpy;
(void) contextID;
return 0;
}
-static int
-Fake_glXQueryContextInfoEXT(Display *dpy, GLXContext context, int attribute, int *value)
+int
+glXQueryContextInfoEXT(Display *dpy, GLXContext context, int attribute, int *value)
{
(void) dpy;
(void) context;
@@ -2237,21 +2289,21 @@ Fake_glXQueryContextInfoEXT(Display *dpy, GLXContext context, int attribute, int
/*** GLX_SGIX_fbconfig ***/
-static int
-Fake_glXGetFBConfigAttribSGIX(Display *dpy, GLXFBConfigSGIX config, int attribute, int *value)
+int
+glXGetFBConfigAttribSGIX(Display *dpy, GLXFBConfigSGIX config, int attribute, int *value)
{
- return Fake_glXGetFBConfigAttrib(dpy, config, attribute, value);
+ return glXGetFBConfigAttrib(dpy, config, attribute, value);
}
-static GLXFBConfigSGIX *
-Fake_glXChooseFBConfigSGIX(Display *dpy, int screen, int *attrib_list, int *nelements)
+GLXFBConfigSGIX *
+glXChooseFBConfigSGIX(Display *dpy, int screen, int *attrib_list, int *nelements)
{
- return (GLXFBConfig *) Fake_glXChooseFBConfig(dpy, screen, attrib_list, nelements);
+ return (GLXFBConfig *) glXChooseFBConfig(dpy, screen, attrib_list, nelements);
}
-static GLXPixmap
-Fake_glXCreateGLXPixmapWithConfigSGIX(Display *dpy, GLXFBConfigSGIX config, Pixmap pixmap)
+GLXPixmap
+glXCreateGLXPixmapWithConfigSGIX(Display *dpy, GLXFBConfigSGIX config, Pixmap pixmap)
{
XMesaVisual xmvis = (XMesaVisual) config;
XMesaBuffer xmbuf = XMesaCreatePixmapBuffer(xmvis, pixmap, 0);
@@ -2259,14 +2311,14 @@ Fake_glXCreateGLXPixmapWithConfigSGIX(Display *dpy, GLXFBConfigSGIX config, Pixm
}
-static GLXContext
-Fake_glXCreateContextWithConfigSGIX(Display *dpy, GLXFBConfigSGIX config, int render_type, GLXContext share_list, Bool direct)
+GLXContext
+glXCreateContextWithConfigSGIX(Display *dpy, GLXFBConfigSGIX config, int render_type, GLXContext share_list, Bool direct)
{
XMesaVisual xmvis = (XMesaVisual) config;
- struct fake_glx_context *glxCtx;
- struct fake_glx_context *shareCtx = (struct fake_glx_context *) share_list;
+ GLXContext glxCtx;
+ GLXContext shareCtx = share_list;
- glxCtx = CALLOC_STRUCT(fake_glx_context);
+ glxCtx = CALLOC_STRUCT(__GLXcontextRec);
if (!glxCtx)
return 0;
@@ -2280,25 +2332,23 @@ Fake_glXCreateContextWithConfigSGIX(Display *dpy, GLXFBConfigSGIX config, int re
return NULL;
}
- glxCtx->glxContext.isDirect = DEFAULT_DIRECT;
- glxCtx->glxContext.currentDpy = dpy;
- glxCtx->glxContext.xid = (XID) glxCtx; /* self pointer */
-
- assert((void *) glxCtx == (void *) &(glxCtx->glxContext));
+ glxCtx->isDirect = DEFAULT_DIRECT;
+ glxCtx->currentDpy = dpy;
+ glxCtx->xid = (XID) glxCtx; /* self pointer */
- return (GLXContext) glxCtx;
+ return glxCtx;
}
-static XVisualInfo *
-Fake_glXGetVisualFromFBConfigSGIX(Display *dpy, GLXFBConfigSGIX config)
+XVisualInfo *
+glXGetVisualFromFBConfigSGIX(Display *dpy, GLXFBConfigSGIX config)
{
- return Fake_glXGetVisualFromFBConfig(dpy, config);
+ return glXGetVisualFromFBConfig(dpy, config);
}
-static GLXFBConfigSGIX
-Fake_glXGetFBConfigFromVisualSGIX(Display *dpy, XVisualInfo *vis)
+GLXFBConfigSGIX
+glXGetFBConfigFromVisualSGIX(Display *dpy, XVisualInfo *vis)
{
XMesaVisual xmvis = find_glx_visual(dpy, vis);
if (!xmvis) {
@@ -2313,8 +2363,8 @@ Fake_glXGetFBConfigFromVisualSGIX(Display *dpy, XVisualInfo *vis)
/*** GLX_SGIX_pbuffer ***/
-static GLXPbufferSGIX
-Fake_glXCreateGLXPbufferSGIX(Display *dpy, GLXFBConfigSGIX config,
+GLXPbufferSGIX
+glXCreateGLXPbufferSGIX(Display *dpy, GLXFBConfigSGIX config,
unsigned int width, unsigned int height,
int *attribList)
{
@@ -2352,8 +2402,8 @@ Fake_glXCreateGLXPbufferSGIX(Display *dpy, GLXFBConfigSGIX config,
}
-static void
-Fake_glXDestroyGLXPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuf)
+void
+glXDestroyGLXPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuf)
{
XMesaBuffer xmbuf = XMesaFindBuffer(dpy, pbuf);
if (xmbuf) {
@@ -2362,8 +2412,8 @@ Fake_glXDestroyGLXPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuf)
}
-static int
-Fake_glXQueryGLXPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuf, int attribute, unsigned int *value)
+int
+glXQueryGLXPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuf, int attribute, unsigned int *value)
{
const XMesaBuffer xmbuf = XMesaFindBuffer(dpy, pbuf);
@@ -2395,8 +2445,8 @@ Fake_glXQueryGLXPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuf, int attribute, un
}
-static void
-Fake_glXSelectEventSGIX(Display *dpy, GLXDrawable drawable, unsigned long mask)
+void
+glXSelectEventSGIX(Display *dpy, GLXDrawable drawable, unsigned long mask)
{
XMesaBuffer xmbuf = XMesaFindBuffer(dpy, drawable);
if (xmbuf) {
@@ -2406,8 +2456,8 @@ Fake_glXSelectEventSGIX(Display *dpy, GLXDrawable drawable, unsigned long mask)
}
-static void
-Fake_glXGetSelectedEventSGIX(Display *dpy, GLXDrawable drawable, unsigned long *mask)
+void
+glXGetSelectedEventSGIX(Display *dpy, GLXDrawable drawable, unsigned long *mask)
{
XMesaBuffer xmbuf = XMesaFindBuffer(dpy, drawable);
if (xmbuf) {
@@ -2422,8 +2472,8 @@ Fake_glXGetSelectedEventSGIX(Display *dpy, GLXDrawable drawable, unsigned long *
/*** GLX_SGI_cushion ***/
-static void
-Fake_glXCushionSGI(Display *dpy, Window win, float cushion)
+void
+glXCushionSGI(Display *dpy, Window win, float cushion)
{
(void) dpy;
(void) win;
@@ -2434,8 +2484,8 @@ Fake_glXCushionSGI(Display *dpy, Window win, float cushion)
/*** GLX_SGIX_video_resize ***/
-static int
-Fake_glXBindChannelToWindowSGIX(Display *dpy, int screen, int channel , Window window)
+int
+glXBindChannelToWindowSGIX(Display *dpy, int screen, int channel , Window window)
{
(void) dpy;
(void) screen;
@@ -2444,8 +2494,8 @@ Fake_glXBindChannelToWindowSGIX(Display *dpy, int screen, int channel , Window w
return 0;
}
-static int
-Fake_glXChannelRectSGIX(Display *dpy, int screen, int channel, int x, int y, int w, int h)
+int
+glXChannelRectSGIX(Display *dpy, int screen, int channel, int x, int y, int w, int h)
{
(void) dpy;
(void) screen;
@@ -2457,8 +2507,8 @@ Fake_glXChannelRectSGIX(Display *dpy, int screen, int channel, int x, int y, int
return 0;
}
-static int
-Fake_glXQueryChannelRectSGIX(Display *dpy, int screen, int channel, int *x, int *y, int *w, int *h)
+int
+glXQueryChannelRectSGIX(Display *dpy, int screen, int channel, int *x, int *y, int *w, int *h)
{
(void) dpy;
(void) screen;
@@ -2470,8 +2520,8 @@ Fake_glXQueryChannelRectSGIX(Display *dpy, int screen, int channel, int *x, int
return 0;
}
-static int
-Fake_glXQueryChannelDeltasSGIX(Display *dpy, int screen, int channel, int *dx, int *dy, int *dw, int *dh)
+int
+glXQueryChannelDeltasSGIX(Display *dpy, int screen, int channel, int *dx, int *dy, int *dw, int *dh)
{
(void) dpy;
(void) screen;
@@ -2483,8 +2533,8 @@ Fake_glXQueryChannelDeltasSGIX(Display *dpy, int screen, int channel, int *dx, i
return 0;
}
-static int
-Fake_glXChannelRectSyncSGIX(Display *dpy, int screen, int channel, GLenum synctype)
+int
+glXChannelRectSyncSGIX(Display *dpy, int screen, int channel, GLenum synctype)
{
(void) dpy;
(void) screen;
@@ -2498,8 +2548,8 @@ Fake_glXChannelRectSyncSGIX(Display *dpy, int screen, int channel, GLenum syncty
/*** GLX_SGIX_dmbuffer **/
#if defined(_DM_BUFFER_H_)
-static Bool
-Fake_glXAssociateDMPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuffer, DMparams *params, DMbuffer dmbuffer)
+Bool
+glXAssociateDMPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuffer, DMparams *params, DMbuffer dmbuffer)
{
(void) dpy;
(void) pbuffer;
@@ -2512,8 +2562,8 @@ Fake_glXAssociateDMPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuffer, DMparams *p
/*** GLX_SGIX_swap_group ***/
-static void
-Fake_glXJoinSwapGroupSGIX(Display *dpy, GLXDrawable drawable, GLXDrawable member)
+void
+glXJoinSwapGroupSGIX(Display *dpy, GLXDrawable drawable, GLXDrawable member)
{
(void) dpy;
(void) drawable;
@@ -2524,16 +2574,16 @@ Fake_glXJoinSwapGroupSGIX(Display *dpy, GLXDrawable drawable, GLXDrawable member
/*** GLX_SGIX_swap_barrier ***/
-static void
-Fake_glXBindSwapBarrierSGIX(Display *dpy, GLXDrawable drawable, int barrier)
+void
+glXBindSwapBarrierSGIX(Display *dpy, GLXDrawable drawable, int barrier)
{
(void) dpy;
(void) drawable;
(void) barrier;
}
-static Bool
-Fake_glXQueryMaxSwapBarriersSGIX(Display *dpy, int screen, int *max)
+Bool
+glXQueryMaxSwapBarriersSGIX(Display *dpy, int screen, int *max)
{
(void) dpy;
(void) screen;
@@ -2545,8 +2595,8 @@ Fake_glXQueryMaxSwapBarriersSGIX(Display *dpy, int screen, int *max)
/*** GLX_SUN_get_transparent_index ***/
-static Status
-Fake_glXGetTransparentIndexSUN(Display *dpy, Window overlay, Window underlay, long *pTransparent)
+Status
+glXGetTransparentIndexSUN(Display *dpy, Window overlay, Window underlay, long *pTransparent)
{
(void) dpy;
(void) overlay;
@@ -2563,8 +2613,8 @@ Fake_glXGetTransparentIndexSUN(Display *dpy, Window overlay, Window underlay, lo
* Release the depth, stencil, accum buffers attached to a GLXDrawable
* (a window or pixmap) prior to destroying the GLXDrawable.
*/
-static Bool
-Fake_glXReleaseBuffersMESA( Display *dpy, GLXDrawable d )
+Bool
+glXReleaseBuffersMESA( Display *dpy, GLXDrawable d )
{
XMesaBuffer b = XMesaFindBuffer(dpy, d);
if (b) {
@@ -2576,8 +2626,8 @@ Fake_glXReleaseBuffersMESA( Display *dpy, GLXDrawable d )
/*** GLX_EXT_texture_from_pixmap ***/
-static void
-Fake_glXBindTexImageEXT(Display *dpy, GLXDrawable drawable, int buffer,
+void
+glXBindTexImageEXT(Display *dpy, GLXDrawable drawable, int buffer,
const int *attrib_list)
{
XMesaBuffer b = XMesaFindBuffer(dpy, drawable);
@@ -2585,162 +2635,10 @@ Fake_glXBindTexImageEXT(Display *dpy, GLXDrawable drawable, int buffer,
XMesaBindTexImage(dpy, b, buffer, attrib_list);
}
-static void
-Fake_glXReleaseTexImageEXT(Display *dpy, GLXDrawable drawable, int buffer)
+void
+glXReleaseTexImageEXT(Display *dpy, GLXDrawable drawable, int buffer)
{
XMesaBuffer b = XMesaFindBuffer(dpy, drawable);
if (b)
XMesaReleaseTexImage(dpy, b, buffer);
}
-
-
-
-/**
- * Create a new GLX API dispatch table with its function pointers
- * initialized to point to Mesa's "fake" GLX API functions.
- *
- * Note: there used to be a similar function
- * (_real_GetGLXDispatchTable) that returns a new dispatch table with
- * all pointers initalized to point to "real" GLX functions (which
- * understand GLX wire protocol, etc).
- */
-struct _glxapi_table *
-_mesa_GetGLXDispatchTable(void)
-{
- static struct _glxapi_table glx;
-
- /* be sure our dispatch table size <= libGL's table */
- {
- GLuint size = sizeof(struct _glxapi_table) / sizeof(void *);
- (void) size;
- assert(_glxapi_get_dispatch_table_size() >= size);
- }
-
- /* initialize the whole table to no-ops */
- _glxapi_set_no_op_table(&glx);
-
- /* now initialize the table with the functions I implement */
- glx.ChooseVisual = Fake_glXChooseVisual;
- glx.CopyContext = Fake_glXCopyContext;
- glx.CreateContext = Fake_glXCreateContext;
- glx.CreateGLXPixmap = Fake_glXCreateGLXPixmap;
- glx.DestroyContext = Fake_glXDestroyContext;
- glx.DestroyGLXPixmap = Fake_glXDestroyGLXPixmap;
- glx.GetConfig = Fake_glXGetConfig;
- /*glx.GetCurrentContext = Fake_glXGetCurrentContext;*/
- /*glx.GetCurrentDrawable = Fake_glXGetCurrentDrawable;*/
- glx.IsDirect = Fake_glXIsDirect;
- glx.MakeCurrent = Fake_glXMakeCurrent;
- glx.QueryExtension = Fake_glXQueryExtension;
- glx.QueryVersion = Fake_glXQueryVersion;
- glx.SwapBuffers = Fake_glXSwapBuffers;
- glx.UseXFont = Fake_glXUseXFont;
- glx.WaitGL = Fake_glXWaitGL;
- glx.WaitX = Fake_glXWaitX;
-
- /*** GLX_VERSION_1_1 ***/
- glx.GetClientString = Fake_glXGetClientString;
- glx.QueryExtensionsString = Fake_glXQueryExtensionsString;
- glx.QueryServerString = Fake_glXQueryServerString;
-
- /*** GLX_VERSION_1_2 ***/
- /*glx.GetCurrentDisplay = Fake_glXGetCurrentDisplay;*/
-
- /*** GLX_VERSION_1_3 ***/
- glx.ChooseFBConfig = Fake_glXChooseFBConfig;
- glx.CreateNewContext = Fake_glXCreateNewContext;
- glx.CreatePbuffer = Fake_glXCreatePbuffer;
- glx.CreatePixmap = Fake_glXCreatePixmap;
- glx.CreateWindow = Fake_glXCreateWindow;
- glx.DestroyPbuffer = Fake_glXDestroyPbuffer;
- glx.DestroyPixmap = Fake_glXDestroyPixmap;
- glx.DestroyWindow = Fake_glXDestroyWindow;
- /*glx.GetCurrentReadDrawable = Fake_glXGetCurrentReadDrawable;*/
- glx.GetFBConfigAttrib = Fake_glXGetFBConfigAttrib;
- glx.GetFBConfigs = Fake_glXGetFBConfigs;
- glx.GetSelectedEvent = Fake_glXGetSelectedEvent;
- glx.GetVisualFromFBConfig = Fake_glXGetVisualFromFBConfig;
- glx.MakeContextCurrent = Fake_glXMakeContextCurrent;
- glx.QueryContext = Fake_glXQueryContext;
- glx.QueryDrawable = Fake_glXQueryDrawable;
- glx.SelectEvent = Fake_glXSelectEvent;
-
- /*** GLX_SGI_swap_control ***/
- glx.SwapIntervalSGI = Fake_glXSwapIntervalSGI;
-
- /*** GLX_SGI_video_sync ***/
- glx.GetVideoSyncSGI = Fake_glXGetVideoSyncSGI;
- glx.WaitVideoSyncSGI = Fake_glXWaitVideoSyncSGI;
-
- /*** GLX_SGI_make_current_read ***/
- glx.MakeCurrentReadSGI = Fake_glXMakeCurrentReadSGI;
- /*glx.GetCurrentReadDrawableSGI = Fake_glXGetCurrentReadDrawableSGI;*/
-
-/*** GLX_SGIX_video_source ***/
-#if defined(_VL_H)
- glx.CreateGLXVideoSourceSGIX = Fake_glXCreateGLXVideoSourceSGIX;
- glx.DestroyGLXVideoSourceSGIX = Fake_glXDestroyGLXVideoSourceSGIX;
-#endif
-
- /*** GLX_EXT_import_context ***/
- glx.FreeContextEXT = Fake_glXFreeContextEXT;
- glx.GetContextIDEXT = Fake_glXGetContextIDEXT;
- /*glx.GetCurrentDisplayEXT = Fake_glXGetCurrentDisplayEXT;*/
- glx.ImportContextEXT = Fake_glXImportContextEXT;
- glx.QueryContextInfoEXT = Fake_glXQueryContextInfoEXT;
-
- /*** GLX_SGIX_fbconfig ***/
- glx.GetFBConfigAttribSGIX = Fake_glXGetFBConfigAttribSGIX;
- glx.ChooseFBConfigSGIX = Fake_glXChooseFBConfigSGIX;
- glx.CreateGLXPixmapWithConfigSGIX = Fake_glXCreateGLXPixmapWithConfigSGIX;
- glx.CreateContextWithConfigSGIX = Fake_glXCreateContextWithConfigSGIX;
- glx.GetVisualFromFBConfigSGIX = Fake_glXGetVisualFromFBConfigSGIX;
- glx.GetFBConfigFromVisualSGIX = Fake_glXGetFBConfigFromVisualSGIX;
-
- /*** GLX_SGIX_pbuffer ***/
- glx.CreateGLXPbufferSGIX = Fake_glXCreateGLXPbufferSGIX;
- glx.DestroyGLXPbufferSGIX = Fake_glXDestroyGLXPbufferSGIX;
- glx.QueryGLXPbufferSGIX = Fake_glXQueryGLXPbufferSGIX;
- glx.SelectEventSGIX = Fake_glXSelectEventSGIX;
- glx.GetSelectedEventSGIX = Fake_glXGetSelectedEventSGIX;
-
- /*** GLX_SGI_cushion ***/
- glx.CushionSGI = Fake_glXCushionSGI;
-
- /*** GLX_SGIX_video_resize ***/
- glx.BindChannelToWindowSGIX = Fake_glXBindChannelToWindowSGIX;
- glx.ChannelRectSGIX = Fake_glXChannelRectSGIX;
- glx.QueryChannelRectSGIX = Fake_glXQueryChannelRectSGIX;
- glx.QueryChannelDeltasSGIX = Fake_glXQueryChannelDeltasSGIX;
- glx.ChannelRectSyncSGIX = Fake_glXChannelRectSyncSGIX;
-
- /*** GLX_SGIX_dmbuffer **/
-#if defined(_DM_BUFFER_H_)
- glx.AssociateDMPbufferSGIX = NULL;
-#endif
-
- /*** GLX_SGIX_swap_group ***/
- glx.JoinSwapGroupSGIX = Fake_glXJoinSwapGroupSGIX;
-
- /*** GLX_SGIX_swap_barrier ***/
- glx.BindSwapBarrierSGIX = Fake_glXBindSwapBarrierSGIX;
- glx.QueryMaxSwapBarriersSGIX = Fake_glXQueryMaxSwapBarriersSGIX;
-
- /*** GLX_SUN_get_transparent_index ***/
- glx.GetTransparentIndexSUN = Fake_glXGetTransparentIndexSUN;
-
- /*** GLX_MESA_copy_sub_buffer ***/
- glx.CopySubBufferMESA = Fake_glXCopySubBufferMESA;
-
- /*** GLX_MESA_release_buffers ***/
- glx.ReleaseBuffersMESA = Fake_glXReleaseBuffersMESA;
-
- /*** GLX_MESA_pixmap_colormap ***/
- glx.CreateGLXPixmapMESA = Fake_glXCreateGLXPixmapMESA;
-
- /*** GLX_EXT_texture_from_pixmap ***/
- glx.BindTexImageEXT = Fake_glXBindTexImageEXT;
- glx.ReleaseTexImageEXT = Fake_glXReleaseTexImageEXT;
-
- return &glx;
-}
diff --git a/src/gallium/state_trackers/glx/xlib/glx_getproc.c b/src/gallium/state_trackers/glx/xlib/glx_getproc.c
new file mode 100644
index 00000000000..ca7d88c9227
--- /dev/null
+++ b/src/gallium/state_trackers/glx/xlib/glx_getproc.c
@@ -0,0 +1,214 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 7.6
+ *
+ * Copyright (C) 1999-2008 Brian Paul All Rights Reserved.
+ * Copyright (C) 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, 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
+ * BRIAN PAUL 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.
+ */
+
+
+/**
+ * glXGetProcAddress()
+ */
+
+
+#define GLX_GLXEXT_PROTOTYPES
+
+#include <string.h>
+#include "GL/glx.h"
+#include "glapi/glapi.h"
+
+
+struct name_address_pair {
+ const char *Name;
+ __GLXextFuncPtr Address;
+};
+
+
+static struct name_address_pair GLX_functions[] = {
+ /*** GLX_VERSION_1_0 ***/
+ { "glXChooseVisual", (__GLXextFuncPtr) glXChooseVisual },
+ { "glXCopyContext", (__GLXextFuncPtr) glXCopyContext },
+ { "glXCreateContext", (__GLXextFuncPtr) glXCreateContext },
+ { "glXCreateGLXPixmap", (__GLXextFuncPtr) glXCreateGLXPixmap },
+ { "glXDestroyContext", (__GLXextFuncPtr) glXDestroyContext },
+ { "glXDestroyGLXPixmap", (__GLXextFuncPtr) glXDestroyGLXPixmap },
+ { "glXGetConfig", (__GLXextFuncPtr) glXGetConfig },
+ { "glXGetCurrentContext", (__GLXextFuncPtr) glXGetCurrentContext },
+ { "glXGetCurrentDrawable", (__GLXextFuncPtr) glXGetCurrentDrawable },
+ { "glXIsDirect", (__GLXextFuncPtr) glXIsDirect },
+ { "glXMakeCurrent", (__GLXextFuncPtr) glXMakeCurrent },
+ { "glXQueryExtension", (__GLXextFuncPtr) glXQueryExtension },
+ { "glXQueryVersion", (__GLXextFuncPtr) glXQueryVersion },
+ { "glXSwapBuffers", (__GLXextFuncPtr) glXSwapBuffers },
+ { "glXUseXFont", (__GLXextFuncPtr) glXUseXFont },
+ { "glXWaitGL", (__GLXextFuncPtr) glXWaitGL },
+ { "glXWaitX", (__GLXextFuncPtr) glXWaitX },
+
+ /*** GLX_VERSION_1_1 ***/
+ { "glXGetClientString", (__GLXextFuncPtr) glXGetClientString },
+ { "glXQueryExtensionsString", (__GLXextFuncPtr) glXQueryExtensionsString },
+ { "glXQueryServerString", (__GLXextFuncPtr) glXQueryServerString },
+
+ /*** GLX_VERSION_1_2 ***/
+ { "glXGetCurrentDisplay", (__GLXextFuncPtr) glXGetCurrentDisplay },
+
+ /*** GLX_VERSION_1_3 ***/
+ { "glXChooseFBConfig", (__GLXextFuncPtr) glXChooseFBConfig },
+ { "glXCreateNewContext", (__GLXextFuncPtr) glXCreateNewContext },
+ { "glXCreatePbuffer", (__GLXextFuncPtr) glXCreatePbuffer },
+ { "glXCreatePixmap", (__GLXextFuncPtr) glXCreatePixmap },
+ { "glXCreateWindow", (__GLXextFuncPtr) glXCreateWindow },
+ { "glXDestroyPbuffer", (__GLXextFuncPtr) glXDestroyPbuffer },
+ { "glXDestroyPixmap", (__GLXextFuncPtr) glXDestroyPixmap },
+ { "glXDestroyWindow", (__GLXextFuncPtr) glXDestroyWindow },
+ { "glXGetCurrentReadDrawable", (__GLXextFuncPtr) glXGetCurrentReadDrawable },
+ { "glXGetFBConfigAttrib", (__GLXextFuncPtr) glXGetFBConfigAttrib },
+ { "glXGetFBConfigs", (__GLXextFuncPtr) glXGetFBConfigs },
+ { "glXGetSelectedEvent", (__GLXextFuncPtr) glXGetSelectedEvent },
+ { "glXGetVisualFromFBConfig", (__GLXextFuncPtr) glXGetVisualFromFBConfig },
+ { "glXMakeContextCurrent", (__GLXextFuncPtr) glXMakeContextCurrent },
+ { "glXQueryContext", (__GLXextFuncPtr) glXQueryContext },
+ { "glXQueryDrawable", (__GLXextFuncPtr) glXQueryDrawable },
+ { "glXSelectEvent", (__GLXextFuncPtr) glXSelectEvent },
+
+ /*** GLX_VERSION_1_4 ***/
+ { "glXGetProcAddress", (__GLXextFuncPtr) glXGetProcAddress },
+
+ /*** GLX_SGI_swap_control ***/
+ { "glXSwapIntervalSGI", (__GLXextFuncPtr) glXSwapIntervalSGI },
+
+ /*** GLX_SGI_video_sync ***/
+ { "glXGetVideoSyncSGI", (__GLXextFuncPtr) glXGetVideoSyncSGI },
+ { "glXWaitVideoSyncSGI", (__GLXextFuncPtr) glXWaitVideoSyncSGI },
+
+ /*** GLX_SGI_make_current_read ***/
+ { "glXMakeCurrentReadSGI", (__GLXextFuncPtr) glXMakeCurrentReadSGI },
+ { "glXGetCurrentReadDrawableSGI", (__GLXextFuncPtr) glXGetCurrentReadDrawableSGI },
+
+ /*** GLX_SGIX_video_source ***/
+#if defined(_VL_H)
+ { "glXCreateGLXVideoSourceSGIX", (__GLXextFuncPtr) glXCreateGLXVideoSourceSGIX },
+ { "glXDestroyGLXVideoSourceSGIX", (__GLXextFuncPtr) glXDestroyGLXVideoSourceSGIX },
+#endif
+
+ /*** GLX_EXT_import_context ***/
+ { "glXFreeContextEXT", (__GLXextFuncPtr) glXFreeContextEXT },
+ { "glXGetContextIDEXT", (__GLXextFuncPtr) glXGetContextIDEXT },
+ { "glXGetCurrentDisplayEXT", (__GLXextFuncPtr) glXGetCurrentDisplayEXT },
+ { "glXImportContextEXT", (__GLXextFuncPtr) glXImportContextEXT },
+ { "glXQueryContextInfoEXT", (__GLXextFuncPtr) glXQueryContextInfoEXT },
+
+ /*** GLX_SGIX_fbconfig ***/
+ { "glXGetFBConfigAttribSGIX", (__GLXextFuncPtr) glXGetFBConfigAttribSGIX },
+ { "glXChooseFBConfigSGIX", (__GLXextFuncPtr) glXChooseFBConfigSGIX },
+ { "glXCreateGLXPixmapWithConfigSGIX", (__GLXextFuncPtr) glXCreateGLXPixmapWithConfigSGIX },
+ { "glXCreateContextWithConfigSGIX", (__GLXextFuncPtr) glXCreateContextWithConfigSGIX },
+ { "glXGetVisualFromFBConfigSGIX", (__GLXextFuncPtr) glXGetVisualFromFBConfigSGIX },
+ { "glXGetFBConfigFromVisualSGIX", (__GLXextFuncPtr) glXGetFBConfigFromVisualSGIX },
+
+ /*** GLX_SGIX_pbuffer ***/
+ { "glXCreateGLXPbufferSGIX", (__GLXextFuncPtr) glXCreateGLXPbufferSGIX },
+ { "glXDestroyGLXPbufferSGIX", (__GLXextFuncPtr) glXDestroyGLXPbufferSGIX },
+ { "glXQueryGLXPbufferSGIX", (__GLXextFuncPtr) glXQueryGLXPbufferSGIX },
+ { "glXSelectEventSGIX", (__GLXextFuncPtr) glXSelectEventSGIX },
+ { "glXGetSelectedEventSGIX", (__GLXextFuncPtr) glXGetSelectedEventSGIX },
+
+ /*** GLX_SGI_cushion ***/
+ { "glXCushionSGI", (__GLXextFuncPtr) glXCushionSGI },
+
+ /*** GLX_SGIX_video_resize ***/
+ { "glXBindChannelToWindowSGIX", (__GLXextFuncPtr) glXBindChannelToWindowSGIX },
+ { "glXChannelRectSGIX", (__GLXextFuncPtr) glXChannelRectSGIX },
+ { "glXQueryChannelRectSGIX", (__GLXextFuncPtr) glXQueryChannelRectSGIX },
+ { "glXQueryChannelDeltasSGIX", (__GLXextFuncPtr) glXQueryChannelDeltasSGIX },
+ { "glXChannelRectSyncSGIX", (__GLXextFuncPtr) glXChannelRectSyncSGIX },
+
+ /*** GLX_SGIX_dmbuffer **/
+#if defined(_DM_BUFFER_H_)
+ { "glXAssociateDMPbufferSGIX", (__GLXextFuncPtr) glXAssociateDMPbufferSGIX },
+#endif
+
+ /*** GLX_SGIX_swap_group ***/
+ { "glXJoinSwapGroupSGIX", (__GLXextFuncPtr) glXJoinSwapGroupSGIX },
+
+ /*** GLX_SGIX_swap_barrier ***/
+ { "glXBindSwapBarrierSGIX", (__GLXextFuncPtr) glXBindSwapBarrierSGIX },
+ { "glXQueryMaxSwapBarriersSGIX", (__GLXextFuncPtr) glXQueryMaxSwapBarriersSGIX },
+
+ /*** GLX_SUN_get_transparent_index ***/
+ { "glXGetTransparentIndexSUN", (__GLXextFuncPtr) glXGetTransparentIndexSUN },
+
+ /*** GLX_MESA_copy_sub_buffer ***/
+ { "glXCopySubBufferMESA", (__GLXextFuncPtr) glXCopySubBufferMESA },
+
+ /*** GLX_MESA_pixmap_colormap ***/
+ { "glXCreateGLXPixmapMESA", (__GLXextFuncPtr) glXCreateGLXPixmapMESA },
+
+ /*** GLX_MESA_release_buffers ***/
+ { "glXReleaseBuffersMESA", (__GLXextFuncPtr) glXReleaseBuffersMESA },
+
+ /*** GLX_ARB_get_proc_address ***/
+ { "glXGetProcAddressARB", (__GLXextFuncPtr) glXGetProcAddressARB },
+
+ /*** GLX_EXT_texture_from_pixmap ***/
+ { "glXBindTexImageEXT", (__GLXextFuncPtr) glXBindTexImageEXT },
+ { "glXReleaseTexImageEXT", (__GLXextFuncPtr) glXReleaseTexImageEXT },
+
+ { NULL, NULL } /* end of list */
+};
+
+
+
+/**
+ * Return address of named glX function, or NULL if not found.
+ */
+static __GLXextFuncPtr
+_glxapi_get_proc_address(const char *funcName)
+{
+ GLuint i;
+ for (i = 0; GLX_functions[i].Name; i++) {
+ if (strcmp(GLX_functions[i].Name, funcName) == 0)
+ return GLX_functions[i].Address;
+ }
+ return NULL;
+}
+
+
+__GLXextFuncPtr
+glXGetProcAddressARB(const GLubyte *procName)
+{
+ __GLXextFuncPtr f;
+
+ f = _glxapi_get_proc_address((const char *) procName);
+ if (f) {
+ return f;
+ }
+
+ f = (__GLXextFuncPtr) _glapi_get_proc_address((const char *) procName);
+ return f;
+}
+
+
+/* GLX 1.4 */
+void (*glXGetProcAddress(const GLubyte *procName))()
+{
+ return glXGetProcAddressARB(procName);
+}
diff --git a/src/gallium/state_trackers/glx/xlib/fakeglx_fonts.c b/src/gallium/state_trackers/glx/xlib/glx_usefont.c
index e3590467563..acc64df62b6 100644
--- a/src/gallium/state_trackers/glx/xlib/fakeglx_fonts.c
+++ b/src/gallium/state_trackers/glx/xlib/glx_usefont.c
@@ -1,9 +1,10 @@
-
/*
* Mesa 3-D graphics library
- * Version: 3.5
+ * Version: 7.6
*
- * Copyright (C) 1999-2000 Brian Paul All Rights Reserved.
+ * Copyright (C) 1995 Thorsten.Ohl @ Physik.TH-Darmstadt.de
+ * Copyright (C) 1999-2008 Brian Paul All Rights Reserved.
+ * Copyright (C) 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"),
@@ -24,13 +25,13 @@
*/
-/* xfonts.c -- glXUseXFont() for Mesa written by
- * Copyright (C) 1995 Thorsten.Ohl @ Physik.TH-Darmstadt.de
+/**
+ * Fake implementation of glXUseXFont().
*/
-#include "context.h"
-#include "imports.h"
-#include "fakeglx.h"
+
+#include "main/context.h"
+#include "main/imports.h"
#include <GL/glx.h>
@@ -210,7 +211,7 @@ isvalid(XFontStruct * fs, unsigned int which)
void
-Fake_glXUseXFont(Font font, int first, int count, int listbase)
+glXUseXFont(Font font, int first, int count, int listbase)
{
Display *dpy;
Window win;
@@ -228,7 +229,8 @@ Fake_glXUseXFont(Font font, int first, int count, int listbase)
dpy = glXGetCurrentDisplay();
if (!dpy)
return; /* I guess glXMakeCurrent wasn't called */
- win = RootWindow(dpy, DefaultScreen(dpy));
+ i = DefaultScreen(dpy);
+ win = RootWindow(dpy, i);
fs = XQueryFont(dpy, font);
if (!fs) {
diff --git a/src/gallium/state_trackers/glx/xlib/glxapi.c b/src/gallium/state_trackers/glx/xlib/glxapi.c
deleted file mode 100644
index c2cb34d7cf7..00000000000
--- a/src/gallium/state_trackers/glx/xlib/glxapi.c
+++ /dev/null
@@ -1,1254 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version: 7.1
- *
- * Copyright (C) 1999-2007 Brian Paul 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, 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
- * BRIAN PAUL 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.
- */
-
-
-/*
- * This is the GLX API dispatcher. Calls to the glX* functions are
- * either routed to the real GLX encoders or to Mesa's pseudo-GLX functions.
- * See the glxapi.h file for more details.
- */
-
-
-#include <assert.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include "glapi/glapi.h"
-#include "glxapi.h"
-#include "fakeglx.h"
-#include "pipe/p_thread.h"
-
-
-#if defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) >= 303
-# define PUBLIC __attribute__((visibility("default")))
-# define USED __attribute__((used))
-#else
-# define PUBLIC
-# define USED
-#endif
-
-
-struct display_dispatch {
- Display *Dpy;
- struct _glxapi_table *Table;
- struct display_dispatch *Next;
-};
-
-static struct display_dispatch *DispatchList = NULL;
-
-
-/* Display -> Dispatch caching */
-static Display *prevDisplay = NULL;
-static struct _glxapi_table *prevTable = NULL;
-
-
-static struct _glxapi_table *
-get_dispatch(Display *dpy)
-{
- if (!dpy)
- return NULL;
-
- /* search list of display/dispatch pairs for this display */
- {
- const struct display_dispatch *d = DispatchList;
- while (d) {
- if (d->Dpy == dpy) {
- prevDisplay = dpy;
- prevTable = d->Table;
- return d->Table; /* done! */
- }
- d = d->Next;
- }
- }
-
- /* A new display, determine if we should use real GLX
- * or Mesa's pseudo-GLX.
- */
- {
- struct _glxapi_table *t = _mesa_GetGLXDispatchTable();
-
- if (t) {
- struct display_dispatch *d;
- d = (struct display_dispatch *) malloc(sizeof(struct display_dispatch));
- if (d) {
- d->Dpy = dpy;
- d->Table = t;
- /* insert at head of list */
- d->Next = DispatchList;
- DispatchList = d;
- /* update cache */
- prevDisplay = dpy;
- prevTable = t;
- return t;
- }
- }
- }
-
- /* If we get here that means we can't use real GLX on this display
- * and the Mesa pseudo-GLX software renderer wasn't compiled in.
- * Or, we ran out of memory!
- */
- return NULL;
-}
-
-
-/* Don't use the GET_DISPATCH defined in glthread.h */
-#undef GET_DISPATCH
-
-#define GET_DISPATCH(DPY, TABLE) \
- if (DPY == prevDisplay) { \
- TABLE = prevTable; \
- } \
- else if (!DPY) { \
- TABLE = NULL; \
- } \
- else { \
- TABLE = get_dispatch(DPY); \
- }
-
-
-
-
-/**
- * GLX API current context.
- */
-pipe_tsd ContextTSD;
-
-
-static void
-SetCurrentContext(GLXContext c)
-{
- pipe_tsd_set(&ContextTSD, c);
-}
-
-
-/*
- * GLX API entrypoints
- */
-
-/*** GLX_VERSION_1_0 ***/
-
-XVisualInfo PUBLIC *
-glXChooseVisual(Display *dpy, int screen, int *list)
-{
- struct _glxapi_table *t;
- GET_DISPATCH(dpy, t);
- if (!t)
- return NULL;
- return (t->ChooseVisual)(dpy, screen, list);
-}
-
-
-void PUBLIC
-glXCopyContext(Display *dpy, GLXContext src, GLXContext dst, unsigned long mask)
-{
- struct _glxapi_table *t;
- GET_DISPATCH(dpy, t);
- if (!t)
- return;
- (t->CopyContext)(dpy, src, dst, mask);
-}
-
-
-GLXContext PUBLIC
-glXCreateContext(Display *dpy, XVisualInfo *visinfo, GLXContext shareList, Bool direct)
-{
- struct _glxapi_table *t;
- GET_DISPATCH(dpy, t);
- if (!t)
- return 0;
- return (t->CreateContext)(dpy, visinfo, shareList, direct);
-}
-
-
-GLXPixmap PUBLIC
-glXCreateGLXPixmap(Display *dpy, XVisualInfo *visinfo, Pixmap pixmap)
-{
- struct _glxapi_table *t;
- GET_DISPATCH(dpy, t);
- if (!t)
- return 0;
- return (t->CreateGLXPixmap)(dpy, visinfo, pixmap);
-}
-
-
-void PUBLIC
-glXDestroyContext(Display *dpy, GLXContext ctx)
-{
- struct _glxapi_table *t;
- GET_DISPATCH(dpy, t);
- if (!t)
- return;
- if (glXGetCurrentContext() == ctx)
- SetCurrentContext(NULL);
- (t->DestroyContext)(dpy, ctx);
-}
-
-
-void PUBLIC
-glXDestroyGLXPixmap(Display *dpy, GLXPixmap pixmap)
-{
- struct _glxapi_table *t;
- GET_DISPATCH(dpy, t);
- if (!t)
- return;
- (t->DestroyGLXPixmap)(dpy, pixmap);
-}
-
-
-int PUBLIC
-glXGetConfig(Display *dpy, XVisualInfo *visinfo, int attrib, int *value)
-{
- struct _glxapi_table *t;
- GET_DISPATCH(dpy, t);
- if (!t)
- return GLX_NO_EXTENSION;
- return (t->GetConfig)(dpy, visinfo, attrib, value);
-}
-
-
-GLXContext PUBLIC
-glXGetCurrentContext(void)
-{
- return (GLXContext) pipe_tsd_get(&ContextTSD);
-}
-
-
-GLXDrawable PUBLIC
-glXGetCurrentDrawable(void)
-{
- __GLXcontext *gc = (__GLXcontext *) glXGetCurrentContext();
- return gc ? gc->currentDrawable : 0;
-}
-
-
-Bool PUBLIC
-glXIsDirect(Display *dpy, GLXContext ctx)
-{
- struct _glxapi_table *t;
- GET_DISPATCH(dpy, t);
- if (!t)
- return False;
- return (t->IsDirect)(dpy, ctx);
-}
-
-
-Bool PUBLIC
-glXMakeCurrent(Display *dpy, GLXDrawable drawable, GLXContext ctx)
-{
- Bool b;
- struct _glxapi_table *t;
- GET_DISPATCH(dpy, t);
- if (!t) {
- return False;
- }
- b = (*t->MakeCurrent)(dpy, drawable, ctx);
- if (b) {
- SetCurrentContext(ctx);
- }
- return b;
-}
-
-
-Bool PUBLIC
-glXQueryExtension(Display *dpy, int *errorb, int *event)
-{
- struct _glxapi_table *t;
- GET_DISPATCH(dpy, t);
- if (!t)
- return False;
- return (t->QueryExtension)(dpy, errorb, event);
-}
-
-
-Bool PUBLIC
-glXQueryVersion(Display *dpy, int *maj, int *min)
-{
- struct _glxapi_table *t;
- GET_DISPATCH(dpy, t);
- if (!t)
- return False;
- return (t->QueryVersion)(dpy, maj, min);
-}
-
-
-void PUBLIC
-glXSwapBuffers(Display *dpy, GLXDrawable drawable)
-{
- struct _glxapi_table *t;
- GET_DISPATCH(dpy, t);
- if (!t)
- return;
- (t->SwapBuffers)(dpy, drawable);
-}
-
-
-void PUBLIC
-glXUseXFont(Font font, int first, int count, int listBase)
-{
- struct _glxapi_table *t;
- Display *dpy = glXGetCurrentDisplay();
- GET_DISPATCH(dpy, t);
- if (!t)
- return;
- (t->UseXFont)(font, first, count, listBase);
-}
-
-
-void PUBLIC
-glXWaitGL(void)
-{
- struct _glxapi_table *t;
- Display *dpy = glXGetCurrentDisplay();
- GET_DISPATCH(dpy, t);
- if (!t)
- return;
- (t->WaitGL)();
-}
-
-
-void PUBLIC
-glXWaitX(void)
-{
- struct _glxapi_table *t;
- Display *dpy = glXGetCurrentDisplay();
- GET_DISPATCH(dpy, t);
- if (!t)
- return;
- (t->WaitX)();
-}
-
-
-
-/*** GLX_VERSION_1_1 ***/
-
-const char PUBLIC *
-glXGetClientString(Display *dpy, int name)
-{
- struct _glxapi_table *t;
- GET_DISPATCH(dpy, t);
- if (!t)
- return NULL;
- return (t->GetClientString)(dpy, name);
-}
-
-
-const char PUBLIC *
-glXQueryExtensionsString(Display *dpy, int screen)
-{
- struct _glxapi_table *t;
- GET_DISPATCH(dpy, t);
- if (!t)
- return NULL;
- return (t->QueryExtensionsString)(dpy, screen);
-}
-
-
-const char PUBLIC *
-glXQueryServerString(Display *dpy, int screen, int name)
-{
- struct _glxapi_table *t;
- GET_DISPATCH(dpy, t);
- if (!t)
- return NULL;
- return (t->QueryServerString)(dpy, screen, name);
-}
-
-
-/*** GLX_VERSION_1_2 ***/
-
-Display PUBLIC *
-glXGetCurrentDisplay(void)
-{
- /* Same code as in libGL's glxext.c */
- __GLXcontext *gc = (__GLXcontext *) glXGetCurrentContext();
- if (NULL == gc) return NULL;
- return gc->currentDpy;
-}
-
-
-
-/*** GLX_VERSION_1_3 ***/
-
-GLXFBConfig PUBLIC *
-glXChooseFBConfig(Display *dpy, int screen, const int *attribList, int *nitems)
-{
- struct _glxapi_table *t;
- GET_DISPATCH(dpy, t);
- if (!t)
- return 0;
- return (t->ChooseFBConfig)(dpy, screen, attribList, nitems);
-}
-
-
-GLXContext PUBLIC
-glXCreateNewContext(Display *dpy, GLXFBConfig config, int renderType, GLXContext shareList, Bool direct)
-{
- struct _glxapi_table *t;
- GET_DISPATCH(dpy, t);
- if (!t)
- return 0;
- return (t->CreateNewContext)(dpy, config, renderType, shareList, direct);
-}
-
-
-GLXPbuffer PUBLIC
-glXCreatePbuffer(Display *dpy, GLXFBConfig config, const int *attribList)
-{
- struct _glxapi_table *t;
- GET_DISPATCH(dpy, t);
- if (!t)
- return 0;
- return (t->CreatePbuffer)(dpy, config, attribList);
-}
-
-
-GLXPixmap PUBLIC
-glXCreatePixmap(Display *dpy, GLXFBConfig config, Pixmap pixmap, const int *attribList)
-{
- struct _glxapi_table *t;
- GET_DISPATCH(dpy, t);
- if (!t)
- return 0;
- return (t->CreatePixmap)(dpy, config, pixmap, attribList);
-}
-
-
-GLXWindow PUBLIC
-glXCreateWindow(Display *dpy, GLXFBConfig config, Window win, const int *attribList)
-{
- struct _glxapi_table *t;
- GET_DISPATCH(dpy, t);
- if (!t)
- return 0;
- return (t->CreateWindow)(dpy, config, win, attribList);
-}
-
-
-void PUBLIC
-glXDestroyPbuffer(Display *dpy, GLXPbuffer pbuf)
-{
- struct _glxapi_table *t;
- GET_DISPATCH(dpy, t);
- if (!t)
- return;
- (t->DestroyPbuffer)(dpy, pbuf);
-}
-
-
-void PUBLIC
-glXDestroyPixmap(Display *dpy, GLXPixmap pixmap)
-{
- struct _glxapi_table *t;
- GET_DISPATCH(dpy, t);
- if (!t)
- return;
- (t->DestroyPixmap)(dpy, pixmap);
-}
-
-
-void PUBLIC
-glXDestroyWindow(Display *dpy, GLXWindow window)
-{
- struct _glxapi_table *t;
- GET_DISPATCH(dpy, t);
- if (!t)
- return;
- (t->DestroyWindow)(dpy, window);
-}
-
-
-GLXDrawable PUBLIC
-glXGetCurrentReadDrawable(void)
-{
- __GLXcontext *gc = (__GLXcontext *) glXGetCurrentContext();
- return gc ? gc->currentReadable : 0;
-}
-
-
-int PUBLIC
-glXGetFBConfigAttrib(Display *dpy, GLXFBConfig config, int attribute, int *value)
-{
- struct _glxapi_table *t;
- GET_DISPATCH(dpy, t);
- if (!t)
- return GLX_NO_EXTENSION;
- return (t->GetFBConfigAttrib)(dpy, config, attribute, value);
-}
-
-
-GLXFBConfig PUBLIC *
-glXGetFBConfigs(Display *dpy, int screen, int *nelements)
-{
- struct _glxapi_table *t;
- GET_DISPATCH(dpy, t);
- if (!t)
- return 0;
- return (t->GetFBConfigs)(dpy, screen, nelements);
-}
-
-void PUBLIC
-glXGetSelectedEvent(Display *dpy, GLXDrawable drawable, unsigned long *mask)
-{
- struct _glxapi_table *t;
- GET_DISPATCH(dpy, t);
- if (!t)
- return;
- (t->GetSelectedEvent)(dpy, drawable, mask);
-}
-
-
-XVisualInfo PUBLIC *
-glXGetVisualFromFBConfig(Display *dpy, GLXFBConfig config)
-{
- struct _glxapi_table *t;
- GET_DISPATCH(dpy, t);
- if (!t)
- return NULL;
- return (t->GetVisualFromFBConfig)(dpy, config);
-}
-
-
-Bool PUBLIC
-glXMakeContextCurrent(Display *dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx)
-{
- Bool b;
- struct _glxapi_table *t;
- GET_DISPATCH(dpy, t);
- if (!t)
- return False;
- b = (t->MakeContextCurrent)(dpy, draw, read, ctx);
- if (b) {
- SetCurrentContext(ctx);
- }
- return b;
-}
-
-
-int PUBLIC
-glXQueryContext(Display *dpy, GLXContext ctx, int attribute, int *value)
-{
- struct _glxapi_table *t;
- GET_DISPATCH(dpy, t);
- assert(t);
- if (!t)
- return 0; /* XXX correct? */
- return (t->QueryContext)(dpy, ctx, attribute, value);
-}
-
-
-void PUBLIC
-glXQueryDrawable(Display *dpy, GLXDrawable draw, int attribute, unsigned int *value)
-{
- struct _glxapi_table *t;
- GET_DISPATCH(dpy, t);
- if (!t)
- return;
- (t->QueryDrawable)(dpy, draw, attribute, value);
-}
-
-
-void PUBLIC
-glXSelectEvent(Display *dpy, GLXDrawable drawable, unsigned long mask)
-{
- struct _glxapi_table *t;
- GET_DISPATCH(dpy, t);
- if (!t)
- return;
- (t->SelectEvent)(dpy, drawable, mask);
-}
-
-
-
-/*** GLX_SGI_swap_control ***/
-
-int PUBLIC
-glXSwapIntervalSGI(int interval)
-{
- struct _glxapi_table *t;
- Display *dpy = glXGetCurrentDisplay();
- GET_DISPATCH(dpy, t);
- if (!t)
- return 0;
- return (t->SwapIntervalSGI)(interval);
-}
-
-
-
-/*** GLX_SGI_video_sync ***/
-
-int PUBLIC
-glXGetVideoSyncSGI(unsigned int *count)
-{
- struct _glxapi_table *t;
- Display *dpy = glXGetCurrentDisplay();
- GET_DISPATCH(dpy, t);
- if (!t || !glXGetCurrentContext())
- return GLX_BAD_CONTEXT;
- return (t->GetVideoSyncSGI)(count);
-}
-
-int PUBLIC
-glXWaitVideoSyncSGI(int divisor, int remainder, unsigned int *count)
-{
- struct _glxapi_table *t;
- Display *dpy = glXGetCurrentDisplay();
- GET_DISPATCH(dpy, t);
- if (!t || !glXGetCurrentContext())
- return GLX_BAD_CONTEXT;
- return (t->WaitVideoSyncSGI)(divisor, remainder, count);
-}
-
-
-
-/*** GLX_SGI_make_current_read ***/
-
-Bool PUBLIC
-glXMakeCurrentReadSGI(Display *dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx)
-{
- struct _glxapi_table *t;
- GET_DISPATCH(dpy, t);
- if (!t)
- return False;
- return (t->MakeCurrentReadSGI)(dpy, draw, read, ctx);
-}
-
-GLXDrawable PUBLIC
-glXGetCurrentReadDrawableSGI(void)
-{
- return glXGetCurrentReadDrawable();
-}
-
-
-#if defined(_VL_H)
-
-GLXVideoSourceSGIX PUBLIC
-glXCreateGLXVideoSourceSGIX(Display *dpy, int screen, VLServer server, VLPath path, int nodeClass, VLNode drainNode)
-{
- struct _glxapi_table *t;
- GET_DISPATCH(dpy, t);
- if (!t)
- return 0;
- return (t->CreateGLXVideoSourceSGIX)(dpy, screen, server, path, nodeClass, drainNode);
-}
-
-void PUBLIC
-glXDestroyGLXVideoSourceSGIX(Display *dpy, GLXVideoSourceSGIX src)
-{
- struct _glxapi_table *t;
- GET_DISPATCH(dpy, t);
- if (!t)
- return 0;
- return (t->DestroyGLXVideoSourceSGIX)(dpy, src);
-}
-
-#endif
-
-
-/*** GLX_EXT_import_context ***/
-
-void PUBLIC
-glXFreeContextEXT(Display *dpy, GLXContext context)
-{
- struct _glxapi_table *t;
- GET_DISPATCH(dpy, t);
- if (!t)
- return;
- (t->FreeContextEXT)(dpy, context);
-}
-
-GLXContextID PUBLIC
-glXGetContextIDEXT(const GLXContext context)
-{
- return ((__GLXcontext *) context)->xid;
-}
-
-Display PUBLIC *
-glXGetCurrentDisplayEXT(void)
-{
- return glXGetCurrentDisplay();
-}
-
-GLXContext PUBLIC
-glXImportContextEXT(Display *dpy, GLXContextID contextID)
-{
- struct _glxapi_table *t;
- GET_DISPATCH(dpy, t);
- if (!t)
- return 0;
- return (t->ImportContextEXT)(dpy, contextID);
-}
-
-int PUBLIC
-glXQueryContextInfoEXT(Display *dpy, GLXContext context, int attribute,int *value)
-{
- struct _glxapi_table *t;
- GET_DISPATCH(dpy, t);
- if (!t)
- return 0; /* XXX ok? */
- return (t->QueryContextInfoEXT)(dpy, context, attribute, value);
-}
-
-
-
-/*** GLX_SGIX_fbconfig ***/
-
-int PUBLIC
-glXGetFBConfigAttribSGIX(Display *dpy, GLXFBConfigSGIX config, int attribute, int *value)
-{
- struct _glxapi_table *t;
- GET_DISPATCH(dpy, t);
- if (!t)
- return 0;
- return (t->GetFBConfigAttribSGIX)(dpy, config, attribute, value);
-}
-
-GLXFBConfigSGIX PUBLIC *
-glXChooseFBConfigSGIX(Display *dpy, int screen, int *attrib_list, int *nelements)
-{
- struct _glxapi_table *t;
- GET_DISPATCH(dpy, t);
- if (!t)
- return 0;
- return (t->ChooseFBConfigSGIX)(dpy, screen, attrib_list, nelements);
-}
-
-GLXPixmap PUBLIC
-glXCreateGLXPixmapWithConfigSGIX(Display *dpy, GLXFBConfigSGIX config, Pixmap pixmap)
-{
- struct _glxapi_table *t;
- GET_DISPATCH(dpy, t);
- if (!t)
- return 0;
- return (t->CreateGLXPixmapWithConfigSGIX)(dpy, config, pixmap);
-}
-
-GLXContext PUBLIC
-glXCreateContextWithConfigSGIX(Display *dpy, GLXFBConfigSGIX config, int render_type, GLXContext share_list, Bool direct)
-{
- struct _glxapi_table *t;
- GET_DISPATCH(dpy, t);
- if (!t)
- return 0;
- return (t->CreateContextWithConfigSGIX)(dpy, config, render_type, share_list, direct);
-}
-
-XVisualInfo PUBLIC *
-glXGetVisualFromFBConfigSGIX(Display *dpy, GLXFBConfigSGIX config)
-{
- struct _glxapi_table *t;
- GET_DISPATCH(dpy, t);
- if (!t)
- return 0;
- return (t->GetVisualFromFBConfigSGIX)(dpy, config);
-}
-
-GLXFBConfigSGIX PUBLIC
-glXGetFBConfigFromVisualSGIX(Display *dpy, XVisualInfo *vis)
-{
- struct _glxapi_table *t;
- GET_DISPATCH(dpy, t);
- if (!t)
- return 0;
- return (t->GetFBConfigFromVisualSGIX)(dpy, vis);
-}
-
-
-
-/*** GLX_SGIX_pbuffer ***/
-
-GLXPbufferSGIX PUBLIC
-glXCreateGLXPbufferSGIX(Display *dpy, GLXFBConfigSGIX config, unsigned int width, unsigned int height, int *attrib_list)
-{
- struct _glxapi_table *t;
- GET_DISPATCH(dpy, t);
- if (!t)
- return 0;
- return (t->CreateGLXPbufferSGIX)(dpy, config, width, height, attrib_list);
-}
-
-void PUBLIC
-glXDestroyGLXPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuf)
-{
- struct _glxapi_table *t;
- GET_DISPATCH(dpy, t);
- if (!t)
- return;
- (t->DestroyGLXPbufferSGIX)(dpy, pbuf);
-}
-
-int PUBLIC
-glXQueryGLXPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuf, int attribute, unsigned int *value)
-{
- struct _glxapi_table *t;
- GET_DISPATCH(dpy, t);
- if (!t)
- return 0;
- return (t->QueryGLXPbufferSGIX)(dpy, pbuf, attribute, value);
-}
-
-void PUBLIC
-glXSelectEventSGIX(Display *dpy, GLXDrawable drawable, unsigned long mask)
-{
- struct _glxapi_table *t;
- GET_DISPATCH(dpy, t);
- if (!t)
- return;
- (t->SelectEventSGIX)(dpy, drawable, mask);
-}
-
-void PUBLIC
-glXGetSelectedEventSGIX(Display *dpy, GLXDrawable drawable, unsigned long *mask)
-{
- struct _glxapi_table *t;
- GET_DISPATCH(dpy, t);
- if (!t)
- return;
- (t->GetSelectedEventSGIX)(dpy, drawable, mask);
-}
-
-
-
-/*** GLX_SGI_cushion ***/
-
-void PUBLIC
-glXCushionSGI(Display *dpy, Window win, float cushion)
-{
- struct _glxapi_table *t;
- GET_DISPATCH(dpy, t);
- if (!t)
- return;
- (t->CushionSGI)(dpy, win, cushion);
-}
-
-
-
-/*** GLX_SGIX_video_resize ***/
-
-int PUBLIC
-glXBindChannelToWindowSGIX(Display *dpy, int screen, int channel , Window window)
-{
- struct _glxapi_table *t;
- GET_DISPATCH(dpy, t);
- if (!t)
- return 0;
- return (t->BindChannelToWindowSGIX)(dpy, screen, channel, window);
-}
-
-int PUBLIC
-glXChannelRectSGIX(Display *dpy, int screen, int channel, int x, int y, int w, int h)
-{
- struct _glxapi_table *t;
- GET_DISPATCH(dpy, t);
- if (!t)
- return 0;
- return (t->ChannelRectSGIX)(dpy, screen, channel, x, y, w, h);
-}
-
-int PUBLIC
-glXQueryChannelRectSGIX(Display *dpy, int screen, int channel, int *x, int *y, int *w, int *h)
-{
- struct _glxapi_table *t;
- GET_DISPATCH(dpy, t);
- if (!t)
- return 0;
- return (t->QueryChannelRectSGIX)(dpy, screen, channel, x, y, w, h);
-}
-
-int PUBLIC
-glXQueryChannelDeltasSGIX(Display *dpy, int screen, int channel, int *dx, int *dy, int *dw, int *dh)
-{
- struct _glxapi_table *t;
- GET_DISPATCH(dpy, t);
- if (!t)
- return 0;
- return (t->QueryChannelDeltasSGIX)(dpy, screen, channel, dx, dy, dw, dh);
-}
-
-int PUBLIC
-glXChannelRectSyncSGIX(Display *dpy, int screen, int channel, GLenum synctype)
-{
- struct _glxapi_table *t;
- GET_DISPATCH(dpy, t);
- if (!t)
- return 0;
- return (t->ChannelRectSyncSGIX)(dpy, screen, channel, synctype);
-}
-
-
-
-#if defined(_DM_BUFFER_H_)
-
-Bool PUBLIC
-glXAssociateDMPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuffer, DMparams *params, DMbuffer dmbuffer)
-{
- struct _glxapi_table *t;
- GET_DISPATCH(dpy, t);
- if (!t)
- return False;
- return (t->AssociateDMPbufferSGIX)(dpy, pbuffer, params, dmbuffer);
-}
-
-#endif
-
-
-/*** GLX_SGIX_swap_group ***/
-
-void PUBLIC
-glXJoinSwapGroupSGIX(Display *dpy, GLXDrawable drawable, GLXDrawable member)
-{
- struct _glxapi_table *t;
- GET_DISPATCH(dpy, t);
- if (!t)
- return;
- (*t->JoinSwapGroupSGIX)(dpy, drawable, member);
-}
-
-
-/*** GLX_SGIX_swap_barrier ***/
-
-void PUBLIC
-glXBindSwapBarrierSGIX(Display *dpy, GLXDrawable drawable, int barrier)
-{
- struct _glxapi_table *t;
- GET_DISPATCH(dpy, t);
- if (!t)
- return;
- (*t->BindSwapBarrierSGIX)(dpy, drawable, barrier);
-}
-
-Bool PUBLIC
-glXQueryMaxSwapBarriersSGIX(Display *dpy, int screen, int *max)
-{
- struct _glxapi_table *t;
- GET_DISPATCH(dpy, t);
- if (!t)
- return False;
- return (*t->QueryMaxSwapBarriersSGIX)(dpy, screen, max);
-}
-
-
-
-/*** GLX_SUN_get_transparent_index ***/
-
-Status PUBLIC
-glXGetTransparentIndexSUN(Display *dpy, Window overlay, Window underlay, long *pTransparent)
-{
- struct _glxapi_table *t;
- GET_DISPATCH(dpy, t);
- if (!t)
- return False;
- return (*t->GetTransparentIndexSUN)(dpy, overlay, underlay, pTransparent);
-}
-
-
-
-/*** GLX_MESA_copy_sub_buffer ***/
-
-void PUBLIC
-glXCopySubBufferMESA(Display *dpy, GLXDrawable drawable, int x, int y, int width, int height)
-{
- struct _glxapi_table *t;
- GET_DISPATCH(dpy, t);
- if (!t)
- return;
- (t->CopySubBufferMESA)(dpy, drawable, x, y, width, height);
-}
-
-
-
-/*** GLX_MESA_release_buffers ***/
-
-Bool PUBLIC
-glXReleaseBuffersMESA(Display *dpy, Window w)
-{
- struct _glxapi_table *t;
- GET_DISPATCH(dpy, t);
- if (!t)
- return False;
- return (t->ReleaseBuffersMESA)(dpy, w);
-}
-
-
-
-/*** GLX_MESA_pixmap_colormap ***/
-
-GLXPixmap PUBLIC
-glXCreateGLXPixmapMESA(Display *dpy, XVisualInfo *visinfo, Pixmap pixmap, Colormap cmap)
-{
- struct _glxapi_table *t;
- GET_DISPATCH(dpy, t);
- if (!t)
- return 0;
- return (t->CreateGLXPixmapMESA)(dpy, visinfo, pixmap, cmap);
-}
-
-/*** GLX_EXT_texture_from_pixmap */
-
-void
-glXBindTexImageEXT(Display *dpy, GLXDrawable drawable, int buffer,
- const int *attrib_list)
-{
- struct _glxapi_table *t;
- GET_DISPATCH(dpy, t);
- if (t)
- t->BindTexImageEXT(dpy, drawable, buffer, attrib_list);
-}
-
-void
-glXReleaseTexImageEXT(Display *dpy, GLXDrawable drawable, int buffer)
-{
- struct _glxapi_table *t;
- GET_DISPATCH(dpy, t);
- if (t)
- t->ReleaseTexImageEXT(dpy, drawable, buffer);
-}
-
-
-/**********************************************************************/
-/* GLX API management functions */
-/**********************************************************************/
-
-
-const char *
-_glxapi_get_version(void)
-{
- return "1.3";
-}
-
-
-
-/*
- * Return size of the GLX dispatch table, in entries, not bytes.
- */
-GLuint
-_glxapi_get_dispatch_table_size(void)
-{
- return sizeof(struct _glxapi_table) / sizeof(void *);
-}
-
-
-static int
-generic_no_op_func(void)
-{
- return 0;
-}
-
-
-/*
- * Initialize all functions in given dispatch table to be no-ops
- */
-void
-_glxapi_set_no_op_table(struct _glxapi_table *t)
-{
- typedef int (*nop_func)(void);
- nop_func *dispatch = (nop_func *) t;
- GLuint n = _glxapi_get_dispatch_table_size();
- GLuint i;
- for (i = 0; i < n; i++) {
- dispatch[i] = generic_no_op_func;
- }
-}
-
-
-struct name_address_pair {
- const char *Name;
- __GLXextFuncPtr Address;
-};
-
-static struct name_address_pair GLX_functions[] = {
- /*** GLX_VERSION_1_0 ***/
- { "glXChooseVisual", (__GLXextFuncPtr) glXChooseVisual },
- { "glXCopyContext", (__GLXextFuncPtr) glXCopyContext },
- { "glXCreateContext", (__GLXextFuncPtr) glXCreateContext },
- { "glXCreateGLXPixmap", (__GLXextFuncPtr) glXCreateGLXPixmap },
- { "glXDestroyContext", (__GLXextFuncPtr) glXDestroyContext },
- { "glXDestroyGLXPixmap", (__GLXextFuncPtr) glXDestroyGLXPixmap },
- { "glXGetConfig", (__GLXextFuncPtr) glXGetConfig },
- { "glXGetCurrentContext", (__GLXextFuncPtr) glXGetCurrentContext },
- { "glXGetCurrentDrawable", (__GLXextFuncPtr) glXGetCurrentDrawable },
- { "glXIsDirect", (__GLXextFuncPtr) glXIsDirect },
- { "glXMakeCurrent", (__GLXextFuncPtr) glXMakeCurrent },
- { "glXQueryExtension", (__GLXextFuncPtr) glXQueryExtension },
- { "glXQueryVersion", (__GLXextFuncPtr) glXQueryVersion },
- { "glXSwapBuffers", (__GLXextFuncPtr) glXSwapBuffers },
- { "glXUseXFont", (__GLXextFuncPtr) glXUseXFont },
- { "glXWaitGL", (__GLXextFuncPtr) glXWaitGL },
- { "glXWaitX", (__GLXextFuncPtr) glXWaitX },
-
- /*** GLX_VERSION_1_1 ***/
- { "glXGetClientString", (__GLXextFuncPtr) glXGetClientString },
- { "glXQueryExtensionsString", (__GLXextFuncPtr) glXQueryExtensionsString },
- { "glXQueryServerString", (__GLXextFuncPtr) glXQueryServerString },
-
- /*** GLX_VERSION_1_2 ***/
- { "glXGetCurrentDisplay", (__GLXextFuncPtr) glXGetCurrentDisplay },
-
- /*** GLX_VERSION_1_3 ***/
- { "glXChooseFBConfig", (__GLXextFuncPtr) glXChooseFBConfig },
- { "glXCreateNewContext", (__GLXextFuncPtr) glXCreateNewContext },
- { "glXCreatePbuffer", (__GLXextFuncPtr) glXCreatePbuffer },
- { "glXCreatePixmap", (__GLXextFuncPtr) glXCreatePixmap },
- { "glXCreateWindow", (__GLXextFuncPtr) glXCreateWindow },
- { "glXDestroyPbuffer", (__GLXextFuncPtr) glXDestroyPbuffer },
- { "glXDestroyPixmap", (__GLXextFuncPtr) glXDestroyPixmap },
- { "glXDestroyWindow", (__GLXextFuncPtr) glXDestroyWindow },
- { "glXGetCurrentReadDrawable", (__GLXextFuncPtr) glXGetCurrentReadDrawable },
- { "glXGetFBConfigAttrib", (__GLXextFuncPtr) glXGetFBConfigAttrib },
- { "glXGetFBConfigs", (__GLXextFuncPtr) glXGetFBConfigs },
- { "glXGetSelectedEvent", (__GLXextFuncPtr) glXGetSelectedEvent },
- { "glXGetVisualFromFBConfig", (__GLXextFuncPtr) glXGetVisualFromFBConfig },
- { "glXMakeContextCurrent", (__GLXextFuncPtr) glXMakeContextCurrent },
- { "glXQueryContext", (__GLXextFuncPtr) glXQueryContext },
- { "glXQueryDrawable", (__GLXextFuncPtr) glXQueryDrawable },
- { "glXSelectEvent", (__GLXextFuncPtr) glXSelectEvent },
-
- /*** GLX_VERSION_1_4 ***/
- { "glXGetProcAddress", (__GLXextFuncPtr) glXGetProcAddress },
-
- /*** GLX_SGI_swap_control ***/
- { "glXSwapIntervalSGI", (__GLXextFuncPtr) glXSwapIntervalSGI },
-
- /*** GLX_SGI_video_sync ***/
- { "glXGetVideoSyncSGI", (__GLXextFuncPtr) glXGetVideoSyncSGI },
- { "glXWaitVideoSyncSGI", (__GLXextFuncPtr) glXWaitVideoSyncSGI },
-
- /*** GLX_SGI_make_current_read ***/
- { "glXMakeCurrentReadSGI", (__GLXextFuncPtr) glXMakeCurrentReadSGI },
- { "glXGetCurrentReadDrawableSGI", (__GLXextFuncPtr) glXGetCurrentReadDrawableSGI },
-
- /*** GLX_SGIX_video_source ***/
-#if defined(_VL_H)
- { "glXCreateGLXVideoSourceSGIX", (__GLXextFuncPtr) glXCreateGLXVideoSourceSGIX },
- { "glXDestroyGLXVideoSourceSGIX", (__GLXextFuncPtr) glXDestroyGLXVideoSourceSGIX },
-#endif
-
- /*** GLX_EXT_import_context ***/
- { "glXFreeContextEXT", (__GLXextFuncPtr) glXFreeContextEXT },
- { "glXGetContextIDEXT", (__GLXextFuncPtr) glXGetContextIDEXT },
- { "glXGetCurrentDisplayEXT", (__GLXextFuncPtr) glXGetCurrentDisplayEXT },
- { "glXImportContextEXT", (__GLXextFuncPtr) glXImportContextEXT },
- { "glXQueryContextInfoEXT", (__GLXextFuncPtr) glXQueryContextInfoEXT },
-
- /*** GLX_SGIX_fbconfig ***/
- { "glXGetFBConfigAttribSGIX", (__GLXextFuncPtr) glXGetFBConfigAttribSGIX },
- { "glXChooseFBConfigSGIX", (__GLXextFuncPtr) glXChooseFBConfigSGIX },
- { "glXCreateGLXPixmapWithConfigSGIX", (__GLXextFuncPtr) glXCreateGLXPixmapWithConfigSGIX },
- { "glXCreateContextWithConfigSGIX", (__GLXextFuncPtr) glXCreateContextWithConfigSGIX },
- { "glXGetVisualFromFBConfigSGIX", (__GLXextFuncPtr) glXGetVisualFromFBConfigSGIX },
- { "glXGetFBConfigFromVisualSGIX", (__GLXextFuncPtr) glXGetFBConfigFromVisualSGIX },
-
- /*** GLX_SGIX_pbuffer ***/
- { "glXCreateGLXPbufferSGIX", (__GLXextFuncPtr) glXCreateGLXPbufferSGIX },
- { "glXDestroyGLXPbufferSGIX", (__GLXextFuncPtr) glXDestroyGLXPbufferSGIX },
- { "glXQueryGLXPbufferSGIX", (__GLXextFuncPtr) glXQueryGLXPbufferSGIX },
- { "glXSelectEventSGIX", (__GLXextFuncPtr) glXSelectEventSGIX },
- { "glXGetSelectedEventSGIX", (__GLXextFuncPtr) glXGetSelectedEventSGIX },
-
- /*** GLX_SGI_cushion ***/
- { "glXCushionSGI", (__GLXextFuncPtr) glXCushionSGI },
-
- /*** GLX_SGIX_video_resize ***/
- { "glXBindChannelToWindowSGIX", (__GLXextFuncPtr) glXBindChannelToWindowSGIX },
- { "glXChannelRectSGIX", (__GLXextFuncPtr) glXChannelRectSGIX },
- { "glXQueryChannelRectSGIX", (__GLXextFuncPtr) glXQueryChannelRectSGIX },
- { "glXQueryChannelDeltasSGIX", (__GLXextFuncPtr) glXQueryChannelDeltasSGIX },
- { "glXChannelRectSyncSGIX", (__GLXextFuncPtr) glXChannelRectSyncSGIX },
-
- /*** GLX_SGIX_dmbuffer **/
-#if defined(_DM_BUFFER_H_)
- { "glXAssociateDMPbufferSGIX", (__GLXextFuncPtr) glXAssociateDMPbufferSGIX },
-#endif
-
- /*** GLX_SGIX_swap_group ***/
- { "glXJoinSwapGroupSGIX", (__GLXextFuncPtr) glXJoinSwapGroupSGIX },
-
- /*** GLX_SGIX_swap_barrier ***/
- { "glXBindSwapBarrierSGIX", (__GLXextFuncPtr) glXBindSwapBarrierSGIX },
- { "glXQueryMaxSwapBarriersSGIX", (__GLXextFuncPtr) glXQueryMaxSwapBarriersSGIX },
-
- /*** GLX_SUN_get_transparent_index ***/
- { "glXGetTransparentIndexSUN", (__GLXextFuncPtr) glXGetTransparentIndexSUN },
-
- /*** GLX_MESA_copy_sub_buffer ***/
- { "glXCopySubBufferMESA", (__GLXextFuncPtr) glXCopySubBufferMESA },
-
- /*** GLX_MESA_pixmap_colormap ***/
- { "glXCreateGLXPixmapMESA", (__GLXextFuncPtr) glXCreateGLXPixmapMESA },
-
- /*** GLX_MESA_release_buffers ***/
- { "glXReleaseBuffersMESA", (__GLXextFuncPtr) glXReleaseBuffersMESA },
-
- /*** GLX_ARB_get_proc_address ***/
- { "glXGetProcAddressARB", (__GLXextFuncPtr) glXGetProcAddressARB },
-
- /*** GLX_EXT_texture_from_pixmap ***/
- { "glXBindTexImageEXT", (__GLXextFuncPtr) glXBindTexImageEXT },
- { "glXReleaseTexImageEXT", (__GLXextFuncPtr) glXReleaseTexImageEXT },
-
- { NULL, NULL } /* end of list */
-};
-
-
-
-/*
- * Return address of named glX function, or NULL if not found.
- */
-__GLXextFuncPtr
-_glxapi_get_proc_address(const char *funcName)
-{
- GLuint i;
- for (i = 0; GLX_functions[i].Name; i++) {
- if (strcmp(GLX_functions[i].Name, funcName) == 0)
- return GLX_functions[i].Address;
- }
- return NULL;
-}
-
-
-
-/*
- * This function does not get dispatched through the dispatch table
- * since it's really a "meta" function.
- */
-__GLXextFuncPtr
-glXGetProcAddressARB(const GLubyte *procName)
-{
- __GLXextFuncPtr f;
-
- f = _glxapi_get_proc_address((const char *) procName);
- if (f) {
- return f;
- }
-
- f = (__GLXextFuncPtr) _glapi_get_proc_address((const char *) procName);
- return f;
-}
-
-
-/* GLX 1.4 */
-void (*glXGetProcAddress(const GLubyte *procName))()
-{
- return glXGetProcAddressARB(procName);
-}
diff --git a/src/gallium/state_trackers/glx/xlib/glxapi.h b/src/gallium/state_trackers/glx/xlib/glxapi.h
deleted file mode 100644
index b4e12b4162b..00000000000
--- a/src/gallium/state_trackers/glx/xlib/glxapi.h
+++ /dev/null
@@ -1,213 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version: 6.3
- *
- * Copyright (C) 1999-2004 Brian Paul 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, 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
- * BRIAN PAUL 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 _glxapi_h_
-#define _glxapi_h_
-
-
-#define GLX_GLXEXT_PROTOTYPES
-#include "GL/glx.h"
-
-
-/* The GLX API dispatcher (i.e. this code) is being built into stand-alone
- * Mesa. We don't know anything about XFree86 or real GLX so we define a
- * minimal __GLXContextRec here so some of the functions in this file can
- * work properly.
- */
-typedef struct __GLXcontextRec {
- Display *currentDpy;
- GLboolean isDirect;
- GLXDrawable currentDrawable;
- GLXDrawable currentReadable;
- XID xid;
-} __GLXcontext;
-
-
-/*
- * Almost all the GLX API functions get routed through this dispatch table.
- * The exceptions are the glXGetCurrentXXX() functions.
- *
- * This dispatch table allows multiple GLX client-side modules to coexist.
- * Specifically, a real GLX library (like SGI's or the Utah GLX) and Mesa's
- * pseudo-GLX can be present at the same time. The former being used on
- * GLX-enabled X servers and the later on non-GLX X servers.
- *
- * Red Hat has been using this since Red Hat Linux 7.0 (I think).
- * This'll be a standard feature in XFree86 4.3. It basically allows one
- * libGL to do both DRI-rendering and "fake GLX" rendering to X displays
- * that lack the GLX extension.
- */
-struct _glxapi_table {
- /*** GLX_VERSION_1_0 ***/
- XVisualInfo *(*ChooseVisual)(Display *dpy, int screen, int *list);
- void (*CopyContext)(Display *dpy, GLXContext src, GLXContext dst, unsigned long mask);
- GLXContext (*CreateContext)(Display *dpy, XVisualInfo *visinfo, GLXContext shareList, Bool direct);
- GLXPixmap (*CreateGLXPixmap)(Display *dpy, XVisualInfo *visinfo, Pixmap pixmap);
- void (*DestroyContext)(Display *dpy, GLXContext ctx);
- void (*DestroyGLXPixmap)(Display *dpy, GLXPixmap pixmap);
- int (*GetConfig)(Display *dpy, XVisualInfo *visinfo, int attrib, int *value);
- /*GLXContext (*GetCurrentContext)(void);*/
- /*GLXDrawable (*GetCurrentDrawable)(void);*/
- Bool (*IsDirect)(Display *dpy, GLXContext ctx);
- Bool (*MakeCurrent)(Display *dpy, GLXDrawable drawable, GLXContext ctx);
- Bool (*QueryExtension)(Display *dpy, int *errorb, int *event);
- Bool (*QueryVersion)(Display *dpy, int *maj, int *min);
- void (*SwapBuffers)(Display *dpy, GLXDrawable drawable);
- void (*UseXFont)(Font font, int first, int count, int listBase);
- void (*WaitGL)(void);
- void (*WaitX)(void);
-
- /*** GLX_VERSION_1_1 ***/
- const char *(*GetClientString)(Display *dpy, int name);
- const char *(*QueryExtensionsString)(Display *dpy, int screen);
- const char *(*QueryServerString)(Display *dpy, int screen, int name);
-
- /*** GLX_VERSION_1_2 ***/
- /*Display *(*GetCurrentDisplay)(void);*/
-
- /*** GLX_VERSION_1_3 ***/
- GLXFBConfig *(*ChooseFBConfig)(Display *dpy, int screen, const int *attribList, int *nitems);
- GLXContext (*CreateNewContext)(Display *dpy, GLXFBConfig config, int renderType, GLXContext shareList, Bool direct);
- GLXPbuffer (*CreatePbuffer)(Display *dpy, GLXFBConfig config, const int *attribList);
- GLXPixmap (*CreatePixmap)(Display *dpy, GLXFBConfig config, Pixmap pixmap, const int *attribList);
- GLXWindow (*CreateWindow)(Display *dpy, GLXFBConfig config, Window win, const int *attribList);
- void (*DestroyPbuffer)(Display *dpy, GLXPbuffer pbuf);
- void (*DestroyPixmap)(Display *dpy, GLXPixmap pixmap);
- void (*DestroyWindow)(Display *dpy, GLXWindow window);
- /*GLXDrawable (*GetCurrentReadDrawable)(void);*/
- int (*GetFBConfigAttrib)(Display *dpy, GLXFBConfig config, int attribute, int *value);
- GLXFBConfig *(*GetFBConfigs)(Display *dpy, int screen, int *nelements);
- void (*GetSelectedEvent)(Display *dpy, GLXDrawable drawable, unsigned long *mask);
- XVisualInfo *(*GetVisualFromFBConfig)(Display *dpy, GLXFBConfig config);
- Bool (*MakeContextCurrent)(Display *dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx);
- int (*QueryContext)(Display *dpy, GLXContext ctx, int attribute, int *value);
- void (*QueryDrawable)(Display *dpy, GLXDrawable draw, int attribute, unsigned int *value);
- void (*SelectEvent)(Display *dpy, GLXDrawable drawable, unsigned long mask);
-
- /*** GLX_SGI_swap_control ***/
- int (*SwapIntervalSGI)(int);
-
- /*** GLX_SGI_video_sync ***/
- int (*GetVideoSyncSGI)(unsigned int *count);
- int (*WaitVideoSyncSGI)(int divisor, int remainder, unsigned int *count);
-
- /*** GLX_SGI_make_current_read ***/
- Bool (*MakeCurrentReadSGI)(Display *, GLXDrawable, GLXDrawable, GLXContext);
- /*GLXDrawable (*GetCurrentReadDrawableSGI)(void);*/
-
- /*** GLX_SGIX_video_source (needs video library) ***/
-#if defined(_VL_H_)
- GLXVideoSourceSGIX (*CreateGLXVideoSourceSGIX)(Display *, int, VLServer, VLPath, int, VLNode);
- void (*DestroyGLXVideoSourceSGIX)(Display *, GLXVideoSourceSGIX);
-#else
- void *CreateGLXVideoSourceSGIX;
- void *DestroyGLXVideoSourceSGIX;
-#endif
-
- /*** GLX_EXT_import_context ***/
- void (*FreeContextEXT)(Display *dpy, GLXContext context);
- GLXContextID (*GetContextIDEXT)(const GLXContext context);
- /*Display *(*GetCurrentDisplayEXT)(void);*/
- GLXContext (*ImportContextEXT)(Display *dpy, GLXContextID contextID);
- int (*QueryContextInfoEXT)(Display *dpy, GLXContext context, int attribute,int *value);
-
- /*** GLX_SGIX_fbconfig ***/
- int (*GetFBConfigAttribSGIX)(Display *, GLXFBConfigSGIX, int, int *);
- GLXFBConfigSGIX * (*ChooseFBConfigSGIX)(Display *, int, int *, int *);
- GLXPixmap (*CreateGLXPixmapWithConfigSGIX)(Display *, GLXFBConfigSGIX, Pixmap);
- GLXContext (*CreateContextWithConfigSGIX)(Display *, GLXFBConfigSGIX, int, GLXContext, Bool);
- XVisualInfo * (*GetVisualFromFBConfigSGIX)(Display *, GLXFBConfigSGIX);
- GLXFBConfigSGIX (*GetFBConfigFromVisualSGIX)(Display *, XVisualInfo *);
-
- /*** GLX_SGIX_pbuffer ***/
- GLXPbufferSGIX (*CreateGLXPbufferSGIX)(Display *, GLXFBConfigSGIX, unsigned int, unsigned int, int *);
- void (*DestroyGLXPbufferSGIX)(Display *, GLXPbufferSGIX);
- int (*QueryGLXPbufferSGIX)(Display *, GLXPbufferSGIX, int, unsigned int *);
- void (*SelectEventSGIX)(Display *, GLXDrawable, unsigned long);
- void (*GetSelectedEventSGIX)(Display *, GLXDrawable, unsigned long *);
-
- /*** GLX_SGI_cushion ***/
- void (*CushionSGI)(Display *, Window, float);
-
- /*** GLX_SGIX_video_resize ***/
- int (*BindChannelToWindowSGIX)(Display *, int, int, Window);
- int (*ChannelRectSGIX)(Display *, int, int, int, int, int, int);
- int (*QueryChannelRectSGIX)(Display *, int, int, int *, int *, int *, int *);
- int (*QueryChannelDeltasSGIX)(Display *, int, int, int *, int *, int *, int *);
- int (*ChannelRectSyncSGIX)(Display *, int, int, GLenum);
-
- /*** GLX_SGIX_dmbuffer (needs dmedia library) ***/
-#if defined (_DM_BUFFER_H_)
- Bool (*AssociateDMPbufferSGIX)(Display *, GLXPbufferSGIX, DMparams *, DMbuffer);
-#else
- void *AssociciateDMPbufferSGIX;
-#endif
-
- /*** GLX_SGIX_swap_group ***/
- void (*JoinSwapGroupSGIX)(Display *, GLXDrawable, GLXDrawable);
-
- /*** GLX_SGIX_swap_barrier ***/
- void (*BindSwapBarrierSGIX)(Display *, GLXDrawable, int);
- Bool (*QueryMaxSwapBarriersSGIX)(Display *, int, int *);
-
- /*** GLX_SUN_get_transparent_index ***/
- Status (*GetTransparentIndexSUN)(Display *, Window, Window, long *);
-
- /*** GLX_MESA_copy_sub_buffer ***/
- void (*CopySubBufferMESA)(Display *dpy, GLXDrawable drawable, int x, int y, int width, int height);
-
- /*** GLX_MESA_release_buffers ***/
- Bool (*ReleaseBuffersMESA)(Display *dpy, Window w);
-
- /*** GLX_MESA_pixmap_colormap ***/
- GLXPixmap (*CreateGLXPixmapMESA)(Display *dpy, XVisualInfo *visinfo, Pixmap pixmap, Colormap cmap);
-
- /*** GLX_EXT_texture_from_pixmap ***/
- void (*BindTexImageEXT)(Display *dpy, GLXDrawable drawable, int buffer,
- const int *attrib_list);
- void (*ReleaseTexImageEXT)(Display *dpy, GLXDrawable drawable, int buffer);
-};
-
-
-
-extern const char *
-_glxapi_get_version(void);
-
-
-
-
-extern GLuint
-_glxapi_get_dispatch_table_size(void);
-
-
-extern void
-_glxapi_set_no_op_table(struct _glxapi_table *t);
-
-
-extern __GLXextFuncPtr
-_glxapi_get_proc_address(const char *funcName);
-
-
-#endif
diff --git a/src/gallium/state_trackers/glx/xlib/xm_api.h b/src/gallium/state_trackers/glx/xlib/xm_api.h
index bdd434cd364..ce97a3ec768 100644
--- a/src/gallium/state_trackers/glx/xlib/xm_api.h
+++ b/src/gallium/state_trackers/glx/xlib/xm_api.h
@@ -57,7 +57,7 @@ and create a window, you must do the following to use the X/Mesa interface:
#define XMESA_H
-#include "mtypes.h"
+#include "main/mtypes.h"
#include "state_tracker/st_context.h"
#include "state_tracker/st_public.h"
#include "pipe/p_thread.h"
diff --git a/src/gallium/state_trackers/vega/asm_filters.h b/src/gallium/state_trackers/vega/asm_filters.h
index 49807b9ab41..9a49f2e12d0 100644
--- a/src/gallium/state_trackers/vega/asm_filters.h
+++ b/src/gallium/state_trackers/vega/asm_filters.h
@@ -60,7 +60,7 @@ static const char convolution_asm[] =
"DCL SAMP[0], CONSTANT\n"
"0: MOV TEMP[0], CONST[0].xxxx\n"
"1: MOV TEMP[1], CONST[0].xxxx\n"
- "2: BGNLOOP2 :14\n"
+ "2: BGNLOOP :14\n"
"3: SGE TEMP[0].z, TEMP[0].yyyy, CONST[1].xxxx\n"
"4: IF TEMP[0].zzzz :7\n"
"5: BRK\n"
@@ -72,7 +72,7 @@ static const char convolution_asm[] =
"11: MOV TEMP[3], CONST[ADDR[0]+%d]\n"
"12: MAD TEMP[1], TEMP[2], TEMP[3], TEMP[1]\n"
"13: ADD TEMP[0].y, TEMP[0].yyyy, CONST[0].yyyy\n"
- "14: ENDLOOP2 :2\n"
+ "14: ENDLOOP :2\n"
"15: MAD OUT[0], TEMP[1], CONST[1].yyyy, CONST[1].zzzz\n"
"16: END\n";
diff --git a/src/gallium/state_trackers/vega/vg_tracker.c b/src/gallium/state_trackers/vega/vg_tracker.c
index c262ce08fa9..56cc60aebe1 100644
--- a/src/gallium/state_trackers/vega/vg_tracker.c
+++ b/src/gallium/state_trackers/vega/vg_tracker.c
@@ -367,6 +367,11 @@ void st_make_current(struct vg_context *st,
}
}
+struct vg_context *st_get_current(void)
+{
+ return vg_current_context();
+}
+
void st_flush(struct vg_context *st, uint pipeFlushFlags,
struct pipe_fence_handle **fence)
{
@@ -399,8 +404,13 @@ void st_notify_swapbuffers_complete(struct st_framebuffer *stfb)
{
}
-int
-st_set_teximage(struct pipe_texture *pt, int target)
+int st_bind_texture_surface(struct pipe_surface *ps, int target, int level,
+ enum pipe_format format)
+{
+ return 0;
+}
+
+int st_unbind_texture_surface(struct pipe_surface *ps, int target, int level)
{
return 0;
}
diff --git a/src/gallium/state_trackers/vega/vg_tracker.h b/src/gallium/state_trackers/vega/vg_tracker.h
index 805c58ccc70..5457631106f 100644
--- a/src/gallium/state_trackers/vega/vg_tracker.h
+++ b/src/gallium/state_trackers/vega/vg_tracker.h
@@ -70,7 +70,10 @@ void st_set_framebuffer_surface(struct st_framebuffer *stfb,
void st_get_framebuffer_dimensions( struct st_framebuffer *stfb,
uint *width, uint *height);
-int st_set_teximage(struct pipe_texture *pt, int target);
+int st_bind_texture_surface(struct pipe_surface *ps, int target, int level,
+ enum pipe_format format);
+
+int st_unbind_texture_surface(struct pipe_surface *ps, int target, int level);
int st_get_framebuffer_surface(struct st_framebuffer *stfb,
uint surfIndex, struct pipe_surface **surf);
@@ -86,6 +89,8 @@ void st_make_current(struct vg_context *st,
struct st_framebuffer *draw,
struct st_framebuffer *read);
+struct vg_context *st_get_current(void);
+
void st_flush(struct vg_context *st, uint pipeFlushFlags,
struct pipe_fence_handle **fence);
void st_finish(struct vg_context *st);
diff --git a/src/gallium/state_trackers/xorg/xorg_dri2.c b/src/gallium/state_trackers/xorg/xorg_dri2.c
index ae3338ffeff..3fbab4dc51d 100644
--- a/src/gallium/state_trackers/xorg/xorg_dri2.c
+++ b/src/gallium/state_trackers/xorg/xorg_dri2.c
@@ -39,10 +39,13 @@
#include "pipe/p_state.h"
#include "pipe/p_inlines.h"
+#include "util/u_rect.h"
+
typedef struct {
PixmapPtr pPixmap;
struct pipe_texture *tex;
struct pipe_buffer *buf;
+ struct pipe_fence_handle *fence;
} *BufferPrivatePtr;
static DRI2BufferPtr
@@ -83,7 +86,6 @@ driCreateBuffers(DrawablePtr pDraw, unsigned int *attachments, int count)
pipe_texture_reference(&tex, depth);
} else if (attachments[i] == DRI2BufferDepth) {
struct pipe_texture template;
-
memset(&template, 0, sizeof(template));
template.target = PIPE_TEXTURE_2D;
template.format = PIPE_FORMAT_S8Z24_UNORM;
@@ -92,22 +94,20 @@ driCreateBuffers(DrawablePtr pDraw, unsigned int *attachments, int count)
template.height[0] = pDraw->height;
template.depth[0] = 1;
template.last_level = 0;
- template.tex_usage = PIPE_TEXTURE_USAGE_RENDER_TARGET;
+ template.tex_usage = PIPE_TEXTURE_USAGE_DEPTH_STENCIL;
tex = ms->screen->texture_create(ms->screen, &template);
+ depth = tex;
} else {
- struct pipe_texture template;
- memset(&template, 0, sizeof(template));
- template.target = PIPE_TEXTURE_2D;
- template.format = PIPE_FORMAT_A8R8G8B8_UNORM;
- pf_get_block(template.format, &template.block);
- template.width[0] = pDraw->width;
- template.height[0] = pDraw->height;
- template.depth[0] = 1;
- template.last_level = 0;
- template.tex_usage = PIPE_TEXTURE_USAGE_RENDER_TARGET;
- tex = ms->screen->texture_create(ms->screen, &template);
+ pPixmap = (*pScreen->CreatePixmap)(pScreen, pDraw->width,
+ pDraw->height,
+ pDraw->depth,
+ 0);
+ tex = xorg_exa_get_texture(pPixmap);
}
+ if (!tex)
+ FatalError("NO TEXTURE IN DRI2\n");
+
ms->api->buffer_from_texture(ms->api, tex, &buf, &stride);
ms->api->global_handle_from_buffer(ms->api, ms->screen, buf, &handle);
@@ -138,15 +138,17 @@ driDestroyBuffers(DrawablePtr pDraw, DRI2BufferPtr buffers, int count)
modesettingPtr ms = modesettingPTR(pScrn);
BufferPrivatePtr private;
int i;
+ (void)ms;
for (i = 0; i < count; i++) {
private = buffers[i].driverPrivate;
- if (private->pPixmap)
- (*pScreen->DestroyPixmap)(private->pPixmap);
-
pipe_texture_reference(&private->tex, NULL);
pipe_buffer_reference(&private->buf, NULL);
+ ms->screen->fence_reference(ms->screen, &private->fence, NULL);
+
+ if (private->pPixmap)
+ (*pScreen->DestroyPixmap)(private->pPixmap);
}
if (buffers) {
@@ -164,19 +166,42 @@ driCopyRegion(DrawablePtr pDraw, RegionPtr pRegion,
modesettingPtr ms = modesettingPTR(pScrn);
BufferPrivatePtr dst_priv = pDestBuffer->driverPrivate;
BufferPrivatePtr src_priv = pSrcBuffer->driverPrivate;
+ PixmapPtr src_pixmap;
+ PixmapPtr dst_pixmap;
+ GCPtr gc;
+ RegionPtr copy_clip;
+
+ src_pixmap = src_priv->pPixmap;
+ dst_pixmap = dst_priv->pPixmap;
+ if (pSrcBuffer->attachment == DRI2BufferFrontLeft)
+ src_pixmap = (PixmapPtr)pDraw;
+ if (pDestBuffer->attachment == DRI2BufferFrontLeft)
+ dst_pixmap = (PixmapPtr)pDraw;
+ gc = GetScratchGC(pDraw->depth, pScreen);
+ copy_clip = REGION_CREATE(pScreen, NULL, 0);
+ REGION_COPY(pScreen, copy_clip, pRegion);
+ (*gc->funcs->ChangeClip) (gc, CT_REGION, copy_clip, 0);
+ ValidateGC(&dst_pixmap->drawable, gc);
+
+ /* If this is a full buffer swap, throttle on the previous one */
+ if (dst_priv->fence && REGION_NUM_RECTS(pRegion) == 1) {
+ BoxPtr extents = REGION_EXTENTS(pScreen, pRegion);
+
+ if (extents->x1 == 0 && extents->y1 == 0 &&
+ extents->x2 == pDraw->width && extents->y2 == pDraw->height) {
+ ms->screen->fence_finish(ms->screen, dst_priv->fence, 0);
+ ms->screen->fence_reference(ms->screen, &dst_priv->fence, NULL);
+ }
+ }
- struct pipe_surface *dst_surf =
- ms->screen->get_tex_surface(ms->screen, dst_priv->tex, 0, 0, 0,
- PIPE_BUFFER_USAGE_GPU_WRITE);
- struct pipe_surface *src_surf =
- ms->screen->get_tex_surface(ms->screen, src_priv->tex, 0, 0, 0,
- PIPE_BUFFER_USAGE_GPU_READ);
+ (*gc->ops->CopyArea)(&src_pixmap->drawable, &dst_pixmap->drawable, gc,
+ 0, 0, pDraw->width, pDraw->height, 0, 0);
- ms->ctx->surface_copy(ms->ctx, dst_surf, 0, 0, src_surf,
- 0, 0, pDraw->width, pDraw->height);
+ FreeScratchGC(gc);
- pipe_surface_reference(&dst_surf, NULL);
- pipe_surface_reference(&src_surf, NULL);
+ ms->ctx->flush(ms->ctx, PIPE_FLUSH_SWAPBUFFERS,
+ pDestBuffer->attachment == DRI2BufferFrontLeft ?
+ &dst_priv->fence : NULL);
}
Bool
diff --git a/src/gallium/state_trackers/xorg/xorg_driver.c b/src/gallium/state_trackers/xorg/xorg_driver.c
index e01e5294b11..53d1a330951 100644
--- a/src/gallium/state_trackers/xorg/xorg_driver.c
+++ b/src/gallium/state_trackers/xorg/xorg_driver.c
@@ -179,8 +179,10 @@ CreateFrontBuffer(ScrnInfoPtr pScrn)
modesettingPtr ms = modesettingPTR(pScrn);
ScreenPtr pScreen = pScrn->pScreen;
PixmapPtr rootPixmap = pScreen->GetScreenPixmap(pScreen);
+ unsigned handle, stride;
ms->noEvict = TRUE;
+ xorg_exa_set_displayed_usage(rootPixmap);
pScreen->ModifyPixmapHeader(rootPixmap,
pScrn->virtualX, pScrn->virtualY,
pScrn->depth, pScrn->bitsPerPixel,
@@ -188,13 +190,16 @@ CreateFrontBuffer(ScrnInfoPtr pScrn)
NULL);
ms->noEvict = FALSE;
+ handle = xorg_exa_get_pixmap_handle(rootPixmap, &stride);
+
drmModeAddFB(ms->fd,
pScrn->virtualX,
pScrn->virtualY,
pScrn->depth,
pScrn->bitsPerPixel,
- pScrn->displayWidth * pScrn->bitsPerPixel / 8,
- xorg_exa_get_pixmap_handle(rootPixmap), &ms->fb_id);
+ stride,
+ handle,
+ &ms->fb_id);
pScrn->frameX0 = 0;
pScrn->frameY0 = 0;
@@ -426,6 +431,7 @@ CreateScreenResources(ScreenPtr pScreen)
modesettingPtr ms = modesettingPTR(pScrn);
PixmapPtr rootPixmap;
Bool ret;
+ unsigned handle, stride;
ms->noEvict = TRUE;
@@ -435,18 +441,22 @@ CreateScreenResources(ScreenPtr pScreen)
rootPixmap = pScreen->GetScreenPixmap(pScreen);
+ xorg_exa_set_displayed_usage(rootPixmap);
if (!pScreen->ModifyPixmapHeader(rootPixmap, -1, -1, -1, -1, -1, NULL))
FatalError("Couldn't adjust screen pixmap\n");
ms->noEvict = FALSE;
+ handle = xorg_exa_get_pixmap_handle(rootPixmap, &stride);
+
drmModeAddFB(ms->fd,
pScrn->virtualX,
pScrn->virtualY,
pScrn->depth,
pScrn->bitsPerPixel,
- pScrn->displayWidth * pScrn->bitsPerPixel / 8,
- xorg_exa_get_pixmap_handle(rootPixmap), &ms->fb_id);
+ stride,
+ handle,
+ &ms->fb_id);
AdjustFrame(pScrn->scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
@@ -623,6 +633,10 @@ LeaveVT(int scrnIndex, int flags)
RestoreHWState(pScrn);
+ if (drmDropMaster(ms->fd))
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "drmDropMaster failed: %s\n", strerror(errno));
+
pScrn->vtSema = FALSE;
}
@@ -635,6 +649,17 @@ EnterVT(int scrnIndex, int flags)
ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
modesettingPtr ms = modesettingPTR(pScrn);
+ if (drmSetMaster(ms->fd)) {
+ if (errno == EINVAL) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "drmSetMaster failed: 2.6.29 or newer kernel required for "
+ "multi-server DRI\n");
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "drmSetMaster failed: %s\n", strerror(errno));
+ }
+ }
+
/*
* Only save state once per server generation since that's what most
* drivers do. Could change this to save state at each VT enter.
diff --git a/src/gallium/state_trackers/xorg/xorg_exa.c b/src/gallium/state_trackers/xorg/xorg_exa.c
index 2c4291aa4ea..f2dac73e908 100644
--- a/src/gallium/state_trackers/xorg/xorg_exa.c
+++ b/src/gallium/state_trackers/xorg/xorg_exa.c
@@ -359,8 +359,48 @@ ExaPixmapIsOffscreen(PixmapPtr pPixmap)
return FALSE;
}
+int
+xorg_exa_set_displayed_usage(PixmapPtr pPixmap)
+{
+ struct exa_pixmap_priv *priv;
+ priv = exaGetPixmapDriverPrivate(pPixmap);
+
+ if (!priv) {
+ FatalError("NO PIXMAP PRIVATE\n");
+ return 0;
+ }
+
+ if (priv->flags & ~PIPE_TEXTURE_USAGE_PRIMARY) {
+ FatalError("BAD FLAGS\n");
+ return 0;
+ }
+ priv->flags = PIPE_TEXTURE_USAGE_PRIMARY;
+
+ return 0;
+}
+
+int
+xorg_exa_set_shared_usage(PixmapPtr pPixmap)
+{
+ struct exa_pixmap_priv *priv;
+ priv = exaGetPixmapDriverPrivate(pPixmap);
+
+ if (!priv) {
+ FatalError("NO PIXMAP PRIVATE\n");
+ return 0;
+ }
+
+ if (priv->flags & ~PIPE_TEXTURE_USAGE_DISPLAY_TARGET) {
+ FatalError("BAD FLAGS\n");
+ return 0;
+ }
+ priv->flags = PIPE_TEXTURE_USAGE_DISPLAY_TARGET;
+
+ return 0;
+}
+
unsigned
-xorg_exa_get_pixmap_handle(PixmapPtr pPixmap)
+xorg_exa_get_pixmap_handle(PixmapPtr pPixmap, unsigned *stride_out)
{
ScreenPtr pScreen = pPixmap->drawable.pScreen;
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
@@ -385,6 +425,9 @@ xorg_exa_get_pixmap_handle(PixmapPtr pPixmap)
ms->api->buffer_from_texture(ms->api, priv->tex, &buffer, &stride);
ms->api->handle_from_buffer(ms->api, ms->screen, buffer, &handle);
pipe_buffer_reference(&buffer, NULL);
+ if (stride_out)
+ *stride_out = stride;
+
return handle;
}
@@ -421,7 +464,9 @@ ExaModifyPixmapHeader(PixmapPtr pPixmap, int width, int height,
bitsPerPixel, devKind, NULL);
/* Deal with screen resize */
- if (priv->tex && (priv->tex->width[0] != width || priv->tex->height[0] != height)) {
+ if (priv->tex && (priv->tex->width[0] != width ||
+ priv->tex->height[0] != height ||
+ priv->tex_flags != priv->flags)) {
pipe_texture_reference(&priv->tex, NULL);
}
@@ -436,7 +481,8 @@ ExaModifyPixmapHeader(PixmapPtr pPixmap, int width, int height,
template.height[0] = height;
template.depth[0] = 1;
template.last_level = 0;
- template.tex_usage = PIPE_TEXTURE_USAGE_RENDER_TARGET;
+ template.tex_usage = PIPE_TEXTURE_USAGE_RENDER_TARGET | priv->flags;
+ priv->tex_flags = priv->flags;
priv->tex = exa->scrn->texture_create(exa->scrn, &template);
}
diff --git a/src/gallium/state_trackers/xorg/xorg_exa.h b/src/gallium/state_trackers/xorg/xorg_exa.h
index 650997aec67..f0508eb2d53 100644
--- a/src/gallium/state_trackers/xorg/xorg_exa.h
+++ b/src/gallium/state_trackers/xorg/xorg_exa.h
@@ -14,6 +14,8 @@ struct exa_context
struct exa_pixmap_priv
{
int flags;
+ int tex_flags;
+
struct pipe_texture *tex;
unsigned int color;
struct pipe_surface *src_surf; /* for copies */
diff --git a/src/gallium/state_trackers/xorg/xorg_tracker.h b/src/gallium/state_trackers/xorg/xorg_tracker.h
index b4742bdbf56..910782dbc44 100644
--- a/src/gallium/state_trackers/xorg/xorg_tracker.h
+++ b/src/gallium/state_trackers/xorg/xorg_tracker.h
@@ -31,6 +31,7 @@
#ifndef _XORG_TRACKER_H_
#define _XORG_TRACKER_H_
+#include <stddef.h>
#include <stdint.h>
#include <errno.h>
#include <drm.h>
@@ -98,7 +99,13 @@ struct pipe_texture *
xorg_exa_get_texture(PixmapPtr pPixmap);
unsigned
-xorg_exa_get_pixmap_handle(PixmapPtr pPixmap);
+xorg_exa_get_pixmap_handle(PixmapPtr pPixmap, unsigned *stride);
+
+int
+xorg_exa_set_displayed_usage(PixmapPtr pPixmap);
+
+int
+xorg_exa_set_shared_usage(PixmapPtr pPixmap);
void *
xorg_exa_init(ScrnInfoPtr pScrn);
diff --git a/src/gallium/winsys/drm/Makefile.template b/src/gallium/winsys/drm/Makefile.template
index 985e5a861fc..9635c3c50e9 100644
--- a/src/gallium/winsys/drm/Makefile.template
+++ b/src/gallium/winsys/drm/Makefile.template
@@ -83,7 +83,9 @@ default: depend symlinks $(TOP)/$(LIB_DIR)/gallium/$(LIBNAME)
$(LIBNAME): $(OBJECTS) $(MESA_MODULES) $(PIPE_DRIVERS) $(WINOBJ) Makefile $(TOP)/src/mesa/drivers/dri/Makefile.template
$(MKLIB) -noprefix -o $@ \
- $(OBJECTS) $(PIPE_DRIVERS) $(MESA_MODULES) $(WINOBJ) $(DRI_LIB_DEPS) $(DRIVER_EXTRAS)
+ $(OBJECTS) $(PIPE_DRIVERS) \
+ -Wl,--start-group $(MESA_MODULES) -Wl,--end-group \
+ $(WINOBJ) $(DRI_LIB_DEPS) $(DRIVER_EXTRAS)
$(LIBNAME_EGL): $(WINSYS_OBJECTS) $(LIBS)
$(MKLIB) -o $(LIBNAME_EGL) \
diff --git a/src/gallium/winsys/drm/intel/dri/SConscript b/src/gallium/winsys/drm/intel/dri/SConscript
index e14e96e32fd..6c00861f517 100644
--- a/src/gallium/winsys/drm/intel/dri/SConscript
+++ b/src/gallium/winsys/drm/intel/dri/SConscript
@@ -2,11 +2,14 @@ Import('*')
env = drienv.Clone()
+env.ParseConfig('pkg-config --cflags --libs libdrm_intel')
+
drivers = [
+ st_dri,
+ inteldrm,
softpipe,
i915simple,
trace,
- inteldrm
]
env.SharedLibrary(
diff --git a/src/gallium/winsys/drm/intel/egl/Makefile b/src/gallium/winsys/drm/intel/egl/Makefile
index c5217ad2d63..490baded66b 100644
--- a/src/gallium/winsys/drm/intel/egl/Makefile
+++ b/src/gallium/winsys/drm/intel/egl/Makefile
@@ -8,6 +8,7 @@ PIPE_DRIVERS = \
$(TOP)/src/gallium/state_trackers/egl/libegldrm.a \
$(GALLIUMDIR)/winsys/drm/intel/gem/libinteldrm.a \
$(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \
+ $(TOP)/src/gallium/drivers/trace/libtrace.a \
$(TOP)/src/gallium/drivers/i915simple/libi915simple.a
DRIVER_SOURCES =
diff --git a/src/gallium/winsys/drm/intel/gem/intel_be_batchbuffer.c b/src/gallium/winsys/drm/intel/gem/intel_be_batchbuffer.c
index d5e63c3bae5..c4a79586e68 100644
--- a/src/gallium/winsys/drm/intel/gem/intel_be_batchbuffer.c
+++ b/src/gallium/winsys/drm/intel/gem/intel_be_batchbuffer.c
@@ -21,12 +21,10 @@ intel_be_batchbuffer_alloc(struct intel_be_context *intel)
batch->base.size = 0;
batch->base.actual_size = intel->device->max_batch_size;
batch->base.relocs = 0;
- batch->base.max_relocs = 500;/*INTEL_DEFAULT_RELOCS;*/
+ batch->base.max_relocs = 100;/*INTEL_DEFAULT_RELOCS;*/
- batch->base.map = malloc(batch->base.actual_size);
- memset(batch->base.map, 0, batch->base.actual_size);
-
- batch->base.ptr = batch->base.map;
+ batch->intel = intel;
+ batch->device = intel->device;
intel_be_batchbuffer_reset(batch);
@@ -41,16 +39,17 @@ intel_be_batchbuffer_reset(struct intel_be_batchbuffer *batch)
if (batch->bo)
drm_intel_bo_unreference(batch->bo);
+ batch->bo = drm_intel_bo_alloc(dev->pools.gem,
+ "gallium3d_batch_buffer",
+ batch->base.actual_size,
+ 4096);
+ drm_intel_bo_map(batch->bo, TRUE);
+ batch->base.map = batch->bo->virtual;
memset(batch->base.map, 0, batch->base.actual_size);
batch->base.ptr = batch->base.map;
batch->base.size = batch->base.actual_size - BATCH_RESERVED;
-
batch->base.relocs = 0;
-
- batch->bo = drm_intel_bo_alloc(dev->pools.gem,
- "gallium3d_batch_buffer",
- batch->base.actual_size, 0);
}
int
@@ -88,6 +87,7 @@ intel_be_batchbuffer_flush(struct intel_be_batchbuffer *batch,
struct i915_batchbuffer *i915 = &batch->base;
unsigned used = 0;
int ret = 0;
+ int i;
assert(i915_batchbuffer_space(i915) >= 0);
@@ -105,11 +105,29 @@ intel_be_batchbuffer_flush(struct intel_be_batchbuffer *batch,
used = batch->base.ptr - batch->base.map;
- drm_intel_bo_subdata(batch->bo, 0, used, batch->base.map);
- ret = drm_intel_bo_exec(batch->bo, used, NULL, 0, 0);
+ drm_intel_bo_unmap(batch->bo);
+ /* Do the sending to HW */
+ ret = drm_intel_bo_exec(batch->bo, used, NULL, 0, 0);
assert(ret == 0);
+ if (batch->device->dump_cmd) {
+ unsigned *ptr;
+ drm_intel_bo_map(batch->bo, FALSE);
+ ptr = (unsigned*)batch->bo->virtual;
+
+ debug_printf("%s:\n", __func__);
+ for (i = 0; i < used / 4; i++, ptr++) {
+ debug_printf("\t%08x: %08x\n", i*4, *ptr);
+ }
+
+ drm_intel_bo_unmap(batch->bo);
+ } else {
+ /* TODO figgure out why the gpu hangs if we don't run sync */
+ drm_intel_bo_map(batch->bo, FALSE);
+ drm_intel_bo_unmap(batch->bo);
+ }
+
intel_be_batchbuffer_reset(batch);
if (fence) {
@@ -134,6 +152,5 @@ intel_be_batchbuffer_free(struct intel_be_batchbuffer *batch)
if (batch->bo)
drm_intel_bo_unreference(batch->bo);
- free(batch->base.map);
free(batch);
}
diff --git a/src/gallium/winsys/drm/intel/gem/intel_be_context.c b/src/gallium/winsys/drm/intel/gem/intel_be_context.c
index db84f9af514..629987c6f92 100644
--- a/src/gallium/winsys/drm/intel/gem/intel_be_context.c
+++ b/src/gallium/winsys/drm/intel/gem/intel_be_context.c
@@ -36,7 +36,7 @@ intel_be_batch_reloc(struct i915_winsys *sws,
}
if (access_flags & I915_BUFFER_ACCESS_READ) {
- read |= I915_GEM_DOMAIN_VERTEX;
+ read |= I915_GEM_DOMAIN_SAMPLER;
}
ret = intel_be_offset_relocation(intel->batch,
diff --git a/src/gallium/winsys/drm/intel/gem/intel_be_device.c b/src/gallium/winsys/drm/intel/gem/intel_be_device.c
index e3630f5d120..5312865a039 100644
--- a/src/gallium/winsys/drm/intel/gem/intel_be_device.c
+++ b/src/gallium/winsys/drm/intel/gem/intel_be_device.c
@@ -7,6 +7,7 @@
#include "pipe/p_inlines.h"
#include "util/u_memory.h"
#include "util/u_debug.h"
+#include "util/u_math.h"
#include "intel_be_fence.h"
@@ -16,6 +17,8 @@
#include "intel_be_api.h"
#include <stdio.h>
+#define I915_TILING_X 1
+
/*
* Buffer
*/
@@ -25,9 +28,10 @@ intel_be_buffer_map(struct pipe_winsys *winsys,
struct pipe_buffer *buf,
unsigned flags)
{
+ struct intel_be_buffer *buffer = intel_be_buffer(buf);
drm_intel_bo *bo = intel_bo(buf);
int write = 0;
- int ret;
+ int ret = 0;
if (flags & PIPE_BUFFER_USAGE_DONTBLOCK) {
/* Remove this when drm_intel_bo_map supports DONTBLOCK
@@ -38,19 +42,37 @@ intel_be_buffer_map(struct pipe_winsys *winsys,
if (flags & PIPE_BUFFER_USAGE_CPU_WRITE)
write = 1;
- ret = drm_intel_bo_map(bo, write);
+ if (buffer->map_count)
+ goto out;
+
+ if (buffer->map_gtt)
+ ret = drm_intel_gem_bo_map_gtt(bo);
+ else
+ ret = drm_intel_bo_map(bo, write);
+
+ buffer->ptr = bo->virtual;
+out:
if (ret)
return NULL;
- return bo->virtual;
+ buffer->map_count++;
+ return buffer->ptr;
}
static void
intel_be_buffer_unmap(struct pipe_winsys *winsys,
struct pipe_buffer *buf)
{
- drm_intel_bo_unmap(intel_bo(buf));
+ struct intel_be_buffer *buffer = intel_be_buffer(buf);
+
+ if (--buffer->map_count)
+ return;
+
+ if (buffer->map_gtt)
+ drm_intel_gem_bo_unmap_gtt(intel_bo(buf));
+ else
+ drm_intel_bo_unmap(intel_bo(buf));
}
static void
@@ -80,8 +102,13 @@ intel_be_buffer_create(struct pipe_winsys *winsys,
buffer->base.size = size;
buffer->flinked = FALSE;
buffer->flink = 0;
+ buffer->map_gtt = FALSE;
- if (usage & (PIPE_BUFFER_USAGE_VERTEX | PIPE_BUFFER_USAGE_CONSTANT)) {
+ if (usage & I915_BUFFER_USAGE_SCANOUT) {
+ /* Scanout buffer */
+ name = "gallium3d_scanout";
+ pool = dev->pools.gem;
+ } else if (usage & (PIPE_BUFFER_USAGE_VERTEX | PIPE_BUFFER_USAGE_CONSTANT)) {
/* Local buffer */
name = "gallium3d_local";
pool = dev->pools.gem;
@@ -96,6 +123,12 @@ intel_be_buffer_create(struct pipe_winsys *winsys,
}
buffer->bo = drm_intel_bo_alloc(pool, name, size, alignment);
+ if (usage & I915_BUFFER_USAGE_SCANOUT) {
+ unsigned tiling = I915_TILING_X;
+ unsigned stride = 2048 * 4; /* TODO do something smarter here */
+ drm_intel_bo_set_tiling(buffer->bo, &tiling, stride);
+ buffer->map_gtt = TRUE;
+ }
if (!buffer->bo)
goto err;
@@ -142,6 +175,40 @@ err:
return NULL;
}
+static struct pipe_buffer *
+intel_be_surface_buffer_create(struct pipe_winsys *winsys,
+ unsigned width, unsigned height,
+ enum pipe_format format,
+ unsigned usage,
+ unsigned tex_usage,
+ unsigned *stride)
+{
+ struct pipe_format_block block;
+ unsigned buf_usage = 0;
+ unsigned buf_stride = 0;
+ unsigned buf_size = 0;
+
+ pf_get_block(format, &block);
+ buf_stride = pf_get_stride(&block, width);
+ buf_stride = align(buf_stride, 64);
+
+ if (tex_usage & PIPE_TEXTURE_USAGE_PRIMARY) {
+ /* TODO more checks */
+ assert(buf_stride <= 2048*4);
+ assert(height % 8 == 0);
+ buf_stride = 2048 * 4;
+ buf_usage |= I915_BUFFER_USAGE_SCANOUT;
+ }
+
+ buf_size = buf_stride * height;
+ *stride = buf_stride;
+
+ return intel_be_buffer_create(winsys,
+ 0,
+ buf_usage,
+ buf_size);
+}
+
boolean
intel_be_get_texture_buffer(struct drm_api *api,
struct pipe_texture *texture,
@@ -225,6 +292,7 @@ intel_be_global_handle_from_buffer(struct drm_api *api,
*handle = buf->flink;
return TRUE;
}
+
/*
* Fence
*/
@@ -296,8 +364,8 @@ intel_be_init_device(struct intel_be_device *dev, int fd, unsigned id)
dev->base.buffer_unmap = intel_be_buffer_unmap;
dev->base.buffer_destroy = intel_be_buffer_destroy;
- /* Not used anymore */
- dev->base.surface_buffer_create = NULL;
+ /* Used by softpipe */
+ dev->base.surface_buffer_create = intel_be_surface_buffer_create;
dev->base.fence_reference = intel_be_fence_refunref;
dev->base.fence_signalled = intel_be_fence_signalled;
@@ -308,6 +376,7 @@ intel_be_init_device(struct intel_be_device *dev, int fd, unsigned id)
dev->pools.gem = drm_intel_bufmgr_gem_init(dev->fd, dev->max_batch_size);
dev->softpipe = debug_get_bool_option("INTEL_SOFTPIPE", FALSE);
+ dev->dump_cmd = debug_get_bool_option("INTEL_DUMP_CMD", FALSE);
return true;
}
diff --git a/src/gallium/winsys/drm/intel/gem/intel_be_device.h b/src/gallium/winsys/drm/intel/gem/intel_be_device.h
index 56d95bd7fe0..c397048f8c5 100644
--- a/src/gallium/winsys/drm/intel/gem/intel_be_device.h
+++ b/src/gallium/winsys/drm/intel/gem/intel_be_device.h
@@ -19,6 +19,7 @@ struct intel_be_device
struct pipe_winsys base;
boolean softpipe;
+ boolean dump_cmd;
int fd; /**< Drm file discriptor */
@@ -47,6 +48,10 @@ intel_be_init_device(struct intel_be_device *device, int fd, unsigned id);
struct intel_be_buffer {
struct pipe_buffer base;
+ void *ptr;
+ unsigned map_count;
+ boolean map_gtt;
+
drm_intel_bo *bo;
boolean flinked;
unsigned flink;
diff --git a/src/gallium/winsys/drm/intel/xorg/Makefile b/src/gallium/winsys/drm/intel/xorg/Makefile
index d51cca8d213..9e56853b021 100644
--- a/src/gallium/winsys/drm/intel/xorg/Makefile
+++ b/src/gallium/winsys/drm/intel/xorg/Makefile
@@ -19,6 +19,7 @@ LIBS = \
$(TOP)/src/gallium/state_trackers/xorg/libxorgtracker.a \
$(TOP)/src/gallium/winsys/drm/intel/gem/libinteldrm.a \
$(TOP)/src/gallium/drivers/i915simple/libi915simple.a \
+ $(TOP)/src/gallium/drivers/trace/libtrace.a \
$(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \
$(GALLIUM_AUXILIARIES)
diff --git a/src/gallium/winsys/drm/radeon/core/radeon_buffer.c b/src/gallium/winsys/drm/radeon/core/radeon_buffer.c
index 684a487f242..775bda8308f 100644
--- a/src/gallium/winsys/drm/radeon/core/radeon_buffer.c
+++ b/src/gallium/winsys/drm/radeon/core/radeon_buffer.c
@@ -72,6 +72,7 @@ static struct pipe_buffer *radeon_buffer_create(struct pipe_winsys *ws,
alignment, domain, 0);
if (radeon_buffer->bo == NULL) {
FREE(radeon_buffer);
+ return NULL;
}
return &radeon_buffer->base;
}
diff --git a/src/gallium/winsys/drm/radeon/core/radeon_buffer.h b/src/gallium/winsys/drm/radeon/core/radeon_buffer.h
index 8c8b61fa10b..f5153b06af5 100644
--- a/src/gallium/winsys/drm/radeon/core/radeon_buffer.h
+++ b/src/gallium/winsys/drm/radeon/core/radeon_buffer.h
@@ -61,11 +61,6 @@ struct radeon_winsys_priv {
/* Radeon BO manager. */
struct radeon_bo_manager* bom;
- /* Radeon BO space checker. */
- struct radeon_cs_space_check sc[RADEON_MAX_BOS];
- /* Current BO count. */
- unsigned bo_count;
-
/* Radeon CS manager. */
struct radeon_cs_manager* csm;
diff --git a/src/gallium/winsys/drm/radeon/core/radeon_drm.c b/src/gallium/winsys/drm/radeon/core/radeon_drm.c
index da2010184a2..8d818cf8301 100644
--- a/src/gallium/winsys/drm/radeon/core/radeon_drm.c
+++ b/src/gallium/winsys/drm/radeon/core/radeon_drm.c
@@ -29,7 +29,6 @@
*/
#include "radeon_drm.h"
-#include "trace/tr_drm.h"
/* Create a pipe_screen. */
struct pipe_screen* radeon_create_screen(struct drm_api* api,
@@ -54,7 +53,8 @@ struct pipe_context* radeon_create_context(struct drm_api* api,
if (getenv("RADEON_SOFTPIPE")) {
return radeon_create_softpipe(screen->winsys);
} else {
- return r300_create_context(screen, screen->winsys);
+ return r300_create_context(screen,
+ (struct r300_winsys*)screen->winsys);
}
}
diff --git a/src/gallium/winsys/drm/radeon/core/radeon_drm.h b/src/gallium/winsys/drm/radeon/core/radeon_drm.h
index 8560f71db65..88a5c82b284 100644
--- a/src/gallium/winsys/drm/radeon/core/radeon_drm.h
+++ b/src/gallium/winsys/drm/radeon/core/radeon_drm.h
@@ -30,8 +30,13 @@
#ifndef RADEON_DRM_H
#define RADEON_DRM_H
+#include <sys/ioctl.h>
+
+#include "xf86drm.h"
+
#include "pipe/p_screen.h"
+#include "trace/tr_drm.h"
#include "util/u_memory.h"
#include "state_tracker/drm_api.h"
@@ -40,6 +45,9 @@
#include "radeon_r300.h"
#include "radeon_winsys_softpipe.h"
+/* XXX */
+#include "r300_screen.h"
+
struct pipe_screen* radeon_create_screen(struct drm_api* api,
int drmFB,
struct drm_create_screen_arg *arg);
diff --git a/src/gallium/winsys/drm/radeon/core/radeon_r300.c b/src/gallium/winsys/drm/radeon/core/radeon_r300.c
index 8c5f756ddf8..4e9a2ddd161 100644
--- a/src/gallium/winsys/drm/radeon/core/radeon_r300.c
+++ b/src/gallium/winsys/drm/radeon/core/radeon_r300.c
@@ -27,66 +27,25 @@ static boolean radeon_r300_add_buffer(struct r300_winsys* winsys,
uint32_t rd,
uint32_t wd)
{
- int i;
struct radeon_winsys_priv* priv =
(struct radeon_winsys_priv*)winsys->radeon_winsys;
- struct radeon_cs_space_check* sc = priv->sc;
struct radeon_bo* bo = ((struct radeon_pipe_buffer*)pbuffer)->bo;
- /* Check to see if this BO is already in line for validation;
- * find a slot for it otherwise. */
- for (i = 0; i < priv->bo_count; i++) {
- if (sc[i].bo == bo) {
- sc[i].read_domains |= rd;
- sc[i].write_domain |= wd;
- return TRUE;
- }
- }
-
- if (priv->bo_count >= RADEON_MAX_BOS) {
- /* Dohoho. Not falling for that one again. Request a flush. */
- return FALSE;
- }
-
- sc[priv->bo_count].bo = bo;
- sc[priv->bo_count].read_domains = rd;
- sc[priv->bo_count].write_domain = wd;
- priv->bo_count++;
-
+ radeon_cs_space_add_persistent_bo(priv->cs, bo, rd, wd);
return TRUE;
}
static boolean radeon_r300_validate(struct r300_winsys* winsys)
{
- int retval, i;
struct radeon_winsys_priv* priv =
(struct radeon_winsys_priv*)winsys->radeon_winsys;
- struct radeon_cs_space_check* sc = priv->sc;
-
- retval = radeon_cs_space_check(priv->cs, sc, priv->bo_count);
-
- if (retval == RADEON_CS_SPACE_OP_TO_BIG) {
- /* We might as well HCF, since this is not going to fit in the card,
- * period. */
- /* XXX just drop it on the floor instead */
- exit(1);
- } else if (retval == RADEON_CS_SPACE_FLUSH) {
- /* We must flush before more rendering can commence. */
- return TRUE;
- }
- /* XXX should probably be its own function */
- for (i = 0; i < priv->bo_count; i++) {
- if (sc[i].read_domains && sc[i].write_domain) {
- /* Cute, cute. We need to flush first. */
- debug_printf("radeon: BO %p can't be read and written; "
- "requesting flush.\n", sc[i].bo);
- return TRUE;
- }
+ if (radeon_cs_space_check(priv->cs) < 0) {
+ return FALSE;
}
/* Things are fine, we can proceed as normal. */
- return FALSE;
+ return TRUE;
}
static boolean radeon_r300_check_cs(struct r300_winsys* winsys, int size)
@@ -151,8 +110,7 @@ static void radeon_r300_flush_cs(struct r300_winsys* winsys)
{
struct radeon_winsys_priv* priv =
(struct radeon_winsys_priv*)winsys->radeon_winsys;
- struct radeon_cs_space_check* sc = priv->sc;
- int retval = 1;
+ int retval;
/* Emit the CS. */
retval = radeon_cs_emit(priv->cs);
@@ -160,40 +118,34 @@ static void radeon_r300_flush_cs(struct r300_winsys* winsys)
debug_printf("radeon: Bad CS, dumping...\n");
radeon_cs_print(priv->cs, stderr);
}
- radeon_cs_erase(priv->cs);
/* Clean out BOs. */
- memset(sc, 0, sizeof(struct radeon_cs_space_check) * RADEON_MAX_BOS);
- priv->bo_count = 0;
+ radeon_cs_space_reset_bos(priv->cs);
+
+ /* Reset CS.
+ * Someday, when we care about performance, we should really find a way
+ * to rotate between two or three CS objects so that the GPU can be
+ * spinning through one CS while another one is being filled. */
+ radeon_cs_erase(priv->cs);
}
/* Helper function to do the ioctls needed for setup and init. */
static void do_ioctls(struct r300_winsys* winsys, int fd)
{
struct drm_radeon_gem_info gem_info = {0};
- drm_radeon_getparam_t gp = {0};
struct drm_radeon_info info = {0};
int target = 0;
int retval;
info.value = &target;
- gp.value = &target;
/* First, get PCI ID */
info.request = RADEON_INFO_DEVICE_ID;
retval = drmCommandWriteRead(fd, DRM_RADEON_INFO, &info, sizeof(info));
if (retval) {
- fprintf(stderr, "%s: New ioctl for PCI ID failed "
- "(error number %d), trying classic ioctl...\n",
- __FUNCTION__, retval);
- gp.param = RADEON_PARAM_DEVICE_ID;
- retval = drmCommandWriteRead(fd, DRM_RADEON_GETPARAM, &gp,
- sizeof(gp));
- if (retval) {
- fprintf(stderr, "%s: Failed to get PCI ID, "
- "error number %d\n", __FUNCTION__, retval);
- exit(1);
- }
+ fprintf(stderr, "%s: Failed to get PCI ID, "
+ "error number %d\n", __FUNCTION__, retval);
+ exit(1);
}
winsys->pci_id = target;
diff --git a/src/gallium/winsys/drm/radeon/core/radeon_r300.h b/src/gallium/winsys/drm/radeon/core/radeon_r300.h
index a2e0e582485..741c1371889 100644
--- a/src/gallium/winsys/drm/radeon/core/radeon_r300.h
+++ b/src/gallium/winsys/drm/radeon/core/radeon_r300.h
@@ -20,6 +20,9 @@
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
* USE OR OTHER DEALINGS IN THE SOFTWARE. */
+#ifndef RADEON_R300_H
+#define RADEON_R300_H
+
/* XXX WTF is this! I shouldn't have to include those first three! FUCK! */
#include <stdint.h>
#include <stdlib.h>
@@ -31,18 +34,9 @@
#include "radeon_buffer.h"
-/* protect us from bonghits */
-#ifndef RADEON_INFO_DEVICE_ID
-#define RADEON_INFO_DEVICE_ID 0
-#endif
-#ifndef DRM_RADEON_INFO
-#define DRM_RADEON_INFO 0x1
-struct drm_radeon_info {
- uint32_t request;
- uint32_t pad;
- uint64_t value;
-};
-#endif
+struct radeon_winsys;
struct r300_winsys*
radeon_create_r300_winsys(int fd, struct radeon_winsys* old_winsys);
+
+#endif /* RADEON_R300_H */
diff --git a/src/gallium/winsys/egl_xlib/egl_xlib.c b/src/gallium/winsys/egl_xlib/egl_xlib.c
index e1ddcae97ba..f409a3fd6ba 100644
--- a/src/gallium/winsys/egl_xlib/egl_xlib.c
+++ b/src/gallium/winsys/egl_xlib/egl_xlib.c
@@ -82,6 +82,7 @@ struct xlib_egl_surface
{
_EGLSurface Base; /**< base class */
+ /* These are set for window surface */
Display *Dpy; /**< The X Display of the window */
Window Win; /**< The user-created window ID */
GC Gc;
@@ -101,7 +102,7 @@ xlib_egl_driver(_EGLDriver *drv)
}
-static struct xlib_egl_surface *
+static INLINE struct xlib_egl_surface *
lookup_surface(EGLSurface surf)
{
_EGLSurface *surface = _eglLookupSurface(surf);
@@ -109,10 +110,10 @@ lookup_surface(EGLSurface surf)
}
-static struct xlib_egl_context *
-lookup_context(EGLContext surf)
+static INLINE struct xlib_egl_context *
+lookup_context(EGLContext ctx)
{
- _EGLContext *context = _eglLookupContext(surf);
+ _EGLContext *context = _eglLookupContext(ctx);
return (struct xlib_egl_context *) context;
}
@@ -180,7 +181,9 @@ create_configs(_EGLDriver *drv, EGLDisplay dpy)
SET_CONFIG_ATTRIB(config, EGL_NATIVE_RENDERABLE, EGL_FALSE);
SET_CONFIG_ATTRIB(config, EGL_CONFORMANT, all_apis);
SET_CONFIG_ATTRIB(config, EGL_RENDERABLE_TYPE, all_apis);
- SET_CONFIG_ATTRIB(config, EGL_SURFACE_TYPE, EGL_WINDOW_BIT);
+ SET_CONFIG_ATTRIB(config, EGL_SURFACE_TYPE, EGL_WINDOW_BIT | EGL_PBUFFER_BIT);
+ SET_CONFIG_ATTRIB(config, EGL_BIND_TO_TEXTURE_RGBA, EGL_TRUE);
+ SET_CONFIG_ATTRIB(config, EGL_BIND_TO_TEXTURE_RGB, EGL_TRUE);
_eglAddConfig(disp, config);
}
@@ -264,7 +267,13 @@ static void
check_and_update_buffer_size(struct xlib_egl_surface *surface)
{
uint width, height;
- get_drawable_size(surface->Dpy, surface->Win, &width, &height);
+ if (surface->Base.Type == EGL_PBUFFER_BIT) {
+ width = surface->Base.Width;
+ height = surface->Base.Height;
+ }
+ else {
+ get_drawable_size(surface->Dpy, surface->Win, &width, &height);
+ }
st_resize_framebuffer(surface->Framebuffer, width, height);
surface->Base.Width = width;
surface->Base.Height = height;
@@ -281,6 +290,9 @@ display_surface(struct pipe_winsys *pws,
XImage *ximage;
void *data;
+ if (xsurf->Base.Type == EGL_PBUFFER_BIT)
+ return;
+
ximage = XCreateImage(xsurf->Dpy,
xsurf->VisInfo.visual,
xsurf->VisInfo.depth,
@@ -382,7 +394,7 @@ xlib_eglDestroyContext(_EGLDriver *drv, EGLDisplay dpy, EGLContext ctx)
struct xlib_egl_context *context = lookup_context(ctx);
if (context) {
_eglUnlinkContext(&context->Base);
- if (!context->Base.IsBound) {
+ if (!_eglIsContextBound(&context->Base)) {
/* API-dependent clean-up */
switch (context->Base.ClientAPI) {
case EGL_OPENGL_ES_API:
@@ -415,10 +427,14 @@ xlib_eglMakeCurrent(_EGLDriver *drv, EGLDisplay dpy,
struct xlib_egl_context *context = lookup_context(ctx);
struct xlib_egl_surface *draw_surf = lookup_surface(draw);
struct xlib_egl_surface *read_surf = lookup_surface(read);
+ struct st_context *oldctx = st_get_current();
if (!_eglMakeCurrent(drv, dpy, draw, read, context))
return EGL_FALSE;
+ /* Flush before switching context. Check client API? */
+ if (oldctx)
+ st_flush(oldctx, PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_FRAME, NULL);
st_make_current((context ? context->Context : NULL),
(draw_surf ? draw_surf->Framebuffer : NULL),
(read_surf ? read_surf->Framebuffer : NULL));
@@ -527,14 +543,92 @@ xlib_eglCreateWindowSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
}
+static EGLSurface
+xlib_eglCreatePbufferSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
+ const EGLint *attrib_list)
+{
+ struct xlib_egl_driver *xdrv = xlib_egl_driver(drv);
+ _EGLDisplay *disp = _eglLookupDisplay(dpy);
+ _EGLConfig *conf = _eglLookupConfig(drv, dpy, config);
+ struct xlib_egl_surface *surf;
+ __GLcontextModes visual;
+ uint width, height;
+ EGLBoolean bind_texture;
+
+ if (!disp) {
+ _eglError(EGL_BAD_DISPLAY, "eglCreatePbufferSurface");
+ return EGL_NO_SURFACE;
+ }
+ if (!conf) {
+ _eglError(EGL_BAD_CONFIG, "eglCreatePbufferSurface");
+ return EGL_NO_SURFACE;
+ }
+
+ surf = CALLOC_STRUCT(xlib_egl_surface);
+ if (!surf) {
+ _eglError(EGL_BAD_ALLOC, "eglCreatePbufferSurface");
+ return EGL_NO_SURFACE;
+ }
+
+ if (!_eglInitSurface(drv, &surf->Base, EGL_PBUFFER_BIT,
+ conf, attrib_list)) {
+ free(surf);
+ return EGL_NO_SURFACE;
+ }
+ if (surf->Base.Width < 0 || surf->Base.Height < 0) {
+ _eglError(EGL_BAD_PARAMETER, "eglCreatePbufferSurface");
+ free(surf);
+ return EGL_NO_SURFACE;
+ }
+
+ bind_texture = (surf->Base.TextureFormat != EGL_NO_TEXTURE);
+ width = (uint) surf->Base.Width;
+ height = (uint) surf->Base.Height;
+ if ((surf->Base.TextureTarget == EGL_NO_TEXTURE && bind_texture) ||
+ (surf->Base.TextureTarget != EGL_NO_TEXTURE && !bind_texture)) {
+ _eglError(EGL_BAD_MATCH, "eglCreatePbufferSurface");
+ free(surf);
+ return EGL_NO_SURFACE;
+ }
+ /* a framebuffer of zero width or height confuses st */
+ if (width == 0 || height == 0) {
+ _eglError(EGL_BAD_MATCH, "eglCreatePbufferSurface");
+ free(surf);
+ return EGL_NO_SURFACE;
+ }
+ /* no mipmap generation */
+ if (surf->Base.MipmapTexture) {
+ _eglError(EGL_BAD_MATCH, "eglCreatePbufferSurface");
+ free(surf);
+ return EGL_NO_SURFACE;
+ }
+
+ surf->winsys = xdrv->winsys;
+
+ _eglConfigToContextModesRec(conf, &visual);
+
+ /* Create GL statetracker framebuffer */
+ surf->Framebuffer = st_create_framebuffer(&visual,
+ choose_color_format(&visual),
+ choose_depth_format(&visual),
+ choose_stencil_format(&visual),
+ width, height,
+ (void *) surf);
+ st_resize_framebuffer(surf->Framebuffer, width, height);
+
+ return _eglLinkSurface(&surf->Base, disp);
+}
+
+
static EGLBoolean
xlib_eglDestroySurface(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface)
{
struct xlib_egl_surface *surf = lookup_surface(surface);
if (surf) {
_eglUnlinkSurface(&surf->Base);
- if (!surf->Base.IsBound) {
- XFreeGC(surf->Dpy, surf->Gc);
+ if (!_eglIsSurfaceBound(&surf->Base)) {
+ if (surf->Base.Type != EGL_PBUFFER_BIT)
+ XFreeGC(surf->Dpy, surf->Gc);
st_unreference_framebuffer(surf->Framebuffer);
free(surf);
}
@@ -548,6 +642,86 @@ xlib_eglDestroySurface(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface)
static EGLBoolean
+xlib_eglBindTexImage(_EGLDriver *drv, EGLDisplay dpy,
+ EGLSurface surface, EGLint buffer)
+{
+ struct xlib_egl_surface *xsurf = lookup_surface(surface);
+ struct xlib_egl_context *xctx;
+ struct pipe_surface *psurf;
+ enum pipe_format format;
+ int target;
+
+ if (!xsurf || xsurf->Base.Type != EGL_PBUFFER_BIT)
+ return _eglError(EGL_BAD_SURFACE, "eglBindTexImage");
+ if (buffer != EGL_BACK_BUFFER)
+ return _eglError(EGL_BAD_PARAMETER, "eglBindTexImage");
+ if (xsurf->Base.BoundToTexture)
+ return _eglError(EGL_BAD_ACCESS, "eglBindTexImage");
+
+ /* this should be updated when choose_color_format is */
+ switch (xsurf->Base.TextureFormat) {
+ case EGL_TEXTURE_RGB:
+ format = PIPE_FORMAT_R8G8B8_UNORM;
+ break;
+ case EGL_TEXTURE_RGBA:
+ format = PIPE_FORMAT_A8R8G8B8_UNORM;
+ break;
+ default:
+ return _eglError(EGL_BAD_MATCH, "eglBindTexImage");
+ }
+
+ switch (xsurf->Base.TextureTarget) {
+ case EGL_TEXTURE_2D:
+ target = ST_TEXTURE_2D;
+ break;
+ default:
+ return _eglError(EGL_BAD_MATCH, "eglBindTexImage");
+ }
+
+ /* flush properly */
+ if (eglGetCurrentSurface(EGL_DRAW) == surface) {
+ xctx = lookup_context(eglGetCurrentContext());
+ st_flush(xctx->Context, PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_FRAME,
+ NULL);
+ }
+ else if (_eglIsSurfaceBound(&xsurf->Base)) {
+ xctx = lookup_context(_eglGetContextHandle(xsurf->Base.Binding));
+ if (xctx)
+ st_finish(xctx->Context);
+ }
+
+ st_get_framebuffer_surface(xsurf->Framebuffer, ST_SURFACE_BACK_LEFT,
+ &psurf);
+ st_bind_texture_surface(psurf, target, xsurf->Base.MipmapLevel, format);
+ xsurf->Base.BoundToTexture = EGL_TRUE;
+
+ return EGL_TRUE;
+}
+
+
+static EGLBoolean
+xlib_eglReleaseTexImage(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface,
+ EGLint buffer)
+{
+ struct xlib_egl_surface *xsurf = lookup_surface(surface);
+ struct pipe_surface *psurf;
+
+ if (!xsurf || xsurf->Base.Type != EGL_PBUFFER_BIT ||
+ !xsurf->Base.BoundToTexture)
+ return _eglError(EGL_BAD_SURFACE, "eglReleaseTexImage");
+ if (buffer != EGL_BACK_BUFFER)
+ return _eglError(EGL_BAD_PARAMETER, "eglReleaseTexImage");
+
+ st_get_framebuffer_surface(xsurf->Framebuffer, ST_SURFACE_BACK_LEFT,
+ &psurf);
+ st_unbind_texture_surface(psurf, ST_TEXTURE_2D, xsurf->Base.MipmapLevel);
+ xsurf->Base.BoundToTexture = EGL_FALSE;
+
+ return EGL_TRUE;
+}
+
+
+static EGLBoolean
xlib_eglSwapBuffers(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw)
{
/* error checking step: */
@@ -631,7 +805,10 @@ _eglMain(_EGLDisplay *dpy, const char *args)
xdrv->Base.API.CreateContext = xlib_eglCreateContext;
xdrv->Base.API.DestroyContext = xlib_eglDestroyContext;
xdrv->Base.API.CreateWindowSurface = xlib_eglCreateWindowSurface;
+ xdrv->Base.API.CreatePbufferSurface = xlib_eglCreatePbufferSurface;
xdrv->Base.API.DestroySurface = xlib_eglDestroySurface;
+ xdrv->Base.API.BindTexImage = xlib_eglBindTexImage;
+ xdrv->Base.API.ReleaseTexImage = xlib_eglReleaseTexImage;
xdrv->Base.API.MakeCurrent = xlib_eglMakeCurrent;
xdrv->Base.API.SwapBuffers = xlib_eglSwapBuffers;
diff --git a/src/gallium/winsys/egl_xlib/sw_winsys.c b/src/gallium/winsys/egl_xlib/sw_winsys.c
index aa1bfa8e883..79ff2cc985d 100644
--- a/src/gallium/winsys/egl_xlib/sw_winsys.c
+++ b/src/gallium/winsys/egl_xlib/sw_winsys.c
@@ -166,6 +166,7 @@ surface_buffer_create(struct pipe_winsys *winsys,
unsigned width, unsigned height,
enum pipe_format format,
unsigned usage,
+ unsigned tex_usage,
unsigned *stride)
{
const unsigned alignment = 64;
diff --git a/src/gallium/winsys/xlib/xlib_brw_screen.c b/src/gallium/winsys/xlib/xlib_brw_screen.c
index fe8dfff7672..6f3861e2cd6 100644
--- a/src/gallium/winsys/xlib/xlib_brw_screen.c
+++ b/src/gallium/winsys/xlib/xlib_brw_screen.c
@@ -249,6 +249,7 @@ aub_i915_surface_buffer_create(struct pipe_winsys *winsys,
unsigned width, unsigned height,
enum pipe_format format,
unsigned usage,
+ unsigned tex_usage,
unsigned *stride)
{
const unsigned alignment = 64;
diff --git a/src/gallium/winsys/xlib/xlib_softpipe.c b/src/gallium/winsys/xlib/xlib_softpipe.c
index 44b8464518a..277e724d2ac 100644
--- a/src/gallium/winsys/xlib/xlib_softpipe.c
+++ b/src/gallium/winsys/xlib/xlib_softpipe.c
@@ -375,6 +375,7 @@ xm_surface_buffer_create(struct pipe_winsys *winsys,
unsigned width, unsigned height,
enum pipe_format format,
unsigned usage,
+ unsigned tex_usage,
unsigned *stride)
{
const unsigned alignment = 64;