101e04c3fSmrg/* 201e04c3fSmrg * Copyright (c) 2014-2015 Etnaviv Project 301e04c3fSmrg * 401e04c3fSmrg * Permission is hereby granted, free of charge, to any person obtaining a 501e04c3fSmrg * copy of this software and associated documentation files (the "Software"), 601e04c3fSmrg * to deal in the Software without restriction, including without limitation 701e04c3fSmrg * the rights to use, copy, modify, merge, publish, distribute, sub license, 801e04c3fSmrg * and/or sell copies of the Software, and to permit persons to whom the 901e04c3fSmrg * Software is furnished to do so, subject to the following conditions: 1001e04c3fSmrg * 1101e04c3fSmrg * The above copyright notice and this permission notice (including the 1201e04c3fSmrg * next paragraph) shall be included in all copies or substantial portions 1301e04c3fSmrg * of the Software. 1401e04c3fSmrg * 1501e04c3fSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1601e04c3fSmrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1701e04c3fSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 1801e04c3fSmrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 1901e04c3fSmrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 2001e04c3fSmrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 2101e04c3fSmrg * DEALINGS IN THE SOFTWARE. 2201e04c3fSmrg * 2301e04c3fSmrg * Authors: 2401e04c3fSmrg * Wladimir J. van der Laan <laanwj@gmail.com> 2501e04c3fSmrg */ 2601e04c3fSmrg 2701e04c3fSmrg#include "etnaviv_emit.h" 2801e04c3fSmrg 2901e04c3fSmrg#include "etnaviv_blend.h" 3001e04c3fSmrg#include "etnaviv_compiler.h" 3101e04c3fSmrg#include "etnaviv_context.h" 3201e04c3fSmrg#include "etnaviv_rasterizer.h" 3301e04c3fSmrg#include "etnaviv_resource.h" 3401e04c3fSmrg#include "etnaviv_rs.h" 3501e04c3fSmrg#include "etnaviv_screen.h" 3601e04c3fSmrg#include "etnaviv_shader.h" 3701e04c3fSmrg#include "etnaviv_texture.h" 3801e04c3fSmrg#include "etnaviv_translate.h" 3901e04c3fSmrg#include "etnaviv_uniforms.h" 4001e04c3fSmrg#include "etnaviv_util.h" 4101e04c3fSmrg#include "etnaviv_zsa.h" 4201e04c3fSmrg#include "hw/common.xml.h" 4301e04c3fSmrg#include "hw/state.xml.h" 4401e04c3fSmrg#include "hw/state_blt.xml.h" 4501e04c3fSmrg#include "util/u_math.h" 4601e04c3fSmrg 4701e04c3fSmrg/* Queue a STALL command (queues 2 words) */ 4801e04c3fSmrgstatic inline void 4901e04c3fSmrgCMD_STALL(struct etna_cmd_stream *stream, uint32_t from, uint32_t to) 5001e04c3fSmrg{ 5101e04c3fSmrg etna_cmd_stream_emit(stream, VIV_FE_STALL_HEADER_OP_STALL); 5201e04c3fSmrg etna_cmd_stream_emit(stream, VIV_FE_STALL_TOKEN_FROM(from) | VIV_FE_STALL_TOKEN_TO(to)); 5301e04c3fSmrg} 5401e04c3fSmrg 5501e04c3fSmrgvoid 5601e04c3fSmrgetna_stall(struct etna_cmd_stream *stream, uint32_t from, uint32_t to) 5701e04c3fSmrg{ 5801e04c3fSmrg bool blt = (from == SYNC_RECIPIENT_BLT) || (to == SYNC_RECIPIENT_BLT); 5901e04c3fSmrg etna_cmd_stream_reserve(stream, blt ? 8 : 4); 6001e04c3fSmrg 6101e04c3fSmrg if (blt) { 6201e04c3fSmrg etna_emit_load_state(stream, VIVS_BLT_ENABLE >> 2, 1, 0); 6301e04c3fSmrg etna_cmd_stream_emit(stream, 1); 6401e04c3fSmrg } 6501e04c3fSmrg 6601e04c3fSmrg /* TODO: set bit 28/29 of token after BLT COPY_BUFFER */ 6701e04c3fSmrg etna_emit_load_state(stream, VIVS_GL_SEMAPHORE_TOKEN >> 2, 1, 0); 6801e04c3fSmrg etna_cmd_stream_emit(stream, VIVS_GL_SEMAPHORE_TOKEN_FROM(from) | VIVS_GL_SEMAPHORE_TOKEN_TO(to)); 6901e04c3fSmrg 7001e04c3fSmrg if (from == SYNC_RECIPIENT_FE) { 7101e04c3fSmrg /* if the frontend is to be stalled, queue a STALL frontend command */ 7201e04c3fSmrg CMD_STALL(stream, from, to); 7301e04c3fSmrg } else { 7401e04c3fSmrg /* otherwise, load the STALL token state */ 7501e04c3fSmrg etna_emit_load_state(stream, VIVS_GL_STALL_TOKEN >> 2, 1, 0); 7601e04c3fSmrg etna_cmd_stream_emit(stream, VIVS_GL_STALL_TOKEN_FROM(from) | VIVS_GL_STALL_TOKEN_TO(to)); 7701e04c3fSmrg } 7801e04c3fSmrg 7901e04c3fSmrg if (blt) { 8001e04c3fSmrg etna_emit_load_state(stream, VIVS_BLT_ENABLE >> 2, 1, 0); 8101e04c3fSmrg etna_cmd_stream_emit(stream, 0); 8201e04c3fSmrg } 8301e04c3fSmrg} 8401e04c3fSmrg 8501e04c3fSmrg#define EMIT_STATE(state_name, src_value) \ 8601e04c3fSmrg etna_coalsence_emit(stream, &coalesce, VIVS_##state_name, src_value) 8701e04c3fSmrg 8801e04c3fSmrg#define EMIT_STATE_FIXP(state_name, src_value) \ 8901e04c3fSmrg etna_coalsence_emit_fixp(stream, &coalesce, VIVS_##state_name, src_value) 9001e04c3fSmrg 9101e04c3fSmrg#define EMIT_STATE_RELOC(state_name, src_value) \ 9201e04c3fSmrg etna_coalsence_emit_reloc(stream, &coalesce, VIVS_##state_name, src_value) 9301e04c3fSmrg 9401e04c3fSmrg#define ETNA_3D_CONTEXT_SIZE (400) /* keep this number above "Total state updates (fixed)" from gen_weave_state tool */ 9501e04c3fSmrg 9601e04c3fSmrgstatic unsigned 9701e04c3fSmrgrequired_stream_size(struct etna_context *ctx) 9801e04c3fSmrg{ 9901e04c3fSmrg unsigned size = ETNA_3D_CONTEXT_SIZE; 10001e04c3fSmrg 10101e04c3fSmrg /* stall + flush */ 10201e04c3fSmrg size += 2 + 4; 10301e04c3fSmrg 10401e04c3fSmrg /* vertex elements */ 10501e04c3fSmrg size += ctx->vertex_elements->num_elements + 1; 10601e04c3fSmrg 10701e04c3fSmrg /* uniforms - worst case (2 words per uniform load) */ 1087ec681f3Smrg size += ctx->shader.vs->uniforms.count * 2; 1097ec681f3Smrg size += ctx->shader.fs->uniforms.count * 2; 11001e04c3fSmrg 11101e04c3fSmrg /* shader */ 11201e04c3fSmrg size += ctx->shader_state.vs_inst_mem_size + 1; 11301e04c3fSmrg size += ctx->shader_state.ps_inst_mem_size + 1; 11401e04c3fSmrg 11501e04c3fSmrg /* DRAW_INDEXED_PRIMITIVES command */ 11601e04c3fSmrg size += 6; 11701e04c3fSmrg 11801e04c3fSmrg /* reserve for alignment etc. */ 11901e04c3fSmrg size += 64; 12001e04c3fSmrg 12101e04c3fSmrg return size; 12201e04c3fSmrg} 12301e04c3fSmrg 12401e04c3fSmrg/* Emit state that only exists on HALTI5+ */ 12501e04c3fSmrgstatic void 12601e04c3fSmrgemit_halti5_only_state(struct etna_context *ctx, int vs_output_count) 12701e04c3fSmrg{ 12801e04c3fSmrg struct etna_cmd_stream *stream = ctx->stream; 12901e04c3fSmrg uint32_t dirty = ctx->dirty; 13001e04c3fSmrg struct etna_coalesce coalesce; 13101e04c3fSmrg 13201e04c3fSmrg etna_coalesce_start(stream, &coalesce); 13301e04c3fSmrg if (unlikely(dirty & (ETNA_DIRTY_SHADER))) { 13401e04c3fSmrg /* Magic states (load balancing, inter-unit sync, buffers) */ 1357ec681f3Smrg /*007C4*/ EMIT_STATE(FE_HALTI5_ID_CONFIG, ctx->shader_state.FE_HALTI5_ID_CONFIG); 13601e04c3fSmrg /*00870*/ EMIT_STATE(VS_HALTI5_OUTPUT_COUNT, vs_output_count | ((vs_output_count * 0x10) << 8)); 13701e04c3fSmrg /*008A0*/ EMIT_STATE(VS_HALTI5_UNK008A0, 0x0001000e | ((0x110/vs_output_count) << 20)); 13801e04c3fSmrg for (int x = 0; x < 4; ++x) { 13901e04c3fSmrg /*008E0*/ EMIT_STATE(VS_HALTI5_OUTPUT(x), ctx->shader_state.VS_OUTPUT[x]); 14001e04c3fSmrg } 14101e04c3fSmrg } 14201e04c3fSmrg if (unlikely(dirty & (ETNA_DIRTY_VERTEX_ELEMENTS | ETNA_DIRTY_SHADER))) { 14301e04c3fSmrg for (int x = 0; x < 4; ++x) { 14401e04c3fSmrg /*008C0*/ EMIT_STATE(VS_HALTI5_INPUT(x), ctx->shader_state.VS_INPUT[x]); 14501e04c3fSmrg } 14601e04c3fSmrg } 14701e04c3fSmrg if (unlikely(dirty & (ETNA_DIRTY_SHADER))) { 1487ec681f3Smrg /*00A90*/ EMIT_STATE(PA_VARYING_NUM_COMPONENTS(0), ctx->shader_state.GL_VARYING_NUM_COMPONENTS[0]); 1497ec681f3Smrg /*00A94*/ EMIT_STATE(PA_VARYING_NUM_COMPONENTS(1), ctx->shader_state.GL_VARYING_NUM_COMPONENTS[1]); 15001e04c3fSmrg /*00AA8*/ EMIT_STATE(PA_VS_OUTPUT_COUNT, vs_output_count); 1517ec681f3Smrg /*01080*/ EMIT_STATE(PS_VARYING_NUM_COMPONENTS(0), ctx->shader_state.GL_VARYING_NUM_COMPONENTS[0]); 1527ec681f3Smrg /*01084*/ EMIT_STATE(PS_VARYING_NUM_COMPONENTS(1), ctx->shader_state.GL_VARYING_NUM_COMPONENTS[1]); 15301e04c3fSmrg /*03888*/ EMIT_STATE(GL_HALTI5_SH_SPECIALS, ctx->shader_state.GL_HALTI5_SH_SPECIALS); 15401e04c3fSmrg } 15501e04c3fSmrg etna_coalesce_end(stream, &coalesce); 15601e04c3fSmrg} 15701e04c3fSmrg 15801e04c3fSmrg/* Emit state that no longer exists on HALTI5 */ 15901e04c3fSmrgstatic void 16001e04c3fSmrgemit_pre_halti5_state(struct etna_context *ctx) 16101e04c3fSmrg{ 16201e04c3fSmrg struct etna_cmd_stream *stream = ctx->stream; 16301e04c3fSmrg uint32_t dirty = ctx->dirty; 16401e04c3fSmrg struct etna_coalesce coalesce; 16501e04c3fSmrg 16601e04c3fSmrg etna_coalesce_start(stream, &coalesce); 16701e04c3fSmrg if (unlikely(dirty & (ETNA_DIRTY_SHADER))) { 16801e04c3fSmrg /*00800*/ EMIT_STATE(VS_END_PC, ctx->shader_state.VS_END_PC); 16901e04c3fSmrg } 17001e04c3fSmrg if (unlikely(dirty & (ETNA_DIRTY_SHADER))) { 17101e04c3fSmrg for (int x = 0; x < 4; ++x) { 17201e04c3fSmrg /*00810*/ EMIT_STATE(VS_OUTPUT(x), ctx->shader_state.VS_OUTPUT[x]); 17301e04c3fSmrg } 17401e04c3fSmrg } 17501e04c3fSmrg if (unlikely(dirty & (ETNA_DIRTY_VERTEX_ELEMENTS | ETNA_DIRTY_SHADER))) { 17601e04c3fSmrg for (int x = 0; x < 4; ++x) { 17701e04c3fSmrg /*00820*/ EMIT_STATE(VS_INPUT(x), ctx->shader_state.VS_INPUT[x]); 17801e04c3fSmrg } 17901e04c3fSmrg } 18001e04c3fSmrg if (unlikely(dirty & (ETNA_DIRTY_SHADER))) { 18101e04c3fSmrg /*00838*/ EMIT_STATE(VS_START_PC, ctx->shader_state.VS_START_PC); 18201e04c3fSmrg } 18301e04c3fSmrg if (unlikely(dirty & (ETNA_DIRTY_SHADER))) { 18401e04c3fSmrg for (int x = 0; x < 10; ++x) { 18501e04c3fSmrg /*00A40*/ EMIT_STATE(PA_SHADER_ATTRIBUTES(x), ctx->shader_state.PA_SHADER_ATTRIBUTES[x]); 18601e04c3fSmrg } 18701e04c3fSmrg } 18801e04c3fSmrg if (unlikely(dirty & (ETNA_DIRTY_FRAMEBUFFER))) { 18901e04c3fSmrg /*00E04*/ EMIT_STATE(RA_MULTISAMPLE_UNK00E04, ctx->framebuffer.RA_MULTISAMPLE_UNK00E04); 19001e04c3fSmrg for (int x = 0; x < 4; ++x) { 19101e04c3fSmrg /*00E10*/ EMIT_STATE(RA_MULTISAMPLE_UNK00E10(x), ctx->framebuffer.RA_MULTISAMPLE_UNK00E10[x]); 19201e04c3fSmrg } 19301e04c3fSmrg for (int x = 0; x < 16; ++x) { 19401e04c3fSmrg /*00E40*/ EMIT_STATE(RA_CENTROID_TABLE(x), ctx->framebuffer.RA_CENTROID_TABLE[x]); 19501e04c3fSmrg } 19601e04c3fSmrg } 19701e04c3fSmrg if (unlikely(dirty & (ETNA_DIRTY_SHADER | ETNA_DIRTY_FRAMEBUFFER))) { 19801e04c3fSmrg /*01000*/ EMIT_STATE(PS_END_PC, ctx->shader_state.PS_END_PC); 19901e04c3fSmrg } 20001e04c3fSmrg if (unlikely(dirty & (ETNA_DIRTY_SHADER | ETNA_DIRTY_FRAMEBUFFER))) { 20101e04c3fSmrg /*01018*/ EMIT_STATE(PS_START_PC, ctx->shader_state.PS_START_PC); 20201e04c3fSmrg } 20301e04c3fSmrg if (unlikely(dirty & (ETNA_DIRTY_SHADER))) { 2047ec681f3Smrg /*03820*/ EMIT_STATE(GL_VARYING_NUM_COMPONENTS, ctx->shader_state.GL_VARYING_NUM_COMPONENTS[0]); 20501e04c3fSmrg for (int x = 0; x < 2; ++x) { 20601e04c3fSmrg /*03828*/ EMIT_STATE(GL_VARYING_COMPONENT_USE(x), ctx->shader_state.GL_VARYING_COMPONENT_USE[x]); 20701e04c3fSmrg } 2087ec681f3Smrg /*03834*/ EMIT_STATE(GL_VARYING_NUM_COMPONENTS2, ctx->shader_state.GL_VARYING_NUM_COMPONENTS[1]); 20901e04c3fSmrg } 21001e04c3fSmrg etna_coalesce_end(stream, &coalesce); 21101e04c3fSmrg} 21201e04c3fSmrg 21301e04c3fSmrg/* Weave state before draw operation. This function merges all the compiled 21401e04c3fSmrg * state blocks under the context into one device register state. Parts of 21501e04c3fSmrg * this state that are changed since last call (dirty) will be uploaded as 21601e04c3fSmrg * state changes in the command buffer. */ 21701e04c3fSmrgvoid 21801e04c3fSmrgetna_emit_state(struct etna_context *ctx) 21901e04c3fSmrg{ 22001e04c3fSmrg struct etna_cmd_stream *stream = ctx->stream; 2217ec681f3Smrg struct etna_screen *screen = ctx->screen; 2227ec681f3Smrg unsigned ccw = ctx->rasterizer->front_ccw; 2237ec681f3Smrg 22401e04c3fSmrg 22501e04c3fSmrg /* Pre-reserve the command buffer space which we are likely to need. 22601e04c3fSmrg * This must cover all the state emitted below, and the following 22701e04c3fSmrg * draw command. */ 22801e04c3fSmrg etna_cmd_stream_reserve(stream, required_stream_size(ctx)); 22901e04c3fSmrg 23001e04c3fSmrg uint32_t dirty = ctx->dirty; 23101e04c3fSmrg 23201e04c3fSmrg /* Pre-processing: see what caches we need to flush before making state changes. */ 23301e04c3fSmrg uint32_t to_flush = 0; 2347ec681f3Smrg if (unlikely(dirty & (ETNA_DIRTY_BLEND))) 23501e04c3fSmrg to_flush |= VIVS_GL_FLUSH_CACHE_COLOR; 2367ec681f3Smrg if (unlikely(dirty & ETNA_DIRTY_ZSA)) 2377ec681f3Smrg to_flush |= VIVS_GL_FLUSH_CACHE_DEPTH; 23801e04c3fSmrg if (unlikely(dirty & (ETNA_DIRTY_TEXTURE_CACHES))) 23901e04c3fSmrg to_flush |= VIVS_GL_FLUSH_CACHE_TEXTURE; 24001e04c3fSmrg if (unlikely(dirty & (ETNA_DIRTY_FRAMEBUFFER))) /* Framebuffer config changed? */ 24101e04c3fSmrg to_flush |= VIVS_GL_FLUSH_CACHE_COLOR | VIVS_GL_FLUSH_CACHE_DEPTH; 24201e04c3fSmrg if (DBG_ENABLED(ETNA_DBG_CFLUSH_ALL)) 24301e04c3fSmrg to_flush |= VIVS_GL_FLUSH_CACHE_TEXTURE | VIVS_GL_FLUSH_CACHE_COLOR | VIVS_GL_FLUSH_CACHE_DEPTH; 24401e04c3fSmrg 24501e04c3fSmrg if (to_flush) { 24601e04c3fSmrg etna_set_state(stream, VIVS_GL_FLUSH_CACHE, to_flush); 24701e04c3fSmrg etna_stall(stream, SYNC_RECIPIENT_RA, SYNC_RECIPIENT_PE); 24801e04c3fSmrg } 24901e04c3fSmrg 25001e04c3fSmrg /* Flush TS cache before changing TS configuration. */ 25101e04c3fSmrg if (unlikely(dirty & ETNA_DIRTY_TS)) { 25201e04c3fSmrg etna_set_state(stream, VIVS_TS_FLUSH_CACHE, VIVS_TS_FLUSH_CACHE_FLUSH); 25301e04c3fSmrg } 25401e04c3fSmrg 25501e04c3fSmrg /* Update vertex elements. This is different from any of the other states, in that 25601e04c3fSmrg * a) the number of vertex elements written matters: so write only active ones 25701e04c3fSmrg * b) the vertex element states must all be written: do not skip entries that stay the same */ 25801e04c3fSmrg if (dirty & (ETNA_DIRTY_VERTEX_ELEMENTS)) { 2597ec681f3Smrg if (screen->specs.halti >= 5) { 26001e04c3fSmrg /*17800*/ etna_set_state_multi(stream, VIVS_NFE_GENERIC_ATTRIB_CONFIG0(0), 26101e04c3fSmrg ctx->vertex_elements->num_elements, 26201e04c3fSmrg ctx->vertex_elements->NFE_GENERIC_ATTRIB_CONFIG0); 26301e04c3fSmrg /*17A00*/ etna_set_state_multi(stream, VIVS_NFE_GENERIC_ATTRIB_SCALE(0), 26401e04c3fSmrg ctx->vertex_elements->num_elements, 26501e04c3fSmrg ctx->vertex_elements->NFE_GENERIC_ATTRIB_SCALE); 26601e04c3fSmrg /*17A80*/ etna_set_state_multi(stream, VIVS_NFE_GENERIC_ATTRIB_CONFIG1(0), 26701e04c3fSmrg ctx->vertex_elements->num_elements, 26801e04c3fSmrg ctx->vertex_elements->NFE_GENERIC_ATTRIB_CONFIG1); 26901e04c3fSmrg } else { 27001e04c3fSmrg /* Special case: vertex elements must always be sent in full if changed */ 27101e04c3fSmrg /*00600*/ etna_set_state_multi(stream, VIVS_FE_VERTEX_ELEMENT_CONFIG(0), 27201e04c3fSmrg ctx->vertex_elements->num_elements, 27301e04c3fSmrg ctx->vertex_elements->FE_VERTEX_ELEMENT_CONFIG); 2747ec681f3Smrg if (screen->specs.halti >= 2) { 27501e04c3fSmrg /*00780*/ etna_set_state_multi(stream, VIVS_FE_GENERIC_ATTRIB_SCALE(0), 27601e04c3fSmrg ctx->vertex_elements->num_elements, 27701e04c3fSmrg ctx->vertex_elements->NFE_GENERIC_ATTRIB_SCALE); 27801e04c3fSmrg } 27901e04c3fSmrg } 28001e04c3fSmrg } 28101e04c3fSmrg unsigned vs_output_count = etna_rasterizer_state(ctx->rasterizer)->point_size_per_vertex 28201e04c3fSmrg ? ctx->shader_state.VS_OUTPUT_COUNT_PSIZE 28301e04c3fSmrg : ctx->shader_state.VS_OUTPUT_COUNT; 28401e04c3fSmrg 28501e04c3fSmrg /* The following code is originally generated by gen_merge_state.py, to 28601e04c3fSmrg * emit state in increasing order of address (this makes it possible to merge 28701e04c3fSmrg * consecutive register updates into one SET_STATE command) 28801e04c3fSmrg * 28901e04c3fSmrg * There have been some manual changes, where the weaving operation is not 29001e04c3fSmrg * simply bitwise or: 29101e04c3fSmrg * - scissor fixp 29201e04c3fSmrg * - num vertex elements 29301e04c3fSmrg * - scissor handling 29401e04c3fSmrg * - num samplers 29501e04c3fSmrg * - texture lod 29601e04c3fSmrg * - ETNA_DIRTY_TS 29701e04c3fSmrg * - removed ETNA_DIRTY_BASE_SETUP statements -- these are guaranteed to not 29801e04c3fSmrg * change anyway 29901e04c3fSmrg * - PS / framebuffer interaction for MSAA 30001e04c3fSmrg * - move update of GL_MULTI_SAMPLE_CONFIG first 30101e04c3fSmrg * - add unlikely()/likely() 30201e04c3fSmrg */ 30301e04c3fSmrg struct etna_coalesce coalesce; 30401e04c3fSmrg 30501e04c3fSmrg etna_coalesce_start(stream, &coalesce); 30601e04c3fSmrg 30701e04c3fSmrg /* begin only EMIT_STATE -- make sure no new etna_reserve calls are done here 30801e04c3fSmrg * directly 30901e04c3fSmrg * or indirectly */ 31001e04c3fSmrg /* multi sample config is set first, and outside of the normal sorting 31101e04c3fSmrg * order, as changing the multisample state clobbers PS.INPUT_COUNT (and 31201e04c3fSmrg * possibly PS.TEMP_REGISTER_CONTROL). 31301e04c3fSmrg */ 31401e04c3fSmrg if (unlikely(dirty & (ETNA_DIRTY_FRAMEBUFFER | ETNA_DIRTY_SAMPLE_MASK))) { 31501e04c3fSmrg uint32_t val = VIVS_GL_MULTI_SAMPLE_CONFIG_MSAA_ENABLES(ctx->sample_mask); 31601e04c3fSmrg val |= ctx->framebuffer.GL_MULTI_SAMPLE_CONFIG; 31701e04c3fSmrg 31801e04c3fSmrg /*03818*/ EMIT_STATE(GL_MULTI_SAMPLE_CONFIG, val); 31901e04c3fSmrg } 32001e04c3fSmrg if (likely(dirty & (ETNA_DIRTY_INDEX_BUFFER))) { 32101e04c3fSmrg /*00644*/ EMIT_STATE_RELOC(FE_INDEX_STREAM_BASE_ADDR, &ctx->index_buffer.FE_INDEX_STREAM_BASE_ADDR); 32201e04c3fSmrg /*00648*/ EMIT_STATE(FE_INDEX_STREAM_CONTROL, ctx->index_buffer.FE_INDEX_STREAM_CONTROL); 32301e04c3fSmrg } 32401e04c3fSmrg if (likely(dirty & (ETNA_DIRTY_INDEX_BUFFER))) { 32501e04c3fSmrg /*00674*/ EMIT_STATE(FE_PRIMITIVE_RESTART_INDEX, ctx->index_buffer.FE_PRIMITIVE_RESTART_INDEX); 32601e04c3fSmrg } 32701e04c3fSmrg if (likely(dirty & (ETNA_DIRTY_VERTEX_BUFFERS))) { 3287ec681f3Smrg if (screen->specs.halti >= 2) { /* HALTI2+: NFE_VERTEX_STREAMS */ 32901e04c3fSmrg for (int x = 0; x < ctx->vertex_buffer.count; ++x) { 33001e04c3fSmrg /*14600*/ EMIT_STATE_RELOC(NFE_VERTEX_STREAMS_BASE_ADDR(x), &ctx->vertex_buffer.cvb[x].FE_VERTEX_STREAM_BASE_ADDR); 33101e04c3fSmrg } 33201e04c3fSmrg for (int x = 0; x < ctx->vertex_buffer.count; ++x) { 33301e04c3fSmrg if (ctx->vertex_buffer.cvb[x].FE_VERTEX_STREAM_BASE_ADDR.bo) { 33401e04c3fSmrg /*14640*/ EMIT_STATE(NFE_VERTEX_STREAMS_CONTROL(x), ctx->vertex_buffer.cvb[x].FE_VERTEX_STREAM_CONTROL); 33501e04c3fSmrg } 33601e04c3fSmrg } 3377ec681f3Smrg } else if(screen->specs.stream_count > 1) { /* hw w/ multiple vertex streams */ 33801e04c3fSmrg for (int x = 0; x < ctx->vertex_buffer.count; ++x) { 33901e04c3fSmrg /*00680*/ EMIT_STATE_RELOC(FE_VERTEX_STREAMS_BASE_ADDR(x), &ctx->vertex_buffer.cvb[x].FE_VERTEX_STREAM_BASE_ADDR); 34001e04c3fSmrg } 34101e04c3fSmrg for (int x = 0; x < ctx->vertex_buffer.count; ++x) { 34201e04c3fSmrg if (ctx->vertex_buffer.cvb[x].FE_VERTEX_STREAM_BASE_ADDR.bo) { 34301e04c3fSmrg /*006A0*/ EMIT_STATE(FE_VERTEX_STREAMS_CONTROL(x), ctx->vertex_buffer.cvb[x].FE_VERTEX_STREAM_CONTROL); 34401e04c3fSmrg } 34501e04c3fSmrg } 34601e04c3fSmrg } else { /* hw w/ single vertex stream */ 34701e04c3fSmrg /*0064C*/ EMIT_STATE_RELOC(FE_VERTEX_STREAM_BASE_ADDR, &ctx->vertex_buffer.cvb[0].FE_VERTEX_STREAM_BASE_ADDR); 34801e04c3fSmrg /*00650*/ EMIT_STATE(FE_VERTEX_STREAM_CONTROL, ctx->vertex_buffer.cvb[0].FE_VERTEX_STREAM_CONTROL); 34901e04c3fSmrg } 35001e04c3fSmrg } 3517ec681f3Smrg /* gallium has instance divisor as part of elements state */ 3527ec681f3Smrg if ((dirty & (ETNA_DIRTY_VERTEX_ELEMENTS)) && screen->specs.halti >= 2) { 3537ec681f3Smrg for (int x = 0; x < ctx->vertex_elements->num_buffers; ++x) { 3547ec681f3Smrg /*14680*/ EMIT_STATE(NFE_VERTEX_STREAMS_VERTEX_DIVISOR(x), ctx->vertex_elements->NFE_VERTEX_STREAMS_VERTEX_DIVISOR[x]); 3557ec681f3Smrg } 3567ec681f3Smrg } 3577ec681f3Smrg 35801e04c3fSmrg if (unlikely(dirty & (ETNA_DIRTY_SHADER | ETNA_DIRTY_RASTERIZER))) { 35901e04c3fSmrg 36001e04c3fSmrg /*00804*/ EMIT_STATE(VS_OUTPUT_COUNT, vs_output_count); 36101e04c3fSmrg } 36201e04c3fSmrg if (unlikely(dirty & (ETNA_DIRTY_VERTEX_ELEMENTS | ETNA_DIRTY_SHADER))) { 36301e04c3fSmrg /*00808*/ EMIT_STATE(VS_INPUT_COUNT, ctx->shader_state.VS_INPUT_COUNT); 36401e04c3fSmrg /*0080C*/ EMIT_STATE(VS_TEMP_REGISTER_CONTROL, ctx->shader_state.VS_TEMP_REGISTER_CONTROL); 36501e04c3fSmrg } 36601e04c3fSmrg if (unlikely(dirty & (ETNA_DIRTY_SHADER))) { 36701e04c3fSmrg /*00830*/ EMIT_STATE(VS_LOAD_BALANCING, ctx->shader_state.VS_LOAD_BALANCING); 36801e04c3fSmrg } 36901e04c3fSmrg if (unlikely(dirty & (ETNA_DIRTY_VIEWPORT))) { 37001e04c3fSmrg /*00A00*/ EMIT_STATE_FIXP(PA_VIEWPORT_SCALE_X, ctx->viewport.PA_VIEWPORT_SCALE_X); 37101e04c3fSmrg /*00A04*/ EMIT_STATE_FIXP(PA_VIEWPORT_SCALE_Y, ctx->viewport.PA_VIEWPORT_SCALE_Y); 37201e04c3fSmrg /*00A08*/ EMIT_STATE(PA_VIEWPORT_SCALE_Z, ctx->viewport.PA_VIEWPORT_SCALE_Z); 37301e04c3fSmrg /*00A0C*/ EMIT_STATE_FIXP(PA_VIEWPORT_OFFSET_X, ctx->viewport.PA_VIEWPORT_OFFSET_X); 37401e04c3fSmrg /*00A10*/ EMIT_STATE_FIXP(PA_VIEWPORT_OFFSET_Y, ctx->viewport.PA_VIEWPORT_OFFSET_Y); 37501e04c3fSmrg /*00A14*/ EMIT_STATE(PA_VIEWPORT_OFFSET_Z, ctx->viewport.PA_VIEWPORT_OFFSET_Z); 37601e04c3fSmrg } 37701e04c3fSmrg if (unlikely(dirty & (ETNA_DIRTY_RASTERIZER))) { 37801e04c3fSmrg struct etna_rasterizer_state *rasterizer = etna_rasterizer_state(ctx->rasterizer); 37901e04c3fSmrg 38001e04c3fSmrg /*00A18*/ EMIT_STATE(PA_LINE_WIDTH, rasterizer->PA_LINE_WIDTH); 38101e04c3fSmrg /*00A1C*/ EMIT_STATE(PA_POINT_SIZE, rasterizer->PA_POINT_SIZE); 38201e04c3fSmrg /*00A28*/ EMIT_STATE(PA_SYSTEM_MODE, rasterizer->PA_SYSTEM_MODE); 38301e04c3fSmrg } 38401e04c3fSmrg if (unlikely(dirty & (ETNA_DIRTY_SHADER))) { 38501e04c3fSmrg /*00A30*/ EMIT_STATE(PA_ATTRIBUTE_ELEMENT_COUNT, ctx->shader_state.PA_ATTRIBUTE_ELEMENT_COUNT); 38601e04c3fSmrg } 38701e04c3fSmrg if (unlikely(dirty & (ETNA_DIRTY_RASTERIZER | ETNA_DIRTY_SHADER))) { 38801e04c3fSmrg uint32_t val = etna_rasterizer_state(ctx->rasterizer)->PA_CONFIG; 38901e04c3fSmrg /*00A34*/ EMIT_STATE(PA_CONFIG, val & ctx->shader_state.PA_CONFIG); 39001e04c3fSmrg } 39101e04c3fSmrg if (unlikely(dirty & (ETNA_DIRTY_RASTERIZER))) { 39201e04c3fSmrg struct etna_rasterizer_state *rasterizer = etna_rasterizer_state(ctx->rasterizer); 39301e04c3fSmrg /*00A38*/ EMIT_STATE(PA_WIDE_LINE_WIDTH0, rasterizer->PA_LINE_WIDTH); 39401e04c3fSmrg /*00A3C*/ EMIT_STATE(PA_WIDE_LINE_WIDTH1, rasterizer->PA_LINE_WIDTH); 39501e04c3fSmrg } 3967ec681f3Smrg if (unlikely(dirty & (ETNA_DIRTY_SCISSOR_CLIP))) { 3977ec681f3Smrg /*00C00*/ EMIT_STATE_FIXP(SE_SCISSOR_LEFT, ctx->clipping.minx << 16); 3987ec681f3Smrg /*00C04*/ EMIT_STATE_FIXP(SE_SCISSOR_TOP, ctx->clipping.miny << 16); 3997ec681f3Smrg /*00C08*/ EMIT_STATE_FIXP(SE_SCISSOR_RIGHT, (ctx->clipping.maxx << 16) + ETNA_SE_SCISSOR_MARGIN_RIGHT); 4007ec681f3Smrg /*00C0C*/ EMIT_STATE_FIXP(SE_SCISSOR_BOTTOM, (ctx->clipping.maxy << 16) + ETNA_SE_SCISSOR_MARGIN_BOTTOM); 40101e04c3fSmrg } 40201e04c3fSmrg if (unlikely(dirty & (ETNA_DIRTY_RASTERIZER))) { 40301e04c3fSmrg struct etna_rasterizer_state *rasterizer = etna_rasterizer_state(ctx->rasterizer); 40401e04c3fSmrg 40501e04c3fSmrg /*00C10*/ EMIT_STATE(SE_DEPTH_SCALE, rasterizer->SE_DEPTH_SCALE); 40601e04c3fSmrg /*00C14*/ EMIT_STATE(SE_DEPTH_BIAS, rasterizer->SE_DEPTH_BIAS); 40701e04c3fSmrg /*00C18*/ EMIT_STATE(SE_CONFIG, rasterizer->SE_CONFIG); 40801e04c3fSmrg } 4097ec681f3Smrg if (unlikely(dirty & (ETNA_DIRTY_SCISSOR_CLIP))) { 4107ec681f3Smrg /*00C20*/ EMIT_STATE_FIXP(SE_CLIP_RIGHT, (ctx->clipping.maxx << 16) + ETNA_SE_CLIP_MARGIN_RIGHT); 4117ec681f3Smrg /*00C24*/ EMIT_STATE_FIXP(SE_CLIP_BOTTOM, (ctx->clipping.maxy << 16) + ETNA_SE_CLIP_MARGIN_BOTTOM); 41201e04c3fSmrg } 41301e04c3fSmrg if (unlikely(dirty & (ETNA_DIRTY_SHADER))) { 41401e04c3fSmrg /*00E00*/ EMIT_STATE(RA_CONTROL, ctx->shader_state.RA_CONTROL); 41501e04c3fSmrg } 4167ec681f3Smrg if (unlikely(dirty & (ETNA_DIRTY_ZSA))) { 4177ec681f3Smrg /*00E08*/ EMIT_STATE(RA_EARLY_DEPTH, etna_zsa_state(ctx->zsa)->RA_DEPTH_CONFIG); 4187ec681f3Smrg } 41901e04c3fSmrg if (unlikely(dirty & (ETNA_DIRTY_SHADER | ETNA_DIRTY_FRAMEBUFFER))) { 42001e04c3fSmrg /*01004*/ EMIT_STATE(PS_OUTPUT_REG, ctx->shader_state.PS_OUTPUT_REG); 42101e04c3fSmrg /*01008*/ EMIT_STATE(PS_INPUT_COUNT, 42201e04c3fSmrg ctx->framebuffer.msaa_mode 42301e04c3fSmrg ? ctx->shader_state.PS_INPUT_COUNT_MSAA 42401e04c3fSmrg : ctx->shader_state.PS_INPUT_COUNT); 42501e04c3fSmrg /*0100C*/ EMIT_STATE(PS_TEMP_REGISTER_CONTROL, 42601e04c3fSmrg ctx->framebuffer.msaa_mode 42701e04c3fSmrg ? ctx->shader_state.PS_TEMP_REGISTER_CONTROL_MSAA 42801e04c3fSmrg : ctx->shader_state.PS_TEMP_REGISTER_CONTROL); 4297ec681f3Smrg /*01010*/ EMIT_STATE(PS_CONTROL, ctx->framebuffer.PS_CONTROL); 4307ec681f3Smrg /*01030*/ EMIT_STATE(PS_CONTROL_EXT, ctx->framebuffer.PS_CONTROL_EXT); 43101e04c3fSmrg } 4327ec681f3Smrg if (unlikely(dirty & (ETNA_DIRTY_ZSA | ETNA_DIRTY_FRAMEBUFFER | ETNA_DIRTY_SHADER))) { 4337ec681f3Smrg /*01400*/ EMIT_STATE(PE_DEPTH_CONFIG, (etna_zsa_state(ctx->zsa)->PE_DEPTH_CONFIG | 4347ec681f3Smrg ctx->framebuffer.PE_DEPTH_CONFIG)); 43501e04c3fSmrg } 43601e04c3fSmrg if (unlikely(dirty & (ETNA_DIRTY_VIEWPORT))) { 43701e04c3fSmrg /*01404*/ EMIT_STATE(PE_DEPTH_NEAR, ctx->viewport.PE_DEPTH_NEAR); 43801e04c3fSmrg /*01408*/ EMIT_STATE(PE_DEPTH_FAR, ctx->viewport.PE_DEPTH_FAR); 43901e04c3fSmrg } 44001e04c3fSmrg if (unlikely(dirty & (ETNA_DIRTY_FRAMEBUFFER))) { 44101e04c3fSmrg /*0140C*/ EMIT_STATE(PE_DEPTH_NORMALIZE, ctx->framebuffer.PE_DEPTH_NORMALIZE); 44201e04c3fSmrg 4437ec681f3Smrg if (screen->specs.pixel_pipes == 1) { 44401e04c3fSmrg /*01410*/ EMIT_STATE_RELOC(PE_DEPTH_ADDR, &ctx->framebuffer.PE_DEPTH_ADDR); 44501e04c3fSmrg } 44601e04c3fSmrg 44701e04c3fSmrg /*01414*/ EMIT_STATE(PE_DEPTH_STRIDE, ctx->framebuffer.PE_DEPTH_STRIDE); 44801e04c3fSmrg } 4497ec681f3Smrg 4507ec681f3Smrg if (unlikely(dirty & (ETNA_DIRTY_ZSA | ETNA_DIRTY_RASTERIZER))) { 4517ec681f3Smrg uint32_t val = etna_zsa_state(ctx->zsa)->PE_STENCIL_OP[ccw]; 45201e04c3fSmrg /*01418*/ EMIT_STATE(PE_STENCIL_OP, val); 45301e04c3fSmrg } 4547ec681f3Smrg if (unlikely(dirty & (ETNA_DIRTY_ZSA | ETNA_DIRTY_STENCIL_REF | ETNA_DIRTY_RASTERIZER))) { 4557ec681f3Smrg uint32_t val = etna_zsa_state(ctx->zsa)->PE_STENCIL_CONFIG[ccw]; 4567ec681f3Smrg /*0141C*/ EMIT_STATE(PE_STENCIL_CONFIG, val | ctx->stencil_ref.PE_STENCIL_CONFIG[ccw]); 45701e04c3fSmrg } 45801e04c3fSmrg if (unlikely(dirty & (ETNA_DIRTY_ZSA))) { 45901e04c3fSmrg uint32_t val = etna_zsa_state(ctx->zsa)->PE_ALPHA_OP; 46001e04c3fSmrg /*01420*/ EMIT_STATE(PE_ALPHA_OP, val); 46101e04c3fSmrg } 46201e04c3fSmrg if (unlikely(dirty & (ETNA_DIRTY_BLEND_COLOR))) { 46301e04c3fSmrg /*01424*/ EMIT_STATE(PE_ALPHA_BLEND_COLOR, ctx->blend_color.PE_ALPHA_BLEND_COLOR); 46401e04c3fSmrg } 46501e04c3fSmrg if (unlikely(dirty & (ETNA_DIRTY_BLEND))) { 46601e04c3fSmrg uint32_t val = etna_blend_state(ctx->blend)->PE_ALPHA_CONFIG; 46701e04c3fSmrg /*01428*/ EMIT_STATE(PE_ALPHA_CONFIG, val); 46801e04c3fSmrg } 46901e04c3fSmrg if (unlikely(dirty & (ETNA_DIRTY_BLEND | ETNA_DIRTY_FRAMEBUFFER))) { 47001e04c3fSmrg uint32_t val; 47101e04c3fSmrg /* Use the components and overwrite bits in framebuffer.PE_COLOR_FORMAT 47201e04c3fSmrg * as a mask to enable the bits from blend PE_COLOR_FORMAT */ 47301e04c3fSmrg val = ~(VIVS_PE_COLOR_FORMAT_COMPONENTS__MASK | 47401e04c3fSmrg VIVS_PE_COLOR_FORMAT_OVERWRITE); 47501e04c3fSmrg val |= etna_blend_state(ctx->blend)->PE_COLOR_FORMAT; 47601e04c3fSmrg val &= ctx->framebuffer.PE_COLOR_FORMAT; 47701e04c3fSmrg /*0142C*/ EMIT_STATE(PE_COLOR_FORMAT, val); 47801e04c3fSmrg } 47901e04c3fSmrg if (unlikely(dirty & (ETNA_DIRTY_FRAMEBUFFER))) { 4807ec681f3Smrg if (screen->specs.pixel_pipes == 1) { 48101e04c3fSmrg /*01430*/ EMIT_STATE_RELOC(PE_COLOR_ADDR, &ctx->framebuffer.PE_COLOR_ADDR); 48201e04c3fSmrg /*01434*/ EMIT_STATE(PE_COLOR_STRIDE, ctx->framebuffer.PE_COLOR_STRIDE); 48301e04c3fSmrg /*01454*/ EMIT_STATE(PE_HDEPTH_CONTROL, ctx->framebuffer.PE_HDEPTH_CONTROL); 4847ec681f3Smrg } else if (screen->specs.pixel_pipes == 2) { 48501e04c3fSmrg /*01434*/ EMIT_STATE(PE_COLOR_STRIDE, ctx->framebuffer.PE_COLOR_STRIDE); 48601e04c3fSmrg /*01454*/ EMIT_STATE(PE_HDEPTH_CONTROL, ctx->framebuffer.PE_HDEPTH_CONTROL); 48701e04c3fSmrg /*01460*/ EMIT_STATE_RELOC(PE_PIPE_COLOR_ADDR(0), &ctx->framebuffer.PE_PIPE_COLOR_ADDR[0]); 48801e04c3fSmrg /*01464*/ EMIT_STATE_RELOC(PE_PIPE_COLOR_ADDR(1), &ctx->framebuffer.PE_PIPE_COLOR_ADDR[1]); 48901e04c3fSmrg /*01480*/ EMIT_STATE_RELOC(PE_PIPE_DEPTH_ADDR(0), &ctx->framebuffer.PE_PIPE_DEPTH_ADDR[0]); 49001e04c3fSmrg /*01484*/ EMIT_STATE_RELOC(PE_PIPE_DEPTH_ADDR(1), &ctx->framebuffer.PE_PIPE_DEPTH_ADDR[1]); 49101e04c3fSmrg } else { 49201e04c3fSmrg abort(); 49301e04c3fSmrg } 49401e04c3fSmrg } 4957ec681f3Smrg if (unlikely(dirty & (ETNA_DIRTY_STENCIL_REF | ETNA_DIRTY_RASTERIZER | ETNA_DIRTY_ZSA))) { 4967ec681f3Smrg uint32_t val = etna_zsa_state(ctx->zsa)->PE_STENCIL_CONFIG_EXT; 4977ec681f3Smrg /*014A0*/ EMIT_STATE(PE_STENCIL_CONFIG_EXT, val | ctx->stencil_ref.PE_STENCIL_CONFIG_EXT[ccw]); 49801e04c3fSmrg } 49901e04c3fSmrg if (unlikely(dirty & (ETNA_DIRTY_BLEND | ETNA_DIRTY_FRAMEBUFFER))) { 50001e04c3fSmrg struct etna_blend_state *blend = etna_blend_state(ctx->blend); 50101e04c3fSmrg /*014A4*/ EMIT_STATE(PE_LOGIC_OP, blend->PE_LOGIC_OP | ctx->framebuffer.PE_LOGIC_OP); 50201e04c3fSmrg } 50301e04c3fSmrg if (unlikely(dirty & (ETNA_DIRTY_BLEND))) { 50401e04c3fSmrg struct etna_blend_state *blend = etna_blend_state(ctx->blend); 50501e04c3fSmrg for (int x = 0; x < 2; ++x) { 50601e04c3fSmrg /*014A8*/ EMIT_STATE(PE_DITHER(x), blend->PE_DITHER[x]); 50701e04c3fSmrg } 50801e04c3fSmrg } 5097ec681f3Smrg if (unlikely(dirty & (ETNA_DIRTY_BLEND_COLOR)) && 5107ec681f3Smrg VIV_FEATURE(screen, chipMinorFeatures1, HALF_FLOAT)) { 5117ec681f3Smrg /*014B0*/ EMIT_STATE(PE_ALPHA_COLOR_EXT0, ctx->blend_color.PE_ALPHA_COLOR_EXT0); 5127ec681f3Smrg /*014B4*/ EMIT_STATE(PE_ALPHA_COLOR_EXT1, ctx->blend_color.PE_ALPHA_COLOR_EXT1); 5137ec681f3Smrg } 5147ec681f3Smrg if (unlikely(dirty & (ETNA_DIRTY_ZSA | ETNA_DIRTY_RASTERIZER))) { 5157ec681f3Smrg /*014B8*/ EMIT_STATE(PE_STENCIL_CONFIG_EXT2, etna_zsa_state(ctx->zsa)->PE_STENCIL_CONFIG_EXT2[ccw]); 5167ec681f3Smrg } 5177ec681f3Smrg if (unlikely(dirty & (ETNA_DIRTY_FRAMEBUFFER)) && screen->specs.halti >= 3) 5187ec681f3Smrg /*014BC*/ EMIT_STATE(PE_MEM_CONFIG, ctx->framebuffer.PE_MEM_CONFIG); 51901e04c3fSmrg if (unlikely(dirty & (ETNA_DIRTY_FRAMEBUFFER | ETNA_DIRTY_TS))) { 52001e04c3fSmrg /*01654*/ EMIT_STATE(TS_MEM_CONFIG, ctx->framebuffer.TS_MEM_CONFIG); 52101e04c3fSmrg /*01658*/ EMIT_STATE_RELOC(TS_COLOR_STATUS_BASE, &ctx->framebuffer.TS_COLOR_STATUS_BASE); 52201e04c3fSmrg /*0165C*/ EMIT_STATE_RELOC(TS_COLOR_SURFACE_BASE, &ctx->framebuffer.TS_COLOR_SURFACE_BASE); 52301e04c3fSmrg /*01660*/ EMIT_STATE(TS_COLOR_CLEAR_VALUE, ctx->framebuffer.TS_COLOR_CLEAR_VALUE); 52401e04c3fSmrg /*01664*/ EMIT_STATE_RELOC(TS_DEPTH_STATUS_BASE, &ctx->framebuffer.TS_DEPTH_STATUS_BASE); 52501e04c3fSmrg /*01668*/ EMIT_STATE_RELOC(TS_DEPTH_SURFACE_BASE, &ctx->framebuffer.TS_DEPTH_SURFACE_BASE); 52601e04c3fSmrg /*0166C*/ EMIT_STATE(TS_DEPTH_CLEAR_VALUE, ctx->framebuffer.TS_DEPTH_CLEAR_VALUE); 5277ec681f3Smrg /*016BC*/ EMIT_STATE(TS_COLOR_CLEAR_VALUE_EXT, ctx->framebuffer.TS_COLOR_CLEAR_VALUE_EXT); 52801e04c3fSmrg } 52901e04c3fSmrg if (unlikely(dirty & (ETNA_DIRTY_SHADER))) { 53001e04c3fSmrg /*0381C*/ EMIT_STATE(GL_VARYING_TOTAL_COMPONENTS, ctx->shader_state.GL_VARYING_TOTAL_COMPONENTS); 53101e04c3fSmrg } 53201e04c3fSmrg etna_coalesce_end(stream, &coalesce); 53301e04c3fSmrg /* end only EMIT_STATE */ 53401e04c3fSmrg 53501e04c3fSmrg /* Emit strongly architecture-specific state */ 5367ec681f3Smrg if (screen->specs.halti >= 5) 53701e04c3fSmrg emit_halti5_only_state(ctx, vs_output_count); 53801e04c3fSmrg else 53901e04c3fSmrg emit_pre_halti5_state(ctx); 54001e04c3fSmrg 5417ec681f3Smrg /* Beginning from Halti0 some of the new shader and sampler states are not 5427ec681f3Smrg * self-synchronizing anymore. Thus we need to stall the FE on PE completion 5437ec681f3Smrg * before loading the new states to avoid corrupting the state of the 5447ec681f3Smrg * in-flight draw. 5457ec681f3Smrg */ 5467ec681f3Smrg if (screen->specs.halti >= 0 && 5477ec681f3Smrg (ctx->dirty & (ETNA_DIRTY_SHADER | ETNA_DIRTY_CONSTBUF | 5487ec681f3Smrg ETNA_DIRTY_SAMPLERS | ETNA_DIRTY_SAMPLER_VIEWS))) 54901e04c3fSmrg etna_stall(ctx->stream, SYNC_RECIPIENT_FE, SYNC_RECIPIENT_PE); 55001e04c3fSmrg 5517ec681f3Smrg ctx->emit_texture_state(ctx); 5527ec681f3Smrg 55301e04c3fSmrg /* We need to update the uniform cache only if one of the following bits are 55401e04c3fSmrg * set in ctx->dirty: 55501e04c3fSmrg * - ETNA_DIRTY_SHADER 55601e04c3fSmrg * - ETNA_DIRTY_CONSTBUF 55701e04c3fSmrg * - uniforms_dirty_bits 55801e04c3fSmrg * 55901e04c3fSmrg * In case of ETNA_DIRTY_SHADER we need load all uniforms from the cache. In 56001e04c3fSmrg * all 56101e04c3fSmrg * other cases we can load on the changed uniforms. 56201e04c3fSmrg */ 56301e04c3fSmrg static const uint32_t uniform_dirty_bits = 56401e04c3fSmrg ETNA_DIRTY_SHADER | ETNA_DIRTY_CONSTBUF; 56501e04c3fSmrg 56601e04c3fSmrg /**** Large dynamically-sized state ****/ 5677ec681f3Smrg bool do_uniform_flush = screen->specs.halti < 5; 56801e04c3fSmrg if (dirty & (ETNA_DIRTY_SHADER)) { 56901e04c3fSmrg /* Special case: a new shader was loaded; simply re-load all uniforms and 57001e04c3fSmrg * shader code at once */ 57101e04c3fSmrg /* This sequence is special, do not change ordering unless necessary. According to comment 57201e04c3fSmrg snippets in the Vivante kernel driver a process called "steering" goes on while programming 57301e04c3fSmrg shader state. This (as I understand it) means certain unified states are "steered" 57401e04c3fSmrg toward a specific shader unit (VS/PS/...) based on either explicit flags in register 57501e04c3fSmrg 00860, or what other state is written before "auto-steering". So this means some 57601e04c3fSmrg state can legitimately be programmed multiple times. 57701e04c3fSmrg */ 57801e04c3fSmrg 5797ec681f3Smrg if (screen->specs.halti >= 5) { /* ICACHE (HALTI5) */ 58001e04c3fSmrg assert(ctx->shader_state.VS_INST_ADDR.bo && ctx->shader_state.PS_INST_ADDR.bo); 58101e04c3fSmrg /* Set icache (VS) */ 58201e04c3fSmrg etna_set_state(stream, VIVS_VS_NEWRANGE_LOW, 0); 58301e04c3fSmrg etna_set_state(stream, VIVS_VS_NEWRANGE_HIGH, ctx->shader_state.vs_inst_mem_size / 4); 58401e04c3fSmrg assert(ctx->shader_state.VS_INST_ADDR.bo); 58501e04c3fSmrg etna_set_state_reloc(stream, VIVS_VS_INST_ADDR, &ctx->shader_state.VS_INST_ADDR); 58601e04c3fSmrg etna_set_state(stream, VIVS_SH_CONFIG, 0x00000002); 58701e04c3fSmrg etna_set_state(stream, VIVS_VS_ICACHE_CONTROL, VIVS_VS_ICACHE_CONTROL_ENABLE); 58801e04c3fSmrg etna_set_state(stream, VIVS_VS_ICACHE_COUNT, ctx->shader_state.vs_inst_mem_size / 4 - 1); 58901e04c3fSmrg 59001e04c3fSmrg /* Set icache (PS) */ 59101e04c3fSmrg etna_set_state(stream, VIVS_PS_NEWRANGE_LOW, 0); 59201e04c3fSmrg etna_set_state(stream, VIVS_PS_NEWRANGE_HIGH, ctx->shader_state.ps_inst_mem_size / 4); 59301e04c3fSmrg assert(ctx->shader_state.PS_INST_ADDR.bo); 59401e04c3fSmrg etna_set_state_reloc(stream, VIVS_PS_INST_ADDR, &ctx->shader_state.PS_INST_ADDR); 59501e04c3fSmrg etna_set_state(stream, VIVS_SH_CONFIG, 0x00000002); 59601e04c3fSmrg etna_set_state(stream, VIVS_VS_ICACHE_CONTROL, VIVS_VS_ICACHE_CONTROL_ENABLE); 59701e04c3fSmrg etna_set_state(stream, VIVS_PS_ICACHE_COUNT, ctx->shader_state.ps_inst_mem_size / 4 - 1); 59801e04c3fSmrg 59901e04c3fSmrg } else if (ctx->shader_state.VS_INST_ADDR.bo || ctx->shader_state.PS_INST_ADDR.bo) { 60001e04c3fSmrg /* ICACHE (pre-HALTI5) */ 6017ec681f3Smrg assert(screen->specs.has_icache && screen->specs.has_shader_range_registers); 60201e04c3fSmrg /* Set icache (VS) */ 60301e04c3fSmrg etna_set_state(stream, VIVS_VS_RANGE, (ctx->shader_state.vs_inst_mem_size / 4 - 1) << 16); 60401e04c3fSmrg etna_set_state(stream, VIVS_VS_ICACHE_CONTROL, 60501e04c3fSmrg VIVS_VS_ICACHE_CONTROL_ENABLE | 60601e04c3fSmrg VIVS_VS_ICACHE_CONTROL_FLUSH_VS); 60701e04c3fSmrg assert(ctx->shader_state.VS_INST_ADDR.bo); 60801e04c3fSmrg etna_set_state_reloc(stream, VIVS_VS_INST_ADDR, &ctx->shader_state.VS_INST_ADDR); 60901e04c3fSmrg 61001e04c3fSmrg /* Set icache (PS) */ 61101e04c3fSmrg etna_set_state(stream, VIVS_PS_RANGE, (ctx->shader_state.ps_inst_mem_size / 4 - 1) << 16); 61201e04c3fSmrg etna_set_state(stream, VIVS_VS_ICACHE_CONTROL, 61301e04c3fSmrg VIVS_VS_ICACHE_CONTROL_ENABLE | 61401e04c3fSmrg VIVS_VS_ICACHE_CONTROL_FLUSH_PS); 61501e04c3fSmrg assert(ctx->shader_state.PS_INST_ADDR.bo); 61601e04c3fSmrg etna_set_state_reloc(stream, VIVS_PS_INST_ADDR, &ctx->shader_state.PS_INST_ADDR); 61701e04c3fSmrg } else { 61801e04c3fSmrg /* Upload shader directly, first flushing and disabling icache if 61901e04c3fSmrg * supported on this hw */ 6207ec681f3Smrg if (screen->specs.has_icache) { 62101e04c3fSmrg etna_set_state(stream, VIVS_VS_ICACHE_CONTROL, 62201e04c3fSmrg VIVS_VS_ICACHE_CONTROL_FLUSH_PS | 62301e04c3fSmrg VIVS_VS_ICACHE_CONTROL_FLUSH_VS); 62401e04c3fSmrg } 6257ec681f3Smrg if (screen->specs.has_shader_range_registers) { 62601e04c3fSmrg etna_set_state(stream, VIVS_VS_RANGE, (ctx->shader_state.vs_inst_mem_size / 4 - 1) << 16); 62701e04c3fSmrg etna_set_state(stream, VIVS_PS_RANGE, ((ctx->shader_state.ps_inst_mem_size / 4 - 1 + 0x100) << 16) | 62801e04c3fSmrg 0x100); 62901e04c3fSmrg } 6307ec681f3Smrg etna_set_state_multi(stream, screen->specs.vs_offset, 63101e04c3fSmrg ctx->shader_state.vs_inst_mem_size, 63201e04c3fSmrg ctx->shader_state.VS_INST_MEM); 6337ec681f3Smrg etna_set_state_multi(stream, screen->specs.ps_offset, 63401e04c3fSmrg ctx->shader_state.ps_inst_mem_size, 63501e04c3fSmrg ctx->shader_state.PS_INST_MEM); 63601e04c3fSmrg } 63701e04c3fSmrg 6387ec681f3Smrg if (screen->specs.has_unified_uniforms) { 63901e04c3fSmrg etna_set_state(stream, VIVS_VS_UNIFORM_BASE, 0); 6407ec681f3Smrg etna_set_state(stream, VIVS_PS_UNIFORM_BASE, screen->specs.max_vs_uniforms); 64101e04c3fSmrg } 64201e04c3fSmrg 64301e04c3fSmrg if (do_uniform_flush) 64401e04c3fSmrg etna_set_state(stream, VIVS_VS_UNIFORM_CACHE, VIVS_VS_UNIFORM_CACHE_FLUSH); 6457ec681f3Smrg 6467ec681f3Smrg etna_uniforms_write(ctx, ctx->shader.vs, ctx->constant_buffer[PIPE_SHADER_VERTEX].cb); 6477ec681f3Smrg 64801e04c3fSmrg if (do_uniform_flush) 64901e04c3fSmrg etna_set_state(stream, VIVS_VS_UNIFORM_CACHE, VIVS_VS_UNIFORM_CACHE_FLUSH | VIVS_VS_UNIFORM_CACHE_PS); 6507ec681f3Smrg 6517ec681f3Smrg etna_uniforms_write(ctx, ctx->shader.fs, ctx->constant_buffer[PIPE_SHADER_FRAGMENT].cb); 6527ec681f3Smrg 6537ec681f3Smrg if (screen->specs.halti >= 5) { 65401e04c3fSmrg /* HALTI5 needs to be prompted to pre-fetch shaders */ 65501e04c3fSmrg etna_set_state(stream, VIVS_VS_ICACHE_PREFETCH, 0x00000000); 65601e04c3fSmrg etna_set_state(stream, VIVS_PS_ICACHE_PREFETCH, 0x00000000); 65701e04c3fSmrg etna_stall(stream, SYNC_RECIPIENT_RA, SYNC_RECIPIENT_PE); 65801e04c3fSmrg } 65901e04c3fSmrg } else { 66001e04c3fSmrg /* ideally this cache would only be flushed if there are VS uniform changes */ 66101e04c3fSmrg if (do_uniform_flush) 66201e04c3fSmrg etna_set_state(stream, VIVS_VS_UNIFORM_CACHE, VIVS_VS_UNIFORM_CACHE_FLUSH); 6637ec681f3Smrg 6647ec681f3Smrg if (dirty & (uniform_dirty_bits | ctx->shader.vs->uniforms_dirty_bits)) 6657ec681f3Smrg etna_uniforms_write(ctx, ctx->shader.vs, ctx->constant_buffer[PIPE_SHADER_VERTEX].cb); 66601e04c3fSmrg 66701e04c3fSmrg /* ideally this cache would only be flushed if there are PS uniform changes */ 66801e04c3fSmrg if (do_uniform_flush) 66901e04c3fSmrg etna_set_state(stream, VIVS_VS_UNIFORM_CACHE, VIVS_VS_UNIFORM_CACHE_FLUSH | VIVS_VS_UNIFORM_CACHE_PS); 6707ec681f3Smrg 6717ec681f3Smrg if (dirty & (uniform_dirty_bits | ctx->shader.fs->uniforms_dirty_bits)) 6727ec681f3Smrg etna_uniforms_write(ctx, ctx->shader.fs, ctx->constant_buffer[PIPE_SHADER_FRAGMENT].cb); 67301e04c3fSmrg } 67401e04c3fSmrg/**** End of state update ****/ 67501e04c3fSmrg#undef EMIT_STATE 67601e04c3fSmrg#undef EMIT_STATE_FIXP 67701e04c3fSmrg#undef EMIT_STATE_RELOC 67801e04c3fSmrg ctx->dirty = 0; 67901e04c3fSmrg ctx->dirty_sampler_views = 0; 68001e04c3fSmrg} 681