nvc0: hook up to new shader code generator

Also includes loading of shared shader library code (used for f64
and integer division) and setting up the immediate array buffer
which is appended to the code.
This commit is contained in:
Christoph Bumiller 2011-09-13 23:10:35 +02:00
parent 57594065c3
commit 3afabfb929
10 changed files with 556 additions and 660 deletions

View file

@ -153,6 +153,7 @@ extern struct draw_stage *nv50_draw_render_stage(struct nv50_context *);
/* nv50_program.c */
boolean nv50_program_translate(struct nv50_program *);
boolean nv50_program_translate_new(struct nv50_program *);
void nv50_program_destroy(struct nv50_context *, struct nv50_program *);
/* nv50_query.c */

View file

@ -29,6 +29,8 @@
#include "tgsi/tgsi_util.h"
#include "tgsi/tgsi_dump.h"
#include "codegen/nv50_ir_driver.h"
static INLINE unsigned
bitcount4(const uint32_t val)
{
@ -625,6 +627,17 @@ nv50_prog_scan(struct nv50_translation_info *ti)
return ret;
}
/* Temporary, need a reference to nv50_ir_generate_code in libnv50 or
* it "gets disappeared" and cannot be used in libnvc0 ...
*/
boolean
nv50_program_translate_new(struct nv50_program *p)
{
struct nv50_ir_prog_info info;
return nv50_ir_generate_code(&info);
}
boolean
nv50_program_translate(struct nv50_program *p)
{

View file

@ -13,12 +13,6 @@ C_SOURCES := \
nvc0_vbo.c \
nvc0_program.c \
nvc0_shader_state.c \
nvc0_pc.c \
nvc0_pc_print.c \
nvc0_pc_emit.c \
nvc0_tgsi_to_nc.c \
nvc0_pc_optimize.c \
nvc0_pc_regalloc.c \
nvc0_push.c \
nvc0_push2.c \
nvc0_query.c

View file

@ -152,6 +152,9 @@ nvc0_create(struct pipe_screen *pscreen, void *priv)
nouveau_context_init_vdec(&nvc0->base);
/* shader builtin library is per-screen, but we need a context for m2mf */
nvc0_program_library_upload(nvc0);
return pipe;
}

View file

@ -79,6 +79,7 @@ struct nvc0_context {
uint8_t num_textures[5];
uint8_t num_samplers[5];
uint8_t tls_required; /* bitmask of shader types using l[] */
uint8_t c14_bound; /* whether immediate array constbuf is bound */
uint16_t scissor;
uint32_t uniform_buffer_bound[5];
} state;
@ -161,7 +162,9 @@ extern struct draw_stage *nvc0_draw_render_stage(struct nvc0_context *);
/* nvc0_program.c */
boolean nvc0_program_translate(struct nvc0_program *);
boolean nvc0_program_upload_code(struct nvc0_context *, struct nvc0_program *);
void nvc0_program_destroy(struct nvc0_context *, struct nvc0_program *);
void nvc0_program_library_upload(struct nvc0_context *);
/* nvc0_query.c */
void nvc0_init_query_functions(struct nvc0_context *);

File diff suppressed because it is too large Load diff

View file

@ -3,9 +3,8 @@
#define __NVC0_PROGRAM_H__
#include "pipe/p_state.h"
#include "tgsi/tgsi_scan.h"
#define NVC0_CAP_MAX_PROGRAM_TEMPS 64
#define NVC0_CAP_MAX_PROGRAM_TEMPS 128
#define NVC0_SHADER_HEADER_SIZE (20 * 4)
@ -14,15 +13,17 @@ struct nvc0_program {
ubyte type;
boolean translated;
ubyte max_gpr;
uint8_t max_gpr;
uint32_t *code;
uint32_t *immd_data;
unsigned code_base;
unsigned code_size;
unsigned parm_size;
uint32_t hdr[20]; /* TODO: move this into code to save space */
unsigned immd_base;
unsigned immd_size; /* size of immediate array data */
unsigned parm_size; /* size of non-bindable uniforms (c0[]) */
uint32_t hdr[20];
uint32_t flags[2];
struct {
@ -34,59 +35,14 @@ struct nvc0_program {
uint8_t early_z;
uint8_t in_pos[PIPE_MAX_SHADER_INPUTS];
} fp;
struct {
uint32_t tess_mode; /* ~0 if defined by the other stage */
uint32_t input_patch_size;
} tp;
void *relocs;
unsigned num_relocs;
struct nouveau_resource *res;
};
/* first 2 bits are written into the program header, for each input */
#define NVC0_INTERP_FLAT (1 << 0)
#define NVC0_INTERP_PERSPECTIVE (2 << 0)
#define NVC0_INTERP_LINEAR (3 << 0)
#define NVC0_INTERP_CENTROID (1 << 2)
/* analyze TGSI and see which TEMP[] are used as subroutine inputs/outputs */
struct nvc0_subroutine {
unsigned id;
unsigned first_insn;
uint32_t argv[NVC0_CAP_MAX_PROGRAM_TEMPS][4];
uint32_t retv[NVC0_CAP_MAX_PROGRAM_TEMPS][4];
};
struct nvc0_translation_info {
struct nvc0_program *prog;
struct tgsi_full_instruction *insns;
unsigned num_insns;
ubyte input_file;
ubyte output_file;
ubyte fp_depth_output;
uint16_t input_loc[PIPE_MAX_SHADER_INPUTS][4];
uint16_t output_loc[PIPE_MAX_SHADER_OUTPUTS][4];
uint16_t sysval_loc[TGSI_SEMANTIC_COUNT];
boolean sysval_in[TGSI_SEMANTIC_COUNT];
int input_access[PIPE_MAX_SHADER_INPUTS][4];
int output_access[PIPE_MAX_SHADER_OUTPUTS][4];
ubyte interp_mode[PIPE_MAX_SHADER_INPUTS];
boolean indirect_inputs;
boolean indirect_outputs;
boolean require_stores;
boolean global_stores;
uint32_t *immd32;
ubyte *immd32_ty;
unsigned immd32_nr;
unsigned temp128_nr;
ubyte edgeflag_out;
struct nvc0_subroutine *subr;
unsigned num_subrs;
boolean append_ucp;
struct tgsi_shader_info scan;
};
int nvc0_generate_code(struct nvc0_translation_info *);
void nvc0_relocate_program(struct nvc0_program *,
uint32_t code_base, uint32_t data_base);
#endif

View file

@ -155,7 +155,7 @@ nvc0_screen_get_shader_param(struct pipe_screen *pscreen, unsigned shader,
case PIPE_SHADER_CAP_MAX_TEX_INDIRECTIONS:
return 16384;
case PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH:
return 4;
return 16;
case PIPE_SHADER_CAP_MAX_INPUTS:
if (shader == PIPE_SHADER_VERTEX)
return 32;
@ -179,9 +179,9 @@ nvc0_screen_get_shader_param(struct pipe_screen *pscreen, unsigned shader,
case PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED:
return 1;
case PIPE_SHADER_CAP_SUBROUTINES:
return 0; /* please inline, or provide function declarations */
return 1; /* but inlining everything, we need function declarations */
case PIPE_SHADER_CAP_INTEGERS:
return 0;
return 1;
default:
NOUVEAU_ERR("unknown PIPE_SHADER_CAP %d\n", param);
return 0;
@ -225,6 +225,7 @@ nvc0_screen_destroy(struct pipe_screen *pscreen)
nouveau_bo_ref(NULL, &screen->fence.bo);
nouveau_bo_ref(NULL, &screen->vfetch_cache);
nouveau_resource_destroy(&screen->lib_code);
nouveau_resource_destroy(&screen->text_heap);
if (screen->tic.entries)

View file

@ -34,6 +34,7 @@ struct nvc0_screen {
uint64_t tls_size;
struct nouveau_resource *text_heap;
struct nouveau_resource *lib_code; /* allocated from text_heap */
struct {
struct nouveau_bo *bo[NVC0_SCRATCH_NR_BUFFERS];

View file

@ -31,18 +31,37 @@ static INLINE void
nvc0_program_update_context_state(struct nvc0_context *nvc0,
struct nvc0_program *prog, int stage)
{
struct nouveau_channel *chan = nvc0->screen->base.channel;
if (prog->hdr[1])
nvc0->state.tls_required |= 1 << stage;
else
nvc0->state.tls_required &= ~(1 << stage);
if (prog->immd_size) {
const unsigned rl = NOUVEAU_BO_VRAM | NOUVEAU_BO_RD;
BEGIN_RING(chan, RING_3D(CB_SIZE), 3);
/* NOTE: may overlap code of a different shader */
OUT_RING (chan, align(prog->immd_size, 0x100));
OUT_RELOCh(chan, nvc0->screen->text, prog->immd_base, rl);
OUT_RELOCl(chan, nvc0->screen->text, prog->immd_base, rl);
BEGIN_RING(chan, RING_3D(CB_BIND(stage)), 1);
OUT_RING (chan, (14 << 4) | 1);
nvc0->state.c14_bound |= 1 << stage;
} else
if (nvc0->state.c14_bound & (1 << stage)) {
BEGIN_RING(chan, RING_3D(CB_BIND(stage)), 1);
OUT_RING (chan, (14 << 4) | 0);
nvc0->state.c14_bound &= ~(1 << stage);
}
}
static boolean
static INLINE boolean
nvc0_program_validate(struct nvc0_context *nvc0, struct nvc0_program *prog)
{
int ret;
unsigned size;
if (prog->translated)
return TRUE;
@ -50,25 +69,7 @@ nvc0_program_validate(struct nvc0_context *nvc0, struct nvc0_program *prog)
if (!prog->translated)
return FALSE;
size = align(prog->code_size + NVC0_SHADER_HEADER_SIZE, 0x100);
ret = nouveau_resource_alloc(nvc0->screen->text_heap, size, prog,
&prog->res);
if (ret)
return FALSE;
prog->code_base = prog->res->start;
nvc0_m2mf_push_linear(&nvc0->base, nvc0->screen->text, prog->code_base,
NOUVEAU_BO_VRAM, NVC0_SHADER_HEADER_SIZE, prog->hdr);
nvc0_m2mf_push_linear(&nvc0->base, nvc0->screen->text,
prog->code_base + NVC0_SHADER_HEADER_SIZE,
NOUVEAU_BO_VRAM, prog->code_size, prog->code);
BEGIN_RING(nvc0->screen->base.channel, RING_3D(MEM_BARRIER), 1);
OUT_RING (nvc0->screen->base.channel, 0x1111);
return TRUE;
return nvc0_program_upload_code(nvc0, prog);
}
void