Path: blob/21.2-virgl/src/gallium/drivers/freedreno/a5xx/fd5_emit.c
4574 views
/*1* Copyright (C) 2016 Rob Clark <[email protected]>2*3* Permission is hereby granted, free of charge, to any person obtaining a4* copy of this software and associated documentation files (the "Software"),5* to deal in the Software without restriction, including without limitation6* the rights to use, copy, modify, merge, publish, distribute, sublicense,7* and/or sell copies of the Software, and to permit persons to whom the8* Software is furnished to do so, subject to the following conditions:9*10* The above copyright notice and this permission notice (including the next11* paragraph) shall be included in all copies or substantial portions of the12* Software.13*14* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR15* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,16* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL17* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER18* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,19* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE20* SOFTWARE.21*22* Authors:23* Rob Clark <[email protected]>24*/2526#include "pipe/p_state.h"27#include "util/format/u_format.h"28#include "util/u_helpers.h"29#include "util/u_memory.h"30#include "util/u_string.h"31#include "util/u_viewport.h"3233#include "freedreno_query_hw.h"34#include "freedreno_resource.h"3536#include "fd5_blend.h"37#include "fd5_blitter.h"38#include "fd5_context.h"39#include "fd5_emit.h"40#include "fd5_format.h"41#include "fd5_image.h"42#include "fd5_program.h"43#include "fd5_rasterizer.h"44#include "fd5_screen.h"45#include "fd5_texture.h"46#include "fd5_zsa.h"4748#define emit_const_user fd5_emit_const_user49#define emit_const_bo fd5_emit_const_bo50#include "ir3_const.h"5152/* regid: base const register53* prsc or dwords: buffer containing constant values54* sizedwords: size of const value buffer55*/56static void57fd5_emit_const_user(struct fd_ringbuffer *ring,58const struct ir3_shader_variant *v, uint32_t regid,59uint32_t sizedwords, const uint32_t *dwords)60{61emit_const_asserts(ring, v, regid, sizedwords);6263OUT_PKT7(ring, CP_LOAD_STATE4, 3 + sizedwords);64OUT_RING(ring, CP_LOAD_STATE4_0_DST_OFF(regid / 4) |65CP_LOAD_STATE4_0_STATE_SRC(SS4_DIRECT) |66CP_LOAD_STATE4_0_STATE_BLOCK(fd4_stage2shadersb(v->type)) |67CP_LOAD_STATE4_0_NUM_UNIT(sizedwords / 4));68OUT_RING(ring, CP_LOAD_STATE4_1_EXT_SRC_ADDR(0) |69CP_LOAD_STATE4_1_STATE_TYPE(ST4_CONSTANTS));70OUT_RING(ring, CP_LOAD_STATE4_2_EXT_SRC_ADDR_HI(0));71for (int i = 0; i < sizedwords; i++)72OUT_RING(ring, ((uint32_t *)dwords)[i]);73}7475static void76fd5_emit_const_bo(struct fd_ringbuffer *ring,77const struct ir3_shader_variant *v, uint32_t regid,78uint32_t offset, uint32_t sizedwords, struct fd_bo *bo)79{80uint32_t dst_off = regid / 4;81assert(dst_off % 4 == 0);82uint32_t num_unit = sizedwords / 4;83assert(num_unit % 4 == 0);8485emit_const_asserts(ring, v, regid, sizedwords);8687OUT_PKT7(ring, CP_LOAD_STATE4, 3);88OUT_RING(ring, CP_LOAD_STATE4_0_DST_OFF(dst_off) |89CP_LOAD_STATE4_0_STATE_SRC(SS4_INDIRECT) |90CP_LOAD_STATE4_0_STATE_BLOCK(fd4_stage2shadersb(v->type)) |91CP_LOAD_STATE4_0_NUM_UNIT(num_unit));92OUT_RELOC(ring, bo, offset, CP_LOAD_STATE4_1_STATE_TYPE(ST4_CONSTANTS), 0);93}9495static void96fd5_emit_const_ptrs(struct fd_ringbuffer *ring, gl_shader_stage type,97uint32_t regid, uint32_t num, struct fd_bo **bos,98uint32_t *offsets)99{100uint32_t anum = align(num, 2);101uint32_t i;102103debug_assert((regid % 4) == 0);104105OUT_PKT7(ring, CP_LOAD_STATE4, 3 + (2 * anum));106OUT_RING(ring, CP_LOAD_STATE4_0_DST_OFF(regid / 4) |107CP_LOAD_STATE4_0_STATE_SRC(SS4_DIRECT) |108CP_LOAD_STATE4_0_STATE_BLOCK(fd4_stage2shadersb(type)) |109CP_LOAD_STATE4_0_NUM_UNIT(anum / 2));110OUT_RING(ring, CP_LOAD_STATE4_1_EXT_SRC_ADDR(0) |111CP_LOAD_STATE4_1_STATE_TYPE(ST4_CONSTANTS));112OUT_RING(ring, CP_LOAD_STATE4_2_EXT_SRC_ADDR_HI(0));113114for (i = 0; i < num; i++) {115if (bos[i]) {116OUT_RELOC(ring, bos[i], offsets[i], 0, 0);117} else {118OUT_RING(ring, 0xbad00000 | (i << 16));119OUT_RING(ring, 0xbad00000 | (i << 16));120}121}122123for (; i < anum; i++) {124OUT_RING(ring, 0xffffffff);125OUT_RING(ring, 0xffffffff);126}127}128129static bool130is_stateobj(struct fd_ringbuffer *ring)131{132return false;133}134135static void136emit_const_ptrs(struct fd_ringbuffer *ring, const struct ir3_shader_variant *v,137uint32_t dst_offset, uint32_t num, struct fd_bo **bos,138uint32_t *offsets)139{140/* TODO inline this */141assert(dst_offset + num <= v->constlen * 4);142fd5_emit_const_ptrs(ring, v->type, dst_offset, num, bos, offsets);143}144145void146fd5_emit_cs_consts(const struct ir3_shader_variant *v,147struct fd_ringbuffer *ring, struct fd_context *ctx,148const struct pipe_grid_info *info)149{150ir3_emit_cs_consts(v, ring, ctx, info);151}152153/* Border color layout is diff from a4xx/a5xx.. if it turns out to be154* the same as a6xx then move this somewhere common ;-)155*156* Entry layout looks like (total size, 0x60 bytes):157*/158159struct PACKED bcolor_entry {160uint32_t fp32[4];161uint16_t ui16[4];162int16_t si16[4];163164uint16_t fp16[4];165uint16_t rgb565;166uint16_t rgb5a1;167uint16_t rgba4;168uint8_t __pad0[2];169uint8_t ui8[4];170int8_t si8[4];171uint32_t rgb10a2;172uint32_t z24; /* also s8? */173174uint16_t175srgb[4]; /* appears to duplicate fp16[], but clamped, used for srgb */176uint8_t __pad1[24];177};178179#define FD5_BORDER_COLOR_SIZE 0x60180#define FD5_BORDER_COLOR_UPLOAD_SIZE \181(2 * PIPE_MAX_SAMPLERS * FD5_BORDER_COLOR_SIZE)182183static void184setup_border_colors(struct fd_texture_stateobj *tex,185struct bcolor_entry *entries)186{187unsigned i, j;188STATIC_ASSERT(sizeof(struct bcolor_entry) == FD5_BORDER_COLOR_SIZE);189190for (i = 0; i < tex->num_samplers; i++) {191struct bcolor_entry *e = &entries[i];192struct pipe_sampler_state *sampler = tex->samplers[i];193union pipe_color_union *bc;194195if (!sampler)196continue;197198bc = &sampler->border_color;199200/*201* XXX HACK ALERT XXX202*203* The border colors need to be swizzled in a particular204* format-dependent order. Even though samplers don't know about205* formats, we can assume that with a GL state tracker, there's a206* 1:1 correspondence between sampler and texture. Take advantage207* of that knowledge.208*/209if ((i >= tex->num_textures) || !tex->textures[i])210continue;211212enum pipe_format format = tex->textures[i]->format;213const struct util_format_description *desc =214util_format_description(format);215216e->rgb565 = 0;217e->rgb5a1 = 0;218e->rgba4 = 0;219e->rgb10a2 = 0;220e->z24 = 0;221222for (j = 0; j < 4; j++) {223int c = desc->swizzle[j];224int cd = c;225226/*227* HACK: for PIPE_FORMAT_X24S8_UINT we end up w/ the228* stencil border color value in bc->ui[0] but according229* to desc->swizzle and desc->channel, the .x component230* is NONE and the stencil value is in the y component.231* Meanwhile the hardware wants this in the .x componetn.232*/233if ((format == PIPE_FORMAT_X24S8_UINT) ||234(format == PIPE_FORMAT_X32_S8X24_UINT)) {235if (j == 0) {236c = 1;237cd = 0;238} else {239continue;240}241}242243if (c >= 4)244continue;245246if (desc->channel[c].pure_integer) {247uint16_t clamped;248switch (desc->channel[c].size) {249case 2:250assert(desc->channel[c].type == UTIL_FORMAT_TYPE_UNSIGNED);251clamped = CLAMP(bc->ui[j], 0, 0x3);252break;253case 8:254if (desc->channel[c].type == UTIL_FORMAT_TYPE_SIGNED)255clamped = CLAMP(bc->i[j], -128, 127);256else257clamped = CLAMP(bc->ui[j], 0, 255);258break;259case 10:260assert(desc->channel[c].type == UTIL_FORMAT_TYPE_UNSIGNED);261clamped = CLAMP(bc->ui[j], 0, 0x3ff);262break;263case 16:264if (desc->channel[c].type == UTIL_FORMAT_TYPE_SIGNED)265clamped = CLAMP(bc->i[j], -32768, 32767);266else267clamped = CLAMP(bc->ui[j], 0, 65535);268break;269default:270assert(!"Unexpected bit size");271case 32:272clamped = 0;273break;274}275e->fp32[cd] = bc->ui[j];276e->fp16[cd] = clamped;277} else {278float f = bc->f[j];279float f_u = CLAMP(f, 0, 1);280float f_s = CLAMP(f, -1, 1);281282e->fp32[c] = fui(f);283e->fp16[c] = _mesa_float_to_half(f);284e->srgb[c] = _mesa_float_to_half(f_u);285e->ui16[c] = f_u * 0xffff;286e->si16[c] = f_s * 0x7fff;287e->ui8[c] = f_u * 0xff;288e->si8[c] = f_s * 0x7f;289if (c == 1)290e->rgb565 |= (int)(f_u * 0x3f) << 5;291else if (c < 3)292e->rgb565 |= (int)(f_u * 0x1f) << (c ? 11 : 0);293if (c == 3)294e->rgb5a1 |= (f_u > 0.5) ? 0x8000 : 0;295else296e->rgb5a1 |= (int)(f_u * 0x1f) << (c * 5);297if (c == 3)298e->rgb10a2 |= (int)(f_u * 0x3) << 30;299else300e->rgb10a2 |= (int)(f_u * 0x3ff) << (c * 10);301e->rgba4 |= (int)(f_u * 0xf) << (c * 4);302if (c == 0)303e->z24 = f_u * 0xffffff;304}305}306307#ifdef DEBUG308memset(&e->__pad0, 0, sizeof(e->__pad0));309memset(&e->__pad1, 0, sizeof(e->__pad1));310#endif311}312}313314static void315emit_border_color(struct fd_context *ctx, struct fd_ringbuffer *ring) assert_dt316{317struct fd5_context *fd5_ctx = fd5_context(ctx);318struct bcolor_entry *entries;319unsigned off;320void *ptr;321322STATIC_ASSERT(sizeof(struct bcolor_entry) == FD5_BORDER_COLOR_SIZE);323324u_upload_alloc(fd5_ctx->border_color_uploader, 0,325FD5_BORDER_COLOR_UPLOAD_SIZE, FD5_BORDER_COLOR_UPLOAD_SIZE,326&off, &fd5_ctx->border_color_buf, &ptr);327328entries = ptr;329330setup_border_colors(&ctx->tex[PIPE_SHADER_VERTEX], &entries[0]);331setup_border_colors(&ctx->tex[PIPE_SHADER_FRAGMENT],332&entries[ctx->tex[PIPE_SHADER_VERTEX].num_samplers]);333334OUT_PKT4(ring, REG_A5XX_TPL1_TP_BORDER_COLOR_BASE_ADDR_LO, 2);335OUT_RELOC(ring, fd_resource(fd5_ctx->border_color_buf)->bo, off, 0, 0);336337u_upload_unmap(fd5_ctx->border_color_uploader);338}339340static bool341emit_textures(struct fd_context *ctx, struct fd_ringbuffer *ring,342enum a4xx_state_block sb,343struct fd_texture_stateobj *tex) assert_dt344{345bool needs_border = false;346unsigned bcolor_offset =347(sb == SB4_FS_TEX) ? ctx->tex[PIPE_SHADER_VERTEX].num_samplers : 0;348unsigned i;349350if (tex->num_samplers > 0) {351/* output sampler state: */352OUT_PKT7(ring, CP_LOAD_STATE4, 3 + (4 * tex->num_samplers));353OUT_RING(ring, CP_LOAD_STATE4_0_DST_OFF(0) |354CP_LOAD_STATE4_0_STATE_SRC(SS4_DIRECT) |355CP_LOAD_STATE4_0_STATE_BLOCK(sb) |356CP_LOAD_STATE4_0_NUM_UNIT(tex->num_samplers));357OUT_RING(ring, CP_LOAD_STATE4_1_STATE_TYPE(ST4_SHADER) |358CP_LOAD_STATE4_1_EXT_SRC_ADDR(0));359OUT_RING(ring, CP_LOAD_STATE4_2_EXT_SRC_ADDR_HI(0));360for (i = 0; i < tex->num_samplers; i++) {361static const struct fd5_sampler_stateobj dummy_sampler = {};362const struct fd5_sampler_stateobj *sampler =363tex->samplers[i] ? fd5_sampler_stateobj(tex->samplers[i])364: &dummy_sampler;365OUT_RING(ring, sampler->texsamp0);366OUT_RING(ring, sampler->texsamp1);367OUT_RING(ring, sampler->texsamp2 |368A5XX_TEX_SAMP_2_BCOLOR_OFFSET(bcolor_offset + i));369OUT_RING(ring, sampler->texsamp3);370371needs_border |= sampler->needs_border;372}373}374375if (tex->num_textures > 0) {376unsigned num_textures = tex->num_textures;377378/* emit texture state: */379OUT_PKT7(ring, CP_LOAD_STATE4, 3 + (12 * num_textures));380OUT_RING(ring, CP_LOAD_STATE4_0_DST_OFF(0) |381CP_LOAD_STATE4_0_STATE_SRC(SS4_DIRECT) |382CP_LOAD_STATE4_0_STATE_BLOCK(sb) |383CP_LOAD_STATE4_0_NUM_UNIT(num_textures));384OUT_RING(ring, CP_LOAD_STATE4_1_STATE_TYPE(ST4_CONSTANTS) |385CP_LOAD_STATE4_1_EXT_SRC_ADDR(0));386OUT_RING(ring, CP_LOAD_STATE4_2_EXT_SRC_ADDR_HI(0));387for (i = 0; i < tex->num_textures; i++) {388static const struct fd5_pipe_sampler_view dummy_view = {};389const struct fd5_pipe_sampler_view *view =390tex->textures[i] ? fd5_pipe_sampler_view(tex->textures[i])391: &dummy_view;392enum a5xx_tile_mode tile_mode = TILE5_LINEAR;393394if (view->base.texture)395tile_mode = fd_resource(view->base.texture)->layout.tile_mode;396397OUT_RING(ring,398view->texconst0 | A5XX_TEX_CONST_0_TILE_MODE(tile_mode));399OUT_RING(ring, view->texconst1);400OUT_RING(ring, view->texconst2);401OUT_RING(ring, view->texconst3);402if (view->base.texture) {403struct fd_resource *rsc = fd_resource(view->base.texture);404if (view->base.format == PIPE_FORMAT_X32_S8X24_UINT)405rsc = rsc->stencil;406OUT_RELOC(ring, rsc->bo, view->offset,407(uint64_t)view->texconst5 << 32, 0);408} else {409OUT_RING(ring, 0x00000000);410OUT_RING(ring, view->texconst5);411}412OUT_RING(ring, view->texconst6);413OUT_RING(ring, view->texconst7);414OUT_RING(ring, view->texconst8);415OUT_RING(ring, view->texconst9);416OUT_RING(ring, view->texconst10);417OUT_RING(ring, view->texconst11);418}419}420421return needs_border;422}423424static void425emit_ssbos(struct fd_context *ctx, struct fd_ringbuffer *ring,426enum a4xx_state_block sb, struct fd_shaderbuf_stateobj *so,427const struct ir3_shader_variant *v)428{429unsigned count = util_last_bit(so->enabled_mask);430431for (unsigned i = 0; i < count; i++) {432OUT_PKT7(ring, CP_LOAD_STATE4, 5);433OUT_RING(ring, CP_LOAD_STATE4_0_DST_OFF(i) |434CP_LOAD_STATE4_0_STATE_SRC(SS4_DIRECT) |435CP_LOAD_STATE4_0_STATE_BLOCK(sb) |436CP_LOAD_STATE4_0_NUM_UNIT(1));437OUT_RING(ring, CP_LOAD_STATE4_1_STATE_TYPE(1) |438CP_LOAD_STATE4_1_EXT_SRC_ADDR(0));439OUT_RING(ring, CP_LOAD_STATE4_2_EXT_SRC_ADDR_HI(0));440441struct pipe_shader_buffer *buf = &so->sb[i];442unsigned sz = buf->buffer_size;443444/* width is in dwords, overflows into height: */445sz /= 4;446447OUT_RING(ring, A5XX_SSBO_1_0_WIDTH(sz));448OUT_RING(ring, A5XX_SSBO_1_1_HEIGHT(sz >> 16));449450OUT_PKT7(ring, CP_LOAD_STATE4, 5);451OUT_RING(ring, CP_LOAD_STATE4_0_DST_OFF(i) |452CP_LOAD_STATE4_0_STATE_SRC(SS4_DIRECT) |453CP_LOAD_STATE4_0_STATE_BLOCK(sb) |454CP_LOAD_STATE4_0_NUM_UNIT(1));455OUT_RING(ring, CP_LOAD_STATE4_1_STATE_TYPE(2) |456CP_LOAD_STATE4_1_EXT_SRC_ADDR(0));457OUT_RING(ring, CP_LOAD_STATE4_2_EXT_SRC_ADDR_HI(0));458459if (buf->buffer) {460struct fd_resource *rsc = fd_resource(buf->buffer);461OUT_RELOC(ring, rsc->bo, buf->buffer_offset, 0, 0);462} else {463OUT_RING(ring, 0x00000000);464OUT_RING(ring, 0x00000000);465}466}467}468469void470fd5_emit_vertex_bufs(struct fd_ringbuffer *ring, struct fd5_emit *emit)471{472int32_t i, j;473const struct fd_vertex_state *vtx = emit->vtx;474const struct ir3_shader_variant *vp = fd5_emit_get_vp(emit);475476for (i = 0, j = 0; i <= vp->inputs_count; i++) {477if (vp->inputs[i].sysval)478continue;479if (vp->inputs[i].compmask) {480struct pipe_vertex_element *elem = &vtx->vtx->pipe[i];481const struct pipe_vertex_buffer *vb =482&vtx->vertexbuf.vb[elem->vertex_buffer_index];483struct fd_resource *rsc = fd_resource(vb->buffer.resource);484enum pipe_format pfmt = elem->src_format;485enum a5xx_vtx_fmt fmt = fd5_pipe2vtx(pfmt);486bool isint = util_format_is_pure_integer(pfmt);487uint32_t off = vb->buffer_offset + elem->src_offset;488uint32_t size = fd_bo_size(rsc->bo) - off;489debug_assert(fmt != VFMT5_NONE);490491#ifdef DEBUG492/* see493* dEQP-GLES31.stress.vertex_attribute_binding.buffer_bounds.bind_vertex_buffer_offset_near_wrap_10494*/495if (off > fd_bo_size(rsc->bo))496continue;497#endif498499OUT_PKT4(ring, REG_A5XX_VFD_FETCH(j), 4);500OUT_RELOC(ring, rsc->bo, off, 0, 0);501OUT_RING(ring, size); /* VFD_FETCH[j].SIZE */502OUT_RING(ring, vb->stride); /* VFD_FETCH[j].STRIDE */503504OUT_PKT4(ring, REG_A5XX_VFD_DECODE(j), 2);505OUT_RING(506ring,507A5XX_VFD_DECODE_INSTR_IDX(j) | A5XX_VFD_DECODE_INSTR_FORMAT(fmt) |508COND(elem->instance_divisor, A5XX_VFD_DECODE_INSTR_INSTANCED) |509A5XX_VFD_DECODE_INSTR_SWAP(fd5_pipe2swap(pfmt)) |510A5XX_VFD_DECODE_INSTR_UNK30 |511COND(!isint, A5XX_VFD_DECODE_INSTR_FLOAT));512OUT_RING(513ring,514MAX2(1, elem->instance_divisor)); /* VFD_DECODE[j].STEP_RATE */515516OUT_PKT4(ring, REG_A5XX_VFD_DEST_CNTL(j), 1);517OUT_RING(ring,518A5XX_VFD_DEST_CNTL_INSTR_WRITEMASK(vp->inputs[i].compmask) |519A5XX_VFD_DEST_CNTL_INSTR_REGID(vp->inputs[i].regid));520521j++;522}523}524525OUT_PKT4(ring, REG_A5XX_VFD_CONTROL_0, 1);526OUT_RING(ring, A5XX_VFD_CONTROL_0_VTXCNT(j));527}528529void530fd5_emit_state(struct fd_context *ctx, struct fd_ringbuffer *ring,531struct fd5_emit *emit)532{533struct pipe_framebuffer_state *pfb = &ctx->batch->framebuffer;534const struct ir3_shader_variant *vp = fd5_emit_get_vp(emit);535const struct ir3_shader_variant *fp = fd5_emit_get_fp(emit);536const enum fd_dirty_3d_state dirty = emit->dirty;537bool needs_border = false;538539emit_marker5(ring, 5);540541if ((dirty & FD_DIRTY_FRAMEBUFFER) && !emit->binning_pass) {542unsigned char mrt_comp[A5XX_MAX_RENDER_TARGETS] = {0};543544for (unsigned i = 0; i < A5XX_MAX_RENDER_TARGETS; i++) {545mrt_comp[i] = ((i < pfb->nr_cbufs) && pfb->cbufs[i]) ? 0xf : 0;546}547548OUT_PKT4(ring, REG_A5XX_RB_RENDER_COMPONENTS, 1);549OUT_RING(ring, A5XX_RB_RENDER_COMPONENTS_RT0(mrt_comp[0]) |550A5XX_RB_RENDER_COMPONENTS_RT1(mrt_comp[1]) |551A5XX_RB_RENDER_COMPONENTS_RT2(mrt_comp[2]) |552A5XX_RB_RENDER_COMPONENTS_RT3(mrt_comp[3]) |553A5XX_RB_RENDER_COMPONENTS_RT4(mrt_comp[4]) |554A5XX_RB_RENDER_COMPONENTS_RT5(mrt_comp[5]) |555A5XX_RB_RENDER_COMPONENTS_RT6(mrt_comp[6]) |556A5XX_RB_RENDER_COMPONENTS_RT7(mrt_comp[7]));557}558559if (dirty & (FD_DIRTY_ZSA | FD_DIRTY_FRAMEBUFFER)) {560struct fd5_zsa_stateobj *zsa = fd5_zsa_stateobj(ctx->zsa);561uint32_t rb_alpha_control = zsa->rb_alpha_control;562563if (util_format_is_pure_integer(pipe_surface_format(pfb->cbufs[0])))564rb_alpha_control &= ~A5XX_RB_ALPHA_CONTROL_ALPHA_TEST;565566OUT_PKT4(ring, REG_A5XX_RB_ALPHA_CONTROL, 1);567OUT_RING(ring, rb_alpha_control);568569OUT_PKT4(ring, REG_A5XX_RB_STENCIL_CONTROL, 1);570OUT_RING(ring, zsa->rb_stencil_control);571}572573if (dirty & (FD_DIRTY_ZSA | FD_DIRTY_BLEND | FD_DIRTY_PROG)) {574struct fd5_blend_stateobj *blend = fd5_blend_stateobj(ctx->blend);575struct fd5_zsa_stateobj *zsa = fd5_zsa_stateobj(ctx->zsa);576577if (pfb->zsbuf) {578struct fd_resource *rsc = fd_resource(pfb->zsbuf->texture);579uint32_t gras_lrz_cntl = zsa->gras_lrz_cntl;580581if (emit->no_lrz_write || !rsc->lrz || !rsc->lrz_valid)582gras_lrz_cntl = 0;583else if (emit->binning_pass && blend->lrz_write && zsa->lrz_write)584gras_lrz_cntl |= A5XX_GRAS_LRZ_CNTL_LRZ_WRITE;585586OUT_PKT4(ring, REG_A5XX_GRAS_LRZ_CNTL, 1);587OUT_RING(ring, gras_lrz_cntl);588}589}590591if (dirty & (FD_DIRTY_ZSA | FD_DIRTY_STENCIL_REF)) {592struct fd5_zsa_stateobj *zsa = fd5_zsa_stateobj(ctx->zsa);593struct pipe_stencil_ref *sr = &ctx->stencil_ref;594595OUT_PKT4(ring, REG_A5XX_RB_STENCILREFMASK, 2);596OUT_RING(ring, zsa->rb_stencilrefmask |597A5XX_RB_STENCILREFMASK_STENCILREF(sr->ref_value[0]));598OUT_RING(ring, zsa->rb_stencilrefmask_bf |599A5XX_RB_STENCILREFMASK_BF_STENCILREF(sr->ref_value[1]));600}601602if (dirty & (FD_DIRTY_ZSA | FD_DIRTY_RASTERIZER | FD_DIRTY_PROG)) {603struct fd5_zsa_stateobj *zsa = fd5_zsa_stateobj(ctx->zsa);604bool fragz = fp->no_earlyz || fp->has_kill || zsa->base.alpha_enabled ||605fp->writes_pos;606607OUT_PKT4(ring, REG_A5XX_RB_DEPTH_CNTL, 1);608OUT_RING(ring, zsa->rb_depth_cntl);609610OUT_PKT4(ring, REG_A5XX_RB_DEPTH_PLANE_CNTL, 1);611OUT_RING(ring, COND(fragz, A5XX_RB_DEPTH_PLANE_CNTL_FRAG_WRITES_Z) |612COND(fragz && fp->fragcoord_compmask != 0,613A5XX_RB_DEPTH_PLANE_CNTL_UNK1));614615OUT_PKT4(ring, REG_A5XX_GRAS_SU_DEPTH_PLANE_CNTL, 1);616OUT_RING(ring, COND(fragz, A5XX_GRAS_SU_DEPTH_PLANE_CNTL_FRAG_WRITES_Z) |617COND(fragz && fp->fragcoord_compmask != 0,618A5XX_GRAS_SU_DEPTH_PLANE_CNTL_UNK1));619}620621/* NOTE: scissor enabled bit is part of rasterizer state: */622if (dirty & (FD_DIRTY_SCISSOR | FD_DIRTY_RASTERIZER)) {623struct pipe_scissor_state *scissor = fd_context_get_scissor(ctx);624625OUT_PKT4(ring, REG_A5XX_GRAS_SC_SCREEN_SCISSOR_TL_0, 2);626OUT_RING(ring, A5XX_GRAS_SC_SCREEN_SCISSOR_TL_0_X(scissor->minx) |627A5XX_GRAS_SC_SCREEN_SCISSOR_TL_0_Y(scissor->miny));628OUT_RING(ring, A5XX_GRAS_SC_SCREEN_SCISSOR_TL_0_X(scissor->maxx - 1) |629A5XX_GRAS_SC_SCREEN_SCISSOR_TL_0_Y(scissor->maxy - 1));630631OUT_PKT4(ring, REG_A5XX_GRAS_SC_VIEWPORT_SCISSOR_TL_0, 2);632OUT_RING(ring, A5XX_GRAS_SC_VIEWPORT_SCISSOR_TL_0_X(scissor->minx) |633A5XX_GRAS_SC_VIEWPORT_SCISSOR_TL_0_Y(scissor->miny));634OUT_RING(ring,635A5XX_GRAS_SC_VIEWPORT_SCISSOR_TL_0_X(scissor->maxx - 1) |636A5XX_GRAS_SC_VIEWPORT_SCISSOR_TL_0_Y(scissor->maxy - 1));637638ctx->batch->max_scissor.minx =639MIN2(ctx->batch->max_scissor.minx, scissor->minx);640ctx->batch->max_scissor.miny =641MIN2(ctx->batch->max_scissor.miny, scissor->miny);642ctx->batch->max_scissor.maxx =643MAX2(ctx->batch->max_scissor.maxx, scissor->maxx);644ctx->batch->max_scissor.maxy =645MAX2(ctx->batch->max_scissor.maxy, scissor->maxy);646}647648if (dirty & FD_DIRTY_VIEWPORT) {649fd_wfi(ctx->batch, ring);650OUT_PKT4(ring, REG_A5XX_GRAS_CL_VPORT_XOFFSET_0, 6);651OUT_RING(ring, A5XX_GRAS_CL_VPORT_XOFFSET_0(ctx->viewport.translate[0]));652OUT_RING(ring, A5XX_GRAS_CL_VPORT_XSCALE_0(ctx->viewport.scale[0]));653OUT_RING(ring, A5XX_GRAS_CL_VPORT_YOFFSET_0(ctx->viewport.translate[1]));654OUT_RING(ring, A5XX_GRAS_CL_VPORT_YSCALE_0(ctx->viewport.scale[1]));655OUT_RING(ring, A5XX_GRAS_CL_VPORT_ZOFFSET_0(ctx->viewport.translate[2]));656OUT_RING(ring, A5XX_GRAS_CL_VPORT_ZSCALE_0(ctx->viewport.scale[2]));657}658659if (dirty & FD_DIRTY_PROG)660fd5_program_emit(ctx, ring, emit);661662if (dirty & FD_DIRTY_RASTERIZER) {663struct fd5_rasterizer_stateobj *rasterizer =664fd5_rasterizer_stateobj(ctx->rasterizer);665666OUT_PKT4(ring, REG_A5XX_GRAS_SU_CNTL, 1);667OUT_RING(ring, rasterizer->gras_su_cntl |668COND(pfb->samples > 1, A5XX_GRAS_SU_CNTL_MSAA_ENABLE));669670OUT_PKT4(ring, REG_A5XX_GRAS_SU_POINT_MINMAX, 2);671OUT_RING(ring, rasterizer->gras_su_point_minmax);672OUT_RING(ring, rasterizer->gras_su_point_size);673674OUT_PKT4(ring, REG_A5XX_GRAS_SU_POLY_OFFSET_SCALE, 3);675OUT_RING(ring, rasterizer->gras_su_poly_offset_scale);676OUT_RING(ring, rasterizer->gras_su_poly_offset_offset);677OUT_RING(ring, rasterizer->gras_su_poly_offset_clamp);678679OUT_PKT4(ring, REG_A5XX_PC_RASTER_CNTL, 1);680OUT_RING(ring, rasterizer->pc_raster_cntl);681682OUT_PKT4(ring, REG_A5XX_GRAS_CL_CNTL, 1);683OUT_RING(ring, rasterizer->gras_cl_clip_cntl);684}685686/* note: must come after program emit.. because there is some overlap687* in registers, ex. PC_PRIMITIVE_CNTL and we rely on some cached688* values from fd5_program_emit() to avoid having to re-emit the prog689* every time rast state changes.690*691* Since the primitive restart state is not part of a tracked object, we692* re-emit this register every time.693*/694if (emit->info && ctx->rasterizer) {695struct fd5_rasterizer_stateobj *rasterizer =696fd5_rasterizer_stateobj(ctx->rasterizer);697unsigned max_loc = fd5_context(ctx)->max_loc;698699OUT_PKT4(ring, REG_A5XX_PC_PRIMITIVE_CNTL, 1);700OUT_RING(ring,701rasterizer->pc_primitive_cntl |702A5XX_PC_PRIMITIVE_CNTL_STRIDE_IN_VPC(max_loc) |703COND(emit->info->primitive_restart && emit->info->index_size,704A5XX_PC_PRIMITIVE_CNTL_PRIMITIVE_RESTART));705}706707if (dirty & (FD_DIRTY_FRAMEBUFFER | FD_DIRTY_RASTERIZER | FD_DIRTY_PROG)) {708uint32_t posz_regid = ir3_find_output_regid(fp, FRAG_RESULT_DEPTH);709unsigned nr = pfb->nr_cbufs;710711if (emit->binning_pass)712nr = 0;713else if (ctx->rasterizer->rasterizer_discard)714nr = 0;715716OUT_PKT4(ring, REG_A5XX_RB_FS_OUTPUT_CNTL, 1);717OUT_RING(ring,718A5XX_RB_FS_OUTPUT_CNTL_MRT(nr) |719COND(fp->writes_pos, A5XX_RB_FS_OUTPUT_CNTL_FRAG_WRITES_Z));720721OUT_PKT4(ring, REG_A5XX_SP_FS_OUTPUT_CNTL, 1);722OUT_RING(ring, A5XX_SP_FS_OUTPUT_CNTL_MRT(nr) |723A5XX_SP_FS_OUTPUT_CNTL_DEPTH_REGID(posz_regid) |724A5XX_SP_FS_OUTPUT_CNTL_SAMPLEMASK_REGID(regid(63, 0)));725}726727ir3_emit_vs_consts(vp, ring, ctx, emit->info, emit->indirect, emit->draw);728if (!emit->binning_pass)729ir3_emit_fs_consts(fp, ring, ctx);730731struct ir3_stream_output_info *info = &vp->shader->stream_output;732if (info->num_outputs) {733struct fd_streamout_stateobj *so = &ctx->streamout;734735for (unsigned i = 0; i < so->num_targets; i++) {736struct fd_stream_output_target *target =737fd_stream_output_target(so->targets[i]);738739if (!target)740continue;741742OUT_PKT4(ring, REG_A5XX_VPC_SO_BUFFER_BASE_LO(i), 3);743/* VPC_SO[i].BUFFER_BASE_LO: */744OUT_RELOC(ring, fd_resource(target->base.buffer)->bo, 0, 0, 0);745OUT_RING(ring, target->base.buffer_size + target->base.buffer_offset);746747struct fd_bo *offset_bo = fd_resource(target->offset_buf)->bo;748749if (so->reset & (1 << i)) {750assert(so->offsets[i] == 0);751752OUT_PKT7(ring, CP_MEM_WRITE, 3);753OUT_RELOC(ring, offset_bo, 0, 0, 0);754OUT_RING(ring, target->base.buffer_offset);755756OUT_PKT4(ring, REG_A5XX_VPC_SO_BUFFER_OFFSET(i), 1);757OUT_RING(ring, target->base.buffer_offset);758} else {759OUT_PKT7(ring, CP_MEM_TO_REG, 3);760OUT_RING(ring,761CP_MEM_TO_REG_0_REG(REG_A5XX_VPC_SO_BUFFER_OFFSET(i)) |762CP_MEM_TO_REG_0_SHIFT_BY_2 | CP_MEM_TO_REG_0_UNK31 |763CP_MEM_TO_REG_0_CNT(0));764OUT_RELOC(ring, offset_bo, 0, 0, 0);765}766767// After a draw HW would write the new offset to offset_bo768OUT_PKT4(ring, REG_A5XX_VPC_SO_FLUSH_BASE_LO(i), 2);769OUT_RELOC(ring, offset_bo, 0, 0, 0);770771so->reset &= ~(1 << i);772773emit->streamout_mask |= (1 << i);774}775}776777if (dirty & FD_DIRTY_BLEND) {778struct fd5_blend_stateobj *blend = fd5_blend_stateobj(ctx->blend);779uint32_t i;780781for (i = 0; i < A5XX_MAX_RENDER_TARGETS; i++) {782enum pipe_format format = pipe_surface_format(pfb->cbufs[i]);783bool is_int = util_format_is_pure_integer(format);784bool has_alpha = util_format_has_alpha(format);785uint32_t control = blend->rb_mrt[i].control;786787if (is_int) {788control &= A5XX_RB_MRT_CONTROL_COMPONENT_ENABLE__MASK;789control |= A5XX_RB_MRT_CONTROL_ROP_CODE(ROP_COPY);790}791792if (!has_alpha) {793control &= ~A5XX_RB_MRT_CONTROL_BLEND2;794}795796OUT_PKT4(ring, REG_A5XX_RB_MRT_CONTROL(i), 1);797OUT_RING(ring, control);798799OUT_PKT4(ring, REG_A5XX_RB_MRT_BLEND_CONTROL(i), 1);800OUT_RING(ring, blend->rb_mrt[i].blend_control);801}802803OUT_PKT4(ring, REG_A5XX_SP_BLEND_CNTL, 1);804OUT_RING(ring, blend->sp_blend_cntl);805}806807if (dirty & (FD_DIRTY_BLEND | FD_DIRTY_SAMPLE_MASK)) {808struct fd5_blend_stateobj *blend = fd5_blend_stateobj(ctx->blend);809810OUT_PKT4(ring, REG_A5XX_RB_BLEND_CNTL, 1);811OUT_RING(ring, blend->rb_blend_cntl |812A5XX_RB_BLEND_CNTL_SAMPLE_MASK(ctx->sample_mask));813}814815if (dirty & FD_DIRTY_BLEND_COLOR) {816struct pipe_blend_color *bcolor = &ctx->blend_color;817818OUT_PKT4(ring, REG_A5XX_RB_BLEND_RED, 8);819OUT_RING(ring, A5XX_RB_BLEND_RED_FLOAT(bcolor->color[0]) |820A5XX_RB_BLEND_RED_UINT(bcolor->color[0] * 0xff) |821A5XX_RB_BLEND_RED_SINT(bcolor->color[0] * 0x7f));822OUT_RING(ring, A5XX_RB_BLEND_RED_F32(bcolor->color[0]));823OUT_RING(ring, A5XX_RB_BLEND_GREEN_FLOAT(bcolor->color[1]) |824A5XX_RB_BLEND_GREEN_UINT(bcolor->color[1] * 0xff) |825A5XX_RB_BLEND_GREEN_SINT(bcolor->color[1] * 0x7f));826OUT_RING(ring, A5XX_RB_BLEND_RED_F32(bcolor->color[1]));827OUT_RING(ring, A5XX_RB_BLEND_BLUE_FLOAT(bcolor->color[2]) |828A5XX_RB_BLEND_BLUE_UINT(bcolor->color[2] * 0xff) |829A5XX_RB_BLEND_BLUE_SINT(bcolor->color[2] * 0x7f));830OUT_RING(ring, A5XX_RB_BLEND_BLUE_F32(bcolor->color[2]));831OUT_RING(ring, A5XX_RB_BLEND_ALPHA_FLOAT(bcolor->color[3]) |832A5XX_RB_BLEND_ALPHA_UINT(bcolor->color[3] * 0xff) |833A5XX_RB_BLEND_ALPHA_SINT(bcolor->color[3] * 0x7f));834OUT_RING(ring, A5XX_RB_BLEND_ALPHA_F32(bcolor->color[3]));835}836837if (ctx->dirty_shader[PIPE_SHADER_VERTEX] & FD_DIRTY_SHADER_TEX) {838needs_border |=839emit_textures(ctx, ring, SB4_VS_TEX, &ctx->tex[PIPE_SHADER_VERTEX]);840OUT_PKT4(ring, REG_A5XX_TPL1_VS_TEX_COUNT, 1);841OUT_RING(ring, ctx->tex[PIPE_SHADER_VERTEX].num_textures);842}843844if (ctx->dirty_shader[PIPE_SHADER_FRAGMENT] & FD_DIRTY_SHADER_TEX) {845needs_border |=846emit_textures(ctx, ring, SB4_FS_TEX, &ctx->tex[PIPE_SHADER_FRAGMENT]);847}848849OUT_PKT4(ring, REG_A5XX_TPL1_FS_TEX_COUNT, 1);850OUT_RING(ring, ctx->shaderimg[PIPE_SHADER_FRAGMENT].enabled_mask851? ~0852: ctx->tex[PIPE_SHADER_FRAGMENT].num_textures);853854OUT_PKT4(ring, REG_A5XX_TPL1_CS_TEX_COUNT, 1);855OUT_RING(ring, 0);856857if (needs_border)858emit_border_color(ctx, ring);859860if (ctx->dirty_shader[PIPE_SHADER_FRAGMENT] & FD_DIRTY_SHADER_SSBO)861emit_ssbos(ctx, ring, SB4_SSBO, &ctx->shaderbuf[PIPE_SHADER_FRAGMENT],862fp);863864if (ctx->dirty_shader[PIPE_SHADER_FRAGMENT] & FD_DIRTY_SHADER_IMAGE)865fd5_emit_images(ctx, ring, PIPE_SHADER_FRAGMENT, fp);866}867868void869fd5_emit_cs_state(struct fd_context *ctx, struct fd_ringbuffer *ring,870struct ir3_shader_variant *cp)871{872enum fd_dirty_shader_state dirty = ctx->dirty_shader[PIPE_SHADER_COMPUTE];873874if (dirty & FD_DIRTY_SHADER_TEX) {875bool needs_border = false;876needs_border |=877emit_textures(ctx, ring, SB4_CS_TEX, &ctx->tex[PIPE_SHADER_COMPUTE]);878879if (needs_border)880emit_border_color(ctx, ring);881882OUT_PKT4(ring, REG_A5XX_TPL1_VS_TEX_COUNT, 1);883OUT_RING(ring, 0);884885OUT_PKT4(ring, REG_A5XX_TPL1_HS_TEX_COUNT, 1);886OUT_RING(ring, 0);887888OUT_PKT4(ring, REG_A5XX_TPL1_DS_TEX_COUNT, 1);889OUT_RING(ring, 0);890891OUT_PKT4(ring, REG_A5XX_TPL1_GS_TEX_COUNT, 1);892OUT_RING(ring, 0);893894OUT_PKT4(ring, REG_A5XX_TPL1_FS_TEX_COUNT, 1);895OUT_RING(ring, 0);896}897898OUT_PKT4(ring, REG_A5XX_TPL1_CS_TEX_COUNT, 1);899OUT_RING(ring, ctx->shaderimg[PIPE_SHADER_COMPUTE].enabled_mask900? ~0901: ctx->tex[PIPE_SHADER_COMPUTE].num_textures);902903if (dirty & FD_DIRTY_SHADER_SSBO)904emit_ssbos(ctx, ring, SB4_CS_SSBO, &ctx->shaderbuf[PIPE_SHADER_COMPUTE],905cp);906907if (dirty & FD_DIRTY_SHADER_IMAGE)908fd5_emit_images(ctx, ring, PIPE_SHADER_COMPUTE, cp);909}910911/* emit setup at begin of new cmdstream buffer (don't rely on previous912* state, there could have been a context switch between ioctls):913*/914void915fd5_emit_restore(struct fd_batch *batch, struct fd_ringbuffer *ring)916{917struct fd_context *ctx = batch->ctx;918919fd5_set_render_mode(ctx, ring, BYPASS);920fd5_cache_flush(batch, ring);921922OUT_PKT4(ring, REG_A5XX_HLSQ_UPDATE_CNTL, 1);923OUT_RING(ring, 0xfffff);924925/*926t7 opcode: CP_PERFCOUNTER_ACTION (50) (4 dwords)9270000000500024048: 70d08003 00000000 001c5000 00000005928t7 opcode: CP_PERFCOUNTER_ACTION (50) (4 dwords)9290000000500024058: 70d08003 00000010 001c7000 00000005930931t7 opcode: CP_WAIT_FOR_IDLE (26) (1 dwords)9320000000500024068: 70268000933*/934935OUT_PKT4(ring, REG_A5XX_PC_RESTART_INDEX, 1);936OUT_RING(ring, 0xffffffff);937938OUT_PKT4(ring, REG_A5XX_PC_RASTER_CNTL, 1);939OUT_RING(ring, 0x00000012);940941OUT_PKT4(ring, REG_A5XX_GRAS_SU_POINT_MINMAX, 2);942OUT_RING(ring, A5XX_GRAS_SU_POINT_MINMAX_MIN(1.0) |943A5XX_GRAS_SU_POINT_MINMAX_MAX(4092.0));944OUT_RING(ring, A5XX_GRAS_SU_POINT_SIZE(0.5));945946OUT_PKT4(ring, REG_A5XX_GRAS_SU_CONSERVATIVE_RAS_CNTL, 1);947OUT_RING(ring, 0x00000000); /* GRAS_SU_CONSERVATIVE_RAS_CNTL */948949OUT_PKT4(ring, REG_A5XX_GRAS_SC_SCREEN_SCISSOR_CNTL, 1);950OUT_RING(ring, 0x00000000); /* GRAS_SC_SCREEN_SCISSOR_CNTL */951952OUT_PKT4(ring, REG_A5XX_SP_VS_CONFIG_MAX_CONST, 1);953OUT_RING(ring, 0); /* SP_VS_CONFIG_MAX_CONST */954955OUT_PKT4(ring, REG_A5XX_SP_FS_CONFIG_MAX_CONST, 1);956OUT_RING(ring, 0); /* SP_FS_CONFIG_MAX_CONST */957958OUT_PKT4(ring, REG_A5XX_UNKNOWN_E292, 2);959OUT_RING(ring, 0x00000000); /* UNKNOWN_E292 */960OUT_RING(ring, 0x00000000); /* UNKNOWN_E293 */961962OUT_PKT4(ring, REG_A5XX_RB_MODE_CNTL, 1);963OUT_RING(ring, 0x00000044); /* RB_MODE_CNTL */964965OUT_PKT4(ring, REG_A5XX_RB_DBG_ECO_CNTL, 1);966OUT_RING(ring, 0x00100000); /* RB_DBG_ECO_CNTL */967968OUT_PKT4(ring, REG_A5XX_VFD_MODE_CNTL, 1);969OUT_RING(ring, 0x00000000); /* VFD_MODE_CNTL */970971OUT_PKT4(ring, REG_A5XX_PC_MODE_CNTL, 1);972OUT_RING(ring, 0x0000001f); /* PC_MODE_CNTL */973974OUT_PKT4(ring, REG_A5XX_SP_MODE_CNTL, 1);975OUT_RING(ring, 0x0000001e); /* SP_MODE_CNTL */976977if (ctx->screen->gpu_id == 540) {978OUT_PKT4(ring, REG_A5XX_SP_DBG_ECO_CNTL, 1);979OUT_RING(ring, 0x800); /* SP_DBG_ECO_CNTL */980981OUT_PKT4(ring, REG_A5XX_HLSQ_DBG_ECO_CNTL, 1);982OUT_RING(ring, 0x0);983984OUT_PKT4(ring, REG_A5XX_VPC_DBG_ECO_CNTL, 1);985OUT_RING(ring, 0x800400);986} else {987OUT_PKT4(ring, REG_A5XX_SP_DBG_ECO_CNTL, 1);988OUT_RING(ring, 0x40000800); /* SP_DBG_ECO_CNTL */989}990991OUT_PKT4(ring, REG_A5XX_TPL1_MODE_CNTL, 1);992OUT_RING(ring, 0x00000544); /* TPL1_MODE_CNTL */993994OUT_PKT4(ring, REG_A5XX_HLSQ_TIMEOUT_THRESHOLD_0, 2);995OUT_RING(ring, 0x00000080); /* HLSQ_TIMEOUT_THRESHOLD_0 */996OUT_RING(ring, 0x00000000); /* HLSQ_TIMEOUT_THRESHOLD_1 */997998OUT_PKT4(ring, REG_A5XX_VPC_DBG_ECO_CNTL, 1);999OUT_RING(ring, 0x00000400); /* VPC_DBG_ECO_CNTL */10001001OUT_PKT4(ring, REG_A5XX_HLSQ_MODE_CNTL, 1);1002OUT_RING(ring, 0x00000001); /* HLSQ_MODE_CNTL */10031004OUT_PKT4(ring, REG_A5XX_VPC_MODE_CNTL, 1);1005OUT_RING(ring, 0x00000000); /* VPC_MODE_CNTL */10061007/* we don't use this yet.. probably best to disable.. */1008OUT_PKT7(ring, CP_SET_DRAW_STATE, 3);1009OUT_RING(ring, CP_SET_DRAW_STATE__0_COUNT(0) |1010CP_SET_DRAW_STATE__0_DISABLE_ALL_GROUPS |1011CP_SET_DRAW_STATE__0_GROUP_ID(0));1012OUT_RING(ring, CP_SET_DRAW_STATE__1_ADDR_LO(0));1013OUT_RING(ring, CP_SET_DRAW_STATE__2_ADDR_HI(0));10141015OUT_PKT4(ring, REG_A5XX_GRAS_SU_CONSERVATIVE_RAS_CNTL, 1);1016OUT_RING(ring, 0x00000000); /* GRAS_SU_CONSERVATIVE_RAS_CNTL */10171018OUT_PKT4(ring, REG_A5XX_GRAS_SC_BIN_CNTL, 1);1019OUT_RING(ring, 0x00000000); /* GRAS_SC_BIN_CNTL */10201021OUT_PKT4(ring, REG_A5XX_GRAS_SC_BIN_CNTL, 1);1022OUT_RING(ring, 0x00000000); /* GRAS_SC_BIN_CNTL */10231024OUT_PKT4(ring, REG_A5XX_VPC_FS_PRIMITIVEID_CNTL, 1);1025OUT_RING(ring, 0x000000ff); /* VPC_FS_PRIMITIVEID_CNTL */10261027OUT_PKT4(ring, REG_A5XX_VPC_SO_OVERRIDE, 1);1028OUT_RING(ring, A5XX_VPC_SO_OVERRIDE_SO_DISABLE);10291030OUT_PKT4(ring, REG_A5XX_VPC_SO_BUFFER_BASE_LO(0), 3);1031OUT_RING(ring, 0x00000000); /* VPC_SO_BUFFER_BASE_LO_0 */1032OUT_RING(ring, 0x00000000); /* VPC_SO_BUFFER_BASE_HI_0 */1033OUT_RING(ring, 0x00000000); /* VPC_SO_BUFFER_SIZE_0 */10341035OUT_PKT4(ring, REG_A5XX_VPC_SO_FLUSH_BASE_LO(0), 2);1036OUT_RING(ring, 0x00000000); /* VPC_SO_FLUSH_BASE_LO_0 */1037OUT_RING(ring, 0x00000000); /* VPC_SO_FLUSH_BASE_HI_0 */10381039OUT_PKT4(ring, REG_A5XX_PC_GS_PARAM, 1);1040OUT_RING(ring, 0x00000000); /* PC_GS_PARAM */10411042OUT_PKT4(ring, REG_A5XX_PC_HS_PARAM, 1);1043OUT_RING(ring, 0x00000000); /* PC_HS_PARAM */10441045OUT_PKT4(ring, REG_A5XX_TPL1_TP_FS_ROTATION_CNTL, 1);1046OUT_RING(ring, 0x00000000); /* TPL1_TP_FS_ROTATION_CNTL */10471048OUT_PKT4(ring, REG_A5XX_UNKNOWN_E004, 1);1049OUT_RING(ring, 0x00000000); /* UNKNOWN_E004 */10501051OUT_PKT4(ring, REG_A5XX_GRAS_SU_LAYERED, 1);1052OUT_RING(ring, 0x00000000); /* GRAS_SU_LAYERED */10531054OUT_PKT4(ring, REG_A5XX_VPC_SO_BUF_CNTL, 1);1055OUT_RING(ring, 0x00000000); /* VPC_SO_BUF_CNTL */10561057OUT_PKT4(ring, REG_A5XX_VPC_SO_BUFFER_OFFSET(0), 1);1058OUT_RING(ring, 0x00000000); /* UNKNOWN_E2AB */10591060OUT_PKT4(ring, REG_A5XX_PC_GS_LAYERED, 1);1061OUT_RING(ring, 0x00000000); /* PC_GS_LAYERED */10621063OUT_PKT4(ring, REG_A5XX_UNKNOWN_E5AB, 1);1064OUT_RING(ring, 0x00000000); /* UNKNOWN_E5AB */10651066OUT_PKT4(ring, REG_A5XX_UNKNOWN_E5C2, 1);1067OUT_RING(ring, 0x00000000); /* UNKNOWN_E5C2 */10681069OUT_PKT4(ring, REG_A5XX_VPC_SO_BUFFER_BASE_LO(1), 3);1070OUT_RING(ring, 0x00000000);1071OUT_RING(ring, 0x00000000);1072OUT_RING(ring, 0x00000000);10731074OUT_PKT4(ring, REG_A5XX_VPC_SO_BUFFER_OFFSET(1), 6);1075OUT_RING(ring, 0x00000000);1076OUT_RING(ring, 0x00000000);1077OUT_RING(ring, 0x00000000);1078OUT_RING(ring, 0x00000000);1079OUT_RING(ring, 0x00000000);1080OUT_RING(ring, 0x00000000);10811082OUT_PKT4(ring, REG_A5XX_VPC_SO_BUFFER_OFFSET(2), 6);1083OUT_RING(ring, 0x00000000);1084OUT_RING(ring, 0x00000000);1085OUT_RING(ring, 0x00000000);1086OUT_RING(ring, 0x00000000);1087OUT_RING(ring, 0x00000000);1088OUT_RING(ring, 0x00000000);10891090OUT_PKT4(ring, REG_A5XX_VPC_SO_BUFFER_OFFSET(3), 3);1091OUT_RING(ring, 0x00000000);1092OUT_RING(ring, 0x00000000);1093OUT_RING(ring, 0x00000000);10941095OUT_PKT4(ring, REG_A5XX_UNKNOWN_E5DB, 1);1096OUT_RING(ring, 0x00000000);10971098OUT_PKT4(ring, REG_A5XX_SP_HS_CTRL_REG0, 1);1099OUT_RING(ring, 0x00000000);11001101OUT_PKT4(ring, REG_A5XX_SP_GS_CTRL_REG0, 1);1102OUT_RING(ring, 0x00000000);11031104OUT_PKT4(ring, REG_A5XX_TPL1_VS_TEX_COUNT, 4);1105OUT_RING(ring, 0x00000000);1106OUT_RING(ring, 0x00000000);1107OUT_RING(ring, 0x00000000);1108OUT_RING(ring, 0x00000000);11091110OUT_PKT4(ring, REG_A5XX_TPL1_FS_TEX_COUNT, 2);1111OUT_RING(ring, 0x00000000);1112OUT_RING(ring, 0x00000000);11131114OUT_PKT4(ring, REG_A5XX_UNKNOWN_E7C0, 3);1115OUT_RING(ring, 0x00000000);1116OUT_RING(ring, 0x00000000);1117OUT_RING(ring, 0x00000000);11181119OUT_PKT4(ring, REG_A5XX_UNKNOWN_E7C5, 3);1120OUT_RING(ring, 0x00000000);1121OUT_RING(ring, 0x00000000);1122OUT_RING(ring, 0x00000000);11231124OUT_PKT4(ring, REG_A5XX_UNKNOWN_E7CA, 3);1125OUT_RING(ring, 0x00000000);1126OUT_RING(ring, 0x00000000);1127OUT_RING(ring, 0x00000000);11281129OUT_PKT4(ring, REG_A5XX_UNKNOWN_E7CF, 3);1130OUT_RING(ring, 0x00000000);1131OUT_RING(ring, 0x00000000);1132OUT_RING(ring, 0x00000000);11331134OUT_PKT4(ring, REG_A5XX_UNKNOWN_E7D4, 3);1135OUT_RING(ring, 0x00000000);1136OUT_RING(ring, 0x00000000);1137OUT_RING(ring, 0x00000000);11381139OUT_PKT4(ring, REG_A5XX_UNKNOWN_E7D9, 3);1140OUT_RING(ring, 0x00000000);1141OUT_RING(ring, 0x00000000);1142OUT_RING(ring, 0x00000000);11431144OUT_PKT4(ring, REG_A5XX_RB_CLEAR_CNTL, 1);1145OUT_RING(ring, 0x00000000);1146}11471148static void1149fd5_mem_to_mem(struct fd_ringbuffer *ring, struct pipe_resource *dst,1150unsigned dst_off, struct pipe_resource *src, unsigned src_off,1151unsigned sizedwords)1152{1153struct fd_bo *src_bo = fd_resource(src)->bo;1154struct fd_bo *dst_bo = fd_resource(dst)->bo;1155unsigned i;11561157for (i = 0; i < sizedwords; i++) {1158OUT_PKT7(ring, CP_MEM_TO_MEM, 5);1159OUT_RING(ring, 0x00000000);1160OUT_RELOC(ring, dst_bo, dst_off, 0, 0);1161OUT_RELOC(ring, src_bo, src_off, 0, 0);11621163dst_off += 4;1164src_off += 4;1165}1166}11671168void1169fd5_emit_init_screen(struct pipe_screen *pscreen)1170{1171struct fd_screen *screen = fd_screen(pscreen);1172screen->emit_ib = fd5_emit_ib;1173screen->mem_to_mem = fd5_mem_to_mem;1174}11751176void1177fd5_emit_init(struct pipe_context *pctx)1178{1179}118011811182