src/gallium/auxiliary/pipe-loader/Makefile
src/gallium/drivers/Makefile
src/gallium/drivers/freedreno/Makefile
+ src/gallium/drivers/freedreno/a2xx/Makefile
src/gallium/drivers/i915/Makefile
src/gallium/drivers/ilo/Makefile
src/gallium/drivers/llvmpipe/Makefile
AM_CFLAGS = \
-Wno-packed-bitfield-compat \
-I$(top_srcdir)/src/gallium/drivers \
+ -I$(top_srcdir)/src/gallium/drivers/freedreno/a2xx \
$(GALLIUM_CFLAGS) \
$(FREEDRENO_CFLAGS) \
- $(PIC_FLAGS) \
$(VISIBILITY_CFLAGS)
+SUBDIRS = a2xx
+
libfreedreno_la_SOURCES = \
freedreno_util.c \
freedreno_fence.c \
freedreno_resource.c \
freedreno_surface.c \
- freedreno_vbo.c \
- freedreno_blend.c \
- freedreno_rasterizer.c \
- freedreno_zsa.c \
+ freedreno_draw.c \
freedreno_state.c \
- freedreno_clear.c \
- freedreno_program.c \
freedreno_texture.c \
freedreno_context.c \
freedreno_screen.c \
- freedreno_gmem.c \
- freedreno_compiler.c \
- ir-a2xx.c \
- disasm.c
+ freedreno_gmem.c
+
+libfreedreno_la_LIBADD = \
+ a2xx/libfd2xx.la
+++ /dev/null
-#ifndef A2XX_XML
-#define A2XX_XML
-
-/* Autogenerated file, DO NOT EDIT manually!
-
-This file was generated by the rules-ng-ng headergen tool in this git repository:
-http://0x04.net/cgit/index.cgi/rules-ng-ng
-git clone git://0x04.net/rules-ng-ng
-
-The rules-ng-ng source files this header was generated from are:
-- /home/robclark/src/freedreno/envytools/rnndb/a2xx.xml ( 30372 bytes, from 2013-04-05 17:32:29)
-- /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1453 bytes, from 2013-03-31 16:51:27)
-- /home/robclark/src/freedreno/envytools/rnndb/adreno_common.xml ( 2972 bytes, from 2013-04-05 17:32:38)
-- /home/robclark/src/freedreno/envytools/rnndb/adreno_pm4.xml ( 7736 bytes, from 2013-04-04 20:24:12)
-
-Copyright (C) 2013 by the following authors:
-- Rob Clark <robdclark@gmail.com> (robclark)
-
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the
-"Software"), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice (including the
-next paragraph) shall be included in all copies or substantial
-portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
-LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-*/
-
-
-enum a2xx_rb_dither_type {
- DITHER_PIXEL = 0,
- DITHER_SUBPIXEL = 1,
-};
-
-enum a2xx_colorformatx {
- COLORX_4_4_4_4 = 0,
- COLORX_1_5_5_5 = 1,
- COLORX_5_6_5 = 2,
- COLORX_8 = 3,
- COLORX_8_8 = 4,
- COLORX_8_8_8_8 = 5,
- COLORX_S8_8_8_8 = 6,
- COLORX_16_FLOAT = 7,
- COLORX_16_16_FLOAT = 8,
- COLORX_16_16_16_16_FLOAT = 9,
- COLORX_32_FLOAT = 10,
- COLORX_32_32_FLOAT = 11,
- COLORX_32_32_32_32_FLOAT = 12,
- COLORX_2_3_3 = 13,
- COLORX_8_8_8 = 14,
- COLORX_INVALID = 15,
-};
-
-enum a2xx_sq_surfaceformat {
- FMT_1_REVERSE = 0,
- FMT_1 = 1,
- FMT_8 = 2,
- FMT_1_5_5_5 = 3,
- FMT_5_6_5 = 4,
- FMT_6_5_5 = 5,
- FMT_8_8_8_8 = 6,
- FMT_2_10_10_10 = 7,
- FMT_8_A = 8,
- FMT_8_B = 9,
- FMT_8_8 = 10,
- FMT_Cr_Y1_Cb_Y0 = 11,
- FMT_Y1_Cr_Y0_Cb = 12,
- FMT_5_5_5_1 = 13,
- FMT_8_8_8_8_A = 14,
- FMT_4_4_4_4 = 15,
- FMT_10_11_11 = 16,
- FMT_11_11_10 = 17,
- FMT_DXT1 = 18,
- FMT_DXT2_3 = 19,
- FMT_DXT4_5 = 20,
- FMT_24_8 = 22,
- FMT_24_8_FLOAT = 23,
- FMT_16 = 24,
- FMT_16_16 = 25,
- FMT_16_16_16_16 = 26,
- FMT_16_EXPAND = 27,
- FMT_16_16_EXPAND = 28,
- FMT_16_16_16_16_EXPAND = 29,
- FMT_16_FLOAT = 30,
- FMT_16_16_FLOAT = 31,
- FMT_16_16_16_16_FLOAT = 32,
- FMT_32 = 33,
- FMT_32_32 = 34,
- FMT_32_32_32_32 = 35,
- FMT_32_FLOAT = 36,
- FMT_32_32_FLOAT = 37,
- FMT_32_32_32_32_FLOAT = 38,
- FMT_32_AS_8 = 39,
- FMT_32_AS_8_8 = 40,
- FMT_16_MPEG = 41,
- FMT_16_16_MPEG = 42,
- FMT_8_INTERLACED = 43,
- FMT_32_AS_8_INTERLACED = 44,
- FMT_32_AS_8_8_INTERLACED = 45,
- FMT_16_INTERLACED = 46,
- FMT_16_MPEG_INTERLACED = 47,
- FMT_16_16_MPEG_INTERLACED = 48,
- FMT_DXN = 49,
- FMT_8_8_8_8_AS_16_16_16_16 = 50,
- FMT_DXT1_AS_16_16_16_16 = 51,
- FMT_DXT2_3_AS_16_16_16_16 = 52,
- FMT_DXT4_5_AS_16_16_16_16 = 53,
- FMT_2_10_10_10_AS_16_16_16_16 = 54,
- FMT_10_11_11_AS_16_16_16_16 = 55,
- FMT_11_11_10_AS_16_16_16_16 = 56,
- FMT_32_32_32_FLOAT = 57,
- FMT_DXT3A = 58,
- FMT_DXT5A = 59,
- FMT_CTX1 = 60,
- FMT_DXT3A_AS_1_1_1_1 = 61,
- FMT_INVALID = 62,
-};
-
-enum a2xx_rb_depth_format {
- DEPTHX_16 = 0,
- DEPTHX_24_8 = 1,
- DEPTHX_INVALID = 2,
-};
-
-enum a2xx_sq_ps_vtx_mode {
- POSITION_1_VECTOR = 0,
- POSITION_2_VECTORS_UNUSED = 1,
- POSITION_2_VECTORS_SPRITE = 2,
- POSITION_2_VECTORS_EDGE = 3,
- POSITION_2_VECTORS_KILL = 4,
- POSITION_2_VECTORS_SPRITE_KILL = 5,
- POSITION_2_VECTORS_EDGE_KILL = 6,
- MULTIPASS = 7,
-};
-
-enum a2xx_sq_sample_cntl {
- CENTROIDS_ONLY = 0,
- CENTERS_ONLY = 1,
- CENTROIDS_AND_CENTERS = 2,
-};
-
-enum a2xx_dx_clip_space {
- DXCLIP_OPENGL = 0,
- DXCLIP_DIRECTX = 1,
-};
-
-enum a2xx_pa_su_sc_polymode {
- POLY_DISABLED = 0,
- POLY_DUALMODE = 1,
-};
-
-enum a2xx_rb_edram_mode {
- EDRAM_NOP = 0,
- COLOR_DEPTH = 4,
- DEPTH_ONLY = 5,
- EDRAM_COPY = 6,
-};
-
-enum a2xx_pa_sc_pattern_bit_order {
- LITTLE = 0,
- BIG = 1,
-};
-
-enum a2xx_pa_sc_auto_reset_cntl {
- NEVER = 0,
- EACH_PRIMITIVE = 1,
- EACH_PACKET = 2,
-};
-
-enum a2xx_pa_pixcenter {
- PIXCENTER_D3D = 0,
- PIXCENTER_OGL = 1,
-};
-
-enum a2xx_pa_roundmode {
- TRUNCATE = 0,
- ROUND = 1,
- ROUNDTOEVEN = 2,
- ROUNDTOODD = 3,
-};
-
-enum a2xx_pa_quantmode {
- ONE_SIXTEENTH = 0,
- ONE_EIGTH = 1,
- ONE_QUARTER = 2,
- ONE_HALF = 3,
- ONE = 4,
-};
-
-enum a2xx_rb_copy_sample_select {
- SAMPLE_0 = 0,
- SAMPLE_1 = 1,
- SAMPLE_2 = 2,
- SAMPLE_3 = 3,
- SAMPLE_01 = 4,
- SAMPLE_23 = 5,
- SAMPLE_0123 = 6,
-};
-
-enum sq_tex_clamp {
- SQ_TEX_WRAP = 0,
- SQ_TEX_MIRROR = 1,
- SQ_TEX_CLAMP_LAST_TEXEL = 2,
- SQ_TEX_MIRROR_ONCE_LAST_TEXEL = 3,
- SQ_TEX_CLAMP_HALF_BORDER = 4,
- SQ_TEX_MIRROR_ONCE_HALF_BORDER = 5,
- SQ_TEX_CLAMP_BORDER = 6,
- SQ_TEX_MIRROR_ONCE_BORDER = 7,
-};
-
-enum sq_tex_swiz {
- SQ_TEX_X = 0,
- SQ_TEX_Y = 1,
- SQ_TEX_Z = 2,
- SQ_TEX_W = 3,
- SQ_TEX_ZERO = 4,
- SQ_TEX_ONE = 5,
-};
-
-enum sq_tex_filter {
- SQ_TEX_FILTER_POINT = 0,
- SQ_TEX_FILTER_BILINEAR = 1,
- SQ_TEX_FILTER_BICUBIC = 2,
-};
-
-#define REG_A2XX_RBBM_PATCH_RELEASE 0x00000001
-
-#define REG_A2XX_RBBM_CNTL 0x0000003b
-
-#define REG_A2XX_RBBM_SOFT_RESET 0x0000003c
-
-#define REG_A2XX_CP_PFP_UCODE_ADDR 0x000000c0
-
-#define REG_A2XX_CP_PFP_UCODE_DATA 0x000000c1
-
-#define REG_A2XX_CP_RB_BASE 0x000001c0
-
-#define REG_A2XX_CP_RB_CNTL 0x000001c1
-
-#define REG_A2XX_CP_RB_RPTR_ADDR 0x000001c3
-
-#define REG_A2XX_CP_RB_RPTR 0x000001c4
-
-#define REG_A2XX_CP_RB_WPTR 0x000001c5
-
-#define REG_A2XX_CP_RB_WPTR_DELAY 0x000001c6
-
-#define REG_A2XX_CP_RB_RPTR_WR 0x000001c7
-
-#define REG_A2XX_CP_RB_WPTR_BASE 0x000001c8
-
-#define REG_A2XX_CP_QUEUE_THRESHOLDS 0x000001d5
-
-#define REG_A2XX_SCRATCH_UMSK 0x000001dc
-
-#define REG_A2XX_SCRATCH_ADDR 0x000001dd
-
-#define REG_A2XX_CP_STATE_DEBUG_INDEX 0x000001ec
-
-#define REG_A2XX_CP_STATE_DEBUG_DATA 0x000001ed
-
-#define REG_A2XX_CP_INT_CNTL 0x000001f2
-
-#define REG_A2XX_CP_INT_STATUS 0x000001f3
-
-#define REG_A2XX_CP_INT_ACK 0x000001f4
-
-#define REG_A2XX_CP_ME_CNTL 0x000001f6
-
-#define REG_A2XX_CP_ME_STATUS 0x000001f7
-
-#define REG_A2XX_CP_ME_RAM_WADDR 0x000001f8
-
-#define REG_A2XX_CP_ME_RAM_RADDR 0x000001f9
-
-#define REG_A2XX_CP_ME_RAM_DATA 0x000001fa
-
-#define REG_A2XX_CP_DEBUG 0x000001fc
-
-#define REG_A2XX_CP_CSQ_RB_STAT 0x000001fd
-
-#define REG_A2XX_CP_CSQ_IB1_STAT 0x000001fe
-
-#define REG_A2XX_CP_CSQ_IB2_STAT 0x000001ff
-
-#define REG_A2XX_RBBM_PERFCOUNTER1_SELECT 0x00000395
-
-#define REG_A2XX_RBBM_PERFCOUNTER1_LO 0x00000397
-
-#define REG_A2XX_RBBM_PERFCOUNTER1_HI 0x00000398
-
-#define REG_A2XX_RBBM_DEBUG 0x0000039b
-
-#define REG_A2XX_RBBM_PM_OVERRIDE1 0x0000039c
-
-#define REG_A2XX_RBBM_PM_OVERRIDE2 0x0000039d
-
-#define REG_A2XX_RBBM_DEBUG_OUT 0x000003a0
-
-#define REG_A2XX_RBBM_DEBUG_CNTL 0x000003a1
-
-#define REG_A2XX_RBBM_READ_ERROR 0x000003b3
-
-#define REG_A2XX_RBBM_INT_CNTL 0x000003b4
-
-#define REG_A2XX_RBBM_INT_STATUS 0x000003b5
-
-#define REG_A2XX_RBBM_INT_ACK 0x000003b6
-
-#define REG_A2XX_MASTER_INT_SIGNAL 0x000003b7
-
-#define REG_A2XX_RBBM_PERIPHID1 0x000003f9
-
-#define REG_A2XX_RBBM_PERIPHID2 0x000003fa
-
-#define REG_A2XX_CP_PERFMON_CNTL 0x00000444
-
-#define REG_A2XX_CP_PERFCOUNTER_SELECT 0x00000445
-
-#define REG_A2XX_CP_PERFCOUNTER_LO 0x00000446
-
-#define REG_A2XX_CP_PERFCOUNTER_HI 0x00000447
-
-#define REG_A2XX_CP_ST_BASE 0x0000044d
-
-#define REG_A2XX_CP_ST_BUFSZ 0x0000044e
-
-#define REG_A2XX_CP_IB1_BASE 0x00000458
-
-#define REG_A2XX_CP_IB1_BUFSZ 0x00000459
-
-#define REG_A2XX_CP_IB2_BASE 0x0000045a
-
-#define REG_A2XX_CP_IB2_BUFSZ 0x0000045b
-
-#define REG_A2XX_CP_STAT 0x0000047f
-
-#define REG_A2XX_SCRATCH_REG0 0x00000578
-
-#define REG_A2XX_SCRATCH_REG2 0x0000057a
-
-#define REG_A2XX_RBBM_STATUS 0x000005d0
-
-#define REG_A2XX_A220_VSC_BIN_SIZE 0x00000c01
-#define A2XX_A220_VSC_BIN_SIZE_WIDTH__MASK 0x0000001f
-#define A2XX_A220_VSC_BIN_SIZE_WIDTH__SHIFT 0
-static inline uint32_t A2XX_A220_VSC_BIN_SIZE_WIDTH(uint32_t val)
-{
- return ((val >> 5) << A2XX_A220_VSC_BIN_SIZE_WIDTH__SHIFT) & A2XX_A220_VSC_BIN_SIZE_WIDTH__MASK;
-}
-#define A2XX_A220_VSC_BIN_SIZE_HEIGHT__MASK 0x000003e0
-#define A2XX_A220_VSC_BIN_SIZE_HEIGHT__SHIFT 5
-static inline uint32_t A2XX_A220_VSC_BIN_SIZE_HEIGHT(uint32_t val)
-{
- return ((val >> 5) << A2XX_A220_VSC_BIN_SIZE_HEIGHT__SHIFT) & A2XX_A220_VSC_BIN_SIZE_HEIGHT__MASK;
-}
-
-#define REG_A2XX_VSC_PIPE(i0) (0x00000c06 + 0x3*(i0))
-
-#define REG_A2XX_VSC_PIPE_CONFIG(i0) (0x00000c06 + 0x3*(i0))
-
-#define REG_A2XX_VSC_PIPE_DATA_ADDRESS(i0) (0x00000c07 + 0x3*(i0))
-
-#define REG_A2XX_VSC_PIPE_DATA_LENGTH(i0) (0x00000c08 + 0x3*(i0))
-
-#define REG_A2XX_PC_DEBUG_CNTL 0x00000c38
-
-#define REG_A2XX_PC_DEBUG_DATA 0x00000c39
-
-#define REG_A2XX_PA_SC_VIZ_QUERY_STATUS 0x00000c44
-
-#define REG_A2XX_GRAS_DEBUG_CNTL 0x00000c80
-
-#define REG_A2XX_PA_SU_DEBUG_CNTL 0x00000c80
-
-#define REG_A2XX_GRAS_DEBUG_DATA 0x00000c81
-
-#define REG_A2XX_PA_SU_DEBUG_DATA 0x00000c81
-
-#define REG_A2XX_PA_SU_FACE_DATA 0x00000c86
-
-#define REG_A2XX_SQ_GPR_MANAGEMENT 0x00000d00
-
-#define REG_A2XX_SQ_FLOW_CONTROL 0x00000d01
-
-#define REG_A2XX_SQ_INST_STORE_MANAGMENT 0x00000d02
-
-#define REG_A2XX_SQ_DEBUG_MISC 0x00000d05
-
-#define REG_A2XX_SQ_INT_CNTL 0x00000d34
-
-#define REG_A2XX_SQ_INT_STATUS 0x00000d35
-
-#define REG_A2XX_SQ_INT_ACK 0x00000d36
-
-#define REG_A2XX_SQ_DEBUG_INPUT_FSM 0x00000dae
-
-#define REG_A2XX_SQ_DEBUG_CONST_MGR_FSM 0x00000daf
-
-#define REG_A2XX_SQ_DEBUG_TP_FSM 0x00000db0
-
-#define REG_A2XX_SQ_DEBUG_FSM_ALU_0 0x00000db1
-
-#define REG_A2XX_SQ_DEBUG_FSM_ALU_1 0x00000db2
-
-#define REG_A2XX_SQ_DEBUG_EXP_ALLOC 0x00000db3
-
-#define REG_A2XX_SQ_DEBUG_PTR_BUFF 0x00000db4
-
-#define REG_A2XX_SQ_DEBUG_GPR_VTX 0x00000db5
-
-#define REG_A2XX_SQ_DEBUG_GPR_PIX 0x00000db6
-
-#define REG_A2XX_SQ_DEBUG_TB_STATUS_SEL 0x00000db7
-
-#define REG_A2XX_SQ_DEBUG_VTX_TB_0 0x00000db8
-
-#define REG_A2XX_SQ_DEBUG_VTX_TB_1 0x00000db9
-
-#define REG_A2XX_SQ_DEBUG_VTX_TB_STATUS_REG 0x00000dba
-
-#define REG_A2XX_SQ_DEBUG_VTX_TB_STATE_MEM 0x00000dbb
-
-#define REG_A2XX_SQ_DEBUG_PIX_TB_0 0x00000dbc
-
-#define REG_A2XX_SQ_DEBUG_PIX_TB_STATUS_REG_0 0x00000dbd
-
-#define REG_A2XX_SQ_DEBUG_PIX_TB_STATUS_REG_1 0x00000dbe
-
-#define REG_A2XX_SQ_DEBUG_PIX_TB_STATUS_REG_2 0x00000dbf
-
-#define REG_A2XX_SQ_DEBUG_PIX_TB_STATUS_REG_3 0x00000dc0
-
-#define REG_A2XX_SQ_DEBUG_PIX_TB_STATE_MEM 0x00000dc1
-
-#define REG_A2XX_TC_CNTL_STATUS 0x00000e00
-#define A2XX_TC_CNTL_STATUS_L2_INVALIDATE 0x00000001
-
-#define REG_A2XX_TP0_CHICKEN 0x00000e1e
-
-#define REG_A2XX_RB_BC_CONTROL 0x00000f01
-#define A2XX_RB_BC_CONTROL_ACCUM_LINEAR_MODE_ENABLE 0x00000001
-#define A2XX_RB_BC_CONTROL_ACCUM_TIMEOUT_SELECT__MASK 0x00000006
-#define A2XX_RB_BC_CONTROL_ACCUM_TIMEOUT_SELECT__SHIFT 1
-static inline uint32_t A2XX_RB_BC_CONTROL_ACCUM_TIMEOUT_SELECT(uint32_t val)
-{
- return ((val) << A2XX_RB_BC_CONTROL_ACCUM_TIMEOUT_SELECT__SHIFT) & A2XX_RB_BC_CONTROL_ACCUM_TIMEOUT_SELECT__MASK;
-}
-#define A2XX_RB_BC_CONTROL_DISABLE_EDRAM_CAM 0x00000008
-#define A2XX_RB_BC_CONTROL_DISABLE_EZ_FAST_CONTEXT_SWITCH 0x00000010
-#define A2XX_RB_BC_CONTROL_DISABLE_EZ_NULL_ZCMD_DROP 0x00000020
-#define A2XX_RB_BC_CONTROL_DISABLE_LZ_NULL_ZCMD_DROP 0x00000040
-#define A2XX_RB_BC_CONTROL_ENABLE_AZ_THROTTLE 0x00000080
-#define A2XX_RB_BC_CONTROL_AZ_THROTTLE_COUNT__MASK 0x00001f00
-#define A2XX_RB_BC_CONTROL_AZ_THROTTLE_COUNT__SHIFT 8
-static inline uint32_t A2XX_RB_BC_CONTROL_AZ_THROTTLE_COUNT(uint32_t val)
-{
- return ((val) << A2XX_RB_BC_CONTROL_AZ_THROTTLE_COUNT__SHIFT) & A2XX_RB_BC_CONTROL_AZ_THROTTLE_COUNT__MASK;
-}
-#define A2XX_RB_BC_CONTROL_ENABLE_CRC_UPDATE 0x00004000
-#define A2XX_RB_BC_CONTROL_CRC_MODE 0x00008000
-#define A2XX_RB_BC_CONTROL_DISABLE_SAMPLE_COUNTERS 0x00010000
-#define A2XX_RB_BC_CONTROL_DISABLE_ACCUM 0x00020000
-#define A2XX_RB_BC_CONTROL_ACCUM_ALLOC_MASK__MASK 0x003c0000
-#define A2XX_RB_BC_CONTROL_ACCUM_ALLOC_MASK__SHIFT 18
-static inline uint32_t A2XX_RB_BC_CONTROL_ACCUM_ALLOC_MASK(uint32_t val)
-{
- return ((val) << A2XX_RB_BC_CONTROL_ACCUM_ALLOC_MASK__SHIFT) & A2XX_RB_BC_CONTROL_ACCUM_ALLOC_MASK__MASK;
-}
-#define A2XX_RB_BC_CONTROL_LINEAR_PERFORMANCE_ENABLE 0x00400000
-#define A2XX_RB_BC_CONTROL_ACCUM_DATA_FIFO_LIMIT__MASK 0x07800000
-#define A2XX_RB_BC_CONTROL_ACCUM_DATA_FIFO_LIMIT__SHIFT 23
-static inline uint32_t A2XX_RB_BC_CONTROL_ACCUM_DATA_FIFO_LIMIT(uint32_t val)
-{
- return ((val) << A2XX_RB_BC_CONTROL_ACCUM_DATA_FIFO_LIMIT__SHIFT) & A2XX_RB_BC_CONTROL_ACCUM_DATA_FIFO_LIMIT__MASK;
-}
-#define A2XX_RB_BC_CONTROL_MEM_EXPORT_TIMEOUT_SELECT__MASK 0x18000000
-#define A2XX_RB_BC_CONTROL_MEM_EXPORT_TIMEOUT_SELECT__SHIFT 27
-static inline uint32_t A2XX_RB_BC_CONTROL_MEM_EXPORT_TIMEOUT_SELECT(uint32_t val)
-{
- return ((val) << A2XX_RB_BC_CONTROL_MEM_EXPORT_TIMEOUT_SELECT__SHIFT) & A2XX_RB_BC_CONTROL_MEM_EXPORT_TIMEOUT_SELECT__MASK;
-}
-#define A2XX_RB_BC_CONTROL_MEM_EXPORT_LINEAR_MODE_ENABLE 0x20000000
-#define A2XX_RB_BC_CONTROL_CRC_SYSTEM 0x40000000
-#define A2XX_RB_BC_CONTROL_RESERVED6 0x80000000
-
-#define REG_A2XX_RB_EDRAM_INFO 0x00000f02
-
-#define REG_A2XX_RB_DEBUG_CNTL 0x00000f26
-
-#define REG_A2XX_RB_DEBUG_DATA 0x00000f27
-
-#define REG_A2XX_RB_SURFACE_INFO 0x00002000
-
-#define REG_A2XX_RB_COLOR_INFO 0x00002001
-#define A2XX_RB_COLOR_INFO_FORMAT__MASK 0x0000000f
-#define A2XX_RB_COLOR_INFO_FORMAT__SHIFT 0
-static inline uint32_t A2XX_RB_COLOR_INFO_FORMAT(enum a2xx_colorformatx val)
-{
- return ((val) << A2XX_RB_COLOR_INFO_FORMAT__SHIFT) & A2XX_RB_COLOR_INFO_FORMAT__MASK;
-}
-#define A2XX_RB_COLOR_INFO_ROUND_MODE__MASK 0x00000030
-#define A2XX_RB_COLOR_INFO_ROUND_MODE__SHIFT 4
-static inline uint32_t A2XX_RB_COLOR_INFO_ROUND_MODE(uint32_t val)
-{
- return ((val) << A2XX_RB_COLOR_INFO_ROUND_MODE__SHIFT) & A2XX_RB_COLOR_INFO_ROUND_MODE__MASK;
-}
-#define A2XX_RB_COLOR_INFO_LINEAR 0x00000040
-#define A2XX_RB_COLOR_INFO_ENDIAN__MASK 0x00000180
-#define A2XX_RB_COLOR_INFO_ENDIAN__SHIFT 7
-static inline uint32_t A2XX_RB_COLOR_INFO_ENDIAN(uint32_t val)
-{
- return ((val) << A2XX_RB_COLOR_INFO_ENDIAN__SHIFT) & A2XX_RB_COLOR_INFO_ENDIAN__MASK;
-}
-#define A2XX_RB_COLOR_INFO_SWAP__MASK 0x00000600
-#define A2XX_RB_COLOR_INFO_SWAP__SHIFT 9
-static inline uint32_t A2XX_RB_COLOR_INFO_SWAP(uint32_t val)
-{
- return ((val) << A2XX_RB_COLOR_INFO_SWAP__SHIFT) & A2XX_RB_COLOR_INFO_SWAP__MASK;
-}
-#define A2XX_RB_COLOR_INFO_BASE__MASK 0xfffff000
-#define A2XX_RB_COLOR_INFO_BASE__SHIFT 12
-static inline uint32_t A2XX_RB_COLOR_INFO_BASE(uint32_t val)
-{
- return ((val >> 10) << A2XX_RB_COLOR_INFO_BASE__SHIFT) & A2XX_RB_COLOR_INFO_BASE__MASK;
-}
-
-#define REG_A2XX_RB_DEPTH_INFO 0x00002002
-#define A2XX_RB_DEPTH_INFO_DEPTH_FORMAT__MASK 0x00000001
-#define A2XX_RB_DEPTH_INFO_DEPTH_FORMAT__SHIFT 0
-static inline uint32_t A2XX_RB_DEPTH_INFO_DEPTH_FORMAT(enum a2xx_rb_depth_format val)
-{
- return ((val) << A2XX_RB_DEPTH_INFO_DEPTH_FORMAT__SHIFT) & A2XX_RB_DEPTH_INFO_DEPTH_FORMAT__MASK;
-}
-#define A2XX_RB_DEPTH_INFO_DEPTH_BASE__MASK 0xfffff000
-#define A2XX_RB_DEPTH_INFO_DEPTH_BASE__SHIFT 12
-static inline uint32_t A2XX_RB_DEPTH_INFO_DEPTH_BASE(uint32_t val)
-{
- return ((val >> 10) << A2XX_RB_DEPTH_INFO_DEPTH_BASE__SHIFT) & A2XX_RB_DEPTH_INFO_DEPTH_BASE__MASK;
-}
-
-#define REG_A2XX_A225_RB_COLOR_INFO3 0x00002005
-
-#define REG_A2XX_COHER_DEST_BASE_0 0x00002006
-
-#define REG_A2XX_PA_SC_SCREEN_SCISSOR_TL 0x0000200e
-#define A2XX_PA_SC_SCREEN_SCISSOR_TL_WINDOW_OFFSET_DISABLE 0x80000000
-#define A2XX_PA_SC_SCREEN_SCISSOR_TL_X__MASK 0x00007fff
-#define A2XX_PA_SC_SCREEN_SCISSOR_TL_X__SHIFT 0
-static inline uint32_t A2XX_PA_SC_SCREEN_SCISSOR_TL_X(uint32_t val)
-{
- return ((val) << A2XX_PA_SC_SCREEN_SCISSOR_TL_X__SHIFT) & A2XX_PA_SC_SCREEN_SCISSOR_TL_X__MASK;
-}
-#define A2XX_PA_SC_SCREEN_SCISSOR_TL_Y__MASK 0x7fff0000
-#define A2XX_PA_SC_SCREEN_SCISSOR_TL_Y__SHIFT 16
-static inline uint32_t A2XX_PA_SC_SCREEN_SCISSOR_TL_Y(uint32_t val)
-{
- return ((val) << A2XX_PA_SC_SCREEN_SCISSOR_TL_Y__SHIFT) & A2XX_PA_SC_SCREEN_SCISSOR_TL_Y__MASK;
-}
-
-#define REG_A2XX_PA_SC_SCREEN_SCISSOR_BR 0x0000200f
-#define A2XX_PA_SC_SCREEN_SCISSOR_BR_WINDOW_OFFSET_DISABLE 0x80000000
-#define A2XX_PA_SC_SCREEN_SCISSOR_BR_X__MASK 0x00007fff
-#define A2XX_PA_SC_SCREEN_SCISSOR_BR_X__SHIFT 0
-static inline uint32_t A2XX_PA_SC_SCREEN_SCISSOR_BR_X(uint32_t val)
-{
- return ((val) << A2XX_PA_SC_SCREEN_SCISSOR_BR_X__SHIFT) & A2XX_PA_SC_SCREEN_SCISSOR_BR_X__MASK;
-}
-#define A2XX_PA_SC_SCREEN_SCISSOR_BR_Y__MASK 0x7fff0000
-#define A2XX_PA_SC_SCREEN_SCISSOR_BR_Y__SHIFT 16
-static inline uint32_t A2XX_PA_SC_SCREEN_SCISSOR_BR_Y(uint32_t val)
-{
- return ((val) << A2XX_PA_SC_SCREEN_SCISSOR_BR_Y__SHIFT) & A2XX_PA_SC_SCREEN_SCISSOR_BR_Y__MASK;
-}
-
-#define REG_A2XX_PA_SC_WINDOW_OFFSET 0x00002080
-#define A2XX_PA_SC_WINDOW_OFFSET_X__MASK 0x00007fff
-#define A2XX_PA_SC_WINDOW_OFFSET_X__SHIFT 0
-static inline uint32_t A2XX_PA_SC_WINDOW_OFFSET_X(uint32_t val)
-{
- return ((val) << A2XX_PA_SC_WINDOW_OFFSET_X__SHIFT) & A2XX_PA_SC_WINDOW_OFFSET_X__MASK;
-}
-#define A2XX_PA_SC_WINDOW_OFFSET_Y__MASK 0x7fff0000
-#define A2XX_PA_SC_WINDOW_OFFSET_Y__SHIFT 16
-static inline uint32_t A2XX_PA_SC_WINDOW_OFFSET_Y(uint32_t val)
-{
- return ((val) << A2XX_PA_SC_WINDOW_OFFSET_Y__SHIFT) & A2XX_PA_SC_WINDOW_OFFSET_Y__MASK;
-}
-#define A2XX_PA_SC_WINDOW_OFFSET_DISABLE 0x80000000
-
-#define REG_A2XX_PA_SC_WINDOW_SCISSOR_TL 0x00002081
-#define A2XX_PA_SC_WINDOW_SCISSOR_TL_WINDOW_OFFSET_DISABLE 0x80000000
-#define A2XX_PA_SC_WINDOW_SCISSOR_TL_X__MASK 0x00007fff
-#define A2XX_PA_SC_WINDOW_SCISSOR_TL_X__SHIFT 0
-static inline uint32_t A2XX_PA_SC_WINDOW_SCISSOR_TL_X(uint32_t val)
-{
- return ((val) << A2XX_PA_SC_WINDOW_SCISSOR_TL_X__SHIFT) & A2XX_PA_SC_WINDOW_SCISSOR_TL_X__MASK;
-}
-#define A2XX_PA_SC_WINDOW_SCISSOR_TL_Y__MASK 0x7fff0000
-#define A2XX_PA_SC_WINDOW_SCISSOR_TL_Y__SHIFT 16
-static inline uint32_t A2XX_PA_SC_WINDOW_SCISSOR_TL_Y(uint32_t val)
-{
- return ((val) << A2XX_PA_SC_WINDOW_SCISSOR_TL_Y__SHIFT) & A2XX_PA_SC_WINDOW_SCISSOR_TL_Y__MASK;
-}
-
-#define REG_A2XX_PA_SC_WINDOW_SCISSOR_BR 0x00002082
-#define A2XX_PA_SC_WINDOW_SCISSOR_BR_WINDOW_OFFSET_DISABLE 0x80000000
-#define A2XX_PA_SC_WINDOW_SCISSOR_BR_X__MASK 0x00007fff
-#define A2XX_PA_SC_WINDOW_SCISSOR_BR_X__SHIFT 0
-static inline uint32_t A2XX_PA_SC_WINDOW_SCISSOR_BR_X(uint32_t val)
-{
- return ((val) << A2XX_PA_SC_WINDOW_SCISSOR_BR_X__SHIFT) & A2XX_PA_SC_WINDOW_SCISSOR_BR_X__MASK;
-}
-#define A2XX_PA_SC_WINDOW_SCISSOR_BR_Y__MASK 0x7fff0000
-#define A2XX_PA_SC_WINDOW_SCISSOR_BR_Y__SHIFT 16
-static inline uint32_t A2XX_PA_SC_WINDOW_SCISSOR_BR_Y(uint32_t val)
-{
- return ((val) << A2XX_PA_SC_WINDOW_SCISSOR_BR_Y__SHIFT) & A2XX_PA_SC_WINDOW_SCISSOR_BR_Y__MASK;
-}
-
-#define REG_A2XX_UNKNOWN_2010 0x00002010
-
-#define REG_A2XX_VGT_MAX_VTX_INDX 0x00002100
-
-#define REG_A2XX_VGT_MIN_VTX_INDX 0x00002101
-
-#define REG_A2XX_VGT_INDX_OFFSET 0x00002102
-
-#define REG_A2XX_A225_PC_MULTI_PRIM_IB_RESET_INDX 0x00002103
-
-#define REG_A2XX_RB_COLOR_MASK 0x00002104
-#define A2XX_RB_COLOR_MASK_WRITE_RED 0x00000001
-#define A2XX_RB_COLOR_MASK_WRITE_GREEN 0x00000002
-#define A2XX_RB_COLOR_MASK_WRITE_BLUE 0x00000004
-#define A2XX_RB_COLOR_MASK_WRITE_ALPHA 0x00000008
-
-#define REG_A2XX_RB_BLEND_RED 0x00002105
-
-#define REG_A2XX_RB_BLEND_GREEN 0x00002106
-
-#define REG_A2XX_RB_BLEND_BLUE 0x00002107
-
-#define REG_A2XX_RB_BLEND_ALPHA 0x00002108
-
-#define REG_A2XX_RB_FOG_COLOR 0x00002109
-
-#define REG_A2XX_RB_STENCILREFMASK_BF 0x0000210c
-#define A2XX_RB_STENCILREFMASK_BF_STENCILREF__MASK 0x000000ff
-#define A2XX_RB_STENCILREFMASK_BF_STENCILREF__SHIFT 0
-static inline uint32_t A2XX_RB_STENCILREFMASK_BF_STENCILREF(uint32_t val)
-{
- return ((val) << A2XX_RB_STENCILREFMASK_BF_STENCILREF__SHIFT) & A2XX_RB_STENCILREFMASK_BF_STENCILREF__MASK;
-}
-#define A2XX_RB_STENCILREFMASK_BF_STENCILMASK__MASK 0x0000ff00
-#define A2XX_RB_STENCILREFMASK_BF_STENCILMASK__SHIFT 8
-static inline uint32_t A2XX_RB_STENCILREFMASK_BF_STENCILMASK(uint32_t val)
-{
- return ((val) << A2XX_RB_STENCILREFMASK_BF_STENCILMASK__SHIFT) & A2XX_RB_STENCILREFMASK_BF_STENCILMASK__MASK;
-}
-#define A2XX_RB_STENCILREFMASK_BF_STENCILWRITEMASK__MASK 0x00ff0000
-#define A2XX_RB_STENCILREFMASK_BF_STENCILWRITEMASK__SHIFT 16
-static inline uint32_t A2XX_RB_STENCILREFMASK_BF_STENCILWRITEMASK(uint32_t val)
-{
- return ((val) << A2XX_RB_STENCILREFMASK_BF_STENCILWRITEMASK__SHIFT) & A2XX_RB_STENCILREFMASK_BF_STENCILWRITEMASK__MASK;
-}
-
-#define REG_A2XX_RB_STENCILREFMASK 0x0000210d
-#define A2XX_RB_STENCILREFMASK_STENCILREF__MASK 0x000000ff
-#define A2XX_RB_STENCILREFMASK_STENCILREF__SHIFT 0
-static inline uint32_t A2XX_RB_STENCILREFMASK_STENCILREF(uint32_t val)
-{
- return ((val) << A2XX_RB_STENCILREFMASK_STENCILREF__SHIFT) & A2XX_RB_STENCILREFMASK_STENCILREF__MASK;
-}
-#define A2XX_RB_STENCILREFMASK_STENCILMASK__MASK 0x0000ff00
-#define A2XX_RB_STENCILREFMASK_STENCILMASK__SHIFT 8
-static inline uint32_t A2XX_RB_STENCILREFMASK_STENCILMASK(uint32_t val)
-{
- return ((val) << A2XX_RB_STENCILREFMASK_STENCILMASK__SHIFT) & A2XX_RB_STENCILREFMASK_STENCILMASK__MASK;
-}
-#define A2XX_RB_STENCILREFMASK_STENCILWRITEMASK__MASK 0x00ff0000
-#define A2XX_RB_STENCILREFMASK_STENCILWRITEMASK__SHIFT 16
-static inline uint32_t A2XX_RB_STENCILREFMASK_STENCILWRITEMASK(uint32_t val)
-{
- return ((val) << A2XX_RB_STENCILREFMASK_STENCILWRITEMASK__SHIFT) & A2XX_RB_STENCILREFMASK_STENCILWRITEMASK__MASK;
-}
-
-#define REG_A2XX_RB_ALPHA_REF 0x0000210e
-
-#define REG_A2XX_PA_CL_VPORT_XSCALE 0x0000210f
-#define A2XX_PA_CL_VPORT_XSCALE__MASK 0xffffffff
-#define A2XX_PA_CL_VPORT_XSCALE__SHIFT 0
-static inline uint32_t A2XX_PA_CL_VPORT_XSCALE(float val)
-{
- return ((fui(val)) << A2XX_PA_CL_VPORT_XSCALE__SHIFT) & A2XX_PA_CL_VPORT_XSCALE__MASK;
-}
-
-#define REG_A2XX_PA_CL_VPORT_XOFFSET 0x00002110
-#define A2XX_PA_CL_VPORT_XOFFSET__MASK 0xffffffff
-#define A2XX_PA_CL_VPORT_XOFFSET__SHIFT 0
-static inline uint32_t A2XX_PA_CL_VPORT_XOFFSET(float val)
-{
- return ((fui(val)) << A2XX_PA_CL_VPORT_XOFFSET__SHIFT) & A2XX_PA_CL_VPORT_XOFFSET__MASK;
-}
-
-#define REG_A2XX_PA_CL_VPORT_YSCALE 0x00002111
-#define A2XX_PA_CL_VPORT_YSCALE__MASK 0xffffffff
-#define A2XX_PA_CL_VPORT_YSCALE__SHIFT 0
-static inline uint32_t A2XX_PA_CL_VPORT_YSCALE(float val)
-{
- return ((fui(val)) << A2XX_PA_CL_VPORT_YSCALE__SHIFT) & A2XX_PA_CL_VPORT_YSCALE__MASK;
-}
-
-#define REG_A2XX_PA_CL_VPORT_YOFFSET 0x00002112
-#define A2XX_PA_CL_VPORT_YOFFSET__MASK 0xffffffff
-#define A2XX_PA_CL_VPORT_YOFFSET__SHIFT 0
-static inline uint32_t A2XX_PA_CL_VPORT_YOFFSET(float val)
-{
- return ((fui(val)) << A2XX_PA_CL_VPORT_YOFFSET__SHIFT) & A2XX_PA_CL_VPORT_YOFFSET__MASK;
-}
-
-#define REG_A2XX_PA_CL_VPORT_ZSCALE 0x00002113
-#define A2XX_PA_CL_VPORT_ZSCALE__MASK 0xffffffff
-#define A2XX_PA_CL_VPORT_ZSCALE__SHIFT 0
-static inline uint32_t A2XX_PA_CL_VPORT_ZSCALE(float val)
-{
- return ((fui(val)) << A2XX_PA_CL_VPORT_ZSCALE__SHIFT) & A2XX_PA_CL_VPORT_ZSCALE__MASK;
-}
-
-#define REG_A2XX_PA_CL_VPORT_ZOFFSET 0x00002114
-#define A2XX_PA_CL_VPORT_ZOFFSET__MASK 0xffffffff
-#define A2XX_PA_CL_VPORT_ZOFFSET__SHIFT 0
-static inline uint32_t A2XX_PA_CL_VPORT_ZOFFSET(float val)
-{
- return ((fui(val)) << A2XX_PA_CL_VPORT_ZOFFSET__SHIFT) & A2XX_PA_CL_VPORT_ZOFFSET__MASK;
-}
-
-#define REG_A2XX_SQ_PROGRAM_CNTL 0x00002180
-#define A2XX_SQ_PROGRAM_CNTL_VS_REGS__MASK 0x000000ff
-#define A2XX_SQ_PROGRAM_CNTL_VS_REGS__SHIFT 0
-static inline uint32_t A2XX_SQ_PROGRAM_CNTL_VS_REGS(uint32_t val)
-{
- return ((val) << A2XX_SQ_PROGRAM_CNTL_VS_REGS__SHIFT) & A2XX_SQ_PROGRAM_CNTL_VS_REGS__MASK;
-}
-#define A2XX_SQ_PROGRAM_CNTL_PS_REGS__MASK 0x0000ff00
-#define A2XX_SQ_PROGRAM_CNTL_PS_REGS__SHIFT 8
-static inline uint32_t A2XX_SQ_PROGRAM_CNTL_PS_REGS(uint32_t val)
-{
- return ((val) << A2XX_SQ_PROGRAM_CNTL_PS_REGS__SHIFT) & A2XX_SQ_PROGRAM_CNTL_PS_REGS__MASK;
-}
-#define A2XX_SQ_PROGRAM_CNTL_VS_RESOURCE 0x00010000
-#define A2XX_SQ_PROGRAM_CNTL_PS_RESOURCE 0x00020000
-#define A2XX_SQ_PROGRAM_CNTL_PARAM_GEN 0x00040000
-#define A2XX_SQ_PROGRAM_CNTL_GEN_INDEX_PIX 0x00080000
-#define A2XX_SQ_PROGRAM_CNTL_VS_EXPORT_COUNT__MASK 0x00f00000
-#define A2XX_SQ_PROGRAM_CNTL_VS_EXPORT_COUNT__SHIFT 20
-static inline uint32_t A2XX_SQ_PROGRAM_CNTL_VS_EXPORT_COUNT(uint32_t val)
-{
- return ((val) << A2XX_SQ_PROGRAM_CNTL_VS_EXPORT_COUNT__SHIFT) & A2XX_SQ_PROGRAM_CNTL_VS_EXPORT_COUNT__MASK;
-}
-#define A2XX_SQ_PROGRAM_CNTL_VS_EXPORT_MODE__MASK 0x07000000
-#define A2XX_SQ_PROGRAM_CNTL_VS_EXPORT_MODE__SHIFT 24
-static inline uint32_t A2XX_SQ_PROGRAM_CNTL_VS_EXPORT_MODE(enum a2xx_sq_ps_vtx_mode val)
-{
- return ((val) << A2XX_SQ_PROGRAM_CNTL_VS_EXPORT_MODE__SHIFT) & A2XX_SQ_PROGRAM_CNTL_VS_EXPORT_MODE__MASK;
-}
-#define A2XX_SQ_PROGRAM_CNTL_PS_EXPORT_MODE__MASK 0x78000000
-#define A2XX_SQ_PROGRAM_CNTL_PS_EXPORT_MODE__SHIFT 27
-static inline uint32_t A2XX_SQ_PROGRAM_CNTL_PS_EXPORT_MODE(uint32_t val)
-{
- return ((val) << A2XX_SQ_PROGRAM_CNTL_PS_EXPORT_MODE__SHIFT) & A2XX_SQ_PROGRAM_CNTL_PS_EXPORT_MODE__MASK;
-}
-#define A2XX_SQ_PROGRAM_CNTL_GEN_INDEX_VTX 0x80000000
-
-#define REG_A2XX_SQ_CONTEXT_MISC 0x00002181
-#define A2XX_SQ_CONTEXT_MISC_INST_PRED_OPTIMIZE 0x00000001
-#define A2XX_SQ_CONTEXT_MISC_SC_OUTPUT_SCREEN_XY 0x00000002
-#define A2XX_SQ_CONTEXT_MISC_SC_SAMPLE_CNTL__MASK 0x0000000c
-#define A2XX_SQ_CONTEXT_MISC_SC_SAMPLE_CNTL__SHIFT 2
-static inline uint32_t A2XX_SQ_CONTEXT_MISC_SC_SAMPLE_CNTL(enum a2xx_sq_sample_cntl val)
-{
- return ((val) << A2XX_SQ_CONTEXT_MISC_SC_SAMPLE_CNTL__SHIFT) & A2XX_SQ_CONTEXT_MISC_SC_SAMPLE_CNTL__MASK;
-}
-#define A2XX_SQ_CONTEXT_MISC_PARAM_GEN_POS__MASK 0x0000ff00
-#define A2XX_SQ_CONTEXT_MISC_PARAM_GEN_POS__SHIFT 8
-static inline uint32_t A2XX_SQ_CONTEXT_MISC_PARAM_GEN_POS(uint32_t val)
-{
- return ((val) << A2XX_SQ_CONTEXT_MISC_PARAM_GEN_POS__SHIFT) & A2XX_SQ_CONTEXT_MISC_PARAM_GEN_POS__MASK;
-}
-#define A2XX_SQ_CONTEXT_MISC_PERFCOUNTER_REF 0x00010000
-#define A2XX_SQ_CONTEXT_MISC_YEILD_OPTIMIZE 0x00020000
-#define A2XX_SQ_CONTEXT_MISC_TX_CACHE_SEL 0x00040000
-
-#define REG_A2XX_SQ_INTERPOLATOR_CNTL 0x00002182
-
-#define REG_A2XX_SQ_WRAPPING_0 0x00002183
-
-#define REG_A2XX_SQ_WRAPPING_1 0x00002184
-
-#define REG_A2XX_SQ_PS_PROGRAM 0x000021f6
-
-#define REG_A2XX_SQ_VS_PROGRAM 0x000021f7
-
-#define REG_A2XX_RB_DEPTHCONTROL 0x00002200
-#define A2XX_RB_DEPTHCONTROL_STENCIL_ENABLE 0x00000001
-#define A2XX_RB_DEPTHCONTROL_Z_ENABLE 0x00000002
-#define A2XX_RB_DEPTHCONTROL_Z_WRITE_ENABLE 0x00000004
-#define A2XX_RB_DEPTHCONTROL_EARLY_Z_ENABLE 0x00000008
-#define A2XX_RB_DEPTHCONTROL_ZFUNC__MASK 0x00000070
-#define A2XX_RB_DEPTHCONTROL_ZFUNC__SHIFT 4
-static inline uint32_t A2XX_RB_DEPTHCONTROL_ZFUNC(enum adreno_compare_func val)
-{
- return ((val) << A2XX_RB_DEPTHCONTROL_ZFUNC__SHIFT) & A2XX_RB_DEPTHCONTROL_ZFUNC__MASK;
-}
-#define A2XX_RB_DEPTHCONTROL_BACKFACE_ENABLE 0x00000080
-#define A2XX_RB_DEPTHCONTROL_STENCILFUNC__MASK 0x00000700
-#define A2XX_RB_DEPTHCONTROL_STENCILFUNC__SHIFT 8
-static inline uint32_t A2XX_RB_DEPTHCONTROL_STENCILFUNC(enum adreno_compare_func val)
-{
- return ((val) << A2XX_RB_DEPTHCONTROL_STENCILFUNC__SHIFT) & A2XX_RB_DEPTHCONTROL_STENCILFUNC__MASK;
-}
-#define A2XX_RB_DEPTHCONTROL_STENCILFAIL__MASK 0x00003800
-#define A2XX_RB_DEPTHCONTROL_STENCILFAIL__SHIFT 11
-static inline uint32_t A2XX_RB_DEPTHCONTROL_STENCILFAIL(enum adreno_stencil_op val)
-{
- return ((val) << A2XX_RB_DEPTHCONTROL_STENCILFAIL__SHIFT) & A2XX_RB_DEPTHCONTROL_STENCILFAIL__MASK;
-}
-#define A2XX_RB_DEPTHCONTROL_STENCILZPASS__MASK 0x0001c000
-#define A2XX_RB_DEPTHCONTROL_STENCILZPASS__SHIFT 14
-static inline uint32_t A2XX_RB_DEPTHCONTROL_STENCILZPASS(enum adreno_stencil_op val)
-{
- return ((val) << A2XX_RB_DEPTHCONTROL_STENCILZPASS__SHIFT) & A2XX_RB_DEPTHCONTROL_STENCILZPASS__MASK;
-}
-#define A2XX_RB_DEPTHCONTROL_STENCILZFAIL__MASK 0x000e0000
-#define A2XX_RB_DEPTHCONTROL_STENCILZFAIL__SHIFT 17
-static inline uint32_t A2XX_RB_DEPTHCONTROL_STENCILZFAIL(enum adreno_stencil_op val)
-{
- return ((val) << A2XX_RB_DEPTHCONTROL_STENCILZFAIL__SHIFT) & A2XX_RB_DEPTHCONTROL_STENCILZFAIL__MASK;
-}
-#define A2XX_RB_DEPTHCONTROL_STENCILFUNC_BF__MASK 0x00700000
-#define A2XX_RB_DEPTHCONTROL_STENCILFUNC_BF__SHIFT 20
-static inline uint32_t A2XX_RB_DEPTHCONTROL_STENCILFUNC_BF(enum adreno_compare_func val)
-{
- return ((val) << A2XX_RB_DEPTHCONTROL_STENCILFUNC_BF__SHIFT) & A2XX_RB_DEPTHCONTROL_STENCILFUNC_BF__MASK;
-}
-#define A2XX_RB_DEPTHCONTROL_STENCILFAIL_BF__MASK 0x03800000
-#define A2XX_RB_DEPTHCONTROL_STENCILFAIL_BF__SHIFT 23
-static inline uint32_t A2XX_RB_DEPTHCONTROL_STENCILFAIL_BF(enum adreno_stencil_op val)
-{
- return ((val) << A2XX_RB_DEPTHCONTROL_STENCILFAIL_BF__SHIFT) & A2XX_RB_DEPTHCONTROL_STENCILFAIL_BF__MASK;
-}
-#define A2XX_RB_DEPTHCONTROL_STENCILZPASS_BF__MASK 0x1c000000
-#define A2XX_RB_DEPTHCONTROL_STENCILZPASS_BF__SHIFT 26
-static inline uint32_t A2XX_RB_DEPTHCONTROL_STENCILZPASS_BF(enum adreno_stencil_op val)
-{
- return ((val) << A2XX_RB_DEPTHCONTROL_STENCILZPASS_BF__SHIFT) & A2XX_RB_DEPTHCONTROL_STENCILZPASS_BF__MASK;
-}
-#define A2XX_RB_DEPTHCONTROL_STENCILZFAIL_BF__MASK 0xe0000000
-#define A2XX_RB_DEPTHCONTROL_STENCILZFAIL_BF__SHIFT 29
-static inline uint32_t A2XX_RB_DEPTHCONTROL_STENCILZFAIL_BF(enum adreno_stencil_op val)
-{
- return ((val) << A2XX_RB_DEPTHCONTROL_STENCILZFAIL_BF__SHIFT) & A2XX_RB_DEPTHCONTROL_STENCILZFAIL_BF__MASK;
-}
-
-#define REG_A2XX_RB_BLEND_CONTROL 0x00002201
-#define A2XX_RB_BLEND_CONTROL_COLOR_SRCBLEND__MASK 0x0000001f
-#define A2XX_RB_BLEND_CONTROL_COLOR_SRCBLEND__SHIFT 0
-static inline uint32_t A2XX_RB_BLEND_CONTROL_COLOR_SRCBLEND(enum adreno_rb_blend_factor val)
-{
- return ((val) << A2XX_RB_BLEND_CONTROL_COLOR_SRCBLEND__SHIFT) & A2XX_RB_BLEND_CONTROL_COLOR_SRCBLEND__MASK;
-}
-#define A2XX_RB_BLEND_CONTROL_COLOR_COMB_FCN__MASK 0x000000e0
-#define A2XX_RB_BLEND_CONTROL_COLOR_COMB_FCN__SHIFT 5
-static inline uint32_t A2XX_RB_BLEND_CONTROL_COLOR_COMB_FCN(enum adreno_rb_blend_opcode val)
-{
- return ((val) << A2XX_RB_BLEND_CONTROL_COLOR_COMB_FCN__SHIFT) & A2XX_RB_BLEND_CONTROL_COLOR_COMB_FCN__MASK;
-}
-#define A2XX_RB_BLEND_CONTROL_COLOR_DESTBLEND__MASK 0x00001f00
-#define A2XX_RB_BLEND_CONTROL_COLOR_DESTBLEND__SHIFT 8
-static inline uint32_t A2XX_RB_BLEND_CONTROL_COLOR_DESTBLEND(enum adreno_rb_blend_factor val)
-{
- return ((val) << A2XX_RB_BLEND_CONTROL_COLOR_DESTBLEND__SHIFT) & A2XX_RB_BLEND_CONTROL_COLOR_DESTBLEND__MASK;
-}
-#define A2XX_RB_BLEND_CONTROL_ALPHA_SRCBLEND__MASK 0x001f0000
-#define A2XX_RB_BLEND_CONTROL_ALPHA_SRCBLEND__SHIFT 16
-static inline uint32_t A2XX_RB_BLEND_CONTROL_ALPHA_SRCBLEND(enum adreno_rb_blend_factor val)
-{
- return ((val) << A2XX_RB_BLEND_CONTROL_ALPHA_SRCBLEND__SHIFT) & A2XX_RB_BLEND_CONTROL_ALPHA_SRCBLEND__MASK;
-}
-#define A2XX_RB_BLEND_CONTROL_ALPHA_COMB_FCN__MASK 0x00e00000
-#define A2XX_RB_BLEND_CONTROL_ALPHA_COMB_FCN__SHIFT 21
-static inline uint32_t A2XX_RB_BLEND_CONTROL_ALPHA_COMB_FCN(enum adreno_rb_blend_opcode val)
-{
- return ((val) << A2XX_RB_BLEND_CONTROL_ALPHA_COMB_FCN__SHIFT) & A2XX_RB_BLEND_CONTROL_ALPHA_COMB_FCN__MASK;
-}
-#define A2XX_RB_BLEND_CONTROL_ALPHA_DESTBLEND__MASK 0x1f000000
-#define A2XX_RB_BLEND_CONTROL_ALPHA_DESTBLEND__SHIFT 24
-static inline uint32_t A2XX_RB_BLEND_CONTROL_ALPHA_DESTBLEND(enum adreno_rb_blend_factor val)
-{
- return ((val) << A2XX_RB_BLEND_CONTROL_ALPHA_DESTBLEND__SHIFT) & A2XX_RB_BLEND_CONTROL_ALPHA_DESTBLEND__MASK;
-}
-#define A2XX_RB_BLEND_CONTROL_BLEND_FORCE_ENABLE 0x20000000
-#define A2XX_RB_BLEND_CONTROL_BLEND_FORCE 0x40000000
-
-#define REG_A2XX_RB_COLORCONTROL 0x00002202
-#define A2XX_RB_COLORCONTROL_ALPHA_FUNC__MASK 0x00000007
-#define A2XX_RB_COLORCONTROL_ALPHA_FUNC__SHIFT 0
-static inline uint32_t A2XX_RB_COLORCONTROL_ALPHA_FUNC(enum adreno_compare_func val)
-{
- return ((val) << A2XX_RB_COLORCONTROL_ALPHA_FUNC__SHIFT) & A2XX_RB_COLORCONTROL_ALPHA_FUNC__MASK;
-}
-#define A2XX_RB_COLORCONTROL_ALPHA_TEST_ENABLE 0x00000008
-#define A2XX_RB_COLORCONTROL_ALPHA_TO_MASK_ENABLE 0x00000010
-#define A2XX_RB_COLORCONTROL_BLEND_DISABLE 0x00000020
-#define A2XX_RB_COLORCONTROL_VOB_ENABLE 0x00000040
-#define A2XX_RB_COLORCONTROL_VS_EXPORTS_FOG 0x00000080
-#define A2XX_RB_COLORCONTROL_ROP_CODE__MASK 0x00000f00
-#define A2XX_RB_COLORCONTROL_ROP_CODE__SHIFT 8
-static inline uint32_t A2XX_RB_COLORCONTROL_ROP_CODE(uint32_t val)
-{
- return ((val) << A2XX_RB_COLORCONTROL_ROP_CODE__SHIFT) & A2XX_RB_COLORCONTROL_ROP_CODE__MASK;
-}
-#define A2XX_RB_COLORCONTROL_DITHER_MODE__MASK 0x00003000
-#define A2XX_RB_COLORCONTROL_DITHER_MODE__SHIFT 12
-static inline uint32_t A2XX_RB_COLORCONTROL_DITHER_MODE(enum adreno_rb_dither_mode val)
-{
- return ((val) << A2XX_RB_COLORCONTROL_DITHER_MODE__SHIFT) & A2XX_RB_COLORCONTROL_DITHER_MODE__MASK;
-}
-#define A2XX_RB_COLORCONTROL_DITHER_TYPE__MASK 0x0000c000
-#define A2XX_RB_COLORCONTROL_DITHER_TYPE__SHIFT 14
-static inline uint32_t A2XX_RB_COLORCONTROL_DITHER_TYPE(enum a2xx_rb_dither_type val)
-{
- return ((val) << A2XX_RB_COLORCONTROL_DITHER_TYPE__SHIFT) & A2XX_RB_COLORCONTROL_DITHER_TYPE__MASK;
-}
-#define A2XX_RB_COLORCONTROL_PIXEL_FOG 0x00010000
-#define A2XX_RB_COLORCONTROL_ALPHA_TO_MASK_OFFSET0__MASK 0x03000000
-#define A2XX_RB_COLORCONTROL_ALPHA_TO_MASK_OFFSET0__SHIFT 24
-static inline uint32_t A2XX_RB_COLORCONTROL_ALPHA_TO_MASK_OFFSET0(uint32_t val)
-{
- return ((val) << A2XX_RB_COLORCONTROL_ALPHA_TO_MASK_OFFSET0__SHIFT) & A2XX_RB_COLORCONTROL_ALPHA_TO_MASK_OFFSET0__MASK;
-}
-#define A2XX_RB_COLORCONTROL_ALPHA_TO_MASK_OFFSET1__MASK 0x0c000000
-#define A2XX_RB_COLORCONTROL_ALPHA_TO_MASK_OFFSET1__SHIFT 26
-static inline uint32_t A2XX_RB_COLORCONTROL_ALPHA_TO_MASK_OFFSET1(uint32_t val)
-{
- return ((val) << A2XX_RB_COLORCONTROL_ALPHA_TO_MASK_OFFSET1__SHIFT) & A2XX_RB_COLORCONTROL_ALPHA_TO_MASK_OFFSET1__MASK;
-}
-#define A2XX_RB_COLORCONTROL_ALPHA_TO_MASK_OFFSET2__MASK 0x30000000
-#define A2XX_RB_COLORCONTROL_ALPHA_TO_MASK_OFFSET2__SHIFT 28
-static inline uint32_t A2XX_RB_COLORCONTROL_ALPHA_TO_MASK_OFFSET2(uint32_t val)
-{
- return ((val) << A2XX_RB_COLORCONTROL_ALPHA_TO_MASK_OFFSET2__SHIFT) & A2XX_RB_COLORCONTROL_ALPHA_TO_MASK_OFFSET2__MASK;
-}
-#define A2XX_RB_COLORCONTROL_ALPHA_TO_MASK_OFFSET3__MASK 0xc0000000
-#define A2XX_RB_COLORCONTROL_ALPHA_TO_MASK_OFFSET3__SHIFT 30
-static inline uint32_t A2XX_RB_COLORCONTROL_ALPHA_TO_MASK_OFFSET3(uint32_t val)
-{
- return ((val) << A2XX_RB_COLORCONTROL_ALPHA_TO_MASK_OFFSET3__SHIFT) & A2XX_RB_COLORCONTROL_ALPHA_TO_MASK_OFFSET3__MASK;
-}
-
-#define REG_A2XX_VGT_CURRENT_BIN_ID_MAX 0x00002203
-#define A2XX_VGT_CURRENT_BIN_ID_MAX_COLUMN__MASK 0x00000007
-#define A2XX_VGT_CURRENT_BIN_ID_MAX_COLUMN__SHIFT 0
-static inline uint32_t A2XX_VGT_CURRENT_BIN_ID_MAX_COLUMN(uint32_t val)
-{
- return ((val) << A2XX_VGT_CURRENT_BIN_ID_MAX_COLUMN__SHIFT) & A2XX_VGT_CURRENT_BIN_ID_MAX_COLUMN__MASK;
-}
-#define A2XX_VGT_CURRENT_BIN_ID_MAX_ROW__MASK 0x00000038
-#define A2XX_VGT_CURRENT_BIN_ID_MAX_ROW__SHIFT 3
-static inline uint32_t A2XX_VGT_CURRENT_BIN_ID_MAX_ROW(uint32_t val)
-{
- return ((val) << A2XX_VGT_CURRENT_BIN_ID_MAX_ROW__SHIFT) & A2XX_VGT_CURRENT_BIN_ID_MAX_ROW__MASK;
-}
-#define A2XX_VGT_CURRENT_BIN_ID_MAX_GUARD_BAND_MASK__MASK 0x000001c0
-#define A2XX_VGT_CURRENT_BIN_ID_MAX_GUARD_BAND_MASK__SHIFT 6
-static inline uint32_t A2XX_VGT_CURRENT_BIN_ID_MAX_GUARD_BAND_MASK(uint32_t val)
-{
- return ((val) << A2XX_VGT_CURRENT_BIN_ID_MAX_GUARD_BAND_MASK__SHIFT) & A2XX_VGT_CURRENT_BIN_ID_MAX_GUARD_BAND_MASK__MASK;
-}
-
-#define REG_A2XX_PA_CL_CLIP_CNTL 0x00002204
-#define A2XX_PA_CL_CLIP_CNTL_CLIP_DISABLE 0x00010000
-#define A2XX_PA_CL_CLIP_CNTL_BOUNDARY_EDGE_FLAG_ENA 0x00040000
-#define A2XX_PA_CL_CLIP_CNTL_DX_CLIP_SPACE_DEF__MASK 0x00080000
-#define A2XX_PA_CL_CLIP_CNTL_DX_CLIP_SPACE_DEF__SHIFT 19
-static inline uint32_t A2XX_PA_CL_CLIP_CNTL_DX_CLIP_SPACE_DEF(enum a2xx_dx_clip_space val)
-{
- return ((val) << A2XX_PA_CL_CLIP_CNTL_DX_CLIP_SPACE_DEF__SHIFT) & A2XX_PA_CL_CLIP_CNTL_DX_CLIP_SPACE_DEF__MASK;
-}
-#define A2XX_PA_CL_CLIP_CNTL_DIS_CLIP_ERR_DETECT 0x00100000
-#define A2XX_PA_CL_CLIP_CNTL_VTX_KILL_OR 0x00200000
-#define A2XX_PA_CL_CLIP_CNTL_XY_NAN_RETAIN 0x00400000
-#define A2XX_PA_CL_CLIP_CNTL_Z_NAN_RETAIN 0x00800000
-#define A2XX_PA_CL_CLIP_CNTL_W_NAN_RETAIN 0x01000000
-
-#define REG_A2XX_PA_SU_SC_MODE_CNTL 0x00002205
-#define A2XX_PA_SU_SC_MODE_CNTL_CULL_FRONT 0x00000001
-#define A2XX_PA_SU_SC_MODE_CNTL_CULL_BACK 0x00000002
-#define A2XX_PA_SU_SC_MODE_CNTL_FACE 0x00000004
-#define A2XX_PA_SU_SC_MODE_CNTL_POLYMODE__MASK 0x00000018
-#define A2XX_PA_SU_SC_MODE_CNTL_POLYMODE__SHIFT 3
-static inline uint32_t A2XX_PA_SU_SC_MODE_CNTL_POLYMODE(enum a2xx_pa_su_sc_polymode val)
-{
- return ((val) << A2XX_PA_SU_SC_MODE_CNTL_POLYMODE__SHIFT) & A2XX_PA_SU_SC_MODE_CNTL_POLYMODE__MASK;
-}
-#define A2XX_PA_SU_SC_MODE_CNTL_FRONT_PTYPE__MASK 0x000000e0
-#define A2XX_PA_SU_SC_MODE_CNTL_FRONT_PTYPE__SHIFT 5
-static inline uint32_t A2XX_PA_SU_SC_MODE_CNTL_FRONT_PTYPE(enum adreno_pa_su_sc_draw val)
-{
- return ((val) << A2XX_PA_SU_SC_MODE_CNTL_FRONT_PTYPE__SHIFT) & A2XX_PA_SU_SC_MODE_CNTL_FRONT_PTYPE__MASK;
-}
-#define A2XX_PA_SU_SC_MODE_CNTL_BACK_PTYPE__MASK 0x00000700
-#define A2XX_PA_SU_SC_MODE_CNTL_BACK_PTYPE__SHIFT 8
-static inline uint32_t A2XX_PA_SU_SC_MODE_CNTL_BACK_PTYPE(enum adreno_pa_su_sc_draw val)
-{
- return ((val) << A2XX_PA_SU_SC_MODE_CNTL_BACK_PTYPE__SHIFT) & A2XX_PA_SU_SC_MODE_CNTL_BACK_PTYPE__MASK;
-}
-#define A2XX_PA_SU_SC_MODE_CNTL_POLY_OFFSET_FRONT_ENABLE 0x00000800
-#define A2XX_PA_SU_SC_MODE_CNTL_POLY_OFFSET_BACK_ENABLE 0x00001000
-#define A2XX_PA_SU_SC_MODE_CNTL_POLY_OFFSET_PARA_ENABLE 0x00002000
-#define A2XX_PA_SU_SC_MODE_CNTL_MSAA_ENABLE 0x00008000
-#define A2XX_PA_SU_SC_MODE_CNTL_VTX_WINDOW_OFFSET_ENABLE 0x00010000
-#define A2XX_PA_SU_SC_MODE_CNTL_LINE_STIPPLE_ENABLE 0x00040000
-#define A2XX_PA_SU_SC_MODE_CNTL_PROVOKING_VTX_LAST 0x00080000
-#define A2XX_PA_SU_SC_MODE_CNTL_PERSP_CORR_DIS 0x00100000
-#define A2XX_PA_SU_SC_MODE_CNTL_MULTI_PRIM_IB_ENA 0x00200000
-#define A2XX_PA_SU_SC_MODE_CNTL_QUAD_ORDER_ENABLE 0x00800000
-#define A2XX_PA_SU_SC_MODE_CNTL_WAIT_RB_IDLE_ALL_TRI 0x02000000
-#define A2XX_PA_SU_SC_MODE_CNTL_WAIT_RB_IDLE_FIRST_TRI_NEW_STATE 0x04000000
-#define A2XX_PA_SU_SC_MODE_CNTL_CLAMPED_FACENESS 0x10000000
-#define A2XX_PA_SU_SC_MODE_CNTL_ZERO_AREA_FACENESS 0x20000000
-#define A2XX_PA_SU_SC_MODE_CNTL_FACE_KILL_ENABLE 0x40000000
-#define A2XX_PA_SU_SC_MODE_CNTL_FACE_WRITE_ENABLE 0x80000000
-
-#define REG_A2XX_PA_CL_VTE_CNTL 0x00002206
-#define A2XX_PA_CL_VTE_CNTL_VPORT_X_SCALE_ENA 0x00000001
-#define A2XX_PA_CL_VTE_CNTL_VPORT_X_OFFSET_ENA 0x00000002
-#define A2XX_PA_CL_VTE_CNTL_VPORT_Y_SCALE_ENA 0x00000004
-#define A2XX_PA_CL_VTE_CNTL_VPORT_Y_OFFSET_ENA 0x00000008
-#define A2XX_PA_CL_VTE_CNTL_VPORT_Z_SCALE_ENA 0x00000010
-#define A2XX_PA_CL_VTE_CNTL_VPORT_Z_OFFSET_ENA 0x00000020
-#define A2XX_PA_CL_VTE_CNTL_VTX_XY_FMT 0x00000100
-#define A2XX_PA_CL_VTE_CNTL_VTX_Z_FMT 0x00000200
-#define A2XX_PA_CL_VTE_CNTL_VTX_W0_FMT 0x00000400
-#define A2XX_PA_CL_VTE_CNTL_PERFCOUNTER_REF 0x00000800
-
-#define REG_A2XX_VGT_CURRENT_BIN_ID_MIN 0x00002207
-#define A2XX_VGT_CURRENT_BIN_ID_MIN_COLUMN__MASK 0x00000007
-#define A2XX_VGT_CURRENT_BIN_ID_MIN_COLUMN__SHIFT 0
-static inline uint32_t A2XX_VGT_CURRENT_BIN_ID_MIN_COLUMN(uint32_t val)
-{
- return ((val) << A2XX_VGT_CURRENT_BIN_ID_MIN_COLUMN__SHIFT) & A2XX_VGT_CURRENT_BIN_ID_MIN_COLUMN__MASK;
-}
-#define A2XX_VGT_CURRENT_BIN_ID_MIN_ROW__MASK 0x00000038
-#define A2XX_VGT_CURRENT_BIN_ID_MIN_ROW__SHIFT 3
-static inline uint32_t A2XX_VGT_CURRENT_BIN_ID_MIN_ROW(uint32_t val)
-{
- return ((val) << A2XX_VGT_CURRENT_BIN_ID_MIN_ROW__SHIFT) & A2XX_VGT_CURRENT_BIN_ID_MIN_ROW__MASK;
-}
-#define A2XX_VGT_CURRENT_BIN_ID_MIN_GUARD_BAND_MASK__MASK 0x000001c0
-#define A2XX_VGT_CURRENT_BIN_ID_MIN_GUARD_BAND_MASK__SHIFT 6
-static inline uint32_t A2XX_VGT_CURRENT_BIN_ID_MIN_GUARD_BAND_MASK(uint32_t val)
-{
- return ((val) << A2XX_VGT_CURRENT_BIN_ID_MIN_GUARD_BAND_MASK__SHIFT) & A2XX_VGT_CURRENT_BIN_ID_MIN_GUARD_BAND_MASK__MASK;
-}
-
-#define REG_A2XX_RB_MODECONTROL 0x00002208
-#define A2XX_RB_MODECONTROL_EDRAM_MODE__MASK 0x00000007
-#define A2XX_RB_MODECONTROL_EDRAM_MODE__SHIFT 0
-static inline uint32_t A2XX_RB_MODECONTROL_EDRAM_MODE(enum a2xx_rb_edram_mode val)
-{
- return ((val) << A2XX_RB_MODECONTROL_EDRAM_MODE__SHIFT) & A2XX_RB_MODECONTROL_EDRAM_MODE__MASK;
-}
-
-#define REG_A2XX_A220_RB_LRZ_VSC_CONTROL 0x00002209
-
-#define REG_A2XX_RB_SAMPLE_POS 0x0000220a
-
-#define REG_A2XX_CLEAR_COLOR 0x0000220b
-#define A2XX_CLEAR_COLOR_RED__MASK 0x000000ff
-#define A2XX_CLEAR_COLOR_RED__SHIFT 0
-static inline uint32_t A2XX_CLEAR_COLOR_RED(uint32_t val)
-{
- return ((val) << A2XX_CLEAR_COLOR_RED__SHIFT) & A2XX_CLEAR_COLOR_RED__MASK;
-}
-#define A2XX_CLEAR_COLOR_GREEN__MASK 0x0000ff00
-#define A2XX_CLEAR_COLOR_GREEN__SHIFT 8
-static inline uint32_t A2XX_CLEAR_COLOR_GREEN(uint32_t val)
-{
- return ((val) << A2XX_CLEAR_COLOR_GREEN__SHIFT) & A2XX_CLEAR_COLOR_GREEN__MASK;
-}
-#define A2XX_CLEAR_COLOR_BLUE__MASK 0x00ff0000
-#define A2XX_CLEAR_COLOR_BLUE__SHIFT 16
-static inline uint32_t A2XX_CLEAR_COLOR_BLUE(uint32_t val)
-{
- return ((val) << A2XX_CLEAR_COLOR_BLUE__SHIFT) & A2XX_CLEAR_COLOR_BLUE__MASK;
-}
-#define A2XX_CLEAR_COLOR_ALPHA__MASK 0xff000000
-#define A2XX_CLEAR_COLOR_ALPHA__SHIFT 24
-static inline uint32_t A2XX_CLEAR_COLOR_ALPHA(uint32_t val)
-{
- return ((val) << A2XX_CLEAR_COLOR_ALPHA__SHIFT) & A2XX_CLEAR_COLOR_ALPHA__MASK;
-}
-
-#define REG_A2XX_A220_GRAS_CONTROL 0x00002210
-
-#define REG_A2XX_PA_SU_POINT_SIZE 0x00002280
-#define A2XX_PA_SU_POINT_SIZE_HEIGHT__MASK 0x0000ffff
-#define A2XX_PA_SU_POINT_SIZE_HEIGHT__SHIFT 0
-static inline uint32_t A2XX_PA_SU_POINT_SIZE_HEIGHT(float val)
-{
- return ((((uint32_t)(val * 8.0))) << A2XX_PA_SU_POINT_SIZE_HEIGHT__SHIFT) & A2XX_PA_SU_POINT_SIZE_HEIGHT__MASK;
-}
-#define A2XX_PA_SU_POINT_SIZE_WIDTH__MASK 0xffff0000
-#define A2XX_PA_SU_POINT_SIZE_WIDTH__SHIFT 16
-static inline uint32_t A2XX_PA_SU_POINT_SIZE_WIDTH(float val)
-{
- return ((((uint32_t)(val * 8.0))) << A2XX_PA_SU_POINT_SIZE_WIDTH__SHIFT) & A2XX_PA_SU_POINT_SIZE_WIDTH__MASK;
-}
-
-#define REG_A2XX_PA_SU_POINT_MINMAX 0x00002281
-#define A2XX_PA_SU_POINT_MINMAX_MIN__MASK 0x0000ffff
-#define A2XX_PA_SU_POINT_MINMAX_MIN__SHIFT 0
-static inline uint32_t A2XX_PA_SU_POINT_MINMAX_MIN(float val)
-{
- return ((((uint32_t)(val * 8.0))) << A2XX_PA_SU_POINT_MINMAX_MIN__SHIFT) & A2XX_PA_SU_POINT_MINMAX_MIN__MASK;
-}
-#define A2XX_PA_SU_POINT_MINMAX_MAX__MASK 0xffff0000
-#define A2XX_PA_SU_POINT_MINMAX_MAX__SHIFT 16
-static inline uint32_t A2XX_PA_SU_POINT_MINMAX_MAX(float val)
-{
- return ((((uint32_t)(val * 8.0))) << A2XX_PA_SU_POINT_MINMAX_MAX__SHIFT) & A2XX_PA_SU_POINT_MINMAX_MAX__MASK;
-}
-
-#define REG_A2XX_PA_SU_LINE_CNTL 0x00002282
-#define A2XX_PA_SU_LINE_CNTL_WIDTH__MASK 0x0000ffff
-#define A2XX_PA_SU_LINE_CNTL_WIDTH__SHIFT 0
-static inline uint32_t A2XX_PA_SU_LINE_CNTL_WIDTH(float val)
-{
- return ((((uint32_t)(val * 8.0))) << A2XX_PA_SU_LINE_CNTL_WIDTH__SHIFT) & A2XX_PA_SU_LINE_CNTL_WIDTH__MASK;
-}
-
-#define REG_A2XX_PA_SC_LINE_STIPPLE 0x00002283
-#define A2XX_PA_SC_LINE_STIPPLE_LINE_PATTERN__MASK 0x0000ffff
-#define A2XX_PA_SC_LINE_STIPPLE_LINE_PATTERN__SHIFT 0
-static inline uint32_t A2XX_PA_SC_LINE_STIPPLE_LINE_PATTERN(uint32_t val)
-{
- return ((val) << A2XX_PA_SC_LINE_STIPPLE_LINE_PATTERN__SHIFT) & A2XX_PA_SC_LINE_STIPPLE_LINE_PATTERN__MASK;
-}
-#define A2XX_PA_SC_LINE_STIPPLE_REPEAT_COUNT__MASK 0x00ff0000
-#define A2XX_PA_SC_LINE_STIPPLE_REPEAT_COUNT__SHIFT 16
-static inline uint32_t A2XX_PA_SC_LINE_STIPPLE_REPEAT_COUNT(uint32_t val)
-{
- return ((val) << A2XX_PA_SC_LINE_STIPPLE_REPEAT_COUNT__SHIFT) & A2XX_PA_SC_LINE_STIPPLE_REPEAT_COUNT__MASK;
-}
-#define A2XX_PA_SC_LINE_STIPPLE_PATTERN_BIT_ORDER__MASK 0x10000000
-#define A2XX_PA_SC_LINE_STIPPLE_PATTERN_BIT_ORDER__SHIFT 28
-static inline uint32_t A2XX_PA_SC_LINE_STIPPLE_PATTERN_BIT_ORDER(enum a2xx_pa_sc_pattern_bit_order val)
-{
- return ((val) << A2XX_PA_SC_LINE_STIPPLE_PATTERN_BIT_ORDER__SHIFT) & A2XX_PA_SC_LINE_STIPPLE_PATTERN_BIT_ORDER__MASK;
-}
-#define A2XX_PA_SC_LINE_STIPPLE_AUTO_RESET_CNTL__MASK 0x60000000
-#define A2XX_PA_SC_LINE_STIPPLE_AUTO_RESET_CNTL__SHIFT 29
-static inline uint32_t A2XX_PA_SC_LINE_STIPPLE_AUTO_RESET_CNTL(enum a2xx_pa_sc_auto_reset_cntl val)
-{
- return ((val) << A2XX_PA_SC_LINE_STIPPLE_AUTO_RESET_CNTL__SHIFT) & A2XX_PA_SC_LINE_STIPPLE_AUTO_RESET_CNTL__MASK;
-}
-
-#define REG_A2XX_PA_SC_VIZ_QUERY 0x00002293
-
-#define REG_A2XX_VGT_ENHANCE 0x00002294
-
-#define REG_A2XX_PA_SC_LINE_CNTL 0x00002300
-#define A2XX_PA_SC_LINE_CNTL_BRES_CNTL__MASK 0x0000ffff
-#define A2XX_PA_SC_LINE_CNTL_BRES_CNTL__SHIFT 0
-static inline uint32_t A2XX_PA_SC_LINE_CNTL_BRES_CNTL(uint32_t val)
-{
- return ((val) << A2XX_PA_SC_LINE_CNTL_BRES_CNTL__SHIFT) & A2XX_PA_SC_LINE_CNTL_BRES_CNTL__MASK;
-}
-#define A2XX_PA_SC_LINE_CNTL_USE_BRES_CNTL 0x00000100
-#define A2XX_PA_SC_LINE_CNTL_EXPAND_LINE_WIDTH 0x00000200
-#define A2XX_PA_SC_LINE_CNTL_LAST_PIXEL 0x00000400
-
-#define REG_A2XX_PA_SC_AA_CONFIG 0x00002301
-
-#define REG_A2XX_PA_SU_VTX_CNTL 0x00002302
-#define A2XX_PA_SU_VTX_CNTL_PIX_CENTER__MASK 0x00000001
-#define A2XX_PA_SU_VTX_CNTL_PIX_CENTER__SHIFT 0
-static inline uint32_t A2XX_PA_SU_VTX_CNTL_PIX_CENTER(enum a2xx_pa_pixcenter val)
-{
- return ((val) << A2XX_PA_SU_VTX_CNTL_PIX_CENTER__SHIFT) & A2XX_PA_SU_VTX_CNTL_PIX_CENTER__MASK;
-}
-#define A2XX_PA_SU_VTX_CNTL_ROUND_MODE__MASK 0x00000006
-#define A2XX_PA_SU_VTX_CNTL_ROUND_MODE__SHIFT 1
-static inline uint32_t A2XX_PA_SU_VTX_CNTL_ROUND_MODE(enum a2xx_pa_roundmode val)
-{
- return ((val) << A2XX_PA_SU_VTX_CNTL_ROUND_MODE__SHIFT) & A2XX_PA_SU_VTX_CNTL_ROUND_MODE__MASK;
-}
-#define A2XX_PA_SU_VTX_CNTL_QUANT_MODE__MASK 0x00000380
-#define A2XX_PA_SU_VTX_CNTL_QUANT_MODE__SHIFT 7
-static inline uint32_t A2XX_PA_SU_VTX_CNTL_QUANT_MODE(enum a2xx_pa_quantmode val)
-{
- return ((val) << A2XX_PA_SU_VTX_CNTL_QUANT_MODE__SHIFT) & A2XX_PA_SU_VTX_CNTL_QUANT_MODE__MASK;
-}
-
-#define REG_A2XX_PA_CL_GB_VERT_CLIP_ADJ 0x00002303
-#define A2XX_PA_CL_GB_VERT_CLIP_ADJ__MASK 0xffffffff
-#define A2XX_PA_CL_GB_VERT_CLIP_ADJ__SHIFT 0
-static inline uint32_t A2XX_PA_CL_GB_VERT_CLIP_ADJ(float val)
-{
- return ((fui(val)) << A2XX_PA_CL_GB_VERT_CLIP_ADJ__SHIFT) & A2XX_PA_CL_GB_VERT_CLIP_ADJ__MASK;
-}
-
-#define REG_A2XX_PA_CL_GB_VERT_DISC_ADJ 0x00002304
-#define A2XX_PA_CL_GB_VERT_DISC_ADJ__MASK 0xffffffff
-#define A2XX_PA_CL_GB_VERT_DISC_ADJ__SHIFT 0
-static inline uint32_t A2XX_PA_CL_GB_VERT_DISC_ADJ(float val)
-{
- return ((fui(val)) << A2XX_PA_CL_GB_VERT_DISC_ADJ__SHIFT) & A2XX_PA_CL_GB_VERT_DISC_ADJ__MASK;
-}
-
-#define REG_A2XX_PA_CL_GB_HORZ_CLIP_ADJ 0x00002305
-#define A2XX_PA_CL_GB_HORZ_CLIP_ADJ__MASK 0xffffffff
-#define A2XX_PA_CL_GB_HORZ_CLIP_ADJ__SHIFT 0
-static inline uint32_t A2XX_PA_CL_GB_HORZ_CLIP_ADJ(float val)
-{
- return ((fui(val)) << A2XX_PA_CL_GB_HORZ_CLIP_ADJ__SHIFT) & A2XX_PA_CL_GB_HORZ_CLIP_ADJ__MASK;
-}
-
-#define REG_A2XX_PA_CL_GB_HORZ_DISC_ADJ 0x00002306
-#define A2XX_PA_CL_GB_HORZ_DISC_ADJ__MASK 0xffffffff
-#define A2XX_PA_CL_GB_HORZ_DISC_ADJ__SHIFT 0
-static inline uint32_t A2XX_PA_CL_GB_HORZ_DISC_ADJ(float val)
-{
- return ((fui(val)) << A2XX_PA_CL_GB_HORZ_DISC_ADJ__SHIFT) & A2XX_PA_CL_GB_HORZ_DISC_ADJ__MASK;
-}
-
-#define REG_A2XX_SQ_VS_CONST 0x00002307
-#define A2XX_SQ_VS_CONST_BASE__MASK 0x000001ff
-#define A2XX_SQ_VS_CONST_BASE__SHIFT 0
-static inline uint32_t A2XX_SQ_VS_CONST_BASE(uint32_t val)
-{
- return ((val) << A2XX_SQ_VS_CONST_BASE__SHIFT) & A2XX_SQ_VS_CONST_BASE__MASK;
-}
-#define A2XX_SQ_VS_CONST_SIZE__MASK 0x001ff000
-#define A2XX_SQ_VS_CONST_SIZE__SHIFT 12
-static inline uint32_t A2XX_SQ_VS_CONST_SIZE(uint32_t val)
-{
- return ((val) << A2XX_SQ_VS_CONST_SIZE__SHIFT) & A2XX_SQ_VS_CONST_SIZE__MASK;
-}
-
-#define REG_A2XX_SQ_PS_CONST 0x00002308
-#define A2XX_SQ_PS_CONST_BASE__MASK 0x000001ff
-#define A2XX_SQ_PS_CONST_BASE__SHIFT 0
-static inline uint32_t A2XX_SQ_PS_CONST_BASE(uint32_t val)
-{
- return ((val) << A2XX_SQ_PS_CONST_BASE__SHIFT) & A2XX_SQ_PS_CONST_BASE__MASK;
-}
-#define A2XX_SQ_PS_CONST_SIZE__MASK 0x001ff000
-#define A2XX_SQ_PS_CONST_SIZE__SHIFT 12
-static inline uint32_t A2XX_SQ_PS_CONST_SIZE(uint32_t val)
-{
- return ((val) << A2XX_SQ_PS_CONST_SIZE__SHIFT) & A2XX_SQ_PS_CONST_SIZE__MASK;
-}
-
-#define REG_A2XX_SQ_DEBUG_MISC_0 0x00002309
-
-#define REG_A2XX_SQ_DEBUG_MISC_1 0x0000230a
-
-#define REG_A2XX_PA_SC_AA_MASK 0x00002312
-
-#define REG_A2XX_VGT_VERTEX_REUSE_BLOCK_CNTL 0x00002316
-
-#define REG_A2XX_VGT_OUT_DEALLOC_CNTL 0x00002317
-
-#define REG_A2XX_RB_COPY_CONTROL 0x00002318
-#define A2XX_RB_COPY_CONTROL_COPY_SAMPLE_SELECT__MASK 0x00000007
-#define A2XX_RB_COPY_CONTROL_COPY_SAMPLE_SELECT__SHIFT 0
-static inline uint32_t A2XX_RB_COPY_CONTROL_COPY_SAMPLE_SELECT(enum a2xx_rb_copy_sample_select val)
-{
- return ((val) << A2XX_RB_COPY_CONTROL_COPY_SAMPLE_SELECT__SHIFT) & A2XX_RB_COPY_CONTROL_COPY_SAMPLE_SELECT__MASK;
-}
-#define A2XX_RB_COPY_CONTROL_DEPTH_CLEAR_ENABLE 0x00000008
-#define A2XX_RB_COPY_CONTROL_CLEAR_MASK__MASK 0x000000f0
-#define A2XX_RB_COPY_CONTROL_CLEAR_MASK__SHIFT 4
-static inline uint32_t A2XX_RB_COPY_CONTROL_CLEAR_MASK(uint32_t val)
-{
- return ((val) << A2XX_RB_COPY_CONTROL_CLEAR_MASK__SHIFT) & A2XX_RB_COPY_CONTROL_CLEAR_MASK__MASK;
-}
-
-#define REG_A2XX_RB_COPY_DEST_BASE 0x00002319
-
-#define REG_A2XX_RB_COPY_DEST_PITCH 0x0000231a
-#define A2XX_RB_COPY_DEST_PITCH__MASK 0xffffffff
-#define A2XX_RB_COPY_DEST_PITCH__SHIFT 0
-static inline uint32_t A2XX_RB_COPY_DEST_PITCH(uint32_t val)
-{
- return ((val >> 5) << A2XX_RB_COPY_DEST_PITCH__SHIFT) & A2XX_RB_COPY_DEST_PITCH__MASK;
-}
-
-#define REG_A2XX_RB_COPY_DEST_INFO 0x0000231b
-#define A2XX_RB_COPY_DEST_INFO_DEST_ENDIAN__MASK 0x00000007
-#define A2XX_RB_COPY_DEST_INFO_DEST_ENDIAN__SHIFT 0
-static inline uint32_t A2XX_RB_COPY_DEST_INFO_DEST_ENDIAN(enum adreno_rb_surface_endian val)
-{
- return ((val) << A2XX_RB_COPY_DEST_INFO_DEST_ENDIAN__SHIFT) & A2XX_RB_COPY_DEST_INFO_DEST_ENDIAN__MASK;
-}
-#define A2XX_RB_COPY_DEST_INFO_LINEAR 0x00000008
-#define A2XX_RB_COPY_DEST_INFO_FORMAT__MASK 0x000000f0
-#define A2XX_RB_COPY_DEST_INFO_FORMAT__SHIFT 4
-static inline uint32_t A2XX_RB_COPY_DEST_INFO_FORMAT(enum a2xx_colorformatx val)
-{
- return ((val) << A2XX_RB_COPY_DEST_INFO_FORMAT__SHIFT) & A2XX_RB_COPY_DEST_INFO_FORMAT__MASK;
-}
-#define A2XX_RB_COPY_DEST_INFO_SWAP__MASK 0x00000300
-#define A2XX_RB_COPY_DEST_INFO_SWAP__SHIFT 8
-static inline uint32_t A2XX_RB_COPY_DEST_INFO_SWAP(uint32_t val)
-{
- return ((val) << A2XX_RB_COPY_DEST_INFO_SWAP__SHIFT) & A2XX_RB_COPY_DEST_INFO_SWAP__MASK;
-}
-#define A2XX_RB_COPY_DEST_INFO_DITHER_MODE__MASK 0x00000c00
-#define A2XX_RB_COPY_DEST_INFO_DITHER_MODE__SHIFT 10
-static inline uint32_t A2XX_RB_COPY_DEST_INFO_DITHER_MODE(enum adreno_rb_dither_mode val)
-{
- return ((val) << A2XX_RB_COPY_DEST_INFO_DITHER_MODE__SHIFT) & A2XX_RB_COPY_DEST_INFO_DITHER_MODE__MASK;
-}
-#define A2XX_RB_COPY_DEST_INFO_DITHER_TYPE__MASK 0x00003000
-#define A2XX_RB_COPY_DEST_INFO_DITHER_TYPE__SHIFT 12
-static inline uint32_t A2XX_RB_COPY_DEST_INFO_DITHER_TYPE(enum a2xx_rb_dither_type val)
-{
- return ((val) << A2XX_RB_COPY_DEST_INFO_DITHER_TYPE__SHIFT) & A2XX_RB_COPY_DEST_INFO_DITHER_TYPE__MASK;
-}
-#define A2XX_RB_COPY_DEST_INFO_WRITE_RED 0x00004000
-#define A2XX_RB_COPY_DEST_INFO_WRITE_GREEN 0x00008000
-#define A2XX_RB_COPY_DEST_INFO_WRITE_BLUE 0x00010000
-#define A2XX_RB_COPY_DEST_INFO_WRITE_ALPHA 0x00020000
-
-#define REG_A2XX_RB_COPY_DEST_OFFSET 0x0000231c
-#define A2XX_RB_COPY_DEST_OFFSET_X__MASK 0x00001fff
-#define A2XX_RB_COPY_DEST_OFFSET_X__SHIFT 0
-static inline uint32_t A2XX_RB_COPY_DEST_OFFSET_X(uint32_t val)
-{
- return ((val) << A2XX_RB_COPY_DEST_OFFSET_X__SHIFT) & A2XX_RB_COPY_DEST_OFFSET_X__MASK;
-}
-#define A2XX_RB_COPY_DEST_OFFSET_Y__MASK 0x03ffe000
-#define A2XX_RB_COPY_DEST_OFFSET_Y__SHIFT 13
-static inline uint32_t A2XX_RB_COPY_DEST_OFFSET_Y(uint32_t val)
-{
- return ((val) << A2XX_RB_COPY_DEST_OFFSET_Y__SHIFT) & A2XX_RB_COPY_DEST_OFFSET_Y__MASK;
-}
-
-#define REG_A2XX_RB_DEPTH_CLEAR 0x0000231d
-
-#define REG_A2XX_RB_SAMPLE_COUNT_CTL 0x00002324
-
-#define REG_A2XX_RB_COLOR_DEST_MASK 0x00002326
-
-#define REG_A2XX_A225_GRAS_UCP0X 0x00002340
-
-#define REG_A2XX_A225_GRAS_UCP5W 0x00002357
-
-#define REG_A2XX_A225_GRAS_UCP_ENABLED 0x00002360
-
-#define REG_A2XX_PA_SU_POLY_OFFSET_FRONT_SCALE 0x00002380
-
-#define REG_A2XX_PA_SU_POLY_OFFSET_BACK_OFFSET 0x00002383
-
-#define REG_A2XX_SQ_CONSTANT_0 0x00004000
-
-#define REG_A2XX_SQ_FETCH_0 0x00004800
-
-#define REG_A2XX_SQ_CF_BOOLEANS 0x00004900
-
-#define REG_A2XX_SQ_CF_LOOP 0x00004908
-
-#define REG_A2XX_COHER_SIZE_PM4 0x00000a29
-
-#define REG_A2XX_COHER_BASE_PM4 0x00000a2a
-
-#define REG_A2XX_COHER_STATUS_PM4 0x00000a2b
-
-#define REG_A2XX_SQ_TEX_0 0x00000000
-#define A2XX_SQ_TEX_0_CLAMP_X__MASK 0x00001c00
-#define A2XX_SQ_TEX_0_CLAMP_X__SHIFT 10
-static inline uint32_t A2XX_SQ_TEX_0_CLAMP_X(enum sq_tex_clamp val)
-{
- return ((val) << A2XX_SQ_TEX_0_CLAMP_X__SHIFT) & A2XX_SQ_TEX_0_CLAMP_X__MASK;
-}
-#define A2XX_SQ_TEX_0_CLAMP_Y__MASK 0x0000e000
-#define A2XX_SQ_TEX_0_CLAMP_Y__SHIFT 13
-static inline uint32_t A2XX_SQ_TEX_0_CLAMP_Y(enum sq_tex_clamp val)
-{
- return ((val) << A2XX_SQ_TEX_0_CLAMP_Y__SHIFT) & A2XX_SQ_TEX_0_CLAMP_Y__MASK;
-}
-#define A2XX_SQ_TEX_0_CLAMP_Z__MASK 0x00070000
-#define A2XX_SQ_TEX_0_CLAMP_Z__SHIFT 16
-static inline uint32_t A2XX_SQ_TEX_0_CLAMP_Z(enum sq_tex_clamp val)
-{
- return ((val) << A2XX_SQ_TEX_0_CLAMP_Z__SHIFT) & A2XX_SQ_TEX_0_CLAMP_Z__MASK;
-}
-#define A2XX_SQ_TEX_0_PITCH__MASK 0xffc00000
-#define A2XX_SQ_TEX_0_PITCH__SHIFT 22
-static inline uint32_t A2XX_SQ_TEX_0_PITCH(uint32_t val)
-{
- return ((val >> 5) << A2XX_SQ_TEX_0_PITCH__SHIFT) & A2XX_SQ_TEX_0_PITCH__MASK;
-}
-
-#define REG_A2XX_SQ_TEX_1 0x00000001
-
-#define REG_A2XX_SQ_TEX_2 0x00000002
-#define A2XX_SQ_TEX_2_WIDTH__MASK 0x00001fff
-#define A2XX_SQ_TEX_2_WIDTH__SHIFT 0
-static inline uint32_t A2XX_SQ_TEX_2_WIDTH(uint32_t val)
-{
- return ((val) << A2XX_SQ_TEX_2_WIDTH__SHIFT) & A2XX_SQ_TEX_2_WIDTH__MASK;
-}
-#define A2XX_SQ_TEX_2_HEIGHT__MASK 0x03ffe000
-#define A2XX_SQ_TEX_2_HEIGHT__SHIFT 13
-static inline uint32_t A2XX_SQ_TEX_2_HEIGHT(uint32_t val)
-{
- return ((val) << A2XX_SQ_TEX_2_HEIGHT__SHIFT) & A2XX_SQ_TEX_2_HEIGHT__MASK;
-}
-
-#define REG_A2XX_SQ_TEX_3 0x00000003
-#define A2XX_SQ_TEX_3_SWIZ_X__MASK 0x0000000e
-#define A2XX_SQ_TEX_3_SWIZ_X__SHIFT 1
-static inline uint32_t A2XX_SQ_TEX_3_SWIZ_X(enum sq_tex_swiz val)
-{
- return ((val) << A2XX_SQ_TEX_3_SWIZ_X__SHIFT) & A2XX_SQ_TEX_3_SWIZ_X__MASK;
-}
-#define A2XX_SQ_TEX_3_SWIZ_Y__MASK 0x00000070
-#define A2XX_SQ_TEX_3_SWIZ_Y__SHIFT 4
-static inline uint32_t A2XX_SQ_TEX_3_SWIZ_Y(enum sq_tex_swiz val)
-{
- return ((val) << A2XX_SQ_TEX_3_SWIZ_Y__SHIFT) & A2XX_SQ_TEX_3_SWIZ_Y__MASK;
-}
-#define A2XX_SQ_TEX_3_SWIZ_Z__MASK 0x00000380
-#define A2XX_SQ_TEX_3_SWIZ_Z__SHIFT 7
-static inline uint32_t A2XX_SQ_TEX_3_SWIZ_Z(enum sq_tex_swiz val)
-{
- return ((val) << A2XX_SQ_TEX_3_SWIZ_Z__SHIFT) & A2XX_SQ_TEX_3_SWIZ_Z__MASK;
-}
-#define A2XX_SQ_TEX_3_SWIZ_W__MASK 0x00001c00
-#define A2XX_SQ_TEX_3_SWIZ_W__SHIFT 10
-static inline uint32_t A2XX_SQ_TEX_3_SWIZ_W(enum sq_tex_swiz val)
-{
- return ((val) << A2XX_SQ_TEX_3_SWIZ_W__SHIFT) & A2XX_SQ_TEX_3_SWIZ_W__MASK;
-}
-#define A2XX_SQ_TEX_3_XY_MAG_FILTER__MASK 0x00180000
-#define A2XX_SQ_TEX_3_XY_MAG_FILTER__SHIFT 19
-static inline uint32_t A2XX_SQ_TEX_3_XY_MAG_FILTER(enum sq_tex_filter val)
-{
- return ((val) << A2XX_SQ_TEX_3_XY_MAG_FILTER__SHIFT) & A2XX_SQ_TEX_3_XY_MAG_FILTER__MASK;
-}
-#define A2XX_SQ_TEX_3_XY_MIN_FILTER__MASK 0x00600000
-#define A2XX_SQ_TEX_3_XY_MIN_FILTER__SHIFT 21
-static inline uint32_t A2XX_SQ_TEX_3_XY_MIN_FILTER(enum sq_tex_filter val)
-{
- return ((val) << A2XX_SQ_TEX_3_XY_MIN_FILTER__SHIFT) & A2XX_SQ_TEX_3_XY_MIN_FILTER__MASK;
-}
-
-
-#endif /* A2XX_XML */
--- /dev/null
+include $(top_srcdir)/src/gallium/Automake.inc
+
+noinst_LTLIBRARIES = libfd2xx.la
+
+AM_CFLAGS = \
+ -Wno-packed-bitfield-compat \
+ -I$(top_srcdir)/src/gallium/drivers \
+ -I$(top_srcdir)/src/gallium/drivers/freedreno \
+ $(GALLIUM_CFLAGS) \
+ $(FREEDRENO_CFLAGS) \
+ $(VISIBILITY_CFLAGS)
+
+libfd2xx_la_SOURCES = \
+ fd2_blend.c \
+ fd2_compiler.c \
+ fd2_context.c \
+ fd2_draw.c \
+ fd2_emit.c \
+ fd2_gmem.c \
+ fd2_program.c \
+ fd2_rasterizer.c \
+ fd2_screen.c \
+ fd2_texture.c \
+ fd2_util.c \
+ fd2_zsa.c \
+ disasm-a2xx.c \
+ ir-a2xx.c
--- /dev/null
+#ifndef A2XX_XML
+#define A2XX_XML
+
+/* Autogenerated file, DO NOT EDIT manually!
+
+This file was generated by the rules-ng-ng headergen tool in this git repository:
+http://0x04.net/cgit/index.cgi/rules-ng-ng
+git clone git://0x04.net/rules-ng-ng
+
+The rules-ng-ng source files this header was generated from are:
+- /home/robclark/src/freedreno/envytools/rnndb/a2xx.xml ( 30127 bytes, from 2013-05-05 18:29:35)
+- /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1453 bytes, from 2013-03-31 16:51:27)
+- /home/robclark/src/freedreno/envytools/rnndb/adreno_common.xml ( 3094 bytes, from 2013-05-05 18:29:22)
+- /home/robclark/src/freedreno/envytools/rnndb/adreno_pm4.xml ( 9712 bytes, from 2013-05-26 15:22:37)
+
+Copyright (C) 2013 by the following authors:
+- Rob Clark <robdclark@gmail.com> (robclark)
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice (including the
+next paragraph) shall be included in all copies or substantial
+portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+
+enum a2xx_rb_dither_type {
+ DITHER_PIXEL = 0,
+ DITHER_SUBPIXEL = 1,
+};
+
+enum a2xx_colorformatx {
+ COLORX_4_4_4_4 = 0,
+ COLORX_1_5_5_5 = 1,
+ COLORX_5_6_5 = 2,
+ COLORX_8 = 3,
+ COLORX_8_8 = 4,
+ COLORX_8_8_8_8 = 5,
+ COLORX_S8_8_8_8 = 6,
+ COLORX_16_FLOAT = 7,
+ COLORX_16_16_FLOAT = 8,
+ COLORX_16_16_16_16_FLOAT = 9,
+ COLORX_32_FLOAT = 10,
+ COLORX_32_32_FLOAT = 11,
+ COLORX_32_32_32_32_FLOAT = 12,
+ COLORX_2_3_3 = 13,
+ COLORX_8_8_8 = 14,
+};
+
+enum a2xx_sq_surfaceformat {
+ FMT_1_REVERSE = 0,
+ FMT_1 = 1,
+ FMT_8 = 2,
+ FMT_1_5_5_5 = 3,
+ FMT_5_6_5 = 4,
+ FMT_6_5_5 = 5,
+ FMT_8_8_8_8 = 6,
+ FMT_2_10_10_10 = 7,
+ FMT_8_A = 8,
+ FMT_8_B = 9,
+ FMT_8_8 = 10,
+ FMT_Cr_Y1_Cb_Y0 = 11,
+ FMT_Y1_Cr_Y0_Cb = 12,
+ FMT_5_5_5_1 = 13,
+ FMT_8_8_8_8_A = 14,
+ FMT_4_4_4_4 = 15,
+ FMT_10_11_11 = 16,
+ FMT_11_11_10 = 17,
+ FMT_DXT1 = 18,
+ FMT_DXT2_3 = 19,
+ FMT_DXT4_5 = 20,
+ FMT_24_8 = 22,
+ FMT_24_8_FLOAT = 23,
+ FMT_16 = 24,
+ FMT_16_16 = 25,
+ FMT_16_16_16_16 = 26,
+ FMT_16_EXPAND = 27,
+ FMT_16_16_EXPAND = 28,
+ FMT_16_16_16_16_EXPAND = 29,
+ FMT_16_FLOAT = 30,
+ FMT_16_16_FLOAT = 31,
+ FMT_16_16_16_16_FLOAT = 32,
+ FMT_32 = 33,
+ FMT_32_32 = 34,
+ FMT_32_32_32_32 = 35,
+ FMT_32_FLOAT = 36,
+ FMT_32_32_FLOAT = 37,
+ FMT_32_32_32_32_FLOAT = 38,
+ FMT_32_AS_8 = 39,
+ FMT_32_AS_8_8 = 40,
+ FMT_16_MPEG = 41,
+ FMT_16_16_MPEG = 42,
+ FMT_8_INTERLACED = 43,
+ FMT_32_AS_8_INTERLACED = 44,
+ FMT_32_AS_8_8_INTERLACED = 45,
+ FMT_16_INTERLACED = 46,
+ FMT_16_MPEG_INTERLACED = 47,
+ FMT_16_16_MPEG_INTERLACED = 48,
+ FMT_DXN = 49,
+ FMT_8_8_8_8_AS_16_16_16_16 = 50,
+ FMT_DXT1_AS_16_16_16_16 = 51,
+ FMT_DXT2_3_AS_16_16_16_16 = 52,
+ FMT_DXT4_5_AS_16_16_16_16 = 53,
+ FMT_2_10_10_10_AS_16_16_16_16 = 54,
+ FMT_10_11_11_AS_16_16_16_16 = 55,
+ FMT_11_11_10_AS_16_16_16_16 = 56,
+ FMT_32_32_32_FLOAT = 57,
+ FMT_DXT3A = 58,
+ FMT_DXT5A = 59,
+ FMT_CTX1 = 60,
+ FMT_DXT3A_AS_1_1_1_1 = 61,
+};
+
+enum a2xx_sq_ps_vtx_mode {
+ POSITION_1_VECTOR = 0,
+ POSITION_2_VECTORS_UNUSED = 1,
+ POSITION_2_VECTORS_SPRITE = 2,
+ POSITION_2_VECTORS_EDGE = 3,
+ POSITION_2_VECTORS_KILL = 4,
+ POSITION_2_VECTORS_SPRITE_KILL = 5,
+ POSITION_2_VECTORS_EDGE_KILL = 6,
+ MULTIPASS = 7,
+};
+
+enum a2xx_sq_sample_cntl {
+ CENTROIDS_ONLY = 0,
+ CENTERS_ONLY = 1,
+ CENTROIDS_AND_CENTERS = 2,
+};
+
+enum a2xx_dx_clip_space {
+ DXCLIP_OPENGL = 0,
+ DXCLIP_DIRECTX = 1,
+};
+
+enum a2xx_pa_su_sc_polymode {
+ POLY_DISABLED = 0,
+ POLY_DUALMODE = 1,
+};
+
+enum a2xx_rb_edram_mode {
+ EDRAM_NOP = 0,
+ COLOR_DEPTH = 4,
+ DEPTH_ONLY = 5,
+ EDRAM_COPY = 6,
+};
+
+enum a2xx_pa_sc_pattern_bit_order {
+ LITTLE = 0,
+ BIG = 1,
+};
+
+enum a2xx_pa_sc_auto_reset_cntl {
+ NEVER = 0,
+ EACH_PRIMITIVE = 1,
+ EACH_PACKET = 2,
+};
+
+enum a2xx_pa_pixcenter {
+ PIXCENTER_D3D = 0,
+ PIXCENTER_OGL = 1,
+};
+
+enum a2xx_pa_roundmode {
+ TRUNCATE = 0,
+ ROUND = 1,
+ ROUNDTOEVEN = 2,
+ ROUNDTOODD = 3,
+};
+
+enum a2xx_pa_quantmode {
+ ONE_SIXTEENTH = 0,
+ ONE_EIGTH = 1,
+ ONE_QUARTER = 2,
+ ONE_HALF = 3,
+ ONE = 4,
+};
+
+enum a2xx_rb_copy_sample_select {
+ SAMPLE_0 = 0,
+ SAMPLE_1 = 1,
+ SAMPLE_2 = 2,
+ SAMPLE_3 = 3,
+ SAMPLE_01 = 4,
+ SAMPLE_23 = 5,
+ SAMPLE_0123 = 6,
+};
+
+enum sq_tex_clamp {
+ SQ_TEX_WRAP = 0,
+ SQ_TEX_MIRROR = 1,
+ SQ_TEX_CLAMP_LAST_TEXEL = 2,
+ SQ_TEX_MIRROR_ONCE_LAST_TEXEL = 3,
+ SQ_TEX_CLAMP_HALF_BORDER = 4,
+ SQ_TEX_MIRROR_ONCE_HALF_BORDER = 5,
+ SQ_TEX_CLAMP_BORDER = 6,
+ SQ_TEX_MIRROR_ONCE_BORDER = 7,
+};
+
+enum sq_tex_swiz {
+ SQ_TEX_X = 0,
+ SQ_TEX_Y = 1,
+ SQ_TEX_Z = 2,
+ SQ_TEX_W = 3,
+ SQ_TEX_ZERO = 4,
+ SQ_TEX_ONE = 5,
+};
+
+enum sq_tex_filter {
+ SQ_TEX_FILTER_POINT = 0,
+ SQ_TEX_FILTER_BILINEAR = 1,
+ SQ_TEX_FILTER_BICUBIC = 2,
+};
+
+#define REG_A2XX_RBBM_PATCH_RELEASE 0x00000001
+
+#define REG_A2XX_RBBM_CNTL 0x0000003b
+
+#define REG_A2XX_RBBM_SOFT_RESET 0x0000003c
+
+#define REG_A2XX_CP_PFP_UCODE_ADDR 0x000000c0
+
+#define REG_A2XX_CP_PFP_UCODE_DATA 0x000000c1
+
+#define REG_A2XX_CP_RB_BASE 0x000001c0
+
+#define REG_A2XX_CP_RB_CNTL 0x000001c1
+
+#define REG_A2XX_CP_RB_RPTR_ADDR 0x000001c3
+
+#define REG_A2XX_CP_RB_RPTR 0x000001c4
+
+#define REG_A2XX_CP_RB_WPTR 0x000001c5
+
+#define REG_A2XX_CP_RB_WPTR_DELAY 0x000001c6
+
+#define REG_A2XX_CP_RB_RPTR_WR 0x000001c7
+
+#define REG_A2XX_CP_RB_WPTR_BASE 0x000001c8
+
+#define REG_A2XX_CP_QUEUE_THRESHOLDS 0x000001d5
+
+#define REG_A2XX_SCRATCH_UMSK 0x000001dc
+
+#define REG_A2XX_SCRATCH_ADDR 0x000001dd
+
+#define REG_A2XX_CP_STATE_DEBUG_INDEX 0x000001ec
+
+#define REG_A2XX_CP_STATE_DEBUG_DATA 0x000001ed
+
+#define REG_A2XX_CP_INT_CNTL 0x000001f2
+
+#define REG_A2XX_CP_INT_STATUS 0x000001f3
+
+#define REG_A2XX_CP_INT_ACK 0x000001f4
+
+#define REG_A2XX_CP_ME_CNTL 0x000001f6
+
+#define REG_A2XX_CP_ME_STATUS 0x000001f7
+
+#define REG_A2XX_CP_ME_RAM_WADDR 0x000001f8
+
+#define REG_A2XX_CP_ME_RAM_RADDR 0x000001f9
+
+#define REG_A2XX_CP_ME_RAM_DATA 0x000001fa
+
+#define REG_A2XX_CP_DEBUG 0x000001fc
+
+#define REG_A2XX_CP_CSQ_RB_STAT 0x000001fd
+
+#define REG_A2XX_CP_CSQ_IB1_STAT 0x000001fe
+
+#define REG_A2XX_CP_CSQ_IB2_STAT 0x000001ff
+
+#define REG_A2XX_RBBM_PERFCOUNTER1_SELECT 0x00000395
+
+#define REG_A2XX_RBBM_PERFCOUNTER1_LO 0x00000397
+
+#define REG_A2XX_RBBM_PERFCOUNTER1_HI 0x00000398
+
+#define REG_A2XX_RBBM_DEBUG 0x0000039b
+
+#define REG_A2XX_RBBM_PM_OVERRIDE1 0x0000039c
+
+#define REG_A2XX_RBBM_PM_OVERRIDE2 0x0000039d
+
+#define REG_A2XX_RBBM_DEBUG_OUT 0x000003a0
+
+#define REG_A2XX_RBBM_DEBUG_CNTL 0x000003a1
+
+#define REG_A2XX_RBBM_READ_ERROR 0x000003b3
+
+#define REG_A2XX_RBBM_INT_CNTL 0x000003b4
+
+#define REG_A2XX_RBBM_INT_STATUS 0x000003b5
+
+#define REG_A2XX_RBBM_INT_ACK 0x000003b6
+
+#define REG_A2XX_MASTER_INT_SIGNAL 0x000003b7
+
+#define REG_A2XX_RBBM_PERIPHID1 0x000003f9
+
+#define REG_A2XX_RBBM_PERIPHID2 0x000003fa
+
+#define REG_A2XX_CP_PERFMON_CNTL 0x00000444
+
+#define REG_A2XX_CP_PERFCOUNTER_SELECT 0x00000445
+
+#define REG_A2XX_CP_PERFCOUNTER_LO 0x00000446
+
+#define REG_A2XX_CP_PERFCOUNTER_HI 0x00000447
+
+#define REG_A2XX_CP_ST_BASE 0x0000044d
+
+#define REG_A2XX_CP_ST_BUFSZ 0x0000044e
+
+#define REG_A2XX_CP_IB1_BASE 0x00000458
+
+#define REG_A2XX_CP_IB1_BUFSZ 0x00000459
+
+#define REG_A2XX_CP_IB2_BASE 0x0000045a
+
+#define REG_A2XX_CP_IB2_BUFSZ 0x0000045b
+
+#define REG_A2XX_CP_STAT 0x0000047f
+
+#define REG_A2XX_SCRATCH_REG0 0x00000578
+
+#define REG_A2XX_SCRATCH_REG2 0x0000057a
+
+#define REG_A2XX_RBBM_STATUS 0x000005d0
+
+#define REG_A2XX_A220_VSC_BIN_SIZE 0x00000c01
+#define A2XX_A220_VSC_BIN_SIZE_WIDTH__MASK 0x0000001f
+#define A2XX_A220_VSC_BIN_SIZE_WIDTH__SHIFT 0
+static inline uint32_t A2XX_A220_VSC_BIN_SIZE_WIDTH(uint32_t val)
+{
+ return ((val >> 5) << A2XX_A220_VSC_BIN_SIZE_WIDTH__SHIFT) & A2XX_A220_VSC_BIN_SIZE_WIDTH__MASK;
+}
+#define A2XX_A220_VSC_BIN_SIZE_HEIGHT__MASK 0x000003e0
+#define A2XX_A220_VSC_BIN_SIZE_HEIGHT__SHIFT 5
+static inline uint32_t A2XX_A220_VSC_BIN_SIZE_HEIGHT(uint32_t val)
+{
+ return ((val >> 5) << A2XX_A220_VSC_BIN_SIZE_HEIGHT__SHIFT) & A2XX_A220_VSC_BIN_SIZE_HEIGHT__MASK;
+}
+
+#define REG_A2XX_VSC_PIPE(i0) (0x00000c06 + 0x3*(i0))
+
+#define REG_A2XX_VSC_PIPE_CONFIG(i0) (0x00000c06 + 0x3*(i0))
+
+#define REG_A2XX_VSC_PIPE_DATA_ADDRESS(i0) (0x00000c07 + 0x3*(i0))
+
+#define REG_A2XX_VSC_PIPE_DATA_LENGTH(i0) (0x00000c08 + 0x3*(i0))
+
+#define REG_A2XX_PC_DEBUG_CNTL 0x00000c38
+
+#define REG_A2XX_PC_DEBUG_DATA 0x00000c39
+
+#define REG_A2XX_PA_SC_VIZ_QUERY_STATUS 0x00000c44
+
+#define REG_A2XX_GRAS_DEBUG_CNTL 0x00000c80
+
+#define REG_A2XX_PA_SU_DEBUG_CNTL 0x00000c80
+
+#define REG_A2XX_GRAS_DEBUG_DATA 0x00000c81
+
+#define REG_A2XX_PA_SU_DEBUG_DATA 0x00000c81
+
+#define REG_A2XX_PA_SU_FACE_DATA 0x00000c86
+
+#define REG_A2XX_SQ_GPR_MANAGEMENT 0x00000d00
+
+#define REG_A2XX_SQ_FLOW_CONTROL 0x00000d01
+
+#define REG_A2XX_SQ_INST_STORE_MANAGMENT 0x00000d02
+
+#define REG_A2XX_SQ_DEBUG_MISC 0x00000d05
+
+#define REG_A2XX_SQ_INT_CNTL 0x00000d34
+
+#define REG_A2XX_SQ_INT_STATUS 0x00000d35
+
+#define REG_A2XX_SQ_INT_ACK 0x00000d36
+
+#define REG_A2XX_SQ_DEBUG_INPUT_FSM 0x00000dae
+
+#define REG_A2XX_SQ_DEBUG_CONST_MGR_FSM 0x00000daf
+
+#define REG_A2XX_SQ_DEBUG_TP_FSM 0x00000db0
+
+#define REG_A2XX_SQ_DEBUG_FSM_ALU_0 0x00000db1
+
+#define REG_A2XX_SQ_DEBUG_FSM_ALU_1 0x00000db2
+
+#define REG_A2XX_SQ_DEBUG_EXP_ALLOC 0x00000db3
+
+#define REG_A2XX_SQ_DEBUG_PTR_BUFF 0x00000db4
+
+#define REG_A2XX_SQ_DEBUG_GPR_VTX 0x00000db5
+
+#define REG_A2XX_SQ_DEBUG_GPR_PIX 0x00000db6
+
+#define REG_A2XX_SQ_DEBUG_TB_STATUS_SEL 0x00000db7
+
+#define REG_A2XX_SQ_DEBUG_VTX_TB_0 0x00000db8
+
+#define REG_A2XX_SQ_DEBUG_VTX_TB_1 0x00000db9
+
+#define REG_A2XX_SQ_DEBUG_VTX_TB_STATUS_REG 0x00000dba
+
+#define REG_A2XX_SQ_DEBUG_VTX_TB_STATE_MEM 0x00000dbb
+
+#define REG_A2XX_SQ_DEBUG_PIX_TB_0 0x00000dbc
+
+#define REG_A2XX_SQ_DEBUG_PIX_TB_STATUS_REG_0 0x00000dbd
+
+#define REG_A2XX_SQ_DEBUG_PIX_TB_STATUS_REG_1 0x00000dbe
+
+#define REG_A2XX_SQ_DEBUG_PIX_TB_STATUS_REG_2 0x00000dbf
+
+#define REG_A2XX_SQ_DEBUG_PIX_TB_STATUS_REG_3 0x00000dc0
+
+#define REG_A2XX_SQ_DEBUG_PIX_TB_STATE_MEM 0x00000dc1
+
+#define REG_A2XX_TC_CNTL_STATUS 0x00000e00
+#define A2XX_TC_CNTL_STATUS_L2_INVALIDATE 0x00000001
+
+#define REG_A2XX_TP0_CHICKEN 0x00000e1e
+
+#define REG_A2XX_RB_BC_CONTROL 0x00000f01
+#define A2XX_RB_BC_CONTROL_ACCUM_LINEAR_MODE_ENABLE 0x00000001
+#define A2XX_RB_BC_CONTROL_ACCUM_TIMEOUT_SELECT__MASK 0x00000006
+#define A2XX_RB_BC_CONTROL_ACCUM_TIMEOUT_SELECT__SHIFT 1
+static inline uint32_t A2XX_RB_BC_CONTROL_ACCUM_TIMEOUT_SELECT(uint32_t val)
+{
+ return ((val) << A2XX_RB_BC_CONTROL_ACCUM_TIMEOUT_SELECT__SHIFT) & A2XX_RB_BC_CONTROL_ACCUM_TIMEOUT_SELECT__MASK;
+}
+#define A2XX_RB_BC_CONTROL_DISABLE_EDRAM_CAM 0x00000008
+#define A2XX_RB_BC_CONTROL_DISABLE_EZ_FAST_CONTEXT_SWITCH 0x00000010
+#define A2XX_RB_BC_CONTROL_DISABLE_EZ_NULL_ZCMD_DROP 0x00000020
+#define A2XX_RB_BC_CONTROL_DISABLE_LZ_NULL_ZCMD_DROP 0x00000040
+#define A2XX_RB_BC_CONTROL_ENABLE_AZ_THROTTLE 0x00000080
+#define A2XX_RB_BC_CONTROL_AZ_THROTTLE_COUNT__MASK 0x00001f00
+#define A2XX_RB_BC_CONTROL_AZ_THROTTLE_COUNT__SHIFT 8
+static inline uint32_t A2XX_RB_BC_CONTROL_AZ_THROTTLE_COUNT(uint32_t val)
+{
+ return ((val) << A2XX_RB_BC_CONTROL_AZ_THROTTLE_COUNT__SHIFT) & A2XX_RB_BC_CONTROL_AZ_THROTTLE_COUNT__MASK;
+}
+#define A2XX_RB_BC_CONTROL_ENABLE_CRC_UPDATE 0x00004000
+#define A2XX_RB_BC_CONTROL_CRC_MODE 0x00008000
+#define A2XX_RB_BC_CONTROL_DISABLE_SAMPLE_COUNTERS 0x00010000
+#define A2XX_RB_BC_CONTROL_DISABLE_ACCUM 0x00020000
+#define A2XX_RB_BC_CONTROL_ACCUM_ALLOC_MASK__MASK 0x003c0000
+#define A2XX_RB_BC_CONTROL_ACCUM_ALLOC_MASK__SHIFT 18
+static inline uint32_t A2XX_RB_BC_CONTROL_ACCUM_ALLOC_MASK(uint32_t val)
+{
+ return ((val) << A2XX_RB_BC_CONTROL_ACCUM_ALLOC_MASK__SHIFT) & A2XX_RB_BC_CONTROL_ACCUM_ALLOC_MASK__MASK;
+}
+#define A2XX_RB_BC_CONTROL_LINEAR_PERFORMANCE_ENABLE 0x00400000
+#define A2XX_RB_BC_CONTROL_ACCUM_DATA_FIFO_LIMIT__MASK 0x07800000
+#define A2XX_RB_BC_CONTROL_ACCUM_DATA_FIFO_LIMIT__SHIFT 23
+static inline uint32_t A2XX_RB_BC_CONTROL_ACCUM_DATA_FIFO_LIMIT(uint32_t val)
+{
+ return ((val) << A2XX_RB_BC_CONTROL_ACCUM_DATA_FIFO_LIMIT__SHIFT) & A2XX_RB_BC_CONTROL_ACCUM_DATA_FIFO_LIMIT__MASK;
+}
+#define A2XX_RB_BC_CONTROL_MEM_EXPORT_TIMEOUT_SELECT__MASK 0x18000000
+#define A2XX_RB_BC_CONTROL_MEM_EXPORT_TIMEOUT_SELECT__SHIFT 27
+static inline uint32_t A2XX_RB_BC_CONTROL_MEM_EXPORT_TIMEOUT_SELECT(uint32_t val)
+{
+ return ((val) << A2XX_RB_BC_CONTROL_MEM_EXPORT_TIMEOUT_SELECT__SHIFT) & A2XX_RB_BC_CONTROL_MEM_EXPORT_TIMEOUT_SELECT__MASK;
+}
+#define A2XX_RB_BC_CONTROL_MEM_EXPORT_LINEAR_MODE_ENABLE 0x20000000
+#define A2XX_RB_BC_CONTROL_CRC_SYSTEM 0x40000000
+#define A2XX_RB_BC_CONTROL_RESERVED6 0x80000000
+
+#define REG_A2XX_RB_EDRAM_INFO 0x00000f02
+
+#define REG_A2XX_RB_DEBUG_CNTL 0x00000f26
+
+#define REG_A2XX_RB_DEBUG_DATA 0x00000f27
+
+#define REG_A2XX_RB_SURFACE_INFO 0x00002000
+
+#define REG_A2XX_RB_COLOR_INFO 0x00002001
+#define A2XX_RB_COLOR_INFO_FORMAT__MASK 0x0000000f
+#define A2XX_RB_COLOR_INFO_FORMAT__SHIFT 0
+static inline uint32_t A2XX_RB_COLOR_INFO_FORMAT(enum a2xx_colorformatx val)
+{
+ return ((val) << A2XX_RB_COLOR_INFO_FORMAT__SHIFT) & A2XX_RB_COLOR_INFO_FORMAT__MASK;
+}
+#define A2XX_RB_COLOR_INFO_ROUND_MODE__MASK 0x00000030
+#define A2XX_RB_COLOR_INFO_ROUND_MODE__SHIFT 4
+static inline uint32_t A2XX_RB_COLOR_INFO_ROUND_MODE(uint32_t val)
+{
+ return ((val) << A2XX_RB_COLOR_INFO_ROUND_MODE__SHIFT) & A2XX_RB_COLOR_INFO_ROUND_MODE__MASK;
+}
+#define A2XX_RB_COLOR_INFO_LINEAR 0x00000040
+#define A2XX_RB_COLOR_INFO_ENDIAN__MASK 0x00000180
+#define A2XX_RB_COLOR_INFO_ENDIAN__SHIFT 7
+static inline uint32_t A2XX_RB_COLOR_INFO_ENDIAN(uint32_t val)
+{
+ return ((val) << A2XX_RB_COLOR_INFO_ENDIAN__SHIFT) & A2XX_RB_COLOR_INFO_ENDIAN__MASK;
+}
+#define A2XX_RB_COLOR_INFO_SWAP__MASK 0x00000600
+#define A2XX_RB_COLOR_INFO_SWAP__SHIFT 9
+static inline uint32_t A2XX_RB_COLOR_INFO_SWAP(uint32_t val)
+{
+ return ((val) << A2XX_RB_COLOR_INFO_SWAP__SHIFT) & A2XX_RB_COLOR_INFO_SWAP__MASK;
+}
+#define A2XX_RB_COLOR_INFO_BASE__MASK 0xfffff000
+#define A2XX_RB_COLOR_INFO_BASE__SHIFT 12
+static inline uint32_t A2XX_RB_COLOR_INFO_BASE(uint32_t val)
+{
+ return ((val >> 10) << A2XX_RB_COLOR_INFO_BASE__SHIFT) & A2XX_RB_COLOR_INFO_BASE__MASK;
+}
+
+#define REG_A2XX_RB_DEPTH_INFO 0x00002002
+#define A2XX_RB_DEPTH_INFO_DEPTH_FORMAT__MASK 0x00000001
+#define A2XX_RB_DEPTH_INFO_DEPTH_FORMAT__SHIFT 0
+static inline uint32_t A2XX_RB_DEPTH_INFO_DEPTH_FORMAT(enum adreno_rb_depth_format val)
+{
+ return ((val) << A2XX_RB_DEPTH_INFO_DEPTH_FORMAT__SHIFT) & A2XX_RB_DEPTH_INFO_DEPTH_FORMAT__MASK;
+}
+#define A2XX_RB_DEPTH_INFO_DEPTH_BASE__MASK 0xfffff000
+#define A2XX_RB_DEPTH_INFO_DEPTH_BASE__SHIFT 12
+static inline uint32_t A2XX_RB_DEPTH_INFO_DEPTH_BASE(uint32_t val)
+{
+ return ((val >> 10) << A2XX_RB_DEPTH_INFO_DEPTH_BASE__SHIFT) & A2XX_RB_DEPTH_INFO_DEPTH_BASE__MASK;
+}
+
+#define REG_A2XX_A225_RB_COLOR_INFO3 0x00002005
+
+#define REG_A2XX_COHER_DEST_BASE_0 0x00002006
+
+#define REG_A2XX_PA_SC_SCREEN_SCISSOR_TL 0x0000200e
+#define A2XX_PA_SC_SCREEN_SCISSOR_TL_WINDOW_OFFSET_DISABLE 0x80000000
+#define A2XX_PA_SC_SCREEN_SCISSOR_TL_X__MASK 0x00007fff
+#define A2XX_PA_SC_SCREEN_SCISSOR_TL_X__SHIFT 0
+static inline uint32_t A2XX_PA_SC_SCREEN_SCISSOR_TL_X(uint32_t val)
+{
+ return ((val) << A2XX_PA_SC_SCREEN_SCISSOR_TL_X__SHIFT) & A2XX_PA_SC_SCREEN_SCISSOR_TL_X__MASK;
+}
+#define A2XX_PA_SC_SCREEN_SCISSOR_TL_Y__MASK 0x7fff0000
+#define A2XX_PA_SC_SCREEN_SCISSOR_TL_Y__SHIFT 16
+static inline uint32_t A2XX_PA_SC_SCREEN_SCISSOR_TL_Y(uint32_t val)
+{
+ return ((val) << A2XX_PA_SC_SCREEN_SCISSOR_TL_Y__SHIFT) & A2XX_PA_SC_SCREEN_SCISSOR_TL_Y__MASK;
+}
+
+#define REG_A2XX_PA_SC_SCREEN_SCISSOR_BR 0x0000200f
+#define A2XX_PA_SC_SCREEN_SCISSOR_BR_WINDOW_OFFSET_DISABLE 0x80000000
+#define A2XX_PA_SC_SCREEN_SCISSOR_BR_X__MASK 0x00007fff
+#define A2XX_PA_SC_SCREEN_SCISSOR_BR_X__SHIFT 0
+static inline uint32_t A2XX_PA_SC_SCREEN_SCISSOR_BR_X(uint32_t val)
+{
+ return ((val) << A2XX_PA_SC_SCREEN_SCISSOR_BR_X__SHIFT) & A2XX_PA_SC_SCREEN_SCISSOR_BR_X__MASK;
+}
+#define A2XX_PA_SC_SCREEN_SCISSOR_BR_Y__MASK 0x7fff0000
+#define A2XX_PA_SC_SCREEN_SCISSOR_BR_Y__SHIFT 16
+static inline uint32_t A2XX_PA_SC_SCREEN_SCISSOR_BR_Y(uint32_t val)
+{
+ return ((val) << A2XX_PA_SC_SCREEN_SCISSOR_BR_Y__SHIFT) & A2XX_PA_SC_SCREEN_SCISSOR_BR_Y__MASK;
+}
+
+#define REG_A2XX_PA_SC_WINDOW_OFFSET 0x00002080
+#define A2XX_PA_SC_WINDOW_OFFSET_X__MASK 0x00007fff
+#define A2XX_PA_SC_WINDOW_OFFSET_X__SHIFT 0
+static inline uint32_t A2XX_PA_SC_WINDOW_OFFSET_X(int32_t val)
+{
+ return ((val) << A2XX_PA_SC_WINDOW_OFFSET_X__SHIFT) & A2XX_PA_SC_WINDOW_OFFSET_X__MASK;
+}
+#define A2XX_PA_SC_WINDOW_OFFSET_Y__MASK 0x7fff0000
+#define A2XX_PA_SC_WINDOW_OFFSET_Y__SHIFT 16
+static inline uint32_t A2XX_PA_SC_WINDOW_OFFSET_Y(int32_t val)
+{
+ return ((val) << A2XX_PA_SC_WINDOW_OFFSET_Y__SHIFT) & A2XX_PA_SC_WINDOW_OFFSET_Y__MASK;
+}
+#define A2XX_PA_SC_WINDOW_OFFSET_DISABLE 0x80000000
+
+#define REG_A2XX_PA_SC_WINDOW_SCISSOR_TL 0x00002081
+#define A2XX_PA_SC_WINDOW_SCISSOR_TL_WINDOW_OFFSET_DISABLE 0x80000000
+#define A2XX_PA_SC_WINDOW_SCISSOR_TL_X__MASK 0x00007fff
+#define A2XX_PA_SC_WINDOW_SCISSOR_TL_X__SHIFT 0
+static inline uint32_t A2XX_PA_SC_WINDOW_SCISSOR_TL_X(uint32_t val)
+{
+ return ((val) << A2XX_PA_SC_WINDOW_SCISSOR_TL_X__SHIFT) & A2XX_PA_SC_WINDOW_SCISSOR_TL_X__MASK;
+}
+#define A2XX_PA_SC_WINDOW_SCISSOR_TL_Y__MASK 0x7fff0000
+#define A2XX_PA_SC_WINDOW_SCISSOR_TL_Y__SHIFT 16
+static inline uint32_t A2XX_PA_SC_WINDOW_SCISSOR_TL_Y(uint32_t val)
+{
+ return ((val) << A2XX_PA_SC_WINDOW_SCISSOR_TL_Y__SHIFT) & A2XX_PA_SC_WINDOW_SCISSOR_TL_Y__MASK;
+}
+
+#define REG_A2XX_PA_SC_WINDOW_SCISSOR_BR 0x00002082
+#define A2XX_PA_SC_WINDOW_SCISSOR_BR_WINDOW_OFFSET_DISABLE 0x80000000
+#define A2XX_PA_SC_WINDOW_SCISSOR_BR_X__MASK 0x00007fff
+#define A2XX_PA_SC_WINDOW_SCISSOR_BR_X__SHIFT 0
+static inline uint32_t A2XX_PA_SC_WINDOW_SCISSOR_BR_X(uint32_t val)
+{
+ return ((val) << A2XX_PA_SC_WINDOW_SCISSOR_BR_X__SHIFT) & A2XX_PA_SC_WINDOW_SCISSOR_BR_X__MASK;
+}
+#define A2XX_PA_SC_WINDOW_SCISSOR_BR_Y__MASK 0x7fff0000
+#define A2XX_PA_SC_WINDOW_SCISSOR_BR_Y__SHIFT 16
+static inline uint32_t A2XX_PA_SC_WINDOW_SCISSOR_BR_Y(uint32_t val)
+{
+ return ((val) << A2XX_PA_SC_WINDOW_SCISSOR_BR_Y__SHIFT) & A2XX_PA_SC_WINDOW_SCISSOR_BR_Y__MASK;
+}
+
+#define REG_A2XX_UNKNOWN_2010 0x00002010
+
+#define REG_A2XX_VGT_MAX_VTX_INDX 0x00002100
+
+#define REG_A2XX_VGT_MIN_VTX_INDX 0x00002101
+
+#define REG_A2XX_VGT_INDX_OFFSET 0x00002102
+
+#define REG_A2XX_A225_PC_MULTI_PRIM_IB_RESET_INDX 0x00002103
+
+#define REG_A2XX_RB_COLOR_MASK 0x00002104
+#define A2XX_RB_COLOR_MASK_WRITE_RED 0x00000001
+#define A2XX_RB_COLOR_MASK_WRITE_GREEN 0x00000002
+#define A2XX_RB_COLOR_MASK_WRITE_BLUE 0x00000004
+#define A2XX_RB_COLOR_MASK_WRITE_ALPHA 0x00000008
+
+#define REG_A2XX_RB_BLEND_RED 0x00002105
+
+#define REG_A2XX_RB_BLEND_GREEN 0x00002106
+
+#define REG_A2XX_RB_BLEND_BLUE 0x00002107
+
+#define REG_A2XX_RB_BLEND_ALPHA 0x00002108
+
+#define REG_A2XX_RB_FOG_COLOR 0x00002109
+
+#define REG_A2XX_RB_STENCILREFMASK_BF 0x0000210c
+#define A2XX_RB_STENCILREFMASK_BF_STENCILREF__MASK 0x000000ff
+#define A2XX_RB_STENCILREFMASK_BF_STENCILREF__SHIFT 0
+static inline uint32_t A2XX_RB_STENCILREFMASK_BF_STENCILREF(uint32_t val)
+{
+ return ((val) << A2XX_RB_STENCILREFMASK_BF_STENCILREF__SHIFT) & A2XX_RB_STENCILREFMASK_BF_STENCILREF__MASK;
+}
+#define A2XX_RB_STENCILREFMASK_BF_STENCILMASK__MASK 0x0000ff00
+#define A2XX_RB_STENCILREFMASK_BF_STENCILMASK__SHIFT 8
+static inline uint32_t A2XX_RB_STENCILREFMASK_BF_STENCILMASK(uint32_t val)
+{
+ return ((val) << A2XX_RB_STENCILREFMASK_BF_STENCILMASK__SHIFT) & A2XX_RB_STENCILREFMASK_BF_STENCILMASK__MASK;
+}
+#define A2XX_RB_STENCILREFMASK_BF_STENCILWRITEMASK__MASK 0x00ff0000
+#define A2XX_RB_STENCILREFMASK_BF_STENCILWRITEMASK__SHIFT 16
+static inline uint32_t A2XX_RB_STENCILREFMASK_BF_STENCILWRITEMASK(uint32_t val)
+{
+ return ((val) << A2XX_RB_STENCILREFMASK_BF_STENCILWRITEMASK__SHIFT) & A2XX_RB_STENCILREFMASK_BF_STENCILWRITEMASK__MASK;
+}
+
+#define REG_A2XX_RB_STENCILREFMASK 0x0000210d
+#define A2XX_RB_STENCILREFMASK_STENCILREF__MASK 0x000000ff
+#define A2XX_RB_STENCILREFMASK_STENCILREF__SHIFT 0
+static inline uint32_t A2XX_RB_STENCILREFMASK_STENCILREF(uint32_t val)
+{
+ return ((val) << A2XX_RB_STENCILREFMASK_STENCILREF__SHIFT) & A2XX_RB_STENCILREFMASK_STENCILREF__MASK;
+}
+#define A2XX_RB_STENCILREFMASK_STENCILMASK__MASK 0x0000ff00
+#define A2XX_RB_STENCILREFMASK_STENCILMASK__SHIFT 8
+static inline uint32_t A2XX_RB_STENCILREFMASK_STENCILMASK(uint32_t val)
+{
+ return ((val) << A2XX_RB_STENCILREFMASK_STENCILMASK__SHIFT) & A2XX_RB_STENCILREFMASK_STENCILMASK__MASK;
+}
+#define A2XX_RB_STENCILREFMASK_STENCILWRITEMASK__MASK 0x00ff0000
+#define A2XX_RB_STENCILREFMASK_STENCILWRITEMASK__SHIFT 16
+static inline uint32_t A2XX_RB_STENCILREFMASK_STENCILWRITEMASK(uint32_t val)
+{
+ return ((val) << A2XX_RB_STENCILREFMASK_STENCILWRITEMASK__SHIFT) & A2XX_RB_STENCILREFMASK_STENCILWRITEMASK__MASK;
+}
+
+#define REG_A2XX_RB_ALPHA_REF 0x0000210e
+
+#define REG_A2XX_PA_CL_VPORT_XSCALE 0x0000210f
+#define A2XX_PA_CL_VPORT_XSCALE__MASK 0xffffffff
+#define A2XX_PA_CL_VPORT_XSCALE__SHIFT 0
+static inline uint32_t A2XX_PA_CL_VPORT_XSCALE(float val)
+{
+ return ((fui(val)) << A2XX_PA_CL_VPORT_XSCALE__SHIFT) & A2XX_PA_CL_VPORT_XSCALE__MASK;
+}
+
+#define REG_A2XX_PA_CL_VPORT_XOFFSET 0x00002110
+#define A2XX_PA_CL_VPORT_XOFFSET__MASK 0xffffffff
+#define A2XX_PA_CL_VPORT_XOFFSET__SHIFT 0
+static inline uint32_t A2XX_PA_CL_VPORT_XOFFSET(float val)
+{
+ return ((fui(val)) << A2XX_PA_CL_VPORT_XOFFSET__SHIFT) & A2XX_PA_CL_VPORT_XOFFSET__MASK;
+}
+
+#define REG_A2XX_PA_CL_VPORT_YSCALE 0x00002111
+#define A2XX_PA_CL_VPORT_YSCALE__MASK 0xffffffff
+#define A2XX_PA_CL_VPORT_YSCALE__SHIFT 0
+static inline uint32_t A2XX_PA_CL_VPORT_YSCALE(float val)
+{
+ return ((fui(val)) << A2XX_PA_CL_VPORT_YSCALE__SHIFT) & A2XX_PA_CL_VPORT_YSCALE__MASK;
+}
+
+#define REG_A2XX_PA_CL_VPORT_YOFFSET 0x00002112
+#define A2XX_PA_CL_VPORT_YOFFSET__MASK 0xffffffff
+#define A2XX_PA_CL_VPORT_YOFFSET__SHIFT 0
+static inline uint32_t A2XX_PA_CL_VPORT_YOFFSET(float val)
+{
+ return ((fui(val)) << A2XX_PA_CL_VPORT_YOFFSET__SHIFT) & A2XX_PA_CL_VPORT_YOFFSET__MASK;
+}
+
+#define REG_A2XX_PA_CL_VPORT_ZSCALE 0x00002113
+#define A2XX_PA_CL_VPORT_ZSCALE__MASK 0xffffffff
+#define A2XX_PA_CL_VPORT_ZSCALE__SHIFT 0
+static inline uint32_t A2XX_PA_CL_VPORT_ZSCALE(float val)
+{
+ return ((fui(val)) << A2XX_PA_CL_VPORT_ZSCALE__SHIFT) & A2XX_PA_CL_VPORT_ZSCALE__MASK;
+}
+
+#define REG_A2XX_PA_CL_VPORT_ZOFFSET 0x00002114
+#define A2XX_PA_CL_VPORT_ZOFFSET__MASK 0xffffffff
+#define A2XX_PA_CL_VPORT_ZOFFSET__SHIFT 0
+static inline uint32_t A2XX_PA_CL_VPORT_ZOFFSET(float val)
+{
+ return ((fui(val)) << A2XX_PA_CL_VPORT_ZOFFSET__SHIFT) & A2XX_PA_CL_VPORT_ZOFFSET__MASK;
+}
+
+#define REG_A2XX_SQ_PROGRAM_CNTL 0x00002180
+#define A2XX_SQ_PROGRAM_CNTL_VS_REGS__MASK 0x000000ff
+#define A2XX_SQ_PROGRAM_CNTL_VS_REGS__SHIFT 0
+static inline uint32_t A2XX_SQ_PROGRAM_CNTL_VS_REGS(uint32_t val)
+{
+ return ((val) << A2XX_SQ_PROGRAM_CNTL_VS_REGS__SHIFT) & A2XX_SQ_PROGRAM_CNTL_VS_REGS__MASK;
+}
+#define A2XX_SQ_PROGRAM_CNTL_PS_REGS__MASK 0x0000ff00
+#define A2XX_SQ_PROGRAM_CNTL_PS_REGS__SHIFT 8
+static inline uint32_t A2XX_SQ_PROGRAM_CNTL_PS_REGS(uint32_t val)
+{
+ return ((val) << A2XX_SQ_PROGRAM_CNTL_PS_REGS__SHIFT) & A2XX_SQ_PROGRAM_CNTL_PS_REGS__MASK;
+}
+#define A2XX_SQ_PROGRAM_CNTL_VS_RESOURCE 0x00010000
+#define A2XX_SQ_PROGRAM_CNTL_PS_RESOURCE 0x00020000
+#define A2XX_SQ_PROGRAM_CNTL_PARAM_GEN 0x00040000
+#define A2XX_SQ_PROGRAM_CNTL_GEN_INDEX_PIX 0x00080000
+#define A2XX_SQ_PROGRAM_CNTL_VS_EXPORT_COUNT__MASK 0x00f00000
+#define A2XX_SQ_PROGRAM_CNTL_VS_EXPORT_COUNT__SHIFT 20
+static inline uint32_t A2XX_SQ_PROGRAM_CNTL_VS_EXPORT_COUNT(uint32_t val)
+{
+ return ((val) << A2XX_SQ_PROGRAM_CNTL_VS_EXPORT_COUNT__SHIFT) & A2XX_SQ_PROGRAM_CNTL_VS_EXPORT_COUNT__MASK;
+}
+#define A2XX_SQ_PROGRAM_CNTL_VS_EXPORT_MODE__MASK 0x07000000
+#define A2XX_SQ_PROGRAM_CNTL_VS_EXPORT_MODE__SHIFT 24
+static inline uint32_t A2XX_SQ_PROGRAM_CNTL_VS_EXPORT_MODE(enum a2xx_sq_ps_vtx_mode val)
+{
+ return ((val) << A2XX_SQ_PROGRAM_CNTL_VS_EXPORT_MODE__SHIFT) & A2XX_SQ_PROGRAM_CNTL_VS_EXPORT_MODE__MASK;
+}
+#define A2XX_SQ_PROGRAM_CNTL_PS_EXPORT_MODE__MASK 0x78000000
+#define A2XX_SQ_PROGRAM_CNTL_PS_EXPORT_MODE__SHIFT 27
+static inline uint32_t A2XX_SQ_PROGRAM_CNTL_PS_EXPORT_MODE(uint32_t val)
+{
+ return ((val) << A2XX_SQ_PROGRAM_CNTL_PS_EXPORT_MODE__SHIFT) & A2XX_SQ_PROGRAM_CNTL_PS_EXPORT_MODE__MASK;
+}
+#define A2XX_SQ_PROGRAM_CNTL_GEN_INDEX_VTX 0x80000000
+
+#define REG_A2XX_SQ_CONTEXT_MISC 0x00002181
+#define A2XX_SQ_CONTEXT_MISC_INST_PRED_OPTIMIZE 0x00000001
+#define A2XX_SQ_CONTEXT_MISC_SC_OUTPUT_SCREEN_XY 0x00000002
+#define A2XX_SQ_CONTEXT_MISC_SC_SAMPLE_CNTL__MASK 0x0000000c
+#define A2XX_SQ_CONTEXT_MISC_SC_SAMPLE_CNTL__SHIFT 2
+static inline uint32_t A2XX_SQ_CONTEXT_MISC_SC_SAMPLE_CNTL(enum a2xx_sq_sample_cntl val)
+{
+ return ((val) << A2XX_SQ_CONTEXT_MISC_SC_SAMPLE_CNTL__SHIFT) & A2XX_SQ_CONTEXT_MISC_SC_SAMPLE_CNTL__MASK;
+}
+#define A2XX_SQ_CONTEXT_MISC_PARAM_GEN_POS__MASK 0x0000ff00
+#define A2XX_SQ_CONTEXT_MISC_PARAM_GEN_POS__SHIFT 8
+static inline uint32_t A2XX_SQ_CONTEXT_MISC_PARAM_GEN_POS(uint32_t val)
+{
+ return ((val) << A2XX_SQ_CONTEXT_MISC_PARAM_GEN_POS__SHIFT) & A2XX_SQ_CONTEXT_MISC_PARAM_GEN_POS__MASK;
+}
+#define A2XX_SQ_CONTEXT_MISC_PERFCOUNTER_REF 0x00010000
+#define A2XX_SQ_CONTEXT_MISC_YEILD_OPTIMIZE 0x00020000
+#define A2XX_SQ_CONTEXT_MISC_TX_CACHE_SEL 0x00040000
+
+#define REG_A2XX_SQ_INTERPOLATOR_CNTL 0x00002182
+
+#define REG_A2XX_SQ_WRAPPING_0 0x00002183
+
+#define REG_A2XX_SQ_WRAPPING_1 0x00002184
+
+#define REG_A2XX_SQ_PS_PROGRAM 0x000021f6
+
+#define REG_A2XX_SQ_VS_PROGRAM 0x000021f7
+
+#define REG_A2XX_RB_DEPTHCONTROL 0x00002200
+#define A2XX_RB_DEPTHCONTROL_STENCIL_ENABLE 0x00000001
+#define A2XX_RB_DEPTHCONTROL_Z_ENABLE 0x00000002
+#define A2XX_RB_DEPTHCONTROL_Z_WRITE_ENABLE 0x00000004
+#define A2XX_RB_DEPTHCONTROL_EARLY_Z_ENABLE 0x00000008
+#define A2XX_RB_DEPTHCONTROL_ZFUNC__MASK 0x00000070
+#define A2XX_RB_DEPTHCONTROL_ZFUNC__SHIFT 4
+static inline uint32_t A2XX_RB_DEPTHCONTROL_ZFUNC(enum adreno_compare_func val)
+{
+ return ((val) << A2XX_RB_DEPTHCONTROL_ZFUNC__SHIFT) & A2XX_RB_DEPTHCONTROL_ZFUNC__MASK;
+}
+#define A2XX_RB_DEPTHCONTROL_BACKFACE_ENABLE 0x00000080
+#define A2XX_RB_DEPTHCONTROL_STENCILFUNC__MASK 0x00000700
+#define A2XX_RB_DEPTHCONTROL_STENCILFUNC__SHIFT 8
+static inline uint32_t A2XX_RB_DEPTHCONTROL_STENCILFUNC(enum adreno_compare_func val)
+{
+ return ((val) << A2XX_RB_DEPTHCONTROL_STENCILFUNC__SHIFT) & A2XX_RB_DEPTHCONTROL_STENCILFUNC__MASK;
+}
+#define A2XX_RB_DEPTHCONTROL_STENCILFAIL__MASK 0x00003800
+#define A2XX_RB_DEPTHCONTROL_STENCILFAIL__SHIFT 11
+static inline uint32_t A2XX_RB_DEPTHCONTROL_STENCILFAIL(enum adreno_stencil_op val)
+{
+ return ((val) << A2XX_RB_DEPTHCONTROL_STENCILFAIL__SHIFT) & A2XX_RB_DEPTHCONTROL_STENCILFAIL__MASK;
+}
+#define A2XX_RB_DEPTHCONTROL_STENCILZPASS__MASK 0x0001c000
+#define A2XX_RB_DEPTHCONTROL_STENCILZPASS__SHIFT 14
+static inline uint32_t A2XX_RB_DEPTHCONTROL_STENCILZPASS(enum adreno_stencil_op val)
+{
+ return ((val) << A2XX_RB_DEPTHCONTROL_STENCILZPASS__SHIFT) & A2XX_RB_DEPTHCONTROL_STENCILZPASS__MASK;
+}
+#define A2XX_RB_DEPTHCONTROL_STENCILZFAIL__MASK 0x000e0000
+#define A2XX_RB_DEPTHCONTROL_STENCILZFAIL__SHIFT 17
+static inline uint32_t A2XX_RB_DEPTHCONTROL_STENCILZFAIL(enum adreno_stencil_op val)
+{
+ return ((val) << A2XX_RB_DEPTHCONTROL_STENCILZFAIL__SHIFT) & A2XX_RB_DEPTHCONTROL_STENCILZFAIL__MASK;
+}
+#define A2XX_RB_DEPTHCONTROL_STENCILFUNC_BF__MASK 0x00700000
+#define A2XX_RB_DEPTHCONTROL_STENCILFUNC_BF__SHIFT 20
+static inline uint32_t A2XX_RB_DEPTHCONTROL_STENCILFUNC_BF(enum adreno_compare_func val)
+{
+ return ((val) << A2XX_RB_DEPTHCONTROL_STENCILFUNC_BF__SHIFT) & A2XX_RB_DEPTHCONTROL_STENCILFUNC_BF__MASK;
+}
+#define A2XX_RB_DEPTHCONTROL_STENCILFAIL_BF__MASK 0x03800000
+#define A2XX_RB_DEPTHCONTROL_STENCILFAIL_BF__SHIFT 23
+static inline uint32_t A2XX_RB_DEPTHCONTROL_STENCILFAIL_BF(enum adreno_stencil_op val)
+{
+ return ((val) << A2XX_RB_DEPTHCONTROL_STENCILFAIL_BF__SHIFT) & A2XX_RB_DEPTHCONTROL_STENCILFAIL_BF__MASK;
+}
+#define A2XX_RB_DEPTHCONTROL_STENCILZPASS_BF__MASK 0x1c000000
+#define A2XX_RB_DEPTHCONTROL_STENCILZPASS_BF__SHIFT 26
+static inline uint32_t A2XX_RB_DEPTHCONTROL_STENCILZPASS_BF(enum adreno_stencil_op val)
+{
+ return ((val) << A2XX_RB_DEPTHCONTROL_STENCILZPASS_BF__SHIFT) & A2XX_RB_DEPTHCONTROL_STENCILZPASS_BF__MASK;
+}
+#define A2XX_RB_DEPTHCONTROL_STENCILZFAIL_BF__MASK 0xe0000000
+#define A2XX_RB_DEPTHCONTROL_STENCILZFAIL_BF__SHIFT 29
+static inline uint32_t A2XX_RB_DEPTHCONTROL_STENCILZFAIL_BF(enum adreno_stencil_op val)
+{
+ return ((val) << A2XX_RB_DEPTHCONTROL_STENCILZFAIL_BF__SHIFT) & A2XX_RB_DEPTHCONTROL_STENCILZFAIL_BF__MASK;
+}
+
+#define REG_A2XX_RB_BLEND_CONTROL 0x00002201
+#define A2XX_RB_BLEND_CONTROL_COLOR_SRCBLEND__MASK 0x0000001f
+#define A2XX_RB_BLEND_CONTROL_COLOR_SRCBLEND__SHIFT 0
+static inline uint32_t A2XX_RB_BLEND_CONTROL_COLOR_SRCBLEND(enum adreno_rb_blend_factor val)
+{
+ return ((val) << A2XX_RB_BLEND_CONTROL_COLOR_SRCBLEND__SHIFT) & A2XX_RB_BLEND_CONTROL_COLOR_SRCBLEND__MASK;
+}
+#define A2XX_RB_BLEND_CONTROL_COLOR_COMB_FCN__MASK 0x000000e0
+#define A2XX_RB_BLEND_CONTROL_COLOR_COMB_FCN__SHIFT 5
+static inline uint32_t A2XX_RB_BLEND_CONTROL_COLOR_COMB_FCN(enum adreno_rb_blend_opcode val)
+{
+ return ((val) << A2XX_RB_BLEND_CONTROL_COLOR_COMB_FCN__SHIFT) & A2XX_RB_BLEND_CONTROL_COLOR_COMB_FCN__MASK;
+}
+#define A2XX_RB_BLEND_CONTROL_COLOR_DESTBLEND__MASK 0x00001f00
+#define A2XX_RB_BLEND_CONTROL_COLOR_DESTBLEND__SHIFT 8
+static inline uint32_t A2XX_RB_BLEND_CONTROL_COLOR_DESTBLEND(enum adreno_rb_blend_factor val)
+{
+ return ((val) << A2XX_RB_BLEND_CONTROL_COLOR_DESTBLEND__SHIFT) & A2XX_RB_BLEND_CONTROL_COLOR_DESTBLEND__MASK;
+}
+#define A2XX_RB_BLEND_CONTROL_ALPHA_SRCBLEND__MASK 0x001f0000
+#define A2XX_RB_BLEND_CONTROL_ALPHA_SRCBLEND__SHIFT 16
+static inline uint32_t A2XX_RB_BLEND_CONTROL_ALPHA_SRCBLEND(enum adreno_rb_blend_factor val)
+{
+ return ((val) << A2XX_RB_BLEND_CONTROL_ALPHA_SRCBLEND__SHIFT) & A2XX_RB_BLEND_CONTROL_ALPHA_SRCBLEND__MASK;
+}
+#define A2XX_RB_BLEND_CONTROL_ALPHA_COMB_FCN__MASK 0x00e00000
+#define A2XX_RB_BLEND_CONTROL_ALPHA_COMB_FCN__SHIFT 21
+static inline uint32_t A2XX_RB_BLEND_CONTROL_ALPHA_COMB_FCN(enum adreno_rb_blend_opcode val)
+{
+ return ((val) << A2XX_RB_BLEND_CONTROL_ALPHA_COMB_FCN__SHIFT) & A2XX_RB_BLEND_CONTROL_ALPHA_COMB_FCN__MASK;
+}
+#define A2XX_RB_BLEND_CONTROL_ALPHA_DESTBLEND__MASK 0x1f000000
+#define A2XX_RB_BLEND_CONTROL_ALPHA_DESTBLEND__SHIFT 24
+static inline uint32_t A2XX_RB_BLEND_CONTROL_ALPHA_DESTBLEND(enum adreno_rb_blend_factor val)
+{
+ return ((val) << A2XX_RB_BLEND_CONTROL_ALPHA_DESTBLEND__SHIFT) & A2XX_RB_BLEND_CONTROL_ALPHA_DESTBLEND__MASK;
+}
+#define A2XX_RB_BLEND_CONTROL_BLEND_FORCE_ENABLE 0x20000000
+#define A2XX_RB_BLEND_CONTROL_BLEND_FORCE 0x40000000
+
+#define REG_A2XX_RB_COLORCONTROL 0x00002202
+#define A2XX_RB_COLORCONTROL_ALPHA_FUNC__MASK 0x00000007
+#define A2XX_RB_COLORCONTROL_ALPHA_FUNC__SHIFT 0
+static inline uint32_t A2XX_RB_COLORCONTROL_ALPHA_FUNC(enum adreno_compare_func val)
+{
+ return ((val) << A2XX_RB_COLORCONTROL_ALPHA_FUNC__SHIFT) & A2XX_RB_COLORCONTROL_ALPHA_FUNC__MASK;
+}
+#define A2XX_RB_COLORCONTROL_ALPHA_TEST_ENABLE 0x00000008
+#define A2XX_RB_COLORCONTROL_ALPHA_TO_MASK_ENABLE 0x00000010
+#define A2XX_RB_COLORCONTROL_BLEND_DISABLE 0x00000020
+#define A2XX_RB_COLORCONTROL_VOB_ENABLE 0x00000040
+#define A2XX_RB_COLORCONTROL_VS_EXPORTS_FOG 0x00000080
+#define A2XX_RB_COLORCONTROL_ROP_CODE__MASK 0x00000f00
+#define A2XX_RB_COLORCONTROL_ROP_CODE__SHIFT 8
+static inline uint32_t A2XX_RB_COLORCONTROL_ROP_CODE(uint32_t val)
+{
+ return ((val) << A2XX_RB_COLORCONTROL_ROP_CODE__SHIFT) & A2XX_RB_COLORCONTROL_ROP_CODE__MASK;
+}
+#define A2XX_RB_COLORCONTROL_DITHER_MODE__MASK 0x00003000
+#define A2XX_RB_COLORCONTROL_DITHER_MODE__SHIFT 12
+static inline uint32_t A2XX_RB_COLORCONTROL_DITHER_MODE(enum adreno_rb_dither_mode val)
+{
+ return ((val) << A2XX_RB_COLORCONTROL_DITHER_MODE__SHIFT) & A2XX_RB_COLORCONTROL_DITHER_MODE__MASK;
+}
+#define A2XX_RB_COLORCONTROL_DITHER_TYPE__MASK 0x0000c000
+#define A2XX_RB_COLORCONTROL_DITHER_TYPE__SHIFT 14
+static inline uint32_t A2XX_RB_COLORCONTROL_DITHER_TYPE(enum a2xx_rb_dither_type val)
+{
+ return ((val) << A2XX_RB_COLORCONTROL_DITHER_TYPE__SHIFT) & A2XX_RB_COLORCONTROL_DITHER_TYPE__MASK;
+}
+#define A2XX_RB_COLORCONTROL_PIXEL_FOG 0x00010000
+#define A2XX_RB_COLORCONTROL_ALPHA_TO_MASK_OFFSET0__MASK 0x03000000
+#define A2XX_RB_COLORCONTROL_ALPHA_TO_MASK_OFFSET0__SHIFT 24
+static inline uint32_t A2XX_RB_COLORCONTROL_ALPHA_TO_MASK_OFFSET0(uint32_t val)
+{
+ return ((val) << A2XX_RB_COLORCONTROL_ALPHA_TO_MASK_OFFSET0__SHIFT) & A2XX_RB_COLORCONTROL_ALPHA_TO_MASK_OFFSET0__MASK;
+}
+#define A2XX_RB_COLORCONTROL_ALPHA_TO_MASK_OFFSET1__MASK 0x0c000000
+#define A2XX_RB_COLORCONTROL_ALPHA_TO_MASK_OFFSET1__SHIFT 26
+static inline uint32_t A2XX_RB_COLORCONTROL_ALPHA_TO_MASK_OFFSET1(uint32_t val)
+{
+ return ((val) << A2XX_RB_COLORCONTROL_ALPHA_TO_MASK_OFFSET1__SHIFT) & A2XX_RB_COLORCONTROL_ALPHA_TO_MASK_OFFSET1__MASK;
+}
+#define A2XX_RB_COLORCONTROL_ALPHA_TO_MASK_OFFSET2__MASK 0x30000000
+#define A2XX_RB_COLORCONTROL_ALPHA_TO_MASK_OFFSET2__SHIFT 28
+static inline uint32_t A2XX_RB_COLORCONTROL_ALPHA_TO_MASK_OFFSET2(uint32_t val)
+{
+ return ((val) << A2XX_RB_COLORCONTROL_ALPHA_TO_MASK_OFFSET2__SHIFT) & A2XX_RB_COLORCONTROL_ALPHA_TO_MASK_OFFSET2__MASK;
+}
+#define A2XX_RB_COLORCONTROL_ALPHA_TO_MASK_OFFSET3__MASK 0xc0000000
+#define A2XX_RB_COLORCONTROL_ALPHA_TO_MASK_OFFSET3__SHIFT 30
+static inline uint32_t A2XX_RB_COLORCONTROL_ALPHA_TO_MASK_OFFSET3(uint32_t val)
+{
+ return ((val) << A2XX_RB_COLORCONTROL_ALPHA_TO_MASK_OFFSET3__SHIFT) & A2XX_RB_COLORCONTROL_ALPHA_TO_MASK_OFFSET3__MASK;
+}
+
+#define REG_A2XX_VGT_CURRENT_BIN_ID_MAX 0x00002203
+#define A2XX_VGT_CURRENT_BIN_ID_MAX_COLUMN__MASK 0x00000007
+#define A2XX_VGT_CURRENT_BIN_ID_MAX_COLUMN__SHIFT 0
+static inline uint32_t A2XX_VGT_CURRENT_BIN_ID_MAX_COLUMN(uint32_t val)
+{
+ return ((val) << A2XX_VGT_CURRENT_BIN_ID_MAX_COLUMN__SHIFT) & A2XX_VGT_CURRENT_BIN_ID_MAX_COLUMN__MASK;
+}
+#define A2XX_VGT_CURRENT_BIN_ID_MAX_ROW__MASK 0x00000038
+#define A2XX_VGT_CURRENT_BIN_ID_MAX_ROW__SHIFT 3
+static inline uint32_t A2XX_VGT_CURRENT_BIN_ID_MAX_ROW(uint32_t val)
+{
+ return ((val) << A2XX_VGT_CURRENT_BIN_ID_MAX_ROW__SHIFT) & A2XX_VGT_CURRENT_BIN_ID_MAX_ROW__MASK;
+}
+#define A2XX_VGT_CURRENT_BIN_ID_MAX_GUARD_BAND_MASK__MASK 0x000001c0
+#define A2XX_VGT_CURRENT_BIN_ID_MAX_GUARD_BAND_MASK__SHIFT 6
+static inline uint32_t A2XX_VGT_CURRENT_BIN_ID_MAX_GUARD_BAND_MASK(uint32_t val)
+{
+ return ((val) << A2XX_VGT_CURRENT_BIN_ID_MAX_GUARD_BAND_MASK__SHIFT) & A2XX_VGT_CURRENT_BIN_ID_MAX_GUARD_BAND_MASK__MASK;
+}
+
+#define REG_A2XX_PA_CL_CLIP_CNTL 0x00002204
+#define A2XX_PA_CL_CLIP_CNTL_CLIP_DISABLE 0x00010000
+#define A2XX_PA_CL_CLIP_CNTL_BOUNDARY_EDGE_FLAG_ENA 0x00040000
+#define A2XX_PA_CL_CLIP_CNTL_DX_CLIP_SPACE_DEF__MASK 0x00080000
+#define A2XX_PA_CL_CLIP_CNTL_DX_CLIP_SPACE_DEF__SHIFT 19
+static inline uint32_t A2XX_PA_CL_CLIP_CNTL_DX_CLIP_SPACE_DEF(enum a2xx_dx_clip_space val)
+{
+ return ((val) << A2XX_PA_CL_CLIP_CNTL_DX_CLIP_SPACE_DEF__SHIFT) & A2XX_PA_CL_CLIP_CNTL_DX_CLIP_SPACE_DEF__MASK;
+}
+#define A2XX_PA_CL_CLIP_CNTL_DIS_CLIP_ERR_DETECT 0x00100000
+#define A2XX_PA_CL_CLIP_CNTL_VTX_KILL_OR 0x00200000
+#define A2XX_PA_CL_CLIP_CNTL_XY_NAN_RETAIN 0x00400000
+#define A2XX_PA_CL_CLIP_CNTL_Z_NAN_RETAIN 0x00800000
+#define A2XX_PA_CL_CLIP_CNTL_W_NAN_RETAIN 0x01000000
+
+#define REG_A2XX_PA_SU_SC_MODE_CNTL 0x00002205
+#define A2XX_PA_SU_SC_MODE_CNTL_CULL_FRONT 0x00000001
+#define A2XX_PA_SU_SC_MODE_CNTL_CULL_BACK 0x00000002
+#define A2XX_PA_SU_SC_MODE_CNTL_FACE 0x00000004
+#define A2XX_PA_SU_SC_MODE_CNTL_POLYMODE__MASK 0x00000018
+#define A2XX_PA_SU_SC_MODE_CNTL_POLYMODE__SHIFT 3
+static inline uint32_t A2XX_PA_SU_SC_MODE_CNTL_POLYMODE(enum a2xx_pa_su_sc_polymode val)
+{
+ return ((val) << A2XX_PA_SU_SC_MODE_CNTL_POLYMODE__SHIFT) & A2XX_PA_SU_SC_MODE_CNTL_POLYMODE__MASK;
+}
+#define A2XX_PA_SU_SC_MODE_CNTL_FRONT_PTYPE__MASK 0x000000e0
+#define A2XX_PA_SU_SC_MODE_CNTL_FRONT_PTYPE__SHIFT 5
+static inline uint32_t A2XX_PA_SU_SC_MODE_CNTL_FRONT_PTYPE(enum adreno_pa_su_sc_draw val)
+{
+ return ((val) << A2XX_PA_SU_SC_MODE_CNTL_FRONT_PTYPE__SHIFT) & A2XX_PA_SU_SC_MODE_CNTL_FRONT_PTYPE__MASK;
+}
+#define A2XX_PA_SU_SC_MODE_CNTL_BACK_PTYPE__MASK 0x00000700
+#define A2XX_PA_SU_SC_MODE_CNTL_BACK_PTYPE__SHIFT 8
+static inline uint32_t A2XX_PA_SU_SC_MODE_CNTL_BACK_PTYPE(enum adreno_pa_su_sc_draw val)
+{
+ return ((val) << A2XX_PA_SU_SC_MODE_CNTL_BACK_PTYPE__SHIFT) & A2XX_PA_SU_SC_MODE_CNTL_BACK_PTYPE__MASK;
+}
+#define A2XX_PA_SU_SC_MODE_CNTL_POLY_OFFSET_FRONT_ENABLE 0x00000800
+#define A2XX_PA_SU_SC_MODE_CNTL_POLY_OFFSET_BACK_ENABLE 0x00001000
+#define A2XX_PA_SU_SC_MODE_CNTL_POLY_OFFSET_PARA_ENABLE 0x00002000
+#define A2XX_PA_SU_SC_MODE_CNTL_MSAA_ENABLE 0x00008000
+#define A2XX_PA_SU_SC_MODE_CNTL_VTX_WINDOW_OFFSET_ENABLE 0x00010000
+#define A2XX_PA_SU_SC_MODE_CNTL_LINE_STIPPLE_ENABLE 0x00040000
+#define A2XX_PA_SU_SC_MODE_CNTL_PROVOKING_VTX_LAST 0x00080000
+#define A2XX_PA_SU_SC_MODE_CNTL_PERSP_CORR_DIS 0x00100000
+#define A2XX_PA_SU_SC_MODE_CNTL_MULTI_PRIM_IB_ENA 0x00200000
+#define A2XX_PA_SU_SC_MODE_CNTL_QUAD_ORDER_ENABLE 0x00800000
+#define A2XX_PA_SU_SC_MODE_CNTL_WAIT_RB_IDLE_ALL_TRI 0x02000000
+#define A2XX_PA_SU_SC_MODE_CNTL_WAIT_RB_IDLE_FIRST_TRI_NEW_STATE 0x04000000
+#define A2XX_PA_SU_SC_MODE_CNTL_CLAMPED_FACENESS 0x10000000
+#define A2XX_PA_SU_SC_MODE_CNTL_ZERO_AREA_FACENESS 0x20000000
+#define A2XX_PA_SU_SC_MODE_CNTL_FACE_KILL_ENABLE 0x40000000
+#define A2XX_PA_SU_SC_MODE_CNTL_FACE_WRITE_ENABLE 0x80000000
+
+#define REG_A2XX_PA_CL_VTE_CNTL 0x00002206
+#define A2XX_PA_CL_VTE_CNTL_VPORT_X_SCALE_ENA 0x00000001
+#define A2XX_PA_CL_VTE_CNTL_VPORT_X_OFFSET_ENA 0x00000002
+#define A2XX_PA_CL_VTE_CNTL_VPORT_Y_SCALE_ENA 0x00000004
+#define A2XX_PA_CL_VTE_CNTL_VPORT_Y_OFFSET_ENA 0x00000008
+#define A2XX_PA_CL_VTE_CNTL_VPORT_Z_SCALE_ENA 0x00000010
+#define A2XX_PA_CL_VTE_CNTL_VPORT_Z_OFFSET_ENA 0x00000020
+#define A2XX_PA_CL_VTE_CNTL_VTX_XY_FMT 0x00000100
+#define A2XX_PA_CL_VTE_CNTL_VTX_Z_FMT 0x00000200
+#define A2XX_PA_CL_VTE_CNTL_VTX_W0_FMT 0x00000400
+#define A2XX_PA_CL_VTE_CNTL_PERFCOUNTER_REF 0x00000800
+
+#define REG_A2XX_VGT_CURRENT_BIN_ID_MIN 0x00002207
+#define A2XX_VGT_CURRENT_BIN_ID_MIN_COLUMN__MASK 0x00000007
+#define A2XX_VGT_CURRENT_BIN_ID_MIN_COLUMN__SHIFT 0
+static inline uint32_t A2XX_VGT_CURRENT_BIN_ID_MIN_COLUMN(uint32_t val)
+{
+ return ((val) << A2XX_VGT_CURRENT_BIN_ID_MIN_COLUMN__SHIFT) & A2XX_VGT_CURRENT_BIN_ID_MIN_COLUMN__MASK;
+}
+#define A2XX_VGT_CURRENT_BIN_ID_MIN_ROW__MASK 0x00000038
+#define A2XX_VGT_CURRENT_BIN_ID_MIN_ROW__SHIFT 3
+static inline uint32_t A2XX_VGT_CURRENT_BIN_ID_MIN_ROW(uint32_t val)
+{
+ return ((val) << A2XX_VGT_CURRENT_BIN_ID_MIN_ROW__SHIFT) & A2XX_VGT_CURRENT_BIN_ID_MIN_ROW__MASK;
+}
+#define A2XX_VGT_CURRENT_BIN_ID_MIN_GUARD_BAND_MASK__MASK 0x000001c0
+#define A2XX_VGT_CURRENT_BIN_ID_MIN_GUARD_BAND_MASK__SHIFT 6
+static inline uint32_t A2XX_VGT_CURRENT_BIN_ID_MIN_GUARD_BAND_MASK(uint32_t val)
+{
+ return ((val) << A2XX_VGT_CURRENT_BIN_ID_MIN_GUARD_BAND_MASK__SHIFT) & A2XX_VGT_CURRENT_BIN_ID_MIN_GUARD_BAND_MASK__MASK;
+}
+
+#define REG_A2XX_RB_MODECONTROL 0x00002208
+#define A2XX_RB_MODECONTROL_EDRAM_MODE__MASK 0x00000007
+#define A2XX_RB_MODECONTROL_EDRAM_MODE__SHIFT 0
+static inline uint32_t A2XX_RB_MODECONTROL_EDRAM_MODE(enum a2xx_rb_edram_mode val)
+{
+ return ((val) << A2XX_RB_MODECONTROL_EDRAM_MODE__SHIFT) & A2XX_RB_MODECONTROL_EDRAM_MODE__MASK;
+}
+
+#define REG_A2XX_A220_RB_LRZ_VSC_CONTROL 0x00002209
+
+#define REG_A2XX_RB_SAMPLE_POS 0x0000220a
+
+#define REG_A2XX_CLEAR_COLOR 0x0000220b
+#define A2XX_CLEAR_COLOR_RED__MASK 0x000000ff
+#define A2XX_CLEAR_COLOR_RED__SHIFT 0
+static inline uint32_t A2XX_CLEAR_COLOR_RED(uint32_t val)
+{
+ return ((val) << A2XX_CLEAR_COLOR_RED__SHIFT) & A2XX_CLEAR_COLOR_RED__MASK;
+}
+#define A2XX_CLEAR_COLOR_GREEN__MASK 0x0000ff00
+#define A2XX_CLEAR_COLOR_GREEN__SHIFT 8
+static inline uint32_t A2XX_CLEAR_COLOR_GREEN(uint32_t val)
+{
+ return ((val) << A2XX_CLEAR_COLOR_GREEN__SHIFT) & A2XX_CLEAR_COLOR_GREEN__MASK;
+}
+#define A2XX_CLEAR_COLOR_BLUE__MASK 0x00ff0000
+#define A2XX_CLEAR_COLOR_BLUE__SHIFT 16
+static inline uint32_t A2XX_CLEAR_COLOR_BLUE(uint32_t val)
+{
+ return ((val) << A2XX_CLEAR_COLOR_BLUE__SHIFT) & A2XX_CLEAR_COLOR_BLUE__MASK;
+}
+#define A2XX_CLEAR_COLOR_ALPHA__MASK 0xff000000
+#define A2XX_CLEAR_COLOR_ALPHA__SHIFT 24
+static inline uint32_t A2XX_CLEAR_COLOR_ALPHA(uint32_t val)
+{
+ return ((val) << A2XX_CLEAR_COLOR_ALPHA__SHIFT) & A2XX_CLEAR_COLOR_ALPHA__MASK;
+}
+
+#define REG_A2XX_A220_GRAS_CONTROL 0x00002210
+
+#define REG_A2XX_PA_SU_POINT_SIZE 0x00002280
+#define A2XX_PA_SU_POINT_SIZE_HEIGHT__MASK 0x0000ffff
+#define A2XX_PA_SU_POINT_SIZE_HEIGHT__SHIFT 0
+static inline uint32_t A2XX_PA_SU_POINT_SIZE_HEIGHT(float val)
+{
+ return ((((uint32_t)(val * 8.0))) << A2XX_PA_SU_POINT_SIZE_HEIGHT__SHIFT) & A2XX_PA_SU_POINT_SIZE_HEIGHT__MASK;
+}
+#define A2XX_PA_SU_POINT_SIZE_WIDTH__MASK 0xffff0000
+#define A2XX_PA_SU_POINT_SIZE_WIDTH__SHIFT 16
+static inline uint32_t A2XX_PA_SU_POINT_SIZE_WIDTH(float val)
+{
+ return ((((uint32_t)(val * 8.0))) << A2XX_PA_SU_POINT_SIZE_WIDTH__SHIFT) & A2XX_PA_SU_POINT_SIZE_WIDTH__MASK;
+}
+
+#define REG_A2XX_PA_SU_POINT_MINMAX 0x00002281
+#define A2XX_PA_SU_POINT_MINMAX_MIN__MASK 0x0000ffff
+#define A2XX_PA_SU_POINT_MINMAX_MIN__SHIFT 0
+static inline uint32_t A2XX_PA_SU_POINT_MINMAX_MIN(float val)
+{
+ return ((((uint32_t)(val * 8.0))) << A2XX_PA_SU_POINT_MINMAX_MIN__SHIFT) & A2XX_PA_SU_POINT_MINMAX_MIN__MASK;
+}
+#define A2XX_PA_SU_POINT_MINMAX_MAX__MASK 0xffff0000
+#define A2XX_PA_SU_POINT_MINMAX_MAX__SHIFT 16
+static inline uint32_t A2XX_PA_SU_POINT_MINMAX_MAX(float val)
+{
+ return ((((uint32_t)(val * 8.0))) << A2XX_PA_SU_POINT_MINMAX_MAX__SHIFT) & A2XX_PA_SU_POINT_MINMAX_MAX__MASK;
+}
+
+#define REG_A2XX_PA_SU_LINE_CNTL 0x00002282
+#define A2XX_PA_SU_LINE_CNTL_WIDTH__MASK 0x0000ffff
+#define A2XX_PA_SU_LINE_CNTL_WIDTH__SHIFT 0
+static inline uint32_t A2XX_PA_SU_LINE_CNTL_WIDTH(float val)
+{
+ return ((((uint32_t)(val * 8.0))) << A2XX_PA_SU_LINE_CNTL_WIDTH__SHIFT) & A2XX_PA_SU_LINE_CNTL_WIDTH__MASK;
+}
+
+#define REG_A2XX_PA_SC_LINE_STIPPLE 0x00002283
+#define A2XX_PA_SC_LINE_STIPPLE_LINE_PATTERN__MASK 0x0000ffff
+#define A2XX_PA_SC_LINE_STIPPLE_LINE_PATTERN__SHIFT 0
+static inline uint32_t A2XX_PA_SC_LINE_STIPPLE_LINE_PATTERN(uint32_t val)
+{
+ return ((val) << A2XX_PA_SC_LINE_STIPPLE_LINE_PATTERN__SHIFT) & A2XX_PA_SC_LINE_STIPPLE_LINE_PATTERN__MASK;
+}
+#define A2XX_PA_SC_LINE_STIPPLE_REPEAT_COUNT__MASK 0x00ff0000
+#define A2XX_PA_SC_LINE_STIPPLE_REPEAT_COUNT__SHIFT 16
+static inline uint32_t A2XX_PA_SC_LINE_STIPPLE_REPEAT_COUNT(uint32_t val)
+{
+ return ((val) << A2XX_PA_SC_LINE_STIPPLE_REPEAT_COUNT__SHIFT) & A2XX_PA_SC_LINE_STIPPLE_REPEAT_COUNT__MASK;
+}
+#define A2XX_PA_SC_LINE_STIPPLE_PATTERN_BIT_ORDER__MASK 0x10000000
+#define A2XX_PA_SC_LINE_STIPPLE_PATTERN_BIT_ORDER__SHIFT 28
+static inline uint32_t A2XX_PA_SC_LINE_STIPPLE_PATTERN_BIT_ORDER(enum a2xx_pa_sc_pattern_bit_order val)
+{
+ return ((val) << A2XX_PA_SC_LINE_STIPPLE_PATTERN_BIT_ORDER__SHIFT) & A2XX_PA_SC_LINE_STIPPLE_PATTERN_BIT_ORDER__MASK;
+}
+#define A2XX_PA_SC_LINE_STIPPLE_AUTO_RESET_CNTL__MASK 0x60000000
+#define A2XX_PA_SC_LINE_STIPPLE_AUTO_RESET_CNTL__SHIFT 29
+static inline uint32_t A2XX_PA_SC_LINE_STIPPLE_AUTO_RESET_CNTL(enum a2xx_pa_sc_auto_reset_cntl val)
+{
+ return ((val) << A2XX_PA_SC_LINE_STIPPLE_AUTO_RESET_CNTL__SHIFT) & A2XX_PA_SC_LINE_STIPPLE_AUTO_RESET_CNTL__MASK;
+}
+
+#define REG_A2XX_PA_SC_VIZ_QUERY 0x00002293
+
+#define REG_A2XX_VGT_ENHANCE 0x00002294
+
+#define REG_A2XX_PA_SC_LINE_CNTL 0x00002300
+#define A2XX_PA_SC_LINE_CNTL_BRES_CNTL__MASK 0x0000ffff
+#define A2XX_PA_SC_LINE_CNTL_BRES_CNTL__SHIFT 0
+static inline uint32_t A2XX_PA_SC_LINE_CNTL_BRES_CNTL(uint32_t val)
+{
+ return ((val) << A2XX_PA_SC_LINE_CNTL_BRES_CNTL__SHIFT) & A2XX_PA_SC_LINE_CNTL_BRES_CNTL__MASK;
+}
+#define A2XX_PA_SC_LINE_CNTL_USE_BRES_CNTL 0x00000100
+#define A2XX_PA_SC_LINE_CNTL_EXPAND_LINE_WIDTH 0x00000200
+#define A2XX_PA_SC_LINE_CNTL_LAST_PIXEL 0x00000400
+
+#define REG_A2XX_PA_SC_AA_CONFIG 0x00002301
+
+#define REG_A2XX_PA_SU_VTX_CNTL 0x00002302
+#define A2XX_PA_SU_VTX_CNTL_PIX_CENTER__MASK 0x00000001
+#define A2XX_PA_SU_VTX_CNTL_PIX_CENTER__SHIFT 0
+static inline uint32_t A2XX_PA_SU_VTX_CNTL_PIX_CENTER(enum a2xx_pa_pixcenter val)
+{
+ return ((val) << A2XX_PA_SU_VTX_CNTL_PIX_CENTER__SHIFT) & A2XX_PA_SU_VTX_CNTL_PIX_CENTER__MASK;
+}
+#define A2XX_PA_SU_VTX_CNTL_ROUND_MODE__MASK 0x00000006
+#define A2XX_PA_SU_VTX_CNTL_ROUND_MODE__SHIFT 1
+static inline uint32_t A2XX_PA_SU_VTX_CNTL_ROUND_MODE(enum a2xx_pa_roundmode val)
+{
+ return ((val) << A2XX_PA_SU_VTX_CNTL_ROUND_MODE__SHIFT) & A2XX_PA_SU_VTX_CNTL_ROUND_MODE__MASK;
+}
+#define A2XX_PA_SU_VTX_CNTL_QUANT_MODE__MASK 0x00000380
+#define A2XX_PA_SU_VTX_CNTL_QUANT_MODE__SHIFT 7
+static inline uint32_t A2XX_PA_SU_VTX_CNTL_QUANT_MODE(enum a2xx_pa_quantmode val)
+{
+ return ((val) << A2XX_PA_SU_VTX_CNTL_QUANT_MODE__SHIFT) & A2XX_PA_SU_VTX_CNTL_QUANT_MODE__MASK;
+}
+
+#define REG_A2XX_PA_CL_GB_VERT_CLIP_ADJ 0x00002303
+#define A2XX_PA_CL_GB_VERT_CLIP_ADJ__MASK 0xffffffff
+#define A2XX_PA_CL_GB_VERT_CLIP_ADJ__SHIFT 0
+static inline uint32_t A2XX_PA_CL_GB_VERT_CLIP_ADJ(float val)
+{
+ return ((fui(val)) << A2XX_PA_CL_GB_VERT_CLIP_ADJ__SHIFT) & A2XX_PA_CL_GB_VERT_CLIP_ADJ__MASK;
+}
+
+#define REG_A2XX_PA_CL_GB_VERT_DISC_ADJ 0x00002304
+#define A2XX_PA_CL_GB_VERT_DISC_ADJ__MASK 0xffffffff
+#define A2XX_PA_CL_GB_VERT_DISC_ADJ__SHIFT 0
+static inline uint32_t A2XX_PA_CL_GB_VERT_DISC_ADJ(float val)
+{
+ return ((fui(val)) << A2XX_PA_CL_GB_VERT_DISC_ADJ__SHIFT) & A2XX_PA_CL_GB_VERT_DISC_ADJ__MASK;
+}
+
+#define REG_A2XX_PA_CL_GB_HORZ_CLIP_ADJ 0x00002305
+#define A2XX_PA_CL_GB_HORZ_CLIP_ADJ__MASK 0xffffffff
+#define A2XX_PA_CL_GB_HORZ_CLIP_ADJ__SHIFT 0
+static inline uint32_t A2XX_PA_CL_GB_HORZ_CLIP_ADJ(float val)
+{
+ return ((fui(val)) << A2XX_PA_CL_GB_HORZ_CLIP_ADJ__SHIFT) & A2XX_PA_CL_GB_HORZ_CLIP_ADJ__MASK;
+}
+
+#define REG_A2XX_PA_CL_GB_HORZ_DISC_ADJ 0x00002306
+#define A2XX_PA_CL_GB_HORZ_DISC_ADJ__MASK 0xffffffff
+#define A2XX_PA_CL_GB_HORZ_DISC_ADJ__SHIFT 0
+static inline uint32_t A2XX_PA_CL_GB_HORZ_DISC_ADJ(float val)
+{
+ return ((fui(val)) << A2XX_PA_CL_GB_HORZ_DISC_ADJ__SHIFT) & A2XX_PA_CL_GB_HORZ_DISC_ADJ__MASK;
+}
+
+#define REG_A2XX_SQ_VS_CONST 0x00002307
+#define A2XX_SQ_VS_CONST_BASE__MASK 0x000001ff
+#define A2XX_SQ_VS_CONST_BASE__SHIFT 0
+static inline uint32_t A2XX_SQ_VS_CONST_BASE(uint32_t val)
+{
+ return ((val) << A2XX_SQ_VS_CONST_BASE__SHIFT) & A2XX_SQ_VS_CONST_BASE__MASK;
+}
+#define A2XX_SQ_VS_CONST_SIZE__MASK 0x001ff000
+#define A2XX_SQ_VS_CONST_SIZE__SHIFT 12
+static inline uint32_t A2XX_SQ_VS_CONST_SIZE(uint32_t val)
+{
+ return ((val) << A2XX_SQ_VS_CONST_SIZE__SHIFT) & A2XX_SQ_VS_CONST_SIZE__MASK;
+}
+
+#define REG_A2XX_SQ_PS_CONST 0x00002308
+#define A2XX_SQ_PS_CONST_BASE__MASK 0x000001ff
+#define A2XX_SQ_PS_CONST_BASE__SHIFT 0
+static inline uint32_t A2XX_SQ_PS_CONST_BASE(uint32_t val)
+{
+ return ((val) << A2XX_SQ_PS_CONST_BASE__SHIFT) & A2XX_SQ_PS_CONST_BASE__MASK;
+}
+#define A2XX_SQ_PS_CONST_SIZE__MASK 0x001ff000
+#define A2XX_SQ_PS_CONST_SIZE__SHIFT 12
+static inline uint32_t A2XX_SQ_PS_CONST_SIZE(uint32_t val)
+{
+ return ((val) << A2XX_SQ_PS_CONST_SIZE__SHIFT) & A2XX_SQ_PS_CONST_SIZE__MASK;
+}
+
+#define REG_A2XX_SQ_DEBUG_MISC_0 0x00002309
+
+#define REG_A2XX_SQ_DEBUG_MISC_1 0x0000230a
+
+#define REG_A2XX_PA_SC_AA_MASK 0x00002312
+
+#define REG_A2XX_VGT_VERTEX_REUSE_BLOCK_CNTL 0x00002316
+
+#define REG_A2XX_VGT_OUT_DEALLOC_CNTL 0x00002317
+
+#define REG_A2XX_RB_COPY_CONTROL 0x00002318
+#define A2XX_RB_COPY_CONTROL_COPY_SAMPLE_SELECT__MASK 0x00000007
+#define A2XX_RB_COPY_CONTROL_COPY_SAMPLE_SELECT__SHIFT 0
+static inline uint32_t A2XX_RB_COPY_CONTROL_COPY_SAMPLE_SELECT(enum a2xx_rb_copy_sample_select val)
+{
+ return ((val) << A2XX_RB_COPY_CONTROL_COPY_SAMPLE_SELECT__SHIFT) & A2XX_RB_COPY_CONTROL_COPY_SAMPLE_SELECT__MASK;
+}
+#define A2XX_RB_COPY_CONTROL_DEPTH_CLEAR_ENABLE 0x00000008
+#define A2XX_RB_COPY_CONTROL_CLEAR_MASK__MASK 0x000000f0
+#define A2XX_RB_COPY_CONTROL_CLEAR_MASK__SHIFT 4
+static inline uint32_t A2XX_RB_COPY_CONTROL_CLEAR_MASK(uint32_t val)
+{
+ return ((val) << A2XX_RB_COPY_CONTROL_CLEAR_MASK__SHIFT) & A2XX_RB_COPY_CONTROL_CLEAR_MASK__MASK;
+}
+
+#define REG_A2XX_RB_COPY_DEST_BASE 0x00002319
+
+#define REG_A2XX_RB_COPY_DEST_PITCH 0x0000231a
+#define A2XX_RB_COPY_DEST_PITCH__MASK 0xffffffff
+#define A2XX_RB_COPY_DEST_PITCH__SHIFT 0
+static inline uint32_t A2XX_RB_COPY_DEST_PITCH(uint32_t val)
+{
+ return ((val >> 5) << A2XX_RB_COPY_DEST_PITCH__SHIFT) & A2XX_RB_COPY_DEST_PITCH__MASK;
+}
+
+#define REG_A2XX_RB_COPY_DEST_INFO 0x0000231b
+#define A2XX_RB_COPY_DEST_INFO_DEST_ENDIAN__MASK 0x00000007
+#define A2XX_RB_COPY_DEST_INFO_DEST_ENDIAN__SHIFT 0
+static inline uint32_t A2XX_RB_COPY_DEST_INFO_DEST_ENDIAN(enum adreno_rb_surface_endian val)
+{
+ return ((val) << A2XX_RB_COPY_DEST_INFO_DEST_ENDIAN__SHIFT) & A2XX_RB_COPY_DEST_INFO_DEST_ENDIAN__MASK;
+}
+#define A2XX_RB_COPY_DEST_INFO_LINEAR 0x00000008
+#define A2XX_RB_COPY_DEST_INFO_FORMAT__MASK 0x000000f0
+#define A2XX_RB_COPY_DEST_INFO_FORMAT__SHIFT 4
+static inline uint32_t A2XX_RB_COPY_DEST_INFO_FORMAT(enum a2xx_colorformatx val)
+{
+ return ((val) << A2XX_RB_COPY_DEST_INFO_FORMAT__SHIFT) & A2XX_RB_COPY_DEST_INFO_FORMAT__MASK;
+}
+#define A2XX_RB_COPY_DEST_INFO_SWAP__MASK 0x00000300
+#define A2XX_RB_COPY_DEST_INFO_SWAP__SHIFT 8
+static inline uint32_t A2XX_RB_COPY_DEST_INFO_SWAP(uint32_t val)
+{
+ return ((val) << A2XX_RB_COPY_DEST_INFO_SWAP__SHIFT) & A2XX_RB_COPY_DEST_INFO_SWAP__MASK;
+}
+#define A2XX_RB_COPY_DEST_INFO_DITHER_MODE__MASK 0x00000c00
+#define A2XX_RB_COPY_DEST_INFO_DITHER_MODE__SHIFT 10
+static inline uint32_t A2XX_RB_COPY_DEST_INFO_DITHER_MODE(enum adreno_rb_dither_mode val)
+{
+ return ((val) << A2XX_RB_COPY_DEST_INFO_DITHER_MODE__SHIFT) & A2XX_RB_COPY_DEST_INFO_DITHER_MODE__MASK;
+}
+#define A2XX_RB_COPY_DEST_INFO_DITHER_TYPE__MASK 0x00003000
+#define A2XX_RB_COPY_DEST_INFO_DITHER_TYPE__SHIFT 12
+static inline uint32_t A2XX_RB_COPY_DEST_INFO_DITHER_TYPE(enum a2xx_rb_dither_type val)
+{
+ return ((val) << A2XX_RB_COPY_DEST_INFO_DITHER_TYPE__SHIFT) & A2XX_RB_COPY_DEST_INFO_DITHER_TYPE__MASK;
+}
+#define A2XX_RB_COPY_DEST_INFO_WRITE_RED 0x00004000
+#define A2XX_RB_COPY_DEST_INFO_WRITE_GREEN 0x00008000
+#define A2XX_RB_COPY_DEST_INFO_WRITE_BLUE 0x00010000
+#define A2XX_RB_COPY_DEST_INFO_WRITE_ALPHA 0x00020000
+
+#define REG_A2XX_RB_COPY_DEST_OFFSET 0x0000231c
+#define A2XX_RB_COPY_DEST_OFFSET_X__MASK 0x00001fff
+#define A2XX_RB_COPY_DEST_OFFSET_X__SHIFT 0
+static inline uint32_t A2XX_RB_COPY_DEST_OFFSET_X(uint32_t val)
+{
+ return ((val) << A2XX_RB_COPY_DEST_OFFSET_X__SHIFT) & A2XX_RB_COPY_DEST_OFFSET_X__MASK;
+}
+#define A2XX_RB_COPY_DEST_OFFSET_Y__MASK 0x03ffe000
+#define A2XX_RB_COPY_DEST_OFFSET_Y__SHIFT 13
+static inline uint32_t A2XX_RB_COPY_DEST_OFFSET_Y(uint32_t val)
+{
+ return ((val) << A2XX_RB_COPY_DEST_OFFSET_Y__SHIFT) & A2XX_RB_COPY_DEST_OFFSET_Y__MASK;
+}
+
+#define REG_A2XX_RB_DEPTH_CLEAR 0x0000231d
+
+#define REG_A2XX_RB_SAMPLE_COUNT_CTL 0x00002324
+
+#define REG_A2XX_RB_COLOR_DEST_MASK 0x00002326
+
+#define REG_A2XX_A225_GRAS_UCP0X 0x00002340
+
+#define REG_A2XX_A225_GRAS_UCP5W 0x00002357
+
+#define REG_A2XX_A225_GRAS_UCP_ENABLED 0x00002360
+
+#define REG_A2XX_PA_SU_POLY_OFFSET_FRONT_SCALE 0x00002380
+
+#define REG_A2XX_PA_SU_POLY_OFFSET_BACK_OFFSET 0x00002383
+
+#define REG_A2XX_SQ_CONSTANT_0 0x00004000
+
+#define REG_A2XX_SQ_FETCH_0 0x00004800
+
+#define REG_A2XX_SQ_CF_BOOLEANS 0x00004900
+
+#define REG_A2XX_SQ_CF_LOOP 0x00004908
+
+#define REG_A2XX_COHER_SIZE_PM4 0x00000a29
+
+#define REG_A2XX_COHER_BASE_PM4 0x00000a2a
+
+#define REG_A2XX_COHER_STATUS_PM4 0x00000a2b
+
+#define REG_A2XX_SQ_TEX_0 0x00000000
+#define A2XX_SQ_TEX_0_CLAMP_X__MASK 0x00001c00
+#define A2XX_SQ_TEX_0_CLAMP_X__SHIFT 10
+static inline uint32_t A2XX_SQ_TEX_0_CLAMP_X(enum sq_tex_clamp val)
+{
+ return ((val) << A2XX_SQ_TEX_0_CLAMP_X__SHIFT) & A2XX_SQ_TEX_0_CLAMP_X__MASK;
+}
+#define A2XX_SQ_TEX_0_CLAMP_Y__MASK 0x0000e000
+#define A2XX_SQ_TEX_0_CLAMP_Y__SHIFT 13
+static inline uint32_t A2XX_SQ_TEX_0_CLAMP_Y(enum sq_tex_clamp val)
+{
+ return ((val) << A2XX_SQ_TEX_0_CLAMP_Y__SHIFT) & A2XX_SQ_TEX_0_CLAMP_Y__MASK;
+}
+#define A2XX_SQ_TEX_0_CLAMP_Z__MASK 0x00070000
+#define A2XX_SQ_TEX_0_CLAMP_Z__SHIFT 16
+static inline uint32_t A2XX_SQ_TEX_0_CLAMP_Z(enum sq_tex_clamp val)
+{
+ return ((val) << A2XX_SQ_TEX_0_CLAMP_Z__SHIFT) & A2XX_SQ_TEX_0_CLAMP_Z__MASK;
+}
+#define A2XX_SQ_TEX_0_PITCH__MASK 0xffc00000
+#define A2XX_SQ_TEX_0_PITCH__SHIFT 22
+static inline uint32_t A2XX_SQ_TEX_0_PITCH(uint32_t val)
+{
+ return ((val >> 5) << A2XX_SQ_TEX_0_PITCH__SHIFT) & A2XX_SQ_TEX_0_PITCH__MASK;
+}
+
+#define REG_A2XX_SQ_TEX_1 0x00000001
+
+#define REG_A2XX_SQ_TEX_2 0x00000002
+#define A2XX_SQ_TEX_2_WIDTH__MASK 0x00001fff
+#define A2XX_SQ_TEX_2_WIDTH__SHIFT 0
+static inline uint32_t A2XX_SQ_TEX_2_WIDTH(uint32_t val)
+{
+ return ((val) << A2XX_SQ_TEX_2_WIDTH__SHIFT) & A2XX_SQ_TEX_2_WIDTH__MASK;
+}
+#define A2XX_SQ_TEX_2_HEIGHT__MASK 0x03ffe000
+#define A2XX_SQ_TEX_2_HEIGHT__SHIFT 13
+static inline uint32_t A2XX_SQ_TEX_2_HEIGHT(uint32_t val)
+{
+ return ((val) << A2XX_SQ_TEX_2_HEIGHT__SHIFT) & A2XX_SQ_TEX_2_HEIGHT__MASK;
+}
+
+#define REG_A2XX_SQ_TEX_3 0x00000003
+#define A2XX_SQ_TEX_3_SWIZ_X__MASK 0x0000000e
+#define A2XX_SQ_TEX_3_SWIZ_X__SHIFT 1
+static inline uint32_t A2XX_SQ_TEX_3_SWIZ_X(enum sq_tex_swiz val)
+{
+ return ((val) << A2XX_SQ_TEX_3_SWIZ_X__SHIFT) & A2XX_SQ_TEX_3_SWIZ_X__MASK;
+}
+#define A2XX_SQ_TEX_3_SWIZ_Y__MASK 0x00000070
+#define A2XX_SQ_TEX_3_SWIZ_Y__SHIFT 4
+static inline uint32_t A2XX_SQ_TEX_3_SWIZ_Y(enum sq_tex_swiz val)
+{
+ return ((val) << A2XX_SQ_TEX_3_SWIZ_Y__SHIFT) & A2XX_SQ_TEX_3_SWIZ_Y__MASK;
+}
+#define A2XX_SQ_TEX_3_SWIZ_Z__MASK 0x00000380
+#define A2XX_SQ_TEX_3_SWIZ_Z__SHIFT 7
+static inline uint32_t A2XX_SQ_TEX_3_SWIZ_Z(enum sq_tex_swiz val)
+{
+ return ((val) << A2XX_SQ_TEX_3_SWIZ_Z__SHIFT) & A2XX_SQ_TEX_3_SWIZ_Z__MASK;
+}
+#define A2XX_SQ_TEX_3_SWIZ_W__MASK 0x00001c00
+#define A2XX_SQ_TEX_3_SWIZ_W__SHIFT 10
+static inline uint32_t A2XX_SQ_TEX_3_SWIZ_W(enum sq_tex_swiz val)
+{
+ return ((val) << A2XX_SQ_TEX_3_SWIZ_W__SHIFT) & A2XX_SQ_TEX_3_SWIZ_W__MASK;
+}
+#define A2XX_SQ_TEX_3_XY_MAG_FILTER__MASK 0x00180000
+#define A2XX_SQ_TEX_3_XY_MAG_FILTER__SHIFT 19
+static inline uint32_t A2XX_SQ_TEX_3_XY_MAG_FILTER(enum sq_tex_filter val)
+{
+ return ((val) << A2XX_SQ_TEX_3_XY_MAG_FILTER__SHIFT) & A2XX_SQ_TEX_3_XY_MAG_FILTER__MASK;
+}
+#define A2XX_SQ_TEX_3_XY_MIN_FILTER__MASK 0x00600000
+#define A2XX_SQ_TEX_3_XY_MIN_FILTER__SHIFT 21
+static inline uint32_t A2XX_SQ_TEX_3_XY_MIN_FILTER(enum sq_tex_filter val)
+{
+ return ((val) << A2XX_SQ_TEX_3_XY_MIN_FILTER__SHIFT) & A2XX_SQ_TEX_3_XY_MIN_FILTER__MASK;
+}
+
+
+#endif /* A2XX_XML */
--- /dev/null
+/*
+ * Copyright (c) 2012 Rob Clark <robdclark@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <string.h>
+
+#include "disasm.h"
+#include "instr-a2xx.h"
+
+static const char *levels[] = {
+ "\t",
+ "\t\t",
+ "\t\t\t",
+ "\t\t\t\t",
+ "\t\t\t\t\t",
+ "\t\t\t\t\t\t",
+ "\t\t\t\t\t\t\t",
+ "\t\t\t\t\t\t\t\t",
+ "\t\t\t\t\t\t\t\t\t",
+ "x",
+ "x",
+ "x",
+ "x",
+ "x",
+ "x",
+};
+
+static enum debug_t debug;
+
+/*
+ * ALU instructions:
+ */
+
+static const char chan_names[] = {
+ 'x', 'y', 'z', 'w',
+ /* these only apply to FETCH dst's: */
+ '0', '1', '?', '_',
+};
+
+static void print_srcreg(uint32_t num, uint32_t type,
+ uint32_t swiz, uint32_t negate, uint32_t abs)
+{
+ if (negate)
+ printf("-");
+ if (abs)
+ printf("|");
+ printf("%c%u", type ? 'R' : 'C', num);
+ if (swiz) {
+ int i;
+ printf(".");
+ for (i = 0; i < 4; i++) {
+ printf("%c", chan_names[(swiz + i) & 0x3]);
+ swiz >>= 2;
+ }
+ }
+ if (abs)
+ printf("|");
+}
+
+static void print_dstreg(uint32_t num, uint32_t mask, uint32_t dst_exp)
+{
+ printf("%s%u", dst_exp ? "export" : "R", num);
+ if (mask != 0xf) {
+ int i;
+ printf(".");
+ for (i = 0; i < 4; i++) {
+ printf("%c", (mask & 0x1) ? chan_names[i] : '_');
+ mask >>= 1;
+ }
+ }
+}
+
+static void print_export_comment(uint32_t num, enum shader_t type)
+{
+ const char *name = NULL;
+ switch (type) {
+ case SHADER_VERTEX:
+ switch (num) {
+ case 62: name = "gl_Position"; break;
+ case 63: name = "gl_PointSize"; break;
+ }
+ break;
+ case SHADER_FRAGMENT:
+ switch (num) {
+ case 0: name = "gl_FragColor"; break;
+ }
+ break;
+ }
+ /* if we had a symbol table here, we could look
+ * up the name of the varying..
+ */
+ if (name) {
+ printf("\t; %s", name);
+ }
+}
+
+struct {
+ uint32_t num_srcs;
+ const char *name;
+} vector_instructions[0x20] = {
+#define INSTR(opc, num_srcs) [opc] = { num_srcs, #opc }
+ INSTR(ADDv, 2),
+ INSTR(MULv, 2),
+ INSTR(MAXv, 2),
+ INSTR(MINv, 2),
+ INSTR(SETEv, 2),
+ INSTR(SETGTv, 2),
+ INSTR(SETGTEv, 2),
+ INSTR(SETNEv, 2),
+ INSTR(FRACv, 1),
+ INSTR(TRUNCv, 1),
+ INSTR(FLOORv, 1),
+ INSTR(MULADDv, 3),
+ INSTR(CNDEv, 3),
+ INSTR(CNDGTEv, 3),
+ INSTR(CNDGTv, 3),
+ INSTR(DOT4v, 2),
+ INSTR(DOT3v, 2),
+ INSTR(DOT2ADDv, 3), // ???
+ INSTR(CUBEv, 2),
+ INSTR(MAX4v, 1),
+ INSTR(PRED_SETE_PUSHv, 2),
+ INSTR(PRED_SETNE_PUSHv, 2),
+ INSTR(PRED_SETGT_PUSHv, 2),
+ INSTR(PRED_SETGTE_PUSHv, 2),
+ INSTR(KILLEv, 2),
+ INSTR(KILLGTv, 2),
+ INSTR(KILLGTEv, 2),
+ INSTR(KILLNEv, 2),
+ INSTR(DSTv, 2),
+ INSTR(MOVAv, 1),
+}, scalar_instructions[0x40] = {
+ INSTR(ADDs, 1),
+ INSTR(ADD_PREVs, 1),
+ INSTR(MULs, 1),
+ INSTR(MUL_PREVs, 1),
+ INSTR(MUL_PREV2s, 1),
+ INSTR(MAXs, 1),
+ INSTR(MINs, 1),
+ INSTR(SETEs, 1),
+ INSTR(SETGTs, 1),
+ INSTR(SETGTEs, 1),
+ INSTR(SETNEs, 1),
+ INSTR(FRACs, 1),
+ INSTR(TRUNCs, 1),
+ INSTR(FLOORs, 1),
+ INSTR(EXP_IEEE, 1),
+ INSTR(LOG_CLAMP, 1),
+ INSTR(LOG_IEEE, 1),
+ INSTR(RECIP_CLAMP, 1),
+ INSTR(RECIP_FF, 1),
+ INSTR(RECIP_IEEE, 1),
+ INSTR(RECIPSQ_CLAMP, 1),
+ INSTR(RECIPSQ_FF, 1),
+ INSTR(RECIPSQ_IEEE, 1),
+ INSTR(MOVAs, 1),
+ INSTR(MOVA_FLOORs, 1),
+ INSTR(SUBs, 1),
+ INSTR(SUB_PREVs, 1),
+ INSTR(PRED_SETEs, 1),
+ INSTR(PRED_SETNEs, 1),
+ INSTR(PRED_SETGTs, 1),
+ INSTR(PRED_SETGTEs, 1),
+ INSTR(PRED_SET_INVs, 1),
+ INSTR(PRED_SET_POPs, 1),
+ INSTR(PRED_SET_CLRs, 1),
+ INSTR(PRED_SET_RESTOREs, 1),
+ INSTR(KILLEs, 1),
+ INSTR(KILLGTs, 1),
+ INSTR(KILLGTEs, 1),
+ INSTR(KILLNEs, 1),
+ INSTR(KILLONEs, 1),
+ INSTR(SQRT_IEEE, 1),
+ INSTR(MUL_CONST_0, 1),
+ INSTR(MUL_CONST_1, 1),
+ INSTR(ADD_CONST_0, 1),
+ INSTR(ADD_CONST_1, 1),
+ INSTR(SUB_CONST_0, 1),
+ INSTR(SUB_CONST_1, 1),
+ INSTR(SIN, 1),
+ INSTR(COS, 1),
+ INSTR(RETAIN_PREV, 1),
+#undef INSTR
+};
+
+static int disasm_alu(uint32_t *dwords, uint32_t alu_off,
+ int level, int sync, enum shader_t type)
+{
+ instr_alu_t *alu = (instr_alu_t *)dwords;
+
+ printf("%s", levels[level]);
+ if (debug & PRINT_RAW) {
+ printf("%02x: %08x %08x %08x\t", alu_off,
+ dwords[0], dwords[1], dwords[2]);
+ }
+
+ printf(" %sALU:\t", sync ? "(S)" : " ");
+
+ printf("%s", vector_instructions[alu->vector_opc].name);
+
+ if (alu->pred_select & 0x2) {
+ /* seems to work similar to conditional execution in ARM instruction
+ * set, so let's use a similar syntax for now:
+ */
+ printf((alu->pred_select & 0x1) ? "EQ" : "NE");
+ }
+
+ printf("\t");
+
+ print_dstreg(alu->vector_dest, alu->vector_write_mask, alu->export_data);
+ printf(" = ");
+ if (vector_instructions[alu->vector_opc].num_srcs == 3) {
+ print_srcreg(alu->src3_reg, alu->src3_sel, alu->src3_swiz,
+ alu->src3_reg_negate, alu->src3_reg_abs);
+ printf(", ");
+ }
+ print_srcreg(alu->src1_reg, alu->src1_sel, alu->src1_swiz,
+ alu->src1_reg_negate, alu->src1_reg_abs);
+ if (vector_instructions[alu->vector_opc].num_srcs > 1) {
+ printf(", ");
+ print_srcreg(alu->src2_reg, alu->src2_sel, alu->src2_swiz,
+ alu->src2_reg_negate, alu->src2_reg_abs);
+ }
+
+ if (alu->vector_clamp)
+ printf(" CLAMP");
+
+ if (alu->export_data)
+ print_export_comment(alu->vector_dest, type);
+
+ printf("\n");
+
+ if (alu->scalar_write_mask || !alu->vector_write_mask) {
+ /* 2nd optional scalar op: */
+
+ printf("%s", levels[level]);
+ if (debug & PRINT_RAW)
+ printf(" \t");
+
+ if (scalar_instructions[alu->scalar_opc].name) {
+ printf("\t \t%s\t", scalar_instructions[alu->scalar_opc].name);
+ } else {
+ printf("\t \tOP(%u)\t", alu->scalar_opc);
+ }
+
+ print_dstreg(alu->scalar_dest, alu->scalar_write_mask, alu->export_data);
+ printf(" = ");
+ print_srcreg(alu->src3_reg, alu->src3_sel, alu->src3_swiz,
+ alu->src3_reg_negate, alu->src3_reg_abs);
+ // TODO ADD/MUL must have another src?!?
+ if (alu->scalar_clamp)
+ printf(" CLAMP");
+ if (alu->export_data)
+ print_export_comment(alu->scalar_dest, type);
+ printf("\n");
+ }
+
+ return 0;
+}
+
+
+/*
+ * FETCH instructions:
+ */
+
+struct {
+ const char *name;
+} fetch_types[0xff] = {
+#define TYPE(id) [id] = { #id }
+ TYPE(FMT_1_REVERSE),
+ TYPE(FMT_32_FLOAT),
+ TYPE(FMT_32_32_FLOAT),
+ TYPE(FMT_32_32_32_FLOAT),
+ TYPE(FMT_32_32_32_32_FLOAT),
+ TYPE(FMT_16),
+ TYPE(FMT_16_16),
+ TYPE(FMT_16_16_16_16),
+ TYPE(FMT_8),
+ TYPE(FMT_8_8),
+ TYPE(FMT_8_8_8_8),
+ TYPE(FMT_32),
+ TYPE(FMT_32_32),
+ TYPE(FMT_32_32_32_32),
+#undef TYPE
+};
+
+static void print_fetch_dst(uint32_t dst_reg, uint32_t dst_swiz)
+{
+ int i;
+ printf("\tR%u.", dst_reg);
+ for (i = 0; i < 4; i++) {
+ printf("%c", chan_names[dst_swiz & 0x7]);
+ dst_swiz >>= 3;
+ }
+}
+
+static void print_fetch_vtx(instr_fetch_t *fetch)
+{
+ instr_fetch_vtx_t *vtx = &fetch->vtx;
+
+ if (vtx->pred_select) {
+ /* seems to work similar to conditional execution in ARM instruction
+ * set, so let's use a similar syntax for now:
+ */
+ printf(vtx->pred_condition ? "EQ" : "NE");
+ }
+
+ print_fetch_dst(vtx->dst_reg, vtx->dst_swiz);
+ printf(" = R%u.", vtx->src_reg);
+ printf("%c", chan_names[vtx->src_swiz & 0x3]);
+ if (fetch_types[vtx->format].name) {
+ printf(" %s", fetch_types[vtx->format].name);
+ } else {
+ printf(" TYPE(0x%x)", vtx->format);
+ }
+ printf(" %s", vtx->format_comp_all ? "SIGNED" : "UNSIGNED");
+ if (!vtx->num_format_all)
+ printf(" NORMALIZED");
+ printf(" STRIDE(%u)", vtx->stride);
+ if (vtx->offset)
+ printf(" OFFSET(%u)", vtx->offset);
+ printf(" CONST(%u, %u)", vtx->const_index, vtx->const_index_sel);
+ if (0) {
+ // XXX
+ printf(" src_reg_am=%u", vtx->src_reg_am);
+ printf(" dst_reg_am=%u", vtx->dst_reg_am);
+ printf(" num_format_all=%u", vtx->num_format_all);
+ printf(" signed_rf_mode_all=%u", vtx->signed_rf_mode_all);
+ printf(" exp_adjust_all=%u", vtx->exp_adjust_all);
+ }
+}
+
+static void print_fetch_tex(instr_fetch_t *fetch)
+{
+ static const char *filter[] = {
+ [TEX_FILTER_POINT] = "POINT",
+ [TEX_FILTER_LINEAR] = "LINEAR",
+ [TEX_FILTER_BASEMAP] = "BASEMAP",
+ };
+ static const char *aniso_filter[] = {
+ [ANISO_FILTER_DISABLED] = "DISABLED",
+ [ANISO_FILTER_MAX_1_1] = "MAX_1_1",
+ [ANISO_FILTER_MAX_2_1] = "MAX_2_1",
+ [ANISO_FILTER_MAX_4_1] = "MAX_4_1",
+ [ANISO_FILTER_MAX_8_1] = "MAX_8_1",
+ [ANISO_FILTER_MAX_16_1] = "MAX_16_1",
+ };
+ static const char *arbitrary_filter[] = {
+ [ARBITRARY_FILTER_2X4_SYM] = "2x4_SYM",
+ [ARBITRARY_FILTER_2X4_ASYM] = "2x4_ASYM",
+ [ARBITRARY_FILTER_4X2_SYM] = "4x2_SYM",
+ [ARBITRARY_FILTER_4X2_ASYM] = "4x2_ASYM",
+ [ARBITRARY_FILTER_4X4_SYM] = "4x4_SYM",
+ [ARBITRARY_FILTER_4X4_ASYM] = "4x4_ASYM",
+ };
+ static const char *sample_loc[] = {
+ [SAMPLE_CENTROID] = "CENTROID",
+ [SAMPLE_CENTER] = "CENTER",
+ };
+ instr_fetch_tex_t *tex = &fetch->tex;
+ uint32_t src_swiz = tex->src_swiz;
+ int i;
+
+ if (tex->pred_select) {
+ /* seems to work similar to conditional execution in ARM instruction
+ * set, so let's use a similar syntax for now:
+ */
+ printf(tex->pred_condition ? "EQ" : "NE");
+ }
+
+ print_fetch_dst(tex->dst_reg, tex->dst_swiz);
+ printf(" = R%u.", tex->src_reg);
+ for (i = 0; i < 3; i++) {
+ printf("%c", chan_names[src_swiz & 0x3]);
+ src_swiz >>= 2;
+ }
+ printf(" CONST(%u)", tex->const_idx);
+ if (tex->fetch_valid_only)
+ printf(" VALID_ONLY");
+ if (tex->tx_coord_denorm)
+ printf(" DENORM");
+ if (tex->mag_filter != TEX_FILTER_USE_FETCH_CONST)
+ printf(" MAG(%s)", filter[tex->mag_filter]);
+ if (tex->min_filter != TEX_FILTER_USE_FETCH_CONST)
+ printf(" MIN(%s)", filter[tex->min_filter]);
+ if (tex->mip_filter != TEX_FILTER_USE_FETCH_CONST)
+ printf(" MIP(%s)", filter[tex->mip_filter]);
+ if (tex->aniso_filter != ANISO_FILTER_USE_FETCH_CONST)
+ printf(" ANISO(%s)", aniso_filter[tex->aniso_filter]);
+ if (tex->arbitrary_filter != ARBITRARY_FILTER_USE_FETCH_CONST)
+ printf(" ARBITRARY(%s)", arbitrary_filter[tex->arbitrary_filter]);
+ if (tex->vol_mag_filter != TEX_FILTER_USE_FETCH_CONST)
+ printf(" VOL_MAG(%s)", filter[tex->vol_mag_filter]);
+ if (tex->vol_min_filter != TEX_FILTER_USE_FETCH_CONST)
+ printf(" VOL_MIN(%s)", filter[tex->vol_min_filter]);
+ if (!tex->use_comp_lod) {
+ printf(" LOD(%u)", tex->use_comp_lod);
+ printf(" LOD_BIAS(%u)", tex->lod_bias);
+ }
+ if (tex->use_reg_gradients)
+ printf(" USE_REG_GRADIENTS");
+ printf(" LOCATION(%s)", sample_loc[tex->sample_location]);
+ if (tex->offset_x || tex->offset_y || tex->offset_z)
+ printf(" OFFSET(%u,%u,%u)", tex->offset_x, tex->offset_y, tex->offset_z);
+}
+
+struct {
+ const char *name;
+ void (*fxn)(instr_fetch_t *cf);
+} fetch_instructions[] = {
+#define INSTR(opc, name, fxn) [opc] = { name, fxn }
+ INSTR(VTX_FETCH, "VERTEX", print_fetch_vtx),
+ INSTR(TEX_FETCH, "SAMPLE", print_fetch_tex),
+ INSTR(TEX_GET_BORDER_COLOR_FRAC, "?", print_fetch_tex),
+ INSTR(TEX_GET_COMP_TEX_LOD, "?", print_fetch_tex),
+ INSTR(TEX_GET_GRADIENTS, "?", print_fetch_tex),
+ INSTR(TEX_GET_WEIGHTS, "?", print_fetch_tex),
+ INSTR(TEX_SET_TEX_LOD, "SET_TEX_LOD", print_fetch_tex),
+ INSTR(TEX_SET_GRADIENTS_H, "?", print_fetch_tex),
+ INSTR(TEX_SET_GRADIENTS_V, "?", print_fetch_tex),
+ INSTR(TEX_RESERVED_4, "?", print_fetch_tex),
+#undef INSTR
+};
+
+static int disasm_fetch(uint32_t *dwords, uint32_t alu_off, int level, int sync)
+{
+ instr_fetch_t *fetch = (instr_fetch_t *)dwords;
+
+ printf("%s", levels[level]);
+ if (debug & PRINT_RAW) {
+ printf("%02x: %08x %08x %08x\t", alu_off,
+ dwords[0], dwords[1], dwords[2]);
+ }
+
+ printf(" %sFETCH:\t", sync ? "(S)" : " ");
+ printf("%s", fetch_instructions[fetch->opc].name);
+ fetch_instructions[fetch->opc].fxn(fetch);
+ printf("\n");
+
+ return 0;
+}
+
+/*
+ * CF instructions:
+ */
+
+static int cf_exec(instr_cf_t *cf)
+{
+ return (cf->opc == EXEC) ||
+ (cf->opc == EXEC_END) ||
+ (cf->opc == COND_EXEC) ||
+ (cf->opc == COND_EXEC_END) ||
+ (cf->opc == COND_PRED_EXEC) ||
+ (cf->opc == COND_PRED_EXEC_END) ||
+ (cf->opc == COND_EXEC_PRED_CLEAN) ||
+ (cf->opc == COND_EXEC_PRED_CLEAN_END);
+}
+
+static int cf_cond_exec(instr_cf_t *cf)
+{
+ return (cf->opc == COND_EXEC) ||
+ (cf->opc == COND_EXEC_END) ||
+ (cf->opc == COND_PRED_EXEC) ||
+ (cf->opc == COND_PRED_EXEC_END) ||
+ (cf->opc == COND_EXEC_PRED_CLEAN) ||
+ (cf->opc == COND_EXEC_PRED_CLEAN_END);
+}
+
+static void print_cf_nop(instr_cf_t *cf)
+{
+}
+
+static void print_cf_exec(instr_cf_t *cf)
+{
+ printf(" ADDR(0x%x) CNT(0x%x)", cf->exec.address, cf->exec.count);
+ if (cf->exec.yeild)
+ printf(" YIELD");
+ if (cf->exec.vc)
+ printf(" VC(0x%x)", cf->exec.vc);
+ if (cf->exec.bool_addr)
+ printf(" BOOL_ADDR(0x%x)", cf->exec.bool_addr);
+ if (cf->exec.address_mode == ABSOLUTE_ADDR)
+ printf(" ABSOLUTE_ADDR");
+ if (cf_cond_exec(cf))
+ printf(" COND(%d)", cf->exec.condition);
+}
+
+static void print_cf_loop(instr_cf_t *cf)
+{
+ printf(" ADDR(0x%x) LOOP_ID(%d)", cf->loop.address, cf->loop.loop_id);
+ if (cf->loop.address_mode == ABSOLUTE_ADDR)
+ printf(" ABSOLUTE_ADDR");
+}
+
+static void print_cf_jmp_call(instr_cf_t *cf)
+{
+ printf(" ADDR(0x%x) DIR(%d)", cf->jmp_call.address, cf->jmp_call.direction);
+ if (cf->jmp_call.force_call)
+ printf(" FORCE_CALL");
+ if (cf->jmp_call.predicated_jmp)
+ printf(" COND(%d)", cf->jmp_call.condition);
+ if (cf->jmp_call.bool_addr)
+ printf(" BOOL_ADDR(0x%x)", cf->jmp_call.bool_addr);
+ if (cf->jmp_call.address_mode == ABSOLUTE_ADDR)
+ printf(" ABSOLUTE_ADDR");
+}
+
+static void print_cf_alloc(instr_cf_t *cf)
+{
+ static const char *bufname[] = {
+ [SQ_NO_ALLOC] = "NO ALLOC",
+ [SQ_POSITION] = "POSITION",
+ [SQ_PARAMETER_PIXEL] = "PARAM/PIXEL",
+ [SQ_MEMORY] = "MEMORY",
+ };
+ printf(" %s SIZE(0x%x)", bufname[cf->alloc.buffer_select], cf->alloc.size);
+ if (cf->alloc.no_serial)
+ printf(" NO_SERIAL");
+ if (cf->alloc.alloc_mode) // ???
+ printf(" ALLOC_MODE");
+}
+
+struct {
+ const char *name;
+ void (*fxn)(instr_cf_t *cf);
+} cf_instructions[] = {
+#define INSTR(opc, fxn) [opc] = { #opc, fxn }
+ INSTR(NOP, print_cf_nop),
+ INSTR(EXEC, print_cf_exec),
+ INSTR(EXEC_END, print_cf_exec),
+ INSTR(COND_EXEC, print_cf_exec),
+ INSTR(COND_EXEC_END, print_cf_exec),
+ INSTR(COND_PRED_EXEC, print_cf_exec),
+ INSTR(COND_PRED_EXEC_END, print_cf_exec),
+ INSTR(LOOP_START, print_cf_loop),
+ INSTR(LOOP_END, print_cf_loop),
+ INSTR(COND_CALL, print_cf_jmp_call),
+ INSTR(RETURN, print_cf_jmp_call),
+ INSTR(COND_JMP, print_cf_jmp_call),
+ INSTR(ALLOC, print_cf_alloc),
+ INSTR(COND_EXEC_PRED_CLEAN, print_cf_exec),
+ INSTR(COND_EXEC_PRED_CLEAN_END, print_cf_exec),
+ INSTR(MARK_VS_FETCH_DONE, print_cf_nop), // ??
+#undef INSTR
+};
+
+static void print_cf(instr_cf_t *cf, int level)
+{
+ printf("%s", levels[level]);
+ if (debug & PRINT_RAW) {
+ uint16_t *words = (uint16_t *)cf;
+ printf(" %04x %04x %04x \t",
+ words[0], words[1], words[2]);
+ }
+ printf("%s", cf_instructions[cf->opc].name);
+ cf_instructions[cf->opc].fxn(cf);
+ printf("\n");
+}
+
+/*
+ * The adreno shader microcode consists of two parts:
+ * 1) A CF (control-flow) program, at the header of the compiled shader,
+ * which refers to ALU/FETCH instructions that follow it by address.
+ * 2) ALU and FETCH instructions
+ */
+
+int disasm_a2xx(uint32_t *dwords, int sizedwords, int level, enum shader_t type)
+{
+ instr_cf_t *cfs = (instr_cf_t *)dwords;
+ int idx, max_idx;
+
+ for (idx = 0; ; idx++) {
+ instr_cf_t *cf = &cfs[idx];
+ if (cf_exec(cf)) {
+ max_idx = 2 * cf->exec.address;
+ break;
+ }
+ }
+
+ for (idx = 0; idx < max_idx; idx++) {
+ instr_cf_t *cf = &cfs[idx];
+
+ print_cf(cf, level);
+
+ if (cf_exec(cf)) {
+ uint32_t sequence = cf->exec.serialize;
+ uint32_t i;
+ for (i = 0; i < cf->exec.count; i++) {
+ uint32_t alu_off = (cf->exec.address + i);
+ if (sequence & 0x1) {
+ disasm_fetch(dwords + alu_off * 3, alu_off, level, sequence & 0x2);
+ } else {
+ disasm_alu(dwords + alu_off * 3, alu_off, level, sequence & 0x2, type);
+ }
+ sequence >>= 2;
+ }
+ }
+ }
+
+ return 0;
+}
+
+void disasm_set_debug(enum debug_t d)
+{
+ debug = d;
+}
--- /dev/null
+/* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */
+
+/*
+ * Copyright (C) 2012-2013 Rob Clark <robclark@freedesktop.org>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Authors:
+ * Rob Clark <robclark@freedesktop.org>
+ */
+
+#include "pipe/p_state.h"
+#include "util/u_string.h"
+#include "util/u_memory.h"
+
+#include "fd2_blend.h"
+#include "fd2_context.h"
+#include "fd2_util.h"
+
+void *
+fd2_blend_state_create(struct pipe_context *pctx,
+ const struct pipe_blend_state *cso)
+{
+ const struct pipe_rt_blend_state *rt = &cso->rt[0];
+ struct fd2_blend_stateobj *so;
+
+ if (cso->logicop_enable) {
+ DBG("Unsupported! logicop");
+ return NULL;
+ }
+
+ if (cso->independent_blend_enable) {
+ DBG("Unsupported! independent blend state");
+ return NULL;
+ }
+
+ so = CALLOC_STRUCT(fd2_blend_stateobj);
+ if (!so)
+ return NULL;
+
+ so->base = *cso;
+
+ so->rb_colorcontrol = A2XX_RB_COLORCONTROL_ROP_CODE(12);
+
+ so->rb_blendcontrol =
+ A2XX_RB_BLEND_CONTROL_COLOR_SRCBLEND(fd_blend_factor(rt->rgb_src_factor)) |
+ A2XX_RB_BLEND_CONTROL_COLOR_COMB_FCN(fd_blend_func(rt->rgb_func)) |
+ A2XX_RB_BLEND_CONTROL_COLOR_DESTBLEND(fd_blend_factor(rt->rgb_dst_factor)) |
+ A2XX_RB_BLEND_CONTROL_ALPHA_SRCBLEND(fd_blend_factor(rt->alpha_src_factor)) |
+ A2XX_RB_BLEND_CONTROL_ALPHA_COMB_FCN(fd_blend_func(rt->alpha_func)) |
+ A2XX_RB_BLEND_CONTROL_ALPHA_DESTBLEND(fd_blend_factor(rt->alpha_dst_factor));
+
+ if (rt->colormask & PIPE_MASK_R)
+ so->rb_colormask |= A2XX_RB_COLOR_MASK_WRITE_RED;
+ if (rt->colormask & PIPE_MASK_G)
+ so->rb_colormask |= A2XX_RB_COLOR_MASK_WRITE_GREEN;
+ if (rt->colormask & PIPE_MASK_B)
+ so->rb_colormask |= A2XX_RB_COLOR_MASK_WRITE_BLUE;
+ if (rt->colormask & PIPE_MASK_A)
+ so->rb_colormask |= A2XX_RB_COLOR_MASK_WRITE_ALPHA;
+
+ if (!rt->blend_enable)
+ so->rb_colorcontrol |= A2XX_RB_COLORCONTROL_BLEND_DISABLE;
+
+ if (cso->dither)
+ so->rb_colorcontrol |= A2XX_RB_COLORCONTROL_DITHER_MODE(DITHER_ALWAYS);
+
+ return so;
+}
--- /dev/null
+/* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */
+
+/*
+ * Copyright (C) 2012-2013 Rob Clark <robclark@freedesktop.org>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Authors:
+ * Rob Clark <robclark@freedesktop.org>
+ */
+
+#ifndef FD2_BLEND_H_
+#define FD2_BLEND_H_
+
+#include "pipe/p_state.h"
+#include "pipe/p_context.h"
+
+struct fd2_blend_stateobj {
+ struct pipe_blend_state base;
+ uint32_t rb_blendcontrol;
+ uint32_t rb_colorcontrol; /* must be OR'd w/ zsa->rb_colorcontrol */
+ uint32_t rb_colormask;
+};
+
+static INLINE struct fd2_blend_stateobj *
+fd2_blend_stateobj(struct pipe_blend_state *blend)
+{
+ return (struct fd2_blend_stateobj *)blend;
+}
+
+void * fd2_blend_state_create(struct pipe_context *pctx,
+ const struct pipe_blend_state *cso);
+
+#endif /* FD2_BLEND_H_ */
--- /dev/null
+/* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */
+
+/*
+ * Copyright (C) 2012 Rob Clark <robclark@freedesktop.org>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Authors:
+ * Rob Clark <robclark@freedesktop.org>
+ */
+
+#include "pipe/p_state.h"
+#include "util/u_string.h"
+#include "util/u_memory.h"
+#include "util/u_inlines.h"
+#include "tgsi/tgsi_parse.h"
+#include "tgsi/tgsi_ureg.h"
+#include "tgsi/tgsi_info.h"
+#include "tgsi/tgsi_strings.h"
+#include "tgsi/tgsi_dump.h"
+
+#include "fd2_compiler.h"
+#include "fd2_program.h"
+#include "fd2_util.h"
+
+#include "instr-a2xx.h"
+#include "ir-a2xx.h"
+
+struct fd2_compile_context {
+ struct fd_program_stateobj *prog;
+ struct fd2_shader_stateobj *so;
+
+ struct tgsi_parse_context parser;
+ unsigned type;
+
+ /* predicate stack: */
+ int pred_depth;
+ enum ir2_pred pred_stack[8];
+
+ /* Internal-Temporary and Predicate register assignment:
+ *
+ * Some TGSI instructions which translate into multiple actual
+ * instructions need one or more temporary registers, which are not
+ * assigned from TGSI perspective (ie. not TGSI_FILE_TEMPORARY).
+ * And some instructions (texture fetch) cannot write directly to
+ * output registers. We could be more clever and re-use dst or a
+ * src register in some cases. But for now don't try to be clever.
+ * Eventually we should implement an optimization pass that re-
+ * juggles the register usage and gets rid of unneeded temporaries.
+ *
+ * The predicate register must be valid across multiple TGSI
+ * instructions, but internal temporary's do not. For this reason,
+ * once the predicate register is requested, until it is no longer
+ * needed, it gets the first register slot after after the TGSI
+ * assigned temporaries (ie. num_regs[TGSI_FILE_TEMPORARY]), and the
+ * internal temporaries get the register slots above this.
+ */
+
+ int pred_reg;
+ int num_internal_temps;
+
+ uint8_t num_regs[TGSI_FILE_COUNT];
+
+ /* maps input register idx to prog->export_linkage idx: */
+ uint8_t input_export_idx[64];
+
+ /* maps output register idx to prog->export_linkage idx: */
+ uint8_t output_export_idx[64];
+
+ /* idx/slot for last compiler generated immediate */
+ unsigned immediate_idx;
+
+ // TODO we can skip emit exports in the VS that the FS doesn't need..
+ // and get rid perhaps of num_param..
+ unsigned num_position, num_param;
+ unsigned position, psize;
+
+ uint64_t need_sync;
+
+ /* current exec CF instruction */
+ struct ir2_cf *cf;
+};
+
+static int
+semantic_idx(struct tgsi_declaration_semantic *semantic)
+{
+ int idx = semantic->Name;
+ if (idx == TGSI_SEMANTIC_GENERIC)
+ idx = TGSI_SEMANTIC_COUNT + semantic->Index;
+ return idx;
+}
+
+/* assign/get the input/export register # for given semantic idx as
+ * returned by semantic_idx():
+ */
+static int
+export_linkage(struct fd2_compile_context *ctx, int idx)
+{
+ struct fd_program_stateobj *prog = ctx->prog;
+
+ /* if first time we've seen this export, assign the next available slot: */
+ if (prog->export_linkage[idx] == 0xff)
+ prog->export_linkage[idx] = prog->num_exports++;
+
+ return prog->export_linkage[idx];
+}
+
+static unsigned
+compile_init(struct fd2_compile_context *ctx, struct fd_program_stateobj *prog,
+ struct fd2_shader_stateobj *so)
+{
+ unsigned ret;
+
+ ctx->prog = prog;
+ ctx->so = so;
+ ctx->cf = NULL;
+ ctx->pred_depth = 0;
+
+ ret = tgsi_parse_init(&ctx->parser, so->tokens);
+ if (ret != TGSI_PARSE_OK)
+ return ret;
+
+ ctx->type = ctx->parser.FullHeader.Processor.Processor;
+ ctx->position = ~0;
+ ctx->psize = ~0;
+ ctx->num_position = 0;
+ ctx->num_param = 0;
+ ctx->need_sync = 0;
+ ctx->immediate_idx = 0;
+ ctx->pred_reg = -1;
+ ctx->num_internal_temps = 0;
+
+ memset(ctx->num_regs, 0, sizeof(ctx->num_regs));
+ memset(ctx->input_export_idx, 0, sizeof(ctx->input_export_idx));
+ memset(ctx->output_export_idx, 0, sizeof(ctx->output_export_idx));
+
+ /* do first pass to extract declarations: */
+ while (!tgsi_parse_end_of_tokens(&ctx->parser)) {
+ tgsi_parse_token(&ctx->parser);
+
+ switch (ctx->parser.FullToken.Token.Type) {
+ case TGSI_TOKEN_TYPE_DECLARATION: {
+ struct tgsi_full_declaration *decl =
+ &ctx->parser.FullToken.FullDeclaration;
+ if (decl->Declaration.File == TGSI_FILE_OUTPUT) {
+ unsigned name = decl->Semantic.Name;
+
+ assert(decl->Declaration.Semantic); // TODO is this ever not true?
+
+ ctx->output_export_idx[decl->Range.First] =
+ semantic_idx(&decl->Semantic);
+
+ if (ctx->type == TGSI_PROCESSOR_VERTEX) {
+ switch (name) {
+ case TGSI_SEMANTIC_POSITION:
+ ctx->position = ctx->num_regs[TGSI_FILE_OUTPUT];
+ ctx->num_position++;
+ break;
+ case TGSI_SEMANTIC_PSIZE:
+ ctx->psize = ctx->num_regs[TGSI_FILE_OUTPUT];
+ ctx->num_position++;
+ break;
+ case TGSI_SEMANTIC_COLOR:
+ case TGSI_SEMANTIC_GENERIC:
+ ctx->num_param++;
+ break;
+ default:
+ DBG("unknown VS semantic name: %s",
+ tgsi_semantic_names[name]);
+ assert(0);
+ }
+ } else {
+ switch (name) {
+ case TGSI_SEMANTIC_COLOR:
+ case TGSI_SEMANTIC_GENERIC:
+ ctx->num_param++;
+ break;
+ default:
+ DBG("unknown PS semantic name: %s",
+ tgsi_semantic_names[name]);
+ assert(0);
+ }
+ }
+ } else if (decl->Declaration.File == TGSI_FILE_INPUT) {
+ ctx->input_export_idx[decl->Range.First] =
+ semantic_idx(&decl->Semantic);
+ }
+ ctx->num_regs[decl->Declaration.File] =
+ MAX2(ctx->num_regs[decl->Declaration.File], decl->Range.Last + 1);
+ break;
+ }
+ case TGSI_TOKEN_TYPE_IMMEDIATE: {
+ struct tgsi_full_immediate *imm =
+ &ctx->parser.FullToken.FullImmediate;
+ unsigned n = ctx->so->num_immediates++;
+ memcpy(ctx->so->immediates[n].val, imm->u, 16);
+ break;
+ }
+ default:
+ break;
+ }
+ }
+
+ /* TGSI generated immediates are always entire vec4's, ones we
+ * generate internally are not:
+ */
+ ctx->immediate_idx = ctx->so->num_immediates * 4;
+
+ ctx->so->first_immediate = ctx->num_regs[TGSI_FILE_CONSTANT];
+
+ tgsi_parse_free(&ctx->parser);
+
+ return tgsi_parse_init(&ctx->parser, so->tokens);
+}
+
+static void
+compile_free(struct fd2_compile_context *ctx)
+{
+ tgsi_parse_free(&ctx->parser);
+}
+
+static struct ir2_cf *
+next_exec_cf(struct fd2_compile_context *ctx)
+{
+ struct ir2_cf *cf = ctx->cf;
+ if (!cf || cf->exec.instrs_count >= ARRAY_SIZE(ctx->cf->exec.instrs))
+ ctx->cf = cf = ir2_cf_create(ctx->so->ir, EXEC);
+ return cf;
+}
+
+static void
+compile_vtx_fetch(struct fd2_compile_context *ctx)
+{
+ struct ir2_instruction **vfetch_instrs = ctx->so->vfetch_instrs;
+ int i;
+ for (i = 0; i < ctx->num_regs[TGSI_FILE_INPUT]; i++) {
+ struct ir2_instruction *instr = ir2_instr_create(
+ next_exec_cf(ctx), IR2_FETCH);
+ instr->fetch.opc = VTX_FETCH;
+
+ ctx->need_sync |= 1 << (i+1);
+
+ ir2_reg_create(instr, i+1, "xyzw", 0);
+ ir2_reg_create(instr, 0, "x", 0);
+
+ if (i == 0)
+ instr->sync = true;
+
+ vfetch_instrs[i] = instr;
+ }
+ ctx->so->num_vfetch_instrs = i;
+ ctx->cf = NULL;
+}
+
+/*
+ * For vertex shaders (VS):
+ * --- ------ -------------
+ *
+ * Inputs: R1-R(num_input)
+ * Constants: C0-C(num_const-1)
+ * Immediates: C(num_const)-C(num_const+num_imm-1)
+ * Outputs: export0-export(n) and export62, export63
+ * n is # of outputs minus gl_Position (export62) and gl_PointSize (export63)
+ * Temps: R(num_input+1)-R(num_input+num_temps)
+ *
+ * R0 could be clobbered after the vertex fetch instructions.. so we
+ * could use it for one of the temporaries.
+ *
+ * TODO: maybe the vertex fetch part could fetch first input into R0 as
+ * the last vtx fetch instruction, which would let us use the same
+ * register layout in either case.. although this is not what the blob
+ * compiler does.
+ *
+ *
+ * For frag shaders (PS):
+ * --- ---- -------------
+ *
+ * Inputs: R0-R(num_input-1)
+ * Constants: same as VS
+ * Immediates: same as VS
+ * Outputs: export0-export(num_outputs)
+ * Temps: R(num_input)-R(num_input+num_temps-1)
+ *
+ * In either case, immediates are are postpended to the constants
+ * (uniforms).
+ *
+ */
+
+static unsigned
+get_temp_gpr(struct fd2_compile_context *ctx, int idx)
+{
+ unsigned num = idx + ctx->num_regs[TGSI_FILE_INPUT];
+ if (ctx->type == TGSI_PROCESSOR_VERTEX)
+ num++;
+ return num;
+}
+
+static struct ir2_register *
+add_dst_reg(struct fd2_compile_context *ctx, struct ir2_instruction *alu,
+ const struct tgsi_dst_register *dst)
+{
+ unsigned flags = 0, num = 0;
+ char swiz[5];
+
+ switch (dst->File) {
+ case TGSI_FILE_OUTPUT:
+ flags |= IR2_REG_EXPORT;
+ if (ctx->type == TGSI_PROCESSOR_VERTEX) {
+ if (dst->Index == ctx->position) {
+ num = 62;
+ } else if (dst->Index == ctx->psize) {
+ num = 63;
+ } else {
+ num = export_linkage(ctx,
+ ctx->output_export_idx[dst->Index]);
+ }
+ } else {
+ num = dst->Index;
+ }
+ break;
+ case TGSI_FILE_TEMPORARY:
+ num = get_temp_gpr(ctx, dst->Index);
+ break;
+ default:
+ DBG("unsupported dst register file: %s",
+ tgsi_file_name(dst->File));
+ assert(0);
+ break;
+ }
+
+ swiz[0] = (dst->WriteMask & TGSI_WRITEMASK_X) ? 'x' : '_';
+ swiz[1] = (dst->WriteMask & TGSI_WRITEMASK_Y) ? 'y' : '_';
+ swiz[2] = (dst->WriteMask & TGSI_WRITEMASK_Z) ? 'z' : '_';
+ swiz[3] = (dst->WriteMask & TGSI_WRITEMASK_W) ? 'w' : '_';
+ swiz[4] = '\0';
+
+ return ir2_reg_create(alu, num, swiz, flags);
+}
+
+static struct ir2_register *
+add_src_reg(struct fd2_compile_context *ctx, struct ir2_instruction *alu,
+ const struct tgsi_src_register *src)
+{
+ static const char swiz_vals[] = {
+ 'x', 'y', 'z', 'w',
+ };
+ char swiz[5];
+ unsigned flags = 0, num = 0;
+
+ switch (src->File) {
+ case TGSI_FILE_CONSTANT:
+ num = src->Index;
+ flags |= IR2_REG_CONST;
+ break;
+ case TGSI_FILE_INPUT:
+ if (ctx->type == TGSI_PROCESSOR_VERTEX) {
+ num = src->Index + 1;
+ } else {
+ num = export_linkage(ctx,
+ ctx->input_export_idx[src->Index]);
+ }
+ break;
+ case TGSI_FILE_TEMPORARY:
+ num = get_temp_gpr(ctx, src->Index);
+ break;
+ case TGSI_FILE_IMMEDIATE:
+ num = src->Index + ctx->num_regs[TGSI_FILE_CONSTANT];
+ flags |= IR2_REG_CONST;
+ break;
+ default:
+ DBG("unsupported src register file: %s",
+ tgsi_file_name(src->File));
+ assert(0);
+ break;
+ }
+
+ if (src->Absolute)
+ flags |= IR2_REG_ABS;
+ if (src->Negate)
+ flags |= IR2_REG_NEGATE;
+
+ swiz[0] = swiz_vals[src->SwizzleX];
+ swiz[1] = swiz_vals[src->SwizzleY];
+ swiz[2] = swiz_vals[src->SwizzleZ];
+ swiz[3] = swiz_vals[src->SwizzleW];
+ swiz[4] = '\0';
+
+ if ((ctx->need_sync & (uint64_t)(1 << num)) &&
+ !(flags & IR2_REG_CONST)) {
+ alu->sync = true;
+ ctx->need_sync &= ~(uint64_t)(1 << num);
+ }
+
+ return ir2_reg_create(alu, num, swiz, flags);
+}
+
+static void
+add_vector_clamp(struct tgsi_full_instruction *inst, struct ir2_instruction *alu)
+{
+ switch (inst->Instruction.Saturate) {
+ case TGSI_SAT_NONE:
+ break;
+ case TGSI_SAT_ZERO_ONE:
+ alu->alu.vector_clamp = true;
+ break;
+ case TGSI_SAT_MINUS_PLUS_ONE:
+ DBG("unsupported saturate");
+ assert(0);
+ break;
+ }
+}
+
+static void
+add_scalar_clamp(struct tgsi_full_instruction *inst, struct ir2_instruction *alu)
+{
+ switch (inst->Instruction.Saturate) {
+ case TGSI_SAT_NONE:
+ break;
+ case TGSI_SAT_ZERO_ONE:
+ alu->alu.scalar_clamp = true;
+ break;
+ case TGSI_SAT_MINUS_PLUS_ONE:
+ DBG("unsupported saturate");
+ assert(0);
+ break;
+ }
+}
+
+static void
+add_regs_vector_1(struct fd2_compile_context *ctx,
+ struct tgsi_full_instruction *inst, struct ir2_instruction *alu)
+{
+ assert(inst->Instruction.NumSrcRegs == 1);
+ assert(inst->Instruction.NumDstRegs == 1);
+
+ add_dst_reg(ctx, alu, &inst->Dst[0].Register);
+ add_src_reg(ctx, alu, &inst->Src[0].Register);
+ add_src_reg(ctx, alu, &inst->Src[0].Register);
+ add_vector_clamp(inst, alu);
+}
+
+static void
+add_regs_vector_2(struct fd2_compile_context *ctx,
+ struct tgsi_full_instruction *inst, struct ir2_instruction *alu)
+{
+ assert(inst->Instruction.NumSrcRegs == 2);
+ assert(inst->Instruction.NumDstRegs == 1);
+
+ add_dst_reg(ctx, alu, &inst->Dst[0].Register);
+ add_src_reg(ctx, alu, &inst->Src[0].Register);
+ add_src_reg(ctx, alu, &inst->Src[1].Register);
+ add_vector_clamp(inst, alu);
+}
+
+static void
+add_regs_vector_3(struct fd2_compile_context *ctx,
+ struct tgsi_full_instruction *inst, struct ir2_instruction *alu)
+{
+ assert(inst->Instruction.NumSrcRegs == 3);
+ assert(inst->Instruction.NumDstRegs == 1);
+
+ add_dst_reg(ctx, alu, &inst->Dst[0].Register);
+ /* maybe should re-arrange the syntax some day, but
+ * in assembler/disassembler and what ir.c expects
+ * is: MULADDv Rdst = Rsrc2 + Rsrc0 * Rscr1
+ */
+ add_src_reg(ctx, alu, &inst->Src[2].Register);
+ add_src_reg(ctx, alu, &inst->Src[0].Register);
+ add_src_reg(ctx, alu, &inst->Src[1].Register);
+ add_vector_clamp(inst, alu);
+}
+
+static void
+add_regs_dummy_vector(struct ir2_instruction *alu)
+{
+ /* create dummy, non-written vector dst/src regs
+ * for unused vector instr slot:
+ */
+ ir2_reg_create(alu, 0, "____", 0); /* vector dst */
+ ir2_reg_create(alu, 0, NULL, 0); /* vector src1 */
+ ir2_reg_create(alu, 0, NULL, 0); /* vector src2 */
+}
+
+static void
+add_regs_scalar_1(struct fd2_compile_context *ctx,
+ struct tgsi_full_instruction *inst, struct ir2_instruction *alu)
+{
+ assert(inst->Instruction.NumSrcRegs == 1);
+ assert(inst->Instruction.NumDstRegs == 1);
+
+ add_regs_dummy_vector(alu);
+
+ add_dst_reg(ctx, alu, &inst->Dst[0].Register);
+ add_src_reg(ctx, alu, &inst->Src[0].Register);
+ add_scalar_clamp(inst, alu);
+}
+
+/*
+ * Helpers for TGSI instructions that don't map to a single shader instr:
+ */
+
+static void
+src_from_dst(struct tgsi_src_register *src, struct tgsi_dst_register *dst)
+{
+ src->File = dst->File;
+ src->Indirect = dst->Indirect;
+ src->Dimension = dst->Dimension;
+ src->Index = dst->Index;
+ src->Absolute = 0;
+ src->Negate = 0;
+ src->SwizzleX = TGSI_SWIZZLE_X;
+ src->SwizzleY = TGSI_SWIZZLE_Y;
+ src->SwizzleZ = TGSI_SWIZZLE_Z;
+ src->SwizzleW = TGSI_SWIZZLE_W;
+}
+
+/* Get internal-temp src/dst to use for a sequence of instructions
+ * generated by a single TGSI op.
+ */
+static void
+get_internal_temp(struct fd2_compile_context *ctx,
+ struct tgsi_dst_register *tmp_dst,
+ struct tgsi_src_register *tmp_src)
+{
+ int n;
+
+ tmp_dst->File = TGSI_FILE_TEMPORARY;
+ tmp_dst->WriteMask = TGSI_WRITEMASK_XYZW;
+ tmp_dst->Indirect = 0;
+ tmp_dst->Dimension = 0;
+
+ /* assign next temporary: */
+ n = ctx->num_internal_temps++;
+ if (ctx->pred_reg != -1)
+ n++;
+
+ tmp_dst->Index = ctx->num_regs[TGSI_FILE_TEMPORARY] + n;
+
+ src_from_dst(tmp_src, tmp_dst);
+}
+
+static void
+get_predicate(struct fd2_compile_context *ctx, struct tgsi_dst_register *dst,
+ struct tgsi_src_register *src)
+{
+ assert(ctx->pred_reg != -1);
+
+ dst->File = TGSI_FILE_TEMPORARY;
+ dst->WriteMask = TGSI_WRITEMASK_W;
+ dst->Indirect = 0;
+ dst->Dimension = 0;
+ dst->Index = get_temp_gpr(ctx, ctx->pred_reg);
+
+ if (src) {
+ src_from_dst(src, dst);
+ src->SwizzleX = TGSI_SWIZZLE_W;
+ src->SwizzleY = TGSI_SWIZZLE_W;
+ src->SwizzleZ = TGSI_SWIZZLE_W;
+ src->SwizzleW = TGSI_SWIZZLE_W;
+ }
+}
+
+static void
+push_predicate(struct fd2_compile_context *ctx, struct tgsi_src_register *src)
+{
+ struct ir2_instruction *alu;
+ struct tgsi_dst_register pred_dst;
+
+ /* NOTE blob compiler seems to always puts PRED_* instrs in a CF by
+ * themselves:
+ */
+ ctx->cf = NULL;
+
+ if (ctx->pred_depth == 0) {
+ /* assign predicate register: */
+ ctx->pred_reg = ctx->num_regs[TGSI_FILE_TEMPORARY];
+
+ get_predicate(ctx, &pred_dst, NULL);
+
+ alu = ir2_instr_create_alu(next_exec_cf(ctx), ~0, PRED_SETNEs);
+ add_regs_dummy_vector(alu);
+ add_dst_reg(ctx, alu, &pred_dst);
+ add_src_reg(ctx, alu, src);
+ } else {
+ struct tgsi_src_register pred_src;
+
+ get_predicate(ctx, &pred_dst, &pred_src);
+
+ alu = ir2_instr_create_alu(next_exec_cf(ctx), MULv, ~0);
+ add_dst_reg(ctx, alu, &pred_dst);
+ add_src_reg(ctx, alu, &pred_src);
+ add_src_reg(ctx, alu, src);
+
+ // XXX need to make PRED_SETE_PUSHv IR2_PRED_NONE.. but need to make
+ // sure src reg is valid if it was calculated with a predicate
+ // condition..
+ alu->pred = IR2_PRED_NONE;
+ }
+
+ /* save previous pred state to restore in pop_predicate(): */
+ ctx->pred_stack[ctx->pred_depth++] = ctx->so->ir->pred;
+
+ ctx->cf = NULL;
+}
+
+static void
+pop_predicate(struct fd2_compile_context *ctx)
+{
+ /* NOTE blob compiler seems to always puts PRED_* instrs in a CF by
+ * themselves:
+ */
+ ctx->cf = NULL;
+
+ /* restore previous predicate state: */
+ ctx->so->ir->pred = ctx->pred_stack[--ctx->pred_depth];
+
+ if (ctx->pred_depth != 0) {
+ struct ir2_instruction *alu;
+ struct tgsi_dst_register pred_dst;
+ struct tgsi_src_register pred_src;
+
+ get_predicate(ctx, &pred_dst, &pred_src);
+
+ alu = ir2_instr_create_alu(next_exec_cf(ctx), ~0, PRED_SET_POPs);
+ add_regs_dummy_vector(alu);
+ add_dst_reg(ctx, alu, &pred_dst);
+ add_src_reg(ctx, alu, &pred_src);
+ alu->pred = IR2_PRED_NONE;
+ } else {
+ /* predicate register no longer needed: */
+ ctx->pred_reg = -1;
+ }
+
+ ctx->cf = NULL;
+}
+
+static void
+get_immediate(struct fd2_compile_context *ctx,
+ struct tgsi_src_register *reg, uint32_t val)
+{
+ unsigned neg, swiz, idx, i;
+ /* actually maps 1:1 currently.. not sure if that is safe to rely on: */
+ static const unsigned swiz2tgsi[] = {
+ TGSI_SWIZZLE_X, TGSI_SWIZZLE_Y, TGSI_SWIZZLE_Z, TGSI_SWIZZLE_W,
+ };
+
+ for (i = 0; i < ctx->immediate_idx; i++) {
+ swiz = i % 4;
+ idx = i / 4;
+
+ if (ctx->so->immediates[idx].val[swiz] == val) {
+ neg = 0;
+ break;
+ }
+
+ if (ctx->so->immediates[idx].val[swiz] == -val) {
+ neg = 1;
+ break;
+ }
+ }
+
+ if (i == ctx->immediate_idx) {
+ /* need to generate a new immediate: */
+ swiz = i % 4;
+ idx = i / 4;
+ neg = 0;
+ ctx->so->immediates[idx].val[swiz] = val;
+ ctx->so->num_immediates = idx + 1;
+ ctx->immediate_idx++;
+ }
+
+ reg->File = TGSI_FILE_IMMEDIATE;
+ reg->Indirect = 0;
+ reg->Dimension = 0;
+ reg->Index = idx;
+ reg->Absolute = 0;
+ reg->Negate = neg;
+ reg->SwizzleX = swiz2tgsi[swiz];
+ reg->SwizzleY = swiz2tgsi[swiz];
+ reg->SwizzleZ = swiz2tgsi[swiz];
+ reg->SwizzleW = swiz2tgsi[swiz];
+}
+
+/* POW(a,b) = EXP2(b * LOG2(a)) */
+static void
+translate_pow(struct fd2_compile_context *ctx,
+ struct tgsi_full_instruction *inst)
+{
+ struct tgsi_dst_register tmp_dst;
+ struct tgsi_src_register tmp_src;
+ struct ir2_instruction *alu;
+
+ get_internal_temp(ctx, &tmp_dst, &tmp_src);
+
+ alu = ir2_instr_create_alu(next_exec_cf(ctx), ~0, LOG_CLAMP);
+ add_regs_dummy_vector(alu);
+ add_dst_reg(ctx, alu, &tmp_dst);
+ add_src_reg(ctx, alu, &inst->Src[0].Register);
+
+ alu = ir2_instr_create_alu(next_exec_cf(ctx), MULv, ~0);
+ add_dst_reg(ctx, alu, &tmp_dst);
+ add_src_reg(ctx, alu, &tmp_src);
+ add_src_reg(ctx, alu, &inst->Src[1].Register);
+
+ /* NOTE: some of the instructions, like EXP_IEEE, seem hard-
+ * coded to take their input from the w component.
+ */
+ switch(inst->Dst[0].Register.WriteMask) {
+ case TGSI_WRITEMASK_X:
+ tmp_src.SwizzleW = TGSI_SWIZZLE_X;
+ break;
+ case TGSI_WRITEMASK_Y:
+ tmp_src.SwizzleW = TGSI_SWIZZLE_Y;
+ break;
+ case TGSI_WRITEMASK_Z:
+ tmp_src.SwizzleW = TGSI_SWIZZLE_Z;
+ break;
+ case TGSI_WRITEMASK_W:
+ tmp_src.SwizzleW = TGSI_SWIZZLE_W;
+ break;
+ default:
+ DBG("invalid writemask!");
+ assert(0);
+ break;
+ }
+
+ alu = ir2_instr_create_alu(next_exec_cf(ctx), ~0, EXP_IEEE);
+ add_regs_dummy_vector(alu);
+ add_dst_reg(ctx, alu, &inst->Dst[0].Register);
+ add_src_reg(ctx, alu, &tmp_src);
+ add_scalar_clamp(inst, alu);
+}
+
+static void
+translate_tex(struct fd2_compile_context *ctx,
+ struct tgsi_full_instruction *inst, unsigned opc)
+{
+ struct ir2_instruction *instr;
+ struct ir2_register *reg;
+ struct tgsi_dst_register tmp_dst;
+ struct tgsi_src_register tmp_src;
+ const struct tgsi_src_register *coord;
+ bool using_temp = (inst->Dst[0].Register.File == TGSI_FILE_OUTPUT) ||
+ (inst->Instruction.Saturate != TGSI_SAT_NONE);
+ int idx;
+
+ if (using_temp || (opc == TGSI_OPCODE_TXP))
+ get_internal_temp(ctx, &tmp_dst, &tmp_src);
+
+ if (opc == TGSI_OPCODE_TXP) {
+ static const char *swiz[] = {
+ [TGSI_SWIZZLE_X] = "xxxx",
+ [TGSI_SWIZZLE_Y] = "yyyy",
+ [TGSI_SWIZZLE_Z] = "zzzz",
+ [TGSI_SWIZZLE_W] = "wwww",
+ };
+
+ /* TXP - Projective Texture Lookup:
+ *
+ * coord.x = src0.x / src.w
+ * coord.y = src0.y / src.w
+ * coord.z = src0.z / src.w
+ * coord.w = src0.w
+ * bias = 0.0
+ *
+ * dst = texture_sample(unit, coord, bias)
+ */
+ instr = ir2_instr_create_alu(next_exec_cf(ctx), MAXv, RECIP_IEEE);
+
+ /* MAXv: */
+ add_dst_reg(ctx, instr, &tmp_dst)->swizzle = "___w";
+ add_src_reg(ctx, instr, &inst->Src[0].Register);
+ add_src_reg(ctx, instr, &inst->Src[0].Register);
+
+ /* RECIP_IEEE: */
+ add_dst_reg(ctx, instr, &tmp_dst)->swizzle = "x___";
+ add_src_reg(ctx, instr, &inst->Src[0].Register)->swizzle =
+ swiz[inst->Src[0].Register.SwizzleW];
+
+ instr = ir2_instr_create_alu(next_exec_cf(ctx), MULv, ~0);
+ add_dst_reg(ctx, instr, &tmp_dst)->swizzle = "xyz_";
+ add_src_reg(ctx, instr, &tmp_src)->swizzle = "xxxx";
+ add_src_reg(ctx, instr, &inst->Src[0].Register);
+
+ coord = &tmp_src;
+ } else {
+ coord = &inst->Src[0].Register;
+ }
+
+ instr = ir2_instr_create(next_exec_cf(ctx), IR2_FETCH);
+ instr->fetch.opc = TEX_FETCH;
+ instr->fetch.is_cube = (inst->Texture.Texture == TGSI_TEXTURE_3D);
+ assert(inst->Texture.NumOffsets <= 1); // TODO what to do in other cases?
+
+ /* save off the tex fetch to be patched later with correct const_idx: */
+ idx = ctx->so->num_tfetch_instrs++;
+ ctx->so->tfetch_instrs[idx].samp_id = inst->Src[1].Register.Index;
+ ctx->so->tfetch_instrs[idx].instr = instr;
+
+ add_dst_reg(ctx, instr, using_temp ? &tmp_dst : &inst->Dst[0].Register);
+ reg = add_src_reg(ctx, instr, coord);
+
+ /* blob compiler always sets 3rd component to same as 1st for 2d: */
+ if (inst->Texture.Texture == TGSI_TEXTURE_2D)
+ reg->swizzle[2] = reg->swizzle[0];
+
+ /* dst register needs to be marked for sync: */
+ ctx->need_sync |= 1 << instr->regs[0]->num;
+
+ /* TODO we need some way to know if the tex fetch needs to sync on alu pipe.. */
+ instr->sync = true;
+
+ if (using_temp) {
+ /* texture fetch can't write directly to export, so if tgsi
+ * is telling us the dst register is in output file, we load
+ * the texture to a temp and the use ALU instruction to move
+ * to output
+ */
+ instr = ir2_instr_create_alu(next_exec_cf(ctx), MAXv, ~0);
+
+ add_dst_reg(ctx, instr, &inst->Dst[0].Register);
+ add_src_reg(ctx, instr, &tmp_src);
+ add_src_reg(ctx, instr, &tmp_src);
+ add_vector_clamp(inst, instr);
+ }
+}
+
+/* SGE(a,b) = GTE((b - a), 1.0, 0.0) */
+/* SLT(a,b) = GTE((b - a), 0.0, 1.0) */
+static void
+translate_sge_slt(struct fd2_compile_context *ctx,
+ struct tgsi_full_instruction *inst, unsigned opc)
+{
+ struct ir2_instruction *instr;
+ struct tgsi_dst_register tmp_dst;
+ struct tgsi_src_register tmp_src;
+ struct tgsi_src_register tmp_const;
+ float c0, c1;
+
+ switch (opc) {
+ default:
+ assert(0);
+ case TGSI_OPCODE_SGE:
+ c0 = 1.0;
+ c1 = 0.0;
+ break;
+ case TGSI_OPCODE_SLT:
+ c0 = 0.0;
+ c1 = 1.0;
+ break;
+ }
+
+ get_internal_temp(ctx, &tmp_dst, &tmp_src);
+
+ instr = ir2_instr_create_alu(next_exec_cf(ctx), ADDv, ~0);
+ add_dst_reg(ctx, instr, &tmp_dst);
+ add_src_reg(ctx, instr, &inst->Src[0].Register)->flags |= IR2_REG_NEGATE;
+ add_src_reg(ctx, instr, &inst->Src[1].Register);
+
+ instr = ir2_instr_create_alu(next_exec_cf(ctx), CNDGTEv, ~0);
+ add_dst_reg(ctx, instr, &inst->Dst[0].Register);
+ /* maybe should re-arrange the syntax some day, but
+ * in assembler/disassembler and what ir.c expects
+ * is: MULADDv Rdst = Rsrc2 + Rsrc0 * Rscr1
+ */
+ get_immediate(ctx, &tmp_const, fui(c0));
+ add_src_reg(ctx, instr, &tmp_const);
+ add_src_reg(ctx, instr, &tmp_src);
+ get_immediate(ctx, &tmp_const, fui(c1));
+ add_src_reg(ctx, instr, &tmp_const);
+}
+
+/* LRP(a,b,c) = (a * b) + ((1 - a) * c) */
+static void
+translate_lrp(struct fd2_compile_context *ctx,
+ struct tgsi_full_instruction *inst,
+ unsigned opc)
+{
+ struct ir2_instruction *instr;
+ struct tgsi_dst_register tmp_dst1, tmp_dst2;
+ struct tgsi_src_register tmp_src1, tmp_src2;
+ struct tgsi_src_register tmp_const;
+
+ get_internal_temp(ctx, &tmp_dst1, &tmp_src1);
+ get_internal_temp(ctx, &tmp_dst2, &tmp_src2);
+
+ get_immediate(ctx, &tmp_const, fui(1.0));
+
+ /* tmp1 = (a * b) */
+ instr = ir2_instr_create_alu(next_exec_cf(ctx), MULv, ~0);
+ add_dst_reg(ctx, instr, &tmp_dst1);
+ add_src_reg(ctx, instr, &inst->Src[0].Register);
+ add_src_reg(ctx, instr, &inst->Src[1].Register);
+
+ /* tmp2 = (1 - a) */
+ instr = ir2_instr_create_alu(next_exec_cf(ctx), ADDv, ~0);
+ add_dst_reg(ctx, instr, &tmp_dst2);
+ add_src_reg(ctx, instr, &tmp_const);
+ add_src_reg(ctx, instr, &inst->Src[0].Register)->flags |= IR2_REG_NEGATE;
+
+ /* tmp2 = tmp2 * c */
+ instr = ir2_instr_create_alu(next_exec_cf(ctx), MULv, ~0);
+ add_dst_reg(ctx, instr, &tmp_dst2);
+ add_src_reg(ctx, instr, &tmp_src2);
+ add_src_reg(ctx, instr, &inst->Src[2].Register);
+
+ /* dst = tmp1 + tmp2 */
+ instr = ir2_instr_create_alu(next_exec_cf(ctx), ADDv, ~0);
+ add_dst_reg(ctx, instr, &inst->Dst[0].Register);
+ add_src_reg(ctx, instr, &tmp_src1);
+ add_src_reg(ctx, instr, &tmp_src2);
+}
+
+static void
+translate_trig(struct fd2_compile_context *ctx,
+ struct tgsi_full_instruction *inst,
+ unsigned opc)
+{
+ struct ir2_instruction *instr;
+ struct tgsi_dst_register tmp_dst;
+ struct tgsi_src_register tmp_src;
+ struct tgsi_src_register tmp_const;
+ instr_scalar_opc_t op;
+
+ switch (opc) {
+ default:
+ assert(0);
+ case TGSI_OPCODE_SIN:
+ op = SIN;
+ break;
+ case TGSI_OPCODE_COS:
+ op = COS;
+ break;
+ }
+
+ get_internal_temp(ctx, &tmp_dst, &tmp_src);
+
+ tmp_dst.WriteMask = TGSI_WRITEMASK_X;
+ tmp_src.SwizzleX = tmp_src.SwizzleY =
+ tmp_src.SwizzleZ = tmp_src.SwizzleW = TGSI_SWIZZLE_X;
+
+ /* maybe should re-arrange the syntax some day, but
+ * in assembler/disassembler and what ir.c expects
+ * is: MULADDv Rdst = Rsrc2 + Rsrc0 * Rscr1
+ */
+ instr = ir2_instr_create_alu(next_exec_cf(ctx), MULADDv, ~0);
+ add_dst_reg(ctx, instr, &tmp_dst);
+ get_immediate(ctx, &tmp_const, fui(0.5));
+ add_src_reg(ctx, instr, &tmp_const);
+ add_src_reg(ctx, instr, &inst->Src[0].Register);
+ get_immediate(ctx, &tmp_const, fui(0.159155));
+ add_src_reg(ctx, instr, &tmp_const);
+
+ instr = ir2_instr_create_alu(next_exec_cf(ctx), FRACv, ~0);
+ add_dst_reg(ctx, instr, &tmp_dst);
+ add_src_reg(ctx, instr, &tmp_src);
+ add_src_reg(ctx, instr, &tmp_src);
+
+ instr = ir2_instr_create_alu(next_exec_cf(ctx), MULADDv, ~0);
+ add_dst_reg(ctx, instr, &tmp_dst);
+ get_immediate(ctx, &tmp_const, fui(-3.141593));
+ add_src_reg(ctx, instr, &tmp_const);
+ add_src_reg(ctx, instr, &tmp_src);
+ get_immediate(ctx, &tmp_const, fui(6.283185));
+ add_src_reg(ctx, instr, &tmp_const);
+
+ instr = ir2_instr_create_alu(next_exec_cf(ctx), ~0, op);
+ add_regs_dummy_vector(instr);
+ add_dst_reg(ctx, instr, &inst->Dst[0].Register);
+ add_src_reg(ctx, instr, &tmp_src);
+}
+
+/*
+ * Main part of compiler/translator:
+ */
+
+static void
+translate_instruction(struct fd2_compile_context *ctx,
+ struct tgsi_full_instruction *inst)
+{
+ unsigned opc = inst->Instruction.Opcode;
+ struct ir2_instruction *instr;
+ static struct ir2_cf *cf;
+
+ if (opc == TGSI_OPCODE_END)
+ return;
+
+ if (inst->Dst[0].Register.File == TGSI_FILE_OUTPUT) {
+ unsigned num = inst->Dst[0].Register.Index;
+ /* seems like we need to ensure that position vs param/pixel
+ * exports don't end up in the same EXEC clause.. easy way
+ * to do this is force a new EXEC clause on first appearance
+ * of an position or param/pixel export.
+ */
+ if ((num == ctx->position) || (num == ctx->psize)) {
+ if (ctx->num_position > 0) {
+ ctx->cf = NULL;
+ ir2_cf_create_alloc(ctx->so->ir, SQ_POSITION,
+ ctx->num_position - 1);
+ ctx->num_position = 0;
+ }
+ } else {
+ if (ctx->num_param > 0) {
+ ctx->cf = NULL;
+ ir2_cf_create_alloc(ctx->so->ir, SQ_PARAMETER_PIXEL,
+ ctx->num_param - 1);
+ ctx->num_param = 0;
+ }
+ }
+ }
+
+ cf = next_exec_cf(ctx);
+
+ /* TODO turn this into a table: */
+ switch (opc) {
+ case TGSI_OPCODE_MOV:
+ instr = ir2_instr_create_alu(cf, MAXv, ~0);
+ add_regs_vector_1(ctx, inst, instr);
+ break;
+ case TGSI_OPCODE_RCP:
+ instr = ir2_instr_create_alu(cf, ~0, RECIP_IEEE);
+ add_regs_scalar_1(ctx, inst, instr);
+ break;
+ case TGSI_OPCODE_RSQ:
+ instr = ir2_instr_create_alu(cf, ~0, RECIPSQ_IEEE);
+ add_regs_scalar_1(ctx, inst, instr);
+ break;
+ case TGSI_OPCODE_MUL:
+ instr = ir2_instr_create_alu(cf, MULv, ~0);
+ add_regs_vector_2(ctx, inst, instr);
+ break;
+ case TGSI_OPCODE_ADD:
+ instr = ir2_instr_create_alu(cf, ADDv, ~0);
+ add_regs_vector_2(ctx, inst, instr);
+ break;
+ case TGSI_OPCODE_DP3:
+ instr = ir2_instr_create_alu(cf, DOT3v, ~0);
+ add_regs_vector_2(ctx, inst, instr);
+ break;
+ case TGSI_OPCODE_DP4:
+ instr = ir2_instr_create_alu(cf, DOT4v, ~0);
+ add_regs_vector_2(ctx, inst, instr);
+ break;
+ case TGSI_OPCODE_MIN:
+ instr = ir2_instr_create_alu(cf, MINv, ~0);
+ add_regs_vector_2(ctx, inst, instr);
+ break;
+ case TGSI_OPCODE_MAX:
+ instr = ir2_instr_create_alu(cf, MAXv, ~0);
+ add_regs_vector_2(ctx, inst, instr);
+ break;
+ case TGSI_OPCODE_SLT:
+ case TGSI_OPCODE_SGE:
+ translate_sge_slt(ctx, inst, opc);
+ break;
+ case TGSI_OPCODE_MAD:
+ instr = ir2_instr_create_alu(cf, MULADDv, ~0);
+ add_regs_vector_3(ctx, inst, instr);
+ break;
+ case TGSI_OPCODE_LRP:
+ translate_lrp(ctx, inst, opc);
+ break;
+ case TGSI_OPCODE_FRC:
+ instr = ir2_instr_create_alu(cf, FRACv, ~0);
+ add_regs_vector_1(ctx, inst, instr);
+ break;
+ case TGSI_OPCODE_FLR:
+ instr = ir2_instr_create_alu(cf, FLOORv, ~0);
+ add_regs_vector_1(ctx, inst, instr);
+ break;
+ case TGSI_OPCODE_EX2:
+ instr = ir2_instr_create_alu(cf, ~0, EXP_IEEE);
+ add_regs_scalar_1(ctx, inst, instr);
+ break;
+ case TGSI_OPCODE_POW:
+ translate_pow(ctx, inst);
+ break;
+ case TGSI_OPCODE_ABS:
+ instr = ir2_instr_create_alu(cf, MAXv, ~0);
+ add_regs_vector_1(ctx, inst, instr);
+ instr->regs[1]->flags |= IR2_REG_NEGATE; /* src0 */
+ break;
+ case TGSI_OPCODE_COS:
+ case TGSI_OPCODE_SIN:
+ translate_trig(ctx, inst, opc);
+ break;
+ case TGSI_OPCODE_TEX:
+ case TGSI_OPCODE_TXP:
+ translate_tex(ctx, inst, opc);
+ break;
+ case TGSI_OPCODE_CMP:
+ instr = ir2_instr_create_alu(cf, CNDGTEv, ~0);
+ add_regs_vector_3(ctx, inst, instr);
+ // TODO this should be src0 if regs where in sane order..
+ instr->regs[2]->flags ^= IR2_REG_NEGATE; /* src1 */
+ break;
+ case TGSI_OPCODE_IF:
+ push_predicate(ctx, &inst->Src[0].Register);
+ ctx->so->ir->pred = IR2_PRED_EQ;
+ break;
+ case TGSI_OPCODE_ELSE:
+ ctx->so->ir->pred = IR2_PRED_NE;
+ /* not sure if this is required in all cases, but blob compiler
+ * won't combine EQ and NE in same CF:
+ */
+ ctx->cf = NULL;
+ break;
+ case TGSI_OPCODE_ENDIF:
+ pop_predicate(ctx);
+ break;
+ case TGSI_OPCODE_F2I:
+ instr = ir2_instr_create_alu(cf, TRUNCv, ~0);
+ add_regs_vector_1(ctx, inst, instr);
+ break;
+ default:
+ DBG("unknown TGSI opc: %s", tgsi_get_opcode_name(opc));
+ tgsi_dump(ctx->so->tokens, 0);
+ assert(0);
+ break;
+ }
+
+ /* internal temporaries are only valid for the duration of a single
+ * TGSI instruction:
+ */
+ ctx->num_internal_temps = 0;
+}
+
+static void
+compile_instructions(struct fd2_compile_context *ctx)
+{
+ while (!tgsi_parse_end_of_tokens(&ctx->parser)) {
+ tgsi_parse_token(&ctx->parser);
+
+ switch (ctx->parser.FullToken.Token.Type) {
+ case TGSI_TOKEN_TYPE_INSTRUCTION:
+ translate_instruction(ctx,
+ &ctx->parser.FullToken.FullInstruction);
+ break;
+ default:
+ break;
+ }
+ }
+
+ ctx->cf->cf_type = EXEC_END;
+}
+
+int
+fd2_compile_shader(struct fd_program_stateobj *prog,
+ struct fd2_shader_stateobj *so)
+{
+ struct fd2_compile_context ctx;
+
+ ir2_shader_destroy(so->ir);
+ so->ir = ir2_shader_create();
+ so->num_vfetch_instrs = so->num_tfetch_instrs = so->num_immediates = 0;
+
+ if (compile_init(&ctx, prog, so) != TGSI_PARSE_OK)
+ return -1;
+
+ if (ctx.type == TGSI_PROCESSOR_VERTEX) {
+ compile_vtx_fetch(&ctx);
+ } else if (ctx.type == TGSI_PROCESSOR_FRAGMENT) {
+ prog->num_exports = 0;
+ memset(prog->export_linkage, 0xff,
+ sizeof(prog->export_linkage));
+ }
+
+ compile_instructions(&ctx);
+
+ compile_free(&ctx);
+
+ return 0;
+}
+
--- /dev/null
+/* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */
+
+/*
+ * Copyright (C) 2012 Rob Clark <robclark@freedesktop.org>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Authors:
+ * Rob Clark <robclark@freedesktop.org>
+ */
+
+#ifndef FD2_COMPILER_H_
+#define FD2_COMPILER_H_
+
+#include "fd2_program.h"
+#include "fd2_util.h"
+
+int fd2_compile_shader(struct fd_program_stateobj *prog,
+ struct fd2_shader_stateobj *so);
+
+#endif /* FD2_COMPILER_H_ */
--- /dev/null
+/* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */
+
+/*
+ * Copyright (C) 2013 Rob Clark <robclark@freedesktop.org>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Authors:
+ * Rob Clark <robclark@freedesktop.org>
+ */
+
+
+#include "fd2_context.h"
+#include "fd2_blend.h"
+#include "fd2_draw.h"
+#include "fd2_emit.h"
+#include "fd2_gmem.h"
+#include "fd2_program.h"
+#include "fd2_rasterizer.h"
+#include "fd2_texture.h"
+#include "fd2_zsa.h"
+
+static void
+fd2_context_destroy(struct pipe_context *pctx)
+{
+ fd2_prog_fini(pctx);
+ fd_context_destroy(pctx);
+}
+
+static struct pipe_resource *
+create_solid_vertexbuf(struct pipe_context *pctx)
+{
+ static const float init_shader_const[] = {
+ /* for clear/gmem2mem: */
+ -1.000000, +1.000000, +1.000000, +1.100000,
+ +1.000000, +1.000000, -1.000000, -1.100000,
+ +1.000000, +1.100000, -1.100000, +1.000000,
+ /* for mem2gmem: (vertices) */
+ -1.000000, +1.000000, +1.000000, +1.000000,
+ +1.000000, +1.000000, -1.000000, -1.000000,
+ +1.000000, +1.000000, -1.000000, +1.000000,
+ /* for mem2gmem: (tex coords) */
+ +0.000000, +0.000000, +1.000000, +0.000000,
+ +0.000000, +1.000000, +1.000000, +1.000000,
+ };
+ struct pipe_resource *prsc = pipe_buffer_create(pctx->screen,
+ PIPE_BIND_CUSTOM, PIPE_USAGE_IMMUTABLE, sizeof(init_shader_const));
+ pipe_buffer_write(pctx, prsc, 0,
+ sizeof(init_shader_const), init_shader_const);
+ return prsc;
+}
+
+struct pipe_context *
+fd2_context_create(struct pipe_screen *pscreen, void *priv)
+{
+ struct fd2_context *fd2_ctx = CALLOC_STRUCT(fd2_context);
+ struct pipe_context *pctx;
+
+ if (!fd2_ctx)
+ return NULL;
+
+ pctx = &fd2_ctx->base.base;
+
+ pctx->destroy = fd2_context_destroy;
+ pctx->create_blend_state = fd2_blend_state_create;
+ pctx->create_rasterizer_state = fd2_rasterizer_state_create;
+ pctx->create_depth_stencil_alpha_state = fd2_zsa_state_create;
+
+ fd2_draw_init(pctx);
+ fd2_gmem_init(pctx);
+ fd2_texture_init(pctx);
+ fd2_prog_init(pctx);
+
+ pctx = fd_context_init(&fd2_ctx->base, pscreen, priv);
+ if (!pctx)
+ return NULL;
+
+ /* construct vertex state used for solid ops (clear, and gmem<->mem) */
+ fd2_ctx->solid_vertexbuf = create_solid_vertexbuf(pctx);
+
+ fd2_emit_setup(&fd2_ctx->base);
+
+ return pctx;
+}
--- /dev/null
+/* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */
+
+/*
+ * Copyright (C) 2013 Rob Clark <robclark@freedesktop.org>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Authors:
+ * Rob Clark <robclark@freedesktop.org>
+ */
+
+#ifndef FD2_CONTEXT_H_
+#define FD2_CONTEXT_H_
+
+#include "freedreno_context.h"
+
+struct fd2_context {
+ struct fd_context base;
+
+ /* vertex buf used for clear/gmem->mem vertices, and mem->gmem
+ * vertices and tex coords:
+ */
+ struct pipe_resource *solid_vertexbuf;
+};
+
+static INLINE struct fd2_context *
+fd2_context(struct fd_context *ctx)
+{
+ return (struct fd2_context *)ctx;
+}
+
+struct pipe_context *
+fd2_context_create(struct pipe_screen *pscreen, void *priv);
+
+#endif /* FD2_CONTEXT_H_ */
--- /dev/null
+/* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */
+
+/*
+ * Copyright (C) 2012-2013 Rob Clark <robclark@freedesktop.org>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Authors:
+ * Rob Clark <robclark@freedesktop.org>
+ */
+
+#include "pipe/p_state.h"
+#include "util/u_string.h"
+#include "util/u_memory.h"
+#include "util/u_prim.h"
+#include "util/u_pack_color.h"
+
+#include "freedreno_state.h"
+#include "freedreno_resource.h"
+
+#include "fd2_draw.h"
+#include "fd2_context.h"
+#include "fd2_emit.h"
+#include "fd2_program.h"
+#include "fd2_util.h"
+#include "fd2_zsa.h"
+
+
+static void
+emit_cacheflush(struct fd_ringbuffer *ring)
+{
+ unsigned i;
+
+ for (i = 0; i < 12; i++) {
+ OUT_PKT3(ring, CP_EVENT_WRITE, 1);
+ OUT_RING(ring, CACHE_FLUSH);
+ }
+}
+
+static void
+emit_vertexbufs(struct fd_context *ctx)
+{
+ struct fd_vertex_stateobj *vtx = ctx->vtx;
+ struct fd_vertexbuf_stateobj *vertexbuf = &ctx->vertexbuf;
+ struct fd2_vertex_buf bufs[PIPE_MAX_ATTRIBS];
+ unsigned i;
+
+ if (!vtx->num_elements)
+ return;
+
+ for (i = 0; i < vtx->num_elements; i++) {
+ struct pipe_vertex_element *elem = &vtx->pipe[i];
+ struct pipe_vertex_buffer *vb =
+ &vertexbuf->vb[elem->vertex_buffer_index];
+ bufs[i].offset = vb->buffer_offset;
+ bufs[i].size = fd_bo_size(fd_resource(vb->buffer)->bo);
+ bufs[i].prsc = vb->buffer;
+ }
+
+ // NOTE I believe the 0x78 (or 0x9c in solid_vp) relates to the
+ // CONST(20,0) (or CONST(26,0) in soliv_vp)
+
+ fd2_emit_vertex_bufs(ctx->ring, 0x78, bufs, vtx->num_elements);
+}
+
+static void
+fd2_draw(struct fd_context *ctx, const struct pipe_draw_info *info)
+{
+ struct fd_ringbuffer *ring = ctx->ring;
+
+ if (ctx->dirty & FD_DIRTY_VTXBUF)
+ emit_vertexbufs(ctx);
+
+ fd2_emit_state(ctx, ctx->dirty);
+
+ OUT_PKT3(ring, CP_SET_CONSTANT, 2);
+ OUT_RING(ring, CP_REG(REG_A2XX_VGT_INDX_OFFSET));
+ OUT_RING(ring, info->start);
+
+ OUT_PKT3(ring, CP_SET_CONSTANT, 2);
+ OUT_RING(ring, CP_REG(REG_A2XX_VGT_VERTEX_REUSE_BLOCK_CNTL));
+ OUT_RING(ring, 0x0000003b);
+
+ OUT_PKT0(ring, REG_A2XX_TC_CNTL_STATUS, 1);
+ OUT_RING(ring, A2XX_TC_CNTL_STATUS_L2_INVALIDATE);
+
+ OUT_PKT3(ring, CP_WAIT_FOR_IDLE, 1);
+ OUT_RING(ring, 0x0000000);
+
+ OUT_PKT3(ring, CP_SET_CONSTANT, 3);
+ OUT_RING(ring, CP_REG(REG_A2XX_VGT_MAX_VTX_INDX));
+ OUT_RING(ring, info->max_index); /* VGT_MAX_VTX_INDX */
+ OUT_RING(ring, info->min_index); /* VGT_MIN_VTX_INDX */
+
+ fd_draw_emit(ctx, info);
+
+ OUT_PKT3(ring, CP_SET_CONSTANT, 2);
+ OUT_RING(ring, CP_REG(REG_A2XX_UNKNOWN_2010));
+ OUT_RING(ring, 0x00000000);
+
+ emit_cacheflush(ring);
+}
+
+
+static uint32_t
+pack_rgba(enum pipe_format format, const float *rgba)
+{
+ union util_color uc;
+ util_pack_color(rgba, format, &uc);
+ return uc.ui;
+}
+
+static void
+fd2_clear(struct fd_context *ctx, unsigned buffers,
+ const union pipe_color_union *color, double depth, unsigned stencil)
+{
+ struct fd2_context *fd2_ctx = fd2_context(ctx);
+ struct fd_ringbuffer *ring = ctx->ring;
+ struct pipe_framebuffer_state *fb = &ctx->framebuffer;
+ uint32_t reg, colr = 0;
+
+ if ((buffers & PIPE_CLEAR_COLOR) && fb->nr_cbufs)
+ colr = pack_rgba(fb->cbufs[0]->format, color->f);
+
+ /* emit generic state now: */
+ fd2_emit_state(ctx, ctx->dirty &
+ (FD_DIRTY_BLEND | FD_DIRTY_VIEWPORT |
+ FD_DIRTY_FRAMEBUFFER | FD_DIRTY_SCISSOR));
+
+ fd2_emit_vertex_bufs(ring, 0x9c, (struct fd2_vertex_buf[]) {
+ { .prsc = fd2_ctx->solid_vertexbuf, .size = 48 },
+ }, 1);
+
+ OUT_PKT3(ring, CP_SET_CONSTANT, 2);
+ OUT_RING(ring, CP_REG(REG_A2XX_VGT_INDX_OFFSET));
+ OUT_RING(ring, 0);
+
+ OUT_PKT3(ring, CP_SET_CONSTANT, 2);
+ OUT_RING(ring, CP_REG(REG_A2XX_VGT_VERTEX_REUSE_BLOCK_CNTL));
+ OUT_RING(ring, 0x0000028f);
+
+ fd2_program_emit(ring, &ctx->solid_prog);
+
+ OUT_PKT0(ring, REG_A2XX_TC_CNTL_STATUS, 1);
+ OUT_RING(ring, A2XX_TC_CNTL_STATUS_L2_INVALIDATE);
+
+ OUT_PKT3(ring, CP_SET_CONSTANT, 2);
+ OUT_RING(ring, CP_REG(REG_A2XX_CLEAR_COLOR));
+ OUT_RING(ring, colr);
+
+ OUT_PKT3(ring, CP_SET_CONSTANT, 2);
+ OUT_RING(ring, CP_REG(REG_A2XX_A220_RB_LRZ_VSC_CONTROL));
+ OUT_RING(ring, 0x00000084);
+
+ OUT_PKT3(ring, CP_SET_CONSTANT, 2);
+ OUT_RING(ring, CP_REG(REG_A2XX_RB_COPY_CONTROL));
+ reg = 0;
+ if (buffers & (PIPE_CLEAR_DEPTH | PIPE_CLEAR_STENCIL)) {
+ reg |= A2XX_RB_COPY_CONTROL_DEPTH_CLEAR_ENABLE;
+ switch (fd_pipe2depth(fb->zsbuf->format)) {
+ case DEPTHX_24_8:
+ if (buffers & PIPE_CLEAR_DEPTH)
+ reg |= A2XX_RB_COPY_CONTROL_CLEAR_MASK(0xe);
+ if (buffers & PIPE_CLEAR_STENCIL)
+ reg |= A2XX_RB_COPY_CONTROL_CLEAR_MASK(0x1);
+ break;
+ case DEPTHX_16:
+ if (buffers & PIPE_CLEAR_DEPTH)
+ reg |= A2XX_RB_COPY_CONTROL_CLEAR_MASK(0xf);
+ break;
+ default:
+ assert(1);
+ break;
+ }
+ }
+ OUT_RING(ring, reg);
+
+ OUT_PKT3(ring, CP_SET_CONSTANT, 2);
+ OUT_RING(ring, CP_REG(REG_A2XX_RB_DEPTH_CLEAR));
+ reg = 0;
+ if (buffers & (PIPE_CLEAR_DEPTH | PIPE_CLEAR_STENCIL)) {
+ switch (fd_pipe2depth(fb->zsbuf->format)) {
+ case DEPTHX_24_8:
+ reg = (((uint32_t)(0xffffff * depth)) << 8) |
+ (stencil & 0xff);
+ break;
+ case DEPTHX_16:
+ reg = (uint32_t)(0xffffffff * depth);
+ break;
+ }
+ }
+ OUT_RING(ring, reg);
+
+ OUT_PKT3(ring, CP_SET_CONSTANT, 2);
+ OUT_RING(ring, CP_REG(REG_A2XX_RB_DEPTHCONTROL));
+ reg = 0;
+ if (buffers & PIPE_CLEAR_DEPTH) {
+ reg |= A2XX_RB_DEPTHCONTROL_ZFUNC(FUNC_ALWAYS) |
+ A2XX_RB_DEPTHCONTROL_Z_ENABLE |
+ A2XX_RB_DEPTHCONTROL_Z_WRITE_ENABLE |
+ A2XX_RB_DEPTHCONTROL_EARLY_Z_ENABLE;
+ }
+ if (buffers & PIPE_CLEAR_STENCIL) {
+ reg |= A2XX_RB_DEPTHCONTROL_STENCILFUNC(FUNC_ALWAYS) |
+ A2XX_RB_DEPTHCONTROL_STENCIL_ENABLE |
+ A2XX_RB_DEPTHCONTROL_STENCILZPASS(STENCIL_REPLACE);
+ }
+ OUT_RING(ring, reg);
+
+ OUT_PKT3(ring, CP_SET_CONSTANT, 3);
+ OUT_RING(ring, CP_REG(REG_A2XX_RB_STENCILREFMASK_BF));
+ OUT_RING(ring, 0xff000000 | A2XX_RB_STENCILREFMASK_BF_STENCILWRITEMASK(0xff));
+ OUT_RING(ring, 0xff000000 | A2XX_RB_STENCILREFMASK_STENCILWRITEMASK(0xff));
+
+ OUT_PKT3(ring, CP_SET_CONSTANT, 2);
+ OUT_RING(ring, CP_REG(REG_A2XX_RB_COLORCONTROL));
+ OUT_RING(ring, A2XX_RB_COLORCONTROL_ALPHA_FUNC(FUNC_ALWAYS) |
+ A2XX_RB_COLORCONTROL_BLEND_DISABLE |
+ A2XX_RB_COLORCONTROL_ROP_CODE(12) |
+ A2XX_RB_COLORCONTROL_DITHER_MODE(DITHER_DISABLE) |
+ A2XX_RB_COLORCONTROL_DITHER_TYPE(DITHER_PIXEL));
+
+ OUT_PKT3(ring, CP_SET_CONSTANT, 3);
+ OUT_RING(ring, CP_REG(REG_A2XX_PA_CL_CLIP_CNTL));
+ OUT_RING(ring, 0x00000000); /* PA_CL_CLIP_CNTL */
+ OUT_RING(ring, A2XX_PA_SU_SC_MODE_CNTL_PROVOKING_VTX_LAST | /* PA_SU_SC_MODE_CNTL */
+ A2XX_PA_SU_SC_MODE_CNTL_FRONT_PTYPE(PC_DRAW_TRIANGLES) |
+ A2XX_PA_SU_SC_MODE_CNTL_BACK_PTYPE(PC_DRAW_TRIANGLES));
+
+ OUT_PKT3(ring, CP_SET_CONSTANT, 2);
+ OUT_RING(ring, CP_REG(REG_A2XX_PA_SC_AA_MASK));
+ OUT_RING(ring, 0x0000ffff);
+
+ OUT_PKT3(ring, CP_SET_CONSTANT, 3);
+ OUT_RING(ring, CP_REG(REG_A2XX_PA_SC_WINDOW_SCISSOR_TL));
+ OUT_RING(ring, xy2d(0,0)); /* PA_SC_WINDOW_SCISSOR_TL */
+ OUT_RING(ring, xy2d(fb->width, /* PA_SC_WINDOW_SCISSOR_BR */
+ fb->height));
+
+ OUT_PKT3(ring, CP_SET_CONSTANT, 2);
+ OUT_RING(ring, CP_REG(REG_A2XX_RB_COLOR_MASK));
+ if (buffers & PIPE_CLEAR_COLOR) {
+ OUT_RING(ring, A2XX_RB_COLOR_MASK_WRITE_RED |
+ A2XX_RB_COLOR_MASK_WRITE_GREEN |
+ A2XX_RB_COLOR_MASK_WRITE_BLUE |
+ A2XX_RB_COLOR_MASK_WRITE_ALPHA);
+ } else {
+ OUT_RING(ring, 0x0);
+ }
+
+ OUT_PKT3(ring, CP_SET_CONSTANT, 3);
+ OUT_RING(ring, CP_REG(REG_A2XX_VGT_MAX_VTX_INDX));
+ OUT_RING(ring, 3); /* VGT_MAX_VTX_INDX */
+ OUT_RING(ring, 0); /* VGT_MIN_VTX_INDX */
+
+ OUT_PKT3(ring, CP_DRAW_INDX, 3);
+ OUT_RING(ring, 0x00000000);
+ OUT_RING(ring, DRAW(DI_PT_RECTLIST, DI_SRC_SEL_AUTO_INDEX,
+ INDEX_SIZE_IGN, IGNORE_VISIBILITY));
+ OUT_RING(ring, 3); /* NumIndices */
+
+ OUT_PKT3(ring, CP_SET_CONSTANT, 2);
+ OUT_RING(ring, CP_REG(REG_A2XX_A220_RB_LRZ_VSC_CONTROL));
+ OUT_RING(ring, 0x00000000);
+
+ OUT_PKT3(ring, CP_SET_CONSTANT, 2);
+ OUT_RING(ring, CP_REG(REG_A2XX_RB_COPY_CONTROL));
+ OUT_RING(ring, 0x00000000);
+}
+
+void
+fd2_draw_init(struct pipe_context *pctx)
+{
+ struct fd_context *ctx = fd_context(pctx);
+ ctx->draw = fd2_draw;
+ ctx->clear = fd2_clear;
+}
--- /dev/null
+/* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */
+
+/*
+ * Copyright (C) 2012-2013 Rob Clark <robclark@freedesktop.org>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Authors:
+ * Rob Clark <robclark@freedesktop.org>
+ */
+
+#ifndef FD2_DRAW_H_
+#define FD2_DRAW_H_
+
+#include "pipe/p_context.h"
+
+#include "freedreno_draw.h"
+
+void fd2_draw_init(struct pipe_context *pctx);
+
+#endif /* FD2_DRAW_H_ */
--- /dev/null
+/* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */
+
+/*
+ * Copyright (C) 2012-2013 Rob Clark <robclark@freedesktop.org>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Authors:
+ * Rob Clark <robclark@freedesktop.org>
+ */
+
+#include "pipe/p_state.h"
+#include "util/u_string.h"
+#include "util/u_memory.h"
+#include "util/u_helpers.h"
+
+#include "freedreno_resource.h"
+
+#include "fd2_emit.h"
+#include "fd2_blend.h"
+#include "fd2_context.h"
+#include "fd2_program.h"
+#include "fd2_rasterizer.h"
+#include "fd2_texture.h"
+#include "fd2_util.h"
+#include "fd2_zsa.h"
+
+/* NOTE: just define the position for const regs statically.. the blob
+ * driver doesn't seem to change these dynamically, and I can't really
+ * think of a good reason to so..
+ */
+#define VS_CONST_BASE 0x20
+#define PS_CONST_BASE 0x120
+
+static void
+emit_constants(struct fd_ringbuffer *ring, uint32_t base,
+ struct fd_constbuf_stateobj *constbuf,
+ struct fd2_shader_stateobj *shader)
+{
+ uint32_t enabled_mask = constbuf->enabled_mask;
+ uint32_t start_base = base;
+ unsigned i;
+
+ // XXX TODO only emit dirty consts.. but we need to keep track if
+ // they are clobbered by a clear, gmem2mem, or mem2gmem..
+ constbuf->dirty_mask = enabled_mask;
+
+ /* emit user constants: */
+ while (enabled_mask) {
+ unsigned index = ffs(enabled_mask) - 1;
+ struct pipe_constant_buffer *cb = &constbuf->cb[index];
+ unsigned size = align(cb->buffer_size, 4) / 4; /* size in dwords */
+
+ // I expect that size should be a multiple of vec4's:
+ assert(size == align(size, 4));
+
+ /* hmm, sometimes we still seem to end up with consts bound,
+ * even if shader isn't using them, which ends up overwriting
+ * const reg's used for immediates.. this is a hack to work
+ * around that:
+ */
+ if (shader && ((base - start_base) >= (shader->first_immediate * 4)))
+ break;
+
+ if (constbuf->dirty_mask & (1 << index)) {
+ const uint32_t *dwords;
+
+ if (cb->user_buffer) {
+ dwords = cb->user_buffer;
+ } else {
+ struct fd_resource *rsc = fd_resource(cb->buffer);
+ dwords = fd_bo_map(rsc->bo);
+ }
+
+ dwords = (uint32_t *)(((uint8_t *)dwords) + cb->buffer_offset);
+
+ OUT_PKT3(ring, CP_SET_CONSTANT, size + 1);
+ OUT_RING(ring, base);
+ for (i = 0; i < size; i++)
+ OUT_RING(ring, *(dwords++));
+
+ constbuf->dirty_mask &= ~(1 << index);
+ }
+
+ base += size;
+ enabled_mask &= ~(1 << index);
+ }
+
+ /* emit shader immediates: */
+ if (shader) {
+ for (i = 0; i < shader->num_immediates; i++) {
+ OUT_PKT3(ring, CP_SET_CONSTANT, 5);
+ OUT_RING(ring, start_base + (4 * (shader->first_immediate + i)));
+ OUT_RING(ring, shader->immediates[i].val[0]);
+ OUT_RING(ring, shader->immediates[i].val[1]);
+ OUT_RING(ring, shader->immediates[i].val[2]);
+ OUT_RING(ring, shader->immediates[i].val[3]);
+ base += 4;
+ }
+ }
+}
+
+typedef uint32_t texmask;
+
+static texmask
+emit_texture(struct fd_ringbuffer *ring, struct fd_context *ctx,
+ struct fd_texture_stateobj *tex, unsigned samp_id, texmask emitted)
+{
+ unsigned const_idx = fd2_get_const_idx(ctx, tex, samp_id);
+ struct fd2_sampler_stateobj *sampler;
+ struct fd2_pipe_sampler_view *view;
+
+ if (emitted & (1 << const_idx))
+ return 0;
+
+ sampler = fd2_sampler_stateobj(tex->samplers[samp_id]);
+ view = fd2_pipe_sampler_view(tex->textures[samp_id]);
+
+ OUT_PKT3(ring, CP_SET_CONSTANT, 7);
+ OUT_RING(ring, 0x00010000 + (0x6 * const_idx));
+
+ OUT_RING(ring, sampler->tex0 | view->tex0);
+ OUT_RELOC(ring, view->tex_resource->bo, 0, view->fmt);
+ OUT_RING(ring, view->tex2);
+ OUT_RING(ring, sampler->tex3 | view->tex3);
+ OUT_RING(ring, sampler->tex4);
+ OUT_RING(ring, sampler->tex5);
+
+ return (1 << const_idx);
+}
+
+static void
+emit_textures(struct fd_ringbuffer *ring, struct fd_context *ctx)
+{
+ texmask emitted = 0;
+ unsigned i;
+
+ for (i = 0; i < ctx->verttex.num_samplers; i++)
+ if (ctx->verttex.samplers[i])
+ emitted |= emit_texture(ring, ctx, &ctx->verttex, i, emitted);
+
+ for (i = 0; i < ctx->fragtex.num_samplers; i++)
+ if (ctx->fragtex.samplers[i])
+ emitted |= emit_texture(ring, ctx, &ctx->fragtex, i, emitted);
+}
+
+void
+fd2_emit_vertex_bufs(struct fd_ringbuffer *ring, uint32_t val,
+ struct fd2_vertex_buf *vbufs, uint32_t n)
+{
+ unsigned i;
+
+ OUT_PKT3(ring, CP_SET_CONSTANT, 1 + (2 * n));
+ OUT_RING(ring, (0x1 << 16) | (val & 0xffff));
+ for (i = 0; i < n; i++) {
+ struct fd_resource *rsc = fd_resource(vbufs[i].prsc);
+ OUT_RELOC(ring, rsc->bo, vbufs[i].offset, 3);
+ OUT_RING (ring, vbufs[i].size);
+ }
+}
+
+void
+fd2_emit_state(struct fd_context *ctx, uint32_t dirty)
+{
+ struct fd2_blend_stateobj *blend = fd2_blend_stateobj(ctx->blend);
+ struct fd2_zsa_stateobj *zsa = fd2_zsa_stateobj(ctx->zsa);
+ struct fd_ringbuffer *ring = ctx->ring;
+
+ /* NOTE: we probably want to eventually refactor this so each state
+ * object handles emitting it's own state.. although the mapping of
+ * state to registers is not always orthogonal, sometimes a single
+ * register contains bitfields coming from multiple state objects,
+ * so not sure the best way to deal with that yet.
+ */
+
+ if (dirty & FD_DIRTY_SAMPLE_MASK) {
+ OUT_PKT3(ring, CP_SET_CONSTANT, 2);
+ OUT_RING(ring, CP_REG(REG_A2XX_PA_SC_AA_MASK));
+ OUT_RING(ring, ctx->sample_mask);
+ }
+
+ if (dirty & (FD_DIRTY_ZSA | FD_DIRTY_STENCIL_REF)) {
+ struct pipe_stencil_ref *sr = &ctx->stencil_ref;
+
+ OUT_PKT3(ring, CP_SET_CONSTANT, 2);
+ OUT_RING(ring, CP_REG(REG_A2XX_RB_DEPTHCONTROL));
+ OUT_RING(ring, zsa->rb_depthcontrol);
+
+ OUT_PKT3(ring, CP_SET_CONSTANT, 4);
+ OUT_RING(ring, CP_REG(REG_A2XX_RB_STENCILREFMASK_BF));
+ OUT_RING(ring, zsa->rb_stencilrefmask_bf |
+ A2XX_RB_STENCILREFMASK_STENCILREF(sr->ref_value[1]));
+ OUT_RING(ring, zsa->rb_stencilrefmask |
+ A2XX_RB_STENCILREFMASK_STENCILREF(sr->ref_value[0]));
+ OUT_RING(ring, zsa->rb_alpha_ref);
+ }
+
+ if (dirty & (FD_DIRTY_RASTERIZER | FD_DIRTY_FRAMEBUFFER)) {
+ struct fd2_rasterizer_stateobj *rasterizer =
+ fd2_rasterizer_stateobj(ctx->rasterizer);
+ OUT_PKT3(ring, CP_SET_CONSTANT, 3);
+ OUT_RING(ring, CP_REG(REG_A2XX_PA_CL_CLIP_CNTL));
+ OUT_RING(ring, rasterizer->pa_cl_clip_cntl);
+ OUT_RING(ring, rasterizer->pa_su_sc_mode_cntl |
+ A2XX_PA_SU_SC_MODE_CNTL_VTX_WINDOW_OFFSET_ENABLE);
+
+ OUT_PKT3(ring, CP_SET_CONSTANT, 5);
+ OUT_RING(ring, CP_REG(REG_A2XX_PA_SU_POINT_SIZE));
+ OUT_RING(ring, rasterizer->pa_su_point_size);
+ OUT_RING(ring, rasterizer->pa_su_point_minmax);
+ OUT_RING(ring, rasterizer->pa_su_line_cntl);
+ OUT_RING(ring, rasterizer->pa_sc_line_stipple);
+
+ OUT_PKT3(ring, CP_SET_CONSTANT, 6);
+ OUT_RING(ring, CP_REG(REG_A2XX_PA_SU_VTX_CNTL));
+ OUT_RING(ring, rasterizer->pa_su_vtx_cntl);
+ OUT_RING(ring, fui(1.0)); /* PA_CL_GB_VERT_CLIP_ADJ */
+ OUT_RING(ring, fui(1.0)); /* PA_CL_GB_VERT_DISC_ADJ */
+ OUT_RING(ring, fui(1.0)); /* PA_CL_GB_HORZ_CLIP_ADJ */
+ OUT_RING(ring, fui(1.0)); /* PA_CL_GB_HORZ_DISC_ADJ */
+ }
+
+ if (dirty & FD_DIRTY_SCISSOR) {
+ OUT_PKT3(ring, CP_SET_CONSTANT, 3);
+ OUT_RING(ring, CP_REG(REG_A2XX_PA_SC_WINDOW_SCISSOR_TL));
+ OUT_RING(ring, xy2d(ctx->scissor.minx, /* PA_SC_WINDOW_SCISSOR_TL */
+ ctx->scissor.miny));
+ OUT_RING(ring, xy2d(ctx->scissor.maxx, /* PA_SC_WINDOW_SCISSOR_BR */
+ ctx->scissor.maxy));
+
+ ctx->max_scissor.minx = MIN2(ctx->max_scissor.minx, ctx->scissor.minx);
+ ctx->max_scissor.miny = MIN2(ctx->max_scissor.miny, ctx->scissor.miny);
+ ctx->max_scissor.maxx = MAX2(ctx->max_scissor.maxx, ctx->scissor.maxx);
+ ctx->max_scissor.maxy = MAX2(ctx->max_scissor.maxy, ctx->scissor.maxy);
+ }
+
+ if (dirty & FD_DIRTY_VIEWPORT) {
+ OUT_PKT3(ring, CP_SET_CONSTANT, 7);
+ OUT_RING(ring, CP_REG(REG_A2XX_PA_CL_VPORT_XSCALE));
+ OUT_RING(ring, fui(ctx->viewport.scale[0])); /* PA_CL_VPORT_XSCALE */
+ OUT_RING(ring, fui(ctx->viewport.translate[0])); /* PA_CL_VPORT_XOFFSET */
+ OUT_RING(ring, fui(ctx->viewport.scale[1])); /* PA_CL_VPORT_YSCALE */
+ OUT_RING(ring, fui(ctx->viewport.translate[1])); /* PA_CL_VPORT_YOFFSET */
+ OUT_RING(ring, fui(ctx->viewport.scale[2])); /* PA_CL_VPORT_ZSCALE */
+ OUT_RING(ring, fui(ctx->viewport.translate[2])); /* PA_CL_VPORT_ZOFFSET */
+
+ OUT_PKT3(ring, CP_SET_CONSTANT, 2);
+ OUT_RING(ring, CP_REG(REG_A2XX_PA_CL_VTE_CNTL));
+ OUT_RING(ring, A2XX_PA_CL_VTE_CNTL_VTX_W0_FMT |
+ A2XX_PA_CL_VTE_CNTL_VPORT_X_SCALE_ENA |
+ A2XX_PA_CL_VTE_CNTL_VPORT_X_OFFSET_ENA |
+ A2XX_PA_CL_VTE_CNTL_VPORT_Y_SCALE_ENA |
+ A2XX_PA_CL_VTE_CNTL_VPORT_Y_OFFSET_ENA |
+ A2XX_PA_CL_VTE_CNTL_VPORT_Z_SCALE_ENA |
+ A2XX_PA_CL_VTE_CNTL_VPORT_Z_OFFSET_ENA);
+ }
+
+ if (dirty & (FD_DIRTY_PROG | FD_DIRTY_VTXSTATE | FD_DIRTY_TEXSTATE)) {
+ fd2_program_validate(ctx);
+ fd2_program_emit(ring, &ctx->prog);
+ }
+
+ if (dirty & (FD_DIRTY_PROG | FD_DIRTY_CONSTBUF)) {
+ emit_constants(ring, VS_CONST_BASE * 4,
+ &ctx->constbuf[PIPE_SHADER_VERTEX],
+ (dirty & FD_DIRTY_PROG) ? ctx->prog.vp : NULL);
+ emit_constants(ring, PS_CONST_BASE * 4,
+ &ctx->constbuf[PIPE_SHADER_FRAGMENT],
+ (dirty & FD_DIRTY_PROG) ? ctx->prog.fp : NULL);
+ }
+
+ if (dirty & (FD_DIRTY_BLEND | FD_DIRTY_ZSA)) {
+ OUT_PKT3(ring, CP_SET_CONSTANT, 2);
+ OUT_RING(ring, CP_REG(REG_A2XX_RB_COLORCONTROL));
+ OUT_RING(ring, zsa->rb_colorcontrol | blend->rb_colorcontrol);
+ }
+
+ if (dirty & FD_DIRTY_BLEND) {
+ OUT_PKT3(ring, CP_SET_CONSTANT, 2);
+ OUT_RING(ring, CP_REG(REG_A2XX_RB_BLEND_CONTROL));
+ OUT_RING(ring, blend->rb_blendcontrol);
+
+ OUT_PKT3(ring, CP_SET_CONSTANT, 2);
+ OUT_RING(ring, CP_REG(REG_A2XX_RB_COLOR_MASK));
+ OUT_RING(ring, blend->rb_colormask);
+ }
+
+ if (dirty & (FD_DIRTY_VERTTEX | FD_DIRTY_FRAGTEX | FD_DIRTY_PROG))
+ emit_textures(ring, ctx);
+
+ ctx->dirty &= ~dirty;
+}
+
+/* emit per-context initialization:
+ */
+void
+fd2_emit_setup(struct fd_context *ctx)
+{
+ struct fd_ringbuffer *ring = ctx->ring;
+
+ OUT_PKT0(ring, REG_A2XX_TP0_CHICKEN, 1);
+ OUT_RING(ring, 0x00000002);
+
+ OUT_PKT3(ring, CP_INVALIDATE_STATE, 1);
+ OUT_RING(ring, 0x00007fff);
+
+ OUT_PKT3(ring, CP_SET_CONSTANT, 2);
+ OUT_RING(ring, CP_REG(REG_A2XX_SQ_VS_CONST));
+ OUT_RING(ring, A2XX_SQ_VS_CONST_BASE(VS_CONST_BASE) |
+ A2XX_SQ_VS_CONST_SIZE(0x100));
+
+ OUT_PKT3(ring, CP_SET_CONSTANT, 2);
+ OUT_RING(ring, CP_REG(REG_A2XX_SQ_PS_CONST));
+ OUT_RING(ring, A2XX_SQ_PS_CONST_BASE(PS_CONST_BASE) |
+ A2XX_SQ_PS_CONST_SIZE(0xe0));
+
+ OUT_PKT3(ring, CP_SET_CONSTANT, 3);
+ OUT_RING(ring, CP_REG(REG_A2XX_VGT_MAX_VTX_INDX));
+ OUT_RING(ring, 0xffffffff); /* VGT_MAX_VTX_INDX */
+ OUT_RING(ring, 0x00000000); /* VGT_MIN_VTX_INDX */
+
+ OUT_PKT3(ring, CP_SET_CONSTANT, 2);
+ OUT_RING(ring, CP_REG(REG_A2XX_VGT_INDX_OFFSET));
+ OUT_RING(ring, 0x00000000);
+
+ OUT_PKT3(ring, CP_SET_CONSTANT, 2);
+ OUT_RING(ring, CP_REG(REG_A2XX_VGT_VERTEX_REUSE_BLOCK_CNTL));
+ OUT_RING(ring, 0x0000003b);
+
+ OUT_PKT3(ring, CP_SET_CONSTANT, 2);
+ OUT_RING(ring, CP_REG(REG_A2XX_SQ_CONTEXT_MISC));
+ OUT_RING(ring, A2XX_SQ_CONTEXT_MISC_SC_SAMPLE_CNTL(CENTERS_ONLY));
+
+ OUT_PKT3(ring, CP_SET_CONSTANT, 2);
+ OUT_RING(ring, CP_REG(REG_A2XX_SQ_INTERPOLATOR_CNTL));
+ OUT_RING(ring, 0xffffffff);
+
+ OUT_PKT3(ring, CP_SET_CONSTANT, 2);
+ OUT_RING(ring, CP_REG(REG_A2XX_PA_SC_AA_CONFIG));
+ OUT_RING(ring, 0x00000000);
+
+ OUT_PKT3(ring, CP_SET_CONSTANT, 2);
+ OUT_RING(ring, CP_REG(REG_A2XX_PA_SC_LINE_CNTL));
+ OUT_RING(ring, 0x00000000);
+
+ OUT_PKT3(ring, CP_SET_CONSTANT, 2);
+ OUT_RING(ring, CP_REG(REG_A2XX_PA_SC_WINDOW_OFFSET));
+ OUT_RING(ring, 0x00000000);
+
+ // XXX we change this dynamically for draw/clear.. vs gmem<->mem..
+ OUT_PKT3(ring, CP_SET_CONSTANT, 2);
+ OUT_RING(ring, CP_REG(REG_A2XX_RB_MODECONTROL));
+ OUT_RING(ring, A2XX_RB_MODECONTROL_EDRAM_MODE(COLOR_DEPTH));
+
+ OUT_PKT3(ring, CP_SET_CONSTANT, 2);
+ OUT_RING(ring, CP_REG(REG_A2XX_RB_SAMPLE_POS));
+ OUT_RING(ring, 0x88888888);
+
+ OUT_PKT3(ring, CP_SET_CONSTANT, 2);
+ OUT_RING(ring, CP_REG(REG_A2XX_RB_COLOR_DEST_MASK));
+ OUT_RING(ring, 0xffffffff);
+
+ OUT_PKT3(ring, CP_SET_CONSTANT, 2);
+ OUT_RING(ring, CP_REG(REG_A2XX_RB_COPY_DEST_INFO));
+ OUT_RING(ring, A2XX_RB_COPY_DEST_INFO_FORMAT(COLORX_4_4_4_4) |
+ A2XX_RB_COPY_DEST_INFO_WRITE_RED |
+ A2XX_RB_COPY_DEST_INFO_WRITE_GREEN |
+ A2XX_RB_COPY_DEST_INFO_WRITE_BLUE |
+ A2XX_RB_COPY_DEST_INFO_WRITE_ALPHA);
+
+ OUT_PKT3(ring, CP_SET_CONSTANT, 3);
+ OUT_RING(ring, CP_REG(REG_A2XX_SQ_WRAPPING_0));
+ OUT_RING(ring, 0x00000000); /* SQ_WRAPPING_0 */
+ OUT_RING(ring, 0x00000000); /* SQ_WRAPPING_1 */
+
+ OUT_PKT3(ring, CP_SET_DRAW_INIT_FLAGS, 1);
+ OUT_RING(ring, 0x00000000);
+
+ OUT_PKT3(ring, CP_WAIT_REG_EQ, 4);
+ OUT_RING(ring, 0x000005d0);
+ OUT_RING(ring, 0x00000000);
+ OUT_RING(ring, 0x5f601000);
+ OUT_RING(ring, 0x00000001);
+
+ OUT_PKT0(ring, REG_A2XX_SQ_INST_STORE_MANAGMENT, 1);
+ OUT_RING(ring, 0x00000180);
+
+ OUT_PKT3(ring, CP_INVALIDATE_STATE, 1);
+ OUT_RING(ring, 0x00000300);
+
+ OUT_PKT3(ring, CP_SET_SHADER_BASES, 1);
+ OUT_RING(ring, 0x80000180);
+
+ /* not sure what this form of CP_SET_CONSTANT is.. */
+ OUT_PKT3(ring, CP_SET_CONSTANT, 13);
+ OUT_RING(ring, 0x00000000);
+ OUT_RING(ring, 0x00000000);
+ OUT_RING(ring, 0x00000000);
+ OUT_RING(ring, 0x00000000);
+ OUT_RING(ring, 0x00000000);
+ OUT_RING(ring, 0x469c4000);
+ OUT_RING(ring, 0x3f800000);
+ OUT_RING(ring, 0x3f000000);
+ OUT_RING(ring, 0x00000000);
+ OUT_RING(ring, 0x40000000);
+ OUT_RING(ring, 0x3f400000);
+ OUT_RING(ring, 0x3ec00000);
+ OUT_RING(ring, 0x3e800000);
+
+ OUT_PKT3(ring, CP_SET_CONSTANT, 2);
+ OUT_RING(ring, CP_REG(REG_A2XX_RB_COLOR_MASK));
+ OUT_RING(ring, A2XX_RB_COLOR_MASK_WRITE_RED |
+ A2XX_RB_COLOR_MASK_WRITE_GREEN |
+ A2XX_RB_COLOR_MASK_WRITE_BLUE |
+ A2XX_RB_COLOR_MASK_WRITE_ALPHA);
+
+ OUT_PKT3(ring, CP_SET_CONSTANT, 5);
+ OUT_RING(ring, CP_REG(REG_A2XX_RB_BLEND_RED));
+ OUT_RING(ring, 0x00000000); /* RB_BLEND_RED */
+ OUT_RING(ring, 0x00000000); /* RB_BLEND_GREEN */
+ OUT_RING(ring, 0x00000000); /* RB_BLEND_BLUE */
+ OUT_RING(ring, 0x000000ff); /* RB_BLEND_ALPHA */
+
+ fd_ringbuffer_flush(ring);
+ fd_ringmarker_mark(ctx->draw_start);
+}
--- /dev/null
+/* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */
+
+/*
+ * Copyright (C) 2012-2013 Rob Clark <robclark@freedesktop.org>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Authors:
+ * Rob Clark <robclark@freedesktop.org>
+ */
+
+#ifndef FD2_EMIT_H
+#define FD2_EMIT_H
+
+#include "pipe/p_context.h"
+
+#include "freedreno_context.h"
+
+struct fd_ringbuffer;
+
+struct fd2_vertex_buf {
+ unsigned offset, size;
+ struct pipe_resource *prsc;
+};
+
+void fd2_emit_vertex_bufs(struct fd_ringbuffer *ring, uint32_t val,
+ struct fd2_vertex_buf *vbufs, uint32_t n);
+void fd2_emit_state(struct fd_context *ctx, uint32_t dirty);
+void fd2_emit_setup(struct fd_context *ctx);
+
+#endif /* FD2_EMIT_H */
--- /dev/null
+/* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */
+
+/*
+ * Copyright (C) 2012 Rob Clark <robclark@freedesktop.org>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Authors:
+ * Rob Clark <robclark@freedesktop.org>
+ */
+
+#include "pipe/p_state.h"
+#include "util/u_string.h"
+#include "util/u_memory.h"
+#include "util/u_inlines.h"
+
+#include "freedreno_state.h"
+#include "freedreno_resource.h"
+
+#include "fd2_gmem.h"
+#include "fd2_context.h"
+#include "fd2_emit.h"
+#include "fd2_program.h"
+#include "fd2_util.h"
+#include "fd2_zsa.h"
+
+static uint32_t fmt2swap(enum pipe_format format)
+{
+ switch (format) {
+ case PIPE_FORMAT_B8G8R8A8_UNORM:
+ /* TODO probably some more.. */
+ return 1;
+ default:
+ return 0;
+ }
+}
+
+/* transfer from gmem to system memory (ie. normal RAM) */
+
+static void
+emit_gmem2mem_surf(struct fd_ringbuffer *ring, uint32_t base,
+ struct pipe_surface *psurf)
+{
+ struct fd_resource *rsc = fd_resource(psurf->texture);
+ uint32_t swap = fmt2swap(psurf->format);
+
+ OUT_PKT3(ring, CP_SET_CONSTANT, 2);
+ OUT_RING(ring, CP_REG(REG_A2XX_RB_COLOR_INFO));
+ OUT_RING(ring, A2XX_RB_COLOR_INFO_SWAP(swap) |
+ A2XX_RB_COLOR_INFO_BASE(base) |
+ A2XX_RB_COLOR_INFO_FORMAT(fd2_pipe2color(psurf->format)));
+
+ OUT_PKT3(ring, CP_SET_CONSTANT, 5);
+ OUT_RING(ring, CP_REG(REG_A2XX_RB_COPY_CONTROL));
+ OUT_RING(ring, 0x00000000); /* RB_COPY_CONTROL */
+ OUT_RELOC(ring, rsc->bo, 0, 0); /* RB_COPY_DEST_BASE */
+ OUT_RING(ring, rsc->pitch >> 5); /* RB_COPY_DEST_PITCH */
+ OUT_RING(ring, /* RB_COPY_DEST_INFO */
+ A2XX_RB_COPY_DEST_INFO_FORMAT(fd2_pipe2color(psurf->format)) |
+ A2XX_RB_COPY_DEST_INFO_LINEAR |
+ A2XX_RB_COPY_DEST_INFO_SWAP(swap) |
+ A2XX_RB_COPY_DEST_INFO_WRITE_RED |
+ A2XX_RB_COPY_DEST_INFO_WRITE_GREEN |
+ A2XX_RB_COPY_DEST_INFO_WRITE_BLUE |
+ A2XX_RB_COPY_DEST_INFO_WRITE_ALPHA);
+
+ OUT_PKT3(ring, CP_WAIT_FOR_IDLE, 1);
+ OUT_RING(ring, 0x0000000);
+
+ OUT_PKT3(ring, CP_SET_CONSTANT, 3);
+ OUT_RING(ring, CP_REG(REG_A2XX_VGT_MAX_VTX_INDX));
+ OUT_RING(ring, 3); /* VGT_MAX_VTX_INDX */
+ OUT_RING(ring, 0); /* VGT_MIN_VTX_INDX */
+
+ OUT_PKT3(ring, CP_DRAW_INDX, 3);
+ OUT_RING(ring, 0x00000000);
+ OUT_RING(ring, DRAW(DI_PT_RECTLIST, DI_SRC_SEL_AUTO_INDEX,
+ INDEX_SIZE_IGN, IGNORE_VISIBILITY));
+ OUT_RING(ring, 3); /* NumIndices */
+}
+
+static void
+fd2_emit_tile_gmem2mem(struct fd_context *ctx, uint32_t xoff, uint32_t yoff,
+ uint32_t bin_w, uint32_t bin_h)
+{
+ struct fd2_context *fd2_ctx = fd2_context(ctx);
+ struct fd_ringbuffer *ring = ctx->ring;
+ struct pipe_framebuffer_state *pfb = &ctx->framebuffer;
+
+ fd2_emit_vertex_bufs(ring, 0x9c, (struct fd2_vertex_buf[]) {
+ { .prsc = fd2_ctx->solid_vertexbuf, .size = 48 },
+ }, 1);
+
+ OUT_PKT3(ring, CP_SET_CONSTANT, 2);
+ OUT_RING(ring, CP_REG(REG_A2XX_PA_SC_WINDOW_OFFSET));
+ OUT_RING(ring, 0x00000000); /* PA_SC_WINDOW_OFFSET */
+
+ OUT_PKT3(ring, CP_SET_CONSTANT, 2);
+ OUT_RING(ring, CP_REG(REG_A2XX_VGT_INDX_OFFSET));
+ OUT_RING(ring, 0);
+
+ OUT_PKT3(ring, CP_SET_CONSTANT, 2);
+ OUT_RING(ring, CP_REG(REG_A2XX_VGT_VERTEX_REUSE_BLOCK_CNTL));
+ OUT_RING(ring, 0x0000028f);
+
+ fd2_program_emit(ring, &ctx->solid_prog);
+
+ OUT_PKT3(ring, CP_SET_CONSTANT, 2);
+ OUT_RING(ring, CP_REG(REG_A2XX_PA_SC_AA_MASK));
+ OUT_RING(ring, 0x0000ffff);
+
+ OUT_PKT3(ring, CP_SET_CONSTANT, 2);
+ OUT_RING(ring, CP_REG(REG_A2XX_RB_DEPTHCONTROL));
+ OUT_RING(ring, A2XX_RB_DEPTHCONTROL_EARLY_Z_ENABLE);
+
+ OUT_PKT3(ring, CP_SET_CONSTANT, 2);
+ OUT_RING(ring, CP_REG(REG_A2XX_PA_SU_SC_MODE_CNTL));
+ OUT_RING(ring, A2XX_PA_SU_SC_MODE_CNTL_PROVOKING_VTX_LAST | /* PA_SU_SC_MODE_CNTL */
+ A2XX_PA_SU_SC_MODE_CNTL_FRONT_PTYPE(PC_DRAW_TRIANGLES) |
+ A2XX_PA_SU_SC_MODE_CNTL_BACK_PTYPE(PC_DRAW_TRIANGLES));
+
+ OUT_PKT3(ring, CP_SET_CONSTANT, 3);
+ OUT_RING(ring, CP_REG(REG_A2XX_PA_SC_WINDOW_SCISSOR_TL));
+ OUT_RING(ring, xy2d(0, 0)); /* PA_SC_WINDOW_SCISSOR_TL */
+ OUT_RING(ring, xy2d(pfb->width, pfb->height)); /* PA_SC_WINDOW_SCISSOR_BR */
+
+ OUT_PKT3(ring, CP_SET_CONSTANT, 2);
+ OUT_RING(ring, CP_REG(REG_A2XX_PA_CL_VTE_CNTL));
+ OUT_RING(ring, A2XX_PA_CL_VTE_CNTL_VTX_W0_FMT |
+ A2XX_PA_CL_VTE_CNTL_VPORT_X_SCALE_ENA |
+ A2XX_PA_CL_VTE_CNTL_VPORT_X_OFFSET_ENA |
+ A2XX_PA_CL_VTE_CNTL_VPORT_Y_SCALE_ENA |
+ A2XX_PA_CL_VTE_CNTL_VPORT_Y_OFFSET_ENA);
+
+ OUT_PKT3(ring, CP_SET_CONSTANT, 2);
+ OUT_RING(ring, CP_REG(REG_A2XX_PA_CL_CLIP_CNTL));
+ OUT_RING(ring, 0x00000000);
+
+ OUT_PKT3(ring, CP_SET_CONSTANT, 2);
+ OUT_RING(ring, CP_REG(REG_A2XX_RB_MODECONTROL));
+ OUT_RING(ring, A2XX_RB_MODECONTROL_EDRAM_MODE(EDRAM_COPY));
+
+ OUT_PKT3(ring, CP_SET_CONSTANT, 2);
+ OUT_RING(ring, CP_REG(REG_A2XX_RB_COPY_DEST_OFFSET));
+ OUT_RING(ring, A2XX_RB_COPY_DEST_OFFSET_X(xoff) |
+ A2XX_RB_COPY_DEST_OFFSET_Y(yoff));
+
+ if (ctx->resolve & (FD_BUFFER_DEPTH | FD_BUFFER_STENCIL))
+ emit_gmem2mem_surf(ring, bin_w * bin_h, pfb->zsbuf);
+
+ if (ctx->resolve & FD_BUFFER_COLOR)
+ emit_gmem2mem_surf(ring, 0, pfb->cbufs[0]);
+
+ OUT_PKT3(ring, CP_SET_CONSTANT, 2);
+ OUT_RING(ring, CP_REG(REG_A2XX_RB_MODECONTROL));
+ OUT_RING(ring, A2XX_RB_MODECONTROL_EDRAM_MODE(COLOR_DEPTH));
+}
+
+/* transfer from system memory to gmem */
+
+static void
+emit_mem2gmem_surf(struct fd_ringbuffer *ring, uint32_t base,
+ struct pipe_surface *psurf)
+{
+ struct fd_resource *rsc = fd_resource(psurf->texture);
+ uint32_t swiz;
+
+ OUT_PKT3(ring, CP_SET_CONSTANT, 2);
+ OUT_RING(ring, CP_REG(REG_A2XX_RB_COLOR_INFO));
+ OUT_RING(ring, A2XX_RB_COLOR_INFO_SWAP(fmt2swap(psurf->format)) |
+ A2XX_RB_COLOR_INFO_BASE(base) |
+ A2XX_RB_COLOR_INFO_FORMAT(fd2_pipe2color(psurf->format)));
+
+ swiz = fd2_tex_swiz(psurf->format, PIPE_SWIZZLE_RED, PIPE_SWIZZLE_GREEN,
+ PIPE_SWIZZLE_BLUE, PIPE_SWIZZLE_ALPHA);
+
+ /* emit fb as a texture: */
+ OUT_PKT3(ring, CP_SET_CONSTANT, 7);
+ OUT_RING(ring, 0x00010000);
+ OUT_RING(ring, A2XX_SQ_TEX_0_CLAMP_X(SQ_TEX_WRAP) |
+ A2XX_SQ_TEX_0_CLAMP_Y(SQ_TEX_WRAP) |
+ A2XX_SQ_TEX_0_CLAMP_Z(SQ_TEX_WRAP) |
+ A2XX_SQ_TEX_0_PITCH(rsc->pitch));
+ OUT_RELOC(ring, rsc->bo, 0,
+ fd2_pipe2surface(psurf->format) | 0x800);
+ OUT_RING(ring, A2XX_SQ_TEX_2_WIDTH(psurf->width - 1) |
+ A2XX_SQ_TEX_2_HEIGHT(psurf->height - 1));
+ OUT_RING(ring, 0x01000000 | // XXX
+ swiz |
+ A2XX_SQ_TEX_3_XY_MAG_FILTER(SQ_TEX_FILTER_POINT) |
+ A2XX_SQ_TEX_3_XY_MIN_FILTER(SQ_TEX_FILTER_POINT));
+ OUT_RING(ring, 0x00000000);
+ OUT_RING(ring, 0x00000200);
+
+ OUT_PKT3(ring, CP_SET_CONSTANT, 3);
+ OUT_RING(ring, CP_REG(REG_A2XX_VGT_MAX_VTX_INDX));
+ OUT_RING(ring, 3); /* VGT_MAX_VTX_INDX */
+ OUT_RING(ring, 0); /* VGT_MIN_VTX_INDX */
+
+ OUT_PKT3(ring, CP_DRAW_INDX, 3);
+ OUT_RING(ring, 0x00000000);
+ OUT_RING(ring, DRAW(DI_PT_RECTLIST, DI_SRC_SEL_AUTO_INDEX,
+ INDEX_SIZE_IGN, IGNORE_VISIBILITY));
+ OUT_RING(ring, 3); /* NumIndices */
+}
+
+static void
+fd2_emit_tile_mem2gmem(struct fd_context *ctx, uint32_t xoff, uint32_t yoff,
+ uint32_t bin_w, uint32_t bin_h)
+{
+ struct fd2_context *fd2_ctx = fd2_context(ctx);
+ struct fd_ringbuffer *ring = ctx->ring;
+ struct pipe_framebuffer_state *pfb = &ctx->framebuffer;
+ float x0, y0, x1, y1;
+
+ fd2_emit_vertex_bufs(ring, 0x9c, (struct fd2_vertex_buf[]) {
+ { .prsc = fd2_ctx->solid_vertexbuf, .size = 48, .offset = 0x30 },
+ { .prsc = fd2_ctx->solid_vertexbuf, .size = 32, .offset = 0x60 },
+ }, 2);
+
+ /* write texture coordinates to vertexbuf: */
+ x0 = ((float)xoff) / ((float)pfb->width);
+ x1 = ((float)xoff + bin_w) / ((float)pfb->width);
+ y0 = ((float)yoff) / ((float)pfb->height);
+ y1 = ((float)yoff + bin_h) / ((float)pfb->height);
+ OUT_PKT3(ring, CP_MEM_WRITE, 9);
+ OUT_RELOC(ring, fd_resource(fd2_ctx->solid_vertexbuf)->bo, 0x60, 0);
+ OUT_RING(ring, fui(x0));
+ OUT_RING(ring, fui(y0));
+ OUT_RING(ring, fui(x1));
+ OUT_RING(ring, fui(y0));
+ OUT_RING(ring, fui(x0));
+ OUT_RING(ring, fui(y1));
+ OUT_RING(ring, fui(x1));
+ OUT_RING(ring, fui(y1));
+
+ OUT_PKT3(ring, CP_SET_CONSTANT, 2);
+ OUT_RING(ring, CP_REG(REG_A2XX_VGT_INDX_OFFSET));
+ OUT_RING(ring, 0);
+
+ OUT_PKT3(ring, CP_SET_CONSTANT, 2);
+ OUT_RING(ring, CP_REG(REG_A2XX_VGT_VERTEX_REUSE_BLOCK_CNTL));
+ OUT_RING(ring, 0x0000003b);
+
+ fd2_program_emit(ring, &ctx->blit_prog);
+
+ OUT_PKT0(ring, REG_A2XX_TC_CNTL_STATUS, 1);
+ OUT_RING(ring, A2XX_TC_CNTL_STATUS_L2_INVALIDATE);
+
+ OUT_PKT3(ring, CP_SET_CONSTANT, 2);
+ OUT_RING(ring, CP_REG(REG_A2XX_RB_DEPTHCONTROL));
+ OUT_RING(ring, A2XX_RB_DEPTHCONTROL_EARLY_Z_ENABLE);
+
+ OUT_PKT3(ring, CP_SET_CONSTANT, 2);
+ OUT_RING(ring, CP_REG(REG_A2XX_PA_SU_SC_MODE_CNTL));
+ OUT_RING(ring, A2XX_PA_SU_SC_MODE_CNTL_PROVOKING_VTX_LAST |
+ A2XX_PA_SU_SC_MODE_CNTL_FRONT_PTYPE(PC_DRAW_TRIANGLES) |
+ A2XX_PA_SU_SC_MODE_CNTL_BACK_PTYPE(PC_DRAW_TRIANGLES));
+
+ OUT_PKT3(ring, CP_SET_CONSTANT, 2);
+ OUT_RING(ring, CP_REG(REG_A2XX_PA_SC_AA_MASK));
+ OUT_RING(ring, 0x0000ffff);
+
+ OUT_PKT3(ring, CP_SET_CONSTANT, 2);
+ OUT_RING(ring, CP_REG(REG_A2XX_RB_COLORCONTROL));
+ OUT_RING(ring, A2XX_RB_COLORCONTROL_ALPHA_FUNC(PIPE_FUNC_ALWAYS) |
+ A2XX_RB_COLORCONTROL_BLEND_DISABLE |
+ A2XX_RB_COLORCONTROL_ROP_CODE(12) |
+ A2XX_RB_COLORCONTROL_DITHER_MODE(DITHER_DISABLE) |
+ A2XX_RB_COLORCONTROL_DITHER_TYPE(DITHER_PIXEL));
+
+ OUT_PKT3(ring, CP_SET_CONSTANT, 2);
+ OUT_RING(ring, CP_REG(REG_A2XX_RB_BLEND_CONTROL));
+ OUT_RING(ring, A2XX_RB_BLEND_CONTROL_COLOR_SRCBLEND(FACTOR_ONE) |
+ A2XX_RB_BLEND_CONTROL_COLOR_COMB_FCN(BLEND_DST_PLUS_SRC) |
+ A2XX_RB_BLEND_CONTROL_COLOR_DESTBLEND(FACTOR_ZERO) |
+ A2XX_RB_BLEND_CONTROL_ALPHA_SRCBLEND(FACTOR_ONE) |
+ A2XX_RB_BLEND_CONTROL_ALPHA_COMB_FCN(BLEND_DST_PLUS_SRC) |
+ A2XX_RB_BLEND_CONTROL_ALPHA_DESTBLEND(FACTOR_ZERO));
+
+ OUT_PKT3(ring, CP_SET_CONSTANT, 3);
+ OUT_RING(ring, CP_REG(REG_A2XX_PA_SC_WINDOW_SCISSOR_TL));
+ OUT_RING(ring, A2XX_PA_SC_WINDOW_OFFSET_DISABLE |
+ xy2d(0,0)); /* PA_SC_WINDOW_SCISSOR_TL */
+ OUT_RING(ring, xy2d(bin_w, bin_h)); /* PA_SC_WINDOW_SCISSOR_BR */
+
+ OUT_PKT3(ring, CP_SET_CONSTANT, 5);
+ OUT_RING(ring, CP_REG(REG_A2XX_PA_CL_VPORT_XSCALE));
+ OUT_RING(ring, fui((float)bin_w/2.0)); /* PA_CL_VPORT_XSCALE */
+ OUT_RING(ring, fui((float)bin_w/2.0)); /* PA_CL_VPORT_XOFFSET */
+ OUT_RING(ring, fui(-(float)bin_h/2.0)); /* PA_CL_VPORT_YSCALE */
+ OUT_RING(ring, fui((float)bin_h/2.0)); /* PA_CL_VPORT_YOFFSET */
+
+ OUT_PKT3(ring, CP_SET_CONSTANT, 2);
+ OUT_RING(ring, CP_REG(REG_A2XX_PA_CL_VTE_CNTL));
+ OUT_RING(ring, A2XX_PA_CL_VTE_CNTL_VTX_XY_FMT |
+ A2XX_PA_CL_VTE_CNTL_VTX_Z_FMT | // XXX check this???
+ A2XX_PA_CL_VTE_CNTL_VPORT_X_SCALE_ENA |
+ A2XX_PA_CL_VTE_CNTL_VPORT_X_OFFSET_ENA |
+ A2XX_PA_CL_VTE_CNTL_VPORT_Y_SCALE_ENA |
+ A2XX_PA_CL_VTE_CNTL_VPORT_Y_OFFSET_ENA);
+
+ OUT_PKT3(ring, CP_SET_CONSTANT, 2);
+ OUT_RING(ring, CP_REG(REG_A2XX_PA_CL_CLIP_CNTL));
+ OUT_RING(ring, 0x00000000);
+
+ if (ctx->restore & (FD_BUFFER_DEPTH | FD_BUFFER_STENCIL))
+ emit_mem2gmem_surf(ring, bin_w * bin_h, pfb->zsbuf);
+
+ if (ctx->restore & FD_BUFFER_COLOR)
+ emit_mem2gmem_surf(ring, 0, pfb->cbufs[0]);
+
+ /* TODO blob driver seems to toss in a CACHE_FLUSH after each DRAW_INDX.. */
+}
+
+/* before first tile */
+static void
+fd2_emit_tile_init(struct fd_context *ctx)
+{
+ struct fd_ringbuffer *ring = ctx->ring;
+ struct pipe_framebuffer_state *pfb = &ctx->framebuffer;
+ struct fd_gmem_stateobj *gmem = &ctx->gmem;
+ enum pipe_format format = pfb->cbufs[0]->format;
+ uint32_t reg;
+
+ OUT_PKT3(ring, CP_SET_CONSTANT, 4);
+ OUT_RING(ring, CP_REG(REG_A2XX_RB_SURFACE_INFO));
+ OUT_RING(ring, gmem->bin_w); /* RB_SURFACE_INFO */
+ OUT_RING(ring, A2XX_RB_COLOR_INFO_SWAP(fmt2swap(format)) |
+ A2XX_RB_COLOR_INFO_FORMAT(fd2_pipe2color(format)));
+ reg = A2XX_RB_DEPTH_INFO_DEPTH_BASE(align(gmem->bin_w * gmem->bin_h, 4));
+ if (pfb->zsbuf)
+ reg |= A2XX_RB_DEPTH_INFO_DEPTH_FORMAT(fd_pipe2depth(pfb->zsbuf->format));
+ OUT_RING(ring, reg); /* RB_DEPTH_INFO */
+}
+
+/* before mem2gmem */
+static void
+fd2_emit_tile_prep(struct fd_context *ctx, uint32_t xoff, uint32_t yoff,
+ uint32_t bin_w, uint32_t bin_h)
+{
+ struct fd_ringbuffer *ring = ctx->ring;
+ struct pipe_framebuffer_state *pfb = &ctx->framebuffer;
+ enum pipe_format format = pfb->cbufs[0]->format;
+
+ OUT_PKT3(ring, CP_SET_CONSTANT, 2);
+ OUT_RING(ring, CP_REG(REG_A2XX_RB_COLOR_INFO));
+ OUT_RING(ring, A2XX_RB_COLOR_INFO_SWAP(1) | /* RB_COLOR_INFO */
+ A2XX_RB_COLOR_INFO_FORMAT(fd2_pipe2color(format)));
+
+ /* setup screen scissor for current tile (same for mem2gmem): */
+ OUT_PKT3(ring, CP_SET_CONSTANT, 3);
+ OUT_RING(ring, CP_REG(REG_A2XX_PA_SC_SCREEN_SCISSOR_TL));
+ OUT_RING(ring, xy2d(0,0)); /* PA_SC_SCREEN_SCISSOR_TL */
+ OUT_RING(ring, xy2d(bin_w, bin_h)); /* PA_SC_SCREEN_SCISSOR_BR */
+}
+
+/* before IB to rendering cmds: */
+static void
+fd2_emit_tile_renderprep(struct fd_context *ctx, uint32_t xoff, uint32_t yoff,
+ uint32_t bin_w, uint32_t bin_h)
+{
+ struct fd_ringbuffer *ring = ctx->ring;
+ struct pipe_framebuffer_state *pfb = &ctx->framebuffer;
+ enum pipe_format format = pfb->cbufs[0]->format;
+
+ OUT_PKT3(ring, CP_SET_CONSTANT, 2);
+ OUT_RING(ring, CP_REG(REG_A2XX_RB_COLOR_INFO));
+ OUT_RING(ring, A2XX_RB_COLOR_INFO_SWAP(fmt2swap(format)) |
+ A2XX_RB_COLOR_INFO_FORMAT(fd2_pipe2color(format)));
+
+ /* setup window scissor and offset for current tile (different
+ * from mem2gmem):
+ */
+ OUT_PKT3(ring, CP_SET_CONSTANT, 2);
+ OUT_RING(ring, CP_REG(REG_A2XX_PA_SC_WINDOW_OFFSET));
+ OUT_RING(ring, A2XX_PA_SC_WINDOW_OFFSET_X(-xoff) |
+ A2XX_PA_SC_WINDOW_OFFSET_Y(-yoff));
+}
+
+void
+fd2_gmem_init(struct pipe_context *pctx)
+{
+ struct fd_context *ctx = fd_context(pctx);
+
+ ctx->emit_tile_init = fd2_emit_tile_init;
+ ctx->emit_tile_prep = fd2_emit_tile_prep;
+ ctx->emit_tile_mem2gmem = fd2_emit_tile_mem2gmem;
+ ctx->emit_tile_renderprep = fd2_emit_tile_renderprep;
+ ctx->emit_tile_gmem2mem = fd2_emit_tile_gmem2mem;
+}
--- /dev/null
+/* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */
+
+/*
+ * Copyright (C) 2013 Rob Clark <robclark@freedesktop.org>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Authors:
+ * Rob Clark <robclark@freedesktop.org>
+ */
+
+#ifndef FD2_GMEM_H_
+#define FD2_GMEM_H_
+
+#include "pipe/p_context.h"
+
+void fd2_gmem_init(struct pipe_context *pctx);
+
+#endif /* FD2_GMEM_H_ */
--- /dev/null
+/* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */
+
+/*
+ * Copyright (C) 2012 Rob Clark <robclark@freedesktop.org>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Authors:
+ * Rob Clark <robclark@freedesktop.org>
+ */
+
+#include "pipe/p_state.h"
+#include "util/u_string.h"
+#include "util/u_memory.h"
+#include "util/u_inlines.h"
+#include "util/u_format.h"
+#include "tgsi/tgsi_dump.h"
+#include "tgsi/tgsi_parse.h"
+
+#include "fd2_program.h"
+#include "fd2_compiler.h"
+#include "fd2_texture.h"
+#include "fd2_util.h"
+
+static struct fd2_shader_stateobj *
+create_shader(enum shader_t type)
+{
+ struct fd2_shader_stateobj *so = CALLOC_STRUCT(fd2_shader_stateobj);
+ if (!so)
+ return NULL;
+ so->type = type;
+ return so;
+}
+
+static void
+delete_shader(struct fd2_shader_stateobj *so)
+{
+ ir2_shader_destroy(so->ir);
+ free(so->tokens);
+ free(so->bin);
+ free(so);
+}
+
+static struct fd2_shader_stateobj *
+assemble(struct fd2_shader_stateobj *so)
+{
+ free(so->bin);
+ so->bin = ir2_shader_assemble(so->ir, &so->info);
+ if (!so->bin)
+ goto fail;
+
+ if (fd_mesa_debug & FD_DBG_DISASM) {
+ DBG("disassemble: type=%d", so->type);
+ disasm_a2xx(so->bin, so->info.sizedwords, 0, so->type);
+ }
+
+ return so;
+
+fail:
+ debug_error("assemble failed!");
+ delete_shader(so);
+ return NULL;
+}
+
+static struct fd2_shader_stateobj *
+compile(struct fd_program_stateobj *prog, struct fd2_shader_stateobj *so)
+{
+ int ret;
+
+ if (fd_mesa_debug & FD_DBG_DISASM) {
+ DBG("dump tgsi: type=%d", so->type);
+ tgsi_dump(so->tokens, 0);
+ }
+
+ ret = fd2_compile_shader(prog, so);
+ if (ret)
+ goto fail;
+
+ /* NOTE: we don't assemble yet because for VS we don't know the
+ * type information for vertex fetch yet.. so those need to be
+ * patched up later before assembling.
+ */
+
+ so->info.sizedwords = 0;
+
+ return so;
+
+fail:
+ debug_error("compile failed!");
+ delete_shader(so);
+ return NULL;
+}
+
+static void
+emit(struct fd_ringbuffer *ring, struct fd2_shader_stateobj *so)
+{
+ unsigned i;
+
+ if (so->info.sizedwords == 0)
+ assemble(so);
+
+ OUT_PKT3(ring, CP_IM_LOAD_IMMEDIATE, 2 + so->info.sizedwords);
+ OUT_RING(ring, (so->type == SHADER_VERTEX) ? 0 : 1);
+ OUT_RING(ring, so->info.sizedwords);
+ for (i = 0; i < so->info.sizedwords; i++)
+ OUT_RING(ring, so->bin[i]);
+}
+
+static void *
+fd2_fp_state_create(struct pipe_context *pctx,
+ const struct pipe_shader_state *cso)
+{
+ struct fd2_shader_stateobj *so = create_shader(SHADER_FRAGMENT);
+ if (!so)
+ return NULL;
+ so->tokens = tgsi_dup_tokens(cso->tokens);
+ return so;
+}
+
+static void
+fd2_fp_state_delete(struct pipe_context *pctx, void *hwcso)
+{
+ struct fd2_shader_stateobj *so = hwcso;
+ delete_shader(so);
+}
+
+static void
+fd2_fp_state_bind(struct pipe_context *pctx, void *hwcso)
+{
+ struct fd_context *ctx = fd_context(pctx);
+ ctx->prog.fp = hwcso;
+ ctx->prog.dirty |= FD_SHADER_DIRTY_FP;
+ ctx->dirty |= FD_DIRTY_PROG;
+}
+
+static void *
+fd2_vp_state_create(struct pipe_context *pctx,
+ const struct pipe_shader_state *cso)
+{
+ struct fd2_shader_stateobj *so = create_shader(SHADER_VERTEX);
+ if (!so)
+ return NULL;
+ so->tokens = tgsi_dup_tokens(cso->tokens);
+ return so;
+}
+
+static void
+fd2_vp_state_delete(struct pipe_context *pctx, void *hwcso)
+{
+ struct fd2_shader_stateobj *so = hwcso;
+ delete_shader(so);
+}
+
+static void
+fd2_vp_state_bind(struct pipe_context *pctx, void *hwcso)
+{
+ struct fd_context *ctx = fd_context(pctx);
+ ctx->prog.vp = hwcso;
+ ctx->prog.dirty |= FD_SHADER_DIRTY_VP;
+ ctx->dirty |= FD_DIRTY_PROG;
+}
+
+static void
+patch_vtx_fetches(struct fd_context *ctx, struct fd2_shader_stateobj *so,
+ struct fd_vertex_stateobj *vtx)
+{
+ unsigned i;
+
+ assert(so->num_vfetch_instrs == vtx->num_elements);
+
+ /* update vtx fetch instructions: */
+ for (i = 0; i < so->num_vfetch_instrs; i++) {
+ struct ir2_instruction *instr = so->vfetch_instrs[i];
+ struct pipe_vertex_element *elem = &vtx->pipe[i];
+ struct pipe_vertex_buffer *vb =
+ &ctx->vertexbuf.vb[elem->vertex_buffer_index];
+ enum pipe_format format = elem->src_format;
+ const struct util_format_description *desc =
+ util_format_description(format);
+ unsigned j;
+
+ /* Find the first non-VOID channel. */
+ for (j = 0; j < 4; j++)
+ if (desc->channel[j].type != UTIL_FORMAT_TYPE_VOID)
+ break;
+
+ /* CI/CIS can probably be set in compiler instead: */
+ instr->fetch.const_idx = 20 + (i / 3);
+ instr->fetch.const_idx_sel = i % 3;
+
+ instr->fetch.fmt = fd2_pipe2surface(format);
+ instr->fetch.is_normalized = desc->channel[j].normalized;
+ instr->fetch.is_signed =
+ desc->channel[j].type == UTIL_FORMAT_TYPE_SIGNED;
+ instr->fetch.stride = vb->stride ? : 1;
+ instr->fetch.offset = elem->src_offset;
+
+ for (j = 0; j < 4; j++)
+ instr->regs[0]->swizzle[j] = "xyzw01__"[desc->swizzle[j]];
+
+ assert(instr->fetch.fmt != ~0);
+
+ DBG("vtx[%d]: %s (%d), ci=%d, cis=%d, id=%d, swizzle=%s, "
+ "stride=%d, offset=%d",
+ i, util_format_name(format),
+ instr->fetch.fmt,
+ instr->fetch.const_idx,
+ instr->fetch.const_idx_sel,
+ elem->instance_divisor,
+ instr->regs[0]->swizzle,
+ instr->fetch.stride,
+ instr->fetch.offset);
+ }
+
+ /* trigger re-assemble: */
+ so->info.sizedwords = 0;
+}
+
+static void
+patch_tex_fetches(struct fd_context *ctx, struct fd2_shader_stateobj *so,
+ struct fd_texture_stateobj *tex)
+{
+ unsigned i;
+
+ /* update tex fetch instructions: */
+ for (i = 0; i < so->num_tfetch_instrs; i++) {
+ struct ir2_instruction *instr = so->tfetch_instrs[i].instr;
+ unsigned samp_id = so->tfetch_instrs[i].samp_id;
+ unsigned const_idx = fd2_get_const_idx(ctx, tex, samp_id);
+
+ if (const_idx != instr->fetch.const_idx) {
+ instr->fetch.const_idx = const_idx;
+ /* trigger re-assemble: */
+ so->info.sizedwords = 0;
+ }
+ }
+}
+
+void
+fd2_program_validate(struct fd_context *ctx)
+{
+ struct fd_program_stateobj *prog = &ctx->prog;
+
+ /* if vertex or frag shader is dirty, we may need to recompile. Compile
+ * frag shader first, as that assigns the register slots for exports
+ * from the vertex shader. And therefore if frag shader has changed we
+ * need to recompile both vert and frag shader.
+ */
+ if (prog->dirty & FD_SHADER_DIRTY_FP)
+ compile(prog, prog->fp);
+
+ if (prog->dirty & (FD_SHADER_DIRTY_FP | FD_SHADER_DIRTY_VP))
+ compile(prog, prog->vp);
+
+ if (prog->dirty)
+ ctx->dirty |= FD_DIRTY_PROG;
+
+ /* if necessary, fix up vertex fetch instructions: */
+ if (ctx->dirty & (FD_DIRTY_VTXSTATE | FD_DIRTY_PROG))
+ patch_vtx_fetches(ctx, prog->vp, ctx->vtx);
+
+ /* if necessary, fix up texture fetch instructions: */
+ if (ctx->dirty & (FD_DIRTY_TEXSTATE | FD_DIRTY_PROG)) {
+ patch_tex_fetches(ctx, prog->vp, &ctx->verttex);
+ patch_tex_fetches(ctx, prog->fp, &ctx->fragtex);
+ }
+}
+
+void
+fd2_program_emit(struct fd_ringbuffer *ring,
+ struct fd_program_stateobj *prog)
+{
+ struct ir2_shader_info *vsi =
+ &((struct fd2_shader_stateobj *)prog->vp)->info;
+ struct ir2_shader_info *fsi =
+ &((struct fd2_shader_stateobj *)prog->fp)->info;
+ uint8_t vs_gprs, fs_gprs, vs_export;
+
+ emit(ring, prog->vp);
+ emit(ring, prog->fp);
+
+ vs_gprs = (vsi->max_reg < 0) ? 0x80 : vsi->max_reg;
+ fs_gprs = (fsi->max_reg < 0) ? 0x80 : fsi->max_reg;
+ vs_export = MAX2(1, prog->num_exports) - 1;
+
+ OUT_PKT3(ring, CP_SET_CONSTANT, 2);
+ OUT_RING(ring, CP_REG(REG_A2XX_SQ_PROGRAM_CNTL));
+ OUT_RING(ring, A2XX_SQ_PROGRAM_CNTL_PS_EXPORT_MODE(POSITION_2_VECTORS_SPRITE) |
+ A2XX_SQ_PROGRAM_CNTL_VS_RESOURCE |
+ A2XX_SQ_PROGRAM_CNTL_PS_RESOURCE |
+ A2XX_SQ_PROGRAM_CNTL_VS_EXPORT_COUNT(vs_export) |
+ A2XX_SQ_PROGRAM_CNTL_PS_REGS(fs_gprs) |
+ A2XX_SQ_PROGRAM_CNTL_VS_REGS(vs_gprs));
+
+ prog->dirty = 0;
+}
+
+/* Creates shader:
+ * EXEC ADDR(0x2) CNT(0x1)
+ * (S)FETCH: SAMPLE R0.xyzw = R0.xyx CONST(0) LOCATION(CENTER)
+ * ALLOC PARAM/PIXEL SIZE(0x0)
+ * EXEC_END ADDR(0x3) CNT(0x1)
+ * ALU: MAXv export0 = R0, R0 ; gl_FragColor
+ * NOP
+ */
+static struct fd2_shader_stateobj *
+create_blit_fp(void)
+{
+ struct fd2_shader_stateobj *so = create_shader(SHADER_FRAGMENT);
+ struct ir2_cf *cf;
+ struct ir2_instruction *instr;
+
+ if (!so)
+ return NULL;
+
+ so->ir = ir2_shader_create();
+
+ cf = ir2_cf_create(so->ir, EXEC);
+
+ instr = ir2_instr_create_tex_fetch(cf, 0);
+ ir2_reg_create(instr, 0, "xyzw", 0);
+ ir2_reg_create(instr, 0, "xyx", 0);
+ instr->sync = true;
+
+ cf = ir2_cf_create_alloc(so->ir, SQ_PARAMETER_PIXEL, 0);
+ cf = ir2_cf_create(so->ir, EXEC_END);
+
+ instr = ir2_instr_create_alu(cf, MAXv, ~0);
+ ir2_reg_create(instr, 0, NULL, IR2_REG_EXPORT);
+ ir2_reg_create(instr, 0, NULL, 0);
+ ir2_reg_create(instr, 0, NULL, 0);
+
+ return assemble(so);
+}
+
+/* Creates shader:
+* EXEC ADDR(0x3) CNT(0x2)
+* FETCH: VERTEX R1.xy01 = R0.x FMT_32_32_FLOAT UNSIGNED STRIDE(8) CONST(26, 1)
+* FETCH: VERTEX R2.xyz1 = R0.x FMT_32_32_32_FLOAT UNSIGNED STRIDE(12) CONST(26, 0)
+* ALLOC POSITION SIZE(0x0)
+* EXEC ADDR(0x5) CNT(0x1)
+* ALU: MAXv export62 = R2, R2 ; gl_Position
+* ALLOC PARAM/PIXEL SIZE(0x0)
+* EXEC_END ADDR(0x6) CNT(0x1)
+* ALU: MAXv export0 = R1, R1
+* NOP
+ */
+static struct fd2_shader_stateobj *
+create_blit_vp(void)
+{
+ struct fd2_shader_stateobj *so = create_shader(SHADER_VERTEX);
+ struct ir2_cf *cf;
+ struct ir2_instruction *instr;
+
+ if (!so)
+ return NULL;
+
+ so->ir = ir2_shader_create();
+
+ cf = ir2_cf_create(so->ir, EXEC);
+
+ instr = ir2_instr_create_vtx_fetch(cf, 26, 1, FMT_32_32_FLOAT, false, 8);
+ instr->fetch.is_normalized = true;
+ ir2_reg_create(instr, 1, "xy01", 0);
+ ir2_reg_create(instr, 0, "x", 0);
+
+ instr = ir2_instr_create_vtx_fetch(cf, 26, 0, FMT_32_32_32_FLOAT, false, 12);
+ instr->fetch.is_normalized = true;
+ ir2_reg_create(instr, 2, "xyz1", 0);
+ ir2_reg_create(instr, 0, "x", 0);
+
+ cf = ir2_cf_create_alloc(so->ir, SQ_POSITION, 0);
+ cf = ir2_cf_create(so->ir, EXEC);
+
+ instr = ir2_instr_create_alu(cf, MAXv, ~0);
+ ir2_reg_create(instr, 62, NULL, IR2_REG_EXPORT);
+ ir2_reg_create(instr, 2, NULL, 0);
+ ir2_reg_create(instr, 2, NULL, 0);
+
+ cf = ir2_cf_create_alloc(so->ir, SQ_PARAMETER_PIXEL, 0);
+ cf = ir2_cf_create(so->ir, EXEC_END);
+
+ instr = ir2_instr_create_alu(cf, MAXv, ~0);
+ ir2_reg_create(instr, 0, NULL, IR2_REG_EXPORT);
+ ir2_reg_create(instr, 1, NULL, 0);
+ ir2_reg_create(instr, 1, NULL, 0);
+
+ return assemble(so);
+}
+
+/* Creates shader:
+ * ALLOC PARAM/PIXEL SIZE(0x0)
+ * EXEC_END ADDR(0x1) CNT(0x1)
+ * ALU: MAXv export0 = C0, C0 ; gl_FragColor
+ */
+static struct fd2_shader_stateobj *
+create_solid_fp(void)
+{
+ struct fd2_shader_stateobj *so = create_shader(SHADER_FRAGMENT);
+ struct ir2_cf *cf;
+ struct ir2_instruction *instr;
+
+ if (!so)
+ return NULL;
+
+ so->ir = ir2_shader_create();
+
+ cf = ir2_cf_create_alloc(so->ir, SQ_PARAMETER_PIXEL, 0);
+ cf = ir2_cf_create(so->ir, EXEC_END);
+
+ instr = ir2_instr_create_alu(cf, MAXv, ~0);
+ ir2_reg_create(instr, 0, NULL, IR2_REG_EXPORT);
+ ir2_reg_create(instr, 0, NULL, IR2_REG_CONST);
+ ir2_reg_create(instr, 0, NULL, IR2_REG_CONST);
+
+ return assemble(so);
+}
+
+/* Creates shader:
+ * EXEC ADDR(0x3) CNT(0x1)
+ * (S)FETCH: VERTEX R1.xyz1 = R0.x FMT_32_32_32_FLOAT
+ * UNSIGNED STRIDE(12) CONST(26, 0)
+ * ALLOC POSITION SIZE(0x0)
+ * EXEC ADDR(0x4) CNT(0x1)
+ * ALU: MAXv export62 = R1, R1 ; gl_Position
+ * ALLOC PARAM/PIXEL SIZE(0x0)
+ * EXEC_END ADDR(0x5) CNT(0x0)
+ */
+static struct fd2_shader_stateobj *
+create_solid_vp(void)
+{
+ struct fd2_shader_stateobj *so = create_shader(SHADER_VERTEX);
+ struct ir2_cf *cf;
+ struct ir2_instruction *instr;
+
+ if (!so)
+ return NULL;
+
+ so->ir = ir2_shader_create();
+
+ cf = ir2_cf_create(so->ir, EXEC);
+
+ instr = ir2_instr_create_vtx_fetch(cf, 26, 0, FMT_32_32_32_FLOAT, false, 12);
+ ir2_reg_create(instr, 1, "xyz1", 0);
+ ir2_reg_create(instr, 0, "x", 0);
+
+ cf = ir2_cf_create_alloc(so->ir, SQ_POSITION, 0);
+ cf = ir2_cf_create(so->ir, EXEC);
+
+ instr = ir2_instr_create_alu(cf, MAXv, ~0);
+ ir2_reg_create(instr, 62, NULL, IR2_REG_EXPORT);
+ ir2_reg_create(instr, 1, NULL, 0);
+ ir2_reg_create(instr, 1, NULL, 0);
+
+ cf = ir2_cf_create_alloc(so->ir, SQ_PARAMETER_PIXEL, 0);
+ cf = ir2_cf_create(so->ir, EXEC_END);
+
+ return assemble(so);
+}
+
+void
+fd2_prog_init(struct pipe_context *pctx)
+{
+ struct fd_context *ctx = fd_context(pctx);
+
+ pctx->create_fs_state = fd2_fp_state_create;
+ pctx->bind_fs_state = fd2_fp_state_bind;
+ pctx->delete_fs_state = fd2_fp_state_delete;
+
+ pctx->create_vs_state = fd2_vp_state_create;
+ pctx->bind_vs_state = fd2_vp_state_bind;
+ pctx->delete_vs_state = fd2_vp_state_delete;
+
+ ctx->solid_prog.fp = create_solid_fp();
+ ctx->solid_prog.vp = create_solid_vp();
+ ctx->blit_prog.fp = create_blit_fp();
+ ctx->blit_prog.vp = create_blit_vp();
+}
+
+void
+fd2_prog_fini(struct pipe_context *pctx)
+{
+ struct fd_context *ctx = fd_context(pctx);
+
+ delete_shader(ctx->solid_prog.vp);
+ delete_shader(ctx->solid_prog.fp);
+ delete_shader(ctx->blit_prog.vp);
+ delete_shader(ctx->blit_prog.fp);
+}
--- /dev/null
+/* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */
+
+/*
+ * Copyright (C) 2012-2013 Rob Clark <robclark@freedesktop.org>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Authors:
+ * Rob Clark <robclark@freedesktop.org>
+ */
+
+#ifndef FD2_PROGRAM_H_
+#define FD2_PROGRAM_H_
+
+#include "pipe/p_context.h"
+
+#include "freedreno_context.h"
+
+#include "ir-a2xx.h"
+#include "disasm.h"
+
+struct fd2_shader_stateobj {
+ enum shader_t type;
+
+ uint32_t *bin;
+
+ struct tgsi_token *tokens;
+
+ /* note that we defer compiling shader until we know both vs and ps..
+ * and if one changes, we potentially need to recompile in order to
+ * get varying linkages correct:
+ */
+ struct ir2_shader_info info;
+ struct ir2_shader *ir;
+
+ /* for vertex shaders, the fetch instructions which need to be
+ * patched up before assembly:
+ */
+ unsigned num_vfetch_instrs;
+ struct ir2_instruction *vfetch_instrs[64];
+
+ /* for all shaders, any tex fetch instructions which need to be
+ * patched before assembly:
+ */
+ unsigned num_tfetch_instrs;
+ struct {
+ unsigned samp_id;
+ struct ir2_instruction *instr;
+ } tfetch_instrs[64];
+
+ unsigned first_immediate; /* const reg # of first immediate */
+ unsigned num_immediates;
+ struct {
+ uint32_t val[4];
+ } immediates[64];
+};
+
+void fd2_program_emit(struct fd_ringbuffer *ring,
+ struct fd_program_stateobj *prog);
+void fd2_program_validate(struct fd_context *ctx);
+
+void fd2_prog_init(struct pipe_context *pctx);
+void fd2_prog_fini(struct pipe_context *pctx);
+
+#endif /* FD2_PROGRAM_H_ */
--- /dev/null
+/* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */
+
+/*
+ * Copyright (C) 2012-2013 Rob Clark <robclark@freedesktop.org>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Authors:
+ * Rob Clark <robclark@freedesktop.org>
+ */
+
+
+#include "pipe/p_state.h"
+#include "util/u_string.h"
+#include "util/u_memory.h"
+
+#include "fd2_rasterizer.h"
+#include "fd2_context.h"
+#include "fd2_util.h"
+
+
+void *
+fd2_rasterizer_state_create(struct pipe_context *pctx,
+ const struct pipe_rasterizer_state *cso)
+{
+ struct fd2_rasterizer_stateobj *so;
+ float psize_min, psize_max;
+
+ so = CALLOC_STRUCT(fd2_rasterizer_stateobj);
+ if (!so)
+ return NULL;
+
+ if (cso->point_size_per_vertex) {
+ psize_min = util_get_min_point_size(cso);
+ psize_max = 8192;
+ } else {
+ /* Force the point size to be as if the vertex output was disabled. */
+ psize_min = cso->point_size;
+ psize_max = cso->point_size;
+ }
+
+ so->base = *cso;
+
+ so->pa_sc_line_stipple = cso->line_stipple_enable ?
+ A2XX_PA_SC_LINE_STIPPLE_LINE_PATTERN(cso->line_stipple_pattern) |
+ A2XX_PA_SC_LINE_STIPPLE_REPEAT_COUNT(cso->line_stipple_factor) : 0;
+
+ so->pa_cl_clip_cntl = 0; // TODO
+
+ so->pa_su_vtx_cntl =
+ A2XX_PA_SU_VTX_CNTL_PIX_CENTER(cso->half_pixel_center ? PIXCENTER_OGL : PIXCENTER_D3D) |
+ A2XX_PA_SU_VTX_CNTL_QUANT_MODE(ONE_SIXTEENTH);
+
+ so->pa_su_point_size =
+ A2XX_PA_SU_POINT_SIZE_HEIGHT(cso->point_size/2) |
+ A2XX_PA_SU_POINT_SIZE_WIDTH(cso->point_size/2);
+
+ so->pa_su_point_minmax =
+ A2XX_PA_SU_POINT_MINMAX_MIN(psize_min/2) |
+ A2XX_PA_SU_POINT_MINMAX_MAX(psize_max/2);
+
+ so->pa_su_line_cntl =
+ A2XX_PA_SU_LINE_CNTL_WIDTH(cso->line_width/2);
+
+ so->pa_su_sc_mode_cntl =
+ A2XX_PA_SU_SC_MODE_CNTL_VTX_WINDOW_OFFSET_ENABLE |
+ A2XX_PA_SU_SC_MODE_CNTL_FRONT_PTYPE(fd_polygon_mode(cso->fill_front)) |
+ A2XX_PA_SU_SC_MODE_CNTL_BACK_PTYPE(fd_polygon_mode(cso->fill_back));
+
+ if (cso->cull_face & PIPE_FACE_FRONT)
+ so->pa_su_sc_mode_cntl |= A2XX_PA_SU_SC_MODE_CNTL_CULL_FRONT;
+ if (cso->cull_face & PIPE_FACE_BACK)
+ so->pa_su_sc_mode_cntl |= A2XX_PA_SU_SC_MODE_CNTL_CULL_BACK;
+ if (!cso->flatshade_first)
+ so->pa_su_sc_mode_cntl |= A2XX_PA_SU_SC_MODE_CNTL_PROVOKING_VTX_LAST;
+ if (!cso->front_ccw)
+ so->pa_su_sc_mode_cntl |= A2XX_PA_SU_SC_MODE_CNTL_FACE;
+ if (cso->line_stipple_enable)
+ so->pa_su_sc_mode_cntl |= A2XX_PA_SU_SC_MODE_CNTL_LINE_STIPPLE_ENABLE;
+ if (cso->multisample)
+ so->pa_su_sc_mode_cntl |= A2XX_PA_SU_SC_MODE_CNTL_MSAA_ENABLE;
+
+ if (cso->fill_front != PIPE_POLYGON_MODE_FILL ||
+ cso->fill_back != PIPE_POLYGON_MODE_FILL)
+ so->pa_su_sc_mode_cntl |= A2XX_PA_SU_SC_MODE_CNTL_POLYMODE(POLY_DUALMODE);
+ else
+ so->pa_su_sc_mode_cntl |= A2XX_PA_SU_SC_MODE_CNTL_POLYMODE(POLY_DISABLED);
+
+ if (cso->offset_tri)
+ so->pa_su_sc_mode_cntl |=
+ A2XX_PA_SU_SC_MODE_CNTL_POLY_OFFSET_FRONT_ENABLE |
+ A2XX_PA_SU_SC_MODE_CNTL_POLY_OFFSET_BACK_ENABLE |
+ A2XX_PA_SU_SC_MODE_CNTL_POLY_OFFSET_PARA_ENABLE;
+
+ return so;
+}
--- /dev/null
+/* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */
+
+/*
+ * Copyright (C) 2012-2013 Rob Clark <robclark@freedesktop.org>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Authors:
+ * Rob Clark <robclark@freedesktop.org>
+ */
+
+#ifndef FD2_RASTERIZER_H_
+#define FD2_RASTERIZER_H_
+
+#include "pipe/p_state.h"
+#include "pipe/p_context.h"
+
+struct fd2_rasterizer_stateobj {
+ struct pipe_rasterizer_state base;
+ uint32_t pa_sc_line_stipple;
+ uint32_t pa_cl_clip_cntl;
+ uint32_t pa_su_vtx_cntl;
+ uint32_t pa_su_point_size;
+ uint32_t pa_su_point_minmax;
+ uint32_t pa_su_line_cntl;
+ uint32_t pa_su_sc_mode_cntl;
+};
+
+static INLINE struct fd2_rasterizer_stateobj *
+fd2_rasterizer_stateobj(struct pipe_rasterizer_state *rast)
+{
+ return (struct fd2_rasterizer_stateobj *)rast;
+}
+
+void * fd2_rasterizer_state_create(struct pipe_context *pctx,
+ const struct pipe_rasterizer_state *cso);
+
+#endif /* FD2_RASTERIZER_H_ */
--- /dev/null
+/* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */
+
+/*
+ * Copyright (C) 2013 Rob Clark <robclark@freedesktop.org>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Authors:
+ * Rob Clark <robclark@freedesktop.org>
+ */
+
+#include "pipe/p_screen.h"
+#include "util/u_format.h"
+
+#include "fd2_screen.h"
+#include "fd2_context.h"
+#include "fd2_util.h"
+
+static boolean
+fd2_screen_is_format_supported(struct pipe_screen *pscreen,
+ enum pipe_format format,
+ enum pipe_texture_target target,
+ unsigned sample_count,
+ unsigned usage)
+{
+ unsigned retval = 0;
+
+ if ((target >= PIPE_MAX_TEXTURE_TYPES) ||
+ (sample_count > 1) || /* TODO add MSAA */
+ !util_format_is_supported(format, usage)) {
+ DBG("not supported: format=%s, target=%d, sample_count=%d, usage=%x",
+ util_format_name(format), target, sample_count, usage);
+ return FALSE;
+ }
+
+ /* TODO figure out how to render to other formats.. */
+ if ((usage & PIPE_BIND_RENDER_TARGET) &&
+ ((format != PIPE_FORMAT_B8G8R8A8_UNORM) &&
+ (format != PIPE_FORMAT_B8G8R8X8_UNORM))) {
+ DBG("not supported render target: format=%s, target=%d, sample_count=%d, usage=%x",
+ util_format_name(format), target, sample_count, usage);
+ return FALSE;
+ }
+
+ if ((usage & (PIPE_BIND_SAMPLER_VIEW |
+ PIPE_BIND_VERTEX_BUFFER)) &&
+ (fd2_pipe2surface(format) != ~0)) {
+ retval |= usage & (PIPE_BIND_SAMPLER_VIEW |
+ PIPE_BIND_VERTEX_BUFFER);
+ }
+
+ if ((usage & (PIPE_BIND_RENDER_TARGET |
+ PIPE_BIND_DISPLAY_TARGET |
+ PIPE_BIND_SCANOUT |
+ PIPE_BIND_SHARED)) &&
+ (fd2_pipe2color(format) != ~0)) {
+ retval |= usage & (PIPE_BIND_RENDER_TARGET |
+ PIPE_BIND_DISPLAY_TARGET |
+ PIPE_BIND_SCANOUT |
+ PIPE_BIND_SHARED);
+ }
+
+ if ((usage & PIPE_BIND_DEPTH_STENCIL) &&
+ (fd_pipe2depth(format) != ~0)) {
+ retval |= PIPE_BIND_DEPTH_STENCIL;
+ }
+
+ if ((usage & PIPE_BIND_INDEX_BUFFER) &&
+ (fd_pipe2index(format) != ~0)) {
+ retval |= PIPE_BIND_INDEX_BUFFER;
+ }
+
+ if (usage & PIPE_BIND_TRANSFER_READ)
+ retval |= PIPE_BIND_TRANSFER_READ;
+ if (usage & PIPE_BIND_TRANSFER_WRITE)
+ retval |= PIPE_BIND_TRANSFER_WRITE;
+
+ if (retval != usage) {
+ DBG("not supported: format=%s, target=%d, sample_count=%d, "
+ "usage=%x, retval=%x", util_format_name(format),
+ target, sample_count, usage, retval);
+ }
+
+ return retval == usage;
+}
+
+void
+fd2_screen_init(struct pipe_screen *pscreen)
+{
+ pscreen->context_create = fd2_context_create;
+ pscreen->is_format_supported = fd2_screen_is_format_supported;
+}
--- /dev/null
+/* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */
+
+/*
+ * Copyright (C) 2013 Rob Clark <robclark@freedesktop.org>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Authors:
+ * Rob Clark <robclark@freedesktop.org>
+ */
+
+#ifndef FD2_SCREEN_H_
+#define FD2_SCREEN_H_
+
+#include "pipe/p_screen.h"
+
+void fd2_screen_init(struct pipe_screen *pscreen);
+
+#endif /* FD2_SCREEN_H_ */
--- /dev/null
+/* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */
+
+/*
+ * Copyright (C) 2012-2013 Rob Clark <robclark@freedesktop.org>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Authors:
+ * Rob Clark <robclark@freedesktop.org>
+ */
+
+#include "pipe/p_state.h"
+#include "util/u_string.h"
+#include "util/u_memory.h"
+#include "util/u_inlines.h"
+
+#include "fd2_texture.h"
+#include "fd2_util.h"
+
+static enum sq_tex_clamp
+tex_clamp(unsigned wrap)
+{
+ switch (wrap) {
+ case PIPE_TEX_WRAP_REPEAT:
+ return SQ_TEX_WRAP;
+ case PIPE_TEX_WRAP_CLAMP:
+ return SQ_TEX_CLAMP_HALF_BORDER;
+ case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
+ return SQ_TEX_CLAMP_LAST_TEXEL;
+ case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
+ return SQ_TEX_CLAMP_BORDER;
+ case PIPE_TEX_WRAP_MIRROR_REPEAT:
+ return SQ_TEX_MIRROR;
+ case PIPE_TEX_WRAP_MIRROR_CLAMP:
+ return SQ_TEX_MIRROR_ONCE_HALF_BORDER;
+ case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE:
+ return SQ_TEX_MIRROR_ONCE_LAST_TEXEL;
+ case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER:
+ return SQ_TEX_MIRROR_ONCE_BORDER;
+ default:
+ DBG("invalid wrap: %u", wrap);
+ return 0;
+ }
+}
+
+static enum sq_tex_filter
+tex_filter(unsigned filter)
+{
+ switch (filter) {
+ case PIPE_TEX_FILTER_NEAREST:
+ return SQ_TEX_FILTER_POINT;
+ case PIPE_TEX_FILTER_LINEAR:
+ return SQ_TEX_FILTER_BILINEAR;
+ default:
+ DBG("invalid filter: %u", filter);
+ return 0;
+ }
+}
+
+static void *
+fd2_sampler_state_create(struct pipe_context *pctx,
+ const struct pipe_sampler_state *cso)
+{
+ struct fd2_sampler_stateobj *so = CALLOC_STRUCT(fd2_sampler_stateobj);
+
+ if (!so)
+ return NULL;
+
+ so->base = *cso;
+
+ /* SQ_TEX0_PITCH() must be OR'd in later when we know the bound texture: */
+ so->tex0 =
+ A2XX_SQ_TEX_0_CLAMP_X(tex_clamp(cso->wrap_s)) |
+ A2XX_SQ_TEX_0_CLAMP_Y(tex_clamp(cso->wrap_t)) |
+ A2XX_SQ_TEX_0_CLAMP_Z(tex_clamp(cso->wrap_r));
+
+ so->tex3 =
+ A2XX_SQ_TEX_3_XY_MAG_FILTER(tex_filter(cso->mag_img_filter)) |
+ A2XX_SQ_TEX_3_XY_MIN_FILTER(tex_filter(cso->min_img_filter));
+
+ so->tex4 = 0x00000000; /* ??? */
+ so->tex5 = 0x00000200; /* ??? */
+
+ return so;
+}
+
+static struct pipe_sampler_view *
+fd2_sampler_view_create(struct pipe_context *pctx, struct pipe_resource *prsc,
+ const struct pipe_sampler_view *cso)
+{
+ struct fd2_pipe_sampler_view *so = CALLOC_STRUCT(fd2_pipe_sampler_view);
+ struct fd_resource *rsc = fd_resource(prsc);
+
+ if (!so)
+ return NULL;
+
+ so->base = *cso;
+ pipe_reference(NULL, &prsc->reference);
+ so->base.texture = prsc;
+ so->base.reference.count = 1;
+ so->base.context = pctx;
+
+ so->tex_resource = rsc;
+ so->fmt = fd2_pipe2surface(cso->format);
+
+ so->tex0 = A2XX_SQ_TEX_0_PITCH(rsc->pitch);
+ so->tex2 =
+ A2XX_SQ_TEX_2_HEIGHT(prsc->height0 - 1) |
+ A2XX_SQ_TEX_2_WIDTH(prsc->width0 - 1);
+ so->tex3 = fd2_tex_swiz(cso->format, cso->swizzle_r, cso->swizzle_g,
+ cso->swizzle_b, cso->swizzle_a);
+
+ return &so->base;
+}
+
+/* map gallium sampler-id to hw const-idx.. adreno uses a flat address
+ * space of samplers (const-idx), so we need to map the gallium sampler-id
+ * which is per-shader to a global const-idx space.
+ *
+ * Fragment shader sampler maps directly to const-idx, and vertex shader
+ * is offset by the # of fragment shader samplers. If the # of fragment
+ * shader samplers changes, this shifts the vertex shader indexes.
+ *
+ * TODO maybe we can do frag shader 0..N and vert shader N..0 to avoid
+ * this??
+ */
+unsigned
+fd2_get_const_idx(struct fd_context *ctx, struct fd_texture_stateobj *tex,
+ unsigned samp_id)
+{
+ if (tex == &ctx->fragtex)
+ return samp_id;
+ return samp_id + ctx->fragtex.num_samplers;
+}
+
+void
+fd2_texture_init(struct pipe_context *pctx)
+{
+ pctx->create_sampler_state = fd2_sampler_state_create;
+ pctx->create_sampler_view = fd2_sampler_view_create;
+}
--- /dev/null
+/* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */
+
+/*
+ * Copyright (C) 2012-2013 Rob Clark <robclark@freedesktop.org>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Authors:
+ * Rob Clark <robclark@freedesktop.org>
+ */
+
+#ifndef FD2_TEXTURE_H_
+#define FD2_TEXTURE_H_
+
+#include "pipe/p_context.h"
+
+#include "freedreno_texture.h"
+#include "freedreno_resource.h"
+
+#include "fd2_context.h"
+#include "fd2_util.h"
+
+struct fd2_sampler_stateobj {
+ struct pipe_sampler_state base;
+ uint32_t tex0, tex3, tex4, tex5;
+};
+
+static INLINE struct fd2_sampler_stateobj *
+fd2_sampler_stateobj(struct pipe_sampler_state *samp)
+{
+ return (struct fd2_sampler_stateobj *)samp;
+}
+
+struct fd2_pipe_sampler_view {
+ struct pipe_sampler_view base;
+ struct fd_resource *tex_resource;
+ enum a2xx_sq_surfaceformat fmt;
+ uint32_t tex0, tex2, tex3;
+};
+
+static INLINE struct fd2_pipe_sampler_view *
+fd2_pipe_sampler_view(struct pipe_sampler_view *pview)
+{
+ return (struct fd2_pipe_sampler_view *)pview;
+}
+
+unsigned fd2_get_const_idx(struct fd_context *ctx,
+ struct fd_texture_stateobj *tex, unsigned samp_id);
+
+void fd2_texture_init(struct pipe_context *pctx);
+
+#endif /* FD2_TEXTURE_H_ */
--- /dev/null
+/* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */
+
+/*
+ * Copyright (C) 2012 Rob Clark <robclark@freedesktop.org>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Authors:
+ * Rob Clark <robclark@freedesktop.org>
+ */
+
+#include "pipe/p_defines.h"
+#include "util/u_format.h"
+
+#include "fd2_util.h"
+
+enum a2xx_sq_surfaceformat
+fd2_pipe2surface(enum pipe_format format)
+{
+ switch (format) {
+ /* 8-bit buffers. */
+ case PIPE_FORMAT_A8_UNORM:
+ case PIPE_FORMAT_A8_SNORM:
+ case PIPE_FORMAT_A8_UINT:
+ case PIPE_FORMAT_A8_SINT:
+ case PIPE_FORMAT_I8_UNORM:
+ case PIPE_FORMAT_I8_SNORM:
+ case PIPE_FORMAT_I8_UINT:
+ case PIPE_FORMAT_I8_SINT:
+ case PIPE_FORMAT_L8_UNORM:
+ case PIPE_FORMAT_L8_SNORM:
+ case PIPE_FORMAT_L8_UINT:
+ case PIPE_FORMAT_L8_SINT:
+ case PIPE_FORMAT_L8_SRGB:
+ case PIPE_FORMAT_R8_UNORM:
+ case PIPE_FORMAT_R8_SNORM:
+ case PIPE_FORMAT_R8_UINT:
+ case PIPE_FORMAT_R8_SINT:
+ return FMT_8;
+
+ /* 16-bit buffers. */
+ case PIPE_FORMAT_B5G6R5_UNORM:
+ return FMT_5_6_5;
+ case PIPE_FORMAT_B5G5R5A1_UNORM:
+ case PIPE_FORMAT_B5G5R5X1_UNORM:
+ return FMT_1_5_5_5;
+ case PIPE_FORMAT_B4G4R4A4_UNORM:
+ case PIPE_FORMAT_B4G4R4X4_UNORM:
+ return FMT_4_4_4_4;
+ case PIPE_FORMAT_Z16_UNORM:
+ return FMT_16;
+ case PIPE_FORMAT_L8A8_UNORM:
+ case PIPE_FORMAT_L8A8_SNORM:
+ case PIPE_FORMAT_L8A8_UINT:
+ case PIPE_FORMAT_L8A8_SINT:
+ case PIPE_FORMAT_L8A8_SRGB:
+ case PIPE_FORMAT_R8G8_UNORM:
+ case PIPE_FORMAT_R8G8_SNORM:
+ case PIPE_FORMAT_R8G8_UINT:
+ case PIPE_FORMAT_R8G8_SINT:
+ return FMT_8_8;
+ case PIPE_FORMAT_R16_UNORM:
+ case PIPE_FORMAT_R16_SNORM:
+ case PIPE_FORMAT_R16_UINT:
+ case PIPE_FORMAT_R16_SINT:
+ case PIPE_FORMAT_A16_UNORM:
+ case PIPE_FORMAT_A16_SNORM:
+ case PIPE_FORMAT_A16_UINT:
+ case PIPE_FORMAT_A16_SINT:
+ case PIPE_FORMAT_L16_UNORM:
+ case PIPE_FORMAT_L16_SNORM:
+ case PIPE_FORMAT_L16_UINT:
+ case PIPE_FORMAT_L16_SINT:
+ case PIPE_FORMAT_I16_UNORM:
+ case PIPE_FORMAT_I16_SNORM:
+ case PIPE_FORMAT_I16_UINT:
+ case PIPE_FORMAT_I16_SINT:
+ return FMT_16;
+ case PIPE_FORMAT_R16_FLOAT:
+ case PIPE_FORMAT_A16_FLOAT:
+ case PIPE_FORMAT_L16_FLOAT:
+ case PIPE_FORMAT_I16_FLOAT:
+ return FMT_16_FLOAT;
+
+ /* 32-bit buffers. */
+ case PIPE_FORMAT_A8B8G8R8_SRGB:
+ case PIPE_FORMAT_A8B8G8R8_UNORM:
+ case PIPE_FORMAT_A8R8G8B8_UNORM:
+ case PIPE_FORMAT_B8G8R8A8_SRGB:
+ case PIPE_FORMAT_B8G8R8A8_UNORM:
+ case PIPE_FORMAT_B8G8R8X8_UNORM:
+ case PIPE_FORMAT_R8G8B8A8_SNORM:
+ case PIPE_FORMAT_R8G8B8A8_UNORM:
+ case PIPE_FORMAT_R8G8B8X8_UNORM:
+ case PIPE_FORMAT_R8SG8SB8UX8U_NORM:
+ case PIPE_FORMAT_X8B8G8R8_UNORM:
+ case PIPE_FORMAT_X8R8G8B8_UNORM:
+ case PIPE_FORMAT_R8G8B8_UNORM:
+ case PIPE_FORMAT_R8G8B8A8_SINT:
+ case PIPE_FORMAT_R8G8B8A8_UINT:
+ return FMT_8_8_8_8;
+ case PIPE_FORMAT_R10G10B10A2_UNORM:
+ case PIPE_FORMAT_R10G10B10X2_SNORM:
+ case PIPE_FORMAT_B10G10R10A2_UNORM:
+ case PIPE_FORMAT_B10G10R10A2_UINT:
+ case PIPE_FORMAT_R10SG10SB10SA2U_NORM:
+ return FMT_2_10_10_10;
+ case PIPE_FORMAT_Z24X8_UNORM:
+ case PIPE_FORMAT_Z24_UNORM_S8_UINT:
+ return FMT_24_8;
+ case PIPE_FORMAT_R32_UINT:
+ case PIPE_FORMAT_R32_SINT:
+ case PIPE_FORMAT_A32_UINT:
+ case PIPE_FORMAT_A32_SINT:
+ case PIPE_FORMAT_L32_UINT:
+ case PIPE_FORMAT_L32_SINT:
+ case PIPE_FORMAT_I32_UINT:
+ case PIPE_FORMAT_I32_SINT:
+ return FMT_32;
+ case PIPE_FORMAT_R32_FLOAT:
+ case PIPE_FORMAT_A32_FLOAT:
+ case PIPE_FORMAT_L32_FLOAT:
+ case PIPE_FORMAT_I32_FLOAT:
+ case PIPE_FORMAT_Z32_FLOAT:
+ return FMT_32_FLOAT;
+ case PIPE_FORMAT_R16G16_FLOAT:
+ case PIPE_FORMAT_L16A16_FLOAT:
+ return FMT_16_16_FLOAT;
+ case PIPE_FORMAT_R16G16_UNORM:
+ case PIPE_FORMAT_R16G16_SNORM:
+ case PIPE_FORMAT_R16G16_UINT:
+ case PIPE_FORMAT_R16G16_SINT:
+ case PIPE_FORMAT_L16A16_UNORM:
+ case PIPE_FORMAT_L16A16_SNORM:
+ case PIPE_FORMAT_L16A16_UINT:
+ case PIPE_FORMAT_L16A16_SINT:
+ return FMT_16_16;
+
+ /* 64-bit buffers. */
+ case PIPE_FORMAT_R16G16B16A16_UINT:
+ case PIPE_FORMAT_R16G16B16A16_SINT:
+ case PIPE_FORMAT_R16G16B16A16_UNORM:
+ case PIPE_FORMAT_R16G16B16A16_SNORM:
+ return FMT_16_16_16_16;
+ case PIPE_FORMAT_R16G16B16A16_FLOAT:
+ return FMT_16_16_16_16_FLOAT;
+ case PIPE_FORMAT_R32G32_FLOAT:
+ case PIPE_FORMAT_L32A32_FLOAT:
+ return FMT_32_32_FLOAT;
+ case PIPE_FORMAT_R32G32_SINT:
+ case PIPE_FORMAT_R32G32_UINT:
+ case PIPE_FORMAT_L32A32_UINT:
+ case PIPE_FORMAT_L32A32_SINT:
+ return FMT_32_32;
+
+ /* 96-bit buffers. */
+ case PIPE_FORMAT_R32G32B32_FLOAT:
+ return FMT_32_32_32_FLOAT;
+
+ /* 128-bit buffers. */
+ case PIPE_FORMAT_R32G32B32A32_SNORM:
+ case PIPE_FORMAT_R32G32B32A32_UNORM:
+ case PIPE_FORMAT_R32G32B32A32_SINT:
+ case PIPE_FORMAT_R32G32B32A32_UINT:
+ return FMT_32_32_32_32;
+ case PIPE_FORMAT_R32G32B32A32_FLOAT:
+ return FMT_32_32_32_32_FLOAT;
+
+ /* YUV buffers. */
+ case PIPE_FORMAT_UYVY:
+ return FMT_Cr_Y1_Cb_Y0;
+ case PIPE_FORMAT_YUYV:
+ return FMT_Y1_Cr_Y0_Cb;
+
+ default:
+ return ~0;
+ }
+}
+
+enum a2xx_colorformatx
+fd2_pipe2color(enum pipe_format format)
+{
+ switch (format) {
+ /* 8-bit buffers. */
+ case PIPE_FORMAT_A8_UNORM:
+ case PIPE_FORMAT_A8_SNORM:
+ case PIPE_FORMAT_A8_UINT:
+ case PIPE_FORMAT_A8_SINT:
+ case PIPE_FORMAT_I8_UNORM:
+ case PIPE_FORMAT_I8_SNORM:
+ case PIPE_FORMAT_I8_UINT:
+ case PIPE_FORMAT_I8_SINT:
+ case PIPE_FORMAT_L8_UNORM:
+ case PIPE_FORMAT_L8_SNORM:
+ case PIPE_FORMAT_L8_UINT:
+ case PIPE_FORMAT_L8_SINT:
+ case PIPE_FORMAT_L8_SRGB:
+ case PIPE_FORMAT_R8_UNORM:
+ case PIPE_FORMAT_R8_SNORM:
+ case PIPE_FORMAT_R8_UINT:
+ case PIPE_FORMAT_R8_SINT:
+ return COLORX_8;
+
+ /* 16-bit buffers. */
+ case PIPE_FORMAT_B5G6R5_UNORM:
+ return COLORX_5_6_5;
+ case PIPE_FORMAT_B5G5R5A1_UNORM:
+ case PIPE_FORMAT_B5G5R5X1_UNORM:
+ return COLORX_1_5_5_5;
+ case PIPE_FORMAT_B4G4R4A4_UNORM:
+ case PIPE_FORMAT_B4G4R4X4_UNORM:
+ return COLORX_4_4_4_4;
+ case PIPE_FORMAT_L8A8_UNORM:
+ case PIPE_FORMAT_L8A8_SNORM:
+ case PIPE_FORMAT_L8A8_UINT:
+ case PIPE_FORMAT_L8A8_SINT:
+ case PIPE_FORMAT_L8A8_SRGB:
+ case PIPE_FORMAT_R8G8_UNORM:
+ case PIPE_FORMAT_R8G8_SNORM:
+ case PIPE_FORMAT_R8G8_UINT:
+ case PIPE_FORMAT_R8G8_SINT:
+ case PIPE_FORMAT_Z16_UNORM:
+ return COLORX_8_8;
+ case PIPE_FORMAT_R16_FLOAT:
+ case PIPE_FORMAT_A16_FLOAT:
+ case PIPE_FORMAT_L16_FLOAT:
+ case PIPE_FORMAT_I16_FLOAT:
+ return COLORX_16_FLOAT;
+
+ /* 32-bit buffers. */
+ case PIPE_FORMAT_A8B8G8R8_SRGB:
+ case PIPE_FORMAT_A8B8G8R8_UNORM:
+ case PIPE_FORMAT_A8R8G8B8_UNORM:
+ case PIPE_FORMAT_B8G8R8A8_SRGB:
+ case PIPE_FORMAT_B8G8R8A8_UNORM:
+ case PIPE_FORMAT_B8G8R8X8_UNORM:
+ case PIPE_FORMAT_R8G8B8A8_SNORM:
+ case PIPE_FORMAT_R8G8B8A8_UNORM:
+ case PIPE_FORMAT_R8G8B8X8_UNORM:
+ case PIPE_FORMAT_R8SG8SB8UX8U_NORM:
+ case PIPE_FORMAT_X8B8G8R8_UNORM:
+ case PIPE_FORMAT_X8R8G8B8_UNORM:
+ case PIPE_FORMAT_R8G8B8_UNORM:
+ case PIPE_FORMAT_R8G8B8A8_SINT:
+ case PIPE_FORMAT_R8G8B8A8_UINT:
+ case PIPE_FORMAT_Z24_UNORM_S8_UINT:
+ case PIPE_FORMAT_Z24X8_UNORM:
+ return COLORX_8_8_8_8;
+ case PIPE_FORMAT_R32_FLOAT:
+ case PIPE_FORMAT_A32_FLOAT:
+ case PIPE_FORMAT_L32_FLOAT:
+ case PIPE_FORMAT_I32_FLOAT:
+ case PIPE_FORMAT_Z32_FLOAT:
+ return COLORX_32_FLOAT;
+ case PIPE_FORMAT_R16G16_FLOAT:
+ case PIPE_FORMAT_L16A16_FLOAT:
+ return COLORX_16_16_FLOAT;
+
+ /* 64-bit buffers. */
+ case PIPE_FORMAT_R16G16B16A16_FLOAT:
+ return COLORX_16_16_16_16_FLOAT;
+ case PIPE_FORMAT_R32G32_FLOAT:
+ case PIPE_FORMAT_L32A32_FLOAT:
+ return COLORX_32_32_FLOAT;
+
+ /* 128-bit buffers. */
+ case PIPE_FORMAT_R32G32B32A32_FLOAT:
+ return COLORX_32_32_32_32_FLOAT;
+
+ default:
+ return ~0;
+ }
+}
+
+static inline enum sq_tex_swiz
+tex_swiz(unsigned swiz)
+{
+ switch (swiz) {
+ default:
+ case PIPE_SWIZZLE_RED: return SQ_TEX_X;
+ case PIPE_SWIZZLE_GREEN: return SQ_TEX_Y;
+ case PIPE_SWIZZLE_BLUE: return SQ_TEX_Z;
+ case PIPE_SWIZZLE_ALPHA: return SQ_TEX_W;
+ case PIPE_SWIZZLE_ZERO: return SQ_TEX_ZERO;
+ case PIPE_SWIZZLE_ONE: return SQ_TEX_ONE;
+ }
+}
+
+uint32_t
+fd2_tex_swiz(enum pipe_format format, unsigned swizzle_r, unsigned swizzle_g,
+ unsigned swizzle_b, unsigned swizzle_a)
+{
+ const struct util_format_description *desc =
+ util_format_description(format);
+ uint8_t swiz[] = {
+ swizzle_r, swizzle_g, swizzle_b, swizzle_a,
+ PIPE_SWIZZLE_ZERO, PIPE_SWIZZLE_ONE,
+ PIPE_SWIZZLE_ONE, PIPE_SWIZZLE_ONE,
+ };
+
+ return A2XX_SQ_TEX_3_SWIZ_X(tex_swiz(swiz[desc->swizzle[0]])) |
+ A2XX_SQ_TEX_3_SWIZ_Y(tex_swiz(swiz[desc->swizzle[1]])) |
+ A2XX_SQ_TEX_3_SWIZ_Z(tex_swiz(swiz[desc->swizzle[2]])) |
+ A2XX_SQ_TEX_3_SWIZ_W(tex_swiz(swiz[desc->swizzle[3]]));
+}
--- /dev/null
+/* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */
+
+/*
+ * Copyright (C) 2012-2013 Rob Clark <robclark@freedesktop.org>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Authors:
+ * Rob Clark <robclark@freedesktop.org>
+ */
+
+#ifndef FD2_UTIL_H_
+#define FD2_UTIL_H_
+
+#include "freedreno_util.h"
+
+#include "a2xx.xml.h"
+
+enum a2xx_sq_surfaceformat fd2_pipe2surface(enum pipe_format format);
+enum a2xx_colorformatx fd2_pipe2color(enum pipe_format format);
+uint32_t fd2_tex_swiz(enum pipe_format format, unsigned swizzle_r,
+ unsigned swizzle_g, unsigned swizzle_b, unsigned swizzle_a);
+
+/* convert x,y to dword */
+static inline uint32_t xy2d(uint16_t x, uint16_t y)
+{
+ return ((y & 0x3fff) << 16) | (x & 0x3fff);
+}
+
+#endif /* FD2_UTIL_H_ */
--- /dev/null
+/* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */
+
+/*
+ * Copyright (C) 2012 Rob Clark <robclark@freedesktop.org>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Authors:
+ * Rob Clark <robclark@freedesktop.org>
+ */
+
+
+#include "pipe/p_state.h"
+#include "util/u_string.h"
+#include "util/u_memory.h"
+
+#include "fd2_zsa.h"
+#include "fd2_context.h"
+#include "fd2_util.h"
+
+void *
+fd2_zsa_state_create(struct pipe_context *pctx,
+ const struct pipe_depth_stencil_alpha_state *cso)
+{
+ struct fd2_zsa_stateobj *so;
+
+ so = CALLOC_STRUCT(fd2_zsa_stateobj);
+ if (!so)
+ return NULL;
+
+ so->base = *cso;
+
+ so->rb_depthcontrol |=
+ A2XX_RB_DEPTHCONTROL_ZFUNC(cso->depth.func); /* maps 1:1 */
+
+ if (cso->depth.enabled)
+ so->rb_depthcontrol |= A2XX_RB_DEPTHCONTROL_Z_ENABLE;
+ if (cso->depth.writemask)
+ so->rb_depthcontrol |= A2XX_RB_DEPTHCONTROL_Z_WRITE_ENABLE;
+
+ if (cso->stencil[0].enabled) {
+ const struct pipe_stencil_state *s = &cso->stencil[0];
+
+ so->rb_depthcontrol |=
+ A2XX_RB_DEPTHCONTROL_STENCIL_ENABLE |
+ A2XX_RB_DEPTHCONTROL_STENCILFUNC(s->func) | /* maps 1:1 */
+ A2XX_RB_DEPTHCONTROL_STENCILFAIL(fd_stencil_op(s->fail_op)) |
+ A2XX_RB_DEPTHCONTROL_STENCILZPASS(fd_stencil_op(s->zpass_op)) |
+ A2XX_RB_DEPTHCONTROL_STENCILZFAIL(fd_stencil_op(s->zfail_op));
+ so->rb_stencilrefmask |=
+ 0xff000000 | /* ??? */
+ A2XX_RB_STENCILREFMASK_STENCILWRITEMASK(s->writemask) |
+ A2XX_RB_STENCILREFMASK_STENCILMASK(s->valuemask);
+
+ if (cso->stencil[1].enabled) {
+ const struct pipe_stencil_state *bs = &cso->stencil[1];
+
+ so->rb_depthcontrol |=
+ A2XX_RB_DEPTHCONTROL_BACKFACE_ENABLE |
+ A2XX_RB_DEPTHCONTROL_STENCILFUNC_BF(bs->func) | /* maps 1:1 */
+ A2XX_RB_DEPTHCONTROL_STENCILFAIL_BF(fd_stencil_op(bs->fail_op)) |
+ A2XX_RB_DEPTHCONTROL_STENCILZPASS_BF(fd_stencil_op(bs->zpass_op)) |
+ A2XX_RB_DEPTHCONTROL_STENCILZFAIL_BF(fd_stencil_op(bs->zfail_op));
+ so->rb_stencilrefmask_bf |=
+ 0xff000000 | /* ??? */
+ A2XX_RB_STENCILREFMASK_STENCILWRITEMASK(bs->writemask) |
+ A2XX_RB_STENCILREFMASK_STENCILMASK(bs->valuemask);
+ }
+ }
+
+ if (cso->alpha.enabled) {
+ so->rb_colorcontrol =
+ A2XX_RB_COLORCONTROL_ALPHA_FUNC(cso->alpha.func) |
+ A2XX_RB_COLORCONTROL_ALPHA_TEST_ENABLE;
+ so->rb_alpha_ref = fui(cso->alpha.ref_value);
+ }
+
+ return so;
+}
--- /dev/null
+/* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */
+
+/*
+ * Copyright (C) 2012-2013 Rob Clark <robclark@freedesktop.org>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Authors:
+ * Rob Clark <robclark@freedesktop.org>
+ */
+
+#ifndef FD2_ZSA_H_
+#define FD2_ZSA_H_
+
+
+#include "pipe/p_state.h"
+#include "pipe/p_context.h"
+
+#include "freedreno_util.h"
+
+struct fd2_zsa_stateobj {
+ struct pipe_depth_stencil_alpha_state base;
+ uint32_t rb_depthcontrol;
+ uint32_t rb_colorcontrol; /* must be OR'd w/ blend->rb_colorcontrol */
+ uint32_t rb_alpha_ref;
+ uint32_t rb_stencilrefmask;
+ uint32_t rb_stencilrefmask_bf;
+};
+
+static INLINE struct fd2_zsa_stateobj *
+fd2_zsa_stateobj(struct pipe_depth_stencil_alpha_state *zsa)
+{
+ return (struct fd2_zsa_stateobj *)zsa;
+}
+
+void * fd2_zsa_state_create(struct pipe_context *pctx,
+ const struct pipe_depth_stencil_alpha_state *cso);
+
+#endif /* FD2_ZSA_H_ */
--- /dev/null
+/*
+ * Copyright (c) 2012 Rob Clark <robdclark@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef INSTR_A2XX_H_
+#define INSTR_A2XX_H_
+
+#define PACKED __attribute__((__packed__))
+
+#include "util/u_math.h"
+#include "adreno_common.xml.h"
+#include "a2xx.xml.h"
+
+
+/*
+ * ALU instructions:
+ */
+
+typedef enum {
+ ADDs = 0,
+ ADD_PREVs = 1,
+ MULs = 2,
+ MUL_PREVs = 3,
+ MUL_PREV2s = 4,
+ MAXs = 5,
+ MINs = 6,
+ SETEs = 7,
+ SETGTs = 8,
+ SETGTEs = 9,
+ SETNEs = 10,
+ FRACs = 11,
+ TRUNCs = 12,
+ FLOORs = 13,
+ EXP_IEEE = 14,
+ LOG_CLAMP = 15,
+ LOG_IEEE = 16,
+ RECIP_CLAMP = 17,
+ RECIP_FF = 18,
+ RECIP_IEEE = 19,
+ RECIPSQ_CLAMP = 20,
+ RECIPSQ_FF = 21,
+ RECIPSQ_IEEE = 22,
+ MOVAs = 23,
+ MOVA_FLOORs = 24,
+ SUBs = 25,
+ SUB_PREVs = 26,
+ PRED_SETEs = 27,
+ PRED_SETNEs = 28,
+ PRED_SETGTs = 29,
+ PRED_SETGTEs = 30,
+ PRED_SET_INVs = 31,
+ PRED_SET_POPs = 32,
+ PRED_SET_CLRs = 33,
+ PRED_SET_RESTOREs = 34,
+ KILLEs = 35,
+ KILLGTs = 36,
+ KILLGTEs = 37,
+ KILLNEs = 38,
+ KILLONEs = 39,
+ SQRT_IEEE = 40,
+ MUL_CONST_0 = 42,
+ MUL_CONST_1 = 43,
+ ADD_CONST_0 = 44,
+ ADD_CONST_1 = 45,
+ SUB_CONST_0 = 46,
+ SUB_CONST_1 = 47,
+ SIN = 48,
+ COS = 49,
+ RETAIN_PREV = 50,
+} instr_scalar_opc_t;
+
+typedef enum {
+ ADDv = 0,
+ MULv = 1,
+ MAXv = 2,
+ MINv = 3,
+ SETEv = 4,
+ SETGTv = 5,
+ SETGTEv = 6,
+ SETNEv = 7,
+ FRACv = 8,
+ TRUNCv = 9,
+ FLOORv = 10,
+ MULADDv = 11,
+ CNDEv = 12,
+ CNDGTEv = 13,
+ CNDGTv = 14,
+ DOT4v = 15,
+ DOT3v = 16,
+ DOT2ADDv = 17,
+ CUBEv = 18,
+ MAX4v = 19,
+ PRED_SETE_PUSHv = 20,
+ PRED_SETNE_PUSHv = 21,
+ PRED_SETGT_PUSHv = 22,
+ PRED_SETGTE_PUSHv = 23,
+ KILLEv = 24,
+ KILLGTv = 25,
+ KILLGTEv = 26,
+ KILLNEv = 27,
+ DSTv = 28,
+ MOVAv = 29,
+} instr_vector_opc_t;
+
+typedef struct PACKED {
+ /* dword0: */
+ uint8_t vector_dest : 6;
+ uint8_t vector_dest_rel : 1;
+ uint8_t low_precision_16b_fp : 1;
+ uint8_t scalar_dest : 6;
+ uint8_t scalar_dest_rel : 1;
+ uint8_t export_data : 1;
+ uint8_t vector_write_mask : 4;
+ uint8_t scalar_write_mask : 4;
+ uint8_t vector_clamp : 1;
+ uint8_t scalar_clamp : 1;
+ instr_scalar_opc_t scalar_opc : 6;
+ /* dword1: */
+ uint8_t src3_swiz : 8;
+ uint8_t src2_swiz : 8;
+ uint8_t src1_swiz : 8;
+ uint8_t src3_reg_negate : 1;
+ uint8_t src2_reg_negate : 1;
+ uint8_t src1_reg_negate : 1;
+ uint8_t pred_select : 2;
+ uint8_t relative_addr : 1;
+ uint8_t const_1_rel_abs : 1;
+ uint8_t const_0_rel_abs : 1;
+ /* dword2: */
+ uint8_t src3_reg : 6;
+ uint8_t src3_reg_select : 1;
+ uint8_t src3_reg_abs : 1;
+ uint8_t src2_reg : 6;
+ uint8_t src2_reg_select : 1;
+ uint8_t src2_reg_abs : 1;
+ uint8_t src1_reg : 6;
+ uint8_t src1_reg_select : 1;
+ uint8_t src1_reg_abs : 1;
+ instr_vector_opc_t vector_opc : 5;
+ uint8_t src3_sel : 1;
+ uint8_t src2_sel : 1;
+ uint8_t src1_sel : 1;
+} instr_alu_t;
+
+
+
+/*
+ * CF instructions:
+ */
+
+typedef enum {
+ NOP = 0,
+ EXEC = 1,
+ EXEC_END = 2,
+ COND_EXEC = 3,
+ COND_EXEC_END = 4,
+ COND_PRED_EXEC = 5,
+ COND_PRED_EXEC_END = 6,
+ LOOP_START = 7,
+ LOOP_END = 8,
+ COND_CALL = 9,
+ RETURN = 10,
+ COND_JMP = 11,
+ ALLOC = 12,
+ COND_EXEC_PRED_CLEAN = 13,
+ COND_EXEC_PRED_CLEAN_END = 14,
+ MARK_VS_FETCH_DONE = 15,
+} instr_cf_opc_t;
+
+typedef enum {
+ RELATIVE_ADDR = 0,
+ ABSOLUTE_ADDR = 1,
+} instr_addr_mode_t;
+
+typedef enum {
+ SQ_NO_ALLOC = 0,
+ SQ_POSITION = 1,
+ SQ_PARAMETER_PIXEL = 2,
+ SQ_MEMORY = 3,
+} instr_alloc_type_t;
+
+typedef struct PACKED {
+ uint16_t address : 9;
+ uint8_t reserved0 : 3;
+ uint8_t count : 3;
+ uint8_t yeild : 1;
+ uint16_t serialize : 12;
+ uint8_t vc : 6; /* vertex cache? */
+ uint8_t bool_addr : 8;
+ uint8_t condition : 1;
+ instr_addr_mode_t address_mode : 1;
+ instr_cf_opc_t opc : 4;
+} instr_cf_exec_t;
+
+typedef struct PACKED {
+ uint16_t address : 10;
+ uint8_t reserved0 : 6;
+ uint8_t loop_id : 5;
+ uint32_t reserved1 : 22;
+ instr_addr_mode_t address_mode : 1;
+ instr_cf_opc_t opc : 4;
+} instr_cf_loop_t;
+
+typedef struct PACKED {
+ uint16_t address : 10;
+ uint8_t reserved0 : 3;
+ uint8_t force_call : 1;
+ uint8_t predicated_jmp : 1;
+ uint32_t reserved1 : 18;
+ uint8_t direction : 1;
+ uint8_t bool_addr : 8;
+ uint8_t condition : 1;
+ instr_addr_mode_t address_mode : 1;
+ instr_cf_opc_t opc : 4;
+} instr_cf_jmp_call_t;
+
+typedef struct PACKED {
+ uint8_t size : 4;
+ uint64_t reserved0 : 36;
+ uint8_t no_serial : 1;
+ instr_alloc_type_t buffer_select : 2;
+ uint8_t alloc_mode : 1;
+ instr_cf_opc_t opc : 4;
+} instr_cf_alloc_t;
+
+typedef union PACKED {
+ instr_cf_exec_t exec;
+ instr_cf_loop_t loop;
+ instr_cf_jmp_call_t jmp_call;
+ instr_cf_alloc_t alloc;
+ struct PACKED {
+ uint64_t dummy : 44;
+ instr_cf_opc_t opc : 4;
+ };
+} instr_cf_t;
+
+
+
+/*
+ * FETCH instructions:
+ */
+
+typedef enum {
+ VTX_FETCH = 0,
+ TEX_FETCH = 1,
+ TEX_GET_BORDER_COLOR_FRAC = 16,
+ TEX_GET_COMP_TEX_LOD = 17,
+ TEX_GET_GRADIENTS = 18,
+ TEX_GET_WEIGHTS = 19,
+ TEX_SET_TEX_LOD = 24,
+ TEX_SET_GRADIENTS_H = 25,
+ TEX_SET_GRADIENTS_V = 26,
+ TEX_RESERVED_4 = 27,
+} instr_fetch_opc_t;
+
+typedef enum {
+ TEX_FILTER_POINT = 0,
+ TEX_FILTER_LINEAR = 1,
+ TEX_FILTER_BASEMAP = 2, /* only applicable for mip-filter */
+ TEX_FILTER_USE_FETCH_CONST = 3,
+} instr_tex_filter_t;
+
+typedef enum {
+ ANISO_FILTER_DISABLED = 0,
+ ANISO_FILTER_MAX_1_1 = 1,
+ ANISO_FILTER_MAX_2_1 = 2,
+ ANISO_FILTER_MAX_4_1 = 3,
+ ANISO_FILTER_MAX_8_1 = 4,
+ ANISO_FILTER_MAX_16_1 = 5,
+ ANISO_FILTER_USE_FETCH_CONST = 7,
+} instr_aniso_filter_t;
+
+typedef enum {
+ ARBITRARY_FILTER_2X4_SYM = 0,
+ ARBITRARY_FILTER_2X4_ASYM = 1,
+ ARBITRARY_FILTER_4X2_SYM = 2,
+ ARBITRARY_FILTER_4X2_ASYM = 3,
+ ARBITRARY_FILTER_4X4_SYM = 4,
+ ARBITRARY_FILTER_4X4_ASYM = 5,
+ ARBITRARY_FILTER_USE_FETCH_CONST = 7,
+} instr_arbitrary_filter_t;
+
+typedef enum {
+ SAMPLE_CENTROID = 0,
+ SAMPLE_CENTER = 1,
+} instr_sample_loc_t;
+
+typedef enum a2xx_sq_surfaceformat instr_surf_fmt_t;
+
+typedef struct PACKED {
+ /* dword0: */
+ instr_fetch_opc_t opc : 5;
+ uint8_t src_reg : 6;
+ uint8_t src_reg_am : 1;
+ uint8_t dst_reg : 6;
+ uint8_t dst_reg_am : 1;
+ uint8_t fetch_valid_only : 1;
+ uint8_t const_idx : 5;
+ uint8_t tx_coord_denorm : 1;
+ uint8_t src_swiz : 6;
+ /* dword1: */
+ uint16_t dst_swiz : 12;
+ instr_tex_filter_t mag_filter : 2;
+ instr_tex_filter_t min_filter : 2;
+ instr_tex_filter_t mip_filter : 2;
+ instr_aniso_filter_t aniso_filter : 3;
+ instr_arbitrary_filter_t arbitrary_filter : 3;
+ instr_tex_filter_t vol_mag_filter : 2;
+ instr_tex_filter_t vol_min_filter : 2;
+ uint8_t use_comp_lod : 1;
+ uint8_t use_reg_lod : 2; /* 0 for cube, 1 for 2d */
+ uint8_t pred_select : 1;
+ /* dword2: */
+ uint8_t use_reg_gradients : 1;
+ instr_sample_loc_t sample_location : 1;
+ uint8_t lod_bias : 7;
+ uint8_t unused : 7;
+ uint8_t offset_x : 5;
+ uint8_t offset_y : 5;
+ uint8_t offset_z : 5;
+ uint8_t pred_condition : 1;
+} instr_fetch_tex_t;
+
+typedef struct PACKED {
+ /* dword0: */
+ instr_fetch_opc_t opc : 5;
+ uint8_t src_reg : 6;
+ uint8_t src_reg_am : 1;
+ uint8_t dst_reg : 6;
+ uint8_t dst_reg_am : 1;
+ uint8_t must_be_one : 1;
+ uint8_t const_index : 5;
+ uint8_t const_index_sel : 2;
+ uint8_t reserved0 : 3;
+ uint8_t src_swiz : 2;
+ /* dword1: */
+ uint16_t dst_swiz : 12;
+ uint8_t format_comp_all : 1; /* '1' for signed, '0' for unsigned? */
+ uint8_t num_format_all : 1; /* '0' for normalized, '1' for unnormalized */
+ uint8_t signed_rf_mode_all : 1;
+ uint8_t reserved1 : 1;
+ instr_surf_fmt_t format : 6;
+ uint8_t reserved2 : 1;
+ uint8_t exp_adjust_all : 7;
+ uint8_t reserved3 : 1;
+ uint8_t pred_select : 1;
+ /* dword2: */
+ uint8_t stride : 8;
+ /* possibly offset and reserved4 are swapped on a200? */
+ uint8_t offset : 8;
+ uint8_t reserved4 : 8;
+ uint8_t reserved5 : 7;
+ uint8_t pred_condition : 1;
+} instr_fetch_vtx_t;
+
+typedef union PACKED {
+ instr_fetch_tex_t tex;
+ instr_fetch_vtx_t vtx;
+ struct PACKED {
+ /* dword0: */
+ instr_fetch_opc_t opc : 5;
+ uint32_t dummy0 : 27;
+ /* dword1: */
+ uint32_t dummy1 : 32;
+ /* dword2: */
+ uint32_t dummy2 : 32;
+ };
+} instr_fetch_t;
+
+#endif /* INSTR_H_ */
--- /dev/null
+/*
+ * Copyright (c) 2012 Rob Clark <robdclark@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include "ir-a2xx.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+
+#include "freedreno_util.h"
+#include "instr-a2xx.h"
+
+#define DEBUG_MSG(f, ...) do { if (0) DBG(f, ##__VA_ARGS__); } while (0)
+#define WARN_MSG(f, ...) DBG("WARN: "f, ##__VA_ARGS__)
+#define ERROR_MSG(f, ...) DBG("ERROR: "f, ##__VA_ARGS__)
+
+#define REG_MASK 0x3f
+
+static int cf_emit(struct ir2_cf *cf, instr_cf_t *instr);
+
+static int instr_emit(struct ir2_instruction *instr, uint32_t *dwords,
+ uint32_t idx, struct ir2_shader_info *info);
+
+static void reg_update_stats(struct ir2_register *reg,
+ struct ir2_shader_info *info, bool dest);
+static uint32_t reg_fetch_src_swiz(struct ir2_register *reg, uint32_t n);
+static uint32_t reg_fetch_dst_swiz(struct ir2_register *reg);
+static uint32_t reg_alu_dst_swiz(struct ir2_register *reg);
+static uint32_t reg_alu_src_swiz(struct ir2_register *reg);
+
+/* simple allocator to carve allocations out of an up-front allocated heap,
+ * so that we can free everything easily in one shot.
+ */
+static void * ir2_alloc(struct ir2_shader *shader, int sz)
+{
+ void *ptr = &shader->heap[shader->heap_idx];
+ shader->heap_idx += align(sz, 4);
+ return ptr;
+}
+
+static char * ir2_strdup(struct ir2_shader *shader, const char *str)
+{
+ char *ptr = NULL;
+ if (str) {
+ int len = strlen(str);
+ ptr = ir2_alloc(shader, len+1);
+ memcpy(ptr, str, len);
+ ptr[len] = '\0';
+ }
+ return ptr;
+}
+
+struct ir2_shader * ir2_shader_create(void)
+{
+ DEBUG_MSG("");
+ return calloc(1, sizeof(struct ir2_shader));
+}
+
+void ir2_shader_destroy(struct ir2_shader *shader)
+{
+ DEBUG_MSG("");
+ free(shader);
+}
+
+/* resolve addr/cnt/sequence fields in the individual CF's */
+static int shader_resolve(struct ir2_shader *shader, struct ir2_shader_info *info)
+{
+ uint32_t addr;
+ unsigned i;
+ int j;
+
+ addr = shader->cfs_count / 2;
+ for (i = 0; i < shader->cfs_count; i++) {
+ struct ir2_cf *cf = shader->cfs[i];
+ if ((cf->cf_type == EXEC) || (cf->cf_type == EXEC_END)) {
+ uint32_t sequence = 0;
+
+ if (cf->exec.addr && (cf->exec.addr != addr))
+ WARN_MSG("invalid addr '%d' at CF %d", cf->exec.addr, i);
+ if (cf->exec.cnt && (cf->exec.cnt != cf->exec.instrs_count))
+ WARN_MSG("invalid cnt '%d' at CF %d", cf->exec.cnt, i);
+
+ for (j = cf->exec.instrs_count - 1; j >= 0; j--) {
+ struct ir2_instruction *instr = cf->exec.instrs[j];
+ sequence <<= 2;
+ if (instr->instr_type == IR2_FETCH)
+ sequence |= 0x1;
+ if (instr->sync)
+ sequence |= 0x2;
+ }
+
+ cf->exec.addr = addr;
+ cf->exec.cnt = cf->exec.instrs_count;
+ cf->exec.sequence = sequence;
+
+ addr += cf->exec.instrs_count;
+ }
+ }
+
+ info->sizedwords = 3 * addr;
+
+ return 0;
+}
+
+void * ir2_shader_assemble(struct ir2_shader *shader, struct ir2_shader_info *info)
+{
+ uint32_t i, j;
+ uint32_t *ptr, *dwords = NULL;
+ uint32_t idx = 0;
+ int ret;
+
+ info->sizedwords = 0;
+ info->max_reg = -1;
+ info->max_input_reg = 0;
+ info->regs_written = 0;
+
+ /* we need an even # of CF's.. insert a NOP if needed */
+ if (shader->cfs_count != align(shader->cfs_count, 2))
+ ir2_cf_create(shader, NOP);
+
+ /* first pass, resolve sizes and addresses: */
+ ret = shader_resolve(shader, info);
+ if (ret) {
+ ERROR_MSG("resolve failed: %d", ret);
+ goto fail;
+ }
+
+ ptr = dwords = calloc(1, 4 * info->sizedwords);
+
+ /* second pass, emit CF program in pairs: */
+ for (i = 0; i < shader->cfs_count; i += 2) {
+ instr_cf_t *cfs = (instr_cf_t *)ptr;
+ ret = cf_emit(shader->cfs[i], &cfs[0]);
+ if (ret) {
+ ERROR_MSG("CF emit failed: %d\n", ret);
+ goto fail;
+ }
+ ret = cf_emit(shader->cfs[i+1], &cfs[1]);
+ if (ret) {
+ ERROR_MSG("CF emit failed: %d\n", ret);
+ goto fail;
+ }
+ ptr += 3;
+ assert((ptr - dwords) <= info->sizedwords);
+ }
+
+ /* third pass, emit ALU/FETCH: */
+ for (i = 0; i < shader->cfs_count; i++) {
+ struct ir2_cf *cf = shader->cfs[i];
+ if ((cf->cf_type == EXEC) || (cf->cf_type == EXEC_END)) {
+ for (j = 0; j < cf->exec.instrs_count; j++) {
+ ret = instr_emit(cf->exec.instrs[j], ptr, idx++, info);
+ if (ret) {
+ ERROR_MSG("instruction emit failed: %d", ret);
+ goto fail;
+ }
+ ptr += 3;
+ assert((ptr - dwords) <= info->sizedwords);
+ }
+ }
+ }
+
+ return dwords;
+
+fail:
+ free(dwords);
+ return NULL;
+}
+
+
+struct ir2_cf * ir2_cf_create(struct ir2_shader *shader, instr_cf_opc_t cf_type)
+{
+ struct ir2_cf *cf = ir2_alloc(shader, sizeof(struct ir2_cf));
+ DEBUG_MSG("%d", cf_type);
+ cf->shader = shader;
+ cf->cf_type = cf_type;
+ assert(shader->cfs_count < ARRAY_SIZE(shader->cfs));
+ shader->cfs[shader->cfs_count++] = cf;
+ return cf;
+}
+
+
+/*
+ * CF instructions:
+ */
+
+static int cf_emit(struct ir2_cf *cf, instr_cf_t *instr)
+{
+ memset(instr, 0, sizeof(*instr));
+
+ instr->opc = cf->cf_type;
+
+ switch (cf->cf_type) {
+ case NOP:
+ break;
+ case EXEC:
+ case EXEC_END:
+ assert(cf->exec.addr <= 0x1ff);
+ assert(cf->exec.cnt <= 0x6);
+ assert(cf->exec.sequence <= 0xfff);
+ instr->exec.address = cf->exec.addr;
+ instr->exec.count = cf->exec.cnt;
+ instr->exec.serialize = cf->exec.sequence;
+ break;
+ case ALLOC:
+ assert(cf->alloc.size <= 0xf);
+ instr->alloc.size = cf->alloc.size;
+ switch (cf->alloc.type) {
+ case SQ_POSITION:
+ case SQ_PARAMETER_PIXEL:
+ instr->alloc.buffer_select = cf->alloc.type;
+ break;
+ default:
+ ERROR_MSG("invalid alloc type: %d", cf->alloc.type);
+ return -1;
+ }
+ break;
+ case COND_EXEC:
+ case COND_EXEC_END:
+ case COND_PRED_EXEC:
+ case COND_PRED_EXEC_END:
+ case LOOP_START:
+ case LOOP_END:
+ case COND_CALL:
+ case RETURN:
+ case COND_JMP:
+ case COND_EXEC_PRED_CLEAN:
+ case COND_EXEC_PRED_CLEAN_END:
+ case MARK_VS_FETCH_DONE:
+ ERROR_MSG("TODO");
+ return -1;
+ }
+
+ return 0;
+}
+
+
+struct ir2_instruction * ir2_instr_create(struct ir2_cf *cf, int instr_type)
+{
+ struct ir2_instruction *instr =
+ ir2_alloc(cf->shader, sizeof(struct ir2_instruction));
+ DEBUG_MSG("%d", instr_type);
+ instr->shader = cf->shader;
+ instr->pred = cf->shader->pred;
+ instr->instr_type = instr_type;
+ assert(cf->exec.instrs_count < ARRAY_SIZE(cf->exec.instrs));
+ cf->exec.instrs[cf->exec.instrs_count++] = instr;
+ return instr;
+}
+
+
+/*
+ * FETCH instructions:
+ */
+
+static int instr_emit_fetch(struct ir2_instruction *instr,
+ uint32_t *dwords, uint32_t idx,
+ struct ir2_shader_info *info)
+{
+ instr_fetch_t *fetch = (instr_fetch_t *)dwords;
+ int reg = 0;
+ struct ir2_register *dst_reg = instr->regs[reg++];
+ struct ir2_register *src_reg = instr->regs[reg++];
+
+ memset(fetch, 0, sizeof(*fetch));
+
+ reg_update_stats(dst_reg, info, true);
+ reg_update_stats(src_reg, info, false);
+
+ fetch->opc = instr->fetch.opc;
+
+ if (instr->fetch.opc == VTX_FETCH) {
+ instr_fetch_vtx_t *vtx = &fetch->vtx;
+
+ assert(instr->fetch.stride <= 0xff);
+ assert(instr->fetch.fmt <= 0x3f);
+ assert(instr->fetch.const_idx <= 0x1f);
+ assert(instr->fetch.const_idx_sel <= 0x3);
+
+ vtx->src_reg = src_reg->num;
+ vtx->src_swiz = reg_fetch_src_swiz(src_reg, 1);
+ vtx->dst_reg = dst_reg->num;
+ vtx->dst_swiz = reg_fetch_dst_swiz(dst_reg);
+ vtx->must_be_one = 1;
+ vtx->const_index = instr->fetch.const_idx;
+ vtx->const_index_sel = instr->fetch.const_idx_sel;
+ vtx->format_comp_all = !!instr->fetch.is_signed;
+ vtx->num_format_all = !instr->fetch.is_normalized;
+ vtx->format = instr->fetch.fmt;
+ vtx->stride = instr->fetch.stride;
+ vtx->offset = instr->fetch.offset;
+
+ if (instr->pred != IR2_PRED_NONE) {
+ vtx->pred_select = 1;
+ vtx->pred_condition = (instr->pred == IR2_PRED_EQ) ? 1 : 0;
+ }
+
+ /* XXX seems like every FETCH but the first has
+ * this bit set:
+ */
+ vtx->reserved3 = (idx > 0) ? 0x1 : 0x0;
+ vtx->reserved0 = (idx > 0) ? 0x2 : 0x3;
+ } else if (instr->fetch.opc == TEX_FETCH) {
+ instr_fetch_tex_t *tex = &fetch->tex;
+
+ assert(instr->fetch.const_idx <= 0x1f);
+
+ tex->src_reg = src_reg->num;
+ tex->src_swiz = reg_fetch_src_swiz(src_reg, 3);
+ tex->dst_reg = dst_reg->num;
+ tex->dst_swiz = reg_fetch_dst_swiz(dst_reg);
+ tex->const_idx = instr->fetch.const_idx;
+ tex->mag_filter = TEX_FILTER_USE_FETCH_CONST;
+ tex->min_filter = TEX_FILTER_USE_FETCH_CONST;
+ tex->mip_filter = TEX_FILTER_USE_FETCH_CONST;
+ tex->aniso_filter = ANISO_FILTER_USE_FETCH_CONST;
+ tex->arbitrary_filter = ARBITRARY_FILTER_USE_FETCH_CONST;
+ tex->vol_mag_filter = TEX_FILTER_USE_FETCH_CONST;
+ tex->vol_min_filter = TEX_FILTER_USE_FETCH_CONST;
+ tex->use_comp_lod = 1;
+ tex->use_reg_lod = !instr->fetch.is_cube;
+ tex->sample_location = SAMPLE_CENTER;
+
+ if (instr->pred != IR2_PRED_NONE) {
+ tex->pred_select = 1;
+ tex->pred_condition = (instr->pred == IR2_PRED_EQ) ? 1 : 0;
+ }
+
+ } else {
+ ERROR_MSG("invalid fetch opc: %d\n", instr->fetch.opc);
+ return -1;
+ }
+
+ return 0;
+}
+
+/*
+ * ALU instructions:
+ */
+
+static int instr_emit_alu(struct ir2_instruction *instr, uint32_t *dwords,
+ struct ir2_shader_info *info)
+{
+ int reg = 0;
+ instr_alu_t *alu = (instr_alu_t *)dwords;
+ struct ir2_register *dst_reg = instr->regs[reg++];
+ struct ir2_register *src1_reg;
+ struct ir2_register *src2_reg;
+ struct ir2_register *src3_reg;
+
+ memset(alu, 0, sizeof(*alu));
+
+ /* handle instructions w/ 3 src operands: */
+ switch (instr->alu.vector_opc) {
+ case MULADDv:
+ case CNDEv:
+ case CNDGTEv:
+ case CNDGTv:
+ case DOT2ADDv:
+ /* note: disassembler lists 3rd src first, ie:
+ * MULADDv Rdst = Rsrc3 + (Rsrc1 * Rsrc2)
+ * which is the reason for this strange ordering.
+ */
+ src3_reg = instr->regs[reg++];
+ break;
+ default:
+ src3_reg = NULL;
+ break;
+ }
+
+ src1_reg = instr->regs[reg++];
+ src2_reg = instr->regs[reg++];
+
+ reg_update_stats(dst_reg, info, true);
+ reg_update_stats(src1_reg, info, false);
+ reg_update_stats(src2_reg, info, false);
+
+ assert((dst_reg->flags & ~IR2_REG_EXPORT) == 0);
+ assert(!dst_reg->swizzle || (strlen(dst_reg->swizzle) == 4));
+ assert((src1_reg->flags & IR2_REG_EXPORT) == 0);
+ assert(!src1_reg->swizzle || (strlen(src1_reg->swizzle) == 4));
+ assert((src2_reg->flags & IR2_REG_EXPORT) == 0);
+ assert(!src2_reg->swizzle || (strlen(src2_reg->swizzle) == 4));
+
+ if (instr->alu.vector_opc == ~0) {
+ alu->vector_opc = MAXv;
+ alu->vector_write_mask = 0;
+ } else {
+ alu->vector_opc = instr->alu.vector_opc;
+ alu->vector_write_mask = reg_alu_dst_swiz(dst_reg);
+ }
+
+ alu->vector_dest = dst_reg->num;
+ alu->export_data = !!(dst_reg->flags & IR2_REG_EXPORT);
+
+ // TODO predicate case/condition.. need to add to parser
+
+ alu->src2_reg = src2_reg->num;
+ alu->src2_swiz = reg_alu_src_swiz(src2_reg);
+ alu->src2_reg_negate = !!(src2_reg->flags & IR2_REG_NEGATE);
+ alu->src2_reg_abs = !!(src2_reg->flags & IR2_REG_ABS);
+ alu->src2_sel = !(src2_reg->flags & IR2_REG_CONST);
+
+ alu->src1_reg = src1_reg->num;
+ alu->src1_swiz = reg_alu_src_swiz(src1_reg);
+ alu->src1_reg_negate = !!(src1_reg->flags & IR2_REG_NEGATE);
+ alu->src1_reg_abs = !!(src1_reg->flags & IR2_REG_ABS);
+ alu->src1_sel = !(src1_reg->flags & IR2_REG_CONST);
+
+ alu->vector_clamp = instr->alu.vector_clamp;
+ alu->scalar_clamp = instr->alu.scalar_clamp;
+
+ if (instr->alu.scalar_opc != ~0) {
+ struct ir2_register *sdst_reg = instr->regs[reg++];
+
+ reg_update_stats(sdst_reg, info, true);
+
+ assert(sdst_reg->flags == dst_reg->flags);
+
+ if (src3_reg) {
+ assert(src3_reg == instr->regs[reg++]);
+ } else {
+ src3_reg = instr->regs[reg++];
+ }
+
+ alu->scalar_dest = sdst_reg->num;
+ alu->scalar_write_mask = reg_alu_dst_swiz(sdst_reg);
+ alu->scalar_opc = instr->alu.scalar_opc;
+ } else {
+ /* not sure if this is required, but adreno compiler seems
+ * to always set scalar opc to MAXs if it is not used:
+ */
+ alu->scalar_opc = MAXs;
+ }
+
+ if (src3_reg) {
+ reg_update_stats(src3_reg, info, false);
+
+ alu->src3_reg = src3_reg->num;
+ alu->src3_swiz = reg_alu_src_swiz(src3_reg);
+ alu->src3_reg_negate = !!(src3_reg->flags & IR2_REG_NEGATE);
+ alu->src3_reg_abs = !!(src3_reg->flags & IR2_REG_ABS);
+ alu->src3_sel = !(src3_reg->flags & IR2_REG_CONST);
+ } else {
+ /* not sure if this is required, but adreno compiler seems
+ * to always set register bank for 3rd src if unused:
+ */
+ alu->src3_sel = 1;
+ }
+
+ if (instr->pred != IR2_PRED_NONE) {
+ alu->pred_select = (instr->pred == IR2_PRED_EQ) ? 3 : 2;
+ }
+
+ return 0;
+}
+
+static int instr_emit(struct ir2_instruction *instr, uint32_t *dwords,
+ uint32_t idx, struct ir2_shader_info *info)
+{
+ switch (instr->instr_type) {
+ case IR2_FETCH: return instr_emit_fetch(instr, dwords, idx, info);
+ case IR2_ALU: return instr_emit_alu(instr, dwords, info);
+ }
+ return -1;
+}
+
+
+struct ir2_register * ir2_reg_create(struct ir2_instruction *instr,
+ int num, const char *swizzle, int flags)
+{
+ struct ir2_register *reg =
+ ir2_alloc(instr->shader, sizeof(struct ir2_register));
+ DEBUG_MSG("%x, %d, %s", flags, num, swizzle);
+ assert(num <= REG_MASK);
+ reg->flags = flags;
+ reg->num = num;
+ reg->swizzle = ir2_strdup(instr->shader, swizzle);
+ assert(instr->regs_count < ARRAY_SIZE(instr->regs));
+ instr->regs[instr->regs_count++] = reg;
+ return reg;
+}
+
+static void reg_update_stats(struct ir2_register *reg,
+ struct ir2_shader_info *info, bool dest)
+{
+ if (!(reg->flags & (IR2_REG_CONST|IR2_REG_EXPORT))) {
+ info->max_reg = MAX2(info->max_reg, reg->num);
+
+ if (dest) {
+ info->regs_written |= (1 << reg->num);
+ } else if (!(info->regs_written & (1 << reg->num))) {
+ /* for registers that haven't been written, they must be an
+ * input register that the thread scheduler (presumably?)
+ * needs to know about:
+ */
+ info->max_input_reg = MAX2(info->max_input_reg, reg->num);
+ }
+ }
+}
+
+static uint32_t reg_fetch_src_swiz(struct ir2_register *reg, uint32_t n)
+{
+ uint32_t swiz = 0;
+ int i;
+
+ assert(reg->flags == 0);
+ assert(reg->swizzle);
+
+ DEBUG_MSG("fetch src R%d.%s", reg->num, reg->swizzle);
+
+ for (i = n-1; i >= 0; i--) {
+ swiz <<= 2;
+ switch (reg->swizzle[i]) {
+ default:
+ ERROR_MSG("invalid fetch src swizzle: %s", reg->swizzle);
+ case 'x': swiz |= 0x0; break;
+ case 'y': swiz |= 0x1; break;
+ case 'z': swiz |= 0x2; break;
+ case 'w': swiz |= 0x3; break;
+ }
+ }
+
+ return swiz;
+}
+
+static uint32_t reg_fetch_dst_swiz(struct ir2_register *reg)
+{
+ uint32_t swiz = 0;
+ int i;
+
+ assert(reg->flags == 0);
+ assert(!reg->swizzle || (strlen(reg->swizzle) == 4));
+
+ DEBUG_MSG("fetch dst R%d.%s", reg->num, reg->swizzle);
+
+ if (reg->swizzle) {
+ for (i = 3; i >= 0; i--) {
+ swiz <<= 3;
+ switch (reg->swizzle[i]) {
+ default:
+ ERROR_MSG("invalid dst swizzle: %s", reg->swizzle);
+ case 'x': swiz |= 0x0; break;
+ case 'y': swiz |= 0x1; break;
+ case 'z': swiz |= 0x2; break;
+ case 'w': swiz |= 0x3; break;
+ case '0': swiz |= 0x4; break;
+ case '1': swiz |= 0x5; break;
+ case '_': swiz |= 0x7; break;
+ }
+ }
+ } else {
+ swiz = 0x688;
+ }
+
+ return swiz;
+}
+
+/* actually, a write-mask */
+static uint32_t reg_alu_dst_swiz(struct ir2_register *reg)
+{
+ uint32_t swiz = 0;
+ int i;
+
+ assert((reg->flags & ~IR2_REG_EXPORT) == 0);
+ assert(!reg->swizzle || (strlen(reg->swizzle) == 4));
+
+ DEBUG_MSG("alu dst R%d.%s", reg->num, reg->swizzle);
+
+ if (reg->swizzle) {
+ for (i = 3; i >= 0; i--) {
+ swiz <<= 1;
+ if (reg->swizzle[i] == "xyzw"[i]) {
+ swiz |= 0x1;
+ } else if (reg->swizzle[i] != '_') {
+ ERROR_MSG("invalid dst swizzle: %s", reg->swizzle);
+ break;
+ }
+ }
+ } else {
+ swiz = 0xf;
+ }
+
+ return swiz;
+}
+
+static uint32_t reg_alu_src_swiz(struct ir2_register *reg)
+{
+ uint32_t swiz = 0;
+ int i;
+
+ assert((reg->flags & IR2_REG_EXPORT) == 0);
+ assert(!reg->swizzle || (strlen(reg->swizzle) == 4));
+
+ DEBUG_MSG("vector src R%d.%s", reg->num, reg->swizzle);
+
+ if (reg->swizzle) {
+ for (i = 3; i >= 0; i--) {
+ swiz <<= 2;
+ switch (reg->swizzle[i]) {
+ default:
+ ERROR_MSG("invalid vector src swizzle: %s", reg->swizzle);
+ case 'x': swiz |= (0x0 - i) & 0x3; break;
+ case 'y': swiz |= (0x1 - i) & 0x3; break;
+ case 'z': swiz |= (0x2 - i) & 0x3; break;
+ case 'w': swiz |= (0x3 - i) & 0x3; break;
+ }
+ }
+ } else {
+ swiz = 0x0;
+ }
+
+ return swiz;
+}
--- /dev/null
+/*
+ * Copyright (c) 2012 Rob Clark <robdclark@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef IR2_H_
+#define IR2_H_
+
+#include <stdint.h>
+#include <stdbool.h>
+
+#include "instr-a2xx.h"
+
+/* low level intermediate representation of an adreno a2xx shader program */
+
+struct ir2_shader;
+
+struct ir2_shader_info {
+ uint16_t sizedwords;
+ int8_t max_reg; /* highest GPR # used by shader */
+ uint8_t max_input_reg;
+ uint64_t regs_written;
+};
+
+struct ir2_register {
+ enum {
+ IR2_REG_CONST = 0x1,
+ IR2_REG_EXPORT = 0x2,
+ IR2_REG_NEGATE = 0x4,
+ IR2_REG_ABS = 0x8,
+ } flags;
+ int num;
+ char *swizzle;
+};
+
+enum ir2_pred {
+ IR2_PRED_NONE = 0,
+ IR2_PRED_EQ = 1,
+ IR2_PRED_NE = 2,
+};
+
+struct ir2_instruction {
+ struct ir2_shader *shader;
+ enum {
+ IR2_FETCH,
+ IR2_ALU,
+ } instr_type;
+ enum ir2_pred pred;
+ int sync;
+ unsigned regs_count;
+ struct ir2_register *regs[5];
+ union {
+ /* FETCH specific: */
+ struct {
+ instr_fetch_opc_t opc;
+ unsigned const_idx;
+ /* texture fetch specific: */
+ bool is_cube : 1;
+ /* vertex fetch specific: */
+ unsigned const_idx_sel;
+ enum a2xx_sq_surfaceformat fmt;
+ bool is_signed : 1;
+ bool is_normalized : 1;
+ uint32_t stride;
+ uint32_t offset;
+ } fetch;
+ /* ALU specific: */
+ struct {
+ instr_vector_opc_t vector_opc;
+ instr_scalar_opc_t scalar_opc;
+ bool vector_clamp : 1;
+ bool scalar_clamp : 1;
+ } alu;
+ };
+};
+
+struct ir2_cf {
+ struct ir2_shader *shader;
+ instr_cf_opc_t cf_type;
+
+ union {
+ /* EXEC/EXEC_END specific: */
+ struct {
+ unsigned instrs_count;
+ struct ir2_instruction *instrs[6];
+ uint32_t addr, cnt, sequence;
+ } exec;
+ /* ALLOC specific: */
+ struct {
+ instr_alloc_type_t type; /* SQ_POSITION or SQ_PARAMETER_PIXEL */
+ int size;
+ } alloc;
+ };
+};
+
+struct ir2_shader {
+ unsigned cfs_count;
+ struct ir2_cf *cfs[0x56];
+ uint32_t heap[100 * 4096];
+ unsigned heap_idx;
+
+ enum ir2_pred pred; /* pred inherited by newly created instrs */
+};
+
+struct ir2_shader * ir2_shader_create(void);
+void ir2_shader_destroy(struct ir2_shader *shader);
+void * ir2_shader_assemble(struct ir2_shader *shader,
+ struct ir2_shader_info *info);
+
+struct ir2_cf * ir2_cf_create(struct ir2_shader *shader, instr_cf_opc_t cf_type);
+
+struct ir2_instruction * ir2_instr_create(struct ir2_cf *cf, int instr_type);
+
+struct ir2_register * ir2_reg_create(struct ir2_instruction *instr,
+ int num, const char *swizzle, int flags);
+
+/* some helper fxns: */
+
+static inline struct ir2_cf *
+ir2_cf_create_alloc(struct ir2_shader *shader, instr_alloc_type_t type, int size)
+{
+ struct ir2_cf *cf = ir2_cf_create(shader, ALLOC);
+ if (!cf)
+ return cf;
+ cf->alloc.type = type;
+ cf->alloc.size = size;
+ return cf;
+}
+static inline struct ir2_instruction *
+ir2_instr_create_alu(struct ir2_cf *cf, instr_vector_opc_t vop, instr_scalar_opc_t sop)
+{
+ struct ir2_instruction *instr = ir2_instr_create(cf, IR2_ALU);
+ if (!instr)
+ return instr;
+ instr->alu.vector_opc = vop;
+ instr->alu.scalar_opc = sop;
+ return instr;
+}
+static inline struct ir2_instruction *
+ir2_instr_create_vtx_fetch(struct ir2_cf *cf, int ci, int cis,
+ enum a2xx_sq_surfaceformat fmt, bool is_signed, int stride)
+{
+ struct ir2_instruction *instr = instr = ir2_instr_create(cf, IR2_FETCH);
+ instr->fetch.opc = VTX_FETCH;
+ instr->fetch.const_idx = ci;
+ instr->fetch.const_idx_sel = cis;
+ instr->fetch.fmt = fmt;
+ instr->fetch.is_signed = is_signed;
+ instr->fetch.stride = stride;
+ return instr;
+}
+static inline struct ir2_instruction *
+ir2_instr_create_tex_fetch(struct ir2_cf *cf, int ci)
+{
+ struct ir2_instruction *instr = instr = ir2_instr_create(cf, IR2_FETCH);
+ instr->fetch.opc = TEX_FETCH;
+ instr->fetch.const_idx = ci;
+ return instr;
+}
+
+
+#endif /* IR2_H_ */
git clone git://0x04.net/rules-ng-ng
The rules-ng-ng source files this header was generated from are:
-- /home/robclark/src/freedreno/envytools/rnndb/a3xx.xml ( 35685 bytes, from 2013-04-05 17:33:03)
+- /home/robclark/src/freedreno/envytools/rnndb/a3xx.xml ( 38794 bytes, from 2013-05-05 22:47:28)
- /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1453 bytes, from 2013-03-31 16:51:27)
-- /home/robclark/src/freedreno/envytools/rnndb/adreno_common.xml ( 2972 bytes, from 2013-04-05 17:32:38)
-- /home/robclark/src/freedreno/envytools/rnndb/adreno_pm4.xml ( 7736 bytes, from 2013-04-04 20:24:12)
+- /home/robclark/src/freedreno/envytools/rnndb/adreno_common.xml ( 3094 bytes, from 2013-05-05 18:29:22)
+- /home/robclark/src/freedreno/envytools/rnndb/adreno_pm4.xml ( 9712 bytes, from 2013-05-26 15:22:37)
Copyright (C) 2013 by the following authors:
- Rob Clark <robdclark@gmail.com> (robclark)
DITHER_IF_ALPHA_OFF = 2,
};
+enum adreno_rb_depth_format {
+ DEPTHX_16 = 0,
+ DEPTHX_24_8 = 1,
+};
+
#endif /* ADRENO_COMMON_XML */
git clone git://0x04.net/rules-ng-ng
The rules-ng-ng source files this header was generated from are:
-- /home/robclark/src/freedreno/envytools/rnndb/a3xx.xml ( 35685 bytes, from 2013-04-05 17:33:03)
+- /home/robclark/src/freedreno/envytools/rnndb/a3xx.xml ( 38794 bytes, from 2013-05-05 22:47:28)
- /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1453 bytes, from 2013-03-31 16:51:27)
-- /home/robclark/src/freedreno/envytools/rnndb/adreno_common.xml ( 2972 bytes, from 2013-04-05 17:32:38)
-- /home/robclark/src/freedreno/envytools/rnndb/adreno_pm4.xml ( 7736 bytes, from 2013-04-04 20:24:12)
+- /home/robclark/src/freedreno/envytools/rnndb/adreno_common.xml ( 3094 bytes, from 2013-05-05 18:29:22)
+- /home/robclark/src/freedreno/envytools/rnndb/adreno_pm4.xml ( 9712 bytes, from 2013-05-26 15:22:37)
Copyright (C) 2013 by the following authors:
- Rob Clark <robdclark@gmail.com> (robclark)
CACHE_FLUSH_TS = 4,
CONTEXT_DONE = 5,
CACHE_FLUSH = 6,
+ HLSQ_FLUSH = 7,
VIZQUERY_START = 7,
VIZQUERY_END = 8,
SC_WAIT_WC = 9,
CP_EVENT_WRITE_SHD = 88,
CP_EVENT_WRITE_CFL = 89,
CP_EVENT_WRITE_ZPD = 91,
+ CP_RUN_OPENCL = 49,
CP_DRAW_INDX = 34,
CP_DRAW_INDX_2 = 54,
CP_DRAW_INDX_BIN = 52,
CP_COND_INDIRECT_BUFFER_PFE = 58,
CP_COND_INDIRECT_BUFFER_PFD = 50,
CP_INDIRECT_BUFFER_PFE = 63,
+ CP_SET_BIN = 76,
};
+enum adreno_state_block {
+ SB_VERT_TEX = 0,
+ SB_VERT_MIPADDR = 1,
+ SB_FRAG_TEX = 2,
+ SB_FRAG_MIPADDR = 3,
+ SB_VERT_SHADER = 4,
+ SB_FRAG_SHADER = 6,
+};
+
+enum adreno_state_type {
+ ST_SHADER = 0,
+ ST_CONSTANTS = 1,
+};
+
+enum adreno_state_src {
+ SS_DIRECT = 0,
+ SS_INDIRECT = 4,
+};
+
+#define REG_CP_LOAD_STATE_0 0x00000000
+#define CP_LOAD_STATE_0_DST_OFF__MASK 0x0000ffff
+#define CP_LOAD_STATE_0_DST_OFF__SHIFT 0
+static inline uint32_t CP_LOAD_STATE_0_DST_OFF(uint32_t val)
+{
+ return ((val) << CP_LOAD_STATE_0_DST_OFF__SHIFT) & CP_LOAD_STATE_0_DST_OFF__MASK;
+}
+#define CP_LOAD_STATE_0_STATE_SRC__MASK 0x00070000
+#define CP_LOAD_STATE_0_STATE_SRC__SHIFT 16
+static inline uint32_t CP_LOAD_STATE_0_STATE_SRC(enum adreno_state_src val)
+{
+ return ((val) << CP_LOAD_STATE_0_STATE_SRC__SHIFT) & CP_LOAD_STATE_0_STATE_SRC__MASK;
+}
+#define CP_LOAD_STATE_0_STATE_BLOCK__MASK 0x00380000
+#define CP_LOAD_STATE_0_STATE_BLOCK__SHIFT 19
+static inline uint32_t CP_LOAD_STATE_0_STATE_BLOCK(enum adreno_state_block val)
+{
+ return ((val) << CP_LOAD_STATE_0_STATE_BLOCK__SHIFT) & CP_LOAD_STATE_0_STATE_BLOCK__MASK;
+}
+#define CP_LOAD_STATE_0_NUM_UNIT__MASK 0x7fc00000
+#define CP_LOAD_STATE_0_NUM_UNIT__SHIFT 22
+static inline uint32_t CP_LOAD_STATE_0_NUM_UNIT(uint32_t val)
+{
+ return ((val) << CP_LOAD_STATE_0_NUM_UNIT__SHIFT) & CP_LOAD_STATE_0_NUM_UNIT__MASK;
+}
+
+#define REG_CP_LOAD_STATE_1 0x00000001
+#define CP_LOAD_STATE_1_STATE_TYPE__MASK 0x00000003
+#define CP_LOAD_STATE_1_STATE_TYPE__SHIFT 0
+static inline uint32_t CP_LOAD_STATE_1_STATE_TYPE(enum adreno_state_type val)
+{
+ return ((val) << CP_LOAD_STATE_1_STATE_TYPE__SHIFT) & CP_LOAD_STATE_1_STATE_TYPE__MASK;
+}
+#define CP_LOAD_STATE_1_EXT_SRC_ADDR__MASK 0xfffffffc
+#define CP_LOAD_STATE_1_EXT_SRC_ADDR__SHIFT 2
+static inline uint32_t CP_LOAD_STATE_1_EXT_SRC_ADDR(uint32_t val)
+{
+ return ((val >> 2) << CP_LOAD_STATE_1_EXT_SRC_ADDR__SHIFT) & CP_LOAD_STATE_1_EXT_SRC_ADDR__MASK;
+}
+
+#define REG_CP_SET_BIN_0 0x00000000
+
+#define REG_CP_SET_BIN_1 0x00000001
+#define CP_SET_BIN_1_X1__MASK 0x0000ffff
+#define CP_SET_BIN_1_X1__SHIFT 0
+static inline uint32_t CP_SET_BIN_1_X1(uint32_t val)
+{
+ return ((val) << CP_SET_BIN_1_X1__SHIFT) & CP_SET_BIN_1_X1__MASK;
+}
+#define CP_SET_BIN_1_Y1__MASK 0xffff0000
+#define CP_SET_BIN_1_Y1__SHIFT 16
+static inline uint32_t CP_SET_BIN_1_Y1(uint32_t val)
+{
+ return ((val) << CP_SET_BIN_1_Y1__SHIFT) & CP_SET_BIN_1_Y1__MASK;
+}
+
+#define REG_CP_SET_BIN_2 0x00000002
+#define CP_SET_BIN_2_X2__MASK 0x0000ffff
+#define CP_SET_BIN_2_X2__SHIFT 0
+static inline uint32_t CP_SET_BIN_2_X2(uint32_t val)
+{
+ return ((val) << CP_SET_BIN_2_X2__SHIFT) & CP_SET_BIN_2_X2__MASK;
+}
+#define CP_SET_BIN_2_Y2__MASK 0xffff0000
+#define CP_SET_BIN_2_Y2__SHIFT 16
+static inline uint32_t CP_SET_BIN_2_Y2(uint32_t val)
+{
+ return ((val) << CP_SET_BIN_2_Y2__SHIFT) & CP_SET_BIN_2_Y2__MASK;
+}
+
#endif /* ADRENO_PM4_XML */
+++ /dev/null
-/*
- * Copyright (c) 2012 Rob Clark <robdclark@gmail.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdint.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <string.h>
-
-#include "disasm.h"
-#include "instr-a2xx.h"
-
-static const char *levels[] = {
- "\t",
- "\t\t",
- "\t\t\t",
- "\t\t\t\t",
- "\t\t\t\t\t",
- "\t\t\t\t\t\t",
- "\t\t\t\t\t\t\t",
- "\t\t\t\t\t\t\t\t",
- "\t\t\t\t\t\t\t\t\t",
- "x",
- "x",
- "x",
- "x",
- "x",
- "x",
-};
-
-static enum debug_t debug;
-
-/*
- * ALU instructions:
- */
-
-static const char chan_names[] = {
- 'x', 'y', 'z', 'w',
- /* these only apply to FETCH dst's: */
- '0', '1', '?', '_',
-};
-
-static void print_srcreg(uint32_t num, uint32_t type,
- uint32_t swiz, uint32_t negate, uint32_t abs)
-{
- if (negate)
- printf("-");
- if (abs)
- printf("|");
- printf("%c%u", type ? 'R' : 'C', num);
- if (swiz) {
- int i;
- printf(".");
- for (i = 0; i < 4; i++) {
- printf("%c", chan_names[(swiz + i) & 0x3]);
- swiz >>= 2;
- }
- }
- if (abs)
- printf("|");
-}
-
-static void print_dstreg(uint32_t num, uint32_t mask, uint32_t dst_exp)
-{
- printf("%s%u", dst_exp ? "export" : "R", num);
- if (mask != 0xf) {
- int i;
- printf(".");
- for (i = 0; i < 4; i++) {
- printf("%c", (mask & 0x1) ? chan_names[i] : '_');
- mask >>= 1;
- }
- }
-}
-
-static void print_export_comment(uint32_t num, enum shader_t type)
-{
- const char *name = NULL;
- switch (type) {
- case SHADER_VERTEX:
- switch (num) {
- case 62: name = "gl_Position"; break;
- case 63: name = "gl_PointSize"; break;
- }
- break;
- case SHADER_FRAGMENT:
- switch (num) {
- case 0: name = "gl_FragColor"; break;
- }
- break;
- }
- /* if we had a symbol table here, we could look
- * up the name of the varying..
- */
- if (name) {
- printf("\t; %s", name);
- }
-}
-
-struct {
- uint32_t num_srcs;
- const char *name;
-} vector_instructions[0x20] = {
-#define INSTR(opc, num_srcs) [opc] = { num_srcs, #opc }
- INSTR(ADDv, 2),
- INSTR(MULv, 2),
- INSTR(MAXv, 2),
- INSTR(MINv, 2),
- INSTR(SETEv, 2),
- INSTR(SETGTv, 2),
- INSTR(SETGTEv, 2),
- INSTR(SETNEv, 2),
- INSTR(FRACv, 1),
- INSTR(TRUNCv, 1),
- INSTR(FLOORv, 1),
- INSTR(MULADDv, 3),
- INSTR(CNDEv, 3),
- INSTR(CNDGTEv, 3),
- INSTR(CNDGTv, 3),
- INSTR(DOT4v, 2),
- INSTR(DOT3v, 2),
- INSTR(DOT2ADDv, 3), // ???
- INSTR(CUBEv, 2),
- INSTR(MAX4v, 1),
- INSTR(PRED_SETE_PUSHv, 2),
- INSTR(PRED_SETNE_PUSHv, 2),
- INSTR(PRED_SETGT_PUSHv, 2),
- INSTR(PRED_SETGTE_PUSHv, 2),
- INSTR(KILLEv, 2),
- INSTR(KILLGTv, 2),
- INSTR(KILLGTEv, 2),
- INSTR(KILLNEv, 2),
- INSTR(DSTv, 2),
- INSTR(MOVAv, 1),
-}, scalar_instructions[0x40] = {
- INSTR(ADDs, 1),
- INSTR(ADD_PREVs, 1),
- INSTR(MULs, 1),
- INSTR(MUL_PREVs, 1),
- INSTR(MUL_PREV2s, 1),
- INSTR(MAXs, 1),
- INSTR(MINs, 1),
- INSTR(SETEs, 1),
- INSTR(SETGTs, 1),
- INSTR(SETGTEs, 1),
- INSTR(SETNEs, 1),
- INSTR(FRACs, 1),
- INSTR(TRUNCs, 1),
- INSTR(FLOORs, 1),
- INSTR(EXP_IEEE, 1),
- INSTR(LOG_CLAMP, 1),
- INSTR(LOG_IEEE, 1),
- INSTR(RECIP_CLAMP, 1),
- INSTR(RECIP_FF, 1),
- INSTR(RECIP_IEEE, 1),
- INSTR(RECIPSQ_CLAMP, 1),
- INSTR(RECIPSQ_FF, 1),
- INSTR(RECIPSQ_IEEE, 1),
- INSTR(MOVAs, 1),
- INSTR(MOVA_FLOORs, 1),
- INSTR(SUBs, 1),
- INSTR(SUB_PREVs, 1),
- INSTR(PRED_SETEs, 1),
- INSTR(PRED_SETNEs, 1),
- INSTR(PRED_SETGTs, 1),
- INSTR(PRED_SETGTEs, 1),
- INSTR(PRED_SET_INVs, 1),
- INSTR(PRED_SET_POPs, 1),
- INSTR(PRED_SET_CLRs, 1),
- INSTR(PRED_SET_RESTOREs, 1),
- INSTR(KILLEs, 1),
- INSTR(KILLGTs, 1),
- INSTR(KILLGTEs, 1),
- INSTR(KILLNEs, 1),
- INSTR(KILLONEs, 1),
- INSTR(SQRT_IEEE, 1),
- INSTR(MUL_CONST_0, 1),
- INSTR(MUL_CONST_1, 1),
- INSTR(ADD_CONST_0, 1),
- INSTR(ADD_CONST_1, 1),
- INSTR(SUB_CONST_0, 1),
- INSTR(SUB_CONST_1, 1),
- INSTR(SIN, 1),
- INSTR(COS, 1),
- INSTR(RETAIN_PREV, 1),
-#undef INSTR
-};
-
-static int disasm_alu(uint32_t *dwords, uint32_t alu_off,
- int level, int sync, enum shader_t type)
-{
- instr_alu_t *alu = (instr_alu_t *)dwords;
-
- printf("%s", levels[level]);
- if (debug & PRINT_RAW) {
- printf("%02x: %08x %08x %08x\t", alu_off,
- dwords[0], dwords[1], dwords[2]);
- }
-
- printf(" %sALU:\t", sync ? "(S)" : " ");
-
- printf("%s", vector_instructions[alu->vector_opc].name);
-
- if (alu->pred_select & 0x2) {
- /* seems to work similar to conditional execution in ARM instruction
- * set, so let's use a similar syntax for now:
- */
- printf((alu->pred_select & 0x1) ? "EQ" : "NE");
- }
-
- printf("\t");
-
- print_dstreg(alu->vector_dest, alu->vector_write_mask, alu->export_data);
- printf(" = ");
- if (vector_instructions[alu->vector_opc].num_srcs == 3) {
- print_srcreg(alu->src3_reg, alu->src3_sel, alu->src3_swiz,
- alu->src3_reg_negate, alu->src3_reg_abs);
- printf(", ");
- }
- print_srcreg(alu->src1_reg, alu->src1_sel, alu->src1_swiz,
- alu->src1_reg_negate, alu->src1_reg_abs);
- if (vector_instructions[alu->vector_opc].num_srcs > 1) {
- printf(", ");
- print_srcreg(alu->src2_reg, alu->src2_sel, alu->src2_swiz,
- alu->src2_reg_negate, alu->src2_reg_abs);
- }
-
- if (alu->vector_clamp)
- printf(" CLAMP");
-
- if (alu->export_data)
- print_export_comment(alu->vector_dest, type);
-
- printf("\n");
-
- if (alu->scalar_write_mask || !alu->vector_write_mask) {
- /* 2nd optional scalar op: */
-
- printf("%s", levels[level]);
- if (debug & PRINT_RAW)
- printf(" \t");
-
- if (scalar_instructions[alu->scalar_opc].name) {
- printf("\t \t%s\t", scalar_instructions[alu->scalar_opc].name);
- } else {
- printf("\t \tOP(%u)\t", alu->scalar_opc);
- }
-
- print_dstreg(alu->scalar_dest, alu->scalar_write_mask, alu->export_data);
- printf(" = ");
- print_srcreg(alu->src3_reg, alu->src3_sel, alu->src3_swiz,
- alu->src3_reg_negate, alu->src3_reg_abs);
- // TODO ADD/MUL must have another src?!?
- if (alu->scalar_clamp)
- printf(" CLAMP");
- if (alu->export_data)
- print_export_comment(alu->scalar_dest, type);
- printf("\n");
- }
-
- return 0;
-}
-
-
-/*
- * FETCH instructions:
- */
-
-struct {
- const char *name;
-} fetch_types[0xff] = {
-#define TYPE(id) [id] = { #id }
- TYPE(FMT_1_REVERSE),
- TYPE(FMT_32_FLOAT),
- TYPE(FMT_32_32_FLOAT),
- TYPE(FMT_32_32_32_FLOAT),
- TYPE(FMT_32_32_32_32_FLOAT),
- TYPE(FMT_16),
- TYPE(FMT_16_16),
- TYPE(FMT_16_16_16_16),
- TYPE(FMT_8),
- TYPE(FMT_8_8),
- TYPE(FMT_8_8_8_8),
- TYPE(FMT_32),
- TYPE(FMT_32_32),
- TYPE(FMT_32_32_32_32),
-#undef TYPE
-};
-
-static void print_fetch_dst(uint32_t dst_reg, uint32_t dst_swiz)
-{
- int i;
- printf("\tR%u.", dst_reg);
- for (i = 0; i < 4; i++) {
- printf("%c", chan_names[dst_swiz & 0x7]);
- dst_swiz >>= 3;
- }
-}
-
-static void print_fetch_vtx(instr_fetch_t *fetch)
-{
- instr_fetch_vtx_t *vtx = &fetch->vtx;
-
- if (vtx->pred_select) {
- /* seems to work similar to conditional execution in ARM instruction
- * set, so let's use a similar syntax for now:
- */
- printf(vtx->pred_condition ? "EQ" : "NE");
- }
-
- print_fetch_dst(vtx->dst_reg, vtx->dst_swiz);
- printf(" = R%u.", vtx->src_reg);
- printf("%c", chan_names[vtx->src_swiz & 0x3]);
- if (fetch_types[vtx->format].name) {
- printf(" %s", fetch_types[vtx->format].name);
- } else {
- printf(" TYPE(0x%x)", vtx->format);
- }
- printf(" %s", vtx->format_comp_all ? "SIGNED" : "UNSIGNED");
- if (!vtx->num_format_all)
- printf(" NORMALIZED");
- printf(" STRIDE(%u)", vtx->stride);
- if (vtx->offset)
- printf(" OFFSET(%u)", vtx->offset);
- printf(" CONST(%u, %u)", vtx->const_index, vtx->const_index_sel);
- if (0) {
- // XXX
- printf(" src_reg_am=%u", vtx->src_reg_am);
- printf(" dst_reg_am=%u", vtx->dst_reg_am);
- printf(" num_format_all=%u", vtx->num_format_all);
- printf(" signed_rf_mode_all=%u", vtx->signed_rf_mode_all);
- printf(" exp_adjust_all=%u", vtx->exp_adjust_all);
- }
-}
-
-static void print_fetch_tex(instr_fetch_t *fetch)
-{
- static const char *filter[] = {
- [TEX_FILTER_POINT] = "POINT",
- [TEX_FILTER_LINEAR] = "LINEAR",
- [TEX_FILTER_BASEMAP] = "BASEMAP",
- };
- static const char *aniso_filter[] = {
- [ANISO_FILTER_DISABLED] = "DISABLED",
- [ANISO_FILTER_MAX_1_1] = "MAX_1_1",
- [ANISO_FILTER_MAX_2_1] = "MAX_2_1",
- [ANISO_FILTER_MAX_4_1] = "MAX_4_1",
- [ANISO_FILTER_MAX_8_1] = "MAX_8_1",
- [ANISO_FILTER_MAX_16_1] = "MAX_16_1",
- };
- static const char *arbitrary_filter[] = {
- [ARBITRARY_FILTER_2X4_SYM] = "2x4_SYM",
- [ARBITRARY_FILTER_2X4_ASYM] = "2x4_ASYM",
- [ARBITRARY_FILTER_4X2_SYM] = "4x2_SYM",
- [ARBITRARY_FILTER_4X2_ASYM] = "4x2_ASYM",
- [ARBITRARY_FILTER_4X4_SYM] = "4x4_SYM",
- [ARBITRARY_FILTER_4X4_ASYM] = "4x4_ASYM",
- };
- static const char *sample_loc[] = {
- [SAMPLE_CENTROID] = "CENTROID",
- [SAMPLE_CENTER] = "CENTER",
- };
- instr_fetch_tex_t *tex = &fetch->tex;
- uint32_t src_swiz = tex->src_swiz;
- int i;
-
- if (tex->pred_select) {
- /* seems to work similar to conditional execution in ARM instruction
- * set, so let's use a similar syntax for now:
- */
- printf(tex->pred_condition ? "EQ" : "NE");
- }
-
- print_fetch_dst(tex->dst_reg, tex->dst_swiz);
- printf(" = R%u.", tex->src_reg);
- for (i = 0; i < 3; i++) {
- printf("%c", chan_names[src_swiz & 0x3]);
- src_swiz >>= 2;
- }
- printf(" CONST(%u)", tex->const_idx);
- if (tex->fetch_valid_only)
- printf(" VALID_ONLY");
- if (tex->tx_coord_denorm)
- printf(" DENORM");
- if (tex->mag_filter != TEX_FILTER_USE_FETCH_CONST)
- printf(" MAG(%s)", filter[tex->mag_filter]);
- if (tex->min_filter != TEX_FILTER_USE_FETCH_CONST)
- printf(" MIN(%s)", filter[tex->min_filter]);
- if (tex->mip_filter != TEX_FILTER_USE_FETCH_CONST)
- printf(" MIP(%s)", filter[tex->mip_filter]);
- if (tex->aniso_filter != ANISO_FILTER_USE_FETCH_CONST)
- printf(" ANISO(%s)", aniso_filter[tex->aniso_filter]);
- if (tex->arbitrary_filter != ARBITRARY_FILTER_USE_FETCH_CONST)
- printf(" ARBITRARY(%s)", arbitrary_filter[tex->arbitrary_filter]);
- if (tex->vol_mag_filter != TEX_FILTER_USE_FETCH_CONST)
- printf(" VOL_MAG(%s)", filter[tex->vol_mag_filter]);
- if (tex->vol_min_filter != TEX_FILTER_USE_FETCH_CONST)
- printf(" VOL_MIN(%s)", filter[tex->vol_min_filter]);
- if (!tex->use_comp_lod) {
- printf(" LOD(%u)", tex->use_comp_lod);
- printf(" LOD_BIAS(%u)", tex->lod_bias);
- }
- if (tex->use_reg_gradients)
- printf(" USE_REG_GRADIENTS");
- printf(" LOCATION(%s)", sample_loc[tex->sample_location]);
- if (tex->offset_x || tex->offset_y || tex->offset_z)
- printf(" OFFSET(%u,%u,%u)", tex->offset_x, tex->offset_y, tex->offset_z);
-}
-
-struct {
- const char *name;
- void (*fxn)(instr_fetch_t *cf);
-} fetch_instructions[] = {
-#define INSTR(opc, name, fxn) [opc] = { name, fxn }
- INSTR(VTX_FETCH, "VERTEX", print_fetch_vtx),
- INSTR(TEX_FETCH, "SAMPLE", print_fetch_tex),
- INSTR(TEX_GET_BORDER_COLOR_FRAC, "?", print_fetch_tex),
- INSTR(TEX_GET_COMP_TEX_LOD, "?", print_fetch_tex),
- INSTR(TEX_GET_GRADIENTS, "?", print_fetch_tex),
- INSTR(TEX_GET_WEIGHTS, "?", print_fetch_tex),
- INSTR(TEX_SET_TEX_LOD, "SET_TEX_LOD", print_fetch_tex),
- INSTR(TEX_SET_GRADIENTS_H, "?", print_fetch_tex),
- INSTR(TEX_SET_GRADIENTS_V, "?", print_fetch_tex),
- INSTR(TEX_RESERVED_4, "?", print_fetch_tex),
-#undef INSTR
-};
-
-static int disasm_fetch(uint32_t *dwords, uint32_t alu_off, int level, int sync)
-{
- instr_fetch_t *fetch = (instr_fetch_t *)dwords;
-
- printf("%s", levels[level]);
- if (debug & PRINT_RAW) {
- printf("%02x: %08x %08x %08x\t", alu_off,
- dwords[0], dwords[1], dwords[2]);
- }
-
- printf(" %sFETCH:\t", sync ? "(S)" : " ");
- printf("%s", fetch_instructions[fetch->opc].name);
- fetch_instructions[fetch->opc].fxn(fetch);
- printf("\n");
-
- return 0;
-}
-
-/*
- * CF instructions:
- */
-
-static int cf_exec(instr_cf_t *cf)
-{
- return (cf->opc == EXEC) ||
- (cf->opc == EXEC_END) ||
- (cf->opc == COND_EXEC) ||
- (cf->opc == COND_EXEC_END) ||
- (cf->opc == COND_PRED_EXEC) ||
- (cf->opc == COND_PRED_EXEC_END) ||
- (cf->opc == COND_EXEC_PRED_CLEAN) ||
- (cf->opc == COND_EXEC_PRED_CLEAN_END);
-}
-
-static int cf_cond_exec(instr_cf_t *cf)
-{
- return (cf->opc == COND_EXEC) ||
- (cf->opc == COND_EXEC_END) ||
- (cf->opc == COND_PRED_EXEC) ||
- (cf->opc == COND_PRED_EXEC_END) ||
- (cf->opc == COND_EXEC_PRED_CLEAN) ||
- (cf->opc == COND_EXEC_PRED_CLEAN_END);
-}
-
-static void print_cf_nop(instr_cf_t *cf)
-{
-}
-
-static void print_cf_exec(instr_cf_t *cf)
-{
- printf(" ADDR(0x%x) CNT(0x%x)", cf->exec.address, cf->exec.count);
- if (cf->exec.yeild)
- printf(" YIELD");
- if (cf->exec.vc)
- printf(" VC(0x%x)", cf->exec.vc);
- if (cf->exec.bool_addr)
- printf(" BOOL_ADDR(0x%x)", cf->exec.bool_addr);
- if (cf->exec.address_mode == ABSOLUTE_ADDR)
- printf(" ABSOLUTE_ADDR");
- if (cf_cond_exec(cf))
- printf(" COND(%d)", cf->exec.condition);
-}
-
-static void print_cf_loop(instr_cf_t *cf)
-{
- printf(" ADDR(0x%x) LOOP_ID(%d)", cf->loop.address, cf->loop.loop_id);
- if (cf->loop.address_mode == ABSOLUTE_ADDR)
- printf(" ABSOLUTE_ADDR");
-}
-
-static void print_cf_jmp_call(instr_cf_t *cf)
-{
- printf(" ADDR(0x%x) DIR(%d)", cf->jmp_call.address, cf->jmp_call.direction);
- if (cf->jmp_call.force_call)
- printf(" FORCE_CALL");
- if (cf->jmp_call.predicated_jmp)
- printf(" COND(%d)", cf->jmp_call.condition);
- if (cf->jmp_call.bool_addr)
- printf(" BOOL_ADDR(0x%x)", cf->jmp_call.bool_addr);
- if (cf->jmp_call.address_mode == ABSOLUTE_ADDR)
- printf(" ABSOLUTE_ADDR");
-}
-
-static void print_cf_alloc(instr_cf_t *cf)
-{
- static const char *bufname[] = {
- [SQ_NO_ALLOC] = "NO ALLOC",
- [SQ_POSITION] = "POSITION",
- [SQ_PARAMETER_PIXEL] = "PARAM/PIXEL",
- [SQ_MEMORY] = "MEMORY",
- };
- printf(" %s SIZE(0x%x)", bufname[cf->alloc.buffer_select], cf->alloc.size);
- if (cf->alloc.no_serial)
- printf(" NO_SERIAL");
- if (cf->alloc.alloc_mode) // ???
- printf(" ALLOC_MODE");
-}
-
-struct {
- const char *name;
- void (*fxn)(instr_cf_t *cf);
-} cf_instructions[] = {
-#define INSTR(opc, fxn) [opc] = { #opc, fxn }
- INSTR(NOP, print_cf_nop),
- INSTR(EXEC, print_cf_exec),
- INSTR(EXEC_END, print_cf_exec),
- INSTR(COND_EXEC, print_cf_exec),
- INSTR(COND_EXEC_END, print_cf_exec),
- INSTR(COND_PRED_EXEC, print_cf_exec),
- INSTR(COND_PRED_EXEC_END, print_cf_exec),
- INSTR(LOOP_START, print_cf_loop),
- INSTR(LOOP_END, print_cf_loop),
- INSTR(COND_CALL, print_cf_jmp_call),
- INSTR(RETURN, print_cf_jmp_call),
- INSTR(COND_JMP, print_cf_jmp_call),
- INSTR(ALLOC, print_cf_alloc),
- INSTR(COND_EXEC_PRED_CLEAN, print_cf_exec),
- INSTR(COND_EXEC_PRED_CLEAN_END, print_cf_exec),
- INSTR(MARK_VS_FETCH_DONE, print_cf_nop), // ??
-#undef INSTR
-};
-
-static void print_cf(instr_cf_t *cf, int level)
-{
- printf("%s", levels[level]);
- if (debug & PRINT_RAW) {
- uint16_t *words = (uint16_t *)cf;
- printf(" %04x %04x %04x \t",
- words[0], words[1], words[2]);
- }
- printf("%s", cf_instructions[cf->opc].name);
- cf_instructions[cf->opc].fxn(cf);
- printf("\n");
-}
-
-/*
- * The adreno shader microcode consists of two parts:
- * 1) A CF (control-flow) program, at the header of the compiled shader,
- * which refers to ALU/FETCH instructions that follow it by address.
- * 2) ALU and FETCH instructions
- */
-
-int disasm(uint32_t *dwords, int sizedwords, int level, enum shader_t type)
-{
- instr_cf_t *cfs = (instr_cf_t *)dwords;
- int idx, max_idx;
-
- for (idx = 0; ; idx++) {
- instr_cf_t *cf = &cfs[idx];
- if (cf_exec(cf)) {
- max_idx = 2 * cf->exec.address;
- break;
- }
- }
-
- for (idx = 0; idx < max_idx; idx++) {
- instr_cf_t *cf = &cfs[idx];
-
- print_cf(cf, level);
-
- if (cf_exec(cf)) {
- uint32_t sequence = cf->exec.serialize;
- uint32_t i;
- for (i = 0; i < cf->exec.count; i++) {
- uint32_t alu_off = (cf->exec.address + i);
- if (sequence & 0x1) {
- disasm_fetch(dwords + alu_off * 3, alu_off, level, sequence & 0x2);
- } else {
- disasm_alu(dwords + alu_off * 3, alu_off, level, sequence & 0x2, type);
- }
- sequence >>= 2;
- }
- }
- }
-
- return 0;
-}
-
-void disasm_set_debug(enum debug_t d)
-{
- debug= d;
-}
enum shader_t {
SHADER_VERTEX,
SHADER_FRAGMENT,
+ SHADER_COMPUTE,
};
/* bitmask of debug flags */
enum debug_t {
PRINT_RAW = 0x1, /* dump raw hexdump */
+ PRINT_VERBOSE = 0x2,
};
-int disasm(uint32_t *dwords, int sizedwords, int level, enum shader_t type);
+int disasm_a2xx(uint32_t *dwords, int sizedwords, int level, enum shader_t type);
+int disasm_a3xx(uint32_t *dwords, int sizedwords, int level, enum shader_t type);
void disasm_set_debug(enum debug_t debug);
#endif /* DISASM_H_ */
+++ /dev/null
-/* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */
-
-/*
- * Copyright (C) 2012 Rob Clark <robclark@freedesktop.org>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Authors:
- * Rob Clark <robclark@freedesktop.org>
- */
-
-#include "pipe/p_state.h"
-#include "util/u_string.h"
-#include "util/u_memory.h"
-
-#include "freedreno_blend.h"
-#include "freedreno_context.h"
-#include "freedreno_util.h"
-
-static enum adreno_rb_blend_factor
-blend_factor(unsigned factor)
-{
- switch (factor) {
- case PIPE_BLENDFACTOR_ONE:
- return FACTOR_ONE;
- case PIPE_BLENDFACTOR_SRC_COLOR:
- return FACTOR_SRC_COLOR;
- case PIPE_BLENDFACTOR_SRC_ALPHA:
- return FACTOR_SRC_ALPHA;
- case PIPE_BLENDFACTOR_DST_ALPHA:
- return FACTOR_DST_ALPHA;
- case PIPE_BLENDFACTOR_DST_COLOR:
- return FACTOR_DST_COLOR;
- case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE:
- return FACTOR_SRC_ALPHA_SATURATE;
- case PIPE_BLENDFACTOR_CONST_COLOR:
- return FACTOR_CONSTANT_COLOR;
- case PIPE_BLENDFACTOR_CONST_ALPHA:
- return FACTOR_CONSTANT_ALPHA;
- case PIPE_BLENDFACTOR_ZERO:
- case 0:
- return FACTOR_ZERO;
- case PIPE_BLENDFACTOR_INV_SRC_COLOR:
- return FACTOR_ONE_MINUS_SRC_COLOR;
- case PIPE_BLENDFACTOR_INV_SRC_ALPHA:
- return FACTOR_ONE_MINUS_SRC_ALPHA;
- case PIPE_BLENDFACTOR_INV_DST_ALPHA:
- return FACTOR_ONE_MINUS_DST_ALPHA;
- case PIPE_BLENDFACTOR_INV_DST_COLOR:
- return FACTOR_ONE_MINUS_DST_COLOR;
- case PIPE_BLENDFACTOR_INV_CONST_COLOR:
- return FACTOR_ONE_MINUS_CONSTANT_COLOR;
- case PIPE_BLENDFACTOR_INV_CONST_ALPHA:
- return FACTOR_ONE_MINUS_CONSTANT_ALPHA;
- case PIPE_BLENDFACTOR_INV_SRC1_COLOR:
- case PIPE_BLENDFACTOR_INV_SRC1_ALPHA:
- case PIPE_BLENDFACTOR_SRC1_COLOR:
- case PIPE_BLENDFACTOR_SRC1_ALPHA:
- /* I don't think these are supported */
- default:
- DBG("invalid blend factor: %x", factor);
- return 0;
- }
-}
-
-static enum adreno_rb_blend_opcode
-blend_func(unsigned func)
-{
- switch (func) {
- case PIPE_BLEND_ADD:
- return BLEND_DST_PLUS_SRC;
- case PIPE_BLEND_MIN:
- return BLEND_MIN_DST_SRC;
- case PIPE_BLEND_MAX:
- return BLEND_MAX_DST_SRC;
- case PIPE_BLEND_SUBTRACT:
- return BLEND_SRC_MINUS_DST;
- case PIPE_BLEND_REVERSE_SUBTRACT:
- return BLEND_DST_MINUS_SRC;
- default:
- DBG("invalid blend func: %x", func);
- return 0;
- }
-}
-
-static void *
-fd_blend_state_create(struct pipe_context *pctx,
- const struct pipe_blend_state *cso)
-{
- const struct pipe_rt_blend_state *rt = &cso->rt[0];
- struct fd_blend_stateobj *so;
-
- if (cso->logicop_enable) {
- DBG("Unsupported! logicop");
- return NULL;
- }
-
- if (cso->independent_blend_enable) {
- DBG("Unsupported! independent blend state");
- return NULL;
- }
-
- so = CALLOC_STRUCT(fd_blend_stateobj);
- if (!so)
- return NULL;
-
- so->base = *cso;
-
- so->rb_colorcontrol = A2XX_RB_COLORCONTROL_ROP_CODE(12);
-
- so->rb_blendcontrol =
- A2XX_RB_BLEND_CONTROL_COLOR_SRCBLEND(blend_factor(rt->rgb_src_factor)) |
- A2XX_RB_BLEND_CONTROL_COLOR_COMB_FCN(blend_func(rt->rgb_func)) |
- A2XX_RB_BLEND_CONTROL_COLOR_DESTBLEND(blend_factor(rt->rgb_dst_factor)) |
- A2XX_RB_BLEND_CONTROL_ALPHA_SRCBLEND(blend_factor(rt->alpha_src_factor)) |
- A2XX_RB_BLEND_CONTROL_ALPHA_COMB_FCN(blend_func(rt->alpha_func)) |
- A2XX_RB_BLEND_CONTROL_ALPHA_DESTBLEND(blend_factor(rt->alpha_dst_factor));
-
- if (rt->colormask & PIPE_MASK_R)
- so->rb_colormask |= A2XX_RB_COLOR_MASK_WRITE_RED;
- if (rt->colormask & PIPE_MASK_G)
- so->rb_colormask |= A2XX_RB_COLOR_MASK_WRITE_GREEN;
- if (rt->colormask & PIPE_MASK_B)
- so->rb_colormask |= A2XX_RB_COLOR_MASK_WRITE_BLUE;
- if (rt->colormask & PIPE_MASK_A)
- so->rb_colormask |= A2XX_RB_COLOR_MASK_WRITE_ALPHA;
-
- if (!rt->blend_enable)
- so->rb_colorcontrol |= A2XX_RB_COLORCONTROL_BLEND_DISABLE;
-
- if (cso->dither)
- so->rb_colorcontrol |= A2XX_RB_COLORCONTROL_DITHER_MODE(DITHER_ALWAYS);
-
- return so;
-}
-
-static void
-fd_blend_state_bind(struct pipe_context *pctx, void *hwcso)
-{
- struct fd_context *ctx = fd_context(pctx);
- ctx->blend = hwcso;
- ctx->dirty |= FD_DIRTY_BLEND;
-}
-
-static void
-fd_blend_state_delete(struct pipe_context *pctx, void *hwcso)
-{
- FREE(hwcso);
-}
-
-void
-fd_blend_init(struct pipe_context *pctx)
-{
- pctx->create_blend_state = fd_blend_state_create;
- pctx->bind_blend_state = fd_blend_state_bind;
- pctx->delete_blend_state = fd_blend_state_delete;
-}
-
+++ /dev/null
-/* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */
-
-/*
- * Copyright (C) 2012 Rob Clark <robclark@freedesktop.org>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Authors:
- * Rob Clark <robclark@freedesktop.org>
- */
-
-#ifndef FREEDRENO_BLEND_H_
-#define FREEDRENO_BLEND_H_
-
-#include "pipe/p_state.h"
-#include "pipe/p_context.h"
-
-struct fd_blend_stateobj {
- struct pipe_blend_state base;
- uint32_t rb_blendcontrol;
- uint32_t rb_colorcontrol; /* must be OR'd w/ zsa->rb_colorcontrol */
- uint32_t rb_colormask;
-};
-
-void fd_blend_init(struct pipe_context *pctx);
-
-#endif /* FREEDRENO_BLEND_H_ */
+++ /dev/null
-/* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */
-
-/*
- * Copyright (C) 2012 Rob Clark <robclark@freedesktop.org>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Authors:
- * Rob Clark <robclark@freedesktop.org>
- */
-
-#include "pipe/p_state.h"
-#include "util/u_string.h"
-#include "util/u_memory.h"
-#include "util/u_inlines.h"
-#include "util/u_pack_color.h"
-
-#include "freedreno_clear.h"
-#include "freedreno_context.h"
-#include "freedreno_resource.h"
-#include "freedreno_state.h"
-#include "freedreno_program.h"
-#include "freedreno_zsa.h"
-#include "freedreno_util.h"
-
-static uint32_t
-pack_rgba(enum pipe_format format, const float *rgba)
-{
- union util_color uc;
- util_pack_color(rgba, format, &uc);
- return uc.ui;
-}
-
-static void
-fd_clear(struct pipe_context *pctx, unsigned buffers,
- const union pipe_color_union *color, double depth, unsigned stencil)
-{
- struct fd_context *ctx = fd_context(pctx);
- struct fd_ringbuffer *ring = ctx->ring;
- struct pipe_framebuffer_state *fb = &ctx->framebuffer;
- uint32_t reg, colr = 0;
-
- ctx->cleared |= buffers;
- ctx->resolve |= buffers;
- ctx->needs_flush = true;
-
- if (buffers & PIPE_CLEAR_COLOR)
- fd_resource(fb->cbufs[0]->texture)->dirty = true;
-
- if (buffers & (PIPE_CLEAR_DEPTH | PIPE_CLEAR_STENCIL))
- fd_resource(fb->zsbuf->texture)->dirty = true;
-
- DBG("%x depth=%f, stencil=%u (%s/%s)", buffers, depth, stencil,
- util_format_name(fb->cbufs[0]->format),
- fb->zsbuf ? util_format_name(fb->zsbuf->format) : "none");
-
- if ((buffers & PIPE_CLEAR_COLOR) && fb->nr_cbufs)
- colr = pack_rgba(fb->cbufs[0]->format, color->f);
-
- /* emit generic state now: */
- fd_state_emit(pctx, ctx->dirty &
- (FD_DIRTY_BLEND | FD_DIRTY_VIEWPORT |
- FD_DIRTY_FRAMEBUFFER | FD_DIRTY_SCISSOR));
-
- fd_emit_vertex_bufs(ring, 0x9c, (struct fd_vertex_buf[]) {
- { .prsc = ctx->solid_vertexbuf, .size = 48 },
- }, 1);
-
- OUT_PKT3(ring, CP_SET_CONSTANT, 2);
- OUT_RING(ring, CP_REG(REG_A2XX_VGT_INDX_OFFSET));
- OUT_RING(ring, 0);
-
- OUT_PKT3(ring, CP_SET_CONSTANT, 2);
- OUT_RING(ring, CP_REG(REG_A2XX_VGT_VERTEX_REUSE_BLOCK_CNTL));
- OUT_RING(ring, 0x0000028f);
-
- fd_program_emit(ring, &ctx->solid_prog);
-
- OUT_PKT0(ring, REG_A2XX_TC_CNTL_STATUS, 1);
- OUT_RING(ring, A2XX_TC_CNTL_STATUS_L2_INVALIDATE);
-
- OUT_PKT3(ring, CP_SET_CONSTANT, 2);
- OUT_RING(ring, CP_REG(REG_A2XX_CLEAR_COLOR));
- OUT_RING(ring, colr);
-
- OUT_PKT3(ring, CP_SET_CONSTANT, 2);
- OUT_RING(ring, CP_REG(REG_A2XX_A220_RB_LRZ_VSC_CONTROL));
- OUT_RING(ring, 0x00000084);
-
- OUT_PKT3(ring, CP_SET_CONSTANT, 2);
- OUT_RING(ring, CP_REG(REG_A2XX_RB_COPY_CONTROL));
- reg = 0;
- if (buffers & (PIPE_CLEAR_DEPTH | PIPE_CLEAR_STENCIL)) {
- reg |= A2XX_RB_COPY_CONTROL_DEPTH_CLEAR_ENABLE;
- switch (fd_pipe2depth(fb->zsbuf->format)) {
- case DEPTHX_24_8:
- if (buffers & PIPE_CLEAR_DEPTH)
- reg |= A2XX_RB_COPY_CONTROL_CLEAR_MASK(0xe);
- if (buffers & PIPE_CLEAR_STENCIL)
- reg |= A2XX_RB_COPY_CONTROL_CLEAR_MASK(0x1);
- break;
- case DEPTHX_16:
- if (buffers & PIPE_CLEAR_DEPTH)
- reg |= A2XX_RB_COPY_CONTROL_CLEAR_MASK(0xf);
- break;
- default:
- assert(1);
- break;
- }
- }
- OUT_RING(ring, reg);
-
- OUT_PKT3(ring, CP_SET_CONSTANT, 2);
- OUT_RING(ring, CP_REG(REG_A2XX_RB_DEPTH_CLEAR));
- reg = 0;
- if (buffers & (PIPE_CLEAR_DEPTH | PIPE_CLEAR_STENCIL)) {
- switch (fd_pipe2depth(fb->zsbuf->format)) {
- case DEPTHX_24_8:
- reg = (((uint32_t)(0xffffff * depth)) << 8) |
- (stencil & 0xff);
- break;
- case DEPTHX_16:
- reg = (uint32_t)(0xffffffff * depth);
- break;
- }
- }
- OUT_RING(ring, reg);
-
- OUT_PKT3(ring, CP_SET_CONSTANT, 2);
- OUT_RING(ring, CP_REG(REG_A2XX_RB_DEPTHCONTROL));
- reg = 0;
- if (buffers & PIPE_CLEAR_DEPTH) {
- reg |= A2XX_RB_DEPTHCONTROL_ZFUNC(FUNC_ALWAYS) |
- A2XX_RB_DEPTHCONTROL_Z_ENABLE |
- A2XX_RB_DEPTHCONTROL_Z_WRITE_ENABLE |
- A2XX_RB_DEPTHCONTROL_EARLY_Z_ENABLE;
- }
- if (buffers & PIPE_CLEAR_STENCIL) {
- reg |= A2XX_RB_DEPTHCONTROL_STENCILFUNC(FUNC_ALWAYS) |
- A2XX_RB_DEPTHCONTROL_STENCIL_ENABLE |
- A2XX_RB_DEPTHCONTROL_STENCILZPASS(STENCIL_REPLACE);
- }
- OUT_RING(ring, reg);
-
- OUT_PKT3(ring, CP_SET_CONSTANT, 3);
- OUT_RING(ring, CP_REG(REG_A2XX_RB_STENCILREFMASK_BF));
- OUT_RING(ring, 0xff000000 | A2XX_RB_STENCILREFMASK_BF_STENCILWRITEMASK(0xff));
- OUT_RING(ring, 0xff000000 | A2XX_RB_STENCILREFMASK_STENCILWRITEMASK(0xff));
-
- OUT_PKT3(ring, CP_SET_CONSTANT, 2);
- OUT_RING(ring, CP_REG(REG_A2XX_RB_COLORCONTROL));
- OUT_RING(ring, A2XX_RB_COLORCONTROL_ALPHA_FUNC(FUNC_ALWAYS) |
- A2XX_RB_COLORCONTROL_BLEND_DISABLE |
- A2XX_RB_COLORCONTROL_ROP_CODE(12) |
- A2XX_RB_COLORCONTROL_DITHER_MODE(DITHER_DISABLE) |
- A2XX_RB_COLORCONTROL_DITHER_TYPE(DITHER_PIXEL));
-
- OUT_PKT3(ring, CP_SET_CONSTANT, 3);
- OUT_RING(ring, CP_REG(REG_A2XX_PA_CL_CLIP_CNTL));
- OUT_RING(ring, 0x00000000); /* PA_CL_CLIP_CNTL */
- OUT_RING(ring, A2XX_PA_SU_SC_MODE_CNTL_PROVOKING_VTX_LAST | /* PA_SU_SC_MODE_CNTL */
- A2XX_PA_SU_SC_MODE_CNTL_FRONT_PTYPE(PC_DRAW_TRIANGLES) |
- A2XX_PA_SU_SC_MODE_CNTL_BACK_PTYPE(PC_DRAW_TRIANGLES));
-
- OUT_PKT3(ring, CP_SET_CONSTANT, 2);
- OUT_RING(ring, CP_REG(REG_A2XX_PA_SC_AA_MASK));
- OUT_RING(ring, 0x0000ffff);
-
- OUT_PKT3(ring, CP_SET_CONSTANT, 3);
- OUT_RING(ring, CP_REG(REG_A2XX_PA_SC_WINDOW_SCISSOR_TL));
- OUT_RING(ring, xy2d(0,0)); /* PA_SC_WINDOW_SCISSOR_TL */
- OUT_RING(ring, xy2d(fb->width, /* PA_SC_WINDOW_SCISSOR_BR */
- fb->height));
-
- OUT_PKT3(ring, CP_SET_CONSTANT, 2);
- OUT_RING(ring, CP_REG(REG_A2XX_RB_COLOR_MASK));
- if (buffers & PIPE_CLEAR_COLOR) {
- OUT_RING(ring, A2XX_RB_COLOR_MASK_WRITE_RED |
- A2XX_RB_COLOR_MASK_WRITE_GREEN |
- A2XX_RB_COLOR_MASK_WRITE_BLUE |
- A2XX_RB_COLOR_MASK_WRITE_ALPHA);
- } else {
- OUT_RING(ring, 0x0);
- }
-
- OUT_PKT3(ring, CP_DRAW_INDX, 3);
- OUT_RING(ring, 0x00000000);
- OUT_RING(ring, DRAW(DI_PT_RECTLIST, DI_SRC_SEL_AUTO_INDEX,
- INDEX_SIZE_IGN, IGNORE_VISIBILITY));
- OUT_RING(ring, 3); /* NumIndices */
-
- OUT_PKT3(ring, CP_SET_CONSTANT, 2);
- OUT_RING(ring, CP_REG(REG_A2XX_A220_RB_LRZ_VSC_CONTROL));
- OUT_RING(ring, 0x00000000);
-
- OUT_PKT3(ring, CP_SET_CONSTANT, 2);
- OUT_RING(ring, CP_REG(REG_A2XX_RB_COPY_CONTROL));
- OUT_RING(ring, 0x00000000);
-
- ctx->dirty |= FD_DIRTY_ZSA |
- FD_DIRTY_RASTERIZER |
- FD_DIRTY_SAMPLE_MASK |
- FD_DIRTY_PROG |
- FD_DIRTY_CONSTBUF |
- FD_DIRTY_BLEND;
-
- if (fd_mesa_debug & FD_DBG_DCLEAR)
- ctx->dirty = 0xffffffff;
-}
-
-static void
-fd_clear_render_target(struct pipe_context *pctx, struct pipe_surface *ps,
- const union pipe_color_union *color,
- unsigned x, unsigned y, unsigned w, unsigned h)
-{
- DBG("TODO: x=%u, y=%u, w=%u, h=%u", x, y, w, h);
-}
-
-static void
-fd_clear_depth_stencil(struct pipe_context *pctx, struct pipe_surface *ps,
- unsigned buffers, double depth, unsigned stencil,
- unsigned x, unsigned y, unsigned w, unsigned h)
-{
- DBG("TODO: buffers=%u, depth=%f, stencil=%u, x=%u, y=%u, w=%u, h=%u",
- buffers, depth, stencil, x, y, w, h);
-}
-
-void
-fd_clear_init(struct pipe_context *pctx)
-{
- pctx->clear = fd_clear;
- pctx->clear_render_target = fd_clear_render_target;
- pctx->clear_depth_stencil = fd_clear_depth_stencil;
-}
+++ /dev/null
-/* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */
-
-/*
- * Copyright (C) 2012 Rob Clark <robclark@freedesktop.org>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Authors:
- * Rob Clark <robclark@freedesktop.org>
- */
-
-#ifndef FREEDRENO_CLEAR_H_
-#define FREEDRENO_CLEAR_H_
-
-#include "pipe/p_context.h"
-
-void fd_clear_init(struct pipe_context *pctx);
-
-
-#endif /* FREEDRENO_CLEAR_H_ */
+++ /dev/null
-/* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */
-
-/*
- * Copyright (C) 2012 Rob Clark <robclark@freedesktop.org>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Authors:
- * Rob Clark <robclark@freedesktop.org>
- */
-
-#include "pipe/p_state.h"
-#include "util/u_string.h"
-#include "util/u_memory.h"
-#include "util/u_inlines.h"
-#include "tgsi/tgsi_parse.h"
-#include "tgsi/tgsi_ureg.h"
-#include "tgsi/tgsi_info.h"
-#include "tgsi/tgsi_strings.h"
-#include "tgsi/tgsi_dump.h"
-
-#include "freedreno_program.h"
-#include "freedreno_compiler.h"
-#include "freedreno_util.h"
-
-#include "instr-a2xx.h"
-#include "ir-a2xx.h"
-
-struct fd_compile_context {
- struct fd_program_stateobj *prog;
- struct fd_shader_stateobj *so;
-
- struct tgsi_parse_context parser;
- unsigned type;
-
- /* predicate stack: */
- int pred_depth;
- enum ir2_pred pred_stack[8];
-
- /* Internal-Temporary and Predicate register assignment:
- *
- * Some TGSI instructions which translate into multiple actual
- * instructions need one or more temporary registers, which are not
- * assigned from TGSI perspective (ie. not TGSI_FILE_TEMPORARY).
- * And some instructions (texture fetch) cannot write directly to
- * output registers. We could be more clever and re-use dst or a
- * src register in some cases. But for now don't try to be clever.
- * Eventually we should implement an optimization pass that re-
- * juggles the register usage and gets rid of unneeded temporaries.
- *
- * The predicate register must be valid across multiple TGSI
- * instructions, but internal temporary's do not. For this reason,
- * once the predicate register is requested, until it is no longer
- * needed, it gets the first register slot after after the TGSI
- * assigned temporaries (ie. num_regs[TGSI_FILE_TEMPORARY]), and the
- * internal temporaries get the register slots above this.
- */
-
- int pred_reg;
- int num_internal_temps;
-
- uint8_t num_regs[TGSI_FILE_COUNT];
-
- /* maps input register idx to prog->export_linkage idx: */
- uint8_t input_export_idx[64];
-
- /* maps output register idx to prog->export_linkage idx: */
- uint8_t output_export_idx[64];
-
- /* idx/slot for last compiler generated immediate */
- unsigned immediate_idx;
-
- // TODO we can skip emit exports in the VS that the FS doesn't need..
- // and get rid perhaps of num_param..
- unsigned num_position, num_param;
- unsigned position, psize;
-
- uint64_t need_sync;
-
- /* current exec CF instruction */
- struct ir2_cf *cf;
-};
-
-static int
-semantic_idx(struct tgsi_declaration_semantic *semantic)
-{
- int idx = semantic->Name;
- if (idx == TGSI_SEMANTIC_GENERIC)
- idx = TGSI_SEMANTIC_COUNT + semantic->Index;
- return idx;
-}
-
-/* assign/get the input/export register # for given semantic idx as
- * returned by semantic_idx():
- */
-static int
-export_linkage(struct fd_compile_context *ctx, int idx)
-{
- struct fd_program_stateobj *prog = ctx->prog;
-
- /* if first time we've seen this export, assign the next available slot: */
- if (prog->export_linkage[idx] == 0xff)
- prog->export_linkage[idx] = prog->num_exports++;
-
- return prog->export_linkage[idx];
-}
-
-static unsigned
-compile_init(struct fd_compile_context *ctx, struct fd_program_stateobj *prog,
- struct fd_shader_stateobj *so)
-{
- unsigned ret;
-
- ctx->prog = prog;
- ctx->so = so;
- ctx->cf = NULL;
- ctx->pred_depth = 0;
-
- ret = tgsi_parse_init(&ctx->parser, so->tokens);
- if (ret != TGSI_PARSE_OK)
- return ret;
-
- ctx->type = ctx->parser.FullHeader.Processor.Processor;
- ctx->position = ~0;
- ctx->psize = ~0;
- ctx->num_position = 0;
- ctx->num_param = 0;
- ctx->need_sync = 0;
- ctx->immediate_idx = 0;
- ctx->pred_reg = -1;
- ctx->num_internal_temps = 0;
-
- memset(ctx->num_regs, 0, sizeof(ctx->num_regs));
- memset(ctx->input_export_idx, 0, sizeof(ctx->input_export_idx));
- memset(ctx->output_export_idx, 0, sizeof(ctx->output_export_idx));
-
- /* do first pass to extract declarations: */
- while (!tgsi_parse_end_of_tokens(&ctx->parser)) {
- tgsi_parse_token(&ctx->parser);
-
- switch (ctx->parser.FullToken.Token.Type) {
- case TGSI_TOKEN_TYPE_DECLARATION: {
- struct tgsi_full_declaration *decl =
- &ctx->parser.FullToken.FullDeclaration;
- if (decl->Declaration.File == TGSI_FILE_OUTPUT) {
- unsigned name = decl->Semantic.Name;
-
- assert(decl->Declaration.Semantic); // TODO is this ever not true?
-
- ctx->output_export_idx[decl->Range.First] =
- semantic_idx(&decl->Semantic);
-
- if (ctx->type == TGSI_PROCESSOR_VERTEX) {
- switch (name) {
- case TGSI_SEMANTIC_POSITION:
- ctx->position = ctx->num_regs[TGSI_FILE_OUTPUT];
- ctx->num_position++;
- break;
- case TGSI_SEMANTIC_PSIZE:
- ctx->psize = ctx->num_regs[TGSI_FILE_OUTPUT];
- ctx->num_position++;
- case TGSI_SEMANTIC_COLOR:
- case TGSI_SEMANTIC_GENERIC:
- ctx->num_param++;
- break;
- default:
- DBG("unknown VS semantic name: %s",
- tgsi_semantic_names[name]);
- assert(0);
- }
- } else {
- switch (name) {
- case TGSI_SEMANTIC_COLOR:
- case TGSI_SEMANTIC_GENERIC:
- ctx->num_param++;
- break;
- default:
- DBG("unknown PS semantic name: %s",
- tgsi_semantic_names[name]);
- assert(0);
- }
- }
- } else if (decl->Declaration.File == TGSI_FILE_INPUT) {
- ctx->input_export_idx[decl->Range.First] =
- semantic_idx(&decl->Semantic);
- }
- ctx->num_regs[decl->Declaration.File] =
- MAX2(ctx->num_regs[decl->Declaration.File], decl->Range.Last + 1);
- break;
- }
- case TGSI_TOKEN_TYPE_IMMEDIATE: {
- struct tgsi_full_immediate *imm =
- &ctx->parser.FullToken.FullImmediate;
- unsigned n = ctx->so->num_immediates++;
- memcpy(ctx->so->immediates[n].val, imm->u, 16);
- break;
- }
- default:
- break;
- }
- }
-
- /* TGSI generated immediates are always entire vec4's, ones we
- * generate internally are not:
- */
- ctx->immediate_idx = ctx->so->num_immediates * 4;
-
- ctx->so->first_immediate = ctx->num_regs[TGSI_FILE_CONSTANT];
-
- tgsi_parse_free(&ctx->parser);
-
- return tgsi_parse_init(&ctx->parser, so->tokens);
-}
-
-static void
-compile_free(struct fd_compile_context *ctx)
-{
- tgsi_parse_free(&ctx->parser);
-}
-
-static struct ir2_cf *
-next_exec_cf(struct fd_compile_context *ctx)
-{
- struct ir2_cf *cf = ctx->cf;
- if (!cf || cf->exec.instrs_count >= ARRAY_SIZE(ctx->cf->exec.instrs))
- ctx->cf = cf = ir2_cf_create(ctx->so->ir, EXEC);
- return cf;
-}
-
-static void
-compile_vtx_fetch(struct fd_compile_context *ctx)
-{
- struct ir2_instruction **vfetch_instrs = ctx->so->vfetch_instrs;
- int i;
- for (i = 0; i < ctx->num_regs[TGSI_FILE_INPUT]; i++) {
- struct ir2_instruction *instr = ir2_instr_create(
- next_exec_cf(ctx), IR2_FETCH);
- instr->fetch.opc = VTX_FETCH;
-
- ctx->need_sync |= 1 << (i+1);
-
- ir2_reg_create(instr, i+1, "xyzw", 0);
- ir2_reg_create(instr, 0, "x", 0);
-
- if (i == 0)
- instr->sync = true;
-
- vfetch_instrs[i] = instr;
- }
- ctx->so->num_vfetch_instrs = i;
- ctx->cf = NULL;
-}
-
-/*
- * For vertex shaders (VS):
- * --- ------ -------------
- *
- * Inputs: R1-R(num_input)
- * Constants: C0-C(num_const-1)
- * Immediates: C(num_const)-C(num_const+num_imm-1)
- * Outputs: export0-export(n) and export62, export63
- * n is # of outputs minus gl_Position (export62) and gl_PointSize (export63)
- * Temps: R(num_input+1)-R(num_input+num_temps)
- *
- * R0 could be clobbered after the vertex fetch instructions.. so we
- * could use it for one of the temporaries.
- *
- * TODO: maybe the vertex fetch part could fetch first input into R0 as
- * the last vtx fetch instruction, which would let us use the same
- * register layout in either case.. although this is not what the blob
- * compiler does.
- *
- *
- * For frag shaders (PS):
- * --- ---- -------------
- *
- * Inputs: R0-R(num_input-1)
- * Constants: same as VS
- * Immediates: same as VS
- * Outputs: export0-export(num_outputs)
- * Temps: R(num_input)-R(num_input+num_temps-1)
- *
- * In either case, immediates are are postpended to the constants
- * (uniforms).
- *
- */
-
-static unsigned
-get_temp_gpr(struct fd_compile_context *ctx, int idx)
-{
- unsigned num = idx + ctx->num_regs[TGSI_FILE_INPUT];
- if (ctx->type == TGSI_PROCESSOR_VERTEX)
- num++;
- return num;
-}
-
-static struct ir2_register *
-add_dst_reg(struct fd_compile_context *ctx, struct ir2_instruction *alu,
- const struct tgsi_dst_register *dst)
-{
- unsigned flags = 0, num = 0;
- char swiz[5];
-
- switch (dst->File) {
- case TGSI_FILE_OUTPUT:
- flags |= IR2_REG_EXPORT;
- if (ctx->type == TGSI_PROCESSOR_VERTEX) {
- if (dst->Index == ctx->position) {
- num = 62;
- } else if (dst->Index == ctx->psize) {
- num = 63;
- } else {
- num = export_linkage(ctx,
- ctx->output_export_idx[dst->Index]);
- }
- } else {
- num = dst->Index;
- }
- break;
- case TGSI_FILE_TEMPORARY:
- num = get_temp_gpr(ctx, dst->Index);
- break;
- default:
- DBG("unsupported dst register file: %s",
- tgsi_file_name(dst->File));
- assert(0);
- break;
- }
-
- swiz[0] = (dst->WriteMask & TGSI_WRITEMASK_X) ? 'x' : '_';
- swiz[1] = (dst->WriteMask & TGSI_WRITEMASK_Y) ? 'y' : '_';
- swiz[2] = (dst->WriteMask & TGSI_WRITEMASK_Z) ? 'z' : '_';
- swiz[3] = (dst->WriteMask & TGSI_WRITEMASK_W) ? 'w' : '_';
- swiz[4] = '\0';
-
- return ir2_reg_create(alu, num, swiz, flags);
-}
-
-static struct ir2_register *
-add_src_reg(struct fd_compile_context *ctx, struct ir2_instruction *alu,
- const struct tgsi_src_register *src)
-{
- static const char swiz_vals[] = {
- 'x', 'y', 'z', 'w',
- };
- char swiz[5];
- unsigned flags = 0, num = 0;
-
- switch (src->File) {
- case TGSI_FILE_CONSTANT:
- num = src->Index;
- flags |= IR2_REG_CONST;
- break;
- case TGSI_FILE_INPUT:
- if (ctx->type == TGSI_PROCESSOR_VERTEX) {
- num = src->Index + 1;
- } else {
- num = export_linkage(ctx,
- ctx->input_export_idx[src->Index]);
- }
- break;
- case TGSI_FILE_TEMPORARY:
- num = get_temp_gpr(ctx, src->Index);
- break;
- case TGSI_FILE_IMMEDIATE:
- num = src->Index + ctx->num_regs[TGSI_FILE_CONSTANT];
- flags |= IR2_REG_CONST;
- break;
- default:
- DBG("unsupported src register file: %s",
- tgsi_file_name(src->File));
- assert(0);
- break;
- }
-
- if (src->Absolute)
- flags |= IR2_REG_ABS;
- if (src->Negate)
- flags |= IR2_REG_NEGATE;
-
- swiz[0] = swiz_vals[src->SwizzleX];
- swiz[1] = swiz_vals[src->SwizzleY];
- swiz[2] = swiz_vals[src->SwizzleZ];
- swiz[3] = swiz_vals[src->SwizzleW];
- swiz[4] = '\0';
-
- if ((ctx->need_sync & (uint64_t)(1 << num)) &&
- !(flags & IR2_REG_CONST)) {
- alu->sync = true;
- ctx->need_sync &= ~(uint64_t)(1 << num);
- }
-
- return ir2_reg_create(alu, num, swiz, flags);
-}
-
-static void
-add_vector_clamp(struct tgsi_full_instruction *inst, struct ir2_instruction *alu)
-{
- switch (inst->Instruction.Saturate) {
- case TGSI_SAT_NONE:
- break;
- case TGSI_SAT_ZERO_ONE:
- alu->alu.vector_clamp = true;
- break;
- case TGSI_SAT_MINUS_PLUS_ONE:
- DBG("unsupported saturate");
- assert(0);
- break;
- }
-}
-
-static void
-add_scalar_clamp(struct tgsi_full_instruction *inst, struct ir2_instruction *alu)
-{
- switch (inst->Instruction.Saturate) {
- case TGSI_SAT_NONE:
- break;
- case TGSI_SAT_ZERO_ONE:
- alu->alu.scalar_clamp = true;
- break;
- case TGSI_SAT_MINUS_PLUS_ONE:
- DBG("unsupported saturate");
- assert(0);
- break;
- }
-}
-
-static void
-add_regs_vector_1(struct fd_compile_context *ctx,
- struct tgsi_full_instruction *inst, struct ir2_instruction *alu)
-{
- assert(inst->Instruction.NumSrcRegs == 1);
- assert(inst->Instruction.NumDstRegs == 1);
-
- add_dst_reg(ctx, alu, &inst->Dst[0].Register);
- add_src_reg(ctx, alu, &inst->Src[0].Register);
- add_src_reg(ctx, alu, &inst->Src[0].Register);
- add_vector_clamp(inst, alu);
-}
-
-static void
-add_regs_vector_2(struct fd_compile_context *ctx,
- struct tgsi_full_instruction *inst, struct ir2_instruction *alu)
-{
- assert(inst->Instruction.NumSrcRegs == 2);
- assert(inst->Instruction.NumDstRegs == 1);
-
- add_dst_reg(ctx, alu, &inst->Dst[0].Register);
- add_src_reg(ctx, alu, &inst->Src[0].Register);
- add_src_reg(ctx, alu, &inst->Src[1].Register);
- add_vector_clamp(inst, alu);
-}
-
-static void
-add_regs_vector_3(struct fd_compile_context *ctx,
- struct tgsi_full_instruction *inst, struct ir2_instruction *alu)
-{
- assert(inst->Instruction.NumSrcRegs == 3);
- assert(inst->Instruction.NumDstRegs == 1);
-
- add_dst_reg(ctx, alu, &inst->Dst[0].Register);
- /* maybe should re-arrange the syntax some day, but
- * in assembler/disassembler and what ir.c expects
- * is: MULADDv Rdst = Rsrc2 + Rsrc0 * Rscr1
- */
- add_src_reg(ctx, alu, &inst->Src[2].Register);
- add_src_reg(ctx, alu, &inst->Src[0].Register);
- add_src_reg(ctx, alu, &inst->Src[1].Register);
- add_vector_clamp(inst, alu);
-}
-
-static void
-add_regs_dummy_vector(struct ir2_instruction *alu)
-{
- /* create dummy, non-written vector dst/src regs
- * for unused vector instr slot:
- */
- ir2_reg_create(alu, 0, "____", 0); /* vector dst */
- ir2_reg_create(alu, 0, NULL, 0); /* vector src1 */
- ir2_reg_create(alu, 0, NULL, 0); /* vector src2 */
-}
-
-static void
-add_regs_scalar_1(struct fd_compile_context *ctx,
- struct tgsi_full_instruction *inst, struct ir2_instruction *alu)
-{
- assert(inst->Instruction.NumSrcRegs == 1);
- assert(inst->Instruction.NumDstRegs == 1);
-
- add_regs_dummy_vector(alu);
-
- add_dst_reg(ctx, alu, &inst->Dst[0].Register);
- add_src_reg(ctx, alu, &inst->Src[0].Register);
- add_scalar_clamp(inst, alu);
-}
-
-/*
- * Helpers for TGSI instructions that don't map to a single shader instr:
- */
-
-static void
-src_from_dst(struct tgsi_src_register *src, struct tgsi_dst_register *dst)
-{
- src->File = dst->File;
- src->Indirect = dst->Indirect;
- src->Dimension = dst->Dimension;
- src->Index = dst->Index;
- src->Absolute = 0;
- src->Negate = 0;
- src->SwizzleX = TGSI_SWIZZLE_X;
- src->SwizzleY = TGSI_SWIZZLE_Y;
- src->SwizzleZ = TGSI_SWIZZLE_Z;
- src->SwizzleW = TGSI_SWIZZLE_W;
-}
-
-/* Get internal-temp src/dst to use for a sequence of instructions
- * generated by a single TGSI op.. if possible, use the final dst
- * register as the temporary to avoid allocating a new register, but
- * if necessary allocate one. If a single TGSI op needs multiple
- * internal temps, pass NULL for orig_dst for all but the first one
- * so that you don't end up using the same register for all your
- * internal temps.
- */
-static void
-get_internal_temp(struct fd_compile_context *ctx,
- struct tgsi_dst_register *tmp_dst,
- struct tgsi_src_register *tmp_src)
-{
- int n;
-
- tmp_dst->File = TGSI_FILE_TEMPORARY;
- tmp_dst->WriteMask = TGSI_WRITEMASK_XYZW;
- tmp_dst->Indirect = 0;
- tmp_dst->Dimension = 0;
-
- /* assign next temporary: */
- n = ctx->num_internal_temps++;
- if (ctx->pred_reg != -1)
- n++;
-
- tmp_dst->Index = ctx->num_regs[TGSI_FILE_TEMPORARY] + n;
-
- src_from_dst(tmp_src, tmp_dst);
-}
-
-static void
-get_predicate(struct fd_compile_context *ctx, struct tgsi_dst_register *dst,
- struct tgsi_src_register *src)
-{
- assert(ctx->pred_reg != -1);
-
- dst->File = TGSI_FILE_TEMPORARY;
- dst->WriteMask = TGSI_WRITEMASK_W;
- dst->Indirect = 0;
- dst->Dimension = 0;
- dst->Index = get_temp_gpr(ctx, ctx->pred_reg);
-
- if (src) {
- src_from_dst(src, dst);
- src->SwizzleX = TGSI_SWIZZLE_W;
- src->SwizzleY = TGSI_SWIZZLE_W;
- src->SwizzleZ = TGSI_SWIZZLE_W;
- src->SwizzleW = TGSI_SWIZZLE_W;
- }
-}
-
-static void
-push_predicate(struct fd_compile_context *ctx, struct tgsi_src_register *src)
-{
- struct ir2_instruction *alu;
- struct tgsi_dst_register pred_dst;
-
- /* NOTE blob compiler seems to always puts PRED_* instrs in a CF by
- * themselves:
- */
- ctx->cf = NULL;
-
- if (ctx->pred_depth == 0) {
- /* assign predicate register: */
- ctx->pred_reg = ctx->num_regs[TGSI_FILE_TEMPORARY];
-
- get_predicate(ctx, &pred_dst, NULL);
-
- alu = ir2_instr_create_alu(next_exec_cf(ctx), ~0, PRED_SETNEs);
- add_regs_dummy_vector(alu);
- add_dst_reg(ctx, alu, &pred_dst);
- add_src_reg(ctx, alu, src);
- } else {
- struct tgsi_src_register pred_src;
-
- get_predicate(ctx, &pred_dst, &pred_src);
-
- alu = ir2_instr_create_alu(next_exec_cf(ctx), MULv, ~0);
- add_dst_reg(ctx, alu, &pred_dst);
- add_src_reg(ctx, alu, &pred_src);
- add_src_reg(ctx, alu, src);
-
- // XXX need to make PRED_SETE_PUSHv IR2_PRED_NONE.. but need to make
- // sure src reg is valid if it was calculated with a predicate
- // condition..
- alu->pred = IR2_PRED_NONE;
- }
-
- /* save previous pred state to restore in pop_predicate(): */
- ctx->pred_stack[ctx->pred_depth++] = ctx->so->ir->pred;
-
- ctx->cf = NULL;
-}
-
-static void
-pop_predicate(struct fd_compile_context *ctx)
-{
- /* NOTE blob compiler seems to always puts PRED_* instrs in a CF by
- * themselves:
- */
- ctx->cf = NULL;
-
- /* restore previous predicate state: */
- ctx->so->ir->pred = ctx->pred_stack[--ctx->pred_depth];
-
- if (ctx->pred_depth != 0) {
- struct ir2_instruction *alu;
- struct tgsi_dst_register pred_dst;
- struct tgsi_src_register pred_src;
-
- get_predicate(ctx, &pred_dst, &pred_src);
-
- alu = ir2_instr_create_alu(next_exec_cf(ctx), ~0, PRED_SET_POPs);
- add_regs_dummy_vector(alu);
- add_dst_reg(ctx, alu, &pred_dst);
- add_src_reg(ctx, alu, &pred_src);
- alu->pred = IR2_PRED_NONE;
- } else {
- /* predicate register no longer needed: */
- ctx->pred_reg = -1;
- }
-
- ctx->cf = NULL;
-}
-
-static void
-get_immediate(struct fd_compile_context *ctx,
- struct tgsi_src_register *reg, uint32_t val)
-{
- unsigned neg, swiz, idx, i;
- /* actually maps 1:1 currently.. not sure if that is safe to rely on: */
- static const unsigned swiz2tgsi[] = {
- TGSI_SWIZZLE_X, TGSI_SWIZZLE_Y, TGSI_SWIZZLE_Z, TGSI_SWIZZLE_W,
- };
-
- for (i = 0; i < ctx->immediate_idx; i++) {
- swiz = i % 4;
- idx = i / 4;
-
- if (ctx->so->immediates[idx].val[swiz] == val) {
- neg = 0;
- break;
- }
-
- if (ctx->so->immediates[idx].val[swiz] == -val) {
- neg = 1;
- break;
- }
- }
-
- if (i == ctx->immediate_idx) {
- /* need to generate a new immediate: */
- swiz = i % 4;
- idx = i / 4;
- neg = 0;
- ctx->so->immediates[idx].val[swiz] = val;
- ctx->so->num_immediates = idx + 1;
- ctx->immediate_idx++;
- }
-
- reg->File = TGSI_FILE_IMMEDIATE;
- reg->Indirect = 0;
- reg->Dimension = 0;
- reg->Index = idx;
- reg->Absolute = 0;
- reg->Negate = neg;
- reg->SwizzleX = swiz2tgsi[swiz];
- reg->SwizzleY = swiz2tgsi[swiz];
- reg->SwizzleZ = swiz2tgsi[swiz];
- reg->SwizzleW = swiz2tgsi[swiz];
-}
-
-/* POW(a,b) = EXP2(b * LOG2(a)) */
-static void
-translate_pow(struct fd_compile_context *ctx,
- struct tgsi_full_instruction *inst)
-{
- struct tgsi_dst_register tmp_dst;
- struct tgsi_src_register tmp_src;
- struct ir2_instruction *alu;
-
- get_internal_temp(ctx, &tmp_dst, &tmp_src);
-
- alu = ir2_instr_create_alu(next_exec_cf(ctx), ~0, LOG_CLAMP);
- add_regs_dummy_vector(alu);
- add_dst_reg(ctx, alu, &tmp_dst);
- add_src_reg(ctx, alu, &inst->Src[0].Register);
-
- alu = ir2_instr_create_alu(next_exec_cf(ctx), MULv, ~0);
- add_dst_reg(ctx, alu, &tmp_dst);
- add_src_reg(ctx, alu, &tmp_src);
- add_src_reg(ctx, alu, &inst->Src[1].Register);
-
- /* NOTE: some of the instructions, like EXP_IEEE, seem hard-
- * coded to take their input from the w component.
- */
- switch(inst->Dst[0].Register.WriteMask) {
- case TGSI_WRITEMASK_X:
- tmp_src.SwizzleW = TGSI_SWIZZLE_X;
- break;
- case TGSI_WRITEMASK_Y:
- tmp_src.SwizzleW = TGSI_SWIZZLE_Y;
- break;
- case TGSI_WRITEMASK_Z:
- tmp_src.SwizzleW = TGSI_SWIZZLE_Z;
- break;
- case TGSI_WRITEMASK_W:
- tmp_src.SwizzleW = TGSI_SWIZZLE_W;
- break;
- default:
- DBG("invalid writemask!");
- assert(0);
- break;
- }
-
- alu = ir2_instr_create_alu(next_exec_cf(ctx), ~0, EXP_IEEE);
- add_regs_dummy_vector(alu);
- add_dst_reg(ctx, alu, &inst->Dst[0].Register);
- add_src_reg(ctx, alu, &tmp_src);
- add_scalar_clamp(inst, alu);
-}
-
-static void
-translate_tex(struct fd_compile_context *ctx,
- struct tgsi_full_instruction *inst, unsigned opc)
-{
- struct ir2_instruction *instr;
- struct ir2_register *reg;
- struct tgsi_dst_register tmp_dst;
- struct tgsi_src_register tmp_src;
- const struct tgsi_src_register *coord;
- bool using_temp = (inst->Dst[0].Register.File == TGSI_FILE_OUTPUT) ||
- (inst->Instruction.Saturate != TGSI_SAT_NONE);
- int idx;
-
- if (using_temp || (opc == TGSI_OPCODE_TXP))
- get_internal_temp(ctx, &tmp_dst, &tmp_src);
-
- if (opc == TGSI_OPCODE_TXP) {
- static const char *swiz[] = {
- [TGSI_SWIZZLE_X] = "xxxx",
- [TGSI_SWIZZLE_Y] = "yyyy",
- [TGSI_SWIZZLE_Z] = "zzzz",
- [TGSI_SWIZZLE_W] = "wwww",
- };
-
- /* TXP - Projective Texture Lookup:
- *
- * coord.x = src0.x / src.w
- * coord.y = src0.y / src.w
- * coord.z = src0.z / src.w
- * coord.w = src0.w
- * bias = 0.0
- *
- * dst = texture_sample(unit, coord, bias)
- */
- instr = ir2_instr_create_alu(next_exec_cf(ctx), MAXv, RECIP_IEEE);
-
- /* MAXv: */
- add_dst_reg(ctx, instr, &tmp_dst)->swizzle = "___w";
- add_src_reg(ctx, instr, &inst->Src[0].Register);
- add_src_reg(ctx, instr, &inst->Src[0].Register);
-
- /* RECIP_IEEE: */
- add_dst_reg(ctx, instr, &tmp_dst)->swizzle = "x___";
- add_src_reg(ctx, instr, &inst->Src[0].Register)->swizzle =
- swiz[inst->Src[0].Register.SwizzleW];
-
- instr = ir2_instr_create_alu(next_exec_cf(ctx), MULv, ~0);
- add_dst_reg(ctx, instr, &tmp_dst)->swizzle = "xyz_";
- add_src_reg(ctx, instr, &tmp_src)->swizzle = "xxxx";
- add_src_reg(ctx, instr, &inst->Src[0].Register);
-
- coord = &tmp_src;
- } else {
- coord = &inst->Src[0].Register;
- }
-
- instr = ir2_instr_create(next_exec_cf(ctx), IR2_FETCH);
- instr->fetch.opc = TEX_FETCH;
- instr->fetch.is_cube = (inst->Texture.Texture == TGSI_TEXTURE_3D);
- assert(inst->Texture.NumOffsets <= 1); // TODO what to do in other cases?
-
- /* save off the tex fetch to be patched later with correct const_idx: */
- idx = ctx->so->num_tfetch_instrs++;
- ctx->so->tfetch_instrs[idx].samp_id = inst->Src[1].Register.Index;
- ctx->so->tfetch_instrs[idx].instr = instr;
-
- add_dst_reg(ctx, instr, using_temp ? &tmp_dst : &inst->Dst[0].Register);
- reg = add_src_reg(ctx, instr, coord);
-
- /* blob compiler always sets 3rd component to same as 1st for 2d: */
- if (inst->Texture.Texture == TGSI_TEXTURE_2D)
- reg->swizzle[2] = reg->swizzle[0];
-
- /* dst register needs to be marked for sync: */
- ctx->need_sync |= 1 << instr->regs[0]->num;
-
- /* TODO we need some way to know if the tex fetch needs to sync on alu pipe.. */
- instr->sync = true;
-
- if (using_temp) {
- /* texture fetch can't write directly to export, so if tgsi
- * is telling us the dst register is in output file, we load
- * the texture to a temp and the use ALU instruction to move
- * to output
- */
- instr = ir2_instr_create_alu(next_exec_cf(ctx), MAXv, ~0);
-
- add_dst_reg(ctx, instr, &inst->Dst[0].Register);
- add_src_reg(ctx, instr, &tmp_src);
- add_src_reg(ctx, instr, &tmp_src);
- add_vector_clamp(inst, instr);
- }
-}
-
-/* SGE(a,b) = GTE((b - a), 1.0, 0.0) */
-/* SLT(a,b) = GTE((b - a), 0.0, 1.0) */
-static void
-translate_sge_slt(struct fd_compile_context *ctx,
- struct tgsi_full_instruction *inst, unsigned opc)
-{
- struct ir2_instruction *instr;
- struct tgsi_dst_register tmp_dst;
- struct tgsi_src_register tmp_src;
- struct tgsi_src_register tmp_const;
- float c0, c1;
-
- switch (opc) {
- default:
- assert(0);
- case TGSI_OPCODE_SGE:
- c0 = 1.0;
- c1 = 0.0;
- break;
- case TGSI_OPCODE_SLT:
- c0 = 0.0;
- c1 = 1.0;
- break;
- }
-
- get_internal_temp(ctx, &tmp_dst, &tmp_src);
-
- instr = ir2_instr_create_alu(next_exec_cf(ctx), ADDv, ~0);
- add_dst_reg(ctx, instr, &tmp_dst);
- add_src_reg(ctx, instr, &inst->Src[0].Register)->flags |= IR2_REG_NEGATE;
- add_src_reg(ctx, instr, &inst->Src[1].Register);
-
- instr = ir2_instr_create_alu(next_exec_cf(ctx), CNDGTEv, ~0);
- add_dst_reg(ctx, instr, &inst->Dst[0].Register);
- /* maybe should re-arrange the syntax some day, but
- * in assembler/disassembler and what ir.c expects
- * is: MULADDv Rdst = Rsrc2 + Rsrc0 * Rscr1
- */
- get_immediate(ctx, &tmp_const, fui(c0));
- add_src_reg(ctx, instr, &tmp_const);
- add_src_reg(ctx, instr, &tmp_src);
- get_immediate(ctx, &tmp_const, fui(c1));
- add_src_reg(ctx, instr, &tmp_const);
-}
-
-/* LRP(a,b,c) = (a * b) + ((1 - a) * c) */
-static void
-translate_lrp(struct fd_compile_context *ctx,
- struct tgsi_full_instruction *inst,
- unsigned opc)
-{
- struct ir2_instruction *instr;
- struct tgsi_dst_register tmp_dst1, tmp_dst2;
- struct tgsi_src_register tmp_src1, tmp_src2;
- struct tgsi_src_register tmp_const;
-
- get_internal_temp(ctx, &tmp_dst1, &tmp_src1);
- get_internal_temp(ctx, &tmp_dst2, &tmp_src2);
-
- get_immediate(ctx, &tmp_const, fui(1.0));
-
- /* tmp1 = (a * b) */
- instr = ir2_instr_create_alu(next_exec_cf(ctx), MULv, ~0);
- add_dst_reg(ctx, instr, &tmp_dst1);
- add_src_reg(ctx, instr, &inst->Src[0].Register);
- add_src_reg(ctx, instr, &inst->Src[1].Register);
-
- /* tmp2 = (1 - a) */
- instr = ir2_instr_create_alu(next_exec_cf(ctx), ADDv, ~0);
- add_dst_reg(ctx, instr, &tmp_dst2);
- add_src_reg(ctx, instr, &tmp_const);
- add_src_reg(ctx, instr, &inst->Src[0].Register)->flags |= IR2_REG_NEGATE;
-
- /* tmp2 = tmp2 * c */
- instr = ir2_instr_create_alu(next_exec_cf(ctx), MULv, ~0);
- add_dst_reg(ctx, instr, &tmp_dst2);
- add_src_reg(ctx, instr, &tmp_src2);
- add_src_reg(ctx, instr, &inst->Src[2].Register);
-
- /* dst = tmp1 + tmp2 */
- instr = ir2_instr_create_alu(next_exec_cf(ctx), ADDv, ~0);
- add_dst_reg(ctx, instr, &inst->Dst[0].Register);
- add_src_reg(ctx, instr, &tmp_src1);
- add_src_reg(ctx, instr, &tmp_src2);
-}
-
-static void
-translate_trig(struct fd_compile_context *ctx,
- struct tgsi_full_instruction *inst,
- unsigned opc)
-{
- struct ir2_instruction *instr;
- struct tgsi_dst_register tmp_dst;
- struct tgsi_src_register tmp_src;
- struct tgsi_src_register tmp_const;
- instr_scalar_opc_t op;
-
- switch (opc) {
- default:
- assert(0);
- case TGSI_OPCODE_SIN:
- op = SIN;
- break;
- case TGSI_OPCODE_COS:
- op = COS;
- break;
- }
-
- get_internal_temp(ctx, &tmp_dst, &tmp_src);
-
- tmp_dst.WriteMask = TGSI_WRITEMASK_X;
- tmp_src.SwizzleX = tmp_src.SwizzleY =
- tmp_src.SwizzleZ = tmp_src.SwizzleW = TGSI_SWIZZLE_X;
-
- /* maybe should re-arrange the syntax some day, but
- * in assembler/disassembler and what ir.c expects
- * is: MULADDv Rdst = Rsrc2 + Rsrc0 * Rscr1
- */
- instr = ir2_instr_create_alu(next_exec_cf(ctx), MULADDv, ~0);
- add_dst_reg(ctx, instr, &tmp_dst);
- get_immediate(ctx, &tmp_const, fui(0.5));
- add_src_reg(ctx, instr, &tmp_const);
- add_src_reg(ctx, instr, &inst->Src[0].Register);
- get_immediate(ctx, &tmp_const, fui(0.159155));
- add_src_reg(ctx, instr, &tmp_const);
-
- instr = ir2_instr_create_alu(next_exec_cf(ctx), FRACv, ~0);
- add_dst_reg(ctx, instr, &tmp_dst);
- add_src_reg(ctx, instr, &tmp_src);
- add_src_reg(ctx, instr, &tmp_src);
-
- instr = ir2_instr_create_alu(next_exec_cf(ctx), MULADDv, ~0);
- add_dst_reg(ctx, instr, &tmp_dst);
- get_immediate(ctx, &tmp_const, fui(-3.141593));
- add_src_reg(ctx, instr, &tmp_const);
- add_src_reg(ctx, instr, &tmp_src);
- get_immediate(ctx, &tmp_const, fui(6.283185));
- add_src_reg(ctx, instr, &tmp_const);
-
- instr = ir2_instr_create_alu(next_exec_cf(ctx), ~0, op);
- add_regs_dummy_vector(instr);
- add_dst_reg(ctx, instr, &inst->Dst[0].Register);
- add_src_reg(ctx, instr, &tmp_src);
-}
-
-/*
- * Main part of compiler/translator:
- */
-
-static void
-translate_instruction(struct fd_compile_context *ctx,
- struct tgsi_full_instruction *inst)
-{
- unsigned opc = inst->Instruction.Opcode;
- struct ir2_instruction *instr;
- static struct ir2_cf *cf;
-
- if (opc == TGSI_OPCODE_END)
- return;
-
- if (inst->Dst[0].Register.File == TGSI_FILE_OUTPUT) {
- unsigned num = inst->Dst[0].Register.Index;
- /* seems like we need to ensure that position vs param/pixel
- * exports don't end up in the same EXEC clause.. easy way
- * to do this is force a new EXEC clause on first appearance
- * of an position or param/pixel export.
- */
- if ((num == ctx->position) || (num == ctx->psize)) {
- if (ctx->num_position > 0) {
- ctx->cf = NULL;
- ir2_cf_create_alloc(ctx->so->ir, SQ_POSITION,
- ctx->num_position - 1);
- ctx->num_position = 0;
- }
- } else {
- if (ctx->num_param > 0) {
- ctx->cf = NULL;
- ir2_cf_create_alloc(ctx->so->ir, SQ_PARAMETER_PIXEL,
- ctx->num_param - 1);
- ctx->num_param = 0;
- }
- }
- }
-
- cf = next_exec_cf(ctx);
-
- /* TODO turn this into a table: */
- switch (opc) {
- case TGSI_OPCODE_MOV:
- instr = ir2_instr_create_alu(cf, MAXv, ~0);
- add_regs_vector_1(ctx, inst, instr);
- break;
- case TGSI_OPCODE_RCP:
- instr = ir2_instr_create_alu(cf, ~0, RECIP_IEEE);
- add_regs_scalar_1(ctx, inst, instr);
- break;
- case TGSI_OPCODE_RSQ:
- instr = ir2_instr_create_alu(cf, ~0, RECIPSQ_IEEE);
- add_regs_scalar_1(ctx, inst, instr);
- break;
- case TGSI_OPCODE_MUL:
- instr = ir2_instr_create_alu(cf, MULv, ~0);
- add_regs_vector_2(ctx, inst, instr);
- break;
- case TGSI_OPCODE_ADD:
- instr = ir2_instr_create_alu(cf, ADDv, ~0);
- add_regs_vector_2(ctx, inst, instr);
- break;
- case TGSI_OPCODE_DP3:
- instr = ir2_instr_create_alu(cf, DOT3v, ~0);
- add_regs_vector_2(ctx, inst, instr);
- break;
- case TGSI_OPCODE_DP4:
- instr = ir2_instr_create_alu(cf, DOT4v, ~0);
- add_regs_vector_2(ctx, inst, instr);
- break;
- case TGSI_OPCODE_MIN:
- instr = ir2_instr_create_alu(cf, MINv, ~0);
- add_regs_vector_2(ctx, inst, instr);
- break;
- case TGSI_OPCODE_MAX:
- instr = ir2_instr_create_alu(cf, MAXv, ~0);
- add_regs_vector_2(ctx, inst, instr);
- break;
- case TGSI_OPCODE_SLT:
- case TGSI_OPCODE_SGE:
- translate_sge_slt(ctx, inst, opc);
- break;
- case TGSI_OPCODE_MAD:
- instr = ir2_instr_create_alu(cf, MULADDv, ~0);
- add_regs_vector_3(ctx, inst, instr);
- break;
- case TGSI_OPCODE_LRP:
- translate_lrp(ctx, inst, opc);
- break;
- case TGSI_OPCODE_FRC:
- instr = ir2_instr_create_alu(cf, FRACv, ~0);
- add_regs_vector_1(ctx, inst, instr);
- break;
- case TGSI_OPCODE_FLR:
- instr = ir2_instr_create_alu(cf, FLOORv, ~0);
- add_regs_vector_1(ctx, inst, instr);
- break;
- case TGSI_OPCODE_EX2:
- instr = ir2_instr_create_alu(cf, ~0, EXP_IEEE);
- add_regs_scalar_1(ctx, inst, instr);
- break;
- case TGSI_OPCODE_POW:
- translate_pow(ctx, inst);
- break;
- case TGSI_OPCODE_ABS:
- instr = ir2_instr_create_alu(cf, MAXv, ~0);
- add_regs_vector_1(ctx, inst, instr);
- instr->regs[1]->flags |= IR2_REG_NEGATE; /* src0 */
- break;
- case TGSI_OPCODE_COS:
- case TGSI_OPCODE_SIN:
- translate_trig(ctx, inst, opc);
- break;
- case TGSI_OPCODE_TEX:
- case TGSI_OPCODE_TXP:
- translate_tex(ctx, inst, opc);
- break;
- case TGSI_OPCODE_CMP:
- instr = ir2_instr_create_alu(cf, CNDGTEv, ~0);
- add_regs_vector_3(ctx, inst, instr);
- // TODO this should be src0 if regs where in sane order..
- instr->regs[2]->flags ^= IR2_REG_NEGATE; /* src1 */
- break;
- case TGSI_OPCODE_IF:
- push_predicate(ctx, &inst->Src[0].Register);
- ctx->so->ir->pred = IR2_PRED_EQ;
- break;
- case TGSI_OPCODE_ELSE:
- ctx->so->ir->pred = IR2_PRED_NE;
- /* not sure if this is required in all cases, but blob compiler
- * won't combine EQ and NE in same CF:
- */
- ctx->cf = NULL;
- break;
- case TGSI_OPCODE_ENDIF:
- pop_predicate(ctx);
- break;
- case TGSI_OPCODE_F2I:
- instr = ir2_instr_create_alu(cf, TRUNCv, ~0);
- add_regs_vector_1(ctx, inst, instr);
- break;
- default:
- DBG("unknown TGSI opc: %s", tgsi_get_opcode_name(opc));
- tgsi_dump(ctx->so->tokens, 0);
- assert(0);
- break;
- }
-
- /* internal temporaries are only valid for the duration of a single
- * TGSI instruction:
- */
- ctx->num_internal_temps = 0;
-}
-
-static void
-compile_instructions(struct fd_compile_context *ctx)
-{
- while (!tgsi_parse_end_of_tokens(&ctx->parser)) {
- tgsi_parse_token(&ctx->parser);
-
- switch (ctx->parser.FullToken.Token.Type) {
- case TGSI_TOKEN_TYPE_INSTRUCTION:
- translate_instruction(ctx,
- &ctx->parser.FullToken.FullInstruction);
- break;
- default:
- break;
- }
- }
-
- ctx->cf->cf_type = EXEC_END;
-}
-
-int
-fd_compile_shader(struct fd_program_stateobj *prog,
- struct fd_shader_stateobj *so)
-{
- struct fd_compile_context ctx;
-
- ir2_shader_destroy(so->ir);
- so->ir = ir2_shader_create();
- so->num_vfetch_instrs = so->num_tfetch_instrs = so->num_immediates = 0;
-
- if (compile_init(&ctx, prog, so) != TGSI_PARSE_OK)
- return -1;
-
- if (ctx.type == TGSI_PROCESSOR_VERTEX) {
- compile_vtx_fetch(&ctx);
- } else if (ctx.type == TGSI_PROCESSOR_FRAGMENT) {
- prog->num_exports = 0;
- memset(prog->export_linkage, 0xff,
- sizeof(prog->export_linkage));
- }
-
- compile_instructions(&ctx);
-
- compile_free(&ctx);
-
- return 0;
-}
-
+++ /dev/null
-/* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */
-
-/*
- * Copyright (C) 2012 Rob Clark <robclark@freedesktop.org>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Authors:
- * Rob Clark <robclark@freedesktop.org>
- */
-
-#ifndef FREEDRENO_COMPILER_H_
-#define FREEDRENO_COMPILER_H_
-
-#include "freedreno_program.h"
-#include "freedreno_util.h"
-
-int fd_compile_shader(struct fd_program_stateobj *prog,
- struct fd_shader_stateobj *so);
-
-#endif /* FREEDRENO_COMPILER_H_ */
*/
#include "freedreno_context.h"
-#include "freedreno_vbo.h"
-#include "freedreno_blend.h"
-#include "freedreno_rasterizer.h"
-#include "freedreno_zsa.h"
-#include "freedreno_state.h"
+#include "freedreno_draw.h"
#include "freedreno_resource.h"
-#include "freedreno_clear.h"
-#include "freedreno_program.h"
#include "freedreno_texture.h"
+#include "freedreno_state.h"
#include "freedreno_gmem.h"
#include "freedreno_util.h"
#endif
fd_context_render(pctx);
- fd_context_wait(pctx);
}
-static void
+void
fd_context_destroy(struct pipe_context *pctx)
{
struct fd_context *ctx = fd_context(pctx);
fd_ringmarker_del(ctx->draw_end);
fd_ringbuffer_del(ctx->ring);
- fd_prog_fini(pctx);
-
FREE(ctx);
}
-static struct pipe_resource *
-create_solid_vertexbuf(struct pipe_context *pctx)
-{
- static const float init_shader_const[] = {
- /* for clear/gmem2mem: */
- -1.000000, +1.000000, +1.000000, +1.100000,
- +1.000000, +1.000000, -1.000000, -1.100000,
- +1.000000, +1.100000, -1.100000, +1.000000,
- /* for mem2gmem: (vertices) */
- -1.000000, +1.000000, +1.000000, +1.000000,
- +1.000000, +1.000000, -1.000000, -1.000000,
- +1.000000, +1.000000, -1.000000, +1.000000,
- /* for mem2gmem: (tex coords) */
- +0.000000, +0.000000, +1.000000, +0.000000,
- +0.000000, +1.000000, +1.000000, +1.000000,
- };
- struct pipe_resource *prsc = pipe_buffer_create(pctx->screen,
- PIPE_BIND_CUSTOM, PIPE_USAGE_IMMUTABLE, sizeof(init_shader_const));
- pipe_buffer_write(pctx, prsc, 0,
- sizeof(init_shader_const), init_shader_const);
- return prsc;
-}
-
struct pipe_context *
-fd_context_create(struct pipe_screen *pscreen, void *priv)
+fd_context_init(struct fd_context *ctx,
+ struct pipe_screen *pscreen, void *priv)
{
struct fd_screen *screen = fd_screen(pscreen);
- struct fd_context *ctx = CALLOC_STRUCT(fd_context);
struct pipe_context *pctx;
- if (!ctx)
- return NULL;
-
- DBG("");
-
ctx->screen = screen;
- ctx->ring = fd_ringbuffer_new(screen->pipe, 0x100000);
- ctx->draw_start = fd_ringmarker_new(ctx->ring);
- ctx->draw_end = fd_ringmarker_new(ctx->ring);
+ /* need some sane default in case state tracker doesn't
+ * set some state:
+ */
+ ctx->sample_mask = 0xffff;
pctx = &ctx->base;
pctx->screen = pscreen;
pctx->priv = priv;
pctx->flush = fd_context_flush;
- pctx->destroy = fd_context_destroy;
+
+ ctx->ring = fd_ringbuffer_new(screen->pipe, 0x100000);
+ if (!ctx->ring)
+ goto fail;
+
+ ctx->draw_start = fd_ringmarker_new(ctx->ring);
+ ctx->draw_end = fd_ringmarker_new(ctx->ring);
util_slab_create(&ctx->transfer_pool, sizeof(struct pipe_transfer),
16, UTIL_SLAB_SINGLETHREADED);
- fd_vbo_init(pctx);
- fd_blend_init(pctx);
- fd_rasterizer_init(pctx);
- fd_zsa_init(pctx);
- fd_state_init(pctx);
+ fd_draw_init(pctx);
fd_resource_context_init(pctx);
- fd_clear_init(pctx);
- fd_prog_init(pctx);
fd_texture_init(pctx);
+ fd_state_init(pctx);
ctx->blitter = util_blitter_create(pctx);
- if (!ctx->blitter) {
- fd_context_destroy(pctx);
- return NULL;
- }
-
- /* construct vertex state used for solid ops (clear, and gmem<->mem) */
- ctx->solid_vertexbuf = create_solid_vertexbuf(pctx);
+ if (!ctx->blitter)
+ goto fail;
- fd_state_emit_setup(pctx);
return pctx;
+
+fail:
+ pctx->destroy(pctx);
+ return NULL;
}
#include "freedreno_screen.h"
-struct fd_blend_stateobj;
-struct fd_rasterizer_stateobj;
-struct fd_zsa_stateobj;
-struct fd_sampler_stateobj;
struct fd_vertex_stateobj;
-struct fd_shader_stateobj;
struct fd_texture_stateobj {
struct pipe_sampler_view *textures[PIPE_MAX_SAMPLERS];
unsigned num_textures;
- struct fd_sampler_stateobj *samplers[PIPE_MAX_SAMPLERS];
+ struct pipe_sampler_state *samplers[PIPE_MAX_SAMPLERS];
unsigned num_samplers;
unsigned dirty_samplers;
};
struct fd_program_stateobj {
- struct fd_shader_stateobj *vp, *fp;
+ void *vp, *fp;
enum {
FD_SHADER_DIRTY_VP = (1 << 0),
FD_SHADER_DIRTY_FP = (1 << 1),
uint32_t dirty_mask;
};
+struct fd_vertex_stateobj {
+ struct pipe_vertex_element pipe[PIPE_MAX_ATTRIBS];
+ unsigned num_elements;
+};
+
struct fd_gmem_stateobj {
struct pipe_scissor_state scissor;
uint cpp;
/* shaders used by mem->gmem blits: */
struct fd_program_stateobj blit_prog; // TODO move to screen?
- /* vertex buff used for clear/gmem->mem vertices, and mem->gmem
- * vertices and tex coords:
- */
- struct pipe_resource *solid_vertexbuf;
-
/* do we need to mem2gmem before rendering. We don't, if for example,
* there was a glClear() that invalidated the entire previous buffer
* contents. Keep track of which buffer(s) are cleared, or needs
struct fd_ringbuffer *ring;
struct fd_ringmarker *draw_start, *draw_end;
- /* scissor can't really be changed mid-render.. we probably need
- * to flush out all pending draws and then start a new tile pass
- * w/ new stencil state..
- */
struct pipe_scissor_state scissor;
/* Track the maximal bounds of the scissor of all the draws within a
FD_DIRTY_SCISSOR = (1 << 17),
} dirty;
- struct fd_blend_stateobj *blend;
- struct fd_rasterizer_stateobj *rasterizer;
- struct fd_zsa_stateobj *zsa;
+ struct pipe_blend_state *blend;
+ struct pipe_rasterizer_state *rasterizer;
+ struct pipe_depth_stencil_alpha_state *zsa;
struct fd_texture_stateobj verttex, fragtex;
struct fd_constbuf_stateobj constbuf[PIPE_SHADER_TYPES];
struct fd_vertexbuf_stateobj vertexbuf;
struct pipe_index_buffer indexbuf;
+
+ /* GMEM/tile handling fxns: */
+ void (*emit_tile_init)(struct fd_context *ctx);
+ void (*emit_tile_prep)(struct fd_context *ctx, uint32_t xoff, uint32_t yoff,
+ uint32_t bin_w, uint32_t bin_h);
+ void (*emit_tile_mem2gmem)(struct fd_context *ctx, uint32_t xoff, uint32_t yoff,
+ uint32_t bin_w, uint32_t bin_h);
+ void (*emit_tile_renderprep)(struct fd_context *ctx, uint32_t xoff, uint32_t yoff,
+ uint32_t bin_w, uint32_t bin_h);
+ void (*emit_tile_gmem2mem)(struct fd_context *ctx, uint32_t xoff, uint32_t yoff,
+ uint32_t bin_w, uint32_t bin_h);
+
+ /* draw: */
+ void (*draw)(struct fd_context *pctx, const struct pipe_draw_info *info);
+ void (*clear)(struct fd_context *ctx, unsigned buffers,
+ const union pipe_color_union *color, double depth, unsigned stencil);
};
static INLINE struct fd_context *
return (struct fd_context *)pctx;
}
-struct pipe_context * fd_context_create(struct pipe_screen *pscreen, void *priv);
+struct pipe_context * fd_context_init(struct fd_context *ctx,
+ struct pipe_screen *pscreen, void *priv);
void fd_context_render(struct pipe_context *pctx);
+void fd_context_destroy(struct pipe_context *pctx);
+
#endif /* FREEDRENO_CONTEXT_H_ */
--- /dev/null
+/* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */
+
+/*
+ * Copyright (C) 2012 Rob Clark <robclark@freedesktop.org>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Authors:
+ * Rob Clark <robclark@freedesktop.org>
+ */
+
+#include "pipe/p_state.h"
+#include "util/u_string.h"
+#include "util/u_memory.h"
+#include "util/u_prim.h"
+#include "util/u_format.h"
+
+#include "freedreno_draw.h"
+#include "freedreno_context.h"
+#include "freedreno_state.h"
+#include "freedreno_resource.h"
+#include "freedreno_util.h"
+
+
+static enum pc_di_primtype
+mode2primtype(unsigned mode)
+{
+ switch (mode) {
+ case PIPE_PRIM_POINTS: return DI_PT_POINTLIST;
+ case PIPE_PRIM_LINES: return DI_PT_LINELIST;
+ case PIPE_PRIM_LINE_STRIP: return DI_PT_LINESTRIP;
+ case PIPE_PRIM_TRIANGLES: return DI_PT_TRILIST;
+ case PIPE_PRIM_TRIANGLE_STRIP: return DI_PT_TRISTRIP;
+ case PIPE_PRIM_TRIANGLE_FAN: return DI_PT_TRIFAN;
+ case PIPE_PRIM_QUADS: return DI_PT_QUADLIST;
+ case PIPE_PRIM_QUAD_STRIP: return DI_PT_QUADSTRIP;
+ case PIPE_PRIM_POLYGON: return DI_PT_POLYGON;
+ }
+ DBG("unsupported mode: (%s) %d", u_prim_name(mode), mode);
+ assert(0);
+ return DI_PT_NONE;
+}
+
+static enum pc_di_index_size
+size2indextype(unsigned index_size)
+{
+ switch (index_size) {
+ case 1: return INDEX_SIZE_8_BIT;
+ case 2: return INDEX_SIZE_16_BIT;
+ case 4: return INDEX_SIZE_32_BIT;
+ }
+ DBG("unsupported index size: %d", index_size);
+ assert(0);
+ return INDEX_SIZE_IGN;
+}
+
+/* this is same for a2xx/a3xx, so split into helper: */
+void
+fd_draw_emit(struct fd_context *ctx, const struct pipe_draw_info *info)
+{
+ struct fd_ringbuffer *ring = ctx->ring;
+ struct pipe_index_buffer *idx = &ctx->indexbuf;
+ struct fd_bo *idx_bo = NULL;
+ enum pc_di_index_size idx_type = INDEX_SIZE_IGN;
+ enum pc_di_src_sel src_sel;
+ uint32_t idx_size, idx_offset;
+
+ if (info->indexed) {
+ assert(!idx->user_buffer);
+
+ idx_bo = fd_resource(idx->buffer)->bo;
+ idx_type = size2indextype(idx->index_size);
+ idx_size = idx->index_size * info->count;
+ idx_offset = idx->offset;
+ src_sel = DI_SRC_SEL_DMA;
+ } else {
+ idx_bo = NULL;
+ idx_type = INDEX_SIZE_IGN;
+ idx_size = 0;
+ idx_offset = 0;
+ src_sel = DI_SRC_SEL_AUTO_INDEX;
+ }
+
+ OUT_PKT3(ring, CP_DRAW_INDX, info->indexed ? 5 : 3);
+ OUT_RING(ring, 0x00000000); /* viz query info. */
+ OUT_RING(ring, DRAW(mode2primtype(info->mode),
+ src_sel, idx_type, IGNORE_VISIBILITY));
+ OUT_RING(ring, info->count); /* NumIndices */
+ if (info->indexed) {
+ OUT_RELOC(ring, idx_bo, idx_offset, 0);
+ OUT_RING (ring, idx_size);
+ }
+}
+
+static void
+fd_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info)
+{
+ struct fd_context *ctx = fd_context(pctx);
+ struct pipe_framebuffer_state *pfb = &ctx->framebuffer;
+ unsigned buffers;
+
+ /* if we supported transform feedback, we'd have to disable this: */
+ if (((ctx->scissor.maxx - ctx->scissor.minx) *
+ (ctx->scissor.maxy - ctx->scissor.miny)) == 0) {
+ return;
+ }
+
+ ctx->needs_flush = true;
+
+ fd_resource(pfb->cbufs[0]->texture)->dirty = true;
+
+ /* figure out the buffers we need: */
+ buffers = FD_BUFFER_COLOR;
+ if (fd_depth_enabled(ctx)) {
+ buffers |= FD_BUFFER_DEPTH;
+ fd_resource(pfb->zsbuf->texture)->dirty = true;
+ }
+ if (fd_stencil_enabled(ctx)) {
+ buffers |= FD_BUFFER_STENCIL;
+ fd_resource(pfb->zsbuf->texture)->dirty = true;
+ }
+
+ /* any buffers that haven't been cleared, we need to restore: */
+ ctx->restore |= buffers & (FD_BUFFER_ALL & ~ctx->cleared);
+ /* and any buffers used, need to be resolved: */
+ ctx->resolve |= buffers;
+
+ ctx->draw(ctx, info);
+}
+
+/* TODO figure out how to make better use of existing state mechanism
+ * for clear (and possibly gmem->mem / mem->gmem) so we can (a) keep
+ * track of what state really actually changes, and (b) reduce the code
+ * in the a2xx/a3xx parts.
+ */
+
+static void
+fd_clear(struct pipe_context *pctx, unsigned buffers,
+ const union pipe_color_union *color, double depth, unsigned stencil)
+{
+ struct fd_context *ctx = fd_context(pctx);
+ struct pipe_framebuffer_state *pfb = &ctx->framebuffer;
+
+ ctx->cleared |= buffers;
+ ctx->resolve |= buffers;
+ ctx->needs_flush = true;
+
+ if (buffers & PIPE_CLEAR_COLOR)
+ fd_resource(pfb->cbufs[0]->texture)->dirty = true;
+
+ if (buffers & (PIPE_CLEAR_DEPTH | PIPE_CLEAR_STENCIL))
+ fd_resource(pfb->zsbuf->texture)->dirty = true;
+
+ DBG("%x depth=%f, stencil=%u (%s/%s)", buffers, depth, stencil,
+ util_format_name(pfb->cbufs[0]->format),
+ pfb->zsbuf ? util_format_name(pfb->zsbuf->format) : "none");
+
+ ctx->clear(ctx, buffers, color, depth, stencil);
+
+ ctx->dirty |= FD_DIRTY_ZSA |
+ FD_DIRTY_RASTERIZER |
+ FD_DIRTY_SAMPLE_MASK |
+ FD_DIRTY_PROG |
+ FD_DIRTY_CONSTBUF |
+ FD_DIRTY_BLEND;
+
+ if (fd_mesa_debug & FD_DBG_DCLEAR)
+ ctx->dirty = 0xffffffff;
+}
+
+static void
+fd_clear_render_target(struct pipe_context *pctx, struct pipe_surface *ps,
+ const union pipe_color_union *color,
+ unsigned x, unsigned y, unsigned w, unsigned h)
+{
+ DBG("TODO: x=%u, y=%u, w=%u, h=%u", x, y, w, h);
+}
+
+static void
+fd_clear_depth_stencil(struct pipe_context *pctx, struct pipe_surface *ps,
+ unsigned buffers, double depth, unsigned stencil,
+ unsigned x, unsigned y, unsigned w, unsigned h)
+{
+ DBG("TODO: buffers=%u, depth=%f, stencil=%u, x=%u, y=%u, w=%u, h=%u",
+ buffers, depth, stencil, x, y, w, h);
+}
+
+void
+fd_draw_init(struct pipe_context *pctx)
+{
+ pctx->draw_vbo = fd_draw_vbo;
+ pctx->clear = fd_clear;
+ pctx->clear_render_target = fd_clear_render_target;
+ pctx->clear_depth_stencil = fd_clear_depth_stencil;
+}
--- /dev/null
+/* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */
+
+/*
+ * Copyright (C) 2012 Rob Clark <robclark@freedesktop.org>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Authors:
+ * Rob Clark <robclark@freedesktop.org>
+ */
+
+#ifndef FREEDRENO_DRAW_H_
+#define FREEDRENO_DRAW_H_
+
+#include "pipe/p_state.h"
+#include "pipe/p_context.h"
+
+#include "freedreno_context.h"
+
+struct fd_ringbuffer;
+
+void fd_draw_emit(struct fd_context *ctx, const struct pipe_draw_info *info);
+
+void fd_draw_init(struct pipe_context *pctx);
+
+#endif /* FREEDRENO_DRAW_H_ */
#include "util/u_string.h"
#include "util/u_memory.h"
#include "util/u_inlines.h"
-#include "util/u_pack_color.h"
+#include "util/u_format.h"
#include "freedreno_gmem.h"
#include "freedreno_context.h"
-#include "freedreno_state.h"
-#include "freedreno_program.h"
#include "freedreno_resource.h"
-#include "freedreno_zsa.h"
#include "freedreno_util.h"
/*
* resolve.
*/
-static uint32_t fmt2swap(enum pipe_format format)
-{
- switch (format) {
- case PIPE_FORMAT_B8G8R8A8_UNORM:
- /* TODO probably some more.. */
- return 1;
- default:
- return 0;
- }
-}
-
-/* transfer from gmem to system memory (ie. normal RAM) */
-
-static void
-emit_gmem2mem_surf(struct fd_ringbuffer *ring, uint32_t base,
- struct pipe_surface *psurf)
-{
- struct fd_resource *rsc = fd_resource(psurf->texture);
- uint32_t swap = fmt2swap(psurf->format);
-
- OUT_PKT3(ring, CP_SET_CONSTANT, 2);
- OUT_RING(ring, CP_REG(REG_A2XX_RB_COLOR_INFO));
- OUT_RING(ring, A2XX_RB_COLOR_INFO_SWAP(swap) |
- A2XX_RB_COLOR_INFO_BASE(base / 1024) |
- A2XX_RB_COLOR_INFO_FORMAT(fd_pipe2color(psurf->format)));
-
- OUT_PKT3(ring, CP_SET_CONSTANT, 5);
- OUT_RING(ring, CP_REG(REG_A2XX_RB_COPY_CONTROL));
- OUT_RING(ring, 0x00000000); /* RB_COPY_CONTROL */
- OUT_RELOC(ring, rsc->bo, 0, 0); /* RB_COPY_DEST_BASE */
- OUT_RING(ring, rsc->pitch >> 5); /* RB_COPY_DEST_PITCH */
- OUT_RING(ring, /* RB_COPY_DEST_INFO */
- A2XX_RB_COPY_DEST_INFO_FORMAT(fd_pipe2color(psurf->format)) |
- A2XX_RB_COPY_DEST_INFO_LINEAR |
- A2XX_RB_COPY_DEST_INFO_SWAP(swap) |
- A2XX_RB_COPY_DEST_INFO_WRITE_RED |
- A2XX_RB_COPY_DEST_INFO_WRITE_GREEN |
- A2XX_RB_COPY_DEST_INFO_WRITE_BLUE |
- A2XX_RB_COPY_DEST_INFO_WRITE_ALPHA);
-
- OUT_PKT3(ring, CP_WAIT_FOR_IDLE, 1);
- OUT_RING(ring, 0x0000000);
-
- OUT_PKT3(ring, CP_DRAW_INDX, 3);
- OUT_RING(ring, 0x00000000);
- OUT_RING(ring, DRAW(DI_PT_RECTLIST, DI_SRC_SEL_AUTO_INDEX,
- INDEX_SIZE_IGN, IGNORE_VISIBILITY));
- OUT_RING(ring, 3); /* NumIndices */
-}
-
-static void
-emit_gmem2mem(struct fd_context *ctx, struct fd_ringbuffer *ring,
- uint32_t xoff, uint32_t yoff, uint32_t bin_w, uint32_t bin_h)
-{
- struct pipe_framebuffer_state *pfb = &ctx->framebuffer;
-
- fd_emit_vertex_bufs(ring, 0x9c, (struct fd_vertex_buf[]) {
- { .prsc = ctx->solid_vertexbuf, .size = 48 },
- }, 1);
-
- OUT_PKT3(ring, CP_SET_CONSTANT, 2);
- OUT_RING(ring, CP_REG(REG_A2XX_VGT_INDX_OFFSET));
- OUT_RING(ring, 0);
-
- OUT_PKT3(ring, CP_SET_CONSTANT, 2);
- OUT_RING(ring, CP_REG(REG_A2XX_VGT_VERTEX_REUSE_BLOCK_CNTL));
- OUT_RING(ring, 0x0000028f);
-
- fd_program_emit(ring, &ctx->solid_prog);
-
- OUT_PKT3(ring, CP_SET_CONSTANT, 2);
- OUT_RING(ring, CP_REG(REG_A2XX_PA_SC_AA_MASK));
- OUT_RING(ring, 0x0000ffff);
-
- OUT_PKT3(ring, CP_SET_CONSTANT, 2);
- OUT_RING(ring, CP_REG(REG_A2XX_RB_DEPTHCONTROL));
- OUT_RING(ring, A2XX_RB_DEPTHCONTROL_EARLY_Z_ENABLE);
-
- OUT_PKT3(ring, CP_SET_CONSTANT, 2);
- OUT_RING(ring, CP_REG(REG_A2XX_PA_SU_SC_MODE_CNTL));
- OUT_RING(ring, A2XX_PA_SU_SC_MODE_CNTL_PROVOKING_VTX_LAST | /* PA_SU_SC_MODE_CNTL */
- A2XX_PA_SU_SC_MODE_CNTL_FRONT_PTYPE(PC_DRAW_TRIANGLES) |
- A2XX_PA_SU_SC_MODE_CNTL_BACK_PTYPE(PC_DRAW_TRIANGLES));
-
- OUT_PKT3(ring, CP_SET_CONSTANT, 3);
- OUT_RING(ring, CP_REG(REG_A2XX_PA_SC_WINDOW_SCISSOR_TL));
- OUT_RING(ring, xy2d(0, 0)); /* PA_SC_WINDOW_SCISSOR_TL */
- OUT_RING(ring, xy2d(pfb->width, pfb->height)); /* PA_SC_WINDOW_SCISSOR_BR */
-
- OUT_PKT3(ring, CP_SET_CONSTANT, 2);
- OUT_RING(ring, CP_REG(REG_A2XX_PA_CL_VTE_CNTL));
- OUT_RING(ring, A2XX_PA_CL_VTE_CNTL_VTX_W0_FMT |
- A2XX_PA_CL_VTE_CNTL_VPORT_X_SCALE_ENA |
- A2XX_PA_CL_VTE_CNTL_VPORT_X_OFFSET_ENA |
- A2XX_PA_CL_VTE_CNTL_VPORT_Y_SCALE_ENA |
- A2XX_PA_CL_VTE_CNTL_VPORT_Y_OFFSET_ENA);
-
- OUT_PKT3(ring, CP_SET_CONSTANT, 2);
- OUT_RING(ring, CP_REG(REG_A2XX_PA_CL_CLIP_CNTL));
- OUT_RING(ring, 0x00000000);
-
- OUT_PKT3(ring, CP_SET_CONSTANT, 2);
- OUT_RING(ring, CP_REG(REG_A2XX_RB_MODECONTROL));
- OUT_RING(ring, A2XX_RB_MODECONTROL_EDRAM_MODE(EDRAM_COPY));
-
- OUT_PKT3(ring, CP_SET_CONSTANT, 2);
- OUT_RING(ring, CP_REG(REG_A2XX_RB_COPY_DEST_OFFSET));
- OUT_RING(ring, A2XX_RB_COPY_DEST_OFFSET_X(xoff) |
- A2XX_RB_COPY_DEST_OFFSET_Y(yoff));
-
- if (ctx->resolve & (FD_BUFFER_DEPTH | FD_BUFFER_STENCIL))
- emit_gmem2mem_surf(ring, bin_w * bin_h, pfb->zsbuf);
-
- if (ctx->resolve & FD_BUFFER_COLOR)
- emit_gmem2mem_surf(ring, 0, pfb->cbufs[0]);
-
- OUT_PKT3(ring, CP_SET_CONSTANT, 2);
- OUT_RING(ring, CP_REG(REG_A2XX_RB_MODECONTROL));
- OUT_RING(ring, A2XX_RB_MODECONTROL_EDRAM_MODE(COLOR_DEPTH));
-}
-
-/* transfer from system memory to gmem */
-
-static void
-emit_mem2gmem_surf(struct fd_ringbuffer *ring, uint32_t base,
- struct pipe_surface *psurf)
-{
- struct fd_resource *rsc = fd_resource(psurf->texture);
- uint32_t swiz;
-
- OUT_PKT3(ring, CP_SET_CONSTANT, 2);
- OUT_RING(ring, CP_REG(REG_A2XX_RB_COLOR_INFO));
- OUT_RING(ring, A2XX_RB_COLOR_INFO_SWAP(fmt2swap(psurf->format)) |
- A2XX_RB_COLOR_INFO_BASE(base) |
- A2XX_RB_COLOR_INFO_FORMAT(fd_pipe2color(psurf->format)));
-
- swiz = fd_tex_swiz(psurf->format, PIPE_SWIZZLE_RED, PIPE_SWIZZLE_GREEN,
- PIPE_SWIZZLE_BLUE, PIPE_SWIZZLE_ALPHA);
-
- /* emit fb as a texture: */
- OUT_PKT3(ring, CP_SET_CONSTANT, 7);
- OUT_RING(ring, 0x00010000);
- OUT_RING(ring, A2XX_SQ_TEX_0_CLAMP_X(SQ_TEX_WRAP) |
- A2XX_SQ_TEX_0_CLAMP_Y(SQ_TEX_WRAP) |
- A2XX_SQ_TEX_0_CLAMP_Z(SQ_TEX_WRAP) |
- A2XX_SQ_TEX_0_PITCH(rsc->pitch));
- OUT_RELOC(ring, rsc->bo, 0,
- fd_pipe2surface(psurf->format) | 0x800);
- OUT_RING(ring, A2XX_SQ_TEX_2_WIDTH(psurf->width - 1) |
- A2XX_SQ_TEX_2_HEIGHT(psurf->height - 1));
- OUT_RING(ring, 0x01000000 | // XXX
- swiz |
- A2XX_SQ_TEX_3_XY_MAG_FILTER(SQ_TEX_FILTER_POINT) |
- A2XX_SQ_TEX_3_XY_MIN_FILTER(SQ_TEX_FILTER_POINT));
- OUT_RING(ring, 0x00000000);
- OUT_RING(ring, 0x00000200);
-
- OUT_PKT3(ring, CP_DRAW_INDX, 3);
- OUT_RING(ring, 0x00000000);
- OUT_RING(ring, DRAW(DI_PT_RECTLIST, DI_SRC_SEL_AUTO_INDEX,
- INDEX_SIZE_IGN, IGNORE_VISIBILITY));
- OUT_RING(ring, 3); /* NumIndices */
-}
-
-static void
-emit_mem2gmem(struct fd_context *ctx, struct fd_ringbuffer *ring,
- uint32_t xoff, uint32_t yoff, uint32_t bin_w, uint32_t bin_h)
-{
- struct pipe_framebuffer_state *pfb = &ctx->framebuffer;
- float x0, y0, x1, y1;
-
- fd_emit_vertex_bufs(ring, 0x9c, (struct fd_vertex_buf[]) {
- { .prsc = ctx->solid_vertexbuf, .size = 48, .offset = 0x30 },
- { .prsc = ctx->solid_vertexbuf, .size = 32, .offset = 0x60 },
- }, 2);
-
- /* write texture coordinates to vertexbuf: */
- x0 = ((float)xoff) / ((float)pfb->width);
- x1 = ((float)xoff + bin_w) / ((float)pfb->width);
- y0 = ((float)yoff) / ((float)pfb->height);
- y1 = ((float)yoff + bin_h) / ((float)pfb->height);
- OUT_PKT3(ring, CP_MEM_WRITE, 9);
- OUT_RELOC(ring, fd_resource(ctx->solid_vertexbuf)->bo, 0x60, 0);
- OUT_RING(ring, fui(x0));
- OUT_RING(ring, fui(y0));
- OUT_RING(ring, fui(x1));
- OUT_RING(ring, fui(y0));
- OUT_RING(ring, fui(x0));
- OUT_RING(ring, fui(y1));
- OUT_RING(ring, fui(x1));
- OUT_RING(ring, fui(y1));
-
- OUT_PKT3(ring, CP_SET_CONSTANT, 2);
- OUT_RING(ring, CP_REG(REG_A2XX_VGT_INDX_OFFSET));
- OUT_RING(ring, 0);
-
- OUT_PKT3(ring, CP_SET_CONSTANT, 2);
- OUT_RING(ring, CP_REG(REG_A2XX_VGT_VERTEX_REUSE_BLOCK_CNTL));
- OUT_RING(ring, 0x0000003b);
-
- fd_program_emit(ring, &ctx->blit_prog);
-
- OUT_PKT0(ring, REG_A2XX_TC_CNTL_STATUS, 1);
- OUT_RING(ring, A2XX_TC_CNTL_STATUS_L2_INVALIDATE);
-
- OUT_PKT3(ring, CP_SET_CONSTANT, 2);
- OUT_RING(ring, CP_REG(REG_A2XX_RB_DEPTHCONTROL));
- OUT_RING(ring, A2XX_RB_DEPTHCONTROL_EARLY_Z_ENABLE);
-
- OUT_PKT3(ring, CP_SET_CONSTANT, 2);
- OUT_RING(ring, CP_REG(REG_A2XX_PA_SU_SC_MODE_CNTL));
- OUT_RING(ring, A2XX_PA_SU_SC_MODE_CNTL_PROVOKING_VTX_LAST |
- A2XX_PA_SU_SC_MODE_CNTL_FRONT_PTYPE(PC_DRAW_TRIANGLES) |
- A2XX_PA_SU_SC_MODE_CNTL_BACK_PTYPE(PC_DRAW_TRIANGLES));
-
- OUT_PKT3(ring, CP_SET_CONSTANT, 2);
- OUT_RING(ring, CP_REG(REG_A2XX_PA_SC_AA_MASK));
- OUT_RING(ring, 0x0000ffff);
-
- OUT_PKT3(ring, CP_SET_CONSTANT, 2);
- OUT_RING(ring, CP_REG(REG_A2XX_RB_COLORCONTROL));
- OUT_RING(ring, A2XX_RB_COLORCONTROL_ALPHA_FUNC(PIPE_FUNC_ALWAYS) |
- A2XX_RB_COLORCONTROL_BLEND_DISABLE |
- A2XX_RB_COLORCONTROL_ROP_CODE(12) |
- A2XX_RB_COLORCONTROL_DITHER_MODE(DITHER_DISABLE) |
- A2XX_RB_COLORCONTROL_DITHER_TYPE(DITHER_PIXEL));
-
- OUT_PKT3(ring, CP_SET_CONSTANT, 2);
- OUT_RING(ring, CP_REG(REG_A2XX_RB_BLEND_CONTROL));
- OUT_RING(ring, A2XX_RB_BLEND_CONTROL_COLOR_SRCBLEND(FACTOR_ONE) |
- A2XX_RB_BLEND_CONTROL_COLOR_COMB_FCN(BLEND_DST_PLUS_SRC) |
- A2XX_RB_BLEND_CONTROL_COLOR_DESTBLEND(FACTOR_ZERO) |
- A2XX_RB_BLEND_CONTROL_ALPHA_SRCBLEND(FACTOR_ONE) |
- A2XX_RB_BLEND_CONTROL_ALPHA_COMB_FCN(BLEND_DST_PLUS_SRC) |
- A2XX_RB_BLEND_CONTROL_ALPHA_DESTBLEND(FACTOR_ZERO));
-
- OUT_PKT3(ring, CP_SET_CONSTANT, 3);
- OUT_RING(ring, CP_REG(REG_A2XX_PA_SC_WINDOW_SCISSOR_TL));
- OUT_RING(ring, A2XX_PA_SC_WINDOW_OFFSET_DISABLE |
- xy2d(0,0)); /* PA_SC_WINDOW_SCISSOR_TL */
- OUT_RING(ring, xy2d(bin_w, bin_h)); /* PA_SC_WINDOW_SCISSOR_BR */
-
- OUT_PKT3(ring, CP_SET_CONSTANT, 5);
- OUT_RING(ring, CP_REG(REG_A2XX_PA_CL_VPORT_XSCALE));
- OUT_RING(ring, fui((float)bin_w/2.0)); /* PA_CL_VPORT_XSCALE */
- OUT_RING(ring, fui((float)bin_w/2.0)); /* PA_CL_VPORT_XOFFSET */
- OUT_RING(ring, fui(-(float)bin_h/2.0)); /* PA_CL_VPORT_YSCALE */
- OUT_RING(ring, fui((float)bin_h/2.0)); /* PA_CL_VPORT_YOFFSET */
-
- OUT_PKT3(ring, CP_SET_CONSTANT, 2);
- OUT_RING(ring, CP_REG(REG_A2XX_PA_CL_VTE_CNTL));
- OUT_RING(ring, A2XX_PA_CL_VTE_CNTL_VTX_XY_FMT |
- A2XX_PA_CL_VTE_CNTL_VTX_Z_FMT | // XXX check this???
- A2XX_PA_CL_VTE_CNTL_VPORT_X_SCALE_ENA |
- A2XX_PA_CL_VTE_CNTL_VPORT_X_OFFSET_ENA |
- A2XX_PA_CL_VTE_CNTL_VPORT_Y_SCALE_ENA |
- A2XX_PA_CL_VTE_CNTL_VPORT_Y_OFFSET_ENA);
-
- OUT_PKT3(ring, CP_SET_CONSTANT, 2);
- OUT_RING(ring, CP_REG(REG_A2XX_PA_CL_CLIP_CNTL));
- OUT_RING(ring, 0x00000000);
-
- if (ctx->restore & (FD_BUFFER_DEPTH | FD_BUFFER_STENCIL))
- emit_mem2gmem_surf(ring, bin_w * bin_h, pfb->zsbuf);
-
- if (ctx->restore & FD_BUFFER_COLOR)
- emit_mem2gmem_surf(ring, 0, pfb->cbufs[0]);
-
- /* TODO blob driver seems to toss in a CACHE_FLUSH after each DRAW_INDX.. */
-}
-
static void
calculate_tiles(struct fd_context *ctx)
{
gmem->height = height;
}
+
void
fd_gmem_render_tiles(struct pipe_context *pctx)
{
struct fd_context *ctx = fd_context(pctx);
struct pipe_framebuffer_state *pfb = &ctx->framebuffer;
struct fd_gmem_stateobj *gmem = &ctx->gmem;
- struct fd_ringbuffer *ring = ctx->ring;
- enum a2xx_colorformatx colorformatx = fd_pipe2color(pfb->cbufs[0]->format);
uint32_t i, timestamp, yoff = 0;
- uint32_t reg;
calculate_tiles(ctx);
/* mark the end of the clear/draw cmds before emitting per-tile cmds: */
fd_ringmarker_mark(ctx->draw_end);
- /* RB_SURFACE_INFO / RB_DEPTH_INFO can be emitted once per tile pass,
- * but RB_COLOR_INFO gets overwritten by gmem2mem and mem2gmem and so
- * needs to be emitted for each tile:
- */
- OUT_PKT3(ring, CP_SET_CONSTANT, 4);
- OUT_RING(ring, CP_REG(REG_A2XX_RB_SURFACE_INFO));
- OUT_RING(ring, gmem->bin_w); /* RB_SURFACE_INFO */
- OUT_RING(ring, A2XX_RB_COLOR_INFO_SWAP(1) | /* RB_COLOR_INFO */
- A2XX_RB_COLOR_INFO_FORMAT(colorformatx));
- reg = A2XX_RB_DEPTH_INFO_DEPTH_BASE(align(gmem->bin_w * gmem->bin_h, 4));
- if (pfb->zsbuf)
- reg |= A2XX_RB_DEPTH_INFO_DEPTH_FORMAT(fd_pipe2depth(pfb->zsbuf->format));
- OUT_RING(ring, reg); /* RB_DEPTH_INFO */
-
yoff= gmem->miny;
+
+ ctx->emit_tile_init(ctx);
+
for (i = 0; i < gmem->nbins_y; i++) {
uint32_t j, xoff = gmem->minx;
uint32_t bh = gmem->bin_h;
DBG("bin_h=%d, yoff=%d, bin_w=%d, xoff=%d",
bh, yoff, bw, xoff);
- /* setup screen scissor for current tile (same for mem2gmem): */
- OUT_PKT3(ring, CP_SET_CONSTANT, 3);
- OUT_RING(ring, CP_REG(REG_A2XX_PA_SC_SCREEN_SCISSOR_TL));
- OUT_RING(ring, xy2d(0,0)); /* PA_SC_SCREEN_SCISSOR_TL */
- OUT_RING(ring, xy2d(bw, bh)); /* PA_SC_SCREEN_SCISSOR_BR */
+ ctx->emit_tile_prep(ctx, xoff, yoff, bw, bh);
if (ctx->restore)
- emit_mem2gmem(ctx, ring, xoff, yoff, bw, bh);
-
- OUT_PKT3(ring, CP_SET_CONSTANT, 2);
- OUT_RING(ring, CP_REG(REG_A2XX_RB_COLOR_INFO));
- OUT_RING(ring, A2XX_RB_COLOR_INFO_SWAP(1) | /* RB_COLOR_INFO */
- A2XX_RB_COLOR_INFO_FORMAT(colorformatx));
+ ctx->emit_tile_mem2gmem(ctx, xoff, yoff, bw, bh);
- /* setup window scissor and offset for current tile (different
- * from mem2gmem):
- */
- OUT_PKT3(ring, CP_SET_CONSTANT, 2);
- OUT_RING(ring, CP_REG(REG_A2XX_PA_SC_WINDOW_OFFSET));
- OUT_RING(ring, A2XX_PA_SC_WINDOW_OFFSET_X(-xoff) |
- A2XX_PA_SC_WINDOW_OFFSET_Y(-yoff));/* PA_SC_WINDOW_OFFSET */
+ ctx->emit_tile_renderprep(ctx, xoff, yoff, bw, bh);
/* emit IB to drawcmds: */
- OUT_IB (ring, ctx->draw_start, ctx->draw_end);
-
- OUT_PKT3(ring, CP_SET_CONSTANT, 2);
- OUT_RING(ring, CP_REG(REG_A2XX_PA_SC_WINDOW_OFFSET));
- OUT_RING(ring, 0x00000000); /* PA_SC_WINDOW_OFFSET */
+ OUT_IB(ctx->ring, ctx->draw_start, ctx->draw_end);
/* emit gmem2mem to transfer tile back to system memory: */
- emit_gmem2mem(ctx, ring, xoff, yoff, bw, bh);
+ ctx->emit_tile_gmem2mem(ctx, xoff, yoff, bw, bh);
xoff += bw;
}
fd_ringmarker_mark(ctx->draw_start);
/* update timestamps on render targets: */
- fd_pipe_timestamp(ctx->screen->pipe, ×tamp);
+ timestamp = fd_ringbuffer_timestamp(ctx->ring);
fd_resource(pfb->cbufs[0]->texture)->timestamp = timestamp;
if (pfb->zsbuf)
fd_resource(pfb->zsbuf->texture)->timestamp = timestamp;
+++ /dev/null
-/* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */
-
-/*
- * Copyright (C) 2012 Rob Clark <robclark@freedesktop.org>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Authors:
- * Rob Clark <robclark@freedesktop.org>
- */
-
-#include "pipe/p_state.h"
-#include "util/u_string.h"
-#include "util/u_memory.h"
-#include "util/u_inlines.h"
-#include "util/u_format.h"
-#include "tgsi/tgsi_dump.h"
-#include "tgsi/tgsi_parse.h"
-
-#include "freedreno_program.h"
-#include "freedreno_compiler.h"
-#include "freedreno_vbo.h"
-#include "freedreno_texture.h"
-#include "freedreno_util.h"
-
-static struct fd_shader_stateobj *
-create_shader(enum shader_t type)
-{
- struct fd_shader_stateobj *so = CALLOC_STRUCT(fd_shader_stateobj);
- if (!so)
- return NULL;
- so->type = type;
- return so;
-}
-
-static void
-delete_shader(struct fd_shader_stateobj *so)
-{
- ir2_shader_destroy(so->ir);
- FREE(so->tokens);
- FREE(so);
-}
-
-static struct fd_shader_stateobj *
-assemble(struct fd_shader_stateobj *so)
-{
- free(so->bin);
- so->bin = ir2_shader_assemble(so->ir, &so->info);
- if (!so->bin)
- goto fail;
-
- if (fd_mesa_debug & FD_DBG_DISASM) {
- DBG("disassemble: type=%d", so->type);
- disasm(so->bin, so->info.sizedwords, 0, so->type);
- }
-
- return so;
-
-fail:
- debug_error("assemble failed!");
- delete_shader(so);
- return NULL;
-}
-
-static struct fd_shader_stateobj *
-compile(struct fd_program_stateobj *prog, struct fd_shader_stateobj *so)
-{
- int ret;
-
- if (fd_mesa_debug & FD_DBG_DISASM) {
- DBG("dump tgsi: type=%d", so->type);
- tgsi_dump(so->tokens, 0);
- }
-
- ret = fd_compile_shader(prog, so);
- if (ret)
- goto fail;
-
- /* NOTE: we don't assemble yet because for VS we don't know the
- * type information for vertex fetch yet.. so those need to be
- * patched up later before assembling.
- */
-
- so->info.sizedwords = 0;
-
- return so;
-
-fail:
- debug_error("compile failed!");
- delete_shader(so);
- return NULL;
-}
-
-static void
-emit(struct fd_ringbuffer *ring, struct fd_shader_stateobj *so)
-{
- unsigned i;
-
- if (so->info.sizedwords == 0)
- assemble(so);
-
- OUT_PKT3(ring, CP_IM_LOAD_IMMEDIATE, 2 + so->info.sizedwords);
- OUT_RING(ring, (so->type == SHADER_VERTEX) ? 0 : 1);
- OUT_RING(ring, so->info.sizedwords);
- for (i = 0; i < so->info.sizedwords; i++)
- OUT_RING(ring, so->bin[i]);
-}
-
-static void *
-fd_fp_state_create(struct pipe_context *pctx,
- const struct pipe_shader_state *cso)
-{
- struct fd_shader_stateobj *so = create_shader(SHADER_FRAGMENT);
- if (!so)
- return NULL;
- so->tokens = tgsi_dup_tokens(cso->tokens);
- return so;
-}
-
-static void
-fd_fp_state_delete(struct pipe_context *pctx, void *hwcso)
-{
- struct fd_shader_stateobj *so = hwcso;
- delete_shader(so);
-}
-
-static void
-fd_fp_state_bind(struct pipe_context *pctx, void *hwcso)
-{
- struct fd_context *ctx = fd_context(pctx);
- ctx->prog.fp = hwcso;
- ctx->prog.dirty |= FD_SHADER_DIRTY_FP;
- ctx->dirty |= FD_DIRTY_PROG;
-}
-
-static void *
-fd_vp_state_create(struct pipe_context *pctx,
- const struct pipe_shader_state *cso)
-{
- struct fd_shader_stateobj *so = create_shader(SHADER_VERTEX);
- if (!so)
- return NULL;
- so->tokens = tgsi_dup_tokens(cso->tokens);
- return so;
-}
-
-static void
-fd_vp_state_delete(struct pipe_context *pctx, void *hwcso)
-{
- struct fd_shader_stateobj *so = hwcso;
- delete_shader(so);
-}
-
-static void
-fd_vp_state_bind(struct pipe_context *pctx, void *hwcso)
-{
- struct fd_context *ctx = fd_context(pctx);
- ctx->prog.vp = hwcso;
- ctx->prog.dirty |= FD_SHADER_DIRTY_VP;
- ctx->dirty |= FD_DIRTY_PROG;
-}
-
-static void
-patch_vtx_fetches(struct fd_context *ctx, struct fd_shader_stateobj *so,
- struct fd_vertex_stateobj *vtx)
-{
- unsigned i;
-
- assert(so->num_vfetch_instrs == vtx->num_elements);
-
- /* update vtx fetch instructions: */
- for (i = 0; i < so->num_vfetch_instrs; i++) {
- struct ir2_instruction *instr = so->vfetch_instrs[i];
- struct pipe_vertex_element *elem = &vtx->pipe[i];
- struct pipe_vertex_buffer *vb =
- &ctx->vertexbuf.vb[elem->vertex_buffer_index];
- enum pipe_format format = elem->src_format;
- const struct util_format_description *desc =
- util_format_description(format);
- unsigned j;
-
- /* Find the first non-VOID channel. */
- for (j = 0; j < 4; j++)
- if (desc->channel[j].type != UTIL_FORMAT_TYPE_VOID)
- break;
-
- /* CI/CIS can probably be set in compiler instead: */
- instr->fetch.const_idx = 20 + (i / 3);
- instr->fetch.const_idx_sel = i % 3;
-
- instr->fetch.fmt = fd_pipe2surface(format);
- instr->fetch.is_normalized = desc->channel[j].normalized;
- instr->fetch.is_signed =
- desc->channel[j].type == UTIL_FORMAT_TYPE_SIGNED;
- instr->fetch.stride = vb->stride ? : 1;
- instr->fetch.offset = elem->src_offset;
-
- for (j = 0; j < 4; j++)
- instr->regs[0]->swizzle[j] = "xyzw01__"[desc->swizzle[j]];
-
- assert(instr->fetch.fmt != FMT_INVALID);
-
- DBG("vtx[%d]: %s (%d), ci=%d, cis=%d, id=%d, swizzle=%s, "
- "stride=%d, offset=%d",
- i, util_format_name(format),
- instr->fetch.fmt,
- instr->fetch.const_idx,
- instr->fetch.const_idx_sel,
- elem->instance_divisor,
- instr->regs[0]->swizzle,
- instr->fetch.stride,
- instr->fetch.offset);
- }
-
- /* trigger re-assemble: */
- so->info.sizedwords = 0;
-}
-
-static void
-patch_tex_fetches(struct fd_context *ctx, struct fd_shader_stateobj *so,
- struct fd_texture_stateobj *tex)
-{
- unsigned i;
-
- /* update tex fetch instructions: */
- for (i = 0; i < so->num_tfetch_instrs; i++) {
- struct ir2_instruction *instr = so->tfetch_instrs[i].instr;
- unsigned samp_id = so->tfetch_instrs[i].samp_id;
- unsigned const_idx = fd_get_const_idx(ctx, tex, samp_id);
-
- if (const_idx != instr->fetch.const_idx) {
- instr->fetch.const_idx = const_idx;
- /* trigger re-assemble: */
- so->info.sizedwords = 0;
- }
- }
-}
-
-void
-fd_program_validate(struct fd_context *ctx)
-{
- struct fd_program_stateobj *prog = &ctx->prog;
-
- /* if vertex or frag shader is dirty, we may need to recompile. Compile
- * frag shader first, as that assigns the register slots for exports
- * from the vertex shader. And therefore if frag shader has changed we
- * need to recompile both vert and frag shader.
- */
- if (prog->dirty & FD_SHADER_DIRTY_FP)
- compile(prog, prog->fp);
-
- if (prog->dirty & (FD_SHADER_DIRTY_FP | FD_SHADER_DIRTY_VP))
- compile(prog, prog->vp);
-
- if (prog->dirty)
- ctx->dirty |= FD_DIRTY_PROG;
-
- prog->dirty = 0;
-
- /* if necessary, fix up vertex fetch instructions: */
- if (ctx->dirty & (FD_DIRTY_VTXSTATE | FD_DIRTY_PROG))
- patch_vtx_fetches(ctx, prog->vp, ctx->vtx);
-
- /* if necessary, fix up texture fetch instructions: */
- if (ctx->dirty & (FD_DIRTY_TEXSTATE | FD_DIRTY_PROG)) {
- patch_tex_fetches(ctx, prog->vp, &ctx->verttex);
- patch_tex_fetches(ctx, prog->fp, &ctx->fragtex);
- }
-}
-
-void
-fd_program_emit(struct fd_ringbuffer *ring,
- struct fd_program_stateobj *prog)
-{
- struct ir2_shader_info *vsi = &prog->vp->info;
- struct ir2_shader_info *fsi = &prog->fp->info;
- uint8_t vs_gprs, fs_gprs, vs_export;
-
- emit(ring, prog->vp);
- emit(ring, prog->fp);
-
- vs_gprs = (vsi->max_reg < 0) ? 0x80 : vsi->max_reg;
- fs_gprs = (fsi->max_reg < 0) ? 0x80 : fsi->max_reg;
- vs_export = MAX2(1, prog->num_exports) - 1;
-
- OUT_PKT3(ring, CP_SET_CONSTANT, 2);
- OUT_RING(ring, CP_REG(REG_A2XX_SQ_PROGRAM_CNTL));
- OUT_RING(ring, A2XX_SQ_PROGRAM_CNTL_PS_EXPORT_MODE(POSITION_2_VECTORS_SPRITE) |
- A2XX_SQ_PROGRAM_CNTL_VS_RESOURCE |
- A2XX_SQ_PROGRAM_CNTL_PS_RESOURCE |
- A2XX_SQ_PROGRAM_CNTL_VS_EXPORT_COUNT(vs_export) |
- A2XX_SQ_PROGRAM_CNTL_PS_REGS(fs_gprs) |
- A2XX_SQ_PROGRAM_CNTL_VS_REGS(vs_gprs));
-}
-
-/* Creates shader:
- * EXEC ADDR(0x2) CNT(0x1)
- * (S)FETCH: SAMPLE R0.xyzw = R0.xyx CONST(0) LOCATION(CENTER)
- * ALLOC PARAM/PIXEL SIZE(0x0)
- * EXEC_END ADDR(0x3) CNT(0x1)
- * ALU: MAXv export0 = R0, R0 ; gl_FragColor
- * NOP
- */
-static struct fd_shader_stateobj *
-create_blit_fp(void)
-{
- struct fd_shader_stateobj *so = create_shader(SHADER_FRAGMENT);
- struct ir2_cf *cf;
- struct ir2_instruction *instr;
-
- if (!so)
- return NULL;
-
- so->ir = ir2_shader_create();
-
- cf = ir2_cf_create(so->ir, EXEC);
-
- instr = ir2_instr_create_tex_fetch(cf, 0);
- ir2_reg_create(instr, 0, "xyzw", 0);
- ir2_reg_create(instr, 0, "xyx", 0);
- instr->sync = true;
-
- cf = ir2_cf_create_alloc(so->ir, SQ_PARAMETER_PIXEL, 0);
- cf = ir2_cf_create(so->ir, EXEC_END);
-
- instr = ir2_instr_create_alu(cf, MAXv, ~0);
- ir2_reg_create(instr, 0, NULL, IR2_REG_EXPORT);
- ir2_reg_create(instr, 0, NULL, 0);
- ir2_reg_create(instr, 0, NULL, 0);
-
- return assemble(so);
-}
-
-/* Creates shader:
-* EXEC ADDR(0x3) CNT(0x2)
-* FETCH: VERTEX R1.xy01 = R0.x FMT_32_32_FLOAT UNSIGNED STRIDE(8) CONST(26, 1)
-* FETCH: VERTEX R2.xyz1 = R0.x FMT_32_32_32_FLOAT UNSIGNED STRIDE(12) CONST(26, 0)
-* ALLOC POSITION SIZE(0x0)
-* EXEC ADDR(0x5) CNT(0x1)
-* ALU: MAXv export62 = R2, R2 ; gl_Position
-* ALLOC PARAM/PIXEL SIZE(0x0)
-* EXEC_END ADDR(0x6) CNT(0x1)
-* ALU: MAXv export0 = R1, R1
-* NOP
- */
-static struct fd_shader_stateobj *
-create_blit_vp(void)
-{
- struct fd_shader_stateobj *so = create_shader(SHADER_VERTEX);
- struct ir2_cf *cf;
- struct ir2_instruction *instr;
-
- if (!so)
- return NULL;
-
- so->ir = ir2_shader_create();
-
- cf = ir2_cf_create(so->ir, EXEC);
-
- instr = ir2_instr_create_vtx_fetch(cf, 26, 1, FMT_32_32_FLOAT, false, 8);
- instr->fetch.is_normalized = true;
- ir2_reg_create(instr, 1, "xy01", 0);
- ir2_reg_create(instr, 0, "x", 0);
-
- instr = ir2_instr_create_vtx_fetch(cf, 26, 0, FMT_32_32_32_FLOAT, false, 12);
- instr->fetch.is_normalized = true;
- ir2_reg_create(instr, 2, "xyz1", 0);
- ir2_reg_create(instr, 0, "x", 0);
-
- cf = ir2_cf_create_alloc(so->ir, SQ_POSITION, 0);
- cf = ir2_cf_create(so->ir, EXEC);
-
- instr = ir2_instr_create_alu(cf, MAXv, ~0);
- ir2_reg_create(instr, 62, NULL, IR2_REG_EXPORT);
- ir2_reg_create(instr, 2, NULL, 0);
- ir2_reg_create(instr, 2, NULL, 0);
-
- cf = ir2_cf_create_alloc(so->ir, SQ_PARAMETER_PIXEL, 0);
- cf = ir2_cf_create(so->ir, EXEC_END);
-
- instr = ir2_instr_create_alu(cf, MAXv, ~0);
- ir2_reg_create(instr, 0, NULL, IR2_REG_EXPORT);
- ir2_reg_create(instr, 1, NULL, 0);
- ir2_reg_create(instr, 1, NULL, 0);
-
- return assemble(so);
-}
-
-/* Creates shader:
- * ALLOC PARAM/PIXEL SIZE(0x0)
- * EXEC_END ADDR(0x1) CNT(0x1)
- * ALU: MAXv export0 = C0, C0 ; gl_FragColor
- */
-static struct fd_shader_stateobj *
-create_solid_fp(void)
-{
- struct fd_shader_stateobj *so = create_shader(SHADER_FRAGMENT);
- struct ir2_cf *cf;
- struct ir2_instruction *instr;
-
- if (!so)
- return NULL;
-
- so->ir = ir2_shader_create();
-
- cf = ir2_cf_create_alloc(so->ir, SQ_PARAMETER_PIXEL, 0);
- cf = ir2_cf_create(so->ir, EXEC_END);
-
- instr = ir2_instr_create_alu(cf, MAXv, ~0);
- ir2_reg_create(instr, 0, NULL, IR2_REG_EXPORT);
- ir2_reg_create(instr, 0, NULL, IR2_REG_CONST);
- ir2_reg_create(instr, 0, NULL, IR2_REG_CONST);
-
- return assemble(so);
-}
-
-/* Creates shader:
- * EXEC ADDR(0x3) CNT(0x1)
- * (S)FETCH: VERTEX R1.xyz1 = R0.x FMT_32_32_32_FLOAT
- * UNSIGNED STRIDE(12) CONST(26, 0)
- * ALLOC POSITION SIZE(0x0)
- * EXEC ADDR(0x4) CNT(0x1)
- * ALU: MAXv export62 = R1, R1 ; gl_Position
- * ALLOC PARAM/PIXEL SIZE(0x0)
- * EXEC_END ADDR(0x5) CNT(0x0)
- */
-static struct fd_shader_stateobj *
-create_solid_vp(void)
-{
- struct fd_shader_stateobj *so = create_shader(SHADER_VERTEX);
- struct ir2_cf *cf;
- struct ir2_instruction *instr;
-
- if (!so)
- return NULL;
-
- so->ir = ir2_shader_create();
-
- cf = ir2_cf_create(so->ir, EXEC);
-
- instr = ir2_instr_create_vtx_fetch(cf, 26, 0, FMT_32_32_32_FLOAT, false, 12);
- ir2_reg_create(instr, 1, "xyz1", 0);
- ir2_reg_create(instr, 0, "x", 0);
-
- cf = ir2_cf_create_alloc(so->ir, SQ_POSITION, 0);
- cf = ir2_cf_create(so->ir, EXEC);
-
- instr = ir2_instr_create_alu(cf, MAXv, ~0);
- ir2_reg_create(instr, 62, NULL, IR2_REG_EXPORT);
- ir2_reg_create(instr, 1, NULL, 0);
- ir2_reg_create(instr, 1, NULL, 0);
-
- cf = ir2_cf_create_alloc(so->ir, SQ_PARAMETER_PIXEL, 0);
- cf = ir2_cf_create(so->ir, EXEC_END);
-
- return assemble(so);
-}
-
-void
-fd_prog_init(struct pipe_context *pctx)
-{
- struct fd_context *ctx = fd_context(pctx);
-
- pctx->create_fs_state = fd_fp_state_create;
- pctx->bind_fs_state = fd_fp_state_bind;
- pctx->delete_fs_state = fd_fp_state_delete;
-
- pctx->create_vs_state = fd_vp_state_create;
- pctx->bind_vs_state = fd_vp_state_bind;
- pctx->delete_vs_state = fd_vp_state_delete;
-
- ctx->solid_prog.fp = create_solid_fp();
- ctx->solid_prog.vp = create_solid_vp();
- ctx->blit_prog.fp = create_blit_fp();
- ctx->blit_prog.vp = create_blit_vp();
-}
-
-void
-fd_prog_fini(struct pipe_context *pctx)
-{
- struct fd_context *ctx = fd_context(pctx);
-
- delete_shader(ctx->solid_prog.vp);
- delete_shader(ctx->solid_prog.fp);
- delete_shader(ctx->blit_prog.vp);
- delete_shader(ctx->blit_prog.fp);
-}
+++ /dev/null
-/* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */
-
-/*
- * Copyright (C) 2012 Rob Clark <robclark@freedesktop.org>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Authors:
- * Rob Clark <robclark@freedesktop.org>
- */
-
-#ifndef FREEDRENO_PROGRAM_H_
-#define FREEDRENO_PROGRAM_H_
-
-#include "pipe/p_context.h"
-
-#include "freedreno_context.h"
-
-#include "ir-a2xx.h"
-#include "disasm.h"
-
-struct fd_shader_stateobj {
- enum shader_t type;
-
- uint32_t *bin;
-
- struct tgsi_token *tokens;
-
- /* note that we defer compiling shader until we know both vs and ps..
- * and if one changes, we potentially need to recompile in order to
- * get varying linkages correct:
- */
- struct ir2_shader_info info;
- struct ir2_shader *ir;
-
- /* for vertex shaders, the fetch instructions which need to be
- * patched up before assembly:
- */
- unsigned num_vfetch_instrs;
- struct ir2_instruction *vfetch_instrs[64];
-
- /* for all shaders, any tex fetch instructions which need to be
- * patched before assembly:
- */
- unsigned num_tfetch_instrs;
- struct {
- unsigned samp_id;
- struct ir2_instruction *instr;
- } tfetch_instrs[64];
-
- unsigned first_immediate; /* const reg # of first immediate */
- unsigned num_immediates;
- struct {
- uint32_t val[4];
- } immediates[64];
-};
-
-void fd_program_emit(struct fd_ringbuffer *ring,
- struct fd_program_stateobj *prog);
-void fd_program_validate(struct fd_context *ctx);
-
-void fd_prog_init(struct pipe_context *pctx);
-void fd_prog_fini(struct pipe_context *pctx);
-
-#endif /* FREEDRENO_PROGRAM_H_ */
+++ /dev/null
-/* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */
-
-/*
- * Copyright (C) 2012 Rob Clark <robclark@freedesktop.org>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Authors:
- * Rob Clark <robclark@freedesktop.org>
- */
-
-
-#include "pipe/p_state.h"
-#include "util/u_string.h"
-#include "util/u_memory.h"
-
-#include "freedreno_rasterizer.h"
-#include "freedreno_context.h"
-#include "freedreno_util.h"
-
-
-static enum adreno_pa_su_sc_draw
-polygon_mode(unsigned mode)
-{
- switch (mode) {
- case PIPE_POLYGON_MODE_POINT:
- return PC_DRAW_POINTS;
- case PIPE_POLYGON_MODE_LINE:
- return PC_DRAW_LINES;
- case PIPE_POLYGON_MODE_FILL:
- return PC_DRAW_TRIANGLES;
- default:
- DBG("invalid polygon mode: %u", mode);
- return 0;
- }
-}
-
-static void *
-fd_rasterizer_state_create(struct pipe_context *pctx,
- const struct pipe_rasterizer_state *cso)
-{
- struct fd_rasterizer_stateobj *so;
- float psize_min, psize_max;
-
- so = CALLOC_STRUCT(fd_rasterizer_stateobj);
- if (!so)
- return NULL;
-
- if (cso->point_size_per_vertex) {
- psize_min = util_get_min_point_size(cso);
- psize_max = 8192;
- } else {
- /* Force the point size to be as if the vertex output was disabled. */
- psize_min = cso->point_size;
- psize_max = cso->point_size;
- }
-
- so->base = *cso;
-
- so->pa_sc_line_stipple = cso->line_stipple_enable ?
- A2XX_PA_SC_LINE_STIPPLE_LINE_PATTERN(cso->line_stipple_pattern) |
- A2XX_PA_SC_LINE_STIPPLE_REPEAT_COUNT(cso->line_stipple_factor) : 0;
-
- so->pa_cl_clip_cntl = 0; // TODO
-
- so->pa_su_vtx_cntl =
- A2XX_PA_SU_VTX_CNTL_PIX_CENTER(cso->half_pixel_center ? PIXCENTER_OGL : PIXCENTER_D3D) |
- A2XX_PA_SU_VTX_CNTL_QUANT_MODE(ONE_SIXTEENTH);
-
- so->pa_su_point_size =
- A2XX_PA_SU_POINT_SIZE_HEIGHT(cso->point_size/2) |
- A2XX_PA_SU_POINT_SIZE_WIDTH(cso->point_size/2);
-
- so->pa_su_point_minmax =
- A2XX_PA_SU_POINT_MINMAX_MIN(psize_min/2) |
- A2XX_PA_SU_POINT_MINMAX_MAX(psize_max/2);
-
- so->pa_su_line_cntl =
- A2XX_PA_SU_LINE_CNTL_WIDTH(cso->line_width/2);
-
- so->pa_su_sc_mode_cntl =
- A2XX_PA_SU_SC_MODE_CNTL_VTX_WINDOW_OFFSET_ENABLE |
- A2XX_PA_SU_SC_MODE_CNTL_FRONT_PTYPE(polygon_mode(cso->fill_front)) |
- A2XX_PA_SU_SC_MODE_CNTL_BACK_PTYPE(polygon_mode(cso->fill_back));
-
- if (cso->cull_face & PIPE_FACE_FRONT)
- so->pa_su_sc_mode_cntl |= A2XX_PA_SU_SC_MODE_CNTL_CULL_FRONT;
- if (cso->cull_face & PIPE_FACE_BACK)
- so->pa_su_sc_mode_cntl |= A2XX_PA_SU_SC_MODE_CNTL_CULL_BACK;
- if (!cso->flatshade_first)
- so->pa_su_sc_mode_cntl |= A2XX_PA_SU_SC_MODE_CNTL_PROVOKING_VTX_LAST;
- if (!cso->front_ccw)
- so->pa_su_sc_mode_cntl |= A2XX_PA_SU_SC_MODE_CNTL_FACE;
- if (cso->line_stipple_enable)
- so->pa_su_sc_mode_cntl |= A2XX_PA_SU_SC_MODE_CNTL_LINE_STIPPLE_ENABLE;
- if (cso->multisample)
- so->pa_su_sc_mode_cntl |= A2XX_PA_SU_SC_MODE_CNTL_MSAA_ENABLE;
-
- if (cso->fill_front != PIPE_POLYGON_MODE_FILL ||
- cso->fill_back != PIPE_POLYGON_MODE_FILL)
- so->pa_su_sc_mode_cntl |= A2XX_PA_SU_SC_MODE_CNTL_POLYMODE(POLY_DUALMODE);
- else
- so->pa_su_sc_mode_cntl |= A2XX_PA_SU_SC_MODE_CNTL_POLYMODE(POLY_DISABLED);
-
- if (cso->offset_tri)
- so->pa_su_sc_mode_cntl |=
- A2XX_PA_SU_SC_MODE_CNTL_POLY_OFFSET_FRONT_ENABLE |
- A2XX_PA_SU_SC_MODE_CNTL_POLY_OFFSET_BACK_ENABLE |
- A2XX_PA_SU_SC_MODE_CNTL_POLY_OFFSET_PARA_ENABLE;
-
- return so;
-}
-
-static void
-fd_rasterizer_state_bind(struct pipe_context *pctx, void *hwcso)
-{
- struct fd_context *ctx = fd_context(pctx);
- ctx->rasterizer = hwcso;
- ctx->dirty |= FD_DIRTY_RASTERIZER;
-}
-
-static void
-fd_rasterizer_state_delete(struct pipe_context *pctx, void *hwcso)
-{
- FREE(hwcso);
-}
-
-void
-fd_rasterizer_init(struct pipe_context *pctx)
-{
- pctx->create_rasterizer_state = fd_rasterizer_state_create;
- pctx->bind_rasterizer_state = fd_rasterizer_state_bind;
- pctx->delete_rasterizer_state = fd_rasterizer_state_delete;
-}
+++ /dev/null
-/* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */
-
-/*
- * Copyright (C) 2012 Rob Clark <robclark@freedesktop.org>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Authors:
- * Rob Clark <robclark@freedesktop.org>
- */
-
-#ifndef FREEDRENO_RASTERIZER_H_
-#define FREEDRENO_RASTERIZER_H_
-
-#include "pipe/p_state.h"
-#include "pipe/p_context.h"
-
-struct fd_rasterizer_stateobj {
- struct pipe_rasterizer_state base;
- uint32_t pa_sc_line_stipple;
- uint32_t pa_cl_clip_cntl;
- uint32_t pa_su_vtx_cntl;
- uint32_t pa_su_point_size;
- uint32_t pa_su_point_minmax;
- uint32_t pa_su_line_cntl;
- uint32_t pa_su_sc_mode_cntl;
-};
-
-void fd_rasterizer_init(struct pipe_context *pctx);
-
-#endif /* FREEDRENO_RASTERIZER_H_ */
#include "freedreno_context.h"
#include "freedreno_util.h"
+static void fd_resource_transfer_flush_region(struct pipe_context *pctx,
+ struct pipe_transfer *ptrans,
+ const struct pipe_box *box)
+{
+ struct fd_context *ctx = fd_context(pctx);
+ struct fd_resource *rsc = fd_resource(ptrans->resource);
+
+ if (rsc->dirty)
+ fd_context_render(pctx);
+
+ if (rsc->timestamp) {
+ fd_pipe_wait(ctx->screen->pipe, rsc->timestamp);
+ rsc->timestamp = 0;
+ }
+}
+
+static void
+fd_resource_transfer_unmap(struct pipe_context *pctx,
+ struct pipe_transfer *ptrans)
+{
+ struct fd_context *ctx = fd_context(pctx);
+ pipe_resource_reference(&ptrans->resource, NULL);
+ util_slab_free(&ctx->transfer_pool, ptrans);
+}
+
static void *
fd_resource_transfer_map(struct pipe_context *pctx,
struct pipe_resource *prsc,
if (!ptrans)
return NULL;
- ptrans->resource = prsc;
+ /* util_slap_alloc() doesn't zero: */
+ memset(ptrans, 0, sizeof(*ptrans));
+
+ pipe_resource_reference(&ptrans->resource, prsc);
ptrans->level = level;
ptrans->usage = usage;
ptrans->box = *box;
ptrans->stride = rsc->pitch * rsc->cpp;
ptrans->layer_stride = ptrans->stride;
+ /* some state trackers (at least XA) don't do this.. */
+ fd_resource_transfer_flush_region(pctx, ptrans, box);
+
buf = fd_bo_map(rsc->bo);
+ if (!buf) {
+ fd_resource_transfer_unmap(pctx, ptrans);
+ return NULL;
+ }
*pptrans = ptrans;
box->x / util_format_get_blockwidth(format) * rsc->cpp;
}
-static void fd_resource_transfer_flush_region(struct pipe_context *pctx,
- struct pipe_transfer *ptrans,
- const struct pipe_box *box)
-{
- struct fd_context *ctx = fd_context(pctx);
- struct fd_resource *rsc = fd_resource(ptrans->resource);
-
- if (rsc->dirty)
- fd_context_render(pctx);
-
- if (rsc->timestamp) {
- fd_pipe_wait(ctx->screen->pipe, rsc->timestamp);
- rsc->timestamp = 0;
- }
-}
-
-static void
-fd_resource_transfer_unmap(struct pipe_context *pctx,
- struct pipe_transfer *ptrans)
-{
- struct fd_context *ctx = fd_context(pctx);
- util_slab_free(&ctx->transfer_pool, ptrans);
-}
-
static void
fd_resource_destroy(struct pipe_screen *pscreen,
struct pipe_resource *prsc)
{
struct fd_resource *rsc = fd_resource(prsc);
- return fd_screen_bo_get_handle(pscreen, rsc->bo, rsc->pitch, handle);
+ return fd_screen_bo_get_handle(pscreen, rsc->bo,
+ rsc->pitch * rsc->cpp, handle);
}
-const struct u_resource_vtbl fd_resource_vtbl = {
+static const struct u_resource_vtbl fd_resource_vtbl = {
.resource_get_handle = fd_resource_get_handle,
.resource_destroy = fd_resource_destroy,
.transfer_map = fd_resource_transfer_map,
rsc->pitch = align(tmpl->width0, 32);
rsc->cpp = util_format_get_blocksize(tmpl->format);
+ assert(rsc->cpp);
+
size = rsc->pitch * tmpl->height0 * rsc->cpp;
flags = DRM_FREEDRENO_GEM_CACHE_WCOMBINE |
DRM_FREEDRENO_GEM_TYPE_KMEM; /* TODO */
rsc->bo = fd_screen_bo_from_handle(pscreen, handle, &rsc->pitch);
rsc->base.vtbl = &fd_resource_vtbl;
- rsc->pitch = align(tmpl->width0, 32);
+ rsc->cpp = util_format_get_blocksize(tmpl->format);
+ rsc->pitch /= rsc->cpp;
+
+ assert(rsc->cpp);
return prsc;
}
#include <errno.h>
#include <stdlib.h>
-#include "freedreno_context.h"
#include "freedreno_screen.h"
#include "freedreno_resource.h"
#include "freedreno_fence.h"
#include "freedreno_util.h"
+#include "fd2_screen.h"
+
/* XXX this should go away */
#include "state_tracker/drm_driver.h"
}
/*
-EGL Version 1.4
-EGL Vendor Qualcomm, Inc
-EGL Extensions EGL_QUALCOMM_shared_image EGL_KHR_image EGL_AMD_create_image EGL_KHR_lock_surface EGL_KHR_lock_surface2 EGL_KHR_fence_sync EGL_IMG_context_priorityEGL_ANDROID_image_native_buffer
-GL extensions: GL_AMD_compressed_ATC_texture GL_AMD_performance_monitor GL_AMD_program_binary_Z400 GL_EXT_texture_filter_anisotropic GL_EXT_texture_format_BGRA8888 GL_EXT_texture_type_2_10_10_10_REV GL_NV_fence GL_OES_compressed_ETC1_RGB8_texture GL_OES_depth_texture GL_OES_depth24 GL_OES_EGL_image GL_OES_EGL_image_external GL_OES_element_index_uint GL_OES_fbo_render_mipmap GL_OES_fragment_precision_high GL_OES_get_program_binary GL_OES_packed_depth_stencil GL_OES_rgb8_rgba8 GL_OES_standard_derivatives GL_OES_texture_3D GL_OES_texture_float GL_OES_texture_half_float GL_OES_texture_half_float_linear GL_OES_texture_npot GL_OES_vertex_half_float GL_OES_vertex_type_10_10_10_2 GL_QCOM_alpha_test GL_QCOM_binning_control GL_QCOM_driver_control GL_QCOM_perfmon_global_mode GL_QCOM_extended_get GL_QCOM_extended_get2 GL_QCOM_tiled_rendering GL_QCOM_writeonly_rendering GL_AMD_compressed_3DC_texture
-GL_MAX_3D_TEXTURE_SIZE_OES: 1024 0 0 0
-no GL_MAX_SAMPLES_ANGLE: GL_INVALID_ENUM
-no GL_MAX_SAMPLES_APPLE: GL_INVALID_ENUM
-GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT: 16 0 0 0
-no GL_MAX_SAMPLES_IMG: GL_INVALID_ENUM
-GL_MAX_TEXTURE_SIZE: 4096 0 0 0
-GL_MAX_VIEWPORT_DIMS: 4096 4096 0 0
-GL_MAX_VERTEX_ATTRIBS: 16 0 0 0
-GL_MAX_VERTEX_UNIFORM_VECTORS: 251 0 0 0
-GL_MAX_VARYING_VECTORS: 8 0 0 0
-GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: 20 0 0 0
-GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS: 4 0 0 0
-GL_MAX_TEXTURE_IMAGE_UNITS: 16 0 0 0
-GL_MAX_FRAGMENT_UNIFORM_VECTORS: 221 0 0 0
-GL_MAX_CUBE_MAP_TEXTURE_SIZE: 4096 0 0 0
-GL_MAX_RENDERBUFFER_SIZE: 4096 0 0 0
-no GL_TEXTURE_NUM_LEVELS_QCOM: GL_INVALID_ENUM
+TODO either move caps to a2xx/a3xx specific code, or maybe have some
+tables for things that differ if the delta is not too much..
*/
static int
fd_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
return 0;
}
-static boolean
-fd_screen_is_format_supported(struct pipe_screen *pscreen,
- enum pipe_format format,
- enum pipe_texture_target target,
- unsigned sample_count,
- unsigned usage)
-{
- unsigned retval = 0;
-
- if ((target >= PIPE_MAX_TEXTURE_TYPES) ||
- (sample_count > 1) || /* TODO add MSAA */
- !util_format_is_supported(format, usage)) {
- DBG("not supported: format=%s, target=%d, sample_count=%d, usage=%x",
- util_format_name(format), target, sample_count, usage);
- return FALSE;
- }
-
- /* TODO figure out how to render to other formats.. */
- if ((usage & PIPE_BIND_RENDER_TARGET) &&
- ((format != PIPE_FORMAT_B8G8R8A8_UNORM) &&
- (format != PIPE_FORMAT_B8G8R8X8_UNORM))) {
- DBG("not supported render target: format=%s, target=%d, sample_count=%d, usage=%x",
- util_format_name(format), target, sample_count, usage);
- return FALSE;
- }
-
- if ((usage & (PIPE_BIND_SAMPLER_VIEW |
- PIPE_BIND_VERTEX_BUFFER)) &&
- (fd_pipe2surface(format) != FMT_INVALID)) {
- retval |= usage & (PIPE_BIND_SAMPLER_VIEW |
- PIPE_BIND_VERTEX_BUFFER);
- }
-
- if ((usage & (PIPE_BIND_RENDER_TARGET |
- PIPE_BIND_DISPLAY_TARGET |
- PIPE_BIND_SCANOUT |
- PIPE_BIND_SHARED)) &&
- (fd_pipe2color(format) != COLORX_INVALID)) {
- retval |= usage & (PIPE_BIND_RENDER_TARGET |
- PIPE_BIND_DISPLAY_TARGET |
- PIPE_BIND_SCANOUT |
- PIPE_BIND_SHARED);
- }
-
- if ((usage & PIPE_BIND_DEPTH_STENCIL) &&
- (fd_pipe2depth(format) != DEPTHX_INVALID)) {
- retval |= PIPE_BIND_DEPTH_STENCIL;
- }
-
- if ((usage & PIPE_BIND_INDEX_BUFFER) &&
- (fd_pipe2index(format) != INDEX_SIZE_INVALID)) {
- retval |= PIPE_BIND_INDEX_BUFFER;
- }
-
- if (usage & PIPE_BIND_TRANSFER_READ)
- retval |= PIPE_BIND_TRANSFER_READ;
- if (usage & PIPE_BIND_TRANSFER_WRITE)
- retval |= PIPE_BIND_TRANSFER_WRITE;
-
- if (retval != usage) {
- DBG("not supported: format=%s, target=%d, sample_count=%d, "
- "usage=%x, retval=%x", util_format_name(format),
- target, sample_count, usage, retval);
- }
-
- return retval == usage;
-}
-
boolean
fd_screen_bo_get_handle(struct pipe_screen *pscreen,
struct fd_bo *bo,
}
screen->device_id = val;
+ if (fd_pipe_get_param(screen->pipe, FD_GPU_ID, &val)) {
+ DBG("could not get gpu-id");
+ goto fail;
+ }
+ screen->gpu_id = val;
+
+ /* explicitly checking for GPU revisions that are known to work. This
+ * may be overly conservative for a3xx, where spoofing the gpu_id with
+ * the blob driver seems to generate identical cmdstream dumps. But
+ * on a2xx, there seem to be small differences between the GPU revs
+ * so it is probably better to actually test first on real hardware
+ * before enabling:
+ *
+ * If you have a different adreno version, feel free to add it to one
+ * of the two cases below and see what happens. And if it works, please
+ * send a patch ;-)
+ */
+ switch (screen->gpu_id) {
+ case 220:
+ fd2_screen_init(pscreen);
+ break;
+ default:
+ debug_printf("unsupported GPU: a%03d\n", screen->gpu_id);
+ goto fail;
+ }
pscreen->destroy = fd_screen_destroy;
pscreen->get_param = fd_screen_get_param;
pscreen->get_paramf = fd_screen_get_paramf;
pscreen->get_shader_param = fd_screen_get_shader_param;
- pscreen->context_create = fd_context_create;
- pscreen->is_format_supported = fd_screen_is_format_supported;
fd_resource_screen_init(pscreen);
uint32_t gmemsize_bytes;
uint32_t device_id;
+ uint32_t gpu_id;
struct fd_device *dev;
struct fd_pipe *pipe;
#include "freedreno_state.h"
#include "freedreno_context.h"
-#include "freedreno_zsa.h"
-#include "freedreno_rasterizer.h"
-#include "freedreno_blend.h"
-#include "freedreno_program.h"
#include "freedreno_resource.h"
#include "freedreno_texture.h"
#include "freedreno_gmem.h"
#include "freedreno_util.h"
+/* All the generic state handling.. In case of CSO's that are specific
+ * to the GPU version, when the bind and the delete are common they can
+ * go in here.
+ */
+
static void
fd_set_blend_color(struct pipe_context *pctx,
const struct pipe_blend_color *blend_color)
static void
fd_set_scissor_states(struct pipe_context *pctx,
- unsigned start_slot,
- unsigned num_scissors,
+ unsigned start_slot,
+ unsigned num_scissors,
const struct pipe_scissor_state *scissor)
{
struct fd_context *ctx = fd_context(pctx);
static void
fd_set_viewport_states(struct pipe_context *pctx,
- unsigned start_slot,
- unsigned num_viewports,
+ unsigned start_slot,
+ unsigned num_viewports,
const struct pipe_viewport_state *viewport)
{
struct fd_context *ctx = fd_context(pctx);
ctx->dirty |= FD_DIRTY_INDEXBUF;
}
-void
-fd_state_init(struct pipe_context *pctx)
+static void
+fd_blend_state_bind(struct pipe_context *pctx, void *hwcso)
{
- pctx->set_blend_color = fd_set_blend_color;
- pctx->set_stencil_ref = fd_set_stencil_ref;
- pctx->set_clip_state = fd_set_clip_state;
- pctx->set_sample_mask = fd_set_sample_mask;
- pctx->set_constant_buffer = fd_set_constant_buffer;
- pctx->set_framebuffer_state = fd_set_framebuffer_state;
- pctx->set_polygon_stipple = fd_set_polygon_stipple;
- pctx->set_scissor_states = fd_set_scissor_states;
- pctx->set_viewport_states = fd_set_viewport_states;
-
- pctx->set_vertex_buffers = fd_set_vertex_buffers;
- pctx->set_index_buffer = fd_set_index_buffer;
+ struct fd_context *ctx = fd_context(pctx);
+ ctx->blend = hwcso;
+ ctx->dirty |= FD_DIRTY_BLEND;
}
-/* NOTE: just define the position for const regs statically.. the blob
- * driver doesn't seem to change these dynamically, and I can't really
- * think of a good reason to so..
- */
-#define VS_CONST_BASE 0x20
-#define PS_CONST_BASE 0x120
-
static void
-emit_constants(struct fd_ringbuffer *ring, uint32_t base,
- struct fd_constbuf_stateobj *constbuf,
- struct fd_shader_stateobj *shader)
+fd_blend_state_delete(struct pipe_context *pctx, void *hwcso)
{
- uint32_t enabled_mask = constbuf->enabled_mask;
- uint32_t start_base = base;
- unsigned i;
-
- // XXX TODO only emit dirty consts.. but we need to keep track if
- // they are clobbered by a clear, gmem2mem, or mem2gmem..
- constbuf->dirty_mask = enabled_mask;
-
- /* emit user constants: */
- while (enabled_mask) {
- unsigned index = ffs(enabled_mask) - 1;
- struct pipe_constant_buffer *cb = &constbuf->cb[index];
- unsigned size = align(cb->buffer_size, 4) / 4; /* size in dwords */
-
- // I expect that size should be a multiple of vec4's:
- assert(size == align(size, 4));
-
- /* hmm, sometimes we still seem to end up with consts bound,
- * even if shader isn't using them, which ends up overwriting
- * const reg's used for immediates.. this is a hack to work
- * around that:
- */
- if (shader && ((base - start_base) >= (shader->first_immediate * 4)))
- break;
-
- if (constbuf->dirty_mask & (1 << index)) {
- const uint32_t *dwords;
-
- if (cb->user_buffer) {
- dwords = cb->user_buffer;
- } else {
- struct fd_resource *rsc = fd_resource(cb->buffer);
- dwords = fd_bo_map(rsc->bo);
- }
-
- dwords = (uint32_t *)(((uint8_t *)dwords) + cb->buffer_offset);
-
- OUT_PKT3(ring, CP_SET_CONSTANT, size + 1);
- OUT_RING(ring, base);
- for (i = 0; i < size; i++)
- OUT_RING(ring, *(dwords++));
-
- constbuf->dirty_mask &= ~(1 << index);
- }
-
- base += size;
- enabled_mask &= ~(1 << index);
- }
+ FREE(hwcso);
+}
- /* emit shader immediates: */
- if (shader) {
- for (i = 0; i < shader->num_immediates; i++) {
- OUT_PKT3(ring, CP_SET_CONSTANT, 5);
- OUT_RING(ring, start_base + (4 * (shader->first_immediate + i)));
- OUT_RING(ring, shader->immediates[i].val[0]);
- OUT_RING(ring, shader->immediates[i].val[1]);
- OUT_RING(ring, shader->immediates[i].val[2]);
- OUT_RING(ring, shader->immediates[i].val[3]);
- base += 4;
- }
- }
+static void
+fd_rasterizer_state_bind(struct pipe_context *pctx, void *hwcso)
+{
+ struct fd_context *ctx = fd_context(pctx);
+ ctx->rasterizer = hwcso;
+ ctx->dirty |= FD_DIRTY_RASTERIZER;
}
-/* this works at least for a220 and earlier.. if later gpu's gain more than
- * 32 texture units, might need to bump this up to uint64_t
- */
-typedef uint32_t texmask;
+static void
+fd_rasterizer_state_delete(struct pipe_context *pctx, void *hwcso)
+{
+ FREE(hwcso);
+}
-static texmask
-emit_texture(struct fd_ringbuffer *ring, struct fd_context *ctx,
- struct fd_texture_stateobj *tex, unsigned samp_id, texmask emitted)
+static void
+fd_zsa_state_bind(struct pipe_context *pctx, void *hwcso)
{
- unsigned const_idx = fd_get_const_idx(ctx, tex, samp_id);
- struct fd_sampler_stateobj *sampler;
- struct fd_pipe_sampler_view *view;
+ struct fd_context *ctx = fd_context(pctx);
+ ctx->zsa = hwcso;
+ ctx->dirty |= FD_DIRTY_ZSA;
+}
- if (emitted & (1 << const_idx))
- return 0;
+static void
+fd_zsa_state_delete(struct pipe_context *pctx, void *hwcso)
+{
+ FREE(hwcso);
+}
- sampler = tex->samplers[samp_id];
- view = fd_pipe_sampler_view(tex->textures[samp_id]);
+static void *
+fd_vertex_state_create(struct pipe_context *pctx, unsigned num_elements,
+ const struct pipe_vertex_element *elements)
+{
+ struct fd_vertex_stateobj *so = CALLOC_STRUCT(fd_vertex_stateobj);
- OUT_PKT3(ring, CP_SET_CONSTANT, 7);
- OUT_RING(ring, 0x00010000 + (0x6 * const_idx));
+ if (!so)
+ return NULL;
- OUT_RING(ring, sampler->tex0 | view->tex0);
- OUT_RELOC(ring, view->tex_resource->bo, 0, view->fmt);
- OUT_RING(ring, view->tex2);
- OUT_RING(ring, sampler->tex3 | view->tex3);
- OUT_RING(ring, sampler->tex4);
- OUT_RING(ring, sampler->tex5);
+ memcpy(so->pipe, elements, sizeof(*elements) * num_elements);
+ so->num_elements = num_elements;
- return (1 << const_idx);
+ return so;
}
static void
-emit_textures(struct fd_ringbuffer *ring, struct fd_context *ctx)
+fd_vertex_state_delete(struct pipe_context *pctx, void *hwcso)
{
- texmask emitted = 0;
- unsigned i;
-
- for (i = 0; i < ctx->verttex.num_samplers; i++)
- if (ctx->verttex.samplers[i])
- emitted |= emit_texture(ring, ctx, &ctx->verttex, i, emitted);
-
- for (i = 0; i < ctx->fragtex.num_samplers; i++)
- if (ctx->fragtex.samplers[i])
- emitted |= emit_texture(ring, ctx, &ctx->fragtex, i, emitted);
+ FREE(hwcso);
}
-void
-fd_emit_vertex_bufs(struct fd_ringbuffer *ring, uint32_t val,
- struct fd_vertex_buf *vbufs, uint32_t n)
+static void
+fd_vertex_state_bind(struct pipe_context *pctx, void *hwcso)
{
- unsigned i;
-
- OUT_PKT3(ring, CP_SET_CONSTANT, 1 + (2 * n));
- OUT_RING(ring, (0x1 << 16) | (val & 0xffff));
- for (i = 0; i < n; i++) {
- struct fd_resource *rsc = fd_resource(vbufs[i].prsc);
- OUT_RELOC(ring, rsc->bo, vbufs[i].offset, 3);
- OUT_RING (ring, vbufs[i].size);
- }
+ struct fd_context *ctx = fd_context(pctx);
+ ctx->vtx = hwcso;
+ ctx->dirty |= FD_DIRTY_VTXSTATE;
}
void
-fd_state_emit(struct pipe_context *pctx, uint32_t dirty)
+fd_state_init(struct pipe_context *pctx)
{
- struct fd_context *ctx = fd_context(pctx);
- struct fd_ringbuffer *ring = ctx->ring;
-
- /* NOTE: we probably want to eventually refactor this so each state
- * object handles emitting it's own state.. although the mapping of
- * state to registers is not always orthogonal, sometimes a single
- * register contains bitfields coming from multiple state objects,
- * so not sure the best way to deal with that yet.
- */
-
- if (dirty & FD_DIRTY_SAMPLE_MASK) {
- OUT_PKT3(ring, CP_SET_CONSTANT, 2);
- OUT_RING(ring, CP_REG(REG_A2XX_PA_SC_AA_MASK));
- OUT_RING(ring, ctx->sample_mask);
- }
-
- if (dirty & FD_DIRTY_ZSA) {
- struct pipe_stencil_ref *sr = &ctx->stencil_ref;
-
- OUT_PKT3(ring, CP_SET_CONSTANT, 2);
- OUT_RING(ring, CP_REG(REG_A2XX_RB_DEPTHCONTROL));
- OUT_RING(ring, ctx->zsa->rb_depthcontrol);
-
- OUT_PKT3(ring, CP_SET_CONSTANT, 4);
- OUT_RING(ring, CP_REG(REG_A2XX_RB_STENCILREFMASK_BF));
- OUT_RING(ring, ctx->zsa->rb_stencilrefmask_bf |
- A2XX_RB_STENCILREFMASK_STENCILREF(sr->ref_value[1]));
- OUT_RING(ring, ctx->zsa->rb_stencilrefmask |
- A2XX_RB_STENCILREFMASK_STENCILREF(sr->ref_value[0]));
- OUT_RING(ring, ctx->zsa->rb_alpha_ref);
- }
-
- if (dirty & (FD_DIRTY_RASTERIZER | FD_DIRTY_FRAMEBUFFER)) {
- OUT_PKT3(ring, CP_SET_CONSTANT, 3);
- OUT_RING(ring, CP_REG(REG_A2XX_PA_CL_CLIP_CNTL));
- OUT_RING(ring, ctx->rasterizer->pa_cl_clip_cntl);
- OUT_RING(ring, ctx->rasterizer->pa_su_sc_mode_cntl |
- A2XX_PA_SU_SC_MODE_CNTL_VTX_WINDOW_OFFSET_ENABLE);
-
- OUT_PKT3(ring, CP_SET_CONSTANT, 5);
- OUT_RING(ring, CP_REG(REG_A2XX_PA_SU_POINT_SIZE));
- OUT_RING(ring, ctx->rasterizer->pa_su_point_size);
- OUT_RING(ring, ctx->rasterizer->pa_su_point_minmax);
- OUT_RING(ring, ctx->rasterizer->pa_su_line_cntl);
- OUT_RING(ring, ctx->rasterizer->pa_sc_line_stipple);
-
- OUT_PKT3(ring, CP_SET_CONSTANT, 6);
- OUT_RING(ring, CP_REG(REG_A2XX_PA_SU_VTX_CNTL));
- OUT_RING(ring, ctx->rasterizer->pa_su_vtx_cntl);
- OUT_RING(ring, fui(1.0)); /* PA_CL_GB_VERT_CLIP_ADJ */
- OUT_RING(ring, fui(1.0)); /* PA_CL_GB_VERT_DISC_ADJ */
- OUT_RING(ring, fui(1.0)); /* PA_CL_GB_HORZ_CLIP_ADJ */
- OUT_RING(ring, fui(1.0)); /* PA_CL_GB_HORZ_DISC_ADJ */
- }
-
- if (dirty & FD_DIRTY_SCISSOR) {
- OUT_PKT3(ring, CP_SET_CONSTANT, 3);
- OUT_RING(ring, CP_REG(REG_A2XX_PA_SC_WINDOW_SCISSOR_TL));
- OUT_RING(ring, xy2d(ctx->scissor.minx, /* PA_SC_WINDOW_SCISSOR_TL */
- ctx->scissor.miny));
- OUT_RING(ring, xy2d(ctx->scissor.maxx, /* PA_SC_WINDOW_SCISSOR_BR */
- ctx->scissor.maxy));
-
- ctx->max_scissor.minx = MIN2(ctx->max_scissor.minx, ctx->scissor.minx);
- ctx->max_scissor.miny = MIN2(ctx->max_scissor.miny, ctx->scissor.miny);
- ctx->max_scissor.maxx = MAX2(ctx->max_scissor.maxx, ctx->scissor.maxx);
- ctx->max_scissor.maxy = MAX2(ctx->max_scissor.maxy, ctx->scissor.maxy);
- }
-
- if (dirty & FD_DIRTY_VIEWPORT) {
- OUT_PKT3(ring, CP_SET_CONSTANT, 7);
- OUT_RING(ring, CP_REG(REG_A2XX_PA_CL_VPORT_XSCALE));
- OUT_RING(ring, fui(ctx->viewport.scale[0])); /* PA_CL_VPORT_XSCALE */
- OUT_RING(ring, fui(ctx->viewport.translate[0])); /* PA_CL_VPORT_XOFFSET */
- OUT_RING(ring, fui(ctx->viewport.scale[1])); /* PA_CL_VPORT_YSCALE */
- OUT_RING(ring, fui(ctx->viewport.translate[1])); /* PA_CL_VPORT_YOFFSET */
- OUT_RING(ring, fui(ctx->viewport.scale[2])); /* PA_CL_VPORT_ZSCALE */
- OUT_RING(ring, fui(ctx->viewport.translate[2])); /* PA_CL_VPORT_ZOFFSET */
-
- OUT_PKT3(ring, CP_SET_CONSTANT, 2);
- OUT_RING(ring, CP_REG(REG_A2XX_PA_CL_VTE_CNTL));
- OUT_RING(ring, A2XX_PA_CL_VTE_CNTL_VTX_W0_FMT |
- A2XX_PA_CL_VTE_CNTL_VPORT_X_SCALE_ENA |
- A2XX_PA_CL_VTE_CNTL_VPORT_X_OFFSET_ENA |
- A2XX_PA_CL_VTE_CNTL_VPORT_Y_SCALE_ENA |
- A2XX_PA_CL_VTE_CNTL_VPORT_Y_OFFSET_ENA |
- A2XX_PA_CL_VTE_CNTL_VPORT_Z_SCALE_ENA |
- A2XX_PA_CL_VTE_CNTL_VPORT_Z_OFFSET_ENA);
- }
-
- if (dirty & (FD_DIRTY_PROG | FD_DIRTY_VTXSTATE | FD_DIRTY_TEXSTATE)) {
- fd_program_validate(ctx);
- fd_program_emit(ring, &ctx->prog);
- }
-
- if (dirty & (FD_DIRTY_PROG | FD_DIRTY_CONSTBUF)) {
- emit_constants(ring, VS_CONST_BASE * 4,
- &ctx->constbuf[PIPE_SHADER_VERTEX],
- (dirty & FD_DIRTY_PROG) ? ctx->prog.vp : NULL);
- emit_constants(ring, PS_CONST_BASE * 4,
- &ctx->constbuf[PIPE_SHADER_FRAGMENT],
- (dirty & FD_DIRTY_PROG) ? ctx->prog.fp : NULL);
- }
-
- if (dirty & (FD_DIRTY_BLEND | FD_DIRTY_ZSA)) {
- OUT_PKT3(ring, CP_SET_CONSTANT, 2);
- OUT_RING(ring, CP_REG(REG_A2XX_RB_COLORCONTROL));
- OUT_RING(ring, ctx->zsa->rb_colorcontrol | ctx->blend->rb_colorcontrol);
- }
+ pctx->set_blend_color = fd_set_blend_color;
+ pctx->set_stencil_ref = fd_set_stencil_ref;
+ pctx->set_clip_state = fd_set_clip_state;
+ pctx->set_sample_mask = fd_set_sample_mask;
+ pctx->set_constant_buffer = fd_set_constant_buffer;
+ pctx->set_framebuffer_state = fd_set_framebuffer_state;
+ pctx->set_polygon_stipple = fd_set_polygon_stipple;
+ pctx->set_scissor_states = fd_set_scissor_states;
+ pctx->set_viewport_states = fd_set_viewport_states;
- if (dirty & FD_DIRTY_BLEND) {
- OUT_PKT3(ring, CP_SET_CONSTANT, 2);
- OUT_RING(ring, CP_REG(REG_A2XX_RB_BLEND_CONTROL));
- OUT_RING(ring, ctx->blend->rb_blendcontrol);
+ pctx->set_vertex_buffers = fd_set_vertex_buffers;
+ pctx->set_index_buffer = fd_set_index_buffer;
- OUT_PKT3(ring, CP_SET_CONSTANT, 2);
- OUT_RING(ring, CP_REG(REG_A2XX_RB_COLOR_MASK));
- OUT_RING(ring, ctx->blend->rb_colormask);
- }
+ pctx->bind_blend_state = fd_blend_state_bind;
+ pctx->delete_blend_state = fd_blend_state_delete;
- if (dirty & (FD_DIRTY_VERTTEX | FD_DIRTY_FRAGTEX | FD_DIRTY_PROG))
- emit_textures(ring, ctx);
+ pctx->bind_rasterizer_state = fd_rasterizer_state_bind;
+ pctx->delete_rasterizer_state = fd_rasterizer_state_delete;
- ctx->dirty &= ~dirty;
-}
+ pctx->bind_depth_stencil_alpha_state = fd_zsa_state_bind;
+ pctx->delete_depth_stencil_alpha_state = fd_zsa_state_delete;
-/* emit per-context initialization:
- */
-void
-fd_state_emit_setup(struct pipe_context *pctx)
-{
- struct fd_context *ctx = fd_context(pctx);
- struct fd_ringbuffer *ring = ctx->ring;
-
- OUT_PKT0(ring, REG_A2XX_TP0_CHICKEN, 1);
- OUT_RING(ring, 0x00000002);
-
- OUT_PKT3(ring, CP_INVALIDATE_STATE, 1);
- OUT_RING(ring, 0x00007fff);
-
- OUT_PKT3(ring, CP_SET_CONSTANT, 2);
- OUT_RING(ring, CP_REG(REG_A2XX_SQ_VS_CONST));
- OUT_RING(ring, A2XX_SQ_VS_CONST_BASE(VS_CONST_BASE) |
- A2XX_SQ_VS_CONST_SIZE(0x100));
-
- OUT_PKT3(ring, CP_SET_CONSTANT, 2);
- OUT_RING(ring, CP_REG(REG_A2XX_SQ_PS_CONST));
- OUT_RING(ring, A2XX_SQ_PS_CONST_BASE(PS_CONST_BASE) |
- A2XX_SQ_PS_CONST_SIZE(0xe0));
-
- OUT_PKT3(ring, CP_SET_CONSTANT, 3);
- OUT_RING(ring, CP_REG(REG_A2XX_VGT_MAX_VTX_INDX));
- OUT_RING(ring, 0xffffffff); /* VGT_MAX_VTX_INDX */
- OUT_RING(ring, 0x00000000); /* VGT_MIN_VTX_INDX */
-
- OUT_PKT3(ring, CP_SET_CONSTANT, 2);
- OUT_RING(ring, CP_REG(REG_A2XX_VGT_INDX_OFFSET));
- OUT_RING(ring, 0x00000000);
-
- OUT_PKT3(ring, CP_SET_CONSTANT, 2);
- OUT_RING(ring, CP_REG(REG_A2XX_VGT_VERTEX_REUSE_BLOCK_CNTL));
- OUT_RING(ring, 0x0000003b);
-
- OUT_PKT3(ring, CP_SET_CONSTANT, 2);
- OUT_RING(ring, CP_REG(REG_A2XX_SQ_CONTEXT_MISC));
- OUT_RING(ring, A2XX_SQ_CONTEXT_MISC_SC_SAMPLE_CNTL(CENTERS_ONLY));
-
- OUT_PKT3(ring, CP_SET_CONSTANT, 2);
- OUT_RING(ring, CP_REG(REG_A2XX_SQ_INTERPOLATOR_CNTL));
- OUT_RING(ring, 0xffffffff);
-
- OUT_PKT3(ring, CP_SET_CONSTANT, 2);
- OUT_RING(ring, CP_REG(REG_A2XX_PA_SC_AA_CONFIG));
- OUT_RING(ring, 0x00000000);
-
- OUT_PKT3(ring, CP_SET_CONSTANT, 2);
- OUT_RING(ring, CP_REG(REG_A2XX_PA_SC_LINE_CNTL));
- OUT_RING(ring, 0x00000000);
-
- OUT_PKT3(ring, CP_SET_CONSTANT, 2);
- OUT_RING(ring, CP_REG(REG_A2XX_PA_SC_WINDOW_OFFSET));
- OUT_RING(ring, 0x00000000);
-
- // XXX we change this dynamically for draw/clear.. vs gmem<->mem..
- OUT_PKT3(ring, CP_SET_CONSTANT, 2);
- OUT_RING(ring, CP_REG(REG_A2XX_RB_MODECONTROL));
- OUT_RING(ring, A2XX_RB_MODECONTROL_EDRAM_MODE(COLOR_DEPTH));
-
- OUT_PKT3(ring, CP_SET_CONSTANT, 2);
- OUT_RING(ring, CP_REG(REG_A2XX_RB_SAMPLE_POS));
- OUT_RING(ring, 0x88888888);
-
- OUT_PKT3(ring, CP_SET_CONSTANT, 2);
- OUT_RING(ring, CP_REG(REG_A2XX_RB_COLOR_DEST_MASK));
- OUT_RING(ring, 0xffffffff);
-
- OUT_PKT3(ring, CP_SET_CONSTANT, 2);
- OUT_RING(ring, CP_REG(REG_A2XX_RB_COPY_DEST_INFO));
- OUT_RING(ring, A2XX_RB_COPY_DEST_INFO_FORMAT(COLORX_4_4_4_4) |
- A2XX_RB_COPY_DEST_INFO_WRITE_RED |
- A2XX_RB_COPY_DEST_INFO_WRITE_GREEN |
- A2XX_RB_COPY_DEST_INFO_WRITE_BLUE |
- A2XX_RB_COPY_DEST_INFO_WRITE_ALPHA);
-
- OUT_PKT3(ring, CP_SET_CONSTANT, 3);
- OUT_RING(ring, CP_REG(REG_A2XX_SQ_WRAPPING_0));
- OUT_RING(ring, 0x00000000); /* SQ_WRAPPING_0 */
- OUT_RING(ring, 0x00000000); /* SQ_WRAPPING_1 */
-
- OUT_PKT3(ring, CP_SET_DRAW_INIT_FLAGS, 1);
- OUT_RING(ring, 0x00000000);
-
- OUT_PKT3(ring, CP_WAIT_REG_EQ, 4);
- OUT_RING(ring, 0x000005d0);
- OUT_RING(ring, 0x00000000);
- OUT_RING(ring, 0x5f601000);
- OUT_RING(ring, 0x00000001);
-
- OUT_PKT0(ring, REG_A2XX_SQ_INST_STORE_MANAGMENT, 1);
- OUT_RING(ring, 0x00000180);
-
- OUT_PKT3(ring, CP_INVALIDATE_STATE, 1);
- OUT_RING(ring, 0x00000300);
-
- OUT_PKT3(ring, CP_SET_SHADER_BASES, 1);
- OUT_RING(ring, 0x80000180);
-
- /* not sure what this form of CP_SET_CONSTANT is.. */
- OUT_PKT3(ring, CP_SET_CONSTANT, 13);
- OUT_RING(ring, 0x00000000);
- OUT_RING(ring, 0x00000000);
- OUT_RING(ring, 0x00000000);
- OUT_RING(ring, 0x00000000);
- OUT_RING(ring, 0x00000000);
- OUT_RING(ring, 0x469c4000);
- OUT_RING(ring, 0x3f800000);
- OUT_RING(ring, 0x3f000000);
- OUT_RING(ring, 0x00000000);
- OUT_RING(ring, 0x40000000);
- OUT_RING(ring, 0x3f400000);
- OUT_RING(ring, 0x3ec00000);
- OUT_RING(ring, 0x3e800000);
-
- OUT_PKT3(ring, CP_SET_CONSTANT, 2);
- OUT_RING(ring, CP_REG(REG_A2XX_RB_COLOR_MASK));
- OUT_RING(ring, A2XX_RB_COLOR_MASK_WRITE_RED |
- A2XX_RB_COLOR_MASK_WRITE_GREEN |
- A2XX_RB_COLOR_MASK_WRITE_BLUE |
- A2XX_RB_COLOR_MASK_WRITE_ALPHA);
-
- OUT_PKT3(ring, CP_SET_CONSTANT, 5);
- OUT_RING(ring, CP_REG(REG_A2XX_RB_BLEND_RED));
- OUT_RING(ring, 0x00000000); /* RB_BLEND_RED */
- OUT_RING(ring, 0x00000000); /* RB_BLEND_GREEN */
- OUT_RING(ring, 0x00000000); /* RB_BLEND_BLUE */
- OUT_RING(ring, 0x000000ff); /* RB_BLEND_ALPHA */
-
- fd_ringbuffer_flush(ring);
- fd_ringmarker_mark(ctx->draw_start);
+ pctx->create_vertex_elements_state = fd_vertex_state_create;
+ pctx->delete_vertex_elements_state = fd_vertex_state_delete;
+ pctx->bind_vertex_elements_state = fd_vertex_state_bind;
}
#define FREEDRENO_STATE_H_
#include "pipe/p_context.h"
+#include "freedreno_context.h"
-struct fd_vertexbuf_stateobj;
-struct fd_zsa_stateobj;
-struct fd_framebuffer_stateobj;
-struct fd_ringbuffer;
+static inline bool fd_depth_enabled(struct fd_context *ctx)
+{
+ return ctx->zsa->depth.enabled;
+}
-void fd_state_init(struct pipe_context *pctx);
-
-struct fd_vertex_buf {
- unsigned offset, size;
- struct pipe_resource *prsc;
-};
+static inline bool fd_stencil_enabled(struct fd_context *ctx)
+{
+ return ctx->zsa->stencil[0].enabled;
+}
-void fd_emit_vertex_bufs(struct fd_ringbuffer *ring, uint32_t val,
- struct fd_vertex_buf *vbufs, uint32_t n);
-void fd_state_emit(struct pipe_context *pctx, uint32_t dirty);
-void fd_state_emit_setup(struct pipe_context *pctx);
+void fd_state_init(struct pipe_context *pctx);
#endif /* FREEDRENO_STATE_H_ */
#include "util/u_inlines.h"
#include "freedreno_texture.h"
+#include "freedreno_context.h"
#include "freedreno_util.h"
-static enum sq_tex_clamp
-tex_clamp(unsigned wrap)
-{
- switch (wrap) {
- case PIPE_TEX_WRAP_REPEAT:
- return SQ_TEX_WRAP;
- case PIPE_TEX_WRAP_CLAMP:
- return SQ_TEX_CLAMP_HALF_BORDER;
- case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
- return SQ_TEX_CLAMP_LAST_TEXEL;
- case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
- return SQ_TEX_CLAMP_BORDER;
- case PIPE_TEX_WRAP_MIRROR_REPEAT:
- return SQ_TEX_MIRROR;
- case PIPE_TEX_WRAP_MIRROR_CLAMP:
- return SQ_TEX_MIRROR_ONCE_HALF_BORDER;
- case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE:
- return SQ_TEX_MIRROR_ONCE_LAST_TEXEL;
- case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER:
- return SQ_TEX_MIRROR_ONCE_BORDER;
- default:
- DBG("invalid wrap: %u", wrap);
- return 0;
- }
-}
-
-static enum sq_tex_filter
-tex_filter(unsigned filter)
-{
- switch (filter) {
- case PIPE_TEX_FILTER_NEAREST:
- return SQ_TEX_FILTER_POINT;
- case PIPE_TEX_FILTER_LINEAR:
- return SQ_TEX_FILTER_BILINEAR;
- default:
- DBG("invalid filter: %u", filter);
- return 0;
- }
-}
-
-static void *
-fd_sampler_state_create(struct pipe_context *pctx,
- const struct pipe_sampler_state *cso)
-{
- struct fd_sampler_stateobj *so = CALLOC_STRUCT(fd_sampler_stateobj);
-
- if (!so)
- return NULL;
-
- so->base = *cso;
-
- /* SQ_TEX0_PITCH() must be OR'd in later when we know the bound texture: */
- so->tex0 =
- A2XX_SQ_TEX_0_CLAMP_X(tex_clamp(cso->wrap_s)) |
- A2XX_SQ_TEX_0_CLAMP_Y(tex_clamp(cso->wrap_t)) |
- A2XX_SQ_TEX_0_CLAMP_Z(tex_clamp(cso->wrap_r));
-
- so->tex3 =
- A2XX_SQ_TEX_3_XY_MAG_FILTER(tex_filter(cso->mag_img_filter)) |
- A2XX_SQ_TEX_3_XY_MIN_FILTER(tex_filter(cso->min_img_filter));
-
- so->tex4 = 0x00000000; /* ??? */
- so->tex5 = 0x00000200; /* ??? */
-
- return so;
-}
-
static void
fd_sampler_state_delete(struct pipe_context *pctx, void *hwcso)
{
FREE(hwcso);
}
-static struct pipe_sampler_view *
-fd_sampler_view_create(struct pipe_context *pctx, struct pipe_resource *prsc,
- const struct pipe_sampler_view *cso)
-{
- struct fd_pipe_sampler_view *so = CALLOC_STRUCT(fd_pipe_sampler_view);
- struct fd_resource *rsc = fd_resource(prsc);
-
- if (!so)
- return NULL;
-
- so->base = *cso;
- pipe_reference(NULL, &prsc->reference);
- so->base.texture = prsc;
- so->base.reference.count = 1;
- so->base.context = pctx;
-
- so->tex_resource = rsc;
- so->fmt = fd_pipe2surface(cso->format);
-
- so->tex0 = A2XX_SQ_TEX_0_PITCH(rsc->pitch);
- so->tex2 =
- A2XX_SQ_TEX_2_HEIGHT(prsc->height0 - 1) |
- A2XX_SQ_TEX_2_WIDTH(prsc->width0 - 1);
- so->tex3 = fd_tex_swiz(cso->format, cso->swizzle_r, cso->swizzle_g,
- cso->swizzle_b, cso->swizzle_a);
-
- return &so->base;
-}
-
static void
fd_sampler_view_destroy(struct pipe_context *pctx,
struct pipe_sampler_view *view)
unsigned nr, void **hwcso)
{
unsigned i;
+ unsigned new_nr = 0;
for (i = 0; i < nr; i++) {
+ if (hwcso[i])
+ new_nr++;
prog->samplers[i] = hwcso[i];
prog->dirty_samplers |= (1 << i);
}
prog->dirty_samplers |= (1 << i);
}
- prog->num_samplers = nr;
+ prog->num_samplers = new_nr;
}
static void set_sampler_views(struct fd_texture_stateobj *prog,
unsigned nr, struct pipe_sampler_view **views)
{
unsigned i;
+ unsigned new_nr = 0;
for (i = 0; i < nr; i++) {
+ if (views[i])
+ new_nr++;
pipe_sampler_view_reference(&prog->textures[i], views[i]);
prog->dirty_samplers |= (1 << i);
}
prog->dirty_samplers |= (1 << i);
}
- prog->num_textures = nr;
+ prog->num_textures = new_nr;
}
static void
ctx->dirty |= FD_DIRTY_VERTTEX;
}
-/* map gallium sampler-id to hw const-idx.. adreno uses a flat address
- * space of samplers (const-idx), so we need to map the gallium sampler-id
- * which is per-shader to a global const-idx space.
- *
- * Fragment shader sampler maps directly to const-idx, and vertex shader
- * is offset by the # of fragment shader samplers. If the # of fragment
- * shader samplers changes, this shifts the vertex shader indexes.
- *
- * TODO maybe we can do frag shader 0..N and vert shader N..0 to avoid
- * this??
- */
-unsigned
-fd_get_const_idx(struct fd_context *ctx, struct fd_texture_stateobj *tex,
- unsigned samp_id)
-{
- if (tex == &ctx->fragtex)
- return samp_id;
- return samp_id + ctx->fragtex.num_samplers;
-}
-
void
fd_texture_init(struct pipe_context *pctx)
{
- pctx->create_sampler_state = fd_sampler_state_create;
pctx->delete_sampler_state = fd_sampler_state_delete;
- pctx->create_sampler_view = fd_sampler_view_create;
pctx->sampler_view_destroy = fd_sampler_view_destroy;
pctx->bind_fragment_sampler_states = fd_fragtex_sampler_states_bind;
#include "pipe/p_context.h"
-#include "freedreno_context.h"
-#include "freedreno_resource.h"
-#include "freedreno_util.h"
-
-struct fd_sampler_stateobj {
- struct pipe_sampler_state base;
- uint32_t tex0, tex3, tex4, tex5;
-};
-
-struct fd_pipe_sampler_view {
- struct pipe_sampler_view base;
- struct fd_resource *tex_resource;
- enum a2xx_sq_surfaceformat fmt;
- uint32_t tex0, tex2, tex3;
-};
-
-static INLINE struct fd_pipe_sampler_view *
-fd_pipe_sampler_view(struct pipe_sampler_view *pview)
-{
- return (struct fd_pipe_sampler_view *)pview;
-}
-
-unsigned fd_get_const_idx(struct fd_context *ctx,
- struct fd_texture_stateobj *tex, unsigned samp_id);
-
void fd_texture_init(struct pipe_context *pctx);
#endif /* FREEDRENO_TEXTURE_H_ */
#include "freedreno_util.h"
-enum a2xx_sq_surfaceformat
-fd_pipe2surface(enum pipe_format format)
-{
- switch (format) {
- /* 8-bit buffers. */
- case PIPE_FORMAT_A8_UNORM:
- case PIPE_FORMAT_A8_SNORM:
- case PIPE_FORMAT_A8_UINT:
- case PIPE_FORMAT_A8_SINT:
- case PIPE_FORMAT_I8_UNORM:
- case PIPE_FORMAT_I8_SNORM:
- case PIPE_FORMAT_I8_UINT:
- case PIPE_FORMAT_I8_SINT:
- case PIPE_FORMAT_L8_UNORM:
- case PIPE_FORMAT_L8_SNORM:
- case PIPE_FORMAT_L8_UINT:
- case PIPE_FORMAT_L8_SINT:
- case PIPE_FORMAT_L8_SRGB:
- case PIPE_FORMAT_R8_UNORM:
- case PIPE_FORMAT_R8_SNORM:
- case PIPE_FORMAT_R8_UINT:
- case PIPE_FORMAT_R8_SINT:
- return FMT_8;
-
- /* 16-bit buffers. */
- case PIPE_FORMAT_B5G6R5_UNORM:
- return FMT_5_6_5;
- case PIPE_FORMAT_B5G5R5A1_UNORM:
- case PIPE_FORMAT_B5G5R5X1_UNORM:
- return FMT_1_5_5_5;
- case PIPE_FORMAT_B4G4R4A4_UNORM:
- case PIPE_FORMAT_B4G4R4X4_UNORM:
- return FMT_4_4_4_4;
- case PIPE_FORMAT_Z16_UNORM:
- return FMT_16;
- case PIPE_FORMAT_L8A8_UNORM:
- case PIPE_FORMAT_L8A8_SNORM:
- case PIPE_FORMAT_L8A8_UINT:
- case PIPE_FORMAT_L8A8_SINT:
- case PIPE_FORMAT_L8A8_SRGB:
- case PIPE_FORMAT_R8G8_UNORM:
- case PIPE_FORMAT_R8G8_SNORM:
- case PIPE_FORMAT_R8G8_UINT:
- case PIPE_FORMAT_R8G8_SINT:
- return FMT_8_8;
- case PIPE_FORMAT_R16_UNORM:
- case PIPE_FORMAT_R16_SNORM:
- case PIPE_FORMAT_R16_UINT:
- case PIPE_FORMAT_R16_SINT:
- case PIPE_FORMAT_A16_UNORM:
- case PIPE_FORMAT_A16_SNORM:
- case PIPE_FORMAT_A16_UINT:
- case PIPE_FORMAT_A16_SINT:
- case PIPE_FORMAT_L16_UNORM:
- case PIPE_FORMAT_L16_SNORM:
- case PIPE_FORMAT_L16_UINT:
- case PIPE_FORMAT_L16_SINT:
- case PIPE_FORMAT_I16_UNORM:
- case PIPE_FORMAT_I16_SNORM:
- case PIPE_FORMAT_I16_UINT:
- case PIPE_FORMAT_I16_SINT:
- return FMT_16;
- case PIPE_FORMAT_R16_FLOAT:
- case PIPE_FORMAT_A16_FLOAT:
- case PIPE_FORMAT_L16_FLOAT:
- case PIPE_FORMAT_I16_FLOAT:
- return FMT_16_FLOAT;
-
- /* 32-bit buffers. */
- case PIPE_FORMAT_A8B8G8R8_SRGB:
- case PIPE_FORMAT_A8B8G8R8_UNORM:
- case PIPE_FORMAT_A8R8G8B8_UNORM:
- case PIPE_FORMAT_B8G8R8A8_SRGB:
- case PIPE_FORMAT_B8G8R8A8_UNORM:
- case PIPE_FORMAT_B8G8R8X8_UNORM:
- case PIPE_FORMAT_R8G8B8A8_SNORM:
- case PIPE_FORMAT_R8G8B8A8_UNORM:
- case PIPE_FORMAT_R8G8B8X8_UNORM:
- case PIPE_FORMAT_R8SG8SB8UX8U_NORM:
- case PIPE_FORMAT_X8B8G8R8_UNORM:
- case PIPE_FORMAT_X8R8G8B8_UNORM:
- case PIPE_FORMAT_R8G8B8_UNORM:
- case PIPE_FORMAT_R8G8B8A8_SINT:
- case PIPE_FORMAT_R8G8B8A8_UINT:
- return FMT_8_8_8_8;
- case PIPE_FORMAT_R10G10B10A2_UNORM:
- case PIPE_FORMAT_R10G10B10X2_SNORM:
- case PIPE_FORMAT_B10G10R10A2_UNORM:
- case PIPE_FORMAT_B10G10R10A2_UINT:
- case PIPE_FORMAT_R10SG10SB10SA2U_NORM:
- return FMT_2_10_10_10;
- case PIPE_FORMAT_Z24X8_UNORM:
- case PIPE_FORMAT_Z24_UNORM_S8_UINT:
- return FMT_24_8;
- case PIPE_FORMAT_R32_UINT:
- case PIPE_FORMAT_R32_SINT:
- case PIPE_FORMAT_A32_UINT:
- case PIPE_FORMAT_A32_SINT:
- case PIPE_FORMAT_L32_UINT:
- case PIPE_FORMAT_L32_SINT:
- case PIPE_FORMAT_I32_UINT:
- case PIPE_FORMAT_I32_SINT:
- return FMT_32;
- case PIPE_FORMAT_R32_FLOAT:
- case PIPE_FORMAT_A32_FLOAT:
- case PIPE_FORMAT_L32_FLOAT:
- case PIPE_FORMAT_I32_FLOAT:
- case PIPE_FORMAT_Z32_FLOAT:
- return FMT_32_FLOAT;
- case PIPE_FORMAT_R16G16_FLOAT:
- case PIPE_FORMAT_L16A16_FLOAT:
- return FMT_16_16_FLOAT;
- case PIPE_FORMAT_R16G16_UNORM:
- case PIPE_FORMAT_R16G16_SNORM:
- case PIPE_FORMAT_R16G16_UINT:
- case PIPE_FORMAT_R16G16_SINT:
- case PIPE_FORMAT_L16A16_UNORM:
- case PIPE_FORMAT_L16A16_SNORM:
- case PIPE_FORMAT_L16A16_UINT:
- case PIPE_FORMAT_L16A16_SINT:
- return FMT_16_16;
-
- /* 64-bit buffers. */
- case PIPE_FORMAT_R16G16B16A16_UINT:
- case PIPE_FORMAT_R16G16B16A16_SINT:
- case PIPE_FORMAT_R16G16B16A16_UNORM:
- case PIPE_FORMAT_R16G16B16A16_SNORM:
- return FMT_16_16_16_16;
- case PIPE_FORMAT_R16G16B16A16_FLOAT:
- return FMT_16_16_16_16_FLOAT;
- case PIPE_FORMAT_R32G32_FLOAT:
- case PIPE_FORMAT_L32A32_FLOAT:
- return FMT_32_32_FLOAT;
- case PIPE_FORMAT_R32G32_SINT:
- case PIPE_FORMAT_R32G32_UINT:
- case PIPE_FORMAT_L32A32_UINT:
- case PIPE_FORMAT_L32A32_SINT:
- return FMT_32_32;
-
- /* 96-bit buffers. */
- case PIPE_FORMAT_R32G32B32_FLOAT:
- return FMT_32_32_32_FLOAT;
-
- /* 128-bit buffers. */
- case PIPE_FORMAT_R32G32B32A32_SNORM:
- case PIPE_FORMAT_R32G32B32A32_UNORM:
- case PIPE_FORMAT_R32G32B32A32_SINT:
- case PIPE_FORMAT_R32G32B32A32_UINT:
- return FMT_32_32_32_32;
- case PIPE_FORMAT_R32G32B32A32_FLOAT:
- return FMT_32_32_32_32_FLOAT;
-
- /* YUV buffers. */
- case PIPE_FORMAT_UYVY:
- return FMT_Cr_Y1_Cb_Y0;
- case PIPE_FORMAT_YUYV:
- return FMT_Y1_Cr_Y0_Cb;
-
- default:
- return FMT_INVALID;
- }
-}
-
-enum a2xx_colorformatx
-fd_pipe2color(enum pipe_format format)
-{
- switch (format) {
- /* 8-bit buffers. */
- case PIPE_FORMAT_A8_UNORM:
- case PIPE_FORMAT_A8_SNORM:
- case PIPE_FORMAT_A8_UINT:
- case PIPE_FORMAT_A8_SINT:
- case PIPE_FORMAT_I8_UNORM:
- case PIPE_FORMAT_I8_SNORM:
- case PIPE_FORMAT_I8_UINT:
- case PIPE_FORMAT_I8_SINT:
- case PIPE_FORMAT_L8_UNORM:
- case PIPE_FORMAT_L8_SNORM:
- case PIPE_FORMAT_L8_UINT:
- case PIPE_FORMAT_L8_SINT:
- case PIPE_FORMAT_L8_SRGB:
- case PIPE_FORMAT_R8_UNORM:
- case PIPE_FORMAT_R8_SNORM:
- case PIPE_FORMAT_R8_UINT:
- case PIPE_FORMAT_R8_SINT:
- return COLORX_8;
-
- /* 16-bit buffers. */
- case PIPE_FORMAT_B5G6R5_UNORM:
- return COLORX_5_6_5;
- case PIPE_FORMAT_B5G5R5A1_UNORM:
- case PIPE_FORMAT_B5G5R5X1_UNORM:
- return COLORX_1_5_5_5;
- case PIPE_FORMAT_B4G4R4A4_UNORM:
- case PIPE_FORMAT_B4G4R4X4_UNORM:
- return COLORX_4_4_4_4;
- case PIPE_FORMAT_L8A8_UNORM:
- case PIPE_FORMAT_L8A8_SNORM:
- case PIPE_FORMAT_L8A8_UINT:
- case PIPE_FORMAT_L8A8_SINT:
- case PIPE_FORMAT_L8A8_SRGB:
- case PIPE_FORMAT_R8G8_UNORM:
- case PIPE_FORMAT_R8G8_SNORM:
- case PIPE_FORMAT_R8G8_UINT:
- case PIPE_FORMAT_R8G8_SINT:
- case PIPE_FORMAT_Z16_UNORM:
- return COLORX_8_8;
- case PIPE_FORMAT_R16_FLOAT:
- case PIPE_FORMAT_A16_FLOAT:
- case PIPE_FORMAT_L16_FLOAT:
- case PIPE_FORMAT_I16_FLOAT:
- return COLORX_16_FLOAT;
-
- /* 32-bit buffers. */
- case PIPE_FORMAT_A8B8G8R8_SRGB:
- case PIPE_FORMAT_A8B8G8R8_UNORM:
- case PIPE_FORMAT_A8R8G8B8_UNORM:
- case PIPE_FORMAT_B8G8R8A8_SRGB:
- case PIPE_FORMAT_B8G8R8A8_UNORM:
- case PIPE_FORMAT_B8G8R8X8_UNORM:
- case PIPE_FORMAT_R8G8B8A8_SNORM:
- case PIPE_FORMAT_R8G8B8A8_UNORM:
- case PIPE_FORMAT_R8G8B8X8_UNORM:
- case PIPE_FORMAT_R8SG8SB8UX8U_NORM:
- case PIPE_FORMAT_X8B8G8R8_UNORM:
- case PIPE_FORMAT_X8R8G8B8_UNORM:
- case PIPE_FORMAT_R8G8B8_UNORM:
- case PIPE_FORMAT_R8G8B8A8_SINT:
- case PIPE_FORMAT_R8G8B8A8_UINT:
- case PIPE_FORMAT_Z24_UNORM_S8_UINT:
- case PIPE_FORMAT_Z24X8_UNORM:
- return COLORX_8_8_8_8;
- case PIPE_FORMAT_R32_FLOAT:
- case PIPE_FORMAT_A32_FLOAT:
- case PIPE_FORMAT_L32_FLOAT:
- case PIPE_FORMAT_I32_FLOAT:
- case PIPE_FORMAT_Z32_FLOAT:
- return COLORX_32_FLOAT;
- case PIPE_FORMAT_R16G16_FLOAT:
- case PIPE_FORMAT_L16A16_FLOAT:
- return COLORX_16_16_FLOAT;
-
- /* 64-bit buffers. */
- case PIPE_FORMAT_R16G16B16A16_FLOAT:
- return COLORX_16_16_16_16_FLOAT;
- case PIPE_FORMAT_R32G32_FLOAT:
- case PIPE_FORMAT_L32A32_FLOAT:
- return COLORX_32_32_FLOAT;
-
- /* 128-bit buffers. */
- case PIPE_FORMAT_R32G32B32A32_FLOAT:
- return COLORX_32_32_32_32_FLOAT;
-
- default:
- return COLORX_INVALID;
- }
-}
-
-enum a2xx_rb_depth_format
+enum adreno_rb_depth_format
fd_pipe2depth(enum pipe_format format)
{
switch (format) {
case PIPE_FORMAT_Z24_UNORM_S8_UINT:
return DEPTHX_24_8;
default:
- return DEPTHX_INVALID;
+ return ~0;
}
}
case PIPE_FORMAT_I32_UINT:
return INDEX_SIZE_32_BIT;
default:
- return INDEX_SIZE_INVALID;
+ return ~0;
}
}
-static inline enum sq_tex_swiz
-tex_swiz(unsigned swiz)
+
+enum adreno_rb_blend_factor
+fd_blend_factor(unsigned factor)
{
- switch (swiz) {
+ switch (factor) {
+ case PIPE_BLENDFACTOR_ONE:
+ return FACTOR_ONE;
+ case PIPE_BLENDFACTOR_SRC_COLOR:
+ return FACTOR_SRC_COLOR;
+ case PIPE_BLENDFACTOR_SRC_ALPHA:
+ return FACTOR_SRC_ALPHA;
+ case PIPE_BLENDFACTOR_DST_ALPHA:
+ return FACTOR_DST_ALPHA;
+ case PIPE_BLENDFACTOR_DST_COLOR:
+ return FACTOR_DST_COLOR;
+ case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE:
+ return FACTOR_SRC_ALPHA_SATURATE;
+ case PIPE_BLENDFACTOR_CONST_COLOR:
+ return FACTOR_CONSTANT_COLOR;
+ case PIPE_BLENDFACTOR_CONST_ALPHA:
+ return FACTOR_CONSTANT_ALPHA;
+ case PIPE_BLENDFACTOR_ZERO:
+ case 0:
+ return FACTOR_ZERO;
+ case PIPE_BLENDFACTOR_INV_SRC_COLOR:
+ return FACTOR_ONE_MINUS_SRC_COLOR;
+ case PIPE_BLENDFACTOR_INV_SRC_ALPHA:
+ return FACTOR_ONE_MINUS_SRC_ALPHA;
+ case PIPE_BLENDFACTOR_INV_DST_ALPHA:
+ return FACTOR_ONE_MINUS_DST_ALPHA;
+ case PIPE_BLENDFACTOR_INV_DST_COLOR:
+ return FACTOR_ONE_MINUS_DST_COLOR;
+ case PIPE_BLENDFACTOR_INV_CONST_COLOR:
+ return FACTOR_ONE_MINUS_CONSTANT_COLOR;
+ case PIPE_BLENDFACTOR_INV_CONST_ALPHA:
+ return FACTOR_ONE_MINUS_CONSTANT_ALPHA;
+ case PIPE_BLENDFACTOR_INV_SRC1_COLOR:
+ case PIPE_BLENDFACTOR_INV_SRC1_ALPHA:
+ case PIPE_BLENDFACTOR_SRC1_COLOR:
+ case PIPE_BLENDFACTOR_SRC1_ALPHA:
+ /* I don't think these are supported */
default:
- case PIPE_SWIZZLE_RED: return SQ_TEX_X;
- case PIPE_SWIZZLE_GREEN: return SQ_TEX_Y;
- case PIPE_SWIZZLE_BLUE: return SQ_TEX_Z;
- case PIPE_SWIZZLE_ALPHA: return SQ_TEX_W;
- case PIPE_SWIZZLE_ZERO: return SQ_TEX_ZERO;
- case PIPE_SWIZZLE_ONE: return SQ_TEX_ONE;
+ DBG("invalid blend factor: %x", factor);
+ return 0;
}
}
-uint32_t
-fd_tex_swiz(enum pipe_format format, unsigned swizzle_r, unsigned swizzle_g,
- unsigned swizzle_b, unsigned swizzle_a)
+enum adreno_rb_blend_opcode
+fd_blend_func(unsigned func)
{
- const struct util_format_description *desc =
- util_format_description(format);
- uint8_t swiz[] = {
- swizzle_r, swizzle_g, swizzle_b, swizzle_a,
- PIPE_SWIZZLE_ZERO, PIPE_SWIZZLE_ONE,
- PIPE_SWIZZLE_ONE, PIPE_SWIZZLE_ONE,
- };
+ switch (func) {
+ case PIPE_BLEND_ADD:
+ return BLEND_DST_PLUS_SRC;
+ case PIPE_BLEND_MIN:
+ return BLEND_MIN_DST_SRC;
+ case PIPE_BLEND_MAX:
+ return BLEND_MAX_DST_SRC;
+ case PIPE_BLEND_SUBTRACT:
+ return BLEND_SRC_MINUS_DST;
+ case PIPE_BLEND_REVERSE_SUBTRACT:
+ return BLEND_DST_MINUS_SRC;
+ default:
+ DBG("invalid blend func: %x", func);
+ return 0;
+ }
+}
- return A2XX_SQ_TEX_3_SWIZ_X(tex_swiz(swiz[desc->swizzle[0]])) |
- A2XX_SQ_TEX_3_SWIZ_Y(tex_swiz(swiz[desc->swizzle[1]])) |
- A2XX_SQ_TEX_3_SWIZ_Z(tex_swiz(swiz[desc->swizzle[2]])) |
- A2XX_SQ_TEX_3_SWIZ_W(tex_swiz(swiz[desc->swizzle[3]]));
+enum adreno_pa_su_sc_draw
+fd_polygon_mode(unsigned mode)
+{
+ switch (mode) {
+ case PIPE_POLYGON_MODE_POINT:
+ return PC_DRAW_POINTS;
+ case PIPE_POLYGON_MODE_LINE:
+ return PC_DRAW_LINES;
+ case PIPE_POLYGON_MODE_FILL:
+ return PC_DRAW_TRIANGLES;
+ default:
+ DBG("invalid polygon mode: %u", mode);
+ return 0;
+ }
+}
+
+enum adreno_stencil_op
+fd_stencil_op(unsigned op)
+{
+ switch (op) {
+ case PIPE_STENCIL_OP_KEEP:
+ return STENCIL_KEEP;
+ case PIPE_STENCIL_OP_ZERO:
+ return STENCIL_ZERO;
+ case PIPE_STENCIL_OP_REPLACE:
+ return STENCIL_REPLACE;
+ case PIPE_STENCIL_OP_INCR:
+ return STENCIL_INCR_CLAMP;
+ case PIPE_STENCIL_OP_DECR:
+ return STENCIL_DECR_CLAMP;
+ case PIPE_STENCIL_OP_INCR_WRAP:
+ return STENCIL_INCR_WRAP;
+ case PIPE_STENCIL_OP_DECR_WRAP:
+ return STENCIL_DECR_WRAP;
+ case PIPE_STENCIL_OP_INVERT:
+ return STENCIL_INVERT;
+ default:
+ DBG("invalid stencil op: %u", op);
+ return 0;
+ }
}
#include "adreno_common.xml.h"
#include "adreno_pm4.xml.h"
-#include "a2xx.xml.h"
-enum a2xx_sq_surfaceformat fd_pipe2surface(enum pipe_format format);
-enum a2xx_colorformatx fd_pipe2color(enum pipe_format format);
-enum a2xx_rb_depth_format fd_pipe2depth(enum pipe_format format);
+enum adreno_rb_depth_format fd_pipe2depth(enum pipe_format format);
enum pc_di_index_size fd_pipe2index(enum pipe_format format);
-uint32_t fd_tex_swiz(enum pipe_format format, unsigned swizzle_r,
- unsigned swizzle_g, unsigned swizzle_b, unsigned swizzle_a);
+enum adreno_rb_blend_factor fd_blend_factor(unsigned factor);
+enum adreno_rb_blend_opcode fd_blend_func(unsigned func);
+enum adreno_pa_su_sc_draw fd_polygon_mode(unsigned mode);
+enum adreno_stencil_op fd_stencil_op(unsigned op);
#define FD_DBG_MSGS 0x1
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
+/* for conditionally setting boolean flag(s): */
+#define COND(bool, val) ((bool) ? (val) : 0)
#define CP_REG(reg) ((0x4 << 16) | ((unsigned int)((reg) - (0x2000))))
(1 << 14);
}
-/* convert x,y to dword */
-static inline uint32_t xy2d(uint16_t x, uint16_t y)
-{
- return ((y & 0x3fff) << 16) | (x & 0x3fff);
-}
-
#define LOG_DWORDS 0
fd_ringbuffer_emit_reloc(ring, bo, offset, or);
}
+/* shifted reloc: */
+static inline void
+OUT_RELOCS(struct fd_ringbuffer *ring, struct fd_bo *bo,
+ uint32_t offset, uint32_t or, int32_t shift)
+{
+ if (LOG_DWORDS) {
+ DBG("ring[%p]: OUT_RELOCS %04x: %p+%u << %d", ring,
+ (uint32_t)(ring->cur - ring->last_start), bo, offset, shift);
+ }
+ fd_ringbuffer_emit_reloc_shift(ring, bo, offset, or, shift);
+}
+
static inline void BEGIN_RING(struct fd_ringbuffer *ring, uint32_t ndwords)
{
if ((ring->cur + ndwords) >= ring->end) {
+++ /dev/null
-/* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */
-
-/*
- * Copyright (C) 2012 Rob Clark <robclark@freedesktop.org>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Authors:
- * Rob Clark <robclark@freedesktop.org>
- */
-
-#include "pipe/p_state.h"
-#include "util/u_string.h"
-#include "util/u_memory.h"
-#include "util/u_prim.h"
-
-#include "freedreno_vbo.h"
-#include "freedreno_context.h"
-#include "freedreno_state.h"
-#include "freedreno_zsa.h"
-#include "freedreno_resource.h"
-#include "freedreno_util.h"
-
-
-static void *
-fd_vertex_state_create(struct pipe_context *pctx, unsigned num_elements,
- const struct pipe_vertex_element *elements)
-{
- struct fd_vertex_stateobj *so = CALLOC_STRUCT(fd_vertex_stateobj);
-
- if (!so)
- return NULL;
-
- memcpy(so->pipe, elements, sizeof(*elements) * num_elements);
- so->num_elements = num_elements;
-
- return so;
-}
-
-static void
-fd_vertex_state_delete(struct pipe_context *pctx, void *hwcso)
-{
- FREE(hwcso);
-}
-
-static void
-fd_vertex_state_bind(struct pipe_context *pctx, void *hwcso)
-{
- struct fd_context *ctx = fd_context(pctx);
- ctx->vtx = hwcso;
- ctx->dirty |= FD_DIRTY_VTXSTATE;
-}
-
-static void
-emit_cacheflush(struct fd_ringbuffer *ring)
-{
- unsigned i;
-
- for (i = 0; i < 12; i++) {
- OUT_PKT3(ring, CP_EVENT_WRITE, 1);
- OUT_RING(ring, CACHE_FLUSH);
- }
-}
-
-static enum pc_di_primtype
-mode2primtype(unsigned mode)
-{
- switch (mode) {
- case PIPE_PRIM_POINTS: return DI_PT_POINTLIST;
- case PIPE_PRIM_LINES: return DI_PT_LINELIST;
- case PIPE_PRIM_LINE_STRIP: return DI_PT_LINESTRIP;
- case PIPE_PRIM_TRIANGLES: return DI_PT_TRILIST;
- case PIPE_PRIM_TRIANGLE_STRIP: return DI_PT_TRISTRIP;
- case PIPE_PRIM_TRIANGLE_FAN: return DI_PT_TRIFAN;
- case PIPE_PRIM_QUADS: return DI_PT_QUADLIST;
- case PIPE_PRIM_QUAD_STRIP: return DI_PT_QUADSTRIP;
- case PIPE_PRIM_POLYGON: return DI_PT_POLYGON;
- }
- DBG("unsupported mode: (%s) %d", u_prim_name(mode), mode);
- assert(0);
- return DI_PT_NONE;
-}
-
-static enum pc_di_index_size
-size2indextype(unsigned index_size)
-{
- switch (index_size) {
- case 1: return INDEX_SIZE_8_BIT;
- case 2: return INDEX_SIZE_16_BIT;
- case 4: return INDEX_SIZE_32_BIT;
- }
- DBG("unsupported index size: %d", index_size);
- assert(0);
- return INDEX_SIZE_IGN;
-}
-
-static void
-emit_vertexbufs(struct fd_context *ctx, unsigned count)
-{
- struct fd_vertex_stateobj *vtx = ctx->vtx;
- struct fd_vertexbuf_stateobj *vertexbuf = &ctx->vertexbuf;
- struct fd_vertex_buf bufs[PIPE_MAX_ATTRIBS];
- unsigned i;
-
- if (!vtx->num_elements)
- return;
-
- for (i = 0; i < vtx->num_elements; i++) {
- struct pipe_vertex_element *elem = &vtx->pipe[i];
- struct pipe_vertex_buffer *vb =
- &vertexbuf->vb[elem->vertex_buffer_index];
- bufs[i].offset = vb->buffer_offset;
- bufs[i].size = count * vb->stride;
- bufs[i].prsc = vb->buffer;
- }
-
- // NOTE I believe the 0x78 (or 0x9c in solid_vp) relates to the
- // CONST(20,0) (or CONST(26,0) in soliv_vp)
-
- fd_emit_vertex_bufs(ctx->ring, 0x78, bufs, vtx->num_elements);
-}
-
-static void
-fd_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info)
-{
- struct fd_context *ctx = fd_context(pctx);
- struct pipe_framebuffer_state *fb = &ctx->framebuffer;
- struct fd_ringbuffer *ring = ctx->ring;
- struct fd_bo *idx_bo = NULL;
- enum pc_di_index_size idx_type = INDEX_SIZE_IGN;
- enum pc_di_src_sel src_sel;
- uint32_t idx_size, idx_offset;
- unsigned buffers;
-
- /* if we supported transform feedback, we'd have to disable this: */
- if (((ctx->scissor.maxx - ctx->scissor.minx) *
- (ctx->scissor.maxy - ctx->scissor.miny)) == 0) {
- return;
- }
-
- ctx->needs_flush = true;
-
- if (info->indexed) {
- struct pipe_index_buffer *idx = &ctx->indexbuf;
-
- assert(!idx->user_buffer);
-
- idx_bo = fd_resource(idx->buffer)->bo;
- idx_type = size2indextype(idx->index_size);
- idx_size = idx->index_size * info->count;
- idx_offset = idx->offset;
- src_sel = DI_SRC_SEL_DMA;
- } else {
- idx_bo = NULL;
- idx_type = INDEX_SIZE_IGN;
- idx_size = 0;
- idx_offset = 0;
- src_sel = DI_SRC_SEL_AUTO_INDEX;
- }
-
- fd_resource(fb->cbufs[0]->texture)->dirty = true;
-
- /* figure out the buffers we need: */
- buffers = FD_BUFFER_COLOR;
- if (fd_depth_enabled(ctx->zsa)) {
- buffers |= FD_BUFFER_DEPTH;
- fd_resource(fb->zsbuf->texture)->dirty = true;
- }
- if (fd_stencil_enabled(ctx->zsa)) {
- buffers |= FD_BUFFER_STENCIL;
- fd_resource(fb->zsbuf->texture)->dirty = true;
- }
-
- /* any buffers that haven't been cleared, we need to restore: */
- ctx->restore |= buffers & (FD_BUFFER_ALL & ~ctx->cleared);
- /* and any buffers used, need to be resolved: */
- ctx->resolve |= buffers;
-
- if (ctx->dirty & FD_DIRTY_VTXBUF)
- emit_vertexbufs(ctx, info->count);
-
- fd_state_emit(pctx, ctx->dirty);
-
- OUT_PKT3(ring, CP_SET_CONSTANT, 2);
- OUT_RING(ring, CP_REG(REG_A2XX_VGT_INDX_OFFSET));
- OUT_RING(ring, info->start);
-
- OUT_PKT3(ring, CP_SET_CONSTANT, 2);
- OUT_RING(ring, CP_REG(REG_A2XX_VGT_VERTEX_REUSE_BLOCK_CNTL));
- OUT_RING(ring, 0x0000003b);
-
- OUT_PKT0(ring, REG_A2XX_TC_CNTL_STATUS, 1);
- OUT_RING(ring, A2XX_TC_CNTL_STATUS_L2_INVALIDATE);
-
- OUT_PKT3(ring, CP_WAIT_FOR_IDLE, 1);
- OUT_RING(ring, 0x0000000);
-
- OUT_PKT3(ring, CP_DRAW_INDX, info->indexed ? 5 : 3);
- OUT_RING(ring, 0x00000000); /* viz query info. */
- OUT_RING(ring, DRAW(mode2primtype(info->mode),
- src_sel, idx_type, IGNORE_VISIBILITY));
- OUT_RING(ring, info->count); /* NumIndices */
- if (info->indexed) {
- OUT_RELOC(ring, idx_bo, idx_offset, 0);
- OUT_RING (ring, idx_size);
- }
-
- OUT_PKT3(ring, CP_SET_CONSTANT, 2);
- OUT_RING(ring, CP_REG(REG_A2XX_UNKNOWN_2010));
- OUT_RING(ring, 0x00000000);
-
- emit_cacheflush(ring);
-}
-
-void
-fd_vbo_init(struct pipe_context *pctx)
-{
- pctx->create_vertex_elements_state = fd_vertex_state_create;
- pctx->delete_vertex_elements_state = fd_vertex_state_delete;
- pctx->bind_vertex_elements_state = fd_vertex_state_bind;
- pctx->draw_vbo = fd_draw_vbo;
-}
+++ /dev/null
-/* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */
-
-/*
- * Copyright (C) 2012 Rob Clark <robclark@freedesktop.org>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Authors:
- * Rob Clark <robclark@freedesktop.org>
- */
-
-#ifndef FREEDRENO_VBO_H_
-#define FREEDRENO_VBO_H_
-
-#include "pipe/p_state.h"
-#include "pipe/p_context.h"
-
-struct fd_vertex_stateobj {
- struct pipe_vertex_element pipe[PIPE_MAX_ATTRIBS];
- unsigned num_elements;
-};
-
-void fd_vbo_init(struct pipe_context *pctx);
-
-#endif /* FREEDRENO_VBO_H_ */
+++ /dev/null
-/* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */
-
-/*
- * Copyright (C) 2012 Rob Clark <robclark@freedesktop.org>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Authors:
- * Rob Clark <robclark@freedesktop.org>
- */
-
-
-#include "pipe/p_state.h"
-#include "util/u_string.h"
-#include "util/u_memory.h"
-
-#include "freedreno_zsa.h"
-#include "freedreno_context.h"
-#include "freedreno_util.h"
-
-static enum adreno_stencil_op
-stencil_op(unsigned op)
-{
- switch (op) {
- case PIPE_STENCIL_OP_KEEP:
- return STENCIL_KEEP;
- case PIPE_STENCIL_OP_ZERO:
- return STENCIL_ZERO;
- case PIPE_STENCIL_OP_REPLACE:
- return STENCIL_REPLACE;
- case PIPE_STENCIL_OP_INCR:
- return STENCIL_INCR_CLAMP;
- case PIPE_STENCIL_OP_DECR:
- return STENCIL_DECR_CLAMP;
- case PIPE_STENCIL_OP_INCR_WRAP:
- return STENCIL_INCR_WRAP;
- case PIPE_STENCIL_OP_DECR_WRAP:
- return STENCIL_DECR_WRAP;
- case PIPE_STENCIL_OP_INVERT:
- return STENCIL_INVERT;
- default:
- DBG("invalid stencil op: %u", op);
- return 0;
- }
-}
-
-static void *
-fd_zsa_state_create(struct pipe_context *pctx,
- const struct pipe_depth_stencil_alpha_state *cso)
-{
- struct fd_zsa_stateobj *so;
-
- so = CALLOC_STRUCT(fd_zsa_stateobj);
- if (!so)
- return NULL;
-
- so->base = *cso;
-
- so->rb_depthcontrol |=
- A2XX_RB_DEPTHCONTROL_ZFUNC(cso->depth.func); /* maps 1:1 */
-
- if (cso->depth.enabled)
- so->rb_depthcontrol |= A2XX_RB_DEPTHCONTROL_Z_ENABLE;
- if (cso->depth.writemask)
- so->rb_depthcontrol |= A2XX_RB_DEPTHCONTROL_Z_WRITE_ENABLE;
-
- if (cso->stencil[0].enabled) {
- const struct pipe_stencil_state *s = &cso->stencil[0];
-
- so->rb_depthcontrol |=
- A2XX_RB_DEPTHCONTROL_STENCIL_ENABLE |
- A2XX_RB_DEPTHCONTROL_STENCILFUNC(s->func) | /* maps 1:1 */
- A2XX_RB_DEPTHCONTROL_STENCILFAIL(stencil_op(s->fail_op)) |
- A2XX_RB_DEPTHCONTROL_STENCILZPASS(stencil_op(s->zpass_op)) |
- A2XX_RB_DEPTHCONTROL_STENCILZFAIL(stencil_op(s->zfail_op));
- so->rb_stencilrefmask |=
- 0xff000000 | /* ??? */
- A2XX_RB_STENCILREFMASK_STENCILWRITEMASK(s->writemask) |
- A2XX_RB_STENCILREFMASK_STENCILMASK(s->valuemask);
-
- if (cso->stencil[1].enabled) {
- const struct pipe_stencil_state *bs = &cso->stencil[1];
-
- so->rb_depthcontrol |=
- A2XX_RB_DEPTHCONTROL_BACKFACE_ENABLE |
- A2XX_RB_DEPTHCONTROL_STENCILFUNC_BF(bs->func) | /* maps 1:1 */
- A2XX_RB_DEPTHCONTROL_STENCILFAIL_BF(stencil_op(bs->fail_op)) |
- A2XX_RB_DEPTHCONTROL_STENCILZPASS_BF(stencil_op(bs->zpass_op)) |
- A2XX_RB_DEPTHCONTROL_STENCILZFAIL_BF(stencil_op(bs->zfail_op));
- so->rb_stencilrefmask_bf |=
- 0xff000000 | /* ??? */
- A2XX_RB_STENCILREFMASK_STENCILWRITEMASK(bs->writemask) |
- A2XX_RB_STENCILREFMASK_STENCILMASK(bs->valuemask);
- }
- }
-
- if (cso->alpha.enabled) {
- so->rb_colorcontrol =
- A2XX_RB_COLORCONTROL_ALPHA_FUNC(cso->alpha.func) |
- A2XX_RB_COLORCONTROL_ALPHA_TEST_ENABLE;
- so->rb_alpha_ref = fui(cso->alpha.ref_value);
- }
-
- return so;
-}
-
-static void
-fd_zsa_state_bind(struct pipe_context *pctx, void *hwcso)
-{
- struct fd_context *ctx = fd_context(pctx);
- ctx->zsa = hwcso;
- ctx->dirty |= FD_DIRTY_ZSA;
-}
-
-static void
-fd_zsa_state_delete(struct pipe_context *pctx, void *hwcso)
-{
- FREE(hwcso);
-}
-
-void
-fd_zsa_init(struct pipe_context *pctx)
-{
- pctx->create_depth_stencil_alpha_state = fd_zsa_state_create;
- pctx->bind_depth_stencil_alpha_state = fd_zsa_state_bind;
- pctx->delete_depth_stencil_alpha_state = fd_zsa_state_delete;
-}
+++ /dev/null
-/* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */
-
-/*
- * Copyright (C) 2012 Rob Clark <robclark@freedesktop.org>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Authors:
- * Rob Clark <robclark@freedesktop.org>
- */
-
-#ifndef FREEDRENO_ZSA_H_
-#define FREEDRENO_ZSA_H_
-
-
-#include "pipe/p_state.h"
-#include "pipe/p_context.h"
-
-#include "freedreno_util.h"
-
-struct fd_zsa_stateobj {
- struct pipe_depth_stencil_alpha_state base;
- uint32_t rb_depthcontrol;
- uint32_t rb_colorcontrol; /* must be OR'd w/ blend->rb_colorcontrol */
- uint32_t rb_alpha_ref;
- uint32_t rb_stencilrefmask;
- uint32_t rb_stencilrefmask_bf;
-};
-
-void fd_zsa_init(struct pipe_context *pctx);
-
-static inline bool fd_depth_enabled(struct fd_zsa_stateobj *zsa)
-{
- return zsa->base.depth.enabled;
-}
-
-static inline bool fd_stencil_enabled(struct fd_zsa_stateobj *zsa)
-{
- return zsa->base.stencil[0].enabled;
-}
-
-#endif /* FREEDRENO_ZSA_H_ */
+++ /dev/null
-/*
- * Copyright (c) 2012 Rob Clark <robdclark@gmail.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#ifndef INSTR_A2XX_H_
-#define INSTR_A2XX_H_
-
-#define PACKED __attribute__((__packed__))
-
-#include "util/u_math.h"
-#include "adreno_common.xml.h"
-#include "a2xx.xml.h"
-
-
-/*
- * ALU instructions:
- */
-
-typedef enum {
- ADDs = 0,
- ADD_PREVs = 1,
- MULs = 2,
- MUL_PREVs = 3,
- MUL_PREV2s = 4,
- MAXs = 5,
- MINs = 6,
- SETEs = 7,
- SETGTs = 8,
- SETGTEs = 9,
- SETNEs = 10,
- FRACs = 11,
- TRUNCs = 12,
- FLOORs = 13,
- EXP_IEEE = 14,
- LOG_CLAMP = 15,
- LOG_IEEE = 16,
- RECIP_CLAMP = 17,
- RECIP_FF = 18,
- RECIP_IEEE = 19,
- RECIPSQ_CLAMP = 20,
- RECIPSQ_FF = 21,
- RECIPSQ_IEEE = 22,
- MOVAs = 23,
- MOVA_FLOORs = 24,
- SUBs = 25,
- SUB_PREVs = 26,
- PRED_SETEs = 27,
- PRED_SETNEs = 28,
- PRED_SETGTs = 29,
- PRED_SETGTEs = 30,
- PRED_SET_INVs = 31,
- PRED_SET_POPs = 32,
- PRED_SET_CLRs = 33,
- PRED_SET_RESTOREs = 34,
- KILLEs = 35,
- KILLGTs = 36,
- KILLGTEs = 37,
- KILLNEs = 38,
- KILLONEs = 39,
- SQRT_IEEE = 40,
- MUL_CONST_0 = 42,
- MUL_CONST_1 = 43,
- ADD_CONST_0 = 44,
- ADD_CONST_1 = 45,
- SUB_CONST_0 = 46,
- SUB_CONST_1 = 47,
- SIN = 48,
- COS = 49,
- RETAIN_PREV = 50,
-} instr_scalar_opc_t;
-
-typedef enum {
- ADDv = 0,
- MULv = 1,
- MAXv = 2,
- MINv = 3,
- SETEv = 4,
- SETGTv = 5,
- SETGTEv = 6,
- SETNEv = 7,
- FRACv = 8,
- TRUNCv = 9,
- FLOORv = 10,
- MULADDv = 11,
- CNDEv = 12,
- CNDGTEv = 13,
- CNDGTv = 14,
- DOT4v = 15,
- DOT3v = 16,
- DOT2ADDv = 17,
- CUBEv = 18,
- MAX4v = 19,
- PRED_SETE_PUSHv = 20,
- PRED_SETNE_PUSHv = 21,
- PRED_SETGT_PUSHv = 22,
- PRED_SETGTE_PUSHv = 23,
- KILLEv = 24,
- KILLGTv = 25,
- KILLGTEv = 26,
- KILLNEv = 27,
- DSTv = 28,
- MOVAv = 29,
-} instr_vector_opc_t;
-
-typedef struct PACKED {
- /* dword0: */
- uint8_t vector_dest : 6;
- uint8_t vector_dest_rel : 1;
- uint8_t low_precision_16b_fp : 1;
- uint8_t scalar_dest : 6;
- uint8_t scalar_dest_rel : 1;
- uint8_t export_data : 1;
- uint8_t vector_write_mask : 4;
- uint8_t scalar_write_mask : 4;
- uint8_t vector_clamp : 1;
- uint8_t scalar_clamp : 1;
- instr_scalar_opc_t scalar_opc : 6;
- /* dword1: */
- uint8_t src3_swiz : 8;
- uint8_t src2_swiz : 8;
- uint8_t src1_swiz : 8;
- uint8_t src3_reg_negate : 1;
- uint8_t src2_reg_negate : 1;
- uint8_t src1_reg_negate : 1;
- uint8_t pred_select : 2;
- uint8_t relative_addr : 1;
- uint8_t const_1_rel_abs : 1;
- uint8_t const_0_rel_abs : 1;
- /* dword2: */
- uint8_t src3_reg : 6;
- uint8_t src3_reg_select : 1;
- uint8_t src3_reg_abs : 1;
- uint8_t src2_reg : 6;
- uint8_t src2_reg_select : 1;
- uint8_t src2_reg_abs : 1;
- uint8_t src1_reg : 6;
- uint8_t src1_reg_select : 1;
- uint8_t src1_reg_abs : 1;
- instr_vector_opc_t vector_opc : 5;
- uint8_t src3_sel : 1;
- uint8_t src2_sel : 1;
- uint8_t src1_sel : 1;
-} instr_alu_t;
-
-
-
-/*
- * CF instructions:
- */
-
-typedef enum {
- NOP = 0,
- EXEC = 1,
- EXEC_END = 2,
- COND_EXEC = 3,
- COND_EXEC_END = 4,
- COND_PRED_EXEC = 5,
- COND_PRED_EXEC_END = 6,
- LOOP_START = 7,
- LOOP_END = 8,
- COND_CALL = 9,
- RETURN = 10,
- COND_JMP = 11,
- ALLOC = 12,
- COND_EXEC_PRED_CLEAN = 13,
- COND_EXEC_PRED_CLEAN_END = 14,
- MARK_VS_FETCH_DONE = 15,
-} instr_cf_opc_t;
-
-typedef enum {
- RELATIVE_ADDR = 0,
- ABSOLUTE_ADDR = 1,
-} instr_addr_mode_t;
-
-typedef enum {
- SQ_NO_ALLOC = 0,
- SQ_POSITION = 1,
- SQ_PARAMETER_PIXEL = 2,
- SQ_MEMORY = 3,
-} instr_alloc_type_t;
-
-typedef struct PACKED {
- uint16_t address : 9;
- uint8_t reserved0 : 3;
- uint8_t count : 3;
- uint8_t yeild : 1;
- uint16_t serialize : 12;
- uint8_t vc : 6; /* vertex cache? */
- uint8_t bool_addr : 8;
- uint8_t condition : 1;
- instr_addr_mode_t address_mode : 1;
- instr_cf_opc_t opc : 4;
-} instr_cf_exec_t;
-
-typedef struct PACKED {
- uint16_t address : 10;
- uint8_t reserved0 : 6;
- uint8_t loop_id : 5;
- uint32_t reserved1 : 22;
- instr_addr_mode_t address_mode : 1;
- instr_cf_opc_t opc : 4;
-} instr_cf_loop_t;
-
-typedef struct PACKED {
- uint16_t address : 10;
- uint8_t reserved0 : 3;
- uint8_t force_call : 1;
- uint8_t predicated_jmp : 1;
- uint32_t reserved1 : 18;
- uint8_t direction : 1;
- uint8_t bool_addr : 8;
- uint8_t condition : 1;
- instr_addr_mode_t address_mode : 1;
- instr_cf_opc_t opc : 4;
-} instr_cf_jmp_call_t;
-
-typedef struct PACKED {
- uint8_t size : 4;
- uint64_t reserved0 : 36;
- uint8_t no_serial : 1;
- instr_alloc_type_t buffer_select : 2;
- uint8_t alloc_mode : 1;
- instr_cf_opc_t opc : 4;
-} instr_cf_alloc_t;
-
-typedef union PACKED {
- instr_cf_exec_t exec;
- instr_cf_loop_t loop;
- instr_cf_jmp_call_t jmp_call;
- instr_cf_alloc_t alloc;
- struct PACKED {
- uint64_t dummy : 44;
- instr_cf_opc_t opc : 4;
- };
-} instr_cf_t;
-
-
-
-/*
- * FETCH instructions:
- */
-
-typedef enum {
- VTX_FETCH = 0,
- TEX_FETCH = 1,
- TEX_GET_BORDER_COLOR_FRAC = 16,
- TEX_GET_COMP_TEX_LOD = 17,
- TEX_GET_GRADIENTS = 18,
- TEX_GET_WEIGHTS = 19,
- TEX_SET_TEX_LOD = 24,
- TEX_SET_GRADIENTS_H = 25,
- TEX_SET_GRADIENTS_V = 26,
- TEX_RESERVED_4 = 27,
-} instr_fetch_opc_t;
-
-typedef enum {
- TEX_FILTER_POINT = 0,
- TEX_FILTER_LINEAR = 1,
- TEX_FILTER_BASEMAP = 2, /* only applicable for mip-filter */
- TEX_FILTER_USE_FETCH_CONST = 3,
-} instr_tex_filter_t;
-
-typedef enum {
- ANISO_FILTER_DISABLED = 0,
- ANISO_FILTER_MAX_1_1 = 1,
- ANISO_FILTER_MAX_2_1 = 2,
- ANISO_FILTER_MAX_4_1 = 3,
- ANISO_FILTER_MAX_8_1 = 4,
- ANISO_FILTER_MAX_16_1 = 5,
- ANISO_FILTER_USE_FETCH_CONST = 7,
-} instr_aniso_filter_t;
-
-typedef enum {
- ARBITRARY_FILTER_2X4_SYM = 0,
- ARBITRARY_FILTER_2X4_ASYM = 1,
- ARBITRARY_FILTER_4X2_SYM = 2,
- ARBITRARY_FILTER_4X2_ASYM = 3,
- ARBITRARY_FILTER_4X4_SYM = 4,
- ARBITRARY_FILTER_4X4_ASYM = 5,
- ARBITRARY_FILTER_USE_FETCH_CONST = 7,
-} instr_arbitrary_filter_t;
-
-typedef enum {
- SAMPLE_CENTROID = 0,
- SAMPLE_CENTER = 1,
-} instr_sample_loc_t;
-
-typedef enum a2xx_sq_surfaceformat instr_surf_fmt_t;
-
-typedef struct PACKED {
- /* dword0: */
- instr_fetch_opc_t opc : 5;
- uint8_t src_reg : 6;
- uint8_t src_reg_am : 1;
- uint8_t dst_reg : 6;
- uint8_t dst_reg_am : 1;
- uint8_t fetch_valid_only : 1;
- uint8_t const_idx : 5;
- uint8_t tx_coord_denorm : 1;
- uint8_t src_swiz : 6;
- /* dword1: */
- uint16_t dst_swiz : 12;
- instr_tex_filter_t mag_filter : 2;
- instr_tex_filter_t min_filter : 2;
- instr_tex_filter_t mip_filter : 2;
- instr_aniso_filter_t aniso_filter : 3;
- instr_arbitrary_filter_t arbitrary_filter : 3;
- instr_tex_filter_t vol_mag_filter : 2;
- instr_tex_filter_t vol_min_filter : 2;
- uint8_t use_comp_lod : 1;
- uint8_t use_reg_lod : 2; /* 0 for cube, 1 for 2d */
- uint8_t pred_select : 1;
- /* dword2: */
- uint8_t use_reg_gradients : 1;
- instr_sample_loc_t sample_location : 1;
- uint8_t lod_bias : 7;
- uint8_t unused : 7;
- uint8_t offset_x : 5;
- uint8_t offset_y : 5;
- uint8_t offset_z : 5;
- uint8_t pred_condition : 1;
-} instr_fetch_tex_t;
-
-typedef struct PACKED {
- /* dword0: */
- instr_fetch_opc_t opc : 5;
- uint8_t src_reg : 6;
- uint8_t src_reg_am : 1;
- uint8_t dst_reg : 6;
- uint8_t dst_reg_am : 1;
- uint8_t must_be_one : 1;
- uint8_t const_index : 5;
- uint8_t const_index_sel : 2;
- uint8_t reserved0 : 3;
- uint8_t src_swiz : 2;
- /* dword1: */
- uint16_t dst_swiz : 12;
- uint8_t format_comp_all : 1; /* '1' for signed, '0' for unsigned? */
- uint8_t num_format_all : 1; /* '0' for normalized, '1' for unnormalized */
- uint8_t signed_rf_mode_all : 1;
- uint8_t reserved1 : 1;
- instr_surf_fmt_t format : 6;
- uint8_t reserved2 : 1;
- uint8_t exp_adjust_all : 7;
- uint8_t reserved3 : 1;
- uint8_t pred_select : 1;
- /* dword2: */
- uint8_t stride : 8;
- /* possibly offset and reserved4 are swapped on a200? */
- uint8_t offset : 8;
- uint8_t reserved4 : 8;
- uint8_t reserved5 : 7;
- uint8_t pred_condition : 1;
-} instr_fetch_vtx_t;
-
-typedef union PACKED {
- instr_fetch_tex_t tex;
- instr_fetch_vtx_t vtx;
- struct PACKED {
- /* dword0: */
- instr_fetch_opc_t opc : 5;
- uint32_t dummy0 : 27;
- /* dword1: */
- uint32_t dummy1 : 32;
- /* dword2: */
- uint32_t dummy2 : 32;
- };
-} instr_fetch_t;
-
-#endif /* INSTR_H_ */
+++ /dev/null
-/*
- * Copyright (c) 2012 Rob Clark <robdclark@gmail.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#include "ir-a2xx.h"
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <assert.h>
-
-#include "freedreno_util.h"
-#include "instr-a2xx.h"
-
-#define DEBUG_MSG(f, ...) do { if (0) DBG(f, ##__VA_ARGS__); } while (0)
-#define WARN_MSG(f, ...) DBG("WARN: "f, ##__VA_ARGS__)
-#define ERROR_MSG(f, ...) DBG("ERROR: "f, ##__VA_ARGS__)
-
-#define REG_MASK 0x3f
-
-static int cf_emit(struct ir2_cf *cf, instr_cf_t *instr);
-
-static int instr_emit(struct ir2_instruction *instr, uint32_t *dwords,
- uint32_t idx, struct ir2_shader_info *info);
-
-static void reg_update_stats(struct ir2_register *reg,
- struct ir2_shader_info *info, bool dest);
-static uint32_t reg_fetch_src_swiz(struct ir2_register *reg, uint32_t n);
-static uint32_t reg_fetch_dst_swiz(struct ir2_register *reg);
-static uint32_t reg_alu_dst_swiz(struct ir2_register *reg);
-static uint32_t reg_alu_src_swiz(struct ir2_register *reg);
-
-/* simple allocator to carve allocations out of an up-front allocated heap,
- * so that we can free everything easily in one shot.
- */
-static void * ir2_alloc(struct ir2_shader *shader, int sz)
-{
- void *ptr = &shader->heap[shader->heap_idx];
- shader->heap_idx += align(sz, 4);
- return ptr;
-}
-
-static char * ir2_strdup(struct ir2_shader *shader, const char *str)
-{
- char *ptr = NULL;
- if (str) {
- int len = strlen(str);
- ptr = ir2_alloc(shader, len+1);
- memcpy(ptr, str, len);
- ptr[len] = '\0';
- }
- return ptr;
-}
-
-struct ir2_shader * ir2_shader_create(void)
-{
- DEBUG_MSG("");
- return calloc(1, sizeof(struct ir2_shader));
-}
-
-void ir2_shader_destroy(struct ir2_shader *shader)
-{
- DEBUG_MSG("");
- free(shader);
-}
-
-/* resolve addr/cnt/sequence fields in the individual CF's */
-static int shader_resolve(struct ir2_shader *shader, struct ir2_shader_info *info)
-{
- uint32_t addr;
- unsigned i;
- int j;
-
- addr = shader->cfs_count / 2;
- for (i = 0; i < shader->cfs_count; i++) {
- struct ir2_cf *cf = shader->cfs[i];
- if ((cf->cf_type == EXEC) || (cf->cf_type == EXEC_END)) {
- uint32_t sequence = 0;
-
- if (cf->exec.addr && (cf->exec.addr != addr))
- WARN_MSG("invalid addr '%d' at CF %d", cf->exec.addr, i);
- if (cf->exec.cnt && (cf->exec.cnt != cf->exec.instrs_count))
- WARN_MSG("invalid cnt '%d' at CF %d", cf->exec.cnt, i);
-
- for (j = cf->exec.instrs_count - 1; j >= 0; j--) {
- struct ir2_instruction *instr = cf->exec.instrs[j];
- sequence <<= 2;
- if (instr->instr_type == IR2_FETCH)
- sequence |= 0x1;
- if (instr->sync)
- sequence |= 0x2;
- }
-
- cf->exec.addr = addr;
- cf->exec.cnt = cf->exec.instrs_count;
- cf->exec.sequence = sequence;
-
- addr += cf->exec.instrs_count;
- }
- }
-
- info->sizedwords = 3 * addr;
-
- return 0;
-}
-
-void * ir2_shader_assemble(struct ir2_shader *shader, struct ir2_shader_info *info)
-{
- uint32_t i, j;
- uint32_t *ptr, *dwords = NULL;
- uint32_t idx = 0;
- int ret;
-
- info->sizedwords = 0;
- info->max_reg = -1;
- info->max_input_reg = 0;
- info->regs_written = 0;
-
- /* we need an even # of CF's.. insert a NOP if needed */
- if (shader->cfs_count != align(shader->cfs_count, 2))
- ir2_cf_create(shader, NOP);
-
- /* first pass, resolve sizes and addresses: */
- ret = shader_resolve(shader, info);
- if (ret) {
- ERROR_MSG("resolve failed: %d", ret);
- goto fail;
- }
-
- ptr = dwords = calloc(1, 4 * info->sizedwords);
-
- /* second pass, emit CF program in pairs: */
- for (i = 0; i < shader->cfs_count; i += 2) {
- instr_cf_t *cfs = (instr_cf_t *)ptr;
- ret = cf_emit(shader->cfs[i], &cfs[0]);
- if (ret) {
- ERROR_MSG("CF emit failed: %d\n", ret);
- goto fail;
- }
- ret = cf_emit(shader->cfs[i+1], &cfs[1]);
- if (ret) {
- ERROR_MSG("CF emit failed: %d\n", ret);
- goto fail;
- }
- ptr += 3;
- assert((ptr - dwords) <= info->sizedwords);
- }
-
- /* third pass, emit ALU/FETCH: */
- for (i = 0; i < shader->cfs_count; i++) {
- struct ir2_cf *cf = shader->cfs[i];
- if ((cf->cf_type == EXEC) || (cf->cf_type == EXEC_END)) {
- for (j = 0; j < cf->exec.instrs_count; j++) {
- ret = instr_emit(cf->exec.instrs[j], ptr, idx++, info);
- if (ret) {
- ERROR_MSG("instruction emit failed: %d", ret);
- goto fail;
- }
- ptr += 3;
- assert((ptr - dwords) <= info->sizedwords);
- }
- }
- }
-
- return dwords;
-
-fail:
- free(dwords);
- return NULL;
-}
-
-
-struct ir2_cf * ir2_cf_create(struct ir2_shader *shader, instr_cf_opc_t cf_type)
-{
- struct ir2_cf *cf = ir2_alloc(shader, sizeof(struct ir2_cf));
- DEBUG_MSG("%d", cf_type);
- cf->shader = shader;
- cf->cf_type = cf_type;
- assert(shader->cfs_count < ARRAY_SIZE(shader->cfs));
- shader->cfs[shader->cfs_count++] = cf;
- return cf;
-}
-
-
-/*
- * CF instructions:
- */
-
-static int cf_emit(struct ir2_cf *cf, instr_cf_t *instr)
-{
- memset(instr, 0, sizeof(*instr));
-
- instr->opc = cf->cf_type;
-
- switch (cf->cf_type) {
- case NOP:
- break;
- case EXEC:
- case EXEC_END:
- assert(cf->exec.addr <= 0x1ff);
- assert(cf->exec.cnt <= 0x6);
- assert(cf->exec.sequence <= 0xfff);
- instr->exec.address = cf->exec.addr;
- instr->exec.count = cf->exec.cnt;
- instr->exec.serialize = cf->exec.sequence;
- break;
- case ALLOC:
- assert(cf->alloc.size <= 0xf);
- instr->alloc.size = cf->alloc.size;
- switch (cf->alloc.type) {
- case SQ_POSITION:
- case SQ_PARAMETER_PIXEL:
- instr->alloc.buffer_select = cf->alloc.type;
- break;
- default:
- ERROR_MSG("invalid alloc type: %d", cf->alloc.type);
- return -1;
- }
- break;
- case COND_EXEC:
- case COND_EXEC_END:
- case COND_PRED_EXEC:
- case COND_PRED_EXEC_END:
- case LOOP_START:
- case LOOP_END:
- case COND_CALL:
- case RETURN:
- case COND_JMP:
- case COND_EXEC_PRED_CLEAN:
- case COND_EXEC_PRED_CLEAN_END:
- case MARK_VS_FETCH_DONE:
- ERROR_MSG("TODO");
- return -1;
- }
-
- return 0;
-}
-
-
-struct ir2_instruction * ir2_instr_create(struct ir2_cf *cf, int instr_type)
-{
- struct ir2_instruction *instr =
- ir2_alloc(cf->shader, sizeof(struct ir2_instruction));
- DEBUG_MSG("%d", instr_type);
- instr->shader = cf->shader;
- instr->pred = cf->shader->pred;
- instr->instr_type = instr_type;
- assert(cf->exec.instrs_count < ARRAY_SIZE(cf->exec.instrs));
- cf->exec.instrs[cf->exec.instrs_count++] = instr;
- return instr;
-}
-
-
-/*
- * FETCH instructions:
- */
-
-static int instr_emit_fetch(struct ir2_instruction *instr,
- uint32_t *dwords, uint32_t idx,
- struct ir2_shader_info *info)
-{
- instr_fetch_t *fetch = (instr_fetch_t *)dwords;
- int reg = 0;
- struct ir2_register *dst_reg = instr->regs[reg++];
- struct ir2_register *src_reg = instr->regs[reg++];
-
- memset(fetch, 0, sizeof(*fetch));
-
- reg_update_stats(dst_reg, info, true);
- reg_update_stats(src_reg, info, false);
-
- fetch->opc = instr->fetch.opc;
-
- if (instr->fetch.opc == VTX_FETCH) {
- instr_fetch_vtx_t *vtx = &fetch->vtx;
-
- assert(instr->fetch.stride <= 0xff);
- assert(instr->fetch.fmt <= 0x3f);
- assert(instr->fetch.const_idx <= 0x1f);
- assert(instr->fetch.const_idx_sel <= 0x3);
-
- vtx->src_reg = src_reg->num;
- vtx->src_swiz = reg_fetch_src_swiz(src_reg, 1);
- vtx->dst_reg = dst_reg->num;
- vtx->dst_swiz = reg_fetch_dst_swiz(dst_reg);
- vtx->must_be_one = 1;
- vtx->const_index = instr->fetch.const_idx;
- vtx->const_index_sel = instr->fetch.const_idx_sel;
- vtx->format_comp_all = !!instr->fetch.is_signed;
- vtx->num_format_all = !instr->fetch.is_normalized;
- vtx->format = instr->fetch.fmt;
- vtx->stride = instr->fetch.stride;
- vtx->offset = instr->fetch.offset;
-
- if (instr->pred != IR2_PRED_NONE) {
- vtx->pred_select = 1;
- vtx->pred_condition = (instr->pred == IR2_PRED_EQ) ? 1 : 0;
- }
-
- /* XXX seems like every FETCH but the first has
- * this bit set:
- */
- vtx->reserved3 = (idx > 0) ? 0x1 : 0x0;
- vtx->reserved0 = (idx > 0) ? 0x2 : 0x3;
- } else if (instr->fetch.opc == TEX_FETCH) {
- instr_fetch_tex_t *tex = &fetch->tex;
-
- assert(instr->fetch.const_idx <= 0x1f);
-
- tex->src_reg = src_reg->num;
- tex->src_swiz = reg_fetch_src_swiz(src_reg, 3);
- tex->dst_reg = dst_reg->num;
- tex->dst_swiz = reg_fetch_dst_swiz(dst_reg);
- tex->const_idx = instr->fetch.const_idx;
- tex->mag_filter = TEX_FILTER_USE_FETCH_CONST;
- tex->min_filter = TEX_FILTER_USE_FETCH_CONST;
- tex->mip_filter = TEX_FILTER_USE_FETCH_CONST;
- tex->aniso_filter = ANISO_FILTER_USE_FETCH_CONST;
- tex->arbitrary_filter = ARBITRARY_FILTER_USE_FETCH_CONST;
- tex->vol_mag_filter = TEX_FILTER_USE_FETCH_CONST;
- tex->vol_min_filter = TEX_FILTER_USE_FETCH_CONST;
- tex->use_comp_lod = 1;
- tex->use_reg_lod = !instr->fetch.is_cube;
- tex->sample_location = SAMPLE_CENTER;
-
- if (instr->pred != IR2_PRED_NONE) {
- tex->pred_select = 1;
- tex->pred_condition = (instr->pred == IR2_PRED_EQ) ? 1 : 0;
- }
-
- } else {
- ERROR_MSG("invalid fetch opc: %d\n", instr->fetch.opc);
- return -1;
- }
-
- return 0;
-}
-
-/*
- * ALU instructions:
- */
-
-static int instr_emit_alu(struct ir2_instruction *instr, uint32_t *dwords,
- struct ir2_shader_info *info)
-{
- int reg = 0;
- instr_alu_t *alu = (instr_alu_t *)dwords;
- struct ir2_register *dst_reg = instr->regs[reg++];
- struct ir2_register *src1_reg;
- struct ir2_register *src2_reg;
- struct ir2_register *src3_reg;
-
- memset(alu, 0, sizeof(*alu));
-
- /* handle instructions w/ 3 src operands: */
- switch (instr->alu.vector_opc) {
- case MULADDv:
- case CNDEv:
- case CNDGTEv:
- case CNDGTv:
- case DOT2ADDv:
- /* note: disassembler lists 3rd src first, ie:
- * MULADDv Rdst = Rsrc3 + (Rsrc1 * Rsrc2)
- * which is the reason for this strange ordering.
- */
- src3_reg = instr->regs[reg++];
- break;
- default:
- src3_reg = NULL;
- break;
- }
-
- src1_reg = instr->regs[reg++];
- src2_reg = instr->regs[reg++];
-
- reg_update_stats(dst_reg, info, true);
- reg_update_stats(src1_reg, info, false);
- reg_update_stats(src2_reg, info, false);
-
- assert((dst_reg->flags & ~IR2_REG_EXPORT) == 0);
- assert(!dst_reg->swizzle || (strlen(dst_reg->swizzle) == 4));
- assert((src1_reg->flags & IR2_REG_EXPORT) == 0);
- assert(!src1_reg->swizzle || (strlen(src1_reg->swizzle) == 4));
- assert((src2_reg->flags & IR2_REG_EXPORT) == 0);
- assert(!src2_reg->swizzle || (strlen(src2_reg->swizzle) == 4));
-
- if (instr->alu.vector_opc == ~0) {
- alu->vector_opc = MAXv;
- alu->vector_write_mask = 0;
- } else {
- alu->vector_opc = instr->alu.vector_opc;
- alu->vector_write_mask = reg_alu_dst_swiz(dst_reg);
- }
-
- alu->vector_dest = dst_reg->num;
- alu->export_data = !!(dst_reg->flags & IR2_REG_EXPORT);
-
- // TODO predicate case/condition.. need to add to parser
-
- alu->src2_reg = src2_reg->num;
- alu->src2_swiz = reg_alu_src_swiz(src2_reg);
- alu->src2_reg_negate = !!(src2_reg->flags & IR2_REG_NEGATE);
- alu->src2_reg_abs = !!(src2_reg->flags & IR2_REG_ABS);
- alu->src2_sel = !(src2_reg->flags & IR2_REG_CONST);
-
- alu->src1_reg = src1_reg->num;
- alu->src1_swiz = reg_alu_src_swiz(src1_reg);
- alu->src1_reg_negate = !!(src1_reg->flags & IR2_REG_NEGATE);
- alu->src1_reg_abs = !!(src1_reg->flags & IR2_REG_ABS);
- alu->src1_sel = !(src1_reg->flags & IR2_REG_CONST);
-
- alu->vector_clamp = instr->alu.vector_clamp;
- alu->scalar_clamp = instr->alu.scalar_clamp;
-
- if (instr->alu.scalar_opc != ~0) {
- struct ir2_register *sdst_reg = instr->regs[reg++];
-
- reg_update_stats(sdst_reg, info, true);
-
- assert(sdst_reg->flags == dst_reg->flags);
-
- if (src3_reg) {
- assert(src3_reg == instr->regs[reg++]);
- } else {
- src3_reg = instr->regs[reg++];
- }
-
- alu->scalar_dest = sdst_reg->num;
- alu->scalar_write_mask = reg_alu_dst_swiz(sdst_reg);
- alu->scalar_opc = instr->alu.scalar_opc;
- } else {
- /* not sure if this is required, but adreno compiler seems
- * to always set scalar opc to MAXs if it is not used:
- */
- alu->scalar_opc = MAXs;
- }
-
- if (src3_reg) {
- reg_update_stats(src3_reg, info, false);
-
- alu->src3_reg = src3_reg->num;
- alu->src3_swiz = reg_alu_src_swiz(src3_reg);
- alu->src3_reg_negate = !!(src3_reg->flags & IR2_REG_NEGATE);
- alu->src3_reg_abs = !!(src3_reg->flags & IR2_REG_ABS);
- alu->src3_sel = !(src3_reg->flags & IR2_REG_CONST);
- } else {
- /* not sure if this is required, but adreno compiler seems
- * to always set register bank for 3rd src if unused:
- */
- alu->src3_sel = 1;
- }
-
- if (instr->pred != IR2_PRED_NONE) {
- alu->pred_select = (instr->pred == IR2_PRED_EQ) ? 3 : 2;
- }
-
- return 0;
-}
-
-static int instr_emit(struct ir2_instruction *instr, uint32_t *dwords,
- uint32_t idx, struct ir2_shader_info *info)
-{
- switch (instr->instr_type) {
- case IR2_FETCH: return instr_emit_fetch(instr, dwords, idx, info);
- case IR2_ALU: return instr_emit_alu(instr, dwords, info);
- }
- return -1;
-}
-
-
-struct ir2_register * ir2_reg_create(struct ir2_instruction *instr,
- int num, const char *swizzle, int flags)
-{
- struct ir2_register *reg =
- ir2_alloc(instr->shader, sizeof(struct ir2_register));
- DEBUG_MSG("%x, %d, %s", flags, num, swizzle);
- assert(num <= REG_MASK);
- reg->flags = flags;
- reg->num = num;
- reg->swizzle = ir2_strdup(instr->shader, swizzle);
- assert(instr->regs_count < ARRAY_SIZE(instr->regs));
- instr->regs[instr->regs_count++] = reg;
- return reg;
-}
-
-static void reg_update_stats(struct ir2_register *reg,
- struct ir2_shader_info *info, bool dest)
-{
- if (!(reg->flags & (IR2_REG_CONST|IR2_REG_EXPORT))) {
- info->max_reg = MAX2(info->max_reg, reg->num);
-
- if (dest) {
- info->regs_written |= (1 << reg->num);
- } else if (!(info->regs_written & (1 << reg->num))) {
- /* for registers that haven't been written, they must be an
- * input register that the thread scheduler (presumably?)
- * needs to know about:
- */
- info->max_input_reg = MAX2(info->max_input_reg, reg->num);
- }
- }
-}
-
-static uint32_t reg_fetch_src_swiz(struct ir2_register *reg, uint32_t n)
-{
- uint32_t swiz = 0;
- int i;
-
- assert(reg->flags == 0);
- assert(reg->swizzle);
-
- DEBUG_MSG("fetch src R%d.%s", reg->num, reg->swizzle);
-
- for (i = n-1; i >= 0; i--) {
- swiz <<= 2;
- switch (reg->swizzle[i]) {
- default:
- ERROR_MSG("invalid fetch src swizzle: %s", reg->swizzle);
- case 'x': swiz |= 0x0; break;
- case 'y': swiz |= 0x1; break;
- case 'z': swiz |= 0x2; break;
- case 'w': swiz |= 0x3; break;
- }
- }
-
- return swiz;
-}
-
-static uint32_t reg_fetch_dst_swiz(struct ir2_register *reg)
-{
- uint32_t swiz = 0;
- int i;
-
- assert(reg->flags == 0);
- assert(!reg->swizzle || (strlen(reg->swizzle) == 4));
-
- DEBUG_MSG("fetch dst R%d.%s", reg->num, reg->swizzle);
-
- if (reg->swizzle) {
- for (i = 3; i >= 0; i--) {
- swiz <<= 3;
- switch (reg->swizzle[i]) {
- default:
- ERROR_MSG("invalid dst swizzle: %s", reg->swizzle);
- case 'x': swiz |= 0x0; break;
- case 'y': swiz |= 0x1; break;
- case 'z': swiz |= 0x2; break;
- case 'w': swiz |= 0x3; break;
- case '0': swiz |= 0x4; break;
- case '1': swiz |= 0x5; break;
- case '_': swiz |= 0x7; break;
- }
- }
- } else {
- swiz = 0x688;
- }
-
- return swiz;
-}
-
-/* actually, a write-mask */
-static uint32_t reg_alu_dst_swiz(struct ir2_register *reg)
-{
- uint32_t swiz = 0;
- int i;
-
- assert((reg->flags & ~IR2_REG_EXPORT) == 0);
- assert(!reg->swizzle || (strlen(reg->swizzle) == 4));
-
- DEBUG_MSG("alu dst R%d.%s", reg->num, reg->swizzle);
-
- if (reg->swizzle) {
- for (i = 3; i >= 0; i--) {
- swiz <<= 1;
- if (reg->swizzle[i] == "xyzw"[i]) {
- swiz |= 0x1;
- } else if (reg->swizzle[i] != '_') {
- ERROR_MSG("invalid dst swizzle: %s", reg->swizzle);
- break;
- }
- }
- } else {
- swiz = 0xf;
- }
-
- return swiz;
-}
-
-static uint32_t reg_alu_src_swiz(struct ir2_register *reg)
-{
- uint32_t swiz = 0;
- int i;
-
- assert((reg->flags & IR2_REG_EXPORT) == 0);
- assert(!reg->swizzle || (strlen(reg->swizzle) == 4));
-
- DEBUG_MSG("vector src R%d.%s", reg->num, reg->swizzle);
-
- if (reg->swizzle) {
- for (i = 3; i >= 0; i--) {
- swiz <<= 2;
- switch (reg->swizzle[i]) {
- default:
- ERROR_MSG("invalid vector src swizzle: %s", reg->swizzle);
- case 'x': swiz |= (0x0 - i) & 0x3; break;
- case 'y': swiz |= (0x1 - i) & 0x3; break;
- case 'z': swiz |= (0x2 - i) & 0x3; break;
- case 'w': swiz |= (0x3 - i) & 0x3; break;
- }
- }
- } else {
- swiz = 0x0;
- }
-
- return swiz;
-}
+++ /dev/null
-/*
- * Copyright (c) 2012 Rob Clark <robdclark@gmail.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#ifndef IR2_H_
-#define IR2_H_
-
-#include <stdint.h>
-#include <stdbool.h>
-
-#include "instr-a2xx.h"
-
-/* low level intermediate representation of an adreno a2xx shader program */
-
-struct ir2_shader;
-
-struct ir2_shader_info {
- uint16_t sizedwords;
- int8_t max_reg; /* highest GPR # used by shader */
- uint8_t max_input_reg;
- uint64_t regs_written;
-};
-
-struct ir2_register {
- enum {
- IR2_REG_CONST = 0x1,
- IR2_REG_EXPORT = 0x2,
- IR2_REG_NEGATE = 0x4,
- IR2_REG_ABS = 0x8,
- } flags;
- int num;
- char *swizzle;
-};
-
-enum ir2_pred {
- IR2_PRED_NONE = 0,
- IR2_PRED_EQ = 1,
- IR2_PRED_NE = 2,
-};
-
-struct ir2_instruction {
- struct ir2_shader *shader;
- enum {
- IR2_FETCH,
- IR2_ALU,
- } instr_type;
- enum ir2_pred pred;
- int sync;
- unsigned regs_count;
- struct ir2_register *regs[5];
- union {
- /* FETCH specific: */
- struct {
- instr_fetch_opc_t opc;
- unsigned const_idx;
- /* texture fetch specific: */
- bool is_cube : 1;
- /* vertex fetch specific: */
- unsigned const_idx_sel;
- enum a2xx_sq_surfaceformat fmt;
- bool is_signed : 1;
- bool is_normalized : 1;
- uint32_t stride;
- uint32_t offset;
- } fetch;
- /* ALU specific: */
- struct {
- instr_vector_opc_t vector_opc;
- instr_scalar_opc_t scalar_opc;
- bool vector_clamp : 1;
- bool scalar_clamp : 1;
- } alu;
- };
-};
-
-struct ir2_cf {
- struct ir2_shader *shader;
- instr_cf_opc_t cf_type;
-
- union {
- /* EXEC/EXEC_END specific: */
- struct {
- unsigned instrs_count;
- struct ir2_instruction *instrs[6];
- uint32_t addr, cnt, sequence;
- } exec;
- /* ALLOC specific: */
- struct {
- instr_alloc_type_t type; /* SQ_POSITION or SQ_PARAMETER_PIXEL */
- int size;
- } alloc;
- };
-};
-
-struct ir2_shader {
- unsigned cfs_count;
- struct ir2_cf *cfs[0x56];
- uint32_t heap[100 * 4096];
- unsigned heap_idx;
-
- enum ir2_pred pred; /* pred inherited by newly created instrs */
-};
-
-struct ir2_shader * ir2_shader_create(void);
-void ir2_shader_destroy(struct ir2_shader *shader);
-void * ir2_shader_assemble(struct ir2_shader *shader,
- struct ir2_shader_info *info);
-
-struct ir2_cf * ir2_cf_create(struct ir2_shader *shader, instr_cf_opc_t cf_type);
-
-struct ir2_instruction * ir2_instr_create(struct ir2_cf *cf, int instr_type);
-
-struct ir2_register * ir2_reg_create(struct ir2_instruction *instr,
- int num, const char *swizzle, int flags);
-
-/* some helper fxns: */
-
-static inline struct ir2_cf *
-ir2_cf_create_alloc(struct ir2_shader *shader, instr_alloc_type_t type, int size)
-{
- struct ir2_cf *cf = ir2_cf_create(shader, ALLOC);
- if (!cf)
- return cf;
- cf->alloc.type = type;
- cf->alloc.size = size;
- return cf;
-}
-static inline struct ir2_instruction *
-ir2_instr_create_alu(struct ir2_cf *cf, instr_vector_opc_t vop, instr_scalar_opc_t sop)
-{
- struct ir2_instruction *instr = ir2_instr_create(cf, IR2_ALU);
- if (!instr)
- return instr;
- instr->alu.vector_opc = vop;
- instr->alu.scalar_opc = sop;
- return instr;
-}
-static inline struct ir2_instruction *
-ir2_instr_create_vtx_fetch(struct ir2_cf *cf, int ci, int cis,
- enum a2xx_sq_surfaceformat fmt, bool is_signed, int stride)
-{
- struct ir2_instruction *instr = instr = ir2_instr_create(cf, IR2_FETCH);
- instr->fetch.opc = VTX_FETCH;
- instr->fetch.const_idx = ci;
- instr->fetch.const_idx_sel = cis;
- instr->fetch.fmt = fmt;
- instr->fetch.is_signed = is_signed;
- instr->fetch.stride = stride;
- return instr;
-}
-static inline struct ir2_instruction *
-ir2_instr_create_tex_fetch(struct ir2_cf *cf, int ci)
-{
- struct ir2_instruction *instr = instr = ir2_instr_create(cf, IR2_FETCH);
- instr->fetch.opc = TEX_FETCH;
- instr->fetch.const_idx = ci;
- return instr;
-}
-
-
-#endif /* IR2_H_ */