diff options
Diffstat (limited to 'src/gallium/drivers/i915/i915_state_static.c')
-rw-r--r-- | src/gallium/drivers/i915/i915_state_static.c | 154 |
1 files changed, 153 insertions, 1 deletions
diff --git a/src/gallium/drivers/i915/i915_state_static.c b/src/gallium/drivers/i915/i915_state_static.c index dc9a4c1e2f..2865298318 100644 --- a/src/gallium/drivers/i915/i915_state_static.c +++ b/src/gallium/drivers/i915/i915_state_static.c @@ -27,17 +27,120 @@ #include "i915_reg.h" #include "i915_context.h" #include "i915_state.h" +#include "i915_resource.h" +#include "i915_screen.h" /*********************************************************************** * Update framebuffer state */ +static unsigned translate_format(enum pipe_format format) +{ + switch (format) { + case PIPE_FORMAT_B8G8R8A8_UNORM: + return COLOR_BUF_ARGB8888; + case PIPE_FORMAT_B5G6R5_UNORM: + return COLOR_BUF_RGB565; + default: + assert(0); + return 0; + } +} + +static unsigned translate_depth_format(enum pipe_format zformat) +{ + switch (zformat) { + case PIPE_FORMAT_Z24X8_UNORM: + case PIPE_FORMAT_Z24_UNORM_S8_USCALED: + return DEPTH_FRMT_24_FIXED_8_OTHER; + case PIPE_FORMAT_Z16_UNORM: + return DEPTH_FRMT_16_FIXED; + default: + assert(0); + return 0; + } +} + +static inline uint32_t +buf_3d_tiling_bits(enum i915_winsys_buffer_tile tiling) +{ + uint32_t tiling_bits = 0; + + switch (tiling) { + case I915_TILE_Y: + tiling_bits |= BUF_3D_TILE_WALK_Y; + case I915_TILE_X: + tiling_bits |= BUF_3D_TILED_SURFACE; + case I915_TILE_NONE: + break; + } + + return tiling_bits; +} + static void update_framebuffer(struct i915_context *i915) { - /* HW emit currently references framebuffer state directly: + struct pipe_surface *cbuf_surface = i915->framebuffer.cbufs[0]; + struct pipe_surface *depth_surface = i915->framebuffer.zsbuf; + unsigned x, y; + int layer; + uint32_t draw_offset, draw_size; + + if (cbuf_surface) { + struct i915_texture *tex = i915_texture(cbuf_surface->texture); + assert(tex); + + i915->current.cbuf_bo = tex->buffer; + i915->current.cbuf_flags = BUF_3D_ID_COLOR_BACK | + BUF_3D_PITCH(tex->stride) | /* pitch in bytes */ + buf_3d_tiling_bits(tex->tiling); + + layer = cbuf_surface->u.tex.first_layer; + + x = tex->image_offset[cbuf_surface->u.tex.level][layer].nblocksx; + y = tex->image_offset[cbuf_surface->u.tex.level][layer].nblocksy; + } else { + i915->current.cbuf_bo = NULL; + x = y = 0; + } + i915->static_dirty |= I915_DST_BUF_COLOR; + + /* What happens if no zbuf?? */ + if (depth_surface) { + struct i915_texture *tex = i915_texture(depth_surface->texture); + unsigned offset = i915_texture_offset(tex, depth_surface->u.tex.level, + depth_surface->u.tex.first_layer); + assert(tex); + assert(offset == 0); + + i915->current.depth_bo = tex->buffer; + i915->current.depth_flags = BUF_3D_ID_DEPTH | + BUF_3D_PITCH(tex->stride) | /* pitch in bytes */ + buf_3d_tiling_bits(tex->tiling); + } else + i915->current.depth_bo = NULL; + i915->static_dirty |= I915_DST_BUF_DEPTH; + + /* drawing rect calculations */ + draw_offset = x | (y << 16); + draw_size = (i915->framebuffer.width - 1 + x) | + ((i915->framebuffer.height - 1 + y) << 16); + if (i915->current.draw_offset != draw_offset) { + i915->current.draw_offset = draw_offset; + i915_set_flush_dirty(i915, I915_PIPELINE_FLUSH); + i915->static_dirty |= I915_DST_RECT; + } + if (i915->current.draw_size != draw_size) { + i915->current.draw_size = draw_size; + i915->static_dirty |= I915_DST_RECT; + } + i915->hardware_dirty |= I915_HW_STATIC; + + /* flush the cache in case we sample from the old renderbuffers */ + i915_set_flush_dirty(i915, I915_FLUSH_CACHE); } struct i915_tracked_state i915_hw_framebuffer = { @@ -45,3 +148,52 @@ struct i915_tracked_state i915_hw_framebuffer = { update_framebuffer, I915_NEW_FRAMEBUFFER }; + +static void update_dst_buf_vars(struct i915_context *i915) +{ + struct pipe_surface *cbuf_surface = i915->framebuffer.cbufs[0]; + struct pipe_surface *depth_surface = i915->framebuffer.zsbuf; + uint32_t dst_buf_vars, cformat, zformat; + uint32_t early_z = 0; + + if (cbuf_surface) + cformat = cbuf_surface->format; + else + cformat = PIPE_FORMAT_B8G8R8A8_UNORM; /* arbitrary */ + cformat = translate_format(cformat); + + if (depth_surface) { + struct i915_texture *tex = i915_texture(depth_surface->texture); + struct i915_screen *is = i915_screen(i915->base.screen); + + zformat = translate_depth_format(depth_surface->format); + + if (is->is_i945 && tex->tiling != I915_TILE_NONE + && !i915->fs->info.writes_z) + early_z = CLASSIC_EARLY_DEPTH; + } else + zformat = 0; + + dst_buf_vars = DSTORG_HORT_BIAS(0x8) | /* .5 */ + DSTORG_VERT_BIAS(0x8) | /* .5 */ + LOD_PRECLAMP_OGL | + TEX_DEFAULT_COLOR_OGL | + cformat | + zformat | + early_z; + + if (i915->current.dst_buf_vars != dst_buf_vars) { + if (early_z != (i915->current.dst_buf_vars & CLASSIC_EARLY_DEPTH)) + i915_set_flush_dirty(i915, I915_PIPELINE_FLUSH); + + i915->current.dst_buf_vars = dst_buf_vars; + i915->static_dirty |= I915_DST_VARS; + i915->hardware_dirty |= I915_HW_STATIC; + } +} + +struct i915_tracked_state i915_hw_dst_buf_vars = { + "dst buf vars", + update_dst_buf_vars, + I915_NEW_FRAMEBUFFER | I915_NEW_FS +}; |