X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fgallium%2Fdrivers%2Fi915%2Fi915_state_static.c;h=9a7ea227ecf2beeefbbdba758bb1d78df7066120;hb=31da39ddc92e780dc539bf34d2de7f82fc65fa86;hp=20cd23f8f736cf833d5fced426f4763028d856cc;hpb=cf143c1f4d7c3636ddd5c767518b1b00ff46b16c;p=mesa.git diff --git a/src/gallium/drivers/i915/i915_state_static.c b/src/gallium/drivers/i915/i915_state_static.c index 20cd23f8f73..9a7ea227ecf 100644 --- a/src/gallium/drivers/i915/i915_state_static.c +++ b/src/gallium/drivers/i915/i915_state_static.c @@ -28,7 +28,7 @@ #include "i915_context.h" #include "i915_state.h" #include "i915_resource.h" - +#include "i915_screen.h" /*********************************************************************** @@ -38,9 +38,23 @@ static unsigned translate_format(enum pipe_format format) { switch (format) { case PIPE_FORMAT_B8G8R8A8_UNORM: + case PIPE_FORMAT_B8G8R8A8_SRGB: + case PIPE_FORMAT_B8G8R8X8_UNORM: + case PIPE_FORMAT_R8G8B8A8_UNORM: + case PIPE_FORMAT_R8G8B8X8_UNORM: return COLOR_BUF_ARGB8888; case PIPE_FORMAT_B5G6R5_UNORM: return COLOR_BUF_RGB565; + case PIPE_FORMAT_B5G5R5A1_UNORM: + return COLOR_BUF_ARGB1555; + case PIPE_FORMAT_B4G4R4A4_UNORM: + return COLOR_BUF_ARGB4444; + case PIPE_FORMAT_B10G10R10A2_UNORM: + return COLOR_BUF_ARGB2101010; + case PIPE_FORMAT_L8_UNORM: + case PIPE_FORMAT_A8_UNORM: + case PIPE_FORMAT_I8_UNORM: + return COLOR_BUF_8BIT; default: assert(0); return 0; @@ -51,7 +65,7 @@ static unsigned translate_depth_format(enum pipe_format zformat) { switch (zformat) { case PIPE_FORMAT_Z24X8_UNORM: - case PIPE_FORMAT_Z24_UNORM_S8_USCALED: + case PIPE_FORMAT_Z24_UNORM_S8_UINT: return DEPTH_FRMT_24_FIXED_8_OTHER; case PIPE_FORMAT_Z16_UNORM: return DEPTH_FRMT_16_FIXED; @@ -78,38 +92,13 @@ buf_3d_tiling_bits(enum i915_winsys_buffer_tile tiling) return tiling_bits; } -/** - * Examine framebuffer state to determine width, height. - */ -static boolean -framebuffer_size(const struct pipe_framebuffer_state *fb, - uint *width, uint *height) -{ - if (fb->cbufs[0]) { - *width = fb->cbufs[0]->width; - *height = fb->cbufs[0]->height; - return TRUE; - } - else if (fb->zsbuf) { - *width = fb->zsbuf->width; - *height = fb->zsbuf->height; - return TRUE; - } - else { - *width = *height = 0; - return FALSE; - } -} - static void update_framebuffer(struct i915_context *i915) { struct pipe_surface *cbuf_surface = i915->framebuffer.cbufs[0]; struct pipe_surface *depth_surface = i915->framebuffer.zsbuf; - unsigned cformat, zformat; - unsigned x, y, w, h; + unsigned x, y; int layer; - uint32_t draw_offset; - boolean ret; + uint32_t draw_offset, draw_size; if (cbuf_surface) { struct i915_texture *tex = i915_texture(cbuf_surface->texture); @@ -119,7 +108,6 @@ static void update_framebuffer(struct i915_context *i915) i915->current.cbuf_flags = BUF_3D_ID_COLOR_BACK | BUF_3D_PITCH(tex->stride) | /* pitch in bytes */ buf_3d_tiling_bits(tex->tiling); - cformat = cbuf_surface->format; layer = cbuf_surface->u.tex.first_layer; @@ -127,10 +115,9 @@ static void update_framebuffer(struct i915_context *i915) y = tex->image_offset[cbuf_surface->u.tex.level][layer].nblocksy; } else { i915->current.cbuf_bo = NULL; - cformat = PIPE_FORMAT_B8G8R8A8_UNORM; /* arbitrary */ x = y = 0; } - cformat = translate_format(cformat); + i915->static_dirty |= I915_DST_BUF_COLOR; /* What happens if no zbuf?? */ @@ -139,34 +126,30 @@ static void update_framebuffer(struct i915_context *i915) unsigned offset = i915_texture_offset(tex, depth_surface->u.tex.level, depth_surface->u.tex.first_layer); assert(tex); - assert(offset == 0); + if (offset != 0) + debug_printf("Depth offset is %d\n",offset); 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); - zformat = translate_depth_format(depth_surface->format); - } else { + } else i915->current.depth_bo = NULL; - zformat = 0; - } - - i915->current.dst_buf_vars = DSTORG_HORT_BIAS(0x8) | /* .5 */ - DSTORG_VERT_BIAS(0x8) | /* .5 */ - LOD_PRECLAMP_OGL | - TEX_DEFAULT_COLOR_OGL | - cformat | - zformat; + i915->static_dirty |= I915_DST_BUF_DEPTH; /* drawing rect calculations */ draw_offset = x | (y << 16); - ret = framebuffer_size(&i915->framebuffer, &w, &h); - assert(ret); + 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->current.draw_size = (w - 1 + x) | ((h - 1 + y) << 16); i915->hardware_dirty |= I915_HW_STATIC; @@ -179,3 +162,94 @@ struct i915_tracked_state i915_hw_framebuffer = { update_framebuffer, I915_NEW_FRAMEBUFFER }; + +static uint32_t need_target_fixup(struct pipe_surface* p, uint32_t *fixup) +{ + const struct + { + enum pipe_format format; + uint hw_swizzle; + } fixup_formats[] = { + { PIPE_FORMAT_R8G8B8A8_UNORM, 0x21030000 /* BGRA */}, + { PIPE_FORMAT_R8G8B8X8_UNORM, 0x21030000 /* BGRX */}, + { PIPE_FORMAT_L8_UNORM, 0x00030000 /* RRRA */}, + { PIPE_FORMAT_I8_UNORM, 0x00030000 /* RRRA */}, + { PIPE_FORMAT_A8_UNORM, 0x33330000 /* AAAA */}, + { PIPE_FORMAT_NONE, 0x00000000}, + }; + + enum pipe_format f; + /* if we don't have a surface bound yet, we don't need to fixup the shader */ + if (!p) + return 0; + + f = p->format; + for(int i = 0; fixup_formats[i].format != PIPE_FORMAT_NONE; i++) + if (fixup_formats[i].format == f) { + *fixup = fixup_formats[i].hw_swizzle; + return f; + } + + *fixup = 0; + return 0; +} + +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; + uint32_t fixup = 0; + int need_fixup; + + 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; + } + + need_fixup = need_target_fixup(cbuf_surface, &fixup); + if (i915->current.target_fixup_format != need_fixup || + i915->current.fixup_swizzle != fixup) { + i915->current.target_fixup_format = need_fixup; + i915->current.fixup_swizzle = fixup; + /* we also send a new program to make sure the fixup for RGBA surfaces happens */ + i915->hardware_dirty |= I915_HW_PROGRAM; + } +} + +struct i915_tracked_state i915_hw_dst_buf_vars = { + "dst buf vars", + update_dst_buf_vars, + I915_NEW_FRAMEBUFFER | I915_NEW_FS +};