diff options
Diffstat (limited to 'src/gallium/drivers/freedreno')
49 files changed, 2798 insertions, 2008 deletions
diff --git a/src/gallium/drivers/freedreno/Makefile.am b/src/gallium/drivers/freedreno/Makefile.am index dde0cf1647b..64dfda62399 100644 --- a/src/gallium/drivers/freedreno/Makefile.am +++ b/src/gallium/drivers/freedreno/Makefile.am @@ -5,28 +5,25 @@ noinst_LTLIBRARIES = libfreedreno.la 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 diff --git a/src/gallium/drivers/freedreno/a2xx/Makefile.am b/src/gallium/drivers/freedreno/a2xx/Makefile.am new file mode 100644 index 00000000000..8ab0f762058 --- /dev/null +++ b/src/gallium/drivers/freedreno/a2xx/Makefile.am @@ -0,0 +1,27 @@ +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 diff --git a/src/gallium/drivers/freedreno/a2xx.xml.h b/src/gallium/drivers/freedreno/a2xx/a2xx.xml.h index da13cfdbba6..bee01f1c7e1 100644 --- a/src/gallium/drivers/freedreno/a2xx.xml.h +++ b/src/gallium/drivers/freedreno/a2xx/a2xx.xml.h @@ -8,10 +8,10 @@ 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/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 ( 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 <[email protected]> (robclark) @@ -59,7 +59,6 @@ enum a2xx_colorformatx { COLORX_32_32_32_32_FLOAT = 12, COLORX_2_3_3 = 13, COLORX_8_8_8 = 14, - COLORX_INVALID = 15, }; enum a2xx_sq_surfaceformat { @@ -124,13 +123,6 @@ enum a2xx_sq_surfaceformat { 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 { @@ -539,7 +531,7 @@ static inline uint32_t A2XX_RB_COLOR_INFO_BASE(uint32_t val) #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) +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; } @@ -587,13 +579,13 @@ static inline uint32_t A2XX_PA_SC_SCREEN_SCISSOR_BR_Y(uint32_t val) #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) +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(uint32_t val) +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; } diff --git a/src/gallium/drivers/freedreno/disasm.c b/src/gallium/drivers/freedreno/a2xx/disasm-a2xx.c index bdb4886cbef..f00d5d4dcf5 100644 --- a/src/gallium/drivers/freedreno/disasm.c +++ b/src/gallium/drivers/freedreno/a2xx/disasm-a2xx.c @@ -590,7 +590,7 @@ static void print_cf(instr_cf_t *cf, int level) * 2) ALU and FETCH instructions */ -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) { instr_cf_t *cfs = (instr_cf_t *)dwords; int idx, max_idx; @@ -628,5 +628,5 @@ int disasm(uint32_t *dwords, int sizedwords, int level, enum shader_t type) void disasm_set_debug(enum debug_t d) { - debug= d; + debug = d; } diff --git a/src/gallium/drivers/freedreno/a2xx/fd2_blend.c b/src/gallium/drivers/freedreno/a2xx/fd2_blend.c new file mode 100644 index 00000000000..d0b324d7fe3 --- /dev/null +++ b/src/gallium/drivers/freedreno/a2xx/fd2_blend.c @@ -0,0 +1,86 @@ +/* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */ + +/* + * Copyright (C) 2012-2013 Rob Clark <[email protected]> + * + * 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 <[email protected]> + */ + +#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; +} diff --git a/src/gallium/drivers/freedreno/freedreno_blend.h b/src/gallium/drivers/freedreno/a2xx/fd2_blend.h index 70950dfa911..7cafcd3747e 100644 --- a/src/gallium/drivers/freedreno/freedreno_blend.h +++ b/src/gallium/drivers/freedreno/a2xx/fd2_blend.h @@ -1,7 +1,7 @@ /* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */ /* - * Copyright (C) 2012 Rob Clark <[email protected]> + * Copyright (C) 2012-2013 Rob Clark <[email protected]> * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -26,19 +26,26 @@ * Rob Clark <[email protected]> */ -#ifndef FREEDRENO_BLEND_H_ -#define FREEDRENO_BLEND_H_ +#ifndef FD2_BLEND_H_ +#define FD2_BLEND_H_ #include "pipe/p_state.h" #include "pipe/p_context.h" -struct fd_blend_stateobj { +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; }; -void fd_blend_init(struct pipe_context *pctx); +static INLINE struct fd2_blend_stateobj * +fd2_blend_stateobj(struct pipe_blend_state *blend) +{ + return (struct fd2_blend_stateobj *)blend; +} -#endif /* FREEDRENO_BLEND_H_ */ +void * fd2_blend_state_create(struct pipe_context *pctx, + const struct pipe_blend_state *cso); + +#endif /* FD2_BLEND_H_ */ diff --git a/src/gallium/drivers/freedreno/freedreno_compiler.c b/src/gallium/drivers/freedreno/a2xx/fd2_compiler.c index 8d1e266d46a..4d0dc323a68 100644 --- a/src/gallium/drivers/freedreno/freedreno_compiler.c +++ b/src/gallium/drivers/freedreno/a2xx/fd2_compiler.c @@ -36,16 +36,16 @@ #include "tgsi/tgsi_strings.h" #include "tgsi/tgsi_dump.h" -#include "freedreno_program.h" -#include "freedreno_compiler.h" -#include "freedreno_util.h" +#include "fd2_compiler.h" +#include "fd2_program.h" +#include "fd2_util.h" #include "instr-a2xx.h" #include "ir-a2xx.h" -struct fd_compile_context { +struct fd2_compile_context { struct fd_program_stateobj *prog; - struct fd_shader_stateobj *so; + struct fd2_shader_stateobj *so; struct tgsi_parse_context parser; unsigned type; @@ -111,7 +111,7 @@ semantic_idx(struct tgsi_declaration_semantic *semantic) * returned by semantic_idx(): */ static int -export_linkage(struct fd_compile_context *ctx, int idx) +export_linkage(struct fd2_compile_context *ctx, int idx) { struct fd_program_stateobj *prog = ctx->prog; @@ -123,8 +123,8 @@ export_linkage(struct fd_compile_context *ctx, int idx) } static unsigned -compile_init(struct fd_compile_context *ctx, struct fd_program_stateobj *prog, - struct fd_shader_stateobj *so) +compile_init(struct fd2_compile_context *ctx, struct fd_program_stateobj *prog, + struct fd2_shader_stateobj *so) { unsigned ret; @@ -176,6 +176,7 @@ compile_init(struct fd_compile_context *ctx, struct fd_program_stateobj *prog, 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++; @@ -230,13 +231,13 @@ compile_init(struct fd_compile_context *ctx, struct fd_program_stateobj *prog, } static void -compile_free(struct fd_compile_context *ctx) +compile_free(struct fd2_compile_context *ctx) { tgsi_parse_free(&ctx->parser); } static struct ir2_cf * -next_exec_cf(struct fd_compile_context *ctx) +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)) @@ -245,7 +246,7 @@ next_exec_cf(struct fd_compile_context *ctx) } static void -compile_vtx_fetch(struct fd_compile_context *ctx) +compile_vtx_fetch(struct fd2_compile_context *ctx) { struct ir2_instruction **vfetch_instrs = ctx->so->vfetch_instrs; int i; @@ -303,7 +304,7 @@ compile_vtx_fetch(struct fd_compile_context *ctx) */ static unsigned -get_temp_gpr(struct fd_compile_context *ctx, int idx) +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) @@ -312,7 +313,7 @@ get_temp_gpr(struct fd_compile_context *ctx, int idx) } static struct ir2_register * -add_dst_reg(struct fd_compile_context *ctx, struct ir2_instruction *alu, +add_dst_reg(struct fd2_compile_context *ctx, struct ir2_instruction *alu, const struct tgsi_dst_register *dst) { unsigned flags = 0, num = 0; @@ -354,7 +355,7 @@ add_dst_reg(struct fd_compile_context *ctx, struct ir2_instruction *alu, } static struct ir2_register * -add_src_reg(struct fd_compile_context *ctx, struct ir2_instruction *alu, +add_src_reg(struct fd2_compile_context *ctx, struct ir2_instruction *alu, const struct tgsi_src_register *src) { static const char swiz_vals[] = { @@ -443,7 +444,7 @@ add_scalar_clamp(struct tgsi_full_instruction *inst, struct ir2_instruction *alu } static void -add_regs_vector_1(struct fd_compile_context *ctx, +add_regs_vector_1(struct fd2_compile_context *ctx, struct tgsi_full_instruction *inst, struct ir2_instruction *alu) { assert(inst->Instruction.NumSrcRegs == 1); @@ -456,7 +457,7 @@ add_regs_vector_1(struct fd_compile_context *ctx, } static void -add_regs_vector_2(struct fd_compile_context *ctx, +add_regs_vector_2(struct fd2_compile_context *ctx, struct tgsi_full_instruction *inst, struct ir2_instruction *alu) { assert(inst->Instruction.NumSrcRegs == 2); @@ -469,7 +470,7 @@ add_regs_vector_2(struct fd_compile_context *ctx, } static void -add_regs_vector_3(struct fd_compile_context *ctx, +add_regs_vector_3(struct fd2_compile_context *ctx, struct tgsi_full_instruction *inst, struct ir2_instruction *alu) { assert(inst->Instruction.NumSrcRegs == 3); @@ -498,7 +499,7 @@ add_regs_dummy_vector(struct ir2_instruction *alu) } static void -add_regs_scalar_1(struct fd_compile_context *ctx, +add_regs_scalar_1(struct fd2_compile_context *ctx, struct tgsi_full_instruction *inst, struct ir2_instruction *alu) { assert(inst->Instruction.NumSrcRegs == 1); @@ -531,15 +532,10 @@ src_from_dst(struct tgsi_src_register *src, struct tgsi_dst_register *dst) } /* 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. + * generated by a single TGSI op. */ static void -get_internal_temp(struct fd_compile_context *ctx, +get_internal_temp(struct fd2_compile_context *ctx, struct tgsi_dst_register *tmp_dst, struct tgsi_src_register *tmp_src) { @@ -561,7 +557,7 @@ get_internal_temp(struct fd_compile_context *ctx, } static void -get_predicate(struct fd_compile_context *ctx, struct tgsi_dst_register *dst, +get_predicate(struct fd2_compile_context *ctx, struct tgsi_dst_register *dst, struct tgsi_src_register *src) { assert(ctx->pred_reg != -1); @@ -582,7 +578,7 @@ get_predicate(struct fd_compile_context *ctx, struct tgsi_dst_register *dst, } static void -push_predicate(struct fd_compile_context *ctx, struct tgsi_src_register *src) +push_predicate(struct fd2_compile_context *ctx, struct tgsi_src_register *src) { struct ir2_instruction *alu; struct tgsi_dst_register pred_dst; @@ -625,7 +621,7 @@ push_predicate(struct fd_compile_context *ctx, struct tgsi_src_register *src) } static void -pop_predicate(struct fd_compile_context *ctx) +pop_predicate(struct fd2_compile_context *ctx) { /* NOTE blob compiler seems to always puts PRED_* instrs in a CF by * themselves: @@ -656,7 +652,7 @@ pop_predicate(struct fd_compile_context *ctx) } static void -get_immediate(struct fd_compile_context *ctx, +get_immediate(struct fd2_compile_context *ctx, struct tgsi_src_register *reg, uint32_t val) { unsigned neg, swiz, idx, i; @@ -704,7 +700,7 @@ get_immediate(struct fd_compile_context *ctx, /* POW(a,b) = EXP2(b * LOG2(a)) */ static void -translate_pow(struct fd_compile_context *ctx, +translate_pow(struct fd2_compile_context *ctx, struct tgsi_full_instruction *inst) { struct tgsi_dst_register tmp_dst; @@ -753,7 +749,7 @@ translate_pow(struct fd_compile_context *ctx, } static void -translate_tex(struct fd_compile_context *ctx, +translate_tex(struct fd2_compile_context *ctx, struct tgsi_full_instruction *inst, unsigned opc) { struct ir2_instruction *instr; @@ -849,7 +845,7 @@ translate_tex(struct fd_compile_context *ctx, /* 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, +translate_sge_slt(struct fd2_compile_context *ctx, struct tgsi_full_instruction *inst, unsigned opc) { struct ir2_instruction *instr; @@ -893,7 +889,7 @@ translate_sge_slt(struct fd_compile_context *ctx, /* LRP(a,b,c) = (a * b) + ((1 - a) * c) */ static void -translate_lrp(struct fd_compile_context *ctx, +translate_lrp(struct fd2_compile_context *ctx, struct tgsi_full_instruction *inst, unsigned opc) { @@ -933,7 +929,7 @@ translate_lrp(struct fd_compile_context *ctx, } static void -translate_trig(struct fd_compile_context *ctx, +translate_trig(struct fd2_compile_context *ctx, struct tgsi_full_instruction *inst, unsigned opc) { @@ -996,7 +992,7 @@ translate_trig(struct fd_compile_context *ctx, */ static void -translate_instruction(struct fd_compile_context *ctx, +translate_instruction(struct fd2_compile_context *ctx, struct tgsi_full_instruction *inst) { unsigned opc = inst->Instruction.Opcode; @@ -1147,7 +1143,7 @@ translate_instruction(struct fd_compile_context *ctx, } static void -compile_instructions(struct fd_compile_context *ctx) +compile_instructions(struct fd2_compile_context *ctx) { while (!tgsi_parse_end_of_tokens(&ctx->parser)) { tgsi_parse_token(&ctx->parser); @@ -1166,10 +1162,10 @@ compile_instructions(struct fd_compile_context *ctx) } int -fd_compile_shader(struct fd_program_stateobj *prog, - struct fd_shader_stateobj *so) +fd2_compile_shader(struct fd_program_stateobj *prog, + struct fd2_shader_stateobj *so) { - struct fd_compile_context ctx; + struct fd2_compile_context ctx; ir2_shader_destroy(so->ir); so->ir = ir2_shader_create(); diff --git a/src/gallium/drivers/freedreno/freedreno_compiler.h b/src/gallium/drivers/freedreno/a2xx/fd2_compiler.h index ce09788c10b..6b1e9f7e8a1 100644 --- a/src/gallium/drivers/freedreno/freedreno_compiler.h +++ b/src/gallium/drivers/freedreno/a2xx/fd2_compiler.h @@ -26,13 +26,13 @@ * Rob Clark <[email protected]> */ -#ifndef FREEDRENO_COMPILER_H_ -#define FREEDRENO_COMPILER_H_ +#ifndef FD2_COMPILER_H_ +#define FD2_COMPILER_H_ -#include "freedreno_program.h" -#include "freedreno_util.h" +#include "fd2_program.h" +#include "fd2_util.h" -int fd_compile_shader(struct fd_program_stateobj *prog, - struct fd_shader_stateobj *so); +int fd2_compile_shader(struct fd_program_stateobj *prog, + struct fd2_shader_stateobj *so); -#endif /* FREEDRENO_COMPILER_H_ */ +#endif /* FD2_COMPILER_H_ */ diff --git a/src/gallium/drivers/freedreno/a2xx/fd2_context.c b/src/gallium/drivers/freedreno/a2xx/fd2_context.c new file mode 100644 index 00000000000..a3192751164 --- /dev/null +++ b/src/gallium/drivers/freedreno/a2xx/fd2_context.c @@ -0,0 +1,101 @@ +/* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */ + +/* + * Copyright (C) 2013 Rob Clark <[email protected]> + * + * 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 <[email protected]> + */ + + +#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; +} diff --git a/src/gallium/drivers/freedreno/a2xx/fd2_context.h b/src/gallium/drivers/freedreno/a2xx/fd2_context.h new file mode 100644 index 00000000000..de845f07a85 --- /dev/null +++ b/src/gallium/drivers/freedreno/a2xx/fd2_context.h @@ -0,0 +1,52 @@ +/* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */ + +/* + * Copyright (C) 2013 Rob Clark <[email protected]> + * + * 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 <[email protected]> + */ + +#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_ */ diff --git a/src/gallium/drivers/freedreno/freedreno_clear.c b/src/gallium/drivers/freedreno/a2xx/fd2_draw.c index 2cdb7bf1120..8e1ca0fec41 100644 --- a/src/gallium/drivers/freedreno/freedreno_clear.c +++ b/src/gallium/drivers/freedreno/a2xx/fd2_draw.c @@ -1,7 +1,7 @@ /* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */ /* - * Copyright (C) 2012 Rob Clark <[email protected]> + * Copyright (C) 2012-2013 Rob Clark <[email protected]> * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -29,16 +29,95 @@ #include "pipe/p_state.h" #include "util/u_string.h" #include "util/u_memory.h" -#include "util/u_inlines.h" +#include "util/u_prim.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" +#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) @@ -49,38 +128,24 @@ pack_rgba(enum pipe_format format, const float *rgba) } static void -fd_clear(struct pipe_context *pctx, unsigned buffers, +fd2_clear(struct fd_context *ctx, unsigned buffers, const union pipe_color_union *color, double depth, unsigned stencil) { - struct fd_context *ctx = fd_context(pctx); + 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; - 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 & + fd2_emit_state(ctx, 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 }, + 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); @@ -91,7 +156,7 @@ fd_clear(struct pipe_context *pctx, unsigned buffers, OUT_RING(ring, CP_REG(REG_A2XX_VGT_VERTEX_REUSE_BLOCK_CNTL)); OUT_RING(ring, 0x0000028f); - fd_program_emit(ring, &ctx->solid_prog); + 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); @@ -200,6 +265,11 @@ fd_clear(struct pipe_context *pctx, unsigned buffers, 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, @@ -213,39 +283,12 @@ fd_clear(struct pipe_context *pctx, unsigned buffers, 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) +fd2_draw_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; + struct fd_context *ctx = fd_context(pctx); + ctx->draw = fd2_draw; + ctx->clear = fd2_clear; } diff --git a/src/gallium/drivers/freedreno/a2xx/fd2_draw.h b/src/gallium/drivers/freedreno/a2xx/fd2_draw.h new file mode 100644 index 00000000000..8a86d2b568e --- /dev/null +++ b/src/gallium/drivers/freedreno/a2xx/fd2_draw.h @@ -0,0 +1,38 @@ +/* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */ + +/* + * Copyright (C) 2012-2013 Rob Clark <[email protected]> + * + * 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 <[email protected]> + */ + +#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_ */ diff --git a/src/gallium/drivers/freedreno/a2xx/fd2_emit.c b/src/gallium/drivers/freedreno/a2xx/fd2_emit.c new file mode 100644 index 00000000000..8a40f9ab7ab --- /dev/null +++ b/src/gallium/drivers/freedreno/a2xx/fd2_emit.c @@ -0,0 +1,443 @@ +/* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */ + +/* + * Copyright (C) 2012-2013 Rob Clark <[email protected]> + * + * 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 <[email protected]> + */ + +#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); +} diff --git a/src/gallium/drivers/freedreno/a2xx/fd2_emit.h b/src/gallium/drivers/freedreno/a2xx/fd2_emit.h new file mode 100644 index 00000000000..8ee04632091 --- /dev/null +++ b/src/gallium/drivers/freedreno/a2xx/fd2_emit.h @@ -0,0 +1,48 @@ +/* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */ + +/* + * Copyright (C) 2012-2013 Rob Clark <[email protected]> + * + * 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 <[email protected]> + */ + +#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 */ diff --git a/src/gallium/drivers/freedreno/a2xx/fd2_gmem.c b/src/gallium/drivers/freedreno/a2xx/fd2_gmem.c new file mode 100644 index 00000000000..e239eedb2e0 --- /dev/null +++ b/src/gallium/drivers/freedreno/a2xx/fd2_gmem.c @@ -0,0 +1,408 @@ +/* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */ + +/* + * Copyright (C) 2012 Rob Clark <[email protected]> + * + * 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 <[email protected]> + */ + +#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; +} diff --git a/src/gallium/drivers/freedreno/freedreno_clear.h b/src/gallium/drivers/freedreno/a2xx/fd2_gmem.h index 31bb0377d0c..bda46e67f2e 100644 --- a/src/gallium/drivers/freedreno/freedreno_clear.h +++ b/src/gallium/drivers/freedreno/a2xx/fd2_gmem.h @@ -1,7 +1,7 @@ /* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */ /* - * Copyright (C) 2012 Rob Clark <[email protected]> + * Copyright (C) 2013 Rob Clark <[email protected]> * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -26,12 +26,11 @@ * Rob Clark <[email protected]> */ -#ifndef FREEDRENO_CLEAR_H_ -#define FREEDRENO_CLEAR_H_ +#ifndef FD2_GMEM_H_ +#define FD2_GMEM_H_ #include "pipe/p_context.h" -void fd_clear_init(struct pipe_context *pctx); +void fd2_gmem_init(struct pipe_context *pctx); - -#endif /* FREEDRENO_CLEAR_H_ */ +#endif /* FD2_GMEM_H_ */ diff --git a/src/gallium/drivers/freedreno/freedreno_program.c b/src/gallium/drivers/freedreno/a2xx/fd2_program.c index 7605e82d877..c62a7f90b98 100644 --- a/src/gallium/drivers/freedreno/freedreno_program.c +++ b/src/gallium/drivers/freedreno/a2xx/fd2_program.c @@ -34,16 +34,15 @@ #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" +#include "fd2_program.h" +#include "fd2_compiler.h" +#include "fd2_texture.h" +#include "fd2_util.h" -static struct fd_shader_stateobj * +static struct fd2_shader_stateobj * create_shader(enum shader_t type) { - struct fd_shader_stateobj *so = CALLOC_STRUCT(fd_shader_stateobj); + struct fd2_shader_stateobj *so = CALLOC_STRUCT(fd2_shader_stateobj); if (!so) return NULL; so->type = type; @@ -51,15 +50,16 @@ create_shader(enum shader_t type) } static void -delete_shader(struct fd_shader_stateobj *so) +delete_shader(struct fd2_shader_stateobj *so) { ir2_shader_destroy(so->ir); - FREE(so->tokens); - FREE(so); + free(so->tokens); + free(so->bin); + free(so); } -static struct fd_shader_stateobj * -assemble(struct fd_shader_stateobj *so) +static struct fd2_shader_stateobj * +assemble(struct fd2_shader_stateobj *so) { free(so->bin); so->bin = ir2_shader_assemble(so->ir, &so->info); @@ -68,7 +68,7 @@ assemble(struct fd_shader_stateobj *so) if (fd_mesa_debug & FD_DBG_DISASM) { DBG("disassemble: type=%d", so->type); - disasm(so->bin, so->info.sizedwords, 0, so->type); + disasm_a2xx(so->bin, so->info.sizedwords, 0, so->type); } return so; @@ -79,8 +79,8 @@ fail: return NULL; } -static struct fd_shader_stateobj * -compile(struct fd_program_stateobj *prog, struct fd_shader_stateobj *so) +static struct fd2_shader_stateobj * +compile(struct fd_program_stateobj *prog, struct fd2_shader_stateobj *so) { int ret; @@ -89,7 +89,7 @@ compile(struct fd_program_stateobj *prog, struct fd_shader_stateobj *so) tgsi_dump(so->tokens, 0); } - ret = fd_compile_shader(prog, so); + ret = fd2_compile_shader(prog, so); if (ret) goto fail; @@ -109,7 +109,7 @@ fail: } static void -emit(struct fd_ringbuffer *ring, struct fd_shader_stateobj *so) +emit(struct fd_ringbuffer *ring, struct fd2_shader_stateobj *so) { unsigned i; @@ -124,10 +124,10 @@ emit(struct fd_ringbuffer *ring, struct fd_shader_stateobj *so) } static void * -fd_fp_state_create(struct pipe_context *pctx, +fd2_fp_state_create(struct pipe_context *pctx, const struct pipe_shader_state *cso) { - struct fd_shader_stateobj *so = create_shader(SHADER_FRAGMENT); + struct fd2_shader_stateobj *so = create_shader(SHADER_FRAGMENT); if (!so) return NULL; so->tokens = tgsi_dup_tokens(cso->tokens); @@ -135,14 +135,14 @@ fd_fp_state_create(struct pipe_context *pctx, } static void -fd_fp_state_delete(struct pipe_context *pctx, void *hwcso) +fd2_fp_state_delete(struct pipe_context *pctx, void *hwcso) { - struct fd_shader_stateobj *so = hwcso; + struct fd2_shader_stateobj *so = hwcso; delete_shader(so); } static void -fd_fp_state_bind(struct pipe_context *pctx, void *hwcso) +fd2_fp_state_bind(struct pipe_context *pctx, void *hwcso) { struct fd_context *ctx = fd_context(pctx); ctx->prog.fp = hwcso; @@ -151,10 +151,10 @@ fd_fp_state_bind(struct pipe_context *pctx, void *hwcso) } static void * -fd_vp_state_create(struct pipe_context *pctx, +fd2_vp_state_create(struct pipe_context *pctx, const struct pipe_shader_state *cso) { - struct fd_shader_stateobj *so = create_shader(SHADER_VERTEX); + struct fd2_shader_stateobj *so = create_shader(SHADER_VERTEX); if (!so) return NULL; so->tokens = tgsi_dup_tokens(cso->tokens); @@ -162,14 +162,14 @@ fd_vp_state_create(struct pipe_context *pctx, } static void -fd_vp_state_delete(struct pipe_context *pctx, void *hwcso) +fd2_vp_state_delete(struct pipe_context *pctx, void *hwcso) { - struct fd_shader_stateobj *so = hwcso; + struct fd2_shader_stateobj *so = hwcso; delete_shader(so); } static void -fd_vp_state_bind(struct pipe_context *pctx, void *hwcso) +fd2_vp_state_bind(struct pipe_context *pctx, void *hwcso) { struct fd_context *ctx = fd_context(pctx); ctx->prog.vp = hwcso; @@ -178,7 +178,7 @@ fd_vp_state_bind(struct pipe_context *pctx, void *hwcso) } static void -patch_vtx_fetches(struct fd_context *ctx, struct fd_shader_stateobj *so, +patch_vtx_fetches(struct fd_context *ctx, struct fd2_shader_stateobj *so, struct fd_vertex_stateobj *vtx) { unsigned i; @@ -205,7 +205,7 @@ patch_vtx_fetches(struct fd_context *ctx, struct fd_shader_stateobj *so, instr->fetch.const_idx = 20 + (i / 3); instr->fetch.const_idx_sel = i % 3; - instr->fetch.fmt = fd_pipe2surface(format); + 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; @@ -215,7 +215,7 @@ patch_vtx_fetches(struct fd_context *ctx, struct fd_shader_stateobj *so, for (j = 0; j < 4; j++) instr->regs[0]->swizzle[j] = "xyzw01__"[desc->swizzle[j]]; - assert(instr->fetch.fmt != FMT_INVALID); + assert(instr->fetch.fmt != ~0); DBG("vtx[%d]: %s (%d), ci=%d, cis=%d, id=%d, swizzle=%s, " "stride=%d, offset=%d", @@ -234,7 +234,7 @@ patch_vtx_fetches(struct fd_context *ctx, struct fd_shader_stateobj *so, } static void -patch_tex_fetches(struct fd_context *ctx, struct fd_shader_stateobj *so, +patch_tex_fetches(struct fd_context *ctx, struct fd2_shader_stateobj *so, struct fd_texture_stateobj *tex) { unsigned i; @@ -243,7 +243,7 @@ patch_tex_fetches(struct fd_context *ctx, struct fd_shader_stateobj *so, 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); + unsigned const_idx = fd2_get_const_idx(ctx, tex, samp_id); if (const_idx != instr->fetch.const_idx) { instr->fetch.const_idx = const_idx; @@ -254,7 +254,7 @@ patch_tex_fetches(struct fd_context *ctx, struct fd_shader_stateobj *so, } void -fd_program_validate(struct fd_context *ctx) +fd2_program_validate(struct fd_context *ctx) { struct fd_program_stateobj *prog = &ctx->prog; @@ -272,8 +272,6 @@ fd_program_validate(struct fd_context *ctx) 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); @@ -286,11 +284,13 @@ fd_program_validate(struct fd_context *ctx) } void -fd_program_emit(struct fd_ringbuffer *ring, +fd2_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; + 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); @@ -308,6 +308,8 @@ fd_program_emit(struct fd_ringbuffer *ring, 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: @@ -318,10 +320,10 @@ fd_program_emit(struct fd_ringbuffer *ring, * ALU: MAXv export0 = R0, R0 ; gl_FragColor * NOP */ -static struct fd_shader_stateobj * +static struct fd2_shader_stateobj * create_blit_fp(void) { - struct fd_shader_stateobj *so = create_shader(SHADER_FRAGMENT); + struct fd2_shader_stateobj *so = create_shader(SHADER_FRAGMENT); struct ir2_cf *cf; struct ir2_instruction *instr; @@ -360,10 +362,10 @@ create_blit_fp(void) * ALU: MAXv export0 = R1, R1 * NOP */ -static struct fd_shader_stateobj * +static struct fd2_shader_stateobj * create_blit_vp(void) { - struct fd_shader_stateobj *so = create_shader(SHADER_VERTEX); + struct fd2_shader_stateobj *so = create_shader(SHADER_VERTEX); struct ir2_cf *cf; struct ir2_instruction *instr; @@ -408,10 +410,10 @@ create_blit_vp(void) * EXEC_END ADDR(0x1) CNT(0x1) * ALU: MAXv export0 = C0, C0 ; gl_FragColor */ -static struct fd_shader_stateobj * +static struct fd2_shader_stateobj * create_solid_fp(void) { - struct fd_shader_stateobj *so = create_shader(SHADER_FRAGMENT); + struct fd2_shader_stateobj *so = create_shader(SHADER_FRAGMENT); struct ir2_cf *cf; struct ir2_instruction *instr; @@ -441,10 +443,10 @@ create_solid_fp(void) * ALLOC PARAM/PIXEL SIZE(0x0) * EXEC_END ADDR(0x5) CNT(0x0) */ -static struct fd_shader_stateobj * +static struct fd2_shader_stateobj * create_solid_vp(void) { - struct fd_shader_stateobj *so = create_shader(SHADER_VERTEX); + struct fd2_shader_stateobj *so = create_shader(SHADER_VERTEX); struct ir2_cf *cf; struct ir2_instruction *instr; @@ -474,17 +476,17 @@ create_solid_vp(void) } void -fd_prog_init(struct pipe_context *pctx) +fd2_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_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 = fd_vp_state_create; - pctx->bind_vs_state = fd_vp_state_bind; - pctx->delete_vs_state = fd_vp_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(); @@ -493,7 +495,7 @@ fd_prog_init(struct pipe_context *pctx) } void -fd_prog_fini(struct pipe_context *pctx) +fd2_prog_fini(struct pipe_context *pctx) { struct fd_context *ctx = fd_context(pctx); diff --git a/src/gallium/drivers/freedreno/freedreno_program.h b/src/gallium/drivers/freedreno/a2xx/fd2_program.h index 9871b0c3b1d..393cb616f63 100644 --- a/src/gallium/drivers/freedreno/freedreno_program.h +++ b/src/gallium/drivers/freedreno/a2xx/fd2_program.h @@ -1,7 +1,7 @@ /* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */ /* - * Copyright (C) 2012 Rob Clark <[email protected]> + * Copyright (C) 2012-2013 Rob Clark <[email protected]> * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -26,8 +26,8 @@ * Rob Clark <[email protected]> */ -#ifndef FREEDRENO_PROGRAM_H_ -#define FREEDRENO_PROGRAM_H_ +#ifndef FD2_PROGRAM_H_ +#define FD2_PROGRAM_H_ #include "pipe/p_context.h" @@ -36,7 +36,7 @@ #include "ir-a2xx.h" #include "disasm.h" -struct fd_shader_stateobj { +struct fd2_shader_stateobj { enum shader_t type; uint32_t *bin; @@ -72,11 +72,11 @@ struct fd_shader_stateobj { } immediates[64]; }; -void fd_program_emit(struct fd_ringbuffer *ring, +void fd2_program_emit(struct fd_ringbuffer *ring, struct fd_program_stateobj *prog); -void fd_program_validate(struct fd_context *ctx); +void fd2_program_validate(struct fd_context *ctx); -void fd_prog_init(struct pipe_context *pctx); -void fd_prog_fini(struct pipe_context *pctx); +void fd2_prog_init(struct pipe_context *pctx); +void fd2_prog_fini(struct pipe_context *pctx); -#endif /* FREEDRENO_PROGRAM_H_ */ +#endif /* FD2_PROGRAM_H_ */ diff --git a/src/gallium/drivers/freedreno/freedreno_rasterizer.c b/src/gallium/drivers/freedreno/a2xx/fd2_rasterizer.c index aa6c64a901f..bf43531c5f1 100644 --- a/src/gallium/drivers/freedreno/freedreno_rasterizer.c +++ b/src/gallium/drivers/freedreno/a2xx/fd2_rasterizer.c @@ -1,7 +1,7 @@ /* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */ /* - * Copyright (C) 2012 Rob Clark <[email protected]> + * Copyright (C) 2012-2013 Rob Clark <[email protected]> * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -31,35 +31,19 @@ #include "util/u_string.h" #include "util/u_memory.h" -#include "freedreno_rasterizer.h" -#include "freedreno_context.h" -#include "freedreno_util.h" +#include "fd2_rasterizer.h" +#include "fd2_context.h" +#include "fd2_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, +void * +fd2_rasterizer_state_create(struct pipe_context *pctx, const struct pipe_rasterizer_state *cso) { - struct fd_rasterizer_stateobj *so; + struct fd2_rasterizer_stateobj *so; float psize_min, psize_max; - so = CALLOC_STRUCT(fd_rasterizer_stateobj); + so = CALLOC_STRUCT(fd2_rasterizer_stateobj); if (!so) return NULL; @@ -97,8 +81,8 @@ fd_rasterizer_state_create(struct pipe_context *pctx, 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)); + 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; @@ -127,25 +111,3 @@ fd_rasterizer_state_create(struct pipe_context *pctx, 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; -} diff --git a/src/gallium/drivers/freedreno/freedreno_rasterizer.h b/src/gallium/drivers/freedreno/a2xx/fd2_rasterizer.h index 519a05edfea..adc0653132b 100644 --- a/src/gallium/drivers/freedreno/freedreno_rasterizer.h +++ b/src/gallium/drivers/freedreno/a2xx/fd2_rasterizer.h @@ -1,7 +1,7 @@ /* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */ /* - * Copyright (C) 2012 Rob Clark <[email protected]> + * Copyright (C) 2012-2013 Rob Clark <[email protected]> * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -26,13 +26,13 @@ * Rob Clark <[email protected]> */ -#ifndef FREEDRENO_RASTERIZER_H_ -#define FREEDRENO_RASTERIZER_H_ +#ifndef FD2_RASTERIZER_H_ +#define FD2_RASTERIZER_H_ #include "pipe/p_state.h" #include "pipe/p_context.h" -struct fd_rasterizer_stateobj { +struct fd2_rasterizer_stateobj { struct pipe_rasterizer_state base; uint32_t pa_sc_line_stipple; uint32_t pa_cl_clip_cntl; @@ -43,6 +43,13 @@ struct fd_rasterizer_stateobj { uint32_t pa_su_sc_mode_cntl; }; -void fd_rasterizer_init(struct pipe_context *pctx); +static INLINE struct fd2_rasterizer_stateobj * +fd2_rasterizer_stateobj(struct pipe_rasterizer_state *rast) +{ + return (struct fd2_rasterizer_stateobj *)rast; +} -#endif /* FREEDRENO_RASTERIZER_H_ */ +void * fd2_rasterizer_state_create(struct pipe_context *pctx, + const struct pipe_rasterizer_state *cso); + +#endif /* FD2_RASTERIZER_H_ */ diff --git a/src/gallium/drivers/freedreno/a2xx/fd2_screen.c b/src/gallium/drivers/freedreno/a2xx/fd2_screen.c new file mode 100644 index 00000000000..1801d957b15 --- /dev/null +++ b/src/gallium/drivers/freedreno/a2xx/fd2_screen.c @@ -0,0 +1,109 @@ +/* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */ + +/* + * Copyright (C) 2013 Rob Clark <[email protected]> + * + * 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 <[email protected]> + */ + +#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; +} diff --git a/src/gallium/drivers/freedreno/a2xx/fd2_screen.h b/src/gallium/drivers/freedreno/a2xx/fd2_screen.h new file mode 100644 index 00000000000..8784598a0bf --- /dev/null +++ b/src/gallium/drivers/freedreno/a2xx/fd2_screen.h @@ -0,0 +1,36 @@ +/* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */ + +/* + * Copyright (C) 2013 Rob Clark <[email protected]> + * + * 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 <[email protected]> + */ + +#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_ */ diff --git a/src/gallium/drivers/freedreno/a2xx/fd2_texture.c b/src/gallium/drivers/freedreno/a2xx/fd2_texture.c new file mode 100644 index 00000000000..c800a869868 --- /dev/null +++ b/src/gallium/drivers/freedreno/a2xx/fd2_texture.c @@ -0,0 +1,158 @@ +/* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */ + +/* + * Copyright (C) 2012-2013 Rob Clark <[email protected]> + * + * 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 <[email protected]> + */ + +#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; +} diff --git a/src/gallium/drivers/freedreno/a2xx/fd2_texture.h b/src/gallium/drivers/freedreno/a2xx/fd2_texture.h new file mode 100644 index 00000000000..b337acd40ae --- /dev/null +++ b/src/gallium/drivers/freedreno/a2xx/fd2_texture.h @@ -0,0 +1,69 @@ +/* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */ + +/* + * Copyright (C) 2012-2013 Rob Clark <[email protected]> + * + * 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 <[email protected]> + */ + +#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_ */ diff --git a/src/gallium/drivers/freedreno/a2xx/fd2_util.c b/src/gallium/drivers/freedreno/a2xx/fd2_util.c new file mode 100644 index 00000000000..9781326a5af --- /dev/null +++ b/src/gallium/drivers/freedreno/a2xx/fd2_util.c @@ -0,0 +1,322 @@ +/* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */ + +/* + * Copyright (C) 2012 Rob Clark <[email protected]> + * + * 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 <[email protected]> + */ + +#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]])); +} diff --git a/src/gallium/drivers/freedreno/a2xx/fd2_util.h b/src/gallium/drivers/freedreno/a2xx/fd2_util.h new file mode 100644 index 00000000000..c2167c725c4 --- /dev/null +++ b/src/gallium/drivers/freedreno/a2xx/fd2_util.h @@ -0,0 +1,47 @@ +/* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */ + +/* + * Copyright (C) 2012-2013 Rob Clark <[email protected]> + * + * 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 <[email protected]> + */ + +#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_ */ diff --git a/src/gallium/drivers/freedreno/freedreno_zsa.c b/src/gallium/drivers/freedreno/a2xx/fd2_zsa.c index 2ca99770271..b3707f3051e 100644 --- a/src/gallium/drivers/freedreno/freedreno_zsa.c +++ b/src/gallium/drivers/freedreno/a2xx/fd2_zsa.c @@ -31,43 +31,17 @@ #include "util/u_string.h" #include "util/u_memory.h" -#include "freedreno_zsa.h" -#include "freedreno_context.h" -#include "freedreno_util.h" +#include "fd2_zsa.h" +#include "fd2_context.h" +#include "fd2_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, +void * +fd2_zsa_state_create(struct pipe_context *pctx, const struct pipe_depth_stencil_alpha_state *cso) { - struct fd_zsa_stateobj *so; + struct fd2_zsa_stateobj *so; - so = CALLOC_STRUCT(fd_zsa_stateobj); + so = CALLOC_STRUCT(fd2_zsa_stateobj); if (!so) return NULL; @@ -87,9 +61,9 @@ fd_zsa_state_create(struct pipe_context *pctx, 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)); + 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) | @@ -101,9 +75,9 @@ fd_zsa_state_create(struct pipe_context *pctx, 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)); + 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) | @@ -120,25 +94,3 @@ fd_zsa_state_create(struct pipe_context *pctx, 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; -} diff --git a/src/gallium/drivers/freedreno/freedreno_zsa.h b/src/gallium/drivers/freedreno/a2xx/fd2_zsa.h index 6f5c5f07e98..dda1e552174 100644 --- a/src/gallium/drivers/freedreno/freedreno_zsa.h +++ b/src/gallium/drivers/freedreno/a2xx/fd2_zsa.h @@ -1,7 +1,7 @@ /* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */ /* - * Copyright (C) 2012 Rob Clark <[email protected]> + * Copyright (C) 2012-2013 Rob Clark <[email protected]> * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -26,8 +26,8 @@ * Rob Clark <[email protected]> */ -#ifndef FREEDRENO_ZSA_H_ -#define FREEDRENO_ZSA_H_ +#ifndef FD2_ZSA_H_ +#define FD2_ZSA_H_ #include "pipe/p_state.h" @@ -35,7 +35,7 @@ #include "freedreno_util.h" -struct fd_zsa_stateobj { +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 */ @@ -44,16 +44,13 @@ struct fd_zsa_stateobj { uint32_t rb_stencilrefmask_bf; }; -void fd_zsa_init(struct pipe_context *pctx); - -static inline bool fd_depth_enabled(struct fd_zsa_stateobj *zsa) +static INLINE struct fd2_zsa_stateobj * +fd2_zsa_stateobj(struct pipe_depth_stencil_alpha_state *zsa) { - return zsa->base.depth.enabled; + return (struct fd2_zsa_stateobj *)zsa; } -static inline bool fd_stencil_enabled(struct fd_zsa_stateobj *zsa) -{ - return zsa->base.stencil[0].enabled; -} +void * fd2_zsa_state_create(struct pipe_context *pctx, + const struct pipe_depth_stencil_alpha_state *cso); -#endif /* FREEDRENO_ZSA_H_ */ +#endif /* FD2_ZSA_H_ */ diff --git a/src/gallium/drivers/freedreno/instr-a2xx.h b/src/gallium/drivers/freedreno/a2xx/instr-a2xx.h index e1e897ee561..e1e897ee561 100644 --- a/src/gallium/drivers/freedreno/instr-a2xx.h +++ b/src/gallium/drivers/freedreno/a2xx/instr-a2xx.h diff --git a/src/gallium/drivers/freedreno/ir-a2xx.c b/src/gallium/drivers/freedreno/a2xx/ir-a2xx.c index 18afba8a5a3..18afba8a5a3 100644 --- a/src/gallium/drivers/freedreno/ir-a2xx.c +++ b/src/gallium/drivers/freedreno/a2xx/ir-a2xx.c diff --git a/src/gallium/drivers/freedreno/ir-a2xx.h b/src/gallium/drivers/freedreno/a2xx/ir-a2xx.h index 822e5ec4c23..822e5ec4c23 100644 --- a/src/gallium/drivers/freedreno/ir-a2xx.h +++ b/src/gallium/drivers/freedreno/a2xx/ir-a2xx.h diff --git a/src/gallium/drivers/freedreno/adreno_common.xml.h b/src/gallium/drivers/freedreno/adreno_common.xml.h index 9dd0946f778..42057da0737 100644 --- a/src/gallium/drivers/freedreno/adreno_common.xml.h +++ b/src/gallium/drivers/freedreno/adreno_common.xml.h @@ -8,10 +8,10 @@ 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/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 <[email protected]> (robclark) @@ -108,5 +108,10 @@ enum adreno_rb_dither_mode { DITHER_IF_ALPHA_OFF = 2, }; +enum adreno_rb_depth_format { + DEPTHX_16 = 0, + DEPTHX_24_8 = 1, +}; + #endif /* ADRENO_COMMON_XML */ diff --git a/src/gallium/drivers/freedreno/adreno_pm4.xml.h b/src/gallium/drivers/freedreno/adreno_pm4.xml.h index 14bd343b094..853206d3757 100644 --- a/src/gallium/drivers/freedreno/adreno_pm4.xml.h +++ b/src/gallium/drivers/freedreno/adreno_pm4.xml.h @@ -8,10 +8,10 @@ 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/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 <[email protected]> (robclark) @@ -46,6 +46,7 @@ enum vgt_event_type { CACHE_FLUSH_TS = 4, CONTEXT_DONE = 5, CACHE_FLUSH = 6, + HLSQ_FLUSH = 7, VIZQUERY_START = 7, VIZQUERY_END = 8, SC_WAIT_WC = 9, @@ -130,6 +131,7 @@ enum adreno_pm4_type3_packets { 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, @@ -154,7 +156,97 @@ enum adreno_pm4_type3_packets { 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 */ diff --git a/src/gallium/drivers/freedreno/disasm.h b/src/gallium/drivers/freedreno/disasm.h index 92efd5ae53c..e81dd1c8ef4 100644 --- a/src/gallium/drivers/freedreno/disasm.h +++ b/src/gallium/drivers/freedreno/disasm.h @@ -27,14 +27,17 @@ 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_ */ diff --git a/src/gallium/drivers/freedreno/freedreno_blend.c b/src/gallium/drivers/freedreno/freedreno_blend.c deleted file mode 100644 index cd6e94503e6..00000000000 --- a/src/gallium/drivers/freedreno/freedreno_blend.c +++ /dev/null @@ -1,175 +0,0 @@ -/* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */ - -/* - * Copyright (C) 2012 Rob Clark <[email protected]> - * - * 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 <[email protected]> - */ - -#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; -} - diff --git a/src/gallium/drivers/freedreno/freedreno_context.c b/src/gallium/drivers/freedreno/freedreno_context.c index 64c21fedaa9..0f16568ffdd 100644 --- a/src/gallium/drivers/freedreno/freedreno_context.c +++ b/src/gallium/drivers/freedreno/freedreno_context.c @@ -27,15 +27,10 @@ */ #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" @@ -108,10 +103,9 @@ fd_context_flush(struct pipe_context *pctx, struct pipe_fence_handle **fence, #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); @@ -125,81 +119,51 @@ fd_context_destroy(struct pipe_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; } diff --git a/src/gallium/drivers/freedreno/freedreno_context.h b/src/gallium/drivers/freedreno/freedreno_context.h index c3a85b5c7ab..a6133c0d8c3 100644 --- a/src/gallium/drivers/freedreno/freedreno_context.h +++ b/src/gallium/drivers/freedreno/freedreno_context.h @@ -37,23 +37,18 @@ #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), @@ -79,6 +74,11 @@ struct fd_vertexbuf_stateobj { 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; @@ -102,11 +102,6 @@ struct fd_context { /* 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 @@ -125,10 +120,6 @@ struct fd_context { 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 @@ -164,9 +155,9 @@ struct fd_context { 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; @@ -183,6 +174,22 @@ struct fd_context { 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 * @@ -191,8 +198,11 @@ fd_context(struct pipe_context *pctx) 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_ */ diff --git a/src/gallium/drivers/freedreno/freedreno_vbo.c b/src/gallium/drivers/freedreno/freedreno_draw.c index fe32d56f222..2b7c16847dc 100644 --- a/src/gallium/drivers/freedreno/freedreno_vbo.c +++ b/src/gallium/drivers/freedreno/freedreno_draw.c @@ -30,55 +30,15 @@ #include "util/u_string.h" #include "util/u_memory.h" #include "util/u_prim.h" +#include "util/u_format.h" -#include "freedreno_vbo.h" +#include "freedreno_draw.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) { @@ -111,55 +71,18 @@ size2indextype(unsigned index_size) 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) +/* 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_context *ctx = fd_context(pctx); - struct pipe_framebuffer_state *fb = &ctx->framebuffer; 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; - 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; @@ -175,17 +98,43 @@ fd_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info) src_sel = DI_SRC_SEL_AUTO_INDEX; } - fd_resource(fb->cbufs[0]->texture)->dirty = true; + 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->zsa)) { + if (fd_depth_enabled(ctx)) { buffers |= FD_BUFFER_DEPTH; - fd_resource(fb->zsbuf->texture)->dirty = true; + fd_resource(pfb->zsbuf->texture)->dirty = true; } - if (fd_stencil_enabled(ctx->zsa)) { + if (fd_stencil_enabled(ctx)) { buffers |= FD_BUFFER_STENCIL; - fd_resource(fb->zsbuf->texture)->dirty = true; + fd_resource(pfb->zsbuf->texture)->dirty = true; } /* any buffers that haven't been cleared, we need to restore: */ @@ -193,47 +142,71 @@ fd_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info) /* and any buffers used, need to be resolved: */ ctx->resolve |= buffers; - if (ctx->dirty & FD_DIRTY_VTXBUF) - emit_vertexbufs(ctx, info->count); + ctx->draw(ctx, info); +} - fd_state_emit(pctx, ctx->dirty); +/* 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. + */ - OUT_PKT3(ring, CP_SET_CONSTANT, 2); - OUT_RING(ring, CP_REG(REG_A2XX_VGT_INDX_OFFSET)); - OUT_RING(ring, info->start); +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; - OUT_PKT3(ring, CP_SET_CONSTANT, 2); - OUT_RING(ring, CP_REG(REG_A2XX_VGT_VERTEX_REUSE_BLOCK_CNTL)); - OUT_RING(ring, 0x0000003b); + ctx->cleared |= buffers; + ctx->resolve |= buffers; + ctx->needs_flush = true; - OUT_PKT0(ring, REG_A2XX_TC_CNTL_STATUS, 1); - OUT_RING(ring, A2XX_TC_CNTL_STATUS_L2_INVALIDATE); + if (buffers & PIPE_CLEAR_COLOR) + fd_resource(pfb->cbufs[0]->texture)->dirty = true; - OUT_PKT3(ring, CP_WAIT_FOR_IDLE, 1); - OUT_RING(ring, 0x0000000); + if (buffers & (PIPE_CLEAR_DEPTH | PIPE_CLEAR_STENCIL)) + fd_resource(pfb->zsbuf->texture)->dirty = true; - 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); - } + 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); - OUT_PKT3(ring, CP_SET_CONSTANT, 2); - OUT_RING(ring, CP_REG(REG_A2XX_UNKNOWN_2010)); - 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; - emit_cacheflush(ring); + 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_vbo_init(struct pipe_context *pctx) +fd_draw_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; + pctx->clear = fd_clear; + pctx->clear_render_target = fd_clear_render_target; + pctx->clear_depth_stencil = fd_clear_depth_stencil; } diff --git a/src/gallium/drivers/freedreno/freedreno_vbo.h b/src/gallium/drivers/freedreno/freedreno_draw.h index 081edf5b8b5..26a1dbbcaf1 100644 --- a/src/gallium/drivers/freedreno/freedreno_vbo.h +++ b/src/gallium/drivers/freedreno/freedreno_draw.h @@ -26,17 +26,18 @@ * Rob Clark <[email protected]> */ -#ifndef FREEDRENO_VBO_H_ -#define FREEDRENO_VBO_H_ +#ifndef FREEDRENO_DRAW_H_ +#define FREEDRENO_DRAW_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; -}; +#include "freedreno_context.h" -void fd_vbo_init(struct pipe_context *pctx); +struct fd_ringbuffer; -#endif /* FREEDRENO_VBO_H_ */ +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_ */ diff --git a/src/gallium/drivers/freedreno/freedreno_gmem.c b/src/gallium/drivers/freedreno/freedreno_gmem.c index 83e5ea664b7..856e441337c 100644 --- a/src/gallium/drivers/freedreno/freedreno_gmem.c +++ b/src/gallium/drivers/freedreno/freedreno_gmem.c @@ -30,14 +30,11 @@ #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" /* @@ -69,277 +66,6 @@ * 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) { @@ -402,16 +128,14 @@ 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); @@ -422,21 +146,10 @@ fd_gmem_render_tiles(struct pipe_context *pctx) /* 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; @@ -453,37 +166,18 @@ fd_gmem_render_tiles(struct pipe_context *pctx) 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; } @@ -498,7 +192,7 @@ fd_gmem_render_tiles(struct pipe_context *pctx) 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; diff --git a/src/gallium/drivers/freedreno/freedreno_resource.c b/src/gallium/drivers/freedreno/freedreno_resource.c index ba814534238..1b1eaa52512 100644 --- a/src/gallium/drivers/freedreno/freedreno_resource.c +++ b/src/gallium/drivers/freedreno/freedreno_resource.c @@ -38,6 +38,31 @@ #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, @@ -54,14 +79,24 @@ fd_resource_transfer_map(struct pipe_context *pctx, 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; @@ -70,30 +105,6 @@ fd_resource_transfer_map(struct pipe_context *pctx, 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) @@ -110,11 +121,12 @@ fd_resource_get_handle(struct pipe_screen *pscreen, { 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, @@ -154,6 +166,8 @@ fd_resource_create(struct pipe_screen *pscreen, 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 */ @@ -194,7 +208,10 @@ fd_resource_from_handle(struct pipe_screen *pscreen, 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; } diff --git a/src/gallium/drivers/freedreno/freedreno_screen.c b/src/gallium/drivers/freedreno/freedreno_screen.c index b4fc20e5c59..9c47a58a81f 100644 --- a/src/gallium/drivers/freedreno/freedreno_screen.c +++ b/src/gallium/drivers/freedreno/freedreno_screen.c @@ -44,12 +44,13 @@ #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" @@ -125,27 +126,8 @@ fd_screen_destroy(struct pipe_screen *pscreen) } /* -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) @@ -337,74 +319,6 @@ fd_screen_get_shader_param(struct pipe_screen *pscreen, unsigned shader, 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, @@ -477,13 +391,36 @@ fd_screen_create(struct fd_device *dev) } 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); diff --git a/src/gallium/drivers/freedreno/freedreno_screen.h b/src/gallium/drivers/freedreno/freedreno_screen.h index 720ee054f89..93501e722f4 100644 --- a/src/gallium/drivers/freedreno/freedreno_screen.h +++ b/src/gallium/drivers/freedreno/freedreno_screen.h @@ -44,6 +44,7 @@ struct fd_screen { uint32_t gmemsize_bytes; uint32_t device_id; + uint32_t gpu_id; struct fd_device *dev; struct fd_pipe *pipe; diff --git a/src/gallium/drivers/freedreno/freedreno_state.c b/src/gallium/drivers/freedreno/freedreno_state.c index 9f4e4f83ade..10031977e61 100644 --- a/src/gallium/drivers/freedreno/freedreno_state.c +++ b/src/gallium/drivers/freedreno/freedreno_state.c @@ -33,15 +33,16 @@ #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) @@ -159,8 +160,8 @@ fd_set_polygon_stipple(struct pipe_context *pctx, 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); @@ -171,8 +172,8 @@ fd_set_scissor_states(struct pipe_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); @@ -228,420 +229,103 @@ fd_set_index_buffer(struct pipe_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; } diff --git a/src/gallium/drivers/freedreno/freedreno_state.h b/src/gallium/drivers/freedreno/freedreno_state.h index 422f0ced484..c966bdcc51d 100644 --- a/src/gallium/drivers/freedreno/freedreno_state.h +++ b/src/gallium/drivers/freedreno/freedreno_state.h @@ -30,22 +30,18 @@ #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_ */ diff --git a/src/gallium/drivers/freedreno/freedreno_texture.c b/src/gallium/drivers/freedreno/freedreno_texture.c index 3ea51ce1e5e..ff8a445dec6 100644 --- a/src/gallium/drivers/freedreno/freedreno_texture.c +++ b/src/gallium/drivers/freedreno/freedreno_texture.c @@ -32,110 +32,15 @@ #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) @@ -148,8 +53,11 @@ static void bind_sampler_states(struct fd_texture_stateobj *prog, 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); } @@ -159,15 +67,18 @@ static void bind_sampler_states(struct fd_texture_stateobj *prog, 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); } @@ -177,7 +88,7 @@ static void set_sampler_views(struct fd_texture_stateobj *prog, prog->dirty_samplers |= (1 << i); } - prog->num_textures = nr; + prog->num_textures = new_nr; } static void @@ -234,33 +145,11 @@ fd_verttex_set_sampler_views(struct pipe_context *pctx, unsigned nr, 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; diff --git a/src/gallium/drivers/freedreno/freedreno_texture.h b/src/gallium/drivers/freedreno/freedreno_texture.h index 94eb755ffb6..f73110dde12 100644 --- a/src/gallium/drivers/freedreno/freedreno_texture.h +++ b/src/gallium/drivers/freedreno/freedreno_texture.h @@ -31,31 +31,6 @@ #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_ */ diff --git a/src/gallium/drivers/freedreno/freedreno_util.c b/src/gallium/drivers/freedreno/freedreno_util.c index 7d458d594c8..83a33db8f5b 100644 --- a/src/gallium/drivers/freedreno/freedreno_util.c +++ b/src/gallium/drivers/freedreno/freedreno_util.c @@ -31,265 +31,7 @@ #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) { @@ -299,7 +41,7 @@ fd_pipe2depth(enum pipe_format format) case PIPE_FORMAT_Z24_UNORM_S8_UINT: return DEPTHX_24_8; default: - return DEPTHX_INVALID; + return ~0; } } @@ -314,38 +56,115 @@ fd_pipe2index(enum pipe_format format) 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; + } } diff --git a/src/gallium/drivers/freedreno/freedreno_util.h b/src/gallium/drivers/freedreno/freedreno_util.h index f73f792857b..f18f0fee989 100644 --- a/src/gallium/drivers/freedreno/freedreno_util.h +++ b/src/gallium/drivers/freedreno/freedreno_util.h @@ -38,14 +38,13 @@ #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 @@ -61,6 +60,8 @@ extern int fd_mesa_debug; #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)))) @@ -76,12 +77,6 @@ static inline uint32_t DRAW(enum pc_di_primtype prim_type, (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 @@ -106,6 +101,18 @@ OUT_RELOC(struct fd_ringbuffer *ring, struct fd_bo *bo, 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) { |