From: Brian Date: Thu, 23 Aug 2007 00:51:39 +0000 (-0600) Subject: Checkpoint: texture image and sampler state handling, plus better vertex format code. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=c990d0fd57a05301429b3af75b7fed0337621941;p=mesa.git Checkpoint: texture image and sampler state handling, plus better vertex format code. Texture image/sampler state code should be working, but is disabled for now. Need to fix outstanding issues with vertex formats and texcoords first... --- diff --git a/src/mesa/pipe/i915simple/i915_context.h b/src/mesa/pipe/i915simple/i915_context.h index a037b202892..849c3b0efc3 100644 --- a/src/mesa/pipe/i915simple/i915_context.h +++ b/src/mesa/pipe/i915simple/i915_context.h @@ -76,6 +76,32 @@ #define I915_MAX_CONSTANT 32 + +/** + * New vertex format stuff... + */ +#define MAX_VERT_ATTRIBS 12 /* OK? */ + +#define FORMAT_OMIT 0 +#define FORMAT_1F 1 +#define FORMAT_2F 2 +#define FORMAT_3F 3 +#define FORMAT_4F 4 +#define FORMAT_4UB 5 + +struct vertex_info +{ + uint num_attribs; + uint hwfmt[2]; /** hardware format info for this format */ + uint attr_mask; /** mask of VF_ATTR_ bits */ + uint slot_to_attrib[MAX_VERT_ATTRIBS]; + uint interp_mode[MAX_VERT_ATTRIBS]; + uint format[MAX_VERT_ATTRIBS]; /**< FORMAT_x */ +}; + + + + struct i915_cache_context; /* Use to calculate differences between state emitted to hardware and @@ -95,10 +121,17 @@ struct i915_state uint *program; uint program_len; + /* texture sampler state */ unsigned sampler[I915_TEX_UNITS][3]; unsigned sampler_enable_flags; unsigned sampler_enable_nr; - + + /* texture image buffers */ + unsigned texbuffer[I915_TEX_UNITS][2]; + + /* vertex format registers */ + struct vertex_info vertex_info; + unsigned id; /* track lost context events */ }; diff --git a/src/mesa/pipe/i915simple/i915_fpc_emit.c b/src/mesa/pipe/i915simple/i915_fpc_emit.c index dfbc5f180c6..235938ac04f 100644 --- a/src/mesa/pipe/i915simple/i915_fpc_emit.c +++ b/src/mesa/pipe/i915simple/i915_fpc_emit.c @@ -192,7 +192,8 @@ uint i915_emit_texld( struct i915_fp_compile *p, uint coord, uint op ) { - if (coord != UREG(GET_UREG_TYPE(coord), GET_UREG_NR(coord))) { + uint k = UREG(GET_UREG_TYPE(coord), GET_UREG_NR(coord)); + if (coord != k) { /* No real way to work around this in the general case - need to * allocate and declare a new temporary register (a utemp won't * do). Will fallback for now. diff --git a/src/mesa/pipe/i915simple/i915_fpc_translate.c b/src/mesa/pipe/i915simple/i915_fpc_translate.c index dcf0d18f4ed..cd2faa8b976 100644 --- a/src/mesa/pipe/i915simple/i915_fpc_translate.c +++ b/src/mesa/pipe/i915simple/i915_fpc_translate.c @@ -153,8 +153,15 @@ src_vector(struct i915_fp_compile *p, src = i915_emit_decl(p, REG_TYPE_T, T_DIFFUSE, D0_CHANNEL_ALL); break; case FRAG_ATTRIB_COL1: +#if 1 src = i915_emit_decl(p, REG_TYPE_T, T_SPECULAR, D0_CHANNEL_XYZ); src = swizzle(src, X, Y, Z, ONE); +#else + /* total hack to force texture mapping */ + src = i915_emit_decl(p, REG_TYPE_T, + T_TEX0/* + (index - FRAG_ATTRIB_TEX0)*/, + D0_CHANNEL_ALL); +#endif break; case FRAG_ATTRIB_FOGC: src = i915_emit_decl(p, REG_TYPE_T, T_FOG_W, D0_CHANNEL_W); @@ -979,7 +986,7 @@ i915_fini_compile(struct i915_context *i915, struct i915_fp_compile *p) static void i915_find_wpos_space(struct i915_fp_compile *p) { - const uint inputs = p->shader->inputs_read; + const uint inputs = p->shader->inputs_read | FRAG_BIT_WPOS; /*XXX hack*/ uint i; p->wpos_tex = -1; diff --git a/src/mesa/pipe/i915simple/i915_prim_emit.c b/src/mesa/pipe/i915simple/i915_prim_emit.c index 2c5f11c225f..ff57d26d388 100644 --- a/src/mesa/pipe/i915simple/i915_prim_emit.c +++ b/src/mesa/pipe/i915simple/i915_prim_emit.c @@ -71,13 +71,56 @@ emit_hw_vertex( struct i915_context *i915, /* colors are ARGB (MSB to LSB) */ OUT_BATCH( pack_ub4(float_to_ubyte( vertex->data[1][2] ), - float_to_ubyte( vertex->data[1][1] ), - float_to_ubyte( vertex->data[1][0] ), - float_to_ubyte( vertex->data[1][3] )) ); + float_to_ubyte( vertex->data[1][1] ), + float_to_ubyte( vertex->data[1][0] ), + float_to_ubyte( vertex->data[1][3] )) ); } +static INLINE void +emit_hw_vertex2( struct i915_context *i915, + const struct vertex_header *vertex) +{ + const struct vertex_info *vinfo = &i915->current.vertex_info; + uint i; + + for (i = 0; i < vinfo->num_attribs; i++) { + switch (vinfo->format[i]) { + case FORMAT_OMIT: + /* no-op */ + break; + case FORMAT_1F: + OUT_BATCH( fui(vertex->data[i][0]) ); + break; + case FORMAT_2F: + OUT_BATCH( fui(vertex->data[i][0]) ); + OUT_BATCH( fui(vertex->data[i][1]) ); + break; + case FORMAT_3F: + OUT_BATCH( fui(vertex->data[i][0]) ); + OUT_BATCH( fui(vertex->data[i][1]) ); + OUT_BATCH( fui(vertex->data[i][2]) ); + break; + case FORMAT_4F: + OUT_BATCH( fui(vertex->data[i][0]) ); + OUT_BATCH( fui(vertex->data[i][1]) ); + OUT_BATCH( fui(vertex->data[i][2]) ); + OUT_BATCH( fui(vertex->data[i][3]) ); + break; + case FORMAT_4UB: + OUT_BATCH( pack_ub4(float_to_ubyte( vertex->data[i][2] ), + float_to_ubyte( vertex->data[i][1] ), + float_to_ubyte( vertex->data[i][0] ), + float_to_ubyte( vertex->data[i][3] )) ); + break; + default: + assert(0); + } + } +} + + static INLINE void emit_prim( struct draw_stage *stage, @@ -120,7 +163,7 @@ emit_prim( struct draw_stage *stage, ((4 + vertex_size * nr)/4 - 2)); for (i = 0; i < nr; i++) { - emit_hw_vertex(i915, prim->v[i]); + emit_hw_vertex2(i915, prim->v[i]); ptr += vertex_size / sizeof(int); } } diff --git a/src/mesa/pipe/i915simple/i915_state.h b/src/mesa/pipe/i915simple/i915_state.h index 43058451f29..86c6b0027d5 100644 --- a/src/mesa/pipe/i915simple/i915_state.h +++ b/src/mesa/pipe/i915simple/i915_state.h @@ -43,6 +43,7 @@ void i915_update_immediate( struct i915_context *i915 ); void i915_update_dynamic( struct i915_context *i915 ); void i915_update_derived( struct i915_context *i915 ); void i915_update_samplers( struct i915_context *i915 ); +void i915_update_textures(struct i915_context *i915); void i915_emit_hardware_state( struct i915_context *i915 ); diff --git a/src/mesa/pipe/i915simple/i915_state_derived.c b/src/mesa/pipe/i915simple/i915_state_derived.c index 5a493cc9cfa..bd952cc567d 100644 --- a/src/mesa/pipe/i915simple/i915_state_derived.c +++ b/src/mesa/pipe/i915simple/i915_state_derived.c @@ -29,20 +29,13 @@ #include "pipe/draw/draw_context.h" #include "i915_context.h" #include "i915_state.h" +#include "i915_reg.h" /* XXX should include i915_fpc.h but that causes some trouble atm */ extern void i915_translate_fragment_program( struct i915_context *i915 ); -#define EMIT_ATTR( VF_ATTR, FRAG_ATTR, INTERP ) \ -do { \ - slot_to_vf_attr[nr_attrs] = VF_ATTR; \ - nr_attrs++; \ - attr_mask |= (1 << (VF_ATTR)); \ -} while (0) - - static const unsigned frag_to_vf[FRAG_ATTRIB_MAX] = { VF_ATTRIB_POS, @@ -68,6 +61,19 @@ static const unsigned frag_to_vf[FRAG_ATTRIB_MAX] = }; +static INLINE void +emit_vertex_attr(struct vertex_info *vinfo, uint vfAttr, uint format) +{ + const uint n = vinfo->num_attribs; + vinfo->attr_mask |= (1 << vfAttr); + vinfo->slot_to_attrib[n] = vfAttr; + /*vinfo->interp_mode[n] = interpMode;*/ + vinfo->format[n] = format; + vinfo->num_attribs++; +} + + + /** * Determine which post-transform / pre-rasterization vertex attributes * we need. @@ -75,19 +81,17 @@ static const unsigned frag_to_vf[FRAG_ATTRIB_MAX] = */ static void calculate_vertex_layout( struct i915_context *i915 ) { -// const unsigned inputsRead = i915->fs.inputs_read; - const unsigned inputsRead = (FRAG_BIT_WPOS | FRAG_BIT_COL0); - unsigned slot_to_vf_attr[VF_ATTRIB_MAX]; - unsigned attr_mask = 0x0; - unsigned nr_attrs = 0; + const unsigned inputsRead = i915->fs.inputs_read; +// const unsigned inputsRead = (FRAG_BIT_WPOS | FRAG_BIT_COL0); unsigned i; + struct vertex_info *vinfo = &i915->current.vertex_info; - memset(slot_to_vf_attr, 0, sizeof(slot_to_vf_attr)); - + memset(vinfo, 0, sizeof(*vinfo)); /* TODO - Figure out if we need to do perspective divide, etc. */ - EMIT_ATTR(VF_ATTRIB_POS, FRAG_ATTRIB_WPOS, INTERP_LINEAR); + emit_vertex_attr(vinfo, VF_ATTRIB_POS, FORMAT_3F); + vinfo->hwfmt[0] |= S4_VFMT_XYZ; /* Pull in the rest of the attributes. They are all in float4 * format. Future optimizations could be to keep some attributes @@ -95,20 +99,29 @@ static void calculate_vertex_layout( struct i915_context *i915 ) */ for (i = 1; i < FRAG_ATTRIB_TEX0; i++) { if (inputsRead & (1 << i)) { - assert(i < sizeof(frag_to_vf) / sizeof(frag_to_vf[0])); + assert(i < Elements(frag_to_vf)); if (i915->setup.flatshade - && (i == FRAG_ATTRIB_COL0 || i == FRAG_ATTRIB_COL1)) - EMIT_ATTR(frag_to_vf[i], i, INTERP_CONSTANT); - else - EMIT_ATTR(frag_to_vf[i], i, INTERP_LINEAR); + && (i == FRAG_ATTRIB_COL0 || i == FRAG_ATTRIB_COL1)) { + emit_vertex_attr(vinfo, frag_to_vf[i], FORMAT_4UB); + } + else { + emit_vertex_attr(vinfo, frag_to_vf[i], FORMAT_4UB); + } + vinfo->hwfmt[0] |= S4_VFMT_COLOR; } } for (i = FRAG_ATTRIB_TEX0; i < FRAG_ATTRIB_MAX; i++) { + uint hwtc; if (inputsRead & (1 << i)) { + hwtc = TEXCOORDFMT_4D; assert(i < sizeof(frag_to_vf) / sizeof(frag_to_vf[0])); - EMIT_ATTR(frag_to_vf[i], i, INTERP_PERSPECTIVE); + emit_vertex_attr(vinfo, frag_to_vf[i], FORMAT_4F); + } + else { + hwtc = TEXCOORDFMT_NOT_PRESENT; } + vinfo->hwfmt[1] |= hwtc << ((i - FRAG_ATTRIB_TEX0) * 4); } /* Additional attributes required for setup: Just twosided @@ -117,24 +130,31 @@ static void calculate_vertex_layout( struct i915_context *i915 ) */ if (i915->setup.light_twoside) { if (inputsRead & FRAG_BIT_COL0) { - EMIT_ATTR(VF_ATTRIB_BFC0, FRAG_ATTRIB_MAX, 0); /* XXX: mark as discarded after setup */ + /* XXX: mark as discarded after setup */ + emit_vertex_attr(vinfo, VF_ATTRIB_BFC0, FORMAT_OMIT); } if (inputsRead & FRAG_BIT_COL1) { - EMIT_ATTR(VF_ATTRIB_BFC1, FRAG_ATTRIB_MAX, 0); /* XXX: discard after setup */ + /* XXX: discard after setup */ + emit_vertex_attr(vinfo, VF_ATTRIB_BFC1, FORMAT_OMIT); } } - /* If the attributes have changed, tell the draw module (which in turn - * tells the vf module) about the new vertex layout. + /* If the attributes have changed, tell the draw module about the new + * vertex layout. We'll also update the hardware vertex format info. */ draw_set_vertex_attributes( i915->draw, - slot_to_vf_attr, - nr_attrs ); + vinfo->slot_to_attrib, + vinfo->num_attribs); +#if 0 + printf("VERTEX_FORMAT LIS2: 0x%x LIS4: 0x%x\n", + vinfo->hwfmt[1], vinfo->hwfmt[0]); +#endif } + /* Hopefully this will remain quite simple, otherwise need to pull in * something like the state tracker mechanism. */ @@ -143,6 +163,12 @@ void i915_update_derived( struct i915_context *i915 ) if (i915->dirty & (I915_NEW_SETUP | I915_NEW_FS)) calculate_vertex_layout( i915 ); + if (i915->dirty & I915_NEW_SAMPLER) + i915_update_samplers(i915); + + if (i915->dirty & I915_NEW_TEXTURE) + i915_update_textures(i915); + if (i915->dirty) i915_update_immediate( i915 ); diff --git a/src/mesa/pipe/i915simple/i915_state_emit.c b/src/mesa/pipe/i915simple/i915_state_emit.c index dff9d40a83d..ceb96289b59 100644 --- a/src/mesa/pipe/i915simple/i915_state_emit.c +++ b/src/mesa/pipe/i915simple/i915_state_emit.c @@ -180,7 +180,6 @@ i915_emit_hardware_state(struct i915_context *i915 ) zformat = translate_depth_format( i915->framebuffer.zbuf->format ); OUT_BATCH(_3DSTATE_DST_BUF_VARS_CMD); - OUT_BATCH(DSTORG_HORT_BIAS(0x8) | /* .5 */ DSTORG_VERT_BIAS(0x8) | /* .5 */ LOD_PRECLAMP_OGL | @@ -190,6 +189,38 @@ i915_emit_hardware_state(struct i915_context *i915 ) } } + +#if 0 + /* texture images */ + if (i915->hardware_dirty & I915_HW_MAP) + { + const uint nr = i915->current.sampler_enable_nr; + const uint enabled = i915->current.sampler_enable_flags; + uint unit; + uint count = 0; + OUT_BATCH(_3DSTATE_MAP_STATE | (3 * nr)); + OUT_BATCH(enabled); + for (unit = 0; unit < I915_TEX_UNITS; unit++) { + if (enabled & (1 << unit)) { + struct pipe_buffer_handle *buf = + i915->texture[unit]->region->buffer; + uint offset = 0; + assert(buf); + + count++; + + OUT_RELOC(buf, + I915_BUFFER_ACCESS_READ, + offset); + OUT_BATCH(i915->current.texbuffer[unit][0]); /* MS3 */ + OUT_BATCH(i915->current.texbuffer[unit][1]); /* MS4 */ + } + } + assert(count == nr); + } +#endif + +#if 0 /* samplers */ if (i915->hardware_dirty & I915_HW_SAMPLER) { @@ -210,8 +241,7 @@ i915_emit_hardware_state(struct i915_context *i915 ) } } } - - +#endif /* constants */ if (i915->hardware_dirty & I915_HW_PROGRAM) diff --git a/src/mesa/pipe/i915simple/i915_state_immediate.c b/src/mesa/pipe/i915simple/i915_state_immediate.c index 1cd18664999..c6f1f59f883 100644 --- a/src/mesa/pipe/i915simple/i915_state_immediate.c +++ b/src/mesa/pipe/i915simple/i915_state_immediate.c @@ -53,8 +53,16 @@ static void upload_S2S4(struct i915_context *i915) unsigned LIS2, LIS4; /* I915_NEW_VERTEX_FORMAT */ +#if 01 LIS2 = 0xffffffff; LIS4 = (S4_VFMT_XYZ | S4_VFMT_COLOR); +#else + assert(LIS2 == i915->current.vertex_info.hwfmt[1]); + assert(LIS4 == i915->current.vertex_info.hwfmt[0]); + LIS2 = i915->current.vertex_info.hwfmt[1]; + LIS4 = i915->current.vertex_info.hwfmt[0]; + printf("UPLOAD FORMAT LIS2: 0x%x LIS4: 0x%x\n", LIS2, LIS4); +#endif /* I915_NEW_SETUP */ diff --git a/src/mesa/pipe/i915simple/i915_state_sampler.c b/src/mesa/pipe/i915simple/i915_state_sampler.c index 591e3684da2..e23e4bdcf74 100644 --- a/src/mesa/pipe/i915simple/i915_state_sampler.c +++ b/src/mesa/pipe/i915simple/i915_state_sampler.c @@ -39,6 +39,7 @@ #include "i915_state_inlines.h" #include "i915_context.h" #include "i915_reg.h" +#include "i915_state.h" //#include "i915_cache.h" @@ -283,3 +284,136 @@ void i915_update_samplers( struct i915_context *i915 ) i915->hardware_dirty |= I915_HW_SAMPLER; } + + + + +static uint +translate_texture_format(uint pipeFormat) +{ + switch (pipeFormat) { + case PIPE_FORMAT_U_L8: + return MAPSURF_8BIT | MT_8BIT_L8; + case PIPE_FORMAT_U_I8: + return MAPSURF_8BIT | MT_8BIT_I8; + case PIPE_FORMAT_U_A8: + return MAPSURF_8BIT | MT_8BIT_A8; + case PIPE_FORMAT_U_L8_A8: + return MAPSURF_16BIT | MT_16BIT_AY88; + case PIPE_FORMAT_U_R5_G6_B5: + return MAPSURF_16BIT | MT_16BIT_RGB565; + case PIPE_FORMAT_U_A1_R5_G5_B5: + return MAPSURF_16BIT | MT_16BIT_ARGB1555; + case PIPE_FORMAT_U_A4_R4_G4_B4: + return MAPSURF_16BIT | MT_16BIT_ARGB4444; + case PIPE_FORMAT_U_A8_R8_G8_B8: + return MAPSURF_32BIT | MT_32BIT_ARGB8888; + case PIPE_FORMAT_YCBCR_REV: + return (MAPSURF_422 | MT_422_YCRCB_NORMAL); + case PIPE_FORMAT_YCBCR: + return (MAPSURF_422 | MT_422_YCRCB_SWAPY); +#if 0 + case PIPE_FORMAT_RGB_FXT1: + case PIPE_FORMAT_RGBA_FXT1: + return (MAPSURF_COMPRESSED | MT_COMPRESS_FXT1); +#endif + case PIPE_FORMAT_U_Z16: + return (MAPSURF_16BIT | MT_16BIT_L16); +#if 0 + case PIPE_FORMAT_RGBA_DXT1: + case PIPE_FORMAT_RGB_DXT1: + return (MAPSURF_COMPRESSED | MT_COMPRESS_DXT1); + case PIPE_FORMAT_RGBA_DXT3: + return (MAPSURF_COMPRESSED | MT_COMPRESS_DXT2_3); + case PIPE_FORMAT_RGBA_DXT5: + return (MAPSURF_COMPRESSED | MT_COMPRESS_DXT4_5); +#endif + case PIPE_FORMAT_S8_Z24: + return (MAPSURF_32BIT | MT_32BIT_xL824); + default: + fprintf(stderr, "i915: translate_texture_format() bad image format %x\n", + pipeFormat); + assert(0); + return 0; + } +} + + +#define I915_TEXREG_MS3 1 +#define I915_TEXREG_MS4 2 + + +static void +i915_update_texture(struct i915_context *i915, uint unit, + uint state[6]) +{ + const struct pipe_mipmap_tree *mt = i915->texture[unit]; + uint format, pitch; + const uint width = mt->width0, height = mt->height0, depth = mt->depth0; + const uint num_levels = mt->last_level - mt->first_level; + + assert(mt); + assert(width); + assert(height); + assert(depth); + +#if 0 + if (i915->state.tex_buffer[unit] != NULL) { + driBOUnReference(i915->state.tex_buffer[unit]); + i915->state.tex_buffer[unit] = NULL; + } +#endif + + + { + struct pipe_buffer_handle *p = driBOReference(mt->region->buffer); + } + +#if 0 + i915->state.tex_buffer[unit] = driBOReference(intelObj->mt->region-> + buffer); + i915->state.tex_offset[unit] = intel_miptree_image_offset(intelObj->mt, + 0, intelObj-> + firstLevel); +#endif + + format = translate_texture_format(mt->format); + pitch = mt->pitch * mt->cpp; + + assert(format); + assert(pitch); + + printf("texture format = 0x%x\n", format); + + /* MS3 state */ + state[0] = + (((height - 1) << MS3_HEIGHT_SHIFT) + | ((width - 1) << MS3_WIDTH_SHIFT) + | format + | MS3_USE_FENCE_REGS); + + /* MS4 state */ + state[1] = + ((((pitch / 4) - 1) << MS4_PITCH_SHIFT) + | MS4_CUBE_FACE_ENA_MASK + | ((num_levels * 4) << MS4_MAX_LOD_SHIFT) + | ((depth - 1) << MS4_VOLUME_DEPTH_SHIFT)); +} + + + +void +i915_update_textures(struct i915_context *i915) +{ + uint unit; + + for (unit = 0; unit < I915_TEX_UNITS; unit++) { + /* determine unit enable/disable by looking for a bound mipmap tree */ + /* could also examine the fragment program? */ + if (i915->texture[unit]) { + i915_update_texture(i915, unit, i915->current.texbuffer[unit]); + } + } + + i915->hardware_dirty |= I915_HW_MAP; +}