X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fgallium%2Fdrivers%2Fetnaviv%2Fetnaviv_state.c;h=5c8448315f0c0f574e5fd50f0a0709eb957778f4;hb=92d5e3c692483a6c90f5738b6cfabb6d11a7ef78;hp=fb7bb0f4c50d88bed181309dab7fdcd91d2a836e;hpb=8644b59b5d98cf58deaecc583f68edd8be23bfca;p=mesa.git diff --git a/src/gallium/drivers/etnaviv/etnaviv_state.c b/src/gallium/drivers/etnaviv/etnaviv_state.c index fb7bb0f4c50..5c8448315f0 100644 --- a/src/gallium/drivers/etnaviv/etnaviv_state.c +++ b/src/gallium/drivers/etnaviv/etnaviv_state.c @@ -37,24 +37,12 @@ #include "etnaviv_surface.h" #include "etnaviv_translate.h" #include "etnaviv_util.h" +#include "util/u_framebuffer.h" #include "util/u_helpers.h" #include "util/u_inlines.h" #include "util/u_math.h" #include "util/u_memory.h" - -static void -etna_set_blend_color(struct pipe_context *pctx, const struct pipe_blend_color *bc) -{ - struct etna_context *ctx = etna_context(pctx); - struct compiled_blend_color *cs = &ctx->blend_color; - - cs->PE_ALPHA_BLEND_COLOR = - VIVS_PE_ALPHA_BLEND_COLOR_R(etna_cfloat_to_uint8(bc->color[0])) | - VIVS_PE_ALPHA_BLEND_COLOR_G(etna_cfloat_to_uint8(bc->color[1])) | - VIVS_PE_ALPHA_BLEND_COLOR_B(etna_cfloat_to_uint8(bc->color[2])) | - VIVS_PE_ALPHA_BLEND_COLOR_A(etna_cfloat_to_uint8(bc->color[3])); - ctx->dirty |= ETNA_DIRTY_BLEND_COLOR; -} +#include "util/u_upload_mgr.h" static void etna_set_stencil_ref(struct pipe_context *pctx, const struct pipe_stencil_ref *sr) @@ -64,10 +52,12 @@ etna_set_stencil_ref(struct pipe_context *pctx, const struct pipe_stencil_ref *s ctx->stencil_ref_s = *sr; - cs->PE_STENCIL_CONFIG = VIVS_PE_STENCIL_CONFIG_REF_FRONT(sr->ref_value[0]); - /* rest of bits weaved in from depth_stencil_alpha */ - cs->PE_STENCIL_CONFIG_EXT = - VIVS_PE_STENCIL_CONFIG_EXT_REF_BACK(sr->ref_value[0]); + for (unsigned i = 0; i < 2; i++) { + cs->PE_STENCIL_CONFIG[i] = + VIVS_PE_STENCIL_CONFIG_REF_FRONT(sr->ref_value[i]); + cs->PE_STENCIL_CONFIG_EXT[i] = + VIVS_PE_STENCIL_CONFIG_EXT_REF_BACK(sr->ref_value[!i]); + } ctx->dirty |= ETNA_DIRTY_STENCIL_REF; } @@ -103,30 +93,40 @@ etna_set_constant_buffer(struct pipe_context *pctx, /* Note that the state tracker can unbind constant buffers by * passing NULL here. */ - if (unlikely(!cb)) + if (unlikely(!cb || (!cb->buffer && !cb->user_buffer))) return; /* there is no support for ARB_uniform_buffer_object */ assert(cb->buffer == NULL && cb->user_buffer != NULL); + if (!cb->buffer) { + struct pipe_constant_buffer *cb = &ctx->constant_buffer[shader]; + u_upload_data(pctx->const_uploader, 0, cb->buffer_size, 16, cb->user_buffer, &cb->buffer_offset, &cb->buffer); + } + ctx->dirty |= ETNA_DIRTY_CONSTBUF; } static void -etna_update_render_resource(struct pipe_context *pctx, struct pipe_resource *pres) +etna_update_render_resource(struct pipe_context *pctx, struct etna_resource *base) { - struct etna_resource *res = etna_resource(pres); + struct etna_resource *to = base, *from = base; + + if (base->texture && etna_resource_newer(etna_resource(base->texture), base)) + from = etna_resource(base->texture); - if (res->texture && etna_resource_older(res, etna_resource(res->texture))) { - /* The render buffer is older than the texture buffer. Copy it over. */ - etna_copy_resource(pctx, pres, res->texture, 0, pres->last_level); - res->seqno = etna_resource(res->texture)->seqno; + if (base->render) + to = etna_resource(base->render); + + if ((to != from) && etna_resource_older(to, from)) { + etna_copy_resource(pctx, &to->base, &from->base, 0, base->base.last_level); + to->seqno = from->seqno; } } static void etna_set_framebuffer_state(struct pipe_context *pctx, - const struct pipe_framebuffer_state *sv) + const struct pipe_framebuffer_state *fb) { struct etna_context *ctx = etna_context(pctx); struct compiled_framebuffer_state *cs = &ctx->framebuffer; @@ -135,21 +135,28 @@ etna_set_framebuffer_state(struct pipe_context *pctx, /* Set up TS as well. Warning: this state is used by both the RS and PE */ uint32_t ts_mem_config = 0; + uint32_t pe_mem_config = 0; - if (sv->nr_cbufs > 0) { /* at least one color buffer? */ - struct etna_surface *cbuf = etna_surface(sv->cbufs[0]); + if (fb->nr_cbufs > 0) { /* at least one color buffer? */ + struct etna_surface *cbuf = etna_surface(fb->cbufs[0]); struct etna_resource *res = etna_resource(cbuf->base.texture); bool color_supertiled = (res->layout & ETNA_LAYOUT_BIT_SUPER) != 0; + uint32_t fmt = translate_pe_format(cbuf->base.format); assert(res->layout & ETNA_LAYOUT_BIT_TILE); /* Cannot render to linear surfaces */ - etna_update_render_resource(pctx, cbuf->base.texture); + etna_update_render_resource(pctx, etna_resource(cbuf->prsc)); + + if (fmt >= PE_FORMAT_R16F) + cs->PE_COLOR_FORMAT = VIVS_PE_COLOR_FORMAT_FORMAT_EXT(fmt) | + VIVS_PE_COLOR_FORMAT_FORMAT_MASK; + else + cs->PE_COLOR_FORMAT = VIVS_PE_COLOR_FORMAT_FORMAT(fmt); - pipe_surface_reference(&cs->cbuf, &cbuf->base); - cs->PE_COLOR_FORMAT = - VIVS_PE_COLOR_FORMAT_FORMAT(translate_rs_format(cbuf->base.format)) | + cs->PE_COLOR_FORMAT |= VIVS_PE_COLOR_FORMAT_COMPONENTS__MASK | VIVS_PE_COLOR_FORMAT_OVERWRITE | - COND(color_supertiled, VIVS_PE_COLOR_FORMAT_SUPER_TILED); + COND(color_supertiled, VIVS_PE_COLOR_FORMAT_SUPER_TILED) | + COND(color_supertiled && ctx->specs.halti >= 5, VIVS_PE_COLOR_FORMAT_SUPER_TILED_NEW); /* VIVS_PE_COLOR_FORMAT_COMPONENTS() and * VIVS_PE_COLOR_FORMAT_OVERWRITE comes from blend_state * but only if we set the bits above. */ @@ -179,7 +186,6 @@ etna_set_framebuffer_state(struct pipe_context *pctx, cs->PE_COLOR_STRIDE = cbuf->surf.stride; if (cbuf->surf.ts_size) { - ts_mem_config |= VIVS_TS_MEM_CONFIG_COLOR_FAST_CLEAR; cs->TS_COLOR_CLEAR_VALUE = cbuf->level->clear_value; cs->TS_COLOR_STATUS_BASE = cbuf->ts_reloc; @@ -187,35 +193,41 @@ etna_set_framebuffer_state(struct pipe_context *pctx, cs->TS_COLOR_SURFACE_BASE = cbuf->reloc[0]; cs->TS_COLOR_SURFACE_BASE.flags = ETNA_RELOC_READ | ETNA_RELOC_WRITE; - } - /* MSAA */ - if (cbuf->base.texture->nr_samples > 1) - ts_mem_config |= - VIVS_TS_MEM_CONFIG_MSAA | translate_msaa_format(cbuf->base.format); + pe_mem_config |= VIVS_PE_MEM_CONFIG_COLOR_TS_MODE(cbuf->level->ts_mode); + + if (cbuf->level->ts_compress_fmt >= 0) { + /* overwrite bit breaks v1/v2 compression */ + if (!ctx->specs.v4_compression) + cs->PE_COLOR_FORMAT &= ~VIVS_PE_COLOR_FORMAT_OVERWRITE; + + ts_mem_config |= + VIVS_TS_MEM_CONFIG_COLOR_COMPRESSION | + VIVS_TS_MEM_CONFIG_COLOR_COMPRESSION_FORMAT(cbuf->level->ts_compress_fmt); + } + } nr_samples_color = cbuf->base.texture->nr_samples; } else { - pipe_surface_reference(&cs->cbuf, NULL); /* Clearing VIVS_PE_COLOR_FORMAT_COMPONENTS__MASK and * VIVS_PE_COLOR_FORMAT_OVERWRITE prevents us from overwriting the * color target */ - cs->PE_COLOR_FORMAT = 0; + cs->PE_COLOR_FORMAT = VIVS_PE_COLOR_FORMAT_OVERWRITE; cs->PE_COLOR_STRIDE = 0; cs->TS_COLOR_STATUS_BASE.bo = NULL; cs->TS_COLOR_SURFACE_BASE.bo = NULL; - for (int i = 0; i < ETNA_MAX_PIXELPIPES; i++) - cs->PE_PIPE_COLOR_ADDR[i].bo = NULL; + cs->PE_COLOR_ADDR = ctx->dummy_rt_reloc; + for (int i = 0; i < ctx->specs.pixel_pipes; i++) + cs->PE_PIPE_COLOR_ADDR[i] = ctx->dummy_rt_reloc; } - if (sv->zsbuf != NULL) { - struct etna_surface *zsbuf = etna_surface(sv->zsbuf); + if (fb->zsbuf != NULL) { + struct etna_surface *zsbuf = etna_surface(fb->zsbuf); struct etna_resource *res = etna_resource(zsbuf->base.texture); - etna_update_render_resource(pctx, zsbuf->base.texture); + etna_update_render_resource(pctx, etna_resource(zsbuf->prsc)); - pipe_surface_reference(&cs->zsbuf, &zsbuf->base); assert(res->layout &ETNA_LAYOUT_BIT_TILE); /* Cannot render to linear surfaces */ uint32_t depth_format = translate_depth_format(zsbuf->base.format); @@ -226,7 +238,10 @@ etna_set_framebuffer_state(struct pipe_context *pctx, cs->PE_DEPTH_CONFIG = depth_format | COND(depth_supertiled, VIVS_PE_DEPTH_CONFIG_SUPER_TILED) | - VIVS_PE_DEPTH_CONFIG_DEPTH_MODE_Z; + VIVS_PE_DEPTH_CONFIG_DEPTH_MODE_Z | + VIVS_PE_DEPTH_CONFIG_UNK18 | /* something to do with clipping? */ + COND(ctx->specs.halti >= 5, VIVS_PE_DEPTH_CONFIG_DISABLE_ZS) /* Needs to be enabled on GC7000, otherwise depth writes hang w/ TS - apparently it does something else now */ + ; /* VIVS_PE_DEPTH_CONFIG_ONLY_DEPTH */ /* merged with depth_stencil_alpha */ @@ -245,7 +260,6 @@ etna_set_framebuffer_state(struct pipe_context *pctx, cs->PE_DEPTH_NORMALIZE = fui(exp2f(depth_bits) - 1.0f); if (zsbuf->surf.ts_size) { - ts_mem_config |= VIVS_TS_MEM_CONFIG_DEPTH_FAST_CLEAR; cs->TS_DEPTH_CLEAR_VALUE = zsbuf->level->clear_value; cs->TS_DEPTH_STATUS_BASE = zsbuf->ts_reloc; @@ -253,19 +267,21 @@ etna_set_framebuffer_state(struct pipe_context *pctx, cs->TS_DEPTH_SURFACE_BASE = zsbuf->reloc[0]; cs->TS_DEPTH_SURFACE_BASE.flags = ETNA_RELOC_READ | ETNA_RELOC_WRITE; + + pe_mem_config |= VIVS_PE_MEM_CONFIG_DEPTH_TS_MODE(zsbuf->level->ts_mode); + + if (zsbuf->level->ts_compress_fmt >= 0) { + ts_mem_config |= + VIVS_TS_MEM_CONFIG_DEPTH_COMPRESSION | + COND(zsbuf->level->ts_compress_fmt == COMPRESSION_FORMAT_D24S8, + VIVS_TS_MEM_CONFIG_STENCIL_ENABLE); + } } ts_mem_config |= COND(depth_bits == 16, VIVS_TS_MEM_CONFIG_DEPTH_16BPP); - /* MSAA */ - if (zsbuf->base.texture->nr_samples > 1) - /* XXX VIVS_TS_MEM_CONFIG_DEPTH_COMPRESSION; - * Disable without MSAA for now, as it causes corruption in glquake. */ - ts_mem_config |= VIVS_TS_MEM_CONFIG_DEPTH_COMPRESSION; - nr_samples_depth = zsbuf->base.texture->nr_samples; } else { - pipe_surface_reference(&cs->zsbuf, NULL); cs->PE_DEPTH_CONFIG = VIVS_PE_DEPTH_CONFIG_DEPTH_MODE_NONE; cs->PE_DEPTH_ADDR.bo = NULL; cs->PE_DEPTH_STRIDE = 0; @@ -325,21 +341,23 @@ etna_set_framebuffer_state(struct pipe_context *pctx, /* Scissor setup */ cs->SE_SCISSOR_LEFT = 0; /* affected by rasterizer and scissor state as well */ cs->SE_SCISSOR_TOP = 0; - cs->SE_SCISSOR_RIGHT = (sv->width << 16) + ETNA_SE_SCISSOR_MARGIN_RIGHT; - cs->SE_SCISSOR_BOTTOM = (sv->height << 16) + ETNA_SE_SCISSOR_MARGIN_BOTTOM; - cs->SE_CLIP_RIGHT = (sv->width << 16) + ETNA_SE_CLIP_MARGIN_RIGHT; - cs->SE_CLIP_BOTTOM = (sv->height << 16) + ETNA_SE_CLIP_MARGIN_BOTTOM; + cs->SE_SCISSOR_RIGHT = (fb->width << 16) + ETNA_SE_SCISSOR_MARGIN_RIGHT; + cs->SE_SCISSOR_BOTTOM = (fb->height << 16) + ETNA_SE_SCISSOR_MARGIN_BOTTOM; + cs->SE_CLIP_RIGHT = (fb->width << 16) + ETNA_SE_CLIP_MARGIN_RIGHT; + cs->SE_CLIP_BOTTOM = (fb->height << 16) + ETNA_SE_CLIP_MARGIN_BOTTOM; cs->TS_MEM_CONFIG = ts_mem_config; + cs->PE_MEM_CONFIG = pe_mem_config; /* Single buffer setup. There is only one switch for this, not a separate * one per color buffer / depth buffer. To keep the logic simple always use * single buffer when this feature is available. */ - cs->PE_LOGIC_OP = VIVS_PE_LOGIC_OP_SINGLE_BUFFER(ctx->specs.single_buffer ? 2 : 0); + cs->PE_LOGIC_OP = VIVS_PE_LOGIC_OP_SINGLE_BUFFER(ctx->specs.single_buffer ? 3 : 0); - ctx->framebuffer_s = *sv; /* keep copy of original structure */ - ctx->dirty |= ETNA_DIRTY_FRAMEBUFFER; + /* keep copy of original structure */ + util_copy_framebuffer_state(&ctx->framebuffer_s, fb); + ctx->dirty |= ETNA_DIRTY_FRAMEBUFFER | ETNA_DIRTY_DERIVE_TS; } static void @@ -558,14 +576,27 @@ etna_vertex_elements_state_create(struct pipe_context *pctx, assert(format_type != ETNA_NO_MATCH); assert(normalize != ETNA_NO_MATCH); - cs->FE_VERTEX_ELEMENT_CONFIG[idx] = - COND(nonconsecutive, VIVS_FE_VERTEX_ELEMENT_CONFIG_NONCONSECUTIVE) | - format_type | - VIVS_FE_VERTEX_ELEMENT_CONFIG_NUM(util_format_get_nr_components(elements[idx].src_format)) | - normalize | VIVS_FE_VERTEX_ELEMENT_CONFIG_ENDIAN(ENDIAN_MODE_NO_SWAP) | - VIVS_FE_VERTEX_ELEMENT_CONFIG_STREAM(elements[idx].vertex_buffer_index) | - VIVS_FE_VERTEX_ELEMENT_CONFIG_START(elements[idx].src_offset) | - VIVS_FE_VERTEX_ELEMENT_CONFIG_END(end_offset - start_offset); + if (ctx->specs.halti < 5) { + cs->FE_VERTEX_ELEMENT_CONFIG[idx] = + COND(nonconsecutive, VIVS_FE_VERTEX_ELEMENT_CONFIG_NONCONSECUTIVE) | + format_type | + VIVS_FE_VERTEX_ELEMENT_CONFIG_NUM(util_format_get_nr_components(elements[idx].src_format)) | + normalize | VIVS_FE_VERTEX_ELEMENT_CONFIG_ENDIAN(ENDIAN_MODE_NO_SWAP) | + VIVS_FE_VERTEX_ELEMENT_CONFIG_STREAM(elements[idx].vertex_buffer_index) | + VIVS_FE_VERTEX_ELEMENT_CONFIG_START(elements[idx].src_offset) | + VIVS_FE_VERTEX_ELEMENT_CONFIG_END(end_offset - start_offset); + } else { /* HALTI5 spread vertex attrib config over two registers */ + cs->NFE_GENERIC_ATTRIB_CONFIG0[idx] = + format_type | + VIVS_NFE_GENERIC_ATTRIB_CONFIG0_NUM(util_format_get_nr_components(elements[idx].src_format)) | + normalize | VIVS_NFE_GENERIC_ATTRIB_CONFIG0_ENDIAN(ENDIAN_MODE_NO_SWAP) | + VIVS_NFE_GENERIC_ATTRIB_CONFIG0_STREAM(elements[idx].vertex_buffer_index) | + VIVS_NFE_GENERIC_ATTRIB_CONFIG0_START(elements[idx].src_offset); + cs->NFE_GENERIC_ATTRIB_CONFIG1[idx] = + COND(nonconsecutive, VIVS_NFE_GENERIC_ATTRIB_CONFIG1_NONCONSECUTIVE) | + VIVS_NFE_GENERIC_ATTRIB_CONFIG1_END(end_offset - start_offset); + } + cs->NFE_GENERIC_ATTRIB_SCALE[idx] = 0x3f800000; /* 1 for integer, 1.0 for float */ } return cs; @@ -586,6 +617,42 @@ etna_vertex_elements_state_bind(struct pipe_context *pctx, void *ve) ctx->dirty |= ETNA_DIRTY_VERTEX_ELEMENTS; } +static bool +etna_update_ts_config(struct etna_context *ctx) +{ + uint32_t new_ts_config = ctx->framebuffer.TS_MEM_CONFIG; + + if (ctx->framebuffer_s.nr_cbufs > 0) { + struct etna_surface *c_surf = etna_surface(ctx->framebuffer_s.cbufs[0]); + + if(c_surf->level->ts_size && c_surf->level->ts_valid) { + new_ts_config |= VIVS_TS_MEM_CONFIG_COLOR_FAST_CLEAR; + } else { + new_ts_config &= ~VIVS_TS_MEM_CONFIG_COLOR_FAST_CLEAR; + } + } + + if (ctx->framebuffer_s.zsbuf) { + struct etna_surface *zs_surf = etna_surface(ctx->framebuffer_s.zsbuf); + + if(zs_surf->level->ts_size && zs_surf->level->ts_valid) { + new_ts_config |= VIVS_TS_MEM_CONFIG_DEPTH_FAST_CLEAR; + } else { + new_ts_config &= ~VIVS_TS_MEM_CONFIG_DEPTH_FAST_CLEAR; + } + } + + if (new_ts_config != ctx->framebuffer.TS_MEM_CONFIG || + (ctx->dirty & ETNA_DIRTY_FRAMEBUFFER)) { + ctx->framebuffer.TS_MEM_CONFIG = new_ts_config; + ctx->dirty |= ETNA_DIRTY_TS; + } + + ctx->dirty &= ~ETNA_DIRTY_DERIVE_TS; + + return true; +} + struct etna_state_updater { bool (*update)(struct etna_context *ctx); uint32_t dirty; @@ -600,6 +667,12 @@ static const struct etna_state_updater etna_state_updates[] = { }, { etna_update_blend, ETNA_DIRTY_BLEND | ETNA_DIRTY_FRAMEBUFFER + }, + { + etna_update_blend_color, ETNA_DIRTY_BLEND_COLOR | ETNA_DIRTY_FRAMEBUFFER, + }, + { + etna_update_ts_config, ETNA_DIRTY_DERIVE_TS, } };