etnaviv: gallium driver for Vivante GPUs
This driver supports a wide range of Vivante IP cores like GC880, GC1000, GC2000 and GC3000. Changes from V1 -> V2: - added missing files to actually integrate the driver into build system. - adapted driver to new renderonly API Signed-off-by: Christian Gmeiner <christian.gmeiner@gmail.com> Signed-off-by: Lucas Stach <l.stach@pengutronix.de> Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de> Signed-off-by: Rob Herring <robh@kernel.org> Signed-off-by: Russell King <rmk@arm.linux.org.uk> Signed-off-by: Wladimir J. van der Laan <laanwj@gmail.com> Acked-by: Emil Velikov <emil.velikov@collabora.com>
This commit is contained in:
parent
848b49b288
commit
c9e8b49b88
11
configure.ac
11
configure.ac
|
@ -76,6 +76,7 @@ LIBDRM_NVVIEUX_REQUIRED=2.4.66
|
|||
LIBDRM_NOUVEAU_REQUIRED=2.4.66
|
||||
LIBDRM_FREEDRENO_REQUIRED=2.4.74
|
||||
LIBDRM_VC4_REQUIRED=2.4.69
|
||||
LIBDRM_ETNAVIV_REQUIRED=2.4.74
|
||||
DRI2PROTO_REQUIRED=2.6
|
||||
DRI3PROTO_REQUIRED=1.0
|
||||
PRESENTPROTO_REQUIRED=1.0
|
||||
|
@ -1233,7 +1234,7 @@ GALLIUM_DRIVERS_DEFAULT="r300,r600,svga,swrast"
|
|||
AC_ARG_WITH([gallium-drivers],
|
||||
[AS_HELP_STRING([--with-gallium-drivers@<:@=DIRS...@:>@],
|
||||
[comma delimited Gallium drivers list, e.g.
|
||||
"i915,ilo,nouveau,r300,r600,radeonsi,freedreno,svga,swrast,vc4,virgl"
|
||||
"i915,ilo,nouveau,r300,r600,radeonsi,freedreno,svga,swrast,vc4,virgl,etnaviv"
|
||||
@<:@default=r300,r600,svga,swrast@:>@])],
|
||||
[with_gallium_drivers="$withval"],
|
||||
[with_gallium_drivers="$GALLIUM_DRIVERS_DEFAULT"])
|
||||
|
@ -2506,6 +2507,11 @@ if test -n "$with_gallium_drivers"; then
|
|||
PKG_CHECK_MODULES([FREEDRENO], [libdrm_freedreno >= $LIBDRM_FREEDRENO_REQUIRED])
|
||||
require_libdrm "freedreno"
|
||||
;;
|
||||
xetnaviv)
|
||||
HAVE_GALLIUM_ETNAVIV=yes
|
||||
PKG_CHECK_MODULES([ETNAVIV], [libdrm_etnaviv >= $LIBDRM_ETNAVIV_REQUIRED])
|
||||
require_libdrm "etnaviv"
|
||||
;;
|
||||
xswrast)
|
||||
HAVE_GALLIUM_SOFTPIPE=yes
|
||||
if test "x$MESA_LLVM" = x1 && test "x$enable_gallium_llvm" == "xyes"; then
|
||||
|
@ -2624,6 +2630,7 @@ AM_CONDITIONAL(HAVE_GALLIUM_RADEON_COMMON, test "x$HAVE_GALLIUM_R600" = xyes -o
|
|||
"x$HAVE_GALLIUM_RADEONSI" = xyes)
|
||||
AM_CONDITIONAL(HAVE_GALLIUM_NOUVEAU, test "x$HAVE_GALLIUM_NOUVEAU" = xyes)
|
||||
AM_CONDITIONAL(HAVE_GALLIUM_FREEDRENO, test "x$HAVE_GALLIUM_FREEDRENO" = xyes)
|
||||
AM_CONDITIONAL(HAVE_GALLIUM_ETNAVIV, test "x$HAVE_GALLIUM_ETNAVIV" = xyes)
|
||||
AM_CONDITIONAL(HAVE_GALLIUM_SOFTPIPE, test "x$HAVE_GALLIUM_SOFTPIPE" = xyes)
|
||||
AM_CONDITIONAL(HAVE_GALLIUM_LLVMPIPE, test "x$HAVE_GALLIUM_LLVMPIPE" = xyes)
|
||||
AM_CONDITIONAL(HAVE_GALLIUM_SWR, test "x$HAVE_GALLIUM_SWR" = xyes)
|
||||
|
@ -2777,6 +2784,7 @@ AC_CONFIG_FILES([Makefile
|
|||
src/gallium/drivers/svga/Makefile
|
||||
src/gallium/drivers/swr/Makefile
|
||||
src/gallium/drivers/trace/Makefile
|
||||
src/gallium/drivers/etnaviv/Makefile
|
||||
src/gallium/drivers/vc4/Makefile
|
||||
src/gallium/drivers/virgl/Makefile
|
||||
src/gallium/state_trackers/clover/Makefile
|
||||
|
@ -2806,6 +2814,7 @@ AC_CONFIG_FILES([Makefile
|
|||
src/gallium/targets/xvmc/Makefile
|
||||
src/gallium/tests/trivial/Makefile
|
||||
src/gallium/tests/unit/Makefile
|
||||
src/gallium/winsys/etnaviv/drm/Makefile
|
||||
src/gallium/winsys/freedreno/drm/Makefile
|
||||
src/gallium/winsys/i915/drm/Makefile
|
||||
src/gallium/winsys/intel/drm/Makefile
|
||||
|
|
|
@ -68,6 +68,10 @@ if NEED_RADEON_DRM_WINSYS
|
|||
SUBDIRS += winsys/radeon/drm
|
||||
endif
|
||||
|
||||
if HAVE_GALLIUM_ETNAVIV
|
||||
SUBDIRS += drivers/etnaviv winsys/etnaviv/drm
|
||||
endif
|
||||
|
||||
## swrast/softpipe
|
||||
if HAVE_GALLIUM_SOFTPIPE
|
||||
SUBDIRS += drivers/softpipe
|
||||
|
|
|
@ -154,6 +154,11 @@ static const struct drm_driver_descriptor driver_descriptors[] = {
|
|||
.create_screen = pipe_vc4_create_screen,
|
||||
.configuration = configuration_query,
|
||||
},
|
||||
{
|
||||
.driver_name = "etnaviv",
|
||||
.create_screen = pipe_etna_create_screen,
|
||||
.configuration = configuration_query,
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
|
|
|
@ -266,5 +266,27 @@ pipe_vc4_create_screen(int fd)
|
|||
|
||||
#endif
|
||||
|
||||
#ifdef GALLIUM_ETNAVIV
|
||||
#include "etnaviv/drm/etnaviv_drm_public.h"
|
||||
|
||||
struct pipe_screen *
|
||||
pipe_etna_create_screen(int fd)
|
||||
{
|
||||
struct pipe_screen *screen;
|
||||
|
||||
screen = etna_drm_screen_create(fd);
|
||||
return screen ? debug_screen_wrap(screen) : NULL;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
struct pipe_screen *
|
||||
pipe_etna_create_screen(int fd)
|
||||
{
|
||||
fprintf(stderr, "etnaviv: driver missing\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* DRM_HELPER_H */
|
||||
|
|
|
@ -34,4 +34,7 @@ pipe_virgl_create_screen(int fd);
|
|||
struct pipe_screen *
|
||||
pipe_vc4_create_screen(int fd);
|
||||
|
||||
struct pipe_screen *
|
||||
pipe_etna_create_screen(int fd);
|
||||
|
||||
#endif /* _DRM_HELPER_PUBLIC_H */
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
etnaviv_compiler
|
|
@ -0,0 +1,11 @@
|
|||
if HAVE_GALLIUM_ETNAVIV
|
||||
|
||||
TARGET_DRIVERS += etnaviv
|
||||
TARGET_CPPFLAGS += -DGALLIUM_ETNAVIV
|
||||
TARGET_LIB_DEPS += \
|
||||
$(top_builddir)/src/gallium/winsys/etnaviv/drm/libetnavivdrm.la \
|
||||
$(top_builddir)/src/gallium/drivers/etnaviv/libetnaviv.la \
|
||||
$(ETNAVIV_LIBS) \
|
||||
$(LIBDRM_LIBS)
|
||||
|
||||
endif
|
|
@ -0,0 +1,44 @@
|
|||
# Copyright © 2013 W.J. van der Laan
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a
|
||||
# copy of this software and associated documentation files (the "Software"),
|
||||
# to deal in the Software without restriction, including without limitation
|
||||
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
# and/or sell copies of the Software, and to permit persons to whom the
|
||||
# Software is furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice (including the next
|
||||
# paragraph) shall be included in all copies or substantial portions of the
|
||||
# Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
# DEALINGS IN THE SOFTWARE.
|
||||
|
||||
include Makefile.sources
|
||||
include $(top_srcdir)/src/gallium/Automake.inc
|
||||
|
||||
noinst_LTLIBRARIES = libetnaviv.la
|
||||
|
||||
AM_CPPFLAGS = \
|
||||
$(GALLIUM_DRIVER_CFLAGS) \
|
||||
$(ETNAVIV_CFLAGS)
|
||||
|
||||
libetnaviv_la_SOURCES = $(C_SOURCES)
|
||||
|
||||
noinst_PROGRAMS = etnaviv_compiler
|
||||
|
||||
etnaviv_compiler_SOURCES = \
|
||||
etnaviv_compiler_cmdline.c
|
||||
|
||||
etnaviv_compiler_LDADD = \
|
||||
libetnaviv.la \
|
||||
$(top_builddir)/src/gallium/auxiliary/libgallium.la \
|
||||
$(top_builddir)/src/util/libmesautil.la \
|
||||
$(GALLIUM_COMMON_LIB_DEPS) \
|
||||
$(ETNAVIV_LIBS)
|
|
@ -0,0 +1,49 @@
|
|||
C_SOURCES := \
|
||||
etnaviv_asm.c \
|
||||
etnaviv_asm.h \
|
||||
etnaviv_blend.c \
|
||||
etnaviv_blend.h \
|
||||
etnaviv_clear_blit.c \
|
||||
etnaviv_clear_blit.h \
|
||||
etnaviv_compiler.c \
|
||||
etnaviv_compiler.h \
|
||||
etnaviv_context.c \
|
||||
etnaviv_context.h \
|
||||
etnaviv_debug.h \
|
||||
etnaviv_disasm.c \
|
||||
etnaviv_disasm.h \
|
||||
etnaviv_emit.c \
|
||||
etnaviv_emit.h \
|
||||
etnaviv_fence.c \
|
||||
etnaviv_fence.h \
|
||||
etnaviv_format.c \
|
||||
etnaviv_format.h \
|
||||
etnaviv_query.c \
|
||||
etnaviv_query.h \
|
||||
etnaviv_query_sw.c \
|
||||
etnaviv_query_sw.h \
|
||||
etnaviv_rasterizer.c \
|
||||
etnaviv_rasterizer.h \
|
||||
etnaviv_resource.c \
|
||||
etnaviv_resource.h \
|
||||
etnaviv_rs.c \
|
||||
etnaviv_rs.h \
|
||||
etnaviv_screen.c \
|
||||
etnaviv_screen.h \
|
||||
etnaviv_shader.c \
|
||||
etnaviv_shader.h \
|
||||
etnaviv_state.c \
|
||||
etnaviv_state.h \
|
||||
etnaviv_surface.c \
|
||||
etnaviv_surface.h \
|
||||
etnaviv_texture.c \
|
||||
etnaviv_texture.h \
|
||||
etnaviv_tiling.c \
|
||||
etnaviv_tiling.h \
|
||||
etnaviv_transfer.c \
|
||||
etnaviv_transfer.h \
|
||||
etnaviv_uniforms.c \
|
||||
etnaviv_uniforms.h \
|
||||
etnaviv_utils.h \
|
||||
etnaviv_zsa.c \
|
||||
etnaviv_zsa.h
|
|
@ -0,0 +1,13 @@
|
|||
Notes for the etnaviv gallium driver
|
||||
------------------------------------
|
||||
|
||||
There are two ways how this driver might get used:
|
||||
|
||||
- application opens kms device (kmscube, weston, ..)
|
||||
- X via xf86-video-armada
|
||||
|
||||
For the kms device case we provide a renderonly based driver like
|
||||
imx where all the magic for buffer import and export between kms
|
||||
and renderonly GPU is handled automaticly.
|
||||
|
||||
For X/xf86-video-armada we need to provide etnaviv_dri.so.
|
|
@ -0,0 +1,107 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2015 Etnaviv Project
|
||||
*
|
||||
* 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, sub license,
|
||||
* 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 NON-INFRINGEMENT. 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:
|
||||
* Wladimir J. van der Laan <laanwj@gmail.com>
|
||||
*/
|
||||
|
||||
#include "etnaviv_asm.h"
|
||||
#include "etnaviv_debug.h"
|
||||
#include "etnaviv_util.h"
|
||||
|
||||
/* An instruction can only read from one distinct uniform.
|
||||
* This function verifies this property and returns true if the instruction
|
||||
* is deemed correct and false otherwise.
|
||||
*/
|
||||
static bool
|
||||
check_uniforms(const struct etna_inst *inst)
|
||||
{
|
||||
unsigned uni_rgroup = -1;
|
||||
unsigned uni_reg = -1;
|
||||
bool conflict = false;
|
||||
|
||||
for (unsigned i = 0; i < ETNA_NUM_SRC; i++) {
|
||||
const struct etna_inst_src *src = &inst->src[i];
|
||||
|
||||
if (!etna_rgroup_is_uniform(src->rgroup))
|
||||
continue;
|
||||
|
||||
if (uni_reg == -1) { /* first uniform used */
|
||||
uni_rgroup = src->rgroup;
|
||||
uni_reg = src->reg;
|
||||
} else { /* second or later; check that it is a re-use */
|
||||
if (uni_rgroup != src->rgroup || uni_reg != src->reg) {
|
||||
conflict = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return !conflict;
|
||||
}
|
||||
|
||||
int
|
||||
etna_assemble(uint32_t *out, const struct etna_inst *inst)
|
||||
{
|
||||
/* cannot have both src2 and imm */
|
||||
if (inst->imm && inst->src[2].use)
|
||||
return 1;
|
||||
|
||||
if (!check_uniforms(inst))
|
||||
BUG("error: generating instruction that accesses two different uniforms");
|
||||
|
||||
out[0] = VIV_ISA_WORD_0_OPCODE(inst->opcode) |
|
||||
VIV_ISA_WORD_0_COND(inst->cond) |
|
||||
COND(inst->sat, VIV_ISA_WORD_0_SAT) |
|
||||
COND(inst->dst.use, VIV_ISA_WORD_0_DST_USE) |
|
||||
VIV_ISA_WORD_0_DST_AMODE(inst->dst.amode) |
|
||||
VIV_ISA_WORD_0_DST_REG(inst->dst.reg) |
|
||||
VIV_ISA_WORD_0_DST_COMPS(inst->dst.comps) |
|
||||
VIV_ISA_WORD_0_TEX_ID(inst->tex.id);
|
||||
out[1] = VIV_ISA_WORD_1_TEX_AMODE(inst->tex.amode) |
|
||||
VIV_ISA_WORD_1_TEX_SWIZ(inst->tex.swiz) |
|
||||
COND(inst->src[0].use, VIV_ISA_WORD_1_SRC0_USE) |
|
||||
VIV_ISA_WORD_1_SRC0_REG(inst->src[0].reg) |
|
||||
COND(inst->type & 0x4, VIV_ISA_WORD_1_TYPE_BIT2) |
|
||||
VIV_ISA_WORD_1_SRC0_SWIZ(inst->src[0].swiz) |
|
||||
COND(inst->src[0].neg, VIV_ISA_WORD_1_SRC0_NEG) |
|
||||
COND(inst->src[0].abs, VIV_ISA_WORD_1_SRC0_ABS);
|
||||
out[2] = VIV_ISA_WORD_2_SRC0_AMODE(inst->src[0].amode) |
|
||||
VIV_ISA_WORD_2_SRC0_RGROUP(inst->src[0].rgroup) |
|
||||
COND(inst->src[1].use, VIV_ISA_WORD_2_SRC1_USE) |
|
||||
VIV_ISA_WORD_2_SRC1_REG(inst->src[1].reg) |
|
||||
VIV_ISA_WORD_2_SRC1_SWIZ(inst->src[1].swiz) |
|
||||
COND(inst->src[1].neg, VIV_ISA_WORD_2_SRC1_NEG) |
|
||||
COND(inst->src[1].abs, VIV_ISA_WORD_2_SRC1_ABS) |
|
||||
VIV_ISA_WORD_2_SRC1_AMODE(inst->src[1].amode) |
|
||||
VIV_ISA_WORD_2_TYPE_BIT01(inst->type & 0x3);
|
||||
out[3] = VIV_ISA_WORD_3_SRC1_RGROUP(inst->src[1].rgroup) |
|
||||
COND(inst->src[2].use, VIV_ISA_WORD_3_SRC2_USE) |
|
||||
VIV_ISA_WORD_3_SRC2_REG(inst->src[2].reg) |
|
||||
VIV_ISA_WORD_3_SRC2_SWIZ(inst->src[2].swiz) |
|
||||
COND(inst->src[2].neg, VIV_ISA_WORD_3_SRC2_NEG) |
|
||||
COND(inst->src[2].abs, VIV_ISA_WORD_3_SRC2_ABS) |
|
||||
VIV_ISA_WORD_3_SRC2_AMODE(inst->src[2].amode) |
|
||||
VIV_ISA_WORD_3_SRC2_RGROUP(inst->src[2].rgroup);
|
||||
out[3] |= VIV_ISA_WORD_3_SRC2_IMM(inst->imm);
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,133 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2015 Etnaviv Project
|
||||
*
|
||||
* 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, sub license,
|
||||
* 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 NON-INFRINGEMENT. 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:
|
||||
* Wladimir J. van der Laan <laanwj@gmail.com>
|
||||
*/
|
||||
|
||||
#ifndef H_ETNAVIV_ASM
|
||||
#define H_ETNAVIV_ASM
|
||||
|
||||
#include <stdint.h>
|
||||
#include "hw/isa.xml.h"
|
||||
|
||||
/* Size of an instruction in 32-bit words */
|
||||
#define ETNA_INST_SIZE (4)
|
||||
/* Number of source operands per instruction */
|
||||
#define ETNA_NUM_SRC (3)
|
||||
|
||||
/* Broadcast swizzle to all four components */
|
||||
#define INST_SWIZ_BROADCAST(x) \
|
||||
(INST_SWIZ_X(x) | INST_SWIZ_Y(x) | INST_SWIZ_Z(x) | INST_SWIZ_W(x))
|
||||
/* Identity (NOP) swizzle */
|
||||
#define INST_SWIZ_IDENTITY \
|
||||
(INST_SWIZ_X(0) | INST_SWIZ_Y(1) | INST_SWIZ_Z(2) | INST_SWIZ_W(3))
|
||||
/* Fully specified swizzle */
|
||||
#define INST_SWIZ(x,y,z,w) \
|
||||
(INST_SWIZ_X(x) | INST_SWIZ_Y(y) | INST_SWIZ_Z(z) | INST_SWIZ_W(w))
|
||||
#define SWIZZLE(c0,c1,c2,c3) \
|
||||
INST_SWIZ(INST_SWIZ_COMP_##c0, \
|
||||
INST_SWIZ_COMP_##c1, \
|
||||
INST_SWIZ_COMP_##c2, \
|
||||
INST_SWIZ_COMP_##c3)
|
||||
|
||||
/*** operands ***/
|
||||
|
||||
/* destination operand */
|
||||
struct etna_inst_dst {
|
||||
unsigned use:1; /* 0: not in use, 1: in use */
|
||||
unsigned amode:3; /* INST_AMODE_* */
|
||||
unsigned reg:7; /* register number 0..127 */
|
||||
unsigned comps:4; /* INST_COMPS_* */
|
||||
};
|
||||
|
||||
/* texture operand */
|
||||
struct etna_inst_tex {
|
||||
unsigned id:5; /* sampler id */
|
||||
unsigned amode:3; /* INST_AMODE_* */
|
||||
unsigned swiz:8; /* INST_SWIZ */
|
||||
};
|
||||
|
||||
/* source operand */
|
||||
struct etna_inst_src {
|
||||
unsigned use:1; /* 0: not in use, 1: in use */
|
||||
unsigned reg:9; /* register or uniform number 0..511 */
|
||||
unsigned swiz:8; /* INST_SWIZ */
|
||||
unsigned neg:1; /* negate (flip sign) if set */
|
||||
unsigned abs:1; /* absolute (remove sign) if set */
|
||||
unsigned amode:3; /* INST_AMODE_* */
|
||||
unsigned rgroup:3; /* INST_RGROUP_* */
|
||||
};
|
||||
|
||||
/*** instruction ***/
|
||||
struct etna_inst {
|
||||
uint8_t opcode; /* INST_OPCODE_* */
|
||||
uint8_t type; /* INST_TYPE_* */
|
||||
unsigned cond:5; /* INST_CONDITION_* */
|
||||
unsigned sat:1; /* saturate result between 0..1 */
|
||||
struct etna_inst_dst dst; /* destination operand */
|
||||
struct etna_inst_tex tex; /* texture operand */
|
||||
struct etna_inst_src src[ETNA_NUM_SRC]; /* source operand */
|
||||
unsigned imm; /* takes place of src[2] for BRANCH/CALL */
|
||||
};
|
||||
|
||||
/* Compose two swizzles (computes swz1.swz2) */
|
||||
static inline uint32_t inst_swiz_compose(uint32_t swz1, uint32_t swz2)
|
||||
{
|
||||
return INST_SWIZ_X((swz1 >> (((swz2 >> 0)&3)*2))&3) |
|
||||
INST_SWIZ_Y((swz1 >> (((swz2 >> 2)&3)*2))&3) |
|
||||
INST_SWIZ_Z((swz1 >> (((swz2 >> 4)&3)*2))&3) |
|
||||
INST_SWIZ_W((swz1 >> (((swz2 >> 6)&3)*2))&3);
|
||||
};
|
||||
|
||||
/* Return whether the rgroup is one of the uniforms */
|
||||
static inline int
|
||||
etna_rgroup_is_uniform(unsigned rgroup)
|
||||
{
|
||||
return rgroup == INST_RGROUP_UNIFORM_0 ||
|
||||
rgroup == INST_RGROUP_UNIFORM_1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build vivante instruction from structure with
|
||||
* opcode, cond, sat, dst_use, dst_amode,
|
||||
* dst_reg, dst_comps, tex_id, tex_amode, tex_swiz,
|
||||
* src[0-2]_reg, use, swiz, neg, abs, amode, rgroup,
|
||||
* imm
|
||||
*
|
||||
* Return 0 if successful, and a non-zero
|
||||
* value otherwise.
|
||||
*/
|
||||
int
|
||||
etna_assemble(uint32_t *out, const struct etna_inst *inst);
|
||||
|
||||
/**
|
||||
* Set field imm of already-assembled instruction.
|
||||
* This is used for filling in jump destinations in a separate pass.
|
||||
*/
|
||||
static inline void
|
||||
etna_assemble_set_imm(uint32_t *out, uint32_t imm)
|
||||
{
|
||||
out[3] |= VIV_ISA_WORD_3_SRC2_IMM(imm);
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,109 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2015 Etnaviv Project
|
||||
*
|
||||
* 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, sub license,
|
||||
* 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 NON-INFRINGEMENT. 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:
|
||||
* Wladimir J. van der Laan <laanwj@gmail.com>
|
||||
*/
|
||||
|
||||
#include "etnaviv_blend.h"
|
||||
|
||||
#include "etnaviv_context.h"
|
||||
#include "etnaviv_translate.h"
|
||||
#include "pipe/p_defines.h"
|
||||
#include "util/u_memory.h"
|
||||
|
||||
void *
|
||||
etna_blend_state_create(struct pipe_context *pctx,
|
||||
const struct pipe_blend_state *so)
|
||||
{
|
||||
const struct pipe_rt_blend_state *rt0 = &so->rt[0];
|
||||
struct etna_blend_state *co = CALLOC_STRUCT(etna_blend_state);
|
||||
|
||||
if (!co)
|
||||
return NULL;
|
||||
|
||||
co->base = *so;
|
||||
|
||||
/* Enable blending if
|
||||
* - blend enabled in blend state
|
||||
* - NOT source factor is ONE and destination factor ZERO for both rgb and
|
||||
* alpha (which would mean that blending is effectively disabled)
|
||||
*/
|
||||
bool enable = rt0->blend_enable &&
|
||||
!(rt0->rgb_src_factor == PIPE_BLENDFACTOR_ONE &&
|
||||
rt0->rgb_dst_factor == PIPE_BLENDFACTOR_ZERO &&
|
||||
rt0->alpha_src_factor == PIPE_BLENDFACTOR_ONE &&
|
||||
rt0->alpha_dst_factor == PIPE_BLENDFACTOR_ZERO);
|
||||
|
||||
/* Enable separate alpha if
|
||||
* - Blending enabled (see above)
|
||||
* - NOT source factor is equal to destination factor for both rgb abd
|
||||
* alpha (which would effectively that mean alpha is not separate)
|
||||
*/
|
||||
bool separate_alpha = enable &&
|
||||
!(rt0->rgb_src_factor == rt0->alpha_src_factor &&
|
||||
rt0->rgb_dst_factor == rt0->alpha_dst_factor);
|
||||
|
||||
/* If the complete render target is written, set full_overwrite:
|
||||
* - The color mask is 1111
|
||||
* - No blending is used
|
||||
*/
|
||||
bool full_overwrite = (rt0->colormask == 15) && !enable;
|
||||
|
||||
if (enable) {
|
||||
co->PE_ALPHA_CONFIG =
|
||||
VIVS_PE_ALPHA_CONFIG_BLEND_ENABLE_COLOR |
|
||||
COND(separate_alpha, VIVS_PE_ALPHA_CONFIG_BLEND_SEPARATE_ALPHA) |
|
||||
VIVS_PE_ALPHA_CONFIG_SRC_FUNC_COLOR(translate_blend_factor(rt0->rgb_src_factor)) |
|
||||
VIVS_PE_ALPHA_CONFIG_SRC_FUNC_ALPHA(translate_blend_factor(rt0->alpha_src_factor)) |
|
||||
VIVS_PE_ALPHA_CONFIG_DST_FUNC_COLOR(translate_blend_factor(rt0->rgb_dst_factor)) |
|
||||
VIVS_PE_ALPHA_CONFIG_DST_FUNC_ALPHA(translate_blend_factor(rt0->alpha_dst_factor)) |
|
||||
VIVS_PE_ALPHA_CONFIG_EQ_COLOR(translate_blend(rt0->rgb_func)) |
|
||||
VIVS_PE_ALPHA_CONFIG_EQ_ALPHA(translate_blend(rt0->alpha_func));
|
||||
} else {
|
||||
co->PE_ALPHA_CONFIG = 0;
|
||||
}
|
||||
|
||||
co->PE_COLOR_FORMAT =
|
||||
VIVS_PE_COLOR_FORMAT_COMPONENTS(rt0->colormask) |
|
||||
COND(full_overwrite, VIVS_PE_COLOR_FORMAT_OVERWRITE);
|
||||
|
||||
co->PE_LOGIC_OP =
|
||||
VIVS_PE_LOGIC_OP_OP(so->logicop_enable ? so->logicop_func : LOGIC_OP_COPY) |
|
||||
0x000E4000 /* ??? */;
|
||||
|
||||
/* independent_blend_enable not needed: only one rt supported */
|
||||
/* XXX alpha_to_coverage / alpha_to_one? */
|
||||
/* Set dither registers based on dither status. These registers set the
|
||||
* dither pattern,
|
||||
* for now, set the same values as the blob.
|
||||
*/
|
||||
if (so->dither) {
|
||||
co->PE_DITHER[0] = 0x6e4ca280;
|
||||
co->PE_DITHER[1] = 0x5d7f91b3;
|
||||
} else {
|
||||
co->PE_DITHER[0] = 0xffffffff;
|
||||
co->PE_DITHER[1] = 0xffffffff;
|
||||
}
|
||||
|
||||
return co;
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2015 Etnaviv Project
|
||||
*
|
||||
* 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, sub license,
|
||||
* 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 NON-INFRINGEMENT. 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:
|
||||
* Wladimir J. van der Laan <laanwj@gmail.com>
|
||||
*/
|
||||
|
||||
#ifndef H_ETNAVIV_BLEND
|
||||
#define H_ETNAVIV_BLEND
|
||||
|
||||
#include "pipe/p_context.h"
|
||||
#include "pipe/p_state.h"
|
||||
|
||||
struct etna_blend_state {
|
||||
struct pipe_blend_state base;
|
||||
|
||||
uint32_t PE_ALPHA_CONFIG;
|
||||
uint32_t PE_COLOR_FORMAT;
|
||||
uint32_t PE_LOGIC_OP;
|
||||
uint32_t PE_DITHER[2];
|
||||
};
|
||||
|
||||
static inline struct etna_blend_state *
|
||||
etna_blend_state(struct pipe_blend_state *blend)
|
||||
{
|
||||
return (struct etna_blend_state *)blend;
|
||||
}
|
||||
|
||||
void *
|
||||
etna_blend_state_create(struct pipe_context *pctx,
|
||||
const struct pipe_blend_state *so);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,640 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2015 Etnaviv Project
|
||||
*
|
||||
* 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, sub license,
|
||||
* 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 NON-INFRINGEMENT. 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:
|
||||
* Wladimir J. van der Laan <laanwj@gmail.com>
|
||||
*/
|
||||
|
||||
#include "etnaviv_clear_blit.h"
|
||||
|
||||
#include "hw/common.xml.h"
|
||||
|
||||
#include "etnaviv_context.h"
|
||||
#include "etnaviv_emit.h"
|
||||
#include "etnaviv_emit.h"
|
||||
#include "etnaviv_format.h"
|
||||
#include "etnaviv_resource.h"
|
||||
#include "etnaviv_surface.h"
|
||||
#include "etnaviv_translate.h"
|
||||
|
||||
#include "pipe/p_defines.h"
|
||||
#include "pipe/p_state.h"
|
||||
#include "util/u_blitter.h"
|
||||
#include "util/u_inlines.h"
|
||||
#include "util/u_memory.h"
|
||||
#include "util/u_surface.h"
|
||||
|
||||
/* Save current state for blitter operation */
|
||||
static void
|
||||
etna_blit_save_state(struct etna_context *ctx)
|
||||
{
|
||||
util_blitter_save_vertex_buffer_slot(ctx->blitter, ctx->vertex_buffer.vb);
|
||||
util_blitter_save_vertex_elements(ctx->blitter, ctx->vertex_elements);
|
||||
util_blitter_save_vertex_shader(ctx->blitter, ctx->vs);
|
||||
util_blitter_save_rasterizer(ctx->blitter, ctx->rasterizer);
|
||||
util_blitter_save_viewport(ctx->blitter, &ctx->viewport_s);
|
||||
util_blitter_save_scissor(ctx->blitter, &ctx->scissor_s);
|
||||
util_blitter_save_fragment_shader(ctx->blitter, ctx->fs);
|
||||
util_blitter_save_blend(ctx->blitter, ctx->blend);
|
||||
util_blitter_save_depth_stencil_alpha(ctx->blitter, ctx->zsa);
|
||||
util_blitter_save_stencil_ref(ctx->blitter, &ctx->stencil_ref_s);
|
||||
util_blitter_save_sample_mask(ctx->blitter, ctx->sample_mask);
|
||||
util_blitter_save_framebuffer(ctx->blitter, &ctx->framebuffer_s);
|
||||
util_blitter_save_fragment_sampler_states(ctx->blitter,
|
||||
ctx->num_fragment_samplers, (void **)ctx->sampler);
|
||||
util_blitter_save_fragment_sampler_views(ctx->blitter,
|
||||
ctx->num_fragment_sampler_views, ctx->sampler_view);
|
||||
}
|
||||
|
||||
/* Generate clear command for a surface (non-fast clear case) */
|
||||
void
|
||||
etna_rs_gen_clear_surface(struct etna_context *ctx, struct etna_surface *surf,
|
||||
uint32_t clear_value)
|
||||
{
|
||||
struct etna_resource *dst = etna_resource(surf->base.texture);
|
||||
uint32_t format = translate_rs_format(surf->base.format);
|
||||
|
||||
if (format == ETNA_NO_MATCH) {
|
||||
BUG("etna_rs_gen_clear_surface: Unhandled clear fmt %s", util_format_name(surf->base.format));
|
||||
format = RS_FORMAT_A8R8G8B8;
|
||||
assert(0);
|
||||
}
|
||||
|
||||
/* use tiled clear if width is multiple of 16 */
|
||||
bool tiled_clear = (surf->surf.padded_width & ETNA_RS_WIDTH_MASK) == 0 &&
|
||||
(surf->surf.padded_height & ETNA_RS_HEIGHT_MASK) == 0;
|
||||
|
||||
etna_compile_rs_state( ctx, &surf->clear_command, &(struct rs_state) {
|
||||
.source_format = format,
|
||||
.dest_format = format,
|
||||
.dest = dst->bo,
|
||||
.dest_offset = surf->surf.offset,
|
||||
.dest_stride = surf->surf.stride,
|
||||
.dest_padded_height = surf->surf.padded_height,
|
||||
.dest_tiling = tiled_clear ? dst->layout : ETNA_LAYOUT_LINEAR,
|
||||
.dither = {0xffffffff, 0xffffffff},
|
||||
.width = surf->surf.padded_width, /* These must be padded to 16x4 if !LINEAR, otherwise RS will hang */
|
||||
.height = surf->surf.padded_height,
|
||||
.clear_value = {clear_value},
|
||||
.clear_mode = VIVS_RS_CLEAR_CONTROL_MODE_ENABLED1,
|
||||
.clear_bits = 0xffff
|
||||
});
|
||||
}
|
||||
|
||||
static void
|
||||
etna_blit_clear_color(struct pipe_context *pctx, struct pipe_surface *dst,
|
||||
const union pipe_color_union *color)
|
||||
{
|
||||
struct etna_context *ctx = etna_context(pctx);
|
||||
struct etna_surface *surf = etna_surface(dst);
|
||||
uint32_t new_clear_value = translate_clear_color(surf->base.format, color);
|
||||
|
||||
if (surf->surf.ts_size) { /* TS: use precompiled clear command */
|
||||
ctx->framebuffer.TS_COLOR_CLEAR_VALUE = new_clear_value;
|
||||
|
||||
if (!DBG_ENABLED(ETNA_DBG_NO_AUTODISABLE) &&
|
||||
VIV_FEATURE(ctx->screen, chipMinorFeatures1, AUTO_DISABLE)) {
|
||||
/* Set number of color tiles to be filled */
|
||||
etna_set_state(ctx->stream, VIVS_TS_COLOR_AUTO_DISABLE_COUNT,
|
||||
surf->surf.padded_width * surf->surf.padded_height / 16);
|
||||
ctx->framebuffer.TS_MEM_CONFIG |= VIVS_TS_MEM_CONFIG_COLOR_AUTO_DISABLE;
|
||||
}
|
||||
|
||||
ctx->dirty |= ETNA_DIRTY_TS;
|
||||
} else if (unlikely(new_clear_value != surf->level->clear_value)) { /* Queue normal RS clear for non-TS surfaces */
|
||||
/* If clear color changed, re-generate stored command */
|
||||
etna_rs_gen_clear_surface(ctx, surf, new_clear_value);
|
||||
}
|
||||
|
||||
etna_submit_rs_state(ctx, &surf->clear_command);
|
||||
surf->level->clear_value = new_clear_value;
|
||||
resource_written(ctx, surf->base.texture);
|
||||
etna_resource(surf->base.texture)->seqno++;
|
||||
}
|
||||
|
||||
static void
|
||||
etna_blit_clear_zs(struct pipe_context *pctx, struct pipe_surface *dst,
|
||||
unsigned buffers, double depth, unsigned stencil)
|
||||
{
|
||||
struct etna_context *ctx = etna_context(pctx);
|
||||
struct etna_surface *surf = etna_surface(dst);
|
||||
uint32_t new_clear_value = translate_clear_depth_stencil(surf->base.format, depth, stencil);
|
||||
uint32_t new_clear_bits = 0, clear_bits_depth, clear_bits_stencil;
|
||||
|
||||
/* Get the channels to clear */
|
||||
switch (surf->base.format) {
|
||||
case PIPE_FORMAT_Z16_UNORM:
|
||||
clear_bits_depth = 0xffff;
|
||||
clear_bits_stencil = 0;
|
||||
break;
|
||||
case PIPE_FORMAT_X8Z24_UNORM:
|
||||
case PIPE_FORMAT_S8_UINT_Z24_UNORM:
|
||||
clear_bits_depth = 0xeeee;
|
||||
clear_bits_stencil = 0x1111;
|
||||
break;
|
||||
default:
|
||||
clear_bits_depth = clear_bits_stencil = 0xffff;
|
||||
break;
|
||||
}
|
||||
|
||||
if (buffers & PIPE_CLEAR_DEPTH)
|
||||
new_clear_bits |= clear_bits_depth;
|
||||
if (buffers & PIPE_CLEAR_STENCIL)
|
||||
new_clear_bits |= clear_bits_stencil;
|
||||
|
||||
/* FIXME: when tile status is enabled, this becomes more complex as
|
||||
* we may separately clear the depth from the stencil. In this case,
|
||||
* we want to resolve the surface, and avoid using the tile status.
|
||||
* We may be better off recording the pending clear operation,
|
||||
* delaying the actual clear to the first use. This way, we can merge
|
||||
* consecutive clears together. */
|
||||
if (surf->surf.ts_size) { /* TS: use precompiled clear command */
|
||||
/* Set new clear depth value */
|
||||
ctx->framebuffer.TS_DEPTH_CLEAR_VALUE = new_clear_value;
|
||||
if (!DBG_ENABLED(ETNA_DBG_NO_AUTODISABLE) &&
|
||||
VIV_FEATURE(ctx->screen, chipMinorFeatures1, AUTO_DISABLE)) {
|
||||
/* Set number of depth tiles to be filled */
|
||||
etna_set_state(ctx->stream, VIVS_TS_DEPTH_AUTO_DISABLE_COUNT,
|
||||
surf->surf.padded_width * surf->surf.padded_height / 16);
|
||||
ctx->framebuffer.TS_MEM_CONFIG |= VIVS_TS_MEM_CONFIG_DEPTH_AUTO_DISABLE;
|
||||
}
|
||||
|
||||
ctx->dirty |= ETNA_DIRTY_TS;
|
||||
} else {
|
||||
if (unlikely(new_clear_value != surf->level->clear_value)) { /* Queue normal RS clear for non-TS surfaces */
|
||||
/* If clear depth value changed, re-generate stored command */
|
||||
etna_rs_gen_clear_surface(ctx, surf, new_clear_value);
|
||||
}
|
||||
/* Update the channels to be cleared */
|
||||
etna_modify_rs_clearbits(&surf->clear_command, new_clear_bits);
|
||||
}
|
||||
|
||||
etna_submit_rs_state(ctx, &surf->clear_command);
|
||||
surf->level->clear_value = new_clear_value;
|
||||
resource_written(ctx, surf->base.texture);
|
||||
etna_resource(surf->base.texture)->seqno++;
|
||||
}
|
||||
|
||||
static void
|
||||
etna_clear(struct pipe_context *pctx, unsigned buffers,
|
||||
const union pipe_color_union *color, double depth, unsigned stencil)
|
||||
{
|
||||
struct etna_context *ctx = etna_context(pctx);
|
||||
|
||||
/* Flush color and depth cache before clearing anything.
|
||||
* This is especially important when coming from another surface, as
|
||||
* otherwise it may clear part of the old surface instead. */
|
||||
etna_set_state(ctx->stream, VIVS_GL_FLUSH_CACHE, VIVS_GL_FLUSH_CACHE_COLOR | VIVS_GL_FLUSH_CACHE_DEPTH);
|
||||
etna_stall(ctx->stream, SYNC_RECIPIENT_RA, SYNC_RECIPIENT_PE);
|
||||
|
||||
/* Preparation: Flush the TS if needed. This must be done after flushing
|
||||
* color and depth, otherwise it can result in crashes */
|
||||
bool need_ts_flush = false;
|
||||
if ((buffers & PIPE_CLEAR_COLOR) && ctx->framebuffer_s.nr_cbufs) {
|
||||
struct etna_surface *surf = etna_surface(ctx->framebuffer_s.cbufs[0]);
|
||||
if (surf->surf.ts_size)
|
||||
need_ts_flush = true;
|
||||
}
|
||||
if ((buffers & PIPE_CLEAR_DEPTHSTENCIL) && ctx->framebuffer_s.zsbuf != NULL) {
|
||||
struct etna_surface *surf = etna_surface(ctx->framebuffer_s.zsbuf);
|
||||
|
||||
if (surf->surf.ts_size)
|
||||
need_ts_flush = true;
|
||||
}
|
||||
|
||||
if (need_ts_flush)
|
||||
etna_set_state(ctx->stream, VIVS_TS_FLUSH_CACHE, VIVS_TS_FLUSH_CACHE_FLUSH);
|
||||
|
||||
/* No need to set up the TS here as RS clear operations (in contrast to
|
||||
* resolve and copy) do not require the TS state.
|
||||
*/
|
||||
if (buffers & PIPE_CLEAR_COLOR) {
|
||||
for (int idx = 0; idx < ctx->framebuffer_s.nr_cbufs; ++idx) {
|
||||
etna_blit_clear_color(pctx, ctx->framebuffer_s.cbufs[idx],
|
||||
&color[idx]);
|
||||
}
|
||||
}
|
||||
|
||||
/* Flush the color and depth caches before each RS clear operation
|
||||
* This fixes a hang on GC600. */
|
||||
if (buffers & PIPE_CLEAR_DEPTHSTENCIL && buffers & PIPE_CLEAR_COLOR)
|
||||
etna_set_state(ctx->stream, VIVS_GL_FLUSH_CACHE,
|
||||
VIVS_GL_FLUSH_CACHE_COLOR | VIVS_GL_FLUSH_CACHE_DEPTH);
|
||||
|
||||
if ((buffers & PIPE_CLEAR_DEPTHSTENCIL) && ctx->framebuffer_s.zsbuf != NULL)
|
||||
etna_blit_clear_zs(pctx, ctx->framebuffer_s.zsbuf, buffers, depth, stencil);
|
||||
|
||||
etna_stall(ctx->stream, SYNC_RECIPIENT_RA, SYNC_RECIPIENT_PE);
|
||||
}
|
||||
|
||||
static void
|
||||
etna_clear_render_target(struct pipe_context *pctx, struct pipe_surface *dst,
|
||||
const union pipe_color_union *color, unsigned dstx,
|
||||
unsigned dsty, unsigned width, unsigned height,
|
||||
bool render_condition_enabled)
|
||||
{
|
||||
struct etna_context *ctx = etna_context(pctx);
|
||||
|
||||
/* XXX could fall back to RS when target area is full screen / resolveable
|
||||
* and no TS. */
|
||||
etna_blit_save_state(ctx);
|
||||
util_blitter_clear_render_target(ctx->blitter, dst, color, dstx, dsty, width, height);
|
||||
}
|
||||
|
||||
static void
|
||||
etna_clear_depth_stencil(struct pipe_context *pctx, struct pipe_surface *dst,
|
||||
unsigned clear_flags, double depth, unsigned stencil,
|
||||
unsigned dstx, unsigned dsty, unsigned width,
|
||||
unsigned height, bool render_condition_enabled)
|
||||
{
|
||||
struct etna_context *ctx = etna_context(pctx);
|
||||
|
||||
/* XXX could fall back to RS when target area is full screen / resolveable
|
||||
* and no TS. */
|
||||
etna_blit_save_state(ctx);
|
||||
util_blitter_clear_depth_stencil(ctx->blitter, dst, clear_flags, depth,
|
||||
stencil, dstx, dsty, width, height);
|
||||
}
|
||||
|
||||
static void
|
||||
etna_resource_copy_region(struct pipe_context *pctx, struct pipe_resource *dst,
|
||||
unsigned dst_level, unsigned dstx, unsigned dsty,
|
||||
unsigned dstz, struct pipe_resource *src,
|
||||
unsigned src_level, const struct pipe_box *src_box)
|
||||
{
|
||||
struct etna_context *ctx = etna_context(pctx);
|
||||
|
||||
/* The resource must be of the same format. */
|
||||
assert(src->format == dst->format);
|
||||
/* Resources with nr_samples > 1 are not allowed. */
|
||||
assert(src->nr_samples <= 1 && dst->nr_samples <= 1);
|
||||
|
||||
/* XXX we can use the RS as a literal copy engine here
|
||||
* the only complexity is tiling; the size of the boxes needs to be aligned
|
||||
* to the tile size
|
||||
* how to handle the case where a resource is copied from/to a non-aligned
|
||||
* position?
|
||||
* from non-aligned: can fall back to rendering-based copy?
|
||||
* to non-aligned: can fall back to rendering-based copy?
|
||||
* XXX this goes wrong when source surface is supertiled.
|
||||
*/
|
||||
if (util_blitter_is_copy_supported(ctx->blitter, dst, src)) {
|
||||
etna_blit_save_state(ctx);
|
||||
util_blitter_copy_texture(ctx->blitter, dst, dst_level, dstx, dsty, dstz,
|
||||
src, src_level, src_box);
|
||||
} else {
|
||||
util_resource_copy_region(pctx, dst, dst_level, dstx, dsty, dstz, src,
|
||||
src_level, src_box);
|
||||
}
|
||||
}
|
||||
|
||||
static bool
|
||||
etna_manual_blit(struct etna_resource *dst, struct etna_resource_level *dst_lev,
|
||||
unsigned int dst_offset, struct etna_resource *src,
|
||||
struct etna_resource_level *src_lev, unsigned int src_offset,
|
||||
const struct pipe_blit_info *blit_info)
|
||||
{
|
||||
void *smap, *srow, *dmap, *drow;
|
||||
size_t tile_size;
|
||||
|
||||
assert(src->layout == ETNA_LAYOUT_TILED);
|
||||
assert(dst->layout == ETNA_LAYOUT_TILED);
|
||||
assert(src->base.nr_samples == 0);
|
||||
assert(dst->base.nr_samples == 0);
|
||||
|
||||
tile_size = util_format_get_blocksize(blit_info->src.format) * 4 * 4;
|
||||
|
||||
smap = etna_bo_map(src->bo);
|
||||
if (!smap)
|
||||
return false;
|
||||
|
||||
dmap = etna_bo_map(dst->bo);
|
||||
if (!dmap)
|
||||
return false;
|
||||
|
||||
srow = smap + src_offset;
|
||||
drow = dmap + dst_offset;
|
||||
|
||||
etna_bo_cpu_prep(src->bo, DRM_ETNA_PREP_READ);
|
||||
etna_bo_cpu_prep(dst->bo, DRM_ETNA_PREP_WRITE);
|
||||
|
||||
for (int y = 0; y < blit_info->src.box.height; y += 4) {
|
||||
memcpy(drow, srow, tile_size * blit_info->src.box.width);
|
||||
srow += src_lev->stride * 4;
|
||||
drow += dst_lev->stride * 4;
|
||||
}
|
||||
|
||||
etna_bo_cpu_fini(dst->bo);
|
||||
etna_bo_cpu_fini(src->bo);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
etna_try_rs_blit(struct pipe_context *pctx,
|
||||
const struct pipe_blit_info *blit_info)
|
||||
{
|
||||
struct etna_context *ctx = etna_context(pctx);
|
||||
struct etna_resource *src = etna_resource(blit_info->src.resource);
|
||||
struct etna_resource *dst = etna_resource(blit_info->dst.resource);
|
||||
struct compiled_rs_state copy_to_screen;
|
||||
uint32_t ts_mem_config = 0;
|
||||
int msaa_xscale = 1, msaa_yscale = 1;
|
||||
|
||||
/* Ensure that the level is valid */
|
||||
assert(blit_info->src.level <= src->base.last_level);
|
||||
assert(blit_info->dst.level <= dst->base.last_level);
|
||||
|
||||
if (!translate_samples_to_xyscale(src->base.nr_samples, &msaa_xscale, &msaa_yscale, NULL))
|
||||
return FALSE;
|
||||
|
||||
/* The width/height are in pixels; they do not change as a result of
|
||||
* multi-sampling. So, when blitting from a 4x multisampled surface
|
||||
* to a non-multisampled surface, the width and height will be
|
||||
* identical. As we do not support scaling, reject different sizes. */
|
||||
if (blit_info->dst.box.width != blit_info->src.box.width ||
|
||||
blit_info->dst.box.height != blit_info->src.box.height) {
|
||||
DBG("scaling requested: source %dx%d destination %dx%d",
|
||||
blit_info->src.box.width, blit_info->src.box.height,
|
||||
blit_info->dst.box.width, blit_info->dst.box.height);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* No masks - RS can't copy specific channels */
|
||||
unsigned mask = util_format_get_mask(blit_info->dst.format);
|
||||
if ((blit_info->mask & mask) != mask) {
|
||||
DBG("sub-mask requested: 0x%02x vs format mask 0x%02x", blit_info->mask, mask);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
unsigned src_format = etna_compatible_rs_format(blit_info->src.format);
|
||||
unsigned dst_format = etna_compatible_rs_format(blit_info->src.format);
|
||||
if (translate_rs_format(src_format) == ETNA_NO_MATCH ||
|
||||
translate_rs_format(dst_format) == ETNA_NO_MATCH ||
|
||||
blit_info->scissor_enable || blit_info->src.box.x != 0 ||
|
||||
blit_info->src.box.y != 0 || blit_info->dst.box.x != 0 ||
|
||||
blit_info->dst.box.y != 0 ||
|
||||
blit_info->dst.box.depth != blit_info->src.box.depth ||
|
||||
blit_info->dst.box.depth != 1) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Ensure that the Z coordinate is sane */
|
||||
if (dst->base.target != PIPE_TEXTURE_CUBE)
|
||||
assert(blit_info->dst.box.z == 0);
|
||||
if (src->base.target != PIPE_TEXTURE_CUBE)
|
||||
assert(blit_info->src.box.z == 0);
|
||||
|
||||
assert(blit_info->src.box.z < src->base.array_size);
|
||||
assert(blit_info->dst.box.z < dst->base.array_size);
|
||||
|
||||
struct etna_resource_level *src_lev = &src->levels[blit_info->src.level];
|
||||
struct etna_resource_level *dst_lev = &dst->levels[blit_info->dst.level];
|
||||
|
||||
/* we may be given coordinates up to the padded width to avoid
|
||||
* any alignment issues with different tiling formats */
|
||||
assert((blit_info->src.box.x + blit_info->src.box.width) * msaa_xscale <= src_lev->padded_width);
|
||||
assert((blit_info->src.box.y + blit_info->src.box.height) * msaa_yscale <= src_lev->padded_height);
|
||||
assert(blit_info->dst.box.x + blit_info->dst.box.width <= dst_lev->padded_width);
|
||||
assert(blit_info->dst.box.y + blit_info->dst.box.height <= dst_lev->padded_height);
|
||||
|
||||
unsigned src_offset =
|
||||
src_lev->offset + blit_info->src.box.z * src_lev->layer_stride;
|
||||
unsigned dst_offset =
|
||||
dst_lev->offset + blit_info->dst.box.z * dst_lev->layer_stride;
|
||||
|
||||
if (src_lev->padded_width <= ETNA_RS_WIDTH_MASK ||
|
||||
dst_lev->padded_width <= ETNA_RS_WIDTH_MASK ||
|
||||
src_lev->padded_height <= ETNA_RS_HEIGHT_MASK ||
|
||||
dst_lev->padded_height <= ETNA_RS_HEIGHT_MASK)
|
||||
goto manual;
|
||||
|
||||
/* If the width is not aligned to the RS width, but is within our
|
||||
* padding, adjust the width to suite the RS width restriction.
|
||||
* Note: the RS width/height are converted to source samples here. */
|
||||
unsigned int width = blit_info->src.box.width * msaa_xscale;
|
||||
unsigned int height = blit_info->src.box.height * msaa_yscale;
|
||||
unsigned int w_align = ETNA_RS_WIDTH_MASK + 1;
|
||||
unsigned int h_align = (ETNA_RS_HEIGHT_MASK + 1) * ctx->specs.pixel_pipes;
|
||||
|
||||
if (width & (w_align - 1) && width >= src_lev->width * msaa_xscale && width >= dst_lev->width)
|
||||
width = align(width, w_align);
|
||||
|
||||
if (height & (h_align - 1) && height >= src_lev->height * msaa_yscale && height >= dst_lev->height)
|
||||
height = align(height, h_align);
|
||||
|
||||
/* The padded dimensions are in samples */
|
||||
if (width > src_lev->padded_width ||
|
||||
width > dst_lev->padded_width * msaa_xscale ||
|
||||
height > src_lev->padded_height ||
|
||||
height > dst_lev->padded_height * msaa_yscale)
|
||||
goto manual;
|
||||
|
||||
if (src->base.nr_samples > 1) {
|
||||
uint32_t msaa_format = translate_msaa_format(src_format);
|
||||
assert(msaa_format != ETNA_NO_MATCH);
|
||||
ts_mem_config |= VIVS_TS_MEM_CONFIG_MSAA | msaa_format;
|
||||
}
|
||||
|
||||
uint32_t to_flush = 0;
|
||||
|
||||
if (src->base.bind & PIPE_BIND_RENDER_TARGET)
|
||||
to_flush |= VIVS_GL_FLUSH_CACHE_COLOR;
|
||||
if (src->base.bind & PIPE_BIND_DEPTH_STENCIL)
|
||||
to_flush |= VIVS_GL_FLUSH_CACHE_DEPTH;
|
||||
|
||||
if (to_flush) {
|
||||
etna_set_state(ctx->stream, VIVS_GL_FLUSH_CACHE, to_flush);
|
||||
etna_stall(ctx->stream, SYNC_RECIPIENT_RA, SYNC_RECIPIENT_PE);
|
||||
}
|
||||
|
||||
/* Set up color TS to source surface before blit, if needed */
|
||||
if (src->levels[blit_info->src.level].ts_size) {
|
||||
struct etna_reloc reloc;
|
||||
unsigned ts_offset =
|
||||
src_lev->ts_offset + blit_info->src.box.z * src_lev->ts_layer_stride;
|
||||
|
||||
etna_set_state(ctx->stream, VIVS_TS_MEM_CONFIG,
|
||||
VIVS_TS_MEM_CONFIG_COLOR_FAST_CLEAR | ts_mem_config);
|
||||
|
||||
memset(&reloc, 0, sizeof(struct etna_reloc));
|
||||
reloc.bo = src->ts_bo;
|
||||
reloc.offset = ts_offset;
|
||||
reloc.flags = ETNA_RELOC_READ;
|
||||
etna_set_state_reloc(ctx->stream, VIVS_TS_COLOR_STATUS_BASE, &reloc);
|
||||
|
||||
memset(&reloc, 0, sizeof(struct etna_reloc));
|
||||
reloc.bo = src->bo;
|
||||
reloc.offset = src_offset;
|
||||
reloc.flags = ETNA_RELOC_READ;
|
||||
etna_set_state_reloc(ctx->stream, VIVS_TS_COLOR_SURFACE_BASE, &reloc);
|
||||
|
||||
etna_set_state(ctx->stream, VIVS_TS_COLOR_CLEAR_VALUE,
|
||||
src->levels[blit_info->src.level].clear_value);
|
||||
} else {
|
||||
etna_set_state(ctx->stream, VIVS_TS_MEM_CONFIG, ts_mem_config);
|
||||
}
|
||||
ctx->dirty |= ETNA_DIRTY_TS;
|
||||
|
||||
/* Kick off RS here */
|
||||
etna_compile_rs_state(ctx, ©_to_screen, &(struct rs_state) {
|
||||
.source_format = translate_rs_format(src_format),
|
||||
.source_tiling = src->layout,
|
||||
.source = src->bo,
|
||||
.source_offset = src_offset,
|
||||
.source_stride = src_lev->stride,
|
||||
.source_padded_height = src_lev->padded_height,
|
||||
.dest_format = translate_rs_format(dst_format),
|
||||
.dest_tiling = dst->layout,
|
||||
.dest = dst->bo,
|
||||
.dest_offset = dst_offset,
|
||||
.dest_stride = dst_lev->stride,
|
||||
.dest_padded_height = dst_lev->padded_height,
|
||||
.downsample_x = msaa_xscale > 1,
|
||||
.downsample_y = msaa_yscale > 1,
|
||||
.swap_rb = translate_rb_src_dst_swap(src->base.format, dst->base.format),
|
||||
.dither = {0xffffffff, 0xffffffff}, // XXX dither when going from 24 to 16 bit?
|
||||
.clear_mode = VIVS_RS_CLEAR_CONTROL_MODE_DISABLED,
|
||||
.width = width,
|
||||
.height = height
|
||||
});
|
||||
|
||||
etna_submit_rs_state(ctx, ©_to_screen);
|
||||
resource_written(ctx, &dst->base);
|
||||
dst->seqno++;
|
||||
|
||||
return TRUE;
|
||||
|
||||
manual:
|
||||
if (src->layout == ETNA_LAYOUT_TILED && dst->layout == ETNA_LAYOUT_TILED) {
|
||||
etna_resource_wait(pctx, dst);
|
||||
etna_resource_wait(pctx, src);
|
||||
return etna_manual_blit(dst, dst_lev, dst_offset, src, src_lev, src_offset, blit_info);
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
etna_blit(struct pipe_context *pctx, const struct pipe_blit_info *blit_info)
|
||||
{
|
||||
/* This is a more extended version of resource_copy_region */
|
||||
/* TODO Some cases can be handled by RS; if not, fall back to rendering or
|
||||
* even CPU copy block of pixels from info->src to info->dst
|
||||
* (resource, level, box, format);
|
||||
* function is used for scaling, flipping in x and y direction (negative
|
||||
* width/height), format conversion, mask and filter and even a scissor rectangle
|
||||
*
|
||||
* What can the RS do for us:
|
||||
* convert between tiling formats (layouts)
|
||||
* downsample 2x in x and y
|
||||
* convert between a limited number of pixel formats
|
||||
*
|
||||
* For the rest, fall back to util_blitter
|
||||
* XXX this goes wrong when source surface is supertiled. */
|
||||
struct etna_context *ctx = etna_context(pctx);
|
||||
struct pipe_blit_info info = *blit_info;
|
||||
|
||||
if (info.src.resource->nr_samples > 1 &&
|
||||
info.dst.resource->nr_samples <= 1 &&
|
||||
!util_format_is_depth_or_stencil(info.src.resource->format) &&
|
||||
!util_format_is_pure_integer(info.src.resource->format)) {
|
||||
DBG("color resolve unimplemented");
|
||||
return;
|
||||
}
|
||||
|
||||
if (etna_try_rs_blit(pctx, blit_info))
|
||||
return;
|
||||
|
||||
if (util_try_blit_via_copy_region(pctx, blit_info))
|
||||
return;
|
||||
|
||||
if (info.mask & PIPE_MASK_S) {
|
||||
DBG("cannot blit stencil, skipping");
|
||||
info.mask &= ~PIPE_MASK_S;
|
||||
}
|
||||
|
||||
if (!util_blitter_is_blit_supported(ctx->blitter, &info)) {
|
||||
DBG("blit unsupported %s -> %s",
|
||||
util_format_short_name(info.src.resource->format),
|
||||
util_format_short_name(info.dst.resource->format));
|
||||
return;
|
||||
}
|
||||
|
||||
etna_blit_save_state(ctx);
|
||||
util_blitter_blit(ctx->blitter, &info);
|
||||
}
|
||||
|
||||
static void
|
||||
etna_flush_resource(struct pipe_context *pctx, struct pipe_resource *prsc)
|
||||
{
|
||||
struct etna_resource *rsc = etna_resource(prsc);
|
||||
|
||||
if (rsc->scanout)
|
||||
etna_copy_resource(pctx, rsc->scanout->prime, prsc, 0, 0);
|
||||
}
|
||||
|
||||
void
|
||||
etna_copy_resource(struct pipe_context *pctx, struct pipe_resource *dst,
|
||||
struct pipe_resource *src, int first_level, int last_level)
|
||||
{
|
||||
struct etna_resource *src_priv = etna_resource(src);
|
||||
struct etna_resource *dst_priv = etna_resource(dst);
|
||||
|
||||
assert(src->format == dst->format);
|
||||
assert(src->array_size == dst->array_size);
|
||||
assert(last_level <= dst->last_level && last_level <= src->last_level);
|
||||
|
||||
struct pipe_blit_info blit = {};
|
||||
blit.mask = util_format_get_mask(dst->format);
|
||||
blit.filter = PIPE_TEX_FILTER_NEAREST;
|
||||
blit.src.resource = src;
|
||||
blit.src.format = src->format;
|
||||
blit.dst.resource = dst;
|
||||
blit.dst.format = dst->format;
|
||||
blit.dst.box.depth = blit.src.box.depth = 1;
|
||||
|
||||
/* Copy each level and each layer */
|
||||
for (int level = first_level; level <= last_level; level++) {
|
||||
blit.src.level = blit.dst.level = level;
|
||||
blit.src.box.width = blit.dst.box.width =
|
||||
MIN2(src_priv->levels[level].width, dst_priv->levels[level].width);
|
||||
blit.src.box.height = blit.dst.box.height =
|
||||
MIN2(src_priv->levels[level].height, dst_priv->levels[level].height);
|
||||
|
||||
for (int layer = 0; layer < dst->array_size; layer++) {
|
||||
blit.src.box.z = blit.dst.box.z = layer;
|
||||
pctx->blit(pctx, &blit);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
etna_clear_blit_init(struct pipe_context *pctx)
|
||||
{
|
||||
pctx->clear = etna_clear;
|
||||
pctx->clear_render_target = etna_clear_render_target;
|
||||
pctx->clear_depth_stencil = etna_clear_depth_stencil;
|
||||
pctx->resource_copy_region = etna_resource_copy_region;
|
||||
pctx->blit = etna_blit;
|
||||
pctx->flush_resource = etna_flush_resource;
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2013 Etnaviv Project
|
||||
*
|
||||
* 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, sub license,
|
||||
* 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 NON-INFRINGEMENT. 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:
|
||||
* Wladimir J. van der Laan <laanwj@gmail.com>
|
||||
*/
|
||||
|
||||
#ifndef H_ETNAVIV_CLEAR_BLIT
|
||||
#define H_ETNAVIV_CLEAR_BLIT
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
struct etna_context;
|
||||
struct etna_surface;
|
||||
|
||||
#include "pipe/p_context.h"
|
||||
|
||||
void
|
||||
etna_rs_gen_clear_surface(struct etna_context *ctx, struct etna_surface *surf,
|
||||
uint32_t clear_value);
|
||||
|
||||
void
|
||||
etna_copy_resource(struct pipe_context *pctx, struct pipe_resource *dst,
|
||||
struct pipe_resource *src, int first_level, int last_level);
|
||||
|
||||
void
|
||||
etna_clear_blit_init(struct pipe_context *pctx);
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,120 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2015 Etnaviv Project
|
||||
*
|
||||
* 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, sub license,
|
||||
* 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 NON-INFRINGEMENT. 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:
|
||||
* Wladimir J. van der Laan <laanwj@gmail.com>
|
||||
*/
|
||||
|
||||
#ifndef H_ETNAVIV_COMPILER
|
||||
#define H_ETNAVIV_COMPILER
|
||||
|
||||
#include "etnaviv_context.h"
|
||||
#include "etnaviv_internal.h"
|
||||
#include "pipe/p_compiler.h"
|
||||
#include "pipe/p_shader_tokens.h"
|
||||
|
||||
/* XXX some of these are pretty arbitrary limits, may be better to switch
|
||||
* to dynamic allocation at some point.
|
||||
*/
|
||||
#define ETNA_MAX_TEMPS (64) /* max temp register count of all Vivante hw */
|
||||
#define ETNA_MAX_TOKENS (2048)
|
||||
#define ETNA_MAX_IMM (1024) /* max const+imm in 32-bit words */
|
||||
#define ETNA_MAX_DECL (2048) /* max declarations */
|
||||
#define ETNA_MAX_DEPTH (32)
|
||||
#define ETNA_MAX_INSTRUCTIONS (2048)
|
||||
|
||||
/* compiler output per input/output */
|
||||
struct etna_shader_inout {
|
||||
int reg; /* native register */
|
||||
struct tgsi_declaration_semantic semantic; /* tgsi semantic name and index */
|
||||
int num_components;
|
||||
};
|
||||
|
||||
struct etna_shader_io_file {
|
||||
size_t num_reg;
|
||||
struct etna_shader_inout reg[ETNA_NUM_INPUTS];
|
||||
};
|
||||
|
||||
/* shader object, for linking */
|
||||
struct etna_shader {
|
||||
uint processor; /* TGSI_PROCESSOR_... */
|
||||
uint32_t code_size; /* code size in uint32 words */
|
||||
uint32_t *code;
|
||||
unsigned num_temps;
|
||||
|
||||
struct etna_shader_uniform_info uniforms;
|
||||
|
||||
/* ETNA_DIRTY_* flags that, when set in context dirty, mean that the
|
||||
* uniforms have to get (partial) reloaded. */
|
||||
uint32_t uniforms_dirty_bits;
|
||||
|
||||
/* inputs (for linking) for fs, the inputs must be in register 1..N */
|
||||
struct etna_shader_io_file infile;
|
||||
|
||||
/* outputs (for linking) */
|
||||
struct etna_shader_io_file outfile;
|
||||
|
||||
/* index into outputs (for linking) */
|
||||
int output_count_per_semantic[TGSI_SEMANTIC_COUNT];
|
||||
struct etna_shader_inout * *output_per_semantic_list; /* list of pointers to outputs */
|
||||
struct etna_shader_inout **output_per_semantic[TGSI_SEMANTIC_COUNT];
|
||||
|
||||
/* special outputs (vs only) */
|
||||
int vs_pos_out_reg; /* VS position output */
|
||||
int vs_pointsize_out_reg; /* VS point size output */
|
||||
uint32_t vs_load_balancing;
|
||||
|
||||
/* special outputs (ps only) */
|
||||
int ps_color_out_reg; /* color output register */
|
||||
int ps_depth_out_reg; /* depth output register */
|
||||
|
||||
/* unknown input property (XX_INPUT_COUNT, field UNK8) */
|
||||
uint32_t input_count_unk8;
|
||||
};
|
||||
|
||||
struct etna_varying {
|
||||
uint32_t pa_attributes;
|
||||
uint8_t num_components;
|
||||
uint8_t use[4];
|
||||
uint8_t reg;
|
||||
};
|
||||
|
||||
struct etna_shader_link_info {
|
||||
/* each PS input is annotated with the VS output reg */
|
||||
unsigned num_varyings;
|
||||
struct etna_varying varyings[ETNA_NUM_INPUTS];
|
||||
};
|
||||
|
||||
struct etna_shader *
|
||||
etna_compile_shader(const struct etna_specs *specs, const struct tgsi_token *tokens);
|
||||
|
||||
void
|
||||
etna_dump_shader(const struct etna_shader *shader);
|
||||
|
||||
bool
|
||||
etna_link_shader(struct etna_shader_link_info *info,
|
||||
const struct etna_shader *vs, const struct etna_shader *fs);
|
||||
|
||||
void
|
||||
etna_destroy_shader(struct etna_shader *shader);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,146 @@
|
|||
/*
|
||||
* Copyright (c) 2015 Etnaviv Project
|
||||
*
|
||||
* 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, sub license,
|
||||
* 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 NON-INFRINGEMENT. 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>
|
||||
* Christian Gmeiner <christian.gmeiner@gmail.com>
|
||||
*/
|
||||
|
||||
#include <err.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "tgsi/tgsi_dump.h"
|
||||
#include "tgsi/tgsi_parse.h"
|
||||
#include "tgsi/tgsi_text.h"
|
||||
|
||||
#include "etnaviv_compiler.h"
|
||||
#include "etnaviv_debug.h"
|
||||
#include "etnaviv_internal.h"
|
||||
|
||||
static const struct etna_specs specs_gc2000 = {
|
||||
.vs_need_z_div = 0,
|
||||
.has_sin_cos_sqrt = 1,
|
||||
.has_sign_floor_ceil = 1,
|
||||
.vertex_sampler_offset = 8,
|
||||
.vertex_output_buffer_size = 512,
|
||||
.vertex_cache_size = 16,
|
||||
.shader_core_count = 4,
|
||||
.max_instructions = 512,
|
||||
.max_varyings = 12,
|
||||
.max_registers = 64,
|
||||
.max_vs_uniforms = 168,
|
||||
.max_ps_uniforms = 128,
|
||||
.num_constants = 168,
|
||||
};
|
||||
|
||||
static int
|
||||
read_file(const char *filename, void **ptr, size_t *size)
|
||||
{
|
||||
int fd, ret;
|
||||
struct stat st;
|
||||
|
||||
*ptr = MAP_FAILED;
|
||||
|
||||
fd = open(filename, O_RDONLY);
|
||||
if (fd == -1) {
|
||||
warnx("couldn't open `%s'", filename);
|
||||
return 1;
|
||||
}
|
||||
|
||||
ret = fstat(fd, &st);
|
||||
if (ret)
|
||||
errx(1, "couldn't stat `%s'", filename);
|
||||
|
||||
*size = st.st_size;
|
||||
*ptr = mmap(NULL, st.st_size, PROT_READ, MAP_SHARED, fd, 0);
|
||||
if (*ptr == MAP_FAILED)
|
||||
errx(1, "couldn't map `%s'", filename);
|
||||
|
||||
close(fd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
print_usage(void)
|
||||
{
|
||||
printf("Usage: etnaviv_compiler [OPTIONS]... FILE\n");
|
||||
printf(" --verbose - verbose compiler/debug messages\n");
|
||||
printf(" --help - show this message\n");
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
int ret = 0, n = 1;
|
||||
const char *filename;
|
||||
struct tgsi_token toks[65536];
|
||||
struct tgsi_parse_context parse;
|
||||
struct etna_shader *shader_obj;
|
||||
void *ptr;
|
||||
size_t size;
|
||||
|
||||
etna_mesa_debug = ETNA_DBG_MSGS;
|
||||
|
||||
while (n < argc) {
|
||||
if (!strcmp(argv[n], "--verbose")) {
|
||||
etna_mesa_debug |= ETNA_DBG_COMPILER_MSGS;
|
||||
n++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!strcmp(argv[n], "--help")) {
|
||||
print_usage();
|
||||
return 0;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
filename = argv[n];
|
||||
|
||||
ret = read_file(filename, &ptr, &size);
|
||||
if (ret) {
|
||||
print_usage();
|
||||
return ret;
|
||||
}
|
||||
|
||||
debug_printf("%s\n", (char *)ptr);
|
||||
|
||||
if (!tgsi_text_translate(ptr, toks, ARRAY_SIZE(toks)))
|
||||
errx(1, "could not parse `%s'", filename);
|
||||
|
||||
tgsi_parse_init(&parse, toks);
|
||||
|
||||
shader_obj = etna_compile_shader(&specs_gc2000, toks);
|
||||
|
||||
if (shader_obj == NULL) {
|
||||
fprintf(stderr, "compiler failed!\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
etna_dump_shader(shader_obj);
|
||||
etna_destroy_shader(shader_obj);
|
||||
}
|
|
@ -0,0 +1,323 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2015 Etnaviv Project
|
||||
*
|
||||
* 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, sub license,
|
||||
* 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 NON-INFRINGEMENT. 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:
|
||||
* Wladimir J. van der Laan <laanwj@gmail.com>
|
||||
* Christian Gmeiner <christian.gmeiner@gmail.com>
|
||||
*/
|
||||
|
||||
#include "etnaviv_context.h"
|
||||
|
||||
#include "etnaviv_blend.h"
|
||||
#include "etnaviv_clear_blit.h"
|
||||
#include "etnaviv_compiler.h"
|
||||
#include "etnaviv_debug.h"
|
||||
#include "etnaviv_emit.h"
|
||||
#include "etnaviv_fence.h"
|
||||
#include "etnaviv_query.h"
|
||||
#include "etnaviv_rasterizer.h"
|
||||
#include "etnaviv_screen.h"
|
||||
#include "etnaviv_shader.h"
|
||||
#include "etnaviv_state.h"
|
||||
#include "etnaviv_surface.h"
|
||||
#include "etnaviv_texture.h"
|
||||
#include "etnaviv_transfer.h"
|
||||
#include "etnaviv_translate.h"
|
||||
#include "etnaviv_zsa.h"
|
||||
|
||||
#include "pipe/p_context.h"
|
||||
#include "pipe/p_state.h"
|
||||
#include "util/u_blitter.h"
|
||||
#include "util/u_memory.h"
|
||||
#include "util/u_prim.h"
|
||||
|
||||
#include "hw/common.xml.h"
|
||||
|
||||
static void
|
||||
etna_context_destroy(struct pipe_context *pctx)
|
||||
{
|
||||
struct etna_context *ctx = etna_context(pctx);
|
||||
|
||||
if (ctx->primconvert)
|
||||
util_primconvert_destroy(ctx->primconvert);
|
||||
|
||||
if (ctx->blitter)
|
||||
util_blitter_destroy(ctx->blitter);
|
||||
|
||||
if (ctx->stream)
|
||||
etna_cmd_stream_del(ctx->stream);
|
||||
|
||||
slab_destroy_child(&ctx->transfer_pool);
|
||||
|
||||
FREE(pctx);
|
||||
}
|
||||
|
||||
/* Update render state where needed based on draw operation */
|
||||
static void
|
||||
etna_update_state_for_draw(struct etna_context *ctx, const struct pipe_draw_info *info)
|
||||
{
|
||||
/* Handle primitive restart:
|
||||
* - If not an indexed draw, we don't care about the state of the primitive restart bit.
|
||||
* - Otherwise, set the bit in INDEX_STREAM_CONTROL in the index buffer state
|
||||
* accordingly
|
||||
* - If the value of the INDEX_STREAM_CONTROL register changed due to this, or
|
||||
* primitive restart is enabled and the restart index changed, mark the index
|
||||
* buffer state as dirty
|
||||
*/
|
||||
|
||||
if (info->indexed) {
|
||||
uint32_t new_control = ctx->index_buffer.FE_INDEX_STREAM_CONTROL;
|
||||
|
||||
if (info->primitive_restart)
|
||||
new_control |= VIVS_FE_INDEX_STREAM_CONTROL_PRIMITIVE_RESTART;
|
||||
else
|
||||
new_control &= ~VIVS_FE_INDEX_STREAM_CONTROL_PRIMITIVE_RESTART;
|
||||
|
||||
if (ctx->index_buffer.FE_INDEX_STREAM_CONTROL != new_control ||
|
||||
(info->primitive_restart && ctx->index_buffer.FE_PRIMITIVE_RESTART_INDEX != info->restart_index)) {
|
||||
ctx->index_buffer.FE_INDEX_STREAM_CONTROL = new_control;
|
||||
ctx->index_buffer.FE_PRIMITIVE_RESTART_INDEX = info->restart_index;
|
||||
ctx->dirty |= ETNA_DIRTY_INDEX_BUFFER;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
etna_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info)
|
||||
{
|
||||
struct etna_context *ctx = etna_context(pctx);
|
||||
struct pipe_framebuffer_state *pfb = &ctx->framebuffer_s;
|
||||
uint32_t draw_mode;
|
||||
unsigned i;
|
||||
|
||||
if (ctx->vertex_elements == NULL || ctx->vertex_elements->num_elements == 0)
|
||||
return; /* Nothing to do */
|
||||
|
||||
if (!(ctx->prim_hwsupport & (1 << info->mode))) {
|
||||
struct primconvert_context *primconvert = ctx->primconvert;
|
||||
util_primconvert_save_index_buffer(primconvert, &ctx->index_buffer.ib);
|
||||
util_primconvert_save_rasterizer_state(primconvert, ctx->rasterizer);
|
||||
util_primconvert_draw_vbo(primconvert, info);
|
||||
return;
|
||||
}
|
||||
|
||||
int prims = u_decomposed_prims_for_vertices(info->mode, info->count);
|
||||
if (unlikely(prims <= 0)) {
|
||||
DBG("Invalid draw primitive mode=%i or no primitives to be drawn", info->mode);
|
||||
return;
|
||||
}
|
||||
|
||||
draw_mode = translate_draw_mode(info->mode);
|
||||
if (draw_mode == ETNA_NO_MATCH) {
|
||||
BUG("Unsupported draw mode");
|
||||
return;
|
||||
}
|
||||
|
||||
if (info->indexed && !ctx->index_buffer.FE_INDEX_STREAM_BASE_ADDR.bo) {
|
||||
BUG("Unsupported or no index buffer");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Update any derived state */
|
||||
if (!etna_state_update(ctx))
|
||||
return;
|
||||
|
||||
/*
|
||||
* Figure out the buffers/features we need:
|
||||
*/
|
||||
if (etna_depth_enabled(ctx))
|
||||
resource_written(ctx, pfb->zsbuf->texture);
|
||||
|
||||
if (etna_stencil_enabled(ctx))
|
||||
resource_written(ctx, pfb->zsbuf->texture);
|
||||
|
||||
for (i = 0; i < pfb->nr_cbufs; i++) {
|
||||
struct pipe_resource *surf;
|
||||
|
||||
if (!pfb->cbufs[i])
|
||||
continue;
|
||||
|
||||
surf = pfb->cbufs[i]->texture;
|
||||
resource_written(ctx, surf);
|
||||
}
|
||||
|
||||
/* Mark constant buffers as being read */
|
||||
resource_read(ctx, ctx->constant_buffer[PIPE_SHADER_VERTEX].buffer);
|
||||
resource_read(ctx, ctx->constant_buffer[PIPE_SHADER_FRAGMENT].buffer);
|
||||
|
||||
/* Mark VBOs as being read */
|
||||
for (i = 0; i < ctx->vertex_buffer.count; i++) {
|
||||
assert(!ctx->vertex_buffer.vb[i].user_buffer);
|
||||
resource_read(ctx, ctx->vertex_buffer.vb[i].buffer);
|
||||
}
|
||||
|
||||
/* Mark index buffer as being read */
|
||||
resource_read(ctx, ctx->index_buffer.ib.buffer);
|
||||
|
||||
/* Mark textures as being read */
|
||||
for (i = 0; i < PIPE_MAX_SAMPLERS; i++)
|
||||
if (ctx->sampler_view[i])
|
||||
resource_read(ctx, ctx->sampler_view[i]->texture);
|
||||
|
||||
ctx->stats.prims_emitted += u_reduced_prims_for_vertices(info->mode, info->count);
|
||||
ctx->stats.draw_calls++;
|
||||
|
||||
/* Update state for this draw operation */
|
||||
etna_update_state_for_draw(ctx, info);
|
||||
|
||||
/* First, sync state, then emit DRAW_PRIMITIVES or DRAW_INDEXED_PRIMITIVES */
|
||||
etna_emit_state(ctx);
|
||||
|
||||
if (info->indexed)
|
||||
etna_draw_indexed_primitives(ctx->stream, draw_mode, info->start, prims, info->index_bias);
|
||||
else
|
||||
etna_draw_primitives(ctx->stream, draw_mode, info->start, prims);
|
||||
|
||||
if (DBG_ENABLED(ETNA_DBG_DRAW_STALL)) {
|
||||
/* Stall the FE after every draw operation. This allows better
|
||||
* debug of GPU hang conditions, as the FE will indicate which
|
||||
* draw op has caused the hang. */
|
||||
etna_stall(ctx->stream, SYNC_RECIPIENT_FE, SYNC_RECIPIENT_PE);
|
||||
}
|
||||
|
||||
if (DBG_ENABLED(ETNA_DBG_FLUSH_ALL))
|
||||
pctx->flush(pctx, NULL, 0);
|
||||
|
||||
if (ctx->framebuffer.cbuf)
|
||||
etna_resource(ctx->framebuffer.cbuf->texture)->seqno++;
|
||||
if (ctx->framebuffer.zsbuf)
|
||||
etna_resource(ctx->framebuffer.zsbuf->texture)->seqno++;
|
||||
}
|
||||
|
||||
static void
|
||||
etna_flush(struct pipe_context *pctx, struct pipe_fence_handle **fence,
|
||||
enum pipe_flush_flags flags)
|
||||
{
|
||||
struct etna_context *ctx = etna_context(pctx);
|
||||
|
||||
etna_cmd_stream_flush(ctx->stream);
|
||||
|
||||
if (fence)
|
||||
*fence = etna_fence_create(pctx);
|
||||
}
|
||||
|
||||
static void
|
||||
etna_cmd_stream_reset_notify(struct etna_cmd_stream *stream, void *priv)
|
||||
{
|
||||
struct etna_context *ctx = priv;
|
||||
struct etna_resource *rsc, *rsc_tmp;
|
||||
|
||||
etna_set_state(stream, VIVS_GL_API_MODE, VIVS_GL_API_MODE_OPENGL);
|
||||
etna_set_state(stream, VIVS_GL_VERTEX_ELEMENT_CONFIG, 0x00000001);
|
||||
etna_set_state(stream, VIVS_RA_EARLY_DEPTH, 0x00000031);
|
||||
etna_set_state(stream, VIVS_PA_W_CLIP_LIMIT, 0x34000001);
|
||||
|
||||
ctx->dirty = ~0L;
|
||||
|
||||
/* go through all the used resources and clear their status flag */
|
||||
LIST_FOR_EACH_ENTRY_SAFE(rsc, rsc_tmp, &ctx->used_resources, list)
|
||||
{
|
||||
debug_assert(rsc->status != 0);
|
||||
rsc->status = 0;
|
||||
rsc->pending_ctx = NULL;
|
||||
list_delinit(&rsc->list);
|
||||
}
|
||||
|
||||
assert(LIST_IS_EMPTY(&ctx->used_resources));
|
||||
}
|
||||
|
||||
struct pipe_context *
|
||||
etna_context_create(struct pipe_screen *pscreen, void *priv, unsigned flags)
|
||||
{
|
||||
struct etna_context *ctx = CALLOC_STRUCT(etna_context);
|
||||
struct etna_screen *screen;
|
||||
struct pipe_context *pctx = NULL;
|
||||
|
||||
if (ctx == NULL)
|
||||
return NULL;
|
||||
|
||||
screen = etna_screen(pscreen);
|
||||
ctx->stream = etna_cmd_stream_new(screen->pipe, 0x2000, &etna_cmd_stream_reset_notify, ctx);
|
||||
if (ctx->stream == NULL)
|
||||
goto fail;
|
||||
|
||||
pctx = &ctx->base;
|
||||
pctx->priv = ctx;
|
||||
pctx->screen = pscreen;
|
||||
|
||||
/* context ctxate setup */
|
||||
ctx->specs = screen->specs;
|
||||
ctx->screen = screen;
|
||||
/* need some sane default in case state tracker doesn't set some state: */
|
||||
ctx->sample_mask = 0xffff;
|
||||
|
||||
list_inithead(&ctx->used_resources);
|
||||
|
||||
/* Set sensible defaults for state */
|
||||
etna_cmd_stream_reset_notify(ctx->stream, ctx);
|
||||
|
||||
pctx->destroy = etna_context_destroy;
|
||||
pctx->draw_vbo = etna_draw_vbo;
|
||||
pctx->flush = etna_flush;
|
||||
|
||||
/* creation of compile states */
|
||||
pctx->create_blend_state = etna_blend_state_create;
|
||||
pctx->create_rasterizer_state = etna_rasterizer_state_create;
|
||||
pctx->create_depth_stencil_alpha_state = etna_zsa_state_create;
|
||||
|
||||
etna_clear_blit_init(pctx);
|
||||
etna_query_context_init(pctx);
|
||||
etna_state_init(pctx);
|
||||
etna_surface_init(pctx);
|
||||
etna_shader_init(pctx);
|
||||
etna_texture_init(pctx);
|
||||
etna_transfer_init(pctx);
|
||||
|
||||
ctx->blitter = util_blitter_create(pctx);
|
||||
if (!ctx->blitter)
|
||||
goto fail;
|
||||
|
||||
/* Generate the bitmask of supported draw primitives. */
|
||||
ctx->prim_hwsupport = 1 << PIPE_PRIM_POINTS |
|
||||
1 << PIPE_PRIM_LINES |
|
||||
1 << PIPE_PRIM_LINE_STRIP |
|
||||
1 << PIPE_PRIM_TRIANGLES |
|
||||
1 << PIPE_PRIM_TRIANGLE_STRIP |
|
||||
1 << PIPE_PRIM_TRIANGLE_FAN;
|
||||
|
||||
if (VIV_FEATURE(ctx->screen, chipMinorFeatures2, LINE_LOOP))
|
||||
ctx->prim_hwsupport |= 1 << PIPE_PRIM_LINE_LOOP;
|
||||
|
||||
ctx->primconvert = util_primconvert_create(pctx, ctx->prim_hwsupport);
|
||||
if (!ctx->primconvert)
|
||||
goto fail;
|
||||
|
||||
slab_create_child(&ctx->transfer_pool, &screen->transfer_pool);
|
||||
|
||||
return pctx;
|
||||
|
||||
fail:
|
||||
pctx->destroy(pctx);
|
||||
|
||||
return NULL;
|
||||
}
|
|
@ -0,0 +1,194 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2015 Etnaviv Project
|
||||
*
|
||||
* 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, sub license,
|
||||
* 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 NON-INFRINGEMENT. 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:
|
||||
* Wladimir J. van der Laan <laanwj@gmail.com>
|
||||
* Christian Gmeiner <christian.gmeiner@gmail.com>
|
||||
*/
|
||||
|
||||
#ifndef H_ETNAVIV_CONTEXT
|
||||
#define H_ETNAVIV_CONTEXT
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "etnaviv_resource.h"
|
||||
#include "etnaviv_tiling.h"
|
||||
#include "indices/u_primconvert.h"
|
||||
#include "pipe/p_context.h"
|
||||
#include "pipe/p_defines.h"
|
||||
#include "pipe/p_format.h"
|
||||
#include "pipe/p_shader_tokens.h"
|
||||
#include "pipe/p_state.h"
|
||||
#include "util/slab.h"
|
||||
|
||||
struct pipe_screen;
|
||||
struct etna_shader;
|
||||
|
||||
struct etna_index_buffer {
|
||||
struct pipe_index_buffer ib;
|
||||
struct etna_reloc FE_INDEX_STREAM_BASE_ADDR;
|
||||
uint32_t FE_INDEX_STREAM_CONTROL;
|
||||
uint32_t FE_PRIMITIVE_RESTART_INDEX;
|
||||
};
|
||||
|
||||
struct etna_shader_input {
|
||||
int vs_reg; /* VS input register */
|
||||
};
|
||||
|
||||
enum etna_varying_special {
|
||||
ETNA_VARYING_VSOUT = 0, /* from VS */
|
||||
ETNA_VARYING_POINTCOORD, /* point texture coord */
|
||||
};
|
||||
|
||||
struct etna_shader_varying {
|
||||
int num_components;
|
||||
enum etna_varying_special special;
|
||||
int pa_attributes;
|
||||
int vs_reg; /* VS output register */
|
||||
};
|
||||
|
||||
struct etna_transfer {
|
||||
struct pipe_transfer base;
|
||||
struct pipe_resource *rsc;
|
||||
void *staging;
|
||||
};
|
||||
|
||||
struct etna_vertexbuf_state {
|
||||
struct pipe_vertex_buffer vb[PIPE_MAX_ATTRIBS];
|
||||
struct compiled_set_vertex_buffer cvb[PIPE_MAX_ATTRIBS];
|
||||
unsigned count;
|
||||
uint32_t enabled_mask;
|
||||
};
|
||||
|
||||
enum etna_immediate_contents {
|
||||
ETNA_IMMEDIATE_UNUSED = 0,
|
||||
ETNA_IMMEDIATE_CONSTANT,
|
||||
ETNA_IMMEDIATE_TEXRECT_SCALE_X,
|
||||
ETNA_IMMEDIATE_TEXRECT_SCALE_Y,
|
||||
};
|
||||
|
||||
struct etna_shader_uniform_info {
|
||||
enum etna_immediate_contents *imm_contents;
|
||||
uint32_t *imm_data;
|
||||
uint32_t imm_count;
|
||||
uint32_t const_count;
|
||||
};
|
||||
|
||||
struct etna_context {
|
||||
struct pipe_context base;
|
||||
|
||||
struct etna_specs specs;
|
||||
struct etna_screen *screen;
|
||||
struct etna_cmd_stream *stream;
|
||||
|
||||
/* which state objects need to be re-emit'd: */
|
||||
enum {
|
||||
ETNA_DIRTY_BLEND = (1 << 0),
|
||||
ETNA_DIRTY_SAMPLERS = (1 << 1),
|
||||
ETNA_DIRTY_RASTERIZER = (1 << 2),
|
||||
ETNA_DIRTY_ZSA = (1 << 3),
|
||||
ETNA_DIRTY_VERTEX_ELEMENTS = (1 << 4),
|
||||
ETNA_DIRTY_BLEND_COLOR = (1 << 6),
|
||||
ETNA_DIRTY_STENCIL_REF = (1 << 7),
|
||||
ETNA_DIRTY_SAMPLE_MASK = (1 << 8),
|
||||
ETNA_DIRTY_VIEWPORT = (1 << 9),
|
||||
ETNA_DIRTY_FRAMEBUFFER = (1 << 10),
|
||||
ETNA_DIRTY_SCISSOR = (1 << 11),
|
||||
ETNA_DIRTY_SAMPLER_VIEWS = (1 << 12),
|
||||
ETNA_DIRTY_CONSTBUF = (1 << 13),
|
||||
ETNA_DIRTY_VERTEX_BUFFERS = (1 << 14),
|
||||
ETNA_DIRTY_INDEX_BUFFER = (1 << 15),
|
||||
ETNA_DIRTY_SHADER = (1 << 16),
|
||||
ETNA_DIRTY_TS = (1 << 17),
|
||||
ETNA_DIRTY_TEXTURE_CACHES = (1 << 18),
|
||||
} dirty;
|
||||
|
||||
uint32_t prim_hwsupport;
|
||||
struct primconvert_context *primconvert;
|
||||
|
||||
/* list of resources used by currently-unsubmitted renders */
|
||||
struct list_head used_resources;
|
||||
|
||||
struct slab_child_pool transfer_pool;
|
||||
struct blitter_context *blitter;
|
||||
|
||||
/* compiled bindable state */
|
||||
unsigned sample_mask;
|
||||
struct pipe_blend_state *blend;
|
||||
unsigned num_fragment_samplers;
|
||||
uint32_t active_samplers;
|
||||
struct pipe_sampler_state *sampler[PIPE_MAX_SAMPLERS];
|
||||
struct pipe_rasterizer_state *rasterizer;
|
||||
struct pipe_depth_stencil_alpha_state *zsa;
|
||||
struct compiled_vertex_elements_state *vertex_elements;
|
||||
struct compiled_shader_state shader_state;
|
||||
|
||||
/* to simplify the emit process we store pre compiled state objects,
|
||||
* which got 'compiled' during state change. */
|
||||
struct compiled_blend_color blend_color;
|
||||
struct compiled_stencil_ref stencil_ref;
|
||||
struct compiled_framebuffer_state framebuffer;
|
||||
struct compiled_scissor_state scissor;
|
||||
struct compiled_viewport_state viewport;
|
||||
unsigned num_fragment_sampler_views;
|
||||
uint32_t active_sampler_views;
|
||||
struct pipe_sampler_view *sampler_view[PIPE_MAX_SAMPLERS];
|
||||
struct pipe_constant_buffer constant_buffer[PIPE_SHADER_TYPES];
|
||||
struct etna_vertexbuf_state vertex_buffer;
|
||||
struct etna_index_buffer index_buffer;
|
||||
|
||||
/* pointers to the bound state. these are mainly kept around for the blitter */
|
||||
struct etna_shader *vs;
|
||||
struct etna_shader *fs;
|
||||
|
||||
/* saved parameter-like state. these are mainly kept around for the blitter */
|
||||
struct pipe_framebuffer_state framebuffer_s;
|
||||
struct pipe_stencil_ref stencil_ref_s;
|
||||
struct pipe_viewport_state viewport_s;
|
||||
struct pipe_scissor_state scissor_s;
|
||||
|
||||
/* cached state of entire GPU */
|
||||
struct etna_3d_state gpu3d;
|
||||
|
||||
/* stats/counters */
|
||||
struct {
|
||||
uint64_t prims_emitted;
|
||||
uint64_t draw_calls;
|
||||
} stats;
|
||||
};
|
||||
|
||||
static inline struct etna_context *
|
||||
etna_context(struct pipe_context *pctx)
|
||||
{
|
||||
return (struct etna_context *)pctx;
|
||||
}
|
||||
|
||||
static inline struct etna_transfer *
|
||||
etna_transfer(struct pipe_transfer *p)
|
||||
{
|
||||
return (struct etna_transfer *)p;
|
||||
}
|
||||
|
||||
struct pipe_context *
|
||||
etna_context_create(struct pipe_screen *pscreen, void *priv, unsigned flags);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,79 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2013 Etnaviv Project
|
||||
*
|
||||
* 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, sub license,
|
||||
* 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 NON-INFRINGEMENT. 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.
|
||||
*/
|
||||
|
||||
/* Common debug stuffl */
|
||||
#ifndef H_ETNA_DEBUG
|
||||
#define H_ETNA_DEBUG
|
||||
|
||||
#include "util/u_debug.h"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/* Logging */
|
||||
#define ETNA_DBG_MSGS 0x1 /* Warnings and non-fatal errors */
|
||||
#define ETNA_DBG_FRAME_MSGS 0x2
|
||||
#define ETNA_DBG_RESOURCE_MSGS 0x4
|
||||
#define ETNA_DBG_COMPILER_MSGS 0x8
|
||||
#define ETNA_DBG_LINKER_MSGS 0x10
|
||||
#define ETNA_DBG_DUMP_SHADERS 0x20
|
||||
|
||||
/* Bypasses */
|
||||
#define ETNA_DBG_NO_TS 0x1000 /* Disable TS */
|
||||
#define ETNA_DBG_NO_AUTODISABLE 0x2000 /* Disable autodisable */
|
||||
#define ETNA_DBG_NO_SUPERTILE 0x4000 /* Disable supertile */
|
||||
#define ETNA_DBG_NO_EARLY_Z 0x8000 /* Disable early z */
|
||||
#define ETNA_DBG_CFLUSH_ALL 0x10000 /* Flush before every state update + draw call */
|
||||
#define ETNA_DBG_MSAA_2X 0x20000 /* Force 2X MSAA for screen */
|
||||
#define ETNA_DBG_MSAA_4X 0x40000 /* Force 4X MSAA for screen */
|
||||
#define ETNA_DBG_FINISH_ALL 0x80000 /* Finish on every flush */
|
||||
#define ETNA_DBG_FLUSH_ALL 0x100000 /* Flush after every rendered primitive */
|
||||
#define ETNA_DBG_ZERO 0x200000 /* Zero all resources after allocation */
|
||||
#define ETNA_DBG_DRAW_STALL 0x400000 /* Stall FE/PE after every draw op */
|
||||
|
||||
extern int etna_mesa_debug; /* set in etna_screen.c from ETNA_DEBUG */
|
||||
|
||||
#define DBG_ENABLED(flag) unlikely(etna_mesa_debug & (flag))
|
||||
|
||||
#define DBG_F(flag, fmt, ...) \
|
||||
do { \
|
||||
if (etna_mesa_debug & (flag)) \
|
||||
debug_printf("%s:%d: " fmt "\n", __FUNCTION__, __LINE__, \
|
||||
##__VA_ARGS__); \
|
||||
} while (0)
|
||||
|
||||
#define DBG(fmt, ...) \
|
||||
do { \
|
||||
if (etna_mesa_debug & ETNA_DBG_MSGS) \
|
||||
debug_printf("%s:%d: " fmt "\n", __FUNCTION__, __LINE__, \
|
||||
##__VA_ARGS__); \
|
||||
} while (0)
|
||||
|
||||
/* A serious bug, show this even in non-debug mode */
|
||||
#define BUG(fmt, ...) \
|
||||
do { \
|
||||
printf("%s:%d: " fmt "\n", __FUNCTION__, __LINE__, ##__VA_ARGS__); \
|
||||
} while (0)
|
||||
|
||||
#endif
|
|
@ -0,0 +1,612 @@
|
|||
/*
|
||||
* Copyright (c) 2016 Etnaviv Project
|
||||
*
|
||||
* 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, sub license,
|
||||
* 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 NON-INFRINGEMENT. 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:
|
||||
* Christian Gmeiner <christian.gmeiner@gmail.com>
|
||||
*/
|
||||
|
||||
#include "etnaviv_disasm.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "hw/isa.xml.h"
|
||||
|
||||
struct instr {
|
||||
/* dword0: */
|
||||
uint32_t opc : 6;
|
||||
uint32_t cond : 5;
|
||||
uint32_t sat : 1;
|
||||
uint32_t dst_use : 1;
|
||||
uint32_t dst_amode : 3;
|
||||
uint32_t dst_reg : 7;
|
||||
uint32_t dst_comps : 4;
|
||||
uint32_t tex_id : 5;
|
||||
|
||||
/* dword1: */
|
||||
uint32_t tex_amode : 3;
|
||||
uint32_t tex_swiz : 8;
|
||||
uint32_t src0_use : 1;
|
||||
uint32_t src0_reg : 9;
|
||||
uint32_t type_bit2 : 1;
|
||||
uint32_t src0_swiz : 8;
|
||||
uint32_t src0_neg : 1;
|
||||
uint32_t src0_abs : 1;
|
||||
|
||||
/* dword2: */
|
||||
uint32_t src0_amode : 3;
|
||||
uint32_t src0_rgroup : 3;
|
||||
uint32_t src1_use : 1;
|
||||
uint32_t src1_reg : 9;
|
||||
uint32_t opcode_bit6 : 1;
|
||||
uint32_t src1_swiz : 8;
|
||||
uint32_t src1_neg : 1;
|
||||
uint32_t src1_abs : 1;
|
||||
uint32_t src1_amode : 3;
|
||||
uint32_t type_bit01 : 2;
|
||||
|
||||
/* dword3: */
|
||||
union {
|
||||
struct {
|
||||
uint32_t src1_rgroup : 3;
|
||||
uint32_t src2_use : 1;
|
||||
uint32_t src2_reg : 9;
|
||||
uint32_t unk3_13 : 1;
|
||||
uint32_t src2_swiz : 8;
|
||||
uint32_t src2_neg : 1;
|
||||
uint32_t src2_abs : 1;
|
||||
uint32_t unk3_24 : 1;
|
||||
uint32_t src2_amode : 3;
|
||||
uint32_t src2_rgroup : 3;
|
||||
uint32_t unk3_31 : 1;
|
||||
};
|
||||
uint32_t dword3;
|
||||
};
|
||||
};
|
||||
|
||||
struct dst_operand {
|
||||
bool use;
|
||||
uint8_t amode;
|
||||
uint16_t reg;
|
||||
uint8_t comps;
|
||||
};
|
||||
|
||||
struct src_operand {
|
||||
bool use;
|
||||
bool neg;
|
||||
bool abs;
|
||||
uint8_t rgroup;
|
||||
uint16_t reg;
|
||||
uint8_t swiz;
|
||||
uint8_t amode;
|
||||
};
|
||||
|
||||
struct tex_operand {
|
||||
uint8_t id;
|
||||
uint8_t amode;
|
||||
uint8_t swiz;
|
||||
};
|
||||
|
||||
struct opc_operands {
|
||||
struct dst_operand *dst;
|
||||
struct tex_operand *tex;
|
||||
struct src_operand *src0;
|
||||
struct src_operand *src1;
|
||||
struct src_operand *src2;
|
||||
|
||||
int imm;
|
||||
};
|
||||
|
||||
static void
|
||||
printf_type(uint8_t type)
|
||||
{
|
||||
switch(type) {
|
||||
case INST_TYPE_F32:
|
||||
/* as f32 is the default print nothing */
|
||||
break;
|
||||
|
||||
case INST_TYPE_S32:
|
||||
printf(".s32");
|
||||
break;
|
||||
|
||||
case INST_TYPE_S8:
|
||||
printf(".s8");
|
||||
break;
|
||||
|
||||
case INST_TYPE_U16:
|
||||
printf(".u16");
|
||||
break;
|
||||
|
||||
case INST_TYPE_F16:
|
||||
printf(".f16");
|
||||
break;
|
||||
|
||||
case INST_TYPE_S16:
|
||||
printf(".s16");
|
||||
break;
|
||||
|
||||
case INST_TYPE_U32:
|
||||
printf(".u32");
|
||||
break;
|
||||
|
||||
case INST_TYPE_U8:
|
||||
printf(".u8");
|
||||
break;
|
||||
|
||||
default:
|
||||
abort();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
print_condition(uint8_t condition)
|
||||
{
|
||||
switch (condition) {
|
||||
case INST_CONDITION_TRUE:
|
||||
break;
|
||||
|
||||
case INST_CONDITION_GT:
|
||||
printf(".GT");
|
||||
break;
|
||||
|
||||
case INST_CONDITION_LT:
|
||||
printf(".LT");
|
||||
break;
|
||||
|
||||
case INST_CONDITION_GE:
|
||||
printf(".GE");
|
||||
break;
|
||||
|
||||
case INST_CONDITION_LE:
|
||||
printf(".LE");
|
||||
break;
|
||||
|
||||
case INST_CONDITION_EQ:
|
||||
printf(".EQ");
|
||||
break;
|
||||
|
||||
case INST_CONDITION_NE:
|
||||
printf(".NE");
|
||||
break;
|
||||
|
||||
case INST_CONDITION_AND:
|
||||
printf(".AND");
|
||||
break;
|
||||
|
||||
case INST_CONDITION_OR:
|
||||
printf(".OR");
|
||||
break;
|
||||
|
||||
case INST_CONDITION_XOR:
|
||||
printf(".XOR");
|
||||
break;
|
||||
|
||||
case INST_CONDITION_NOT:
|
||||
printf(".NOT");
|
||||
break;
|
||||
|
||||
case INST_CONDITION_NZ:
|
||||
printf(".NZ");
|
||||
break;
|
||||
|
||||
case INST_CONDITION_GEZ:
|
||||
printf(".GEZ");
|
||||
break;
|
||||
|
||||
case INST_CONDITION_GZ:
|
||||
printf(".GZ");
|
||||
break;
|
||||
|
||||
case INST_CONDITION_LEZ:
|
||||
printf(".LEZ");
|
||||
break;
|
||||
|
||||
case INST_CONDITION_LZ:
|
||||
printf(".LZ");
|
||||
break;
|
||||
|
||||
default:
|
||||
abort();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
print_rgroup(uint8_t rgoup)
|
||||
{
|
||||
switch (rgoup) {
|
||||
case INST_RGROUP_TEMP:
|
||||
printf("t");
|
||||
break;
|
||||
|
||||
case INST_RGROUP_INTERNAL:
|
||||
printf("i");
|
||||
break;
|
||||
|
||||
case INST_RGROUP_UNIFORM_0:
|
||||
case INST_RGROUP_UNIFORM_1:
|
||||
printf("u");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
print_components(uint8_t components)
|
||||
{
|
||||
if (components == 15)
|
||||
return;
|
||||
|
||||
printf(".");
|
||||
if (components & INST_COMPS_X)
|
||||
printf("x");
|
||||
else
|
||||
printf("_");
|
||||
|
||||
if (components & INST_COMPS_Y)
|
||||
printf("y");
|
||||
else
|
||||
printf("_");
|
||||
|
||||
if (components & INST_COMPS_Z)
|
||||
printf("z");
|
||||
else
|
||||
printf("_");
|
||||
|
||||
if (components & INST_COMPS_W)
|
||||
printf("w");
|
||||
else
|
||||
printf("_");
|
||||
}
|
||||
|
||||
static inline void
|
||||
print_swiz_comp(uint8_t swiz_comp)
|
||||
{
|
||||
switch (swiz_comp) {
|
||||
case INST_SWIZ_COMP_X:
|
||||
printf("x");
|
||||
break;
|
||||
|
||||
case INST_SWIZ_COMP_Y:
|
||||
printf("y");
|
||||
break;
|
||||
|
||||
case INST_SWIZ_COMP_Z:
|
||||
printf("z");
|
||||
break;
|
||||
|
||||
case INST_SWIZ_COMP_W:
|
||||
printf("w");
|
||||
break;
|
||||
|
||||
default:
|
||||
abort();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
print_swiz(uint8_t swiz)
|
||||
{
|
||||
// if a null swizzle
|
||||
if (swiz == 0xe4)
|
||||
return;
|
||||
|
||||
const unsigned x = swiz & 0x3;
|
||||
const unsigned y = (swiz & 0x0C) >> 2;
|
||||
const unsigned z = (swiz & 0x30) >> 4;
|
||||
const unsigned w = (swiz & 0xc0) >> 6;
|
||||
|
||||
printf(".");
|
||||
print_swiz_comp(x);
|
||||
print_swiz_comp(y);
|
||||
print_swiz_comp(z);
|
||||
print_swiz_comp(w);
|
||||
}
|
||||
|
||||
static void
|
||||
print_amode(uint8_t amode)
|
||||
{
|
||||
switch (amode) {
|
||||
case INST_AMODE_DIRECT:
|
||||
/* nothing to output */
|
||||
break;
|
||||
|
||||
case INST_AMODE_ADD_A_X:
|
||||
printf("[a.x]");
|
||||
break;
|
||||
|
||||
case INST_AMODE_ADD_A_Y:
|
||||
printf("[a.y]");
|
||||
break;
|
||||
|
||||
case INST_AMODE_ADD_A_Z:
|
||||
printf("[a.z]");
|
||||
break;
|
||||
|
||||
case INST_AMODE_ADD_A_W:
|
||||
printf("[a.w]");
|
||||
break;
|
||||
|
||||
default:
|
||||
abort();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
print_dst(struct dst_operand *dst, bool sep)
|
||||
{
|
||||
if (dst->use) {
|
||||
printf("t%u", dst->reg);
|
||||
print_amode(dst->amode);
|
||||
print_components(dst->comps);
|
||||
} else {
|
||||
printf("void");
|
||||
}
|
||||
|
||||
if (sep)
|
||||
printf(", ");
|
||||
}
|
||||
|
||||
static void
|
||||
print_tex(struct tex_operand *tex, bool sep)
|
||||
{
|
||||
printf("tex%u", tex->id);
|
||||
print_amode(tex->amode);
|
||||
print_swiz(tex->swiz);
|
||||
|
||||
if (sep)
|
||||
printf(", ");
|
||||
}
|
||||
|
||||
static void
|
||||
print_src(struct src_operand *src, bool sep)
|
||||
{
|
||||
if (src->use) {
|
||||
if (src->neg)
|
||||
printf("-");
|
||||
|
||||
if (src->abs)
|
||||
printf("|");
|
||||
|
||||
if (src->rgroup == INST_RGROUP_UNIFORM_1)
|
||||
src->reg += 128;
|
||||
|
||||
print_rgroup(src->rgroup);
|
||||
printf("%u", src->reg);
|
||||
print_amode(src->amode);
|
||||
print_swiz(src->swiz);
|
||||
|
||||
if (src->abs)
|
||||
printf("|");
|
||||
} else {
|
||||
printf("void");
|
||||
}
|
||||
|
||||
if (sep)
|
||||
printf(", ");
|
||||
}
|
||||
|
||||
static void
|
||||
print_opc_default(struct opc_operands *operands)
|
||||
{
|
||||
print_dst(operands->dst, true);
|
||||
print_src(operands->src0, true);
|
||||
print_src(operands->src1, true);
|
||||
print_src(operands->src2, false);
|
||||
}
|
||||
|
||||
static void
|
||||
print_opc_mov(struct opc_operands *operands)
|
||||
{
|
||||
// dst (areg)
|
||||
printf("a%u", operands->dst->reg);
|
||||
print_components(operands->dst->comps);
|
||||
printf(", ");
|
||||
|
||||
print_src(operands->src0, true);
|
||||
print_src(operands->src1, true);
|
||||
print_src(operands->src2, false);
|
||||
}
|
||||
|
||||
static void
|
||||
print_opc_tex(struct opc_operands *operands)
|
||||
{
|
||||
print_dst(operands->dst, true);
|
||||
print_tex(operands->tex, true);
|
||||
print_src(operands->src0, true);
|
||||
print_src(operands->src1, true);
|
||||
print_src(operands->src2, false);
|
||||
}
|
||||
|
||||
static void
|
||||
print_opc_imm(struct opc_operands *operands)
|
||||
{
|
||||
print_dst(operands->dst, true);
|
||||
print_src(operands->src0, true);
|
||||
print_src(operands->src1, true);
|
||||
printf("label_%04d", operands->imm);
|
||||
}
|
||||
|
||||
#define OPC_BITS 7
|
||||
|
||||
static const struct opc_info {
|
||||
const char *name;
|
||||
void (*print)(struct opc_operands *operands);
|
||||
} opcs[1 << OPC_BITS] = {
|
||||
#define OPC(opc) [INST_OPCODE_##opc] = {#opc, print_opc_default}
|
||||
#define OPC_MOV(opc) [INST_OPCODE_##opc] = {#opc, print_opc_mov}
|
||||
#define OPC_TEX(opc) [INST_OPCODE_##opc] = {#opc, print_opc_tex}
|
||||
#define OPC_IMM(opc) [INST_OPCODE_##opc] = {#opc, print_opc_imm}
|
||||
OPC(NOP),
|
||||
OPC(ADD),
|
||||
OPC(MAD),
|
||||
OPC(MUL),
|
||||
OPC(DST),
|
||||
OPC(DP3),
|
||||
OPC(DP4),
|
||||
OPC(DSX),
|
||||
OPC(DSY),
|
||||
OPC(MOV),
|
||||
OPC_MOV(MOVAR),
|
||||
OPC_MOV(MOVAF),
|
||||
OPC(RCP),
|
||||
OPC(RSQ),
|
||||
OPC(LITP),
|
||||
OPC(SELECT),
|
||||
OPC(SET),
|
||||
OPC(EXP),
|
||||
OPC(LOG),
|
||||
OPC(FRC),
|
||||
OPC_IMM(CALL),
|
||||
OPC(RET),
|
||||
OPC_IMM(BRANCH),
|
||||
OPC_TEX(TEXKILL),
|
||||
OPC_TEX(TEXLD),
|
||||
OPC_TEX(TEXLDB),
|
||||
OPC_TEX(TEXLDD),
|
||||
OPC_TEX(TEXLDL),
|
||||
OPC_TEX(TEXLDPCF),
|
||||
OPC(REP),
|
||||
OPC(ENDREP),
|
||||
OPC(LOOP),
|
||||
OPC(ENDLOOP),
|
||||
OPC(SQRT),
|
||||
OPC(SIN),
|
||||
OPC(COS),
|
||||
OPC(FLOOR),
|
||||
OPC(CEIL),
|
||||
OPC(SIGN),
|
||||
OPC(I2F),
|
||||
OPC(CMP),
|
||||
OPC(LOAD),
|
||||
OPC(STORE),
|
||||
OPC(IMULLO0),
|
||||
OPC(IMULHI0),
|
||||
OPC(LEADZERO),
|
||||
OPC(LSHIFT),
|
||||
OPC(RSHIFT),
|
||||
OPC(ROTATE),
|
||||
OPC(OR),
|
||||
OPC(AND),
|
||||
OPC(XOR),
|
||||
OPC(NOT),
|
||||
};
|
||||
|
||||
static void
|
||||
print_instr(uint32_t *dwords, int n, enum debug_t debug)
|
||||
{
|
||||
struct instr *instr = (struct instr *)dwords;
|
||||
const unsigned opc = instr->opc | (instr->opcode_bit6 << 6);
|
||||
const char *name = opcs[opc].name;
|
||||
|
||||
printf("%04d: ", n);
|
||||
if (debug & PRINT_RAW)
|
||||
printf("%08x %08x %08x %08x ", dwords[0], dwords[1], dwords[2],
|
||||
dwords[3]);
|
||||
|
||||
if (name) {
|
||||
|
||||
struct dst_operand dst = {
|
||||
.use = instr->dst_use,
|
||||
.amode = instr->dst_amode,
|
||||
.reg = instr->dst_reg,
|
||||
.comps = instr->dst_comps
|
||||
};
|
||||
|
||||
struct tex_operand tex = {
|
||||
.id = instr->tex_id,
|
||||
.amode = instr->tex_amode,
|
||||
.swiz = instr->tex_swiz,
|
||||
};
|
||||
|
||||
struct src_operand src0 = {
|
||||
.use = instr->src0_use,
|
||||
.neg = instr->src0_neg,
|
||||
.abs = instr->src0_abs,
|
||||
.rgroup = instr->src0_rgroup,
|
||||
.reg = instr->src0_reg,
|
||||
.swiz = instr->src0_swiz,
|
||||
.amode = instr->src0_amode,
|
||||
};
|
||||
|
||||
struct src_operand src1 = {
|
||||
.use = instr->src1_use,
|
||||
.neg = instr->src1_neg,
|
||||
.abs = instr->src1_abs,
|
||||
.rgroup = instr->src1_rgroup,
|
||||
.reg = instr->src1_reg,
|
||||
.swiz = instr->src1_swiz,
|
||||
.amode = instr->src1_amode,
|
||||
};
|
||||
|
||||
struct src_operand src2 = {
|
||||
.use = instr->src2_use,
|
||||
.neg = instr->src2_neg,
|
||||
.abs = instr->src2_abs,
|
||||
.rgroup = instr->src2_rgroup,
|
||||
.reg = instr->src2_reg,
|
||||
.swiz = instr->src2_swiz,
|
||||
.amode = instr->src2_amode,
|
||||
};
|
||||
|
||||
int imm = (instr->dword3 & VIV_ISA_WORD_3_SRC2_IMM__MASK)
|
||||
>> VIV_ISA_WORD_3_SRC2_IMM__SHIFT;
|
||||
|
||||
struct opc_operands operands = {
|
||||
.dst = &dst,
|
||||
.tex = &tex,
|
||||
.src0 = &src0,
|
||||
.src1 = &src1,
|
||||
.src2 = &src2,
|
||||
.imm = imm,
|
||||
};
|
||||
|
||||
uint8_t type = instr->type_bit01 | (instr->type_bit2 << 2);
|
||||
|
||||
printf("%s", name);
|
||||
printf_type(type);
|
||||
if (instr->sat)
|
||||
printf(".SAT");
|
||||
print_condition(instr->cond);
|
||||
printf(" ");
|
||||
opcs[opc].print(&operands);
|
||||
} else {
|
||||
printf("unknown (%d)", instr->opc);
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
void
|
||||
etna_disasm(uint32_t *dwords, int sizedwords, enum debug_t debug)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
assert((sizedwords % 2) == 0);
|
||||
|
||||
for (i = 0; i < sizedwords; i += 4)
|
||||
print_instr(&dwords[i], i / 4, debug);
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* Copyright (c) 2016 Etnaviv Project
|
||||
*
|
||||
* 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, sub license,
|
||||
* 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 NON-INFRINGEMENT. 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:
|
||||
* Christian Gmeiner <christian.gmeiner@gmail.com>
|
||||
*/
|
||||
|
||||
#ifndef H_ETNAVIV_DISASM
|
||||
#define H_ETNAVIV_DISASM
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/* bitmask of print flags */
|
||||
enum debug_t {
|
||||
PRINT_RAW = 0x1, /* dump raw hexdump */
|
||||
};
|
||||
|
||||
void
|
||||
etna_disasm(uint32_t *dwords, int sizedwords, enum debug_t debug);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,770 @@
|
|||
/*
|
||||
* Copyright (c) 2014-2015 Etnaviv Project
|
||||
*
|
||||
* 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, sub license,
|
||||
* 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 NON-INFRINGEMENT. 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:
|
||||
* Wladimir J. van der Laan <laanwj@gmail.com>
|
||||
*/
|
||||
|
||||
#include "etnaviv_emit.h"
|
||||
|
||||
#include "etnaviv_blend.h"
|
||||
#include "etnaviv_compiler.h"
|
||||
#include "etnaviv_context.h"
|
||||
#include "etnaviv_rasterizer.h"
|
||||
#include "etnaviv_resource.h"
|
||||
#include "etnaviv_rs.h"
|
||||
#include "etnaviv_screen.h"
|
||||
#include "etnaviv_shader.h"
|
||||
#include "etnaviv_texture.h"
|
||||
#include "etnaviv_translate.h"
|
||||
#include "etnaviv_uniforms.h"
|
||||
#include "etnaviv_util.h"
|
||||
#include "etnaviv_zsa.h"
|
||||
#include "hw/common.xml.h"
|
||||
#include "hw/state.xml.h"
|
||||
#include "util/u_math.h"
|
||||
|
||||
struct etna_coalesce {
|
||||
uint32_t start;
|
||||
uint32_t last_reg;
|
||||
uint32_t last_fixp;
|
||||
};
|
||||
|
||||
/* Queue a STALL command (queues 2 words) */
|
||||
static inline void
|
||||
CMD_STALL(struct etna_cmd_stream *stream, uint32_t from, uint32_t to)
|
||||
{
|
||||
etna_cmd_stream_emit(stream, VIV_FE_STALL_HEADER_OP_STALL);
|
||||
etna_cmd_stream_emit(stream, VIV_FE_STALL_TOKEN_FROM(from) | VIV_FE_STALL_TOKEN_TO(to));
|
||||
}
|
||||
|
||||
void
|
||||
etna_stall(struct etna_cmd_stream *stream, uint32_t from, uint32_t to)
|
||||
{
|
||||
etna_cmd_stream_reserve(stream, 4);
|
||||
|
||||
etna_emit_load_state(stream, VIVS_GL_SEMAPHORE_TOKEN >> 2, 1, 0);
|
||||
etna_cmd_stream_emit(stream, VIVS_GL_SEMAPHORE_TOKEN_FROM(from) | VIVS_GL_SEMAPHORE_TOKEN_TO(to));
|
||||
|
||||
if (from == SYNC_RECIPIENT_FE) {
|
||||
/* if the frontend is to be stalled, queue a STALL frontend command */
|
||||
CMD_STALL(stream, from, to);
|
||||
} else {
|
||||
/* otherwise, load the STALL token state */
|
||||
etna_emit_load_state(stream, VIVS_GL_STALL_TOKEN >> 2, 1, 0);
|
||||
etna_cmd_stream_emit(stream, VIVS_GL_STALL_TOKEN_FROM(from) | VIVS_GL_STALL_TOKEN_TO(to));
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
etna_coalesce_start(struct etna_cmd_stream *stream,
|
||||
struct etna_coalesce *coalesce)
|
||||
{
|
||||
coalesce->start = etna_cmd_stream_offset(stream);
|
||||
coalesce->last_reg = 0;
|
||||
coalesce->last_fixp = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
etna_coalesce_end(struct etna_cmd_stream *stream,
|
||||
struct etna_coalesce *coalesce)
|
||||
{
|
||||
uint32_t end = etna_cmd_stream_offset(stream);
|
||||
uint32_t size = end - coalesce->start;
|
||||
|
||||
if (size) {
|
||||
uint32_t offset = coalesce->start - 1;
|
||||
uint32_t value = etna_cmd_stream_get(stream, offset);
|
||||
|
||||
value |= VIV_FE_LOAD_STATE_HEADER_COUNT(size);
|
||||
etna_cmd_stream_set(stream, offset, value);
|
||||
}
|
||||
|
||||
/* append needed padding */
|
||||
if (end % 2 == 1)
|
||||
etna_cmd_stream_emit(stream, 0xdeadbeef);
|
||||
}
|
||||
|
||||
static void
|
||||
check_coalsence(struct etna_cmd_stream *stream, struct etna_coalesce *coalesce,
|
||||
uint32_t reg, uint32_t fixp)
|
||||
{
|
||||
if (coalesce->last_reg != 0) {
|
||||
if (((coalesce->last_reg + 4) != reg) || (coalesce->last_fixp != fixp)) {
|
||||
etna_coalesce_end(stream, coalesce);
|
||||
etna_emit_load_state(stream, reg >> 2, 0, fixp);
|
||||
coalesce->start = etna_cmd_stream_offset(stream);
|
||||
}
|
||||
} else {
|
||||
etna_emit_load_state(stream, reg >> 2, 0, fixp);
|
||||
coalesce->start = etna_cmd_stream_offset(stream);
|
||||
}
|
||||
|
||||
coalesce->last_reg = reg;
|
||||
coalesce->last_fixp = fixp;
|
||||
}
|
||||
|
||||
static inline void
|
||||
etna_coalsence_emit(struct etna_cmd_stream *stream,
|
||||
struct etna_coalesce *coalesce, uint32_t reg,
|
||||
uint32_t value)
|
||||
{
|
||||
check_coalsence(stream, coalesce, reg, 0);
|
||||
etna_cmd_stream_emit(stream, value);
|
||||
}
|
||||
|
||||
static inline void
|
||||
etna_coalsence_emit_fixp(struct etna_cmd_stream *stream,
|
||||
struct etna_coalesce *coalesce, uint32_t reg,
|
||||
uint32_t value)
|
||||
{
|
||||
check_coalsence(stream, coalesce, reg, 1);
|
||||
etna_cmd_stream_emit(stream, value);
|
||||
}
|
||||
|
||||
static inline void
|
||||
etna_coalsence_emit_reloc(struct etna_cmd_stream *stream,
|
||||
struct etna_coalesce *coalesce, uint32_t reg,
|
||||
const struct etna_reloc *r)
|
||||
{
|
||||
if (r->bo) {
|
||||
check_coalsence(stream, coalesce, reg, 0);
|
||||
etna_cmd_stream_reloc(stream, r);
|
||||
}
|
||||
}
|
||||
|
||||
#define EMIT_STATE(state_name, src_value) \
|
||||
etna_coalsence_emit(stream, &coalesce, VIVS_##state_name, src_value)
|
||||
|
||||
#define EMIT_STATE_FIXP(state_name, src_value) \
|
||||
etna_coalsence_emit_fixp(stream, &coalesce, VIVS_##state_name, src_value)
|
||||
|
||||
#define EMIT_STATE_RELOC(state_name, src_value) \
|
||||
etna_coalsence_emit_reloc(stream, &coalesce, VIVS_##state_name, src_value)
|
||||
|
||||
/* submit RS state, without any processing and no dependence on context
|
||||
* except TS if this is a source-to-destination blit. */
|
||||
void
|
||||
etna_submit_rs_state(struct etna_context *ctx,
|
||||
const struct compiled_rs_state *cs)
|
||||
{
|
||||
struct etna_screen *screen = etna_screen(ctx->base.screen);
|
||||
struct etna_cmd_stream *stream = ctx->stream;
|
||||
struct etna_coalesce coalesce;
|
||||
|
||||
if (screen->specs.pixel_pipes == 1) {
|
||||
etna_cmd_stream_reserve(stream, 22);
|
||||
etna_coalesce_start(stream, &coalesce);
|
||||
/* 0/1 */ EMIT_STATE(RS_CONFIG, cs->RS_CONFIG);
|
||||
/* 2 */ EMIT_STATE_RELOC(RS_SOURCE_ADDR, &cs->source[0]);
|
||||
/* 3 */ EMIT_STATE(RS_SOURCE_STRIDE, cs->RS_SOURCE_STRIDE);
|
||||
/* 4 */ EMIT_STATE_RELOC(RS_DEST_ADDR, &cs->dest[0]);
|
||||
/* 5 */ EMIT_STATE(RS_DEST_STRIDE, cs->RS_DEST_STRIDE);
|
||||
/* 6/7 */ EMIT_STATE(RS_WINDOW_SIZE, cs->RS_WINDOW_SIZE);
|
||||
/* 8/9 */ EMIT_STATE(RS_DITHER(0), cs->RS_DITHER[0]);
|
||||
/*10 */ EMIT_STATE(RS_DITHER(1), cs->RS_DITHER[1]);
|
||||
/*11 - pad */
|
||||
/*12/13*/ EMIT_STATE(RS_CLEAR_CONTROL, cs->RS_CLEAR_CONTROL);
|
||||
/*14 */ EMIT_STATE(RS_FILL_VALUE(0), cs->RS_FILL_VALUE[0]);
|
||||
/*15 */ EMIT_STATE(RS_FILL_VALUE(1), cs->RS_FILL_VALUE[1]);
|
||||
/*16 */ EMIT_STATE(RS_FILL_VALUE(2), cs->RS_FILL_VALUE[2]);
|
||||
/*17 */ EMIT_STATE(RS_FILL_VALUE(3), cs->RS_FILL_VALUE[3]);
|
||||
/*18/19*/ EMIT_STATE(RS_EXTRA_CONFIG, cs->RS_EXTRA_CONFIG);
|
||||
/*20/21*/ EMIT_STATE(RS_KICKER, 0xbeebbeeb);
|
||||
etna_coalesce_end(stream, &coalesce);
|
||||
} else if (screen->specs.pixel_pipes == 2) {
|
||||
etna_cmd_stream_reserve(stream, 34); /* worst case - both pipes multi=1 */
|
||||
etna_coalesce_start(stream, &coalesce);
|
||||
/* 0/1 */ EMIT_STATE(RS_CONFIG, cs->RS_CONFIG);
|
||||
/* 2/3 */ EMIT_STATE(RS_SOURCE_STRIDE, cs->RS_SOURCE_STRIDE);
|
||||
/* 4/5 */ EMIT_STATE(RS_DEST_STRIDE, cs->RS_DEST_STRIDE);
|
||||
/* 6/7 */ EMIT_STATE_RELOC(RS_PIPE_SOURCE_ADDR(0), &cs->source[0]);
|
||||
if (cs->RS_SOURCE_STRIDE & VIVS_RS_SOURCE_STRIDE_MULTI) {
|
||||
/*8 */ EMIT_STATE_RELOC(RS_PIPE_SOURCE_ADDR(1), &cs->source[1]);
|
||||
/*9 - pad */
|
||||
}
|
||||
/*10/11*/ EMIT_STATE_RELOC(RS_PIPE_DEST_ADDR(0), &cs->dest[0]);
|
||||
if (cs->RS_DEST_STRIDE & VIVS_RS_DEST_STRIDE_MULTI) {
|
||||
/*12*/ EMIT_STATE_RELOC(RS_PIPE_DEST_ADDR(1), &cs->dest[1]);
|
||||
/*13 - pad */
|
||||
}
|
||||
/*14/15*/ EMIT_STATE(RS_PIPE_OFFSET(0), cs->RS_PIPE_OFFSET[0]);
|
||||
/*16 */ EMIT_STATE(RS_PIPE_OFFSET(1), cs->RS_PIPE_OFFSET[1]);
|
||||
/*17 - pad */
|
||||
/*18/19*/ EMIT_STATE(RS_WINDOW_SIZE, cs->RS_WINDOW_SIZE);
|
||||
/*20/21*/ EMIT_STATE(RS_DITHER(0), cs->RS_DITHER[0]);
|
||||
/*22 */ EMIT_STATE(RS_DITHER(1), cs->RS_DITHER[1]);
|
||||
/*23 - pad */
|
||||
/*24/25*/ EMIT_STATE(RS_CLEAR_CONTROL, cs->RS_CLEAR_CONTROL);
|
||||
/*26 */ EMIT_STATE(RS_FILL_VALUE(0), cs->RS_FILL_VALUE[0]);
|
||||
/*27 */ EMIT_STATE(RS_FILL_VALUE(1), cs->RS_FILL_VALUE[1]);
|
||||
/*28 */ EMIT_STATE(RS_FILL_VALUE(2), cs->RS_FILL_VALUE[2]);
|
||||
/*29 */ EMIT_STATE(RS_FILL_VALUE(3), cs->RS_FILL_VALUE[3]);
|
||||
/*30/31*/ EMIT_STATE(RS_EXTRA_CONFIG, cs->RS_EXTRA_CONFIG);
|
||||
/*32/33*/ EMIT_STATE(RS_KICKER, 0xbeebbeeb);
|
||||
etna_coalesce_end(stream, &coalesce);
|
||||
} else {
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
/* Create bit field that specifies which samplers are active and thus need to be
|
||||
* programmed
|
||||
* 32 bits is enough for 32 samplers. As far as I know this is the upper bound
|
||||
* supported on any Vivante hw
|
||||
* up to GC4000.
|
||||
*/
|
||||
static uint32_t
|
||||
active_samplers_bits(struct etna_context *ctx)
|
||||
{
|
||||
return ctx->active_sampler_views & ctx->active_samplers;
|
||||
}
|
||||
|
||||
#define ETNA_3D_CONTEXT_SIZE (400) /* keep this number above "Total state updates (fixed)" from gen_weave_state tool */
|
||||
|
||||
static unsigned
|
||||
required_stream_size(struct etna_context *ctx)
|
||||
{
|
||||
unsigned size = ETNA_3D_CONTEXT_SIZE;
|
||||
|
||||
/* stall + flush */
|
||||
size += 2 + 4;
|
||||
|
||||
/* vertex elements */
|
||||
size += ctx->vertex_elements->num_elements + 1;
|
||||
|
||||
/* uniforms - worst case (2 words per uniform load) */
|
||||
size += ctx->vs->uniforms.const_count * 2;
|
||||
size += ctx->fs->uniforms.const_count * 2;
|
||||
|
||||
/* shader */
|
||||
size += ctx->shader_state.vs_inst_mem_size + 1;
|
||||
size += ctx->shader_state.ps_inst_mem_size + 1;
|
||||
|
||||
/* DRAW_INDEXED_PRIMITIVES command */
|
||||
size += 6;
|
||||
|
||||
/* reserve for alignment etc. */
|
||||
size += 64;
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
/* Weave state before draw operation. This function merges all the compiled
|
||||
* state blocks under the context into one device register state. Parts of
|
||||
* this state that are changed since last call (dirty) will be uploaded as
|
||||
* state changes in the command buffer. */
|
||||
void
|
||||
etna_emit_state(struct etna_context *ctx)
|
||||
{
|
||||
struct etna_cmd_stream *stream = ctx->stream;
|
||||
uint32_t active_samplers = active_samplers_bits(ctx);
|
||||
|
||||
/* Pre-reserve the command buffer space which we are likely to need.
|
||||
* This must cover all the state emitted below, and the following
|
||||
* draw command. */
|
||||
etna_cmd_stream_reserve(stream, required_stream_size(ctx));
|
||||
|
||||
uint32_t dirty = ctx->dirty;
|
||||
|
||||
/* Pre-processing: see what caches we need to flush before making state changes. */
|
||||
uint32_t to_flush = 0;
|
||||
if (unlikely(dirty & (ETNA_DIRTY_BLEND))) {
|
||||
/* Need flush COLOR when changing PE.COLOR_FORMAT.OVERWRITE. */
|
||||
#if 0
|
||||
/* TODO*/
|
||||
if ((ctx->gpu3d.PE_COLOR_FORMAT & VIVS_PE_COLOR_FORMAT_OVERWRITE) !=
|
||||
(etna_blend_state(ctx->blend)->PE_COLOR_FORMAT & VIVS_PE_COLOR_FORMAT_OVERWRITE))
|
||||
#endif
|
||||
to_flush |= VIVS_GL_FLUSH_CACHE_COLOR;
|
||||
}
|
||||
if (unlikely(dirty & (ETNA_DIRTY_TEXTURE_CACHES)))
|
||||
to_flush |= VIVS_GL_FLUSH_CACHE_TEXTURE;
|
||||
if (unlikely(dirty & (ETNA_DIRTY_FRAMEBUFFER))) /* Framebuffer config changed? */
|
||||
to_flush |= VIVS_GL_FLUSH_CACHE_COLOR | VIVS_GL_FLUSH_CACHE_DEPTH;
|
||||
if (DBG_ENABLED(ETNA_DBG_CFLUSH_ALL))
|
||||
to_flush |= VIVS_GL_FLUSH_CACHE_TEXTURE | VIVS_GL_FLUSH_CACHE_COLOR | VIVS_GL_FLUSH_CACHE_DEPTH;
|
||||
|
||||
if (to_flush) {
|
||||
etna_set_state(stream, VIVS_GL_FLUSH_CACHE, to_flush);
|
||||
etna_stall(stream, SYNC_RECIPIENT_RA, SYNC_RECIPIENT_PE);
|
||||
}
|
||||
|
||||
/* If MULTI_SAMPLE_CONFIG.MSAA_SAMPLES changed, clobber affected shader
|
||||
* state to make sure it is always rewritten. */
|
||||
if (unlikely(dirty & (ETNA_DIRTY_FRAMEBUFFER))) {
|
||||
if ((ctx->gpu3d.GL_MULTI_SAMPLE_CONFIG & VIVS_GL_MULTI_SAMPLE_CONFIG_MSAA_SAMPLES__MASK) !=
|
||||
(ctx->framebuffer.GL_MULTI_SAMPLE_CONFIG & VIVS_GL_MULTI_SAMPLE_CONFIG_MSAA_SAMPLES__MASK)) {
|
||||
/* XXX what does the GPU set these states to on MSAA samples change?
|
||||
* Does it do the right thing?
|
||||
* (increase/decrease as necessary) or something else? Just set some
|
||||
* invalid value until we know for
|
||||
* sure. */
|
||||
ctx->gpu3d.PS_INPUT_COUNT = 0xffffffff;
|
||||
ctx->gpu3d.PS_TEMP_REGISTER_CONTROL = 0xffffffff;
|
||||
}
|
||||
}
|
||||
|
||||
/* Update vertex elements. This is different from any of the other states, in that
|
||||
* a) the number of vertex elements written matters: so write only active ones
|
||||
* b) the vertex element states must all be written: do not skip entries that stay the same */
|
||||
if (dirty & (ETNA_DIRTY_VERTEX_ELEMENTS)) {
|
||||
/* Special case: vertex elements must always be sent in full if changed */
|
||||
/*00600*/ etna_set_state_multi(stream, VIVS_FE_VERTEX_ELEMENT_CONFIG(0),
|
||||
ctx->vertex_elements->num_elements,
|
||||
ctx->vertex_elements->FE_VERTEX_ELEMENT_CONFIG);
|
||||
}
|
||||
|
||||
/* The following code is originally generated by gen_merge_state.py, to
|
||||
* emit state in increasing order of address (this makes it possible to merge
|
||||
* consecutive register updates into one SET_STATE command)
|
||||
*
|
||||
* There have been some manual changes, where the weaving operation is not
|
||||
* simply bitwise or:
|
||||
* - scissor fixp
|
||||
* - num vertex elements
|
||||
* - scissor handling
|
||||
* - num samplers
|
||||
* - texture lod
|
||||
* - ETNA_DIRTY_TS
|
||||
* - removed ETNA_DIRTY_BASE_SETUP statements -- these are guaranteed to not
|
||||
* change anyway
|
||||
* - PS / framebuffer interaction for MSAA
|
||||
* - move update of GL_MULTI_SAMPLE_CONFIG first
|
||||
* - add unlikely()/likely()
|
||||
*/
|
||||
struct etna_coalesce coalesce;
|
||||
|
||||
etna_coalesce_start(stream, &coalesce);
|
||||
|
||||
/* begin only EMIT_STATE -- make sure no new etna_reserve calls are done here
|
||||
* directly
|
||||
* or indirectly */
|
||||
/* multi sample config is set first, and outside of the normal sorting
|
||||
* order, as changing the multisample state clobbers PS.INPUT_COUNT (and
|
||||
* possibly PS.TEMP_REGISTER_CONTROL).
|
||||
*/
|
||||
if (unlikely(dirty & (ETNA_DIRTY_FRAMEBUFFER | ETNA_DIRTY_SAMPLE_MASK))) {
|
||||
uint32_t val = VIVS_GL_MULTI_SAMPLE_CONFIG_MSAA_ENABLES(ctx->sample_mask);
|
||||
val |= ctx->framebuffer.GL_MULTI_SAMPLE_CONFIG;
|
||||
|
||||
/*03818*/ EMIT_STATE(GL_MULTI_SAMPLE_CONFIG, val);
|
||||
}
|
||||
if (likely(dirty & (ETNA_DIRTY_INDEX_BUFFER)) &&
|
||||
ctx->index_buffer.ib.buffer) {
|
||||
/*00644*/ EMIT_STATE_RELOC(FE_INDEX_STREAM_BASE_ADDR, &ctx->index_buffer.FE_INDEX_STREAM_BASE_ADDR);
|
||||
/*00648*/ EMIT_STATE(FE_INDEX_STREAM_CONTROL, ctx->index_buffer.FE_INDEX_STREAM_CONTROL);
|
||||
}
|
||||
if (likely(dirty & (ETNA_DIRTY_VERTEX_BUFFERS))) {
|
||||
/*0064C*/ EMIT_STATE_RELOC(FE_VERTEX_STREAM_BASE_ADDR, &ctx->vertex_buffer.cvb[0].FE_VERTEX_STREAM_BASE_ADDR);
|
||||
/*00650*/ EMIT_STATE(FE_VERTEX_STREAM_CONTROL, ctx->vertex_buffer.cvb[0].FE_VERTEX_STREAM_CONTROL);
|
||||
}
|
||||
if (likely(dirty & (ETNA_DIRTY_INDEX_BUFFER))) {
|
||||
/*00674*/ EMIT_STATE(FE_PRIMITIVE_RESTART_INDEX, ctx->index_buffer.FE_PRIMITIVE_RESTART_INDEX);
|
||||
}
|
||||
if (likely(dirty & (ETNA_DIRTY_VERTEX_BUFFERS))) {
|
||||
for (int x = 1; x < ctx->vertex_buffer.count; ++x) {
|
||||
/*00680*/ EMIT_STATE_RELOC(FE_VERTEX_STREAMS_BASE_ADDR(x), &ctx->vertex_buffer.cvb[x].FE_VERTEX_STREAM_BASE_ADDR);
|
||||
}
|
||||
for (int x = 1; x < ctx->vertex_buffer.count; ++x) {
|
||||
if (ctx->vertex_buffer.cvb[x].FE_VERTEX_STREAM_BASE_ADDR.bo) {
|
||||
/*006A0*/ EMIT_STATE(FE_VERTEX_STREAMS_CONTROL(x), ctx->vertex_buffer.cvb[x].FE_VERTEX_STREAM_CONTROL);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (unlikely(dirty & (ETNA_DIRTY_SHADER))) {
|
||||
/*00800*/ EMIT_STATE(VS_END_PC, ctx->shader_state.VS_END_PC);
|
||||
}
|
||||
if (unlikely(dirty & (ETNA_DIRTY_SHADER | ETNA_DIRTY_RASTERIZER))) {
|
||||
bool point_size_per_vertex =
|
||||
etna_rasterizer_state(ctx->rasterizer)->point_size_per_vertex;
|
||||
|
||||
/*00804*/ EMIT_STATE(VS_OUTPUT_COUNT,
|
||||
point_size_per_vertex
|
||||
? ctx->shader_state.VS_OUTPUT_COUNT_PSIZE
|
||||
: ctx->shader_state.VS_OUTPUT_COUNT);
|
||||
}
|
||||
if (unlikely(dirty & (ETNA_DIRTY_VERTEX_ELEMENTS | ETNA_DIRTY_SHADER))) {
|
||||
/*00808*/ EMIT_STATE(VS_INPUT_COUNT, ctx->shader_state.VS_INPUT_COUNT);
|
||||
/*0080C*/ EMIT_STATE(VS_TEMP_REGISTER_CONTROL, ctx->shader_state.VS_TEMP_REGISTER_CONTROL);
|
||||
}
|
||||
if (unlikely(dirty & (ETNA_DIRTY_SHADER))) {
|
||||
for (int x = 0; x < 4; ++x) {
|
||||
/*00810*/ EMIT_STATE(VS_OUTPUT(x), ctx->shader_state.VS_OUTPUT[x]);
|
||||
}
|
||||
}
|
||||
if (unlikely(dirty & (ETNA_DIRTY_VERTEX_ELEMENTS | ETNA_DIRTY_SHADER))) {
|
||||
for (int x = 0; x < 4; ++x) {
|
||||
/*00820*/ EMIT_STATE(VS_INPUT(x), ctx->shader_state.VS_INPUT[x]);
|
||||
}
|
||||
}
|
||||
if (unlikely(dirty & (ETNA_DIRTY_SHADER))) {
|
||||
/*00830*/ EMIT_STATE(VS_LOAD_BALANCING, ctx->shader_state.VS_LOAD_BALANCING);
|
||||
/*00838*/ EMIT_STATE(VS_START_PC, ctx->shader_state.VS_START_PC);
|
||||
if (ctx->specs.has_shader_range_registers) {
|
||||
/*0085C*/ EMIT_STATE(VS_RANGE, (ctx->shader_state.vs_inst_mem_size / 4 - 1) << 16);
|
||||
}
|
||||
}
|
||||
if (unlikely(dirty & (ETNA_DIRTY_VIEWPORT))) {
|
||||
/*00A00*/ EMIT_STATE_FIXP(PA_VIEWPORT_SCALE_X, ctx->viewport.PA_VIEWPORT_SCALE_X);
|
||||
/*00A04*/ EMIT_STATE_FIXP(PA_VIEWPORT_SCALE_Y, ctx->viewport.PA_VIEWPORT_SCALE_Y);
|
||||
/*00A08*/ EMIT_STATE(PA_VIEWPORT_SCALE_Z, ctx->viewport.PA_VIEWPORT_SCALE_Z);
|
||||
/*00A0C*/ EMIT_STATE_FIXP(PA_VIEWPORT_OFFSET_X, ctx->viewport.PA_VIEWPORT_OFFSET_X);
|
||||
/*00A10*/ EMIT_STATE_FIXP(PA_VIEWPORT_OFFSET_Y, ctx->viewport.PA_VIEWPORT_OFFSET_Y);
|
||||
/*00A14*/ EMIT_STATE(PA_VIEWPORT_OFFSET_Z, ctx->viewport.PA_VIEWPORT_OFFSET_Z);
|
||||
}
|
||||
if (unlikely(dirty & (ETNA_DIRTY_RASTERIZER))) {
|
||||
struct etna_rasterizer_state *rasterizer = etna_rasterizer_state(ctx->rasterizer);
|
||||
|
||||
/*00A18*/ EMIT_STATE(PA_LINE_WIDTH, rasterizer->PA_LINE_WIDTH);
|
||||
/*00A1C*/ EMIT_STATE(PA_POINT_SIZE, rasterizer->PA_POINT_SIZE);
|
||||
/*00A28*/ EMIT_STATE(PA_SYSTEM_MODE, rasterizer->PA_SYSTEM_MODE);
|
||||
}
|
||||
if (unlikely(dirty & (ETNA_DIRTY_SHADER))) {
|
||||
/*00A30*/ EMIT_STATE(PA_ATTRIBUTE_ELEMENT_COUNT, ctx->shader_state.PA_ATTRIBUTE_ELEMENT_COUNT);
|
||||
}
|
||||
if (unlikely(dirty & (ETNA_DIRTY_RASTERIZER | ETNA_DIRTY_SHADER))) {
|
||||
uint32_t val = etna_rasterizer_state(ctx->rasterizer)->PA_CONFIG;
|
||||
/*00A34*/ EMIT_STATE(PA_CONFIG, val & ctx->shader_state.PA_CONFIG);
|
||||
}
|
||||
if (unlikely(dirty & (ETNA_DIRTY_RASTERIZER))) {
|
||||
struct etna_rasterizer_state *rasterizer = etna_rasterizer_state(ctx->rasterizer);
|
||||
/*00A38*/ EMIT_STATE(PA_WIDE_LINE_WIDTH0, rasterizer->PA_LINE_WIDTH);
|
||||
/*00A3C*/ EMIT_STATE(PA_WIDE_LINE_WIDTH1, rasterizer->PA_LINE_WIDTH);
|
||||
}
|
||||
if (unlikely(dirty & (ETNA_DIRTY_SHADER))) {
|
||||
for (int x = 0; x < 10; ++x) {
|
||||
/*00A40*/ EMIT_STATE(PA_SHADER_ATTRIBUTES(x), ctx->shader_state.PA_SHADER_ATTRIBUTES[x]);
|
||||
}
|
||||
}
|
||||
if (unlikely(dirty & (ETNA_DIRTY_SCISSOR | ETNA_DIRTY_FRAMEBUFFER |
|
||||
ETNA_DIRTY_RASTERIZER | ETNA_DIRTY_VIEWPORT))) {
|
||||
/* this is a bit of a mess: rasterizer.scissor determines whether to use
|
||||
* only the framebuffer scissor, or specific scissor state, and the
|
||||
* viewport clips too so the logic spans four CSOs */
|
||||
struct etna_rasterizer_state *rasterizer = etna_rasterizer_state(ctx->rasterizer);
|
||||
|
||||
uint32_t scissor_left =
|
||||
MAX2(ctx->framebuffer.SE_SCISSOR_LEFT, ctx->viewport.SE_SCISSOR_LEFT);
|
||||
uint32_t scissor_top =
|
||||
MAX2(ctx->framebuffer.SE_SCISSOR_TOP, ctx->viewport.SE_SCISSOR_TOP);
|
||||
uint32_t scissor_right =
|
||||
MIN2(ctx->framebuffer.SE_SCISSOR_RIGHT, ctx->viewport.SE_SCISSOR_RIGHT);
|
||||
uint32_t scissor_bottom =
|
||||
MIN2(ctx->framebuffer.SE_SCISSOR_BOTTOM, ctx->viewport.SE_SCISSOR_BOTTOM);
|
||||
|
||||
if (rasterizer->scissor) {
|
||||
scissor_left = MAX2(ctx->scissor.SE_SCISSOR_LEFT, scissor_left);
|
||||
scissor_top = MAX2(ctx->scissor.SE_SCISSOR_TOP, scissor_top);
|
||||
scissor_right = MIN2(ctx->scissor.SE_SCISSOR_RIGHT, scissor_right);
|
||||
scissor_bottom = MIN2(ctx->scissor.SE_SCISSOR_BOTTOM, scissor_bottom);
|
||||
}
|
||||
|
||||
/*00C00*/ EMIT_STATE_FIXP(SE_SCISSOR_LEFT, scissor_left);
|
||||
/*00C04*/ EMIT_STATE_FIXP(SE_SCISSOR_TOP, scissor_top);
|
||||
/*00C08*/ EMIT_STATE_FIXP(SE_SCISSOR_RIGHT, scissor_right);
|
||||
/*00C0C*/ EMIT_STATE_FIXP(SE_SCISSOR_BOTTOM, scissor_bottom);
|
||||
}
|
||||
if (unlikely(dirty & (ETNA_DIRTY_RASTERIZER))) {
|
||||
struct etna_rasterizer_state *rasterizer = etna_rasterizer_state(ctx->rasterizer);
|
||||
|
||||
/*00C10*/ EMIT_STATE(SE_DEPTH_SCALE, rasterizer->SE_DEPTH_SCALE);
|
||||
/*00C14*/ EMIT_STATE(SE_DEPTH_BIAS, rasterizer->SE_DEPTH_BIAS);
|
||||
/*00C18*/ EMIT_STATE(SE_CONFIG, rasterizer->SE_CONFIG);
|
||||
}
|
||||
if (unlikely(dirty & (ETNA_DIRTY_SHADER))) {
|
||||
/*00E00*/ EMIT_STATE(RA_CONTROL, ctx->shader_state.RA_CONTROL);
|
||||
}
|
||||
if (unlikely(dirty & (ETNA_DIRTY_FRAMEBUFFER))) {
|
||||
/*00E04*/ EMIT_STATE(RA_MULTISAMPLE_UNK00E04, ctx->framebuffer.RA_MULTISAMPLE_UNK00E04);
|
||||
for (int x = 0; x < 4; ++x) {
|
||||
/*00E10*/ EMIT_STATE(RA_MULTISAMPLE_UNK00E10(x), ctx->framebuffer.RA_MULTISAMPLE_UNK00E10[x]);
|
||||
}
|
||||
for (int x = 0; x < 16; ++x) {
|
||||
/*00E40*/ EMIT_STATE(RA_CENTROID_TABLE(x), ctx->framebuffer.RA_CENTROID_TABLE[x]);
|
||||
}
|
||||
}
|
||||
if (unlikely(dirty & (ETNA_DIRTY_SHADER | ETNA_DIRTY_FRAMEBUFFER))) {
|
||||
/*01000*/ EMIT_STATE(PS_END_PC, ctx->shader_state.PS_END_PC);
|
||||
/*01004*/ EMIT_STATE(PS_OUTPUT_REG, ctx->shader_state.PS_OUTPUT_REG);
|
||||
/*01008*/ EMIT_STATE(PS_INPUT_COUNT,
|
||||
ctx->framebuffer.msaa_mode
|
||||
? ctx->shader_state.PS_INPUT_COUNT_MSAA
|
||||
: ctx->shader_state.PS_INPUT_COUNT);
|
||||
/*0100C*/ EMIT_STATE(PS_TEMP_REGISTER_CONTROL,
|
||||
ctx->framebuffer.msaa_mode
|
||||
? ctx->shader_state.PS_TEMP_REGISTER_CONTROL_MSAA
|
||||
: ctx->shader_state.PS_TEMP_REGISTER_CONTROL);
|
||||
/*01010*/ EMIT_STATE(PS_CONTROL, ctx->shader_state.PS_CONTROL);
|
||||
/*01018*/ EMIT_STATE(PS_START_PC, ctx->shader_state.PS_START_PC);
|
||||
if (ctx->specs.has_shader_range_registers) {
|
||||
/*0101C*/ EMIT_STATE(PS_RANGE, ((ctx->shader_state.ps_inst_mem_size / 4 - 1 + 0x100) << 16) |
|
||||
0x100);
|
||||
}
|
||||
}
|
||||
if (unlikely(dirty & (ETNA_DIRTY_ZSA | ETNA_DIRTY_FRAMEBUFFER))) {
|
||||
uint32_t val = etna_zsa_state(ctx->zsa)->PE_DEPTH_CONFIG;
|
||||
/*01400*/ EMIT_STATE(PE_DEPTH_CONFIG, val | ctx->framebuffer.PE_DEPTH_CONFIG);
|
||||
}
|
||||
if (unlikely(dirty & (ETNA_DIRTY_VIEWPORT))) {
|
||||
/*01404*/ EMIT_STATE(PE_DEPTH_NEAR, ctx->viewport.PE_DEPTH_NEAR);
|
||||
/*01408*/ EMIT_STATE(PE_DEPTH_FAR, ctx->viewport.PE_DEPTH_FAR);
|
||||
}
|
||||
if (unlikely(dirty & (ETNA_DIRTY_FRAMEBUFFER))) {
|
||||
/*0140C*/ EMIT_STATE(PE_DEPTH_NORMALIZE, ctx->framebuffer.PE_DEPTH_NORMALIZE);
|
||||
|
||||
if (ctx->specs.pixel_pipes == 1) {
|
||||
/*01410*/ EMIT_STATE_RELOC(PE_DEPTH_ADDR, &ctx->framebuffer.PE_DEPTH_ADDR);
|
||||
}
|
||||
|
||||
/*01414*/ EMIT_STATE(PE_DEPTH_STRIDE, ctx->framebuffer.PE_DEPTH_STRIDE);
|
||||
}
|
||||
if (unlikely(dirty & (ETNA_DIRTY_ZSA))) {
|
||||
uint32_t val = etna_zsa_state(ctx->zsa)->PE_STENCIL_OP;
|
||||
/*01418*/ EMIT_STATE(PE_STENCIL_OP, val);
|
||||
}
|
||||
if (unlikely(dirty & (ETNA_DIRTY_ZSA | ETNA_DIRTY_STENCIL_REF))) {
|
||||
uint32_t val = etna_zsa_state(ctx->zsa)->PE_STENCIL_CONFIG;
|
||||
/*0141C*/ EMIT_STATE(PE_STENCIL_CONFIG, val | ctx->stencil_ref.PE_STENCIL_CONFIG);
|
||||
}
|
||||
if (unlikely(dirty & (ETNA_DIRTY_ZSA))) {
|
||||
uint32_t val = etna_zsa_state(ctx->zsa)->PE_ALPHA_OP;
|
||||
/*01420*/ EMIT_STATE(PE_ALPHA_OP, val);
|
||||
}
|
||||
if (unlikely(dirty & (ETNA_DIRTY_BLEND_COLOR))) {
|
||||
/*01424*/ EMIT_STATE(PE_ALPHA_BLEND_COLOR, ctx->blend_color.PE_ALPHA_BLEND_COLOR);
|
||||
}
|
||||
if (unlikely(dirty & (ETNA_DIRTY_BLEND))) {
|
||||
uint32_t val = etna_blend_state(ctx->blend)->PE_ALPHA_CONFIG;
|
||||
/*01428*/ EMIT_STATE(PE_ALPHA_CONFIG, val);
|
||||
}
|
||||
if (unlikely(dirty & (ETNA_DIRTY_BLEND | ETNA_DIRTY_FRAMEBUFFER))) {
|
||||
uint32_t val;
|
||||
/* Use the components and overwrite bits in framebuffer.PE_COLOR_FORMAT
|
||||
* as a mask to enable the bits from blend PE_COLOR_FORMAT */
|
||||
val = ~(VIVS_PE_COLOR_FORMAT_COMPONENTS__MASK |
|
||||
VIVS_PE_COLOR_FORMAT_OVERWRITE);
|
||||
val |= etna_blend_state(ctx->blend)->PE_COLOR_FORMAT;
|
||||
val &= ctx->framebuffer.PE_COLOR_FORMAT;
|
||||
/*0142C*/ EMIT_STATE(PE_COLOR_FORMAT, val);
|
||||
}
|
||||
if (unlikely(dirty & (ETNA_DIRTY_FRAMEBUFFER))) {
|
||||
if (ctx->specs.pixel_pipes == 1) {
|
||||
/*01430*/ EMIT_STATE_RELOC(PE_COLOR_ADDR, &ctx->framebuffer.PE_COLOR_ADDR);
|
||||
/*01434*/ EMIT_STATE(PE_COLOR_STRIDE, ctx->framebuffer.PE_COLOR_STRIDE);
|
||||
/*01454*/ EMIT_STATE(PE_HDEPTH_CONTROL, ctx->framebuffer.PE_HDEPTH_CONTROL);
|
||||
} else if (ctx->specs.pixel_pipes == 2) {
|
||||
/*01434*/ EMIT_STATE(PE_COLOR_STRIDE, ctx->framebuffer.PE_COLOR_STRIDE);
|
||||
/*01454*/ EMIT_STATE(PE_HDEPTH_CONTROL, ctx->framebuffer.PE_HDEPTH_CONTROL);
|
||||
/*01460*/ EMIT_STATE_RELOC(PE_PIPE_COLOR_ADDR(0), &ctx->framebuffer.PE_PIPE_COLOR_ADDR[0]);
|
||||
/*01464*/ EMIT_STATE_RELOC(PE_PIPE_COLOR_ADDR(1), &ctx->framebuffer.PE_PIPE_COLOR_ADDR[1]);
|
||||
/*01480*/ EMIT_STATE_RELOC(PE_PIPE_DEPTH_ADDR(0), &ctx->framebuffer.PE_PIPE_DEPTH_ADDR[0]);
|
||||
/*01484*/ EMIT_STATE_RELOC(PE_PIPE_DEPTH_ADDR(1), &ctx->framebuffer.PE_PIPE_DEPTH_ADDR[1]);
|
||||
} else {
|
||||
abort();
|
||||
}
|
||||
}
|
||||
if (unlikely(dirty & (ETNA_DIRTY_STENCIL_REF))) {
|
||||
/*014A0*/ EMIT_STATE(PE_STENCIL_CONFIG_EXT, ctx->stencil_ref.PE_STENCIL_CONFIG_EXT);
|
||||
}
|
||||
if (unlikely(dirty & (ETNA_DIRTY_BLEND))) {
|
||||
struct etna_blend_state *blend = etna_blend_state(ctx->blend);
|
||||
|
||||
/*014A4*/ EMIT_STATE(PE_LOGIC_OP, blend->PE_LOGIC_OP);
|
||||
for (int x = 0; x < 2; ++x) {
|
||||
/*014A8*/ EMIT_STATE(PE_DITHER(x), blend->PE_DITHER[x]);
|
||||
}
|
||||
}
|
||||
if (unlikely(dirty & (ETNA_DIRTY_FRAMEBUFFER | ETNA_DIRTY_TS))) {
|
||||
/*01654*/ EMIT_STATE(TS_MEM_CONFIG, ctx->framebuffer.TS_MEM_CONFIG);
|
||||
/*01658*/ EMIT_STATE_RELOC(TS_COLOR_STATUS_BASE, &ctx->framebuffer.TS_COLOR_STATUS_BASE);
|
||||
/*0165C*/ EMIT_STATE_RELOC(TS_COLOR_SURFACE_BASE, &ctx->framebuffer.TS_COLOR_SURFACE_BASE);
|
||||
/*01660*/ EMIT_STATE(TS_COLOR_CLEAR_VALUE, ctx->framebuffer.TS_COLOR_CLEAR_VALUE);
|
||||
/*01664*/ EMIT_STATE_RELOC(TS_DEPTH_STATUS_BASE, &ctx->framebuffer.TS_DEPTH_STATUS_BASE);
|
||||
/*01668*/ EMIT_STATE_RELOC(TS_DEPTH_SURFACE_BASE, &ctx->framebuffer.TS_DEPTH_SURFACE_BASE);
|
||||
/*0166C*/ EMIT_STATE(TS_DEPTH_CLEAR_VALUE, ctx->framebuffer.TS_DEPTH_CLEAR_VALUE);
|
||||
}
|
||||
if (unlikely(dirty & (ETNA_DIRTY_SAMPLER_VIEWS | ETNA_DIRTY_SAMPLERS))) {
|
||||
for (int x = 0; x < VIVS_TE_SAMPLER__LEN; ++x) {
|
||||
uint32_t val = 0; /* 0 == sampler inactive */
|
||||
|
||||
/* set active samplers to their configuration value (determined by both
|
||||
* the sampler state and sampler view) */
|
||||
if ((1 << x) & active_samplers) {
|
||||
struct etna_sampler_state *ss = etna_sampler_state(ctx->sampler[x]);
|
||||
struct etna_sampler_view *sv = etna_sampler_view(ctx->sampler_view[x]);
|
||||
|
||||
val = (ss->TE_SAMPLER_CONFIG0 & sv->TE_SAMPLER_CONFIG0_MASK) |
|
||||
sv->TE_SAMPLER_CONFIG0;
|
||||
}
|
||||
|
||||
/*02000*/ EMIT_STATE(TE_SAMPLER_CONFIG0(x), val);
|
||||
}
|
||||
}
|
||||
if (unlikely(dirty & (ETNA_DIRTY_SAMPLER_VIEWS))) {
|
||||
struct etna_sampler_view *sv;
|
||||
|
||||
for (int x = 0; x < VIVS_TE_SAMPLER__LEN; ++x) {
|
||||
if ((1 << x) & active_samplers) {
|
||||
sv = etna_sampler_view(ctx->sampler_view[x]);
|
||||
/*02040*/ EMIT_STATE(TE_SAMPLER_SIZE(x), sv->TE_SAMPLER_SIZE);
|
||||
}
|
||||
}
|
||||
for (int x = 0; x < VIVS_TE_SAMPLER__LEN; ++x) {
|
||||
if ((1 << x) & active_samplers) {
|
||||
sv = etna_sampler_view(ctx->sampler_view[x]);
|
||||
/*02080*/ EMIT_STATE(TE_SAMPLER_LOG_SIZE(x), sv->TE_SAMPLER_LOG_SIZE);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (unlikely(dirty & (ETNA_DIRTY_SAMPLER_VIEWS | ETNA_DIRTY_SAMPLERS))) {
|
||||
struct etna_sampler_state *ss;
|
||||
struct etna_sampler_view *sv;
|
||||
|
||||
for (int x = 0; x < VIVS_TE_SAMPLER__LEN; ++x) {
|
||||
if ((1 << x) & active_samplers) {
|
||||
ss = etna_sampler_state(ctx->sampler[x]);
|
||||
sv = etna_sampler_view(ctx->sampler_view[x]);
|
||||
|
||||
/* min and max lod is determined both by the sampler and the view */
|
||||
/*020C0*/ EMIT_STATE(TE_SAMPLER_LOD_CONFIG(x),
|
||||
ss->TE_SAMPLER_LOD_CONFIG |
|
||||
VIVS_TE_SAMPLER_LOD_CONFIG_MAX(MIN2(ss->max_lod, sv->max_lod)) |
|
||||
VIVS_TE_SAMPLER_LOD_CONFIG_MIN(MAX2(ss->min_lod, sv->min_lod)));
|
||||
}
|
||||
}
|
||||
for (int x = 0; x < VIVS_TE_SAMPLER__LEN; ++x) {
|
||||
if ((1 << x) & active_samplers) {
|
||||
ss = etna_sampler_state(ctx->sampler[x]);
|
||||
sv = etna_sampler_view(ctx->sampler_view[x]);
|
||||
|
||||
/*021C0*/ EMIT_STATE(TE_SAMPLER_CONFIG1(x), ss->TE_SAMPLER_CONFIG1 |
|
||||
sv->TE_SAMPLER_CONFIG1);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (unlikely(dirty & (ETNA_DIRTY_SAMPLER_VIEWS))) {
|
||||
for (int y = 0; y < VIVS_TE_SAMPLER_LOD_ADDR__LEN; ++y) {
|
||||
for (int x = 0; x < VIVS_TE_SAMPLER__LEN; ++x) {
|
||||
if ((1 << x) & active_samplers) {
|
||||
struct etna_sampler_view *sv = etna_sampler_view(ctx->sampler_view[x]);
|
||||
/*02400*/ EMIT_STATE_RELOC(TE_SAMPLER_LOD_ADDR(x, y),&sv->TE_SAMPLER_LOD_ADDR[y]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (unlikely(dirty & (ETNA_DIRTY_SHADER))) {
|
||||
/*0381C*/ EMIT_STATE(GL_VARYING_TOTAL_COMPONENTS, ctx->shader_state.GL_VARYING_TOTAL_COMPONENTS);
|
||||
/*03820*/ EMIT_STATE(GL_VARYING_NUM_COMPONENTS, ctx->shader_state.GL_VARYING_NUM_COMPONENTS);
|
||||
for (int x = 0; x < 2; ++x) {
|
||||
/*03828*/ EMIT_STATE(GL_VARYING_COMPONENT_USE(x), ctx->shader_state.GL_VARYING_COMPONENT_USE[x]);
|
||||
}
|
||||
}
|
||||
etna_coalesce_end(stream, &coalesce);
|
||||
/* end only EMIT_STATE */
|
||||
|
||||
/* Insert a FE/PE stall as changing the shader instructions (and maybe
|
||||
* the uniforms) can corrupt the previous in-progress draw operation.
|
||||
* Observed with amoeba on GC2000 during the right-to-left rendering
|
||||
* of PI, and can cause GPU hangs immediately after.
|
||||
* I summise that this is because the "new" locations at 0xc000 are not
|
||||
* properly protected against updates as other states seem to be. Hence,
|
||||
* we detect the "new" vertex shader instruction offset to apply this. */
|
||||
if (ctx->dirty & (ETNA_DIRTY_SHADER | ETNA_DIRTY_CONSTBUF) && ctx->specs.vs_offset > 0x4000)
|
||||
etna_stall(ctx->stream, SYNC_RECIPIENT_FE, SYNC_RECIPIENT_PE);
|
||||
|
||||
/* We need to update the uniform cache only if one of the following bits are
|
||||
* set in ctx->dirty:
|
||||
* - ETNA_DIRTY_SHADER
|
||||
* - ETNA_DIRTY_CONSTBUF
|
||||
* - uniforms_dirty_bits
|
||||
*
|
||||
* In case of ETNA_DIRTY_SHADER we need load all uniforms from the cache. In
|
||||
* all
|
||||
* other cases we can load on the changed uniforms.
|
||||
*/
|
||||
static const uint32_t uniform_dirty_bits =
|
||||
ETNA_DIRTY_SHADER | ETNA_DIRTY_CONSTBUF;
|
||||
|
||||
if (dirty & (uniform_dirty_bits | ctx->fs->uniforms_dirty_bits))
|
||||
etna_uniforms_write(
|
||||
ctx, ctx->vs, &ctx->constant_buffer[PIPE_SHADER_VERTEX],
|
||||
ctx->shader_state.VS_UNIFORMS, &ctx->shader_state.vs_uniforms_size);
|
||||
|
||||
if (dirty & (uniform_dirty_bits | ctx->vs->uniforms_dirty_bits))
|
||||
etna_uniforms_write(
|
||||
ctx, ctx->fs, &ctx->constant_buffer[PIPE_SHADER_FRAGMENT],
|
||||
ctx->shader_state.PS_UNIFORMS, &ctx->shader_state.ps_uniforms_size);
|
||||
|
||||
/**** Large dynamically-sized state ****/
|
||||
if (dirty & (ETNA_DIRTY_SHADER)) {
|
||||
/* Special case: a new shader was loaded; simply re-load all uniforms and
|
||||
* shader code at once */
|
||||
/*04000 or 0C000*/
|
||||
etna_set_state_multi(stream, ctx->specs.vs_offset,
|
||||
ctx->shader_state.vs_inst_mem_size,
|
||||
ctx->shader_state.VS_INST_MEM);
|
||||
/*06000 or 0D000*/
|
||||
etna_set_state_multi(stream, ctx->specs.ps_offset,
|
||||
ctx->shader_state.ps_inst_mem_size,
|
||||
ctx->shader_state.PS_INST_MEM);
|
||||
/*05000*/ etna_set_state_multi(stream, VIVS_VS_UNIFORMS(0),
|
||||
ctx->shader_state.vs_uniforms_size,
|
||||
ctx->shader_state.VS_UNIFORMS);
|
||||
/*07000*/ etna_set_state_multi(stream, VIVS_PS_UNIFORMS(0),
|
||||
ctx->shader_state.ps_uniforms_size,
|
||||
ctx->shader_state.PS_UNIFORMS);
|
||||
|
||||
/* Copy uniforms to gpu3d, so that incremental updates to uniforms are
|
||||
* possible as long as the
|
||||
* same shader remains bound */
|
||||
ctx->gpu3d.vs_uniforms_size = ctx->shader_state.vs_uniforms_size;
|
||||
ctx->gpu3d.ps_uniforms_size = ctx->shader_state.ps_uniforms_size;
|
||||
memcpy(ctx->gpu3d.VS_UNIFORMS, ctx->shader_state.VS_UNIFORMS,
|
||||
ctx->shader_state.vs_uniforms_size * 4);
|
||||
memcpy(ctx->gpu3d.PS_UNIFORMS, ctx->shader_state.PS_UNIFORMS,
|
||||
ctx->shader_state.ps_uniforms_size * 4);
|
||||
} else {
|
||||
etna_coalesce_start(stream, &coalesce);
|
||||
for (int x = 0; x < ctx->vs->uniforms.const_count; ++x) {
|
||||
if (ctx->gpu3d.VS_UNIFORMS[x] != ctx->shader_state.VS_UNIFORMS[x]) {
|
||||
/*05000*/ EMIT_STATE(VS_UNIFORMS(x), ctx->shader_state.VS_UNIFORMS[x]);
|
||||
ctx->gpu3d.VS_UNIFORMS[x] = ctx->shader_state.VS_UNIFORMS[x];
|
||||
}
|
||||
}
|
||||
etna_coalesce_end(stream, &coalesce);
|
||||
|
||||
etna_coalesce_start(stream, &coalesce);
|
||||
for (int x = 0; x < ctx->fs->uniforms.const_count; ++x) {
|
||||
if (ctx->gpu3d.PS_UNIFORMS[x] != ctx->shader_state.PS_UNIFORMS[x]) {
|
||||
/*07000*/ EMIT_STATE(PS_UNIFORMS(x), ctx->shader_state.PS_UNIFORMS[x]);
|
||||
ctx->gpu3d.PS_UNIFORMS[x] = ctx->shader_state.PS_UNIFORMS[x];
|
||||
}
|
||||
}
|
||||
etna_coalesce_end(stream, &coalesce);
|
||||
}
|
||||
/**** End of state update ****/
|
||||
#undef EMIT_STATE
|
||||
#undef EMIT_STATE_FIXP
|
||||
#undef EMIT_STATE_RELOC
|
||||
ctx->dirty = 0;
|
||||
}
|
|
@ -0,0 +1,123 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2015 Etnaviv Project
|
||||
*
|
||||
* 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, sub license,
|
||||
* 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 NON-INFRINGEMENT. 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:
|
||||
* Wladimir J. van der Laan <laanwj@gmail.com>
|
||||
*/
|
||||
|
||||
#ifndef H_ETNA_EMIT
|
||||
#define H_ETNA_EMIT
|
||||
|
||||
#include "etnaviv_screen.h"
|
||||
#include "etnaviv_util.h"
|
||||
#include "hw/cmdstream.xml.h"
|
||||
|
||||
struct etna_context;
|
||||
struct compiled_rs_state;
|
||||
|
||||
static inline void
|
||||
etna_emit_load_state(struct etna_cmd_stream *stream, const uint16_t offset,
|
||||
const uint16_t count, const int fixp)
|
||||
{
|
||||
uint32_t v;
|
||||
|
||||
v = VIV_FE_LOAD_STATE_HEADER_OP_LOAD_STATE |
|
||||
COND(fixp, VIV_FE_LOAD_STATE_HEADER_FIXP) |
|
||||
VIV_FE_LOAD_STATE_HEADER_OFFSET(offset) |
|
||||
(VIV_FE_LOAD_STATE_HEADER_COUNT(count) &
|
||||
VIV_FE_LOAD_STATE_HEADER_COUNT__MASK);
|
||||
|
||||
etna_cmd_stream_emit(stream, v);
|
||||
}
|
||||
|
||||
static inline void
|
||||
etna_set_state(struct etna_cmd_stream *stream, uint32_t address, uint32_t value)
|
||||
{
|
||||
etna_cmd_stream_reserve(stream, 2);
|
||||
etna_emit_load_state(stream, address >> 2, 1, 0);
|
||||
etna_cmd_stream_emit(stream, value);
|
||||
}
|
||||
|
||||
static inline void
|
||||
etna_set_state_reloc(struct etna_cmd_stream *stream, uint32_t address,
|
||||
struct etna_reloc *reloc)
|
||||
{
|
||||
etna_cmd_stream_reserve(stream, 2);
|
||||
etna_emit_load_state(stream, address >> 2, 1, 0);
|
||||
etna_cmd_stream_reloc(stream, reloc);
|
||||
}
|
||||
|
||||
static inline void
|
||||
etna_set_state_multi(struct etna_cmd_stream *stream, uint32_t base,
|
||||
uint32_t num, const uint32_t *values)
|
||||
{
|
||||
if (num == 0)
|
||||
return;
|
||||
|
||||
etna_cmd_stream_reserve(stream, 1 + num + 1); /* 1 extra for potential alignment */
|
||||
etna_emit_load_state(stream, base >> 2, num, 0);
|
||||
|
||||
for (uint32_t i = 0; i < num; i++)
|
||||
etna_cmd_stream_emit(stream, values[i]);
|
||||
|
||||
/* add potential padding */
|
||||
if ((num % 2) == 0)
|
||||
etna_cmd_stream_emit(stream, 0);
|
||||
}
|
||||
|
||||
void
|
||||
etna_stall(struct etna_cmd_stream *stream, uint32_t from, uint32_t to);
|
||||
|
||||
void
|
||||
etna_submit_rs_state(struct etna_context *ctx, const struct compiled_rs_state *cs);
|
||||
|
||||
static inline void
|
||||
etna_draw_primitives(struct etna_cmd_stream *stream, uint32_t primitive_type,
|
||||
uint32_t start, uint32_t count)
|
||||
{
|
||||
etna_cmd_stream_reserve(stream, 4);
|
||||
|
||||
etna_cmd_stream_emit(stream, VIV_FE_DRAW_PRIMITIVES_HEADER_OP_DRAW_PRIMITIVES);
|
||||
etna_cmd_stream_emit(stream, primitive_type);
|
||||
etna_cmd_stream_emit(stream, start);
|
||||
etna_cmd_stream_emit(stream, count);
|
||||
}
|
||||
|
||||
static inline void
|
||||
etna_draw_indexed_primitives(struct etna_cmd_stream *stream,
|
||||
uint32_t primitive_type, uint32_t start,
|
||||
uint32_t count, uint32_t offset)
|
||||
{
|
||||
etna_cmd_stream_reserve(stream, 5 + 1);
|
||||
|
||||
etna_cmd_stream_emit(stream, VIV_FE_DRAW_INDEXED_PRIMITIVES_HEADER_OP_DRAW_INDEXED_PRIMITIVES);
|
||||
etna_cmd_stream_emit(stream, primitive_type);
|
||||
etna_cmd_stream_emit(stream, start);
|
||||
etna_cmd_stream_emit(stream, count);
|
||||
etna_cmd_stream_emit(stream, offset);
|
||||
etna_cmd_stream_emit(stream, 0);
|
||||
}
|
||||
|
||||
void
|
||||
etna_emit_state(struct etna_context *ctx);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,87 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2015 Etnaviv Project
|
||||
*
|
||||
* 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, sub license,
|
||||
* 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 NON-INFRINGEMENT. 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:
|
||||
* Wladimir J. van der Laan <laanwj@gmail.com>
|
||||
* Rob Clark <robclark@freedesktop.org>
|
||||
*/
|
||||
|
||||
#include "etnaviv_fence.h"
|
||||
#include "etnaviv_context.h"
|
||||
#include "etnaviv_screen.h"
|
||||
|
||||
#include "util/u_inlines.h"
|
||||
#include "util/u_memory.h"
|
||||
|
||||
struct pipe_fence_handle {
|
||||
struct pipe_reference reference;
|
||||
struct etna_context *ctx;
|
||||
struct etna_screen *screen;
|
||||
uint32_t timestamp;
|
||||
};
|
||||
|
||||
static void
|
||||
etna_screen_fence_reference(struct pipe_screen *pscreen,
|
||||
struct pipe_fence_handle **ptr,
|
||||
struct pipe_fence_handle *fence)
|
||||
{
|
||||
if (pipe_reference(&(*ptr)->reference, &fence->reference))
|
||||
FREE(*ptr);
|
||||
|
||||
*ptr = fence;
|
||||
}
|
||||
|
||||
static boolean
|
||||
etna_screen_fence_finish(struct pipe_screen *pscreen, struct pipe_context *ctx,
|
||||
struct pipe_fence_handle *fence, uint64_t timeout)
|
||||
{
|
||||
if (etna_pipe_wait_ns(fence->screen->pipe, fence->timestamp, timeout))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
struct pipe_fence_handle *
|
||||
etna_fence_create(struct pipe_context *pctx)
|
||||
{
|
||||
struct pipe_fence_handle *fence;
|
||||
struct etna_context *ctx = etna_context(pctx);
|
||||
|
||||
fence = CALLOC_STRUCT(pipe_fence_handle);
|
||||
if (!fence)
|
||||
return NULL;
|
||||
|
||||
pipe_reference_init(&fence->reference, 1);
|
||||
|
||||
fence->ctx = ctx;
|
||||
fence->screen = ctx->screen;
|
||||
fence->timestamp = etna_cmd_stream_timestamp(ctx->stream);
|
||||
|
||||
return fence;
|
||||
}
|
||||
|
||||
void
|
||||
etna_fence_screen_init(struct pipe_screen *pscreen)
|
||||
{
|
||||
pscreen->fence_reference = etna_screen_fence_reference;
|
||||
pscreen->fence_finish = etna_screen_fence_finish;
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2015 Etnaviv Project
|
||||
*
|
||||
* 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, sub license,
|
||||
* 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 NON-INFRINGEMENT. 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:
|
||||
* Wladimir J. van der Laan <laanwj@gmail.com>
|
||||
* Rob Clark <robclark@freedesktop.org>
|
||||
*/
|
||||
|
||||
#ifndef ETNAVIV_FENCE_H_
|
||||
#define ETNAVIV_FENCE_H_
|
||||
|
||||
#include "pipe/p_context.h"
|
||||
|
||||
struct pipe_fence_handle *
|
||||
etna_fence_create(struct pipe_context *pctx);
|
||||
|
||||
void
|
||||
etna_fence_screen_init(struct pipe_screen *pscreen);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,268 @@
|
|||
/*
|
||||
* Copyright (c) 2016 Etnaviv Project
|
||||
*
|
||||
* 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, sub license,
|
||||
* 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 NON-INFRINGEMENT. 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:
|
||||
* Christian Gmeiner <christian.gmeiner@gmail.com>
|
||||
*/
|
||||
|
||||
#include "etnaviv_format.h"
|
||||
|
||||
#include "hw/state.xml.h"
|
||||
#include "hw/state_3d.xml.h"
|
||||
|
||||
#include "pipe/p_defines.h"
|
||||
|
||||
/* Specifies the table of all the formats and their features. Also supplies
|
||||
* the helpers that look up various data in those tables.
|
||||
*/
|
||||
|
||||
struct etna_format {
|
||||
unsigned vtx;
|
||||
unsigned tex;
|
||||
unsigned rs;
|
||||
boolean present;
|
||||
};
|
||||
|
||||
#define RS_FORMAT_NONE ~0
|
||||
|
||||
#define RS_FORMAT_MASK 0xf
|
||||
#define RS_FORMAT(x) ((x) & RS_FORMAT_MASK)
|
||||
#define RS_FORMAT_RB_SWAP 0x10
|
||||
|
||||
#define RS_FORMAT_X8B8G8R8 (RS_FORMAT_X8R8G8B8 | RS_FORMAT_RB_SWAP)
|
||||
#define RS_FORMAT_A8B8G8R8 (RS_FORMAT_A8R8G8B8 | RS_FORMAT_RB_SWAP)
|
||||
|
||||
/* vertex + texture */
|
||||
#define VT(pipe, vtxfmt, texfmt, rsfmt) \
|
||||
[PIPE_FORMAT_##pipe] = { \
|
||||
.vtx = VIVS_FE_VERTEX_ELEMENT_CONFIG_TYPE_##vtxfmt, \
|
||||
.tex = TEXTURE_FORMAT_##texfmt, \
|
||||
.rs = RS_FORMAT_##rsfmt, \
|
||||
.present = 1, \
|
||||
}
|
||||
|
||||
/* texture-only */
|
||||
#define _T(pipe, fmt, rsfmt) \
|
||||
[PIPE_FORMAT_##pipe] = { \
|
||||
.vtx = ETNA_NO_MATCH, \
|
||||
.tex = TEXTURE_FORMAT_##fmt, \
|
||||
.rs = RS_FORMAT_##rsfmt, \
|
||||
.present = 1, \
|
||||
}
|
||||
|
||||
/* vertex-only */
|
||||
#define V_(pipe, fmt, rsfmt) \
|
||||
[PIPE_FORMAT_##pipe] = { \
|
||||
.vtx = VIVS_FE_VERTEX_ELEMENT_CONFIG_TYPE_##fmt, \
|
||||
.tex = ETNA_NO_MATCH, \
|
||||
.rs = RS_FORMAT_##rsfmt, \
|
||||
.present = 1, \
|
||||
}
|
||||
|
||||
static struct etna_format formats[PIPE_FORMAT_COUNT] = {
|
||||
/* 8-bit */
|
||||
V_(R8_UNORM, UNSIGNED_BYTE, NONE),
|
||||
V_(R8_SNORM, BYTE, NONE),
|
||||
V_(R8_UINT, UNSIGNED_BYTE, NONE),
|
||||
V_(R8_SINT, BYTE, NONE),
|
||||
V_(R8_USCALED, UNSIGNED_BYTE, NONE),
|
||||
V_(R8_SSCALED, BYTE, NONE),
|
||||
|
||||
_T(A8_UNORM, A8, NONE),
|
||||
_T(L8_UNORM, L8, NONE),
|
||||
_T(I8_UNORM, I8, NONE),
|
||||
|
||||
/* 16-bit */
|
||||
V_(R16_UNORM, UNSIGNED_SHORT, NONE),
|
||||
V_(R16_SNORM, SHORT, NONE),
|
||||
V_(R16_UINT, UNSIGNED_SHORT, NONE),
|
||||
V_(R16_SINT, SHORT, NONE),
|
||||
V_(R16_USCALED, UNSIGNED_SHORT, NONE),
|
||||
V_(R16_SSCALED, SHORT, NONE),
|
||||
V_(R16_FLOAT, HALF_FLOAT, NONE),
|
||||
|
||||
_T(B4G4R4A4_UNORM, A4R4G4B4, A4R4G4B4),
|
||||
_T(B4G4R4X4_UNORM, X4R4G4B4, X4R4G4B4),
|
||||
|
||||
_T(Z16_UNORM, D16, A4R4G4B4),
|
||||
_T(B5G6R5_UNORM, R5G6B5, R5G6B5),
|
||||
_T(B5G5R5A1_UNORM, A1R5G5B5, A1R5G5B5),
|
||||
_T(B5G5R5X1_UNORM, X1R5G5B5, X1R5G5B5),
|
||||
|
||||
V_(R8G8_UNORM, UNSIGNED_BYTE, NONE),
|
||||
V_(R8G8_SNORM, BYTE, NONE),
|
||||
V_(R8G8_UINT, UNSIGNED_BYTE, NONE),
|
||||
V_(R8G8_SINT, BYTE, NONE),
|
||||
V_(R8G8_USCALED, UNSIGNED_BYTE, NONE),
|
||||
V_(R8G8_SSCALED, BYTE, NONE),
|
||||
|
||||
/* 24-bit */
|
||||
V_(R8G8B8_UNORM, UNSIGNED_BYTE, NONE),
|
||||
V_(R8G8B8_SNORM, BYTE, NONE),
|
||||
V_(R8G8B8_UINT, UNSIGNED_BYTE, NONE),
|
||||
V_(R8G8B8_SINT, BYTE, NONE),
|
||||
V_(R8G8B8_USCALED, UNSIGNED_BYTE, NONE),
|
||||
V_(R8G8B8_SSCALED, BYTE, NONE),
|
||||
|
||||
/* 32-bit */
|
||||
V_(R32_UNORM, UNSIGNED_INT, NONE),
|
||||
V_(R32_SNORM, INT, NONE),
|
||||
V_(R32_SINT, INT, NONE),
|
||||
V_(R32_UINT, UNSIGNED_INT, NONE),
|
||||
V_(R32_USCALED, UNSIGNED_INT, NONE),
|
||||
V_(R32_SSCALED, INT, NONE),
|
||||
V_(R32_FLOAT, FLOAT, NONE),
|
||||
V_(R32_FIXED, FIXED, NONE),
|
||||
|
||||
V_(R16G16_UNORM, UNSIGNED_SHORT, NONE),
|
||||
V_(R16G16_SNORM, SHORT, NONE),
|
||||
V_(R16G16_UINT, UNSIGNED_SHORT, NONE),
|
||||
V_(R16G16_SINT, SHORT, NONE),
|
||||
V_(R16G16_USCALED, UNSIGNED_SHORT, NONE),
|
||||
V_(R16G16_SSCALED, SHORT, NONE),
|
||||
V_(R16G16_FLOAT, HALF_FLOAT, NONE),
|
||||
|
||||
V_(A8B8G8R8_UNORM, UNSIGNED_BYTE, NONE),
|
||||
|
||||
V_(R8G8B8A8_UNORM, UNSIGNED_BYTE, A8B8G8R8),
|
||||
V_(R8G8B8A8_SNORM, BYTE, A8B8G8R8),
|
||||
_T(R8G8B8X8_UNORM, X8B8G8R8, X8B8G8R8),
|
||||
V_(R8G8B8A8_UINT, UNSIGNED_BYTE, A8B8G8R8),
|
||||
V_(R8G8B8A8_SINT, BYTE, A8B8G8R8),
|
||||
V_(R8G8B8A8_USCALED, UNSIGNED_BYTE, A8B8G8R8),
|
||||
V_(R8G8B8A8_SSCALED, BYTE, A8B8G8R8),
|
||||
|
||||
_T(R8G8B8A8_UNORM, A8B8G8R8, A8B8G8R8),
|
||||
_T(R8G8B8X8_UNORM, X8B8G8R8, X8B8G8R8),
|
||||
|
||||
_T(B8G8R8A8_UNORM, A8R8G8B8, A8R8G8B8),
|
||||
_T(B8G8R8X8_UNORM, X8R8G8B8, X8R8G8B8),
|
||||
|
||||
V_(R10G10B10A2_UNORM, UNSIGNED_INT_10_10_10_2, NONE),
|
||||
V_(R10G10B10A2_SNORM, INT_10_10_10_2, NONE),
|
||||
V_(R10G10B10A2_USCALED, UNSIGNED_INT_10_10_10_2, NONE),
|
||||
V_(R10G10B10A2_SSCALED, INT_10_10_10_2, NONE),
|
||||
|
||||
_T(X8Z24_UNORM, D24S8, A8R8G8B8),
|
||||
_T(S8_UINT_Z24_UNORM, D24S8, A8R8G8B8),
|
||||
|
||||
/* 48-bit */
|
||||
V_(R16G16B16_UNORM, UNSIGNED_SHORT, NONE),
|
||||
V_(R16G16B16_SNORM, SHORT, NONE),
|
||||
V_(R16G16B16_UINT, UNSIGNED_SHORT, NONE),
|
||||
V_(R16G16B16_SINT, SHORT, NONE),
|
||||
V_(R16G16B16_USCALED, UNSIGNED_SHORT, NONE),
|
||||
V_(R16G16B16_SSCALED, SHORT, NONE),
|
||||
V_(R16G16B16_FLOAT, HALF_FLOAT, NONE),
|
||||
|
||||
/* 64-bit */
|
||||
V_(R16G16B16A16_UNORM, UNSIGNED_SHORT, NONE),
|
||||
V_(R16G16B16A16_SNORM, SHORT, NONE),
|
||||
V_(R16G16B16A16_UINT, UNSIGNED_SHORT, NONE),
|
||||
V_(R16G16B16A16_SINT, SHORT, NONE),
|
||||
V_(R16G16B16A16_USCALED, UNSIGNED_SHORT, NONE),
|
||||
V_(R16G16B16A16_SSCALED, SHORT, NONE),
|
||||
V_(R16G16B16A16_FLOAT, HALF_FLOAT, NONE),
|
||||
|
||||
V_(R32G32_UNORM, UNSIGNED_INT, NONE),
|
||||
V_(R32G32_SNORM, INT, NONE),
|
||||
V_(R32G32_UINT, UNSIGNED_INT, NONE),
|
||||
V_(R32G32_SINT, INT, NONE),
|
||||
V_(R32G32_USCALED, UNSIGNED_INT, NONE),
|
||||
V_(R32G32_SSCALED, INT, NONE),
|
||||
V_(R32G32_FLOAT, FLOAT, NONE),
|
||||
V_(R32G32_FIXED, FIXED, NONE),
|
||||
|
||||
/* 96-bit */
|
||||
V_(R32G32B32_UNORM, UNSIGNED_INT, NONE),
|
||||
V_(R32G32B32_SNORM, INT, NONE),
|
||||
V_(R32G32B32_UINT, UNSIGNED_INT, NONE),
|
||||
V_(R32G32B32_SINT, INT, NONE),
|
||||
V_(R32G32B32_USCALED, UNSIGNED_INT, NONE),
|
||||
V_(R32G32B32_SSCALED, INT, NONE),
|
||||
V_(R32G32B32_FLOAT, FLOAT, NONE),
|
||||
V_(R32G32B32_FIXED, FIXED, NONE),
|
||||
|
||||
/* 128-bit */
|
||||
V_(R32G32B32A32_UNORM, UNSIGNED_INT, NONE),
|
||||
V_(R32G32B32A32_SNORM, INT, NONE),
|
||||
V_(R32G32B32A32_UINT, UNSIGNED_INT, NONE),
|
||||
V_(R32G32B32A32_SINT, INT, NONE),
|
||||
V_(R32G32B32A32_USCALED, UNSIGNED_INT, NONE),
|
||||
V_(R32G32B32A32_SSCALED, INT, NONE),
|
||||
V_(R32G32B32A32_FLOAT, FLOAT, NONE),
|
||||
V_(R32G32B32A32_FIXED, FIXED, NONE),
|
||||
|
||||
/* compressed */
|
||||
_T(ETC1_RGB8, ETC1, NONE),
|
||||
|
||||
_T(DXT1_RGB, DXT1, NONE),
|
||||
_T(DXT1_RGBA, DXT1, NONE),
|
||||
_T(DXT3_RGBA, DXT2_DXT3, NONE),
|
||||
_T(DXT3_RGBA, DXT2_DXT3, NONE),
|
||||
_T(DXT5_RGBA, DXT4_DXT5, NONE),
|
||||
|
||||
/* YUV */
|
||||
_T(YUYV, YUY2, YUY2),
|
||||
_T(UYVY, UYVY, NONE),
|
||||
};
|
||||
|
||||
uint32_t
|
||||
translate_texture_format(enum pipe_format fmt)
|
||||
{
|
||||
/* XXX with TEXTURE_FORMAT_EXT and swizzle on newer chips we can
|
||||
* support much more */
|
||||
if (!formats[fmt].present)
|
||||
return ETNA_NO_MATCH;
|
||||
|
||||
return formats[fmt].tex;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
translate_rs_format(enum pipe_format fmt)
|
||||
{
|
||||
if (!formats[fmt].present)
|
||||
return ETNA_NO_MATCH;
|
||||
|
||||
if (formats[fmt].rs == ETNA_NO_MATCH)
|
||||
return ETNA_NO_MATCH;
|
||||
|
||||
return RS_FORMAT(formats[fmt].rs);
|
||||
}
|
||||
|
||||
int
|
||||
translate_rs_format_rb_swap(enum pipe_format fmt)
|
||||
{
|
||||
assert(formats[fmt].present);
|
||||
|
||||
return formats[fmt].rs & RS_FORMAT_RB_SWAP;
|
||||
}
|
||||
|
||||
/* Return type flags for vertex element format */
|
||||
uint32_t
|
||||
translate_vertex_format_type(enum pipe_format fmt)
|
||||
{
|
||||
if (!formats[fmt].present)
|
||||
return ETNA_NO_MATCH;
|
||||
|
||||
return formats[fmt].vtx;
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* Copyright (c) 2016 Etnaviv Project
|
||||
*
|
||||
* 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, sub license,
|
||||
* 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 NON-INFRINGEMENT. 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:
|
||||
* Christian Gmeiner <christian.gmeiner@gmail.com>
|
||||
*/
|
||||
|
||||
#ifndef ETNAVIV_FORMAT_H_
|
||||
#define ETNAVIV_FORMAT_H_
|
||||
|
||||
#include "util/u_format.h"
|
||||
#include <stdint.h>
|
||||
|
||||
#define ETNA_NO_MATCH (~0)
|
||||
|
||||
uint32_t
|
||||
translate_texture_format(enum pipe_format fmt);
|
||||
|
||||
uint32_t
|
||||
translate_rs_format(enum pipe_format fmt);
|
||||
|
||||
int
|
||||
translate_rs_format_rb_swap(enum pipe_format fmt);
|
||||
|
||||
uint32_t
|
||||
translate_vertex_format_type(enum pipe_format fmt);
|
||||
|
||||
#endif /* ETNAVIV_FORMAT_H_ */
|
|
@ -0,0 +1,259 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2015 Etnaviv Project
|
||||
*
|
||||
* 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, sub license,
|
||||
* 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 NON-INFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef H_ETNA_INTERNAL
|
||||
#define H_ETNA_INTERNAL
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "hw/state.xml.h"
|
||||
#include "hw/state_3d.xml.h"
|
||||
|
||||
#include <etnaviv_drmif.h>
|
||||
|
||||
#define ETNA_NUM_INPUTS (16)
|
||||
#define ETNA_NUM_VARYINGS 8
|
||||
#define ETNA_NUM_LOD (14)
|
||||
#define ETNA_NUM_LAYERS (6)
|
||||
#define ETNA_MAX_UNIFORMS (256)
|
||||
#define ETNA_MAX_PIXELPIPES 2
|
||||
|
||||
/* All RS operations must have width%16 = 0 */
|
||||
#define ETNA_RS_WIDTH_MASK (16 - 1)
|
||||
/* RS tiled operations must have height%4 = 0 */
|
||||
#define ETNA_RS_HEIGHT_MASK (3)
|
||||
/* PE render targets must be aligned to 64 bytes */
|
||||
#define ETNA_PE_ALIGNMENT (64)
|
||||
|
||||
/* GPU chip 3D specs */
|
||||
struct etna_specs {
|
||||
/* supports SUPERTILE (64x64) tiling? */
|
||||
unsigned can_supertile : 1;
|
||||
/* needs z=(z+w)/2, for older GCxxx */
|
||||
unsigned vs_need_z_div : 1;
|
||||
/* supports trigonometric instructions */
|
||||
unsigned has_sin_cos_sqrt : 1;
|
||||
/* has SIGN/FLOOR/CEIL instructions */
|
||||
unsigned has_sign_floor_ceil : 1;
|
||||
/* can use VS_RANGE, PS_RANGE registers*/
|
||||
unsigned has_shader_range_registers : 1;
|
||||
/* can use any kind of wrapping mode on npot textures */
|
||||
unsigned npot_tex_any_wrap;
|
||||
/* number of bits per TS tile */
|
||||
unsigned bits_per_tile;
|
||||
/* clear value for TS (dependent on bits_per_tile) */
|
||||
uint32_t ts_clear_value;
|
||||
/* base of vertex texture units */
|
||||
unsigned vertex_sampler_offset;
|
||||
/* number of fragment sampler units */
|
||||
unsigned fragment_sampler_count;
|
||||
/* number of vertex sampler units */
|
||||
unsigned vertex_sampler_count;
|
||||
/* size of vertex shader output buffer */
|
||||
unsigned vertex_output_buffer_size;
|
||||
/* maximum number of vertex element configurations */
|
||||
unsigned vertex_max_elements;
|
||||
/* size of a cached vertex (?) */
|
||||
unsigned vertex_cache_size;
|
||||
/* number of shader cores */
|
||||
unsigned shader_core_count;
|
||||
/* number of vertex streams */
|
||||
unsigned stream_count;
|
||||
/* vertex shader memory address*/
|
||||
uint32_t vs_offset;
|
||||
/* pixel shader memory address*/
|
||||
uint32_t ps_offset;
|
||||
/* vertex/fragment shader max instructions */
|
||||
uint32_t max_instructions;
|
||||
/* maximum number of varyings */
|
||||
unsigned max_varyings;
|
||||
/* maximum number of registers */
|
||||
unsigned max_registers;
|
||||
/* maximum vertex uniforms */
|
||||
unsigned max_vs_uniforms;
|
||||
/* maximum pixel uniforms */
|
||||
unsigned max_ps_uniforms;
|
||||
/* maximum texture size */
|
||||
unsigned max_texture_size;
|
||||
/* maximum texture size */
|
||||
unsigned max_rendertarget_size;
|
||||
/* available pixel pipes */
|
||||
unsigned pixel_pipes;
|
||||
/* number of constants */
|
||||
unsigned num_constants;
|
||||
};
|
||||
|
||||
/* Compiled Gallium state. All the different compiled state atoms are woven
|
||||
* together and uploaded only when it is necessary to synchronize the state,
|
||||
* for example before rendering. */
|
||||
|
||||
/* Compiled pipe_blend_color */
|
||||
struct compiled_blend_color {
|
||||
uint32_t PE_ALPHA_BLEND_COLOR;
|
||||
};
|
||||
|
||||
/* Compiled pipe_stencil_ref */
|
||||
struct compiled_stencil_ref {
|
||||
uint32_t PE_STENCIL_CONFIG;
|
||||
uint32_t PE_STENCIL_CONFIG_EXT;
|
||||
};
|
||||
|
||||
/* Compiled pipe_scissor_state */
|
||||
struct compiled_scissor_state {
|
||||
uint32_t SE_SCISSOR_LEFT;
|
||||
uint32_t SE_SCISSOR_TOP;
|
||||
uint32_t SE_SCISSOR_RIGHT;
|
||||
uint32_t SE_SCISSOR_BOTTOM;
|
||||
};
|
||||
|
||||
/* Compiled pipe_viewport_state */
|
||||
struct compiled_viewport_state {
|
||||
uint32_t PA_VIEWPORT_SCALE_X;
|
||||
uint32_t PA_VIEWPORT_SCALE_Y;
|
||||
uint32_t PA_VIEWPORT_SCALE_Z;
|
||||
uint32_t PA_VIEWPORT_OFFSET_X;
|
||||
uint32_t PA_VIEWPORT_OFFSET_Y;
|
||||
uint32_t PA_VIEWPORT_OFFSET_Z;
|
||||
uint32_t SE_SCISSOR_LEFT;
|
||||
uint32_t SE_SCISSOR_TOP;
|
||||
uint32_t SE_SCISSOR_RIGHT;
|
||||
uint32_t SE_SCISSOR_BOTTOM;
|
||||
uint32_t PE_DEPTH_NEAR;
|
||||
uint32_t PE_DEPTH_FAR;
|
||||
};
|
||||
|
||||
/* Compiled pipe_framebuffer_state */
|
||||
struct compiled_framebuffer_state {
|
||||
struct pipe_surface *cbuf, *zsbuf; /* keep reference to surfaces */
|
||||
uint32_t GL_MULTI_SAMPLE_CONFIG;
|
||||
uint32_t PE_COLOR_FORMAT;
|
||||
uint32_t PE_DEPTH_CONFIG;
|
||||
struct etna_reloc PE_DEPTH_ADDR;
|
||||
struct etna_reloc PE_PIPE_DEPTH_ADDR[ETNA_MAX_PIXELPIPES];
|
||||
uint32_t PE_DEPTH_STRIDE;
|
||||
uint32_t PE_HDEPTH_CONTROL;
|
||||
uint32_t PE_DEPTH_NORMALIZE;
|
||||
struct etna_reloc PE_COLOR_ADDR;
|
||||
struct etna_reloc PE_PIPE_COLOR_ADDR[ETNA_MAX_PIXELPIPES];
|
||||
uint32_t PE_COLOR_STRIDE;
|
||||
uint32_t SE_SCISSOR_LEFT;
|
||||
uint32_t SE_SCISSOR_TOP;
|
||||
uint32_t SE_SCISSOR_RIGHT;
|
||||
uint32_t SE_SCISSOR_BOTTOM;
|
||||
uint32_t RA_MULTISAMPLE_UNK00E04;
|
||||
uint32_t RA_MULTISAMPLE_UNK00E10[VIVS_RA_MULTISAMPLE_UNK00E10__LEN];
|
||||
uint32_t RA_CENTROID_TABLE[VIVS_RA_CENTROID_TABLE__LEN];
|
||||
uint32_t TS_MEM_CONFIG;
|
||||
uint32_t TS_DEPTH_CLEAR_VALUE;
|
||||
struct etna_reloc TS_DEPTH_STATUS_BASE;
|
||||
struct etna_reloc TS_DEPTH_SURFACE_BASE;
|
||||
uint32_t TS_COLOR_CLEAR_VALUE;
|
||||
struct etna_reloc TS_COLOR_STATUS_BASE;
|
||||
struct etna_reloc TS_COLOR_SURFACE_BASE;
|
||||
bool msaa_mode; /* adds input (and possible temp) to PS */
|
||||
};
|
||||
|
||||
/* Compiled context->create_vertex_elements_state */
|
||||
struct compiled_vertex_elements_state {
|
||||
unsigned num_elements;
|
||||
uint32_t FE_VERTEX_ELEMENT_CONFIG[VIVS_FE_VERTEX_ELEMENT_CONFIG__LEN];
|
||||
};
|
||||
|
||||
/* Compiled context->set_vertex_buffer result */
|
||||
struct compiled_set_vertex_buffer {
|
||||
uint32_t FE_VERTEX_STREAM_CONTROL;
|
||||
struct etna_reloc FE_VERTEX_STREAM_BASE_ADDR;
|
||||
};
|
||||
|
||||
/* Compiled linked VS+PS shader state */
|
||||
struct compiled_shader_state {
|
||||
uint32_t RA_CONTROL;
|
||||
uint32_t PA_ATTRIBUTE_ELEMENT_COUNT;
|
||||
uint32_t PA_CONFIG;
|
||||
uint32_t PA_SHADER_ATTRIBUTES[VIVS_PA_SHADER_ATTRIBUTES__LEN];
|
||||
uint32_t VS_END_PC;
|
||||
uint32_t VS_OUTPUT_COUNT; /* number of outputs if point size per vertex disabled */
|
||||
uint32_t VS_OUTPUT_COUNT_PSIZE; /* number of outputs of point size per vertex enabled */
|
||||
uint32_t VS_INPUT_COUNT;
|
||||
uint32_t VS_TEMP_REGISTER_CONTROL;
|
||||
uint32_t VS_OUTPUT[4];
|
||||
uint32_t VS_INPUT[4];
|
||||
uint32_t VS_LOAD_BALANCING;
|
||||
uint32_t VS_START_PC;
|
||||
uint32_t PS_END_PC;
|
||||
uint32_t PS_OUTPUT_REG;
|
||||
uint32_t PS_INPUT_COUNT;
|
||||
uint32_t PS_INPUT_COUNT_MSAA; /* Adds an input */
|
||||
uint32_t PS_TEMP_REGISTER_CONTROL;
|
||||
uint32_t PS_TEMP_REGISTER_CONTROL_MSAA; /* Adds a temporary if needed to make space for extra input */
|
||||
uint32_t PS_CONTROL;
|
||||
uint32_t PS_START_PC;
|
||||
uint32_t GL_VARYING_TOTAL_COMPONENTS;
|
||||
uint32_t GL_VARYING_NUM_COMPONENTS;
|
||||
uint32_t GL_VARYING_COMPONENT_USE[2];
|
||||
unsigned vs_inst_mem_size;
|
||||
unsigned vs_uniforms_size;
|
||||
unsigned ps_inst_mem_size;
|
||||
unsigned ps_uniforms_size;
|
||||
uint32_t *VS_INST_MEM;
|
||||
uint32_t VS_UNIFORMS[ETNA_MAX_UNIFORMS * 4];
|
||||
uint32_t *PS_INST_MEM;
|
||||
uint32_t PS_UNIFORMS[ETNA_MAX_UNIFORMS * 4];
|
||||
};
|
||||
|
||||
/* state of some 3d and common registers relevant to etna driver */
|
||||
struct etna_3d_state {
|
||||
unsigned vs_uniforms_size;
|
||||
unsigned ps_uniforms_size;
|
||||
|
||||
uint32_t /*01008*/ PS_INPUT_COUNT;
|
||||
uint32_t /*0100C*/ PS_TEMP_REGISTER_CONTROL;
|
||||
uint32_t /*03818*/ GL_MULTI_SAMPLE_CONFIG;
|
||||
uint32_t /*05000*/ VS_UNIFORMS[VIVS_VS_UNIFORMS__LEN];
|
||||
uint32_t /*07000*/ PS_UNIFORMS[VIVS_PS_UNIFORMS__LEN];
|
||||
};
|
||||
|
||||
/* Helpers to assist creating and setting bitarrays (eg, for varyings).
|
||||
* field_size must be a power of two, and <= 32. */
|
||||
#define DEFINE_ETNA_BITARRAY(name, num, field_size) \
|
||||
uint32_t name[(num) * (field_size) / 32]
|
||||
|
||||
static inline void
|
||||
etna_bitarray_set(uint32_t *array, size_t array_size, size_t field_size,
|
||||
size_t index, uint32_t value)
|
||||
{
|
||||
size_t shift = (index * field_size) % 32;
|
||||
size_t offset = (index * field_size) / 32;
|
||||
|
||||
assert(index < array_size * 32 / field_size);
|
||||
assert(value < 1 << field_size);
|
||||
|
||||
array[offset] |= value << shift;
|
||||
}
|
||||
|
||||
#define etna_bitarray_set(array, field_size, index, value) \
|
||||
etna_bitarray_set((array), ARRAY_SIZE(array), field_size, index, value)
|
||||
|
||||
#endif
|
|
@ -0,0 +1,120 @@
|
|||
/*
|
||||
* Copyright (c) 2016 Etnaviv Project
|
||||
*
|
||||
* 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, sub license,
|
||||
* 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 NON-INFRINGEMENT. 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>
|
||||
* Christian Gmeiner <christian.gmeiner@gmail.com>
|
||||
*/
|
||||
|
||||
#include "pipe/p_screen.h"
|
||||
|
||||
#include "etnaviv_context.h"
|
||||
#include "etnaviv_query.h"
|
||||
#include "etnaviv_query_sw.h"
|
||||
|
||||
static struct pipe_query *
|
||||
etna_create_query(struct pipe_context *pctx, unsigned query_type,
|
||||
unsigned index)
|
||||
{
|
||||
struct etna_context *ctx = etna_context(pctx);
|
||||
struct etna_query *q;
|
||||
|
||||
q = etna_sw_create_query(ctx, query_type);
|
||||
|
||||
return (struct pipe_query *)q;
|
||||
}
|
||||
|
||||
static void
|
||||
etna_destroy_query(struct pipe_context *pctx, struct pipe_query *pq)
|
||||
{
|
||||
struct etna_query *q = etna_query(pq);
|
||||
|
||||
q->funcs->destroy_query(etna_context(pctx), q);
|
||||
}
|
||||
|
||||
static boolean
|
||||
etna_begin_query(struct pipe_context *pctx, struct pipe_query *pq)
|
||||
{
|
||||
struct etna_query *q = etna_query(pq);
|
||||
|
||||
return q->funcs->begin_query(etna_context(pctx), q);
|
||||
}
|
||||
|
||||
static bool
|
||||
etna_end_query(struct pipe_context *pctx, struct pipe_query *pq)
|
||||
{
|
||||
struct etna_query *q = etna_query(pq);
|
||||
|
||||
q->funcs->end_query(etna_context(pctx), q);
|
||||
return true;
|
||||
}
|
||||
|
||||
static boolean
|
||||
etna_get_query_result(struct pipe_context *pctx, struct pipe_query *pq,
|
||||
boolean wait, union pipe_query_result *result)
|
||||
{
|
||||
struct etna_query *q = etna_query(pq);
|
||||
|
||||
return q->funcs->get_query_result(etna_context(pctx), q, wait, result);
|
||||
}
|
||||
|
||||
static int
|
||||
etna_get_driver_query_info(struct pipe_screen *pscreen, unsigned index,
|
||||
struct pipe_driver_query_info *info)
|
||||
{
|
||||
struct pipe_driver_query_info list[] = {
|
||||
{"prims-emitted", PIPE_QUERY_PRIMITIVES_EMITTED, { 0 }},
|
||||
{"draw-calls", ETNA_QUERY_DRAW_CALLS, { 0 }},
|
||||
};
|
||||
|
||||
if (!info)
|
||||
return ARRAY_SIZE(list);
|
||||
|
||||
if (index >= ARRAY_SIZE(list))
|
||||
return 0;
|
||||
|
||||
*info = list[index];
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
etna_set_active_query_state(struct pipe_context *pipe, boolean enable)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
etna_query_screen_init(struct pipe_screen *pscreen)
|
||||
{
|
||||
pscreen->get_driver_query_info = etna_get_driver_query_info;
|
||||
}
|
||||
|
||||
void
|
||||
etna_query_context_init(struct pipe_context *pctx)
|
||||
{
|
||||
pctx->create_query = etna_create_query;
|
||||
pctx->destroy_query = etna_destroy_query;
|
||||
pctx->begin_query = etna_begin_query;
|
||||
pctx->end_query = etna_end_query;
|
||||
pctx->get_query_result = etna_get_query_result;
|
||||
pctx->set_active_query_state = etna_set_active_query_state;
|
||||
}
|
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
* Copyright (c) 2016 Etnaviv Project
|
||||
*
|
||||
* 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, sub license,
|
||||
* 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 NON-INFRINGEMENT. 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>
|
||||
* Christian Gmeiner <christian.gmeiner@gmail.com>
|
||||
*/
|
||||
|
||||
#ifndef H_ETNAVIV_QUERY
|
||||
#define H_ETNAVIV_QUERY
|
||||
|
||||
#include "pipe/p_context.h"
|
||||
|
||||
struct etna_context;
|
||||
struct etna_query;
|
||||
|
||||
struct etna_query_funcs {
|
||||
void (*destroy_query)(struct etna_context *ctx, struct etna_query *q);
|
||||
boolean (*begin_query)(struct etna_context *ctx, struct etna_query *q);
|
||||
void (*end_query)(struct etna_context *ctx, struct etna_query *q);
|
||||
boolean (*get_query_result)(struct etna_context *ctx, struct etna_query *q,
|
||||
boolean wait, union pipe_query_result *result);
|
||||
};
|
||||
|
||||
struct etna_query {
|
||||
const struct etna_query_funcs *funcs;
|
||||
bool active;
|
||||
int type;
|
||||
};
|
||||
|
||||
static inline struct etna_query *
|
||||
etna_query(struct pipe_query *pq)
|
||||
{
|
||||
return (struct etna_query *)pq;
|
||||
}
|
||||
|
||||
#define ETNA_QUERY_DRAW_CALLS (PIPE_QUERY_DRIVER_SPECIFIC + 0)
|
||||
|
||||
void
|
||||
etna_query_screen_init(struct pipe_screen *pscreen);
|
||||
|
||||
void
|
||||
etna_query_context_init(struct pipe_context *pctx);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,123 @@
|
|||
/*
|
||||
* Copyright (c) 2016 Etnaviv Project
|
||||
*
|
||||
* 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, sub license,
|
||||
* 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 NON-INFRINGEMENT. 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>
|
||||
* Christian Gmeiner <christian.gmeiner@gmail.com>
|
||||
*/
|
||||
|
||||
#include "os/os_time.h"
|
||||
#include "pipe/p_state.h"
|
||||
#include "util/u_inlines.h"
|
||||
#include "util/u_memory.h"
|
||||
#include "util/u_string.h"
|
||||
|
||||
#include "etnaviv_context.h"
|
||||
#include "etnaviv_query_sw.h"
|
||||
|
||||
static void
|
||||
etna_sw_destroy_query(struct etna_context *ctx, struct etna_query *q)
|
||||
{
|
||||
struct etna_sw_query *sq = etna_sw_query(q);
|
||||
|
||||
FREE(sq);
|
||||
}
|
||||
|
||||
static uint64_t
|
||||
read_counter(struct etna_context *ctx, int type)
|
||||
{
|
||||
switch (type) {
|
||||
case PIPE_QUERY_PRIMITIVES_EMITTED:
|
||||
return ctx->stats.prims_emitted;
|
||||
case ETNA_QUERY_DRAW_CALLS:
|
||||
return ctx->stats.draw_calls;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static boolean
|
||||
etna_sw_begin_query(struct etna_context *ctx, struct etna_query *q)
|
||||
{
|
||||
struct etna_sw_query *sq = etna_sw_query(q);
|
||||
|
||||
q->active = true;
|
||||
sq->begin_value = read_counter(ctx, q->type);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void
|
||||
etna_sw_end_query(struct etna_context *ctx, struct etna_query *q)
|
||||
{
|
||||
struct etna_sw_query *sq = etna_sw_query(q);
|
||||
|
||||
q->active = false;
|
||||
sq->end_value = read_counter(ctx, q->type);
|
||||
}
|
||||
|
||||
static boolean
|
||||
etna_sw_get_query_result(struct etna_context *ctx, struct etna_query *q,
|
||||
boolean wait, union pipe_query_result *result)
|
||||
{
|
||||
struct etna_sw_query *sq = etna_sw_query(q);
|
||||
|
||||
if (q->active)
|
||||
return false;
|
||||
|
||||
util_query_clear_result(result, q->type);
|
||||
result->u64 = sq->end_value - sq->begin_value;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static const struct etna_query_funcs sw_query_funcs = {
|
||||
.destroy_query = etna_sw_destroy_query,
|
||||
.begin_query = etna_sw_begin_query,
|
||||
.end_query = etna_sw_end_query,
|
||||
.get_query_result = etna_sw_get_query_result,
|
||||
};
|
||||
|
||||
struct etna_query *
|
||||
etna_sw_create_query(struct etna_context *ctx, unsigned query_type)
|
||||
{
|
||||
struct etna_sw_query *sq;
|
||||
struct etna_query *q;
|
||||
|
||||
switch (query_type) {
|
||||
case PIPE_QUERY_PRIMITIVES_EMITTED:
|
||||
case ETNA_QUERY_DRAW_CALLS:
|
||||
break;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
sq = CALLOC_STRUCT(etna_sw_query);
|
||||
if (!sq)
|
||||
return NULL;
|
||||
|
||||
q = &sq->base;
|
||||
q->funcs = &sw_query_funcs;
|
||||
q->type = query_type;
|
||||
|
||||
return q;
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* Copyright (c) 2016 Etnaviv Project
|
||||
*
|
||||
* 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, sub license,
|
||||
* 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 NON-INFRINGEMENT. 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>
|
||||
* Christian Gmeiner <christian.gmeiner@gmail.com>
|
||||
*/
|
||||
|
||||
#ifndef H_ETNAVIV_QUERY_SW
|
||||
#define H_ETNAVIV_QUERY_SW
|
||||
|
||||
#include "etnaviv_query.h"
|
||||
|
||||
struct etna_sw_query {
|
||||
struct etna_query base;
|
||||
uint64_t begin_value, end_value;
|
||||
};
|
||||
|
||||
static inline struct etna_sw_query *
|
||||
etna_sw_query(struct etna_query *q)
|
||||
{
|
||||
return (struct etna_sw_query *)q;
|
||||
}
|
||||
|
||||
struct etna_query *
|
||||
etna_sw_create_query(struct etna_context *ctx, unsigned query_type);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,81 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2015 Etnaviv Project
|
||||
*
|
||||
* 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, sub license,
|
||||
* 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 NON-INFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "etnaviv_rasterizer.h"
|
||||
#include "etnaviv_context.h"
|
||||
#include "etnaviv_screen.h"
|
||||
|
||||
#include "hw/common.xml.h"
|
||||
|
||||
#include "etnaviv_translate.h"
|
||||
#include "util/u_math.h"
|
||||
#include "util/u_memory.h"
|
||||
|
||||
void *
|
||||
etna_rasterizer_state_create(struct pipe_context *pctx,
|
||||
const struct pipe_rasterizer_state *so)
|
||||
{
|
||||
struct etna_rasterizer_state *cs;
|
||||
struct etna_context *ctx = etna_context(pctx);
|
||||
|
||||
/* Disregard flatshading on GC880+, as a HW bug there seem to disable all
|
||||
* varying interpolation if it's enabled */
|
||||
bool flatshade = ctx->screen->model < 880 ? so->flatshade : false;
|
||||
|
||||
if (so->fill_front != so->fill_back)
|
||||
DBG("Different front and back fill mode not supported");
|
||||
|
||||
cs = CALLOC_STRUCT(etna_rasterizer_state);
|
||||
if (!cs)
|
||||
return NULL;
|
||||
|
||||
cs->base = *so;
|
||||
|
||||
cs->PA_CONFIG = (flatshade ? VIVS_PA_CONFIG_SHADE_MODEL_FLAT : VIVS_PA_CONFIG_SHADE_MODEL_SMOOTH) |
|
||||
translate_cull_face(so->cull_face, so->front_ccw) |
|
||||
translate_polygon_mode(so->fill_front) |
|
||||
COND(so->point_quad_rasterization, VIVS_PA_CONFIG_POINT_SPRITE_ENABLE) |
|
||||
COND(so->point_size_per_vertex, VIVS_PA_CONFIG_POINT_SIZE_ENABLE) |
|
||||
COND(VIV_FEATURE(ctx->screen, chipMinorFeatures1, WIDE_LINE), VIVS_PA_CONFIG_WIDE_LINE);
|
||||
cs->PA_LINE_WIDTH = fui(so->line_width / 2.0f);
|
||||
cs->PA_POINT_SIZE = fui(so->point_size / 2.0f);
|
||||
cs->SE_DEPTH_SCALE = fui(so->offset_scale);
|
||||
cs->SE_DEPTH_BIAS = fui(so->offset_units) / 65535.0f;
|
||||
cs->SE_CONFIG = COND(so->line_last_pixel, VIVS_SE_CONFIG_LAST_PIXEL_ENABLE);
|
||||
/* XXX anything else? */
|
||||
/* XXX bottom_edge_rule */
|
||||
cs->PA_SYSTEM_MODE =
|
||||
COND(so->half_pixel_center, VIVS_PA_SYSTEM_MODE_UNK0 | VIVS_PA_SYSTEM_MODE_UNK4);
|
||||
|
||||
/* so->scissor overrides the scissor, defaulting to the whole framebuffer,
|
||||
* with the scissor state */
|
||||
cs->scissor = so->scissor;
|
||||
|
||||
/* point size per vertex adds a vertex shader output */
|
||||
cs->point_size_per_vertex = so->point_size_per_vertex;
|
||||
|
||||
assert(!so->clip_halfz); /* could be supported with shader magic, actually
|
||||
D3D z is default on older gc */
|
||||
|
||||
return cs;
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2015 Etnaviv Project
|
||||
*
|
||||
* 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, sub license,
|
||||
* 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 NON-INFRINGEMENT. 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:
|
||||
* Wladimir J. van der Laan <laanwj@gmail.com>
|
||||
*/
|
||||
|
||||
#ifndef H_ETNAVIV_RASTERIZER
|
||||
#define H_ETNAVIV_RASTERIZER
|
||||
|
||||
#include "pipe/p_context.h"
|
||||
#include "pipe/p_state.h"
|
||||
|
||||
struct etna_rasterizer_state {
|
||||
struct pipe_rasterizer_state base;
|
||||
|
||||
uint32_t PA_CONFIG;
|
||||
uint32_t PA_LINE_WIDTH;
|
||||
uint32_t PA_POINT_SIZE;
|
||||
uint32_t PA_SYSTEM_MODE;
|
||||
uint32_t SE_DEPTH_SCALE;
|
||||
uint32_t SE_DEPTH_BIAS;
|
||||
uint32_t SE_CONFIG;
|
||||
bool point_size_per_vertex;
|
||||
bool scissor;
|
||||
};
|
||||
|
||||
static inline struct etna_rasterizer_state *
|
||||
etna_rasterizer_state(struct pipe_rasterizer_state *rast)
|
||||
{
|
||||
return (struct etna_rasterizer_state *)rast;
|
||||
}
|
||||
|
||||
void *
|
||||
etna_rasterizer_state_create(struct pipe_context *pctx,
|
||||
const struct pipe_rasterizer_state *so);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,438 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2015 Etnaviv Project
|
||||
*
|
||||
* 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, sub license,
|
||||
* 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 NON-INFRINGEMENT. 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:
|
||||
* Wladimir J. van der Laan <laanwj@gmail.com>
|
||||
*/
|
||||
|
||||
#include "etnaviv_resource.h"
|
||||
|
||||
#include "hw/common.xml.h"
|
||||
|
||||
#include "etnaviv_context.h"
|
||||
#include "etnaviv_debug.h"
|
||||
#include "etnaviv_screen.h"
|
||||
#include "etnaviv_translate.h"
|
||||
|
||||
#include "util/u_inlines.h"
|
||||
#include "util/u_memory.h"
|
||||
|
||||
/* A tile is 4x4 pixels, having 'screen->specs.bits_per_tile' of tile status.
|
||||
* So, in a buffer of N pixels, there are N / (4 * 4) tiles.
|
||||
* We need N * screen->specs.bits_per_tile / (4 * 4) bits of tile status, or
|
||||
* N * screen->specs.bits_per_tile / (4 * 4 * 8) bytes.
|
||||
*/
|
||||
bool
|
||||
etna_screen_resource_alloc_ts(struct pipe_screen *pscreen,
|
||||
struct etna_resource *rsc)
|
||||
{
|
||||
struct etna_screen *screen = etna_screen(pscreen);
|
||||
size_t rt_ts_size, ts_layer_stride, pixels;
|
||||
|
||||
assert(!rsc->ts_bo);
|
||||
|
||||
/* TS only for level 0 -- XXX is this formula correct? */
|
||||
pixels = rsc->levels[0].layer_stride / util_format_get_blocksize(rsc->base.format);
|
||||
ts_layer_stride = align(pixels * screen->specs.bits_per_tile / 0x80, 0x100);
|
||||
rt_ts_size = ts_layer_stride * rsc->base.array_size;
|
||||
if (rt_ts_size == 0)
|
||||
return true;
|
||||
|
||||
DBG_F(ETNA_DBG_RESOURCE_MSGS, "%p: Allocating tile status of size %zu",
|
||||
rsc, rt_ts_size);
|
||||
|
||||
struct etna_bo *rt_ts;
|
||||
rt_ts = etna_bo_new(screen->dev, rt_ts_size, DRM_ETNA_GEM_CACHE_WC);
|
||||
|
||||
if (unlikely(!rt_ts)) {
|
||||
BUG("Problem allocating tile status for resource");
|
||||
return false;
|
||||
}
|
||||
|
||||
rsc->ts_bo = rt_ts;
|
||||
rsc->levels[0].ts_offset = 0;
|
||||
rsc->levels[0].ts_layer_stride = ts_layer_stride;
|
||||
rsc->levels[0].ts_size = rt_ts_size;
|
||||
|
||||
/* It is important to initialize the TS, as random pattern
|
||||
* can result in crashes. Do this on the CPU as this only happens once
|
||||
* per surface anyway and it's a small area, so it may not be worth
|
||||
* queuing this to the GPU. */
|
||||
void *ts_map = etna_bo_map(rt_ts);
|
||||
memset(ts_map, screen->specs.ts_clear_value, rt_ts_size);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static boolean
|
||||
etna_screen_can_create_resource(struct pipe_screen *pscreen,
|
||||
const struct pipe_resource *templat)
|
||||
{
|
||||
struct etna_screen *screen = etna_screen(pscreen);
|
||||
if (!translate_samples_to_xyscale(templat->nr_samples, NULL, NULL, NULL))
|
||||
return false;
|
||||
|
||||
/* templat->bind is not set here, so we must use the minimum sizes */
|
||||
uint max_size =
|
||||
MIN2(screen->specs.max_rendertarget_size, screen->specs.max_texture_size);
|
||||
|
||||
if (templat->width0 > max_size || templat->height0 > max_size)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static unsigned
|
||||
setup_miptree(struct etna_resource *rsc, unsigned paddingX, unsigned paddingY,
|
||||
unsigned msaa_xscale, unsigned msaa_yscale)
|
||||
{
|
||||
struct pipe_resource *prsc = &rsc->base;
|
||||
unsigned level, size = 0;
|
||||
unsigned width = prsc->width0;
|
||||
unsigned height = prsc->height0;
|
||||
unsigned depth = prsc->depth0;
|
||||
|
||||
for (level = 0; level <= prsc->last_level; level++) {
|
||||
struct etna_resource_level *mip = &rsc->levels[level];
|
||||
|
||||
mip->width = width;
|
||||
mip->height = height;
|
||||
mip->padded_width = align(width * msaa_xscale, paddingX);
|
||||
mip->padded_height = align(height * msaa_yscale, paddingY);
|
||||
mip->stride = util_format_get_stride(prsc->format, mip->padded_width);
|
||||
mip->offset = size;
|
||||
mip->layer_stride = mip->stride * util_format_get_nblocksy(prsc->format, mip->padded_height);
|
||||
mip->size = prsc->array_size * mip->layer_stride;
|
||||
|
||||
/* align levels to 64 bytes to be able to render to them */
|
||||
size += align(mip->size, ETNA_PE_ALIGNMENT) * depth;
|
||||
|
||||
width = u_minify(width, 1);
|
||||
height = u_minify(height, 1);
|
||||
depth = u_minify(depth, 1);
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
/* Create a new resource object, using the given template info */
|
||||
struct pipe_resource *
|
||||
etna_resource_alloc(struct pipe_screen *pscreen, unsigned layout,
|
||||
const struct pipe_resource *templat)
|
||||
{
|
||||
struct etna_screen *screen = etna_screen(pscreen);
|
||||
unsigned size;
|
||||
|
||||
DBG_F(ETNA_DBG_RESOURCE_MSGS,
|
||||
"target=%d, format=%s, %ux%ux%u, array_size=%u, "
|
||||
"last_level=%u, nr_samples=%u, usage=%u, bind=%x, flags=%x",
|
||||
templat->target, util_format_name(templat->format), templat->width0,
|
||||
templat->height0, templat->depth0, templat->array_size,
|
||||
templat->last_level, templat->nr_samples, templat->usage,
|
||||
templat->bind, templat->flags);
|
||||
|
||||
/* Determine scaling for antialiasing, allow override using debug flag */
|
||||
int nr_samples = templat->nr_samples;
|
||||
if ((templat->bind & (PIPE_BIND_RENDER_TARGET | PIPE_BIND_DEPTH_STENCIL)) &&
|
||||
!(templat->bind & PIPE_BIND_SAMPLER_VIEW)) {
|
||||
if (DBG_ENABLED(ETNA_DBG_MSAA_2X))
|
||||
nr_samples = 2;
|
||||
if (DBG_ENABLED(ETNA_DBG_MSAA_4X))
|
||||
nr_samples = 4;
|
||||
}
|
||||
|
||||
int msaa_xscale = 1, msaa_yscale = 1;
|
||||
if (!translate_samples_to_xyscale(nr_samples, &msaa_xscale, &msaa_yscale, NULL)) {
|
||||
/* Number of samples not supported */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* If we have the TEXTURE_HALIGN feature, we can always align to the
|
||||
* resolve engine's width. If not, we must not align resources used
|
||||
* only for textures. */
|
||||
bool rs_align = VIV_FEATURE(screen, chipMinorFeatures1, TEXTURE_HALIGN) ||
|
||||
!etna_resource_sampler_only(templat);
|
||||
|
||||
/* Determine needed padding (alignment of height/width) */
|
||||
unsigned paddingX = 0, paddingY = 0;
|
||||
unsigned halign = TEXTURE_HALIGN_FOUR;
|
||||
etna_layout_multiple(layout, screen->specs.pixel_pipes, rs_align, &paddingX,
|
||||
&paddingY, &halign);
|
||||
assert(paddingX && paddingY);
|
||||
|
||||
if (templat->bind != PIPE_BUFFER) {
|
||||
unsigned min_paddingY = 4 * screen->specs.pixel_pipes;
|
||||
if (paddingY < min_paddingY)
|
||||
paddingY = min_paddingY;
|
||||
}
|
||||
|
||||
struct etna_resource *rsc = CALLOC_STRUCT(etna_resource);
|
||||
|
||||
if (!rsc)
|
||||
return NULL;
|
||||
|
||||
rsc->base = *templat;
|
||||
rsc->base.screen = pscreen;
|
||||
rsc->base.nr_samples = nr_samples;
|
||||
rsc->layout = layout;
|
||||
rsc->halign = halign;
|
||||
|
||||
pipe_reference_init(&rsc->base.reference, 1);
|
||||
list_inithead(&rsc->list);
|
||||
|
||||
size = setup_miptree(rsc, paddingX, paddingY, msaa_xscale, msaa_yscale);
|
||||
|
||||
struct etna_bo *bo = etna_bo_new(screen->dev, size, DRM_ETNA_GEM_CACHE_WC);
|
||||
if (unlikely(bo == NULL)) {
|
||||
BUG("Problem allocating video memory for resource");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
rsc->bo = bo;
|
||||
rsc->ts_bo = 0; /* TS is only created when first bound to surface */
|
||||
|
||||
if (templat->bind & PIPE_BIND_SCANOUT)
|
||||
rsc->scanout = renderonly_scanout_for_resource(&rsc->base, screen->ro);
|
||||
|
||||
if (DBG_ENABLED(ETNA_DBG_ZERO)) {
|
||||
void *map = etna_bo_map(bo);
|
||||
memset(map, 0, size);
|
||||
}
|
||||
|
||||
return &rsc->base;
|
||||
}
|
||||
|
||||
static struct pipe_resource *
|
||||
etna_resource_create(struct pipe_screen *pscreen,
|
||||
const struct pipe_resource *templat)
|
||||
{
|
||||
struct etna_screen *screen = etna_screen(pscreen);
|
||||
|
||||
/* Figure out what tiling to use -- for now, assume that textures cannot be
|
||||
* supertiled, and cannot be linear.
|
||||
* There is a feature flag SUPERTILED_TEXTURE (not supported on any known hw)
|
||||
* that may allow this, as well
|
||||
* as LINEAR_TEXTURE_SUPPORT (supported on gc880 and gc2000 at least), but
|
||||
* not sure how it works.
|
||||
* Buffers always have LINEAR layout.
|
||||
*/
|
||||
unsigned layout = ETNA_LAYOUT_LINEAR;
|
||||
if (etna_resource_sampler_only(templat)) {
|
||||
/* The buffer is only used for texturing, so create something
|
||||
* directly compatible with the sampler. Such a buffer can
|
||||
* never be rendered to. */
|
||||
layout = ETNA_LAYOUT_TILED;
|
||||
|
||||
if (util_format_is_compressed(templat->format))
|
||||
layout = ETNA_LAYOUT_LINEAR;
|
||||
} else if (templat->target != PIPE_BUFFER) {
|
||||
bool want_multitiled = screen->specs.pixel_pipes > 1;
|
||||
bool want_supertiled = screen->specs.can_supertile && !DBG_ENABLED(ETNA_DBG_NO_SUPERTILE);
|
||||
|
||||
/* Keep single byte blocksized resources as tiled, since we
|
||||
* are unable to use the RS blit to de-tile them. However,
|
||||
* if they're used as a render target or depth/stencil, they
|
||||
* must be multi-tiled for GPUs with multiple pixel pipes.
|
||||
* Ignore depth/stencil here, but it is an error for a render
|
||||
* target.
|
||||
*/
|
||||
if (util_format_get_blocksize(templat->format) == 1 &&
|
||||
!(templat->bind & PIPE_BIND_DEPTH_STENCIL)) {
|
||||
assert(!(templat->bind & PIPE_BIND_RENDER_TARGET && want_multitiled));
|
||||
want_multitiled = want_supertiled = false;
|
||||
}
|
||||
|
||||
layout = ETNA_LAYOUT_BIT_TILE;
|
||||
if (want_multitiled)
|
||||
layout |= ETNA_LAYOUT_BIT_MULTI;
|
||||
if (want_supertiled)
|
||||
layout |= ETNA_LAYOUT_BIT_SUPER;
|
||||
}
|
||||
|
||||
if (templat->target == PIPE_TEXTURE_3D)
|
||||
layout = ETNA_LAYOUT_LINEAR;
|
||||
|
||||
return etna_resource_alloc(pscreen, layout, templat);
|
||||
}
|
||||
|
||||
static void
|
||||
etna_resource_destroy(struct pipe_screen *pscreen, struct pipe_resource *prsc)
|
||||
{
|
||||
struct etna_resource *rsc = etna_resource(prsc);
|
||||
|
||||
if (rsc->bo)
|
||||
etna_bo_del(rsc->bo);
|
||||
|
||||
if (rsc->ts_bo)
|
||||
etna_bo_del(rsc->ts_bo);
|
||||
|
||||
if (rsc->scanout)
|
||||
renderonly_scanout_destroy(rsc->scanout);
|
||||
|
||||
list_delinit(&rsc->list);
|
||||
|
||||
pipe_resource_reference(&rsc->texture, NULL);
|
||||
|
||||
FREE(rsc);
|
||||
}
|
||||
|
||||
static struct pipe_resource *
|
||||
etna_resource_from_handle(struct pipe_screen *pscreen,
|
||||
const struct pipe_resource *tmpl,
|
||||
struct winsys_handle *handle, unsigned usage)
|
||||
{
|
||||
struct etna_screen *screen = etna_screen(pscreen);
|
||||
struct etna_resource *rsc = CALLOC_STRUCT(etna_resource);
|
||||
struct etna_resource_level *level = &rsc->levels[0];
|
||||
struct pipe_resource *prsc = &rsc->base;
|
||||
struct pipe_resource *ptiled = NULL;
|
||||
|
||||
DBG("target=%d, format=%s, %ux%ux%u, array_size=%u, last_level=%u, "
|
||||
"nr_samples=%u, usage=%u, bind=%x, flags=%x",
|
||||
tmpl->target, util_format_name(tmpl->format), tmpl->width0,
|
||||
tmpl->height0, tmpl->depth0, tmpl->array_size, tmpl->last_level,
|
||||
tmpl->nr_samples, tmpl->usage, tmpl->bind, tmpl->flags);
|
||||
|
||||
if (!rsc)
|
||||
return NULL;
|
||||
|
||||
*prsc = *tmpl;
|
||||
|
||||
pipe_reference_init(&prsc->reference, 1);
|
||||
list_inithead(&rsc->list);
|
||||
prsc->screen = pscreen;
|
||||
|
||||
rsc->bo = etna_screen_bo_from_handle(pscreen, handle, &level->stride);
|
||||
if (!rsc->bo)
|
||||
goto fail;
|
||||
|
||||
level->width = tmpl->width0;
|
||||
level->height = tmpl->height0;
|
||||
|
||||
/* We will be using the RS to copy with this resource, so we must
|
||||
* ensure that it is appropriately aligned for the RS requirements. */
|
||||
unsigned paddingX = ETNA_RS_WIDTH_MASK + 1;
|
||||
unsigned paddingY = (ETNA_RS_HEIGHT_MASK + 1) * screen->specs.pixel_pipes;
|
||||
|
||||
level->padded_width = align(level->width, paddingX);
|
||||
level->padded_height = align(level->height, paddingY);
|
||||
|
||||
/* The DDX must give us a BO which conforms to our padding size.
|
||||
* The stride of the BO must be greater or equal to our padded
|
||||
* stride. The size of the BO must accomodate the padded height. */
|
||||
if (level->stride < util_format_get_stride(tmpl->format, level->padded_width)) {
|
||||
BUG("BO stride is too small for RS engine width padding");
|
||||
goto fail;
|
||||
}
|
||||
if (etna_bo_size(rsc->bo) < level->stride * level->padded_height) {
|
||||
BUG("BO size is too small for RS engine height padding");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (handle->type == DRM_API_HANDLE_TYPE_SHARED && tmpl->bind & PIPE_BIND_RENDER_TARGET) {
|
||||
/* Render targets are linear in Xorg but must be tiled
|
||||
* here. It would be nice if dri_drawable_get_format()
|
||||
* set scanout for these buffers too. */
|
||||
struct etna_resource *tiled;
|
||||
|
||||
ptiled = etna_resource_create(pscreen, tmpl);
|
||||
if (!ptiled)
|
||||
goto fail;
|
||||
|
||||
tiled = etna_resource(ptiled);
|
||||
tiled->scanout = renderonly_scanout_for_prime(prsc, screen->ro);
|
||||
if (!tiled->scanout)
|
||||
goto fail;
|
||||
|
||||
return ptiled;
|
||||
}
|
||||
|
||||
return prsc;
|
||||
|
||||
fail:
|
||||
etna_resource_destroy(pscreen, prsc);
|
||||
if (ptiled)
|
||||
etna_resource_destroy(pscreen, ptiled);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static boolean
|
||||
etna_resource_get_handle(struct pipe_screen *pscreen,
|
||||
struct pipe_context *pctx,
|
||||
struct pipe_resource *prsc,
|
||||
struct winsys_handle *handle, unsigned usage)
|
||||
{
|
||||
struct etna_resource *rsc = etna_resource(prsc);
|
||||
|
||||
if (renderonly_get_handle(rsc->scanout, handle))
|
||||
return TRUE;
|
||||
|
||||
return etna_screen_bo_get_handle(pscreen, rsc->bo, rsc->levels[0].stride,
|
||||
handle);
|
||||
}
|
||||
|
||||
void
|
||||
etna_resource_used(struct etna_context *ctx, struct pipe_resource *prsc,
|
||||
enum etna_resource_status status)
|
||||
{
|
||||
struct etna_resource *rsc;
|
||||
|
||||
if (!prsc)
|
||||
return;
|
||||
|
||||
rsc = etna_resource(prsc);
|
||||
rsc->status |= status;
|
||||
|
||||
/* TODO resources can actually be shared across contexts,
|
||||
* so I'm not sure a single list-head will do the trick? */
|
||||
debug_assert((rsc->pending_ctx == ctx) || !rsc->pending_ctx);
|
||||
list_delinit(&rsc->list);
|
||||
list_addtail(&rsc->list, &ctx->used_resources);
|
||||
rsc->pending_ctx = ctx;
|
||||
}
|
||||
|
||||
void
|
||||
etna_resource_wait(struct pipe_context *pctx, struct etna_resource *rsc)
|
||||
{
|
||||
if (rsc->status & ETNA_PENDING_WRITE) {
|
||||
struct pipe_fence_handle *fence;
|
||||
struct pipe_screen *pscreen = pctx->screen;
|
||||
|
||||
pctx->flush(pctx, &fence, 0);
|
||||
|
||||
if (!pscreen->fence_finish(pscreen, pctx, fence, 5000000000ULL))
|
||||
BUG("fence timed out (hung GPU?)");
|
||||
|
||||
pscreen->fence_reference(pscreen, &fence, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
etna_resource_screen_init(struct pipe_screen *pscreen)
|
||||
{
|
||||
pscreen->can_create_resource = etna_screen_can_create_resource;
|
||||
pscreen->resource_create = etna_resource_create;
|
||||
pscreen->resource_from_handle = etna_resource_from_handle;
|
||||
pscreen->resource_get_handle = etna_resource_get_handle;
|
||||
pscreen->resource_destroy = etna_resource_destroy;
|
||||
}
|
|
@ -0,0 +1,148 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2015 Etnaviv Project
|
||||
*
|
||||
* 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, sub license,
|
||||
* 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 NON-INFRINGEMENT. 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:
|
||||
* Wladimir J. van der Laan <laanwj@gmail.com>
|
||||
*/
|
||||
|
||||
#ifndef H_ETNAVIV_RESOURCE
|
||||
#define H_ETNAVIV_RESOURCE
|
||||
|
||||
#include "etnaviv_internal.h"
|
||||
#include "etnaviv_tiling.h"
|
||||
#include "pipe/p_state.h"
|
||||
#include "util/list.h"
|
||||
|
||||
struct pipe_screen;
|
||||
|
||||
struct etna_resource_level {
|
||||
unsigned width, padded_width; /* in pixels */
|
||||
unsigned height, padded_height; /* in samples */
|
||||
unsigned offset; /* offset into memory area */
|
||||
uint32_t stride; /* row stride */
|
||||
uint32_t layer_stride; /* layer stride */
|
||||
unsigned size; /* total size of memory area */
|
||||
|
||||
uint32_t ts_offset;
|
||||
uint32_t ts_layer_stride;
|
||||
uint32_t ts_size;
|
||||
uint32_t clear_value; /* clear value of resource level (mainly for TS) */
|
||||
};
|
||||
|
||||
/* status of queued up but not flushed reads and write operations.
|
||||
* In _transfer_map() we need to know if queued up rendering needs
|
||||
* to be flushed to preserve the order of cpu and gpu access. */
|
||||
enum etna_resource_status {
|
||||
ETNA_PENDING_WRITE = 0x01,
|
||||
ETNA_PENDING_READ = 0x02,
|
||||
};
|
||||
|
||||
struct etna_resource {
|
||||
struct pipe_resource base;
|
||||
struct renderonly_scanout *scanout;
|
||||
uint32_t seqno;
|
||||
|
||||
/* only lod 0 used for non-texture buffers */
|
||||
/* Layout for surface (tiled, multitiled, split tiled, ...) */
|
||||
enum etna_surface_layout layout;
|
||||
/* Horizontal alignment for texture unit (TEXTURE_HALIGN_*) */
|
||||
unsigned halign;
|
||||
struct etna_bo *bo; /* Surface video memory */
|
||||
struct etna_bo *ts_bo; /* Tile status video memory */
|
||||
|
||||
struct etna_resource_level levels[ETNA_NUM_LOD];
|
||||
|
||||
/* When we are rendering to a texture, we need a differently tiled resource */
|
||||
struct pipe_resource *texture;
|
||||
|
||||
enum etna_resource_status status;
|
||||
|
||||
/* resources accessed by queued but not flushed draws are tracked
|
||||
* in the used_resources list. */
|
||||
struct list_head list;
|
||||
struct etna_context *pending_ctx;
|
||||
};
|
||||
|
||||
/* returns TRUE if a is newer than b */
|
||||
static inline bool
|
||||
etna_resource_newer(struct etna_resource *a, struct etna_resource *b)
|
||||
{
|
||||
return (int)(a->seqno - b->seqno) > 0;
|
||||
}
|
||||
|
||||
/* returns TRUE if a is older than b */
|
||||
static inline bool
|
||||
etna_resource_older(struct etna_resource *a, struct etna_resource *b)
|
||||
{
|
||||
return (int)(a->seqno - b->seqno) < 0;
|
||||
}
|
||||
|
||||
/* is the resource only used on the sampler? */
|
||||
static inline bool
|
||||
etna_resource_sampler_only(const struct pipe_resource *pres)
|
||||
{
|
||||
return (pres->bind & (PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET |
|
||||
PIPE_BIND_DEPTH_STENCIL | PIPE_BIND_BLENDABLE)) ==
|
||||
PIPE_BIND_SAMPLER_VIEW;
|
||||
}
|
||||
|
||||
static inline struct etna_resource *
|
||||
etna_resource(struct pipe_resource *p)
|
||||
{
|
||||
return (struct etna_resource *)p;
|
||||
}
|
||||
|
||||
void
|
||||
etna_resource_used(struct etna_context *ctx, struct pipe_resource *prsc,
|
||||
enum etna_resource_status status);
|
||||
|
||||
void
|
||||
etna_resource_wait(struct pipe_context *ctx, struct etna_resource *rsc);
|
||||
|
||||
static inline void
|
||||
resource_read(struct etna_context *ctx, struct pipe_resource *prsc)
|
||||
{
|
||||
etna_resource_used(ctx, prsc, ETNA_PENDING_READ);
|
||||
}
|
||||
|
||||
static inline void
|
||||
resource_written(struct etna_context *ctx, struct pipe_resource *prsc)
|
||||
{
|
||||
etna_resource_used(ctx, prsc, ETNA_PENDING_WRITE);
|
||||
}
|
||||
|
||||
/* Allocate Tile Status for an etna resource.
|
||||
* Tile status is a cache of the clear status per tile. This means a smaller
|
||||
* surface has to be cleared which is faster.
|
||||
* This is also called "fast clear". */
|
||||
bool
|
||||
etna_screen_resource_alloc_ts(struct pipe_screen *pscreen,
|
||||
struct etna_resource *prsc);
|
||||
|
||||
struct pipe_resource *
|
||||
etna_resource_alloc(struct pipe_screen *pscreen, unsigned layout,
|
||||
const struct pipe_resource *templat);
|
||||
|
||||
void
|
||||
etna_resource_screen_init(struct pipe_screen *pscreen);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,127 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2015 Etnaviv Project
|
||||
*
|
||||
* 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, sub license,
|
||||
* 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 NON-INFRINGEMENT. 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:
|
||||
* Wladimir J. van der Laan <laanwj@gmail.com>
|
||||
*/
|
||||
|
||||
#include "etnaviv_rs.h"
|
||||
#include "etnaviv_screen.h"
|
||||
#include "etnaviv_tiling.h"
|
||||
#include "etnaviv_util.h"
|
||||
|
||||
#include "hw/common.xml.h"
|
||||
#include "hw/state.xml.h"
|
||||
#include "hw/state_3d.xml.h"
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
void
|
||||
etna_compile_rs_state(struct etna_context *ctx, struct compiled_rs_state *cs,
|
||||
const struct rs_state *rs)
|
||||
{
|
||||
memset(cs, 0, sizeof(*cs));
|
||||
|
||||
/* TILED and SUPERTILED layout have their strides multiplied with 4 in RS */
|
||||
unsigned source_stride_shift = COND(rs->source_tiling != ETNA_LAYOUT_LINEAR, 2);
|
||||
unsigned dest_stride_shift = COND(rs->dest_tiling != ETNA_LAYOUT_LINEAR, 2);
|
||||
|
||||
/* tiling == ETNA_LAYOUT_MULTI_TILED or ETNA_LAYOUT_MULTI_SUPERTILED? */
|
||||
int source_multi = COND(rs->source_tiling & ETNA_LAYOUT_BIT_MULTI, 1);
|
||||
int dest_multi = COND(rs->dest_tiling & ETNA_LAYOUT_BIT_MULTI, 1);
|
||||
|
||||
/* Vivante RS needs widths to be a multiple of 16 or bad things
|
||||
* happen, such as scribbing over memory, or the GPU hanging,
|
||||
* even for non-tiled formats. As this is serious, use abort().
|
||||
*/
|
||||
if (rs->width & ETNA_RS_WIDTH_MASK)
|
||||
abort();
|
||||
|
||||
/* TODO could just pre-generate command buffer, would simply submit to one memcpy */
|
||||
cs->RS_CONFIG = VIVS_RS_CONFIG_SOURCE_FORMAT(rs->source_format) |
|
||||
COND(rs->downsample_x, VIVS_RS_CONFIG_DOWNSAMPLE_X) |
|
||||
COND(rs->downsample_y, VIVS_RS_CONFIG_DOWNSAMPLE_Y) |
|
||||
COND(rs->source_tiling & 1, VIVS_RS_CONFIG_SOURCE_TILED) |
|
||||
VIVS_RS_CONFIG_DEST_FORMAT(rs->dest_format) |
|
||||
COND(rs->dest_tiling & 1, VIVS_RS_CONFIG_DEST_TILED) |
|
||||
COND(rs->swap_rb, VIVS_RS_CONFIG_SWAP_RB) |
|
||||
COND(rs->flip, VIVS_RS_CONFIG_FLIP);
|
||||
|
||||
cs->RS_SOURCE_STRIDE = (rs->source_stride << source_stride_shift) |
|
||||
COND(rs->source_tiling & 2, VIVS_RS_SOURCE_STRIDE_TILING) |
|
||||
COND(source_multi, VIVS_RS_SOURCE_STRIDE_MULTI);
|
||||
|
||||
cs->source[0].bo = rs->source;
|
||||
cs->source[0].offset = rs->source_offset;
|
||||
cs->source[0].flags = ETNA_RELOC_READ;
|
||||
|
||||
cs->dest[0].bo = rs->dest;
|
||||
cs->dest[0].offset = rs->dest_offset;
|
||||
cs->dest[0].flags = ETNA_RELOC_WRITE;
|
||||
|
||||
cs->RS_DEST_STRIDE = (rs->dest_stride << dest_stride_shift) |
|
||||
COND(rs->dest_tiling & 2, VIVS_RS_DEST_STRIDE_TILING) |
|
||||
COND(dest_multi, VIVS_RS_DEST_STRIDE_MULTI);
|
||||
|
||||
if (ctx->specs.pixel_pipes == 1) {
|
||||
cs->RS_WINDOW_SIZE = VIVS_RS_WINDOW_SIZE_WIDTH(rs->width) |
|
||||
VIVS_RS_WINDOW_SIZE_HEIGHT(rs->height);
|
||||
} else if (ctx->specs.pixel_pipes == 2) {
|
||||
assert((rs->height & 7) == 0); /* GPU hangs happen if height not 8-aligned */
|
||||
|
||||
if (source_multi) {
|
||||
cs->source[1].bo = rs->source;
|
||||
cs->source[1].offset = rs->source_offset + rs->source_stride * rs->source_padded_height / 2;
|
||||
cs->source[1].flags = ETNA_RELOC_READ;
|
||||
}
|
||||
|
||||
if (dest_multi) {
|
||||
cs->dest[1].bo = rs->dest;
|
||||
cs->dest[1].offset = rs->dest_offset + rs->dest_stride * rs->dest_padded_height / 2;
|
||||
cs->dest[1].flags = ETNA_RELOC_WRITE;
|
||||
}
|
||||
|
||||
cs->RS_WINDOW_SIZE = VIVS_RS_WINDOW_SIZE_WIDTH(rs->width) |
|
||||
VIVS_RS_WINDOW_SIZE_HEIGHT(rs->height / 2);
|
||||
} else {
|
||||
abort();
|
||||
}
|
||||
|
||||
cs->RS_PIPE_OFFSET[0] = VIVS_RS_PIPE_OFFSET_X(0) | VIVS_RS_PIPE_OFFSET_Y(0);
|
||||
cs->RS_PIPE_OFFSET[1] = VIVS_RS_PIPE_OFFSET_X(0) | VIVS_RS_PIPE_OFFSET_Y(rs->height / 2);
|
||||
cs->RS_DITHER[0] = rs->dither[0];
|
||||
cs->RS_DITHER[1] = rs->dither[1];
|
||||
cs->RS_CLEAR_CONTROL = VIVS_RS_CLEAR_CONTROL_BITS(rs->clear_bits) | rs->clear_mode;
|
||||
cs->RS_FILL_VALUE[0] = rs->clear_value[0];
|
||||
cs->RS_FILL_VALUE[1] = rs->clear_value[1];
|
||||
cs->RS_FILL_VALUE[2] = rs->clear_value[2];
|
||||
cs->RS_FILL_VALUE[3] = rs->clear_value[3];
|
||||
cs->RS_EXTRA_CONFIG = VIVS_RS_EXTRA_CONFIG_AA(rs->aa) |
|
||||
VIVS_RS_EXTRA_CONFIG_ENDIAN(rs->endian_mode);
|
||||
}
|
||||
|
||||
void
|
||||
etna_modify_rs_clearbits(struct compiled_rs_state *cs, uint32_t clear_bits)
|
||||
{
|
||||
cs->RS_CLEAR_CONTROL &= ~VIVS_RS_CLEAR_CONTROL_BITS__MASK;
|
||||
cs->RS_CLEAR_CONTROL |= VIVS_RS_CLEAR_CONTROL_BITS(clear_bits);
|
||||
}
|
|
@ -0,0 +1,86 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2013 Etnaviv Project
|
||||
*
|
||||
* 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, sub license,
|
||||
* 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 NON-INFRINGEMENT. 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:
|
||||
* Wladimir J. van der Laan <laanwj@gmail.com>
|
||||
*/
|
||||
|
||||
#ifndef H_ETNAVIV_RS
|
||||
#define H_ETNAVIV_RS
|
||||
|
||||
#include "etnaviv_context.h"
|
||||
#include <stdint.h>
|
||||
|
||||
struct rs_state {
|
||||
uint8_t downsample_x : 1; /* Downsample in x direction */
|
||||
uint8_t downsample_y : 1; /* Downsample in y direction */
|
||||
|
||||
uint8_t source_format; /* RS_FORMAT_XXX */
|
||||
uint8_t source_tiling; /* ETNA_LAYOUT_XXX */
|
||||
uint8_t dest_tiling; /* ETNA_LAYOUT_XXX */
|
||||
uint8_t dest_format; /* RS_FORMAT_XXX */
|
||||
uint8_t swap_rb;
|
||||
uint8_t flip;
|
||||
struct etna_bo *source;
|
||||
uint32_t source_offset;
|
||||
uint32_t source_stride;
|
||||
uint32_t source_padded_height; /* total padded height */
|
||||
struct etna_bo *dest;
|
||||
uint32_t dest_offset;
|
||||
uint32_t dest_stride;
|
||||
uint32_t dest_padded_height; /* total padded height */
|
||||
uint16_t width; /* source width */
|
||||
uint16_t height; /* source height */
|
||||
uint32_t dither[2];
|
||||
uint32_t clear_bits;
|
||||
uint32_t clear_mode; /* VIVS_RS_CLEAR_CONTROL_MODE_XXX */
|
||||
uint32_t clear_value[4];
|
||||
uint8_t aa;
|
||||
uint8_t endian_mode; /* ENDIAN_MODE_XXX */
|
||||
};
|
||||
|
||||
/* treat this as opaque structure */
|
||||
struct compiled_rs_state {
|
||||
uint32_t RS_CONFIG;
|
||||
uint32_t RS_SOURCE_STRIDE;
|
||||
uint32_t RS_DEST_STRIDE;
|
||||
uint32_t RS_WINDOW_SIZE;
|
||||
uint32_t RS_DITHER[2];
|
||||
uint32_t RS_CLEAR_CONTROL;
|
||||
uint32_t RS_FILL_VALUE[4];
|
||||
uint32_t RS_EXTRA_CONFIG;
|
||||
uint32_t RS_PIPE_OFFSET[2];
|
||||
|
||||
struct etna_reloc source[2];
|
||||
struct etna_reloc dest[2];
|
||||
};
|
||||
|
||||
/* compile RS state struct */
|
||||
void
|
||||
etna_compile_rs_state(struct etna_context *ctx, struct compiled_rs_state *cs,
|
||||
const struct rs_state *rs);
|
||||
|
||||
/* modify the clear bits value in the compiled RS state */
|
||||
void
|
||||
etna_modify_rs_clearbits(struct compiled_rs_state *cs, uint32_t clear_bits);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,813 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2015 Etnaviv Project
|
||||
*
|
||||
* 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, sub license,
|
||||
* 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 NON-INFRINGEMENT. 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:
|
||||
* Wladimir J. van der Laan <laanwj@gmail.com>
|
||||
* Christian Gmeiner <christian.gmeiner@gmail.com>
|
||||
*/
|
||||
|
||||
#include "etnaviv_screen.h"
|
||||
|
||||
#include "hw/common.xml.h"
|
||||
|
||||
#include "etnaviv_compiler.h"
|
||||
#include "etnaviv_context.h"
|
||||
#include "etnaviv_debug.h"
|
||||
#include "etnaviv_fence.h"
|
||||
#include "etnaviv_format.h"
|
||||
#include "etnaviv_query.h"
|
||||
#include "etnaviv_resource.h"
|
||||
#include "etnaviv_translate.h"
|
||||
|
||||
#include "os/os_time.h"
|
||||
#include "util/u_math.h"
|
||||
#include "util/u_memory.h"
|
||||
#include "util/u_string.h"
|
||||
|
||||
#include "state_tracker/drm_driver.h"
|
||||
|
||||
static const struct debug_named_value debug_options[] = {
|
||||
{"dbg_msgs", ETNA_DBG_MSGS, "Print debug messages"},
|
||||
{"frame_msgs", ETNA_DBG_FRAME_MSGS, "Print frame messages"},
|
||||
{"resource_msgs", ETNA_DBG_RESOURCE_MSGS, "Print resource messages"},
|
||||
{"compiler_msgs", ETNA_DBG_COMPILER_MSGS, "Print compiler messages"},
|
||||
{"linker_msgs", ETNA_DBG_LINKER_MSGS, "Print linker messages"},
|
||||
{"dump_shaders", ETNA_DBG_DUMP_SHADERS, "Dump shaders"},
|
||||
{"no_ts", ETNA_DBG_NO_TS, "Disable TS"},
|
||||
{"no_autodisable", ETNA_DBG_NO_AUTODISABLE, "Disable autodisable"},
|
||||
{"no_supertile", ETNA_DBG_NO_SUPERTILE, "Disable supertiles"},
|
||||
{"no_early_z", ETNA_DBG_NO_EARLY_Z, "Disable early z"},
|
||||
{"cflush_all", ETNA_DBG_CFLUSH_ALL, "Flush every cash before state update"},
|
||||
{"msaa2x", ETNA_DBG_MSAA_2X, "Force 2x msaa"},
|
||||
{"msaa4x", ETNA_DBG_MSAA_4X, "Force 4x msaa"},
|
||||
{"flush_all", ETNA_DBG_FLUSH_ALL, "Flush after every rendered primitive"},
|
||||
{"zero", ETNA_DBG_ZERO, "Zero all resources after allocation"},
|
||||
{"draw_stall", ETNA_DBG_DRAW_STALL, "Stall FE/PE after each rendered primitive"},
|
||||
DEBUG_NAMED_VALUE_END
|
||||
};
|
||||
|
||||
DEBUG_GET_ONCE_FLAGS_OPTION(etna_mesa_debug, "ETNA_MESA_DEBUG", debug_options, 0)
|
||||
int etna_mesa_debug = 0;
|
||||
|
||||
static void
|
||||
etna_screen_destroy(struct pipe_screen *pscreen)
|
||||
{
|
||||
struct etna_screen *screen = etna_screen(pscreen);
|
||||
|
||||
if (screen->pipe)
|
||||
etna_pipe_del(screen->pipe);
|
||||
|
||||
if (screen->gpu)
|
||||
etna_gpu_del(screen->gpu);
|
||||
|
||||
if (screen->ro)
|
||||
FREE(screen->ro);
|
||||
|
||||
if (screen->dev)
|
||||
etna_device_del(screen->dev);
|
||||
|
||||
FREE(screen);
|
||||
}
|
||||
|
||||
static const char *
|
||||
etna_screen_get_name(struct pipe_screen *pscreen)
|
||||
{
|
||||
struct etna_screen *priv = etna_screen(pscreen);
|
||||
static char buffer[128];
|
||||
|
||||
util_snprintf(buffer, sizeof(buffer), "Vivante GC%x rev %04x", priv->model,
|
||||
priv->revision);
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
static const char *
|
||||
etna_screen_get_vendor(struct pipe_screen *pscreen)
|
||||
{
|
||||
return "etnaviv";
|
||||
}
|
||||
|
||||
static const char *
|
||||
etna_screen_get_device_vendor(struct pipe_screen *pscreen)
|
||||
{
|
||||
return "Vivante";
|
||||
}
|
||||
|
||||
static int
|
||||
etna_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
|
||||
{
|
||||
struct etna_screen *screen = etna_screen(pscreen);
|
||||
|
||||
switch (param) {
|
||||
/* Supported features (boolean caps). */
|
||||
case PIPE_CAP_TWO_SIDED_STENCIL:
|
||||
case PIPE_CAP_ANISOTROPIC_FILTER:
|
||||
case PIPE_CAP_POINT_SPRITE:
|
||||
case PIPE_CAP_TEXTURE_SHADOW_MAP:
|
||||
case PIPE_CAP_BLEND_EQUATION_SEPARATE:
|
||||
case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT:
|
||||
case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER:
|
||||
case PIPE_CAP_SM3:
|
||||
case PIPE_CAP_TEXTURE_BARRIER:
|
||||
case PIPE_CAP_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION:
|
||||
case PIPE_CAP_VERTEX_BUFFER_OFFSET_4BYTE_ALIGNED_ONLY:
|
||||
case PIPE_CAP_VERTEX_BUFFER_STRIDE_4BYTE_ALIGNED_ONLY:
|
||||
case PIPE_CAP_VERTEX_ELEMENT_SRC_OFFSET_4BYTE_ALIGNED_ONLY:
|
||||
case PIPE_CAP_USER_CONSTANT_BUFFERS:
|
||||
case PIPE_CAP_TGSI_TEXCOORD:
|
||||
case PIPE_CAP_VERTEX_COLOR_UNCLAMPED:
|
||||
return 1;
|
||||
|
||||
/* Memory */
|
||||
case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT:
|
||||
return 256;
|
||||
case PIPE_CAP_MIN_MAP_BUFFER_ALIGNMENT:
|
||||
return 4; /* XXX could easily be supported */
|
||||
case PIPE_CAP_GLSL_FEATURE_LEVEL:
|
||||
return 120;
|
||||
|
||||
case PIPE_CAP_NPOT_TEXTURES:
|
||||
return true; /* VIV_FEATURE(priv->dev, chipMinorFeatures1,
|
||||
NON_POWER_OF_TWO); */
|
||||
|
||||
case PIPE_CAP_PRIMITIVE_RESTART:
|
||||
return VIV_FEATURE(screen, chipMinorFeatures1, HALTI0);
|
||||
|
||||
case PIPE_CAP_ENDIANNESS:
|
||||
return PIPE_ENDIAN_LITTLE; /* on most Viv hw this is configurable (feature
|
||||
ENDIANNESS_CONFIG) */
|
||||
|
||||
/* Unsupported features. */
|
||||
case PIPE_CAP_SEAMLESS_CUBE_MAP:
|
||||
case PIPE_CAP_TEXTURE_SWIZZLE: /* XXX supported on gc2000 */
|
||||
case PIPE_CAP_COMPUTE: /* XXX supported on gc2000 */
|
||||
case PIPE_CAP_MIXED_COLORBUFFER_FORMATS: /* only one colorbuffer supported, so mixing makes no sense */
|
||||
case PIPE_CAP_CONDITIONAL_RENDER: /* no occlusion queries */
|
||||
case PIPE_CAP_TGSI_INSTANCEID: /* no idea, really */
|
||||
case PIPE_CAP_START_INSTANCE: /* instancing not supported AFAIK */
|
||||
case PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR: /* instancing not supported AFAIK */
|
||||
case PIPE_CAP_SHADER_STENCIL_EXPORT: /* Fragment shader cannot export stencil value */
|
||||
case PIPE_CAP_MAX_DUAL_SOURCE_RENDER_TARGETS: /* no dual-source supported */
|
||||
case PIPE_CAP_TEXTURE_MULTISAMPLE: /* no texture multisample */
|
||||
case PIPE_CAP_TEXTURE_MIRROR_CLAMP: /* only mirrored repeat */
|
||||
case PIPE_CAP_INDEP_BLEND_ENABLE:
|
||||
case PIPE_CAP_INDEP_BLEND_FUNC:
|
||||
case PIPE_CAP_DEPTH_CLIP_DISABLE:
|
||||
case PIPE_CAP_SEAMLESS_CUBE_MAP_PER_TEXTURE:
|
||||
case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT:
|
||||
case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER:
|
||||
case PIPE_CAP_TGSI_CAN_COMPACT_CONSTANTS: /* Don't skip strict max uniform limit check */
|
||||
case PIPE_CAP_FRAGMENT_COLOR_CLAMPED:
|
||||
case PIPE_CAP_VERTEX_COLOR_CLAMPED:
|
||||
case PIPE_CAP_USER_VERTEX_BUFFERS:
|
||||
case PIPE_CAP_USER_INDEX_BUFFERS:
|
||||
case PIPE_CAP_TEXTURE_BUFFER_OBJECTS:
|
||||
case PIPE_CAP_TEXTURE_BUFFER_OFFSET_ALIGNMENT:
|
||||
case PIPE_CAP_BUFFER_SAMPLER_VIEW_RGBA_ONLY:
|
||||
case PIPE_CAP_MIXED_FRAMEBUFFER_SIZES: /* TODO: test me out with piglit */
|
||||
case PIPE_CAP_TGSI_VS_LAYER_VIEWPORT:
|
||||
case PIPE_CAP_MAX_TEXTURE_GATHER_COMPONENTS:
|
||||
case PIPE_CAP_TEXTURE_GATHER_SM5:
|
||||
case PIPE_CAP_BUFFER_MAP_PERSISTENT_COHERENT:
|
||||
case PIPE_CAP_FAKE_SW_MSAA:
|
||||
case PIPE_CAP_TEXTURE_QUERY_LOD:
|
||||
case PIPE_CAP_SAMPLE_SHADING:
|
||||
case PIPE_CAP_TEXTURE_GATHER_OFFSETS:
|
||||
case PIPE_CAP_TGSI_VS_WINDOW_SPACE_POSITION:
|
||||
case PIPE_CAP_DRAW_INDIRECT:
|
||||
case PIPE_CAP_TGSI_FS_FINE_DERIVATIVE:
|
||||
case PIPE_CAP_CONDITIONAL_RENDER_INVERTED:
|
||||
case PIPE_CAP_SAMPLER_VIEW_TARGET:
|
||||
case PIPE_CAP_CLIP_HALFZ:
|
||||
case PIPE_CAP_VERTEXID_NOBASE:
|
||||
case PIPE_CAP_POLYGON_OFFSET_CLAMP:
|
||||
case PIPE_CAP_MULTISAMPLE_Z_RESOLVE:
|
||||
case PIPE_CAP_RESOURCE_FROM_USER_MEMORY:
|
||||
case PIPE_CAP_DEVICE_RESET_STATUS_QUERY:
|
||||
case PIPE_CAP_MAX_SHADER_PATCH_VARYINGS:
|
||||
case PIPE_CAP_TEXTURE_FLOAT_LINEAR:
|
||||
case PIPE_CAP_TEXTURE_HALF_FLOAT_LINEAR:
|
||||
case PIPE_CAP_DEPTH_BOUNDS_TEST:
|
||||
case PIPE_CAP_TGSI_TXQS:
|
||||
case PIPE_CAP_FORCE_PERSAMPLE_INTERP:
|
||||
case PIPE_CAP_SHAREABLE_SHADERS:
|
||||
case PIPE_CAP_COPY_BETWEEN_COMPRESSED_AND_PLAIN_FORMATS:
|
||||
case PIPE_CAP_CLEAR_TEXTURE:
|
||||
case PIPE_CAP_DRAW_PARAMETERS:
|
||||
case PIPE_CAP_TGSI_PACK_HALF_FLOAT:
|
||||
case PIPE_CAP_MULTI_DRAW_INDIRECT:
|
||||
case PIPE_CAP_MULTI_DRAW_INDIRECT_PARAMS:
|
||||
case PIPE_CAP_TGSI_FS_POSITION_IS_SYSVAL:
|
||||
case PIPE_CAP_TGSI_FS_FACE_IS_INTEGER_SYSVAL:
|
||||
case PIPE_CAP_SHADER_BUFFER_OFFSET_ALIGNMENT:
|
||||
case PIPE_CAP_INVALIDATE_BUFFER:
|
||||
case PIPE_CAP_GENERATE_MIPMAP:
|
||||
case PIPE_CAP_STRING_MARKER:
|
||||
case PIPE_CAP_SURFACE_REINTERPRET_BLOCKS:
|
||||
case PIPE_CAP_QUERY_BUFFER_OBJECT:
|
||||
case PIPE_CAP_QUERY_MEMORY_INFO:
|
||||
case PIPE_CAP_FRAMEBUFFER_NO_ATTACHMENT:
|
||||
case PIPE_CAP_ROBUST_BUFFER_ACCESS_BEHAVIOR:
|
||||
case PIPE_CAP_CULL_DISTANCE:
|
||||
case PIPE_CAP_PRIMITIVE_RESTART_FOR_PATCHES:
|
||||
case PIPE_CAP_TGSI_VOTE:
|
||||
case PIPE_CAP_MAX_WINDOW_RECTANGLES:
|
||||
case PIPE_CAP_POLYGON_OFFSET_UNITS_UNSCALED:
|
||||
case PIPE_CAP_VIEWPORT_SUBPIXEL_BITS:
|
||||
case PIPE_CAP_MIXED_COLOR_DEPTH_BITS:
|
||||
case PIPE_CAP_TGSI_ARRAY_COMPONENTS:
|
||||
case PIPE_CAP_STREAM_OUTPUT_INTERLEAVE_BUFFERS:
|
||||
case PIPE_CAP_TGSI_CAN_READ_OUTPUTS:
|
||||
case PIPE_CAP_NATIVE_FENCE_FD:
|
||||
case PIPE_CAP_GLSL_OPTIMIZE_CONSERVATIVELY:
|
||||
return 0;
|
||||
|
||||
/* Stream output. */
|
||||
case PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS:
|
||||
case PIPE_CAP_STREAM_OUTPUT_PAUSE_RESUME:
|
||||
case PIPE_CAP_MAX_STREAM_OUTPUT_SEPARATE_COMPONENTS:
|
||||
case PIPE_CAP_MAX_STREAM_OUTPUT_INTERLEAVED_COMPONENTS:
|
||||
return 0;
|
||||
|
||||
/* Geometry shader output, unsupported. */
|
||||
case PIPE_CAP_MAX_GEOMETRY_OUTPUT_VERTICES:
|
||||
case PIPE_CAP_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS:
|
||||
case PIPE_CAP_MAX_VERTEX_STREAMS:
|
||||
return 0;
|
||||
|
||||
case PIPE_CAP_MAX_VERTEX_ATTRIB_STRIDE:
|
||||
return 128;
|
||||
|
||||
/* Texturing. */
|
||||
case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
|
||||
case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
|
||||
{
|
||||
int log2_max_tex_size = util_last_bit(screen->specs.max_texture_size);
|
||||
assert(log2_max_tex_size > 0);
|
||||
return log2_max_tex_size;
|
||||
}
|
||||
case PIPE_CAP_MAX_TEXTURE_3D_LEVELS: /* 3D textures not supported - fake it */
|
||||
return 5;
|
||||
case PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS:
|
||||
return 0;
|
||||
case PIPE_CAP_CUBE_MAP_ARRAY:
|
||||
return 0;
|
||||
case PIPE_CAP_MIN_TEXTURE_GATHER_OFFSET:
|
||||
case PIPE_CAP_MIN_TEXEL_OFFSET:
|
||||
return -8;
|
||||
case PIPE_CAP_MAX_TEXTURE_GATHER_OFFSET:
|
||||
case PIPE_CAP_MAX_TEXEL_OFFSET:
|
||||
return 7;
|
||||
case PIPE_CAP_TEXTURE_BORDER_COLOR_QUIRK:
|
||||
return 0;
|
||||
case PIPE_CAP_MAX_TEXTURE_BUFFER_SIZE:
|
||||
return 65536;
|
||||
|
||||
/* Render targets. */
|
||||
case PIPE_CAP_MAX_RENDER_TARGETS:
|
||||
return 1;
|
||||
|
||||
/* Viewports and scissors. */
|
||||
case PIPE_CAP_MAX_VIEWPORTS:
|
||||
return 1;
|
||||
|
||||
/* Timer queries. */
|
||||
case PIPE_CAP_QUERY_TIME_ELAPSED:
|
||||
case PIPE_CAP_OCCLUSION_QUERY:
|
||||
return 0;
|
||||
case PIPE_CAP_QUERY_TIMESTAMP:
|
||||
return 1;
|
||||
case PIPE_CAP_QUERY_PIPELINE_STATISTICS:
|
||||
return 0;
|
||||
|
||||
/* Preferences */
|
||||
case PIPE_CAP_PREFER_BLIT_BASED_TEXTURE_TRANSFER:
|
||||
return 0;
|
||||
|
||||
case PIPE_CAP_PCI_GROUP:
|
||||
case PIPE_CAP_PCI_BUS:
|
||||
case PIPE_CAP_PCI_DEVICE:
|
||||
case PIPE_CAP_PCI_FUNCTION:
|
||||
return 0;
|
||||
case PIPE_CAP_VENDOR_ID:
|
||||
case PIPE_CAP_DEVICE_ID:
|
||||
return 0xFFFFFFFF;
|
||||
case PIPE_CAP_ACCELERATED:
|
||||
return 1;
|
||||
case PIPE_CAP_VIDEO_MEMORY:
|
||||
return 0;
|
||||
case PIPE_CAP_UMA:
|
||||
return 1;
|
||||
}
|
||||
|
||||
debug_printf("unknown param %d", param);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static float
|
||||
etna_screen_get_paramf(struct pipe_screen *pscreen, enum pipe_capf param)
|
||||
{
|
||||
switch (param) {
|
||||
case PIPE_CAPF_MAX_LINE_WIDTH:
|
||||
case PIPE_CAPF_MAX_LINE_WIDTH_AA:
|
||||
case PIPE_CAPF_MAX_POINT_WIDTH:
|
||||
case PIPE_CAPF_MAX_POINT_WIDTH_AA:
|
||||
return 8192.0f;
|
||||
case PIPE_CAPF_MAX_TEXTURE_ANISOTROPY:
|
||||
return 16.0f;
|
||||
case PIPE_CAPF_MAX_TEXTURE_LOD_BIAS:
|
||||
return 16.0f;
|
||||
case PIPE_CAPF_GUARD_BAND_LEFT:
|
||||
case PIPE_CAPF_GUARD_BAND_TOP:
|
||||
case PIPE_CAPF_GUARD_BAND_RIGHT:
|
||||
case PIPE_CAPF_GUARD_BAND_BOTTOM:
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
debug_printf("unknown paramf %d", param);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
etna_screen_get_shader_param(struct pipe_screen *pscreen, unsigned shader,
|
||||
enum pipe_shader_cap param)
|
||||
{
|
||||
struct etna_screen *screen = etna_screen(pscreen);
|
||||
|
||||
switch (shader) {
|
||||
case PIPE_SHADER_FRAGMENT:
|
||||
case PIPE_SHADER_VERTEX:
|
||||
break;
|
||||
case PIPE_SHADER_COMPUTE:
|
||||
case PIPE_SHADER_GEOMETRY:
|
||||
case PIPE_SHADER_TESS_CTRL:
|
||||
case PIPE_SHADER_TESS_EVAL:
|
||||
return 0;
|
||||
default:
|
||||
DBG("unknown shader type %d", shader);
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch (param) {
|
||||
case PIPE_SHADER_CAP_MAX_INSTRUCTIONS:
|
||||
case PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS:
|
||||
case PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS:
|
||||
case PIPE_SHADER_CAP_MAX_TEX_INDIRECTIONS:
|
||||
return ETNA_MAX_TOKENS;
|
||||
case PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH:
|
||||
return ETNA_MAX_DEPTH; /* XXX */
|
||||
case PIPE_SHADER_CAP_MAX_INPUTS:
|
||||
/* Maximum number of inputs for the vertex shader is the number
|
||||
* of vertex elements - each element defines one vertex shader
|
||||
* input register. For the fragment shader, this is the number
|
||||
* of varyings. */
|
||||
return shader == PIPE_SHADER_FRAGMENT ? screen->specs.max_varyings
|
||||
: screen->specs.vertex_max_elements;
|
||||
case PIPE_SHADER_CAP_MAX_OUTPUTS:
|
||||
return 16; /* see VIVS_VS_OUTPUT */
|
||||
case PIPE_SHADER_CAP_MAX_TEMPS:
|
||||
return 64; /* Max native temporaries. */
|
||||
case PIPE_SHADER_CAP_MAX_CONST_BUFFERS:
|
||||
return 1;
|
||||
case PIPE_SHADER_CAP_MAX_PREDS:
|
||||
return 0; /* nothing uses this */
|
||||
case PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED:
|
||||
return 1;
|
||||
case PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR:
|
||||
case PIPE_SHADER_CAP_INDIRECT_OUTPUT_ADDR:
|
||||
case PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR:
|
||||
case PIPE_SHADER_CAP_INDIRECT_CONST_ADDR:
|
||||
return 1;
|
||||
case PIPE_SHADER_CAP_SUBROUTINES:
|
||||
return 0;
|
||||
case PIPE_SHADER_CAP_TGSI_SQRT_SUPPORTED:
|
||||
return VIV_FEATURE(screen, chipMinorFeatures0, HAS_SQRT_TRIG);
|
||||
case PIPE_SHADER_CAP_INTEGERS:
|
||||
return 0;
|
||||
case PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS:
|
||||
case PIPE_SHADER_CAP_MAX_SAMPLER_VIEWS:
|
||||
return shader == PIPE_SHADER_FRAGMENT
|
||||
? screen->specs.fragment_sampler_count
|
||||
: screen->specs.vertex_sampler_count;
|
||||
case PIPE_SHADER_CAP_PREFERRED_IR:
|
||||
return PIPE_SHADER_IR_TGSI;
|
||||
case PIPE_SHADER_CAP_MAX_CONST_BUFFER_SIZE:
|
||||
return 4096;
|
||||
case PIPE_SHADER_CAP_DOUBLES:
|
||||
case PIPE_SHADER_CAP_TGSI_DROUND_SUPPORTED:
|
||||
case PIPE_SHADER_CAP_TGSI_DFRACEXP_DLDEXP_SUPPORTED:
|
||||
case PIPE_SHADER_CAP_TGSI_FMA_SUPPORTED:
|
||||
case PIPE_SHADER_CAP_TGSI_ANY_INOUT_DECL_RANGE:
|
||||
return false;
|
||||
case PIPE_SHADER_CAP_SUPPORTED_IRS:
|
||||
return 0;
|
||||
case PIPE_SHADER_CAP_MAX_UNROLL_ITERATIONS_HINT:
|
||||
return 32;
|
||||
case PIPE_SHADER_CAP_MAX_SHADER_BUFFERS:
|
||||
case PIPE_SHADER_CAP_MAX_SHADER_IMAGES:
|
||||
case PIPE_SHADER_CAP_LOWER_IF_THRESHOLD:
|
||||
return 0;
|
||||
}
|
||||
|
||||
debug_printf("unknown shader param %d", param);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static uint64_t
|
||||
etna_screen_get_timestamp(struct pipe_screen *pscreen)
|
||||
{
|
||||
return os_time_get_nano();
|
||||
}
|
||||
|
||||
static bool
|
||||
gpu_supports_texure_format(struct etna_screen *screen, uint32_t fmt)
|
||||
{
|
||||
if (fmt == TEXTURE_FORMAT_ETC1)
|
||||
return VIV_FEATURE(screen, chipFeatures, ETC1_TEXTURE_COMPRESSION);
|
||||
|
||||
if (fmt >= TEXTURE_FORMAT_DXT1 && fmt <= TEXTURE_FORMAT_DXT4_DXT5)
|
||||
return VIV_FEATURE(screen, chipFeatures, DXT_TEXTURE_COMPRESSION);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static boolean
|
||||
etna_screen_is_format_supported(struct pipe_screen *pscreen,
|
||||
enum pipe_format format,
|
||||
enum pipe_texture_target target,
|
||||
unsigned sample_count, unsigned usage)
|
||||
{
|
||||
struct etna_screen *screen = etna_screen(pscreen);
|
||||
unsigned allowed = 0;
|
||||
|
||||
if (target != PIPE_BUFFER &&
|
||||
target != PIPE_TEXTURE_1D &&
|
||||
target != PIPE_TEXTURE_2D &&
|
||||
target != PIPE_TEXTURE_3D &&
|
||||
target != PIPE_TEXTURE_CUBE &&
|
||||
target != PIPE_TEXTURE_RECT)
|
||||
return FALSE;
|
||||
|
||||
if (usage & PIPE_BIND_RENDER_TARGET) {
|
||||
/* if render target, must be RS-supported format */
|
||||
if (translate_rs_format(format) != ETNA_NO_MATCH) {
|
||||
/* Validate MSAA; number of samples must be allowed, and render target
|
||||
* must have MSAA'able format. */
|
||||
if (sample_count > 1) {
|
||||
if (translate_samples_to_xyscale(sample_count, NULL, NULL, NULL) &&
|
||||
translate_msaa_format(format) != ETNA_NO_MATCH) {
|
||||
allowed |= PIPE_BIND_RENDER_TARGET;
|
||||
}
|
||||
} else {
|
||||
allowed |= PIPE_BIND_RENDER_TARGET;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (usage & PIPE_BIND_DEPTH_STENCIL) {
|
||||
if (translate_depth_format(format) != ETNA_NO_MATCH)
|
||||
allowed |= PIPE_BIND_DEPTH_STENCIL;
|
||||
}
|
||||
|
||||
if (usage & PIPE_BIND_SAMPLER_VIEW) {
|
||||
uint32_t fmt = translate_texture_format(format);
|
||||
|
||||
if (!gpu_supports_texure_format(screen, fmt))
|
||||
fmt = ETNA_NO_MATCH;
|
||||
|
||||
if (sample_count < 2 && fmt != ETNA_NO_MATCH)
|
||||
allowed |= PIPE_BIND_SAMPLER_VIEW;
|
||||
}
|
||||
|
||||
if (usage & PIPE_BIND_VERTEX_BUFFER) {
|
||||
if (translate_vertex_format_type(format) != ETNA_NO_MATCH)
|
||||
allowed |= PIPE_BIND_VERTEX_BUFFER;
|
||||
}
|
||||
|
||||
if (usage & PIPE_BIND_INDEX_BUFFER) {
|
||||
/* must be supported index format */
|
||||
if (format == PIPE_FORMAT_I8_UINT || format == PIPE_FORMAT_I16_UINT ||
|
||||
(format == PIPE_FORMAT_I32_UINT &&
|
||||
VIV_FEATURE(screen, chipFeatures, 32_BIT_INDICES))) {
|
||||
allowed |= PIPE_BIND_INDEX_BUFFER;
|
||||
}
|
||||
}
|
||||
|
||||
/* Always allowed */
|
||||
allowed |=
|
||||
usage & (PIPE_BIND_DISPLAY_TARGET | PIPE_BIND_SCANOUT | PIPE_BIND_SHARED);
|
||||
|
||||
if (usage != allowed) {
|
||||
DBG("not supported: format=%s, target=%d, sample_count=%d, "
|
||||
"usage=%x, allowed=%x",
|
||||
util_format_name(format), target, sample_count, usage, allowed);
|
||||
}
|
||||
|
||||
return usage == allowed;
|
||||
}
|
||||
|
||||
static boolean
|
||||
etna_get_specs(struct etna_screen *screen)
|
||||
{
|
||||
uint64_t val;
|
||||
uint32_t instruction_count;
|
||||
|
||||
if (etna_gpu_get_param(screen->gpu, ETNA_GPU_INSTRUCTION_COUNT, &val)) {
|
||||
DBG("could not get ETNA_GPU_INSTRUCTION_COUNT");
|
||||
goto fail;
|
||||
}
|
||||
instruction_count = val;
|
||||
|
||||
if (etna_gpu_get_param(screen->gpu, ETNA_GPU_VERTEX_OUTPUT_BUFFER_SIZE,
|
||||
&val)) {
|
||||
DBG("could not get ETNA_GPU_VERTEX_OUTPUT_BUFFER_SIZE");
|
||||
goto fail;
|
||||
}
|
||||
screen->specs.vertex_output_buffer_size = val;
|
||||
|
||||
if (etna_gpu_get_param(screen->gpu, ETNA_GPU_VERTEX_CACHE_SIZE, &val)) {
|
||||
DBG("could not get ETNA_GPU_VERTEX_CACHE_SIZE");
|
||||
goto fail;
|
||||
}
|
||||
screen->specs.vertex_cache_size = val;
|
||||
|
||||
if (etna_gpu_get_param(screen->gpu, ETNA_GPU_SHADER_CORE_COUNT, &val)) {
|
||||
DBG("could not get ETNA_GPU_SHADER_CORE_COUNT");
|
||||
goto fail;
|
||||
}
|
||||
screen->specs.shader_core_count = val;
|
||||
|
||||
if (etna_gpu_get_param(screen->gpu, ETNA_GPU_STREAM_COUNT, &val)) {
|
||||
DBG("could not get ETNA_GPU_STREAM_COUNT");
|
||||
goto fail;
|
||||
}
|
||||
screen->specs.stream_count = val;
|
||||
|
||||
if (etna_gpu_get_param(screen->gpu, ETNA_GPU_REGISTER_MAX, &val)) {
|
||||
DBG("could not get ETNA_GPU_REGISTER_MAX");
|
||||
goto fail;
|
||||
}
|
||||
screen->specs.max_registers = val;
|
||||
|
||||
if (etna_gpu_get_param(screen->gpu, ETNA_GPU_PIXEL_PIPES, &val)) {
|
||||
DBG("could not get ETNA_GPU_PIXEL_PIPES");
|
||||
goto fail;
|
||||
}
|
||||
if (val < 1 && val > ETNA_MAX_PIXELPIPES) {
|
||||
if (val == 0) {
|
||||
fprintf(stderr, "Warning: zero pixel pipes (update kernel?)\n");
|
||||
val = 1;
|
||||
} else {
|
||||
fprintf(stderr, "Error: bad pixel pipes value %u\n",
|
||||
(unsigned int)val);
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
screen->specs.pixel_pipes = val;
|
||||
|
||||
if (etna_gpu_get_param(screen->gpu, ETNA_GPU_NUM_CONSTANTS, &val)) {
|
||||
DBG("could not get %s", "ETNA_GPU_NUM_CONSTANTS");
|
||||
goto fail;
|
||||
}
|
||||
if (val == 0) {
|
||||
fprintf(stderr, "Warning: zero num constants (update kernel?)\n");
|
||||
val = 168;
|
||||
}
|
||||
screen->specs.num_constants = val;
|
||||
|
||||
screen->specs.can_supertile =
|
||||
VIV_FEATURE(screen, chipMinorFeatures0, SUPER_TILED);
|
||||
screen->specs.bits_per_tile =
|
||||
VIV_FEATURE(screen, chipMinorFeatures0, 2BITPERTILE) ? 2 : 4;
|
||||
screen->specs.ts_clear_value =
|
||||
VIV_FEATURE(screen, chipMinorFeatures0, 2BITPERTILE) ? 0x55555555
|
||||
: 0x11111111;
|
||||
|
||||
/* vertex and fragment samplers live in one address space */
|
||||
screen->specs.vertex_sampler_offset = 8;
|
||||
screen->specs.fragment_sampler_count = 8;
|
||||
screen->specs.vertex_sampler_count = 4;
|
||||
screen->specs.vs_need_z_div =
|
||||
screen->model < 0x1000 && screen->model != 0x880;
|
||||
screen->specs.has_sin_cos_sqrt =
|
||||
VIV_FEATURE(screen, chipMinorFeatures0, HAS_SQRT_TRIG);
|
||||
screen->specs.has_sign_floor_ceil =
|
||||
VIV_FEATURE(screen, chipMinorFeatures0, HAS_SIGN_FLOOR_CEIL);
|
||||
screen->specs.has_shader_range_registers =
|
||||
screen->model >= 0x1000 || screen->model == 0x880;
|
||||
screen->specs.npot_tex_any_wrap =
|
||||
VIV_FEATURE(screen, chipMinorFeatures1, NON_POWER_OF_TWO);
|
||||
|
||||
if (instruction_count > 256) { /* unified instruction memory? */
|
||||
screen->specs.vs_offset = 0xC000;
|
||||
screen->specs.ps_offset = 0xD000; /* like vivante driver */
|
||||
screen->specs.max_instructions = 256;
|
||||
} else {
|
||||
screen->specs.vs_offset = 0x4000;
|
||||
screen->specs.ps_offset = 0x6000;
|
||||
screen->specs.max_instructions = instruction_count / 2;
|
||||
}
|
||||
|
||||
if (VIV_FEATURE(screen, chipMinorFeatures1, HALTI0)) {
|
||||
screen->specs.max_varyings = 12;
|
||||
screen->specs.vertex_max_elements = 16;
|
||||
} else {
|
||||
screen->specs.max_varyings = 8;
|
||||
/* Etna_viv documentation seems confused over the correct value
|
||||
* here so choose the lower to be safe: HALTI0 says 16 i.s.o.
|
||||
* 10, but VERTEX_ELEMENT_CONFIG register says 16 i.s.o. 12. */
|
||||
screen->specs.vertex_max_elements = 10;
|
||||
}
|
||||
|
||||
/* Etna_viv documentation does not indicate where varyings above 8 are
|
||||
* stored. Moreover, if we are passed more than 8 varyings, we will
|
||||
* walk off the end of some arrays. Limit the maximum number of varyings. */
|
||||
if (screen->specs.max_varyings > ETNA_NUM_VARYINGS)
|
||||
screen->specs.max_varyings = ETNA_NUM_VARYINGS;
|
||||
|
||||
/* from QueryShaderCaps in kernel driver */
|
||||
if (screen->model < chipModel_GC4000) {
|
||||
screen->specs.max_vs_uniforms = 168;
|
||||
screen->specs.max_ps_uniforms = 64;
|
||||
} else {
|
||||
screen->specs.max_vs_uniforms = 256;
|
||||
screen->specs.max_ps_uniforms = 256;
|
||||
}
|
||||
|
||||
screen->specs.max_texture_size =
|
||||
VIV_FEATURE(screen, chipMinorFeatures0, TEXTURE_8K) ? 8192 : 2048;
|
||||
screen->specs.max_rendertarget_size =
|
||||
VIV_FEATURE(screen, chipMinorFeatures0, RENDERTARGET_8K) ? 8192 : 2048;
|
||||
|
||||
return true;
|
||||
|
||||
fail:
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean
|
||||
etna_screen_bo_get_handle(struct pipe_screen *pscreen, struct etna_bo *bo,
|
||||
unsigned stride, struct winsys_handle *whandle)
|
||||
{
|
||||
whandle->stride = stride;
|
||||
|
||||
if (whandle->type == DRM_API_HANDLE_TYPE_SHARED) {
|
||||
return etna_bo_get_name(bo, &whandle->handle) == 0;
|
||||
} else if (whandle->type == DRM_API_HANDLE_TYPE_KMS) {
|
||||
whandle->handle = etna_bo_handle(bo);
|
||||
return TRUE;
|
||||
} else if (whandle->type == DRM_API_HANDLE_TYPE_FD) {
|
||||
whandle->handle = etna_bo_dmabuf(bo);
|
||||
return TRUE;
|
||||
} else {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
struct etna_bo *
|
||||
etna_screen_bo_from_handle(struct pipe_screen *pscreen,
|
||||
struct winsys_handle *whandle, unsigned *out_stride)
|
||||
{
|
||||
struct etna_screen *screen = etna_screen(pscreen);
|
||||
struct etna_bo *bo;
|
||||
|
||||
if (whandle->type == DRM_API_HANDLE_TYPE_SHARED) {
|
||||
bo = etna_bo_from_name(screen->dev, whandle->handle);
|
||||
} else if (whandle->type == DRM_API_HANDLE_TYPE_FD) {
|
||||
bo = etna_bo_from_dmabuf(screen->dev, whandle->handle);
|
||||
} else {
|
||||
DBG("Attempt to import unsupported handle type %d", whandle->type);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!bo) {
|
||||
DBG("ref name 0x%08x failed", whandle->handle);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
*out_stride = whandle->stride;
|
||||
|
||||
return bo;
|
||||
}
|
||||
|
||||
struct pipe_screen *
|
||||
etna_screen_create(struct etna_device *dev, struct etna_gpu *gpu,
|
||||
struct renderonly *ro)
|
||||
{
|
||||
struct etna_screen *screen = CALLOC_STRUCT(etna_screen);
|
||||
struct pipe_screen *pscreen;
|
||||
uint64_t val;
|
||||
|
||||
if (!screen)
|
||||
return NULL;
|
||||
|
||||
pscreen = &screen->base;
|
||||
screen->dev = dev;
|
||||
screen->gpu = gpu;
|
||||
screen->ro = renderonly_dup(ro);
|
||||
|
||||
if (!screen->ro) {
|
||||
DBG("could not create renderonly object");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
etna_mesa_debug = debug_get_option_etna_mesa_debug();
|
||||
|
||||
/* FIXME: Disable tile status for stability at the moment */
|
||||
etna_mesa_debug |= ETNA_DBG_NO_TS;
|
||||
|
||||
screen->pipe = etna_pipe_new(gpu, ETNA_PIPE_3D);
|
||||
if (!screen->pipe) {
|
||||
DBG("could not create 3d pipe");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (etna_gpu_get_param(screen->gpu, ETNA_GPU_MODEL, &val)) {
|
||||
DBG("could not get ETNA_GPU_MODEL");
|
||||
goto fail;
|
||||
}
|
||||
screen->model = val;
|
||||
|
||||
if (etna_gpu_get_param(screen->gpu, ETNA_GPU_REVISION, &val)) {
|
||||
DBG("could not get ETNA_GPU_REVISION");
|
||||
goto fail;
|
||||
}
|
||||
screen->revision = val;
|
||||
|
||||
if (etna_gpu_get_param(screen->gpu, ETNA_GPU_FEATURES_0, &val)) {
|
||||
DBG("could not get ETNA_GPU_FEATURES_0");
|
||||
goto fail;
|
||||
}
|
||||
screen->features[0] = val;
|
||||
|
||||
if (etna_gpu_get_param(screen->gpu, ETNA_GPU_FEATURES_1, &val)) {
|
||||
DBG("could not get ETNA_GPU_FEATURES_1");
|
||||
goto fail;
|
||||
}
|
||||
screen->features[1] = val;
|
||||
|
||||
if (etna_gpu_get_param(screen->gpu, ETNA_GPU_FEATURES_2, &val)) {
|
||||
DBG("could not get ETNA_GPU_FEATURES_2");
|
||||
goto fail;
|
||||
}
|
||||
screen->features[2] = val;
|
||||
|
||||
if (etna_gpu_get_param(screen->gpu, ETNA_GPU_FEATURES_3, &val)) {
|
||||
DBG("could not get ETNA_GPU_FEATURES_3");
|
||||
goto fail;
|
||||
}
|
||||
screen->features[3] = val;
|
||||
|
||||
if (etna_gpu_get_param(screen->gpu, ETNA_GPU_FEATURES_4, &val)) {
|
||||
DBG("could not get ETNA_GPU_FEATURES_4");
|
||||
goto fail;
|
||||
}
|
||||
screen->features[4] = val;
|
||||
|
||||
if (!etna_get_specs(screen))
|
||||
goto fail;
|
||||
|
||||
pscreen->destroy = etna_screen_destroy;
|
||||
pscreen->get_param = etna_screen_get_param;
|
||||
pscreen->get_paramf = etna_screen_get_paramf;
|
||||
pscreen->get_shader_param = etna_screen_get_shader_param;
|
||||
|
||||
pscreen->get_name = etna_screen_get_name;
|
||||
pscreen->get_vendor = etna_screen_get_vendor;
|
||||
pscreen->get_device_vendor = etna_screen_get_device_vendor;
|
||||
|
||||
pscreen->get_timestamp = etna_screen_get_timestamp;
|
||||
pscreen->context_create = etna_context_create;
|
||||
pscreen->is_format_supported = etna_screen_is_format_supported;
|
||||
|
||||
etna_fence_screen_init(pscreen);
|
||||
etna_query_screen_init(pscreen);
|
||||
etna_resource_screen_init(pscreen);
|
||||
|
||||
slab_create_parent(&screen->transfer_pool, sizeof(struct etna_transfer), 16);
|
||||
|
||||
return pscreen;
|
||||
|
||||
fail:
|
||||
etna_screen_destroy(pscreen);
|
||||
return NULL;
|
||||
}
|
|
@ -0,0 +1,95 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2015 Etnaviv Project
|
||||
*
|
||||
* 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, sub license,
|
||||
* 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 NON-INFRINGEMENT. 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:
|
||||
* Wladimir J. van der Laan <laanwj@gmail.com>
|
||||
* Christian Gmeiner <christian.gmeiner@gmail.com>
|
||||
*/
|
||||
|
||||
#ifndef H_ETNAVIV_SCREEN
|
||||
#define H_ETNAVIV_SCREEN
|
||||
|
||||
#include "etnaviv_internal.h"
|
||||
|
||||
#include "os/os_thread.h"
|
||||
#include "pipe/p_screen.h"
|
||||
#include "renderonly/renderonly.h"
|
||||
#include "util/slab.h"
|
||||
|
||||
struct etna_bo;
|
||||
|
||||
/* Enum with indices for each of the feature words */
|
||||
enum viv_features_word {
|
||||
viv_chipFeatures = 0,
|
||||
viv_chipMinorFeatures0 = 1,
|
||||
viv_chipMinorFeatures1 = 2,
|
||||
viv_chipMinorFeatures2 = 3,
|
||||
viv_chipMinorFeatures3 = 4,
|
||||
VIV_FEATURES_WORD_COUNT /* Must be last */
|
||||
};
|
||||
|
||||
/** Convenience macro to probe features from state.xml.h:
|
||||
* VIV_FEATURE(chipFeatures, FAST_CLEAR)
|
||||
* VIV_FEATURE(chipMinorFeatures1, AUTO_DISABLE)
|
||||
*/
|
||||
#define VIV_FEATURE(screen, word, feature) \
|
||||
((screen->features[viv_ ## word] & (word ## _ ## feature)) != 0)
|
||||
|
||||
struct etna_screen {
|
||||
struct pipe_screen base;
|
||||
|
||||
int refcnt;
|
||||
void *winsys_priv;
|
||||
|
||||
struct etna_device *dev;
|
||||
struct etna_gpu *gpu;
|
||||
struct etna_pipe *pipe;
|
||||
struct renderonly *ro;
|
||||
|
||||
struct slab_parent_pool transfer_pool;
|
||||
|
||||
uint32_t model;
|
||||
uint32_t revision;
|
||||
uint32_t features[5];
|
||||
|
||||
struct etna_specs specs;
|
||||
};
|
||||
|
||||
static inline struct etna_screen *
|
||||
etna_screen(struct pipe_screen *pscreen)
|
||||
{
|
||||
return (struct etna_screen *)pscreen;
|
||||
}
|
||||
|
||||
boolean
|
||||
etna_screen_bo_get_handle(struct pipe_screen *pscreen, struct etna_bo *bo,
|
||||
unsigned stride, struct winsys_handle *whandle);
|
||||
|
||||
struct etna_bo *
|
||||
etna_screen_bo_from_handle(struct pipe_screen *pscreen,
|
||||
struct winsys_handle *whandle, unsigned *out_stride);
|
||||
|
||||
struct pipe_screen *
|
||||
etna_screen_create(struct etna_device *dev, struct etna_gpu *gpu,
|
||||
struct renderonly *ro);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,285 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2015 Etnaviv Project
|
||||
*
|
||||
* 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, sub license,
|
||||
* 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 NON-INFRINGEMENT. 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:
|
||||
* Wladimir J. van der Laan <laanwj@gmail.com>
|
||||
*/
|
||||
|
||||
#include "etnaviv_shader.h"
|
||||
|
||||
#include "etnaviv_compiler.h"
|
||||
#include "etnaviv_context.h"
|
||||
#include "etnaviv_debug.h"
|
||||
#include "etnaviv_util.h"
|
||||
|
||||
#include "util/u_math.h"
|
||||
#include "util/u_memory.h"
|
||||
|
||||
/* Link vs and fs together: fill in shader_state from vs and fs
|
||||
* as this function is called every time a new fs or vs is bound, the goal is to
|
||||
* do little processing as possible here, and to precompute as much as possible in
|
||||
* the vs/fs shader_object.
|
||||
*
|
||||
* XXX we could cache the link result for a certain set of VS/PS; usually a pair
|
||||
* of VS and PS will be used together anyway.
|
||||
*/
|
||||
static bool
|
||||
etna_link_shaders(struct etna_context *ctx, struct compiled_shader_state *cs,
|
||||
const struct etna_shader *vs, const struct etna_shader *fs)
|
||||
{
|
||||
struct etna_shader_link_info link = { };
|
||||
|
||||
assert(vs->processor == PIPE_SHADER_VERTEX);
|
||||
assert(fs->processor == PIPE_SHADER_FRAGMENT);
|
||||
|
||||
#ifdef DEBUG
|
||||
if (DBG_ENABLED(ETNA_DBG_DUMP_SHADERS)) {
|
||||
etna_dump_shader(vs);
|
||||
etna_dump_shader(fs);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (etna_link_shader(&link, vs, fs)) {
|
||||
/* linking failed: some fs inputs do not have corresponding
|
||||
* vs outputs */
|
||||
assert(0);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (DBG_ENABLED(ETNA_DBG_LINKER_MSGS)) {
|
||||
debug_printf("link result:\n");
|
||||
debug_printf(" vs -> fs comps use pa_attr\n");
|
||||
|
||||
for (int idx = 0; idx < link.num_varyings; ++idx)
|
||||
debug_printf(" t%-2u -> t%-2u %-5.*s %u,%u,%u,%u 0x%08x\n",
|
||||
link.varyings[idx].reg, idx + 1,
|
||||
link.varyings[idx].num_components, "xyzw",
|
||||
link.varyings[idx].use[0], link.varyings[idx].use[1],
|
||||
link.varyings[idx].use[2], link.varyings[idx].use[3],
|
||||
link.varyings[idx].pa_attributes);
|
||||
}
|
||||
|
||||
/* set last_varying_2x flag if the last varying has 1 or 2 components */
|
||||
bool last_varying_2x = false;
|
||||
if (link.num_varyings > 0 && link.varyings[link.num_varyings - 1].num_components <= 2)
|
||||
last_varying_2x = true;
|
||||
|
||||
cs->RA_CONTROL = VIVS_RA_CONTROL_UNK0 |
|
||||
COND(last_varying_2x, VIVS_RA_CONTROL_LAST_VARYING_2X);
|
||||
|
||||
cs->PA_ATTRIBUTE_ELEMENT_COUNT = VIVS_PA_ATTRIBUTE_ELEMENT_COUNT_COUNT(link.num_varyings);
|
||||
for (int idx = 0; idx < link.num_varyings; ++idx)
|
||||
cs->PA_SHADER_ATTRIBUTES[idx] = link.varyings[idx].pa_attributes;
|
||||
|
||||
cs->VS_END_PC = vs->code_size / 4;
|
||||
cs->VS_OUTPUT_COUNT = 1 + link.num_varyings; /* position + varyings */
|
||||
|
||||
/* vs outputs (varyings) */
|
||||
DEFINE_ETNA_BITARRAY(vs_output, 16, 8) = {0};
|
||||
int varid = 0;
|
||||
etna_bitarray_set(vs_output, 8, varid++, vs->vs_pos_out_reg);
|
||||
for (int idx = 0; idx < link.num_varyings; ++idx)
|
||||
etna_bitarray_set(vs_output, 8, varid++, link.varyings[idx].reg);
|
||||
if (vs->vs_pointsize_out_reg >= 0)
|
||||
etna_bitarray_set(vs_output, 8, varid++, vs->vs_pointsize_out_reg); /* pointsize is last */
|
||||
|
||||
for (int idx = 0; idx < ARRAY_SIZE(cs->VS_OUTPUT); ++idx)
|
||||
cs->VS_OUTPUT[idx] = vs_output[idx];
|
||||
|
||||
if (vs->vs_pointsize_out_reg != -1) {
|
||||
/* vertex shader outputs point coordinate, provide extra output and make
|
||||
* sure PA config is
|
||||
* not masked */
|
||||
cs->PA_CONFIG = ~0;
|
||||
cs->VS_OUTPUT_COUNT_PSIZE = cs->VS_OUTPUT_COUNT + 1;
|
||||
} else {
|
||||
/* vertex shader does not output point coordinate, make sure thate
|
||||
* POINT_SIZE_ENABLE is masked
|
||||
* and no extra output is given */
|
||||
cs->PA_CONFIG = ~VIVS_PA_CONFIG_POINT_SIZE_ENABLE;
|
||||
cs->VS_OUTPUT_COUNT_PSIZE = cs->VS_OUTPUT_COUNT;
|
||||
}
|
||||
|
||||
cs->VS_LOAD_BALANCING = vs->vs_load_balancing;
|
||||
cs->VS_START_PC = 0;
|
||||
|
||||
cs->PS_END_PC = fs->code_size / 4;
|
||||
cs->PS_OUTPUT_REG = fs->ps_color_out_reg;
|
||||
cs->PS_INPUT_COUNT =
|
||||
VIVS_PS_INPUT_COUNT_COUNT(link.num_varyings + 1) | /* Number of inputs plus position */
|
||||
VIVS_PS_INPUT_COUNT_UNK8(fs->input_count_unk8);
|
||||
cs->PS_TEMP_REGISTER_CONTROL =
|
||||
VIVS_PS_TEMP_REGISTER_CONTROL_NUM_TEMPS(MAX2(fs->num_temps, link.num_varyings + 1));
|
||||
cs->PS_CONTROL = VIVS_PS_CONTROL_UNK1; /* XXX when can we set BYPASS? */
|
||||
cs->PS_START_PC = 0;
|
||||
|
||||
/* Precompute PS_INPUT_COUNT and TEMP_REGISTER_CONTROL in the case of MSAA
|
||||
* mode, avoids some fumbling in sync_context. */
|
||||
cs->PS_INPUT_COUNT_MSAA =
|
||||
VIVS_PS_INPUT_COUNT_COUNT(link.num_varyings + 2) | /* MSAA adds another input */
|
||||
VIVS_PS_INPUT_COUNT_UNK8(fs->input_count_unk8);
|
||||
cs->PS_TEMP_REGISTER_CONTROL_MSAA =
|
||||
VIVS_PS_TEMP_REGISTER_CONTROL_NUM_TEMPS(MAX2(fs->num_temps, link.num_varyings + 2));
|
||||
|
||||
uint32_t total_components = 0;
|
||||
DEFINE_ETNA_BITARRAY(num_components, ETNA_NUM_VARYINGS, 4) = {0};
|
||||
DEFINE_ETNA_BITARRAY(component_use, 4 * ETNA_NUM_VARYINGS, 2) = {0};
|
||||
for (int idx = 0; idx < link.num_varyings; ++idx) {
|
||||
const struct etna_varying *varying = &link.varyings[idx];
|
||||
|
||||
etna_bitarray_set(num_components, 4, idx, varying->num_components);
|
||||
for (int comp = 0; comp < varying->num_components; ++comp) {
|
||||
etna_bitarray_set(component_use, 2, total_components, varying->use[comp]);
|
||||
total_components += 1;
|
||||
}
|
||||
}
|
||||
|
||||
cs->GL_VARYING_TOTAL_COMPONENTS =
|
||||
VIVS_GL_VARYING_TOTAL_COMPONENTS_NUM(align(total_components, 2));
|
||||
cs->GL_VARYING_NUM_COMPONENTS = num_components[0];
|
||||
cs->GL_VARYING_COMPONENT_USE[0] = component_use[0];
|
||||
cs->GL_VARYING_COMPONENT_USE[1] = component_use[1];
|
||||
|
||||
/* reference instruction memory */
|
||||
cs->vs_inst_mem_size = vs->code_size;
|
||||
cs->VS_INST_MEM = vs->code;
|
||||
cs->ps_inst_mem_size = fs->code_size;
|
||||
cs->PS_INST_MEM = fs->code;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
etna_shader_link(struct etna_context *ctx)
|
||||
{
|
||||
if (!ctx->vs || !ctx->fs)
|
||||
return false;
|
||||
|
||||
/* re-link vs and fs if needed */
|
||||
return etna_link_shaders(ctx, &ctx->shader_state, ctx->vs, ctx->fs);
|
||||
}
|
||||
|
||||
static bool
|
||||
etna_shader_update_vs_inputs(struct etna_context *ctx,
|
||||
struct compiled_shader_state *cs,
|
||||
const struct etna_shader *vs,
|
||||
const struct compiled_vertex_elements_state *ves)
|
||||
{
|
||||
unsigned num_temps, cur_temp, num_vs_inputs;
|
||||
|
||||
if (!vs)
|
||||
return false;
|
||||
|
||||
/* Number of vertex elements determines number of VS inputs. Otherwise,
|
||||
* the GPU crashes. Allocate any unused vertex elements to VS temporary
|
||||
* registers. */
|
||||
num_vs_inputs = MAX2(ves->num_elements, vs->infile.num_reg);
|
||||
if (num_vs_inputs != ves->num_elements) {
|
||||
BUG("Number of elements %u does not match the number of VS inputs %zu",
|
||||
ctx->vertex_elements->num_elements, ctx->vs->infile.num_reg);
|
||||
return false;
|
||||
}
|
||||
|
||||
cur_temp = vs->num_temps;
|
||||
num_temps = num_vs_inputs - vs->infile.num_reg + cur_temp;
|
||||
|
||||
cs->VS_INPUT_COUNT = VIVS_VS_INPUT_COUNT_COUNT(num_vs_inputs) |
|
||||
VIVS_VS_INPUT_COUNT_UNK8(vs->input_count_unk8);
|
||||
cs->VS_TEMP_REGISTER_CONTROL =
|
||||
VIVS_VS_TEMP_REGISTER_CONTROL_NUM_TEMPS(num_temps);
|
||||
|
||||
/* vs inputs (attributes) */
|
||||
DEFINE_ETNA_BITARRAY(vs_input, 16, 8) = {0};
|
||||
for (int idx = 0; idx < num_vs_inputs; ++idx) {
|
||||
if (idx < vs->infile.num_reg)
|
||||
etna_bitarray_set(vs_input, 8, idx, vs->infile.reg[idx].reg);
|
||||
else
|
||||
etna_bitarray_set(vs_input, 8, idx, cur_temp++);
|
||||
}
|
||||
|
||||
for (int idx = 0; idx < ARRAY_SIZE(cs->VS_INPUT); ++idx)
|
||||
cs->VS_INPUT[idx] = vs_input[idx];
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
etna_shader_update_vertex(struct etna_context *ctx)
|
||||
{
|
||||
return etna_shader_update_vs_inputs(ctx, &ctx->shader_state, ctx->vs,
|
||||
ctx->vertex_elements);
|
||||
}
|
||||
|
||||
static void *
|
||||
etna_create_shader_state(struct pipe_context *pctx,
|
||||
const struct pipe_shader_state *pss)
|
||||
{
|
||||
struct etna_context *ctx = etna_context(pctx);
|
||||
|
||||
return etna_compile_shader(&ctx->specs, pss->tokens);
|
||||
}
|
||||
|
||||
static void
|
||||
etna_delete_shader_state(struct pipe_context *pctx, void *ss)
|
||||
{
|
||||
etna_destroy_shader(ss);
|
||||
}
|
||||
|
||||
static void
|
||||
etna_bind_fs_state(struct pipe_context *pctx, void *fss_)
|
||||
{
|
||||
struct etna_context *ctx = etna_context(pctx);
|
||||
struct etna_shader *fss = fss_;
|
||||
|
||||
if (ctx->fs == fss) /* skip if already bound */
|
||||
return;
|
||||
|
||||
assert(fss == NULL || fss->processor == PIPE_SHADER_FRAGMENT);
|
||||
ctx->fs = fss;
|
||||
ctx->dirty |= ETNA_DIRTY_SHADER;
|
||||
}
|
||||
|
||||
static void
|
||||
etna_bind_vs_state(struct pipe_context *pctx, void *vss_)
|
||||
{
|
||||
struct etna_context *ctx = etna_context(pctx);
|
||||
struct etna_shader *vss = vss_;
|
||||
|
||||
if (ctx->vs == vss) /* skip if already bound */
|
||||
return;
|
||||
|
||||
assert(vss == NULL || vss->processor == PIPE_SHADER_VERTEX);
|
||||
ctx->vs = vss;
|
||||
ctx->dirty |= ETNA_DIRTY_SHADER;
|
||||
}
|
||||
|
||||
void
|
||||
etna_shader_init(struct pipe_context *pctx)
|
||||
{
|
||||
pctx->create_fs_state = etna_create_shader_state;
|
||||
pctx->bind_fs_state = etna_bind_fs_state;
|
||||
pctx->delete_fs_state = etna_delete_shader_state;
|
||||
pctx->create_vs_state = etna_create_shader_state;
|
||||
pctx->bind_vs_state = etna_bind_vs_state;
|
||||
pctx->delete_vs_state = etna_delete_shader_state;
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2015 Etnaviv Project
|
||||
*
|
||||
* 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, sub license,
|
||||
* 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 NON-INFRINGEMENT. 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:
|
||||
* Wladimir J. van der Laan <laanwj@gmail.com>
|
||||
*/
|
||||
|
||||
#ifndef H_ETNAVIV_SHADER
|
||||
#define H_ETNAVIV_SHADER
|
||||
|
||||
#include "pipe/p_state.h"
|
||||
|
||||
struct etna_context;
|
||||
struct etna_shader;
|
||||
struct compiled_shader_state;
|
||||
|
||||
bool
|
||||
etna_shader_link(struct etna_context *ctx);
|
||||
|
||||
bool
|
||||
etna_shader_update_vertex(struct etna_context *ctx);
|
||||
|
||||
void
|
||||
etna_shader_init(struct pipe_context *pctx);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,664 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2015 Etnaviv Project
|
||||
*
|
||||
* 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, sub license,
|
||||
* 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 NON-INFRINGEMENT. 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:
|
||||
* Wladimir J. van der Laan <laanwj@gmail.com>
|
||||
* Christian Gmeiner <christian.gmeiner@gmail.com>
|
||||
*/
|
||||
|
||||
#include "etnaviv_state.h"
|
||||
|
||||
#include "hw/common.xml.h"
|
||||
|
||||
#include "etnaviv_clear_blit.h"
|
||||
#include "etnaviv_context.h"
|
||||
#include "etnaviv_format.h"
|
||||
#include "etnaviv_shader.h"
|
||||
#include "etnaviv_surface.h"
|
||||
#include "etnaviv_translate.h"
|
||||
#include "etnaviv_util.h"
|
||||
#include "util/u_helpers.h"
|
||||
#include "util/u_inlines.h"
|
||||
#include "util/u_math.h"
|
||||
#include "util/u_memory.h"
|
||||
|
||||
static void
|
||||
etna_set_blend_color(struct pipe_context *pctx, const struct pipe_blend_color *bc)
|
||||
{
|
||||
struct etna_context *ctx = etna_context(pctx);
|
||||
struct compiled_blend_color *cs = &ctx->blend_color;
|
||||
|
||||
cs->PE_ALPHA_BLEND_COLOR =
|
||||
VIVS_PE_ALPHA_BLEND_COLOR_R(etna_cfloat_to_uint8(bc->color[0])) |
|
||||
VIVS_PE_ALPHA_BLEND_COLOR_G(etna_cfloat_to_uint8(bc->color[1])) |
|
||||
VIVS_PE_ALPHA_BLEND_COLOR_B(etna_cfloat_to_uint8(bc->color[2])) |
|
||||
VIVS_PE_ALPHA_BLEND_COLOR_A(etna_cfloat_to_uint8(bc->color[3]));
|
||||
ctx->dirty |= ETNA_DIRTY_BLEND_COLOR;
|
||||
}
|
||||
|
||||
static void
|
||||
etna_set_stencil_ref(struct pipe_context *pctx, const struct pipe_stencil_ref *sr)
|
||||
{
|
||||
struct etna_context *ctx = etna_context(pctx);
|
||||
struct compiled_stencil_ref *cs = &ctx->stencil_ref;
|
||||
|
||||
ctx->stencil_ref_s = *sr;
|
||||
|
||||
cs->PE_STENCIL_CONFIG = VIVS_PE_STENCIL_CONFIG_REF_FRONT(sr->ref_value[0]);
|
||||
/* rest of bits weaved in from depth_stencil_alpha */
|
||||
cs->PE_STENCIL_CONFIG_EXT =
|
||||
VIVS_PE_STENCIL_CONFIG_EXT_REF_BACK(sr->ref_value[0]);
|
||||
ctx->dirty |= ETNA_DIRTY_STENCIL_REF;
|
||||
}
|
||||
|
||||
static void
|
||||
etna_set_clip_state(struct pipe_context *pctx, const struct pipe_clip_state *pcs)
|
||||
{
|
||||
/* NOOP */
|
||||
}
|
||||
|
||||
static void
|
||||
etna_set_sample_mask(struct pipe_context *pctx, unsigned sample_mask)
|
||||
{
|
||||
struct etna_context *ctx = etna_context(pctx);
|
||||
|
||||
ctx->sample_mask = sample_mask;
|
||||
ctx->dirty |= ETNA_DIRTY_SAMPLE_MASK;
|
||||
}
|
||||
|
||||
static void
|
||||
etna_set_constant_buffer(struct pipe_context *pctx, uint shader, uint index,
|
||||
const struct pipe_constant_buffer *cb)
|
||||
{
|
||||
struct etna_context *ctx = etna_context(pctx);
|
||||
|
||||
if (unlikely(index > 0)) {
|
||||
DBG("Unhandled buffer index %i", index);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
util_copy_constant_buffer(&ctx->constant_buffer[shader], cb);
|
||||
|
||||
/* Note that the state tracker can unbind constant buffers by
|
||||
* passing NULL here. */
|
||||
if (unlikely(!cb))
|
||||
return;
|
||||
|
||||
/* there is no support for ARB_uniform_buffer_object */
|
||||
assert(cb->buffer == NULL && cb->user_buffer != NULL);
|
||||
|
||||
ctx->dirty |= ETNA_DIRTY_CONSTBUF;
|
||||
}
|
||||
|
||||
static void
|
||||
etna_update_render_resource(struct pipe_context *pctx, struct pipe_resource *pres)
|
||||
{
|
||||
struct etna_resource *res = etna_resource(pres);
|
||||
|
||||
if (res->texture && etna_resource_older(res, etna_resource(res->texture))) {
|
||||
/* The render buffer is older than the texture buffer. Copy it over. */
|
||||
etna_copy_resource(pctx, pres, res->texture, 0, pres->last_level);
|
||||
res->seqno = etna_resource(res->texture)->seqno;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
etna_set_framebuffer_state(struct pipe_context *pctx,
|
||||
const struct pipe_framebuffer_state *sv)
|
||||
{
|
||||
struct etna_context *ctx = etna_context(pctx);
|
||||
struct compiled_framebuffer_state *cs = &ctx->framebuffer;
|
||||
int nr_samples_color = -1;
|
||||
int nr_samples_depth = -1;
|
||||
|
||||
/* Set up TS as well. Warning: this state is used by both the RS and PE */
|
||||
uint32_t ts_mem_config = 0;
|
||||
|
||||
if (sv->nr_cbufs > 0) { /* at least one color buffer? */
|
||||
struct etna_surface *cbuf = etna_surface(sv->cbufs[0]);
|
||||
struct etna_resource *res = etna_resource(cbuf->base.texture);
|
||||
bool color_supertiled = (res->layout & ETNA_LAYOUT_BIT_SUPER) != 0;
|
||||
|
||||
assert(res->layout & ETNA_LAYOUT_BIT_TILE); /* Cannot render to linear surfaces */
|
||||
etna_update_render_resource(pctx, cbuf->base.texture);
|
||||
|
||||
pipe_surface_reference(&cs->cbuf, &cbuf->base);
|
||||
cs->PE_COLOR_FORMAT =
|
||||
VIVS_PE_COLOR_FORMAT_FORMAT(translate_rs_format(cbuf->base.format)) |
|
||||
VIVS_PE_COLOR_FORMAT_COMPONENTS__MASK |
|
||||
VIVS_PE_COLOR_FORMAT_OVERWRITE |
|
||||
COND(color_supertiled, VIVS_PE_COLOR_FORMAT_SUPER_TILED);
|
||||
/* VIVS_PE_COLOR_FORMAT_COMPONENTS() and
|
||||
* VIVS_PE_COLOR_FORMAT_OVERWRITE comes from blend_state
|
||||
* but only if we set the bits above. */
|
||||
/* merged with depth_stencil_alpha */
|
||||
if ((cbuf->surf.offset & 63) ||
|
||||
(((cbuf->surf.stride * 4) & 63) && cbuf->surf.height > 4)) {
|
||||
/* XXX Must make temporary surface here.
|
||||
* Need the same mechanism on gc2000 when we want to do mipmap
|
||||
* generation by
|
||||
* rendering to levels > 1 due to multitiled / tiled conversion. */
|
||||
BUG("Alignment error, trying to render to offset %08x with tile "
|
||||
"stride %i",
|
||||
cbuf->surf.offset, cbuf->surf.stride * 4);
|
||||
}
|
||||
|
||||
if (ctx->specs.pixel_pipes == 1) {
|
||||
cs->PE_COLOR_ADDR = cbuf->reloc[0];
|
||||
cs->PE_COLOR_ADDR.flags = ETNA_RELOC_READ | ETNA_RELOC_WRITE;
|
||||
} else {
|
||||
/* Rendered textures must always be multi-tiled */
|
||||
assert(res->layout & ETNA_LAYOUT_BIT_MULTI);
|
||||
for (int i = 0; i < ctx->specs.pixel_pipes; i++) {
|
||||
cs->PE_PIPE_COLOR_ADDR[i] = cbuf->reloc[i];
|
||||
cs->PE_PIPE_COLOR_ADDR[i].flags = ETNA_RELOC_READ | ETNA_RELOC_WRITE;
|
||||
}
|
||||
}
|
||||
cs->PE_COLOR_STRIDE = cbuf->surf.stride;
|
||||
|
||||
if (cbuf->surf.ts_size) {
|
||||
ts_mem_config |= VIVS_TS_MEM_CONFIG_COLOR_FAST_CLEAR;
|
||||
cs->TS_COLOR_CLEAR_VALUE = cbuf->level->clear_value;
|
||||
|
||||
cs->TS_COLOR_STATUS_BASE = cbuf->ts_reloc;
|
||||
cs->TS_COLOR_STATUS_BASE.flags = ETNA_RELOC_READ | ETNA_RELOC_WRITE;
|
||||
|
||||
cs->TS_COLOR_SURFACE_BASE = cbuf->reloc[0];
|
||||
cs->TS_COLOR_SURFACE_BASE.flags = ETNA_RELOC_READ | ETNA_RELOC_WRITE;
|
||||
}
|
||||
|
||||
/* MSAA */
|
||||
if (cbuf->base.texture->nr_samples > 1)
|
||||
ts_mem_config |=
|
||||
VIVS_TS_MEM_CONFIG_MSAA | translate_msaa_format(cbuf->base.format);
|
||||
|
||||
nr_samples_color = cbuf->base.texture->nr_samples;
|
||||
} else {
|
||||
pipe_surface_reference(&cs->cbuf, NULL);
|
||||
/* Clearing VIVS_PE_COLOR_FORMAT_COMPONENTS__MASK and
|
||||
* VIVS_PE_COLOR_FORMAT_OVERWRITE prevents us from overwriting the
|
||||
* color target */
|
||||
cs->PE_COLOR_FORMAT = 0;
|
||||
cs->PE_COLOR_STRIDE = 0;
|
||||
cs->TS_COLOR_STATUS_BASE.bo = NULL;
|
||||
cs->TS_COLOR_SURFACE_BASE.bo = NULL;
|
||||
|
||||
for (int i = 0; i < ETNA_MAX_PIXELPIPES; i++)
|
||||
cs->PE_PIPE_COLOR_ADDR[i].bo = NULL;
|
||||
}
|
||||
|
||||
if (sv->zsbuf != NULL) {
|
||||
struct etna_surface *zsbuf = etna_surface(sv->zsbuf);
|
||||
struct etna_resource *res = etna_resource(zsbuf->base.texture);
|
||||
|
||||
etna_update_render_resource(pctx, zsbuf->base.texture);
|
||||
|
||||
pipe_surface_reference(&cs->zsbuf, &zsbuf->base);
|
||||
assert(res->layout &ETNA_LAYOUT_BIT_TILE); /* Cannot render to linear surfaces */
|
||||
|
||||
uint32_t depth_format = translate_depth_format(zsbuf->base.format);
|
||||
unsigned depth_bits =
|
||||
depth_format == VIVS_PE_DEPTH_CONFIG_DEPTH_FORMAT_D16 ? 16 : 24;
|
||||
bool depth_supertiled = (res->layout & ETNA_LAYOUT_BIT_SUPER) != 0;
|
||||
|
||||
cs->PE_DEPTH_CONFIG =
|
||||
depth_format |
|
||||
COND(depth_supertiled, VIVS_PE_DEPTH_CONFIG_SUPER_TILED) |
|
||||
VIVS_PE_DEPTH_CONFIG_DEPTH_MODE_Z;
|
||||
/* VIVS_PE_DEPTH_CONFIG_ONLY_DEPTH */
|
||||
/* merged with depth_stencil_alpha */
|
||||
|
||||
if (ctx->specs.pixel_pipes == 1) {
|
||||
cs->PE_DEPTH_ADDR = zsbuf->reloc[0];
|
||||
cs->PE_DEPTH_ADDR.flags = ETNA_RELOC_READ | ETNA_RELOC_WRITE;
|
||||
} else {
|
||||
for (int i = 0; i < ctx->specs.pixel_pipes; i++) {
|
||||
cs->PE_PIPE_DEPTH_ADDR[i] = zsbuf->reloc[i];
|
||||
cs->PE_PIPE_DEPTH_ADDR[i].flags = ETNA_RELOC_READ | ETNA_RELOC_WRITE;
|
||||
}
|
||||
}
|
||||
|
||||
cs->PE_DEPTH_STRIDE = zsbuf->surf.stride;
|
||||
cs->PE_HDEPTH_CONTROL = VIVS_PE_HDEPTH_CONTROL_FORMAT_DISABLED;
|
||||
cs->PE_DEPTH_NORMALIZE = fui(exp2f(depth_bits) - 1.0f);
|
||||
|
||||
if (zsbuf->surf.ts_size) {
|
||||
ts_mem_config |= VIVS_TS_MEM_CONFIG_DEPTH_FAST_CLEAR;
|
||||
cs->TS_DEPTH_CLEAR_VALUE = zsbuf->level->clear_value;
|
||||
|
||||
cs->TS_DEPTH_STATUS_BASE = zsbuf->ts_reloc;
|
||||
cs->TS_DEPTH_STATUS_BASE.flags = ETNA_RELOC_READ | ETNA_RELOC_WRITE;
|
||||
|
||||
cs->TS_DEPTH_SURFACE_BASE = zsbuf->reloc[0];
|
||||
cs->TS_DEPTH_SURFACE_BASE.flags = ETNA_RELOC_READ | ETNA_RELOC_WRITE;
|
||||
}
|
||||
|
||||
ts_mem_config |= COND(depth_bits == 16, VIVS_TS_MEM_CONFIG_DEPTH_16BPP);
|
||||
|
||||
/* MSAA */
|
||||
if (zsbuf->base.texture->nr_samples > 1)
|
||||
/* XXX VIVS_TS_MEM_CONFIG_DEPTH_COMPRESSION;
|
||||
* Disable without MSAA for now, as it causes corruption in glquake. */
|
||||
ts_mem_config |= VIVS_TS_MEM_CONFIG_DEPTH_COMPRESSION;
|
||||
|
||||
nr_samples_depth = zsbuf->base.texture->nr_samples;
|
||||
} else {
|
||||
pipe_surface_reference(&cs->zsbuf, NULL);
|
||||
cs->PE_DEPTH_CONFIG = VIVS_PE_DEPTH_CONFIG_DEPTH_MODE_NONE;
|
||||
cs->PE_DEPTH_ADDR.bo = NULL;
|
||||
cs->PE_DEPTH_STRIDE = 0;
|
||||
cs->TS_DEPTH_STATUS_BASE.bo = NULL;
|
||||
cs->TS_DEPTH_SURFACE_BASE.bo = NULL;
|
||||
|
||||
for (int i = 0; i < ETNA_MAX_PIXELPIPES; i++)
|
||||
cs->PE_PIPE_DEPTH_ADDR[i].bo = NULL;
|
||||
}
|
||||
|
||||
/* MSAA setup */
|
||||
if (nr_samples_depth != -1 && nr_samples_color != -1 &&
|
||||
nr_samples_depth != nr_samples_color) {
|
||||
BUG("Number of samples in color and depth texture must match (%i and %i respectively)",
|
||||
nr_samples_color, nr_samples_depth);
|
||||
}
|
||||
|
||||
switch (MAX2(nr_samples_depth, nr_samples_color)) {
|
||||
case 0:
|
||||
case 1: /* Are 0 and 1 samples allowed? */
|
||||
cs->GL_MULTI_SAMPLE_CONFIG =
|
||||
VIVS_GL_MULTI_SAMPLE_CONFIG_MSAA_SAMPLES_NONE;
|
||||
cs->msaa_mode = false;
|
||||
break;
|
||||
case 2:
|
||||
cs->GL_MULTI_SAMPLE_CONFIG = VIVS_GL_MULTI_SAMPLE_CONFIG_MSAA_SAMPLES_2X;
|
||||
cs->msaa_mode = true; /* Add input to PS */
|
||||
cs->RA_MULTISAMPLE_UNK00E04 = 0x0;
|
||||
cs->RA_MULTISAMPLE_UNK00E10[0] = 0x0000aa22;
|
||||
cs->RA_CENTROID_TABLE[0] = 0x66aa2288;
|
||||
cs->RA_CENTROID_TABLE[1] = 0x88558800;
|
||||
cs->RA_CENTROID_TABLE[2] = 0x88881100;
|
||||
cs->RA_CENTROID_TABLE[3] = 0x33888800;
|
||||
break;
|
||||
case 4:
|
||||
cs->GL_MULTI_SAMPLE_CONFIG = VIVS_GL_MULTI_SAMPLE_CONFIG_MSAA_SAMPLES_4X;
|
||||
cs->msaa_mode = true; /* Add input to PS */
|
||||
cs->RA_MULTISAMPLE_UNK00E04 = 0x0;
|
||||
cs->RA_MULTISAMPLE_UNK00E10[0] = 0xeaa26e26;
|
||||
cs->RA_MULTISAMPLE_UNK00E10[1] = 0xe6ae622a;
|
||||
cs->RA_MULTISAMPLE_UNK00E10[2] = 0xaaa22a22;
|
||||
cs->RA_CENTROID_TABLE[0] = 0x4a6e2688;
|
||||
cs->RA_CENTROID_TABLE[1] = 0x888888a2;
|
||||
cs->RA_CENTROID_TABLE[2] = 0x888888ea;
|
||||
cs->RA_CENTROID_TABLE[3] = 0x888888c6;
|
||||
cs->RA_CENTROID_TABLE[4] = 0x46622a88;
|
||||
cs->RA_CENTROID_TABLE[5] = 0x888888ae;
|
||||
cs->RA_CENTROID_TABLE[6] = 0x888888e6;
|
||||
cs->RA_CENTROID_TABLE[7] = 0x888888ca;
|
||||
cs->RA_CENTROID_TABLE[8] = 0x262a2288;
|
||||
cs->RA_CENTROID_TABLE[9] = 0x886688a2;
|
||||
cs->RA_CENTROID_TABLE[10] = 0x888866aa;
|
||||
cs->RA_CENTROID_TABLE[11] = 0x668888a6;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Scissor setup */
|
||||
cs->SE_SCISSOR_LEFT = 0; /* affected by rasterizer and scissor state as well */
|
||||
cs->SE_SCISSOR_TOP = 0;
|
||||
cs->SE_SCISSOR_RIGHT = (sv->width << 16) - 1;
|
||||
cs->SE_SCISSOR_BOTTOM = (sv->height << 16) - 1;
|
||||
|
||||
cs->TS_MEM_CONFIG = ts_mem_config;
|
||||
|
||||
ctx->framebuffer_s = *sv; /* keep copy of original structure */
|
||||
ctx->dirty |= ETNA_DIRTY_FRAMEBUFFER;
|
||||
}
|
||||
|
||||
static void
|
||||
etna_set_polygon_stipple(struct pipe_context *pctx,
|
||||
const struct pipe_poly_stipple *stipple)
|
||||
{
|
||||
/* NOP */
|
||||
}
|
||||
|
||||
static void
|
||||
etna_set_scissor_states(struct pipe_context *pctx, unsigned start_slot,
|
||||
unsigned num_scissors, const struct pipe_scissor_state *ss)
|
||||
{
|
||||
struct etna_context *ctx = etna_context(pctx);
|
||||
struct compiled_scissor_state *cs = &ctx->scissor;
|
||||
|
||||
/* note that this state is only used when rasterizer_state->scissor is on */
|
||||
ctx->scissor_s = *ss;
|
||||
cs->SE_SCISSOR_LEFT = (ss->minx << 16);
|
||||
cs->SE_SCISSOR_TOP = (ss->miny << 16);
|
||||
cs->SE_SCISSOR_RIGHT = (ss->maxx << 16) - 1;
|
||||
cs->SE_SCISSOR_BOTTOM = (ss->maxy << 16) - 1;
|
||||
|
||||
ctx->dirty |= ETNA_DIRTY_SCISSOR;
|
||||
}
|
||||
|
||||
static void
|
||||
etna_set_viewport_states(struct pipe_context *pctx, unsigned start_slot,
|
||||
unsigned num_scissors, const struct pipe_viewport_state *vs)
|
||||
{
|
||||
struct etna_context *ctx = etna_context(pctx);
|
||||
struct compiled_viewport_state *cs = &ctx->viewport;
|
||||
|
||||
ctx->viewport_s = *vs;
|
||||
/**
|
||||
* For Vivante GPU, viewport z transformation is 0..1 to 0..1 instead of
|
||||
* -1..1 to 0..1.
|
||||
* scaling and translation to 0..1 already happened, so remove that
|
||||
*
|
||||
* z' = (z * 2 - 1) * scale + translate
|
||||
* = z * (2 * scale) + (translate - scale)
|
||||
*
|
||||
* scale' = 2 * scale
|
||||
* translate' = translate - scale
|
||||
*/
|
||||
|
||||
/* must be fixp as v4 state deltas assume it is */
|
||||
cs->PA_VIEWPORT_SCALE_X = etna_f32_to_fixp16(vs->scale[0]);
|
||||
cs->PA_VIEWPORT_SCALE_Y = etna_f32_to_fixp16(vs->scale[1]);
|
||||
cs->PA_VIEWPORT_SCALE_Z = fui(vs->scale[2] * 2.0f);
|
||||
cs->PA_VIEWPORT_OFFSET_X = etna_f32_to_fixp16(vs->translate[0]);
|
||||
cs->PA_VIEWPORT_OFFSET_Y = etna_f32_to_fixp16(vs->translate[1]);
|
||||
cs->PA_VIEWPORT_OFFSET_Z = fui(vs->translate[2] - vs->scale[2]);
|
||||
|
||||
/* Compute scissor rectangle (fixp) from viewport.
|
||||
* Make sure left is always < right and top always < bottom.
|
||||
*/
|
||||
cs->SE_SCISSOR_LEFT = etna_f32_to_fixp16(MAX2(vs->translate[0] - vs->scale[0], 0.0f));
|
||||
cs->SE_SCISSOR_TOP = etna_f32_to_fixp16(MAX2(vs->translate[1] - vs->scale[1], 0.0f));
|
||||
cs->SE_SCISSOR_RIGHT = etna_f32_to_fixp16(MAX2(vs->translate[0] + vs->scale[0], 0.0f));
|
||||
cs->SE_SCISSOR_BOTTOM = etna_f32_to_fixp16(MAX2(vs->translate[1] + vs->scale[1], 0.0f));
|
||||
|
||||
if (cs->SE_SCISSOR_LEFT > cs->SE_SCISSOR_RIGHT) {
|
||||
uint32_t tmp = cs->SE_SCISSOR_RIGHT;
|
||||
cs->SE_SCISSOR_RIGHT = cs->SE_SCISSOR_LEFT;
|
||||
cs->SE_SCISSOR_LEFT = tmp;
|
||||
}
|
||||
|
||||
if (cs->SE_SCISSOR_TOP > cs->SE_SCISSOR_BOTTOM) {
|
||||
uint32_t tmp = cs->SE_SCISSOR_BOTTOM;
|
||||
cs->SE_SCISSOR_BOTTOM = cs->SE_SCISSOR_TOP;
|
||||
cs->SE_SCISSOR_TOP = tmp;
|
||||
}
|
||||
|
||||
cs->PE_DEPTH_NEAR = fui(0.0); /* not affected if depth mode is Z (as in GL) */
|
||||
cs->PE_DEPTH_FAR = fui(1.0);
|
||||
ctx->dirty |= ETNA_DIRTY_VIEWPORT;
|
||||
}
|
||||
|
||||
static void
|
||||
etna_set_vertex_buffers(struct pipe_context *pctx, unsigned start_slot,
|
||||
unsigned num_buffers, const struct pipe_vertex_buffer *vb)
|
||||
{
|
||||
struct etna_context *ctx = etna_context(pctx);
|
||||
struct etna_vertexbuf_state *so = &ctx->vertex_buffer;
|
||||
|
||||
util_set_vertex_buffers_mask(so->vb, &so->enabled_mask, vb, start_slot, num_buffers);
|
||||
so->count = util_last_bit(so->enabled_mask);
|
||||
|
||||
for (unsigned idx = start_slot; idx < start_slot + num_buffers; ++idx) {
|
||||
struct compiled_set_vertex_buffer *cs = &so->cvb[idx];
|
||||
struct pipe_vertex_buffer *vbi = &so->vb[idx];
|
||||
|
||||
assert(!vbi->user_buffer); /* XXX support user_buffer using
|
||||
etna_usermem_map */
|
||||
|
||||
if (vbi->buffer) { /* GPU buffer */
|
||||
cs->FE_VERTEX_STREAM_BASE_ADDR.bo = etna_resource(vbi->buffer)->bo;
|
||||
cs->FE_VERTEX_STREAM_BASE_ADDR.offset = vbi->buffer_offset;
|
||||
cs->FE_VERTEX_STREAM_BASE_ADDR.flags = ETNA_RELOC_READ;
|
||||
cs->FE_VERTEX_STREAM_CONTROL =
|
||||
FE_VERTEX_STREAM_CONTROL_VERTEX_STRIDE(vbi->stride);
|
||||
} else {
|
||||
cs->FE_VERTEX_STREAM_BASE_ADDR.bo = NULL;
|
||||
cs->FE_VERTEX_STREAM_CONTROL = 0;
|
||||
}
|
||||
}
|
||||
|
||||
ctx->dirty |= ETNA_DIRTY_VERTEX_BUFFERS;
|
||||
}
|
||||
|
||||
static void
|
||||
etna_set_index_buffer(struct pipe_context *pctx, const struct pipe_index_buffer *ib)
|
||||
{
|
||||
struct etna_context *ctx = etna_context(pctx);
|
||||
uint32_t ctrl;
|
||||
|
||||
if (ib) {
|
||||
pipe_resource_reference(&ctx->index_buffer.ib.buffer, ib->buffer);
|
||||
memcpy(&ctx->index_buffer.ib, ib, sizeof(ctx->index_buffer.ib));
|
||||
ctrl = translate_index_size(ctx->index_buffer.ib.index_size);
|
||||
} else {
|
||||
pipe_resource_reference(&ctx->index_buffer.ib.buffer, NULL);
|
||||
ctrl = 0;
|
||||
}
|
||||
|
||||
if (ctx->index_buffer.ib.buffer && ctrl != ETNA_NO_MATCH) {
|
||||
ctx->index_buffer.FE_INDEX_STREAM_BASE_ADDR.bo = etna_resource(ctx->index_buffer.ib.buffer)->bo;
|
||||
ctx->index_buffer.FE_INDEX_STREAM_BASE_ADDR.offset = ctx->index_buffer.ib.offset;
|
||||
ctx->index_buffer.FE_INDEX_STREAM_BASE_ADDR.flags = ETNA_RELOC_READ;
|
||||
ctx->index_buffer.FE_INDEX_STREAM_CONTROL = ctrl;
|
||||
} else {
|
||||
ctx->index_buffer.FE_INDEX_STREAM_BASE_ADDR.bo = NULL;
|
||||
ctx->index_buffer.FE_INDEX_STREAM_CONTROL = 0;
|
||||
}
|
||||
|
||||
ctx->dirty |= ETNA_DIRTY_INDEX_BUFFER;
|
||||
}
|
||||
|
||||
static void
|
||||
etna_blend_state_bind(struct pipe_context *pctx, void *bs)
|
||||
{
|
||||
struct etna_context *ctx = etna_context(pctx);
|
||||
|
||||
ctx->blend = bs;
|
||||
ctx->dirty |= ETNA_DIRTY_BLEND;
|
||||
}
|
||||
|
||||
static void
|
||||
etna_blend_state_delete(struct pipe_context *pctx, void *bs)
|
||||
{
|
||||
FREE(bs);
|
||||
}
|
||||
|
||||
static void
|
||||
etna_rasterizer_state_bind(struct pipe_context *pctx, void *rs)
|
||||
{
|
||||
struct etna_context *ctx = etna_context(pctx);
|
||||
|
||||
ctx->rasterizer = rs;
|
||||
ctx->dirty |= ETNA_DIRTY_RASTERIZER;
|
||||
}
|
||||
|
||||
static void
|
||||
etna_rasterizer_state_delete(struct pipe_context *pctx, void *rs)
|
||||
{
|
||||
FREE(rs);
|
||||
}
|
||||
|
||||
static void
|
||||
etna_zsa_state_bind(struct pipe_context *pctx, void *zs)
|
||||
{
|
||||
struct etna_context *ctx = etna_context(pctx);
|
||||
|
||||
ctx->zsa = zs;
|
||||
ctx->dirty |= ETNA_DIRTY_ZSA;
|
||||
}
|
||||
|
||||
static void
|
||||
etna_zsa_state_delete(struct pipe_context *pctx, void *zs)
|
||||
{
|
||||
FREE(zs);
|
||||
}
|
||||
|
||||
/** Create vertex element states, which define a layout for fetching
|
||||
* vertices for rendering.
|
||||
*/
|
||||
static void *
|
||||
etna_vertex_elements_state_create(struct pipe_context *pctx,
|
||||
unsigned num_elements, const struct pipe_vertex_element *elements)
|
||||
{
|
||||
struct etna_context *ctx = etna_context(pctx);
|
||||
struct compiled_vertex_elements_state *cs = CALLOC_STRUCT(compiled_vertex_elements_state);
|
||||
|
||||
if (!cs)
|
||||
return NULL;
|
||||
|
||||
if (num_elements > ctx->specs.vertex_max_elements) {
|
||||
BUG("number of elements (%u) exceeds chip maximum (%u)", num_elements,
|
||||
ctx->specs.vertex_max_elements);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* XXX could minimize number of consecutive stretches here by sorting, and
|
||||
* permuting the inputs in shader or does Mesa do this already? */
|
||||
|
||||
/* Check that vertex element binding is compatible with hardware; thus
|
||||
* elements[idx].vertex_buffer_index are < stream_count. If not, the binding
|
||||
* uses more streams than is supported, and u_vbuf should have done some
|
||||
* reorganization for compatibility. */
|
||||
|
||||
/* TODO: does mesa this for us? */
|
||||
bool incompatible = false;
|
||||
for (unsigned idx = 0; idx < num_elements; ++idx) {
|
||||
if (elements[idx].vertex_buffer_index >= ctx->specs.stream_count || elements[idx].instance_divisor > 0)
|
||||
incompatible = true;
|
||||
}
|
||||
|
||||
cs->num_elements = num_elements;
|
||||
if (incompatible || num_elements == 0) {
|
||||
DBG("Error: zero vertex elements, or more vertex buffers used than supported");
|
||||
FREE(cs);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
unsigned start_offset = 0; /* start of current consecutive stretch */
|
||||
bool nonconsecutive = true; /* previous value of nonconsecutive */
|
||||
|
||||
for (unsigned idx = 0; idx < num_elements; ++idx) {
|
||||
unsigned element_size = util_format_get_blocksize(elements[idx].src_format);
|
||||
unsigned end_offset = elements[idx].src_offset + element_size;
|
||||
uint32_t format_type, normalize;
|
||||
|
||||
if (nonconsecutive)
|
||||
start_offset = elements[idx].src_offset;
|
||||
|
||||
/* maximum vertex size is 256 bytes */
|
||||
assert(element_size != 0 && end_offset <= 256);
|
||||
|
||||
/* check whether next element is consecutive to this one */
|
||||
nonconsecutive = (idx == (num_elements - 1)) ||
|
||||
elements[idx + 1].vertex_buffer_index != elements[idx].vertex_buffer_index ||
|
||||
end_offset != elements[idx + 1].src_offset;
|
||||
|
||||
format_type = translate_vertex_format_type(elements[idx].src_format);
|
||||
normalize = translate_vertex_format_normalize(elements[idx].src_format);
|
||||
|
||||
assert(format_type != ETNA_NO_MATCH);
|
||||
assert(normalize != ETNA_NO_MATCH);
|
||||
|
||||
cs->FE_VERTEX_ELEMENT_CONFIG[idx] =
|
||||
COND(nonconsecutive, VIVS_FE_VERTEX_ELEMENT_CONFIG_NONCONSECUTIVE) |
|
||||
format_type |
|
||||
VIVS_FE_VERTEX_ELEMENT_CONFIG_NUM(util_format_get_nr_components(elements[idx].src_format)) |
|
||||
normalize | VIVS_FE_VERTEX_ELEMENT_CONFIG_ENDIAN(ENDIAN_MODE_NO_SWAP) |
|
||||
VIVS_FE_VERTEX_ELEMENT_CONFIG_STREAM(elements[idx].vertex_buffer_index) |
|
||||
VIVS_FE_VERTEX_ELEMENT_CONFIG_START(elements[idx].src_offset) |
|
||||
VIVS_FE_VERTEX_ELEMENT_CONFIG_END(end_offset - start_offset);
|
||||
}
|
||||
|
||||
return cs;
|
||||
}
|
||||
|
||||
static void
|
||||
etna_vertex_elements_state_delete(struct pipe_context *pctx, void *ve)
|
||||
{
|
||||
FREE(ve);
|
||||
}
|
||||
|
||||
static void
|
||||
etna_vertex_elements_state_bind(struct pipe_context *pctx, void *ve)
|
||||
{
|
||||
struct etna_context *ctx = etna_context(pctx);
|
||||
|
||||
ctx->vertex_elements = ve;
|
||||
ctx->dirty |= ETNA_DIRTY_VERTEX_ELEMENTS;
|
||||
}
|
||||
|
||||
struct etna_state_updater {
|
||||
bool (*update)(struct etna_context *ctx);
|
||||
uint32_t dirty;
|
||||
};
|
||||
|
||||
static const struct etna_state_updater etna_state_updates[] = {
|
||||
{
|
||||
etna_shader_update_vertex, ETNA_DIRTY_SHADER | ETNA_DIRTY_VERTEX_ELEMENTS,
|
||||
},
|
||||
{
|
||||
etna_shader_link, ETNA_DIRTY_SHADER,
|
||||
}
|
||||
};
|
||||
|
||||
bool
|
||||
etna_state_update(struct etna_context *ctx)
|
||||
{
|
||||
for (unsigned int i = 0; i < ARRAY_SIZE(etna_state_updates); i++)
|
||||
if (ctx->dirty & etna_state_updates[i].dirty)
|
||||
if (!etna_state_updates[i].update(ctx))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
etna_state_init(struct pipe_context *pctx)
|
||||
{
|
||||
pctx->set_blend_color = etna_set_blend_color;
|
||||
pctx->set_stencil_ref = etna_set_stencil_ref;
|
||||
pctx->set_clip_state = etna_set_clip_state;
|
||||
pctx->set_sample_mask = etna_set_sample_mask;
|
||||
pctx->set_constant_buffer = etna_set_constant_buffer;
|
||||
pctx->set_framebuffer_state = etna_set_framebuffer_state;
|
||||
pctx->set_polygon_stipple = etna_set_polygon_stipple;
|
||||
pctx->set_scissor_states = etna_set_scissor_states;
|
||||
pctx->set_viewport_states = etna_set_viewport_states;
|
||||
|
||||
pctx->set_vertex_buffers = etna_set_vertex_buffers;
|
||||
pctx->set_index_buffer = etna_set_index_buffer;
|
||||
|
||||
pctx->bind_blend_state = etna_blend_state_bind;
|
||||
pctx->delete_blend_state = etna_blend_state_delete;
|
||||
|
||||
pctx->bind_rasterizer_state = etna_rasterizer_state_bind;
|
||||
pctx->delete_rasterizer_state = etna_rasterizer_state_delete;
|
||||
|
||||
pctx->bind_depth_stencil_alpha_state = etna_zsa_state_bind;
|
||||
pctx->delete_depth_stencil_alpha_state = etna_zsa_state_delete;
|
||||
|
||||
pctx->create_vertex_elements_state = etna_vertex_elements_state_create;
|
||||
pctx->delete_vertex_elements_state = etna_vertex_elements_state_delete;
|
||||
pctx->bind_vertex_elements_state = etna_vertex_elements_state_bind;
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2015 Etnaviv Project
|
||||
*
|
||||
* 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, sub license,
|
||||
* 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 NON-INFRINGEMENT. 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:
|
||||
* Wladimir J. van der Laan <laanwj@gmail.com>
|
||||
* Christian Gmeiner <christian.gmeiner@gmail.com>
|
||||
*/
|
||||
|
||||
#ifndef ETNAVIV_STATE_H_
|
||||
#define ETNAVIV_STATE_H_
|
||||
|
||||
#include "etnaviv_context.h"
|
||||
#include "pipe/p_context.h"
|
||||
|
||||
static inline bool
|
||||
etna_depth_enabled(struct etna_context *ctx)
|
||||
{
|
||||
return ctx->zsa && ctx->zsa->depth.enabled;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
etna_stencil_enabled(struct etna_context *ctx)
|
||||
{
|
||||
return ctx->zsa && ctx->zsa->stencil[0].enabled;
|
||||
}
|
||||
|
||||
bool
|
||||
etna_state_update(struct etna_context *ctx);
|
||||
|
||||
void
|
||||
etna_state_init(struct pipe_context *pctx);
|
||||
|
||||
#endif /* ETNAVIV_STATE_H_ */
|
|
@ -0,0 +1,152 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2013 Etnaviv Project
|
||||
*
|
||||
* 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, sub license,
|
||||
* 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 NON-INFRINGEMENT. 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:
|
||||
* Wladimir J. van der Laan <laanwj@gmail.com>
|
||||
*/
|
||||
|
||||
#include "etnaviv_surface.h"
|
||||
#include "etnaviv_screen.h"
|
||||
|
||||
#include "etnaviv_clear_blit.h"
|
||||
#include "etnaviv_context.h"
|
||||
#include "etnaviv_translate.h"
|
||||
#include "pipe/p_defines.h"
|
||||
#include "pipe/p_state.h"
|
||||
#include "util/u_inlines.h"
|
||||
#include "util/u_memory.h"
|
||||
|
||||
#include "hw/common.xml.h"
|
||||
|
||||
static struct pipe_surface *
|
||||
etna_create_surface(struct pipe_context *pctx, struct pipe_resource *prsc,
|
||||
const struct pipe_surface *templat)
|
||||
{
|
||||
struct etna_context *ctx = etna_context(pctx);
|
||||
struct etna_resource *rsc = etna_resource(prsc);
|
||||
struct etna_surface *surf = CALLOC_STRUCT(etna_surface);
|
||||
|
||||
if (!surf)
|
||||
return NULL;
|
||||
|
||||
assert(templat->u.tex.first_layer == templat->u.tex.last_layer);
|
||||
unsigned layer = templat->u.tex.first_layer;
|
||||
unsigned level = templat->u.tex.level;
|
||||
assert(layer < rsc->base.array_size);
|
||||
|
||||
surf->base.context = pctx;
|
||||
|
||||
pipe_reference_init(&surf->base.reference, 1);
|
||||
pipe_resource_reference(&surf->base.texture, &rsc->base);
|
||||
|
||||
/* Allocate a TS for the resource if there isn't one yet,
|
||||
* and it is allowed by the hw (width is a multiple of 16).
|
||||
* Avoid doing this for GPUs with MC1.0, as kernel sources
|
||||
* indicate the tile status module bypasses the memory
|
||||
* offset and MMU. */
|
||||
|
||||
/* XXX for now, don't do TS for render textures as this path
|
||||
* is not stable. */
|
||||
if (VIV_FEATURE(ctx->screen, chipFeatures, FAST_CLEAR) &&
|
||||
VIV_FEATURE(ctx->screen, chipMinorFeatures0, MC20) &&
|
||||
!DBG_ENABLED(ETNA_DBG_NO_TS) && !rsc->ts_bo &&
|
||||
!(rsc->base.bind & (PIPE_BIND_SAMPLER_VIEW)) &&
|
||||
(rsc->levels[level].padded_width & ETNA_RS_WIDTH_MASK) == 0 &&
|
||||
(rsc->levels[level].padded_height & ETNA_RS_HEIGHT_MASK) == 0) {
|
||||
etna_screen_resource_alloc_ts(pctx->screen, rsc);
|
||||
}
|
||||
|
||||
surf->base.texture = &rsc->base;
|
||||
surf->base.format = rsc->base.format;
|
||||
surf->base.width = rsc->levels[level].width;
|
||||
surf->base.height = rsc->levels[level].height;
|
||||
surf->base.writable = templat->writable; /* what is this for anyway */
|
||||
surf->base.u = templat->u;
|
||||
|
||||
surf->level = &rsc->levels[level]; /* Keep pointer to actual level to set
|
||||
* clear color on underlying resource
|
||||
* instead of surface */
|
||||
surf->surf = rsc->levels [level]; /* Make copy of level to narrow down
|
||||
* address to layer */
|
||||
|
||||
/* XXX we don't really need a copy but it's convenient */
|
||||
surf->surf.offset += layer * surf->surf.layer_stride;
|
||||
|
||||
struct etna_resource_level *lev = &rsc->levels[level];
|
||||
|
||||
/* Setup template relocations for this surface */
|
||||
surf->reloc[0].bo = rsc->bo;
|
||||
surf->reloc[0].offset = surf->surf.offset;
|
||||
surf->reloc[0].flags = 0;
|
||||
surf->reloc[1].bo = rsc->bo;
|
||||
surf->reloc[1].offset = surf->surf.offset + lev->stride * lev->padded_height / 2;
|
||||
surf->reloc[1].flags = 0;
|
||||
|
||||
if (surf->surf.ts_size) {
|
||||
unsigned int layer_offset = layer * surf->surf.ts_layer_stride;
|
||||
assert(layer_offset < surf->surf.ts_size);
|
||||
|
||||
surf->surf.ts_offset += layer_offset;
|
||||
surf->surf.ts_size -= layer_offset;
|
||||
|
||||
surf->ts_reloc.bo = rsc->ts_bo;
|
||||
surf->ts_reloc.offset = surf->surf.ts_offset;
|
||||
surf->ts_reloc.flags = 0;
|
||||
|
||||
/* This (ab)uses the RS as a plain buffer memset().
|
||||
* Currently uses a fixed row size of 64 bytes. Some benchmarking with
|
||||
* different sizes may be in order. */
|
||||
struct etna_bo *ts_bo = etna_resource(surf->base.texture)->ts_bo;
|
||||
etna_compile_rs_state(ctx, &surf->clear_command, &(struct rs_state) {
|
||||
.source_format = RS_FORMAT_A8R8G8B8,
|
||||
.dest_format = RS_FORMAT_A8R8G8B8,
|
||||
.dest = ts_bo,
|
||||
.dest_offset = surf->surf.ts_offset,
|
||||
.dest_stride = 0x40,
|
||||
.dest_tiling = ETNA_LAYOUT_TILED,
|
||||
.dither = {0xffffffff, 0xffffffff},
|
||||
.width = 16,
|
||||
.height = etna_align_up(surf->surf.ts_size / 0x40, 4),
|
||||
.clear_value = {ctx->specs.ts_clear_value},
|
||||
.clear_mode = VIVS_RS_CLEAR_CONTROL_MODE_ENABLED1,
|
||||
.clear_bits = 0xffff
|
||||
});
|
||||
} else {
|
||||
etna_rs_gen_clear_surface(ctx, surf, surf->level->clear_value);
|
||||
}
|
||||
|
||||
return &surf->base;
|
||||
}
|
||||
|
||||
static void
|
||||
etna_surface_destroy(struct pipe_context *pctx, struct pipe_surface *psurf)
|
||||
{
|
||||
pipe_resource_reference(&psurf->texture, NULL);
|
||||
FREE(psurf);
|
||||
}
|
||||
|
||||
void
|
||||
etna_surface_init(struct pipe_context *pctx)
|
||||
{
|
||||
pctx->create_surface = etna_create_surface;
|
||||
pctx->surface_destroy = etna_surface_destroy;
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2015 Etnaviv Project
|
||||
*
|
||||
* 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, sub license,
|
||||
* 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 NON-INFRINGEMENT. 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:
|
||||
* Wladimir J. van der Laan <laanwj@gmail.com>
|
||||
*/
|
||||
|
||||
#ifndef H_ETNAVIV_SURFACE
|
||||
#define H_ETNAVIV_SURFACE
|
||||
|
||||
#include "etnaviv_resource.h"
|
||||
#include "etnaviv_rs.h"
|
||||
#include "etnaviv_tiling.h"
|
||||
#include "pipe/p_state.h"
|
||||
|
||||
struct etna_surface {
|
||||
struct pipe_surface base;
|
||||
|
||||
struct etna_resource_level surf;
|
||||
struct compiled_rs_state clear_command;
|
||||
/* Keep pointer to resource level, for fast clear */
|
||||
struct etna_resource_level *level;
|
||||
struct etna_reloc reloc[ETNA_MAX_PIXELPIPES];
|
||||
struct etna_reloc ts_reloc;
|
||||
};
|
||||
|
||||
static inline struct etna_surface *
|
||||
etna_surface(struct pipe_surface *p)
|
||||
{
|
||||
return (struct etna_surface *)p;
|
||||
}
|
||||
|
||||
void
|
||||
etna_surface_init(struct pipe_context *pctx);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,338 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2015 Etnaviv Project
|
||||
*
|
||||
* 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, sub license,
|
||||
* 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 NON-INFRINGEMENT. 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:
|
||||
* Wladimir J. van der Laan <laanwj@gmail.com>
|
||||
*/
|
||||
|
||||
#include "etnaviv_texture.h"
|
||||
|
||||
#include "hw/common.xml.h"
|
||||
|
||||
#include "etnaviv_clear_blit.h"
|
||||
#include "etnaviv_context.h"
|
||||
#include "etnaviv_emit.h"
|
||||
#include "etnaviv_format.h"
|
||||
#include "etnaviv_translate.h"
|
||||
#include "util/u_inlines.h"
|
||||
#include "util/u_memory.h"
|
||||
|
||||
static void *
|
||||
etna_create_sampler_state(struct pipe_context *pipe,
|
||||
const struct pipe_sampler_state *ss)
|
||||
{
|
||||
struct etna_sampler_state *cs = CALLOC_STRUCT(etna_sampler_state);
|
||||
|
||||
if (!cs)
|
||||
return NULL;
|
||||
|
||||
cs->TE_SAMPLER_CONFIG0 =
|
||||
VIVS_TE_SAMPLER_CONFIG0_UWRAP(translate_texture_wrapmode(ss->wrap_s)) |
|
||||
VIVS_TE_SAMPLER_CONFIG0_VWRAP(translate_texture_wrapmode(ss->wrap_t)) |
|
||||
VIVS_TE_SAMPLER_CONFIG0_MIN(translate_texture_filter(ss->min_img_filter)) |
|
||||
VIVS_TE_SAMPLER_CONFIG0_MIP(translate_texture_mipfilter(ss->min_mip_filter)) |
|
||||
VIVS_TE_SAMPLER_CONFIG0_MAG(translate_texture_filter(ss->mag_img_filter)) |
|
||||
COND(ss->normalized_coords, VIVS_TE_SAMPLER_CONFIG0_ROUND_UV);
|
||||
cs->TE_SAMPLER_CONFIG1 = 0; /* VIVS_TE_SAMPLER_CONFIG1 (swizzle, extended
|
||||
format) fully determined by sampler view */
|
||||
cs->TE_SAMPLER_LOD_CONFIG =
|
||||
COND(ss->lod_bias != 0.0, VIVS_TE_SAMPLER_LOD_CONFIG_BIAS_ENABLE) |
|
||||
VIVS_TE_SAMPLER_LOD_CONFIG_BIAS(etna_float_to_fixp55(ss->lod_bias));
|
||||
|
||||
if (ss->min_mip_filter != PIPE_TEX_MIPFILTER_NONE) {
|
||||
cs->min_lod = etna_float_to_fixp55(ss->min_lod);
|
||||
cs->max_lod = etna_float_to_fixp55(ss->max_lod);
|
||||
} else {
|
||||
/* when not mipmapping, we need to set max/min lod so that always
|
||||
* lowest LOD is selected */
|
||||
cs->min_lod = cs->max_lod = etna_float_to_fixp55(ss->min_lod);
|
||||
}
|
||||
|
||||
return cs;
|
||||
}
|
||||
|
||||
static void
|
||||
etna_bind_sampler_states(struct pipe_context *pctx, unsigned shader,
|
||||
unsigned start_slot, unsigned num_samplers,
|
||||
void **samplers)
|
||||
{
|
||||
/* bind fragment sampler */
|
||||
struct etna_context *ctx = etna_context(pctx);
|
||||
int offset;
|
||||
|
||||
switch (shader) {
|
||||
case PIPE_SHADER_FRAGMENT:
|
||||
offset = 0;
|
||||
ctx->num_fragment_samplers = num_samplers;
|
||||
break;
|
||||
case PIPE_SHADER_VERTEX:
|
||||
offset = ctx->specs.vertex_sampler_offset;
|
||||
break;
|
||||
default:
|
||||
assert(!"Invalid shader");
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t mask = 1 << offset;
|
||||
for (int idx = 0; idx < num_samplers; ++idx, mask <<= 1) {
|
||||
ctx->sampler[offset + idx] = samplers[idx];
|
||||
if (samplers[idx])
|
||||
ctx->active_samplers |= mask;
|
||||
else
|
||||
ctx->active_samplers &= ~mask;
|
||||
}
|
||||
|
||||
ctx->dirty |= ETNA_DIRTY_SAMPLERS;
|
||||
}
|
||||
|
||||
static void
|
||||
etna_delete_sampler_state(struct pipe_context *pctx, void *ss)
|
||||
{
|
||||
FREE(ss);
|
||||
}
|
||||
|
||||
static void
|
||||
etna_update_sampler_source(struct pipe_sampler_view *view)
|
||||
{
|
||||
struct etna_resource *res = etna_resource(view->texture);
|
||||
|
||||
if (res->texture && etna_resource_older(etna_resource(res->texture), res)) {
|
||||
/* Texture is older than render buffer, copy the texture using RS */
|
||||
etna_copy_resource(view->context, res->texture, view->texture, 0,
|
||||
view->texture->last_level);
|
||||
etna_resource(res->texture)->seqno = res->seqno;
|
||||
}
|
||||
}
|
||||
|
||||
static bool
|
||||
etna_resource_sampler_compatible(struct etna_resource *res)
|
||||
{
|
||||
if (util_format_is_compressed(res->base.format))
|
||||
return true;
|
||||
|
||||
/* The sampler (as we currently know it) only accepts tiled layouts */
|
||||
if (res->layout != ETNA_LAYOUT_TILED)
|
||||
return false;
|
||||
|
||||
/* If we have HALIGN support, we can allow for the RS padding */
|
||||
struct etna_screen *screen = etna_screen(res->base.screen);
|
||||
if (VIV_FEATURE(screen, chipMinorFeatures1, TEXTURE_HALIGN))
|
||||
return true;
|
||||
|
||||
/* Non-HALIGN GPUs only accept 4x4 tile-aligned textures */
|
||||
if (res->halign != TEXTURE_HALIGN_FOUR)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static struct pipe_sampler_view *
|
||||
etna_create_sampler_view(struct pipe_context *pctx, struct pipe_resource *prsc,
|
||||
const struct pipe_sampler_view *so)
|
||||
{
|
||||
struct etna_sampler_view *sv = CALLOC_STRUCT(etna_sampler_view);
|
||||
struct etna_resource *res = etna_resource(prsc);
|
||||
struct etna_context *ctx = etna_context(pctx);
|
||||
|
||||
if (!sv)
|
||||
return NULL;
|
||||
|
||||
if (!etna_resource_sampler_compatible(res)) {
|
||||
/* The original resource is not compatible with the sampler.
|
||||
* Allocate an appropriately tiled texture. */
|
||||
if (!res->texture) {
|
||||
struct pipe_resource templat = *prsc;
|
||||
|
||||
templat.bind &= ~(PIPE_BIND_DEPTH_STENCIL | PIPE_BIND_RENDER_TARGET |
|
||||
PIPE_BIND_BLENDABLE);
|
||||
res->texture =
|
||||
etna_resource_alloc(pctx->screen, ETNA_LAYOUT_TILED, &templat);
|
||||
}
|
||||
|
||||
if (!res->texture) {
|
||||
free(sv);
|
||||
return NULL;
|
||||
}
|
||||
res = etna_resource(res->texture);
|
||||
}
|
||||
|
||||
sv->base = *so;
|
||||
pipe_reference(NULL, &prsc->reference);
|
||||
sv->base.texture = prsc;
|
||||
sv->base.reference.count = 1;
|
||||
sv->base.context = pctx;
|
||||
|
||||
/* merged with sampler state */
|
||||
sv->TE_SAMPLER_CONFIG0 =
|
||||
VIVS_TE_SAMPLER_CONFIG0_FORMAT(translate_texture_format(sv->base.format));
|
||||
sv->TE_SAMPLER_CONFIG0_MASK = 0xffffffff;
|
||||
|
||||
switch (sv->base.target) {
|
||||
case PIPE_TEXTURE_1D:
|
||||
/* For 1D textures, we will have a height of 1, so we can use 2D
|
||||
* but set T wrap to repeat */
|
||||
sv->TE_SAMPLER_CONFIG0_MASK = ~VIVS_TE_SAMPLER_CONFIG0_VWRAP__MASK;
|
||||
sv->TE_SAMPLER_CONFIG0 |= VIVS_TE_SAMPLER_CONFIG0_VWRAP(TEXTURE_WRAPMODE_REPEAT);
|
||||
case PIPE_TEXTURE_2D:
|
||||
case PIPE_TEXTURE_RECT:
|
||||
sv->TE_SAMPLER_CONFIG0 |= VIVS_TE_SAMPLER_CONFIG0_TYPE(TEXTURE_TYPE_2D);
|
||||
break;
|
||||
case PIPE_TEXTURE_CUBE:
|
||||
sv->TE_SAMPLER_CONFIG0 |= VIVS_TE_SAMPLER_CONFIG0_TYPE(TEXTURE_TYPE_CUBE_MAP);
|
||||
break;
|
||||
default:
|
||||
BUG("Unhandled texture target");
|
||||
free(sv);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
sv->TE_SAMPLER_CONFIG1 = VIVS_TE_SAMPLER_CONFIG1_SWIZZLE_R(so->swizzle_r) |
|
||||
VIVS_TE_SAMPLER_CONFIG1_SWIZZLE_G(so->swizzle_g) |
|
||||
VIVS_TE_SAMPLER_CONFIG1_SWIZZLE_B(so->swizzle_b) |
|
||||
VIVS_TE_SAMPLER_CONFIG1_SWIZZLE_A(so->swizzle_a) |
|
||||
VIVS_TE_SAMPLER_CONFIG1_HALIGN(res->halign);
|
||||
sv->TE_SAMPLER_SIZE = VIVS_TE_SAMPLER_SIZE_WIDTH(res->base.width0) |
|
||||
VIVS_TE_SAMPLER_SIZE_HEIGHT(res->base.height0);
|
||||
sv->TE_SAMPLER_LOG_SIZE =
|
||||
VIVS_TE_SAMPLER_LOG_SIZE_WIDTH(etna_log2_fixp55(res->base.width0)) |
|
||||
VIVS_TE_SAMPLER_LOG_SIZE_HEIGHT(etna_log2_fixp55(res->base.height0));
|
||||
|
||||
/* Set up levels-of-detail */
|
||||
for (int lod = 0; lod <= res->base.last_level; ++lod) {
|
||||
sv->TE_SAMPLER_LOD_ADDR[lod].bo = res->bo;
|
||||
sv->TE_SAMPLER_LOD_ADDR[lod].offset = res->levels[lod].offset;
|
||||
sv->TE_SAMPLER_LOD_ADDR[lod].flags = ETNA_RELOC_READ;
|
||||
}
|
||||
sv->min_lod = sv->base.u.tex.first_level << 5;
|
||||
sv->max_lod = MIN2(sv->base.u.tex.last_level, res->base.last_level) << 5;
|
||||
|
||||
/* Workaround for npot textures -- it appears that only CLAMP_TO_EDGE is
|
||||
* supported when the appropriate capability is not set. */
|
||||
if (!ctx->specs.npot_tex_any_wrap &&
|
||||
(!util_is_power_of_two(res->base.width0) || !util_is_power_of_two(res->base.height0))) {
|
||||
sv->TE_SAMPLER_CONFIG0_MASK = ~(VIVS_TE_SAMPLER_CONFIG0_UWRAP__MASK |
|
||||
VIVS_TE_SAMPLER_CONFIG0_VWRAP__MASK);
|
||||
sv->TE_SAMPLER_CONFIG0 |=
|
||||
VIVS_TE_SAMPLER_CONFIG0_UWRAP(TEXTURE_WRAPMODE_CLAMP_TO_EDGE) |
|
||||
VIVS_TE_SAMPLER_CONFIG0_VWRAP(TEXTURE_WRAPMODE_CLAMP_TO_EDGE);
|
||||
}
|
||||
|
||||
return &sv->base;
|
||||
}
|
||||
|
||||
static void
|
||||
etna_sampler_view_destroy(struct pipe_context *pctx,
|
||||
struct pipe_sampler_view *view)
|
||||
{
|
||||
pipe_resource_reference(&view->texture, NULL);
|
||||
FREE(view);
|
||||
}
|
||||
|
||||
static void
|
||||
set_sampler_views(struct etna_context *ctx, unsigned start, unsigned end,
|
||||
unsigned nr, struct pipe_sampler_view **views)
|
||||
{
|
||||
unsigned i, j;
|
||||
uint32_t mask = 1 << start;
|
||||
|
||||
for (i = start, j = 0; j < nr; i++, j++, mask <<= 1) {
|
||||
pipe_sampler_view_reference(&ctx->sampler_view[i], views[j]);
|
||||
if (views[j])
|
||||
ctx->active_sampler_views |= mask;
|
||||
else
|
||||
ctx->active_sampler_views &= ~mask;
|
||||
}
|
||||
|
||||
for (; i < end; i++, mask <<= 1) {
|
||||
pipe_sampler_view_reference(&ctx->sampler_view[i], NULL);
|
||||
ctx->active_sampler_views &= ~mask;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
etna_fragtex_set_sampler_views(struct etna_context *ctx, unsigned nr,
|
||||
struct pipe_sampler_view **views)
|
||||
{
|
||||
unsigned start = 0;
|
||||
unsigned end = start + ctx->specs.fragment_sampler_count;
|
||||
|
||||
set_sampler_views(ctx, start, end, nr, views);
|
||||
ctx->num_fragment_sampler_views = nr;
|
||||
}
|
||||
|
||||
|
||||
static inline void
|
||||
etna_vertex_set_sampler_views(struct etna_context *ctx, unsigned nr,
|
||||
struct pipe_sampler_view **views)
|
||||
{
|
||||
unsigned start = ctx->specs.vertex_sampler_offset;
|
||||
unsigned end = start + ctx->specs.vertex_sampler_count;
|
||||
|
||||
set_sampler_views(ctx, start, end, nr, views);
|
||||
}
|
||||
|
||||
static void
|
||||
etna_set_sampler_views(struct pipe_context *pctx, unsigned shader,
|
||||
unsigned start_slot, unsigned num_views,
|
||||
struct pipe_sampler_view **views)
|
||||
{
|
||||
struct etna_context *ctx = etna_context(pctx);
|
||||
assert(start_slot == 0);
|
||||
|
||||
ctx->dirty |= ETNA_DIRTY_SAMPLER_VIEWS | ETNA_DIRTY_TEXTURE_CACHES;
|
||||
|
||||
for (unsigned idx = 0; idx < num_views; ++idx) {
|
||||
if (views[idx])
|
||||
etna_update_sampler_source(views[idx]);
|
||||
}
|
||||
|
||||
switch (shader) {
|
||||
case PIPE_SHADER_FRAGMENT:
|
||||
etna_fragtex_set_sampler_views(ctx, num_views, views);
|
||||
break;
|
||||
case PIPE_SHADER_VERTEX:
|
||||
etna_vertex_set_sampler_views(ctx, num_views, views);
|
||||
break;
|
||||
default:;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
etna_texture_barrier(struct pipe_context *pctx)
|
||||
{
|
||||
struct etna_context *ctx = etna_context(pctx);
|
||||
/* clear color and texture cache to make sure that texture unit reads
|
||||
* what has been written */
|
||||
etna_set_state(ctx->stream, VIVS_GL_FLUSH_CACHE, VIVS_GL_FLUSH_CACHE_COLOR | VIVS_GL_FLUSH_CACHE_TEXTURE);
|
||||
}
|
||||
|
||||
void
|
||||
etna_texture_init(struct pipe_context *pctx)
|
||||
{
|
||||
pctx->create_sampler_state = etna_create_sampler_state;
|
||||
pctx->bind_sampler_states = etna_bind_sampler_states;
|
||||
pctx->delete_sampler_state = etna_delete_sampler_state;
|
||||
pctx->set_sampler_views = etna_set_sampler_views;
|
||||
pctx->create_sampler_view = etna_create_sampler_view;
|
||||
pctx->sampler_view_destroy = etna_sampler_view_destroy;
|
||||
pctx->texture_barrier = etna_texture_barrier;
|
||||
}
|
|
@ -0,0 +1,75 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2015 Etnaviv Project
|
||||
*
|
||||
* 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, sub license,
|
||||
* 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 NON-INFRINGEMENT. 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:
|
||||
* Wladimir J. van der Laan <laanwj@gmail.com>
|
||||
*/
|
||||
|
||||
#ifndef H_ETNAVIV_TEXTURE
|
||||
#define H_ETNAVIV_TEXTURE
|
||||
|
||||
#include <etnaviv_drmif.h>
|
||||
|
||||
#include "pipe/p_context.h"
|
||||
#include "pipe/p_state.h"
|
||||
|
||||
#include "hw/state_3d.xml.h"
|
||||
|
||||
struct etna_sampler_state {
|
||||
struct pipe_sampler_state base;
|
||||
|
||||
/* sampler offset +4*sampler, interleave when committing state */
|
||||
uint32_t TE_SAMPLER_CONFIG0;
|
||||
uint32_t TE_SAMPLER_CONFIG1;
|
||||
uint32_t TE_SAMPLER_LOD_CONFIG;
|
||||
unsigned min_lod, max_lod;
|
||||
};
|
||||
|
||||
static inline struct etna_sampler_state *
|
||||
etna_sampler_state(struct pipe_sampler_state *samp)
|
||||
{
|
||||
return (struct etna_sampler_state *)samp;
|
||||
}
|
||||
|
||||
struct etna_sampler_view {
|
||||
struct pipe_sampler_view base;
|
||||
|
||||
/* sampler offset +4*sampler, interleave when committing state */
|
||||
uint32_t TE_SAMPLER_CONFIG0;
|
||||
uint32_t TE_SAMPLER_CONFIG0_MASK;
|
||||
uint32_t TE_SAMPLER_CONFIG1;
|
||||
uint32_t TE_SAMPLER_SIZE;
|
||||
uint32_t TE_SAMPLER_LOG_SIZE;
|
||||
struct etna_reloc TE_SAMPLER_LOD_ADDR[VIVS_TE_SAMPLER_LOD_ADDR__LEN];
|
||||
unsigned min_lod, max_lod; /* 5.5 fixp */
|
||||
};
|
||||
|
||||
static inline struct etna_sampler_view *
|
||||
etna_sampler_view(struct pipe_sampler_view *view)
|
||||
{
|
||||
return (struct etna_sampler_view *)view;
|
||||
}
|
||||
|
||||
void
|
||||
etna_texture_init(struct pipe_context *pctx);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,96 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2015 Etnaviv Project
|
||||
*
|
||||
* 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, sub license,
|
||||
* 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 NON-INFRINGEMENT. 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:
|
||||
* Wladimir J. van der Laan <laanwj@gmail.com>
|
||||
*/
|
||||
|
||||
#include "etnaviv_tiling.h"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#define TEX_TILE_WIDTH (4)
|
||||
#define TEX_TILE_HEIGHT (4)
|
||||
#define TEX_TILE_WORDS (TEX_TILE_WIDTH * TEX_TILE_HEIGHT)
|
||||
|
||||
#define DO_TILE(type) \
|
||||
src_stride /= sizeof(type); \
|
||||
dst_stride = (dst_stride * TEX_TILE_HEIGHT) / sizeof(type); \
|
||||
for (unsigned srcy = 0; srcy < height; ++srcy) { \
|
||||
unsigned dsty = basey + srcy; \
|
||||
unsigned ty = (dsty / TEX_TILE_HEIGHT) * dst_stride + \
|
||||
(dsty % TEX_TILE_HEIGHT) * TEX_TILE_WIDTH; \
|
||||
for (unsigned srcx = 0; srcx < width; ++srcx) { \
|
||||
unsigned dstx = basex + srcx; \
|
||||
((type *)dest)[ty + (dstx / TEX_TILE_WIDTH) * TEX_TILE_WORDS + \
|
||||
(dstx % TEX_TILE_WIDTH)] = \
|
||||
((type *)src)[srcy * src_stride + srcx]; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define DO_UNTILE(type) \
|
||||
src_stride = (src_stride * TEX_TILE_HEIGHT) / sizeof(type); \
|
||||
dst_stride /= sizeof(type); \
|
||||
for (unsigned dsty = 0; dsty < height; ++dsty) { \
|
||||
unsigned srcy = basey + dsty; \
|
||||
unsigned sy = (srcy / TEX_TILE_HEIGHT) * src_stride + \
|
||||
(srcy % TEX_TILE_HEIGHT) * TEX_TILE_WIDTH; \
|
||||
for (unsigned dstx = 0; dstx < width; ++dstx) { \
|
||||
unsigned srcx = basex + dstx; \
|
||||
((type *)dest)[dsty * dst_stride + dstx] = \
|
||||
((type *)src)[sy + (srcx / TEX_TILE_WIDTH) * TEX_TILE_WORDS + \
|
||||
(srcx % TEX_TILE_WIDTH)]; \
|
||||
} \
|
||||
}
|
||||
|
||||
void
|
||||
etna_texture_tile(void *dest, void *src, unsigned basex, unsigned basey,
|
||||
unsigned dst_stride, unsigned width, unsigned height,
|
||||
unsigned src_stride, unsigned elmtsize)
|
||||
{
|
||||
if (elmtsize == 4) {
|
||||
DO_TILE(uint32_t)
|
||||
} else if (elmtsize == 2) {
|
||||
DO_TILE(uint16_t)
|
||||
} else if (elmtsize == 1) {
|
||||
DO_TILE(uint8_t)
|
||||
} else {
|
||||
printf("etna_texture_tile: unhandled element size %i\n", elmtsize);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
etna_texture_untile(void *dest, void *src, unsigned basex, unsigned basey,
|
||||
unsigned src_stride, unsigned width, unsigned height,
|
||||
unsigned dst_stride, unsigned elmtsize)
|
||||
{
|
||||
if (elmtsize == 4) {
|
||||
DO_UNTILE(uint32_t);
|
||||
} else if (elmtsize == 2) {
|
||||
DO_UNTILE(uint16_t);
|
||||
} else if (elmtsize == 1) {
|
||||
DO_UNTILE(uint8_t);
|
||||
} else {
|
||||
printf("etna_texture_tile: unhandled element size %i\n", elmtsize);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2015 Etnaviv Project
|
||||
*
|
||||
* 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, sub license,
|
||||
* 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 NON-INFRINGEMENT. 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:
|
||||
* Wladimir J. van der Laan <laanwj@gmail.com>
|
||||
*/
|
||||
|
||||
#ifndef H_ETNAVIV_TILING
|
||||
#define H_ETNAVIV_TILING
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/* texture or surface layout */
|
||||
enum etna_surface_layout {
|
||||
ETNA_LAYOUT_BIT_TILE = (1 << 0),
|
||||
ETNA_LAYOUT_BIT_SUPER = (1 << 1),
|
||||
ETNA_LAYOUT_BIT_MULTI = (1 << 2),
|
||||
ETNA_LAYOUT_LINEAR = 0,
|
||||
ETNA_LAYOUT_TILED = ETNA_LAYOUT_BIT_TILE,
|
||||
ETNA_LAYOUT_SUPER_TILED = ETNA_LAYOUT_BIT_TILE | ETNA_LAYOUT_BIT_SUPER,
|
||||
ETNA_LAYOUT_MULTI_TILED = ETNA_LAYOUT_BIT_TILE | ETNA_LAYOUT_BIT_MULTI,
|
||||
ETNA_LAYOUT_MULTI_SUPERTILED = ETNA_LAYOUT_BIT_TILE | ETNA_LAYOUT_BIT_SUPER | ETNA_LAYOUT_BIT_MULTI,
|
||||
};
|
||||
|
||||
void
|
||||
etna_texture_tile(void *dest, void *src, unsigned basex, unsigned basey,
|
||||
unsigned dst_stride, unsigned width, unsigned height,
|
||||
unsigned src_stride, unsigned elmtsize);
|
||||
void
|
||||
etna_texture_untile(void *dest, void *src, unsigned basex, unsigned basey,
|
||||
unsigned src_stride, unsigned width, unsigned height,
|
||||
unsigned dst_stride, unsigned elmtsize);
|
||||
|
||||
/* XXX from/to supertiling (can have different layouts, may be better
|
||||
* to leave to RS) */
|
||||
|
||||
#endif
|
|
@ -0,0 +1,355 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2015 Etnaviv Project
|
||||
*
|
||||
* 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, sub license,
|
||||
* 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 NON-INFRINGEMENT. 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:
|
||||
* Wladimir J. van der Laan <laanwj@gmail.com>
|
||||
*/
|
||||
|
||||
#include "etnaviv_transfer.h"
|
||||
#include "etnaviv_clear_blit.h"
|
||||
#include "etnaviv_context.h"
|
||||
#include "etnaviv_debug.h"
|
||||
|
||||
#include "pipe/p_defines.h"
|
||||
#include "pipe/p_format.h"
|
||||
#include "pipe/p_screen.h"
|
||||
#include "pipe/p_state.h"
|
||||
#include "util/u_format.h"
|
||||
#include "util/u_inlines.h"
|
||||
#include "util/u_memory.h"
|
||||
#include "util/u_surface.h"
|
||||
#include "util/u_transfer.h"
|
||||
|
||||
/* Compute offset into a 1D/2D/3D buffer of a certain box.
|
||||
* This box must be aligned to the block width and height of the
|
||||
* underlying format. */
|
||||
static inline size_t
|
||||
etna_compute_offset(enum pipe_format format, const struct pipe_box *box,
|
||||
size_t stride, size_t layer_stride)
|
||||
{
|
||||
return box->z * layer_stride +
|
||||
box->y / util_format_get_blockheight(format) * stride +
|
||||
box->x / util_format_get_blockwidth(format) *
|
||||
util_format_get_blocksize(format);
|
||||
}
|
||||
|
||||
static void
|
||||
etna_transfer_unmap(struct pipe_context *pctx, struct pipe_transfer *ptrans)
|
||||
{
|
||||
struct etna_context *ctx = etna_context(pctx);
|
||||
struct etna_transfer *trans = etna_transfer(ptrans);
|
||||
struct etna_resource *rsc = etna_resource(ptrans->resource);
|
||||
|
||||
/* XXX
|
||||
* When writing to a resource that is already in use, replace the resource
|
||||
* with a completely new buffer
|
||||
* and free the old one using a fenced free.
|
||||
* The most tricky case to implement will be: tiled or supertiled surface,
|
||||
* partial write, target not aligned to 4/64. */
|
||||
assert(ptrans->level <= rsc->base.last_level);
|
||||
|
||||
if (rsc->texture && !etna_resource_newer(rsc, etna_resource(rsc->texture)))
|
||||
rsc = etna_resource(rsc->texture); /* switch to using the texture resource */
|
||||
|
||||
if (ptrans->usage & PIPE_TRANSFER_WRITE) {
|
||||
if (trans->rsc) {
|
||||
/* We have a temporary resource due to either tile status or
|
||||
* tiling format. Write back the updated buffer contents.
|
||||
* FIXME: we need to invalidate the tile status. */
|
||||
etna_copy_resource(pctx, ptrans->resource, trans->rsc, ptrans->level,
|
||||
trans->rsc->last_level);
|
||||
} else if (trans->staging) {
|
||||
/* map buffer object */
|
||||
struct etna_resource_level *res_level = &rsc->levels[ptrans->level];
|
||||
void *mapped = etna_bo_map(rsc->bo) + res_level->offset;
|
||||
|
||||
if (rsc->layout == ETNA_LAYOUT_LINEAR || rsc->layout == ETNA_LAYOUT_TILED) {
|
||||
if (rsc->layout == ETNA_LAYOUT_TILED && !util_format_is_compressed(rsc->base.format)) {
|
||||
etna_texture_tile(
|
||||
mapped + ptrans->box.z * res_level->layer_stride,
|
||||
trans->staging, ptrans->box.x, ptrans->box.y,
|
||||
res_level->stride, ptrans->box.width, ptrans->box.height,
|
||||
ptrans->stride, util_format_get_blocksize(rsc->base.format));
|
||||
} else { /* non-tiled or compressed format */
|
||||
util_copy_box(mapped, rsc->base.format, res_level->stride,
|
||||
res_level->layer_stride, ptrans->box.x,
|
||||
ptrans->box.y, ptrans->box.z, ptrans->box.width,
|
||||
ptrans->box.height, ptrans->box.depth,
|
||||
trans->staging, ptrans->stride,
|
||||
ptrans->layer_stride, 0, 0, 0 /* src x,y,z */);
|
||||
}
|
||||
} else {
|
||||
BUG("unsupported tiling %i", rsc->layout);
|
||||
}
|
||||
|
||||
FREE(trans->staging);
|
||||
}
|
||||
|
||||
rsc->seqno++;
|
||||
etna_bo_cpu_fini(rsc->bo);
|
||||
|
||||
if (rsc->base.bind & PIPE_BIND_SAMPLER_VIEW) {
|
||||
/* XXX do we need to flush the CPU cache too or start a write barrier
|
||||
* to make sure the GPU sees it? */
|
||||
ctx->dirty |= ETNA_DIRTY_TEXTURE_CACHES;
|
||||
}
|
||||
}
|
||||
|
||||
pipe_resource_reference(&trans->rsc, NULL);
|
||||
pipe_resource_reference(&ptrans->resource, NULL);
|
||||
slab_free(&ctx->transfer_pool, trans);
|
||||
}
|
||||
|
||||
static void *
|
||||
etna_transfer_map(struct pipe_context *pctx, struct pipe_resource *prsc,
|
||||
unsigned level,
|
||||
unsigned usage,
|
||||
const struct pipe_box *box,
|
||||
struct pipe_transfer **out_transfer)
|
||||
{
|
||||
struct etna_context *ctx = etna_context(pctx);
|
||||
struct etna_resource *rsc = etna_resource(prsc);
|
||||
struct etna_transfer *trans;
|
||||
struct pipe_transfer *ptrans;
|
||||
enum pipe_format format = prsc->format;
|
||||
|
||||
trans = slab_alloc(&ctx->transfer_pool);
|
||||
if (!trans)
|
||||
return NULL;
|
||||
|
||||
/* slab_alloc() doesn't zero */
|
||||
memset(trans, 0, sizeof(*trans));
|
||||
|
||||
ptrans = &trans->base;
|
||||
pipe_resource_reference(&ptrans->resource, prsc);
|
||||
ptrans->level = level;
|
||||
ptrans->usage = usage;
|
||||
ptrans->box = *box;
|
||||
|
||||
assert(level <= prsc->last_level);
|
||||
|
||||
if (rsc->texture && !etna_resource_newer(rsc, etna_resource(rsc->texture))) {
|
||||
/* We have a texture resource which is the same age or newer than the
|
||||
* render resource. Use the texture resource, which avoids bouncing
|
||||
* pixels between the two resources, and we can de-tile it in s/w. */
|
||||
rsc = etna_resource(rsc->texture);
|
||||
} else if (rsc->ts_bo ||
|
||||
(rsc->layout != ETNA_LAYOUT_LINEAR &&
|
||||
util_format_get_blocksize(format) > 1 &&
|
||||
/* HALIGN 4 resources are incompatible with the resolve engine,
|
||||
* so fall back to using software to detile this resource. */
|
||||
rsc->halign != TEXTURE_HALIGN_FOUR)) {
|
||||
/* If the surface has tile status, we need to resolve it first.
|
||||
* The strategy we implement here is to use the RS to copy the
|
||||
* depth buffer, filling in the "holes" where the tile status
|
||||
* indicates that it's clear. We also do this for tiled
|
||||
* resources, but only if the RS can blit them. */
|
||||
if (usage & PIPE_TRANSFER_MAP_DIRECTLY) {
|
||||
slab_free(&ctx->transfer_pool, trans);
|
||||
BUG("unsupported transfer flags %#x with tile status/tiled layout", usage);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (prsc->depth0 > 1) {
|
||||
slab_free(&ctx->transfer_pool, trans);
|
||||
BUG("resource has depth >1 with tile status");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct pipe_resource templ = *prsc;
|
||||
templ.nr_samples = 0;
|
||||
templ.bind = PIPE_BIND_RENDER_TARGET;
|
||||
|
||||
trans->rsc = etna_resource_alloc(pctx->screen, ETNA_LAYOUT_LINEAR, &templ);
|
||||
if (!trans->rsc) {
|
||||
slab_free(&ctx->transfer_pool, trans);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
etna_copy_resource(pctx, trans->rsc, prsc, level, trans->rsc->last_level);
|
||||
|
||||
/* Switch to using the temporary resource instead */
|
||||
rsc = etna_resource(trans->rsc);
|
||||
}
|
||||
|
||||
struct etna_resource_level *res_level = &rsc->levels[level];
|
||||
|
||||
/* Always sync if we have the temporary resource. The PIPE_TRANSFER_READ
|
||||
* case could be optimised if we knew whether the resource has outstanding
|
||||
* rendering. */
|
||||
if (usage & PIPE_TRANSFER_READ || trans->rsc)
|
||||
etna_resource_wait(pctx, rsc);
|
||||
|
||||
/* XXX we don't handle PIPE_TRANSFER_FLUSH_EXPLICIT; this flag can be ignored
|
||||
* when mapping in-place,
|
||||
* but when not in place we need to fire off the copy operation in
|
||||
* transfer_flush_region (currently
|
||||
* a no-op) instead of unmap. Need to handle this to support
|
||||
* ARB_map_buffer_range extension at least.
|
||||
*/
|
||||
/* XXX we don't take care of current operations on the resource; which can
|
||||
be, at some point in the pipeline
|
||||
which is not yet executed:
|
||||
|
||||
- bound as surface
|
||||
- bound through vertex buffer
|
||||
- bound through index buffer
|
||||
- bound in sampler view
|
||||
- used in clear_render_target / clear_depth_stencil operation
|
||||
- used in blit
|
||||
- used in resource_copy_region
|
||||
|
||||
How do other drivers record this information over course of the rendering
|
||||
pipeline?
|
||||
Is it necessary at all? Only in case we want to provide a fast path and
|
||||
map the resource directly
|
||||
(and for PIPE_TRANSFER_MAP_DIRECTLY) and we don't want to force a sync.
|
||||
We also need to know whether the resource is in use to determine if a sync
|
||||
is needed (or just do it
|
||||
always, but that comes at the expense of performance).
|
||||
|
||||
A conservative approximation without too much overhead would be to mark
|
||||
all resources that have
|
||||
been bound at some point as busy. A drawback would be that accessing
|
||||
resources that have
|
||||
been bound but are no longer in use for a while still carry a performance
|
||||
penalty. On the other hand,
|
||||
the program could be using PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE or
|
||||
PIPE_TRANSFER_UNSYNCHRONIZED to
|
||||
avoid this in the first place...
|
||||
|
||||
A) We use an in-pipe copy engine, and queue the copy operation after unmap
|
||||
so that the copy
|
||||
will be performed when all current commands have been executed.
|
||||
Using the RS is possible, not sure if always efficient. This can also
|
||||
do any kind of tiling for us.
|
||||
Only possible when PIPE_TRANSFER_DISCARD_RANGE is set.
|
||||
B) We discard the entire resource (or at least, the mipmap level) and
|
||||
allocate new memory for it.
|
||||
Only possible when mapping the entire resource or
|
||||
PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE is set.
|
||||
*/
|
||||
|
||||
/* No need to allocate a buffer for copying if the resource is not in use,
|
||||
* and no tiling is needed, can just return a direct pointer.
|
||||
*/
|
||||
bool in_place = rsc->layout == ETNA_LAYOUT_LINEAR ||
|
||||
(rsc->layout == ETNA_LAYOUT_TILED &&
|
||||
util_format_is_compressed(prsc->format));
|
||||
|
||||
/* Ignore PIPE_TRANSFER_UNSYNCHRONIZED and PIPE_TRANSFER_DONTBLOCK here.
|
||||
* It appears that Gallium operates the index/vertex buffers in a
|
||||
* circular fashion, and the CPU can catch up with the GPU and starts
|
||||
* overwriting yet-to-be-processed entries, causing rendering corruption. */
|
||||
uint32_t prep_flags = 0;
|
||||
|
||||
if (usage & PIPE_TRANSFER_READ)
|
||||
prep_flags |= DRM_ETNA_PREP_READ;
|
||||
if (usage & PIPE_TRANSFER_WRITE)
|
||||
prep_flags |= DRM_ETNA_PREP_WRITE;
|
||||
|
||||
if (etna_bo_cpu_prep(rsc->bo, prep_flags))
|
||||
goto fail_prep;
|
||||
|
||||
/* map buffer object */
|
||||
void *mapped = etna_bo_map(rsc->bo);
|
||||
if (!mapped)
|
||||
goto fail;
|
||||
|
||||
*out_transfer = ptrans;
|
||||
|
||||
if (in_place) {
|
||||
ptrans->stride = res_level->stride;
|
||||
ptrans->layer_stride = res_level->layer_stride;
|
||||
|
||||
return mapped + res_level->offset +
|
||||
etna_compute_offset(prsc->format, box, res_level->stride,
|
||||
res_level->layer_stride);
|
||||
} else {
|
||||
unsigned divSizeX = util_format_get_blockwidth(format);
|
||||
unsigned divSizeY = util_format_get_blockheight(format);
|
||||
|
||||
/* No direct mappings of tiled, since we need to manually
|
||||
* tile/untile.
|
||||
*/
|
||||
if (usage & PIPE_TRANSFER_MAP_DIRECTLY)
|
||||
goto fail;
|
||||
|
||||
mapped += res_level->offset;
|
||||
ptrans->stride = align(box->width, divSizeX) * util_format_get_blocksize(format); /* row stride in bytes */
|
||||
ptrans->layer_stride = align(box->height, divSizeY) * ptrans->stride;
|
||||
size_t size = ptrans->layer_stride * box->depth;
|
||||
|
||||
trans->staging = MALLOC(size);
|
||||
if (!trans->staging)
|
||||
goto fail;
|
||||
|
||||
if (usage & PIPE_TRANSFER_READ) {
|
||||
/* untile or copy resource for reading */
|
||||
if (rsc->layout == ETNA_LAYOUT_LINEAR || rsc->layout == ETNA_LAYOUT_TILED) {
|
||||
if (rsc->layout == ETNA_LAYOUT_TILED && !util_format_is_compressed(rsc->base.format)) {
|
||||
etna_texture_untile(trans->staging,
|
||||
mapped + ptrans->box.z * res_level->layer_stride,
|
||||
ptrans->box.x, ptrans->box.y, res_level->stride,
|
||||
ptrans->box.width, ptrans->box.height, ptrans->stride,
|
||||
util_format_get_blocksize(rsc->base.format));
|
||||
} else { /* non-tiled or compressed format */
|
||||
util_copy_box(trans->staging, rsc->base.format, ptrans->stride,
|
||||
ptrans->layer_stride, 0, 0, 0, /* dst x,y,z */
|
||||
ptrans->box.width, ptrans->box.height,
|
||||
ptrans->box.depth, mapped, res_level->stride,
|
||||
res_level->layer_stride, ptrans->box.x,
|
||||
ptrans->box.y, ptrans->box.z);
|
||||
}
|
||||
} else /* TODO supertiling */
|
||||
{
|
||||
BUG("unsupported tiling %i for reading", rsc->layout);
|
||||
}
|
||||
}
|
||||
|
||||
return trans->staging;
|
||||
}
|
||||
|
||||
fail:
|
||||
etna_bo_cpu_fini(rsc->bo);
|
||||
fail_prep:
|
||||
etna_transfer_unmap(pctx, ptrans);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
etna_transfer_flush_region(struct pipe_context *pctx,
|
||||
struct pipe_transfer *transfer,
|
||||
const struct pipe_box *box)
|
||||
{
|
||||
/* NOOP for now */
|
||||
}
|
||||
|
||||
void
|
||||
etna_transfer_init(struct pipe_context *pctx)
|
||||
{
|
||||
pctx->transfer_map = etna_transfer_map;
|
||||
pctx->transfer_flush_region = etna_transfer_flush_region;
|
||||
pctx->transfer_unmap = etna_transfer_unmap;
|
||||
pctx->buffer_subdata = u_default_buffer_subdata;
|
||||
pctx->texture_subdata = u_default_texture_subdata;
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2015 Etnaviv Project
|
||||
*
|
||||
* 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, sub license,
|
||||
* 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 NON-INFRINGEMENT. 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:
|
||||
* Wladimir J. van der Laan <laanwj@gmail.com>
|
||||
*/
|
||||
|
||||
#ifndef H_ETNAVIV_TRANSFER
|
||||
#define H_ETNAVIV_TRANSFER
|
||||
|
||||
#include "pipe/p_state.h"
|
||||
|
||||
void
|
||||
etna_transfer_init(struct pipe_context *pctx);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,516 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2013 Etnaviv Project
|
||||
*
|
||||
* 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, sub license,
|
||||
* 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 NON-INFRINGEMENT. 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.
|
||||
*/
|
||||
/* inlined translation functions between gallium and vivante */
|
||||
#ifndef H_TRANSLATE
|
||||
#define H_TRANSLATE
|
||||
|
||||
#include "pipe/p_defines.h"
|
||||
#include "pipe/p_format.h"
|
||||
#include "pipe/p_state.h"
|
||||
|
||||
#include "etnaviv_debug.h"
|
||||
#include "etnaviv_format.h"
|
||||
#include "etnaviv_tiling.h"
|
||||
#include "etnaviv_util.h"
|
||||
#include "hw/cmdstream.xml.h"
|
||||
#include "hw/state.xml.h"
|
||||
#include "hw/state_3d.xml.h"
|
||||
|
||||
#include "util/u_format.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
/* Returned when there is no match of pipe value to etna value */
|
||||
#define ETNA_NO_MATCH (~0)
|
||||
|
||||
static inline uint32_t
|
||||
translate_cull_face(unsigned cull_face, unsigned front_ccw)
|
||||
{
|
||||
switch (cull_face) {
|
||||
case PIPE_FACE_NONE:
|
||||
return VIVS_PA_CONFIG_CULL_FACE_MODE_OFF;
|
||||
case PIPE_FACE_BACK:
|
||||
return front_ccw ? VIVS_PA_CONFIG_CULL_FACE_MODE_CW
|
||||
: VIVS_PA_CONFIG_CULL_FACE_MODE_CCW;
|
||||
case PIPE_FACE_FRONT:
|
||||
return front_ccw ? VIVS_PA_CONFIG_CULL_FACE_MODE_CCW
|
||||
: VIVS_PA_CONFIG_CULL_FACE_MODE_CW;
|
||||
default:
|
||||
DBG("Unhandled cull face mode %i", cull_face);
|
||||
return ETNA_NO_MATCH;
|
||||
}
|
||||
}
|
||||
|
||||
static inline uint32_t
|
||||
translate_polygon_mode(unsigned polygon_mode)
|
||||
{
|
||||
switch (polygon_mode) {
|
||||
case PIPE_POLYGON_MODE_FILL:
|
||||
return VIVS_PA_CONFIG_FILL_MODE_SOLID;
|
||||
case PIPE_POLYGON_MODE_LINE:
|
||||
return VIVS_PA_CONFIG_FILL_MODE_WIREFRAME;
|
||||
case PIPE_POLYGON_MODE_POINT:
|
||||
return VIVS_PA_CONFIG_FILL_MODE_POINT;
|
||||
default:
|
||||
DBG("Unhandled polygon mode %i", polygon_mode);
|
||||
return ETNA_NO_MATCH;
|
||||
}
|
||||
}
|
||||
|
||||
static inline uint32_t
|
||||
translate_stencil_mode(bool enable_0, bool enable_1)
|
||||
{
|
||||
if (enable_0) {
|
||||
return enable_1 ? VIVS_PE_STENCIL_CONFIG_MODE_TWO_SIDED
|
||||
: VIVS_PE_STENCIL_CONFIG_MODE_ONE_SIDED;
|
||||
} else {
|
||||
return VIVS_PE_STENCIL_CONFIG_MODE_DISABLED;
|
||||
}
|
||||
}
|
||||
|
||||
static inline uint32_t
|
||||
translate_stencil_op(unsigned stencil_op)
|
||||
{
|
||||
switch (stencil_op) {
|
||||
case PIPE_STENCIL_OP_KEEP:
|
||||
return STENCIL_OP_KEEP;
|
||||
case PIPE_STENCIL_OP_ZERO:
|
||||
return STENCIL_OP_ZERO;
|
||||
case PIPE_STENCIL_OP_REPLACE:
|
||||
return STENCIL_OP_REPLACE;
|
||||
case PIPE_STENCIL_OP_INCR:
|
||||
return STENCIL_OP_INCR;
|
||||
case PIPE_STENCIL_OP_DECR:
|
||||
return STENCIL_OP_DECR;
|
||||
case PIPE_STENCIL_OP_INCR_WRAP:
|
||||
return STENCIL_OP_INCR_WRAP;
|
||||
case PIPE_STENCIL_OP_DECR_WRAP:
|
||||
return STENCIL_OP_DECR_WRAP;
|
||||
case PIPE_STENCIL_OP_INVERT:
|
||||
return STENCIL_OP_INVERT;
|
||||
default:
|
||||
DBG("Unhandled stencil op: %i", stencil_op);
|
||||
return ETNA_NO_MATCH;
|
||||
}
|
||||
}
|
||||
|
||||
static inline uint32_t
|
||||
translate_blend(unsigned blend)
|
||||
{
|
||||
switch (blend) {
|
||||
case PIPE_BLEND_ADD:
|
||||
return BLEND_EQ_ADD;
|
||||
case PIPE_BLEND_SUBTRACT:
|
||||
return BLEND_EQ_SUBTRACT;
|
||||
case PIPE_BLEND_REVERSE_SUBTRACT:
|
||||
return BLEND_EQ_REVERSE_SUBTRACT;
|
||||
case PIPE_BLEND_MIN:
|
||||
return BLEND_EQ_MIN;
|
||||
case PIPE_BLEND_MAX:
|
||||
return BLEND_EQ_MAX;
|
||||
default:
|
||||
DBG("Unhandled blend: %i", blend);
|
||||
return ETNA_NO_MATCH;
|
||||
}
|
||||
}
|
||||
|
||||
static inline uint32_t
|
||||
translate_blend_factor(unsigned blend_factor)
|
||||
{
|
||||
switch (blend_factor) {
|
||||
case PIPE_BLENDFACTOR_ONE:
|
||||
return BLEND_FUNC_ONE;
|
||||
case PIPE_BLENDFACTOR_SRC_COLOR:
|
||||
return BLEND_FUNC_SRC_COLOR;
|
||||
case PIPE_BLENDFACTOR_SRC_ALPHA:
|
||||
return BLEND_FUNC_SRC_ALPHA;
|
||||
case PIPE_BLENDFACTOR_DST_ALPHA:
|
||||
return BLEND_FUNC_DST_ALPHA;
|
||||
case PIPE_BLENDFACTOR_DST_COLOR:
|
||||
return BLEND_FUNC_DST_COLOR;
|
||||
case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE:
|
||||
return BLEND_FUNC_SRC_ALPHA_SATURATE;
|
||||
case PIPE_BLENDFACTOR_CONST_COLOR:
|
||||
return BLEND_FUNC_CONSTANT_COLOR;
|
||||
case PIPE_BLENDFACTOR_CONST_ALPHA:
|
||||
return BLEND_FUNC_CONSTANT_ALPHA;
|
||||
case PIPE_BLENDFACTOR_ZERO:
|
||||
return BLEND_FUNC_ZERO;
|
||||
case PIPE_BLENDFACTOR_INV_SRC_COLOR:
|
||||
return BLEND_FUNC_ONE_MINUS_SRC_COLOR;
|
||||
case PIPE_BLENDFACTOR_INV_SRC_ALPHA:
|
||||
return BLEND_FUNC_ONE_MINUS_SRC_ALPHA;
|
||||
case PIPE_BLENDFACTOR_INV_DST_ALPHA:
|
||||
return BLEND_FUNC_ONE_MINUS_DST_ALPHA;
|
||||
case PIPE_BLENDFACTOR_INV_DST_COLOR:
|
||||
return BLEND_FUNC_ONE_MINUS_DST_COLOR;
|
||||
case PIPE_BLENDFACTOR_INV_CONST_COLOR:
|
||||
return BLEND_FUNC_ONE_MINUS_CONSTANT_COLOR;
|
||||
case PIPE_BLENDFACTOR_INV_CONST_ALPHA:
|
||||
return BLEND_FUNC_ONE_MINUS_CONSTANT_ALPHA;
|
||||
case PIPE_BLENDFACTOR_SRC1_COLOR:
|
||||
case PIPE_BLENDFACTOR_SRC1_ALPHA:
|
||||
case PIPE_BLENDFACTOR_INV_SRC1_COLOR:
|
||||
case PIPE_BLENDFACTOR_INV_SRC1_ALPHA:
|
||||
default:
|
||||
DBG("Unhandled blend factor: %i", blend_factor);
|
||||
return ETNA_NO_MATCH;
|
||||
}
|
||||
}
|
||||
|
||||
static inline uint32_t
|
||||
translate_texture_wrapmode(unsigned wrap)
|
||||
{
|
||||
switch (wrap) {
|
||||
case PIPE_TEX_WRAP_REPEAT:
|
||||
return TEXTURE_WRAPMODE_REPEAT;
|
||||
case PIPE_TEX_WRAP_CLAMP:
|
||||
return TEXTURE_WRAPMODE_CLAMP_TO_EDGE;
|
||||
case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
|
||||
return TEXTURE_WRAPMODE_CLAMP_TO_EDGE;
|
||||
case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
|
||||
return TEXTURE_WRAPMODE_CLAMP_TO_EDGE; /* XXX */
|
||||
case PIPE_TEX_WRAP_MIRROR_REPEAT:
|
||||
return TEXTURE_WRAPMODE_MIRRORED_REPEAT;
|
||||
case PIPE_TEX_WRAP_MIRROR_CLAMP:
|
||||
return TEXTURE_WRAPMODE_MIRRORED_REPEAT; /* XXX */
|
||||
case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE:
|
||||
return TEXTURE_WRAPMODE_MIRRORED_REPEAT; /* XXX */
|
||||
case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER:
|
||||
return TEXTURE_WRAPMODE_MIRRORED_REPEAT; /* XXX */
|
||||
default:
|
||||
DBG("Unhandled texture wrapmode: %i", wrap);
|
||||
return ETNA_NO_MATCH;
|
||||
}
|
||||
}
|
||||
|
||||
static inline uint32_t
|
||||
translate_texture_mipfilter(unsigned filter)
|
||||
{
|
||||
switch (filter) {
|
||||
case PIPE_TEX_MIPFILTER_NEAREST:
|
||||
return TEXTURE_FILTER_NEAREST;
|
||||
case PIPE_TEX_MIPFILTER_LINEAR:
|
||||
return TEXTURE_FILTER_LINEAR;
|
||||
case PIPE_TEX_MIPFILTER_NONE:
|
||||
return TEXTURE_FILTER_NONE;
|
||||
default:
|
||||
DBG("Unhandled texture mipfilter: %i", filter);
|
||||
return ETNA_NO_MATCH;
|
||||
}
|
||||
}
|
||||
|
||||
static inline uint32_t
|
||||
translate_texture_filter(unsigned filter)
|
||||
{
|
||||
switch (filter) {
|
||||
case PIPE_TEX_FILTER_NEAREST:
|
||||
return TEXTURE_FILTER_NEAREST;
|
||||
case PIPE_TEX_FILTER_LINEAR:
|
||||
return TEXTURE_FILTER_LINEAR;
|
||||
/* What about anisotropic? */
|
||||
default:
|
||||
DBG("Unhandled texture filter: %i", filter);
|
||||
return ETNA_NO_MATCH;
|
||||
}
|
||||
}
|
||||
|
||||
/* return a RS "compatible" format for use when copying */
|
||||
static inline enum pipe_format
|
||||
etna_compatible_rs_format(enum pipe_format fmt)
|
||||
{
|
||||
/* YUYV and UYVY are blocksize 4, but 2 bytes per pixel */
|
||||
if (fmt == PIPE_FORMAT_YUYV || fmt == PIPE_FORMAT_UYVY)
|
||||
return PIPE_FORMAT_B4G4R4A4_UNORM;
|
||||
|
||||
switch (util_format_get_blocksize(fmt)) {
|
||||
case 2:
|
||||
return PIPE_FORMAT_B4G4R4A4_UNORM;
|
||||
case 4:
|
||||
return PIPE_FORMAT_B8G8R8A8_UNORM;
|
||||
default:
|
||||
return fmt;
|
||||
}
|
||||
}
|
||||
|
||||
static inline int
|
||||
translate_rb_src_dst_swap(enum pipe_format src, enum pipe_format dst)
|
||||
{
|
||||
return translate_rs_format_rb_swap(src) ^ translate_rs_format_rb_swap(dst);
|
||||
}
|
||||
|
||||
static inline uint32_t
|
||||
translate_depth_format(enum pipe_format fmt)
|
||||
{
|
||||
/* Note: Pipe format convention is LSB to MSB, VIVS is MSB to LSB */
|
||||
switch (fmt) {
|
||||
case PIPE_FORMAT_Z16_UNORM:
|
||||
return VIVS_PE_DEPTH_CONFIG_DEPTH_FORMAT_D16;
|
||||
case PIPE_FORMAT_X8Z24_UNORM:
|
||||
return VIVS_PE_DEPTH_CONFIG_DEPTH_FORMAT_D24S8;
|
||||
case PIPE_FORMAT_S8_UINT_Z24_UNORM:
|
||||
return VIVS_PE_DEPTH_CONFIG_DEPTH_FORMAT_D24S8;
|
||||
default:
|
||||
return ETNA_NO_MATCH;
|
||||
}
|
||||
}
|
||||
|
||||
/* render target format for MSAA */
|
||||
static inline uint32_t
|
||||
translate_msaa_format(enum pipe_format fmt)
|
||||
{
|
||||
/* Note: Pipe format convention is LSB to MSB, VIVS is MSB to LSB */
|
||||
switch (fmt) {
|
||||
case PIPE_FORMAT_B4G4R4X4_UNORM:
|
||||
return VIVS_TS_MEM_CONFIG_MSAA_FORMAT_A4R4G4B4;
|
||||
case PIPE_FORMAT_B4G4R4A4_UNORM:
|
||||
return VIVS_TS_MEM_CONFIG_MSAA_FORMAT_A4R4G4B4;
|
||||
case PIPE_FORMAT_B5G5R5X1_UNORM:
|
||||
return VIVS_TS_MEM_CONFIG_MSAA_FORMAT_A1R5G5B5;
|
||||
case PIPE_FORMAT_B5G5R5A1_UNORM:
|
||||
return VIVS_TS_MEM_CONFIG_MSAA_FORMAT_A1R5G5B5;
|
||||
case PIPE_FORMAT_B5G6R5_UNORM:
|
||||
return VIVS_TS_MEM_CONFIG_MSAA_FORMAT_R5G6B5;
|
||||
case PIPE_FORMAT_B8G8R8X8_UNORM:
|
||||
return VIVS_TS_MEM_CONFIG_MSAA_FORMAT_X8R8G8B8;
|
||||
case PIPE_FORMAT_B8G8R8A8_UNORM:
|
||||
return VIVS_TS_MEM_CONFIG_MSAA_FORMAT_A8R8G8B8;
|
||||
/* MSAA with YUYV not supported */
|
||||
default:
|
||||
return ETNA_NO_MATCH;
|
||||
}
|
||||
}
|
||||
|
||||
/* Return normalization flag for vertex element format */
|
||||
static inline uint32_t
|
||||
translate_vertex_format_normalize(enum pipe_format fmt)
|
||||
{
|
||||
const struct util_format_description *desc = util_format_description(fmt);
|
||||
if (!desc)
|
||||
return VIVS_FE_VERTEX_ELEMENT_CONFIG_NORMALIZE_OFF;
|
||||
|
||||
/* assumes that normalization of channel 0 holds for all channels;
|
||||
* this holds for all vertex formats that we support */
|
||||
return desc->channel[0].normalized
|
||||
? VIVS_FE_VERTEX_ELEMENT_CONFIG_NORMALIZE_ON
|
||||
: VIVS_FE_VERTEX_ELEMENT_CONFIG_NORMALIZE_OFF;
|
||||
}
|
||||
|
||||
static inline uint32_t
|
||||
translate_index_size(unsigned index_size)
|
||||
{
|
||||
switch (index_size) {
|
||||
case 1:
|
||||
return VIVS_FE_INDEX_STREAM_CONTROL_TYPE_UNSIGNED_CHAR;
|
||||
case 2:
|
||||
return VIVS_FE_INDEX_STREAM_CONTROL_TYPE_UNSIGNED_SHORT;
|
||||
case 4:
|
||||
return VIVS_FE_INDEX_STREAM_CONTROL_TYPE_UNSIGNED_INT;
|
||||
default:
|
||||
DBG("Unhandled index size %i", index_size);
|
||||
return ETNA_NO_MATCH;
|
||||
}
|
||||
}
|
||||
|
||||
static inline uint32_t
|
||||
translate_draw_mode(unsigned mode)
|
||||
{
|
||||
switch (mode) {
|
||||
case PIPE_PRIM_POINTS:
|
||||
return PRIMITIVE_TYPE_POINTS;
|
||||
case PIPE_PRIM_LINES:
|
||||
return PRIMITIVE_TYPE_LINES;
|
||||
case PIPE_PRIM_LINE_LOOP:
|
||||
return PRIMITIVE_TYPE_LINE_LOOP;
|
||||
case PIPE_PRIM_LINE_STRIP:
|
||||
return PRIMITIVE_TYPE_LINE_STRIP;
|
||||
case PIPE_PRIM_TRIANGLES:
|
||||
return PRIMITIVE_TYPE_TRIANGLES;
|
||||
case PIPE_PRIM_TRIANGLE_STRIP:
|
||||
return PRIMITIVE_TYPE_TRIANGLE_STRIP;
|
||||
case PIPE_PRIM_TRIANGLE_FAN:
|
||||
return PRIMITIVE_TYPE_TRIANGLE_FAN;
|
||||
case PIPE_PRIM_QUADS:
|
||||
return PRIMITIVE_TYPE_QUADS;
|
||||
default:
|
||||
DBG("Unhandled draw mode primitive %i", mode);
|
||||
return ETNA_NO_MATCH;
|
||||
}
|
||||
}
|
||||
|
||||
/* Get size multiple for size of texture/rendertarget with a certain layout
|
||||
* This is affected by many different parameters:
|
||||
* - A horizontal multiple of 16 is used when possible as resolve can be used
|
||||
* at the cost of only a little bit extra memory usage.
|
||||
* - If the surface is to be used with the resolve engine, set rs_align true.
|
||||
* If set, a horizontal multiple of 16 will be used for tiled and linear,
|
||||
* otherwise one of 16. However, such a surface will be incompatible
|
||||
* with the samplers if the GPU does hot support the HALIGN feature.
|
||||
* - If the surface is supertiled, horizontal and vertical multiple is always 64
|
||||
* - If the surface is multi tiled or supertiled, make sure that the vertical size
|
||||
* is a multiple of the number of pixel pipes as well.
|
||||
* */
|
||||
static inline void
|
||||
etna_layout_multiple(unsigned layout, unsigned pixel_pipes, bool rs_align,
|
||||
unsigned *paddingX, unsigned *paddingY, unsigned *halign)
|
||||
{
|
||||
switch (layout) {
|
||||
case ETNA_LAYOUT_LINEAR:
|
||||
*paddingX = rs_align ? 16 : 4;
|
||||
*paddingY = 1;
|
||||
*halign = rs_align ? TEXTURE_HALIGN_SIXTEEN : TEXTURE_HALIGN_FOUR;
|
||||
break;
|
||||
case ETNA_LAYOUT_TILED:
|
||||
*paddingX = rs_align ? 16 : 4;
|
||||
*paddingY = 4;
|
||||
*halign = rs_align ? TEXTURE_HALIGN_SIXTEEN : TEXTURE_HALIGN_FOUR;
|
||||
break;
|
||||
case ETNA_LAYOUT_SUPER_TILED:
|
||||
*paddingX = 64;
|
||||
*paddingY = 64;
|
||||
*halign = TEXTURE_HALIGN_SUPER_TILED;
|
||||
break;
|
||||
case ETNA_LAYOUT_MULTI_TILED:
|
||||
*paddingX = 16;
|
||||
*paddingY = 4 * pixel_pipes;
|
||||
*halign = TEXTURE_HALIGN_SPLIT_TILED;
|
||||
break;
|
||||
case ETNA_LAYOUT_MULTI_SUPERTILED:
|
||||
*paddingX = 64;
|
||||
*paddingY = 64 * pixel_pipes;
|
||||
*halign = TEXTURE_HALIGN_SPLIT_SUPER_TILED;
|
||||
break;
|
||||
default:
|
||||
DBG("Unhandled layout %i", layout);
|
||||
}
|
||||
}
|
||||
|
||||
/* return 32-bit clear pattern for color */
|
||||
static inline uint32_t
|
||||
translate_clear_color(enum pipe_format format,
|
||||
const union pipe_color_union *color)
|
||||
{
|
||||
uint32_t clear_value = 0;
|
||||
|
||||
// XXX util_pack_color
|
||||
switch (format) {
|
||||
case PIPE_FORMAT_B8G8R8A8_UNORM:
|
||||
case PIPE_FORMAT_B8G8R8X8_UNORM:
|
||||
clear_value = etna_cfloat_to_uintN(color->f[2], 8) |
|
||||
(etna_cfloat_to_uintN(color->f[1], 8) << 8) |
|
||||
(etna_cfloat_to_uintN(color->f[0], 8) << 16) |
|
||||
(etna_cfloat_to_uintN(color->f[3], 8) << 24);
|
||||
break;
|
||||
case PIPE_FORMAT_B4G4R4X4_UNORM:
|
||||
case PIPE_FORMAT_B4G4R4A4_UNORM:
|
||||
clear_value = etna_cfloat_to_uintN(color->f[2], 4) |
|
||||
(etna_cfloat_to_uintN(color->f[1], 4) << 4) |
|
||||
(etna_cfloat_to_uintN(color->f[0], 4) << 8) |
|
||||
(etna_cfloat_to_uintN(color->f[3], 4) << 12);
|
||||
clear_value |= clear_value << 16;
|
||||
break;
|
||||
case PIPE_FORMAT_B5G5R5X1_UNORM:
|
||||
case PIPE_FORMAT_B5G5R5A1_UNORM:
|
||||
clear_value = etna_cfloat_to_uintN(color->f[2], 5) |
|
||||
(etna_cfloat_to_uintN(color->f[1], 5) << 5) |
|
||||
(etna_cfloat_to_uintN(color->f[0], 5) << 10) |
|
||||
(etna_cfloat_to_uintN(color->f[3], 1) << 15);
|
||||
clear_value |= clear_value << 16;
|
||||
break;
|
||||
case PIPE_FORMAT_B5G6R5_UNORM:
|
||||
clear_value = etna_cfloat_to_uintN(color->f[2], 5) |
|
||||
(etna_cfloat_to_uintN(color->f[1], 6) << 5) |
|
||||
(etna_cfloat_to_uintN(color->f[0], 5) << 11);
|
||||
clear_value |= clear_value << 16;
|
||||
break;
|
||||
default:
|
||||
DBG("Unhandled pipe format for color clear: %i", format);
|
||||
}
|
||||
|
||||
return clear_value;
|
||||
}
|
||||
|
||||
static inline uint32_t
|
||||
translate_clear_depth_stencil(enum pipe_format format, float depth,
|
||||
unsigned stencil)
|
||||
{
|
||||
uint32_t clear_value = 0;
|
||||
|
||||
// XXX util_pack_color
|
||||
switch (format) {
|
||||
case PIPE_FORMAT_Z16_UNORM:
|
||||
clear_value = etna_cfloat_to_uintN(depth, 16);
|
||||
clear_value |= clear_value << 16;
|
||||
break;
|
||||
case PIPE_FORMAT_X8Z24_UNORM:
|
||||
case PIPE_FORMAT_S8_UINT_Z24_UNORM:
|
||||
clear_value = (etna_cfloat_to_uintN(depth, 24) << 8) | (stencil & 0xFF);
|
||||
break;
|
||||
default:
|
||||
DBG("Unhandled pipe format for depth stencil clear: %i", format);
|
||||
}
|
||||
return clear_value;
|
||||
}
|
||||
|
||||
/* Convert MSAA number of samples to x and y scaling factor and
|
||||
* VIVS_GL_MULTI_SAMPLE_CONFIG value.
|
||||
* Return true if supported and false otherwise. */
|
||||
static inline bool
|
||||
translate_samples_to_xyscale(int num_samples, int *xscale_out, int *yscale_out,
|
||||
uint32_t *config_out)
|
||||
{
|
||||
int xscale, yscale;
|
||||
uint32_t config;
|
||||
|
||||
switch (num_samples) {
|
||||
case 0:
|
||||
case 1:
|
||||
xscale = 1;
|
||||
yscale = 1;
|
||||
config = VIVS_GL_MULTI_SAMPLE_CONFIG_MSAA_SAMPLES_NONE;
|
||||
break;
|
||||
case 2:
|
||||
xscale = 2;
|
||||
yscale = 1;
|
||||
config = VIVS_GL_MULTI_SAMPLE_CONFIG_MSAA_SAMPLES_2X;
|
||||
break;
|
||||
case 4:
|
||||
xscale = 2;
|
||||
yscale = 2;
|
||||
config = VIVS_GL_MULTI_SAMPLE_CONFIG_MSAA_SAMPLES_4X;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
if (xscale_out)
|
||||
*xscale_out = xscale;
|
||||
if (yscale_out)
|
||||
*yscale_out = yscale;
|
||||
if (config_out)
|
||||
*config_out = config;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,118 @@
|
|||
/*
|
||||
* Copyright (c) 2016 Etnaviv Project
|
||||
*
|
||||
* 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, sub license,
|
||||
* 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 NON-INFRINGEMENT. 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:
|
||||
* Christian Gmeiner <christian.gmeiner@gmail.com>
|
||||
*/
|
||||
|
||||
#include "etnaviv_uniforms.h"
|
||||
|
||||
#include "etnaviv_compiler.h"
|
||||
#include "etnaviv_context.h"
|
||||
#include "etnaviv_util.h"
|
||||
#include "pipe/p_defines.h"
|
||||
#include "util/u_math.h"
|
||||
|
||||
static unsigned
|
||||
get_const_idx(const struct etna_context *ctx, bool frag, unsigned samp_id)
|
||||
{
|
||||
if (frag)
|
||||
return samp_id;
|
||||
|
||||
return samp_id + ctx->specs.vertex_sampler_offset;
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
get_texrect_scale(const struct etna_context *ctx, bool frag,
|
||||
enum etna_immediate_contents contents, uint32_t data)
|
||||
{
|
||||
unsigned index = get_const_idx(ctx, frag, data);
|
||||
struct pipe_sampler_view *texture = ctx->sampler_view[index];
|
||||
uint32_t dim;
|
||||
|
||||
if (contents == ETNA_IMMEDIATE_TEXRECT_SCALE_X)
|
||||
dim = texture->texture->width0;
|
||||
else
|
||||
dim = texture->texture->height0;
|
||||
|
||||
return fui(1.0f / dim);
|
||||
}
|
||||
|
||||
void
|
||||
etna_uniforms_write(const struct etna_context *ctx,
|
||||
const struct etna_shader *sobj,
|
||||
struct pipe_constant_buffer *cb, uint32_t *uniforms,
|
||||
unsigned *size)
|
||||
{
|
||||
const struct etna_shader_uniform_info *uinfo = &sobj->uniforms;
|
||||
bool frag = false;
|
||||
|
||||
if (cb->user_buffer) {
|
||||
unsigned size = MIN2(cb->buffer_size, uinfo->const_count * 4);
|
||||
|
||||
memcpy(uniforms, cb->user_buffer, size);
|
||||
}
|
||||
|
||||
if (sobj == ctx->fs)
|
||||
frag = true;
|
||||
|
||||
for (uint32_t i = 0; i < uinfo->imm_count; i++) {
|
||||
switch (uinfo->imm_contents[i]) {
|
||||
case ETNA_IMMEDIATE_CONSTANT:
|
||||
uniforms[i + uinfo->const_count] = uinfo->imm_data[i];
|
||||
break;
|
||||
|
||||
case ETNA_IMMEDIATE_TEXRECT_SCALE_X:
|
||||
case ETNA_IMMEDIATE_TEXRECT_SCALE_Y:
|
||||
uniforms[i + uinfo->const_count] =
|
||||
get_texrect_scale(ctx, frag, uinfo->imm_contents[i], uinfo->imm_data[i]);
|
||||
break;
|
||||
|
||||
case ETNA_IMMEDIATE_UNUSED:
|
||||
/* nothing to do */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
*size = uinfo->const_count + uinfo->imm_count;
|
||||
}
|
||||
|
||||
void
|
||||
etna_set_shader_uniforms_dirty_flags(struct etna_shader *sobj)
|
||||
{
|
||||
uint32_t dirty = 0;
|
||||
|
||||
for (uint32_t i = 0; i < sobj->uniforms.imm_count; i++) {
|
||||
switch (sobj->uniforms.imm_contents[i]) {
|
||||
case ETNA_IMMEDIATE_UNUSED:
|
||||
case ETNA_IMMEDIATE_CONSTANT:
|
||||
break;
|
||||
|
||||
case ETNA_IMMEDIATE_TEXRECT_SCALE_X:
|
||||
case ETNA_IMMEDIATE_TEXRECT_SCALE_Y:
|
||||
dirty |= ETNA_DIRTY_SAMPLER_VIEWS;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
sobj->uniforms_dirty_bits = dirty;
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* Copyright (c) 2016 Etnaviv Project
|
||||
*
|
||||
* 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, sub license,
|
||||
* 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 NON-INFRINGEMENT. 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:
|
||||
* Christian Gmeiner <christian.gmeiner@gmail.com>
|
||||
*/
|
||||
|
||||
#ifndef ETNAVIV_UNIFORMS_H_
|
||||
#define ETNAVIV_UNIFORMS_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
struct etna_context;
|
||||
struct etna_shader;
|
||||
struct pipe_constant_buffer;
|
||||
|
||||
void
|
||||
etna_uniforms_write(const struct etna_context *ctx,
|
||||
const struct etna_shader *sobj,
|
||||
struct pipe_constant_buffer *cb, uint32_t *uniforms,
|
||||
unsigned *size);
|
||||
|
||||
void
|
||||
etna_set_shader_uniforms_dirty_flags(struct etna_shader *sobj);
|
||||
|
||||
#endif /* ETNAVIV_UNIFORMS_H_ */
|
|
@ -0,0 +1,108 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2015 Etnaviv Project
|
||||
*
|
||||
* 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, sub license,
|
||||
* 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 NON-INFRINGEMENT. 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.
|
||||
*/
|
||||
|
||||
/* Misc util */
|
||||
#ifndef H_ETNA_UTIL
|
||||
#define H_ETNA_UTIL
|
||||
|
||||
#include <math.h>
|
||||
|
||||
/* for conditionally setting boolean flag(s): */
|
||||
#define COND(bool, val) ((bool) ? (val) : 0)
|
||||
|
||||
/* align to a value divisable by granularity >= value, works only for powers of two */
|
||||
static inline uint32_t
|
||||
etna_align_up(uint32_t value, uint32_t granularity)
|
||||
{
|
||||
return (value + (granularity - 1)) & (~(granularity - 1));
|
||||
}
|
||||
|
||||
static inline uint32_t
|
||||
etna_bits_ones(unsigned num)
|
||||
{
|
||||
return (1 << num) - 1;
|
||||
}
|
||||
|
||||
/* clamped float [0.0 .. 1.0] -> [0 .. 255] */
|
||||
static inline uint8_t
|
||||
etna_cfloat_to_uint8(float f)
|
||||
{
|
||||
if (f <= 0.0f)
|
||||
return 0;
|
||||
|
||||
if (f >= (1.0f - 1.0f / 256.0f))
|
||||
return 255;
|
||||
|
||||
return f * 256.0f;
|
||||
}
|
||||
|
||||
/* clamped float [0.0 .. 1.0] -> [0 .. (1<<bits)-1] */
|
||||
static inline uint32_t
|
||||
etna_cfloat_to_uintN(float f, int bits)
|
||||
{
|
||||
if (f <= 0.0f)
|
||||
return 0;
|
||||
|
||||
if (f >= (1.0f - 1.0f / (1 << bits)))
|
||||
return (1 << bits) - 1;
|
||||
|
||||
return f * (1 << bits);
|
||||
}
|
||||
|
||||
/* 1/log10(2) */
|
||||
#define RCPLOG2 (1.4426950408889634f)
|
||||
|
||||
/* float to fixp 5.5 */
|
||||
static inline uint32_t
|
||||
etna_float_to_fixp55(float f)
|
||||
{
|
||||
if (f >= 15.953125f)
|
||||
return 511;
|
||||
|
||||
if (f < -16.0f)
|
||||
return 512;
|
||||
|
||||
return (int32_t)(f * 32.0f + 0.5f);
|
||||
}
|
||||
|
||||
/* texture size to log2 in fixp 5.5 format */
|
||||
static inline uint32_t
|
||||
etna_log2_fixp55(unsigned width)
|
||||
{
|
||||
return etna_float_to_fixp55(logf((float)width) * RCPLOG2);
|
||||
}
|
||||
|
||||
/* float to fixp 16.16 */
|
||||
static inline uint32_t
|
||||
etna_f32_to_fixp16(float f)
|
||||
{
|
||||
if (f >= (32768.0f - 1.0f / 65536.0f))
|
||||
return 0x7fffffff;
|
||||
|
||||
if (f < -32768.0f)
|
||||
return 0x80000000;
|
||||
|
||||
return (int32_t)(f * 65536.0f + 0.5f);
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,123 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2015 Etnaviv Project
|
||||
*
|
||||
* 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, sub license,
|
||||
* 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 NON-INFRINGEMENT. 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:
|
||||
* Wladimir J. van der Laan <laanwj@gmail.com>
|
||||
*/
|
||||
|
||||
#include "etnaviv_zsa.h"
|
||||
|
||||
#include "etnaviv_context.h"
|
||||
#include "etnaviv_translate.h"
|
||||
#include "util/u_memory.h"
|
||||
|
||||
void *
|
||||
etna_zsa_state_create(struct pipe_context *pctx,
|
||||
const struct pipe_depth_stencil_alpha_state *so)
|
||||
{
|
||||
struct etna_zsa_state *cs = CALLOC_STRUCT(etna_zsa_state);
|
||||
|
||||
if (!cs)
|
||||
return NULL;
|
||||
|
||||
cs->base = *so;
|
||||
|
||||
/* XXX does stencil[0] / stencil[1] order depend on rs->front_ccw? */
|
||||
bool early_z = true;
|
||||
bool disable_zs =
|
||||
(!so->depth.enabled || so->depth.func == PIPE_FUNC_ALWAYS) &&
|
||||
!so->depth.writemask;
|
||||
|
||||
/* Set operations to KEEP if write mask is 0.
|
||||
* When we don't do this, the depth buffer is written for the entire primitive
|
||||
* instead of just where the stencil condition holds (GC600 rev 0x0019, without
|
||||
* feature CORRECT_STENCIL).
|
||||
* Not sure if this is a hardware bug or just a strange edge case. */
|
||||
#if 0 /* TODO: It looks like a hardware bug */
|
||||
for(int i=0; i<2; ++i)
|
||||
{
|
||||
if(so->stencil[i].writemask == 0)
|
||||
{
|
||||
so->stencil[i].fail_op = so->stencil[i].zfail_op = so->stencil[i].zpass_op = PIPE_STENCIL_OP_KEEP;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Determine whether to enable early z reject. Don't enable it when any of
|
||||
* the stencil-modifying functions is used. */
|
||||
if (so->stencil[0].enabled) {
|
||||
if (so->stencil[0].func != PIPE_FUNC_ALWAYS ||
|
||||
(so->stencil[1].enabled && so->stencil[1].func != PIPE_FUNC_ALWAYS))
|
||||
disable_zs = false;
|
||||
|
||||
if (so->stencil[0].fail_op != PIPE_STENCIL_OP_KEEP ||
|
||||
so->stencil[0].zfail_op != PIPE_STENCIL_OP_KEEP ||
|
||||
so->stencil[0].zpass_op != PIPE_STENCIL_OP_KEEP) {
|
||||
disable_zs = early_z = false;
|
||||
} else if (so->stencil[1].enabled) {
|
||||
if (so->stencil[1].fail_op != PIPE_STENCIL_OP_KEEP ||
|
||||
so->stencil[1].zfail_op != PIPE_STENCIL_OP_KEEP ||
|
||||
so->stencil[1].zpass_op != PIPE_STENCIL_OP_KEEP) {
|
||||
disable_zs = early_z = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Disable early z reject when no depth test is enabled.
|
||||
* This avoids having to sample depth even though we know it's going to
|
||||
* succeed. */
|
||||
if (so->depth.enabled == false || so->depth.func == PIPE_FUNC_ALWAYS)
|
||||
early_z = false;
|
||||
|
||||
if (DBG_ENABLED(ETNA_DBG_NO_EARLY_Z))
|
||||
early_z = false;
|
||||
|
||||
/* compare funcs have 1 to 1 mapping */
|
||||
cs->PE_DEPTH_CONFIG =
|
||||
VIVS_PE_DEPTH_CONFIG_DEPTH_FUNC(so->depth.enabled ? so->depth.func
|
||||
: PIPE_FUNC_ALWAYS) |
|
||||
COND(so->depth.writemask, VIVS_PE_DEPTH_CONFIG_WRITE_ENABLE) |
|
||||
COND(early_z, VIVS_PE_DEPTH_CONFIG_EARLY_Z) |
|
||||
COND(disable_zs, VIVS_PE_DEPTH_CONFIG_DISABLE_ZS);
|
||||
cs->PE_ALPHA_OP =
|
||||
COND(so->alpha.enabled, VIVS_PE_ALPHA_OP_ALPHA_TEST) |
|
||||
VIVS_PE_ALPHA_OP_ALPHA_FUNC(so->alpha.func) |
|
||||
VIVS_PE_ALPHA_OP_ALPHA_REF(etna_cfloat_to_uint8(so->alpha.ref_value));
|
||||
cs->PE_STENCIL_OP =
|
||||
VIVS_PE_STENCIL_OP_FUNC_FRONT(so->stencil[0].func) |
|
||||
VIVS_PE_STENCIL_OP_FUNC_BACK(so->stencil[1].func) |
|
||||
VIVS_PE_STENCIL_OP_FAIL_FRONT(translate_stencil_op(so->stencil[0].fail_op)) |
|
||||
VIVS_PE_STENCIL_OP_FAIL_BACK(translate_stencil_op(so->stencil[1].fail_op)) |
|
||||
VIVS_PE_STENCIL_OP_DEPTH_FAIL_FRONT(translate_stencil_op(so->stencil[0].zfail_op)) |
|
||||
VIVS_PE_STENCIL_OP_DEPTH_FAIL_BACK(translate_stencil_op(so->stencil[1].zfail_op)) |
|
||||
VIVS_PE_STENCIL_OP_PASS_FRONT(translate_stencil_op(so->stencil[0].zpass_op)) |
|
||||
VIVS_PE_STENCIL_OP_PASS_BACK(translate_stencil_op(so->stencil[1].zpass_op));
|
||||
cs->PE_STENCIL_CONFIG =
|
||||
translate_stencil_mode(so->stencil[0].enabled, so->stencil[1].enabled) |
|
||||
VIVS_PE_STENCIL_CONFIG_MASK_FRONT(so->stencil[0].valuemask) |
|
||||
VIVS_PE_STENCIL_CONFIG_WRITE_MASK_FRONT(so->stencil[0].writemask);
|
||||
/* XXX back masks in VIVS_PE_DEPTH_CONFIG_EXT? */
|
||||
/* XXX VIVS_PE_STENCIL_CONFIG_REF_FRONT comes from pipe_stencil_ref */
|
||||
|
||||
/* XXX does alpha/stencil test affect PE_COLOR_FORMAT_OVERWRITE? */
|
||||
return cs;
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2015 Etnaviv Project
|
||||
*
|
||||
* 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, sub license,
|
||||
* 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 NON-INFRINGEMENT. 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:
|
||||
* Wladimir J. van der Laan <laanwj@gmail.com>
|
||||
*/
|
||||
|
||||
#ifndef H_ETNAVIV_ZSA
|
||||
#define H_ETNAVIV_ZSA
|
||||
|
||||
#include "pipe/p_context.h"
|
||||
#include "pipe/p_state.h"
|
||||
|
||||
struct etna_zsa_state {
|
||||
struct pipe_depth_stencil_alpha_state base;
|
||||
|
||||
uint32_t PE_DEPTH_CONFIG;
|
||||
uint32_t PE_ALPHA_OP;
|
||||
uint32_t PE_STENCIL_OP;
|
||||
uint32_t PE_STENCIL_CONFIG;
|
||||
};
|
||||
|
||||
static inline struct etna_zsa_state *
|
||||
etna_zsa_state(struct pipe_depth_stencil_alpha_state *zsa)
|
||||
{
|
||||
return (struct etna_zsa_state *)zsa;
|
||||
}
|
||||
|
||||
void *
|
||||
etna_zsa_state_create(struct pipe_context *pctx,
|
||||
const struct pipe_depth_stencil_alpha_state *so);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,270 @@
|
|||
#ifndef CMDSTREAM_XML
|
||||
#define CMDSTREAM_XML
|
||||
|
||||
/* Autogenerated file, DO NOT EDIT manually!
|
||||
|
||||
This file was generated by the rules-ng-ng headergen tool in this git repository:
|
||||
http://0x04.net/cgit/index.cgi/rules-ng-ng
|
||||
git clone git://0x04.net/rules-ng-ng
|
||||
|
||||
The rules-ng-ng source files this header was generated from are:
|
||||
- cmdstream.xml ( 14094 bytes, from 2016-11-16 18:54:37)
|
||||
- copyright.xml ( 1597 bytes, from 2016-10-02 14:26:13)
|
||||
- common.xml ( 23422 bytes, from 2016-11-16 18:54:37)
|
||||
|
||||
Copyright (C) 2012-2016 by the following authors:
|
||||
- Wladimir J. van der Laan <laanwj@gmail.com>
|
||||
- Christian Gmeiner <christian.gmeiner@gmail.com>
|
||||
- Lucas Stach <l.stach@pengutronix.de>
|
||||
- Russell King <rmk@arm.linux.org.uk>
|
||||
|
||||
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, sub license,
|
||||
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 NON-INFRINGEMENT. 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.
|
||||
*/
|
||||
|
||||
|
||||
#define FE_OPCODE_LOAD_STATE 0x00000001
|
||||
#define FE_OPCODE_END 0x00000002
|
||||
#define FE_OPCODE_NOP 0x00000003
|
||||
#define FE_OPCODE_DRAW_2D 0x00000004
|
||||
#define FE_OPCODE_DRAW_PRIMITIVES 0x00000005
|
||||
#define FE_OPCODE_DRAW_INDEXED_PRIMITIVES 0x00000006
|
||||
#define FE_OPCODE_WAIT 0x00000007
|
||||
#define FE_OPCODE_LINK 0x00000008
|
||||
#define FE_OPCODE_STALL 0x00000009
|
||||
#define FE_OPCODE_CALL 0x0000000a
|
||||
#define FE_OPCODE_RETURN 0x0000000b
|
||||
#define FE_OPCODE_DRAW_INSTANCED 0x0000000c
|
||||
#define FE_OPCODE_CHIP_SELECT 0x0000000d
|
||||
#define PRIMITIVE_TYPE_POINTS 0x00000001
|
||||
#define PRIMITIVE_TYPE_LINES 0x00000002
|
||||
#define PRIMITIVE_TYPE_LINE_STRIP 0x00000003
|
||||
#define PRIMITIVE_TYPE_TRIANGLES 0x00000004
|
||||
#define PRIMITIVE_TYPE_TRIANGLE_STRIP 0x00000005
|
||||
#define PRIMITIVE_TYPE_TRIANGLE_FAN 0x00000006
|
||||
#define PRIMITIVE_TYPE_LINE_LOOP 0x00000007
|
||||
#define PRIMITIVE_TYPE_QUADS 0x00000008
|
||||
#define VIV_FE_LOAD_STATE 0x00000000
|
||||
|
||||
#define VIV_FE_LOAD_STATE_HEADER 0x00000000
|
||||
#define VIV_FE_LOAD_STATE_HEADER_OP__MASK 0xf8000000
|
||||
#define VIV_FE_LOAD_STATE_HEADER_OP__SHIFT 27
|
||||
#define VIV_FE_LOAD_STATE_HEADER_OP_LOAD_STATE 0x08000000
|
||||
#define VIV_FE_LOAD_STATE_HEADER_FIXP 0x04000000
|
||||
#define VIV_FE_LOAD_STATE_HEADER_COUNT__MASK 0x03ff0000
|
||||
#define VIV_FE_LOAD_STATE_HEADER_COUNT__SHIFT 16
|
||||
#define VIV_FE_LOAD_STATE_HEADER_COUNT(x) (((x) << VIV_FE_LOAD_STATE_HEADER_COUNT__SHIFT) & VIV_FE_LOAD_STATE_HEADER_COUNT__MASK)
|
||||
#define VIV_FE_LOAD_STATE_HEADER_OFFSET__MASK 0x0000ffff
|
||||
#define VIV_FE_LOAD_STATE_HEADER_OFFSET__SHIFT 0
|
||||
#define VIV_FE_LOAD_STATE_HEADER_OFFSET(x) (((x) << VIV_FE_LOAD_STATE_HEADER_OFFSET__SHIFT) & VIV_FE_LOAD_STATE_HEADER_OFFSET__MASK)
|
||||
#define VIV_FE_LOAD_STATE_HEADER_OFFSET__SHR 2
|
||||
|
||||
#define VIV_FE_END 0x00000000
|
||||
|
||||
#define VIV_FE_END_HEADER 0x00000000
|
||||
#define VIV_FE_END_HEADER_EVENT_ID__MASK 0x0000001f
|
||||
#define VIV_FE_END_HEADER_EVENT_ID__SHIFT 0
|
||||
#define VIV_FE_END_HEADER_EVENT_ID(x) (((x) << VIV_FE_END_HEADER_EVENT_ID__SHIFT) & VIV_FE_END_HEADER_EVENT_ID__MASK)
|
||||
#define VIV_FE_END_HEADER_EVENT_ENABLE 0x00000100
|
||||
#define VIV_FE_END_HEADER_OP__MASK 0xf8000000
|
||||
#define VIV_FE_END_HEADER_OP__SHIFT 27
|
||||
#define VIV_FE_END_HEADER_OP_END 0x10000000
|
||||
|
||||
#define VIV_FE_NOP 0x00000000
|
||||
|
||||
#define VIV_FE_NOP_HEADER 0x00000000
|
||||
#define VIV_FE_NOP_HEADER_OP__MASK 0xf8000000
|
||||
#define VIV_FE_NOP_HEADER_OP__SHIFT 27
|
||||
#define VIV_FE_NOP_HEADER_OP_NOP 0x18000000
|
||||
|
||||
#define VIV_FE_DRAW_2D 0x00000000
|
||||
|
||||
#define VIV_FE_DRAW_2D_HEADER 0x00000000
|
||||
#define VIV_FE_DRAW_2D_HEADER_COUNT__MASK 0x0000ff00
|
||||
#define VIV_FE_DRAW_2D_HEADER_COUNT__SHIFT 8
|
||||
#define VIV_FE_DRAW_2D_HEADER_COUNT(x) (((x) << VIV_FE_DRAW_2D_HEADER_COUNT__SHIFT) & VIV_FE_DRAW_2D_HEADER_COUNT__MASK)
|
||||
#define VIV_FE_DRAW_2D_HEADER_DATA_COUNT__MASK 0x07ff0000
|
||||
#define VIV_FE_DRAW_2D_HEADER_DATA_COUNT__SHIFT 16
|
||||
#define VIV_FE_DRAW_2D_HEADER_DATA_COUNT(x) (((x) << VIV_FE_DRAW_2D_HEADER_DATA_COUNT__SHIFT) & VIV_FE_DRAW_2D_HEADER_DATA_COUNT__MASK)
|
||||
#define VIV_FE_DRAW_2D_HEADER_OP__MASK 0xf8000000
|
||||
#define VIV_FE_DRAW_2D_HEADER_OP__SHIFT 27
|
||||
#define VIV_FE_DRAW_2D_HEADER_OP_DRAW_2D 0x20000000
|
||||
|
||||
#define VIV_FE_DRAW_2D_TOP_LEFT 0x00000008
|
||||
#define VIV_FE_DRAW_2D_TOP_LEFT_X__MASK 0x0000ffff
|
||||
#define VIV_FE_DRAW_2D_TOP_LEFT_X__SHIFT 0
|
||||
#define VIV_FE_DRAW_2D_TOP_LEFT_X(x) (((x) << VIV_FE_DRAW_2D_TOP_LEFT_X__SHIFT) & VIV_FE_DRAW_2D_TOP_LEFT_X__MASK)
|
||||
#define VIV_FE_DRAW_2D_TOP_LEFT_Y__MASK 0xffff0000
|
||||
#define VIV_FE_DRAW_2D_TOP_LEFT_Y__SHIFT 16
|
||||
#define VIV_FE_DRAW_2D_TOP_LEFT_Y(x) (((x) << VIV_FE_DRAW_2D_TOP_LEFT_Y__SHIFT) & VIV_FE_DRAW_2D_TOP_LEFT_Y__MASK)
|
||||
|
||||
#define VIV_FE_DRAW_2D_BOTTOM_RIGHT 0x0000000c
|
||||
#define VIV_FE_DRAW_2D_BOTTOM_RIGHT_X__MASK 0x0000ffff
|
||||
#define VIV_FE_DRAW_2D_BOTTOM_RIGHT_X__SHIFT 0
|
||||
#define VIV_FE_DRAW_2D_BOTTOM_RIGHT_X(x) (((x) << VIV_FE_DRAW_2D_BOTTOM_RIGHT_X__SHIFT) & VIV_FE_DRAW_2D_BOTTOM_RIGHT_X__MASK)
|
||||
#define VIV_FE_DRAW_2D_BOTTOM_RIGHT_Y__MASK 0xffff0000
|
||||
#define VIV_FE_DRAW_2D_BOTTOM_RIGHT_Y__SHIFT 16
|
||||
#define VIV_FE_DRAW_2D_BOTTOM_RIGHT_Y(x) (((x) << VIV_FE_DRAW_2D_BOTTOM_RIGHT_Y__SHIFT) & VIV_FE_DRAW_2D_BOTTOM_RIGHT_Y__MASK)
|
||||
|
||||
#define VIV_FE_DRAW_PRIMITIVES 0x00000000
|
||||
|
||||
#define VIV_FE_DRAW_PRIMITIVES_HEADER 0x00000000
|
||||
#define VIV_FE_DRAW_PRIMITIVES_HEADER_OP__MASK 0xf8000000
|
||||
#define VIV_FE_DRAW_PRIMITIVES_HEADER_OP__SHIFT 27
|
||||
#define VIV_FE_DRAW_PRIMITIVES_HEADER_OP_DRAW_PRIMITIVES 0x28000000
|
||||
|
||||
#define VIV_FE_DRAW_PRIMITIVES_COMMAND 0x00000004
|
||||
#define VIV_FE_DRAW_PRIMITIVES_COMMAND_TYPE__MASK 0x000000ff
|
||||
#define VIV_FE_DRAW_PRIMITIVES_COMMAND_TYPE__SHIFT 0
|
||||
#define VIV_FE_DRAW_PRIMITIVES_COMMAND_TYPE(x) (((x) << VIV_FE_DRAW_PRIMITIVES_COMMAND_TYPE__SHIFT) & VIV_FE_DRAW_PRIMITIVES_COMMAND_TYPE__MASK)
|
||||
|
||||
#define VIV_FE_DRAW_PRIMITIVES_START 0x00000008
|
||||
|
||||
#define VIV_FE_DRAW_PRIMITIVES_COUNT 0x0000000c
|
||||
|
||||
#define VIV_FE_DRAW_INDEXED_PRIMITIVES 0x00000000
|
||||
|
||||
#define VIV_FE_DRAW_INDEXED_PRIMITIVES_HEADER 0x00000000
|
||||
#define VIV_FE_DRAW_INDEXED_PRIMITIVES_HEADER_OP__MASK 0xf8000000
|
||||
#define VIV_FE_DRAW_INDEXED_PRIMITIVES_HEADER_OP__SHIFT 27
|
||||
#define VIV_FE_DRAW_INDEXED_PRIMITIVES_HEADER_OP_DRAW_INDEXED_PRIMITIVES 0x30000000
|
||||
|
||||
#define VIV_FE_DRAW_INDEXED_PRIMITIVES_COMMAND 0x00000004
|
||||
#define VIV_FE_DRAW_INDEXED_PRIMITIVES_COMMAND_TYPE__MASK 0x000000ff
|
||||
#define VIV_FE_DRAW_INDEXED_PRIMITIVES_COMMAND_TYPE__SHIFT 0
|
||||
#define VIV_FE_DRAW_INDEXED_PRIMITIVES_COMMAND_TYPE(x) (((x) << VIV_FE_DRAW_INDEXED_PRIMITIVES_COMMAND_TYPE__SHIFT) & VIV_FE_DRAW_INDEXED_PRIMITIVES_COMMAND_TYPE__MASK)
|
||||
|
||||
#define VIV_FE_DRAW_INDEXED_PRIMITIVES_START 0x00000008
|
||||
|
||||
#define VIV_FE_DRAW_INDEXED_PRIMITIVES_COUNT 0x0000000c
|
||||
|
||||
#define VIV_FE_DRAW_INDEXED_PRIMITIVES_OFFSET 0x00000010
|
||||
|
||||
#define VIV_FE_WAIT 0x00000000
|
||||
|
||||
#define VIV_FE_WAIT_HEADER 0x00000000
|
||||
#define VIV_FE_WAIT_HEADER_DELAY__MASK 0x0000ffff
|
||||
#define VIV_FE_WAIT_HEADER_DELAY__SHIFT 0
|
||||
#define VIV_FE_WAIT_HEADER_DELAY(x) (((x) << VIV_FE_WAIT_HEADER_DELAY__SHIFT) & VIV_FE_WAIT_HEADER_DELAY__MASK)
|
||||
#define VIV_FE_WAIT_HEADER_OP__MASK 0xf8000000
|
||||
#define VIV_FE_WAIT_HEADER_OP__SHIFT 27
|
||||
#define VIV_FE_WAIT_HEADER_OP_WAIT 0x38000000
|
||||
|
||||
#define VIV_FE_LINK 0x00000000
|
||||
|
||||
#define VIV_FE_LINK_HEADER 0x00000000
|
||||
#define VIV_FE_LINK_HEADER_PREFETCH__MASK 0x0000ffff
|
||||
#define VIV_FE_LINK_HEADER_PREFETCH__SHIFT 0
|
||||
#define VIV_FE_LINK_HEADER_PREFETCH(x) (((x) << VIV_FE_LINK_HEADER_PREFETCH__SHIFT) & VIV_FE_LINK_HEADER_PREFETCH__MASK)
|
||||
#define VIV_FE_LINK_HEADER_OP__MASK 0xf8000000
|
||||
#define VIV_FE_LINK_HEADER_OP__SHIFT 27
|
||||
#define VIV_FE_LINK_HEADER_OP_LINK 0x40000000
|
||||
|
||||
#define VIV_FE_LINK_ADDRESS 0x00000004
|
||||
|
||||
#define VIV_FE_STALL 0x00000000
|
||||
|
||||
#define VIV_FE_STALL_HEADER 0x00000000
|
||||
#define VIV_FE_STALL_HEADER_OP__MASK 0xf8000000
|
||||
#define VIV_FE_STALL_HEADER_OP__SHIFT 27
|
||||
#define VIV_FE_STALL_HEADER_OP_STALL 0x48000000
|
||||
|
||||
#define VIV_FE_STALL_TOKEN 0x00000004
|
||||
#define VIV_FE_STALL_TOKEN_FROM__MASK 0x0000001f
|
||||
#define VIV_FE_STALL_TOKEN_FROM__SHIFT 0
|
||||
#define VIV_FE_STALL_TOKEN_FROM(x) (((x) << VIV_FE_STALL_TOKEN_FROM__SHIFT) & VIV_FE_STALL_TOKEN_FROM__MASK)
|
||||
#define VIV_FE_STALL_TOKEN_TO__MASK 0x00001f00
|
||||
#define VIV_FE_STALL_TOKEN_TO__SHIFT 8
|
||||
#define VIV_FE_STALL_TOKEN_TO(x) (((x) << VIV_FE_STALL_TOKEN_TO__SHIFT) & VIV_FE_STALL_TOKEN_TO__MASK)
|
||||
|
||||
#define VIV_FE_CALL 0x00000000
|
||||
|
||||
#define VIV_FE_CALL_HEADER 0x00000000
|
||||
#define VIV_FE_CALL_HEADER_PREFETCH__MASK 0x0000ffff
|
||||
#define VIV_FE_CALL_HEADER_PREFETCH__SHIFT 0
|
||||
#define VIV_FE_CALL_HEADER_PREFETCH(x) (((x) << VIV_FE_CALL_HEADER_PREFETCH__SHIFT) & VIV_FE_CALL_HEADER_PREFETCH__MASK)
|
||||
#define VIV_FE_CALL_HEADER_OP__MASK 0xf8000000
|
||||
#define VIV_FE_CALL_HEADER_OP__SHIFT 27
|
||||
#define VIV_FE_CALL_HEADER_OP_CALL 0x50000000
|
||||
|
||||
#define VIV_FE_CALL_ADDRESS 0x00000004
|
||||
|
||||
#define VIV_FE_CALL_RETURN_PREFETCH 0x00000008
|
||||
|
||||
#define VIV_FE_CALL_RETURN_ADDRESS 0x0000000c
|
||||
|
||||
#define VIV_FE_RETURN 0x00000000
|
||||
|
||||
#define VIV_FE_RETURN_HEADER 0x00000000
|
||||
#define VIV_FE_RETURN_HEADER_OP__MASK 0xf8000000
|
||||
#define VIV_FE_RETURN_HEADER_OP__SHIFT 27
|
||||
#define VIV_FE_RETURN_HEADER_OP_RETURN 0x58000000
|
||||
|
||||
#define VIV_FE_CHIP_SELECT 0x00000000
|
||||
|
||||
#define VIV_FE_CHIP_SELECT_HEADER 0x00000000
|
||||
#define VIV_FE_CHIP_SELECT_HEADER_OP__MASK 0xf8000000
|
||||
#define VIV_FE_CHIP_SELECT_HEADER_OP__SHIFT 27
|
||||
#define VIV_FE_CHIP_SELECT_HEADER_OP_CHIP_SELECT 0x68000000
|
||||
#define VIV_FE_CHIP_SELECT_HEADER_ENABLE_CHIP15 0x00008000
|
||||
#define VIV_FE_CHIP_SELECT_HEADER_ENABLE_CHIP14 0x00004000
|
||||
#define VIV_FE_CHIP_SELECT_HEADER_ENABLE_CHIP13 0x00002000
|
||||
#define VIV_FE_CHIP_SELECT_HEADER_ENABLE_CHIP12 0x00001000
|
||||
#define VIV_FE_CHIP_SELECT_HEADER_ENABLE_CHIP11 0x00000800
|
||||
#define VIV_FE_CHIP_SELECT_HEADER_ENABLE_CHIP10 0x00000400
|
||||
#define VIV_FE_CHIP_SELECT_HEADER_ENABLE_CHIP9 0x00000200
|
||||
#define VIV_FE_CHIP_SELECT_HEADER_ENABLE_CHIP8 0x00000100
|
||||
#define VIV_FE_CHIP_SELECT_HEADER_ENABLE_CHIP7 0x00000080
|
||||
#define VIV_FE_CHIP_SELECT_HEADER_ENABLE_CHIP6 0x00000040
|
||||
#define VIV_FE_CHIP_SELECT_HEADER_ENABLE_CHIP5 0x00000020
|
||||
#define VIV_FE_CHIP_SELECT_HEADER_ENABLE_CHIP4 0x00000010
|
||||
#define VIV_FE_CHIP_SELECT_HEADER_ENABLE_CHIP3 0x00000008
|
||||
#define VIV_FE_CHIP_SELECT_HEADER_ENABLE_CHIP2 0x00000004
|
||||
#define VIV_FE_CHIP_SELECT_HEADER_ENABLE_CHIP1 0x00000002
|
||||
#define VIV_FE_CHIP_SELECT_HEADER_ENABLE_CHIP0 0x00000001
|
||||
|
||||
#define VIV_FE_DRAW_INSTANCED 0x00000000
|
||||
|
||||
#define VIV_FE_DRAW_INSTANCED_HEADER 0x00000000
|
||||
#define VIV_FE_DRAW_INSTANCED_HEADER_OP__MASK 0xf8000000
|
||||
#define VIV_FE_DRAW_INSTANCED_HEADER_OP__SHIFT 27
|
||||
#define VIV_FE_DRAW_INSTANCED_HEADER_OP_DRAW_INSTANCED 0x60000000
|
||||
#define VIV_FE_DRAW_INSTANCED_HEADER_INDEXED 0x00100000
|
||||
#define VIV_FE_DRAW_INSTANCED_HEADER_TYPE__MASK 0x000f0000
|
||||
#define VIV_FE_DRAW_INSTANCED_HEADER_TYPE__SHIFT 16
|
||||
#define VIV_FE_DRAW_INSTANCED_HEADER_TYPE(x) (((x) << VIV_FE_DRAW_INSTANCED_HEADER_TYPE__SHIFT) & VIV_FE_DRAW_INSTANCED_HEADER_TYPE__MASK)
|
||||
#define VIV_FE_DRAW_INSTANCED_HEADER_INSTANCE_COUNT_LO__MASK 0x0000ffff
|
||||
#define VIV_FE_DRAW_INSTANCED_HEADER_INSTANCE_COUNT_LO__SHIFT 0
|
||||
#define VIV_FE_DRAW_INSTANCED_HEADER_INSTANCE_COUNT_LO(x) (((x) << VIV_FE_DRAW_INSTANCED_HEADER_INSTANCE_COUNT_LO__SHIFT) & VIV_FE_DRAW_INSTANCED_HEADER_INSTANCE_COUNT_LO__MASK)
|
||||
|
||||
#define VIV_FE_DRAW_INSTANCED_COUNT 0x00000004
|
||||
#define VIV_FE_DRAW_INSTANCED_COUNT_INSTANCE_COUNT_HI__MASK 0xff000000
|
||||
#define VIV_FE_DRAW_INSTANCED_COUNT_INSTANCE_COUNT_HI__SHIFT 24
|
||||
#define VIV_FE_DRAW_INSTANCED_COUNT_INSTANCE_COUNT_HI(x) (((x) << VIV_FE_DRAW_INSTANCED_COUNT_INSTANCE_COUNT_HI__SHIFT) & VIV_FE_DRAW_INSTANCED_COUNT_INSTANCE_COUNT_HI__MASK)
|
||||
#define VIV_FE_DRAW_INSTANCED_COUNT_VERTEX_COUNT__MASK 0x00ffffff
|
||||
#define VIV_FE_DRAW_INSTANCED_COUNT_VERTEX_COUNT__SHIFT 0
|
||||
#define VIV_FE_DRAW_INSTANCED_COUNT_VERTEX_COUNT(x) (((x) << VIV_FE_DRAW_INSTANCED_COUNT_VERTEX_COUNT__SHIFT) & VIV_FE_DRAW_INSTANCED_COUNT_VERTEX_COUNT__MASK)
|
||||
|
||||
#define VIV_FE_DRAW_INSTANCED_START 0x00000008
|
||||
#define VIV_FE_DRAW_INSTANCED_START_INDEX__MASK 0xffffffff
|
||||
#define VIV_FE_DRAW_INSTANCED_START_INDEX__SHIFT 0
|
||||
#define VIV_FE_DRAW_INSTANCED_START_INDEX(x) (((x) << VIV_FE_DRAW_INSTANCED_START_INDEX__SHIFT) & VIV_FE_DRAW_INSTANCED_START_INDEX__MASK)
|
||||
|
||||
|
||||
#endif /* CMDSTREAM_XML */
|
|
@ -0,0 +1,320 @@
|
|||
#ifndef COMMON_XML
|
||||
#define COMMON_XML
|
||||
|
||||
/* Autogenerated file, DO NOT EDIT manually!
|
||||
|
||||
This file was generated by the rules-ng-ng headergen tool in this git repository:
|
||||
http://0x04.net/cgit/index.cgi/rules-ng-ng
|
||||
git clone git://0x04.net/rules-ng-ng
|
||||
|
||||
The rules-ng-ng source files this header was generated from are:
|
||||
- state.xml ( 19792 bytes, from 2016-11-16 18:54:37)
|
||||
- common.xml ( 23422 bytes, from 2016-11-16 18:54:37)
|
||||
- state_hi.xml ( 25653 bytes, from 2016-10-02 14:26:13)
|
||||
- copyright.xml ( 1597 bytes, from 2016-10-02 14:26:13)
|
||||
- state_2d.xml ( 51552 bytes, from 2016-10-02 14:26:13)
|
||||
- state_3d.xml ( 57579 bytes, from 2016-11-16 18:54:37)
|
||||
- state_vg.xml ( 5975 bytes, from 2016-10-02 14:26:13)
|
||||
|
||||
Copyright (C) 2012-2016 by the following authors:
|
||||
- Wladimir J. van der Laan <laanwj@gmail.com>
|
||||
- Christian Gmeiner <christian.gmeiner@gmail.com>
|
||||
- Lucas Stach <l.stach@pengutronix.de>
|
||||
- Russell King <rmk@arm.linux.org.uk>
|
||||
|
||||
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, sub license,
|
||||
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 NON-INFRINGEMENT. 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.
|
||||
*/
|
||||
|
||||
|
||||
#define PIPE_ID_PIPE_3D 0x00000000
|
||||
#define PIPE_ID_PIPE_2D 0x00000001
|
||||
#define SYNC_RECIPIENT_FE 0x00000001
|
||||
#define SYNC_RECIPIENT_RA 0x00000005
|
||||
#define SYNC_RECIPIENT_PE 0x00000007
|
||||
#define SYNC_RECIPIENT_DE 0x0000000b
|
||||
#define SYNC_RECIPIENT_VG 0x0000000f
|
||||
#define SYNC_RECIPIENT_TESSELATOR 0x00000010
|
||||
#define SYNC_RECIPIENT_VG2 0x00000011
|
||||
#define SYNC_RECIPIENT_TESSELATOR2 0x00000012
|
||||
#define SYNC_RECIPIENT_VG3 0x00000013
|
||||
#define SYNC_RECIPIENT_TESSELATOR3 0x00000014
|
||||
#define ENDIAN_MODE_NO_SWAP 0x00000000
|
||||
#define ENDIAN_MODE_SWAP_16 0x00000001
|
||||
#define ENDIAN_MODE_SWAP_32 0x00000002
|
||||
#define chipModel_GC200 0x00000200
|
||||
#define chipModel_GC300 0x00000300
|
||||
#define chipModel_GC320 0x00000320
|
||||
#define chipModel_GC328 0x00000328
|
||||
#define chipModel_GC350 0x00000350
|
||||
#define chipModel_GC355 0x00000355
|
||||
#define chipModel_GC400 0x00000400
|
||||
#define chipModel_GC410 0x00000410
|
||||
#define chipModel_GC420 0x00000420
|
||||
#define chipModel_GC428 0x00000428
|
||||
#define chipModel_GC450 0x00000450
|
||||
#define chipModel_GC500 0x00000500
|
||||
#define chipModel_GC520 0x00000520
|
||||
#define chipModel_GC530 0x00000530
|
||||
#define chipModel_GC600 0x00000600
|
||||
#define chipModel_GC700 0x00000700
|
||||
#define chipModel_GC800 0x00000800
|
||||
#define chipModel_GC860 0x00000860
|
||||
#define chipModel_GC880 0x00000880
|
||||
#define chipModel_GC1000 0x00001000
|
||||
#define chipModel_GC1500 0x00001500
|
||||
#define chipModel_GC2000 0x00002000
|
||||
#define chipModel_GC2100 0x00002100
|
||||
#define chipModel_GC2200 0x00002200
|
||||
#define chipModel_GC2500 0x00002500
|
||||
#define chipModel_GC3000 0x00003000
|
||||
#define chipModel_GC4000 0x00004000
|
||||
#define chipModel_GC5000 0x00005000
|
||||
#define chipModel_GC5200 0x00005200
|
||||
#define chipModel_GC6400 0x00006400
|
||||
#define RGBA_BITS_R 0x00000001
|
||||
#define RGBA_BITS_G 0x00000002
|
||||
#define RGBA_BITS_B 0x00000004
|
||||
#define RGBA_BITS_A 0x00000008
|
||||
#define chipFeatures_FAST_CLEAR 0x00000001
|
||||
#define chipFeatures_SPECIAL_ANTI_ALIASING 0x00000002
|
||||
#define chipFeatures_PIPE_3D 0x00000004
|
||||
#define chipFeatures_DXT_TEXTURE_COMPRESSION 0x00000008
|
||||
#define chipFeatures_DEBUG_MODE 0x00000010
|
||||
#define chipFeatures_Z_COMPRESSION 0x00000020
|
||||
#define chipFeatures_YUV420_SCALER 0x00000040
|
||||
#define chipFeatures_MSAA 0x00000080
|
||||
#define chipFeatures_DC 0x00000100
|
||||
#define chipFeatures_PIPE_2D 0x00000200
|
||||
#define chipFeatures_ETC1_TEXTURE_COMPRESSION 0x00000400
|
||||
#define chipFeatures_FAST_SCALER 0x00000800
|
||||
#define chipFeatures_HIGH_DYNAMIC_RANGE 0x00001000
|
||||
#define chipFeatures_YUV420_TILER 0x00002000
|
||||
#define chipFeatures_MODULE_CG 0x00004000
|
||||
#define chipFeatures_MIN_AREA 0x00008000
|
||||
#define chipFeatures_NO_EARLY_Z 0x00010000
|
||||
#define chipFeatures_NO_422_TEXTURE 0x00020000
|
||||
#define chipFeatures_BUFFER_INTERLEAVING 0x00040000
|
||||
#define chipFeatures_BYTE_WRITE_2D 0x00080000
|
||||
#define chipFeatures_NO_SCALER 0x00100000
|
||||
#define chipFeatures_YUY2_AVERAGING 0x00200000
|
||||
#define chipFeatures_HALF_PE_CACHE 0x00400000
|
||||
#define chipFeatures_HALF_TX_CACHE 0x00800000
|
||||
#define chipFeatures_YUY2_RENDER_TARGET 0x01000000
|
||||
#define chipFeatures_MEM32 0x02000000
|
||||
#define chipFeatures_PIPE_VG 0x04000000
|
||||
#define chipFeatures_VGTS 0x08000000
|
||||
#define chipFeatures_FE20 0x10000000
|
||||
#define chipFeatures_BYTE_WRITE_3D 0x20000000
|
||||
#define chipFeatures_RS_YUV_TARGET 0x40000000
|
||||
#define chipFeatures_32_BIT_INDICES 0x80000000
|
||||
#define chipMinorFeatures0_FLIP_Y 0x00000001
|
||||
#define chipMinorFeatures0_DUAL_RETURN_BUS 0x00000002
|
||||
#define chipMinorFeatures0_ENDIANNESS_CONFIG 0x00000004
|
||||
#define chipMinorFeatures0_TEXTURE_8K 0x00000008
|
||||
#define chipMinorFeatures0_CORRECT_TEXTURE_CONVERTER 0x00000010
|
||||
#define chipMinorFeatures0_SPECIAL_MSAA_LOD 0x00000020
|
||||
#define chipMinorFeatures0_FAST_CLEAR_FLUSH 0x00000040
|
||||
#define chipMinorFeatures0_2DPE20 0x00000080
|
||||
#define chipMinorFeatures0_CORRECT_AUTO_DISABLE 0x00000100
|
||||
#define chipMinorFeatures0_RENDERTARGET_8K 0x00000200
|
||||
#define chipMinorFeatures0_2BITPERTILE 0x00000400
|
||||
#define chipMinorFeatures0_SEPARATE_TILE_STATUS_WHEN_INTERLEAVED 0x00000800
|
||||
#define chipMinorFeatures0_SUPER_TILED 0x00001000
|
||||
#define chipMinorFeatures0_VG_20 0x00002000
|
||||
#define chipMinorFeatures0_TS_EXTENDED_COMMANDS 0x00004000
|
||||
#define chipMinorFeatures0_COMPRESSION_FIFO_FIXED 0x00008000
|
||||
#define chipMinorFeatures0_HAS_SIGN_FLOOR_CEIL 0x00010000
|
||||
#define chipMinorFeatures0_VG_FILTER 0x00020000
|
||||
#define chipMinorFeatures0_VG_21 0x00040000
|
||||
#define chipMinorFeatures0_SHADER_HAS_W 0x00080000
|
||||
#define chipMinorFeatures0_HAS_SQRT_TRIG 0x00100000
|
||||
#define chipMinorFeatures0_MORE_MINOR_FEATURES 0x00200000
|
||||
#define chipMinorFeatures0_MC20 0x00400000
|
||||
#define chipMinorFeatures0_MSAA_SIDEBAND 0x00800000
|
||||
#define chipMinorFeatures0_BUG_FIXES0 0x01000000
|
||||
#define chipMinorFeatures0_VAA 0x02000000
|
||||
#define chipMinorFeatures0_BYPASS_IN_MSAA 0x04000000
|
||||
#define chipMinorFeatures0_HZ 0x08000000
|
||||
#define chipMinorFeatures0_NEW_TEXTURE 0x10000000
|
||||
#define chipMinorFeatures0_2D_A8_TARGET 0x20000000
|
||||
#define chipMinorFeatures0_CORRECT_STENCIL 0x40000000
|
||||
#define chipMinorFeatures0_ENHANCE_VR 0x80000000
|
||||
#define chipMinorFeatures1_RSUV_SWIZZLE 0x00000001
|
||||
#define chipMinorFeatures1_V2_COMPRESSION 0x00000002
|
||||
#define chipMinorFeatures1_VG_DOUBLE_BUFFER 0x00000004
|
||||
#define chipMinorFeatures1_EXTRA_EVENT_STATES 0x00000008
|
||||
#define chipMinorFeatures1_NO_STRIPING_NEEDED 0x00000010
|
||||
#define chipMinorFeatures1_TEXTURE_STRIDE 0x00000020
|
||||
#define chipMinorFeatures1_BUG_FIXES3 0x00000040
|
||||
#define chipMinorFeatures1_AUTO_DISABLE 0x00000080
|
||||
#define chipMinorFeatures1_AUTO_RESTART_TS 0x00000100
|
||||
#define chipMinorFeatures1_DISABLE_PE_GATING 0x00000200
|
||||
#define chipMinorFeatures1_L2_WINDOWING 0x00000400
|
||||
#define chipMinorFeatures1_HALF_FLOAT 0x00000800
|
||||
#define chipMinorFeatures1_PIXEL_DITHER 0x00001000
|
||||
#define chipMinorFeatures1_TWO_STENCIL_REFERENCE 0x00002000
|
||||
#define chipMinorFeatures1_EXTENDED_PIXEL_FORMAT 0x00004000
|
||||
#define chipMinorFeatures1_CORRECT_MIN_MAX_DEPTH 0x00008000
|
||||
#define chipMinorFeatures1_2D_DITHER 0x00010000
|
||||
#define chipMinorFeatures1_BUG_FIXES5 0x00020000
|
||||
#define chipMinorFeatures1_NEW_2D 0x00040000
|
||||
#define chipMinorFeatures1_NEW_FP 0x00080000
|
||||
#define chipMinorFeatures1_TEXTURE_HALIGN 0x00100000
|
||||
#define chipMinorFeatures1_NON_POWER_OF_TWO 0x00200000
|
||||
#define chipMinorFeatures1_LINEAR_TEXTURE_SUPPORT 0x00400000
|
||||
#define chipMinorFeatures1_HALTI0 0x00800000
|
||||
#define chipMinorFeatures1_CORRECT_OVERFLOW_VG 0x01000000
|
||||
#define chipMinorFeatures1_NEGATIVE_LOG_FIX 0x02000000
|
||||
#define chipMinorFeatures1_RESOLVE_OFFSET 0x04000000
|
||||
#define chipMinorFeatures1_OK_TO_GATE_AXI_CLOCK 0x08000000
|
||||
#define chipMinorFeatures1_MMU_VERSION 0x10000000
|
||||
#define chipMinorFeatures1_WIDE_LINE 0x20000000
|
||||
#define chipMinorFeatures1_BUG_FIXES6 0x40000000
|
||||
#define chipMinorFeatures1_FC_FLUSH_STALL 0x80000000
|
||||
#define chipMinorFeatures2_LINE_LOOP 0x00000001
|
||||
#define chipMinorFeatures2_LOGIC_OP 0x00000002
|
||||
#define chipMinorFeatures2_SEAMLESS_CUBE_MAP 0x00000004
|
||||
#define chipMinorFeatures2_SUPERTILED_TEXTURE 0x00000008
|
||||
#define chipMinorFeatures2_LINEAR_PE 0x00000010
|
||||
#define chipMinorFeatures2_RECT_PRIMITIVE 0x00000020
|
||||
#define chipMinorFeatures2_COMPOSITION 0x00000040
|
||||
#define chipMinorFeatures2_CORRECT_AUTO_DISABLE_COUNT 0x00000080
|
||||
#define chipMinorFeatures2_PE_SWIZZLE 0x00000100
|
||||
#define chipMinorFeatures2_END_EVENT 0x00000200
|
||||
#define chipMinorFeatures2_S1S8 0x00000400
|
||||
#define chipMinorFeatures2_HALTI1 0x00000800
|
||||
#define chipMinorFeatures2_RGB888 0x00001000
|
||||
#define chipMinorFeatures2_TX__YUV_ASSEMBLER 0x00002000
|
||||
#define chipMinorFeatures2_DYNAMIC_FREQUENCY_SCALING 0x00004000
|
||||
#define chipMinorFeatures2_EXTRA_TEXTURE_STATE 0x00008000
|
||||
#define chipMinorFeatures2_FULL_DIRECTFB 0x00010000
|
||||
#define chipMinorFeatures2_2D_TILING 0x00020000
|
||||
#define chipMinorFeatures2_THREAD_WALKER_IN_PS 0x00040000
|
||||
#define chipMinorFeatures2_TILE_FILLER 0x00080000
|
||||
#define chipMinorFeatures2_YUV_STANDARD 0x00100000
|
||||
#define chipMinorFeatures2_2D_MULTI_SOURCE_BLIT 0x00200000
|
||||
#define chipMinorFeatures2_YUV_CONVERSION 0x00400000
|
||||
#define chipMinorFeatures2_FLUSH_FIXED_2D 0x00800000
|
||||
#define chipMinorFeatures2_INTERLEAVER 0x01000000
|
||||
#define chipMinorFeatures2_MIXED_STREAMS 0x02000000
|
||||
#define chipMinorFeatures2_2D_420_L2CACHE 0x04000000
|
||||
#define chipMinorFeatures2_BUG_FIXES7 0x08000000
|
||||
#define chipMinorFeatures2_2D_NO_INDEX8_BRUSH 0x10000000
|
||||
#define chipMinorFeatures2_TEXTURE_TILED_READ 0x20000000
|
||||
#define chipMinorFeatures2_DECOMPRESS_Z16 0x40000000
|
||||
#define chipMinorFeatures2_BUG_FIXES8 0x80000000
|
||||
#define chipMinorFeatures3_ROTATION_STALL_FIX 0x00000001
|
||||
#define chipMinorFeatures3_OCL_ONLY 0x00000002
|
||||
#define chipMinorFeatures3_2D_MULTI_SOURCE_BLT_EX 0x00000004
|
||||
#define chipMinorFeatures3_INSTRUCTION_CACHE 0x00000008
|
||||
#define chipMinorFeatures3_GEOMETRY_SHADER 0x00000010
|
||||
#define chipMinorFeatures3_TEX_COMPRESSION_SUPERTILED 0x00000020
|
||||
#define chipMinorFeatures3_GENERICS 0x00000040
|
||||
#define chipMinorFeatures3_BUG_FIXES9 0x00000080
|
||||
#define chipMinorFeatures3_FAST_MSAA 0x00000100
|
||||
#define chipMinorFeatures3_WCLIP 0x00000200
|
||||
#define chipMinorFeatures3_BUG_FIXES10 0x00000400
|
||||
#define chipMinorFeatures3_UNIFIED_SAMPLERS 0x00000800
|
||||
#define chipMinorFeatures3_BUG_FIXES11 0x00001000
|
||||
#define chipMinorFeatures3_PERFORMANCE_COUNTERS 0x00002000
|
||||
#define chipMinorFeatures3_HAS_FAST_TRANSCENDENTALS 0x00004000
|
||||
#define chipMinorFeatures3_BUG_FIXES12 0x00008000
|
||||
#define chipMinorFeatures3_BUG_FIXES13 0x00010000
|
||||
#define chipMinorFeatures3_DE_ENHANCEMENTS1 0x00020000
|
||||
#define chipMinorFeatures3_ACE 0x00040000
|
||||
#define chipMinorFeatures3_TX_ENHANCEMENTS1 0x00080000
|
||||
#define chipMinorFeatures3_SH_ENHANCEMENTS1 0x00100000
|
||||
#define chipMinorFeatures3_SH_ENHANCEMENTS2 0x00200000
|
||||
#define chipMinorFeatures3_UNK22 0x00400000
|
||||
#define chipMinorFeatures3_2D_FC_SOURCE 0x00800000
|
||||
#define chipMinorFeatures3_UNK24 0x01000000
|
||||
#define chipMinorFeatures3_UNK25 0x02000000
|
||||
#define chipMinorFeatures3_NEW_HZ 0x04000000
|
||||
#define chipMinorFeatures3_UNK27 0x08000000
|
||||
#define chipMinorFeatures3_UNK28 0x10000000
|
||||
#define chipMinorFeatures3_SH_ENHANCEMENTS3 0x20000000
|
||||
#define chipMinorFeatures3_UNK30 0x40000000
|
||||
#define chipMinorFeatures3_UNK31 0x80000000
|
||||
#define chipMinorFeatures4_UNK0 0x00000001
|
||||
#define chipMinorFeatures4_PE_ENHANCEMENTS2 0x00000002
|
||||
#define chipMinorFeatures4_FRUSTUM_CLIP_FIX 0x00000004
|
||||
#define chipMinorFeatures4_UNK3 0x00000008
|
||||
#define chipMinorFeatures4_UNK4 0x00000010
|
||||
#define chipMinorFeatures4_2D_GAMMA 0x00000020
|
||||
#define chipMinorFeatures4_SINGLE_BUFFER 0x00000040
|
||||
#define chipMinorFeatures4_UNK7 0x00000080
|
||||
#define chipMinorFeatures4_UNK8 0x00000100
|
||||
#define chipMinorFeatures4_UNK9 0x00000200
|
||||
#define chipMinorFeatures4_UNK10 0x00000400
|
||||
#define chipMinorFeatures4_TX_LERP_PRECISION_FIX 0x00000800
|
||||
#define chipMinorFeatures4_2D_COLOR_SPACE_CONVERSION 0x00001000
|
||||
#define chipMinorFeatures4_TEXTURE_ASTC 0x00002000
|
||||
#define chipMinorFeatures4_UNK14 0x00004000
|
||||
#define chipMinorFeatures4_UNK15 0x00008000
|
||||
#define chipMinorFeatures4_HALTI2 0x00010000
|
||||
#define chipMinorFeatures4_UNK17 0x00020000
|
||||
#define chipMinorFeatures4_SMALL_MSAA 0x00040000
|
||||
#define chipMinorFeatures4_UNK19 0x00080000
|
||||
#define chipMinorFeatures4_NEW_RA 0x00100000
|
||||
#define chipMinorFeatures4_2D_OPF_YUV_OUTPUT 0x00200000
|
||||
#define chipMinorFeatures4_2D_MULTI_SOURCE_BLT_EX2 0x00400000
|
||||
#define chipMinorFeatures4_NO_USER_CSC 0x00800000
|
||||
#define chipMinorFeatures4_ZFIXES 0x01000000
|
||||
#define chipMinorFeatures4_BUG_FIXES18 0x02000000
|
||||
#define chipMinorFeatures4_2D_COMPRESSION 0x04000000
|
||||
#define chipMinorFeatures4_PROBE 0x08000000
|
||||
#define chipMinorFeatures4_UNK28 0x10000000
|
||||
#define chipMinorFeatures4_2D_SUPER_TILE_VERSION 0x20000000
|
||||
#define chipMinorFeatures4_UNK30 0x40000000
|
||||
#define chipMinorFeatures4_UNK31 0x80000000
|
||||
#define chipMinorFeatures5_UNK0 0x00000001
|
||||
#define chipMinorFeatures5_UNK1 0x00000002
|
||||
#define chipMinorFeatures5_UNK2 0x00000004
|
||||
#define chipMinorFeatures5_UNK3 0x00000008
|
||||
#define chipMinorFeatures5_EEZ 0x00000010
|
||||
#define chipMinorFeatures5_UNK5 0x00000020
|
||||
#define chipMinorFeatures5_UNK6 0x00000040
|
||||
#define chipMinorFeatures5_UNK7 0x00000080
|
||||
#define chipMinorFeatures5_UNK8 0x00000100
|
||||
#define chipMinorFeatures5_HALTI3 0x00000200
|
||||
#define chipMinorFeatures5_UNK10 0x00000400
|
||||
#define chipMinorFeatures5_2D_ONE_PASS_FILTER_TAP 0x00000800
|
||||
#define chipMinorFeatures5_UNK12 0x00001000
|
||||
#define chipMinorFeatures5_SEPARATE_SRC_DST 0x00002000
|
||||
#define chipMinorFeatures5_HALTI4 0x00004000
|
||||
#define chipMinorFeatures5_UNK15 0x00008000
|
||||
#define chipMinorFeatures5_ANDROID_ONLY 0x00010000
|
||||
#define chipMinorFeatures5_HAS_PRODUCTID 0x00020000
|
||||
#define chipMinorFeatures5_UNK18 0x00040000
|
||||
#define chipMinorFeatures5_UNK19 0x00080000
|
||||
#define chipMinorFeatures5_PE_DITHER_FIX2 0x00100000
|
||||
#define chipMinorFeatures5_UNK21 0x00200000
|
||||
#define chipMinorFeatures5_UNK22 0x00400000
|
||||
#define chipMinorFeatures5_UNK23 0x00800000
|
||||
#define chipMinorFeatures5_UNK24 0x01000000
|
||||
#define chipMinorFeatures5_UNK25 0x02000000
|
||||
#define chipMinorFeatures5_UNK26 0x04000000
|
||||
#define chipMinorFeatures5_RS_DEPTHSTENCIL_NATIVE_SUPPORT 0x08000000
|
||||
#define chipMinorFeatures5_V2_MSAA_COMP_FIX 0x10000000
|
||||
#define chipMinorFeatures5_UNK29 0x20000000
|
||||
#define chipMinorFeatures5_UNK30 0x40000000
|
||||
#define chipMinorFeatures5_UNK31 0x80000000
|
||||
|
||||
#endif /* COMMON_XML */
|
|
@ -0,0 +1,239 @@
|
|||
#ifndef ISA_XML
|
||||
#define ISA_XML
|
||||
|
||||
/* Autogenerated file, DO NOT EDIT manually!
|
||||
|
||||
This file was generated by the rules-ng-ng headergen tool in this git repository:
|
||||
http://0x04.net/cgit/index.cgi/rules-ng-ng
|
||||
git clone git://0x04.net/rules-ng-ng
|
||||
|
||||
The rules-ng-ng source files this header was generated from are:
|
||||
- isa.xml ( 24392 bytes, from 2016-11-16 18:54:37)
|
||||
- copyright.xml ( 1597 bytes, from 2016-10-02 14:26:13)
|
||||
|
||||
Copyright (C) 2012-2016 by the following authors:
|
||||
- Wladimir J. van der Laan <laanwj@gmail.com>
|
||||
- Christian Gmeiner <christian.gmeiner@gmail.com>
|
||||
- Lucas Stach <l.stach@pengutronix.de>
|
||||
- Russell King <rmk@arm.linux.org.uk>
|
||||
|
||||
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, sub license,
|
||||
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 NON-INFRINGEMENT. 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.
|
||||
*/
|
||||
|
||||
|
||||
#define INST_OPCODE_NOP 0x00000000
|
||||
#define INST_OPCODE_ADD 0x00000001
|
||||
#define INST_OPCODE_MAD 0x00000002
|
||||
#define INST_OPCODE_MUL 0x00000003
|
||||
#define INST_OPCODE_DST 0x00000004
|
||||
#define INST_OPCODE_DP3 0x00000005
|
||||
#define INST_OPCODE_DP4 0x00000006
|
||||
#define INST_OPCODE_DSX 0x00000007
|
||||
#define INST_OPCODE_DSY 0x00000008
|
||||
#define INST_OPCODE_MOV 0x00000009
|
||||
#define INST_OPCODE_MOVAR 0x0000000a
|
||||
#define INST_OPCODE_MOVAF 0x0000000b
|
||||
#define INST_OPCODE_RCP 0x0000000c
|
||||
#define INST_OPCODE_RSQ 0x0000000d
|
||||
#define INST_OPCODE_LITP 0x0000000e
|
||||
#define INST_OPCODE_SELECT 0x0000000f
|
||||
#define INST_OPCODE_SET 0x00000010
|
||||
#define INST_OPCODE_EXP 0x00000011
|
||||
#define INST_OPCODE_LOG 0x00000012
|
||||
#define INST_OPCODE_FRC 0x00000013
|
||||
#define INST_OPCODE_CALL 0x00000014
|
||||
#define INST_OPCODE_RET 0x00000015
|
||||
#define INST_OPCODE_BRANCH 0x00000016
|
||||
#define INST_OPCODE_TEXKILL 0x00000017
|
||||
#define INST_OPCODE_TEXLD 0x00000018
|
||||
#define INST_OPCODE_TEXLDB 0x00000019
|
||||
#define INST_OPCODE_TEXLDD 0x0000001a
|
||||
#define INST_OPCODE_TEXLDL 0x0000001b
|
||||
#define INST_OPCODE_TEXLDPCF 0x0000001c
|
||||
#define INST_OPCODE_REP 0x0000001d
|
||||
#define INST_OPCODE_ENDREP 0x0000001e
|
||||
#define INST_OPCODE_LOOP 0x0000001f
|
||||
#define INST_OPCODE_ENDLOOP 0x00000020
|
||||
#define INST_OPCODE_SQRT 0x00000021
|
||||
#define INST_OPCODE_SIN 0x00000022
|
||||
#define INST_OPCODE_COS 0x00000023
|
||||
#define INST_OPCODE_FLOOR 0x00000025
|
||||
#define INST_OPCODE_CEIL 0x00000026
|
||||
#define INST_OPCODE_SIGN 0x00000027
|
||||
#define INST_OPCODE_I2F 0x0000002d
|
||||
#define INST_OPCODE_CMP 0x00000031
|
||||
#define INST_OPCODE_LOAD 0x00000032
|
||||
#define INST_OPCODE_STORE 0x00000033
|
||||
#define INST_OPCODE_IMULLO0 0x0000003c
|
||||
#define INST_OPCODE_IMULHI0 0x00000040
|
||||
#define INST_OPCODE_IMADLO0 0x0000004c
|
||||
#define INST_OPCODE_LEADZERO 0x00000058
|
||||
#define INST_OPCODE_LSHIFT 0x00000059
|
||||
#define INST_OPCODE_RSHIFT 0x0000005a
|
||||
#define INST_OPCODE_ROTATE 0x0000005b
|
||||
#define INST_OPCODE_OR 0x0000005c
|
||||
#define INST_OPCODE_AND 0x0000005d
|
||||
#define INST_OPCODE_XOR 0x0000005e
|
||||
#define INST_OPCODE_NOT 0x0000005f
|
||||
#define INST_CONDITION_TRUE 0x00000000
|
||||
#define INST_CONDITION_GT 0x00000001
|
||||
#define INST_CONDITION_LT 0x00000002
|
||||
#define INST_CONDITION_GE 0x00000003
|
||||
#define INST_CONDITION_LE 0x00000004
|
||||
#define INST_CONDITION_EQ 0x00000005
|
||||
#define INST_CONDITION_NE 0x00000006
|
||||
#define INST_CONDITION_AND 0x00000007
|
||||
#define INST_CONDITION_OR 0x00000008
|
||||
#define INST_CONDITION_XOR 0x00000009
|
||||
#define INST_CONDITION_NOT 0x0000000a
|
||||
#define INST_CONDITION_NZ 0x0000000b
|
||||
#define INST_CONDITION_GEZ 0x0000000c
|
||||
#define INST_CONDITION_GZ 0x0000000d
|
||||
#define INST_CONDITION_LEZ 0x0000000e
|
||||
#define INST_CONDITION_LZ 0x0000000f
|
||||
#define INST_RGROUP_TEMP 0x00000000
|
||||
#define INST_RGROUP_INTERNAL 0x00000001
|
||||
#define INST_RGROUP_UNIFORM_0 0x00000002
|
||||
#define INST_RGROUP_UNIFORM_1 0x00000003
|
||||
#define INST_AMODE_DIRECT 0x00000000
|
||||
#define INST_AMODE_ADD_A_X 0x00000001
|
||||
#define INST_AMODE_ADD_A_Y 0x00000002
|
||||
#define INST_AMODE_ADD_A_Z 0x00000003
|
||||
#define INST_AMODE_ADD_A_W 0x00000004
|
||||
#define INST_SWIZ_COMP_X 0x00000000
|
||||
#define INST_SWIZ_COMP_Y 0x00000001
|
||||
#define INST_SWIZ_COMP_Z 0x00000002
|
||||
#define INST_SWIZ_COMP_W 0x00000003
|
||||
#define INST_TYPE_F32 0x00000000
|
||||
#define INST_TYPE_S32 0x00000001
|
||||
#define INST_TYPE_S8 0x00000002
|
||||
#define INST_TYPE_U16 0x00000003
|
||||
#define INST_TYPE_F16 0x00000004
|
||||
#define INST_TYPE_S16 0x00000005
|
||||
#define INST_TYPE_U32 0x00000006
|
||||
#define INST_TYPE_U8 0x00000007
|
||||
#define INST_COMPS_X 0x00000001
|
||||
#define INST_COMPS_Y 0x00000002
|
||||
#define INST_COMPS_Z 0x00000004
|
||||
#define INST_COMPS_W 0x00000008
|
||||
#define INST_SWIZ_X__MASK 0x00000003
|
||||
#define INST_SWIZ_X__SHIFT 0
|
||||
#define INST_SWIZ_X(x) (((x) << INST_SWIZ_X__SHIFT) & INST_SWIZ_X__MASK)
|
||||
#define INST_SWIZ_Y__MASK 0x0000000c
|
||||
#define INST_SWIZ_Y__SHIFT 2
|
||||
#define INST_SWIZ_Y(x) (((x) << INST_SWIZ_Y__SHIFT) & INST_SWIZ_Y__MASK)
|
||||
#define INST_SWIZ_Z__MASK 0x00000030
|
||||
#define INST_SWIZ_Z__SHIFT 4
|
||||
#define INST_SWIZ_Z(x) (((x) << INST_SWIZ_Z__SHIFT) & INST_SWIZ_Z__MASK)
|
||||
#define INST_SWIZ_W__MASK 0x000000c0
|
||||
#define INST_SWIZ_W__SHIFT 6
|
||||
#define INST_SWIZ_W(x) (((x) << INST_SWIZ_W__SHIFT) & INST_SWIZ_W__MASK)
|
||||
#define VIV_ISA_WORD_0 0x00000000
|
||||
#define VIV_ISA_WORD_0_OPCODE__MASK 0x0000003f
|
||||
#define VIV_ISA_WORD_0_OPCODE__SHIFT 0
|
||||
#define VIV_ISA_WORD_0_OPCODE(x) (((x) << VIV_ISA_WORD_0_OPCODE__SHIFT) & VIV_ISA_WORD_0_OPCODE__MASK)
|
||||
#define VIV_ISA_WORD_0_COND__MASK 0x000007c0
|
||||
#define VIV_ISA_WORD_0_COND__SHIFT 6
|
||||
#define VIV_ISA_WORD_0_COND(x) (((x) << VIV_ISA_WORD_0_COND__SHIFT) & VIV_ISA_WORD_0_COND__MASK)
|
||||
#define VIV_ISA_WORD_0_SAT 0x00000800
|
||||
#define VIV_ISA_WORD_0_DST_USE 0x00001000
|
||||
#define VIV_ISA_WORD_0_DST_AMODE__MASK 0x0000e000
|
||||
#define VIV_ISA_WORD_0_DST_AMODE__SHIFT 13
|
||||
#define VIV_ISA_WORD_0_DST_AMODE(x) (((x) << VIV_ISA_WORD_0_DST_AMODE__SHIFT) & VIV_ISA_WORD_0_DST_AMODE__MASK)
|
||||
#define VIV_ISA_WORD_0_DST_REG__MASK 0x007f0000
|
||||
#define VIV_ISA_WORD_0_DST_REG__SHIFT 16
|
||||
#define VIV_ISA_WORD_0_DST_REG(x) (((x) << VIV_ISA_WORD_0_DST_REG__SHIFT) & VIV_ISA_WORD_0_DST_REG__MASK)
|
||||
#define VIV_ISA_WORD_0_DST_COMPS__MASK 0x07800000
|
||||
#define VIV_ISA_WORD_0_DST_COMPS__SHIFT 23
|
||||
#define VIV_ISA_WORD_0_DST_COMPS(x) (((x) << VIV_ISA_WORD_0_DST_COMPS__SHIFT) & VIV_ISA_WORD_0_DST_COMPS__MASK)
|
||||
#define VIV_ISA_WORD_0_TEX_ID__MASK 0xf8000000
|
||||
#define VIV_ISA_WORD_0_TEX_ID__SHIFT 27
|
||||
#define VIV_ISA_WORD_0_TEX_ID(x) (((x) << VIV_ISA_WORD_0_TEX_ID__SHIFT) & VIV_ISA_WORD_0_TEX_ID__MASK)
|
||||
|
||||
#define VIV_ISA_WORD_1 0x00000004
|
||||
#define VIV_ISA_WORD_1_TEX_AMODE__MASK 0x00000007
|
||||
#define VIV_ISA_WORD_1_TEX_AMODE__SHIFT 0
|
||||
#define VIV_ISA_WORD_1_TEX_AMODE(x) (((x) << VIV_ISA_WORD_1_TEX_AMODE__SHIFT) & VIV_ISA_WORD_1_TEX_AMODE__MASK)
|
||||
#define VIV_ISA_WORD_1_TEX_SWIZ__MASK 0x000007f8
|
||||
#define VIV_ISA_WORD_1_TEX_SWIZ__SHIFT 3
|
||||
#define VIV_ISA_WORD_1_TEX_SWIZ(x) (((x) << VIV_ISA_WORD_1_TEX_SWIZ__SHIFT) & VIV_ISA_WORD_1_TEX_SWIZ__MASK)
|
||||
#define VIV_ISA_WORD_1_SRC0_USE 0x00000800
|
||||
#define VIV_ISA_WORD_1_SRC0_REG__MASK 0x001ff000
|
||||
#define VIV_ISA_WORD_1_SRC0_REG__SHIFT 12
|
||||
#define VIV_ISA_WORD_1_SRC0_REG(x) (((x) << VIV_ISA_WORD_1_SRC0_REG__SHIFT) & VIV_ISA_WORD_1_SRC0_REG__MASK)
|
||||
#define VIV_ISA_WORD_1_TYPE_BIT2 0x00200000
|
||||
#define VIV_ISA_WORD_1_SRC0_SWIZ__MASK 0x3fc00000
|
||||
#define VIV_ISA_WORD_1_SRC0_SWIZ__SHIFT 22
|
||||
#define VIV_ISA_WORD_1_SRC0_SWIZ(x) (((x) << VIV_ISA_WORD_1_SRC0_SWIZ__SHIFT) & VIV_ISA_WORD_1_SRC0_SWIZ__MASK)
|
||||
#define VIV_ISA_WORD_1_SRC0_NEG 0x40000000
|
||||
#define VIV_ISA_WORD_1_SRC0_ABS 0x80000000
|
||||
|
||||
#define VIV_ISA_WORD_2 0x00000008
|
||||
#define VIV_ISA_WORD_2_SRC0_AMODE__MASK 0x00000007
|
||||
#define VIV_ISA_WORD_2_SRC0_AMODE__SHIFT 0
|
||||
#define VIV_ISA_WORD_2_SRC0_AMODE(x) (((x) << VIV_ISA_WORD_2_SRC0_AMODE__SHIFT) & VIV_ISA_WORD_2_SRC0_AMODE__MASK)
|
||||
#define VIV_ISA_WORD_2_SRC0_RGROUP__MASK 0x00000038
|
||||
#define VIV_ISA_WORD_2_SRC0_RGROUP__SHIFT 3
|
||||
#define VIV_ISA_WORD_2_SRC0_RGROUP(x) (((x) << VIV_ISA_WORD_2_SRC0_RGROUP__SHIFT) & VIV_ISA_WORD_2_SRC0_RGROUP__MASK)
|
||||
#define VIV_ISA_WORD_2_SRC1_USE 0x00000040
|
||||
#define VIV_ISA_WORD_2_SRC1_REG__MASK 0x0000ff80
|
||||
#define VIV_ISA_WORD_2_SRC1_REG__SHIFT 7
|
||||
#define VIV_ISA_WORD_2_SRC1_REG(x) (((x) << VIV_ISA_WORD_2_SRC1_REG__SHIFT) & VIV_ISA_WORD_2_SRC1_REG__MASK)
|
||||
#define VIV_ISA_WORD_2_OPCODE_BIT6 0x00010000
|
||||
#define VIV_ISA_WORD_2_SRC1_SWIZ__MASK 0x01fe0000
|
||||
#define VIV_ISA_WORD_2_SRC1_SWIZ__SHIFT 17
|
||||
#define VIV_ISA_WORD_2_SRC1_SWIZ(x) (((x) << VIV_ISA_WORD_2_SRC1_SWIZ__SHIFT) & VIV_ISA_WORD_2_SRC1_SWIZ__MASK)
|
||||
#define VIV_ISA_WORD_2_SRC1_NEG 0x02000000
|
||||
#define VIV_ISA_WORD_2_SRC1_ABS 0x04000000
|
||||
#define VIV_ISA_WORD_2_SRC1_AMODE__MASK 0x38000000
|
||||
#define VIV_ISA_WORD_2_SRC1_AMODE__SHIFT 27
|
||||
#define VIV_ISA_WORD_2_SRC1_AMODE(x) (((x) << VIV_ISA_WORD_2_SRC1_AMODE__SHIFT) & VIV_ISA_WORD_2_SRC1_AMODE__MASK)
|
||||
#define VIV_ISA_WORD_2_TYPE_BIT01__MASK 0xc0000000
|
||||
#define VIV_ISA_WORD_2_TYPE_BIT01__SHIFT 30
|
||||
#define VIV_ISA_WORD_2_TYPE_BIT01(x) (((x) << VIV_ISA_WORD_2_TYPE_BIT01__SHIFT) & VIV_ISA_WORD_2_TYPE_BIT01__MASK)
|
||||
|
||||
#define VIV_ISA_WORD_3 0x0000000c
|
||||
#define VIV_ISA_WORD_3_SRC1_RGROUP__MASK 0x00000007
|
||||
#define VIV_ISA_WORD_3_SRC1_RGROUP__SHIFT 0
|
||||
#define VIV_ISA_WORD_3_SRC1_RGROUP(x) (((x) << VIV_ISA_WORD_3_SRC1_RGROUP__SHIFT) & VIV_ISA_WORD_3_SRC1_RGROUP__MASK)
|
||||
#define VIV_ISA_WORD_3_SRC2_IMM__MASK 0x003fff80
|
||||
#define VIV_ISA_WORD_3_SRC2_IMM__SHIFT 7
|
||||
#define VIV_ISA_WORD_3_SRC2_IMM(x) (((x) << VIV_ISA_WORD_3_SRC2_IMM__SHIFT) & VIV_ISA_WORD_3_SRC2_IMM__MASK)
|
||||
#define VIV_ISA_WORD_3_SRC2_USE 0x00000008
|
||||
#define VIV_ISA_WORD_3_SRC2_REG__MASK 0x00001ff0
|
||||
#define VIV_ISA_WORD_3_SRC2_REG__SHIFT 4
|
||||
#define VIV_ISA_WORD_3_SRC2_REG(x) (((x) << VIV_ISA_WORD_3_SRC2_REG__SHIFT) & VIV_ISA_WORD_3_SRC2_REG__MASK)
|
||||
#define VIV_ISA_WORD_3_UNK3_13 0x00002000
|
||||
#define VIV_ISA_WORD_3_SRC2_SWIZ__MASK 0x003fc000
|
||||
#define VIV_ISA_WORD_3_SRC2_SWIZ__SHIFT 14
|
||||
#define VIV_ISA_WORD_3_SRC2_SWIZ(x) (((x) << VIV_ISA_WORD_3_SRC2_SWIZ__SHIFT) & VIV_ISA_WORD_3_SRC2_SWIZ__MASK)
|
||||
#define VIV_ISA_WORD_3_SRC2_NEG 0x00400000
|
||||
#define VIV_ISA_WORD_3_SRC2_ABS 0x00800000
|
||||
#define VIV_ISA_WORD_3_UNK3_24 0x01000000
|
||||
#define VIV_ISA_WORD_3_SRC2_AMODE__MASK 0x0e000000
|
||||
#define VIV_ISA_WORD_3_SRC2_AMODE__SHIFT 25
|
||||
#define VIV_ISA_WORD_3_SRC2_AMODE(x) (((x) << VIV_ISA_WORD_3_SRC2_AMODE__SHIFT) & VIV_ISA_WORD_3_SRC2_AMODE__MASK)
|
||||
#define VIV_ISA_WORD_3_SRC2_RGROUP__MASK 0x70000000
|
||||
#define VIV_ISA_WORD_3_SRC2_RGROUP__SHIFT 28
|
||||
#define VIV_ISA_WORD_3_SRC2_RGROUP(x) (((x) << VIV_ISA_WORD_3_SRC2_RGROUP__SHIFT) & VIV_ISA_WORD_3_SRC2_RGROUP__MASK)
|
||||
#define VIV_ISA_WORD_3_UNK3_31 0x80000000
|
||||
|
||||
|
||||
#endif /* ISA_XML */
|
|
@ -0,0 +1,397 @@
|
|||
#ifndef STATE_XML
|
||||
#define STATE_XML
|
||||
|
||||
/* Autogenerated file, DO NOT EDIT manually!
|
||||
|
||||
This file was generated by the rules-ng-ng headergen tool in this git repository:
|
||||
http://0x04.net/cgit/index.cgi/rules-ng-ng
|
||||
git clone git://0x04.net/rules-ng-ng
|
||||
|
||||
The rules-ng-ng source files this header was generated from are:
|
||||
- state.xml ( 19792 bytes, from 2016-11-16 18:54:37)
|
||||
- common.xml ( 23422 bytes, from 2016-11-16 18:54:37)
|
||||
- state_hi.xml ( 25653 bytes, from 2016-10-02 14:26:13)
|
||||
- copyright.xml ( 1597 bytes, from 2016-10-02 14:26:13)
|
||||
- state_2d.xml ( 51552 bytes, from 2016-10-02 14:26:13)
|
||||
- state_3d.xml ( 57579 bytes, from 2016-11-16 18:54:37)
|
||||
- state_vg.xml ( 5975 bytes, from 2016-10-02 14:26:13)
|
||||
|
||||
Copyright (C) 2012-2016 by the following authors:
|
||||
- Wladimir J. van der Laan <laanwj@gmail.com>
|
||||
- Christian Gmeiner <christian.gmeiner@gmail.com>
|
||||
- Lucas Stach <l.stach@pengutronix.de>
|
||||
- Russell King <rmk@arm.linux.org.uk>
|
||||
|
||||
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, sub license,
|
||||
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 NON-INFRINGEMENT. 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.
|
||||
*/
|
||||
|
||||
|
||||
#define VARYING_COMPONENT_USE_UNUSED 0x00000000
|
||||
#define VARYING_COMPONENT_USE_USED 0x00000001
|
||||
#define VARYING_COMPONENT_USE_POINTCOORD_X 0x00000002
|
||||
#define VARYING_COMPONENT_USE_POINTCOORD_Y 0x00000003
|
||||
#define FE_VERTEX_STREAM_CONTROL_VERTEX_STRIDE__MASK 0x000000ff
|
||||
#define FE_VERTEX_STREAM_CONTROL_VERTEX_STRIDE__SHIFT 0
|
||||
#define FE_VERTEX_STREAM_CONTROL_VERTEX_STRIDE(x) (((x) << FE_VERTEX_STREAM_CONTROL_VERTEX_STRIDE__SHIFT) & FE_VERTEX_STREAM_CONTROL_VERTEX_STRIDE__MASK)
|
||||
#define FE_VERTEX_STREAM_CONTROL_VERTEX_DIVISOR__MASK 0x00ff0000
|
||||
#define FE_VERTEX_STREAM_CONTROL_VERTEX_DIVISOR__SHIFT 16
|
||||
#define FE_VERTEX_STREAM_CONTROL_VERTEX_DIVISOR(x) (((x) << FE_VERTEX_STREAM_CONTROL_VERTEX_DIVISOR__SHIFT) & FE_VERTEX_STREAM_CONTROL_VERTEX_DIVISOR__MASK)
|
||||
#define VIVS_FE 0x00000000
|
||||
|
||||
#define VIVS_FE_VERTEX_ELEMENT_CONFIG(i0) (0x00000600 + 0x4*(i0))
|
||||
#define VIVS_FE_VERTEX_ELEMENT_CONFIG__ESIZE 0x00000004
|
||||
#define VIVS_FE_VERTEX_ELEMENT_CONFIG__LEN 0x00000010
|
||||
#define VIVS_FE_VERTEX_ELEMENT_CONFIG_TYPE__MASK 0x0000000f
|
||||
#define VIVS_FE_VERTEX_ELEMENT_CONFIG_TYPE__SHIFT 0
|
||||
#define VIVS_FE_VERTEX_ELEMENT_CONFIG_TYPE_BYTE 0x00000000
|
||||
#define VIVS_FE_VERTEX_ELEMENT_CONFIG_TYPE_UNSIGNED_BYTE 0x00000001
|
||||
#define VIVS_FE_VERTEX_ELEMENT_CONFIG_TYPE_SHORT 0x00000002
|
||||
#define VIVS_FE_VERTEX_ELEMENT_CONFIG_TYPE_UNSIGNED_SHORT 0x00000003
|
||||
#define VIVS_FE_VERTEX_ELEMENT_CONFIG_TYPE_INT 0x00000004
|
||||
#define VIVS_FE_VERTEX_ELEMENT_CONFIG_TYPE_UNSIGNED_INT 0x00000005
|
||||
#define VIVS_FE_VERTEX_ELEMENT_CONFIG_TYPE_FLOAT 0x00000008
|
||||
#define VIVS_FE_VERTEX_ELEMENT_CONFIG_TYPE_HALF_FLOAT 0x00000009
|
||||
#define VIVS_FE_VERTEX_ELEMENT_CONFIG_TYPE_FIXED 0x0000000b
|
||||
#define VIVS_FE_VERTEX_ELEMENT_CONFIG_TYPE_INT_10_10_10_2 0x0000000c
|
||||
#define VIVS_FE_VERTEX_ELEMENT_CONFIG_TYPE_UNSIGNED_INT_10_10_10_2 0x0000000d
|
||||
#define VIVS_FE_VERTEX_ELEMENT_CONFIG_ENDIAN__MASK 0x00000030
|
||||
#define VIVS_FE_VERTEX_ELEMENT_CONFIG_ENDIAN__SHIFT 4
|
||||
#define VIVS_FE_VERTEX_ELEMENT_CONFIG_ENDIAN(x) (((x) << VIVS_FE_VERTEX_ELEMENT_CONFIG_ENDIAN__SHIFT) & VIVS_FE_VERTEX_ELEMENT_CONFIG_ENDIAN__MASK)
|
||||
#define VIVS_FE_VERTEX_ELEMENT_CONFIG_NONCONSECUTIVE 0x00000080
|
||||
#define VIVS_FE_VERTEX_ELEMENT_CONFIG_STREAM__MASK 0x00000700
|
||||
#define VIVS_FE_VERTEX_ELEMENT_CONFIG_STREAM__SHIFT 8
|
||||
#define VIVS_FE_VERTEX_ELEMENT_CONFIG_STREAM(x) (((x) << VIVS_FE_VERTEX_ELEMENT_CONFIG_STREAM__SHIFT) & VIVS_FE_VERTEX_ELEMENT_CONFIG_STREAM__MASK)
|
||||
#define VIVS_FE_VERTEX_ELEMENT_CONFIG_NUM__MASK 0x00003000
|
||||
#define VIVS_FE_VERTEX_ELEMENT_CONFIG_NUM__SHIFT 12
|
||||
#define VIVS_FE_VERTEX_ELEMENT_CONFIG_NUM(x) (((x) << VIVS_FE_VERTEX_ELEMENT_CONFIG_NUM__SHIFT) & VIVS_FE_VERTEX_ELEMENT_CONFIG_NUM__MASK)
|
||||
#define VIVS_FE_VERTEX_ELEMENT_CONFIG_NORMALIZE__MASK 0x0000c000
|
||||
#define VIVS_FE_VERTEX_ELEMENT_CONFIG_NORMALIZE__SHIFT 14
|
||||
#define VIVS_FE_VERTEX_ELEMENT_CONFIG_NORMALIZE_OFF 0x00000000
|
||||
#define VIVS_FE_VERTEX_ELEMENT_CONFIG_NORMALIZE_ON 0x00008000
|
||||
#define VIVS_FE_VERTEX_ELEMENT_CONFIG_START__MASK 0x00ff0000
|
||||
#define VIVS_FE_VERTEX_ELEMENT_CONFIG_START__SHIFT 16
|
||||
#define VIVS_FE_VERTEX_ELEMENT_CONFIG_START(x) (((x) << VIVS_FE_VERTEX_ELEMENT_CONFIG_START__SHIFT) & VIVS_FE_VERTEX_ELEMENT_CONFIG_START__MASK)
|
||||
#define VIVS_FE_VERTEX_ELEMENT_CONFIG_END__MASK 0xff000000
|
||||
#define VIVS_FE_VERTEX_ELEMENT_CONFIG_END__SHIFT 24
|
||||
#define VIVS_FE_VERTEX_ELEMENT_CONFIG_END(x) (((x) << VIVS_FE_VERTEX_ELEMENT_CONFIG_END__SHIFT) & VIVS_FE_VERTEX_ELEMENT_CONFIG_END__MASK)
|
||||
|
||||
#define VIVS_FE_CMD_STREAM_BASE_ADDR 0x00000640
|
||||
|
||||
#define VIVS_FE_INDEX_STREAM_BASE_ADDR 0x00000644
|
||||
|
||||
#define VIVS_FE_INDEX_STREAM_CONTROL 0x00000648
|
||||
#define VIVS_FE_INDEX_STREAM_CONTROL_TYPE__MASK 0x00000003
|
||||
#define VIVS_FE_INDEX_STREAM_CONTROL_TYPE__SHIFT 0
|
||||
#define VIVS_FE_INDEX_STREAM_CONTROL_TYPE_UNSIGNED_CHAR 0x00000000
|
||||
#define VIVS_FE_INDEX_STREAM_CONTROL_TYPE_UNSIGNED_SHORT 0x00000001
|
||||
#define VIVS_FE_INDEX_STREAM_CONTROL_TYPE_UNSIGNED_INT 0x00000002
|
||||
#define VIVS_FE_INDEX_STREAM_CONTROL_PRIMITIVE_RESTART 0x00000100
|
||||
|
||||
#define VIVS_FE_VERTEX_STREAM_BASE_ADDR 0x0000064c
|
||||
|
||||
#define VIVS_FE_VERTEX_STREAM_CONTROL 0x00000650
|
||||
|
||||
#define VIVS_FE_COMMAND_ADDRESS 0x00000654
|
||||
|
||||
#define VIVS_FE_COMMAND_CONTROL 0x00000658
|
||||
#define VIVS_FE_COMMAND_CONTROL_PREFETCH__MASK 0x0000ffff
|
||||
#define VIVS_FE_COMMAND_CONTROL_PREFETCH__SHIFT 0
|
||||
#define VIVS_FE_COMMAND_CONTROL_PREFETCH(x) (((x) << VIVS_FE_COMMAND_CONTROL_PREFETCH__SHIFT) & VIVS_FE_COMMAND_CONTROL_PREFETCH__MASK)
|
||||
#define VIVS_FE_COMMAND_CONTROL_ENABLE 0x00010000
|
||||
|
||||
#define VIVS_FE_DMA_STATUS 0x0000065c
|
||||
|
||||
#define VIVS_FE_DMA_DEBUG_STATE 0x00000660
|
||||
#define VIVS_FE_DMA_DEBUG_STATE_CMD_STATE__MASK 0x0000001f
|
||||
#define VIVS_FE_DMA_DEBUG_STATE_CMD_STATE__SHIFT 0
|
||||
#define VIVS_FE_DMA_DEBUG_STATE_CMD_STATE_IDLE 0x00000000
|
||||
#define VIVS_FE_DMA_DEBUG_STATE_CMD_STATE_DEC 0x00000001
|
||||
#define VIVS_FE_DMA_DEBUG_STATE_CMD_STATE_ADR0 0x00000002
|
||||
#define VIVS_FE_DMA_DEBUG_STATE_CMD_STATE_LOAD0 0x00000003
|
||||
#define VIVS_FE_DMA_DEBUG_STATE_CMD_STATE_ADR1 0x00000004
|
||||
#define VIVS_FE_DMA_DEBUG_STATE_CMD_STATE_LOAD1 0x00000005
|
||||
#define VIVS_FE_DMA_DEBUG_STATE_CMD_STATE_3DADR 0x00000006
|
||||
#define VIVS_FE_DMA_DEBUG_STATE_CMD_STATE_3DCMD 0x00000007
|
||||
#define VIVS_FE_DMA_DEBUG_STATE_CMD_STATE_3DCNTL 0x00000008
|
||||
#define VIVS_FE_DMA_DEBUG_STATE_CMD_STATE_3DIDXCNTL 0x00000009
|
||||
#define VIVS_FE_DMA_DEBUG_STATE_CMD_STATE_INITREQDMA 0x0000000a
|
||||
#define VIVS_FE_DMA_DEBUG_STATE_CMD_STATE_DRAWIDX 0x0000000b
|
||||
#define VIVS_FE_DMA_DEBUG_STATE_CMD_STATE_DRAW 0x0000000c
|
||||
#define VIVS_FE_DMA_DEBUG_STATE_CMD_STATE_2DRECT0 0x0000000d
|
||||
#define VIVS_FE_DMA_DEBUG_STATE_CMD_STATE_2DRECT1 0x0000000e
|
||||
#define VIVS_FE_DMA_DEBUG_STATE_CMD_STATE_2DDATA0 0x0000000f
|
||||
#define VIVS_FE_DMA_DEBUG_STATE_CMD_STATE_2DDATA1 0x00000010
|
||||
#define VIVS_FE_DMA_DEBUG_STATE_CMD_STATE_WAITFIFO 0x00000011
|
||||
#define VIVS_FE_DMA_DEBUG_STATE_CMD_STATE_WAIT 0x00000012
|
||||
#define VIVS_FE_DMA_DEBUG_STATE_CMD_STATE_LINK 0x00000013
|
||||
#define VIVS_FE_DMA_DEBUG_STATE_CMD_STATE_END 0x00000014
|
||||
#define VIVS_FE_DMA_DEBUG_STATE_CMD_STATE_STALL 0x00000015
|
||||
#define VIVS_FE_DMA_DEBUG_STATE_CMD_DMA_STATE__MASK 0x00000300
|
||||
#define VIVS_FE_DMA_DEBUG_STATE_CMD_DMA_STATE__SHIFT 8
|
||||
#define VIVS_FE_DMA_DEBUG_STATE_CMD_DMA_STATE_IDLE 0x00000000
|
||||
#define VIVS_FE_DMA_DEBUG_STATE_CMD_DMA_STATE_START 0x00000100
|
||||
#define VIVS_FE_DMA_DEBUG_STATE_CMD_DMA_STATE_REQ 0x00000200
|
||||
#define VIVS_FE_DMA_DEBUG_STATE_CMD_DMA_STATE_END 0x00000300
|
||||
#define VIVS_FE_DMA_DEBUG_STATE_CMD_FETCH_STATE__MASK 0x00000c00
|
||||
#define VIVS_FE_DMA_DEBUG_STATE_CMD_FETCH_STATE__SHIFT 10
|
||||
#define VIVS_FE_DMA_DEBUG_STATE_CMD_FETCH_STATE_IDLE 0x00000000
|
||||
#define VIVS_FE_DMA_DEBUG_STATE_CMD_FETCH_STATE_RAMVALID 0x00000400
|
||||
#define VIVS_FE_DMA_DEBUG_STATE_CMD_FETCH_STATE_VALID 0x00000800
|
||||
#define VIVS_FE_DMA_DEBUG_STATE_REQ_DMA_STATE__MASK 0x00003000
|
||||
#define VIVS_FE_DMA_DEBUG_STATE_REQ_DMA_STATE__SHIFT 12
|
||||
#define VIVS_FE_DMA_DEBUG_STATE_REQ_DMA_STATE_IDLE 0x00000000
|
||||
#define VIVS_FE_DMA_DEBUG_STATE_REQ_DMA_STATE_WAITIDX 0x00001000
|
||||
#define VIVS_FE_DMA_DEBUG_STATE_REQ_DMA_STATE_CAL 0x00002000
|
||||
#define VIVS_FE_DMA_DEBUG_STATE_CAL_STATE__MASK 0x0000c000
|
||||
#define VIVS_FE_DMA_DEBUG_STATE_CAL_STATE__SHIFT 14
|
||||
#define VIVS_FE_DMA_DEBUG_STATE_CAL_STATE_IDLE 0x00000000
|
||||
#define VIVS_FE_DMA_DEBUG_STATE_CAL_STATE_LDADR 0x00004000
|
||||
#define VIVS_FE_DMA_DEBUG_STATE_CAL_STATE_IDXCALC 0x00008000
|
||||
#define VIVS_FE_DMA_DEBUG_STATE_VE_REQ_STATE__MASK 0x00030000
|
||||
#define VIVS_FE_DMA_DEBUG_STATE_VE_REQ_STATE__SHIFT 16
|
||||
#define VIVS_FE_DMA_DEBUG_STATE_VE_REQ_STATE_IDLE 0x00000000
|
||||
#define VIVS_FE_DMA_DEBUG_STATE_VE_REQ_STATE_CKCACHE 0x00010000
|
||||
#define VIVS_FE_DMA_DEBUG_STATE_VE_REQ_STATE_MISS 0x00020000
|
||||
|
||||
#define VIVS_FE_DMA_ADDRESS 0x00000664
|
||||
|
||||
#define VIVS_FE_DMA_LOW 0x00000668
|
||||
|
||||
#define VIVS_FE_DMA_HIGH 0x0000066c
|
||||
|
||||
#define VIVS_FE_AUTO_FLUSH 0x00000670
|
||||
|
||||
#define VIVS_FE_PRIMITIVE_RESTART_INDEX 0x00000674
|
||||
|
||||
#define VIVS_FE_UNK00678 0x00000678
|
||||
|
||||
#define VIVS_FE_UNK0067C 0x0000067c
|
||||
|
||||
#define VIVS_FE_VERTEX_STREAMS(i0) (0x00000000 + 0x4*(i0))
|
||||
#define VIVS_FE_VERTEX_STREAMS__ESIZE 0x00000004
|
||||
#define VIVS_FE_VERTEX_STREAMS__LEN 0x00000008
|
||||
|
||||
#define VIVS_FE_VERTEX_STREAMS_BASE_ADDR(i0) (0x00000680 + 0x4*(i0))
|
||||
|
||||
#define VIVS_FE_VERTEX_STREAMS_CONTROL(i0) (0x000006a0 + 0x4*(i0))
|
||||
|
||||
#define VIVS_FE_UNK00700(i0) (0x00000700 + 0x4*(i0))
|
||||
#define VIVS_FE_UNK00700__ESIZE 0x00000004
|
||||
#define VIVS_FE_UNK00700__LEN 0x00000010
|
||||
|
||||
#define VIVS_FE_UNK00740(i0) (0x00000740 + 0x4*(i0))
|
||||
#define VIVS_FE_UNK00740__ESIZE 0x00000004
|
||||
#define VIVS_FE_UNK00740__LEN 0x00000010
|
||||
|
||||
#define VIVS_FE_UNK00780(i0) (0x00000780 + 0x4*(i0))
|
||||
#define VIVS_FE_UNK00780__ESIZE 0x00000004
|
||||
#define VIVS_FE_UNK00780__LEN 0x00000010
|
||||
|
||||
#define VIVS_GL 0x00000000
|
||||
|
||||
#define VIVS_GL_PIPE_SELECT 0x00003800
|
||||
#define VIVS_GL_PIPE_SELECT_PIPE__MASK 0x00000001
|
||||
#define VIVS_GL_PIPE_SELECT_PIPE__SHIFT 0
|
||||
#define VIVS_GL_PIPE_SELECT_PIPE(x) (((x) << VIVS_GL_PIPE_SELECT_PIPE__SHIFT) & VIVS_GL_PIPE_SELECT_PIPE__MASK)
|
||||
|
||||
#define VIVS_GL_EVENT 0x00003804
|
||||
#define VIVS_GL_EVENT_EVENT_ID__MASK 0x0000001f
|
||||
#define VIVS_GL_EVENT_EVENT_ID__SHIFT 0
|
||||
#define VIVS_GL_EVENT_EVENT_ID(x) (((x) << VIVS_GL_EVENT_EVENT_ID__SHIFT) & VIVS_GL_EVENT_EVENT_ID__MASK)
|
||||
#define VIVS_GL_EVENT_FROM_FE 0x00000020
|
||||
#define VIVS_GL_EVENT_FROM_PE 0x00000040
|
||||
#define VIVS_GL_EVENT_SOURCE__MASK 0x00001f00
|
||||
#define VIVS_GL_EVENT_SOURCE__SHIFT 8
|
||||
#define VIVS_GL_EVENT_SOURCE(x) (((x) << VIVS_GL_EVENT_SOURCE__SHIFT) & VIVS_GL_EVENT_SOURCE__MASK)
|
||||
|
||||
#define VIVS_GL_SEMAPHORE_TOKEN 0x00003808
|
||||
#define VIVS_GL_SEMAPHORE_TOKEN_FROM__MASK 0x0000001f
|
||||
#define VIVS_GL_SEMAPHORE_TOKEN_FROM__SHIFT 0
|
||||
#define VIVS_GL_SEMAPHORE_TOKEN_FROM(x) (((x) << VIVS_GL_SEMAPHORE_TOKEN_FROM__SHIFT) & VIVS_GL_SEMAPHORE_TOKEN_FROM__MASK)
|
||||
#define VIVS_GL_SEMAPHORE_TOKEN_TO__MASK 0x00001f00
|
||||
#define VIVS_GL_SEMAPHORE_TOKEN_TO__SHIFT 8
|
||||
#define VIVS_GL_SEMAPHORE_TOKEN_TO(x) (((x) << VIVS_GL_SEMAPHORE_TOKEN_TO__SHIFT) & VIVS_GL_SEMAPHORE_TOKEN_TO__MASK)
|
||||
|
||||
#define VIVS_GL_FLUSH_CACHE 0x0000380c
|
||||
#define VIVS_GL_FLUSH_CACHE_DEPTH 0x00000001
|
||||
#define VIVS_GL_FLUSH_CACHE_COLOR 0x00000002
|
||||
#define VIVS_GL_FLUSH_CACHE_TEXTURE 0x00000004
|
||||
#define VIVS_GL_FLUSH_CACHE_PE2D 0x00000008
|
||||
#define VIVS_GL_FLUSH_CACHE_TEXTUREVS 0x00000010
|
||||
#define VIVS_GL_FLUSH_CACHE_SHADER_L1 0x00000020
|
||||
#define VIVS_GL_FLUSH_CACHE_SHADER_L2 0x00000040
|
||||
|
||||
#define VIVS_GL_FLUSH_MMU 0x00003810
|
||||
#define VIVS_GL_FLUSH_MMU_FLUSH_FEMMU 0x00000001
|
||||
#define VIVS_GL_FLUSH_MMU_FLUSH_UNK1 0x00000002
|
||||
#define VIVS_GL_FLUSH_MMU_FLUSH_UNK2 0x00000004
|
||||
#define VIVS_GL_FLUSH_MMU_FLUSH_PEMMU 0x00000008
|
||||
#define VIVS_GL_FLUSH_MMU_FLUSH_UNK4 0x00000010
|
||||
|
||||
#define VIVS_GL_VERTEX_ELEMENT_CONFIG 0x00003814
|
||||
|
||||
#define VIVS_GL_MULTI_SAMPLE_CONFIG 0x00003818
|
||||
#define VIVS_GL_MULTI_SAMPLE_CONFIG_MSAA_SAMPLES__MASK 0x00000003
|
||||
#define VIVS_GL_MULTI_SAMPLE_CONFIG_MSAA_SAMPLES__SHIFT 0
|
||||
#define VIVS_GL_MULTI_SAMPLE_CONFIG_MSAA_SAMPLES_NONE 0x00000000
|
||||
#define VIVS_GL_MULTI_SAMPLE_CONFIG_MSAA_SAMPLES_2X 0x00000001
|
||||
#define VIVS_GL_MULTI_SAMPLE_CONFIG_MSAA_SAMPLES_4X 0x00000002
|
||||
#define VIVS_GL_MULTI_SAMPLE_CONFIG_MSAA_SAMPLES_MASK 0x00000008
|
||||
#define VIVS_GL_MULTI_SAMPLE_CONFIG_MSAA_ENABLES__MASK 0x000000f0
|
||||
#define VIVS_GL_MULTI_SAMPLE_CONFIG_MSAA_ENABLES__SHIFT 4
|
||||
#define VIVS_GL_MULTI_SAMPLE_CONFIG_MSAA_ENABLES(x) (((x) << VIVS_GL_MULTI_SAMPLE_CONFIG_MSAA_ENABLES__SHIFT) & VIVS_GL_MULTI_SAMPLE_CONFIG_MSAA_ENABLES__MASK)
|
||||
#define VIVS_GL_MULTI_SAMPLE_CONFIG_MSAA_ENABLES_MASK 0x00000100
|
||||
#define VIVS_GL_MULTI_SAMPLE_CONFIG_UNK12__MASK 0x00007000
|
||||
#define VIVS_GL_MULTI_SAMPLE_CONFIG_UNK12__SHIFT 12
|
||||
#define VIVS_GL_MULTI_SAMPLE_CONFIG_UNK12(x) (((x) << VIVS_GL_MULTI_SAMPLE_CONFIG_UNK12__SHIFT) & VIVS_GL_MULTI_SAMPLE_CONFIG_UNK12__MASK)
|
||||
#define VIVS_GL_MULTI_SAMPLE_CONFIG_UNK12_MASK 0x00008000
|
||||
#define VIVS_GL_MULTI_SAMPLE_CONFIG_UNK16__MASK 0x00030000
|
||||
#define VIVS_GL_MULTI_SAMPLE_CONFIG_UNK16__SHIFT 16
|
||||
#define VIVS_GL_MULTI_SAMPLE_CONFIG_UNK16(x) (((x) << VIVS_GL_MULTI_SAMPLE_CONFIG_UNK16__SHIFT) & VIVS_GL_MULTI_SAMPLE_CONFIG_UNK16__MASK)
|
||||
#define VIVS_GL_MULTI_SAMPLE_CONFIG_UNK16_MASK 0x00080000
|
||||
|
||||
#define VIVS_GL_VARYING_TOTAL_COMPONENTS 0x0000381c
|
||||
#define VIVS_GL_VARYING_TOTAL_COMPONENTS_NUM__MASK 0x000000ff
|
||||
#define VIVS_GL_VARYING_TOTAL_COMPONENTS_NUM__SHIFT 0
|
||||
#define VIVS_GL_VARYING_TOTAL_COMPONENTS_NUM(x) (((x) << VIVS_GL_VARYING_TOTAL_COMPONENTS_NUM__SHIFT) & VIVS_GL_VARYING_TOTAL_COMPONENTS_NUM__MASK)
|
||||
|
||||
#define VIVS_GL_VARYING_NUM_COMPONENTS 0x00003820
|
||||
#define VIVS_GL_VARYING_NUM_COMPONENTS_VAR0__MASK 0x00000007
|
||||
#define VIVS_GL_VARYING_NUM_COMPONENTS_VAR0__SHIFT 0
|
||||
#define VIVS_GL_VARYING_NUM_COMPONENTS_VAR0(x) (((x) << VIVS_GL_VARYING_NUM_COMPONENTS_VAR0__SHIFT) & VIVS_GL_VARYING_NUM_COMPONENTS_VAR0__MASK)
|
||||
#define VIVS_GL_VARYING_NUM_COMPONENTS_VAR1__MASK 0x00000070
|
||||
#define VIVS_GL_VARYING_NUM_COMPONENTS_VAR1__SHIFT 4
|
||||
#define VIVS_GL_VARYING_NUM_COMPONENTS_VAR1(x) (((x) << VIVS_GL_VARYING_NUM_COMPONENTS_VAR1__SHIFT) & VIVS_GL_VARYING_NUM_COMPONENTS_VAR1__MASK)
|
||||
#define VIVS_GL_VARYING_NUM_COMPONENTS_VAR2__MASK 0x00000700
|
||||
#define VIVS_GL_VARYING_NUM_COMPONENTS_VAR2__SHIFT 8
|
||||
#define VIVS_GL_VARYING_NUM_COMPONENTS_VAR2(x) (((x) << VIVS_GL_VARYING_NUM_COMPONENTS_VAR2__SHIFT) & VIVS_GL_VARYING_NUM_COMPONENTS_VAR2__MASK)
|
||||
#define VIVS_GL_VARYING_NUM_COMPONENTS_VAR3__MASK 0x00007000
|
||||
#define VIVS_GL_VARYING_NUM_COMPONENTS_VAR3__SHIFT 12
|
||||
#define VIVS_GL_VARYING_NUM_COMPONENTS_VAR3(x) (((x) << VIVS_GL_VARYING_NUM_COMPONENTS_VAR3__SHIFT) & VIVS_GL_VARYING_NUM_COMPONENTS_VAR3__MASK)
|
||||
#define VIVS_GL_VARYING_NUM_COMPONENTS_VAR4__MASK 0x00070000
|
||||
#define VIVS_GL_VARYING_NUM_COMPONENTS_VAR4__SHIFT 16
|
||||
#define VIVS_GL_VARYING_NUM_COMPONENTS_VAR4(x) (((x) << VIVS_GL_VARYING_NUM_COMPONENTS_VAR4__SHIFT) & VIVS_GL_VARYING_NUM_COMPONENTS_VAR4__MASK)
|
||||
#define VIVS_GL_VARYING_NUM_COMPONENTS_VAR5__MASK 0x00700000
|
||||
#define VIVS_GL_VARYING_NUM_COMPONENTS_VAR5__SHIFT 20
|
||||
#define VIVS_GL_VARYING_NUM_COMPONENTS_VAR5(x) (((x) << VIVS_GL_VARYING_NUM_COMPONENTS_VAR5__SHIFT) & VIVS_GL_VARYING_NUM_COMPONENTS_VAR5__MASK)
|
||||
#define VIVS_GL_VARYING_NUM_COMPONENTS_VAR6__MASK 0x07000000
|
||||
#define VIVS_GL_VARYING_NUM_COMPONENTS_VAR6__SHIFT 24
|
||||
#define VIVS_GL_VARYING_NUM_COMPONENTS_VAR6(x) (((x) << VIVS_GL_VARYING_NUM_COMPONENTS_VAR6__SHIFT) & VIVS_GL_VARYING_NUM_COMPONENTS_VAR6__MASK)
|
||||
#define VIVS_GL_VARYING_NUM_COMPONENTS_VAR7__MASK 0x70000000
|
||||
#define VIVS_GL_VARYING_NUM_COMPONENTS_VAR7__SHIFT 28
|
||||
#define VIVS_GL_VARYING_NUM_COMPONENTS_VAR7(x) (((x) << VIVS_GL_VARYING_NUM_COMPONENTS_VAR7__SHIFT) & VIVS_GL_VARYING_NUM_COMPONENTS_VAR7__MASK)
|
||||
|
||||
#define VIVS_GL_VARYING_COMPONENT_USE(i0) (0x00003828 + 0x4*(i0))
|
||||
#define VIVS_GL_VARYING_COMPONENT_USE__ESIZE 0x00000004
|
||||
#define VIVS_GL_VARYING_COMPONENT_USE__LEN 0x00000002
|
||||
#define VIVS_GL_VARYING_COMPONENT_USE_COMP0__MASK 0x00000003
|
||||
#define VIVS_GL_VARYING_COMPONENT_USE_COMP0__SHIFT 0
|
||||
#define VIVS_GL_VARYING_COMPONENT_USE_COMP0(x) (((x) << VIVS_GL_VARYING_COMPONENT_USE_COMP0__SHIFT) & VIVS_GL_VARYING_COMPONENT_USE_COMP0__MASK)
|
||||
#define VIVS_GL_VARYING_COMPONENT_USE_COMP1__MASK 0x0000000c
|
||||
#define VIVS_GL_VARYING_COMPONENT_USE_COMP1__SHIFT 2
|
||||
#define VIVS_GL_VARYING_COMPONENT_USE_COMP1(x) (((x) << VIVS_GL_VARYING_COMPONENT_USE_COMP1__SHIFT) & VIVS_GL_VARYING_COMPONENT_USE_COMP1__MASK)
|
||||
#define VIVS_GL_VARYING_COMPONENT_USE_COMP2__MASK 0x00000030
|
||||
#define VIVS_GL_VARYING_COMPONENT_USE_COMP2__SHIFT 4
|
||||
#define VIVS_GL_VARYING_COMPONENT_USE_COMP2(x) (((x) << VIVS_GL_VARYING_COMPONENT_USE_COMP2__SHIFT) & VIVS_GL_VARYING_COMPONENT_USE_COMP2__MASK)
|
||||
#define VIVS_GL_VARYING_COMPONENT_USE_COMP3__MASK 0x000000c0
|
||||
#define VIVS_GL_VARYING_COMPONENT_USE_COMP3__SHIFT 6
|
||||
#define VIVS_GL_VARYING_COMPONENT_USE_COMP3(x) (((x) << VIVS_GL_VARYING_COMPONENT_USE_COMP3__SHIFT) & VIVS_GL_VARYING_COMPONENT_USE_COMP3__MASK)
|
||||
#define VIVS_GL_VARYING_COMPONENT_USE_COMP4__MASK 0x00000300
|
||||
#define VIVS_GL_VARYING_COMPONENT_USE_COMP4__SHIFT 8
|
||||
#define VIVS_GL_VARYING_COMPONENT_USE_COMP4(x) (((x) << VIVS_GL_VARYING_COMPONENT_USE_COMP4__SHIFT) & VIVS_GL_VARYING_COMPONENT_USE_COMP4__MASK)
|
||||
#define VIVS_GL_VARYING_COMPONENT_USE_COMP5__MASK 0x00000c00
|
||||
#define VIVS_GL_VARYING_COMPONENT_USE_COMP5__SHIFT 10
|
||||
#define VIVS_GL_VARYING_COMPONENT_USE_COMP5(x) (((x) << VIVS_GL_VARYING_COMPONENT_USE_COMP5__SHIFT) & VIVS_GL_VARYING_COMPONENT_USE_COMP5__MASK)
|
||||
#define VIVS_GL_VARYING_COMPONENT_USE_COMP6__MASK 0x00003000
|
||||
#define VIVS_GL_VARYING_COMPONENT_USE_COMP6__SHIFT 12
|
||||
#define VIVS_GL_VARYING_COMPONENT_USE_COMP6(x) (((x) << VIVS_GL_VARYING_COMPONENT_USE_COMP6__SHIFT) & VIVS_GL_VARYING_COMPONENT_USE_COMP6__MASK)
|
||||
#define VIVS_GL_VARYING_COMPONENT_USE_COMP7__MASK 0x0000c000
|
||||
#define VIVS_GL_VARYING_COMPONENT_USE_COMP7__SHIFT 14
|
||||
#define VIVS_GL_VARYING_COMPONENT_USE_COMP7(x) (((x) << VIVS_GL_VARYING_COMPONENT_USE_COMP7__SHIFT) & VIVS_GL_VARYING_COMPONENT_USE_COMP7__MASK)
|
||||
#define VIVS_GL_VARYING_COMPONENT_USE_COMP8__MASK 0x00030000
|
||||
#define VIVS_GL_VARYING_COMPONENT_USE_COMP8__SHIFT 16
|
||||
#define VIVS_GL_VARYING_COMPONENT_USE_COMP8(x) (((x) << VIVS_GL_VARYING_COMPONENT_USE_COMP8__SHIFT) & VIVS_GL_VARYING_COMPONENT_USE_COMP8__MASK)
|
||||
#define VIVS_GL_VARYING_COMPONENT_USE_COMP9__MASK 0x000c0000
|
||||
#define VIVS_GL_VARYING_COMPONENT_USE_COMP9__SHIFT 18
|
||||
#define VIVS_GL_VARYING_COMPONENT_USE_COMP9(x) (((x) << VIVS_GL_VARYING_COMPONENT_USE_COMP9__SHIFT) & VIVS_GL_VARYING_COMPONENT_USE_COMP9__MASK)
|
||||
#define VIVS_GL_VARYING_COMPONENT_USE_COMP10__MASK 0x00300000
|
||||
#define VIVS_GL_VARYING_COMPONENT_USE_COMP10__SHIFT 20
|
||||
#define VIVS_GL_VARYING_COMPONENT_USE_COMP10(x) (((x) << VIVS_GL_VARYING_COMPONENT_USE_COMP10__SHIFT) & VIVS_GL_VARYING_COMPONENT_USE_COMP10__MASK)
|
||||
#define VIVS_GL_VARYING_COMPONENT_USE_COMP11__MASK 0x00c00000
|
||||
#define VIVS_GL_VARYING_COMPONENT_USE_COMP11__SHIFT 22
|
||||
#define VIVS_GL_VARYING_COMPONENT_USE_COMP11(x) (((x) << VIVS_GL_VARYING_COMPONENT_USE_COMP11__SHIFT) & VIVS_GL_VARYING_COMPONENT_USE_COMP11__MASK)
|
||||
#define VIVS_GL_VARYING_COMPONENT_USE_COMP12__MASK 0x03000000
|
||||
#define VIVS_GL_VARYING_COMPONENT_USE_COMP12__SHIFT 24
|
||||
#define VIVS_GL_VARYING_COMPONENT_USE_COMP12(x) (((x) << VIVS_GL_VARYING_COMPONENT_USE_COMP12__SHIFT) & VIVS_GL_VARYING_COMPONENT_USE_COMP12__MASK)
|
||||
#define VIVS_GL_VARYING_COMPONENT_USE_COMP13__MASK 0x0c000000
|
||||
#define VIVS_GL_VARYING_COMPONENT_USE_COMP13__SHIFT 26
|
||||
#define VIVS_GL_VARYING_COMPONENT_USE_COMP13(x) (((x) << VIVS_GL_VARYING_COMPONENT_USE_COMP13__SHIFT) & VIVS_GL_VARYING_COMPONENT_USE_COMP13__MASK)
|
||||
#define VIVS_GL_VARYING_COMPONENT_USE_COMP14__MASK 0x30000000
|
||||
#define VIVS_GL_VARYING_COMPONENT_USE_COMP14__SHIFT 28
|
||||
#define VIVS_GL_VARYING_COMPONENT_USE_COMP14(x) (((x) << VIVS_GL_VARYING_COMPONENT_USE_COMP14__SHIFT) & VIVS_GL_VARYING_COMPONENT_USE_COMP14__MASK)
|
||||
#define VIVS_GL_VARYING_COMPONENT_USE_COMP15__MASK 0xc0000000
|
||||
#define VIVS_GL_VARYING_COMPONENT_USE_COMP15__SHIFT 30
|
||||
#define VIVS_GL_VARYING_COMPONENT_USE_COMP15(x) (((x) << VIVS_GL_VARYING_COMPONENT_USE_COMP15__SHIFT) & VIVS_GL_VARYING_COMPONENT_USE_COMP15__MASK)
|
||||
|
||||
#define VIVS_GL_UNK03834 0x00003834
|
||||
|
||||
#define VIVS_GL_UNK03838 0x00003838
|
||||
|
||||
#define VIVS_GL_API_MODE 0x0000384c
|
||||
#define VIVS_GL_API_MODE_OPENGL 0x00000000
|
||||
#define VIVS_GL_API_MODE_OPENVG 0x00000001
|
||||
#define VIVS_GL_API_MODE_OPENCL 0x00000002
|
||||
|
||||
#define VIVS_GL_CONTEXT_POINTER 0x00003850
|
||||
|
||||
#define VIVS_GL_UNK03854 0x00003854
|
||||
|
||||
#define VIVS_GL_UNK03A00 0x00003a00
|
||||
|
||||
#define VIVS_GL_STALL_TOKEN 0x00003c00
|
||||
#define VIVS_GL_STALL_TOKEN_FROM__MASK 0x0000001f
|
||||
#define VIVS_GL_STALL_TOKEN_FROM__SHIFT 0
|
||||
#define VIVS_GL_STALL_TOKEN_FROM(x) (((x) << VIVS_GL_STALL_TOKEN_FROM__SHIFT) & VIVS_GL_STALL_TOKEN_FROM__MASK)
|
||||
#define VIVS_GL_STALL_TOKEN_TO__MASK 0x00001f00
|
||||
#define VIVS_GL_STALL_TOKEN_TO__SHIFT 8
|
||||
#define VIVS_GL_STALL_TOKEN_TO(x) (((x) << VIVS_GL_STALL_TOKEN_TO__SHIFT) & VIVS_GL_STALL_TOKEN_TO__MASK)
|
||||
#define VIVS_GL_STALL_TOKEN_FLIP0 0x40000000
|
||||
#define VIVS_GL_STALL_TOKEN_FLIP1 0x80000000
|
||||
|
||||
#define VIVS_NFE 0x00000000
|
||||
|
||||
#define VIVS_NFE_UNK14600(i0) (0x00014600 + 0x4*(i0))
|
||||
#define VIVS_NFE_UNK14600__ESIZE 0x00000004
|
||||
#define VIVS_NFE_UNK14600__LEN 0x00000010
|
||||
|
||||
#define VIVS_NFE_UNK14640(i0) (0x00014640 + 0x4*(i0))
|
||||
#define VIVS_NFE_UNK14640__ESIZE 0x00000004
|
||||
#define VIVS_NFE_UNK14640__LEN 0x00000010
|
||||
|
||||
#define VIVS_NFE_UNK14680(i0) (0x00014680 + 0x4*(i0))
|
||||
#define VIVS_NFE_UNK14680__ESIZE 0x00000004
|
||||
#define VIVS_NFE_UNK14680__LEN 0x00000010
|
||||
|
||||
#define VIVS_DUMMY 0x00000000
|
||||
|
||||
#define VIVS_DUMMY_DUMMY 0x0003fffc
|
||||
|
||||
|
||||
#endif /* STATE_XML */
|
File diff suppressed because it is too large
Load Diff
|
@ -91,6 +91,8 @@ include $(top_srcdir)/src/gallium/drivers/vc4/Automake.inc
|
|||
|
||||
include $(top_srcdir)/src/gallium/drivers/virgl/Automake.inc
|
||||
|
||||
include $(top_srcdir)/src/gallium/drivers/etnaviv/Automake.inc
|
||||
|
||||
include $(top_srcdir)/src/gallium/drivers/softpipe/Automake.inc
|
||||
include $(top_srcdir)/src/gallium/drivers/llvmpipe/Automake.inc
|
||||
include $(top_srcdir)/src/gallium/drivers/swr/Automake.inc
|
||||
|
|
|
@ -162,3 +162,14 @@ PUBLIC const __DRIextension **__driDriverGetExtensions_i965(void)
|
|||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(GALLIUM_ETNAVIV)
|
||||
|
||||
const __DRIextension **__driDriverGetExtensions_etnaviv(void);
|
||||
|
||||
PUBLIC const __DRIextension **__driDriverGetExtensions_etnaviv(void)
|
||||
{
|
||||
globalDriverAPI = &galliumdrm_driver_api;
|
||||
return galliumdrm_driver_extensions;
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
# Copyright © 2012 Intel Corporation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a
|
||||
# copy of this software and associated documentation files (the "Software"),
|
||||
# to deal in the Software without restriction, including without limitation
|
||||
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
# and/or sell copies of the Software, and to permit persons to whom the
|
||||
# Software is furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice (including the next
|
||||
# paragraph) shall be included in all copies or substantial portions of the
|
||||
# Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
# DEALINGS IN THE SOFTWARE.
|
||||
|
||||
include $(top_srcdir)/src/gallium/Automake.inc
|
||||
|
||||
AM_CFLAGS = \
|
||||
-I$(top_srcdir)/src/gallium/drivers \
|
||||
$(GALLIUM_CFLAGS) \
|
||||
$(ETNAVIV_CFLAGS)
|
||||
|
||||
noinst_LTLIBRARIES = libetnavivdrm.la
|
||||
|
||||
libetnavivdrm_la_SOURCES = etnaviv_drm_winsys.c
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* Copyright (c) 2015 Etnaviv Project
|
||||
*
|
||||
* 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, sub license,
|
||||
* 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 NON-INFRINGEMENT. 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:
|
||||
* Christian Gmeiner <christian.gmeiner@gmail.com>
|
||||
*/
|
||||
|
||||
#ifndef __ETNA_DRM_PUBLIC_H__
|
||||
#define __ETNA_DRM_PUBLIC_H__
|
||||
|
||||
struct pipe_screen;
|
||||
struct renderonly;
|
||||
|
||||
struct pipe_screen *
|
||||
etna_drm_screen_create_renderonly(struct renderonly *ro);
|
||||
|
||||
struct pipe_screen *
|
||||
etna_drm_screen_create(int fd);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,162 @@
|
|||
/*
|
||||
* Copyright (c) 2015 Etnaviv Project
|
||||
*
|
||||
* 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, sub license,
|
||||
* 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 NON-INFRINGEMENT. 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:
|
||||
* Christian Gmeiner <christian.gmeiner@gmail.com>
|
||||
*/
|
||||
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "util/u_hash_table.h"
|
||||
#include "util/u_memory.h"
|
||||
|
||||
#include "etnaviv/etnaviv_screen.h"
|
||||
#include "etnaviv/hw/common.xml.h"
|
||||
#include "etnaviv_drm_public.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
static struct pipe_screen *
|
||||
screen_create(struct renderonly *ro)
|
||||
{
|
||||
struct etna_device *dev;
|
||||
struct etna_gpu *gpu;
|
||||
uint64_t val;
|
||||
int i;
|
||||
|
||||
dev = etna_device_new_dup(ro->gpu_fd);
|
||||
if (!dev) {
|
||||
fprintf(stderr, "Error creating device\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (i = 0;; i++) {
|
||||
gpu = etna_gpu_new(dev, i);
|
||||
if (!gpu) {
|
||||
fprintf(stderr, "Error creating gpu\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Look for a 3D capable GPU */
|
||||
int ret = etna_gpu_get_param(gpu, ETNA_GPU_FEATURES_0, &val);
|
||||
if (ret == 0 && (val & chipFeatures_PIPE_3D))
|
||||
break;
|
||||
|
||||
etna_gpu_del(gpu);
|
||||
}
|
||||
|
||||
return etna_screen_create(dev, gpu, ro);
|
||||
}
|
||||
|
||||
static struct util_hash_table *etna_tab = NULL;
|
||||
|
||||
pipe_static_mutex(etna_screen_mutex);
|
||||
|
||||
static void
|
||||
etna_drm_screen_destroy(struct pipe_screen *pscreen)
|
||||
{
|
||||
struct etna_screen *screen = etna_screen(pscreen);
|
||||
boolean destroy;
|
||||
|
||||
pipe_mutex_lock(etna_screen_mutex);
|
||||
destroy = --screen->refcnt == 0;
|
||||
if (destroy) {
|
||||
int fd = etna_device_fd(screen->dev);
|
||||
util_hash_table_remove(etna_tab, intptr_to_pointer(fd));
|
||||
}
|
||||
pipe_mutex_unlock(etna_screen_mutex);
|
||||
|
||||
if (destroy) {
|
||||
pscreen->destroy = screen->winsys_priv;
|
||||
pscreen->destroy(pscreen);
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned hash_fd(void *key)
|
||||
{
|
||||
int fd = pointer_to_intptr(key);
|
||||
struct stat stat;
|
||||
|
||||
fstat(fd, &stat);
|
||||
|
||||
return stat.st_dev ^ stat.st_ino ^ stat.st_rdev;
|
||||
}
|
||||
|
||||
static int compare_fd(void *key1, void *key2)
|
||||
{
|
||||
int fd1 = pointer_to_intptr(key1);
|
||||
int fd2 = pointer_to_intptr(key2);
|
||||
struct stat stat1, stat2;
|
||||
|
||||
fstat(fd1, &stat1);
|
||||
fstat(fd2, &stat2);
|
||||
|
||||
return stat1.st_dev != stat2.st_dev ||
|
||||
stat1.st_ino != stat2.st_ino ||
|
||||
stat1.st_rdev != stat2.st_rdev;
|
||||
}
|
||||
|
||||
struct pipe_screen *
|
||||
etna_drm_screen_create_renderonly(struct renderonly *ro)
|
||||
{
|
||||
struct pipe_screen *pscreen = NULL;
|
||||
|
||||
pipe_mutex_lock(etna_screen_mutex);
|
||||
if (!etna_tab) {
|
||||
etna_tab = util_hash_table_create(hash_fd, compare_fd);
|
||||
if (!etna_tab)
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
pscreen = util_hash_table_get(etna_tab, intptr_to_pointer(ro->gpu_fd));
|
||||
if (pscreen) {
|
||||
etna_screen(pscreen)->refcnt++;
|
||||
} else {
|
||||
pscreen = screen_create(ro);
|
||||
if (pscreen) {
|
||||
int fd = etna_device_fd(etna_screen(pscreen)->dev);
|
||||
util_hash_table_set(etna_tab, intptr_to_pointer(fd), pscreen);
|
||||
|
||||
/* Bit of a hack, to avoid circular linkage dependency,
|
||||
* ie. pipe driver having to call in to winsys, we
|
||||
* override the pipe drivers screen->destroy() */
|
||||
etna_screen(pscreen)->winsys_priv = pscreen->destroy;
|
||||
pscreen->destroy = etna_drm_screen_destroy;
|
||||
}
|
||||
}
|
||||
|
||||
unlock:
|
||||
pipe_mutex_unlock(etna_screen_mutex);
|
||||
return pscreen;
|
||||
}
|
||||
|
||||
struct pipe_screen *
|
||||
etna_drm_screen_create(int fd)
|
||||
{
|
||||
struct renderonly ro = {
|
||||
.create_for_resource = renderonly_create_gpu_import_for_resource,
|
||||
.kms_fd = -1,
|
||||
.gpu_fd = fd
|
||||
};
|
||||
|
||||
return etna_drm_screen_create_renderonly(&ro);
|
||||
}
|
Loading…
Reference in New Issue