summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--configure.ac1
-rw-r--r--src/gallium/drivers/freedreno/Makefile.am19
-rw-r--r--src/gallium/drivers/freedreno/a2xx/Makefile.am27
-rw-r--r--src/gallium/drivers/freedreno/a2xx/a2xx.xml.h (renamed from src/gallium/drivers/freedreno/a2xx.xml.h)20
-rw-r--r--src/gallium/drivers/freedreno/a2xx/disasm-a2xx.c (renamed from src/gallium/drivers/freedreno/disasm.c)4
-rw-r--r--src/gallium/drivers/freedreno/a2xx/fd2_blend.c86
-rw-r--r--src/gallium/drivers/freedreno/a2xx/fd2_blend.h (renamed from src/gallium/drivers/freedreno/freedreno_blend.h)19
-rw-r--r--src/gallium/drivers/freedreno/a2xx/fd2_compiler.c (renamed from src/gallium/drivers/freedreno/freedreno_compiler.c)74
-rw-r--r--src/gallium/drivers/freedreno/a2xx/fd2_compiler.h (renamed from src/gallium/drivers/freedreno/freedreno_compiler.h)14
-rw-r--r--src/gallium/drivers/freedreno/a2xx/fd2_context.c101
-rw-r--r--src/gallium/drivers/freedreno/a2xx/fd2_context.h52
-rw-r--r--src/gallium/drivers/freedreno/a2xx/fd2_draw.c (renamed from src/gallium/drivers/freedreno/freedreno_clear.c)161
-rw-r--r--src/gallium/drivers/freedreno/a2xx/fd2_draw.h38
-rw-r--r--src/gallium/drivers/freedreno/a2xx/fd2_emit.c443
-rw-r--r--src/gallium/drivers/freedreno/a2xx/fd2_emit.h48
-rw-r--r--src/gallium/drivers/freedreno/a2xx/fd2_gmem.c408
-rw-r--r--src/gallium/drivers/freedreno/a2xx/fd2_gmem.h (renamed from src/gallium/drivers/freedreno/freedreno_clear.h)11
-rw-r--r--src/gallium/drivers/freedreno/a2xx/fd2_program.c (renamed from src/gallium/drivers/freedreno/freedreno_program.c)110
-rw-r--r--src/gallium/drivers/freedreno/a2xx/fd2_program.h (renamed from src/gallium/drivers/freedreno/freedreno_program.h)18
-rw-r--r--src/gallium/drivers/freedreno/a2xx/fd2_rasterizer.c (renamed from src/gallium/drivers/freedreno/freedreno_rasterizer.c)58
-rw-r--r--src/gallium/drivers/freedreno/a2xx/fd2_rasterizer.h (renamed from src/gallium/drivers/freedreno/freedreno_rasterizer.h)19
-rw-r--r--src/gallium/drivers/freedreno/a2xx/fd2_screen.c109
-rw-r--r--src/gallium/drivers/freedreno/a2xx/fd2_screen.h36
-rw-r--r--src/gallium/drivers/freedreno/a2xx/fd2_texture.c158
-rw-r--r--src/gallium/drivers/freedreno/a2xx/fd2_texture.h69
-rw-r--r--src/gallium/drivers/freedreno/a2xx/fd2_util.c322
-rw-r--r--src/gallium/drivers/freedreno/a2xx/fd2_util.h47
-rw-r--r--src/gallium/drivers/freedreno/a2xx/fd2_zsa.c (renamed from src/gallium/drivers/freedreno/freedreno_zsa.c)74
-rw-r--r--src/gallium/drivers/freedreno/a2xx/fd2_zsa.h (renamed from src/gallium/drivers/freedreno/freedreno_zsa.h)23
-rw-r--r--src/gallium/drivers/freedreno/a2xx/instr-a2xx.h (renamed from src/gallium/drivers/freedreno/instr-a2xx.h)0
-rw-r--r--src/gallium/drivers/freedreno/a2xx/ir-a2xx.c (renamed from src/gallium/drivers/freedreno/ir-a2xx.c)0
-rw-r--r--src/gallium/drivers/freedreno/a2xx/ir-a2xx.h (renamed from src/gallium/drivers/freedreno/ir-a2xx.h)0
-rw-r--r--src/gallium/drivers/freedreno/adreno_common.xml.h11
-rw-r--r--src/gallium/drivers/freedreno/adreno_pm4.xml.h98
-rw-r--r--src/gallium/drivers/freedreno/disasm.h5
-rw-r--r--src/gallium/drivers/freedreno/freedreno_blend.c175
-rw-r--r--src/gallium/drivers/freedreno/freedreno_context.c84
-rw-r--r--src/gallium/drivers/freedreno/freedreno_context.h50
-rw-r--r--src/gallium/drivers/freedreno/freedreno_draw.c (renamed from src/gallium/drivers/freedreno/freedreno_vbo.c)209
-rw-r--r--src/gallium/drivers/freedreno/freedreno_draw.h (renamed from src/gallium/drivers/freedreno/freedreno_vbo.h)17
-rw-r--r--src/gallium/drivers/freedreno/freedreno_gmem.c328
-rw-r--r--src/gallium/drivers/freedreno/freedreno_resource.c73
-rw-r--r--src/gallium/drivers/freedreno/freedreno_screen.c121
-rw-r--r--src/gallium/drivers/freedreno/freedreno_screen.h1
-rw-r--r--src/gallium/drivers/freedreno/freedreno_state.c470
-rw-r--r--src/gallium/drivers/freedreno/freedreno_state.h24
-rw-r--r--src/gallium/drivers/freedreno/freedreno_texture.c129
-rw-r--r--src/gallium/drivers/freedreno/freedreno_texture.h25
-rw-r--r--src/gallium/drivers/freedreno/freedreno_util.c387
-rw-r--r--src/gallium/drivers/freedreno/freedreno_util.h31
50 files changed, 2799 insertions, 2008 deletions
diff --git a/configure.ac b/configure.ac
index b0daf251d13..8d4a3dc27b0 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1984,6 +1984,7 @@ AC_CONFIG_FILES([Makefile
src/gallium/auxiliary/pipe-loader/Makefile
src/gallium/drivers/Makefile
src/gallium/drivers/freedreno/Makefile
+ src/gallium/drivers/freedreno/a2xx/Makefile
src/gallium/drivers/i915/Makefile
src/gallium/drivers/ilo/Makefile
src/gallium/drivers/llvmpipe/Makefile
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 <robdclark@gmail.com> (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 <robclark@freedesktop.org>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Authors:
+ * Rob Clark <robclark@freedesktop.org>
+ */
+
+#include "pipe/p_state.h"
+#include "util/u_string.h"
+#include "util/u_memory.h"
+
+#include "fd2_blend.h"
+#include "fd2_context.h"
+#include "fd2_util.h"
+
+void *
+fd2_blend_state_create(struct pipe_context *pctx,
+ const struct pipe_blend_state *cso)
+{
+ const struct pipe_rt_blend_state *rt = &cso->rt[0];
+ struct fd2_blend_stateobj *so;
+
+ if (cso->logicop_enable) {
+ DBG("Unsupported! logicop");
+ return NULL;
+ }
+
+ if (cso->independent_blend_enable) {
+ DBG("Unsupported! independent blend state");
+ return NULL;
+ }
+
+ so = CALLOC_STRUCT(fd2_blend_stateobj);
+ if (!so)
+ return NULL;
+
+ so->base = *cso;
+
+ so->rb_colorcontrol = A2XX_RB_COLORCONTROL_ROP_CODE(12);
+
+ so->rb_blendcontrol =
+ A2XX_RB_BLEND_CONTROL_COLOR_SRCBLEND(fd_blend_factor(rt->rgb_src_factor)) |
+ A2XX_RB_BLEND_CONTROL_COLOR_COMB_FCN(fd_blend_func(rt->rgb_func)) |
+ A2XX_RB_BLEND_CONTROL_COLOR_DESTBLEND(fd_blend_factor(rt->rgb_dst_factor)) |
+ A2XX_RB_BLEND_CONTROL_ALPHA_SRCBLEND(fd_blend_factor(rt->alpha_src_factor)) |
+ A2XX_RB_BLEND_CONTROL_ALPHA_COMB_FCN(fd_blend_func(rt->alpha_func)) |
+ A2XX_RB_BLEND_CONTROL_ALPHA_DESTBLEND(fd_blend_factor(rt->alpha_dst_factor));
+
+ if (rt->colormask & PIPE_MASK_R)
+ so->rb_colormask |= A2XX_RB_COLOR_MASK_WRITE_RED;
+ if (rt->colormask & PIPE_MASK_G)
+ so->rb_colormask |= A2XX_RB_COLOR_MASK_WRITE_GREEN;
+ if (rt->colormask & PIPE_MASK_B)
+ so->rb_colormask |= A2XX_RB_COLOR_MASK_WRITE_BLUE;
+ if (rt->colormask & PIPE_MASK_A)
+ so->rb_colormask |= A2XX_RB_COLOR_MASK_WRITE_ALPHA;
+
+ if (!rt->blend_enable)
+ so->rb_colorcontrol |= A2XX_RB_COLORCONTROL_BLEND_DISABLE;
+
+ if (cso->dither)
+ so->rb_colorcontrol |= A2XX_RB_COLORCONTROL_DITHER_MODE(DITHER_ALWAYS);
+
+ return so;
+}
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 <robclark@freedesktop.org>
+ * Copyright (C) 2012-2013 Rob Clark <robclark@freedesktop.org>
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -26,19 +26,26 @@
* Rob Clark <robclark@freedesktop.org>
*/
-#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 <robclark@freedesktop.org>
*/
-#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 <robclark@freedesktop.org>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Authors:
+ * Rob Clark <robclark@freedesktop.org>
+ */
+
+
+#include "fd2_context.h"
+#include "fd2_blend.h"
+#include "fd2_draw.h"
+#include "fd2_emit.h"
+#include "fd2_gmem.h"
+#include "fd2_program.h"
+#include "fd2_rasterizer.h"
+#include "fd2_texture.h"
+#include "fd2_zsa.h"
+
+static void
+fd2_context_destroy(struct pipe_context *pctx)
+{
+ fd2_prog_fini(pctx);
+ fd_context_destroy(pctx);
+}
+
+static struct pipe_resource *
+create_solid_vertexbuf(struct pipe_context *pctx)
+{
+ static const float init_shader_const[] = {
+ /* for clear/gmem2mem: */
+ -1.000000, +1.000000, +1.000000, +1.100000,
+ +1.000000, +1.000000, -1.000000, -1.100000,
+ +1.000000, +1.100000, -1.100000, +1.000000,
+ /* for mem2gmem: (vertices) */
+ -1.000000, +1.000000, +1.000000, +1.000000,
+ +1.000000, +1.000000, -1.000000, -1.000000,
+ +1.000000, +1.000000, -1.000000, +1.000000,
+ /* for mem2gmem: (tex coords) */
+ +0.000000, +0.000000, +1.000000, +0.000000,
+ +0.000000, +1.000000, +1.000000, +1.000000,
+ };
+ struct pipe_resource *prsc = pipe_buffer_create(pctx->screen,
+ PIPE_BIND_CUSTOM, PIPE_USAGE_IMMUTABLE, sizeof(init_shader_const));
+ pipe_buffer_write(pctx, prsc, 0,
+ sizeof(init_shader_const), init_shader_const);
+ return prsc;
+}
+
+struct pipe_context *
+fd2_context_create(struct pipe_screen *pscreen, void *priv)
+{
+ struct fd2_context *fd2_ctx = CALLOC_STRUCT(fd2_context);
+ struct pipe_context *pctx;
+
+ if (!fd2_ctx)
+ return NULL;
+
+ pctx = &fd2_ctx->base.base;
+
+ pctx->destroy = fd2_context_destroy;
+ pctx->create_blend_state = fd2_blend_state_create;
+ pctx->create_rasterizer_state = fd2_rasterizer_state_create;
+ pctx->create_depth_stencil_alpha_state = fd2_zsa_state_create;
+
+ fd2_draw_init(pctx);
+ fd2_gmem_init(pctx);
+ fd2_texture_init(pctx);
+ fd2_prog_init(pctx);
+
+ pctx = fd_context_init(&fd2_ctx->base, pscreen, priv);
+ if (!pctx)
+ return NULL;
+
+ /* construct vertex state used for solid ops (clear, and gmem<->mem) */
+ fd2_ctx->solid_vertexbuf = create_solid_vertexbuf(pctx);
+
+ fd2_emit_setup(&fd2_ctx->base);
+
+ return pctx;
+}
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 <robclark@freedesktop.org>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Authors:
+ * Rob Clark <robclark@freedesktop.org>
+ */
+
+#ifndef FD2_CONTEXT_H_
+#define FD2_CONTEXT_H_
+
+#include "freedreno_context.h"
+
+struct fd2_context {
+ struct fd_context base;
+
+ /* vertex buf used for clear/gmem->mem vertices, and mem->gmem
+ * vertices and tex coords:
+ */
+ struct pipe_resource *solid_vertexbuf;
+};
+
+static INLINE struct fd2_context *
+fd2_context(struct fd_context *ctx)
+{
+ return (struct fd2_context *)ctx;
+}
+
+struct pipe_context *
+fd2_context_create(struct pipe_screen *pscreen, void *priv);
+
+#endif /* FD2_CONTEXT_H_ */
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 <robclark@freedesktop.org>
+ * Copyright (C) 2012-2013 Rob Clark <robclark@freedesktop.org>
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -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 <robclark@freedesktop.org>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Authors:
+ * Rob Clark <robclark@freedesktop.org>
+ */
+
+#ifndef FD2_DRAW_H_
+#define FD2_DRAW_H_
+
+#include "pipe/p_context.h"
+
+#include "freedreno_draw.h"
+
+void fd2_draw_init(struct pipe_context *pctx);
+
+#endif /* FD2_DRAW_H_ */
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 <robclark@freedesktop.org>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Authors:
+ * Rob Clark <robclark@freedesktop.org>
+ */
+
+#include "pipe/p_state.h"
+#include "util/u_string.h"
+#include "util/u_memory.h"
+#include "util/u_helpers.h"
+
+#include "freedreno_resource.h"
+
+#include "fd2_emit.h"
+#include "fd2_blend.h"
+#include "fd2_context.h"
+#include "fd2_program.h"
+#include "fd2_rasterizer.h"
+#include "fd2_texture.h"
+#include "fd2_util.h"
+#include "fd2_zsa.h"
+
+/* NOTE: just define the position for const regs statically.. the blob
+ * driver doesn't seem to change these dynamically, and I can't really
+ * think of a good reason to so..
+ */
+#define VS_CONST_BASE 0x20
+#define PS_CONST_BASE 0x120
+
+static void
+emit_constants(struct fd_ringbuffer *ring, uint32_t base,
+ struct fd_constbuf_stateobj *constbuf,
+ struct fd2_shader_stateobj *shader)
+{
+ uint32_t enabled_mask = constbuf->enabled_mask;
+ uint32_t start_base = base;
+ unsigned i;
+
+ // XXX TODO only emit dirty consts.. but we need to keep track if
+ // they are clobbered by a clear, gmem2mem, or mem2gmem..
+ constbuf->dirty_mask = enabled_mask;
+
+ /* emit user constants: */
+ while (enabled_mask) {
+ unsigned index = ffs(enabled_mask) - 1;
+ struct pipe_constant_buffer *cb = &constbuf->cb[index];
+ unsigned size = align(cb->buffer_size, 4) / 4; /* size in dwords */
+
+ // I expect that size should be a multiple of vec4's:
+ assert(size == align(size, 4));
+
+ /* hmm, sometimes we still seem to end up with consts bound,
+ * even if shader isn't using them, which ends up overwriting
+ * const reg's used for immediates.. this is a hack to work
+ * around that:
+ */
+ if (shader && ((base - start_base) >= (shader->first_immediate * 4)))
+ break;
+
+ if (constbuf->dirty_mask & (1 << index)) {
+ const uint32_t *dwords;
+
+ if (cb->user_buffer) {
+ dwords = cb->user_buffer;
+ } else {
+ struct fd_resource *rsc = fd_resource(cb->buffer);
+ dwords = fd_bo_map(rsc->bo);
+ }
+
+ dwords = (uint32_t *)(((uint8_t *)dwords) + cb->buffer_offset);
+
+ OUT_PKT3(ring, CP_SET_CONSTANT, size + 1);
+ OUT_RING(ring, base);
+ for (i = 0; i < size; i++)
+ OUT_RING(ring, *(dwords++));
+
+ constbuf->dirty_mask &= ~(1 << index);
+ }
+
+ base += size;
+ enabled_mask &= ~(1 << index);
+ }
+
+ /* emit shader immediates: */
+ if (shader) {
+ for (i = 0; i < shader->num_immediates; i++) {
+ OUT_PKT3(ring, CP_SET_CONSTANT, 5);
+ OUT_RING(ring, start_base + (4 * (shader->first_immediate + i)));
+ OUT_RING(ring, shader->immediates[i].val[0]);
+ OUT_RING(ring, shader->immediates[i].val[1]);
+ OUT_RING(ring, shader->immediates[i].val[2]);
+ OUT_RING(ring, shader->immediates[i].val[3]);
+ base += 4;
+ }
+ }
+}
+
+typedef uint32_t texmask;
+
+static texmask
+emit_texture(struct fd_ringbuffer *ring, struct fd_context *ctx,
+ struct fd_texture_stateobj *tex, unsigned samp_id, texmask emitted)
+{
+ unsigned const_idx = fd2_get_const_idx(ctx, tex, samp_id);
+ struct fd2_sampler_stateobj *sampler;
+ struct fd2_pipe_sampler_view *view;
+
+ if (emitted & (1 << const_idx))
+ return 0;
+
+ sampler = fd2_sampler_stateobj(tex->samplers[samp_id]);
+ view = fd2_pipe_sampler_view(tex->textures[samp_id]);
+
+ OUT_PKT3(ring, CP_SET_CONSTANT, 7);
+ OUT_RING(ring, 0x00010000 + (0x6 * const_idx));
+
+ OUT_RING(ring, sampler->tex0 | view->tex0);
+ OUT_RELOC(ring, view->tex_resource->bo, 0, view->fmt);
+ OUT_RING(ring, view->tex2);
+ OUT_RING(ring, sampler->tex3 | view->tex3);
+ OUT_RING(ring, sampler->tex4);
+ OUT_RING(ring, sampler->tex5);
+
+ return (1 << const_idx);
+}
+
+static void
+emit_textures(struct fd_ringbuffer *ring, struct fd_context *ctx)
+{
+ texmask emitted = 0;
+ unsigned i;
+
+ for (i = 0; i < ctx->verttex.num_samplers; i++)
+ if (ctx->verttex.samplers[i])
+ emitted |= emit_texture(ring, ctx, &ctx->verttex, i, emitted);
+
+ for (i = 0; i < ctx->fragtex.num_samplers; i++)
+ if (ctx->fragtex.samplers[i])
+ emitted |= emit_texture(ring, ctx, &ctx->fragtex, i, emitted);
+}
+
+void
+fd2_emit_vertex_bufs(struct fd_ringbuffer *ring, uint32_t val,
+ struct fd2_vertex_buf *vbufs, uint32_t n)
+{
+ unsigned i;
+
+ OUT_PKT3(ring, CP_SET_CONSTANT, 1 + (2 * n));
+ OUT_RING(ring, (0x1 << 16) | (val & 0xffff));
+ for (i = 0; i < n; i++) {
+ struct fd_resource *rsc = fd_resource(vbufs[i].prsc);
+ OUT_RELOC(ring, rsc->bo, vbufs[i].offset, 3);
+ OUT_RING (ring, vbufs[i].size);
+ }
+}
+
+void
+fd2_emit_state(struct fd_context *ctx, uint32_t dirty)
+{
+ struct fd2_blend_stateobj *blend = fd2_blend_stateobj(ctx->blend);
+ struct fd2_zsa_stateobj *zsa = fd2_zsa_stateobj(ctx->zsa);
+ struct fd_ringbuffer *ring = ctx->ring;
+
+ /* NOTE: we probably want to eventually refactor this so each state
+ * object handles emitting it's own state.. although the mapping of
+ * state to registers is not always orthogonal, sometimes a single
+ * register contains bitfields coming from multiple state objects,
+ * so not sure the best way to deal with that yet.
+ */
+
+ if (dirty & FD_DIRTY_SAMPLE_MASK) {
+ OUT_PKT3(ring, CP_SET_CONSTANT, 2);
+ OUT_RING(ring, CP_REG(REG_A2XX_PA_SC_AA_MASK));
+ OUT_RING(ring, ctx->sample_mask);
+ }
+
+ if (dirty & (FD_DIRTY_ZSA | FD_DIRTY_STENCIL_REF)) {
+ struct pipe_stencil_ref *sr = &ctx->stencil_ref;
+
+ OUT_PKT3(ring, CP_SET_CONSTANT, 2);
+ OUT_RING(ring, CP_REG(REG_A2XX_RB_DEPTHCONTROL));
+ OUT_RING(ring, zsa->rb_depthcontrol);
+
+ OUT_PKT3(ring, CP_SET_CONSTANT, 4);
+ OUT_RING(ring, CP_REG(REG_A2XX_RB_STENCILREFMASK_BF));
+ OUT_RING(ring, zsa->rb_stencilrefmask_bf |
+ A2XX_RB_STENCILREFMASK_STENCILREF(sr->ref_value[1]));
+ OUT_RING(ring, zsa->rb_stencilrefmask |
+ A2XX_RB_STENCILREFMASK_STENCILREF(sr->ref_value[0]));
+ OUT_RING(ring, zsa->rb_alpha_ref);
+ }
+
+ if (dirty & (FD_DIRTY_RASTERIZER | FD_DIRTY_FRAMEBUFFER)) {
+ struct fd2_rasterizer_stateobj *rasterizer =
+ fd2_rasterizer_stateobj(ctx->rasterizer);
+ OUT_PKT3(ring, CP_SET_CONSTANT, 3);
+ OUT_RING(ring, CP_REG(REG_A2XX_PA_CL_CLIP_CNTL));
+ OUT_RING(ring, rasterizer->pa_cl_clip_cntl);
+ OUT_RING(ring, rasterizer->pa_su_sc_mode_cntl |
+ A2XX_PA_SU_SC_MODE_CNTL_VTX_WINDOW_OFFSET_ENABLE);
+
+ OUT_PKT3(ring, CP_SET_CONSTANT, 5);
+ OUT_RING(ring, CP_REG(REG_A2XX_PA_SU_POINT_SIZE));
+ OUT_RING(ring, rasterizer->pa_su_point_size);
+ OUT_RING(ring, rasterizer->pa_su_point_minmax);
+ OUT_RING(ring, rasterizer->pa_su_line_cntl);
+ OUT_RING(ring, rasterizer->pa_sc_line_stipple);
+
+ OUT_PKT3(ring, CP_SET_CONSTANT, 6);
+ OUT_RING(ring, CP_REG(REG_A2XX_PA_SU_VTX_CNTL));
+ OUT_RING(ring, rasterizer->pa_su_vtx_cntl);
+ OUT_RING(ring, fui(1.0)); /* PA_CL_GB_VERT_CLIP_ADJ */
+ OUT_RING(ring, fui(1.0)); /* PA_CL_GB_VERT_DISC_ADJ */
+ OUT_RING(ring, fui(1.0)); /* PA_CL_GB_HORZ_CLIP_ADJ */
+ OUT_RING(ring, fui(1.0)); /* PA_CL_GB_HORZ_DISC_ADJ */
+ }
+
+ if (dirty & FD_DIRTY_SCISSOR) {
+ OUT_PKT3(ring, CP_SET_CONSTANT, 3);
+ OUT_RING(ring, CP_REG(REG_A2XX_PA_SC_WINDOW_SCISSOR_TL));
+ OUT_RING(ring, xy2d(ctx->scissor.minx, /* PA_SC_WINDOW_SCISSOR_TL */
+ ctx->scissor.miny));
+ OUT_RING(ring, xy2d(ctx->scissor.maxx, /* PA_SC_WINDOW_SCISSOR_BR */
+ ctx->scissor.maxy));
+
+ ctx->max_scissor.minx = MIN2(ctx->max_scissor.minx, ctx->scissor.minx);
+ ctx->max_scissor.miny = MIN2(ctx->max_scissor.miny, ctx->scissor.miny);
+ ctx->max_scissor.maxx = MAX2(ctx->max_scissor.maxx, ctx->scissor.maxx);
+ ctx->max_scissor.maxy = MAX2(ctx->max_scissor.maxy, ctx->scissor.maxy);
+ }
+
+ if (dirty & FD_DIRTY_VIEWPORT) {
+ OUT_PKT3(ring, CP_SET_CONSTANT, 7);
+ OUT_RING(ring, CP_REG(REG_A2XX_PA_CL_VPORT_XSCALE));
+ OUT_RING(ring, fui(ctx->viewport.scale[0])); /* PA_CL_VPORT_XSCALE */
+ OUT_RING(ring, fui(ctx->viewport.translate[0])); /* PA_CL_VPORT_XOFFSET */
+ OUT_RING(ring, fui(ctx->viewport.scale[1])); /* PA_CL_VPORT_YSCALE */
+ OUT_RING(ring, fui(ctx->viewport.translate[1])); /* PA_CL_VPORT_YOFFSET */
+ OUT_RING(ring, fui(ctx->viewport.scale[2])); /* PA_CL_VPORT_ZSCALE */
+ OUT_RING(ring, fui(ctx->viewport.translate[2])); /* PA_CL_VPORT_ZOFFSET */
+
+ OUT_PKT3(ring, CP_SET_CONSTANT, 2);
+ OUT_RING(ring, CP_REG(REG_A2XX_PA_CL_VTE_CNTL));
+ OUT_RING(ring, A2XX_PA_CL_VTE_CNTL_VTX_W0_FMT |
+ A2XX_PA_CL_VTE_CNTL_VPORT_X_SCALE_ENA |
+ A2XX_PA_CL_VTE_CNTL_VPORT_X_OFFSET_ENA |
+ A2XX_PA_CL_VTE_CNTL_VPORT_Y_SCALE_ENA |
+ A2XX_PA_CL_VTE_CNTL_VPORT_Y_OFFSET_ENA |
+ A2XX_PA_CL_VTE_CNTL_VPORT_Z_SCALE_ENA |
+ A2XX_PA_CL_VTE_CNTL_VPORT_Z_OFFSET_ENA);
+ }
+
+ if (dirty & (FD_DIRTY_PROG | FD_DIRTY_VTXSTATE | FD_DIRTY_TEXSTATE)) {
+ fd2_program_validate(ctx);
+ fd2_program_emit(ring, &ctx->prog);
+ }
+
+ if (dirty & (FD_DIRTY_PROG | FD_DIRTY_CONSTBUF)) {
+ emit_constants(ring, VS_CONST_BASE * 4,
+ &ctx->constbuf[PIPE_SHADER_VERTEX],
+ (dirty & FD_DIRTY_PROG) ? ctx->prog.vp : NULL);
+ emit_constants(ring, PS_CONST_BASE * 4,
+ &ctx->constbuf[PIPE_SHADER_FRAGMENT],
+ (dirty & FD_DIRTY_PROG) ? ctx->prog.fp : NULL);
+ }
+
+ if (dirty & (FD_DIRTY_BLEND | FD_DIRTY_ZSA)) {
+ OUT_PKT3(ring, CP_SET_CONSTANT, 2);
+ OUT_RING(ring, CP_REG(REG_A2XX_RB_COLORCONTROL));
+ OUT_RING(ring, zsa->rb_colorcontrol | blend->rb_colorcontrol);
+ }
+
+ if (dirty & FD_DIRTY_BLEND) {
+ OUT_PKT3(ring, CP_SET_CONSTANT, 2);
+ OUT_RING(ring, CP_REG(REG_A2XX_RB_BLEND_CONTROL));
+ OUT_RING(ring, blend->rb_blendcontrol);
+
+ OUT_PKT3(ring, CP_SET_CONSTANT, 2);
+ OUT_RING(ring, CP_REG(REG_A2XX_RB_COLOR_MASK));
+ OUT_RING(ring, blend->rb_colormask);
+ }
+
+ if (dirty & (FD_DIRTY_VERTTEX | FD_DIRTY_FRAGTEX | FD_DIRTY_PROG))
+ emit_textures(ring, ctx);
+
+ ctx->dirty &= ~dirty;
+}
+
+/* emit per-context initialization:
+ */
+void
+fd2_emit_setup(struct fd_context *ctx)
+{
+ struct fd_ringbuffer *ring = ctx->ring;
+
+ OUT_PKT0(ring, REG_A2XX_TP0_CHICKEN, 1);
+ OUT_RING(ring, 0x00000002);
+
+ OUT_PKT3(ring, CP_INVALIDATE_STATE, 1);
+ OUT_RING(ring, 0x00007fff);
+
+ OUT_PKT3(ring, CP_SET_CONSTANT, 2);
+ OUT_RING(ring, CP_REG(REG_A2XX_SQ_VS_CONST));
+ OUT_RING(ring, A2XX_SQ_VS_CONST_BASE(VS_CONST_BASE) |
+ A2XX_SQ_VS_CONST_SIZE(0x100));
+
+ OUT_PKT3(ring, CP_SET_CONSTANT, 2);
+ OUT_RING(ring, CP_REG(REG_A2XX_SQ_PS_CONST));
+ OUT_RING(ring, A2XX_SQ_PS_CONST_BASE(PS_CONST_BASE) |
+ A2XX_SQ_PS_CONST_SIZE(0xe0));
+
+ OUT_PKT3(ring, CP_SET_CONSTANT, 3);
+ OUT_RING(ring, CP_REG(REG_A2XX_VGT_MAX_VTX_INDX));
+ OUT_RING(ring, 0xffffffff); /* VGT_MAX_VTX_INDX */
+ OUT_RING(ring, 0x00000000); /* VGT_MIN_VTX_INDX */
+
+ OUT_PKT3(ring, CP_SET_CONSTANT, 2);
+ OUT_RING(ring, CP_REG(REG_A2XX_VGT_INDX_OFFSET));
+ OUT_RING(ring, 0x00000000);
+
+ OUT_PKT3(ring, CP_SET_CONSTANT, 2);
+ OUT_RING(ring, CP_REG(REG_A2XX_VGT_VERTEX_REUSE_BLOCK_CNTL));
+ OUT_RING(ring, 0x0000003b);
+
+ OUT_PKT3(ring, CP_SET_CONSTANT, 2);
+ OUT_RING(ring, CP_REG(REG_A2XX_SQ_CONTEXT_MISC));
+ OUT_RING(ring, A2XX_SQ_CONTEXT_MISC_SC_SAMPLE_CNTL(CENTERS_ONLY));
+
+ OUT_PKT3(ring, CP_SET_CONSTANT, 2);
+ OUT_RING(ring, CP_REG(REG_A2XX_SQ_INTERPOLATOR_CNTL));
+ OUT_RING(ring, 0xffffffff);
+
+ OUT_PKT3(ring, CP_SET_CONSTANT, 2);
+ OUT_RING(ring, CP_REG(REG_A2XX_PA_SC_AA_CONFIG));
+ OUT_RING(ring, 0x00000000);
+
+ OUT_PKT3(ring, CP_SET_CONSTANT, 2);
+ OUT_RING(ring, CP_REG(REG_A2XX_PA_SC_LINE_CNTL));
+ OUT_RING(ring, 0x00000000);
+
+ OUT_PKT3(ring, CP_SET_CONSTANT, 2);
+ OUT_RING(ring, CP_REG(REG_A2XX_PA_SC_WINDOW_OFFSET));
+ OUT_RING(ring, 0x00000000);
+
+ // XXX we change this dynamically for draw/clear.. vs gmem<->mem..
+ OUT_PKT3(ring, CP_SET_CONSTANT, 2);
+ OUT_RING(ring, CP_REG(REG_A2XX_RB_MODECONTROL));
+ OUT_RING(ring, A2XX_RB_MODECONTROL_EDRAM_MODE(COLOR_DEPTH));
+
+ OUT_PKT3(ring, CP_SET_CONSTANT, 2);
+ OUT_RING(ring, CP_REG(REG_A2XX_RB_SAMPLE_POS));
+ OUT_RING(ring, 0x88888888);
+
+ OUT_PKT3(ring, CP_SET_CONSTANT, 2);
+ OUT_RING(ring, CP_REG(REG_A2XX_RB_COLOR_DEST_MASK));
+ OUT_RING(ring, 0xffffffff);
+
+ OUT_PKT3(ring, CP_SET_CONSTANT, 2);
+ OUT_RING(ring, CP_REG(REG_A2XX_RB_COPY_DEST_INFO));
+ OUT_RING(ring, A2XX_RB_COPY_DEST_INFO_FORMAT(COLORX_4_4_4_4) |
+ A2XX_RB_COPY_DEST_INFO_WRITE_RED |
+ A2XX_RB_COPY_DEST_INFO_WRITE_GREEN |
+ A2XX_RB_COPY_DEST_INFO_WRITE_BLUE |
+ A2XX_RB_COPY_DEST_INFO_WRITE_ALPHA);
+
+ OUT_PKT3(ring, CP_SET_CONSTANT, 3);
+ OUT_RING(ring, CP_REG(REG_A2XX_SQ_WRAPPING_0));
+ OUT_RING(ring, 0x00000000); /* SQ_WRAPPING_0 */
+ OUT_RING(ring, 0x00000000); /* SQ_WRAPPING_1 */
+
+ OUT_PKT3(ring, CP_SET_DRAW_INIT_FLAGS, 1);
+ OUT_RING(ring, 0x00000000);
+
+ OUT_PKT3(ring, CP_WAIT_REG_EQ, 4);
+ OUT_RING(ring, 0x000005d0);
+ OUT_RING(ring, 0x00000000);
+ OUT_RING(ring, 0x5f601000);
+ OUT_RING(ring, 0x00000001);
+
+ OUT_PKT0(ring, REG_A2XX_SQ_INST_STORE_MANAGMENT, 1);
+ OUT_RING(ring, 0x00000180);
+
+ OUT_PKT3(ring, CP_INVALIDATE_STATE, 1);
+ OUT_RING(ring, 0x00000300);
+
+ OUT_PKT3(ring, CP_SET_SHADER_BASES, 1);
+ OUT_RING(ring, 0x80000180);
+
+ /* not sure what this form of CP_SET_CONSTANT is.. */
+ OUT_PKT3(ring, CP_SET_CONSTANT, 13);
+ OUT_RING(ring, 0x00000000);
+ OUT_RING(ring, 0x00000000);
+ OUT_RING(ring, 0x00000000);
+ OUT_RING(ring, 0x00000000);
+ OUT_RING(ring, 0x00000000);
+ OUT_RING(ring, 0x469c4000);
+ OUT_RING(ring, 0x3f800000);
+ OUT_RING(ring, 0x3f000000);
+ OUT_RING(ring, 0x00000000);
+ OUT_RING(ring, 0x40000000);
+ OUT_RING(ring, 0x3f400000);
+ OUT_RING(ring, 0x3ec00000);
+ OUT_RING(ring, 0x3e800000);
+
+ OUT_PKT3(ring, CP_SET_CONSTANT, 2);
+ OUT_RING(ring, CP_REG(REG_A2XX_RB_COLOR_MASK));
+ OUT_RING(ring, A2XX_RB_COLOR_MASK_WRITE_RED |
+ A2XX_RB_COLOR_MASK_WRITE_GREEN |
+ A2XX_RB_COLOR_MASK_WRITE_BLUE |
+ A2XX_RB_COLOR_MASK_WRITE_ALPHA);
+
+ OUT_PKT3(ring, CP_SET_CONSTANT, 5);
+ OUT_RING(ring, CP_REG(REG_A2XX_RB_BLEND_RED));
+ OUT_RING(ring, 0x00000000); /* RB_BLEND_RED */
+ OUT_RING(ring, 0x00000000); /* RB_BLEND_GREEN */
+ OUT_RING(ring, 0x00000000); /* RB_BLEND_BLUE */
+ OUT_RING(ring, 0x000000ff); /* RB_BLEND_ALPHA */
+
+ fd_ringbuffer_flush(ring);
+ fd_ringmarker_mark(ctx->draw_start);
+}
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 <robclark@freedesktop.org>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Authors:
+ * Rob Clark <robclark@freedesktop.org>
+ */
+
+#ifndef FD2_EMIT_H
+#define FD2_EMIT_H
+
+#include "pipe/p_context.h"
+
+#include "freedreno_context.h"
+
+struct fd_ringbuffer;
+
+struct fd2_vertex_buf {
+ unsigned offset, size;
+ struct pipe_resource *prsc;
+};
+
+void fd2_emit_vertex_bufs(struct fd_ringbuffer *ring, uint32_t val,
+ struct fd2_vertex_buf *vbufs, uint32_t n);
+void fd2_emit_state(struct fd_context *ctx, uint32_t dirty);
+void fd2_emit_setup(struct fd_context *ctx);
+
+#endif /* FD2_EMIT_H */
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 <robclark@freedesktop.org>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Authors:
+ * Rob Clark <robclark@freedesktop.org>
+ */
+
+#include "pipe/p_state.h"
+#include "util/u_string.h"
+#include "util/u_memory.h"
+#include "util/u_inlines.h"
+
+#include "freedreno_state.h"
+#include "freedreno_resource.h"
+
+#include "fd2_gmem.h"
+#include "fd2_context.h"
+#include "fd2_emit.h"
+#include "fd2_program.h"
+#include "fd2_util.h"
+#include "fd2_zsa.h"
+
+static uint32_t fmt2swap(enum pipe_format format)
+{
+ switch (format) {
+ case PIPE_FORMAT_B8G8R8A8_UNORM:
+ /* TODO probably some more.. */
+ return 1;
+ default:
+ return 0;
+ }
+}
+
+/* transfer from gmem to system memory (ie. normal RAM) */
+
+static void
+emit_gmem2mem_surf(struct fd_ringbuffer *ring, uint32_t base,
+ struct pipe_surface *psurf)
+{
+ struct fd_resource *rsc = fd_resource(psurf->texture);
+ uint32_t swap = fmt2swap(psurf->format);
+
+ OUT_PKT3(ring, CP_SET_CONSTANT, 2);
+ OUT_RING(ring, CP_REG(REG_A2XX_RB_COLOR_INFO));
+ OUT_RING(ring, A2XX_RB_COLOR_INFO_SWAP(swap) |
+ A2XX_RB_COLOR_INFO_BASE(base) |
+ A2XX_RB_COLOR_INFO_FORMAT(fd2_pipe2color(psurf->format)));
+
+ OUT_PKT3(ring, CP_SET_CONSTANT, 5);
+ OUT_RING(ring, CP_REG(REG_A2XX_RB_COPY_CONTROL));
+ OUT_RING(ring, 0x00000000); /* RB_COPY_CONTROL */
+ OUT_RELOC(ring, rsc->bo, 0, 0); /* RB_COPY_DEST_BASE */
+ OUT_RING(ring, rsc->pitch >> 5); /* RB_COPY_DEST_PITCH */
+ OUT_RING(ring, /* RB_COPY_DEST_INFO */
+ A2XX_RB_COPY_DEST_INFO_FORMAT(fd2_pipe2color(psurf->format)) |
+ A2XX_RB_COPY_DEST_INFO_LINEAR |
+ A2XX_RB_COPY_DEST_INFO_SWAP(swap) |
+ A2XX_RB_COPY_DEST_INFO_WRITE_RED |
+ A2XX_RB_COPY_DEST_INFO_WRITE_GREEN |
+ A2XX_RB_COPY_DEST_INFO_WRITE_BLUE |
+ A2XX_RB_COPY_DEST_INFO_WRITE_ALPHA);
+
+ OUT_PKT3(ring, CP_WAIT_FOR_IDLE, 1);
+ OUT_RING(ring, 0x0000000);
+
+ OUT_PKT3(ring, CP_SET_CONSTANT, 3);
+ OUT_RING(ring, CP_REG(REG_A2XX_VGT_MAX_VTX_INDX));
+ OUT_RING(ring, 3); /* VGT_MAX_VTX_INDX */
+ OUT_RING(ring, 0); /* VGT_MIN_VTX_INDX */
+
+ OUT_PKT3(ring, CP_DRAW_INDX, 3);
+ OUT_RING(ring, 0x00000000);
+ OUT_RING(ring, DRAW(DI_PT_RECTLIST, DI_SRC_SEL_AUTO_INDEX,
+ INDEX_SIZE_IGN, IGNORE_VISIBILITY));
+ OUT_RING(ring, 3); /* NumIndices */
+}
+
+static void
+fd2_emit_tile_gmem2mem(struct fd_context *ctx, uint32_t xoff, uint32_t yoff,
+ uint32_t bin_w, uint32_t bin_h)
+{
+ struct fd2_context *fd2_ctx = fd2_context(ctx);
+ struct fd_ringbuffer *ring = ctx->ring;
+ struct pipe_framebuffer_state *pfb = &ctx->framebuffer;
+
+ fd2_emit_vertex_bufs(ring, 0x9c, (struct fd2_vertex_buf[]) {
+ { .prsc = fd2_ctx->solid_vertexbuf, .size = 48 },
+ }, 1);
+
+ OUT_PKT3(ring, CP_SET_CONSTANT, 2);
+ OUT_RING(ring, CP_REG(REG_A2XX_PA_SC_WINDOW_OFFSET));
+ OUT_RING(ring, 0x00000000); /* PA_SC_WINDOW_OFFSET */
+
+ OUT_PKT3(ring, CP_SET_CONSTANT, 2);
+ OUT_RING(ring, CP_REG(REG_A2XX_VGT_INDX_OFFSET));
+ OUT_RING(ring, 0);
+
+ OUT_PKT3(ring, CP_SET_CONSTANT, 2);
+ OUT_RING(ring, CP_REG(REG_A2XX_VGT_VERTEX_REUSE_BLOCK_CNTL));
+ OUT_RING(ring, 0x0000028f);
+
+ fd2_program_emit(ring, &ctx->solid_prog);
+
+ OUT_PKT3(ring, CP_SET_CONSTANT, 2);
+ OUT_RING(ring, CP_REG(REG_A2XX_PA_SC_AA_MASK));
+ OUT_RING(ring, 0x0000ffff);
+
+ OUT_PKT3(ring, CP_SET_CONSTANT, 2);
+ OUT_RING(ring, CP_REG(REG_A2XX_RB_DEPTHCONTROL));
+ OUT_RING(ring, A2XX_RB_DEPTHCONTROL_EARLY_Z_ENABLE);
+
+ OUT_PKT3(ring, CP_SET_CONSTANT, 2);
+ OUT_RING(ring, CP_REG(REG_A2XX_PA_SU_SC_MODE_CNTL));
+ OUT_RING(ring, A2XX_PA_SU_SC_MODE_CNTL_PROVOKING_VTX_LAST | /* PA_SU_SC_MODE_CNTL */
+ A2XX_PA_SU_SC_MODE_CNTL_FRONT_PTYPE(PC_DRAW_TRIANGLES) |
+ A2XX_PA_SU_SC_MODE_CNTL_BACK_PTYPE(PC_DRAW_TRIANGLES));
+
+ OUT_PKT3(ring, CP_SET_CONSTANT, 3);
+ OUT_RING(ring, CP_REG(REG_A2XX_PA_SC_WINDOW_SCISSOR_TL));
+ OUT_RING(ring, xy2d(0, 0)); /* PA_SC_WINDOW_SCISSOR_TL */
+ OUT_RING(ring, xy2d(pfb->width, pfb->height)); /* PA_SC_WINDOW_SCISSOR_BR */
+
+ OUT_PKT3(ring, CP_SET_CONSTANT, 2);
+ OUT_RING(ring, CP_REG(REG_A2XX_PA_CL_VTE_CNTL));
+ OUT_RING(ring, A2XX_PA_CL_VTE_CNTL_VTX_W0_FMT |
+ A2XX_PA_CL_VTE_CNTL_VPORT_X_SCALE_ENA |
+ A2XX_PA_CL_VTE_CNTL_VPORT_X_OFFSET_ENA |
+ A2XX_PA_CL_VTE_CNTL_VPORT_Y_SCALE_ENA |
+ A2XX_PA_CL_VTE_CNTL_VPORT_Y_OFFSET_ENA);
+
+ OUT_PKT3(ring, CP_SET_CONSTANT, 2);
+ OUT_RING(ring, CP_REG(REG_A2XX_PA_CL_CLIP_CNTL));
+ OUT_RING(ring, 0x00000000);
+
+ OUT_PKT3(ring, CP_SET_CONSTANT, 2);
+ OUT_RING(ring, CP_REG(REG_A2XX_RB_MODECONTROL));
+ OUT_RING(ring, A2XX_RB_MODECONTROL_EDRAM_MODE(EDRAM_COPY));
+
+ OUT_PKT3(ring, CP_SET_CONSTANT, 2);
+ OUT_RING(ring, CP_REG(REG_A2XX_RB_COPY_DEST_OFFSET));
+ OUT_RING(ring, A2XX_RB_COPY_DEST_OFFSET_X(xoff) |
+ A2XX_RB_COPY_DEST_OFFSET_Y(yoff));
+
+ if (ctx->resolve & (FD_BUFFER_DEPTH | FD_BUFFER_STENCIL))
+ emit_gmem2mem_surf(ring, bin_w * bin_h, pfb->zsbuf);
+
+ if (ctx->resolve & FD_BUFFER_COLOR)
+ emit_gmem2mem_surf(ring, 0, pfb->cbufs[0]);
+
+ OUT_PKT3(ring, CP_SET_CONSTANT, 2);
+ OUT_RING(ring, CP_REG(REG_A2XX_RB_MODECONTROL));
+ OUT_RING(ring, A2XX_RB_MODECONTROL_EDRAM_MODE(COLOR_DEPTH));
+}
+
+/* transfer from system memory to gmem */
+
+static void
+emit_mem2gmem_surf(struct fd_ringbuffer *ring, uint32_t base,
+ struct pipe_surface *psurf)
+{
+ struct fd_resource *rsc = fd_resource(psurf->texture);
+ uint32_t swiz;
+
+ OUT_PKT3(ring, CP_SET_CONSTANT, 2);
+ OUT_RING(ring, CP_REG(REG_A2XX_RB_COLOR_INFO));
+ OUT_RING(ring, A2XX_RB_COLOR_INFO_SWAP(fmt2swap(psurf->format)) |
+ A2XX_RB_COLOR_INFO_BASE(base) |
+ A2XX_RB_COLOR_INFO_FORMAT(fd2_pipe2color(psurf->format)));
+
+ swiz = fd2_tex_swiz(psurf->format, PIPE_SWIZZLE_RED, PIPE_SWIZZLE_GREEN,
+ PIPE_SWIZZLE_BLUE, PIPE_SWIZZLE_ALPHA);
+
+ /* emit fb as a texture: */
+ OUT_PKT3(ring, CP_SET_CONSTANT, 7);
+ OUT_RING(ring, 0x00010000);
+ OUT_RING(ring, A2XX_SQ_TEX_0_CLAMP_X(SQ_TEX_WRAP) |
+ A2XX_SQ_TEX_0_CLAMP_Y(SQ_TEX_WRAP) |
+ A2XX_SQ_TEX_0_CLAMP_Z(SQ_TEX_WRAP) |
+ A2XX_SQ_TEX_0_PITCH(rsc->pitch));
+ OUT_RELOC(ring, rsc->bo, 0,
+ fd2_pipe2surface(psurf->format) | 0x800);
+ OUT_RING(ring, A2XX_SQ_TEX_2_WIDTH(psurf->width - 1) |
+ A2XX_SQ_TEX_2_HEIGHT(psurf->height - 1));
+ OUT_RING(ring, 0x01000000 | // XXX
+ swiz |
+ A2XX_SQ_TEX_3_XY_MAG_FILTER(SQ_TEX_FILTER_POINT) |
+ A2XX_SQ_TEX_3_XY_MIN_FILTER(SQ_TEX_FILTER_POINT));
+ OUT_RING(ring, 0x00000000);
+ OUT_RING(ring, 0x00000200);
+
+ OUT_PKT3(ring, CP_SET_CONSTANT, 3);
+ OUT_RING(ring, CP_REG(REG_A2XX_VGT_MAX_VTX_INDX));
+ OUT_RING(ring, 3); /* VGT_MAX_VTX_INDX */
+ OUT_RING(ring, 0); /* VGT_MIN_VTX_INDX */
+
+ OUT_PKT3(ring, CP_DRAW_INDX, 3);
+ OUT_RING(ring, 0x00000000);
+ OUT_RING(ring, DRAW(DI_PT_RECTLIST, DI_SRC_SEL_AUTO_INDEX,
+ INDEX_SIZE_IGN, IGNORE_VISIBILITY));
+ OUT_RING(ring, 3); /* NumIndices */
+}
+
+static void
+fd2_emit_tile_mem2gmem(struct fd_context *ctx, uint32_t xoff, uint32_t yoff,
+ uint32_t bin_w, uint32_t bin_h)
+{
+ struct fd2_context *fd2_ctx = fd2_context(ctx);
+ struct fd_ringbuffer *ring = ctx->ring;
+ struct pipe_framebuffer_state *pfb = &ctx->framebuffer;
+ float x0, y0, x1, y1;
+
+ fd2_emit_vertex_bufs(ring, 0x9c, (struct fd2_vertex_buf[]) {
+ { .prsc = fd2_ctx->solid_vertexbuf, .size = 48, .offset = 0x30 },
+ { .prsc = fd2_ctx->solid_vertexbuf, .size = 32, .offset = 0x60 },
+ }, 2);
+
+ /* write texture coordinates to vertexbuf: */
+ x0 = ((float)xoff) / ((float)pfb->width);
+ x1 = ((float)xoff + bin_w) / ((float)pfb->width);
+ y0 = ((float)yoff) / ((float)pfb->height);
+ y1 = ((float)yoff + bin_h) / ((float)pfb->height);
+ OUT_PKT3(ring, CP_MEM_WRITE, 9);
+ OUT_RELOC(ring, fd_resource(fd2_ctx->solid_vertexbuf)->bo, 0x60, 0);
+ OUT_RING(ring, fui(x0));
+ OUT_RING(ring, fui(y0));
+ OUT_RING(ring, fui(x1));
+ OUT_RING(ring, fui(y0));
+ OUT_RING(ring, fui(x0));
+ OUT_RING(ring, fui(y1));
+ OUT_RING(ring, fui(x1));
+ OUT_RING(ring, fui(y1));
+
+ OUT_PKT3(ring, CP_SET_CONSTANT, 2);
+ OUT_RING(ring, CP_REG(REG_A2XX_VGT_INDX_OFFSET));
+ OUT_RING(ring, 0);
+
+ OUT_PKT3(ring, CP_SET_CONSTANT, 2);
+ OUT_RING(ring, CP_REG(REG_A2XX_VGT_VERTEX_REUSE_BLOCK_CNTL));
+ OUT_RING(ring, 0x0000003b);
+
+ fd2_program_emit(ring, &ctx->blit_prog);
+
+ OUT_PKT0(ring, REG_A2XX_TC_CNTL_STATUS, 1);
+ OUT_RING(ring, A2XX_TC_CNTL_STATUS_L2_INVALIDATE);
+
+ OUT_PKT3(ring, CP_SET_CONSTANT, 2);
+ OUT_RING(ring, CP_REG(REG_A2XX_RB_DEPTHCONTROL));
+ OUT_RING(ring, A2XX_RB_DEPTHCONTROL_EARLY_Z_ENABLE);
+
+ OUT_PKT3(ring, CP_SET_CONSTANT, 2);
+ OUT_RING(ring, CP_REG(REG_A2XX_PA_SU_SC_MODE_CNTL));
+ OUT_RING(ring, A2XX_PA_SU_SC_MODE_CNTL_PROVOKING_VTX_LAST |
+ A2XX_PA_SU_SC_MODE_CNTL_FRONT_PTYPE(PC_DRAW_TRIANGLES) |
+ A2XX_PA_SU_SC_MODE_CNTL_BACK_PTYPE(PC_DRAW_TRIANGLES));
+
+ OUT_PKT3(ring, CP_SET_CONSTANT, 2);
+ OUT_RING(ring, CP_REG(REG_A2XX_PA_SC_AA_MASK));
+ OUT_RING(ring, 0x0000ffff);
+
+ OUT_PKT3(ring, CP_SET_CONSTANT, 2);
+ OUT_RING(ring, CP_REG(REG_A2XX_RB_COLORCONTROL));
+ OUT_RING(ring, A2XX_RB_COLORCONTROL_ALPHA_FUNC(PIPE_FUNC_ALWAYS) |
+ A2XX_RB_COLORCONTROL_BLEND_DISABLE |
+ A2XX_RB_COLORCONTROL_ROP_CODE(12) |
+ A2XX_RB_COLORCONTROL_DITHER_MODE(DITHER_DISABLE) |
+ A2XX_RB_COLORCONTROL_DITHER_TYPE(DITHER_PIXEL));
+
+ OUT_PKT3(ring, CP_SET_CONSTANT, 2);
+ OUT_RING(ring, CP_REG(REG_A2XX_RB_BLEND_CONTROL));
+ OUT_RING(ring, A2XX_RB_BLEND_CONTROL_COLOR_SRCBLEND(FACTOR_ONE) |
+ A2XX_RB_BLEND_CONTROL_COLOR_COMB_FCN(BLEND_DST_PLUS_SRC) |
+ A2XX_RB_BLEND_CONTROL_COLOR_DESTBLEND(FACTOR_ZERO) |
+ A2XX_RB_BLEND_CONTROL_ALPHA_SRCBLEND(FACTOR_ONE) |
+ A2XX_RB_BLEND_CONTROL_ALPHA_COMB_FCN(BLEND_DST_PLUS_SRC) |
+ A2XX_RB_BLEND_CONTROL_ALPHA_DESTBLEND(FACTOR_ZERO));
+
+ OUT_PKT3(ring, CP_SET_CONSTANT, 3);
+ OUT_RING(ring, CP_REG(REG_A2XX_PA_SC_WINDOW_SCISSOR_TL));
+ OUT_RING(ring, A2XX_PA_SC_WINDOW_OFFSET_DISABLE |
+ xy2d(0,0)); /* PA_SC_WINDOW_SCISSOR_TL */
+ OUT_RING(ring, xy2d(bin_w, bin_h)); /* PA_SC_WINDOW_SCISSOR_BR */
+
+ OUT_PKT3(ring, CP_SET_CONSTANT, 5);
+ OUT_RING(ring, CP_REG(REG_A2XX_PA_CL_VPORT_XSCALE));
+ OUT_RING(ring, fui((float)bin_w/2.0)); /* PA_CL_VPORT_XSCALE */
+ OUT_RING(ring, fui((float)bin_w/2.0)); /* PA_CL_VPORT_XOFFSET */
+ OUT_RING(ring, fui(-(float)bin_h/2.0)); /* PA_CL_VPORT_YSCALE */
+ OUT_RING(ring, fui((float)bin_h/2.0)); /* PA_CL_VPORT_YOFFSET */
+
+ OUT_PKT3(ring, CP_SET_CONSTANT, 2);
+ OUT_RING(ring, CP_REG(REG_A2XX_PA_CL_VTE_CNTL));
+ OUT_RING(ring, A2XX_PA_CL_VTE_CNTL_VTX_XY_FMT |
+ A2XX_PA_CL_VTE_CNTL_VTX_Z_FMT | // XXX check this???
+ A2XX_PA_CL_VTE_CNTL_VPORT_X_SCALE_ENA |
+ A2XX_PA_CL_VTE_CNTL_VPORT_X_OFFSET_ENA |
+ A2XX_PA_CL_VTE_CNTL_VPORT_Y_SCALE_ENA |
+ A2XX_PA_CL_VTE_CNTL_VPORT_Y_OFFSET_ENA);
+
+ OUT_PKT3(ring, CP_SET_CONSTANT, 2);
+ OUT_RING(ring, CP_REG(REG_A2XX_PA_CL_CLIP_CNTL));
+ OUT_RING(ring, 0x00000000);
+
+ if (ctx->restore & (FD_BUFFER_DEPTH | FD_BUFFER_STENCIL))
+ emit_mem2gmem_surf(ring, bin_w * bin_h, pfb->zsbuf);
+
+ if (ctx->restore & FD_BUFFER_COLOR)
+ emit_mem2gmem_surf(ring, 0, pfb->cbufs[0]);
+
+ /* TODO blob driver seems to toss in a CACHE_FLUSH after each DRAW_INDX.. */
+}
+
+/* before first tile */
+static void
+fd2_emit_tile_init(struct fd_context *ctx)
+{
+ struct fd_ringbuffer *ring = ctx->ring;
+ struct pipe_framebuffer_state *pfb = &ctx->framebuffer;
+ struct fd_gmem_stateobj *gmem = &ctx->gmem;
+ enum pipe_format format = pfb->cbufs[0]->format;
+ uint32_t reg;
+
+ OUT_PKT3(ring, CP_SET_CONSTANT, 4);
+ OUT_RING(ring, CP_REG(REG_A2XX_RB_SURFACE_INFO));
+ OUT_RING(ring, gmem->bin_w); /* RB_SURFACE_INFO */
+ OUT_RING(ring, A2XX_RB_COLOR_INFO_SWAP(fmt2swap(format)) |
+ A2XX_RB_COLOR_INFO_FORMAT(fd2_pipe2color(format)));
+ reg = A2XX_RB_DEPTH_INFO_DEPTH_BASE(align(gmem->bin_w * gmem->bin_h, 4));
+ if (pfb->zsbuf)
+ reg |= A2XX_RB_DEPTH_INFO_DEPTH_FORMAT(fd_pipe2depth(pfb->zsbuf->format));
+ OUT_RING(ring, reg); /* RB_DEPTH_INFO */
+}
+
+/* before mem2gmem */
+static void
+fd2_emit_tile_prep(struct fd_context *ctx, uint32_t xoff, uint32_t yoff,
+ uint32_t bin_w, uint32_t bin_h)
+{
+ struct fd_ringbuffer *ring = ctx->ring;
+ struct pipe_framebuffer_state *pfb = &ctx->framebuffer;
+ enum pipe_format format = pfb->cbufs[0]->format;
+
+ OUT_PKT3(ring, CP_SET_CONSTANT, 2);
+ OUT_RING(ring, CP_REG(REG_A2XX_RB_COLOR_INFO));
+ OUT_RING(ring, A2XX_RB_COLOR_INFO_SWAP(1) | /* RB_COLOR_INFO */
+ A2XX_RB_COLOR_INFO_FORMAT(fd2_pipe2color(format)));
+
+ /* setup screen scissor for current tile (same for mem2gmem): */
+ OUT_PKT3(ring, CP_SET_CONSTANT, 3);
+ OUT_RING(ring, CP_REG(REG_A2XX_PA_SC_SCREEN_SCISSOR_TL));
+ OUT_RING(ring, xy2d(0,0)); /* PA_SC_SCREEN_SCISSOR_TL */
+ OUT_RING(ring, xy2d(bin_w, bin_h)); /* PA_SC_SCREEN_SCISSOR_BR */
+}
+
+/* before IB to rendering cmds: */
+static void
+fd2_emit_tile_renderprep(struct fd_context *ctx, uint32_t xoff, uint32_t yoff,
+ uint32_t bin_w, uint32_t bin_h)
+{
+ struct fd_ringbuffer *ring = ctx->ring;
+ struct pipe_framebuffer_state *pfb = &ctx->framebuffer;
+ enum pipe_format format = pfb->cbufs[0]->format;
+
+ OUT_PKT3(ring, CP_SET_CONSTANT, 2);
+ OUT_RING(ring, CP_REG(REG_A2XX_RB_COLOR_INFO));
+ OUT_RING(ring, A2XX_RB_COLOR_INFO_SWAP(fmt2swap(format)) |
+ A2XX_RB_COLOR_INFO_FORMAT(fd2_pipe2color(format)));
+
+ /* setup window scissor and offset for current tile (different
+ * from mem2gmem):
+ */
+ OUT_PKT3(ring, CP_SET_CONSTANT, 2);
+ OUT_RING(ring, CP_REG(REG_A2XX_PA_SC_WINDOW_OFFSET));
+ OUT_RING(ring, A2XX_PA_SC_WINDOW_OFFSET_X(-xoff) |
+ A2XX_PA_SC_WINDOW_OFFSET_Y(-yoff));
+}
+
+void
+fd2_gmem_init(struct pipe_context *pctx)
+{
+ struct fd_context *ctx = fd_context(pctx);
+
+ ctx->emit_tile_init = fd2_emit_tile_init;
+ ctx->emit_tile_prep = fd2_emit_tile_prep;
+ ctx->emit_tile_mem2gmem = fd2_emit_tile_mem2gmem;
+ ctx->emit_tile_renderprep = fd2_emit_tile_renderprep;
+ ctx->emit_tile_gmem2mem = fd2_emit_tile_gmem2mem;
+}
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 <robclark@freedesktop.org>
+ * Copyright (C) 2013 Rob Clark <robclark@freedesktop.org>
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -26,12 +26,11 @@
* Rob Clark <robclark@freedesktop.org>
*/
-#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 <robclark@freedesktop.org>
+ * Copyright (C) 2012-2013 Rob Clark <robclark@freedesktop.org>
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -26,8 +26,8 @@
* Rob Clark <robclark@freedesktop.org>
*/
-#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 <robclark@freedesktop.org>
+ * Copyright (C) 2012-2013 Rob Clark <robclark@freedesktop.org>
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -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 <robclark@freedesktop.org>
+ * Copyright (C) 2012-2013 Rob Clark <robclark@freedesktop.org>
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -26,13 +26,13 @@
* Rob Clark <robclark@freedesktop.org>
*/
-#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 <robclark@freedesktop.org>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Authors:
+ * Rob Clark <robclark@freedesktop.org>
+ */
+
+#include "pipe/p_screen.h"
+#include "util/u_format.h"
+
+#include "fd2_screen.h"
+#include "fd2_context.h"
+#include "fd2_util.h"
+
+static boolean
+fd2_screen_is_format_supported(struct pipe_screen *pscreen,
+ enum pipe_format format,
+ enum pipe_texture_target target,
+ unsigned sample_count,
+ unsigned usage)
+{
+ unsigned retval = 0;
+
+ if ((target >= PIPE_MAX_TEXTURE_TYPES) ||
+ (sample_count > 1) || /* TODO add MSAA */
+ !util_format_is_supported(format, usage)) {
+ DBG("not supported: format=%s, target=%d, sample_count=%d, usage=%x",
+ util_format_name(format), target, sample_count, usage);
+ return FALSE;
+ }
+
+ /* TODO figure out how to render to other formats.. */
+ if ((usage & PIPE_BIND_RENDER_TARGET) &&
+ ((format != PIPE_FORMAT_B8G8R8A8_UNORM) &&
+ (format != PIPE_FORMAT_B8G8R8X8_UNORM))) {
+ DBG("not supported render target: format=%s, target=%d, sample_count=%d, usage=%x",
+ util_format_name(format), target, sample_count, usage);
+ return FALSE;
+ }
+
+ if ((usage & (PIPE_BIND_SAMPLER_VIEW |
+ PIPE_BIND_VERTEX_BUFFER)) &&
+ (fd2_pipe2surface(format) != ~0)) {
+ retval |= usage & (PIPE_BIND_SAMPLER_VIEW |
+ PIPE_BIND_VERTEX_BUFFER);
+ }
+
+ if ((usage & (PIPE_BIND_RENDER_TARGET |
+ PIPE_BIND_DISPLAY_TARGET |
+ PIPE_BIND_SCANOUT |
+ PIPE_BIND_SHARED)) &&
+ (fd2_pipe2color(format) != ~0)) {
+ retval |= usage & (PIPE_BIND_RENDER_TARGET |
+ PIPE_BIND_DISPLAY_TARGET |
+ PIPE_BIND_SCANOUT |
+ PIPE_BIND_SHARED);
+ }
+
+ if ((usage & PIPE_BIND_DEPTH_STENCIL) &&
+ (fd_pipe2depth(format) != ~0)) {
+ retval |= PIPE_BIND_DEPTH_STENCIL;
+ }
+
+ if ((usage & PIPE_BIND_INDEX_BUFFER) &&
+ (fd_pipe2index(format) != ~0)) {
+ retval |= PIPE_BIND_INDEX_BUFFER;
+ }
+
+ if (usage & PIPE_BIND_TRANSFER_READ)
+ retval |= PIPE_BIND_TRANSFER_READ;
+ if (usage & PIPE_BIND_TRANSFER_WRITE)
+ retval |= PIPE_BIND_TRANSFER_WRITE;
+
+ if (retval != usage) {
+ DBG("not supported: format=%s, target=%d, sample_count=%d, "
+ "usage=%x, retval=%x", util_format_name(format),
+ target, sample_count, usage, retval);
+ }
+
+ return retval == usage;
+}
+
+void
+fd2_screen_init(struct pipe_screen *pscreen)
+{
+ pscreen->context_create = fd2_context_create;
+ pscreen->is_format_supported = fd2_screen_is_format_supported;
+}
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 <robclark@freedesktop.org>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Authors:
+ * Rob Clark <robclark@freedesktop.org>
+ */
+
+#ifndef FD2_SCREEN_H_
+#define FD2_SCREEN_H_
+
+#include "pipe/p_screen.h"
+
+void fd2_screen_init(struct pipe_screen *pscreen);
+
+#endif /* FD2_SCREEN_H_ */
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 <robclark@freedesktop.org>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Authors:
+ * Rob Clark <robclark@freedesktop.org>
+ */
+
+#include "pipe/p_state.h"
+#include "util/u_string.h"
+#include "util/u_memory.h"
+#include "util/u_inlines.h"
+
+#include "fd2_texture.h"
+#include "fd2_util.h"
+
+static enum sq_tex_clamp
+tex_clamp(unsigned wrap)
+{
+ switch (wrap) {
+ case PIPE_TEX_WRAP_REPEAT:
+ return SQ_TEX_WRAP;
+ case PIPE_TEX_WRAP_CLAMP:
+ return SQ_TEX_CLAMP_HALF_BORDER;
+ case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
+ return SQ_TEX_CLAMP_LAST_TEXEL;
+ case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
+ return SQ_TEX_CLAMP_BORDER;
+ case PIPE_TEX_WRAP_MIRROR_REPEAT:
+ return SQ_TEX_MIRROR;
+ case PIPE_TEX_WRAP_MIRROR_CLAMP:
+ return SQ_TEX_MIRROR_ONCE_HALF_BORDER;
+ case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE:
+ return SQ_TEX_MIRROR_ONCE_LAST_TEXEL;
+ case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER:
+ return SQ_TEX_MIRROR_ONCE_BORDER;
+ default:
+ DBG("invalid wrap: %u", wrap);
+ return 0;
+ }
+}
+
+static enum sq_tex_filter
+tex_filter(unsigned filter)
+{
+ switch (filter) {
+ case PIPE_TEX_FILTER_NEAREST:
+ return SQ_TEX_FILTER_POINT;
+ case PIPE_TEX_FILTER_LINEAR:
+ return SQ_TEX_FILTER_BILINEAR;
+ default:
+ DBG("invalid filter: %u", filter);
+ return 0;
+ }
+}
+
+static void *
+fd2_sampler_state_create(struct pipe_context *pctx,
+ const struct pipe_sampler_state *cso)
+{
+ struct fd2_sampler_stateobj *so = CALLOC_STRUCT(fd2_sampler_stateobj);
+
+ if (!so)
+ return NULL;
+
+ so->base = *cso;
+
+ /* SQ_TEX0_PITCH() must be OR'd in later when we know the bound texture: */
+ so->tex0 =
+ A2XX_SQ_TEX_0_CLAMP_X(tex_clamp(cso->wrap_s)) |
+ A2XX_SQ_TEX_0_CLAMP_Y(tex_clamp(cso->wrap_t)) |
+ A2XX_SQ_TEX_0_CLAMP_Z(tex_clamp(cso->wrap_r));
+
+ so->tex3 =
+ A2XX_SQ_TEX_3_XY_MAG_FILTER(tex_filter(cso->mag_img_filter)) |
+ A2XX_SQ_TEX_3_XY_MIN_FILTER(tex_filter(cso->min_img_filter));
+
+ so->tex4 = 0x00000000; /* ??? */
+ so->tex5 = 0x00000200; /* ??? */
+
+ return so;
+}
+
+static struct pipe_sampler_view *
+fd2_sampler_view_create(struct pipe_context *pctx, struct pipe_resource *prsc,
+ const struct pipe_sampler_view *cso)
+{
+ struct fd2_pipe_sampler_view *so = CALLOC_STRUCT(fd2_pipe_sampler_view);
+ struct fd_resource *rsc = fd_resource(prsc);
+
+ if (!so)
+ return NULL;
+
+ so->base = *cso;
+ pipe_reference(NULL, &prsc->reference);
+ so->base.texture = prsc;
+ so->base.reference.count = 1;
+ so->base.context = pctx;
+
+ so->tex_resource = rsc;
+ so->fmt = fd2_pipe2surface(cso->format);
+
+ so->tex0 = A2XX_SQ_TEX_0_PITCH(rsc->pitch);
+ so->tex2 =
+ A2XX_SQ_TEX_2_HEIGHT(prsc->height0 - 1) |
+ A2XX_SQ_TEX_2_WIDTH(prsc->width0 - 1);
+ so->tex3 = fd2_tex_swiz(cso->format, cso->swizzle_r, cso->swizzle_g,
+ cso->swizzle_b, cso->swizzle_a);
+
+ return &so->base;
+}
+
+/* map gallium sampler-id to hw const-idx.. adreno uses a flat address
+ * space of samplers (const-idx), so we need to map the gallium sampler-id
+ * which is per-shader to a global const-idx space.
+ *
+ * Fragment shader sampler maps directly to const-idx, and vertex shader
+ * is offset by the # of fragment shader samplers. If the # of fragment
+ * shader samplers changes, this shifts the vertex shader indexes.
+ *
+ * TODO maybe we can do frag shader 0..N and vert shader N..0 to avoid
+ * this??
+ */
+unsigned
+fd2_get_const_idx(struct fd_context *ctx, struct fd_texture_stateobj *tex,
+ unsigned samp_id)
+{
+ if (tex == &ctx->fragtex)
+ return samp_id;
+ return samp_id + ctx->fragtex.num_samplers;
+}
+
+void
+fd2_texture_init(struct pipe_context *pctx)
+{
+ pctx->create_sampler_state = fd2_sampler_state_create;
+ pctx->create_sampler_view = fd2_sampler_view_create;
+}
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 <robclark@freedesktop.org>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Authors:
+ * Rob Clark <robclark@freedesktop.org>
+ */
+
+#ifndef FD2_TEXTURE_H_
+#define FD2_TEXTURE_H_
+
+#include "pipe/p_context.h"
+
+#include "freedreno_texture.h"
+#include "freedreno_resource.h"
+
+#include "fd2_context.h"
+#include "fd2_util.h"
+
+struct fd2_sampler_stateobj {
+ struct pipe_sampler_state base;
+ uint32_t tex0, tex3, tex4, tex5;
+};
+
+static INLINE struct fd2_sampler_stateobj *
+fd2_sampler_stateobj(struct pipe_sampler_state *samp)
+{
+ return (struct fd2_sampler_stateobj *)samp;
+}
+
+struct fd2_pipe_sampler_view {
+ struct pipe_sampler_view base;
+ struct fd_resource *tex_resource;
+ enum a2xx_sq_surfaceformat fmt;
+ uint32_t tex0, tex2, tex3;
+};
+
+static INLINE struct fd2_pipe_sampler_view *
+fd2_pipe_sampler_view(struct pipe_sampler_view *pview)
+{
+ return (struct fd2_pipe_sampler_view *)pview;
+}
+
+unsigned fd2_get_const_idx(struct fd_context *ctx,
+ struct fd_texture_stateobj *tex, unsigned samp_id);
+
+void fd2_texture_init(struct pipe_context *pctx);
+
+#endif /* FD2_TEXTURE_H_ */
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 <robclark@freedesktop.org>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Authors:
+ * Rob Clark <robclark@freedesktop.org>
+ */
+
+#include "pipe/p_defines.h"
+#include "util/u_format.h"
+
+#include "fd2_util.h"
+
+enum a2xx_sq_surfaceformat
+fd2_pipe2surface(enum pipe_format format)
+{
+ switch (format) {
+ /* 8-bit buffers. */
+ case PIPE_FORMAT_A8_UNORM:
+ case PIPE_FORMAT_A8_SNORM:
+ case PIPE_FORMAT_A8_UINT:
+ case PIPE_FORMAT_A8_SINT:
+ case PIPE_FORMAT_I8_UNORM:
+ case PIPE_FORMAT_I8_SNORM:
+ case PIPE_FORMAT_I8_UINT:
+ case PIPE_FORMAT_I8_SINT:
+ case PIPE_FORMAT_L8_UNORM:
+ case PIPE_FORMAT_L8_SNORM:
+ case PIPE_FORMAT_L8_UINT:
+ case PIPE_FORMAT_L8_SINT:
+ case PIPE_FORMAT_L8_SRGB:
+ case PIPE_FORMAT_R8_UNORM:
+ case PIPE_FORMAT_R8_SNORM:
+ case PIPE_FORMAT_R8_UINT:
+ case PIPE_FORMAT_R8_SINT:
+ return FMT_8;
+
+ /* 16-bit buffers. */
+ case PIPE_FORMAT_B5G6R5_UNORM:
+ return FMT_5_6_5;
+ case PIPE_FORMAT_B5G5R5A1_UNORM:
+ case PIPE_FORMAT_B5G5R5X1_UNORM:
+ return FMT_1_5_5_5;
+ case PIPE_FORMAT_B4G4R4A4_UNORM:
+ case PIPE_FORMAT_B4G4R4X4_UNORM:
+ return FMT_4_4_4_4;
+ case PIPE_FORMAT_Z16_UNORM:
+ return FMT_16;
+ case PIPE_FORMAT_L8A8_UNORM:
+ case PIPE_FORMAT_L8A8_SNORM:
+ case PIPE_FORMAT_L8A8_UINT:
+ case PIPE_FORMAT_L8A8_SINT:
+ case PIPE_FORMAT_L8A8_SRGB:
+ case PIPE_FORMAT_R8G8_UNORM:
+ case PIPE_FORMAT_R8G8_SNORM:
+ case PIPE_FORMAT_R8G8_UINT:
+ case PIPE_FORMAT_R8G8_SINT:
+ return FMT_8_8;
+ case PIPE_FORMAT_R16_UNORM:
+ case PIPE_FORMAT_R16_SNORM:
+ case PIPE_FORMAT_R16_UINT:
+ case PIPE_FORMAT_R16_SINT:
+ case PIPE_FORMAT_A16_UNORM:
+ case PIPE_FORMAT_A16_SNORM:
+ case PIPE_FORMAT_A16_UINT:
+ case PIPE_FORMAT_A16_SINT:
+ case PIPE_FORMAT_L16_UNORM:
+ case PIPE_FORMAT_L16_SNORM:
+ case PIPE_FORMAT_L16_UINT:
+ case PIPE_FORMAT_L16_SINT:
+ case PIPE_FORMAT_I16_UNORM:
+ case PIPE_FORMAT_I16_SNORM:
+ case PIPE_FORMAT_I16_UINT:
+ case PIPE_FORMAT_I16_SINT:
+ return FMT_16;
+ case PIPE_FORMAT_R16_FLOAT:
+ case PIPE_FORMAT_A16_FLOAT:
+ case PIPE_FORMAT_L16_FLOAT:
+ case PIPE_FORMAT_I16_FLOAT:
+ return FMT_16_FLOAT;
+
+ /* 32-bit buffers. */
+ case PIPE_FORMAT_A8B8G8R8_SRGB:
+ case PIPE_FORMAT_A8B8G8R8_UNORM:
+ case PIPE_FORMAT_A8R8G8B8_UNORM:
+ case PIPE_FORMAT_B8G8R8A8_SRGB:
+ case PIPE_FORMAT_B8G8R8A8_UNORM:
+ case PIPE_FORMAT_B8G8R8X8_UNORM:
+ case PIPE_FORMAT_R8G8B8A8_SNORM:
+ case PIPE_FORMAT_R8G8B8A8_UNORM:
+ case PIPE_FORMAT_R8G8B8X8_UNORM:
+ case PIPE_FORMAT_R8SG8SB8UX8U_NORM:
+ case PIPE_FORMAT_X8B8G8R8_UNORM:
+ case PIPE_FORMAT_X8R8G8B8_UNORM:
+ case PIPE_FORMAT_R8G8B8_UNORM:
+ case PIPE_FORMAT_R8G8B8A8_SINT:
+ case PIPE_FORMAT_R8G8B8A8_UINT:
+ return FMT_8_8_8_8;
+ case PIPE_FORMAT_R10G10B10A2_UNORM:
+ case PIPE_FORMAT_R10G10B10X2_SNORM:
+ case PIPE_FORMAT_B10G10R10A2_UNORM:
+ case PIPE_FORMAT_B10G10R10A2_UINT:
+ case PIPE_FORMAT_R10SG10SB10SA2U_NORM:
+ return FMT_2_10_10_10;
+ case PIPE_FORMAT_Z24X8_UNORM:
+ case PIPE_FORMAT_Z24_UNORM_S8_UINT:
+ return FMT_24_8;
+ case PIPE_FORMAT_R32_UINT:
+ case PIPE_FORMAT_R32_SINT:
+ case PIPE_FORMAT_A32_UINT:
+ case PIPE_FORMAT_A32_SINT:
+ case PIPE_FORMAT_L32_UINT:
+ case PIPE_FORMAT_L32_SINT:
+ case PIPE_FORMAT_I32_UINT:
+ case PIPE_FORMAT_I32_SINT:
+ return FMT_32;
+ case PIPE_FORMAT_R32_FLOAT:
+ case PIPE_FORMAT_A32_FLOAT:
+ case PIPE_FORMAT_L32_FLOAT:
+ case PIPE_FORMAT_I32_FLOAT:
+ case PIPE_FORMAT_Z32_FLOAT:
+ return FMT_32_FLOAT;
+ case PIPE_FORMAT_R16G16_FLOAT:
+ case PIPE_FORMAT_L16A16_FLOAT:
+ return FMT_16_16_FLOAT;
+ case PIPE_FORMAT_R16G16_UNORM:
+ case PIPE_FORMAT_R16G16_SNORM:
+ case PIPE_FORMAT_R16G16_UINT:
+ case PIPE_FORMAT_R16G16_SINT:
+ case PIPE_FORMAT_L16A16_UNORM:
+ case PIPE_FORMAT_L16A16_SNORM:
+ case PIPE_FORMAT_L16A16_UINT:
+ case PIPE_FORMAT_L16A16_SINT:
+ return FMT_16_16;
+
+ /* 64-bit buffers. */
+ case PIPE_FORMAT_R16G16B16A16_UINT:
+ case PIPE_FORMAT_R16G16B16A16_SINT:
+ case PIPE_FORMAT_R16G16B16A16_UNORM:
+ case PIPE_FORMAT_R16G16B16A16_SNORM:
+ return FMT_16_16_16_16;
+ case PIPE_FORMAT_R16G16B16A16_FLOAT:
+ return FMT_16_16_16_16_FLOAT;
+ case PIPE_FORMAT_R32G32_FLOAT:
+ case PIPE_FORMAT_L32A32_FLOAT:
+ return FMT_32_32_FLOAT;
+ case PIPE_FORMAT_R32G32_SINT:
+ case PIPE_FORMAT_R32G32_UINT:
+ case PIPE_FORMAT_L32A32_UINT:
+ case PIPE_FORMAT_L32A32_SINT:
+ return FMT_32_32;
+
+ /* 96-bit buffers. */
+ case PIPE_FORMAT_R32G32B32_FLOAT:
+ return FMT_32_32_32_FLOAT;
+
+ /* 128-bit buffers. */
+ case PIPE_FORMAT_R32G32B32A32_SNORM:
+ case PIPE_FORMAT_R32G32B32A32_UNORM:
+ case PIPE_FORMAT_R32G32B32A32_SINT:
+ case PIPE_FORMAT_R32G32B32A32_UINT:
+ return FMT_32_32_32_32;
+ case PIPE_FORMAT_R32G32B32A32_FLOAT:
+ return FMT_32_32_32_32_FLOAT;
+
+ /* YUV buffers. */
+ case PIPE_FORMAT_UYVY:
+ return FMT_Cr_Y1_Cb_Y0;
+ case PIPE_FORMAT_YUYV:
+ return FMT_Y1_Cr_Y0_Cb;
+
+ default:
+ return ~0;
+ }
+}
+
+enum a2xx_colorformatx
+fd2_pipe2color(enum pipe_format format)
+{
+ switch (format) {
+ /* 8-bit buffers. */
+ case PIPE_FORMAT_A8_UNORM:
+ case PIPE_FORMAT_A8_SNORM:
+ case PIPE_FORMAT_A8_UINT:
+ case PIPE_FORMAT_A8_SINT:
+ case PIPE_FORMAT_I8_UNORM:
+ case PIPE_FORMAT_I8_SNORM:
+ case PIPE_FORMAT_I8_UINT:
+ case PIPE_FORMAT_I8_SINT:
+ case PIPE_FORMAT_L8_UNORM:
+ case PIPE_FORMAT_L8_SNORM:
+ case PIPE_FORMAT_L8_UINT:
+ case PIPE_FORMAT_L8_SINT:
+ case PIPE_FORMAT_L8_SRGB:
+ case PIPE_FORMAT_R8_UNORM:
+ case PIPE_FORMAT_R8_SNORM:
+ case PIPE_FORMAT_R8_UINT:
+ case PIPE_FORMAT_R8_SINT:
+ return COLORX_8;
+
+ /* 16-bit buffers. */
+ case PIPE_FORMAT_B5G6R5_UNORM:
+ return COLORX_5_6_5;
+ case PIPE_FORMAT_B5G5R5A1_UNORM:
+ case PIPE_FORMAT_B5G5R5X1_UNORM:
+ return COLORX_1_5_5_5;
+ case PIPE_FORMAT_B4G4R4A4_UNORM:
+ case PIPE_FORMAT_B4G4R4X4_UNORM:
+ return COLORX_4_4_4_4;
+ case PIPE_FORMAT_L8A8_UNORM:
+ case PIPE_FORMAT_L8A8_SNORM:
+ case PIPE_FORMAT_L8A8_UINT:
+ case PIPE_FORMAT_L8A8_SINT:
+ case PIPE_FORMAT_L8A8_SRGB:
+ case PIPE_FORMAT_R8G8_UNORM:
+ case PIPE_FORMAT_R8G8_SNORM:
+ case PIPE_FORMAT_R8G8_UINT:
+ case PIPE_FORMAT_R8G8_SINT:
+ case PIPE_FORMAT_Z16_UNORM:
+ return COLORX_8_8;
+ case PIPE_FORMAT_R16_FLOAT:
+ case PIPE_FORMAT_A16_FLOAT:
+ case PIPE_FORMAT_L16_FLOAT:
+ case PIPE_FORMAT_I16_FLOAT:
+ return COLORX_16_FLOAT;
+
+ /* 32-bit buffers. */
+ case PIPE_FORMAT_A8B8G8R8_SRGB:
+ case PIPE_FORMAT_A8B8G8R8_UNORM:
+ case PIPE_FORMAT_A8R8G8B8_UNORM:
+ case PIPE_FORMAT_B8G8R8A8_SRGB:
+ case PIPE_FORMAT_B8G8R8A8_UNORM:
+ case PIPE_FORMAT_B8G8R8X8_UNORM:
+ case PIPE_FORMAT_R8G8B8A8_SNORM:
+ case PIPE_FORMAT_R8G8B8A8_UNORM:
+ case PIPE_FORMAT_R8G8B8X8_UNORM:
+ case PIPE_FORMAT_R8SG8SB8UX8U_NORM:
+ case PIPE_FORMAT_X8B8G8R8_UNORM:
+ case PIPE_FORMAT_X8R8G8B8_UNORM:
+ case PIPE_FORMAT_R8G8B8_UNORM:
+ case PIPE_FORMAT_R8G8B8A8_SINT:
+ case PIPE_FORMAT_R8G8B8A8_UINT:
+ case PIPE_FORMAT_Z24_UNORM_S8_UINT:
+ case PIPE_FORMAT_Z24X8_UNORM:
+ return COLORX_8_8_8_8;
+ case PIPE_FORMAT_R32_FLOAT:
+ case PIPE_FORMAT_A32_FLOAT:
+ case PIPE_FORMAT_L32_FLOAT:
+ case PIPE_FORMAT_I32_FLOAT:
+ case PIPE_FORMAT_Z32_FLOAT:
+ return COLORX_32_FLOAT;
+ case PIPE_FORMAT_R16G16_FLOAT:
+ case PIPE_FORMAT_L16A16_FLOAT:
+ return COLORX_16_16_FLOAT;
+
+ /* 64-bit buffers. */
+ case PIPE_FORMAT_R16G16B16A16_FLOAT:
+ return COLORX_16_16_16_16_FLOAT;
+ case PIPE_FORMAT_R32G32_FLOAT:
+ case PIPE_FORMAT_L32A32_FLOAT:
+ return COLORX_32_32_FLOAT;
+
+ /* 128-bit buffers. */
+ case PIPE_FORMAT_R32G32B32A32_FLOAT:
+ return COLORX_32_32_32_32_FLOAT;
+
+ default:
+ return ~0;
+ }
+}
+
+static inline enum sq_tex_swiz
+tex_swiz(unsigned swiz)
+{
+ switch (swiz) {
+ default:
+ case PIPE_SWIZZLE_RED: return SQ_TEX_X;
+ case PIPE_SWIZZLE_GREEN: return SQ_TEX_Y;
+ case PIPE_SWIZZLE_BLUE: return SQ_TEX_Z;
+ case PIPE_SWIZZLE_ALPHA: return SQ_TEX_W;
+ case PIPE_SWIZZLE_ZERO: return SQ_TEX_ZERO;
+ case PIPE_SWIZZLE_ONE: return SQ_TEX_ONE;
+ }
+}
+
+uint32_t
+fd2_tex_swiz(enum pipe_format format, unsigned swizzle_r, unsigned swizzle_g,
+ unsigned swizzle_b, unsigned swizzle_a)
+{
+ const struct util_format_description *desc =
+ util_format_description(format);
+ uint8_t swiz[] = {
+ swizzle_r, swizzle_g, swizzle_b, swizzle_a,
+ PIPE_SWIZZLE_ZERO, PIPE_SWIZZLE_ONE,
+ PIPE_SWIZZLE_ONE, PIPE_SWIZZLE_ONE,
+ };
+
+ return A2XX_SQ_TEX_3_SWIZ_X(tex_swiz(swiz[desc->swizzle[0]])) |
+ A2XX_SQ_TEX_3_SWIZ_Y(tex_swiz(swiz[desc->swizzle[1]])) |
+ A2XX_SQ_TEX_3_SWIZ_Z(tex_swiz(swiz[desc->swizzle[2]])) |
+ A2XX_SQ_TEX_3_SWIZ_W(tex_swiz(swiz[desc->swizzle[3]]));
+}
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 <robclark@freedesktop.org>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Authors:
+ * Rob Clark <robclark@freedesktop.org>
+ */
+
+#ifndef FD2_UTIL_H_
+#define FD2_UTIL_H_
+
+#include "freedreno_util.h"
+
+#include "a2xx.xml.h"
+
+enum a2xx_sq_surfaceformat fd2_pipe2surface(enum pipe_format format);
+enum a2xx_colorformatx fd2_pipe2color(enum pipe_format format);
+uint32_t fd2_tex_swiz(enum pipe_format format, unsigned swizzle_r,
+ unsigned swizzle_g, unsigned swizzle_b, unsigned swizzle_a);
+
+/* convert x,y to dword */
+static inline uint32_t xy2d(uint16_t x, uint16_t y)
+{
+ return ((y & 0x3fff) << 16) | (x & 0x3fff);
+}
+
+#endif /* FD2_UTIL_H_ */
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 <robclark@freedesktop.org>
+ * Copyright (C) 2012-2013 Rob Clark <robclark@freedesktop.org>
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -26,8 +26,8 @@
* Rob Clark <robclark@freedesktop.org>
*/
-#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 <robdclark@gmail.com> (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 <robdclark@gmail.com> (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 <robclark@freedesktop.org>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Authors:
- * Rob Clark <robclark@freedesktop.org>
- */
-
-#include "pipe/p_state.h"
-#include "util/u_string.h"
-#include "util/u_memory.h"
-
-#include "freedreno_blend.h"
-#include "freedreno_context.h"
-#include "freedreno_util.h"
-
-static enum adreno_rb_blend_factor
-blend_factor(unsigned factor)
-{
- switch (factor) {
- case PIPE_BLENDFACTOR_ONE:
- return FACTOR_ONE;
- case PIPE_BLENDFACTOR_SRC_COLOR:
- return FACTOR_SRC_COLOR;
- case PIPE_BLENDFACTOR_SRC_ALPHA:
- return FACTOR_SRC_ALPHA;
- case PIPE_BLENDFACTOR_DST_ALPHA:
- return FACTOR_DST_ALPHA;
- case PIPE_BLENDFACTOR_DST_COLOR:
- return FACTOR_DST_COLOR;
- case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE:
- return FACTOR_SRC_ALPHA_SATURATE;
- case PIPE_BLENDFACTOR_CONST_COLOR:
- return FACTOR_CONSTANT_COLOR;
- case PIPE_BLENDFACTOR_CONST_ALPHA:
- return FACTOR_CONSTANT_ALPHA;
- case PIPE_BLENDFACTOR_ZERO:
- case 0:
- return FACTOR_ZERO;
- case PIPE_BLENDFACTOR_INV_SRC_COLOR:
- return FACTOR_ONE_MINUS_SRC_COLOR;
- case PIPE_BLENDFACTOR_INV_SRC_ALPHA:
- return FACTOR_ONE_MINUS_SRC_ALPHA;
- case PIPE_BLENDFACTOR_INV_DST_ALPHA:
- return FACTOR_ONE_MINUS_DST_ALPHA;
- case PIPE_BLENDFACTOR_INV_DST_COLOR:
- return FACTOR_ONE_MINUS_DST_COLOR;
- case PIPE_BLENDFACTOR_INV_CONST_COLOR:
- return FACTOR_ONE_MINUS_CONSTANT_COLOR;
- case PIPE_BLENDFACTOR_INV_CONST_ALPHA:
- return FACTOR_ONE_MINUS_CONSTANT_ALPHA;
- case PIPE_BLENDFACTOR_INV_SRC1_COLOR:
- case PIPE_BLENDFACTOR_INV_SRC1_ALPHA:
- case PIPE_BLENDFACTOR_SRC1_COLOR:
- case PIPE_BLENDFACTOR_SRC1_ALPHA:
- /* I don't think these are supported */
- default:
- DBG("invalid blend factor: %x", factor);
- return 0;
- }
-}
-
-static enum adreno_rb_blend_opcode
-blend_func(unsigned func)
-{
- switch (func) {
- case PIPE_BLEND_ADD:
- return BLEND_DST_PLUS_SRC;
- case PIPE_BLEND_MIN:
- return BLEND_MIN_DST_SRC;
- case PIPE_BLEND_MAX:
- return BLEND_MAX_DST_SRC;
- case PIPE_BLEND_SUBTRACT:
- return BLEND_SRC_MINUS_DST;
- case PIPE_BLEND_REVERSE_SUBTRACT:
- return BLEND_DST_MINUS_SRC;
- default:
- DBG("invalid blend func: %x", func);
- return 0;
- }
-}
-
-static void *
-fd_blend_state_create(struct pipe_context *pctx,
- const struct pipe_blend_state *cso)
-{
- const struct pipe_rt_blend_state *rt = &cso->rt[0];
- struct fd_blend_stateobj *so;
-
- if (cso->logicop_enable) {
- DBG("Unsupported! logicop");
- return NULL;
- }
-
- if (cso->independent_blend_enable) {
- DBG("Unsupported! independent blend state");
- return NULL;
- }
-
- so = CALLOC_STRUCT(fd_blend_stateobj);
- if (!so)
- return NULL;
-
- so->base = *cso;
-
- so->rb_colorcontrol = A2XX_RB_COLORCONTROL_ROP_CODE(12);
-
- so->rb_blendcontrol =
- A2XX_RB_BLEND_CONTROL_COLOR_SRCBLEND(blend_factor(rt->rgb_src_factor)) |
- A2XX_RB_BLEND_CONTROL_COLOR_COMB_FCN(blend_func(rt->rgb_func)) |
- A2XX_RB_BLEND_CONTROL_COLOR_DESTBLEND(blend_factor(rt->rgb_dst_factor)) |
- A2XX_RB_BLEND_CONTROL_ALPHA_SRCBLEND(blend_factor(rt->alpha_src_factor)) |
- A2XX_RB_BLEND_CONTROL_ALPHA_COMB_FCN(blend_func(rt->alpha_func)) |
- A2XX_RB_BLEND_CONTROL_ALPHA_DESTBLEND(blend_factor(rt->alpha_dst_factor));
-
- if (rt->colormask & PIPE_MASK_R)
- so->rb_colormask |= A2XX_RB_COLOR_MASK_WRITE_RED;
- if (rt->colormask & PIPE_MASK_G)
- so->rb_colormask |= A2XX_RB_COLOR_MASK_WRITE_GREEN;
- if (rt->colormask & PIPE_MASK_B)
- so->rb_colormask |= A2XX_RB_COLOR_MASK_WRITE_BLUE;
- if (rt->colormask & PIPE_MASK_A)
- so->rb_colormask |= A2XX_RB_COLOR_MASK_WRITE_ALPHA;
-
- if (!rt->blend_enable)
- so->rb_colorcontrol |= A2XX_RB_COLORCONTROL_BLEND_DISABLE;
-
- if (cso->dither)
- so->rb_colorcontrol |= A2XX_RB_COLORCONTROL_DITHER_MODE(DITHER_ALWAYS);
-
- return so;
-}
-
-static void
-fd_blend_state_bind(struct pipe_context *pctx, void *hwcso)
-{
- struct fd_context *ctx = fd_context(pctx);
- ctx->blend = hwcso;
- ctx->dirty |= FD_DIRTY_BLEND;
-}
-
-static void
-fd_blend_state_delete(struct pipe_context *pctx, void *hwcso)
-{
- FREE(hwcso);
-}
-
-void
-fd_blend_init(struct pipe_context *pctx)
-{
- pctx->create_blend_state = fd_blend_state_create;
- pctx->bind_blend_state = fd_blend_state_bind;
- pctx->delete_blend_state = fd_blend_state_delete;
-}
-
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 <robclark@freedesktop.org>
*/
-#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, &timestamp);
+ 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) {