Path: blob/21.2-virgl/src/gallium/drivers/freedreno/a6xx/fd6_emit.h
4574 views
/*1* Copyright (C) 2016 Rob Clark <[email protected]>2* Copyright © 2018 Google, Inc.3*4* Permission is hereby granted, free of charge, to any person obtaining a5* copy of this software and associated documentation files (the "Software"),6* to deal in the Software without restriction, including without limitation7* the rights to use, copy, modify, merge, publish, distribute, sublicense,8* and/or sell copies of the Software, and to permit persons to whom the9* Software is furnished to do so, subject to the following conditions:10*11* The above copyright notice and this permission notice (including the next12* paragraph) shall be included in all copies or substantial portions of the13* Software.14*15* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR16* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,17* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL18* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER19* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,20* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE21* SOFTWARE.22*23* Authors:24* Rob Clark <[email protected]>25*/2627#ifndef FD6_EMIT_H28#define FD6_EMIT_H2930#include "pipe/p_context.h"3132#include "fd6_context.h"33#include "fd6_format.h"34#include "fd6_program.h"35#include "freedreno_context.h"36#include "ir3_gallium.h"3738struct fd_ringbuffer;3940/* To collect all the state objects to emit in a single CP_SET_DRAW_STATE41* packet, the emit tracks a collection of however many state_group's that42* need to be emit'd.43*/44enum fd6_state_id {45FD6_GROUP_PROG_CONFIG,46FD6_GROUP_PROG,47FD6_GROUP_PROG_BINNING,48FD6_GROUP_PROG_INTERP,49FD6_GROUP_PROG_FB_RAST,50FD6_GROUP_LRZ,51FD6_GROUP_LRZ_BINNING,52FD6_GROUP_VTXSTATE,53FD6_GROUP_VBO,54FD6_GROUP_CONST,55FD6_GROUP_VS_DRIVER_PARAMS,56FD6_GROUP_PRIMITIVE_PARAMS,57FD6_GROUP_VS_TEX,58FD6_GROUP_HS_TEX,59FD6_GROUP_DS_TEX,60FD6_GROUP_GS_TEX,61FD6_GROUP_FS_TEX,62FD6_GROUP_RASTERIZER,63FD6_GROUP_ZSA,64FD6_GROUP_BLEND,65FD6_GROUP_SCISSOR,66FD6_GROUP_BLEND_COLOR,67FD6_GROUP_SO,68FD6_GROUP_IBO,69FD6_GROUP_NON_GROUP, /* placeholder group for state emit in IB2, keep last */70};7172#define ENABLE_ALL \73(CP_SET_DRAW_STATE__0_BINNING | CP_SET_DRAW_STATE__0_GMEM | \74CP_SET_DRAW_STATE__0_SYSMEM)75#define ENABLE_DRAW (CP_SET_DRAW_STATE__0_GMEM | CP_SET_DRAW_STATE__0_SYSMEM)7677struct fd6_state_group {78struct fd_ringbuffer *stateobj;79enum fd6_state_id group_id;80/* enable_mask controls which states the stateobj is evaluated in,81* b0 is binning pass b1 and/or b2 is draw pass82*/83uint32_t enable_mask;84};8586/* grouped together emit-state for prog/vertex/state emit: */87struct fd6_emit {88struct fd_context *ctx;89const struct fd_vertex_state *vtx;90const struct pipe_draw_info *info;91unsigned drawid_offset;92const struct pipe_draw_indirect_info *indirect;93const struct pipe_draw_start_count_bias *draw;94struct ir3_cache_key key;95enum fd_dirty_3d_state dirty;96uint32_t dirty_groups;9798uint32_t sprite_coord_enable; /* bitmask */99bool sprite_coord_mode;100bool rasterflat;101bool primitive_restart;102103/* cached to avoid repeated lookups: */104const struct fd6_program_state *prog;105106struct ir3_shader_variant *bs;107struct ir3_shader_variant *vs;108struct ir3_shader_variant *hs;109struct ir3_shader_variant *ds;110struct ir3_shader_variant *gs;111struct ir3_shader_variant *fs;112113unsigned streamout_mask;114115struct fd6_state_group groups[32];116unsigned num_groups;117};118119static inline const struct fd6_program_state *120fd6_emit_get_prog(struct fd6_emit *emit)121{122if (!emit->prog) {123struct ir3_program_state *s = ir3_cache_lookup(124emit->ctx->shader_cache, &emit->key, &emit->ctx->debug);125emit->prog = fd6_program_state(s);126}127return emit->prog;128}129130static inline void131fd6_emit_take_group(struct fd6_emit *emit, struct fd_ringbuffer *stateobj,132enum fd6_state_id group_id, unsigned enable_mask)133{134debug_assert(emit->num_groups < ARRAY_SIZE(emit->groups));135struct fd6_state_group *g = &emit->groups[emit->num_groups++];136g->stateobj = stateobj;137g->group_id = group_id;138g->enable_mask = enable_mask;139}140141static inline void142fd6_emit_add_group(struct fd6_emit *emit, struct fd_ringbuffer *stateobj,143enum fd6_state_id group_id, unsigned enable_mask)144{145fd6_emit_take_group(emit, fd_ringbuffer_ref(stateobj), group_id,146enable_mask);147}148149static inline unsigned150fd6_event_write(struct fd_batch *batch, struct fd_ringbuffer *ring,151enum vgt_event_type evt, bool timestamp)152{153unsigned seqno = 0;154155fd_reset_wfi(batch);156157OUT_PKT7(ring, CP_EVENT_WRITE, timestamp ? 4 : 1);158OUT_RING(ring, CP_EVENT_WRITE_0_EVENT(evt));159if (timestamp) {160struct fd6_context *fd6_ctx = fd6_context(batch->ctx);161seqno = ++fd6_ctx->seqno;162OUT_RELOC(ring, control_ptr(fd6_ctx, seqno)); /* ADDR_LO/HI */163OUT_RING(ring, seqno);164}165166return seqno;167}168169static inline void170fd6_cache_inv(struct fd_batch *batch, struct fd_ringbuffer *ring)171{172fd6_event_write(batch, ring, PC_CCU_INVALIDATE_COLOR, false);173fd6_event_write(batch, ring, PC_CCU_INVALIDATE_DEPTH, false);174fd6_event_write(batch, ring, CACHE_INVALIDATE, false);175}176177static inline void178fd6_cache_flush(struct fd_batch *batch, struct fd_ringbuffer *ring)179{180struct fd6_context *fd6_ctx = fd6_context(batch->ctx);181unsigned seqno;182183seqno = fd6_event_write(batch, ring, RB_DONE_TS, true);184185OUT_PKT7(ring, CP_WAIT_REG_MEM, 6);186OUT_RING(ring, CP_WAIT_REG_MEM_0_FUNCTION(WRITE_EQ) |187CP_WAIT_REG_MEM_0_POLL_MEMORY);188OUT_RELOC(ring, control_ptr(fd6_ctx, seqno));189OUT_RING(ring, CP_WAIT_REG_MEM_3_REF(seqno));190OUT_RING(ring, CP_WAIT_REG_MEM_4_MASK(~0));191OUT_RING(ring, CP_WAIT_REG_MEM_5_DELAY_LOOP_CYCLES(16));192193seqno = fd6_event_write(batch, ring, CACHE_FLUSH_TS, true);194195OUT_PKT7(ring, CP_WAIT_MEM_GTE, 4);196OUT_RING(ring, CP_WAIT_MEM_GTE_0_RESERVED(0));197OUT_RELOC(ring, control_ptr(fd6_ctx, seqno));198OUT_RING(ring, CP_WAIT_MEM_GTE_3_REF(seqno));199}200201static inline void202fd6_emit_blit(struct fd_batch *batch, struct fd_ringbuffer *ring)203{204emit_marker6(ring, 7);205fd6_event_write(batch, ring, BLIT, false);206emit_marker6(ring, 7);207}208209static inline void210fd6_emit_lrz_flush(struct fd_ringbuffer *ring)211{212OUT_PKT7(ring, CP_EVENT_WRITE, 1);213OUT_RING(ring, LRZ_FLUSH);214}215216static inline bool217fd6_geom_stage(gl_shader_stage type)218{219switch (type) {220case MESA_SHADER_VERTEX:221case MESA_SHADER_TESS_CTRL:222case MESA_SHADER_TESS_EVAL:223case MESA_SHADER_GEOMETRY:224return true;225case MESA_SHADER_FRAGMENT:226case MESA_SHADER_COMPUTE:227case MESA_SHADER_KERNEL:228return false;229default:230unreachable("bad shader type");231}232}233234static inline uint32_t235fd6_stage2opcode(gl_shader_stage type)236{237return fd6_geom_stage(type) ? CP_LOAD_STATE6_GEOM : CP_LOAD_STATE6_FRAG;238}239240static inline enum a6xx_state_block241fd6_stage2shadersb(gl_shader_stage type)242{243switch (type) {244case MESA_SHADER_VERTEX:245return SB6_VS_SHADER;246case MESA_SHADER_TESS_CTRL:247return SB6_HS_SHADER;248case MESA_SHADER_TESS_EVAL:249return SB6_DS_SHADER;250case MESA_SHADER_GEOMETRY:251return SB6_GS_SHADER;252case MESA_SHADER_FRAGMENT:253return SB6_FS_SHADER;254case MESA_SHADER_COMPUTE:255case MESA_SHADER_KERNEL:256return SB6_CS_SHADER;257default:258unreachable("bad shader type");259return ~0;260}261}262263static inline enum a6xx_tess_spacing264fd6_gl2spacing(enum gl_tess_spacing spacing)265{266switch (spacing) {267case TESS_SPACING_EQUAL:268return TESS_EQUAL;269case TESS_SPACING_FRACTIONAL_ODD:270return TESS_FRACTIONAL_ODD;271case TESS_SPACING_FRACTIONAL_EVEN:272return TESS_FRACTIONAL_EVEN;273case TESS_SPACING_UNSPECIFIED:274default:275unreachable("spacing must be specified");276}277}278279bool fd6_emit_textures(struct fd_context *ctx, struct fd_ringbuffer *ring,280enum pipe_shader_type type,281struct fd_texture_stateobj *tex, unsigned bcolor_offset,282const struct ir3_shader_variant *v) assert_dt;283284void fd6_emit_state(struct fd_ringbuffer *ring,285struct fd6_emit *emit) assert_dt;286287void fd6_emit_cs_state(struct fd_context *ctx, struct fd_ringbuffer *ring,288struct ir3_shader_variant *cp) assert_dt;289290void fd6_emit_restore(struct fd_batch *batch, struct fd_ringbuffer *ring);291292void fd6_emit_init_screen(struct pipe_screen *pscreen);293void fd6_emit_init(struct pipe_context *pctx);294295static inline void296fd6_emit_ib(struct fd_ringbuffer *ring, struct fd_ringbuffer *target)297{298emit_marker6(ring, 6);299__OUT_IB5(ring, target);300emit_marker6(ring, 6);301}302303#define WRITE(reg, val) \304do { \305OUT_PKT4(ring, reg, 1); \306OUT_RING(ring, val); \307} while (0)308309#endif /* FD6_EMIT_H */310311312