freedreno/ir3: split out shader compiler from a3xx

Move the bits we want to share between generations from fd3_program to
ir3_shader.  So overall structure is:

  fdN_shader_stateobj -> ir3_shader -> ir3_shader_variant -> ir3
                                    |- ...
                                    \- ir3_shader_variant -> ir3

So the ir3_shader becomes the topmost generation neutral object, which
manages the set of variants each of which generates, compiles, and
assembles it's own ir.

There is a bit of additional renaming to s/fd3_compiler/ir3_compiler/,
etc.

Keep the split between the gallium level stateobj and the shader helper
object because it might be a good idea to pre-compute some generation
specific register values (ie. anything that is independent of linking).

Signed-off-by: Rob Clark <robclark@freedesktop.org>
This commit is contained in:
Rob Clark 2014-07-25 11:15:59 -04:00
parent 7d7e6ae9c3
commit db193e5ad0
25 changed files with 580 additions and 477 deletions

View file

@ -7,6 +7,7 @@ AM_CFLAGS = \
-Wno-packed-bitfield-compat \
-I$(top_srcdir)/src/gallium/drivers/freedreno/a3xx \
-I$(top_srcdir)/src/gallium/drivers/freedreno/a2xx \
-I$(top_srcdir)/src/gallium/drivers/freedreno/ir3 \
$(GALLIUM_DRIVER_CFLAGS) \
$(FREEDRENO_CFLAGS)
@ -15,4 +16,5 @@ noinst_LTLIBRARIES = libfreedreno.la
libfreedreno_la_SOURCES = \
$(C_SOURCES) \
$(a2xx_SOURCES) \
$(a3xx_SOURCES)
$(a3xx_SOURCES) \
$(ir3_SOURCES)

View file

@ -33,8 +33,6 @@ a2xx_SOURCES := \
a3xx_SOURCES := \
a3xx/fd3_blend.c \
a3xx/fd3_compiler.c \
a3xx/fd3_compiler_old.c \
a3xx/fd3_context.c \
a3xx/fd3_draw.c \
a3xx/fd3_emit.c \
@ -45,12 +43,17 @@ a3xx_SOURCES := \
a3xx/fd3_screen.c \
a3xx/fd3_texture.c \
a3xx/fd3_util.c \
a3xx/fd3_zsa.c \
a3xx/disasm-a3xx.c \
a3xx/ir3_cp.c \
a3xx/ir3_depth.c \
a3xx/ir3_dump.c \
a3xx/ir3_flatten.c \
a3xx/ir3_ra.c \
a3xx/ir3_sched.c \
a3xx/ir3.c
a3xx/fd3_zsa.c
ir3_SOURCES := \
ir3/disasm-a3xx.c \
ir3/ir3_compiler.c \
ir3/ir3_compiler_old.c \
ir3/ir3_shader.c \
ir3/ir3_cp.c \
ir3/ir3_depth.c \
ir3/ir3_dump.c \
ir3/ir3_flatten.c \
ir3/ir3_ra.c \
ir3/ir3_sched.c \
ir3/ir3.c

View file

@ -44,7 +44,7 @@
static void
emit_vertexbufs(struct fd_context *ctx, struct fd_ringbuffer *ring,
struct fd3_shader_key key)
struct ir3_shader_key key)
{
struct fd_vertex_stateobj *vtx = ctx->vtx;
struct fd_vertexbuf_stateobj *vertexbuf = &ctx->vertexbuf;
@ -70,7 +70,7 @@ emit_vertexbufs(struct fd_context *ctx, struct fd_ringbuffer *ring,
static void
draw_impl(struct fd_context *ctx, const struct pipe_draw_info *info,
struct fd_ringbuffer *ring, unsigned dirty, struct fd3_shader_key key)
struct fd_ringbuffer *ring, unsigned dirty, struct ir3_shader_key key)
{
fd3_emit_state(ctx, ring, &ctx->prog, dirty, key);
@ -99,7 +99,7 @@ static void
fd3_draw(struct fd_context *ctx, const struct pipe_draw_info *info)
{
unsigned dirty = ctx->dirty;
struct fd3_shader_key key = {
struct ir3_shader_key key = {
/* do binning pass first: */
.binning_pass = true,
.color_two_side = ctx->rasterizer ? ctx->rasterizer->light_twoside : false,
@ -127,7 +127,7 @@ fd3_clear_binning(struct fd_context *ctx, unsigned dirty)
{
struct fd3_context *fd3_ctx = fd3_context(ctx);
struct fd_ringbuffer *ring = ctx->binning_ring;
struct fd3_shader_key key = {
struct ir3_shader_key key = {
.binning_pass = true,
.half_precision = true,
};
@ -168,7 +168,7 @@ fd3_clear(struct fd_context *ctx, unsigned buffers,
struct fd_ringbuffer *ring = ctx->ring;
unsigned dirty = ctx->dirty;
unsigned ce, i;
struct fd3_shader_key key = {
struct ir3_shader_key key = {
.half_precision = true,
};

View file

@ -87,7 +87,7 @@ static void
emit_constants(struct fd_ringbuffer *ring,
enum adreno_state_block sb,
struct fd_constbuf_stateobj *constbuf,
struct fd3_shader_variant *shader)
struct ir3_shader_variant *shader)
{
uint32_t enabled_mask = constbuf->enabled_mask;
uint32_t first_immediate;
@ -291,7 +291,7 @@ fd3_emit_gmem_restore_tex(struct fd_ringbuffer *ring, struct pipe_surface *psurf
void
fd3_emit_vertex_bufs(struct fd_ringbuffer *ring,
struct fd3_shader_variant *vp,
struct ir3_shader_variant *vp,
struct fd3_vertex_buf *vbufs, uint32_t n)
{
uint32_t i, j, last = 0;
@ -350,10 +350,10 @@ fd3_emit_vertex_bufs(struct fd_ringbuffer *ring,
void
fd3_emit_state(struct fd_context *ctx, struct fd_ringbuffer *ring,
struct fd_program_stateobj *prog, uint32_t dirty,
struct fd3_shader_key key)
struct ir3_shader_key key)
{
struct fd3_shader_variant *vp;
struct fd3_shader_variant *fp;
struct ir3_shader_variant *vp;
struct ir3_shader_variant *fp;
fp = fd3_shader_variant(prog->fp, key);
vp = fd3_shader_variant(prog->vp, key);

View file

@ -33,7 +33,7 @@
#include "freedreno_context.h"
#include "fd3_util.h"
#include "ir3_shader.h"
struct fd_ringbuffer;
enum adreno_state_block;
@ -56,11 +56,11 @@ struct fd3_vertex_buf {
};
void fd3_emit_vertex_bufs(struct fd_ringbuffer *ring,
struct fd3_shader_variant *vp,
struct ir3_shader_variant *vp,
struct fd3_vertex_buf *vbufs, uint32_t n);
void fd3_emit_state(struct fd_context *ctx, struct fd_ringbuffer *ring,
struct fd_program_stateobj *prog, uint32_t dirty,
struct fd3_shader_key key);
struct ir3_shader_key key);
void fd3_emit_restore(struct fd_context *ctx);
#endif /* FD3_EMIT_H */

View file

@ -43,7 +43,7 @@
#include "fd3_util.h"
#include "fd3_zsa.h"
static const struct fd3_shader_key key = {
static const struct ir3_shader_key key = {
// XXX should set this based on render target format! We don't
// want half_precision if float32 render target!!!
.half_precision = true,

View file

@ -38,176 +38,23 @@
#include "freedreno_program.h"
#include "fd3_program.h"
#include "fd3_compiler.h"
#include "fd3_emit.h"
#include "fd3_texture.h"
#include "fd3_util.h"
static void
delete_variant(struct fd3_shader_variant *v)
delete_shader_stateobj(struct fd3_shader_stateobj *so)
{
ir3_destroy(v->ir);
fd_bo_del(v->bo);
free(v);
}
static void
assemble_variant(struct fd3_shader_variant *so)
{
struct fd_context *ctx = fd_context(so->so->pctx);
uint32_t sz, *bin;
bin = ir3_assemble(so->ir, &so->info);
sz = so->info.sizedwords * 4;
so->bo = fd_bo_new(ctx->dev, sz,
DRM_FREEDRENO_GEM_CACHE_WCOMBINE |
DRM_FREEDRENO_GEM_TYPE_KMEM);
memcpy(fd_bo_map(so->bo), bin, sz);
free(bin);
so->instrlen = so->info.sizedwords / 8;
so->constlen = so->info.max_const + 1;
}
/* for vertex shader, the inputs are loaded into registers before the shader
* is executed, so max_regs from the shader instructions might not properly
* reflect the # of registers actually used:
*/
static void
fixup_vp_regfootprint(struct fd3_shader_variant *so)
{
unsigned i;
for (i = 0; i < so->inputs_count; i++) {
if (so->inputs[i].compmask) {
uint32_t regid = (so->inputs[i].regid + 3) >> 2;
so->info.max_reg = MAX2(so->info.max_reg, regid);
}
}
for (i = 0; i < so->outputs_count; i++) {
uint32_t regid = (so->outputs[i].regid + 3) >> 2;
so->info.max_reg = MAX2(so->info.max_reg, regid);
}
}
static struct fd3_shader_variant *
create_variant(struct fd3_shader_stateobj *so, struct fd3_shader_key key)
{
struct fd3_shader_variant *v = CALLOC_STRUCT(fd3_shader_variant);
const struct tgsi_token *tokens = so->tokens;
int ret;
if (!v)
return NULL;
v->so = so;
v->key = key;
v->type = so->type;
if (fd_mesa_debug & FD_DBG_DISASM) {
DBG("dump tgsi: type=%d, k={bp=%u,cts=%u,hp=%u}", so->type,
key.binning_pass, key.color_two_side, key.half_precision);
tgsi_dump(tokens, 0);
}
if (!(fd_mesa_debug & FD_DBG_NOOPT)) {
ret = fd3_compile_shader(v, tokens, key);
if (ret) {
debug_error("new compiler failed, trying fallback!");
v->inputs_count = 0;
v->outputs_count = 0;
v->total_in = 0;
v->has_samp = false;
v->immediates_count = 0;
}
} else {
ret = -1; /* force fallback to old compiler */
}
if (ret)
ret = fd3_compile_shader_old(v, tokens, key);
if (ret) {
debug_error("compile failed!");
goto fail;
}
assemble_variant(v);
if (!v->bo) {
debug_error("assemble failed!");
goto fail;
}
if (so->type == SHADER_VERTEX)
fixup_vp_regfootprint(v);
if (fd_mesa_debug & FD_DBG_DISASM) {
DBG("disassemble: type=%d, k={bp=%u,cts=%u,hp=%u}", v->type,
key.binning_pass, key.color_two_side, key.half_precision);
disasm_a3xx(fd_bo_map(v->bo), v->info.sizedwords, 0, v->type);
}
return v;
fail:
delete_variant(v);
return NULL;
}
struct fd3_shader_variant *
fd3_shader_variant(struct fd3_shader_stateobj *so, struct fd3_shader_key key)
{
struct fd3_shader_variant *v;
/* some shader key values only apply to vertex or frag shader,
* so normalize the key to avoid constructing multiple identical
* variants:
*/
if (so->type == SHADER_FRAGMENT) {
key.binning_pass = false;
}
if (so->type == SHADER_VERTEX) {
key.color_two_side = false;
key.half_precision = false;
}
for (v = so->variants; v; v = v->next)
if (!memcmp(&key, &v->key, sizeof(key)))
return v;
/* compile new variant if it doesn't exist already: */
v = create_variant(so, key);
v->next = so->variants;
so->variants = v;
return v;
}
static void
delete_shader(struct fd3_shader_stateobj *so)
{
struct fd3_shader_variant *v, *t;
for (v = so->variants; v; ) {
t = v;
v = v->next;
delete_variant(t);
}
free((void *)so->tokens);
ir3_shader_destroy(so->shader);
free(so);
}
static struct fd3_shader_stateobj *
create_shader(struct pipe_context *pctx, const struct pipe_shader_state *cso,
create_shader_stateobj(struct pipe_context *pctx, const struct pipe_shader_state *cso,
enum shader_t type)
{
struct fd3_shader_stateobj *so = CALLOC_STRUCT(fd3_shader_stateobj);
so->pctx = pctx;
so->type = type;
so->tokens = tgsi_dup_tokens(cso->tokens);
so->shader = ir3_shader_create(pctx, cso->tokens, type);
return so;
}
@ -215,32 +62,32 @@ static void *
fd3_fp_state_create(struct pipe_context *pctx,
const struct pipe_shader_state *cso)
{
return create_shader(pctx, cso, SHADER_FRAGMENT);
return create_shader_stateobj(pctx, cso, SHADER_FRAGMENT);
}
static void
fd3_fp_state_delete(struct pipe_context *pctx, void *hwcso)
{
struct fd3_shader_stateobj *so = hwcso;
delete_shader(so);
delete_shader_stateobj(so);
}
static void *
fd3_vp_state_create(struct pipe_context *pctx,
const struct pipe_shader_state *cso)
{
return create_shader(pctx, cso, SHADER_VERTEX);
return create_shader_stateobj(pctx, cso, SHADER_VERTEX);
}
static void
fd3_vp_state_delete(struct pipe_context *pctx, void *hwcso)
{
struct fd3_shader_stateobj *so = hwcso;
delete_shader(so);
delete_shader_stateobj(so);
}
static void
emit_shader(struct fd_ringbuffer *ring, const struct fd3_shader_variant *so)
emit_shader(struct fd_ringbuffer *ring, const struct ir3_shader_variant *so)
{
const struct ir3_info *si = &so->info;
enum adreno_state_block sb;
@ -281,7 +128,7 @@ emit_shader(struct fd_ringbuffer *ring, const struct fd3_shader_variant *so)
}
static int
find_output(const struct fd3_shader_variant *so, fd3_semantic semantic)
find_output(const struct ir3_shader_variant *so, ir3_semantic semantic)
{
int j;
@ -297,7 +144,7 @@ find_output(const struct fd3_shader_variant *so, fd3_semantic semantic)
*/
if (sem2name(semantic) == TGSI_SEMANTIC_BCOLOR) {
unsigned idx = sem2idx(semantic);
return find_output(so, fd3_semantic_name(TGSI_SEMANTIC_COLOR, idx));
return find_output(so, ir3_semantic_name(TGSI_SEMANTIC_COLOR, idx));
}
debug_assert(0);
@ -306,7 +153,7 @@ find_output(const struct fd3_shader_variant *so, fd3_semantic semantic)
}
static int
next_varying(const struct fd3_shader_variant *so, int i)
next_varying(const struct ir3_shader_variant *so, int i)
{
while (++i < so->inputs_count)
if (so->inputs[i].compmask && so->inputs[i].bary)
@ -315,7 +162,7 @@ next_varying(const struct fd3_shader_variant *so, int i)
}
static uint32_t
find_output_regid(const struct fd3_shader_variant *so, fd3_semantic semantic)
find_output_regid(const struct ir3_shader_variant *so, ir3_semantic semantic)
{
int j;
for (j = 0; j < so->outputs_count; j++)
@ -326,9 +173,9 @@ find_output_regid(const struct fd3_shader_variant *so, fd3_semantic semantic)
void
fd3_program_emit(struct fd_ringbuffer *ring,
struct fd_program_stateobj *prog, struct fd3_shader_key key)
struct fd_program_stateobj *prog, struct ir3_shader_key key)
{
const struct fd3_shader_variant *vp, *fp;
const struct ir3_shader_variant *vp, *fp;
const struct ir3_info *vsi, *fsi;
uint32_t pos_regid, posz_regid, psize_regid, color_regid;
int i, j, k;
@ -337,7 +184,7 @@ fd3_program_emit(struct fd_ringbuffer *ring,
if (key.binning_pass) {
/* use dummy stateobj to simplify binning vs non-binning: */
static const struct fd3_shader_variant binning_fp = {};
static const struct ir3_shader_variant binning_fp = {};
fp = &binning_fp;
} else {
fp = fd3_shader_variant(prog->fp, key);
@ -347,13 +194,13 @@ fd3_program_emit(struct fd_ringbuffer *ring,
fsi = &fp->info;
pos_regid = find_output_regid(vp,
fd3_semantic_name(TGSI_SEMANTIC_POSITION, 0));
ir3_semantic_name(TGSI_SEMANTIC_POSITION, 0));
posz_regid = find_output_regid(fp,
fd3_semantic_name(TGSI_SEMANTIC_POSITION, 0));
ir3_semantic_name(TGSI_SEMANTIC_POSITION, 0));
psize_regid = find_output_regid(vp,
fd3_semantic_name(TGSI_SEMANTIC_PSIZE, 0));
ir3_semantic_name(TGSI_SEMANTIC_PSIZE, 0));
color_regid = find_output_regid(fp,
fd3_semantic_name(TGSI_SEMANTIC_COLOR, 0));
ir3_semantic_name(TGSI_SEMANTIC_COLOR, 0));
/* we could probably divide this up into things that need to be
* emitted if frag-prog is dirty vs if vert-prog is dirty..
@ -522,16 +369,16 @@ fd3_program_emit(struct fd_ringbuffer *ring,
A3XX_VPC_PACK_NUMNONPOSVSVAR(fp->total_in));
OUT_PKT0(ring, REG_A3XX_VPC_VARYING_INTERP_MODE(0), 4);
OUT_RING(ring, fp->so->vinterp[0]); /* VPC_VARYING_INTERP[0].MODE */
OUT_RING(ring, fp->so->vinterp[1]); /* VPC_VARYING_INTERP[1].MODE */
OUT_RING(ring, fp->so->vinterp[2]); /* VPC_VARYING_INTERP[2].MODE */
OUT_RING(ring, fp->so->vinterp[3]); /* VPC_VARYING_INTERP[3].MODE */
OUT_RING(ring, fp->shader->vinterp[0]); /* VPC_VARYING_INTERP[0].MODE */
OUT_RING(ring, fp->shader->vinterp[1]); /* VPC_VARYING_INTERP[1].MODE */
OUT_RING(ring, fp->shader->vinterp[2]); /* VPC_VARYING_INTERP[2].MODE */
OUT_RING(ring, fp->shader->vinterp[3]); /* VPC_VARYING_INTERP[3].MODE */
OUT_PKT0(ring, REG_A3XX_VPC_VARYING_PS_REPL_MODE(0), 4);
OUT_RING(ring, fp->so->vpsrepl[0]); /* VPC_VARYING_PS_REPL[0].MODE */
OUT_RING(ring, fp->so->vpsrepl[1]); /* VPC_VARYING_PS_REPL[1].MODE */
OUT_RING(ring, fp->so->vpsrepl[2]); /* VPC_VARYING_PS_REPL[2].MODE */
OUT_RING(ring, fp->so->vpsrepl[3]); /* VPC_VARYING_PS_REPL[3].MODE */
OUT_RING(ring, fp->shader->vpsrepl[0]); /* VPC_VARYING_PS_REPL[0].MODE */
OUT_RING(ring, fp->shader->vpsrepl[1]); /* VPC_VARYING_PS_REPL[1].MODE */
OUT_RING(ring, fp->shader->vpsrepl[2]); /* VPC_VARYING_PS_REPL[2].MODE */
OUT_RING(ring, fp->shader->vpsrepl[3]); /* VPC_VARYING_PS_REPL[3].MODE */
}
OUT_PKT0(ring, REG_A3XX_VFD_VS_THREADING_THRESHOLD, 1);
@ -558,10 +405,10 @@ fix_blit_fp(struct pipe_context *pctx)
struct fd_context *ctx = fd_context(pctx);
struct fd3_shader_stateobj *so = ctx->blit_prog.fp;
so->vpsrepl[0] = 0x99999999;
so->vpsrepl[1] = 0x99999999;
so->vpsrepl[2] = 0x99999999;
so->vpsrepl[3] = 0x99999999;
so->shader->vpsrepl[0] = 0x99999999;
so->shader->vpsrepl[1] = 0x99999999;
so->shader->vpsrepl[2] = 0x99999999;
so->shader->vpsrepl[3] = 0x99999999;
}
void

View file

@ -30,127 +30,22 @@
#define FD3_PROGRAM_H_
#include "pipe/p_context.h"
#include "freedreno_context.h"
#include "fd3_util.h"
#include "ir3.h"
#include "disasm.h"
typedef uint16_t fd3_semantic; /* semantic name + index */
static inline fd3_semantic
fd3_semantic_name(uint8_t name, uint16_t index)
{
return (name << 8) | (index & 0xff);
}
static inline uint8_t sem2name(fd3_semantic sem)
{
return sem >> 8;
}
static inline uint16_t sem2idx(fd3_semantic sem)
{
return sem & 0xff;
}
struct fd3_shader_variant {
struct fd_bo *bo;
struct fd3_shader_key key;
struct ir3_info info;
struct ir3 *ir;
/* the instructions length is in units of instruction groups
* (4 instructions, 8 dwords):
*/
unsigned instrlen;
/* the constants length is in units of vec4's, and is the sum of
* the uniforms and the built-in compiler constants
*/
unsigned constlen;
/* About Linkage:
* + Let the frag shader determine the position/compmask for the
* varyings, since it is the place where we know if the varying
* is actually used, and if so, which components are used. So
* what the hw calls "outloc" is taken from the "inloc" of the
* frag shader.
* + From the vert shader, we only need the output regid
*/
/* for frag shader, pos_regid holds the frag_pos, ie. what is passed
* to bary.f instructions
*/
uint8_t pos_regid;
bool frag_coord, frag_face;
/* varyings/outputs: */
unsigned outputs_count;
struct {
fd3_semantic semantic;
uint8_t regid;
} outputs[16 + 2]; /* +POSITION +PSIZE */
bool writes_pos, writes_psize;
/* vertices/inputs: */
unsigned inputs_count;
struct {
fd3_semantic semantic;
uint8_t regid;
uint8_t compmask;
uint8_t ncomp;
/* in theory inloc of fs should match outloc of vs: */
uint8_t inloc;
uint8_t bary;
} inputs[16 + 2]; /* +POSITION +FACE */
unsigned total_in; /* sum of inputs (scalar) */
/* do we have one or more texture sample instructions: */
bool has_samp;
/* const reg # of first immediate, ie. 1 == c1
* (not regid, because TGSI thinks in terms of vec4 registers,
* not scalar registers)
*/
unsigned first_immediate;
unsigned immediates_count;
struct {
uint32_t val[4];
} immediates[64];
/* shader varients form a linked list: */
struct fd3_shader_variant *next;
/* replicated here to avoid passing extra ptrs everywhere: */
enum shader_t type;
struct fd3_shader_stateobj *so;
};
#include "ir3_shader.h"
struct fd3_shader_stateobj {
enum shader_t type;
struct pipe_context *pctx;
const struct tgsi_token *tokens;
struct fd3_shader_variant *variants;
/* so far, only used for blit_prog shader.. values for
* VPC_VARYING_INTERP[i].MODE and VPC_VARYING_PS_REPL[i].MODE
*
* Possibly should be in fd3_program_variant?
*/
uint32_t vinterp[4], vpsrepl[4];
struct ir3_shader *shader;
};
struct fd3_shader_variant * fd3_shader_variant(struct fd3_shader_stateobj *so,
struct fd3_shader_key key);
void fd3_program_emit(struct fd_ringbuffer *ring,
struct fd_program_stateobj *prog, struct fd3_shader_key key);
struct fd_program_stateobj *prog, struct ir3_shader_key key);
void fd3_prog_init(struct pipe_context *pctx);
static inline struct ir3_shader_variant *
fd3_shader_variant(struct fd3_shader_stateobj *so, struct ir3_shader_key key)
{
return ir3_shader_variant(so->shader, key);
}
#endif /* FD3_PROGRAM_H_ */

View file

@ -43,22 +43,4 @@ enum a3xx_color_swap fd3_pipe2swap(enum pipe_format format);
uint32_t fd3_tex_swiz(enum pipe_format format, unsigned swizzle_r,
unsigned swizzle_g, unsigned swizzle_b, unsigned swizzle_a);
/* Configuration key used to identify a shader variant.. different
* shader variants can be used to implement features not supported
* in hw (two sided color), binning-pass vertex shader, etc.
*
* NOTE: this is declared here (rather than fd3_program.h) as it is
* passed around through a lot of the emit code in various parts
* which would otherwise not necessarily need to incl fd3_program.h
*/
struct fd3_shader_key {
/* vertex shader variant parameters: */
unsigned binning_pass : 1;
/* fragment shader variant parameters: */
unsigned color_two_side : 1;
unsigned half_precision : 1;
};
struct fd3_shader_variant;
#endif /* FD3_UTIL_H_ */

View file

@ -40,18 +40,19 @@
#include "tgsi/tgsi_scan.h"
#include "freedreno_lowering.h"
#include "freedreno_util.h"
#include "fd3_compiler.h"
#include "fd3_program.h"
#include "ir3_compiler.h"
#include "ir3_shader.h"
#include "instr-a3xx.h"
#include "ir3.h"
struct fd3_compile_context {
struct ir3_compile_context {
const struct tgsi_token *tokens;
bool free_tokens;
struct ir3 *ir;
struct fd3_shader_variant *so;
struct ir3_shader_variant *so;
struct ir3_block *block;
struct ir3_instruction *current_instr;
@ -117,15 +118,15 @@ struct fd3_compile_context {
};
static void vectorize(struct fd3_compile_context *ctx,
static void vectorize(struct ir3_compile_context *ctx,
struct ir3_instruction *instr, struct tgsi_dst_register *dst,
int nsrcs, ...);
static void create_mov(struct fd3_compile_context *ctx,
static void create_mov(struct ir3_compile_context *ctx,
struct tgsi_dst_register *dst, struct tgsi_src_register *src);
static type_t get_ftype(struct fd3_compile_context *ctx);
static type_t get_ftype(struct ir3_compile_context *ctx);
static unsigned
compile_init(struct fd3_compile_context *ctx, struct fd3_shader_variant *so,
compile_init(struct ir3_compile_context *ctx, struct ir3_shader_variant *so,
const struct tgsi_token *tokens)
{
unsigned ret;
@ -188,7 +189,7 @@ compile_init(struct fd3_compile_context *ctx, struct fd3_shader_variant *so,
}
static void
compile_error(struct fd3_compile_context *ctx, const char *format, ...)
compile_error(struct ir3_compile_context *ctx, const char *format, ...)
{
va_list ap;
va_start(ap, format);
@ -203,7 +204,7 @@ compile_error(struct fd3_compile_context *ctx, const char *format, ...)
} while (0)
static void
compile_free(struct fd3_compile_context *ctx)
compile_free(struct ir3_compile_context *ctx)
{
if (ctx->free_tokens)
free((void *)ctx->tokens);
@ -212,7 +213,7 @@ compile_free(struct fd3_compile_context *ctx)
struct instr_translater {
void (*fxn)(const struct instr_translater *t,
struct fd3_compile_context *ctx,
struct ir3_compile_context *ctx,
struct tgsi_full_instruction *inst);
unsigned tgsi_opc;
opc_t opc;
@ -221,7 +222,7 @@ struct instr_translater {
};
static void
instr_finish(struct fd3_compile_context *ctx)
instr_finish(struct ir3_compile_context *ctx)
{
unsigned i;
@ -243,34 +244,34 @@ instr_finish(struct fd3_compile_context *ctx)
* stuff.
*/
static void
instr_atomic_start(struct fd3_compile_context *ctx)
instr_atomic_start(struct ir3_compile_context *ctx)
{
ctx->atomic = true;
}
static void
instr_atomic_end(struct fd3_compile_context *ctx)
instr_atomic_end(struct ir3_compile_context *ctx)
{
ctx->atomic = false;
instr_finish(ctx);
}
static struct ir3_instruction *
instr_create(struct fd3_compile_context *ctx, int category, opc_t opc)
instr_create(struct ir3_compile_context *ctx, int category, opc_t opc)
{
instr_finish(ctx);
return (ctx->current_instr = ir3_instr_create(ctx->block, category, opc));
}
static struct ir3_instruction *
instr_clone(struct fd3_compile_context *ctx, struct ir3_instruction *instr)
instr_clone(struct ir3_compile_context *ctx, struct ir3_instruction *instr)
{
instr_finish(ctx);
return (ctx->current_instr = ir3_instr_clone(instr));
}
static struct ir3_block *
push_block(struct fd3_compile_context *ctx)
push_block(struct ir3_compile_context *ctx)
{
struct ir3_block *block;
unsigned ntmp, nin, nout;
@ -320,7 +321,7 @@ push_block(struct fd3_compile_context *ctx)
}
static void
pop_block(struct fd3_compile_context *ctx)
pop_block(struct ir3_compile_context *ctx)
{
ctx->block = ctx->block->parent;
compile_assert(ctx, ctx->block);
@ -390,7 +391,7 @@ block_temporary(struct ir3_block *block, unsigned n)
}
static struct ir3_instruction *
create_immed(struct fd3_compile_context *ctx, float val)
create_immed(struct ir3_compile_context *ctx, float val)
{
/* NOTE: *don't* use instr_create() here!
*/
@ -404,7 +405,7 @@ create_immed(struct fd3_compile_context *ctx, float val)
}
static void
ssa_dst(struct fd3_compile_context *ctx, struct ir3_instruction *instr,
ssa_dst(struct ir3_compile_context *ctx, struct ir3_instruction *instr,
const struct tgsi_dst_register *dst, unsigned chan)
{
unsigned n = regid(dst->Index, chan);
@ -445,7 +446,7 @@ ssa_dst(struct fd3_compile_context *ctx, struct ir3_instruction *instr,
}
static void
ssa_src(struct fd3_compile_context *ctx, struct ir3_register *reg,
ssa_src(struct ir3_compile_context *ctx, struct ir3_register *reg,
const struct tgsi_src_register *src, unsigned chan)
{
struct ir3_block *block = ctx->block;
@ -490,7 +491,7 @@ ssa_src(struct fd3_compile_context *ctx, struct ir3_register *reg,
}
static struct ir3_register *
add_dst_reg_wrmask(struct fd3_compile_context *ctx,
add_dst_reg_wrmask(struct ir3_compile_context *ctx,
struct ir3_instruction *instr, const struct tgsi_dst_register *dst,
unsigned chan, unsigned wrmask)
{
@ -557,14 +558,14 @@ add_dst_reg_wrmask(struct fd3_compile_context *ctx,
}
static struct ir3_register *
add_dst_reg(struct fd3_compile_context *ctx, struct ir3_instruction *instr,
add_dst_reg(struct ir3_compile_context *ctx, struct ir3_instruction *instr,
const struct tgsi_dst_register *dst, unsigned chan)
{
return add_dst_reg_wrmask(ctx, instr, dst, chan, 0x1);
}
static struct ir3_register *
add_src_reg_wrmask(struct fd3_compile_context *ctx,
add_src_reg_wrmask(struct ir3_compile_context *ctx,
struct ir3_instruction *instr, const struct tgsi_src_register *src,
unsigned chan, unsigned wrmask)
{
@ -668,7 +669,7 @@ add_src_reg_wrmask(struct fd3_compile_context *ctx,
}
static struct ir3_register *
add_src_reg(struct fd3_compile_context *ctx, struct ir3_instruction *instr,
add_src_reg(struct ir3_compile_context *ctx, struct ir3_instruction *instr,
const struct tgsi_src_register *src, unsigned chan)
{
return add_src_reg_wrmask(ctx, instr, src, chan, 0x1);
@ -693,7 +694,7 @@ src_from_dst(struct tgsi_src_register *src, struct tgsi_dst_register *dst)
* generated by a single TGSI op.
*/
static struct tgsi_src_register *
get_internal_temp(struct fd3_compile_context *ctx,
get_internal_temp(struct ir3_compile_context *ctx,
struct tgsi_dst_register *tmp_dst)
{
struct tgsi_src_register *tmp_src;
@ -736,13 +737,13 @@ is_rel_or_const(struct tgsi_src_register *src)
}
static type_t
get_ftype(struct fd3_compile_context *ctx)
get_ftype(struct ir3_compile_context *ctx)
{
return TYPE_F32;
}
static type_t
get_utype(struct fd3_compile_context *ctx)
get_utype(struct ir3_compile_context *ctx)
{
return TYPE_U32;
}
@ -764,7 +765,7 @@ src_swiz(struct tgsi_src_register *src, int chan)
* generate a move to temporary gpr:
*/
static struct tgsi_src_register *
get_unconst(struct fd3_compile_context *ctx, struct tgsi_src_register *src)
get_unconst(struct ir3_compile_context *ctx, struct tgsi_src_register *src)
{
struct tgsi_dst_register tmp_dst;
struct tgsi_src_register *tmp_src;
@ -779,7 +780,7 @@ get_unconst(struct fd3_compile_context *ctx, struct tgsi_src_register *src)
}
static void
get_immediate(struct fd3_compile_context *ctx,
get_immediate(struct ir3_compile_context *ctx,
struct tgsi_src_register *reg, uint32_t val)
{
unsigned neg, swiz, idx, i;
@ -826,7 +827,7 @@ get_immediate(struct fd3_compile_context *ctx,
}
static void
create_mov(struct fd3_compile_context *ctx, struct tgsi_dst_register *dst,
create_mov(struct ir3_compile_context *ctx, struct tgsi_dst_register *dst,
struct tgsi_src_register *src)
{
type_t type_mov = get_ftype(ctx);
@ -855,7 +856,7 @@ create_mov(struct fd3_compile_context *ctx, struct tgsi_dst_register *dst,
}
static void
create_clamp(struct fd3_compile_context *ctx,
create_clamp(struct ir3_compile_context *ctx,
struct tgsi_dst_register *dst, struct tgsi_src_register *val,
struct tgsi_src_register *minval, struct tgsi_src_register *maxval)
{
@ -869,7 +870,7 @@ create_clamp(struct fd3_compile_context *ctx,
}
static void
create_clamp_imm(struct fd3_compile_context *ctx,
create_clamp_imm(struct ir3_compile_context *ctx,
struct tgsi_dst_register *dst,
uint32_t minval, uint32_t maxval)
{
@ -885,7 +886,7 @@ create_clamp_imm(struct fd3_compile_context *ctx,
}
static struct tgsi_dst_register *
get_dst(struct fd3_compile_context *ctx, struct tgsi_full_instruction *inst)
get_dst(struct ir3_compile_context *ctx, struct tgsi_full_instruction *inst)
{
struct tgsi_dst_register *dst = &inst->Dst[0].Register;
unsigned i;
@ -908,7 +909,7 @@ get_dst(struct fd3_compile_context *ctx, struct tgsi_full_instruction *inst)
}
static void
put_dst(struct fd3_compile_context *ctx, struct tgsi_full_instruction *inst,
put_dst(struct ir3_compile_context *ctx, struct tgsi_full_instruction *inst,
struct tgsi_dst_register *dst)
{
/* if necessary, add mov back into original dst: */
@ -921,7 +922,7 @@ put_dst(struct fd3_compile_context *ctx, struct tgsi_full_instruction *inst,
* to turn a scalar instruction into a vector operation:
*/
static void
vectorize(struct fd3_compile_context *ctx, struct ir3_instruction *instr,
vectorize(struct ir3_compile_context *ctx, struct ir3_instruction *instr,
struct tgsi_dst_register *dst, int nsrcs, ...)
{
va_list ap;
@ -992,7 +993,7 @@ vectorize(struct fd3_compile_context *ctx, struct ir3_instruction *instr,
static void
trans_clamp(const struct instr_translater *t,
struct fd3_compile_context *ctx,
struct ir3_compile_context *ctx,
struct tgsi_full_instruction *inst)
{
struct tgsi_dst_register *dst = get_dst(ctx, inst);
@ -1008,7 +1009,7 @@ trans_clamp(const struct instr_translater *t,
/* ARL(x) = x, but mova from hrN.x to a0.. */
static void
trans_arl(const struct instr_translater *t,
struct fd3_compile_context *ctx,
struct ir3_compile_context *ctx,
struct tgsi_full_instruction *inst)
{
struct ir3_instruction *instr;
@ -1059,7 +1060,7 @@ struct tex_info {
};
static const struct tex_info *
get_tex_info(struct fd3_compile_context *ctx,
get_tex_info(struct ir3_compile_context *ctx,
struct tgsi_full_instruction *inst)
{
static const struct tex_info tex1d = {
@ -1171,7 +1172,7 @@ get_tex_info(struct fd3_compile_context *ctx,
}
static struct tgsi_src_register *
get_tex_coord(struct fd3_compile_context *ctx,
get_tex_coord(struct ir3_compile_context *ctx,
struct tgsi_full_instruction *inst,
const struct tex_info *tinf)
{
@ -1238,7 +1239,7 @@ get_tex_coord(struct fd3_compile_context *ctx,
static void
trans_samp(const struct instr_translater *t,
struct fd3_compile_context *ctx,
struct ir3_compile_context *ctx,
struct tgsi_full_instruction *inst)
{
struct ir3_instruction *instr;
@ -1291,7 +1292,7 @@ trans_samp(const struct instr_translater *t,
*/
static void
trans_cmp(const struct instr_translater *t,
struct fd3_compile_context *ctx,
struct ir3_compile_context *ctx,
struct tgsi_full_instruction *inst)
{
struct ir3_instruction *instr;
@ -1405,7 +1406,7 @@ trans_cmp(const struct instr_translater *t,
*/
static void
trans_icmp(const struct instr_translater *t,
struct fd3_compile_context *ctx,
struct ir3_compile_context *ctx,
struct tgsi_full_instruction *inst)
{
struct ir3_instruction *instr;
@ -1475,7 +1476,7 @@ trans_icmp(const struct instr_translater *t,
*/
static void
push_branch(struct fd3_compile_context *ctx, bool inv,
push_branch(struct ir3_compile_context *ctx, bool inv,
struct ir3_instruction *instr, struct ir3_instruction *cond)
{
unsigned int idx = ctx->branch_count++;
@ -1488,7 +1489,7 @@ push_branch(struct fd3_compile_context *ctx, bool inv,
}
static struct ir3_instruction *
pop_branch(struct fd3_compile_context *ctx)
pop_branch(struct ir3_compile_context *ctx)
{
unsigned int idx = --ctx->branch_count;
return ctx->branch[idx].instr;
@ -1496,7 +1497,7 @@ pop_branch(struct fd3_compile_context *ctx)
static void
trans_if(const struct instr_translater *t,
struct fd3_compile_context *ctx,
struct ir3_compile_context *ctx,
struct tgsi_full_instruction *inst)
{
struct ir3_instruction *instr, *cond;
@ -1532,7 +1533,7 @@ trans_if(const struct instr_translater *t,
static void
trans_else(const struct instr_translater *t,
struct fd3_compile_context *ctx,
struct ir3_compile_context *ctx,
struct tgsi_full_instruction *inst)
{
struct ir3_instruction *instr;
@ -1565,7 +1566,7 @@ find_output(struct ir3_block *block, unsigned n)
}
static struct ir3_instruction *
create_phi(struct fd3_compile_context *ctx, struct ir3_instruction *cond,
create_phi(struct ir3_compile_context *ctx, struct ir3_instruction *cond,
struct ir3_instruction *a, struct ir3_instruction *b)
{
struct ir3_instruction *phi;
@ -1598,7 +1599,7 @@ create_phi(struct fd3_compile_context *ctx, struct ir3_instruction *cond,
static void
trans_endif(const struct instr_translater *t,
struct fd3_compile_context *ctx,
struct ir3_compile_context *ctx,
struct tgsi_full_instruction *inst)
{
struct ir3_instruction *instr;
@ -1715,7 +1716,7 @@ trans_endif(const struct instr_translater *t,
static void
trans_kill(const struct instr_translater *t,
struct fd3_compile_context *ctx,
struct ir3_compile_context *ctx,
struct tgsi_full_instruction *inst)
{
struct ir3_instruction *instr, *immed, *cond = NULL;
@ -1762,7 +1763,7 @@ trans_kill(const struct instr_translater *t,
static void
trans_killif(const struct instr_translater *t,
struct fd3_compile_context *ctx,
struct ir3_compile_context *ctx,
struct tgsi_full_instruction *inst)
{
struct tgsi_src_register *src = &inst->Src[0].Register;
@ -1795,7 +1796,7 @@ trans_killif(const struct instr_translater *t,
static void
trans_cov(const struct instr_translater *t,
struct fd3_compile_context *ctx,
struct ir3_compile_context *ctx,
struct tgsi_full_instruction *inst)
{
struct ir3_instruction *instr;
@ -1833,7 +1834,7 @@ trans_cov(const struct instr_translater *t,
static void
instr_cat0(const struct instr_translater *t,
struct fd3_compile_context *ctx,
struct ir3_compile_context *ctx,
struct tgsi_full_instruction *inst)
{
instr_create(ctx, 0, t->opc);
@ -1841,7 +1842,7 @@ instr_cat0(const struct instr_translater *t,
static void
instr_cat1(const struct instr_translater *t,
struct fd3_compile_context *ctx,
struct ir3_compile_context *ctx,
struct tgsi_full_instruction *inst)
{
struct tgsi_dst_register *dst = get_dst(ctx, inst);
@ -1852,7 +1853,7 @@ instr_cat1(const struct instr_translater *t,
static void
instr_cat2(const struct instr_translater *t,
struct fd3_compile_context *ctx,
struct ir3_compile_context *ctx,
struct tgsi_full_instruction *inst)
{
struct tgsi_dst_register *dst = get_dst(ctx, inst);
@ -1906,7 +1907,7 @@ instr_cat2(const struct instr_translater *t,
static void
instr_cat3(const struct instr_translater *t,
struct fd3_compile_context *ctx,
struct ir3_compile_context *ctx,
struct tgsi_full_instruction *inst)
{
struct tgsi_dst_register *dst = get_dst(ctx, inst);
@ -1936,7 +1937,7 @@ instr_cat3(const struct instr_translater *t,
static void
instr_cat4(const struct instr_translater *t,
struct fd3_compile_context *ctx,
struct ir3_compile_context *ctx,
struct tgsi_full_instruction *inst)
{
struct tgsi_dst_register *dst = get_dst(ctx, inst);
@ -2035,14 +2036,14 @@ static const struct instr_translater translaters[TGSI_OPCODE_LAST] = {
INSTR(F2U, trans_cov),
};
static fd3_semantic
static ir3_semantic
decl_semantic(const struct tgsi_declaration_semantic *sem)
{
return fd3_semantic_name(sem->Name, sem->Index);
return ir3_semantic_name(sem->Name, sem->Index);
}
static struct ir3_instruction *
decl_in_frag_bary(struct fd3_compile_context *ctx, unsigned regid,
decl_in_frag_bary(struct ir3_compile_context *ctx, unsigned regid,
unsigned j, unsigned inloc)
{
struct ir3_instruction *instr;
@ -2073,7 +2074,7 @@ decl_in_frag_bary(struct fd3_compile_context *ctx, unsigned regid,
* of the interpolated vertex position W component.
*/
static struct ir3_instruction *
decl_in_frag_coord(struct fd3_compile_context *ctx, unsigned regid,
decl_in_frag_coord(struct ir3_compile_context *ctx, unsigned regid,
unsigned j)
{
struct ir3_instruction *instr, *src;
@ -2137,7 +2138,7 @@ decl_in_frag_coord(struct fd3_compile_context *ctx, unsigned regid,
* back-facing polygon.
*/
static struct ir3_instruction *
decl_in_frag_face(struct fd3_compile_context *ctx, unsigned regid,
decl_in_frag_face(struct ir3_compile_context *ctx, unsigned regid,
unsigned j)
{
struct ir3_instruction *instr, *src;
@ -2194,9 +2195,9 @@ decl_in_frag_face(struct fd3_compile_context *ctx, unsigned regid,
}
static void
decl_in(struct fd3_compile_context *ctx, struct tgsi_full_declaration *decl)
decl_in(struct ir3_compile_context *ctx, struct tgsi_full_declaration *decl)
{
struct fd3_shader_variant *so = ctx->so;
struct ir3_shader_variant *so = ctx->so;
unsigned name = decl->Semantic.Name;
unsigned i;
@ -2259,9 +2260,9 @@ decl_in(struct fd3_compile_context *ctx, struct tgsi_full_declaration *decl)
}
static void
decl_out(struct fd3_compile_context *ctx, struct tgsi_full_declaration *decl)
decl_out(struct ir3_compile_context *ctx, struct tgsi_full_declaration *decl)
{
struct fd3_shader_variant *so = ctx->so;
struct ir3_shader_variant *so = ctx->so;
unsigned comp = 0;
unsigned name = decl->Semantic.Name;
unsigned i;
@ -2328,9 +2329,9 @@ decl_out(struct fd3_compile_context *ctx, struct tgsi_full_declaration *decl)
* frag_face.
*/
static void
fixup_frag_inputs(struct fd3_compile_context *ctx)
fixup_frag_inputs(struct ir3_compile_context *ctx)
{
struct fd3_shader_variant *so = ctx->so;
struct ir3_shader_variant *so = ctx->so;
struct ir3_block *block = ctx->block;
struct ir3_instruction **inputs;
struct ir3_instruction *instr;
@ -2395,7 +2396,7 @@ fixup_frag_inputs(struct fd3_compile_context *ctx)
}
static void
compile_instructions(struct fd3_compile_context *ctx)
compile_instructions(struct ir3_compile_context *ctx)
{
push_block(ctx);
@ -2473,7 +2474,7 @@ compile_instructions(struct fd3_compile_context *ctx)
}
static void
compile_dump(struct fd3_compile_context *ctx)
compile_dump(struct ir3_compile_context *ctx)
{
const char *name = (ctx->so->type == SHADER_VERTEX) ? "vert" : "frag";
static unsigned n = 0;
@ -2489,10 +2490,10 @@ compile_dump(struct fd3_compile_context *ctx)
}
int
fd3_compile_shader(struct fd3_shader_variant *so,
const struct tgsi_token *tokens, struct fd3_shader_key key)
ir3_compile_shader(struct ir3_shader_variant *so,
const struct tgsi_token *tokens, struct ir3_shader_key key)
{
struct fd3_compile_context ctx;
struct ir3_compile_context ctx;
struct ir3_block *block;
struct ir3_instruction **inputs;
unsigned i, j, actual_in;

View file

@ -29,15 +29,14 @@
#ifndef FD3_COMPILER_H_
#define FD3_COMPILER_H_
#include "fd3_program.h"
#include "fd3_util.h"
#include "ir3_shader.h"
int fd3_compile_shader(struct fd3_shader_variant *so,
int ir3_compile_shader(struct ir3_shader_variant *so,
const struct tgsi_token *tokens,
struct fd3_shader_key key);
int fd3_compile_shader_old(struct fd3_shader_variant *so,
struct ir3_shader_key key);
int ir3_compile_shader_old(struct ir3_shader_variant *so,
const struct tgsi_token *tokens,
struct fd3_shader_key key);
struct ir3_shader_key key);
#endif /* FD3_COMPILER_H_ */

View file

@ -40,21 +40,21 @@
#include "tgsi/tgsi_scan.h"
#include "freedreno_lowering.h"
#include "freedreno_util.h"
#include "fd3_compiler.h"
#include "fd3_program.h"
#include "fd3_util.h"
#include "ir3_compiler.h"
#include "ir3_shader.h"
#include "instr-a3xx.h"
#include "ir3.h"
struct fd3_compile_context {
struct ir3_compile_context {
const struct tgsi_token *tokens;
bool free_tokens;
struct ir3 *ir;
struct ir3_block *block;
struct fd3_shader_variant *so;
struct ir3_shader_variant *so;
struct tgsi_parse_context parser;
unsigned type;
@ -113,14 +113,14 @@ struct fd3_compile_context {
};
static void vectorize(struct fd3_compile_context *ctx,
static void vectorize(struct ir3_compile_context *ctx,
struct ir3_instruction *instr, struct tgsi_dst_register *dst,
int nsrcs, ...);
static void create_mov(struct fd3_compile_context *ctx,
static void create_mov(struct ir3_compile_context *ctx,
struct tgsi_dst_register *dst, struct tgsi_src_register *src);
static unsigned
compile_init(struct fd3_compile_context *ctx, struct fd3_shader_variant *so,
compile_init(struct ir3_compile_context *ctx, struct ir3_shader_variant *so,
const struct tgsi_token *tokens)
{
unsigned ret, base = 0;
@ -194,7 +194,7 @@ compile_init(struct fd3_compile_context *ctx, struct fd3_shader_variant *so,
}
static void
compile_error(struct fd3_compile_context *ctx, const char *format, ...)
compile_error(struct ir3_compile_context *ctx, const char *format, ...)
{
va_list ap;
va_start(ap, format);
@ -209,7 +209,7 @@ compile_error(struct fd3_compile_context *ctx, const char *format, ...)
} while (0)
static void
compile_free(struct fd3_compile_context *ctx)
compile_free(struct ir3_compile_context *ctx)
{
if (ctx->free_tokens)
free((void *)ctx->tokens);
@ -218,7 +218,7 @@ compile_free(struct fd3_compile_context *ctx)
struct instr_translater {
void (*fxn)(const struct instr_translater *t,
struct fd3_compile_context *ctx,
struct ir3_compile_context *ctx,
struct tgsi_full_instruction *inst);
unsigned tgsi_opc;
opc_t opc;
@ -227,7 +227,7 @@ struct instr_translater {
};
static void
handle_last_rel(struct fd3_compile_context *ctx)
handle_last_rel(struct ir3_compile_context *ctx)
{
if (ctx->last_rel) {
ctx->last_rel->flags |= IR3_INSTR_UL;
@ -236,20 +236,20 @@ handle_last_rel(struct fd3_compile_context *ctx)
}
static struct ir3_instruction *
instr_create(struct fd3_compile_context *ctx, int category, opc_t opc)
instr_create(struct ir3_compile_context *ctx, int category, opc_t opc)
{
return ir3_instr_create(ctx->block, category, opc);
}
static void
add_nop(struct fd3_compile_context *ctx, unsigned count)
add_nop(struct ir3_compile_context *ctx, unsigned count)
{
while (count-- > 0)
instr_create(ctx, 0, OPC_NOP);
}
static unsigned
src_flags(struct fd3_compile_context *ctx, struct ir3_register *reg)
src_flags(struct ir3_compile_context *ctx, struct ir3_register *reg)
{
unsigned flags = 0;
@ -270,7 +270,7 @@ src_flags(struct fd3_compile_context *ctx, struct ir3_register *reg)
}
static struct ir3_register *
add_dst_reg(struct fd3_compile_context *ctx, struct ir3_instruction *instr,
add_dst_reg(struct ir3_compile_context *ctx, struct ir3_instruction *instr,
const struct tgsi_dst_register *dst, unsigned chan)
{
unsigned flags = 0, num = 0;
@ -304,7 +304,7 @@ add_dst_reg(struct fd3_compile_context *ctx, struct ir3_instruction *instr,
}
static struct ir3_register *
add_src_reg(struct fd3_compile_context *ctx, struct ir3_instruction *instr,
add_src_reg(struct ir3_compile_context *ctx, struct ir3_instruction *instr,
const struct tgsi_src_register *src, unsigned chan)
{
unsigned flags = 0, num = 0;
@ -377,7 +377,7 @@ src_from_dst(struct tgsi_src_register *src, struct tgsi_dst_register *dst)
* generated by a single TGSI op.
*/
static struct tgsi_src_register *
get_internal_temp(struct fd3_compile_context *ctx,
get_internal_temp(struct ir3_compile_context *ctx,
struct tgsi_dst_register *tmp_dst)
{
struct tgsi_src_register *tmp_src;
@ -404,7 +404,7 @@ get_internal_temp(struct fd3_compile_context *ctx,
* instructions generated by a single TGSI op.
*/
static struct tgsi_src_register *
get_internal_temp_hr(struct fd3_compile_context *ctx,
get_internal_temp_hr(struct ir3_compile_context *ctx,
struct tgsi_dst_register *tmp_dst)
{
struct tgsi_src_register *tmp_src;
@ -453,13 +453,13 @@ is_rel_or_const(struct tgsi_src_register *src)
}
static type_t
get_ftype(struct fd3_compile_context *ctx)
get_ftype(struct ir3_compile_context *ctx)
{
return ctx->so->key.half_precision ? TYPE_F16 : TYPE_F32;
}
static type_t
get_utype(struct fd3_compile_context *ctx)
get_utype(struct ir3_compile_context *ctx)
{
return ctx->so->key.half_precision ? TYPE_U16 : TYPE_U32;
}
@ -481,7 +481,7 @@ src_swiz(struct tgsi_src_register *src, int chan)
* generate a move to temporary gpr:
*/
static struct tgsi_src_register *
get_unconst(struct fd3_compile_context *ctx, struct tgsi_src_register *src)
get_unconst(struct ir3_compile_context *ctx, struct tgsi_src_register *src)
{
struct tgsi_dst_register tmp_dst;
struct tgsi_src_register *tmp_src;
@ -496,7 +496,7 @@ get_unconst(struct fd3_compile_context *ctx, struct tgsi_src_register *src)
}
static void
get_immediate(struct fd3_compile_context *ctx,
get_immediate(struct ir3_compile_context *ctx,
struct tgsi_src_register *reg, uint32_t val)
{
unsigned neg, swiz, idx, i;
@ -543,7 +543,7 @@ get_immediate(struct fd3_compile_context *ctx,
}
static void
create_mov(struct fd3_compile_context *ctx, struct tgsi_dst_register *dst,
create_mov(struct ir3_compile_context *ctx, struct tgsi_dst_register *dst,
struct tgsi_src_register *src)
{
type_t type_mov = get_ftype(ctx);
@ -574,7 +574,7 @@ create_mov(struct fd3_compile_context *ctx, struct tgsi_dst_register *dst,
}
static void
create_clamp(struct fd3_compile_context *ctx,
create_clamp(struct ir3_compile_context *ctx,
struct tgsi_dst_register *dst, struct tgsi_src_register *val,
struct tgsi_src_register *minval, struct tgsi_src_register *maxval)
{
@ -588,7 +588,7 @@ create_clamp(struct fd3_compile_context *ctx,
}
static void
create_clamp_imm(struct fd3_compile_context *ctx,
create_clamp_imm(struct ir3_compile_context *ctx,
struct tgsi_dst_register *dst,
uint32_t minval, uint32_t maxval)
{
@ -604,7 +604,7 @@ create_clamp_imm(struct fd3_compile_context *ctx,
}
static struct tgsi_dst_register *
get_dst(struct fd3_compile_context *ctx, struct tgsi_full_instruction *inst)
get_dst(struct ir3_compile_context *ctx, struct tgsi_full_instruction *inst)
{
struct tgsi_dst_register *dst = &inst->Dst[0].Register;
unsigned i;
@ -627,7 +627,7 @@ get_dst(struct fd3_compile_context *ctx, struct tgsi_full_instruction *inst)
}
static void
put_dst(struct fd3_compile_context *ctx, struct tgsi_full_instruction *inst,
put_dst(struct ir3_compile_context *ctx, struct tgsi_full_instruction *inst,
struct tgsi_dst_register *dst)
{
/* if necessary, add mov back into original dst: */
@ -640,7 +640,7 @@ put_dst(struct fd3_compile_context *ctx, struct tgsi_full_instruction *inst,
* to turn a scalar instruction into a vector operation:
*/
static void
vectorize(struct fd3_compile_context *ctx, struct ir3_instruction *instr,
vectorize(struct ir3_compile_context *ctx, struct ir3_instruction *instr,
struct tgsi_dst_register *dst, int nsrcs, ...)
{
va_list ap;
@ -716,7 +716,7 @@ vectorize(struct fd3_compile_context *ctx, struct ir3_instruction *instr,
static void
trans_clamp(const struct instr_translater *t,
struct fd3_compile_context *ctx,
struct ir3_compile_context *ctx,
struct tgsi_full_instruction *inst)
{
struct tgsi_dst_register *dst = get_dst(ctx, inst);
@ -732,7 +732,7 @@ trans_clamp(const struct instr_translater *t,
/* ARL(x) = x, but mova from hrN.x to a0.. */
static void
trans_arl(const struct instr_translater *t,
struct fd3_compile_context *ctx,
struct ir3_compile_context *ctx,
struct tgsi_full_instruction *inst)
{
struct ir3_instruction *instr;
@ -778,7 +778,7 @@ trans_arl(const struct instr_translater *t,
/* texture fetch/sample instructions: */
static void
trans_samp(const struct instr_translater *t,
struct fd3_compile_context *ctx,
struct ir3_compile_context *ctx,
struct tgsi_full_instruction *inst)
{
struct ir3_register *r;
@ -908,7 +908,7 @@ trans_samp(const struct instr_translater *t,
*/
static void
trans_cmp(const struct instr_translater *t,
struct fd3_compile_context *ctx,
struct ir3_compile_context *ctx,
struct tgsi_full_instruction *inst)
{
struct ir3_instruction *instr;
@ -1007,7 +1007,7 @@ trans_cmp(const struct instr_translater *t,
*/
static unsigned
find_instruction(struct fd3_compile_context *ctx, struct ir3_instruction *instr)
find_instruction(struct ir3_compile_context *ctx, struct ir3_instruction *instr)
{
unsigned i;
for (i = 0; i < ctx->ir->instrs_count; i++)
@ -1017,13 +1017,13 @@ find_instruction(struct fd3_compile_context *ctx, struct ir3_instruction *instr)
}
static void
push_branch(struct fd3_compile_context *ctx, struct ir3_instruction *instr)
push_branch(struct ir3_compile_context *ctx, struct ir3_instruction *instr)
{
ctx->branch[ctx->branch_count++] = instr;
}
static void
pop_branch(struct fd3_compile_context *ctx)
pop_branch(struct ir3_compile_context *ctx)
{
struct ir3_instruction *instr;
@ -1047,7 +1047,7 @@ pop_branch(struct fd3_compile_context *ctx)
*/
static void
trans_if(const struct instr_translater *t,
struct fd3_compile_context *ctx,
struct ir3_compile_context *ctx,
struct tgsi_full_instruction *inst)
{
struct ir3_instruction *instr;
@ -1071,7 +1071,7 @@ trans_if(const struct instr_translater *t,
static void
trans_else(const struct instr_translater *t,
struct fd3_compile_context *ctx,
struct ir3_compile_context *ctx,
struct tgsi_full_instruction *inst)
{
struct ir3_instruction *instr;
@ -1085,7 +1085,7 @@ trans_else(const struct instr_translater *t,
static void
trans_endif(const struct instr_translater *t,
struct fd3_compile_context *ctx,
struct ir3_compile_context *ctx,
struct tgsi_full_instruction *inst)
{
pop_branch(ctx);
@ -1098,7 +1098,7 @@ trans_endif(const struct instr_translater *t,
static void
instr_cat0(const struct instr_translater *t,
struct fd3_compile_context *ctx,
struct ir3_compile_context *ctx,
struct tgsi_full_instruction *inst)
{
instr_create(ctx, 0, t->opc);
@ -1106,7 +1106,7 @@ instr_cat0(const struct instr_translater *t,
static void
instr_cat1(const struct instr_translater *t,
struct fd3_compile_context *ctx,
struct ir3_compile_context *ctx,
struct tgsi_full_instruction *inst)
{
struct tgsi_dst_register *dst = get_dst(ctx, inst);
@ -1136,7 +1136,7 @@ instr_cat1(const struct instr_translater *t,
static void
instr_cat2(const struct instr_translater *t,
struct fd3_compile_context *ctx,
struct ir3_compile_context *ctx,
struct tgsi_full_instruction *inst)
{
struct tgsi_dst_register *dst = get_dst(ctx, inst);
@ -1188,7 +1188,7 @@ instr_cat2(const struct instr_translater *t,
static void
instr_cat3(const struct instr_translater *t,
struct fd3_compile_context *ctx,
struct ir3_compile_context *ctx,
struct tgsi_full_instruction *inst)
{
struct tgsi_dst_register *dst = get_dst(ctx, inst);
@ -1219,7 +1219,7 @@ instr_cat3(const struct instr_translater *t,
static void
instr_cat4(const struct instr_translater *t,
struct fd3_compile_context *ctx,
struct ir3_compile_context *ctx,
struct tgsi_full_instruction *inst)
{
struct tgsi_dst_register *dst = get_dst(ctx, inst);
@ -1290,16 +1290,16 @@ static const struct instr_translater translaters[TGSI_OPCODE_LAST] = {
INSTR(KILL, instr_cat0, .opc = OPC_KILL),
};
static fd3_semantic
static ir3_semantic
decl_semantic(const struct tgsi_declaration_semantic *sem)
{
return fd3_semantic_name(sem->Name, sem->Index);
return ir3_semantic_name(sem->Name, sem->Index);
}
static int
decl_in(struct fd3_compile_context *ctx, struct tgsi_full_declaration *decl)
decl_in(struct ir3_compile_context *ctx, struct tgsi_full_declaration *decl)
{
struct fd3_shader_variant *so = ctx->so;
struct ir3_shader_variant *so = ctx->so;
unsigned base = ctx->base_reg[TGSI_FILE_INPUT];
unsigned i, flags = 0;
int nop = 0;
@ -1366,9 +1366,9 @@ decl_in(struct fd3_compile_context *ctx, struct tgsi_full_declaration *decl)
}
static void
decl_out(struct fd3_compile_context *ctx, struct tgsi_full_declaration *decl)
decl_out(struct ir3_compile_context *ctx, struct tgsi_full_declaration *decl)
{
struct fd3_shader_variant *so = ctx->so;
struct ir3_shader_variant *so = ctx->so;
unsigned base = ctx->base_reg[TGSI_FILE_OUTPUT];
unsigned comp = 0;
unsigned name = decl->Semantic.Name;
@ -1419,13 +1419,13 @@ decl_out(struct fd3_compile_context *ctx, struct tgsi_full_declaration *decl)
}
static void
decl_samp(struct fd3_compile_context *ctx, struct tgsi_full_declaration *decl)
decl_samp(struct ir3_compile_context *ctx, struct tgsi_full_declaration *decl)
{
ctx->so->has_samp = true;
}
static void
compile_instructions(struct fd3_compile_context *ctx)
compile_instructions(struct ir3_compile_context *ctx)
{
struct ir3 *ir = ctx->ir;
int nop = 0;
@ -1502,10 +1502,10 @@ compile_instructions(struct fd3_compile_context *ctx)
}
int
fd3_compile_shader_old(struct fd3_shader_variant *so,
const struct tgsi_token *tokens, struct fd3_shader_key key)
ir3_compile_shader_old(struct ir3_shader_variant *so,
const struct tgsi_token *tokens, struct ir3_shader_key key)
{
struct fd3_compile_context ctx;
struct ir3_compile_context ctx;
assert(!so->ir);

View file

@ -0,0 +1,211 @@
/* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */
/*
* Copyright (C) 2014 Rob Clark <robclark@freedesktop.org>
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Authors:
* Rob Clark <robclark@freedesktop.org>
*/
#include "pipe/p_state.h"
#include "util/u_string.h"
#include "util/u_memory.h"
#include "util/u_inlines.h"
#include "util/u_format.h"
#include "tgsi/tgsi_dump.h"
#include "tgsi/tgsi_parse.h"
#include "freedreno_context.h"
#include "freedreno_lowering.h"
#include "freedreno_util.h"
#include "ir3_shader.h"
#include "ir3_compiler.h"
static void
delete_variant(struct ir3_shader_variant *v)
{
ir3_destroy(v->ir);
fd_bo_del(v->bo);
free(v);
}
static void
assemble_variant(struct ir3_shader_variant *v)
{
struct fd_context *ctx = fd_context(v->shader->pctx);
uint32_t sz, *bin;
bin = ir3_assemble(v->ir, &v->info);
sz = v->info.sizedwords * 4;
v->bo = fd_bo_new(ctx->dev, sz,
DRM_FREEDRENO_GEM_CACHE_WCOMBINE |
DRM_FREEDRENO_GEM_TYPE_KMEM);
memcpy(fd_bo_map(v->bo), bin, sz);
free(bin);
v->instrlen = v->info.sizedwords / 8;
v->constlen = v->info.max_const + 1;
}
/* for vertex shader, the inputs are loaded into registers before the shader
* is executed, so max_regs from the shader instructions might not properly
* reflect the # of registers actually used:
*/
static void
fixup_vp_regfootprint(struct ir3_shader_variant *v)
{
unsigned i;
for (i = 0; i < v->inputs_count; i++) {
if (v->inputs[i].compmask) {
uint32_t regid = (v->inputs[i].regid + 3) >> 2;
v->info.max_reg = MAX2(v->info.max_reg, regid);
}
}
for (i = 0; i < v->outputs_count; i++) {
uint32_t regid = (v->outputs[i].regid + 3) >> 2;
v->info.max_reg = MAX2(v->info.max_reg, regid);
}
}
static struct ir3_shader_variant *
create_variant(struct ir3_shader *shader, struct ir3_shader_key key)
{
struct ir3_shader_variant *v = CALLOC_STRUCT(ir3_shader_variant);
const struct tgsi_token *tokens = shader->tokens;
int ret;
if (!v)
return NULL;
v->shader = shader;
v->key = key;
v->type = shader->type;
if (fd_mesa_debug & FD_DBG_DISASM) {
DBG("dump tgsi: type=%d, k={bp=%u,cts=%u,hp=%u}", shader->type,
key.binning_pass, key.color_two_side, key.half_precision);
tgsi_dump(tokens, 0);
}
if (!(fd_mesa_debug & FD_DBG_NOOPT)) {
ret = ir3_compile_shader(v, tokens, key);
if (ret) {
debug_error("new compiler failed, trying fallback!");
v->inputs_count = 0;
v->outputs_count = 0;
v->total_in = 0;
v->has_samp = false;
v->immediates_count = 0;
}
} else {
ret = -1; /* force fallback to old compiler */
}
if (ret)
ret = ir3_compile_shader_old(v, tokens, key);
if (ret) {
debug_error("compile failed!");
goto fail;
}
assemble_variant(v);
if (!v->bo) {
debug_error("assemble failed!");
goto fail;
}
if (shader->type == SHADER_VERTEX)
fixup_vp_regfootprint(v);
if (fd_mesa_debug & FD_DBG_DISASM) {
DBG("disassemble: type=%d, k={bp=%u,cts=%u,hp=%u}", v->type,
key.binning_pass, key.color_two_side, key.half_precision);
disasm_a3xx(fd_bo_map(v->bo), v->info.sizedwords, 0, v->type);
}
return v;
fail:
delete_variant(v);
return NULL;
}
struct ir3_shader_variant *
ir3_shader_variant(struct ir3_shader *shader, struct ir3_shader_key key)
{
struct ir3_shader_variant *v;
/* some shader key values only apply to vertex or frag shader,
* so normalize the key to avoid constructing multiple identical
* variants:
*/
if (shader->type == SHADER_FRAGMENT) {
key.binning_pass = false;
}
if (shader->type == SHADER_VERTEX) {
key.color_two_side = false;
key.half_precision = false;
}
for (v = shader->variants; v; v = v->next)
if (!memcmp(&key, &v->key, sizeof(key)))
return v;
/* compile new variant if it doesn't exist already: */
v = create_variant(shader, key);
v->next = shader->variants;
shader->variants = v;
return v;
}
void
ir3_shader_destroy(struct ir3_shader *shader)
{
struct ir3_shader_variant *v, *t;
for (v = shader->variants; v; ) {
t = v;
v = v->next;
delete_variant(t);
}
free((void *)shader->tokens);
free(shader);
}
struct ir3_shader *
ir3_shader_create(struct pipe_context *pctx, const struct tgsi_token *tokens,
enum shader_t type)
{
struct ir3_shader *shader = CALLOC_STRUCT(ir3_shader);
shader->pctx = pctx;
shader->type = type;
shader->tokens = tgsi_dup_tokens(tokens);
return shader;
}

View file

@ -0,0 +1,163 @@
/* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */
/*
* Copyright (C) 2014 Rob Clark <robclark@freedesktop.org>
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Authors:
* Rob Clark <robclark@freedesktop.org>
*/
#ifndef IR3_SHADER_H_
#define IR3_SHADER_H_
#include "ir3.h"
#include "disasm.h"
typedef uint16_t ir3_semantic; /* semantic name + index */
static inline ir3_semantic
ir3_semantic_name(uint8_t name, uint16_t index)
{
return (name << 8) | (index & 0xff);
}
static inline uint8_t sem2name(ir3_semantic sem)
{
return sem >> 8;
}
static inline uint16_t sem2idx(ir3_semantic sem)
{
return sem & 0xff;
}
/* Configuration key used to identify a shader variant.. different
* shader variants can be used to implement features not supported
* in hw (two sided color), binning-pass vertex shader, etc.
*/
struct ir3_shader_key {
/* vertex shader variant parameters: */
unsigned binning_pass : 1;
/* fragment shader variant parameters: */
unsigned color_two_side : 1;
unsigned half_precision : 1;
};
struct ir3_shader_variant {
struct fd_bo *bo;
struct ir3_shader_key key;
struct ir3_info info;
struct ir3 *ir;
/* the instructions length is in units of instruction groups
* (4 instructions, 8 dwords):
*/
unsigned instrlen;
/* the constants length is in units of vec4's, and is the sum of
* the uniforms and the built-in compiler constants
*/
unsigned constlen;
/* About Linkage:
* + Let the frag shader determine the position/compmask for the
* varyings, since it is the place where we know if the varying
* is actually used, and if so, which components are used. So
* what the hw calls "outloc" is taken from the "inloc" of the
* frag shader.
* + From the vert shader, we only need the output regid
*/
/* for frag shader, pos_regid holds the frag_pos, ie. what is passed
* to bary.f instructions
*/
uint8_t pos_regid;
bool frag_coord, frag_face;
/* varyings/outputs: */
unsigned outputs_count;
struct {
ir3_semantic semantic;
uint8_t regid;
} outputs[16 + 2]; /* +POSITION +PSIZE */
bool writes_pos, writes_psize;
/* vertices/inputs: */
unsigned inputs_count;
struct {
ir3_semantic semantic;
uint8_t regid;
uint8_t compmask;
uint8_t ncomp;
/* in theory inloc of fs should match outloc of vs: */
uint8_t inloc;
uint8_t bary;
} inputs[16 + 2]; /* +POSITION +FACE */
unsigned total_in; /* sum of inputs (scalar) */
/* do we have one or more texture sample instructions: */
bool has_samp;
/* const reg # of first immediate, ie. 1 == c1
* (not regid, because TGSI thinks in terms of vec4 registers,
* not scalar registers)
*/
unsigned first_immediate;
unsigned immediates_count;
struct {
uint32_t val[4];
} immediates[64];
/* shader variants form a linked list: */
struct ir3_shader_variant *next;
/* replicated here to avoid passing extra ptrs everywhere: */
enum shader_t type;
struct ir3_shader *shader;
};
struct ir3_shader {
enum shader_t type;
struct pipe_context *pctx;
const struct tgsi_token *tokens;
struct ir3_shader_variant *variants;
/* so far, only used for blit_prog shader.. values for
* VPC_VARYING_INTERP[i].MODE and VPC_VARYING_PS_REPL[i].MODE
*/
uint32_t vinterp[4], vpsrepl[4];
};
struct ir3_shader * ir3_shader_create(struct pipe_context *pctx,
const struct tgsi_token *tokens, enum shader_t type);
void ir3_shader_destroy(struct ir3_shader *shader);
struct ir3_shader_variant * ir3_shader_variant(struct ir3_shader *shader,
struct ir3_shader_key key);
#endif /* IR3_SHADER_H_ */