summaryrefslogtreecommitdiffstats
path: root/src/mesa
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa')
-rw-r--r--src/mesa/drivers/dri/common/spantmp2.h122
-rw-r--r--src/mesa/drivers/dri/i915/i830_vtbl.c5
-rw-r--r--src/mesa/drivers/dri/i915/i915_fragprog.c10
-rw-r--r--src/mesa/drivers/dri/i915/i915_vtbl.c5
-rw-r--r--src/mesa/drivers/dri/i965/brw_defines.h4
-rw-r--r--src/mesa/drivers/dri/i965/brw_draw.c5
-rw-r--r--src/mesa/drivers/dri/i965/brw_eu.h3
-rw-r--r--src/mesa/drivers/dri/i965/brw_eu_emit.c16
-rw-r--r--src/mesa/drivers/dri/i965/brw_fs.cpp12
-rw-r--r--src/mesa/drivers/dri/i965/brw_state.h3
-rw-r--r--src/mesa/drivers/dri/i965/brw_state_batch.c4
-rw-r--r--src/mesa/drivers/dri/i965/brw_vs_emit.c18
-rw-r--r--src/mesa/drivers/dri/i965/brw_wm_emit.c97
-rw-r--r--src/mesa/drivers/dri/i965/brw_wm_surface_state.c168
-rw-r--r--src/mesa/drivers/dri/i965/gen6_vs_state.c1
-rw-r--r--src/mesa/drivers/dri/i965/gen6_wm_state.c3
-rw-r--r--src/mesa/drivers/dri/intel/intel_batchbuffer.c55
-rw-r--r--src/mesa/drivers/dri/intel/intel_batchbuffer.h21
-rw-r--r--src/mesa/drivers/dri/intel/intel_blit.c110
-rw-r--r--src/mesa/drivers/dri/intel/intel_blit.h2
-rw-r--r--src/mesa/drivers/dri/intel/intel_context.h2
-rw-r--r--src/mesa/drivers/dri/intel/intel_fbo.c168
-rw-r--r--src/mesa/drivers/dri/intel/intel_screen.c24
-rw-r--r--src/mesa/drivers/dri/intel/intel_span.c82
-rw-r--r--src/mesa/drivers/dri/intel/intel_span.h4
-rw-r--r--src/mesa/drivers/dri/intel/intel_tex.h1
-rw-r--r--src/mesa/drivers/dri/intel/intel_tex_copy.c72
-rw-r--r--src/mesa/drivers/dri/intel/intel_tex_format.c33
-rw-r--r--src/mesa/drivers/dri/nouveau/nouveau_driver.h2
-rw-r--r--src/mesa/drivers/dri/r300/compiler/radeon_dataflow_swizzles.c1
-rw-r--r--src/mesa/drivers/dri/r300/compiler/radeon_program_alu.c3
-rw-r--r--src/mesa/drivers/dri/r600/r700_assembler.c2
-rw-r--r--src/mesa/main/extensions.c6
-rw-r--r--src/mesa/main/formats.c1
-rw-r--r--src/mesa/main/queryobj.c39
-rw-r--r--src/mesa/program/ir_to_mesa.cpp8
-rw-r--r--src/mesa/program/ir_to_mesa.h7
-rw-r--r--src/mesa/program/nvfragparse.h5
-rw-r--r--src/mesa/program/nvvertparse.h5
-rw-r--r--src/mesa/program/prog_cache.h3
-rw-r--r--src/mesa/program/prog_execute.c12
-rw-r--r--src/mesa/program/prog_optimize.h3
-rw-r--r--src/mesa/program/prog_statevars.h4
-rw-r--r--src/mesa/state_tracker/st_atom_shader.c145
-rw-r--r--src/mesa/state_tracker/st_cb_accum.h6
-rw-r--r--src/mesa/state_tracker/st_cb_bitmap.c132
-rw-r--r--src/mesa/state_tracker/st_cb_bitmap.h8
-rw-r--r--src/mesa/state_tracker/st_cb_bufferobjects.c6
-rw-r--r--src/mesa/state_tracker/st_cb_drawpixels.c199
-rw-r--r--src/mesa/state_tracker/st_cb_drawpixels.h10
-rw-r--r--src/mesa/state_tracker/st_cb_drawtex.c2
-rw-r--r--src/mesa/state_tracker/st_cb_program.c112
-rw-r--r--src/mesa/state_tracker/st_cb_program.h5
-rw-r--r--src/mesa/state_tracker/st_cb_readpixels.h4
-rw-r--r--src/mesa/state_tracker/st_cb_texture.h3
-rw-r--r--src/mesa/state_tracker/st_context.c2
-rw-r--r--src/mesa/state_tracker/st_context.h7
-rw-r--r--src/mesa/state_tracker/st_debug.c4
-rw-r--r--src/mesa/state_tracker/st_draw.c12
-rw-r--r--src/mesa/state_tracker/st_draw.h3
-rw-r--r--src/mesa/state_tracker/st_draw_feedback.c16
-rw-r--r--src/mesa/state_tracker/st_extensions.c3
-rw-r--r--src/mesa/state_tracker/st_format.h3
-rw-r--r--src/mesa/state_tracker/st_program.c817
-rw-r--r--src/mesa/state_tracker/st_program.h139
-rw-r--r--src/mesa/tnl/t_vb_program.c32
66 files changed, 1702 insertions, 1119 deletions
diff --git a/src/mesa/drivers/dri/common/spantmp2.h b/src/mesa/drivers/dri/common/spantmp2.h
index abd79562f98..f436d1398c2 100644
--- a/src/mesa/drivers/dri/common/spantmp2.h
+++ b/src/mesa/drivers/dri/common/spantmp2.h
@@ -48,6 +48,15 @@
#define HW_WRITE_CLIPLOOP() HW_CLIPLOOP()
#endif
+#ifdef SPANTMP_MESA_FMT
+#define SPANTMP_PIXEL_FMT GL_NONE
+#define SPANTMP_PIXEL_TYPE GL_NONE
+#endif
+
+#ifndef SPANTMP_MESA_FMT
+#define SPANTMP_MESA_FMT MESA_FORMAT_COUNT
+#endif
+
#if (SPANTMP_PIXEL_FMT == GL_RGB) && (SPANTMP_PIXEL_TYPE == GL_UNSIGNED_SHORT_5_6_5)
/**
@@ -445,6 +454,118 @@
rgba[3] = p; \
} while (0)
+#elif (SPANTMP_MESA_FMT == MESA_FORMAT_R8)
+
+#ifndef GET_VALUE
+#ifndef GET_PTR
+#define GET_PTR(_x, _y) ( buf + (_x) + (_y) * pitch)
+#endif
+
+#define GET_VALUE(_x, _y) *(volatile GLubyte *)(GET_PTR(_x, _y))
+#define PUT_VALUE(_x, _y, _v) *(volatile GLubyte *)(GET_PTR(_x, _y)) = (_v)
+#endif /* GET_VALUE */
+
+# define INIT_MONO_PIXEL(p, color) \
+ p = color[0]
+
+# define WRITE_RGBA(_x, _y, r, g, b, a) \
+ PUT_VALUE(_x, _y, r)
+
+#define WRITE_PIXEL(_x, _y, p) PUT_VALUE(_x, _y, p)
+
+#define READ_RGBA( rgba, _x, _y ) \
+ do { \
+ GLubyte p = GET_VALUE(_x, _y); \
+ rgba[0] = p; \
+ rgba[1] = 0; \
+ rgba[2] = 0; \
+ rgba[3] = 0; \
+ } while (0)
+
+#elif (SPANTMP_MESA_FMT == MESA_FORMAT_RG88)
+
+#ifndef GET_VALUE
+#ifndef GET_PTR
+#define GET_PTR(_x, _y) ( buf + (_x) * 2 + (_y) * pitch)
+#endif
+
+#define GET_VALUE(_x, _y) *(volatile GLushort *)(GET_PTR(_x, _y))
+#define PUT_VALUE(_x, _y, _v) *(volatile GLushort *)(GET_PTR(_x, _y)) = (_v)
+#endif /* GET_VALUE */
+
+# define INIT_MONO_PIXEL(p, color) \
+ PACK_COLOR_8888(color[0], color[1], 0, 0)
+
+# define WRITE_RGBA(_x, _y, r, g, b, a) \
+ PUT_VALUE(_x, _y, r)
+
+#define WRITE_PIXEL(_x, _y, p) PUT_VALUE(_x, _y, p)
+
+#define READ_RGBA( rgba, _x, _y ) \
+ do { \
+ GLushort p = GET_VALUE(_x, _y); \
+ rgba[0] = p & 0xff; \
+ rgba[1] = (p >> 8) & 0xff; \
+ rgba[2] = 0; \
+ rgba[3] = 0; \
+ } while (0)
+
+#elif (SPANTMP_MESA_FMT == MESA_FORMAT_R16)
+
+#ifndef GET_VALUE
+#ifndef GET_PTR
+#define GET_PTR(_x, _y) ( buf + (_x) * 2 + (_y) * pitch)
+#endif
+
+#define GET_VALUE(_x, _y) *(volatile GLushort *)(GET_PTR(_x, _y))
+#define PUT_VALUE(_x, _y, _v) *(volatile GLushort *)(GET_PTR(_x, _y)) = (_v)
+#endif /* GET_VALUE */
+
+# define INIT_MONO_PIXEL(p, color) \
+ p = color[0]
+
+# define WRITE_RGBA(_x, _y, r, g, b, a) \
+ PUT_VALUE(_x, _y, r)
+
+#define WRITE_PIXEL(_x, _y, p) PUT_VALUE(_x, _y, p)
+
+#define READ_RGBA( rgba, _x, _y ) \
+ do { \
+ GLushort p = GET_VALUE(_x, _y); \
+ rgba[0] = p; \
+ rgba[1] = 0; \
+ rgba[2] = 0; \
+ rgba[3] = 0; \
+ } while (0)
+
+#elif (SPANTMP_MESA_FMT == MESA_FORMAT_RG1616)
+
+#ifndef GET_VALUE
+#ifndef GET_PTR
+#define GET_PTR(_x, _y) ( buf + (_x) * 4 + (_y) * pitch)
+#endif
+
+#define GET_VALUE(_x, _y) *(volatile GLuint *)(GET_PTR(_x, _y))
+#define PUT_VALUE(_x, _y, _v) *(volatile GLuint *)(GET_PTR(_x, _y)) = (_v)
+#endif /* GET_VALUE */
+
+# define INIT_MONO_PIXEL(p, color) \
+ ((color[1] << 16) | (color[0]))
+
+# define WRITE_RGBA(_x, _y, r, g, b, a) \
+ PUT_VALUE(_x, _y, r)
+
+#define WRITE_PIXEL(_x, _y, p) PUT_VALUE(_x, _y, p)
+
+#define READ_RGBA( rgba, _x, _y ) \
+ do { \
+ GLuint p = GET_VALUE(_x, _y); \
+ rgba[0] = p & 0xffff; \
+ rgba[1] = (p >> 16) & 0xffff; \
+ rgba[2] = 0; \
+ rgba[3] = 0; \
+ } while (0)
+
#else
#error SPANTMP_PIXEL_FMT must be set to a valid value!
#endif
@@ -914,3 +1035,4 @@ static void TAG(InitPointers)(struct gl_renderbuffer *rb)
#undef GET_PTR
#undef SPANTMP_PIXEL_FMT
#undef SPANTMP_PIXEL_TYPE
+#undef SPANTMP_MESA_FMT
diff --git a/src/mesa/drivers/dri/i915/i830_vtbl.c b/src/mesa/drivers/dri/i915/i830_vtbl.c
index f7fdb78d059..1621c9544ac 100644
--- a/src/mesa/drivers/dri/i915/i830_vtbl.c
+++ b/src/mesa/drivers/dri/i915/i830_vtbl.c
@@ -364,7 +364,7 @@ i830_emit_invarient_state(struct intel_context *intel)
#define emit( intel, state, size ) \
- intel_batchbuffer_data(intel->batch, state, size )
+ intel_batchbuffer_data(intel->batch, state, size, false)
static GLuint
get_dirty(struct i830_hw_state *state)
@@ -429,7 +429,8 @@ i830_emit_state(struct intel_context *intel)
* batchbuffer fills up.
*/
intel_batchbuffer_require_space(intel->batch,
- get_state_size(state) + INTEL_PRIM_EMIT_SIZE);
+ get_state_size(state) + INTEL_PRIM_EMIT_SIZE,
+ false);
count = 0;
again:
aper_count = 0;
diff --git a/src/mesa/drivers/dri/i915/i915_fragprog.c b/src/mesa/drivers/dri/i915/i915_fragprog.c
index 7a9fb7f088b..1c6e9845172 100644
--- a/src/mesa/drivers/dri/i915/i915_fragprog.c
+++ b/src/mesa/drivers/dri/i915/i915_fragprog.c
@@ -1162,11 +1162,6 @@ translate_program(struct i915_fragment_program *p)
fixup_depth_write(p);
i915_fini_program(p);
- if (INTEL_DEBUG & DEBUG_WM) {
- printf("i915:\n");
- i915_disassemble_program(i915->state.Program, i915->state.ProgramSize);
- }
-
p->translated = 1;
}
@@ -1427,6 +1422,11 @@ i915ValidateFragmentProgram(struct i915_context *i915)
if (!p->on_hardware)
i915_upload_program(i915, p);
+
+ if (INTEL_DEBUG & DEBUG_WM) {
+ printf("i915:\n");
+ i915_disassemble_program(i915->state.Program, i915->state.ProgramSize);
+ }
}
void
diff --git a/src/mesa/drivers/dri/i915/i915_vtbl.c b/src/mesa/drivers/dri/i915/i915_vtbl.c
index 59dfe085632..8d9020f5ef3 100644
--- a/src/mesa/drivers/dri/i915/i915_vtbl.c
+++ b/src/mesa/drivers/dri/i915/i915_vtbl.c
@@ -217,7 +217,7 @@ i915_emit_invarient_state(struct intel_context *intel)
#define emit(intel, state, size ) \
- intel_batchbuffer_data(intel->batch, state, size)
+ intel_batchbuffer_data(intel->batch, state, size, false)
static GLuint
get_dirty(struct i915_hw_state *state)
@@ -300,7 +300,8 @@ i915_emit_state(struct intel_context *intel)
* batchbuffer fills up.
*/
intel_batchbuffer_require_space(intel->batch,
- get_state_size(state) + INTEL_PRIM_EMIT_SIZE);
+ get_state_size(state) + INTEL_PRIM_EMIT_SIZE,
+ false);
count = 0;
again:
aper_count = 0;
diff --git a/src/mesa/drivers/dri/i965/brw_defines.h b/src/mesa/drivers/dri/i965/brw_defines.h
index 7f3e4986808..b48a30d6be9 100644
--- a/src/mesa/drivers/dri/i965/brw_defines.h
+++ b/src/mesa/drivers/dri/i965/brw_defines.h
@@ -906,6 +906,8 @@
# define GEN6_VS_VECTOR_MASK_ENABLE (1 << 30)
# define GEN6_VS_SAMPLER_COUNT_SHIFT 27
# define GEN6_VS_BINDING_TABLE_ENTRY_COUNT_SHIFT 18
+# define GEN6_VS_FLOATING_POINT_MODE_IEEE_754 (0 << 16)
+# define GEN6_VS_FLOATING_POINT_MODE_ALT (1 << 16)
/* DW4 */
# define GEN6_VS_DISPATCH_START_GRF_SHIFT 20
# define GEN6_VS_URB_READ_LENGTH_SHIFT 11
@@ -1048,6 +1050,8 @@
# define GEN6_WM_VECTOR_MASK_ENABLE (1 << 30)
# define GEN6_WM_SAMPLER_COUNT_SHIFT 27
# define GEN6_WM_BINDING_TABLE_ENTRY_COUNT_SHIFT 18
+# define GEN6_WM_FLOATING_POINT_MODE_IEEE_754 (0 << 16)
+# define GEN6_WM_FLOATING_POINT_MODE_ALT (1 << 16)
/* DW3: scratch space */
/* DW4 */
# define GEN6_WM_STATISTICS_ENABLE (1 << 31)
diff --git a/src/mesa/drivers/dri/i965/brw_draw.c b/src/mesa/drivers/dri/i965/brw_draw.c
index a1f403ca4e6..7eb16b71f4a 100644
--- a/src/mesa/drivers/dri/i965/brw_draw.c
+++ b/src/mesa/drivers/dri/i965/brw_draw.c
@@ -159,7 +159,7 @@ static void brw_emit_prim(struct brw_context *brw,
}
if (prim_packet.verts_per_instance) {
intel_batchbuffer_data( brw->intel.batch, &prim_packet,
- sizeof(prim_packet));
+ sizeof(prim_packet), false);
}
if (intel->always_flush_cache) {
intel_batchbuffer_emit_mi_flush(intel->batch);
@@ -351,7 +351,8 @@ static GLboolean brw_try_draw_prims( struct gl_context *ctx,
* an upper bound of how much we might emit in a single
* brw_try_draw_prims().
*/
- intel_batchbuffer_require_space(intel->batch, intel->batch->size / 4);
+ intel_batchbuffer_require_space(intel->batch, intel->batch->size / 4,
+ false);
hw_prim = brw_set_prim(brw, &prim[i]);
diff --git a/src/mesa/drivers/dri/i965/brw_eu.h b/src/mesa/drivers/dri/i965/brw_eu.h
index 4dbdc522100..119ffc72370 100644
--- a/src/mesa/drivers/dri/i965/brw_eu.h
+++ b/src/mesa/drivers/dri/i965/brw_eu.h
@@ -861,7 +861,8 @@ void brw_fb_WRITE(struct brw_compile *p,
GLuint binding_table_index,
GLuint msg_length,
GLuint response_length,
- GLboolean eot);
+ GLboolean eot,
+ GLboolean header_present);
void brw_SAMPLE(struct brw_compile *p,
struct brw_reg dest,
diff --git a/src/mesa/drivers/dri/i965/brw_eu_emit.c b/src/mesa/drivers/dri/i965/brw_eu_emit.c
index 9c764fe779d..6d48ca0e46d 100644
--- a/src/mesa/drivers/dri/i965/brw_eu_emit.c
+++ b/src/mesa/drivers/dri/i965/brw_eu_emit.c
@@ -1812,12 +1812,12 @@ void brw_fb_WRITE(struct brw_compile *p,
GLuint binding_table_index,
GLuint msg_length,
GLuint response_length,
- GLboolean eot)
+ GLboolean eot,
+ GLboolean header_present)
{
struct intel_context *intel = &p->brw->intel;
struct brw_instruction *insn;
GLuint msg_control, msg_type;
- GLboolean header_present = GL_TRUE;
if (intel->gen >= 6 && binding_table_index == 0) {
insn = next_insn(p, BRW_OPCODE_SENDC);
@@ -1829,9 +1829,6 @@ void brw_fb_WRITE(struct brw_compile *p,
insn->header.compression_control = BRW_COMPRESSION_NONE;
if (intel->gen >= 6) {
- if (msg_length == 4)
- header_present = GL_FALSE;
-
/* headerless version, just submit color payload */
src0 = brw_message_reg(msg_reg_nr);
@@ -1936,7 +1933,8 @@ void brw_SAMPLE(struct brw_compile *p,
brw_set_compression_control(p, BRW_COMPRESSION_NONE);
brw_set_mask_control(p, BRW_MASK_DISABLE);
- brw_MOV(p, m1, brw_vec8_grf(0,0));
+ brw_MOV(p, retype(m1, BRW_REGISTER_TYPE_UD),
+ retype(brw_vec8_grf(0,0), BRW_REGISTER_TYPE_UD));
brw_MOV(p, get_element_ud(m1, 2), brw_imm_ud(newmask << 12));
brw_pop_insn_state(p);
@@ -1997,7 +1995,8 @@ void brw_SAMPLE(struct brw_compile *p,
*/
brw_push_insn_state(p);
brw_set_compression_control(p, BRW_COMPRESSION_NONE);
- brw_MOV(p, reg, reg);
+ brw_MOV(p, retype(reg, BRW_REGISTER_TYPE_UD),
+ retype(reg, BRW_REGISTER_TYPE_UD));
brw_pop_insn_state(p);
}
@@ -2029,7 +2028,8 @@ void brw_urb_WRITE(struct brw_compile *p,
if (intel->gen >= 6) {
brw_push_insn_state(p);
brw_set_mask_control( p, BRW_MASK_DISABLE );
- brw_MOV(p, brw_message_reg(msg_reg_nr), src0);
+ brw_MOV(p, retype(brw_message_reg(msg_reg_nr), BRW_REGISTER_TYPE_UD),
+ retype(src0, BRW_REGISTER_TYPE_UD));
brw_pop_insn_state(p);
src0 = brw_message_reg(msg_reg_nr);
}
diff --git a/src/mesa/drivers/dri/i965/brw_fs.cpp b/src/mesa/drivers/dri/i965/brw_fs.cpp
index c3cbe0df618..2de81b28371 100644
--- a/src/mesa/drivers/dri/i965/brw_fs.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs.cpp
@@ -474,8 +474,13 @@ fs_visitor::emit_fragcoord_interpolation(ir_variable *ir)
wpos.reg_offset++;
/* gl_FragCoord.z */
- emit(fs_inst(FS_OPCODE_LINTERP, wpos, this->delta_x, this->delta_y,
- interp_reg(FRAG_ATTRIB_WPOS, 2)));
+ if (intel->gen >= 6) {
+ emit(fs_inst(BRW_OPCODE_MOV, wpos,
+ fs_reg(brw_vec8_grf(c->source_depth_reg, 0))));
+ } else {
+ emit(fs_inst(FS_OPCODE_LINTERP, wpos, this->delta_x, this->delta_y,
+ interp_reg(FRAG_ATTRIB_WPOS, 2)));
+ }
wpos.reg_offset++;
/* gl_FragCoord.w: Already set up in emit_interpolation */
@@ -2158,7 +2163,8 @@ fs_visitor::generate_fb_write(fs_inst *inst)
inst->target,
inst->mlen,
0,
- eot);
+ eot,
+ inst->header_present);
}
void
diff --git a/src/mesa/drivers/dri/i965/brw_state.h b/src/mesa/drivers/dri/i965/brw_state.h
index 3beed16945b..4bb93e73369 100644
--- a/src/mesa/drivers/dri/i965/brw_state.h
+++ b/src/mesa/drivers/dri/i965/brw_state.h
@@ -164,7 +164,8 @@ void brw_destroy_caches( struct brw_context *brw );
/***********************************************************************
* brw_state_batch.c
*/
-#define BRW_BATCH_STRUCT(brw, s) intel_batchbuffer_data( brw->intel.batch, (s), sizeof(*(s)))
+#define BRW_BATCH_STRUCT(brw, s) intel_batchbuffer_data(brw->intel.batch, (s), \
+ sizeof(*(s)), false)
#define BRW_CACHED_BATCH_STRUCT(brw, s) brw_cached_batch_struct( brw, (s), sizeof(*(s)) )
GLboolean brw_cached_batch_struct( struct brw_context *brw,
diff --git a/src/mesa/drivers/dri/i965/brw_state_batch.c b/src/mesa/drivers/dri/i965/brw_state_batch.c
index be3989eb7db..a21af13caa3 100644
--- a/src/mesa/drivers/dri/i965/brw_state_batch.c
+++ b/src/mesa/drivers/dri/i965/brw_state_batch.c
@@ -48,7 +48,7 @@ GLboolean brw_cached_batch_struct( struct brw_context *brw,
struct header *newheader = (struct header *)data;
if (brw->emit_state_always) {
- intel_batchbuffer_data(brw->intel.batch, data, sz);
+ intel_batchbuffer_data(brw->intel.batch, data, sz, false);
return GL_TRUE;
}
@@ -75,7 +75,7 @@ GLboolean brw_cached_batch_struct( struct brw_context *brw,
emit:
memcpy(item->header, newheader, sz);
- intel_batchbuffer_data(brw->intel.batch, data, sz);
+ intel_batchbuffer_data(brw->intel.batch, data, sz, false);
return GL_TRUE;
}
diff --git a/src/mesa/drivers/dri/i965/brw_vs_emit.c b/src/mesa/drivers/dri/i965/brw_vs_emit.c
index 09887dae95d..326bb1e562f 100644
--- a/src/mesa/drivers/dri/i965/brw_vs_emit.c
+++ b/src/mesa/drivers/dri/i965/brw_vs_emit.c
@@ -658,6 +658,22 @@ static void emit_min( struct brw_compile *p,
}
}
+static void emit_arl(struct brw_compile *p,
+ struct brw_reg dst,
+ struct brw_reg src)
+{
+ struct intel_context *intel = &p->brw->intel;
+
+ if (intel->gen >= 6) {
+ struct brw_reg dst_f = retype(dst, BRW_REGISTER_TYPE_F);
+
+ brw_RNDD(p, dst_f, src);
+ brw_MOV(p, dst, dst_f);
+ } else {
+ brw_RNDD(p, dst, src);
+ }
+}
+
static void emit_math1_gen4(struct brw_vs_compile *c,
GLuint function,
struct brw_reg dst,
@@ -1963,7 +1979,7 @@ void brw_vs_emit(struct brw_vs_compile *c )
emit_math1(c, BRW_MATH_FUNCTION_EXP, dst, args[0], BRW_MATH_PRECISION_FULL);
break;
case OPCODE_ARL:
- brw_RNDD(p, dst, args[0]);
+ emit_arl(p, dst, args[0]);
break;
case OPCODE_FLR:
brw_RNDD(p, dst, args[0]);
diff --git a/src/mesa/drivers/dri/i965/brw_wm_emit.c b/src/mesa/drivers/dri/i965/brw_wm_emit.c
index a0e86034e1e..56725c0d471 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_emit.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_emit.c
@@ -219,43 +219,45 @@ void emit_wpos_xy(struct brw_wm_compile *c,
const struct brw_reg *arg0)
{
struct brw_compile *p = &c->func;
+ struct intel_context *intel = &p->brw->intel;
+ struct brw_reg delta_x = retype(arg0[0], BRW_REGISTER_TYPE_W);
+ struct brw_reg delta_y = retype(arg0[1], BRW_REGISTER_TYPE_W);
if (mask & WRITEMASK_X) {
+ if (intel->gen >= 6) {
+ struct brw_reg delta_x_f = retype(delta_x, BRW_REGISTER_TYPE_F);
+ brw_MOV(p, delta_x_f, delta_x);
+ delta_x = delta_x_f;
+ }
+
if (c->fp->program.PixelCenterInteger) {
/* X' = X */
- brw_MOV(p,
- dst[0],
- retype(arg0[0], BRW_REGISTER_TYPE_W));
+ brw_MOV(p, dst[0], delta_x);
} else {
/* X' = X + 0.5 */
- brw_ADD(p,
- dst[0],
- retype(arg0[0], BRW_REGISTER_TYPE_W),
- brw_imm_f(0.5));
+ brw_ADD(p, dst[0], delta_x, brw_imm_f(0.5));
}
}
if (mask & WRITEMASK_Y) {
+ if (intel->gen >= 6) {
+ struct brw_reg delta_y_f = retype(delta_y, BRW_REGISTER_TYPE_F);
+ brw_MOV(p, delta_y_f, delta_y);
+ delta_y = delta_y_f;
+ }
+
if (c->fp->program.OriginUpperLeft) {
if (c->fp->program.PixelCenterInteger) {
/* Y' = Y */
- brw_MOV(p,
- dst[1],
- retype(arg0[1], BRW_REGISTER_TYPE_W));
+ brw_MOV(p, dst[1], delta_y);
} else {
- /* Y' = Y + 0.5 */
- brw_ADD(p,
- dst[1],
- retype(arg0[1], BRW_REGISTER_TYPE_W),
- brw_imm_f(0.5));
+ brw_ADD(p, dst[1], delta_y, brw_imm_f(0.5));
}
} else {
float center_offset = c->fp->program.PixelCenterInteger ? 0.0 : 0.5;
/* Y' = (height - 1) - Y + center */
- brw_ADD(p,
- dst[1],
- negate(retype(arg0[1], BRW_REGISTER_TYPE_W)),
+ brw_ADD(p, dst[1], negate(delta_y),
brw_imm_f(c->key.drawable_height - 1 + center_offset));
}
}
@@ -971,34 +973,23 @@ void emit_math2(struct brw_wm_compile *c,
struct brw_reg temp_dst = dst[dst_chan];
if (arg0[0].hstride == BRW_HORIZONTAL_STRIDE_0) {
- if (arg1[0].hstride == BRW_HORIZONTAL_STRIDE_0) {
- /* Both scalar arguments. Do scalar calc. */
- src0.hstride = BRW_HORIZONTAL_STRIDE_1;
- src1.hstride = BRW_HORIZONTAL_STRIDE_1;
- temp_dst.hstride = BRW_HORIZONTAL_STRIDE_1;
- temp_dst.width = BRW_WIDTH_1;
-
- if (arg0[0].subnr != 0) {
- brw_MOV(p, temp_dst, src0);
- src0 = temp_dst;
-
- /* Ouch. We've used the temp as a dst, and we still
- * need a temp to store arg1 in, because src and dst
- * offsets have to be equal. Leaving this up to
- * glsl2-965 to handle correctly.
- */
- assert(arg1[0].subnr == 0);
- } else if (arg1[0].subnr != 0) {
- brw_MOV(p, temp_dst, src1);
- src1 = temp_dst;
- }
- } else {
- brw_MOV(p, temp_dst, src0);
- src0 = temp_dst;
- }
- } else if (arg1[0].hstride == BRW_HORIZONTAL_STRIDE_0) {
- brw_MOV(p, temp_dst, src1);
- src1 = temp_dst;
+ brw_MOV(p, temp_dst, src0);
+ src0 = temp_dst;
+ }
+
+ if (arg1[0].hstride == BRW_HORIZONTAL_STRIDE_0) {
+ /* This is a heinous hack to get a temporary register for use
+ * in case both arg0 and arg1 are constants. Why you're
+ * doing exponentiation on constant values in the shader, we
+ * don't know.
+ *
+ * max_wm_grf is almost surely less than the maximum GRF, and
+ * gen6 doesn't care about the number of GRFs used in a
+ * shader like pre-gen6 did.
+ */
+ struct brw_reg temp = brw_vec8_grf(c->max_wm_grf, 0);
+ brw_MOV(p, temp, src1);
+ src1 = temp;
}
brw_set_saturate(p, (mask & SATURATE) ? 1 : 0);
@@ -1016,14 +1007,6 @@ void emit_math2(struct brw_wm_compile *c,
sechalf(src0),
sechalf(src1));
}
-
- /* Splat a scalar result into all the channels. */
- if (arg0[0].hstride == BRW_HORIZONTAL_STRIDE_0 &&
- arg1[0].hstride == BRW_HORIZONTAL_STRIDE_0) {
- temp_dst.hstride = BRW_HORIZONTAL_STRIDE_0;
- temp_dst.vstride = BRW_VERTICAL_STRIDE_0;
- brw_MOV(p, dst[dst_chan], temp_dst);
- }
} else {
GLuint saturate = ((mask & SATURATE) ?
BRW_MATH_SATURATE_SATURATE :
@@ -1373,7 +1356,8 @@ static void fire_fb_write( struct brw_wm_compile *c,
target,
nr,
0,
- eot);
+ eot,
+ GL_TRUE);
}
@@ -1518,7 +1502,8 @@ void emit_fb_write(struct brw_wm_compile *c,
*/
brw_push_insn_state(p);
brw_set_mask_control(p, BRW_MASK_DISABLE);
- brw_MOV(p, brw_message_reg(0), brw_vec8_grf(0, 0));
+ brw_MOV(p, retype(brw_message_reg(0), BRW_REGISTER_TYPE_UD),
+ retype(brw_vec8_grf(0, 0), BRW_REGISTER_TYPE_UD));
brw_pop_insn_state(p);
if (target != 0) {
diff --git a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c
index ad744044c70..1cd736a1119 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c
@@ -68,71 +68,43 @@ static GLuint translate_tex_target( GLenum target )
}
}
+static uint32_t brw_format_for_mesa_format[MESA_FORMAT_COUNT] =
+{
+ [MESA_FORMAT_L8] = BRW_SURFACEFORMAT_L8_UNORM,
+ [MESA_FORMAT_I8] = BRW_SURFACEFORMAT_I8_UNORM,
+ [MESA_FORMAT_A8] = BRW_SURFACEFORMAT_A8_UNORM,
+ [MESA_FORMAT_AL88] = BRW_SURFACEFORMAT_L8A8_UNORM,
+ [MESA_FORMAT_AL1616] = BRW_SURFACEFORMAT_L16A16_UNORM,
+ [MESA_FORMAT_R8] = BRW_SURFACEFORMAT_R8_UNORM,
+ [MESA_FORMAT_R16] = BRW_SURFACEFORMAT_R16_UNORM,
+ [MESA_FORMAT_RG88] = BRW_SURFACEFORMAT_R8G8_UNORM,
+ [MESA_FORMAT_RG1616] = BRW_SURFACEFORMAT_R16G16_UNORM,
+ [MESA_FORMAT_ARGB8888] = BRW_SURFACEFORMAT_B8G8R8A8_UNORM,
+ [MESA_FORMAT_XRGB8888] = BRW_SURFACEFORMAT_B8G8R8X8_UNORM,
+ [MESA_FORMAT_RGB565] = BRW_SURFACEFORMAT_B5G6R5_UNORM,
+ [MESA_FORMAT_ARGB1555] = BRW_SURFACEFORMAT_B5G5R5A1_UNORM,
+ [MESA_FORMAT_ARGB4444] = BRW_SURFACEFORMAT_B4G4R4A4_UNORM,
+ [MESA_FORMAT_YCBCR_REV] = BRW_SURFACEFORMAT_YCRCB_NORMAL,
+ [MESA_FORMAT_YCBCR] = BRW_SURFACEFORMAT_YCRCB_SWAPUVY,
+ [MESA_FORMAT_RGB_FXT1] = BRW_SURFACEFORMAT_FXT1,
+ [MESA_FORMAT_RGBA_FXT1] = BRW_SURFACEFORMAT_FXT1,
+ [MESA_FORMAT_RGB_DXT1] = BRW_SURFACEFORMAT_DXT1_RGB,
+ [MESA_FORMAT_RGBA_DXT1] = BRW_SURFACEFORMAT_BC1_UNORM,
+ [MESA_FORMAT_RGBA_DXT3] = BRW_SURFACEFORMAT_BC2_UNORM,
+ [MESA_FORMAT_RGBA_DXT5] = BRW_SURFACEFORMAT_BC3_UNORM,
+ [MESA_FORMAT_SRGB_DXT1] = BRW_SURFACEFORMAT_BC1_UNORM_SRGB,
+ [MESA_FORMAT_SARGB8] = BRW_SURFACEFORMAT_B8G8R8A8_UNORM_SRGB,
+ [MESA_FORMAT_SLA8] = BRW_SURFACEFORMAT_L8A8_UNORM_SRGB,
+ [MESA_FORMAT_SL8] = BRW_SURFACEFORMAT_L8_UNORM_SRGB,
+ [MESA_FORMAT_DUDV8] = BRW_SURFACEFORMAT_R8G8_SNORM,
+ [MESA_FORMAT_SIGNED_RGBA8888_REV] = BRW_SURFACEFORMAT_R8G8B8A8_SNORM,
+};
static GLuint translate_tex_format( gl_format mesa_format,
GLenum internal_format,
GLenum depth_mode )
{
switch( mesa_format ) {
- case MESA_FORMAT_L8:
- return BRW_SURFACEFORMAT_L8_UNORM;
-
- case MESA_FORMAT_I8:
- return BRW_SURFACEFORMAT_I8_UNORM;
-
- case MESA_FORMAT_A8:
- return BRW_SURFACEFORMAT_A8_UNORM;
-
- case MESA_FORMAT_AL88:
- return BRW_SURFACEFORMAT_L8A8_UNORM;
-
- case MESA_FORMAT_AL1616:
- return BRW_SURFACEFORMAT_L16A16_UNORM;
-
- case MESA_FORMAT_R8:
- return BRW_SURFACEFORMAT_R8_UNORM;
-
- case MESA_FORMAT_R16:
- return BRW_SURFACEFORMAT_R16_UNORM;
-
- case MESA_FORMAT_RG88:
- return BRW_SURFACEFORMAT_R8G8_UNORM;
-
- case MESA_FORMAT_RG1616:
- return BRW_SURFACEFORMAT_R16G16_UNORM;
-
- case MESA_FORMAT_RGB888:
- assert(0); /* not supported for sampling */
- return BRW_SURFACEFORMAT_R8G8B8_UNORM;
-
- case MESA_FORMAT_ARGB8888:
- return BRW_SURFACEFORMAT_B8G8R8A8_UNORM;
-
- case MESA_FORMAT_XRGB8888:
- return BRW_SURFACEFORMAT_B8G8R8X8_UNORM;
-
- case MESA_FORMAT_RGBA8888_REV:
- _mesa_problem(NULL, "unexpected format in i965:translate_tex_format()");
- return BRW_SURFACEFORMAT_R8G8B8A8_UNORM;
-
- case MESA_FORMAT_RGB565:
- return BRW_SURFACEFORMAT_B5G6R5_UNORM;
-
- case MESA_FORMAT_ARGB1555:
- return BRW_SURFACEFORMAT_B5G5R5A1_UNORM;
-
- case MESA_FORMAT_ARGB4444:
- return BRW_SURFACEFORMAT_B4G4R4A4_UNORM;
-
- case MESA_FORMAT_YCBCR_REV:
- return BRW_SURFACEFORMAT_YCRCB_NORMAL;
-
- case MESA_FORMAT_YCBCR:
- return BRW_SURFACEFORMAT_YCRCB_SWAPUVY;
-
- case MESA_FORMAT_RGB_FXT1:
- case MESA_FORMAT_RGBA_FXT1:
- return BRW_SURFACEFORMAT_FXT1;
case MESA_FORMAT_Z16:
if (depth_mode == GL_INTENSITY)
@@ -144,30 +116,6 @@ static GLuint translate_tex_format( gl_format mesa_format,
else
return BRW_SURFACEFORMAT_L16_UNORM;
- case MESA_FORMAT_RGB_DXT1:
- return BRW_SURFACEFORMAT_DXT1_RGB;
-
- case MESA_FORMAT_RGBA_DXT1:
- return BRW_SURFACEFORMAT_BC1_UNORM;
-
- case MESA_FORMAT_RGBA_DXT3:
- return BRW_SURFACEFORMAT_BC2_UNORM;
-
- case MESA_FORMAT_RGBA_DXT5:
- return BRW_SURFACEFORMAT_BC3_UNORM;
-
- case MESA_FORMAT_SARGB8:
- return BRW_SURFACEFORMAT_B8G8R8A8_UNORM_SRGB;
-
- case MESA_FORMAT_SLA8:
- return BRW_SURFACEFORMAT_L8A8_UNORM_SRGB;
-
- case MESA_FORMAT_SL8:
- return BRW_SURFACEFORMAT_L8_UNORM_SRGB;
-
- case MESA_FORMAT_SRGB_DXT1:
- return BRW_SURFACEFORMAT_BC1_UNORM_SRGB;
-
case MESA_FORMAT_S8_Z24:
/* XXX: these different surface formats don't seem to
* make any difference for shadow sampler/compares.
@@ -181,15 +129,9 @@ static GLuint translate_tex_format( gl_format mesa_format,
else
return BRW_SURFACEFORMAT_L24X8_UNORM;
- case MESA_FORMAT_DUDV8:
- return BRW_SURFACEFORMAT_R8G8_SNORM;
-
- case MESA_FORMAT_SIGNED_RGBA8888_REV:
- return BRW_SURFACEFORMAT_R8G8B8A8_SNORM;
-
default:
- assert(0);
- return 0;
+ assert(brw_format_for_mesa_format[mesa_format] != 0);
+ return brw_format_for_mesa_format[mesa_format];
}
}
@@ -448,45 +390,19 @@ brw_update_renderbuffer_surface(struct brw_context *brw,
key.surface_type = BRW_SURFACE_2D;
switch (irb->Base.Format) {
- /* XRGB and ARGB are treated the same here because the chips in this
- * family cannot render to XRGB targets. This means that we have to
- * mask writes to alpha (ala glColorMask) and reconfigure the alpha
- * blending hardware to use GL_ONE (or GL_ZERO) for cases where
- * GL_DST_ALPHA (or GL_ONE_MINUS_DST_ALPHA) is used.
- */
- case MESA_FORMAT_ARGB8888:
case MESA_FORMAT_XRGB8888:
+ /* XRGB is handled as ARGB because the chips in this family
+ * cannot render to XRGB targets. This means that we have to
+ * mask writes to alpha (ala glColorMask) and reconfigure the
+ * alpha blending hardware to use GL_ONE (or GL_ZERO) for
+ * cases where GL_DST_ALPHA (or GL_ONE_MINUS_DST_ALPHA) is
+ * used.
+ */
key.surface_format = BRW_SURFACEFORMAT_B8G8R8A8_UNORM;
break;
- case MESA_FORMAT_SARGB8:
- key.surface_format = BRW_SURFACEFORMAT_B8G8R8A8_UNORM_SRGB;
- break;
- case MESA_FORMAT_RGB565:
- key.surface_format = BRW_SURFACEFORMAT_B5G6R5_UNORM;
- break;
- case MESA_FORMAT_ARGB1555:
- key.surface_format = BRW_SURFACEFORMAT_B5G5R5A1_UNORM;
- break;
- case MESA_FORMAT_ARGB4444:
- key.surface_format = BRW_SURFACEFORMAT_B4G4R4A4_UNORM;
- break;
- case MESA_FORMAT_A8:
- key.surface_format = BRW_SURFACEFORMAT_A8_UNORM;
- break;
- case MESA_FORMAT_R8:
- key.surface_format = BRW_SURFACEFORMAT_R8_UNORM;
- break;
- case MESA_FORMAT_R16:
- key.surface_format = BRW_SURFACEFORMAT_R16_UNORM;
- break;
- case MESA_FORMAT_RG88:
- key.surface_format = BRW_SURFACEFORMAT_R8G8_UNORM;
- break;
- case MESA_FORMAT_RG1616:
- key.surface_format = BRW_SURFACEFORMAT_R16G16_UNORM;
- break;
default:
- _mesa_problem(ctx, "Bad renderbuffer format: %d\n", irb->Base.Format);
+ key.surface_format = brw_format_for_mesa_format[irb->Base.Format];
+ assert(key.surface_format != 0);
}
key.tiling = region->tiling;
key.width = rb->Width;
diff --git a/src/mesa/drivers/dri/i965/gen6_vs_state.c b/src/mesa/drivers/dri/i965/gen6_vs_state.c
index 4ef9e2e6072..ed132bdbd93 100644
--- a/src/mesa/drivers/dri/i965/gen6_vs_state.c
+++ b/src/mesa/drivers/dri/i965/gen6_vs_state.c
@@ -130,6 +130,7 @@ upload_vs_state(struct brw_context *brw)
OUT_BATCH(CMD_3D_VS_STATE << 16 | (6 - 2));
OUT_RELOC(brw->vs.prog_bo, I915_GEM_DOMAIN_INSTRUCTION, 0, 0);
OUT_BATCH((0 << GEN6_VS_SAMPLER_COUNT_SHIFT) |
+ GEN6_VS_FLOATING_POINT_MODE_ALT |
(brw->vs.nr_surfaces << GEN6_VS_BINDING_TABLE_ENTRY_COUNT_SHIFT));
OUT_BATCH(0); /* scratch space base offset */
OUT_BATCH((1 << GEN6_VS_DISPATCH_START_GRF_SHIFT) |
diff --git a/src/mesa/drivers/dri/i965/gen6_wm_state.c b/src/mesa/drivers/dri/i965/gen6_wm_state.c
index d80df4e254b..2ae0c093ebe 100644
--- a/src/mesa/drivers/dri/i965/gen6_wm_state.c
+++ b/src/mesa/drivers/dri/i965/gen6_wm_state.c
@@ -133,6 +133,9 @@ upload_wm_state(struct brw_context *brw)
dw5 |= GEN6_WM_LINE_AA_WIDTH_1_0;
dw5 |= GEN6_WM_LINE_END_CAP_AA_WIDTH_0_5;
+ /* OpenGL non-ieee floating point mode */
+ dw2 |= GEN6_WM_FLOATING_POINT_MODE_ALT;
+
/* BRW_NEW_NR_WM_SURFACES */
dw2 |= brw->wm.nr_surfaces << GEN6_WM_BINDING_TABLE_ENTRY_COUNT_SHIFT;
diff --git a/src/mesa/drivers/dri/intel/intel_batchbuffer.c b/src/mesa/drivers/dri/intel/intel_batchbuffer.c
index 21fc9ece886..20574ab5462 100644
--- a/src/mesa/drivers/dri/intel/intel_batchbuffer.c
+++ b/src/mesa/drivers/dri/intel/intel_batchbuffer.c
@@ -93,8 +93,16 @@ do_flush_locked(struct intel_batchbuffer *batch, GLuint used)
batch->ptr = NULL;
if (!intel->intelScreen->no_hw) {
- drm_intel_bo_exec(batch->buf, used, NULL, 0,
- (x_off & 0xffff) | (y_off << 16));
+ int ring;
+
+ if (intel->gen < 6 || !intel->batch->is_blit) {
+ ring = I915_EXEC_RENDER;
+ } else {
+ ring = I915_EXEC_BLT;
+ }
+
+ drm_intel_bo_mrb_exec(batch->buf, used, NULL, 0,
+ (x_off & 0xffff) | (y_off << 16), ring);
}
if (unlikely(INTEL_DEBUG & DEBUG_BATCH)) {
@@ -242,10 +250,10 @@ intel_batchbuffer_emit_reloc_fenced(struct intel_batchbuffer *batch,
void
intel_batchbuffer_data(struct intel_batchbuffer *batch,
- const void *data, GLuint bytes)
+ const void *data, GLuint bytes, bool is_blit)
{
assert((bytes & 3) == 0);
- intel_batchbuffer_require_space(batch, bytes);
+ intel_batchbuffer_require_space(batch, bytes, is_blit);
__memcpy(batch->ptr, data, bytes);
batch->ptr += bytes;
}
@@ -262,22 +270,29 @@ intel_batchbuffer_emit_mi_flush(struct intel_batchbuffer *batch)
struct intel_context *intel = batch->intel;
if (intel->gen >= 6) {
- BEGIN_BATCH(8);
-
- /* XXX workaround: issue any post sync != 0 before write cache flush = 1 */
- OUT_BATCH(_3DSTATE_PIPE_CONTROL);
- OUT_BATCH(PIPE_CONTROL_WRITE_IMMEDIATE);
- OUT_BATCH(0); /* write address */
- OUT_BATCH(0); /* write data */
-
- OUT_BATCH(_3DSTATE_PIPE_CONTROL);
- OUT_BATCH(PIPE_CONTROL_INSTRUCTION_FLUSH |
- PIPE_CONTROL_WRITE_FLUSH |
- PIPE_CONTROL_DEPTH_CACHE_FLUSH |
- PIPE_CONTROL_NO_WRITE);
- OUT_BATCH(0); /* write address */
- OUT_BATCH(0); /* write data */
- ADVANCE_BATCH();
+ if (intel->batch->is_blit) {
+ BEGIN_BATCH_BLT(1);
+ OUT_BATCH(MI_FLUSH);
+ ADVANCE_BATCH();
+ } else {
+ BEGIN_BATCH(8);
+ /* XXX workaround: issue any post sync != 0 before write
+ * cache flush = 1
+ */
+ OUT_BATCH(_3DSTATE_PIPE_CONTROL);
+ OUT_BATCH(PIPE_CONTROL_WRITE_IMMEDIATE);
+ OUT_BATCH(0); /* write address */
+ OUT_BATCH(0); /* write data */
+
+ OUT_BATCH(_3DSTATE_PIPE_CONTROL);
+ OUT_BATCH(PIPE_CONTROL_INSTRUCTION_FLUSH |
+ PIPE_CONTROL_WRITE_FLUSH |
+ PIPE_CONTROL_DEPTH_CACHE_FLUSH |
+ PIPE_CONTROL_NO_WRITE);
+ OUT_BATCH(0); /* write address */
+ OUT_BATCH(0); /* write data */
+ ADVANCE_BATCH();
+ }
} else if (intel->gen >= 4) {
BEGIN_BATCH(4);
OUT_BATCH(_3DSTATE_PIPE_CONTROL |
diff --git a/src/mesa/drivers/dri/intel/intel_batchbuffer.h b/src/mesa/drivers/dri/intel/intel_batchbuffer.h
index 428c027c2f1..635708587a6 100644
--- a/src/mesa/drivers/dri/intel/intel_batchbuffer.h
+++ b/src/mesa/drivers/dri/intel/intel_batchbuffer.h
@@ -31,6 +31,7 @@ struct intel_batchbuffer
} emit;
#endif
+ bool is_blit;
GLuint dirty_state;
GLuint reserved_space;
};
@@ -55,7 +56,7 @@ void intel_batchbuffer_reset(struct intel_batchbuffer *batch);
* intel_buffer_dword() calls.
*/
void intel_batchbuffer_data(struct intel_batchbuffer *batch,
- const void *data, GLuint bytes);
+ const void *data, GLuint bytes, bool is_blit);
void intel_batchbuffer_release_space(struct intel_batchbuffer *batch,
GLuint bytes);
@@ -114,8 +115,16 @@ intel_batchbuffer_emit_float(struct intel_batchbuffer *batch, float f)
static INLINE void
intel_batchbuffer_require_space(struct intel_batchbuffer *batch,
- GLuint sz)
+ GLuint sz, int is_blit)
{
+
+ if (batch->intel->gen >= 6 && batch->is_blit != is_blit &&
+ batch->ptr != batch->map) {
+ intel_batchbuffer_flush(batch);
+ }
+
+ batch->is_blit = is_blit;
+
#ifdef DEBUG
assert(sz < batch->size - 8);
#endif
@@ -124,9 +133,10 @@ intel_batchbuffer_require_space(struct intel_batchbuffer *batch,
}
static INLINE void
-intel_batchbuffer_begin(struct intel_batchbuffer *batch, int n)
+intel_batchbuffer_begin(struct intel_batchbuffer *batch, int n, bool is_blit)
{
- intel_batchbuffer_require_space(batch, n * 4);
+ intel_batchbuffer_require_space(batch, n * 4, is_blit);
+
#ifdef DEBUG
assert(batch->map);
assert(batch->emit.start_ptr == NULL);
@@ -154,7 +164,8 @@ intel_batchbuffer_advance(struct intel_batchbuffer *batch)
*/
#define BATCH_LOCALS
-#define BEGIN_BATCH(n) intel_batchbuffer_begin(intel->batch, n)
+#define BEGIN_BATCH(n) intel_batchbuffer_begin(intel->batch, n, false)
+#define BEGIN_BATCH_BLT(n) intel_batchbuffer_begin(intel->batch, n, true)
#define OUT_BATCH(d) intel_batchbuffer_emit_dword(intel->batch, d)
#define OUT_BATCH_F(f) intel_batchbuffer_emit_float(intel->batch,f)
#define OUT_RELOC(buf, read_domains, write_domain, delta) do { \
diff --git a/src/mesa/drivers/dri/intel/intel_blit.c b/src/mesa/drivers/dri/intel/intel_blit.c
index c2917e9b07e..a2822b11d96 100644
--- a/src/mesa/drivers/dri/intel/intel_blit.c
+++ b/src/mesa/drivers/dri/intel/intel_blit.c
@@ -38,6 +38,8 @@
#include "intel_reg.h"
#include "intel_regions.h"
#include "intel_batchbuffer.h"
+#include "intel_tex.h"
+#include "intel_mipmap_tree.h"
#define FILE_DEBUG_FLAG DEBUG_BLIT
@@ -107,10 +109,6 @@ intelEmitCopyBlit(struct intel_context *intel,
drm_intel_bo *aper_array[3];
BATCH_LOCALS;
- /* Blits are in a different ringbuffer so we don't use them. */
- if (intel->gen >= 6)
- return GL_FALSE;
-
if (dst_tiling != I915_TILING_NONE) {
if (dst_offset & 4095)
return GL_FALSE;
@@ -140,7 +138,7 @@ intelEmitCopyBlit(struct intel_context *intel,
if (pass >= 2)
return GL_FALSE;
- intel_batchbuffer_require_space(intel->batch, 8 * 4);
+ intel_batchbuffer_require_space(intel->batch, 8 * 4, true);
DBG("%s src:buf(%p)/%d+%d %d,%d dst:buf(%p)/%d+%d %d,%d sz:%dx%d\n",
__FUNCTION__,
src_buffer, src_pitch, src_offset, src_x, src_y,
@@ -181,7 +179,7 @@ intelEmitCopyBlit(struct intel_context *intel,
assert(dst_x < dst_x2);
assert(dst_y < dst_y2);
- BEGIN_BATCH(8);
+ BEGIN_BATCH_BLT(8);
OUT_BATCH(CMD);
OUT_BATCH(BR13 | (uint16_t)dst_pitch);
OUT_BATCH((dst_y << 16) | dst_x);
@@ -219,9 +217,6 @@ intelClearWithBlit(struct gl_context *ctx, GLbitfield mask)
GLint cx, cy, cw, ch;
BATCH_LOCALS;
- /* Blits are in a different ringbuffer so we don't use them. */
- assert(intel->gen < 6);
-
/*
* Compute values for clearing the buffers.
*/
@@ -356,7 +351,7 @@ intelClearWithBlit(struct gl_context *ctx, GLbitfield mask)
intel_batchbuffer_flush(intel->batch);
}
- BEGIN_BATCH(6);
+ BEGIN_BATCH_BLT(6);
OUT_BATCH(CMD);
OUT_BATCH(BR13);
OUT_BATCH((y1 << 16) | x1);
@@ -393,10 +388,6 @@ intelEmitImmediateColorExpandBlit(struct intel_context *intel,
int dwords = ALIGN(src_size, 8) / 4;
uint32_t opcode, br13, blit_cmd;
- /* Blits are in a different ringbuffer so we don't use them. */
- if (intel->gen >= 6)
- return GL_FALSE;
-
if (dst_tiling != I915_TILING_NONE) {
if (dst_offset & 4095)
return GL_FALSE;
@@ -420,7 +411,7 @@ intelEmitImmediateColorExpandBlit(struct intel_context *intel,
intel_batchbuffer_require_space( intel->batch,
(8 * 4) +
(3 * 4) +
- dwords * 4 );
+ dwords * 4, true);
opcode = XY_SETUP_BLT_CMD;
if (cpp == 4)
@@ -439,7 +430,7 @@ intelEmitImmediateColorExpandBlit(struct intel_context *intel,
if (dst_tiling != I915_TILING_NONE)
blit_cmd |= XY_DST_TILED;
- BEGIN_BATCH(8 + 3);
+ BEGIN_BATCH_BLT(8 + 3);
OUT_BATCH(opcode);
OUT_BATCH(br13);
OUT_BATCH((0 << 16) | 0); /* clip x1, y1 */
@@ -456,9 +447,9 @@ intelEmitImmediateColorExpandBlit(struct intel_context *intel,
OUT_BATCH(((y + h) << 16) | (x + w));
ADVANCE_BATCH();
- intel_batchbuffer_data( intel->batch,
- src_bits,
- dwords * 4 );
+ intel_batchbuffer_data(intel->batch,
+ src_bits,
+ dwords * 4, true);
intel_batchbuffer_emit_mi_flush(intel->batch);
@@ -480,9 +471,6 @@ intel_emit_linear_blit(struct intel_context *intel,
GLuint pitch, height;
GLboolean ok;
- /* Blits are in a different ringbuffer so we don't use them. */
- assert(intel->gen < 6);
-
/* The pitch given to the GPU must be DWORD aligned, and
* we want width to match pitch. Max width is (1 << 15 - 1),
* rounding that down to the nearest DWORD is 1 << 15 - 4
@@ -514,3 +502,81 @@ intel_emit_linear_blit(struct intel_context *intel,
assert(ok);
}
}
+
+/**
+ * Used to initialize the alpha value of an ARGB8888 teximage after
+ * loading it from an XRGB8888 source.
+ *
+ * This is very common with glCopyTexImage2D().
+ */
+void
+intel_set_teximage_alpha_to_one(struct gl_context *ctx,
+ struct intel_texture_image *intel_image)
+{
+ struct intel_context *intel = intel_context(ctx);
+ unsigned int image_x, image_y;
+ uint32_t x1, y1, x2, y2;
+ uint32_t BR13, CMD;
+ int pitch, cpp;
+ drm_intel_bo *aper_array[2];
+ struct intel_region *region = intel_image->mt->region;
+ BATCH_LOCALS;
+
+ assert(intel_image->base.TexFormat == MESA_FORMAT_ARGB8888);
+
+ /* get dest x/y in destination texture */
+ intel_miptree_get_image_offset(intel_image->mt,
+ intel_image->level,
+ intel_image->face,
+ 0,
+ &image_x, &image_y);
+
+ x1 = image_x;
+ y1 = image_y;
+ x2 = image_x + intel_image->base.Width;
+ y2 = image_y + intel_image->base.Height;
+
+ pitch = region->pitch;
+ cpp = region->cpp;
+
+ DBG("%s dst:buf(%p)/%d %d,%d sz:%dx%d\n",
+ __FUNCTION__,
+ intel_image->mt->region->buffer, (pitch * region->cpp),
+ x1, y1, x2 - x1, y2 - y1);
+
+ BR13 = br13_for_cpp(region->cpp) | 0xf0 << 16;
+ CMD = XY_COLOR_BLT_CMD;
+ CMD |= XY_BLT_WRITE_ALPHA;
+
+ assert(region->tiling != I915_TILING_Y);
+
+#ifndef I915
+ if (region->tiling != I915_TILING_NONE) {
+ CMD |= XY_DST_TILED;
+ pitch /= 4;
+ }
+#endif
+ BR13 |= (pitch * region->cpp);
+
+ /* do space check before going any further */
+ aper_array[0] = intel->batch->buf;
+ aper_array[1] = region->buffer;
+
+ if (drm_intel_bufmgr_check_aperture_space(aper_array,
+ ARRAY_SIZE(aper_array)) != 0) {
+ intel_batchbuffer_flush(intel->batch);
+ }
+
+ BEGIN_BATCH_BLT(6);
+ OUT_BATCH(CMD);
+ OUT_BATCH(BR13);
+ OUT_BATCH((y1 << 16) | x1);
+ OUT_BATCH((y2 << 16) | x2);
+ OUT_RELOC_FENCED(region->buffer,
+ I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER,
+ 0);
+ OUT_BATCH(0xffffffff); /* white, but only alpha gets written */
+ ADVANCE_BATCH();
+
+ intel_batchbuffer_emit_mi_flush(intel->batch);
+}
diff --git a/src/mesa/drivers/dri/intel/intel_blit.h b/src/mesa/drivers/dri/intel/intel_blit.h
index 01631465735..ff69e4f8f8f 100644
--- a/src/mesa/drivers/dri/intel/intel_blit.h
+++ b/src/mesa/drivers/dri/intel/intel_blit.h
@@ -69,5 +69,7 @@ void intel_emit_linear_blit(struct intel_context *intel,
drm_intel_bo *src_bo,
unsigned int src_offset,
unsigned int size);
+void intel_set_teximage_alpha_to_one(struct gl_context *ctx,
+ struct intel_texture_image *intel_image);
#endif
diff --git a/src/mesa/drivers/dri/intel/intel_context.h b/src/mesa/drivers/dri/intel/intel_context.h
index 96493c0f2bb..53a11ba9a7e 100644
--- a/src/mesa/drivers/dri/intel/intel_context.h
+++ b/src/mesa/drivers/dri/intel/intel_context.h
@@ -29,7 +29,7 @@
#define INTELCONTEXT_INC
-
+#include <stdbool.h>
#include "main/mtypes.h"
#include "main/mm.h"
#include "dri_metaops.h"
diff --git a/src/mesa/drivers/dri/intel/intel_fbo.c b/src/mesa/drivers/dri/intel/intel_fbo.c
index 18e796a1186..c3f528c2ae5 100644
--- a/src/mesa/drivers/dri/intel/intel_fbo.c
+++ b/src/mesa/drivers/dri/intel/intel_fbo.c
@@ -42,6 +42,8 @@
#include "intel_fbo.h"
#include "intel_mipmap_tree.h"
#include "intel_regions.h"
+#include "intel_tex.h"
+#include "intel_span.h"
#define FILE_DEBUG_FLAG DEBUG_FBO
@@ -107,79 +109,27 @@ intel_alloc_renderbuffer_storage(struct gl_context * ctx, struct gl_renderbuffer
ASSERT(rb->Name != 0);
switch (internalFormat) {
- case GL_RED:
- case GL_R8:
- rb->Format = MESA_FORMAT_R8;
- rb->DataType = GL_UNSIGNED_BYTE;
- break;
- case GL_R16:
- rb->Format = MESA_FORMAT_R16;
- rb->DataType = GL_UNSIGNED_SHORT;
- break;
- case GL_RG:
- case GL_RG8:
- rb->Format = MESA_FORMAT_RG88;
- rb->DataType = GL_UNSIGNED_BYTE;
- break;
- case GL_RG16:
- rb->Format = MESA_FORMAT_RG1616;
- rb->DataType = GL_UNSIGNED_SHORT;
- break;
- case GL_R3_G3_B2:
- case GL_RGB4:
- case GL_RGB5:
- rb->Format = MESA_FORMAT_RGB565;
- rb->DataType = GL_UNSIGNED_BYTE;
- break;
- case GL_RGB:
- case GL_RGB8:
- case GL_RGB10:
- case GL_RGB12:
- case GL_RGB16:
- rb->Format = MESA_FORMAT_XRGB8888;
- rb->DataType = GL_UNSIGNED_BYTE;
- break;
- case GL_RGBA:
- case GL_RGBA2:
- case GL_RGBA4:
- case GL_RGB5_A1:
- case GL_RGBA8:
- case GL_RGB10_A2:
- case GL_RGBA12:
- case GL_RGBA16:
- rb->Format = MESA_FORMAT_ARGB8888;
- rb->DataType = GL_UNSIGNED_BYTE;
- break;
- case GL_ALPHA:
- case GL_ALPHA8:
- rb->Format = MESA_FORMAT_A8;
- rb->DataType = GL_UNSIGNED_BYTE;
- break;
- case GL_DEPTH_COMPONENT16:
- rb->Format = MESA_FORMAT_Z16;
- rb->DataType = GL_UNSIGNED_SHORT;
+ default:
+ /* Use the same format-choice logic as for textures.
+ * Renderbuffers aren't any different from textures for us,
+ * except they're less useful because you can't texture with
+ * them.
+ */
+ rb->Format = intelChooseTextureFormat(ctx, internalFormat,
+ GL_NONE, GL_NONE);
break;
case GL_STENCIL_INDEX:
case GL_STENCIL_INDEX1_EXT:
case GL_STENCIL_INDEX4_EXT:
case GL_STENCIL_INDEX8_EXT:
case GL_STENCIL_INDEX16_EXT:
- case GL_DEPTH_COMPONENT:
- case GL_DEPTH_COMPONENT24:
- case GL_DEPTH_COMPONENT32:
- case GL_DEPTH_STENCIL_EXT:
- case GL_DEPTH24_STENCIL8_EXT:
- /* alloc a depth+stencil buffer */
+ /* These aren't actual texture formats, so force them here. */
rb->Format = MESA_FORMAT_S8_Z24;
- rb->DataType = GL_UNSIGNED_INT_24_8_EXT;
break;
- default:
- _mesa_problem(ctx,
- "Unexpected format in intel_alloc_renderbuffer_storage");
- return GL_FALSE;
}
rb->_BaseFormat = _mesa_base_fbo_format(ctx, internalFormat);
+ rb->DataType = intel_mesa_format_to_rb_datatype(rb->Format);
cpp = _mesa_get_format_bytes(rb->Format);
intel_flush(ctx);
@@ -338,39 +288,30 @@ intel_create_renderbuffer(gl_format format)
switch (format) {
case MESA_FORMAT_RGB565:
irb->Base._BaseFormat = GL_RGB;
- irb->Base.DataType = GL_UNSIGNED_BYTE;
break;
case MESA_FORMAT_XRGB8888:
irb->Base._BaseFormat = GL_RGB;
- irb->Base.DataType = GL_UNSIGNED_BYTE;
break;
case MESA_FORMAT_ARGB8888:
irb->Base._BaseFormat = GL_RGBA;
- irb->Base.DataType = GL_UNSIGNED_BYTE;
break;
case MESA_FORMAT_Z16:
irb->Base._BaseFormat = GL_DEPTH_COMPONENT;
- irb->Base.DataType = GL_UNSIGNED_SHORT;
break;
case MESA_FORMAT_X8_Z24:
irb->Base._BaseFormat = GL_DEPTH_COMPONENT;
- irb->Base.DataType = GL_UNSIGNED_INT;
break;
case MESA_FORMAT_S8_Z24:
irb->Base._BaseFormat = GL_DEPTH_STENCIL;
- irb->Base.DataType = GL_UNSIGNED_INT_24_8_EXT;
break;
case MESA_FORMAT_A8:
irb->Base._BaseFormat = GL_ALPHA;
- irb->Base.DataType = GL_UNSIGNED_BYTE;
break;
case MESA_FORMAT_R8:
irb->Base._BaseFormat = GL_RED;
- irb->Base.DataType = GL_UNSIGNED_BYTE;
break;
case MESA_FORMAT_RG88:
irb->Base._BaseFormat = GL_RG;
- irb->Base.DataType = GL_UNSIGNED_BYTE;
break;
default:
_mesa_problem(NULL,
@@ -381,6 +322,7 @@ intel_create_renderbuffer(gl_format format)
irb->Base.Format = format;
irb->Base.InternalFormat = irb->Base._BaseFormat;
+ irb->Base.DataType = intel_mesa_format_to_rb_datatype(format);
/* intel-specific methods */
irb->Base.Delete = intel_delete_renderbuffer;
@@ -457,70 +399,16 @@ static GLboolean
intel_update_wrapper(struct gl_context *ctx, struct intel_renderbuffer *irb,
struct gl_texture_image *texImage)
{
- if (texImage->TexFormat == MESA_FORMAT_ARGB8888) {
- irb->Base.DataType = GL_UNSIGNED_BYTE;
- DBG("Render to RGBA8 texture OK\n");
- }
- else if (texImage->TexFormat == MESA_FORMAT_XRGB8888) {
- irb->Base.DataType = GL_UNSIGNED_BYTE;
- DBG("Render to XGBA8 texture OK\n");
- }
-#ifndef I915
- else if (texImage->TexFormat == MESA_FORMAT_SARGB8) {
- irb->Base.DataType = GL_UNSIGNED_BYTE;
- DBG("Render to SARGB8 texture OK\n");
- }
-#endif
- else if (texImage->TexFormat == MESA_FORMAT_RGB565) {
- irb->Base.DataType = GL_UNSIGNED_BYTE;
- DBG("Render to RGB5 texture OK\n");
- }
- else if (texImage->TexFormat == MESA_FORMAT_ARGB1555) {
- irb->Base.DataType = GL_UNSIGNED_BYTE;
- DBG("Render to ARGB1555 texture OK\n");
- }
- else if (texImage->TexFormat == MESA_FORMAT_ARGB4444) {
- irb->Base.DataType = GL_UNSIGNED_BYTE;
- DBG("Render to ARGB4444 texture OK\n");
- }
-#ifndef I915
- else if (texImage->TexFormat == MESA_FORMAT_A8) {
- irb->Base.DataType = GL_UNSIGNED_BYTE;
- DBG("Render to A8 texture OK\n");
- }
- else if (texImage->TexFormat == MESA_FORMAT_R8) {
- irb->Base.DataType = GL_UNSIGNED_BYTE;
- DBG("Render to R8 texture OK\n");
- }
- else if (texImage->TexFormat == MESA_FORMAT_RG88) {
- irb->Base.DataType = GL_UNSIGNED_BYTE;
- DBG("Render to RG88 texture OK\n");
- }
- else if (texImage->TexFormat == MESA_FORMAT_R16) {
- irb->Base.DataType = GL_UNSIGNED_SHORT;
- DBG("Render to R8 texture OK\n");
- }
- else if (texImage->TexFormat == MESA_FORMAT_RG1616) {
- irb->Base.DataType = GL_UNSIGNED_SHORT;
- DBG("Render to RG88 texture OK\n");
- }
-#endif
- else if (texImage->TexFormat == MESA_FORMAT_Z16) {
- irb->Base.DataType = GL_UNSIGNED_SHORT;
- DBG("Render to DEPTH16 texture OK\n");
- }
- else if (texImage->TexFormat == MESA_FORMAT_S8_Z24) {
- irb->Base.DataType = GL_UNSIGNED_INT_24_8_EXT;
- DBG("Render to DEPTH_STENCIL texture OK\n");
- }
- else {
+ if (!intel_span_supports_format(texImage->TexFormat)) {
DBG("Render to texture BAD FORMAT %s\n",
_mesa_get_format_name(texImage->TexFormat));
return GL_FALSE;
+ } else {
+ DBG("Render to texture %s\n", _mesa_get_format_name(texImage->TexFormat));
}
irb->Base.Format = texImage->TexFormat;
-
+ irb->Base.DataType = intel_mesa_format_to_rb_datatype(texImage->TexFormat);
irb->Base.InternalFormat = texImage->InternalFormat;
irb->Base._BaseFormat = _mesa_base_fbo_format(ctx, irb->Base.InternalFormat);
irb->Base.Width = texImage->Width;
@@ -659,7 +547,8 @@ intel_finish_render_texture(struct gl_context * ctx,
_glthread_GetID(), att->Texture->Name);
/* Flag that this image may now be validated into the object's miptree. */
- intel_image->used_as_render_target = GL_FALSE;
+ if (intel_image)
+ intel_image->used_as_render_target = GL_FALSE;
/* Since we've (probably) rendered to the texture and will (likely) use
* it in the texture domain later on in this batchbuffer, flush the
@@ -711,22 +600,9 @@ intel_validate_framebuffer(struct gl_context *ctx, struct gl_framebuffer *fb)
continue;
}
- switch (irb->Base.Format) {
- case MESA_FORMAT_ARGB8888:
- case MESA_FORMAT_XRGB8888:
- case MESA_FORMAT_RGB565:
- case MESA_FORMAT_ARGB1555:
- case MESA_FORMAT_ARGB4444:
-#ifndef I915
- case MESA_FORMAT_SARGB8:
- case MESA_FORMAT_A8:
- case MESA_FORMAT_R8:
- case MESA_FORMAT_R16:
- case MESA_FORMAT_RG88:
- case MESA_FORMAT_RG1616:
-#endif
- break;
- default:
+ if (!intel_span_supports_format(irb->Base.Format)) {
+ DBG("Unsupported texture/renderbuffer format attached: %s\n",
+ _mesa_get_format_name(irb->Base.Format));
fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT;
}
}
diff --git a/src/mesa/drivers/dri/intel/intel_screen.c b/src/mesa/drivers/dri/intel/intel_screen.c
index 3f13589a214..d683e675328 100644
--- a/src/mesa/drivers/dri/intel/intel_screen.c
+++ b/src/mesa/drivers/dri/intel/intel_screen.c
@@ -35,19 +35,6 @@
#include "utils.h"
#include "xmlpool.h"
-#include "intel_batchbuffer.h"
-#include "intel_buffers.h"
-#include "intel_bufmgr.h"
-#include "intel_chipset.h"
-#include "intel_fbo.h"
-#include "intel_screen.h"
-#include "intel_tex.h"
-#include "intel_regions.h"
-
-#include "i915_drm.h"
-
-#define DRI_CONF_TEXTURE_TILING(def) \
-
PUBLIC const char __driConfigOptions[] =
DRI_CONF_BEGIN
DRI_CONF_SECTION_PERFORMANCE
@@ -92,6 +79,17 @@ DRI_CONF_END;
const GLuint __driNConfigOptions = 11;
+#include "intel_batchbuffer.h"
+#include "intel_buffers.h"
+#include "intel_bufmgr.h"
+#include "intel_chipset.h"
+#include "intel_fbo.h"
+#include "intel_screen.h"
+#include "intel_tex.h"
+#include "intel_regions.h"
+
+#include "i915_drm.h"
+
#ifdef USE_NEW_INTERFACE
static PFNGLXCREATECONTEXTMODES create_context_modes = NULL;
#endif /*USE_NEW_INTERFACE */
diff --git a/src/mesa/drivers/dri/intel/intel_span.c b/src/mesa/drivers/dri/intel/intel_span.c
index 104cadf0f9e..1f41518535c 100644
--- a/src/mesa/drivers/dri/intel/intel_span.c
+++ b/src/mesa/drivers/dri/intel/intel_span.c
@@ -25,6 +25,7 @@
*
**************************************************************************/
+#include <stdbool.h>
#include "main/glheader.h"
#include "main/macros.h"
#include "main/mtypes.h"
@@ -113,6 +114,26 @@ intel_set_span_functions(struct intel_context *intel,
#define TAG2(x,y) intel_##x##y##_A8
#include "spantmp2.h"
+#define SPANTMP_MESA_FMT MESA_FORMAT_R8
+#define TAG(x) intel_##x##_R8
+#define TAG2(x,y) intel_##x##y##_R8
+#include "spantmp2.h"
+
+#define SPANTMP_MESA_FMT MESA_FORMAT_RG88
+#define TAG(x) intel_##x##_RG88
+#define TAG2(x,y) intel_##x##y##_RG88
+#include "spantmp2.h"
+
+#define SPANTMP_MESA_FMT MESA_FORMAT_R16
+#define TAG(x) intel_##x##_R16
+#define TAG2(x,y) intel_##x##y##_R16
+#include "spantmp2.h"
+
+#define SPANTMP_MESA_FMT MESA_FORMAT_RG1616
+#define TAG(x) intel_##x##_RG1616
+#define TAG2(x,y) intel_##x##y##_RG1616
+#include "spantmp2.h"
+
#define LOCAL_DEPTH_VARS \
struct intel_renderbuffer *irb = intel_renderbuffer(rb); \
const GLint yScale = rb->Name ? 1 : -1; \
@@ -339,6 +360,32 @@ intel_unmap_vertex_shader_textures(struct gl_context *ctx)
}
}
+typedef void (*span_init_func)(struct gl_renderbuffer *rb);
+
+static span_init_func intel_span_init_funcs[MESA_FORMAT_COUNT] =
+{
+ [MESA_FORMAT_A8] = intel_InitPointers_A8,
+ [MESA_FORMAT_RGB565] = intel_InitPointers_RGB565,
+ [MESA_FORMAT_ARGB4444] = intel_InitPointers_ARGB4444,
+ [MESA_FORMAT_ARGB1555] = intel_InitPointers_ARGB1555,
+ [MESA_FORMAT_XRGB8888] = intel_InitPointers_xRGB8888,
+ [MESA_FORMAT_ARGB8888] = intel_InitPointers_ARGB8888,
+ [MESA_FORMAT_SARGB8] = intel_InitPointers_ARGB8888,
+ [MESA_FORMAT_Z16] = intel_InitDepthPointers_z16,
+ [MESA_FORMAT_X8_Z24] = intel_InitDepthPointers_z24_s8,
+ [MESA_FORMAT_S8_Z24] = intel_InitDepthPointers_z24_s8,
+ [MESA_FORMAT_R8] = intel_InitPointers_R8,
+ [MESA_FORMAT_RG88] = intel_InitPointers_RG88,
+ [MESA_FORMAT_R16] = intel_InitPointers_R16,
+ [MESA_FORMAT_RG1616] = intel_InitPointers_RG1616,
+};
+
+bool
+intel_span_supports_format(gl_format format)
+{
+ return intel_span_init_funcs[format] != NULL;
+}
+
/**
* Plug in appropriate span read/write functions for the given renderbuffer.
* These are used for the software fallbacks.
@@ -349,37 +396,6 @@ intel_set_span_functions(struct intel_context *intel,
{
struct intel_renderbuffer *irb = (struct intel_renderbuffer *) rb;
- switch (irb->Base.Format) {
- case MESA_FORMAT_A8:
- intel_InitPointers_A8(rb);
- break;
- case MESA_FORMAT_RGB565:
- intel_InitPointers_RGB565(rb);
- break;
- case MESA_FORMAT_ARGB4444:
- intel_InitPointers_ARGB4444(rb);
- break;
- case MESA_FORMAT_ARGB1555:
- intel_InitPointers_ARGB1555(rb);
- break;
- case MESA_FORMAT_XRGB8888:
- intel_InitPointers_xRGB8888(rb);
- break;
- case MESA_FORMAT_ARGB8888:
- case MESA_FORMAT_SARGB8:
- intel_InitPointers_ARGB8888(rb);
- break;
- case MESA_FORMAT_Z16:
- intel_InitDepthPointers_z16(rb);
- break;
- case MESA_FORMAT_X8_Z24:
- case MESA_FORMAT_S8_Z24:
- intel_InitDepthPointers_z24_s8(rb);
- break;
- default:
- _mesa_problem(NULL,
- "Unexpected MesaFormat %d in intelSetSpanFunctions",
- irb->Base.Format);
- break;
- }
+ assert(intel_span_init_funcs[irb->Base.Format]);
+ intel_span_init_funcs[irb->Base.Format](rb);
}
diff --git a/src/mesa/drivers/dri/intel/intel_span.h b/src/mesa/drivers/dri/intel/intel_span.h
index aa8d08e843a..5a4c4e8e52a 100644
--- a/src/mesa/drivers/dri/intel/intel_span.h
+++ b/src/mesa/drivers/dri/intel/intel_span.h
@@ -28,6 +28,9 @@
#ifndef _INTEL_SPAN_H
#define _INTEL_SPAN_H
+#include "main/formats.h"
+#include <stdbool.h>
+
extern void intelInitSpanFuncs(struct gl_context * ctx);
extern void intelSpanRenderFinish(struct gl_context * ctx);
@@ -38,5 +41,6 @@ void intel_renderbuffer_unmap(struct intel_context *intel,
struct gl_renderbuffer *rb);
void intel_map_vertex_shader_textures(struct gl_context *ctx);
void intel_unmap_vertex_shader_textures(struct gl_context *ctx);
+bool intel_span_supports_format(gl_format format);
#endif
diff --git a/src/mesa/drivers/dri/intel/intel_tex.h b/src/mesa/drivers/dri/intel/intel_tex.h
index 7906554e453..b638628c711 100644
--- a/src/mesa/drivers/dri/intel/intel_tex.h
+++ b/src/mesa/drivers/dri/intel/intel_tex.h
@@ -42,6 +42,7 @@ void intelInitTextureCopyImageFuncs(struct dd_function_table *functions);
gl_format intelChooseTextureFormat(struct gl_context *ctx, GLint internalFormat,
GLenum format, GLenum type);
+GLenum intel_mesa_format_to_rb_datatype(gl_format format);
void intelSetTexBuffer(__DRIcontext *pDRICtx,
GLint target, __DRIdrawable *pDraw);
diff --git a/src/mesa/drivers/dri/intel/intel_tex_copy.c b/src/mesa/drivers/dri/intel/intel_tex_copy.c
index 87b31bf078c..c6bc3d962ab 100644
--- a/src/mesa/drivers/dri/intel/intel_tex_copy.c
+++ b/src/mesa/drivers/dri/intel/intel_tex_copy.c
@@ -50,44 +50,20 @@
* Do the best we can using the blitter. A future project is to use
* the texture engine and fragment programs for these copies.
*/
-static const struct intel_region *
-get_teximage_source(struct intel_context *intel, GLenum internalFormat)
+static struct intel_renderbuffer *
+get_teximage_readbuffer(struct intel_context *intel, GLenum internalFormat)
{
- struct intel_renderbuffer *irb;
-
DBG("%s %s\n", __FUNCTION__,
_mesa_lookup_enum_by_nr(internalFormat));
switch (internalFormat) {
case GL_DEPTH_COMPONENT:
case GL_DEPTH_COMPONENT16:
- irb = intel_get_renderbuffer(intel->ctx.ReadBuffer, BUFFER_DEPTH);
- if (irb && irb->region && irb->region->cpp == 2)
- return irb->region;
- return NULL;
case GL_DEPTH24_STENCIL8_EXT:
case GL_DEPTH_STENCIL_EXT:
- irb = intel_get_renderbuffer(intel->ctx.ReadBuffer, BUFFER_DEPTH);
- if (irb && irb->region && irb->region->cpp == 4)
- return irb->region;
- return NULL;
- case 4:
- case GL_RGBA:
- case GL_RGBA8:
- irb = intel_renderbuffer(intel->ctx.ReadBuffer->_ColorReadBuffer);
- /* We're required to set alpha to 1.0 in this case, but we can't
- * do that with the blitter, so fall back. We could use the 3D
- * engine or do two passes with the blitter, but it doesn't seem
- * worth it for this case. */
- if (irb->Base._BaseFormat == GL_RGB)
- return NULL;
- return irb->region;
- case 3:
- case GL_RGB:
- case GL_RGB8:
- return intel_readbuf_region(intel);
+ return intel_get_renderbuffer(intel->ctx.ReadBuffer, BUFFER_DEPTH);
default:
- return NULL;
+ return intel_renderbuffer(intel->ctx.ReadBuffer->_ColorReadBuffer);
}
}
@@ -101,23 +77,34 @@ do_copy_texsubimage(struct intel_context *intel,
GLint x, GLint y, GLsizei width, GLsizei height)
{
struct gl_context *ctx = &intel->ctx;
- const struct intel_region *src = get_teximage_source(intel, internalFormat);
+ struct intel_renderbuffer *irb;
+ bool copy_supported_with_alpha_override = false;
+
+ intel_prepare_render(intel);
- if (!intelImage->mt || !src || !src->buffer) {
+ irb = get_teximage_readbuffer(intel, internalFormat);
+ if (!intelImage->mt || !irb || !irb->region) {
if (unlikely(INTEL_DEBUG & DEBUG_FALLBACKS))
fprintf(stderr, "%s fail %p %p (0x%08x)\n",
- __FUNCTION__, intelImage->mt, src, internalFormat);
+ __FUNCTION__, intelImage->mt, irb, internalFormat);
return GL_FALSE;
}
- if (intelImage->mt->cpp != src->cpp) {
- fallback_debug("%s fail %d vs %d cpp\n",
- __FUNCTION__, intelImage->mt->cpp, src->cpp);
+ if (irb->Base.Format == MESA_FORMAT_XRGB8888 &&
+ intelImage->base.TexFormat == MESA_FORMAT_ARGB8888) {
+ copy_supported_with_alpha_override = true;
+ }
+
+ if (intelImage->base.TexFormat != irb->Base.Format &&
+ !copy_supported_with_alpha_override) {
+ if (unlikely(INTEL_DEBUG & DEBUG_FALLBACKS))
+ fprintf(stderr, "%s mismatched formats %s, %s\n",
+ __FUNCTION__,
+ _mesa_get_format_name(intelImage->base.TexFormat),
+ _mesa_get_format_name(irb->Base.Format));
return GL_FALSE;
}
- /* intel_flush(ctx); */
- intel_prepare_render(intel);
{
drm_intel_bo *dst_bo = intel_region_buffer(intel,
intelImage->mt->region,
@@ -140,24 +127,24 @@ do_copy_texsubimage(struct intel_context *intel,
if (ctx->ReadBuffer->Name == 0) {
/* Flip vertical orientation for system framebuffers */
y = ctx->ReadBuffer->Height - (y + height);
- src_pitch = -src->pitch;
+ src_pitch = -irb->region->pitch;
} else {
/* reading from a FBO, y is already oriented the way we like */
- src_pitch = src->pitch;
+ src_pitch = irb->region->pitch;
}
/* blit from src buffer to texture */
if (!intelEmitCopyBlit(intel,
intelImage->mt->cpp,
src_pitch,
- src->buffer,
+ irb->region->buffer,
0,
- src->tiling,
+ irb->region->tiling,
intelImage->mt->region->pitch,
dst_bo,
0,
intelImage->mt->region->tiling,
- src->draw_x + x, src->draw_y + y,
+ irb->region->draw_x + x, irb->region->draw_y + y,
image_x + dstx, image_y + dsty,
width, height,
GL_COPY)) {
@@ -165,6 +152,9 @@ do_copy_texsubimage(struct intel_context *intel,
}
}
+ if (copy_supported_with_alpha_override)
+ intel_set_teximage_alpha_to_one(ctx, intelImage);
+
return GL_TRUE;
}
diff --git a/src/mesa/drivers/dri/intel/intel_tex_format.c b/src/mesa/drivers/dri/intel/intel_tex_format.c
index f8316ae2f8d..c9763c9ae16 100644
--- a/src/mesa/drivers/dri/intel/intel_tex_format.c
+++ b/src/mesa/drivers/dri/intel/intel_tex_format.c
@@ -4,6 +4,39 @@
#include "main/formats.h"
/**
+ * Returns the renderbuffer DataType for a MESA_FORMAT.
+ */
+GLenum
+intel_mesa_format_to_rb_datatype(gl_format format)
+{
+ switch (format) {
+ case MESA_FORMAT_ARGB8888:
+ case MESA_FORMAT_XRGB8888:
+ case MESA_FORMAT_SARGB8:
+ case MESA_FORMAT_R8:
+ case MESA_FORMAT_RG88:
+ case MESA_FORMAT_A8:
+ case MESA_FORMAT_AL88:
+ case MESA_FORMAT_RGB565:
+ case MESA_FORMAT_ARGB1555:
+ case MESA_FORMAT_ARGB4444:
+ return GL_UNSIGNED_BYTE;
+ case MESA_FORMAT_R16:
+ case MESA_FORMAT_RG1616:
+ case MESA_FORMAT_Z16:
+ return GL_UNSIGNED_SHORT;
+ case MESA_FORMAT_X8_Z24:
+ return GL_UNSIGNED_INT;
+ case MESA_FORMAT_S8_Z24:
+ return GL_UNSIGNED_INT_24_8_EXT;
+ default:
+ _mesa_problem(NULL, "unexpected MESA_FORMAT for renderbuffer");
+ return GL_UNSIGNED_BYTE;
+ }
+}
+
+
+/**
* Choose hardware texture format given the user's glTexImage parameters.
*
* It works out that this function is fine for all the supported
diff --git a/src/mesa/drivers/dri/nouveau/nouveau_driver.h b/src/mesa/drivers/dri/nouveau/nouveau_driver.h
index 8036b18edc0..c5ac1282d0d 100644
--- a/src/mesa/drivers/dri/nouveau/nouveau_driver.h
+++ b/src/mesa/drivers/dri/nouveau/nouveau_driver.h
@@ -38,7 +38,6 @@
#include <assert.h>
#include "nouveau_device.h"
-#include "nouveau_pushbuf.h"
#include "nouveau_grobj.h"
#include "nouveau_channel.h"
#include "nouveau_bo.h"
@@ -46,6 +45,7 @@
#include "nouveau_screen.h"
#include "nouveau_state.h"
#include "nouveau_surface.h"
+#include "nv04_pushbuf.h"
#define DRIVER_DATE "20091015"
#define DRIVER_AUTHOR "Nouveau"
diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_dataflow_swizzles.c b/src/mesa/drivers/dri/r300/compiler/radeon_dataflow_swizzles.c
index a0f7bd81741..133a9f72ec7 100644
--- a/src/mesa/drivers/dri/r300/compiler/radeon_dataflow_swizzles.c
+++ b/src/mesa/drivers/dri/r300/compiler/radeon_dataflow_swizzles.c
@@ -56,6 +56,7 @@ static void rewrite_source(struct radeon_compiler * c,
mov->U.I.DstReg.Index = tempreg;
mov->U.I.DstReg.WriteMask = split.Phase[phase];
mov->U.I.SrcReg[0] = inst->U.I.SrcReg[src];
+ mov->U.I.PreSub = inst->U.I.PreSub;
phase_refmask = 0;
for(unsigned int chan = 0; chan < 4; ++chan) {
diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_program_alu.c b/src/mesa/drivers/dri/r300/compiler/radeon_program_alu.c
index 58977a40c7c..c8063171b81 100644
--- a/src/mesa/drivers/dri/r300/compiler/radeon_program_alu.c
+++ b/src/mesa/drivers/dri/r300/compiler/radeon_program_alu.c
@@ -689,11 +689,12 @@ static void transform_r300_vertex_fix_LIT(struct radeon_compiler* c,
&constant_swizzle);
/* MOV dst, src */
+ dst.WriteMask = RC_MASK_XYZW;
emit1(c, inst->Prev, RC_OPCODE_MOV, 0,
dst,
inst->U.I.SrcReg[0]);
- /* MAX dst.z, src, 0.00...001 */
+ /* MAX dst.y, src, 0.00...001 */
emit2(c, inst->Prev, RC_OPCODE_MAX, 0,
dstregtmpmask(dst.Index, RC_MASK_Y),
srcreg(RC_FILE_TEMPORARY, dst.Index),
diff --git a/src/mesa/drivers/dri/r600/r700_assembler.c b/src/mesa/drivers/dri/r600/r700_assembler.c
index 1fa559cec1a..bee9c3bc6d3 100644
--- a/src/mesa/drivers/dri/r600/r700_assembler.c
+++ b/src/mesa/drivers/dri/r600/r700_assembler.c
@@ -1134,7 +1134,7 @@ GLboolean EG_assemble_vfetch_instruction(r700_AssemblerBase* pAsm,
EG_VTX_WORD1__DST_SEL_W_shift,
EG_VTX_WORD1__DST_SEL_W_mask);
- SETfield(vfetch_instruction_ptr->m_Word1.val, 0, /* use format here, in r6/r7, format used set in const, need to use same */
+ SETfield(vfetch_instruction_ptr->m_Word1.val, 1,
EG_VTX_WORD1__UCF_shift,
EG_VTX_WORD1__UCF_bit);
SETfield(vfetch_instruction_ptr->m_Word1.val, data_format,
diff --git a/src/mesa/main/extensions.c b/src/mesa/main/extensions.c
index b71afdd61f3..fd5b4e915cd 100644
--- a/src/mesa/main/extensions.c
+++ b/src/mesa/main/extensions.c
@@ -249,7 +249,8 @@ _mesa_enable_sw_extensions(struct gl_context *ctx)
#if FEATURE_ARB_framebuffer_object
ctx->Extensions.ARB_framebuffer_object = GL_TRUE;
#endif
-#if FEATURE_ARB_geometry_shader4
+#if FEATURE_ARB_geometry_shader4 && 0
+ /* XXX re-enable when GLSL compiler again supports geometry shaders */
ctx->Extensions.ARB_geometry_shader4 = GL_TRUE;
#endif
ctx->Extensions.ARB_half_float_pixel = GL_TRUE;
@@ -258,6 +259,7 @@ _mesa_enable_sw_extensions(struct gl_context *ctx)
ctx->Extensions.ARB_multitexture = GL_TRUE;
#if FEATURE_queryobj
ctx->Extensions.ARB_occlusion_query = GL_TRUE;
+ ctx->Extensions.ARB_occlusion_query2 = GL_TRUE;
#endif
ctx->Extensions.ARB_point_sprite = GL_TRUE;
#if FEATURE_ARB_shader_objects
@@ -857,8 +859,6 @@ make_extension_string_es2(const struct gl_context *ctx, GLubyte *str)
{
size_t len = 0;
- len += append_extension(&str, "GL_OES_compressed_paletted_texture");
-
if (ctx->Extensions.ARB_framebuffer_object) {
len += append_extension(&str, "GL_OES_depth24");
len += append_extension(&str, "GL_OES_depth32");
diff --git a/src/mesa/main/formats.c b/src/mesa/main/formats.c
index cd9eb81852f..42f70ca232b 100644
--- a/src/mesa/main/formats.c
+++ b/src/mesa/main/formats.c
@@ -863,7 +863,6 @@ const char *
_mesa_get_format_name(gl_format format)
{
const struct gl_format_info *info = _mesa_get_format_info(format);
- ASSERT(info->BytesPerBlock);
return info->StrName;
}
diff --git a/src/mesa/main/queryobj.c b/src/mesa/main/queryobj.c
index 88743977206..66fb5980589 100644
--- a/src/mesa/main/queryobj.c
+++ b/src/mesa/main/queryobj.c
@@ -143,6 +143,11 @@ get_query_binding_point(struct gl_context *ctx, GLenum target)
return &ctx->Query.CurrentOcclusionObject;
else
return NULL;
+ case GL_ANY_SAMPLES_PASSED:
+ if (ctx->Extensions.ARB_occlusion_query2)
+ return &ctx->Query.CurrentOcclusionObject;
+ else
+ return NULL;
case GL_TIME_ELAPSED_EXT:
if (ctx->Extensions.EXT_timer_query)
return &ctx->Query.CurrentTimerObject;
@@ -378,11 +383,18 @@ _mesa_GetQueryObjectivARB(GLuint id, GLenum pname, GLint *params)
if (!q->Ready)
ctx->Driver.WaitQuery(ctx, q);
/* if result is too large for returned type, clamp to max value */
- if (q->Result > 0x7fffffff) {
- *params = 0x7fffffff;
- }
- else {
- *params = (GLint)q->Result;
+ if (q->Target == GL_ANY_SAMPLES_PASSED) {
+ if (q->Result)
+ *params = GL_TRUE;
+ else
+ *params = GL_FALSE;
+ } else {
+ if (q->Result > 0x7fffffff) {
+ *params = 0x7fffffff;
+ }
+ else {
+ *params = (GLint)q->Result;
+ }
}
break;
case GL_QUERY_RESULT_AVAILABLE_ARB:
@@ -418,11 +430,18 @@ _mesa_GetQueryObjectuivARB(GLuint id, GLenum pname, GLuint *params)
if (!q->Ready)
ctx->Driver.WaitQuery(ctx, q);
/* if result is too large for returned type, clamp to max value */
- if (q->Result > 0xffffffff) {
- *params = 0xffffffff;
- }
- else {
- *params = (GLuint)q->Result;
+ if (q->Target == GL_ANY_SAMPLES_PASSED) {
+ if (q->Result)
+ *params = GL_TRUE;
+ else
+ *params = GL_FALSE;
+ } else {
+ if (q->Result > 0xffffffff) {
+ *params = 0xffffffff;
+ }
+ else {
+ *params = (GLuint)q->Result;
+ }
}
break;
case GL_QUERY_RESULT_AVAILABLE_ARB:
diff --git a/src/mesa/program/ir_to_mesa.cpp b/src/mesa/program/ir_to_mesa.cpp
index b274a961b28..490c4cab7ab 100644
--- a/src/mesa/program/ir_to_mesa.cpp
+++ b/src/mesa/program/ir_to_mesa.cpp
@@ -1569,7 +1569,13 @@ ir_to_mesa_visitor::visit(ir_dereference_record *ir)
break;
offset += type_size(struct_type->fields.structure[i].type);
}
- this->result.swizzle = swizzle_for_size(ir->type->vector_elements);
+
+ /* If the type is smaller than a vec4, replicate the last channel out. */
+ if (ir->type->is_scalar() || ir->type->is_vector())
+ this->result.swizzle = swizzle_for_size(ir->type->vector_elements);
+ else
+ this->result.swizzle = SWIZZLE_NOOP;
+
this->result.index += offset;
}
diff --git a/src/mesa/program/ir_to_mesa.h b/src/mesa/program/ir_to_mesa.h
index 7197615f949..7410e149735 100644
--- a/src/mesa/program/ir_to_mesa.h
+++ b/src/mesa/program/ir_to_mesa.h
@@ -25,8 +25,11 @@
extern "C" {
#endif
-#include "main/config.h"
-#include "main/mtypes.h"
+#include "main/glheader.h"
+
+struct gl_context;
+struct gl_shader;
+struct gl_shader_program;
void _mesa_glsl_compile_shader(struct gl_context *ctx, struct gl_shader *sh);
void _mesa_glsl_link_shader(struct gl_context *ctx, struct gl_shader_program *prog);
diff --git a/src/mesa/program/nvfragparse.h b/src/mesa/program/nvfragparse.h
index 3e85dd2c30b..088e7527d5b 100644
--- a/src/mesa/program/nvfragparse.h
+++ b/src/mesa/program/nvfragparse.h
@@ -30,7 +30,10 @@
#ifndef NVFRAGPARSE_H
#define NVFRAGPARSE_H
-#include "main/mtypes.h"
+#include "main/glheader.h"
+
+struct gl_context;
+struct gl_fragment_program;
extern void
_mesa_parse_nv_fragment_program(struct gl_context *ctx, GLenum target,
diff --git a/src/mesa/program/nvvertparse.h b/src/mesa/program/nvvertparse.h
index e98e867320f..7318e149416 100644
--- a/src/mesa/program/nvvertparse.h
+++ b/src/mesa/program/nvvertparse.h
@@ -29,7 +29,10 @@
#ifndef NVVERTPARSE_H
#define NVVERTPARSE_H
-#include "main/mtypes.h"
+#include "main/glheader.h"
+
+struct gl_context;
+struct gl_vertex_program;
extern void
_mesa_parse_nv_vertex_program(struct gl_context *ctx, GLenum target,
diff --git a/src/mesa/program/prog_cache.h b/src/mesa/program/prog_cache.h
index 4907ae3030e..01673348279 100644
--- a/src/mesa/program/prog_cache.h
+++ b/src/mesa/program/prog_cache.h
@@ -30,8 +30,9 @@
#define PROG_CACHE_H
-#include "main/mtypes.h"
+#include "main/glheader.h"
+struct gl_context;
/** Opaque type */
struct gl_program_cache;
diff --git a/src/mesa/program/prog_execute.c b/src/mesa/program/prog_execute.c
index 1d97a077f52..dd15e9a1ccd 100644
--- a/src/mesa/program/prog_execute.c
+++ b/src/mesa/program/prog_execute.c
@@ -1670,6 +1670,18 @@ _mesa_execute_program(struct gl_context * ctx,
fetch_texel(ctx, machine, inst, texcoord, lodBias, color);
+ if (DEBUG_PROG) {
+ printf("TXB (%g, %g, %g, %g) = texture[%d][%g %g %g %g]"
+ " bias %g\n",
+ color[0], color[1], color[2], color[3],
+ inst->TexSrcUnit,
+ texcoord[0],
+ texcoord[1],
+ texcoord[2],
+ texcoord[3],
+ lodBias);
+ }
+
store_vector4(inst, machine, color);
}
break;
diff --git a/src/mesa/program/prog_optimize.h b/src/mesa/program/prog_optimize.h
index 00f1080449b..463f5fc51c4 100644
--- a/src/mesa/program/prog_optimize.h
+++ b/src/mesa/program/prog_optimize.h
@@ -27,9 +27,10 @@
#include "main/config.h"
-#include "main/mtypes.h"
+#include "main/glheader.h"
+struct gl_context;
struct gl_program;
struct prog_instruction;
diff --git a/src/mesa/program/prog_statevars.h b/src/mesa/program/prog_statevars.h
index 009ebde0012..f2407af9c87 100644
--- a/src/mesa/program/prog_statevars.h
+++ b/src/mesa/program/prog_statevars.h
@@ -25,8 +25,10 @@
#ifndef PROG_STATEVARS_H
#define PROG_STATEVARS_H
-#include "main/mtypes.h"
+#include "main/glheader.h"
+struct gl_context;
+struct gl_program_parameter_list;
/**
* Number of STATE_* values we need to address any GL state.
diff --git a/src/mesa/state_tracker/st_atom_shader.c b/src/mesa/state_tracker/st_atom_shader.c
index 05442ef91b5..c311d043931 100644
--- a/src/mesa/state_tracker/st_atom_shader.c
+++ b/src/mesa/state_tracker/st_atom_shader.c
@@ -50,99 +50,6 @@
#include "st_program.h"
-
-/**
- * Translate fragment program if needed.
- */
-static void
-translate_fp(struct st_context *st,
- struct st_fragment_program *stfp)
-{
- if (!stfp->tgsi.tokens) {
- assert(stfp->Base.Base.NumInstructions > 0);
-
- st_translate_fragment_program(st, stfp);
- }
-}
-
-/*
- * Translate geometry program if needed.
- */
-static void
-translate_gp(struct st_context *st,
- struct st_geometry_program *stgp)
-{
- if (!stgp->tgsi.tokens) {
- assert(stgp->Base.Base.NumInstructions > 1);
-
- st_translate_geometry_program(st, stgp);
- }
-}
-
-/**
- * Find a translated vertex program that corresponds to stvp and
- * has outputs matched to stfp's inputs.
- * This performs vertex and fragment translation (to TGSI) when needed.
- */
-static struct st_vp_varient *
-find_translated_vp(struct st_context *st,
- struct st_vertex_program *stvp )
-{
- struct st_vp_varient *vpv;
- struct st_vp_varient_key key;
-
- /* Nothing in our key yet. This will change:
- */
- memset(&key, 0, sizeof key);
-
- /* When this is true, we will add an extra input to the vertex
- * shader translation (for edgeflags), an extra output with
- * edgeflag semantics, and extend the vertex shader to pass through
- * the input to the output. We'll need to use similar logic to set
- * up the extra vertex_element input for edgeflags.
- * _NEW_POLYGON, ST_NEW_EDGEFLAGS_DATA
- */
- key.passthrough_edgeflags = (st->vertdata_edgeflags && (
- st->ctx->Polygon.FrontMode != GL_FILL ||
- st->ctx->Polygon.BackMode != GL_FILL));
-
-
- /* Do we need to throw away old translations after a change in the
- * GL program string?
- */
- if (stvp->serialNo != stvp->lastSerialNo) {
- /* These may have changed if the program string changed.
- */
- st_prepare_vertex_program( st, stvp );
-
- /* We are now up-to-date:
- */
- stvp->lastSerialNo = stvp->serialNo;
- }
-
- /* See if we've got a translated vertex program whose outputs match
- * the fragment program's inputs.
- */
- for (vpv = stvp->varients; vpv; vpv = vpv->next) {
- if (memcmp(&vpv->key, &key, sizeof key) == 0) {
- break;
- }
- }
-
- /* No? Perform new translation here. */
- if (!vpv) {
- vpv = st_translate_vertex_program(st, stvp, &key);
- if (!vpv)
- return NULL;
-
- vpv->next = stvp->varients;
- stvp->varients = vpv;
- }
-
- return vpv;
-}
-
-
/**
* Return pointer to a pass-through fragment shader.
* This shader is used when a texture is missing/incomplete.
@@ -167,12 +74,16 @@ static void
update_fp( struct st_context *st )
{
struct st_fragment_program *stfp;
+ struct st_fp_variant_key key;
assert(st->ctx->FragmentProgram._Current);
stfp = st_fragment_program(st->ctx->FragmentProgram._Current);
assert(stfp->Base.Base.Target == GL_FRAGMENT_PROGRAM_ARB);
- translate_fp(st, stfp);
+ memset(&key, 0, sizeof(key));
+ key.st = st;
+
+ st->fp_variant = st_get_fp_variant(st, stfp, &key);
st_reference_fragprog(st, &st->fp, stfp);
@@ -182,7 +93,8 @@ update_fp( struct st_context *st )
cso_set_fragment_shader_handle(st->cso_context, fs);
}
else {
- cso_set_fragment_shader_handle(st->cso_context, stfp->driver_shader);
+ cso_set_fragment_shader_handle(st->cso_context,
+ st->fp_variant->driver_shader);
}
}
@@ -206,6 +118,7 @@ static void
update_vp( struct st_context *st )
{
struct st_vertex_program *stvp;
+ struct st_vp_variant_key key;
/* find active shader and params -- Should be covered by
* ST_NEW_VERTEX_PROGRAM
@@ -214,12 +127,26 @@ update_vp( struct st_context *st )
stvp = st_vertex_program(st->ctx->VertexProgram._Current);
assert(stvp->Base.Base.Target == GL_VERTEX_PROGRAM_ARB);
- st->vp_varient = find_translated_vp(st, stvp);
+ memset(&key, 0, sizeof key);
+ key.st = st; /* variants are per-context */
+
+ /* When this is true, we will add an extra input to the vertex
+ * shader translation (for edgeflags), an extra output with
+ * edgeflag semantics, and extend the vertex shader to pass through
+ * the input to the output. We'll need to use similar logic to set
+ * up the extra vertex_element input for edgeflags.
+ * _NEW_POLYGON, ST_NEW_EDGEFLAGS_DATA
+ */
+ key.passthrough_edgeflags = (st->vertdata_edgeflags && (
+ st->ctx->Polygon.FrontMode != GL_FILL ||
+ st->ctx->Polygon.BackMode != GL_FILL));
+
+ st->vp_variant = st_get_vp_variant(st, stvp, &key);
st_reference_vertprog(st, &st->vp, stvp);
cso_set_vertex_shader_handle(st->cso_context,
- st->vp_varient->driver_shader);
+ st->vp_variant->driver_shader);
st->vertex_result_to_slot = stvp->result_to_output;
}
@@ -231,14 +158,16 @@ const struct st_tracked_state st_update_vp = {
_NEW_POLYGON, /* mesa */
ST_NEW_VERTEX_PROGRAM | ST_NEW_EDGEFLAGS_DATA /* st */
},
- update_vp /* update */
+ update_vp /* update */
};
+
+
static void
update_gp( struct st_context *st )
{
-
struct st_geometry_program *stgp;
+ struct st_gp_variant_key key;
if (!st->ctx->GeometryProgram._Current) {
cso_set_geometry_shader_handle(st->cso_context, NULL);
@@ -248,18 +177,22 @@ update_gp( struct st_context *st )
stgp = st_geometry_program(st->ctx->GeometryProgram._Current);
assert(stgp->Base.Base.Target == MESA_GEOMETRY_PROGRAM);
- translate_gp(st, stgp);
+ memset(&key, 0, sizeof(key));
+ key.st = st;
+
+ st->gp_variant = st_get_gp_variant(st, stgp, &key);
st_reference_geomprog(st, &st->gp, stgp);
- cso_set_geometry_shader_handle(st->cso_context, stgp->driver_shader);
+ cso_set_geometry_shader_handle(st->cso_context,
+ st->gp_variant->driver_shader);
}
const struct st_tracked_state st_update_gp = {
- "st_update_gp", /* name */
- { /* dirty */
- 0, /* mesa */
- ST_NEW_GEOMETRY_PROGRAM /* st */
+ "st_update_gp", /* name */
+ { /* dirty */
+ 0, /* mesa */
+ ST_NEW_GEOMETRY_PROGRAM /* st */
},
- update_gp /* update */
+ update_gp /* update */
};
diff --git a/src/mesa/state_tracker/st_cb_accum.h b/src/mesa/state_tracker/st_cb_accum.h
index b8c9c350031..050a21483e4 100644
--- a/src/mesa/state_tracker/st_cb_accum.h
+++ b/src/mesa/state_tracker/st_cb_accum.h
@@ -30,7 +30,11 @@
#define ST_CB_ACCUM_H
-#include "main/mtypes.h"
+#include "main/mfeatures.h"
+
+struct dd_function_table;
+struct gl_context;
+struct gl_renderbuffer;
#if FEATURE_accum
diff --git a/src/mesa/state_tracker/st_cb_bitmap.c b/src/mesa/state_tracker/st_cb_bitmap.c
index f08697fe23b..516346c8c7a 100644
--- a/src/mesa/state_tracker/st_cb_bitmap.c
+++ b/src/mesa/state_tracker/st_cb_bitmap.c
@@ -185,48 +185,47 @@ find_free_bit(uint bitfield)
/**
* Combine basic bitmap fragment program with the user-defined program.
+ * \param st current context
+ * \param fpIn the incoming fragment program
+ * \param fpOut the new fragment program which does fragment culling
+ * \param bitmap_sampler sampler number for the bitmap texture
*/
-static struct st_fragment_program *
-combined_bitmap_fragment_program(struct gl_context *ctx)
+void
+st_make_bitmap_fragment_program(struct st_context *st,
+ struct gl_fragment_program *fpIn,
+ struct gl_fragment_program **fpOut,
+ GLuint *bitmap_sampler)
{
- struct st_context *st = st_context(ctx);
- struct st_fragment_program *stfp = st->fp;
-
- if (!stfp->bitmap_program) {
- /*
- * Generate new program which is the user-defined program prefixed
- * with the bitmap sampler/kill instructions.
- */
- struct st_fragment_program *bitmap_prog;
- uint sampler;
-
- sampler = find_free_bit(st->fp->Base.Base.SamplersUsed);
- bitmap_prog = make_bitmap_fragment_program(ctx, sampler);
+ struct st_fragment_program *bitmap_prog;
+ struct gl_program *newProg;
+ uint sampler;
- stfp->bitmap_program = (struct st_fragment_program *)
- _mesa_combine_programs(ctx,
- &bitmap_prog->Base.Base, &stfp->Base.Base);
- stfp->bitmap_program->bitmap_sampler = sampler;
+ /*
+ * Generate new program which is the user-defined program prefixed
+ * with the bitmap sampler/kill instructions.
+ */
+ sampler = find_free_bit(fpIn->Base.SamplersUsed);
+ bitmap_prog = make_bitmap_fragment_program(st->ctx, sampler);
- /* done with this after combining */
- st_reference_fragprog(st, &bitmap_prog, NULL);
+ newProg = _mesa_combine_programs(st->ctx,
+ &bitmap_prog->Base.Base,
+ &fpIn->Base);
+ /* done with this after combining */
+ st_reference_fragprog(st, &bitmap_prog, NULL);
#if 0
- {
- struct gl_program *p = &stfp->bitmap_program->Base.Base;
- printf("Combined bitmap program:\n");
- _mesa_print_program(p);
- printf("InputsRead: 0x%x\n", p->InputsRead);
- printf("OutputsWritten: 0x%x\n", p->OutputsWritten);
- _mesa_print_parameter_list(p->Parameters);
- }
-#endif
-
- /* translate to TGSI tokens */
- st_translate_fragment_program(st, stfp->bitmap_program);
+ {
+ printf("Combined bitmap program:\n");
+ _mesa_print_program(newProg);
+ printf("InputsRead: 0x%x\n", newProg->InputsRead);
+ printf("OutputsWritten: 0x%x\n", newProg->OutputsWritten);
+ _mesa_print_parameter_list(newProg->Parameters);
}
+#endif
- return stfp->bitmap_program;
+ /* return results */
+ *fpOut = (struct gl_fragment_program *) newProg;
+ *bitmap_sampler = sampler;
}
@@ -349,7 +348,8 @@ setup_bitmap_vertex_data(struct st_context *st, bool normalized,
if (!st->bitmap.vbuf) {
st->bitmap.vbuf = pipe_buffer_create(pipe->screen,
PIPE_BIND_VERTEX_BUFFER,
- max_slots * sizeof(st->bitmap.vertices));
+ max_slots *
+ sizeof(st->bitmap.vertices));
}
/* Positions are in clip coords since we need to do clipping in case
@@ -389,10 +389,11 @@ setup_bitmap_vertex_data(struct st_context *st, bool normalized,
/* put vertex data into vbuf */
pipe_buffer_write_nooverlap(st->pipe,
- st->bitmap.vbuf,
- st->bitmap.vbuf_slot * sizeof st->bitmap.vertices,
- sizeof st->bitmap.vertices,
- st->bitmap.vertices);
+ st->bitmap.vbuf,
+ st->bitmap.vbuf_slot
+ * sizeof(st->bitmap.vertices),
+ sizeof st->bitmap.vertices,
+ st->bitmap.vertices);
return st->bitmap.vbuf_slot++ * sizeof st->bitmap.vertices;
}
@@ -411,11 +412,16 @@ draw_bitmap_quad(struct gl_context *ctx, GLint x, GLint y, GLfloat z,
struct st_context *st = st_context(ctx);
struct pipe_context *pipe = st->pipe;
struct cso_context *cso = st->cso_context;
- struct st_fragment_program *stfp;
+ struct st_fp_variant *fpv;
+ struct st_fp_variant_key key;
GLuint maxSize;
GLuint offset;
- stfp = combined_bitmap_fragment_program(ctx);
+ memset(&key, 0, sizeof(key));
+ key.st = st;
+ key.bitmap = GL_TRUE;
+
+ fpv = st_get_fp_variant(st, st->fp, &key);
/* As an optimization, Mesa's fragment programs will sometimes get the
* primary color from a statevar/constant rather than a varying variable.
@@ -428,7 +434,7 @@ draw_bitmap_quad(struct gl_context *ctx, GLint x, GLint y, GLfloat z,
GLfloat colorSave[4];
COPY_4V(colorSave, ctx->Current.Attrib[VERT_ATTRIB_COLOR0]);
COPY_4V(ctx->Current.Attrib[VERT_ATTRIB_COLOR0], color);
- st_upload_constants(st, stfp->Base.Base.Parameters, PIPE_SHADER_FRAGMENT);
+ st_upload_constants(st, fpv->parameters, PIPE_SHADER_FRAGMENT);
COPY_4V(ctx->Current.Attrib[VERT_ATTRIB_COLOR0], colorSave);
}
@@ -437,7 +443,8 @@ draw_bitmap_quad(struct gl_context *ctx, GLint x, GLint y, GLfloat z,
/* XXX if the bitmap is larger than the max texture size, break
* it up into chunks.
*/
- maxSize = 1 << (pipe->screen->get_param(pipe->screen, PIPE_CAP_MAX_TEXTURE_2D_LEVELS) - 1);
+ maxSize = 1 << (pipe->screen->get_param(pipe->screen,
+ PIPE_CAP_MAX_TEXTURE_2D_LEVELS) - 1);
assert(width <= (GLsizei)maxSize);
assert(height <= (GLsizei)maxSize);
@@ -454,7 +461,7 @@ draw_bitmap_quad(struct gl_context *ctx, GLint x, GLint y, GLfloat z,
cso_set_rasterizer(cso, &st->bitmap.rasterizer);
/* fragment shader state: TEX lookup program */
- cso_set_fragment_shader_handle(cso, stfp->driver_shader);
+ cso_set_fragment_shader_handle(cso, fpv->driver_shader);
/* vertex shader state: position + texcoord pass-through */
cso_set_vertex_shader_handle(cso, st->bitmap.vs);
@@ -462,21 +469,22 @@ draw_bitmap_quad(struct gl_context *ctx, GLint x, GLint y, GLfloat z,
/* user samplers, plus our bitmap sampler */
{
struct pipe_sampler_state *samplers[PIPE_MAX_SAMPLERS];
- uint num = MAX2(stfp->bitmap_sampler + 1, st->state.num_samplers);
+ uint num = MAX2(fpv->bitmap_sampler + 1, st->state.num_samplers);
uint i;
for (i = 0; i < st->state.num_samplers; i++) {
samplers[i] = &st->state.samplers[i];
}
- samplers[stfp->bitmap_sampler] = &st->bitmap.samplers[sv->texture->target != PIPE_TEXTURE_RECT];
+ samplers[fpv->bitmap_sampler] =
+ &st->bitmap.samplers[sv->texture->target != PIPE_TEXTURE_RECT];
cso_set_samplers(cso, num, (const struct pipe_sampler_state **) samplers);
}
/* user textures, plus the bitmap texture */
{
struct pipe_sampler_view *sampler_views[PIPE_MAX_SAMPLERS];
- uint num = MAX2(stfp->bitmap_sampler + 1, st->state.num_textures);
+ uint num = MAX2(fpv->bitmap_sampler + 1, st->state.num_textures);
memcpy(sampler_views, st->state.sampler_views, sizeof(sampler_views));
- sampler_views[stfp->bitmap_sampler] = sv;
+ sampler_views[fpv->bitmap_sampler] = sv;
cso_set_fragment_sampler_views(cso, num, sampler_views);
}
@@ -504,7 +512,9 @@ draw_bitmap_quad(struct gl_context *ctx, GLint x, GLint y, GLfloat z,
z = z * 2.0 - 1.0;
/* draw textured quad */
- offset = setup_bitmap_vertex_data(st, sv->texture->target != PIPE_TEXTURE_RECT, x, y, width, height, z, color);
+ offset = setup_bitmap_vertex_data(st,
+ sv->texture->target != PIPE_TEXTURE_RECT,
+ x, y, width, height, z, color);
util_draw_vertex_buffer(pipe, st->bitmap.vbuf, offset,
PIPE_PRIM_TRIANGLE_FAN,
@@ -573,6 +583,9 @@ print_cache(const struct bitmap_cache *cache)
}
+/**
+ * Create gallium pipe_transfer object for the bitmap cache.
+ */
static void
create_cache_trans(struct st_context *st)
{
@@ -651,7 +664,9 @@ st_flush_bitmap_cache(struct st_context *st)
}
}
-/* Flush bitmap cache and release vertex buffer.
+
+/**
+ * Flush bitmap cache and release vertex buffer.
*/
void
st_flush_bitmap( struct st_context *st )
@@ -737,7 +752,8 @@ accum_bitmap(struct st_context *st,
* Called via ctx->Driver.Bitmap()
*/
static void
-st_Bitmap(struct gl_context *ctx, GLint x, GLint y, GLsizei width, GLsizei height,
+st_Bitmap(struct gl_context *ctx, GLint x, GLint y,
+ GLsizei width, GLsizei height,
const struct gl_pixelstore_attrib *unpack, const GLubyte *bitmap )
{
struct st_context *st = st_context(ctx);
@@ -764,7 +780,8 @@ st_Bitmap(struct gl_context *ctx, GLint x, GLint y, GLsizei width, GLsizei heigh
pt = make_bitmap_texture(ctx, width, height, unpack, bitmap);
if (pt) {
- struct pipe_sampler_view *sv = st_create_texture_sampler_view(st->pipe, pt);
+ struct pipe_sampler_view *sv =
+ st_create_texture_sampler_view(st->pipe, pt);
assert(pt->target == PIPE_TEXTURE_2D || pt->target == PIPE_TEXTURE_RECT);
@@ -814,15 +831,18 @@ st_init_bitmap(struct st_context *st)
st->bitmap.rasterizer.gl_rasterization_rules = 1;
/* find a usable texture format */
- if (screen->is_format_supported(screen, PIPE_FORMAT_I8_UNORM, PIPE_TEXTURE_2D, 0,
+ if (screen->is_format_supported(screen, PIPE_FORMAT_I8_UNORM,
+ PIPE_TEXTURE_2D, 0,
PIPE_BIND_SAMPLER_VIEW, 0)) {
st->bitmap.tex_format = PIPE_FORMAT_I8_UNORM;
}
- else if (screen->is_format_supported(screen, PIPE_FORMAT_A8_UNORM, PIPE_TEXTURE_2D, 0,
+ else if (screen->is_format_supported(screen, PIPE_FORMAT_A8_UNORM,
+ PIPE_TEXTURE_2D, 0,
PIPE_BIND_SAMPLER_VIEW, 0)) {
st->bitmap.tex_format = PIPE_FORMAT_A8_UNORM;
}
- else if (screen->is_format_supported(screen, PIPE_FORMAT_L8_UNORM, PIPE_TEXTURE_2D, 0,
+ else if (screen->is_format_supported(screen, PIPE_FORMAT_L8_UNORM,
+ PIPE_TEXTURE_2D, 0,
PIPE_BIND_SAMPLER_VIEW, 0)) {
st->bitmap.tex_format = PIPE_FORMAT_L8_UNORM;
}
@@ -845,8 +865,6 @@ st_destroy_bitmap(struct st_context *st)
struct pipe_context *pipe = st->pipe;
struct bitmap_cache *cache = st->bitmap.cache;
-
-
if (st->bitmap.vs) {
cso_delete_vertex_shader(st->cso_context, st->bitmap.vs);
st->bitmap.vs = NULL;
diff --git a/src/mesa/state_tracker/st_cb_bitmap.h b/src/mesa/state_tracker/st_cb_bitmap.h
index d04b2b67795..2bd63b9b741 100644
--- a/src/mesa/state_tracker/st_cb_bitmap.h
+++ b/src/mesa/state_tracker/st_cb_bitmap.h
@@ -34,6 +34,8 @@
struct dd_function_table;
struct st_context;
+struct gl_fragment_program;
+struct st_fragment_program;
#if FEATURE_drawpix
@@ -47,6 +49,12 @@ extern void
st_destroy_bitmap(struct st_context *st);
extern void
+st_make_bitmap_fragment_program(struct st_context *st,
+ struct gl_fragment_program *fpIn,
+ struct gl_fragment_program **fpOut,
+ GLuint *bitmap_sampler);
+
+extern void
st_flush_bitmap_cache(struct st_context *st);
/* Flush bitmap cache and release vertex buffer. Needed at end of
diff --git a/src/mesa/state_tracker/st_cb_bufferobjects.c b/src/mesa/state_tracker/st_cb_bufferobjects.c
index 8b60f9040d0..d4d9af4ada3 100644
--- a/src/mesa/state_tracker/st_cb_bufferobjects.c
+++ b/src/mesa/state_tracker/st_cb_bufferobjects.c
@@ -360,7 +360,7 @@ st_bufferobj_unmap(struct gl_context *ctx, GLenum target, struct gl_buffer_objec
struct st_buffer_object *st_obj = st_buffer_object(obj);
if (obj->Length)
- pipe_buffer_unmap(pipe, st_obj->buffer, st_obj->transfer);
+ pipe_buffer_unmap(pipe, st_obj->transfer);
st_obj->transfer = NULL;
obj->Pointer = NULL;
@@ -409,8 +409,8 @@ st_copy_buffer_subdata(struct gl_context *ctx,
if (srcPtr && dstPtr)
memcpy(dstPtr + writeOffset, srcPtr + readOffset, size);
- pipe_buffer_unmap(pipe, srcObj->buffer, src_transfer);
- pipe_buffer_unmap(pipe, dstObj->buffer, dst_transfer);
+ pipe_buffer_unmap(pipe, src_transfer);
+ pipe_buffer_unmap(pipe, dst_transfer);
}
diff --git a/src/mesa/state_tracker/st_cb_drawpixels.c b/src/mesa/state_tracker/st_cb_drawpixels.c
index c9786024575..1fc47688e4a 100644
--- a/src/mesa/state_tracker/st_cb_drawpixels.c
+++ b/src/mesa/state_tracker/st_cb_drawpixels.c
@@ -94,88 +94,61 @@ is_passthrough_program(const struct gl_fragment_program *prog)
/**
* Make fragment shader for glDraw/CopyPixels. This shader is made
* by combining the pixel transfer shader with the user-defined shader.
- * \return pointer to Gallium driver fragment shader
+ * \param fpIn the current/incoming fragment program
+ * \param fpOut returns the combined fragment program
*/
-static void *
-combined_drawpix_fragment_program(struct gl_context *ctx)
+void
+st_make_drawpix_fragment_program(struct st_context *st,
+ struct gl_fragment_program *fpIn,
+ struct gl_fragment_program **fpOut)
{
- struct st_context *st = st_context(ctx);
- struct st_fragment_program *stfp;
+ struct gl_program *newProg;
- if (st->pixel_xfer.program->serialNo == st->pixel_xfer.xfer_prog_sn
- && st->fp->serialNo == st->pixel_xfer.user_prog_sn) {
- /* the pixel tranfer program has not changed and the user-defined
- * program has not changed, so re-use the combined program.
- */
- stfp = st->pixel_xfer.combined_prog;
+ if (is_passthrough_program(fpIn)) {
+ newProg = (struct gl_program *) _mesa_clone_fragment_program(st->ctx,
+ &st->pixel_xfer.program->Base);
}
else {
- /* Concatenate the pixel transfer program with the current user-
- * defined program.
- */
- if (is_passthrough_program(&st->fp->Base)) {
- stfp = (struct st_fragment_program *)
- _mesa_clone_fragment_program(ctx, &st->pixel_xfer.program->Base);
- }
- else {
#if 0
- printf("Base program:\n");
- _mesa_print_program(&st->fp->Base.Base);
- printf("DrawPix program:\n");
- _mesa_print_program(&st->pixel_xfer.program->Base.Base);
+ /* debug */
+ printf("Base program:\n");
+ _mesa_print_program(&fpIn->Base);
+ printf("DrawPix program:\n");
+ _mesa_print_program(&st->pixel_xfer.program->Base.Base);
#endif
- stfp = (struct st_fragment_program *)
- _mesa_combine_programs(ctx,
- &st->pixel_xfer.program->Base.Base,
- &st->fp->Base.Base);
- }
+ newProg = _mesa_combine_programs(st->ctx,
+ &st->pixel_xfer.program->Base.Base,
+ &fpIn->Base);
+ }
#if 0
- {
- struct gl_program *p = &stfp->Base.Base;
- printf("Combined DrawPixels program:\n");
- _mesa_print_program(p);
- printf("InputsRead: 0x%x\n", p->InputsRead);
- printf("OutputsWritten: 0x%x\n", p->OutputsWritten);
- _mesa_print_parameter_list(p->Parameters);
- }
+ /* debug */
+ printf("Combined DrawPixels program:\n");
+ _mesa_print_program(newProg);
+ printf("InputsRead: 0x%x\n", newProg->InputsRead);
+ printf("OutputsWritten: 0x%x\n", newProg->OutputsWritten);
+ _mesa_print_parameter_list(newProg->Parameters);
#endif
- /* translate to TGSI tokens */
- st_translate_fragment_program(st, stfp);
-
- /* save new program, update serial numbers */
- st->pixel_xfer.xfer_prog_sn = st->pixel_xfer.program->serialNo;
- st->pixel_xfer.user_prog_sn = st->fp->serialNo;
- st->pixel_xfer.combined_prog_sn = stfp->serialNo;
- /* can't reference new program directly, already have a reference on it */
- st_reference_fragprog(st, &st->pixel_xfer.combined_prog, NULL);
- st->pixel_xfer.combined_prog = stfp;
- }
-
- /* Ideally we'd have updated the pipe constants during the normal
- * st/atom mechanism. But we can't since this is specific to glDrawPixels.
- */
- st_upload_constants(st, stfp->Base.Base.Parameters, PIPE_SHADER_FRAGMENT);
-
- return stfp->driver_shader;
+ *fpOut = (struct gl_fragment_program *) newProg;
}
/**
- * Create fragment shader that does a TEX() instruction to get a Z and/or
+ * Create fragment program that does a TEX() instruction to get a Z and/or
* stencil value value, then writes to FRAG_RESULT_DEPTH/FRAG_RESULT_STENCIL.
* Used for glDrawPixels(GL_DEPTH_COMPONENT / GL_STENCIL_INDEX).
* Pass fragment color through as-is.
- * \return pointer to the Gallium driver fragment shader
+ * \return pointer to the gl_fragment program
*/
-static void *
-make_fragment_shader_z_stencil(struct st_context *st, GLboolean write_depth,
- GLboolean write_stencil)
+struct gl_fragment_program *
+st_make_drawpix_z_stencil_program(struct st_context *st,
+ GLboolean write_depth,
+ GLboolean write_stencil)
{
struct gl_context *ctx = st->ctx;
struct gl_program *p;
- struct st_fragment_program *stp;
+ struct gl_fragment_program *fp;
GLuint ic = 0;
const GLuint shaderIndex = write_depth * 2 + write_stencil;
@@ -183,7 +156,7 @@ make_fragment_shader_z_stencil(struct st_context *st, GLboolean write_depth,
if (st->drawpix.shaders[shaderIndex]) {
/* already have the proper shader */
- return st->drawpix.shaders[shaderIndex]->driver_shader;
+ return st->drawpix.shaders[shaderIndex];
}
/*
@@ -245,18 +218,15 @@ make_fragment_shader_z_stencil(struct st_context *st, GLboolean write_depth,
if (write_stencil)
p->SamplersUsed |= 1 << 1;
- stp = st_fragment_program((struct gl_fragment_program *) p);
+ fp = (struct gl_fragment_program *) p;
/* save the new shader */
- st->drawpix.shaders[shaderIndex] = stp;
+ st->drawpix.shaders[shaderIndex] = fp;
- st_translate_fragment_program(st, stp);
-
- return stp->driver_shader;
+ return fp;
}
-
/**
* Create a simple vertex shader that just passes through the
* vertex position and texcoord (and optionally, color).
@@ -873,6 +843,61 @@ draw_stencil_pixels(struct gl_context *ctx, GLint x, GLint y,
/**
+ * Get fragment program variant for a glDrawPixels or glCopyPixels
+ * command for RGBA data.
+ */
+static struct st_fp_variant *
+get_color_fp_variant(struct st_context *st)
+{
+ struct gl_context *ctx = st->ctx;
+ struct st_fp_variant_key key;
+ struct st_fp_variant *fpv;
+
+ memset(&key, 0, sizeof(key));
+
+ key.st = st;
+ key.drawpixels = 1;
+ key.scaleAndBias = (ctx->Pixel.RedBias != 0.0 ||
+ ctx->Pixel.RedScale != 1.0 ||
+ ctx->Pixel.GreenBias != 0.0 ||
+ ctx->Pixel.GreenScale != 1.0 ||
+ ctx->Pixel.BlueBias != 0.0 ||
+ ctx->Pixel.BlueScale != 1.0 ||
+ ctx->Pixel.AlphaBias != 0.0 ||
+ ctx->Pixel.AlphaScale != 1.0);
+ key.pixelMaps = ctx->Pixel.MapColorFlag;
+
+ fpv = st_get_fp_variant(st, st->fp, &key);
+
+ return fpv;
+}
+
+
+/**
+ * Get fragment program variant for a glDrawPixels or glCopyPixels
+ * command for depth/stencil data.
+ */
+static struct st_fp_variant *
+get_depth_stencil_fp_variant(struct st_context *st, GLboolean write_depth,
+ GLboolean write_stencil)
+{
+ struct st_fp_variant_key key;
+ struct st_fp_variant *fpv;
+
+ memset(&key, 0, sizeof(key));
+
+ key.st = st;
+ key.drawpixels = 1;
+ key.drawpixels_z = write_depth;
+ key.drawpixels_stencil = write_stencil;
+
+ fpv = st_get_fp_variant(st, st->fp, &key);
+
+ return fpv;
+}
+
+
+/**
* Called via ctx->Driver.DrawPixels()
*/
static void
@@ -889,6 +914,7 @@ st_DrawPixels(struct gl_context *ctx, GLint x, GLint y,
struct pipe_sampler_view *sv[2];
int num_sampler_view = 1;
enum pipe_format stencil_format = PIPE_FORMAT_NONE;
+ struct st_fp_variant *fpv;
if (format == GL_DEPTH_STENCIL)
write_stencil = write_depth = GL_TRUE;
@@ -921,14 +947,25 @@ st_DrawPixels(struct gl_context *ctx, GLint x, GLint y,
st_validate_state(st);
+ /*
+ * Get vertex/fragment shaders
+ */
if (write_depth || write_stencil) {
- driver_fp = make_fragment_shader_z_stencil(st, write_depth, write_stencil);
+ fpv = get_depth_stencil_fp_variant(st, write_depth, write_stencil);
+
+ driver_fp = fpv->driver_shader;
+
driver_vp = make_passthrough_vertex_shader(st, GL_TRUE);
+
color = ctx->Current.RasterColor;
}
else {
- driver_fp = combined_drawpix_fragment_program(ctx);
+ fpv = get_color_fp_variant(st);
+
+ driver_fp = fpv->driver_shader;
+
driver_vp = make_passthrough_vertex_shader(st, GL_FALSE);
+
color = NULL;
if (st->pixel_xfer.pixelmap_enabled) {
sv[1] = st->pixel_xfer.pixelmap_sampler_view;
@@ -936,6 +973,9 @@ st_DrawPixels(struct gl_context *ctx, GLint x, GLint y,
}
}
+ /* update fragment program constants */
+ st_upload_constants(st, fpv->parameters, PIPE_SHADER_FRAGMENT);
+
/* draw with textured quad */
{
struct pipe_resource *pt
@@ -1116,6 +1156,7 @@ st_CopyPixels(struct gl_context *ctx, GLint srcx, GLint srcy,
GLint readX, readY, readW, readH;
GLuint sample_count;
struct gl_pixelstore_attrib pack = ctx->DefaultPacking;
+ struct st_fp_variant *fpv;
st_validate_state(st);
@@ -1125,11 +1166,18 @@ st_CopyPixels(struct gl_context *ctx, GLint srcx, GLint srcy,
return;
}
+ /*
+ * Get vertex/fragment shaders
+ */
if (type == GL_COLOR) {
rbRead = st_get_color_read_renderbuffer(ctx);
color = NULL;
- driver_fp = combined_drawpix_fragment_program(ctx);
+
+ fpv = get_color_fp_variant(st);
+ driver_fp = fpv->driver_shader;
+
driver_vp = make_passthrough_vertex_shader(st, GL_FALSE);
+
if (st->pixel_xfer.pixelmap_enabled) {
sv[1] = st->pixel_xfer.pixelmap_sampler_view;
num_sampler_view++;
@@ -1139,10 +1187,17 @@ st_CopyPixels(struct gl_context *ctx, GLint srcx, GLint srcy,
assert(type == GL_DEPTH);
rbRead = st_renderbuffer(ctx->ReadBuffer->_DepthBuffer);
color = ctx->Current.Attrib[VERT_ATTRIB_COLOR0];
- driver_fp = make_fragment_shader_z_stencil(st, GL_TRUE, GL_FALSE);
+
+ fpv = get_depth_stencil_fp_variant(st, GL_TRUE, GL_FALSE);
+ driver_fp = fpv->driver_shader;
+
driver_vp = make_passthrough_vertex_shader(st, GL_TRUE);
}
+ /* update fragment program constants */
+ st_upload_constants(st, fpv->parameters, PIPE_SHADER_FRAGMENT);
+
+
if (rbRead->Base.Wrapped)
rbRead = st_renderbuffer(rbRead->Base.Wrapped);
@@ -1294,7 +1349,7 @@ st_destroy_drawpix(struct st_context *st)
for (i = 0; i < Elements(st->drawpix.shaders); i++) {
if (st->drawpix.shaders[i])
- st_reference_fragprog(st, &st->drawpix.shaders[i], NULL);
+ _mesa_reference_fragprog(st->ctx, &st->drawpix.shaders[i], NULL);
}
st_reference_fragprog(st, &st->pixel_xfer.combined_prog, NULL);
diff --git a/src/mesa/state_tracker/st_cb_drawpixels.h b/src/mesa/state_tracker/st_cb_drawpixels.h
index 575f169e08e..8f73e626240 100644
--- a/src/mesa/state_tracker/st_cb_drawpixels.h
+++ b/src/mesa/state_tracker/st_cb_drawpixels.h
@@ -42,6 +42,16 @@ extern void st_init_drawpixels_functions(struct dd_function_table *functions);
extern void
st_destroy_drawpix(struct st_context *st);
+extern void
+st_make_drawpix_fragment_program(struct st_context *st,
+ struct gl_fragment_program *fpIn,
+ struct gl_fragment_program **fpOut);
+
+extern struct gl_fragment_program *
+st_make_drawpix_z_stencil_program(struct st_context *st,
+ GLboolean write_depth,
+ GLboolean write_stencil);
+
#else
static INLINE void
diff --git a/src/mesa/state_tracker/st_cb_drawtex.c b/src/mesa/state_tracker/st_cb_drawtex.c
index 6cad7d3216e..22a5ed425e5 100644
--- a/src/mesa/state_tracker/st_cb_drawtex.c
+++ b/src/mesa/state_tracker/st_cb_drawtex.c
@@ -220,7 +220,7 @@ st_DrawTex(struct gl_context *ctx, GLfloat x, GLfloat y, GLfloat z,
}
}
- pipe_buffer_unmap(pipe, vbuffer, vbuffer_transfer);
+ pipe_buffer_unmap(pipe, vbuffer_transfer);
#undef SET_ATTRIB
}
diff --git a/src/mesa/state_tracker/st_cb_program.c b/src/mesa/state_tracker/st_cb_program.c
index 4d83fcc6ccb..32694975d17 100644
--- a/src/mesa/state_tracker/st_cb_program.c
+++ b/src/mesa/state_tracker/st_cb_program.c
@@ -46,16 +46,13 @@
#include "st_cb_program.h"
-static GLuint SerialNo = 1;
-
/**
* Called via ctx->Driver.BindProgram() to bind an ARB vertex or
* fragment program.
*/
-static void st_bind_program( struct gl_context *ctx,
- GLenum target,
- struct gl_program *prog )
+static void
+st_bind_program(struct gl_context *ctx, GLenum target, struct gl_program *prog)
{
struct st_context *st = st_context(ctx);
@@ -77,7 +74,8 @@ static void st_bind_program( struct gl_context *ctx,
* Called via ctx->Driver.UseProgram() to bind a linked GLSL program
* (vertex shader + fragment shader).
*/
-static void st_use_program( struct gl_context *ctx, struct gl_shader_program *shProg)
+static void
+st_use_program(struct gl_context *ctx, struct gl_shader_program *shProg)
{
struct st_context *st = st_context(ctx);
@@ -87,48 +85,28 @@ static void st_use_program( struct gl_context *ctx, struct gl_shader_program *sh
}
-
/**
* Called via ctx->Driver.NewProgram() to allocate a new vertex or
* fragment program.
*/
-static struct gl_program *st_new_program( struct gl_context *ctx,
- GLenum target,
- GLuint id )
+static struct gl_program *
+st_new_program(struct gl_context *ctx, GLenum target, GLuint id)
{
switch (target) {
case GL_VERTEX_PROGRAM_ARB: {
struct st_vertex_program *prog = ST_CALLOC_STRUCT(st_vertex_program);
-
- prog->serialNo = SerialNo++;
-
- return _mesa_init_vertex_program( ctx,
- &prog->Base,
- target,
- id );
+ return _mesa_init_vertex_program(ctx, &prog->Base, target, id);
}
case GL_FRAGMENT_PROGRAM_ARB:
case GL_FRAGMENT_PROGRAM_NV: {
struct st_fragment_program *prog = ST_CALLOC_STRUCT(st_fragment_program);
-
- prog->serialNo = SerialNo++;
-
- return _mesa_init_fragment_program( ctx,
- &prog->Base,
- target,
- id );
+ return _mesa_init_fragment_program(ctx, &prog->Base, target, id);
}
case MESA_GEOMETRY_PROGRAM: {
struct st_geometry_program *prog = ST_CALLOC_STRUCT(st_geometry_program);
-
- prog->serialNo = SerialNo++;
-
- return _mesa_init_geometry_program( ctx,
- &prog->Base,
- target,
- id );
+ return _mesa_init_geometry_program(ctx, &prog->Base, target, id);
}
default:
@@ -138,7 +116,10 @@ static struct gl_program *st_new_program( struct gl_context *ctx,
}
-void
+/**
+ * Called via ctx->Driver.DeleteProgram()
+ */
+static void
st_delete_program(struct gl_context *ctx, struct gl_program *prog)
{
struct st_context *st = st_context(ctx);
@@ -147,17 +128,15 @@ st_delete_program(struct gl_context *ctx, struct gl_program *prog)
case GL_VERTEX_PROGRAM_ARB:
{
struct st_vertex_program *stvp = (struct st_vertex_program *) prog;
- st_vp_release_varients( st, stvp );
+ st_release_vp_variants( st, stvp );
}
break;
case MESA_GEOMETRY_PROGRAM:
{
- struct st_geometry_program *stgp = (struct st_geometry_program *) prog;
+ struct st_geometry_program *stgp =
+ (struct st_geometry_program *) prog;
- if (stgp->driver_shader) {
- cso_delete_geometry_shader(st->cso_context, stgp->driver_shader);
- stgp->driver_shader = NULL;
- }
+ st_release_gp_variants(st, stgp);
if (stgp->tgsi.tokens) {
st_free_tokens((void *) stgp->tgsi.tokens);
@@ -167,23 +146,15 @@ st_delete_program(struct gl_context *ctx, struct gl_program *prog)
break;
case GL_FRAGMENT_PROGRAM_ARB:
{
- struct st_fragment_program *stfp = (struct st_fragment_program *) prog;
+ struct st_fragment_program *stfp =
+ (struct st_fragment_program *) prog;
- if (stfp->driver_shader) {
- cso_delete_fragment_shader(st->cso_context, stfp->driver_shader);
- stfp->driver_shader = NULL;
- }
+ st_release_fp_variants(st, stfp);
if (stfp->tgsi.tokens) {
st_free_tokens(stfp->tgsi.tokens);
stfp->tgsi.tokens = NULL;
}
-
- if (stfp->bitmap_program) {
- struct gl_program *prg = &stfp->bitmap_program->Base.Base;
- _mesa_reference_program(ctx, &prg, NULL);
- stfp->bitmap_program = NULL;
- }
}
break;
default:
@@ -195,15 +166,25 @@ st_delete_program(struct gl_context *ctx, struct gl_program *prog)
}
-static GLboolean st_is_program_native( struct gl_context *ctx,
- GLenum target,
- struct gl_program *prog )
+/**
+ * Called via ctx->Driver.IsProgramNative()
+ */
+static GLboolean
+st_is_program_native(struct gl_context *ctx,
+ GLenum target,
+ struct gl_program *prog)
{
return GL_TRUE;
}
-static GLboolean st_program_string_notify( struct gl_context *ctx,
+/**
+ * Called via ctx->Driver.ProgramStringNotify()
+ * Called when the program's text/code is changed. We have to free
+ * all shader variants and corresponding gallium shaders when this happens.
+ */
+static GLboolean
+st_program_string_notify( struct gl_context *ctx,
GLenum target,
struct gl_program *prog )
{
@@ -212,12 +193,7 @@ static GLboolean st_program_string_notify( struct gl_context *ctx,
if (target == GL_FRAGMENT_PROGRAM_ARB) {
struct st_fragment_program *stfp = (struct st_fragment_program *) prog;
- stfp->serialNo++;
-
- if (stfp->driver_shader) {
- cso_delete_fragment_shader(st->cso_context, stfp->driver_shader);
- stfp->driver_shader = NULL;
- }
+ st_release_fp_variants(st, stfp);
if (stfp->tgsi.tokens) {
st_free_tokens(stfp->tgsi.tokens);
@@ -230,12 +206,7 @@ static GLboolean st_program_string_notify( struct gl_context *ctx,
else if (target == MESA_GEOMETRY_PROGRAM) {
struct st_geometry_program *stgp = (struct st_geometry_program *) prog;
- stgp->serialNo++;
-
- if (stgp->driver_shader) {
- cso_delete_geometry_shader(st->cso_context, stgp->driver_shader);
- stgp->driver_shader = NULL;
- }
+ st_release_gp_variants(st, stgp);
if (stgp->tgsi.tokens) {
st_free_tokens((void *) stgp->tgsi.tokens);
@@ -248,9 +219,7 @@ static GLboolean st_program_string_notify( struct gl_context *ctx,
else if (target == GL_VERTEX_PROGRAM_ARB) {
struct st_vertex_program *stvp = (struct st_vertex_program *) prog;
- stvp->serialNo++;
-
- st_vp_release_varients( st, stvp );
+ st_release_vp_variants( st, stvp );
if (st->vp == stvp)
st->dirty.st |= ST_NEW_VERTEX_PROGRAM;
@@ -261,8 +230,11 @@ static GLboolean st_program_string_notify( struct gl_context *ctx,
}
-
-void st_init_program_functions(struct dd_function_table *functions)
+/**
+ * Plug in the program and shader-related device driver functions.
+ */
+void
+st_init_program_functions(struct dd_function_table *functions)
{
functions->BindProgram = st_bind_program;
functions->UseProgram = st_use_program;
diff --git a/src/mesa/state_tracker/st_cb_program.h b/src/mesa/state_tracker/st_cb_program.h
index 004afb6d812..091a4439c48 100644
--- a/src/mesa/state_tracker/st_cb_program.h
+++ b/src/mesa/state_tracker/st_cb_program.h
@@ -29,15 +29,10 @@
#define ST_CB_PROGRAM_H
-#include "main/mtypes.h"
-
struct dd_function_table;
extern void
st_init_program_functions(struct dd_function_table *functions);
-extern void
-st_delete_program(struct gl_context *ctx, struct gl_program *prog);
-
#endif
diff --git a/src/mesa/state_tracker/st_cb_readpixels.h b/src/mesa/state_tracker/st_cb_readpixels.h
index 83c9b659e3d..9622ae6feea 100644
--- a/src/mesa/state_tracker/st_cb_readpixels.h
+++ b/src/mesa/state_tracker/st_cb_readpixels.h
@@ -29,9 +29,11 @@
#ifndef ST_CB_READPIXELS_H
#define ST_CB_READPIXELS_H
-#include "main/mtypes.h"
+#include "main/glheader.h"
struct dd_function_table;
+struct gl_context;
+struct gl_pixelstore_attrib;
extern struct st_renderbuffer *
st_get_color_read_renderbuffer(struct gl_context *ctx);
diff --git a/src/mesa/state_tracker/st_cb_texture.h b/src/mesa/state_tracker/st_cb_texture.h
index 60987055eb1..f1502bda788 100644
--- a/src/mesa/state_tracker/st_cb_texture.h
+++ b/src/mesa/state_tracker/st_cb_texture.h
@@ -31,9 +31,10 @@
#include "main/glheader.h"
-#include "main/mtypes.h"
struct dd_function_table;
+struct gl_context;
+struct gl_texture_object;
struct pipe_context;
struct st_context;
diff --git a/src/mesa/state_tracker/st_context.c b/src/mesa/state_tracker/st_context.c
index 6ec9c699a26..21bb91f47a8 100644
--- a/src/mesa/state_tracker/st_context.c
+++ b/src/mesa/state_tracker/st_context.c
@@ -252,6 +252,8 @@ void st_destroy_context( struct st_context *st )
_vbo_DestroyContext(st->ctx);
+ st_destroy_program_variants(st);
+
_mesa_free_context_data(ctx);
st_destroy_context_priv(st);
diff --git a/src/mesa/state_tracker/st_context.h b/src/mesa/state_tracker/st_context.h
index d342c0cff1e..1fd80053c1b 100644
--- a/src/mesa/state_tracker/st_context.h
+++ b/src/mesa/state_tracker/st_context.h
@@ -1,4 +1,3 @@
-//struct dd_function_table;
/**************************************************************************
*
* Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
@@ -130,7 +129,9 @@ struct st_context
struct st_fragment_program *fp; /**< Currently bound fragment program */
struct st_geometry_program *gp; /**< Currently bound geometry program */
- struct st_vp_varient *vp_varient;
+ struct st_vp_variant *vp_variant;
+ struct st_fp_variant *fp_variant;
+ struct st_gp_variant *gp_variant;
struct gl_texture_object *default_texture;
@@ -160,7 +161,7 @@ struct st_context
/** for glDraw/CopyPixels */
struct {
- struct st_fragment_program *shaders[4];
+ struct gl_fragment_program *shaders[4];
void *vert_shaders[2]; /**< ureg shaders */
} drawpix;
diff --git a/src/mesa/state_tracker/st_debug.c b/src/mesa/state_tracker/st_debug.c
index df32491d044..e1e373d07d4 100644
--- a/src/mesa/state_tracker/st_debug.c
+++ b/src/mesa/state_tracker/st_debug.c
@@ -89,8 +89,8 @@ st_print_current(void)
}
#endif
- if (st->vp->varients)
- tgsi_dump( st->vp->varients[0].tgsi.tokens, 0 );
+ if (st->vp->variants)
+ tgsi_dump( st->vp->variants[0].tgsi.tokens, 0 );
if (st->vp->Base.Base.Parameters)
_mesa_print_parameter_list(st->vp->Base.Base.Parameters);
diff --git a/src/mesa/state_tracker/st_draw.c b/src/mesa/state_tracker/st_draw.c
index 61a0e1b0877..f4bf1802390 100644
--- a/src/mesa/state_tracker/st_draw.c
+++ b/src/mesa/state_tracker/st_draw.c
@@ -241,7 +241,7 @@ st_pipe_vertex_format(GLenum type, GLuint size, GLenum format,
*/
static GLboolean
is_interleaved_arrays(const struct st_vertex_program *vp,
- const struct st_vp_varient *vpv,
+ const struct st_vp_variant *vpv,
const struct gl_client_array **arrays,
GLboolean *userSpace)
{
@@ -297,7 +297,7 @@ is_interleaved_arrays(const struct st_vertex_program *vp,
*/
static void
get_arrays_bounds(const struct st_vertex_program *vp,
- const struct st_vp_varient *vpv,
+ const struct st_vp_variant *vpv,
const struct gl_client_array **arrays,
GLuint max_index,
const GLubyte **low, const GLubyte **high)
@@ -343,7 +343,7 @@ get_arrays_bounds(const struct st_vertex_program *vp,
static void
setup_interleaved_attribs(struct gl_context *ctx,
const struct st_vertex_program *vp,
- const struct st_vp_varient *vpv,
+ const struct st_vp_variant *vpv,
const struct gl_client_array **arrays,
GLuint max_index,
GLboolean userSpace,
@@ -409,7 +409,7 @@ setup_interleaved_attribs(struct gl_context *ctx,
static void
setup_non_interleaved_attribs(struct gl_context *ctx,
const struct st_vertex_program *vp,
- const struct st_vp_varient *vpv,
+ const struct st_vp_variant *vpv,
const struct gl_client_array **arrays,
GLuint max_index,
GLboolean *userSpace,
@@ -617,7 +617,7 @@ st_draw_vbo(struct gl_context *ctx,
struct st_context *st = st_context(ctx);
struct pipe_context *pipe = st->pipe;
const struct st_vertex_program *vp;
- const struct st_vp_varient *vpv;
+ const struct st_vp_variant *vpv;
struct pipe_vertex_buffer vbuffer[PIPE_MAX_SHADER_INPUTS];
GLuint attr;
struct pipe_vertex_element velements[PIPE_MAX_ATTRIBS];
@@ -650,7 +650,7 @@ st_draw_vbo(struct gl_context *ctx,
/* must get these after state validation! */
vp = st->vp;
- vpv = st->vp_varient;
+ vpv = st->vp_variant;
#if 0
if (MESA_VERBOSE & VERBOSE_GLSL) {
diff --git a/src/mesa/state_tracker/st_draw.h b/src/mesa/state_tracker/st_draw.h
index 2e4c468cff5..5d3c278228f 100644
--- a/src/mesa/state_tracker/st_draw.h
+++ b/src/mesa/state_tracker/st_draw.h
@@ -36,10 +36,11 @@
#include "main/compiler.h"
#include "main/glheader.h"
-#include "main/mtypes.h"
struct _mesa_index_buffer;
struct _mesa_prim;
+struct gl_client_array;
+struct gl_context;
struct st_context;
void st_init_draw( struct st_context *st );
diff --git a/src/mesa/state_tracker/st_draw_feedback.c b/src/mesa/state_tracker/st_draw_feedback.c
index 7f392fc4916..da67c713710 100644
--- a/src/mesa/state_tracker/st_draw_feedback.c
+++ b/src/mesa/state_tracker/st_draw_feedback.c
@@ -123,10 +123,10 @@ st_feedback_draw_vbo(struct gl_context *ctx,
/* must get these after state validation! */
vp = st->vp;
- vs = &st->vp_varient->tgsi;
+ vs = &st->vp_variant->tgsi;
- if (!st->vp_varient->draw_shader) {
- st->vp_varient->draw_shader = draw_create_vertex_shader(draw, vs);
+ if (!st->vp_variant->draw_shader) {
+ st->vp_variant->draw_shader = draw_create_vertex_shader(draw, vs);
}
/*
@@ -139,7 +139,7 @@ st_feedback_draw_vbo(struct gl_context *ctx,
draw_set_viewport_state(draw, &st->state.viewport);
draw_set_clip_state(draw, &st->state.clip);
draw_set_rasterizer_state(draw, &st->state.rasterizer, NULL);
- draw_bind_vertex_shader(draw, st->vp_varient->draw_shader);
+ draw_bind_vertex_shader(draw, st->vp_variant->draw_shader);
set_feedback_vertex_format(ctx);
/* loop over TGSI shader inputs to determine vertex buffer
@@ -259,16 +259,14 @@ st_feedback_draw_vbo(struct gl_context *ctx,
/* unmap constant buffers */
- pipe_buffer_unmap(pipe, st->state.constants[PIPE_SHADER_VERTEX],
- cb_transfer);
+ pipe_buffer_unmap(pipe, cb_transfer);
/*
* unmap vertex/index buffers
*/
for (i = 0; i < PIPE_MAX_ATTRIBS; i++) {
if (draw->pt.vertex_buffer[i].buffer) {
- pipe_buffer_unmap(pipe, draw->pt.vertex_buffer[i].buffer,
- vb_transfer[i]);
+ pipe_buffer_unmap(pipe, vb_transfer[i]);
pipe_resource_reference(&draw->pt.vertex_buffer[i].buffer, NULL);
draw_set_mapped_vertex_buffer(draw, i, NULL);
}
@@ -279,7 +277,7 @@ st_feedback_draw_vbo(struct gl_context *ctx,
draw_set_index_buffer(draw, NULL);
if (ib_transfer)
- pipe_buffer_unmap(pipe, ibuffer.buffer, ib_transfer);
+ pipe_buffer_unmap(pipe, ib_transfer);
pipe_resource_reference(&ibuffer.buffer, NULL);
}
}
diff --git a/src/mesa/state_tracker/st_extensions.c b/src/mesa/state_tracker/st_extensions.c
index 930b60ade2d..62c9ce7273d 100644
--- a/src/mesa/state_tracker/st_extensions.c
+++ b/src/mesa/state_tracker/st_extensions.c
@@ -343,6 +343,7 @@ void st_init_extensions(struct st_context *st)
if (screen->get_param(screen, PIPE_CAP_OCCLUSION_QUERY)) {
ctx->Extensions.ARB_occlusion_query = GL_TRUE;
+ ctx->Extensions.ARB_occlusion_query2 = GL_TRUE;
}
if (screen->get_param(screen, PIPE_CAP_TIMER_QUERY)) {
ctx->Extensions.EXT_timer_query = GL_TRUE;
@@ -442,7 +443,9 @@ void st_init_extensions(struct st_context *st)
#endif
if (screen->get_shader_param(screen, PIPE_SHADER_GEOMETRY, PIPE_SHADER_CAP_MAX_INSTRUCTIONS) > 0) {
+#if 0 /* XXX re-enable when GLSL compiler again supports geometry shaders */
ctx->Extensions.ARB_geometry_shader4 = GL_TRUE;
+#endif
}
if (screen->get_param(screen, PIPE_CAP_PRIMITIVE_RESTART)) {
diff --git a/src/mesa/state_tracker/st_format.h b/src/mesa/state_tracker/st_format.h
index 43fa59b1006..fe195c1069b 100644
--- a/src/mesa/state_tracker/st_format.h
+++ b/src/mesa/state_tracker/st_format.h
@@ -31,11 +31,12 @@
#define ST_FORMAT_H
#include "main/formats.h"
-#include "main/mtypes.h"
+#include "main/glheader.h"
#include "pipe/p_defines.h"
#include "pipe/p_format.h"
+struct gl_context;
struct pipe_screen;
extern GLenum
diff --git a/src/mesa/state_tracker/st_program.c b/src/mesa/state_tracker/st_program.c
index aae2913c202..cfdc96b9dbe 100644
--- a/src/mesa/state_tracker/st_program.c
+++ b/src/mesa/state_tracker/st_program.c
@@ -32,7 +32,9 @@
#include "main/imports.h"
+#include "main/hash.h"
#include "main/mtypes.h"
+#include "program/prog_parameter.h"
#include "program/prog_print.h"
#include "program/programopt.h"
@@ -44,6 +46,8 @@
#include "tgsi/tgsi_ureg.h"
#include "st_debug.h"
+#include "st_cb_bitmap.h"
+#include "st_cb_drawpixels.h"
#include "st_context.h"
#include "st_program.h"
#include "st_mesa_to_tgsi.h"
@@ -52,34 +56,109 @@
/**
+ * Delete a vertex program variant. Note the caller must unlink
+ * the variant from the linked list.
+ */
+static void
+delete_vp_variant(struct st_context *st, struct st_vp_variant *vpv)
+{
+ if (vpv->driver_shader)
+ cso_delete_vertex_shader(st->cso_context, vpv->driver_shader);
+
+#if FEATURE_feedback || FEATURE_rastpos
+ if (vpv->draw_shader)
+ draw_delete_vertex_shader( st->draw, vpv->draw_shader );
+#endif
+
+ if (vpv->tgsi.tokens)
+ st_free_tokens(vpv->tgsi.tokens);
+
+ FREE( vpv );
+}
+
+
+
+/**
* Clean out any old compilations:
*/
void
-st_vp_release_varients( struct st_context *st,
+st_release_vp_variants( struct st_context *st,
struct st_vertex_program *stvp )
{
- struct st_vp_varient *vpv;
+ struct st_vp_variant *vpv;
- for (vpv = stvp->varients; vpv; ) {
- struct st_vp_varient *next = vpv->next;
+ for (vpv = stvp->variants; vpv; ) {
+ struct st_vp_variant *next = vpv->next;
+ delete_vp_variant(st, vpv);
+ vpv = next;
+ }
- if (vpv->driver_shader)
- cso_delete_vertex_shader(st->cso_context, vpv->driver_shader);
-
-#if FEATURE_feedback || FEATURE_rastpos
- if (vpv->draw_shader)
- draw_delete_vertex_shader( st->draw, vpv->draw_shader );
-#endif
+ stvp->variants = NULL;
+}
+
+
+
+/**
+ * Delete a fragment program variant. Note the caller must unlink
+ * the variant from the linked list.
+ */
+static void
+delete_fp_variant(struct st_context *st, struct st_fp_variant *fpv)
+{
+ if (fpv->driver_shader)
+ cso_delete_fragment_shader(st->cso_context, fpv->driver_shader);
- if (vpv->tgsi.tokens)
- st_free_tokens(vpv->tgsi.tokens);
+ FREE(fpv);
+}
+
+
+/**
+ * Free all variants of a fragment program.
+ */
+void
+st_release_fp_variants(struct st_context *st, struct st_fragment_program *stfp)
+{
+ struct st_fp_variant *fpv;
+
+ for (fpv = stfp->variants; fpv; ) {
+ struct st_fp_variant *next = fpv->next;
+ delete_fp_variant(st, fpv);
+ fpv = next;
+ }
+
+ stfp->variants = NULL;
+}
+
+
+/**
+ * Delete a geometry program variant. Note the caller must unlink
+ * the variant from the linked list.
+ */
+static void
+delete_gp_variant(struct st_context *st, struct st_gp_variant *gpv)
+{
+ if (gpv->driver_shader)
+ cso_delete_geometry_shader(st->cso_context, gpv->driver_shader);
- FREE( vpv );
+ FREE(gpv);
+}
- vpv = next;
+
+/**
+ * Free all variants of a geometry program.
+ */
+void
+st_release_gp_variants(struct st_context *st, struct st_geometry_program *stgp)
+{
+ struct st_gp_variant *gpv;
+
+ for (gpv = stgp->variants; gpv; ) {
+ struct st_gp_variant *next = gpv->next;
+ delete_gp_variant(st, gpv);
+ gpv = next;
}
- stvp->varients = NULL;
+ stgp->variants = NULL;
}
@@ -92,7 +171,7 @@ st_vp_release_varients( struct st_context *st,
* \param tokensOut destination for TGSI tokens
* \return pointer to cached pipe_shader object.
*/
-void
+static void
st_prepare_vertex_program(struct st_context *st,
struct st_vertex_program *stvp)
{
@@ -196,17 +275,22 @@ st_prepare_vertex_program(struct st_context *st,
}
-struct st_vp_varient *
+/**
+ * Translate a vertex program to create a new variant.
+ */
+static struct st_vp_variant *
st_translate_vertex_program(struct st_context *st,
struct st_vertex_program *stvp,
- const struct st_vp_varient_key *key)
+ const struct st_vp_variant_key *key)
{
- struct st_vp_varient *vpv = CALLOC_STRUCT(st_vp_varient);
+ struct st_vp_variant *vpv = CALLOC_STRUCT(st_vp_variant);
struct pipe_context *pipe = st->pipe;
struct ureg_program *ureg;
enum pipe_error error;
unsigned num_outputs;
+ st_prepare_vertex_program( st, stvp );
+
_mesa_remove_output_reads(&stvp->Base.Base, PROGRAM_OUTPUT);
_mesa_remove_output_reads(&stvp->Base.Base, PROGRAM_VARYING);
@@ -231,23 +315,22 @@ st_translate_vertex_program(struct st_context *st,
debug_printf("\n");
}
- error =
- st_translate_mesa_program(st->ctx,
- TGSI_PROCESSOR_VERTEX,
- ureg,
- &stvp->Base.Base,
- /* inputs */
- vpv->num_inputs,
- stvp->input_to_index,
- NULL, /* input semantic name */
- NULL, /* input semantic index */
- NULL,
- /* outputs */
- num_outputs,
- stvp->result_to_output,
- stvp->output_semantic_name,
- stvp->output_semantic_index,
- key->passthrough_edgeflags );
+ error = st_translate_mesa_program(st->ctx,
+ TGSI_PROCESSOR_VERTEX,
+ ureg,
+ &stvp->Base.Base,
+ /* inputs */
+ vpv->num_inputs,
+ stvp->input_to_index,
+ NULL, /* input semantic name */
+ NULL, /* input semantic index */
+ NULL,
+ /* outputs */
+ num_outputs,
+ stvp->result_to_output,
+ stvp->output_semantic_name,
+ stvp->output_semantic_index,
+ key->passthrough_edgeflags );
if (error)
goto fail;
@@ -277,201 +360,310 @@ fail:
}
+/**
+ * Find/create a vertex program variant.
+ */
+struct st_vp_variant *
+st_get_vp_variant(struct st_context *st,
+ struct st_vertex_program *stvp,
+ const struct st_vp_variant_key *key)
+{
+ struct st_vp_variant *vpv;
+
+ /* Search for existing variant */
+ for (vpv = stvp->variants; vpv; vpv = vpv->next) {
+ if (memcmp(&vpv->key, key, sizeof(*key)) == 0) {
+ break;
+ }
+ }
+
+ if (!vpv) {
+ /* create now */
+ vpv = st_translate_vertex_program(st, stvp, key);
+ if (vpv) {
+ /* insert into list */
+ vpv->next = stvp->variants;
+ stvp->variants = vpv;
+ }
+ }
+
+ return vpv;
+}
+
/**
- * Translate a Mesa fragment shader into a TGSI shader.
- * \return pointer to cached pipe_shader object.
+ * Translate a Mesa fragment shader into a TGSI shader using extra info in
+ * the key.
+ * \return new fragment program variant
*/
-void
+static struct st_fp_variant *
st_translate_fragment_program(struct st_context *st,
- struct st_fragment_program *stfp )
+ struct st_fragment_program *stfp,
+ const struct st_fp_variant_key *key)
{
struct pipe_context *pipe = st->pipe;
- GLuint outputMapping[FRAG_RESULT_MAX];
- GLuint inputMapping[FRAG_ATTRIB_MAX];
- GLuint interpMode[PIPE_MAX_SHADER_INPUTS]; /* XXX size? */
- GLuint attr;
- enum pipe_error error;
- const GLbitfield inputsRead = stfp->Base.Base.InputsRead;
- struct ureg_program *ureg;
+ struct st_fp_variant *variant = CALLOC_STRUCT(st_fp_variant);
- ubyte input_semantic_name[PIPE_MAX_SHADER_INPUTS];
- ubyte input_semantic_index[PIPE_MAX_SHADER_INPUTS];
- uint fs_num_inputs = 0;
+ if (!variant)
+ return NULL;
- ubyte fs_output_semantic_name[PIPE_MAX_SHADER_OUTPUTS];
- ubyte fs_output_semantic_index[PIPE_MAX_SHADER_OUTPUTS];
- uint fs_num_outputs = 0;
+ assert(!(key->bitmap && key->drawpixels));
- _mesa_remove_output_reads(&stfp->Base.Base, PROGRAM_OUTPUT);
+ if (key->bitmap) {
+ /* glBitmap drawing */
+ struct gl_fragment_program *fp;
- /*
- * Convert Mesa program inputs to TGSI input register semantics.
- */
- for (attr = 0; attr < FRAG_ATTRIB_MAX; attr++) {
- if (inputsRead & (1 << attr)) {
- const GLuint slot = fs_num_inputs++;
+ st_make_bitmap_fragment_program(st, &stfp->Base,
+ &fp, &variant->bitmap_sampler);
- inputMapping[attr] = slot;
+ variant->parameters = _mesa_clone_parameter_list(fp->Base.Parameters);
+ stfp = st_fragment_program(fp);
+ }
+ else if (key->drawpixels) {
+ /* glDrawPixels drawing */
+ struct gl_fragment_program *fp;
- switch (attr) {
- case FRAG_ATTRIB_WPOS:
- input_semantic_name[slot] = TGSI_SEMANTIC_POSITION;
- input_semantic_index[slot] = 0;
- interpMode[slot] = TGSI_INTERPOLATE_LINEAR;
- break;
- case FRAG_ATTRIB_COL0:
- input_semantic_name[slot] = TGSI_SEMANTIC_COLOR;
- input_semantic_index[slot] = 0;
- interpMode[slot] = TGSI_INTERPOLATE_LINEAR;
- break;
- case FRAG_ATTRIB_COL1:
- input_semantic_name[slot] = TGSI_SEMANTIC_COLOR;
- input_semantic_index[slot] = 1;
- interpMode[slot] = TGSI_INTERPOLATE_LINEAR;
- break;
- case FRAG_ATTRIB_FOGC:
- input_semantic_name[slot] = TGSI_SEMANTIC_FOG;
- input_semantic_index[slot] = 0;
- interpMode[slot] = TGSI_INTERPOLATE_PERSPECTIVE;
- break;
- case FRAG_ATTRIB_FACE:
- input_semantic_name[slot] = TGSI_SEMANTIC_FACE;
- input_semantic_index[slot] = 0;
- interpMode[slot] = TGSI_INTERPOLATE_CONSTANT;
- break;
- /* In most cases, there is nothing special about these
- * inputs, so adopt a convention to use the generic
- * semantic name and the mesa FRAG_ATTRIB_ number as the
- * index.
- *
- * All that is required is that the vertex shader labels
- * its own outputs similarly, and that the vertex shader
- * generates at least every output required by the
- * fragment shader plus fixed-function hardware (such as
- * BFC).
- *
- * There is no requirement that semantic indexes start at
- * zero or be restricted to a particular range -- nobody
- * should be building tables based on semantic index.
- */
- case FRAG_ATTRIB_PNTC:
- case FRAG_ATTRIB_TEX0:
- case FRAG_ATTRIB_TEX1:
- case FRAG_ATTRIB_TEX2:
- case FRAG_ATTRIB_TEX3:
- case FRAG_ATTRIB_TEX4:
- case FRAG_ATTRIB_TEX5:
- case FRAG_ATTRIB_TEX6:
- case FRAG_ATTRIB_TEX7:
- case FRAG_ATTRIB_VAR0:
- default:
- /* Actually, let's try and zero-base this just for
- * readability of the generated TGSI.
- */
- assert(attr >= FRAG_ATTRIB_TEX0);
- input_semantic_index[slot] = (attr - FRAG_ATTRIB_TEX0);
- input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC;
- if (attr == FRAG_ATTRIB_PNTC)
- interpMode[slot] = TGSI_INTERPOLATE_LINEAR;
- else
- interpMode[slot] = TGSI_INTERPOLATE_PERSPECTIVE;
- break;
- }
+ if (key->drawpixels_z || key->drawpixels_stencil) {
+ fp = st_make_drawpix_z_stencil_program(st, key->drawpixels_z,
+ key->drawpixels_stencil);
}
else {
- inputMapping[attr] = -1;
+ /* RGBA */
+ st_make_drawpix_fragment_program(st, &stfp->Base, &fp);
+ variant->parameters = _mesa_clone_parameter_list(fp->Base.Parameters);
}
+ stfp = st_fragment_program(fp);
}
- /*
- * Semantics and mapping for outputs
- */
- {
- uint numColors = 0;
- GLbitfield64 outputsWritten = stfp->Base.Base.OutputsWritten;
-
- /* if z is written, emit that first */
- if (outputsWritten & BITFIELD64_BIT(FRAG_RESULT_DEPTH)) {
- fs_output_semantic_name[fs_num_outputs] = TGSI_SEMANTIC_POSITION;
- fs_output_semantic_index[fs_num_outputs] = 0;
- outputMapping[FRAG_RESULT_DEPTH] = fs_num_outputs;
- fs_num_outputs++;
- outputsWritten &= ~(1 << FRAG_RESULT_DEPTH);
- }
+ if (!stfp->tgsi.tokens) {
+ /* need to translate Mesa instructions to TGSI now */
+ GLuint outputMapping[FRAG_RESULT_MAX];
+ GLuint inputMapping[FRAG_ATTRIB_MAX];
+ GLuint interpMode[PIPE_MAX_SHADER_INPUTS]; /* XXX size? */
+ GLuint attr;
+ enum pipe_error error;
+ const GLbitfield inputsRead = stfp->Base.Base.InputsRead;
+ struct ureg_program *ureg;
- if (outputsWritten & BITFIELD64_BIT(FRAG_RESULT_STENCIL)) {
- fs_output_semantic_name[fs_num_outputs] = TGSI_SEMANTIC_STENCIL;
- fs_output_semantic_index[fs_num_outputs] = 0;
- outputMapping[FRAG_RESULT_STENCIL] = fs_num_outputs;
- fs_num_outputs++;
- outputsWritten &= ~(1 << FRAG_RESULT_STENCIL);
- }
+ ubyte input_semantic_name[PIPE_MAX_SHADER_INPUTS];
+ ubyte input_semantic_index[PIPE_MAX_SHADER_INPUTS];
+ uint fs_num_inputs = 0;
+
+ ubyte fs_output_semantic_name[PIPE_MAX_SHADER_OUTPUTS];
+ ubyte fs_output_semantic_index[PIPE_MAX_SHADER_OUTPUTS];
+ uint fs_num_outputs = 0;
+
+
+ _mesa_remove_output_reads(&stfp->Base.Base, PROGRAM_OUTPUT);
+
+ /*
+ * Convert Mesa program inputs to TGSI input register semantics.
+ */
+ for (attr = 0; attr < FRAG_ATTRIB_MAX; attr++) {
+ if (inputsRead & (1 << attr)) {
+ const GLuint slot = fs_num_inputs++;
+
+ inputMapping[attr] = slot;
- /* handle remaning outputs (color) */
- for (attr = 0; attr < FRAG_RESULT_MAX; attr++) {
- if (outputsWritten & BITFIELD64_BIT(attr)) {
switch (attr) {
- case FRAG_RESULT_DEPTH:
- case FRAG_RESULT_STENCIL:
- /* handled above */
- assert(0);
+ case FRAG_ATTRIB_WPOS:
+ input_semantic_name[slot] = TGSI_SEMANTIC_POSITION;
+ input_semantic_index[slot] = 0;
+ interpMode[slot] = TGSI_INTERPOLATE_LINEAR;
+ break;
+ case FRAG_ATTRIB_COL0:
+ input_semantic_name[slot] = TGSI_SEMANTIC_COLOR;
+ input_semantic_index[slot] = 0;
+ interpMode[slot] = TGSI_INTERPOLATE_LINEAR;
break;
+ case FRAG_ATTRIB_COL1:
+ input_semantic_name[slot] = TGSI_SEMANTIC_COLOR;
+ input_semantic_index[slot] = 1;
+ interpMode[slot] = TGSI_INTERPOLATE_LINEAR;
+ break;
+ case FRAG_ATTRIB_FOGC:
+ input_semantic_name[slot] = TGSI_SEMANTIC_FOG;
+ input_semantic_index[slot] = 0;
+ interpMode[slot] = TGSI_INTERPOLATE_PERSPECTIVE;
+ break;
+ case FRAG_ATTRIB_FACE:
+ input_semantic_name[slot] = TGSI_SEMANTIC_FACE;
+ input_semantic_index[slot] = 0;
+ interpMode[slot] = TGSI_INTERPOLATE_CONSTANT;
+ break;
+ /* In most cases, there is nothing special about these
+ * inputs, so adopt a convention to use the generic
+ * semantic name and the mesa FRAG_ATTRIB_ number as the
+ * index.
+ *
+ * All that is required is that the vertex shader labels
+ * its own outputs similarly, and that the vertex shader
+ * generates at least every output required by the
+ * fragment shader plus fixed-function hardware (such as
+ * BFC).
+ *
+ * There is no requirement that semantic indexes start at
+ * zero or be restricted to a particular range -- nobody
+ * should be building tables based on semantic index.
+ */
+ case FRAG_ATTRIB_PNTC:
+ case FRAG_ATTRIB_TEX0:
+ case FRAG_ATTRIB_TEX1:
+ case FRAG_ATTRIB_TEX2:
+ case FRAG_ATTRIB_TEX3:
+ case FRAG_ATTRIB_TEX4:
+ case FRAG_ATTRIB_TEX5:
+ case FRAG_ATTRIB_TEX6:
+ case FRAG_ATTRIB_TEX7:
+ case FRAG_ATTRIB_VAR0:
default:
- assert(attr == FRAG_RESULT_COLOR ||
- (FRAG_RESULT_DATA0 <= attr && attr < FRAG_RESULT_MAX));
- fs_output_semantic_name[fs_num_outputs] = TGSI_SEMANTIC_COLOR;
- fs_output_semantic_index[fs_num_outputs] = numColors;
- outputMapping[attr] = fs_num_outputs;
- numColors++;
+ /* Actually, let's try and zero-base this just for
+ * readability of the generated TGSI.
+ */
+ assert(attr >= FRAG_ATTRIB_TEX0);
+ input_semantic_index[slot] = (attr - FRAG_ATTRIB_TEX0);
+ input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC;
+ if (attr == FRAG_ATTRIB_PNTC)
+ interpMode[slot] = TGSI_INTERPOLATE_LINEAR;
+ else
+ interpMode[slot] = TGSI_INTERPOLATE_PERSPECTIVE;
break;
}
+ }
+ else {
+ inputMapping[attr] = -1;
+ }
+ }
+ /*
+ * Semantics and mapping for outputs
+ */
+ {
+ uint numColors = 0;
+ GLbitfield64 outputsWritten = stfp->Base.Base.OutputsWritten;
+
+ /* if z is written, emit that first */
+ if (outputsWritten & BITFIELD64_BIT(FRAG_RESULT_DEPTH)) {
+ fs_output_semantic_name[fs_num_outputs] = TGSI_SEMANTIC_POSITION;
+ fs_output_semantic_index[fs_num_outputs] = 0;
+ outputMapping[FRAG_RESULT_DEPTH] = fs_num_outputs;
fs_num_outputs++;
+ outputsWritten &= ~(1 << FRAG_RESULT_DEPTH);
+ }
+
+ if (outputsWritten & BITFIELD64_BIT(FRAG_RESULT_STENCIL)) {
+ fs_output_semantic_name[fs_num_outputs] = TGSI_SEMANTIC_STENCIL;
+ fs_output_semantic_index[fs_num_outputs] = 0;
+ outputMapping[FRAG_RESULT_STENCIL] = fs_num_outputs;
+ fs_num_outputs++;
+ outputsWritten &= ~(1 << FRAG_RESULT_STENCIL);
+ }
+
+ /* handle remaning outputs (color) */
+ for (attr = 0; attr < FRAG_RESULT_MAX; attr++) {
+ if (outputsWritten & BITFIELD64_BIT(attr)) {
+ switch (attr) {
+ case FRAG_RESULT_DEPTH:
+ case FRAG_RESULT_STENCIL:
+ /* handled above */
+ assert(0);
+ break;
+ default:
+ assert(attr == FRAG_RESULT_COLOR ||
+ (FRAG_RESULT_DATA0 <= attr && attr < FRAG_RESULT_MAX));
+ fs_output_semantic_name[fs_num_outputs] = TGSI_SEMANTIC_COLOR;
+ fs_output_semantic_index[fs_num_outputs] = numColors;
+ outputMapping[attr] = fs_num_outputs;
+ numColors++;
+ break;
+ }
+
+ fs_num_outputs++;
+ }
}
}
- }
- ureg = ureg_create( TGSI_PROCESSOR_FRAGMENT );
- if (ureg == NULL)
- return;
+ ureg = ureg_create( TGSI_PROCESSOR_FRAGMENT );
+ if (ureg == NULL)
+ return NULL;
- if (ST_DEBUG & DEBUG_MESA) {
- _mesa_print_program(&stfp->Base.Base);
- _mesa_print_program_parameters(st->ctx, &stfp->Base.Base);
- debug_printf("\n");
+ if (ST_DEBUG & DEBUG_MESA) {
+ _mesa_print_program(&stfp->Base.Base);
+ _mesa_print_program_parameters(st->ctx, &stfp->Base.Base);
+ debug_printf("\n");
+ }
+
+ error = st_translate_mesa_program(st->ctx,
+ TGSI_PROCESSOR_FRAGMENT,
+ ureg,
+ &stfp->Base.Base,
+ /* inputs */
+ fs_num_inputs,
+ inputMapping,
+ input_semantic_name,
+ input_semantic_index,
+ interpMode,
+ /* outputs */
+ fs_num_outputs,
+ outputMapping,
+ fs_output_semantic_name,
+ fs_output_semantic_index, FALSE );
+
+ stfp->tgsi.tokens = ureg_get_tokens( ureg, NULL );
+ ureg_destroy( ureg );
}
- error =
- st_translate_mesa_program(st->ctx,
- TGSI_PROCESSOR_FRAGMENT,
- ureg,
- &stfp->Base.Base,
- /* inputs */
- fs_num_inputs,
- inputMapping,
- input_semantic_name,
- input_semantic_index,
- interpMode,
- /* outputs */
- fs_num_outputs,
- outputMapping,
- fs_output_semantic_name,
- fs_output_semantic_index, FALSE );
-
- stfp->tgsi.tokens = ureg_get_tokens( ureg, NULL );
- ureg_destroy( ureg );
- stfp->driver_shader = pipe->create_fs_state(pipe, &stfp->tgsi);
+ /* fill in variant */
+ variant->driver_shader = pipe->create_fs_state(pipe, &stfp->tgsi);
+ variant->key = *key;
if (ST_DEBUG & DEBUG_TGSI) {
tgsi_dump( stfp->tgsi.tokens, 0/*TGSI_DUMP_VERBOSE*/ );
debug_printf("\n");
}
+
+ return variant;
}
-void
+
+/**
+ * Translate fragment program if needed.
+ */
+struct st_fp_variant *
+st_get_fp_variant(struct st_context *st,
+ struct st_fragment_program *stfp,
+ const struct st_fp_variant_key *key)
+{
+ struct st_fp_variant *fpv;
+
+ /* Search for existing variant */
+ for (fpv = stfp->variants; fpv; fpv = fpv->next) {
+ if (memcmp(&fpv->key, key, sizeof(*key)) == 0) {
+ break;
+ }
+ }
+
+ if (!fpv) {
+ /* create new */
+ fpv = st_translate_fragment_program(st, stfp, key);
+ if (fpv) {
+ /* insert into list */
+ fpv->next = stfp->variants;
+ stfp->variants = fpv;
+ }
+ }
+
+ return fpv;
+}
+
+
+/**
+ * Translate a geometry program to create a new variant.
+ */
+static struct st_gp_variant *
st_translate_geometry_program(struct st_context *st,
- struct st_geometry_program *stgp)
+ struct st_geometry_program *stgp,
+ const struct st_gp_variant_key *key)
{
GLuint inputMapping[GEOM_ATTRIB_MAX];
GLuint outputMapping[GEOM_RESULT_MAX];
@@ -494,12 +686,19 @@ st_translate_geometry_program(struct st_context *st,
GLuint maxSlot = 0;
struct ureg_program *ureg;
+ struct st_gp_variant *gpv;
+
+ gpv = CALLOC_STRUCT(st_gp_variant);
+ if (!gpv)
+ return NULL;
+
_mesa_remove_output_reads(&stgp->Base.Base, PROGRAM_OUTPUT);
_mesa_remove_output_reads(&stgp->Base.Base, PROGRAM_VARYING);
ureg = ureg_create( TGSI_PROCESSOR_GEOMETRY );
if (ureg == NULL) {
- return;
+ FREE(gpv);
+ return NULL;
}
/* which vertex output goes to the first geometry input */
@@ -529,7 +728,7 @@ st_translate_geometry_program(struct st_context *st,
} else
++gs_builtin_inputs;
-#if 1
+#if 0
debug_printf("input map at %d = %d\n",
slot + gs_array_offset, stgp->input_map[slot + gs_array_offset]);
#endif
@@ -671,37 +870,35 @@ st_translate_geometry_program(struct st_context *st,
st_free_tokens(stgp->tgsi.tokens);
stgp->tgsi.tokens = NULL;
}
- if (stgp->driver_shader) {
- cso_delete_geometry_shader(st->cso_context, stgp->driver_shader);
- stgp->driver_shader = NULL;
- }
ureg_property_gs_input_prim(ureg, stgp->Base.InputType);
ureg_property_gs_output_prim(ureg, stgp->Base.OutputType);
ureg_property_gs_max_vertices(ureg, stgp->Base.VerticesOut);
- error = st_translate_mesa_program(st->ctx,
- TGSI_PROCESSOR_GEOMETRY,
- ureg,
- &stgp->Base.Base,
- /* inputs */
- gs_num_inputs,
- inputMapping,
- stgp->input_semantic_name,
- stgp->input_semantic_index,
- NULL,
- /* outputs */
- gs_num_outputs,
- outputMapping,
- gs_output_semantic_name,
- gs_output_semantic_index,
- FALSE);
-
+ error = st_translate_mesa_program(st->ctx,
+ TGSI_PROCESSOR_GEOMETRY,
+ ureg,
+ &stgp->Base.Base,
+ /* inputs */
+ gs_num_inputs,
+ inputMapping,
+ stgp->input_semantic_name,
+ stgp->input_semantic_index,
+ NULL,
+ /* outputs */
+ gs_num_outputs,
+ outputMapping,
+ gs_output_semantic_name,
+ gs_output_semantic_index,
+ FALSE);
stgp->num_inputs = gs_num_inputs;
stgp->tgsi.tokens = ureg_get_tokens( ureg, NULL );
ureg_destroy( ureg );
- stgp->driver_shader = pipe->create_gs_state(pipe, &stgp->tgsi);
+
+ /* fill in new variant */
+ gpv->driver_shader = pipe->create_gs_state(pipe, &stgp->tgsi);
+ gpv->key = *key;
if ((ST_DEBUG & DEBUG_TGSI) && (ST_DEBUG & DEBUG_MESA)) {
_mesa_print_program(&stgp->Base.Base);
@@ -712,8 +909,44 @@ st_translate_geometry_program(struct st_context *st,
tgsi_dump(stgp->tgsi.tokens, 0);
debug_printf("\n");
}
+
+ return gpv;
+}
+
+
+/**
+ * Get/create geometry program variant.
+ */
+struct st_gp_variant *
+st_get_gp_variant(struct st_context *st,
+ struct st_geometry_program *stgp,
+ const struct st_gp_variant_key *key)
+{
+ struct st_gp_variant *gpv;
+
+ /* Search for existing variant */
+ for (gpv = stgp->variants; gpv; gpv = gpv->next) {
+ if (memcmp(&gpv->key, key, sizeof(*key)) == 0) {
+ break;
+ }
+ }
+
+ if (!gpv) {
+ /* create new */
+ gpv = st_translate_geometry_program(st, stgp, key);
+ if (gpv) {
+ /* insert into list */
+ gpv->next = stgp->variants;
+ stgp->variants = gpv;
+ }
+ }
+
+ return gpv;
}
+
+
+
/**
* Debug- print current shader text
*/
@@ -759,3 +992,155 @@ st_print_shaders(struct gl_context *ctx)
}
}
}
+
+
+/**
+ * Vert/Geom/Frag programs have per-context variants. Free all the
+ * variants attached to the given program which match the given context.
+ */
+static void
+destroy_program_variants(struct st_context *st, struct gl_program *program)
+{
+ if (!program)
+ return;
+
+ switch (program->Target) {
+ case GL_VERTEX_PROGRAM_ARB:
+ {
+ struct st_vertex_program *stvp = (struct st_vertex_program *) program;
+ struct st_vp_variant *vpv, **prevPtr = &stvp->variants;
+
+ for (vpv = stvp->variants; vpv; ) {
+ struct st_vp_variant *next = vpv->next;
+ if (vpv->key.st == st) {
+ /* unlink from list */
+ *prevPtr = next;
+ /* destroy this variant */
+ delete_vp_variant(st, vpv);
+ }
+ else {
+ prevPtr = &vpv->next;
+ }
+ vpv = next;
+ }
+ }
+ break;
+ case GL_FRAGMENT_PROGRAM_ARB:
+ {
+ struct st_fragment_program *stfp =
+ (struct st_fragment_program *) program;
+ struct st_fp_variant *fpv, **prevPtr = &stfp->variants;
+
+ for (fpv = stfp->variants; fpv; ) {
+ struct st_fp_variant *next = fpv->next;
+ if (fpv->key.st == st) {
+ /* unlink from list */
+ *prevPtr = next;
+ /* destroy this variant */
+ delete_fp_variant(st, fpv);
+ }
+ else {
+ prevPtr = &fpv->next;
+ }
+ fpv = next;
+ }
+ }
+ break;
+ case MESA_GEOMETRY_PROGRAM:
+ {
+ struct st_geometry_program *stgp =
+ (struct st_geometry_program *) program;
+ struct st_gp_variant *gpv, **prevPtr = &stgp->variants;
+
+ for (gpv = stgp->variants; gpv; ) {
+ struct st_gp_variant *next = gpv->next;
+ if (gpv->key.st == st) {
+ /* unlink from list */
+ *prevPtr = next;
+ /* destroy this variant */
+ delete_gp_variant(st, gpv);
+ }
+ else {
+ prevPtr = &gpv->next;
+ }
+ gpv = next;
+ }
+ }
+ break;
+ default:
+ _mesa_problem(NULL, "Unexpected program target in "
+ "destroy_program_variants_cb()");
+ }
+}
+
+
+/**
+ * Callback for _mesa_HashWalk. Free all the shader's program variants
+ * which match the given context.
+ */
+static void
+destroy_shader_program_variants_cb(GLuint key, void *data, void *userData)
+{
+ struct st_context *st = (struct st_context *) userData;
+ struct gl_shader *shader = (struct gl_shader *) data;
+
+ switch (shader->Type) {
+ case GL_SHADER_PROGRAM_MESA:
+ {
+ struct gl_shader_program *shProg = (struct gl_shader_program *) data;
+ GLuint i;
+
+ for (i = 0; i < shProg->NumShaders; i++) {
+ destroy_program_variants(st, shProg->Shaders[i]->Program);
+ }
+
+ destroy_program_variants(st, (struct gl_program *)
+ shProg->VertexProgram);
+ destroy_program_variants(st, (struct gl_program *)
+ shProg->FragmentProgram);
+ destroy_program_variants(st, (struct gl_program *)
+ shProg->GeometryProgram);
+ }
+ break;
+ case GL_VERTEX_SHADER:
+ case GL_FRAGMENT_SHADER:
+ case GL_GEOMETRY_SHADER:
+ {
+ destroy_program_variants(st, shader->Program);
+ }
+ break;
+ default:
+ assert(0);
+ }
+}
+
+
+/**
+ * Callback for _mesa_HashWalk. Free all the program variants which match
+ * the given context.
+ */
+static void
+destroy_program_variants_cb(GLuint key, void *data, void *userData)
+{
+ struct st_context *st = (struct st_context *) userData;
+ struct gl_program *program = (struct gl_program *) data;
+ destroy_program_variants(st, program);
+}
+
+
+/**
+ * Walk over all shaders and programs to delete any variants which
+ * belong to the given context.
+ * This is called during context tear-down.
+ */
+void
+st_destroy_program_variants(struct st_context *st)
+{
+ /* ARB vert/frag program */
+ _mesa_HashWalk(st->ctx->Shared->Programs,
+ destroy_program_variants_cb, st);
+
+ /* GLSL vert/frag/geom shaders */
+ _mesa_HashWalk(st->ctx->Shared->ShaderObjects,
+ destroy_shader_program_variants_cb, st);
+}
diff --git a/src/mesa/state_tracker/st_program.h b/src/mesa/state_tracker/st_program.h
index 72dbc715fe1..c4244df939e 100644
--- a/src/mesa/state_tracker/st_program.h
+++ b/src/mesa/state_tracker/st_program.h
@@ -40,26 +40,61 @@
#include "st_context.h"
+/** Fragment program variant key */
+struct st_fp_variant_key
+{
+ struct st_context *st; /**< variants are per-context */
+
+ /** for glBitmap */
+ GLuint bitmap:1; /**< glBitmap variant? */
+
+ /** for glDrawPixels */
+ GLuint drawpixels:1; /**< glDrawPixels variant */
+ GLuint scaleAndBias:1; /**< glDrawPixels w/ scale and/or bias? */
+ GLuint pixelMaps:1; /**< glDrawPixels w/ pixel lookup map? */
+ GLuint drawpixels_z:1; /**< glDrawPixels(GL_DEPTH) */
+ GLuint drawpixels_stencil:1; /**< glDrawPixels(GL_STENCIL) */
+};
+
+
+/**
+ * Variant of a fragment program.
+ */
+struct st_fp_variant
+{
+ /** Parameters which generated this version of fragment program */
+ struct st_fp_variant_key key;
+
+ /** Driver's compiled shader */
+ void *driver_shader;
+
+ /** For glBitmap variants */
+ struct gl_program_parameter_list *parameters;
+ uint bitmap_sampler;
+
+ /** next in linked list */
+ struct st_fp_variant *next;
+};
+
+
/**
* Derived from Mesa gl_fragment_program:
*/
struct st_fragment_program
{
struct gl_fragment_program Base;
- GLuint serialNo;
struct pipe_shader_state tgsi;
- void *driver_shader;
- /** Program prefixed with glBitmap prologue */
- struct st_fragment_program *bitmap_program;
- uint bitmap_sampler;
+ struct st_fp_variant *variants;
};
-struct st_vp_varient_key
+/** Vertex program variant key */
+struct st_vp_variant_key
{
+ struct st_context *st; /**< variants are per-context */
boolean passthrough_edgeflags;
};
@@ -68,12 +103,12 @@ struct st_vp_varient_key
* This represents a vertex program, especially translated to match
* the inputs of a particular fragment shader.
*/
-struct st_vp_varient
+struct st_vp_variant
{
/* Parameters which generated this translated version of a vertex
* shader:
*/
- struct st_vp_varient_key key;
+ struct st_vp_variant_key key;
/**
* TGSI tokens (to later generate a 'draw' module shader for
@@ -88,9 +123,9 @@ struct st_vp_varient
struct draw_vertex_shader *draw_shader;
/** Next in linked list */
- struct st_vp_varient *next;
+ struct st_vp_variant *next;
- /** similar to that in st_vertex_program, but with information about edgeflags too */
+ /** similar to that in st_vertex_program, but with edgeflags info too */
GLuint num_inputs;
};
@@ -101,7 +136,6 @@ struct st_vp_varient
struct st_vertex_program
{
struct gl_vertex_program Base; /**< The Mesa vertex program */
- GLuint serialNo, lastSerialNo;
/** maps a Mesa VERT_ATTRIB_x to a packed TGSI input index */
GLuint input_to_index[VERT_ATTRIB_MAX];
@@ -115,18 +149,41 @@ struct st_vertex_program
ubyte output_semantic_index[VERT_RESULT_MAX];
GLuint num_outputs;
- /** List of translated varients of this vertex program.
+ /** List of translated variants of this vertex program.
*/
- struct st_vp_varient *varients;
+ struct st_vp_variant *variants;
+};
+
+
+
+/** Geometry program variant key */
+struct st_gp_variant_key
+{
+ struct st_context *st; /**< variants are per-context */
+ /* no other fields yet */
+};
+
+
+/**
+ * Geometry program variant.
+ */
+struct st_gp_variant
+{
+ /* Parameters which generated this translated version of a vertex */
+ struct st_gp_variant_key key;
+
+ void *driver_shader;
+
+ struct st_gp_variant *next;
};
+
/**
* Derived from Mesa gl_geometry_program:
*/
struct st_geometry_program
{
struct gl_geometry_program Base; /**< The Mesa geometry program */
- GLuint serialNo;
/** map GP input back to VP output */
GLuint input_map[PIPE_MAX_SHADER_INPUTS];
@@ -145,9 +202,12 @@ struct st_geometry_program
ubyte input_semantic_index[PIPE_MAX_SHADER_INPUTS];
struct pipe_shader_state tgsi;
- void *driver_shader;
+
+ struct st_gp_variant *variants;
};
+
+
static INLINE struct st_fragment_program *
st_fragment_program( struct gl_fragment_program *fp )
{
@@ -162,9 +222,9 @@ st_vertex_program( struct gl_vertex_program *vp )
}
static INLINE struct st_geometry_program *
-st_geometry_program( struct gl_geometry_program *vp )
+st_geometry_program( struct gl_geometry_program *gp )
{
- return (struct st_geometry_program *)vp;
+ return (struct st_geometry_program *)gp;
}
static INLINE void
@@ -198,32 +258,43 @@ st_reference_fragprog(struct st_context *st,
}
-extern void
-st_translate_fragment_program(struct st_context *st,
- struct st_fragment_program *fp);
+extern struct st_vp_variant *
+st_get_vp_variant(struct st_context *st,
+ struct st_vertex_program *stvp,
+ const struct st_vp_variant_key *key);
+
+
+extern struct st_fp_variant *
+st_get_fp_variant(struct st_context *st,
+ struct st_fragment_program *stfp,
+ const struct st_fp_variant_key *key);
+
+
+extern struct st_gp_variant *
+st_get_gp_variant(struct st_context *st,
+ struct st_geometry_program *stgp,
+ const struct st_gp_variant_key *key);
+
+
extern void
-st_translate_geometry_program(struct st_context *st,
- struct st_geometry_program *stgp);
+st_release_vp_variants( struct st_context *st,
+ struct st_vertex_program *stvp );
-/* Called after program string change, discard all previous
- * compilation results.
- */
extern void
-st_prepare_vertex_program(struct st_context *st,
- struct st_vertex_program *stvp);
+st_release_fp_variants( struct st_context *st,
+ struct st_fragment_program *stfp );
-extern struct st_vp_varient *
-st_translate_vertex_program(struct st_context *st,
- struct st_vertex_program *stvp,
- const struct st_vp_varient_key *key);
+extern void
+st_release_gp_variants(struct st_context *st,
+ struct st_geometry_program *stgp);
-void
-st_vp_release_varients( struct st_context *st,
- struct st_vertex_program *stvp );
extern void
st_print_shaders(struct gl_context *ctx);
+extern void
+st_destroy_program_variants(struct st_context *st);
+
#endif
diff --git a/src/mesa/tnl/t_vb_program.c b/src/mesa/tnl/t_vb_program.c
index 76f8fde3f52..94372bbafbc 100644
--- a/src/mesa/tnl/t_vb_program.c
+++ b/src/mesa/tnl/t_vb_program.c
@@ -67,6 +67,8 @@ struct vp_stage_data {
GLvector4f ndcCoords; /**< normalized device coords */
GLubyte *clipmask; /**< clip flags */
GLubyte ormask, andmask; /**< for clipping */
+
+ struct gl_program_machine machine;
};
@@ -311,7 +313,7 @@ run_vp( struct gl_context *ctx, struct tnl_pipeline_stage *stage )
struct vp_stage_data *store = VP_STAGE_DATA(stage);
struct vertex_buffer *VB = &tnl->vb;
struct gl_vertex_program *program = ctx->VertexProgram._Current;
- struct gl_program_machine machine;
+ struct gl_program_machine *machine = &store->machine;
GLuint outputs[VERT_RESULT_MAX], numOutputs;
GLuint i, j;
@@ -339,7 +341,7 @@ run_vp( struct gl_context *ctx, struct tnl_pipeline_stage *stage )
for (i = 0; i < VB->Count; i++) {
GLuint attr;
- init_machine(ctx, &machine);
+ init_machine(ctx, machine);
#if 0
printf("Input %d: %f, %f, %f, %f\n", i,
@@ -372,23 +374,23 @@ run_vp( struct gl_context *ctx, struct tnl_pipeline_stage *stage )
check_float(data[2]);
check_float(data[3]);
#endif
- COPY_CLEAN_4V(machine.VertAttribs[attr], size, data);
+ COPY_CLEAN_4V(machine->VertAttribs[attr], size, data);
}
}
/* execute the program */
- _mesa_execute_program(ctx, &program->Base, &machine);
+ _mesa_execute_program(ctx, &program->Base, machine);
/* copy the output registers into the VB->attribs arrays */
for (j = 0; j < numOutputs; j++) {
const GLuint attr = outputs[j];
#ifdef NAN_CHECK
- check_float(machine.Outputs[attr][0]);
- check_float(machine.Outputs[attr][1]);
- check_float(machine.Outputs[attr][2]);
- check_float(machine.Outputs[attr][3]);
+ check_float(machine->Outputs[attr][0]);
+ check_float(machine->Outputs[attr][1]);
+ check_float(machine->Outputs[attr][2]);
+ check_float(machine->Outputs[attr][3]);
#endif
- COPY_4V(store->results[attr].data[i], machine.Outputs[attr]);
+ COPY_4V(store->results[attr].data[i], machine->Outputs[attr]);
}
/* FOGC is a special case. Fragment shader expects (f,0,0,1) */
@@ -398,14 +400,14 @@ run_vp( struct gl_context *ctx, struct tnl_pipeline_stage *stage )
store->results[VERT_RESULT_FOGC].data[i][3] = 1.0;
}
#ifdef NAN_CHECK
- ASSERT(machine.Outputs[0][3] != 0.0F);
+ ASSERT(machine->Outputs[0][3] != 0.0F);
#endif
#if 0
printf("HPOS: %f %f %f %f\n",
- machine.Outputs[0][0],
- machine.Outputs[0][1],
- machine.Outputs[0][2],
- machine.Outputs[0][3]);
+ machine->Outputs[0][0],
+ machine->Outputs[0][1],
+ machine->Outputs[0][2],
+ machine->Outputs[0][3]);
#endif
}
@@ -501,7 +503,7 @@ init_vp(struct gl_context *ctx, struct tnl_pipeline_stage *stage)
const GLuint size = VB->Size;
GLuint i;
- stage->privatePtr = MALLOC(sizeof(*store));
+ stage->privatePtr = CALLOC(sizeof(*store));
store = VP_STAGE_DATA(stage);
if (!store)
return GL_FALSE;