diff options
author | Rob Clark <[email protected]> | 2013-05-26 17:13:27 -0400 |
---|---|---|
committer | Rob Clark <[email protected]> | 2013-06-08 13:15:51 -0400 |
commit | 18c317b21ddc2ec4538544f9dd69dc568dcf821f (patch) | |
tree | 224e3c0464dcedabbf5784e5c3def952473fd8f8 /src | |
parent | 213c207b3ac40ae769afe01b8578f566b5e7840d (diff) |
freedreno: prepare for a3xx
Split the parts that are specific to adreno a2xx series GPUs from the
parts that will be in common with a3xx, so that a3xx support can be
added more cleanly.
Signed-off-by: Rob Clark <[email protected]>
Diffstat (limited to 'src')
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) { |