- /*04000 or 0C000*/
- etna_set_state_multi(stream, ctx->specs.vs_offset,
- ctx->shader_state.vs_inst_mem_size,
- ctx->shader_state.VS_INST_MEM);
- /*06000 or 0D000*/
- etna_set_state_multi(stream, ctx->specs.ps_offset,
- ctx->shader_state.ps_inst_mem_size,
- ctx->shader_state.PS_INST_MEM);
- /*05000*/ etna_set_state_multi(stream, VIVS_VS_UNIFORMS(0),
+ if (ctx->shader_state.VS_INST_ADDR.bo || ctx->shader_state.PS_INST_ADDR.bo) {
+ assert(ctx->specs.has_icache && ctx->specs.has_shader_range_registers);
+ /* Set icache (VS) */
+ etna_set_state(stream, VIVS_VS_RANGE, (ctx->shader_state.vs_inst_mem_size / 4 - 1) << 16);
+ etna_set_state(stream, VIVS_VS_ICACHE_CONTROL,
+ VIVS_VS_ICACHE_CONTROL_ENABLE |
+ VIVS_VS_ICACHE_CONTROL_FLUSH_VS);
+ assert(ctx->shader_state.VS_INST_ADDR.bo);
+ etna_set_state_reloc(stream, VIVS_VS_INST_ADDR, &ctx->shader_state.VS_INST_ADDR);
+
+ /* Set icache (PS) */
+ etna_set_state(stream, VIVS_PS_RANGE, (ctx->shader_state.ps_inst_mem_size / 4 - 1) << 16);
+ etna_set_state(stream, VIVS_VS_ICACHE_CONTROL,
+ VIVS_VS_ICACHE_CONTROL_ENABLE |
+ VIVS_VS_ICACHE_CONTROL_FLUSH_PS);
+ assert(ctx->shader_state.PS_INST_ADDR.bo);
+ etna_set_state_reloc(stream, VIVS_PS_INST_ADDR, &ctx->shader_state.PS_INST_ADDR);
+ } else {
+ /* Upload shader directly, first flushing and disabling icache if
+ * supported on this hw */
+ if (ctx->specs.has_icache) {
+ etna_set_state(stream, VIVS_VS_ICACHE_CONTROL,
+ VIVS_VS_ICACHE_CONTROL_FLUSH_PS |
+ VIVS_VS_ICACHE_CONTROL_FLUSH_VS);
+ }
+ if (ctx->specs.has_shader_range_registers) {
+ etna_set_state(stream, VIVS_VS_RANGE, (ctx->shader_state.vs_inst_mem_size / 4 - 1) << 16);
+ etna_set_state(stream, VIVS_PS_RANGE, ((ctx->shader_state.ps_inst_mem_size / 4 - 1 + 0x100) << 16) |
+ 0x100);
+ }
+ etna_set_state_multi(stream, ctx->specs.vs_offset,
+ ctx->shader_state.vs_inst_mem_size,
+ ctx->shader_state.VS_INST_MEM);
+ etna_set_state_multi(stream, ctx->specs.ps_offset,
+ ctx->shader_state.ps_inst_mem_size,
+ ctx->shader_state.PS_INST_MEM);
+ }
+
+ if (ctx->specs.has_unified_uniforms) {
+ etna_set_state(stream, VIVS_VS_UNIFORM_BASE, 0);
+ etna_set_state(stream, VIVS_PS_UNIFORM_BASE, ctx->specs.max_vs_uniforms);
+ }
+ etna_set_state(stream, VIVS_VS_UNIFORM_CACHE, VIVS_VS_UNIFORM_CACHE_FLUSH);
+ etna_set_state_multi(stream, ctx->specs.vs_uniforms_offset,