diff options
Diffstat (limited to 'src/gallium/drivers')
28 files changed, 669 insertions, 559 deletions
diff --git a/src/gallium/drivers/llvmpipe/lp_screen.c b/src/gallium/drivers/llvmpipe/lp_screen.c index 9459a3cd113..b6919a5c6d3 100644 --- a/src/gallium/drivers/llvmpipe/lp_screen.c +++ b/src/gallium/drivers/llvmpipe/lp_screen.c @@ -164,6 +164,8 @@ llvmpipe_get_param(struct pipe_screen *screen, enum pipe_cap param) return 1; case PIPE_CAP_DEPTH_CLAMP: return 0; + case PIPE_CAP_INSTANCED_DRAWING: + return 1; default: return 0; } diff --git a/src/gallium/drivers/llvmpipe/lp_state_fs.c b/src/gallium/drivers/llvmpipe/lp_state_fs.c index ae207617cc1..1b9119eda00 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_fs.c +++ b/src/gallium/drivers/llvmpipe/lp_state_fs.c @@ -334,7 +334,8 @@ generate_fs(struct gallivm_state *gallivm, /* Build the actual shader */ lp_build_tgsi_soa(gallivm, tokens, type, &mask, - consts_ptr, interp->pos, interp->inputs, + consts_ptr, NULL, /* sys values array */ + interp->pos, interp->inputs, outputs, sampler, &shader->info.base); /* Alpha test */ diff --git a/src/gallium/drivers/noop/noop_pipe.c b/src/gallium/drivers/noop/noop_pipe.c index 8c9efc2f536..3680f4622da 100644 --- a/src/gallium/drivers/noop/noop_pipe.c +++ b/src/gallium/drivers/noop/noop_pipe.c @@ -124,7 +124,7 @@ static struct pipe_resource *noop_resource_from_handle(struct pipe_screen *scree struct noop_pipe_screen *noop_screen = (struct noop_pipe_screen*)screen; struct pipe_screen *oscreen = noop_screen->oscreen; struct pipe_resource *result; - struct noop_resource *noop_resource; + struct pipe_resource *noop_resource; result = oscreen->resource_from_handle(oscreen, templ, handle); noop_resource = noop_resource_create(screen, result); diff --git a/src/gallium/drivers/nvc0/nvc0_3d.xml.h b/src/gallium/drivers/nvc0/nvc0_3d.xml.h index 702e58b2e3c..31302949d5e 100644 --- a/src/gallium/drivers/nvc0/nvc0_3d.xml.h +++ b/src/gallium/drivers/nvc0/nvc0_3d.xml.h @@ -8,7 +8,7 @@ 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: -- nvc0_3d.xml ( 30401 bytes, from 2011-01-08 18:09:11) +- nvc0_3d.xml ( 30827 bytes, from 2011-01-13 18:23:07) - copyright.xml ( 6452 bytes, from 2010-11-25 23:28:20) - nv_defs.xml ( 4437 bytes, from 2010-07-06 07:43:58) - nv_3ddefs.xml ( 16394 bytes, from 2010-12-17 15:10:40) @@ -449,6 +449,8 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define NVC0_3D_LINKED_TSC 0x00001234 +#define NVC0_3D_DRAW_TFB_BYTES 0x0000123c + #define NVC0_3D_FP_RESULT_COUNT 0x00001298 #define NVC0_3D_DEPTH_TEST_ENABLE 0x000012cc @@ -511,6 +513,10 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define NVC0_3D_ALPHA_TEST_FUNC_GEQUAL 0x00000206 #define NVC0_3D_ALPHA_TEST_FUNC_ALWAYS 0x00000207 +#define NVC0_3D_DRAW_TFB_STRIDE 0x00001318 +#define NVC0_3D_DRAW_TFB_STRIDE__MIN 0x00000001 +#define NVC0_3D_DRAW_TFB_STRIDE__MAX 0x00000fff + #define NVC0_3D_BLEND_COLOR(i0) (0x0000131c + 0x4*(i0)) #define NVC0_3D_BLEND_COLOR__ESIZE 0x00000004 #define NVC0_3D_BLEND_COLOR__LEN 0x00000004 @@ -603,6 +609,8 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define NVC0_3D_STENCIL_FRONT_FUNC_MASK 0x0000139c +#define NVC0_3D_DRAW_TFB_BASE 0x000013a4 + #define NVC0_3D_FRAG_COLOR_CLAMP_EN 0x000013a8 #define NVC0_3D_FRAG_COLOR_CLAMP_EN_0 0x00000001 #define NVC0_3D_FRAG_COLOR_CLAMP_EN_1 0x00000010 @@ -613,7 +621,9 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define NVC0_3D_FRAG_COLOR_CLAMP_EN_6 0x01000000 #define NVC0_3D_FRAG_COLOR_CLAMP_EN_7 0x10000000 -#define NVC0_3D_Y_ORIGIN_BOTTOM 0x000013ac +#define NVC0_3D_SCREEN_Y_CONTROL 0x000013ac +#define NVC0_3D_SCREEN_Y_CONTROL_Y_NEGATE 0x00000001 +#define NVC0_3D_SCREEN_Y_CONTROL_TRIANGLE_RAST_FLIP 0x00000010 #define NVC0_3D_LINE_WIDTH 0x000013b0 @@ -621,7 +631,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define NVC0_3D_GP_VERTEX_OUTPUT_COUNT__MIN 0x00000001 #define NVC0_3D_GP_VERTEX_OUTPUT_COUNT__MAX 0x00000400 -#define NVC0_3D_FENCE_UNK 0x0000142c +#define NVC0_3D_VERTEX_ARRAY_FLUSH 0x0000142c #define NVC0_3D_VB_ELEMENT_BASE 0x00001434 @@ -668,7 +678,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define NVC0_3D_COUNTER_RESET_UNK1E 0x0000001e #define NVC0_3D_COUNTER_RESET_GENERATED_PRIMITIVES 0x0000001f -#define NVC0_3D_MULTISAMPLE_ZETA_ENABLE 0x00001534 +#define NVC0_3D_MULTISAMPLE_ENABLE 0x00001534 #define NVC0_3D_ZETA_ENABLE 0x00001538 @@ -747,7 +757,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define NVC0_3D_STENCIL_BACK_FUNC_FUNC_GEQUAL 0x00000206 #define NVC0_3D_STENCIL_BACK_FUNC_FUNC_ALWAYS 0x00000207 -#define NVC0_3D_MULTISAMPLE_COLOR_ENABLE 0x000015b4 +#define NVC0_3D_CSAA_ENABLE 0x000015b4 #define NVC0_3D_FRAMEBUFFER_SRGB 0x000015b8 @@ -849,6 +859,10 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define NVC0_3D_POINT_SMOOTH_ENABLE 0x00001658 +#define NVC0_3D_POINT_RASTER_RULES 0x0000165c +#define NVC0_3D_POINT_RASTER_RULES_OGL 0x00000000 +#define NVC0_3D_POINT_RASTER_RULES_D3D 0x00000001 + #define NVC0_3D_POINT_SPRITE_CTRL 0x00001660 #define NVC0_3D_TEX_MISC 0x00001664 @@ -1028,6 +1042,14 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define NVC0_3D_VERTEX_ARRAY_FETCH_STRIDE__SHIFT 0 #define NVC0_3D_VERTEX_ARRAY_FETCH_ENABLE 0x00001000 +#define NVC0_3D_VERTEX_ARRAY_START_HIGH(i0) (0x00001c04 + 0x10*(i0)) +#define NVC0_3D_VERTEX_ARRAY_START_HIGH__ESIZE 0x00000010 +#define NVC0_3D_VERTEX_ARRAY_START_HIGH__LEN 0x00000020 + +#define NVC0_3D_VERTEX_ARRAY_START_LOW(i0) (0x00001c08 + 0x10*(i0)) +#define NVC0_3D_VERTEX_ARRAY_START_LOW__ESIZE 0x00000010 +#define NVC0_3D_VERTEX_ARRAY_START_LOW__LEN 0x00000020 + #define NVC0_3D_VERTEX_ARRAY_DIVISOR(i0) (0x00001c0c + 0x10*(i0)) #define NVC0_3D_VERTEX_ARRAY_DIVISOR__ESIZE 0x00000010 #define NVC0_3D_VERTEX_ARRAY_DIVISOR__LEN 0x00000020 @@ -1058,6 +1080,14 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define NVC0_3D_IBLEND_FUNC_DST_ALPHA(i0) (0x00001e18 + 0x20*(i0)) +#define NVC0_3D_VERTEX_ARRAY_LIMIT_HIGH(i0) (0x00001f00 + 0x8*(i0)) +#define NVC0_3D_VERTEX_ARRAY_LIMIT_HIGH__ESIZE 0x00000008 +#define NVC0_3D_VERTEX_ARRAY_LIMIT_HIGH__LEN 0x00000020 + +#define NVC0_3D_VERTEX_ARRAY_LIMIT_LOW(i0) (0x00001f04 + 0x8*(i0)) +#define NVC0_3D_VERTEX_ARRAY_LIMIT_LOW__ESIZE 0x00000008 +#define NVC0_3D_VERTEX_ARRAY_LIMIT_LOW__LEN 0x00000020 + #define NVC0_3D_SP(i0) (0x00002000 + 0x40*(i0)) #define NVC0_3D_SP__ESIZE 0x00000040 #define NVC0_3D_SP__LEN 0x00000006 @@ -1132,14 +1162,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define NVC0_3D_VERTEX_ARRAY_SELECT 0x00003820 -#define NVC0_3D_VERTEX_ARRAY_LIMIT_HIGH 0x00003824 - -#define NVC0_3D_VERTEX_ARRAY_LIMIT_LOW 0x00003828 - -#define NVC0_3D_VERTEX_ARRAY_START_HIGH 0x0000382c - -#define NVC0_3D_VERTEX_ARRAY_START_LOW 0x00003830 - #define NVC0_3D_BLEND_ENABLES 0x00003858 #define NVC0_3D_POLYGON_MODE_FRONT 0x00003868 diff --git a/src/gallium/drivers/nvc0/nvc0_buffer.c b/src/gallium/drivers/nvc0/nvc0_buffer.c index f5ac6557fe9..ea3e642a448 100644 --- a/src/gallium/drivers/nvc0/nvc0_buffer.c +++ b/src/gallium/drivers/nvc0/nvc0_buffer.c @@ -59,6 +59,18 @@ release_allocation(struct nvc0_mm_allocation **mm, struct nvc0_fence *fence) (*mm) = NULL; } +static INLINE boolean +nvc0_buffer_reallocate(struct nvc0_screen *screen, struct nvc0_resource *buf, + unsigned domain) +{ + nouveau_bo_ref(NULL, &buf->bo); + + if (buf->mm) + release_allocation(&buf->mm, buf->fence); + + return nvc0_buffer_allocate(screen, buf, domain); +} + static void nvc0_buffer_destroy(struct pipe_screen *pscreen, struct pipe_resource *presource) @@ -116,6 +128,12 @@ nvc0_buffer_upload(struct nvc0_context *nvc0, struct nvc0_resource *buf, struct nouveau_bo *bounce = NULL; uint32_t offset; + if (size <= 192) { + nvc0_m2mf_push_linear(nvc0, buf->bo, buf->domain, buf->offset + start, + size, buf->data + start); + return TRUE; + } + mm = nvc0_mm_allocate(nvc0->screen->mm_GART, size, &bounce, &offset); if (!bounce) return FALSE; @@ -366,8 +384,9 @@ nvc0_user_buffer_create(struct pipe_screen *pscreen, return &buffer->base; } +/* Like download, but for GART buffers. Merge ? */ static INLINE boolean -nvc0_buffer_fetch_data(struct nvc0_resource *buf, +nvc0_buffer_data_fetch(struct nvc0_resource *buf, struct nouveau_bo *bo, unsigned offset, unsigned size) { if (!buf->data) { @@ -413,7 +432,7 @@ nvc0_buffer_migrate(struct nvc0_context *nvc0, if (new_domain == NOUVEAU_BO_VRAM) { /* keep a system memory copy of our data in case we hit a fallback */ - if (!nvc0_buffer_fetch_data(buf, buf->bo, buf->offset, size)) + if (!nvc0_buffer_data_fetch(buf, buf->bo, buf->offset, size)) return FALSE; debug_printf("migrating %u KiB to VRAM\n", size / 1024); } @@ -444,19 +463,22 @@ nvc0_buffer_migrate(struct nvc0_context *nvc0, } /* Migrate data from glVertexAttribPointer(non-VBO) user buffers to GART. - * MUST NOT FLUSH THE PUSH BUFFER, we could be in the middle of a method. + * We'd like to only allocate @size bytes here, but then we'd have to rebase + * the vertex indices ... */ boolean -nvc0_migrate_vertices(struct nvc0_resource *buf, unsigned base, unsigned size) +nvc0_user_buffer_upload(struct nvc0_resource *buf, unsigned base, unsigned size) { struct nvc0_screen *screen = nvc0_screen(buf->base.screen); int ret; - assert(buf->data && !buf->domain); + assert(buf->status & NVC0_BUFFER_STATUS_USER_MEMORY); - if (!nvc0_buffer_allocate(screen, buf, NOUVEAU_BO_GART)) + buf->base.width0 = base + size; + if (!nvc0_buffer_reallocate(screen, buf, NOUVEAU_BO_GART)) return FALSE; - ret = nouveau_bo_map_range(buf->bo, base + buf->offset, size, + + ret = nouveau_bo_map_range(buf->bo, buf->offset + base, size, NOUVEAU_BO_WR | NOUVEAU_BO_NOSYNC); if (ret) return FALSE; diff --git a/src/gallium/drivers/nvc0/nvc0_context.h b/src/gallium/drivers/nvc0/nvc0_context.h index 0f340beb35a..eeb5beff7a7 100644 --- a/src/gallium/drivers/nvc0/nvc0_context.h +++ b/src/gallium/drivers/nvc0/nvc0_context.h @@ -100,7 +100,8 @@ struct nvc0_context { struct pipe_vertex_buffer vtxbuf[PIPE_MAX_ATTRIBS]; unsigned num_vtxbufs; struct pipe_index_buffer idxbuf; - uint32_t vbo_fifo; + uint32_t vbo_fifo; /* bitmask of vertex elements to be pushed to FIFO */ + uint32_t vbo_user; /* bitmask of vertex buffers pointing to user memory */ unsigned vbo_min_index; /* from pipe_draw_info, for vertex upload */ unsigned vbo_max_index; diff --git a/src/gallium/drivers/nvc0/nvc0_pc.c b/src/gallium/drivers/nvc0/nvc0_pc.c index 72483f120ed..304a1919768 100644 --- a/src/gallium/drivers/nvc0/nvc0_pc.c +++ b/src/gallium/drivers/nvc0/nvc0_pc.c @@ -515,6 +515,13 @@ nvc0_insn_insert_after(struct nv_instruction *at, struct nv_instruction *ni) } void +nvc0_insn_insert_before(struct nv_instruction *at, struct nv_instruction *ni) +{ + nvc0_insn_insert_after(at, ni); + nvc0_insns_permute(at, ni); +} + +void nvc0_insn_delete(struct nv_instruction *nvi) { struct nv_basic_block *b = nvi->bb; diff --git a/src/gallium/drivers/nvc0/nvc0_pc.h b/src/gallium/drivers/nvc0/nvc0_pc.h index 74867f02e72..969cc68c596 100644 --- a/src/gallium/drivers/nvc0/nvc0_pc.h +++ b/src/gallium/drivers/nvc0/nvc0_pc.h @@ -473,6 +473,7 @@ struct nv_pc { }; void nvc0_insn_append(struct nv_basic_block *, struct nv_instruction *); +void nvc0_insn_insert_before(struct nv_instruction *, struct nv_instruction *); void nvc0_insn_insert_after(struct nv_instruction *, struct nv_instruction *); static INLINE struct nv_instruction * diff --git a/src/gallium/drivers/nvc0/nvc0_pc_optimize.c b/src/gallium/drivers/nvc0/nvc0_pc_optimize.c index e4449c285b5..acc72bff14c 100644 --- a/src/gallium/drivers/nvc0/nvc0_pc_optimize.c +++ b/src/gallium/drivers/nvc0/nvc0_pc_optimize.c @@ -249,6 +249,13 @@ check_swap_src_0_1(struct nv_instruction *nvi) nvi->src[0] = src1; nvi->src[1] = src0; } + } else + if (is_immd32_load(src0->value->insn)) { + if (!is_cspace_load(src1->value->insn) && + !is_immd32_load(src1->value->insn)) { + nvi->src[0] = src1; + nvi->src[1] = src0; + } } if (nvi->src[0] != src0 && nvi->opcode == NV_OP_SET) @@ -1101,6 +1108,40 @@ nv_pass_cse(struct nv_pass *ctx, struct nv_basic_block *b) return 0; } +/* Make sure all sources of an NV_OP_BIND are distinct, they need to occupy + * neighbouring registers. CSE might have messed this up. + */ +static int +nv_pass_fix_bind(struct nv_pass *ctx, struct nv_basic_block *b) +{ + struct nv_value *val; + struct nv_instruction *bnd, *nvi, *next; + int s, t; + + for (bnd = b->entry; bnd; bnd = next) { + next = bnd->next; + if (bnd->opcode != NV_OP_BIND) + continue; + for (s = 0; s < 4 && bnd->src[s]; ++s) { + val = bnd->src[s]->value; + for (t = s + 1; t < 4 && bnd->src[t]; ++t) { + if (bnd->src[t]->value != val) + continue; + nvi = nv_alloc_instruction(ctx->pc, NV_OP_MOV); + nvi->def[0] = new_value_like(ctx->pc, val); + nvi->def[0]->insn = nvi; + nv_reference(ctx->pc, nvi, 0, val); + nvc0_insn_insert_before(bnd, nvi); + + nv_reference(ctx->pc, bnd, t, nvi->def[0]); + } + } + } + DESCEND_ARBITRARY(t, nv_pass_fix_bind); + + return 0; +} + static int nv_pc_pass0(struct nv_pc *pc, struct nv_basic_block *root) { @@ -1177,6 +1218,9 @@ nv_pc_pass0(struct nv_pc *pc, struct nv_basic_block *root) if (ret) return ret; + pc->pass_seq++; + ret = nv_pass_fix_bind(&pass, root); + return ret; } diff --git a/src/gallium/drivers/nvc0/nvc0_program.c b/src/gallium/drivers/nvc0/nvc0_program.c index 3e7fc4d350e..57a0874e679 100644 --- a/src/gallium/drivers/nvc0/nvc0_program.c +++ b/src/gallium/drivers/nvc0/nvc0_program.c @@ -598,6 +598,13 @@ nvc0_prog_scan(struct nvc0_translation_info *ti) case PIPE_SHADER_FRAGMENT: ti->input_file = NV_FILE_MEM_V; ti->output_file = NV_FILE_GPR; + + if (ti->scan.writes_z) + prog->flags[0] = 0x11; /* ? */ + else + if (!ti->global_stores) + prog->fp.early_z = 1; + ret = nvc0_fp_gen_header(prog, ti); break; default: diff --git a/src/gallium/drivers/nvc0/nvc0_program.h b/src/gallium/drivers/nvc0/nvc0_program.h index 1271303144e..2e84caecc9e 100644 --- a/src/gallium/drivers/nvc0/nvc0_program.h +++ b/src/gallium/drivers/nvc0/nvc0_program.h @@ -23,12 +23,15 @@ struct nvc0_program { uint32_t hdr[20]; - uint32_t flags[2]; /* FP_ZORDER */ + uint32_t flags[2]; struct { uint8_t edgeflag; uint8_t num_ucps; } vp; + struct { + uint8_t early_z; + } fp; void *relocs; unsigned num_relocs; @@ -66,6 +69,7 @@ struct nvc0_translation_info { boolean indirect_inputs; boolean indirect_outputs; boolean require_stores; + boolean global_stores; uint32_t *immd32; ubyte *immd32_ty; unsigned immd32_nr; diff --git a/src/gallium/drivers/nvc0/nvc0_resource.h b/src/gallium/drivers/nvc0/nvc0_resource.h index d33e2f0ed0a..17e79642a6d 100644 --- a/src/gallium/drivers/nvc0/nvc0_resource.h +++ b/src/gallium/drivers/nvc0/nvc0_resource.h @@ -18,6 +18,12 @@ struct nvc0_context; #define NVC0_BUFFER_SCORE_MAX 25000 #define NVC0_BUFFER_SCORE_VRAM_THRESHOLD 20000 +/* DIRTY: buffer was (or will be after the next flush) written to by GPU and + * resource->data has not been updated to reflect modified VRAM contents + * + * USER_MEMORY: resource->data is a pointer to client memory and may change + * between GL calls + */ #define NVC0_BUFFER_STATUS_DIRTY (1 << 0) #define NVC0_BUFFER_STATUS_USER_MEMORY (1 << 7) @@ -84,7 +90,8 @@ nvc0_resource_map_offset(struct nvc0_context *nvc0, (res->status & NVC0_BUFFER_STATUS_DIRTY)) nvc0_buffer_download(nvc0, res, 0, res->base.width0); - if (res->domain != NOUVEAU_BO_GART) + if ((res->domain != NOUVEAU_BO_GART) || + (res->status & NVC0_BUFFER_STATUS_USER_MEMORY)) return res->data + offset; if (res->mm) @@ -189,6 +196,6 @@ void nvc0_miptree_surface_del(struct pipe_context *, struct pipe_surface *); boolean -nvc0_migrate_vertices(struct nvc0_resource *buf, unsigned base, unsigned size); +nvc0_user_buffer_upload(struct nvc0_resource *, unsigned base, unsigned size); #endif diff --git a/src/gallium/drivers/nvc0/nvc0_screen.c b/src/gallium/drivers/nvc0/nvc0_screen.c index c191790ab14..54eec660b2a 100644 --- a/src/gallium/drivers/nvc0/nvc0_screen.c +++ b/src/gallium/drivers/nvc0/nvc0_screen.c @@ -289,11 +289,11 @@ nvc0_magic_3d_init(struct nouveau_channel *chan) OUT_RING (chan, (2 << 16) | 2); BEGIN_RING(chan, RING_3D_(0x0de8), 1); OUT_RING (chan, 1); - BEGIN_RING(chan, RING_3D_(0x165c), 1); - OUT_RING (chan, 0); +#if 0 /* software method */ BEGIN_RING(chan, RING_3D_(0x1528), 1); /* MP poke */ OUT_RING (chan, 0); +#endif BEGIN_RING(chan, RING_3D_(0x12ac), 1); OUT_RING (chan, 0); @@ -323,8 +323,10 @@ nvc0_magic_3d_init(struct nouveau_channel *chan) OUT_RING (chan, 0); BEGIN_RING(chan, RING_3D_(0x0300), 1); OUT_RING (chan, 3); +#if 0 /* software method */ BEGIN_RING(chan, RING_3D_(0x1280), 1); /* PGRAPH poke */ OUT_RING (chan, 0); +#endif BEGIN_RING(chan, RING_3D_(0x02d0), 1); OUT_RING (chan, 0x1f40); BEGIN_RING(chan, RING_3D_(0x00fdc), 1); @@ -441,9 +443,9 @@ nvc0_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev) BEGIN_RING(chan, RING_3D(RT_CONTROL), 1); OUT_RING (chan, 1); - BEGIN_RING(chan, RING_3D(MULTISAMPLE_ZETA_ENABLE), 1); + BEGIN_RING(chan, RING_3D(CSAA_ENABLE), 1); OUT_RING (chan, 0); - BEGIN_RING(chan, RING_3D(MULTISAMPLE_COLOR_ENABLE), 1); + BEGIN_RING(chan, RING_3D(MULTISAMPLE_ENABLE), 1); OUT_RING (chan, 0); BEGIN_RING(chan, RING_3D(MULTISAMPLE_MODE), 1); OUT_RING (chan, NVC0_3D_MULTISAMPLE_MODE_1X); @@ -503,8 +505,8 @@ nvc0_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev) goto fail; BEGIN_RING(chan, RING_3D_(0x17bc), 3); - OUT_RELOCh(chan, screen->mp_stack_bo, 0, NOUVEAU_BO_GART | NOUVEAU_BO_RDWR); - OUT_RELOCl(chan, screen->mp_stack_bo, 0, NOUVEAU_BO_GART | NOUVEAU_BO_RDWR); + OUT_RELOCh(chan, screen->mp_stack_bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR); + OUT_RELOCl(chan, screen->mp_stack_bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR); OUT_RING (chan, 1); ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 17, 1 << 17, &screen->txc); @@ -521,7 +523,7 @@ nvc0_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev) OUT_RELOCl(chan, screen->txc, 65536, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); OUT_RING (chan, NVC0_TSC_MAX_ENTRIES - 1); - BEGIN_RING(chan, RING_3D(Y_ORIGIN_BOTTOM), 1); + BEGIN_RING(chan, RING_3D(SCREEN_Y_CONTROL), 1); OUT_RING (chan, 0); BEGIN_RING(chan, RING_3D(WINDOW_OFFSET_X), 2); OUT_RING (chan, 0); @@ -587,6 +589,8 @@ nvc0_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev) BEGIN_RING(chan, RING_3D(POINT_COORD_REPLACE), 1); OUT_RING (chan, 0); + BEGIN_RING(chan, RING_3D(POINT_RASTER_RULES), 1); + OUT_RING (chan, NVC0_3D_POINT_RASTER_RULES_OGL); BEGIN_RING(chan, RING_3D(FRAG_COLOR_CLAMP_EN), 1); OUT_RING (chan, 0x11111111); diff --git a/src/gallium/drivers/nvc0/nvc0_shader_state.c b/src/gallium/drivers/nvc0/nvc0_shader_state.c index a6595c56106..981b5488d08 100644 --- a/src/gallium/drivers/nvc0/nvc0_shader_state.c +++ b/src/gallium/drivers/nvc0/nvc0_shader_state.c @@ -100,7 +100,7 @@ nvc0_fragprog_validate(struct nvc0_context *nvc0) return; BEGIN_RING(chan, RING_3D(EARLY_FRAGMENT_TESTS), 1); - OUT_RING (chan, 0); + OUT_RING (chan, fp->fp.early_z); BEGIN_RING(chan, RING_3D(SP_SELECT(5)), 2); OUT_RING (chan, 0x51); OUT_RING (chan, fp->code_base); diff --git a/src/gallium/drivers/nvc0/nvc0_state.c b/src/gallium/drivers/nvc0/nvc0_state.c index 5a9b1c28509..c08f3693f5e 100644 --- a/src/gallium/drivers/nvc0/nvc0_state.c +++ b/src/gallium/drivers/nvc0/nvc0_state.c @@ -207,6 +207,7 @@ nvc0_rasterizer_state_create(struct pipe_context *pipe, SB_DATA (so, fui(cso->point_size)); } SB_IMMED_3D(so, POINT_SPRITE_ENABLE, cso->point_quad_rasterization); + SB_IMMED_3D(so, POINT_SMOOTH_ENABLE, cso->point_smooth); SB_BEGIN_3D(so, POLYGON_MODE_FRONT, 1); SB_DATA (so, nvgl_polygon_mode(cso->fill_front)); diff --git a/src/gallium/drivers/nvc0/nvc0_stateobj.h b/src/gallium/drivers/nvc0/nvc0_stateobj.h index e7cd94800de..ee788c5bb9c 100644 --- a/src/gallium/drivers/nvc0/nvc0_stateobj.h +++ b/src/gallium/drivers/nvc0/nvc0_stateobj.h @@ -48,7 +48,7 @@ nvc0_tic_entry(struct pipe_sampler_view *view) struct nvc0_rasterizer_stateobj { struct pipe_rasterizer_state pipe; int size; - uint32_t state[43]; + uint32_t state[36]; }; struct nvc0_zsa_stateobj { diff --git a/src/gallium/drivers/nvc0/nvc0_vbo.c b/src/gallium/drivers/nvc0/nvc0_vbo.c index fd7a7942cb8..a14e9557382 100644 --- a/src/gallium/drivers/nvc0/nvc0_vbo.c +++ b/src/gallium/drivers/nvc0/nvc0_vbo.c @@ -141,52 +141,107 @@ nvc0_emit_vtxattr(struct nvc0_context *nvc0, struct pipe_vertex_buffer *vb, OUT_RINGf(chan, v[i]); } -void -nvc0_vertex_arrays_validate(struct nvc0_context *nvc0) +static void +nvc0_prevalidate_vbufs(struct nvc0_context *nvc0) { - struct nouveau_channel *chan = nvc0->screen->base.channel; - struct nvc0_vertex_stateobj *vertex = nvc0->vertex; struct pipe_vertex_buffer *vb; - struct nvc0_vertex_element *ve; - unsigned i; - boolean push = FALSE; + struct nvc0_resource *buf; + int i; + uint32_t base, size; - nvc0->vbo_fifo = 0; + nvc0->vbo_fifo = nvc0->vbo_user = 0; for (i = 0; i < nvc0->num_vtxbufs; ++i) { vb = &nvc0->vtxbuf[i]; + if (!vb->stride) + continue; + buf = nvc0_resource(vb->buffer); if (!nvc0_resource_mapped_by_gpu(vb->buffer)) { - if (vb->stride == 0) + if (nvc0->vbo_push_hint) { + nvc0->vbo_fifo = ~0; continue; - push = nvc0->vbo_push_hint; - if (!push) { - unsigned base, size; - base = vb->buffer_offset + nvc0->vbo_min_index * vb->stride; - size = (nvc0->vbo_max_index - nvc0->vbo_min_index + 1) * vb->stride; - nvc0_migrate_vertices(nvc0_resource(vb->buffer), base, size); + } else { + if (buf->status & NVC0_BUFFER_STATUS_USER_MEMORY) { + nvc0->vbo_user |= 1 << i; + assert(vb->stride > vb->buffer_offset); + size = vb->stride * (nvc0->vbo_max_index - + nvc0->vbo_min_index + 1); + base = vb->stride * nvc0->vbo_min_index; + nvc0_user_buffer_upload(buf, base, size); + } else { + nvc0_buffer_migrate(nvc0, buf, NOUVEAU_BO_GART); + } nvc0->vbo_dirty = TRUE; - } else - continue; + } } - nvc0_buffer_adjust_score(nvc0, nvc0_resource(vb->buffer), 1); + nvc0_bufctx_add_resident(nvc0, NVC0_BUFCTX_VERTEX, buf, NOUVEAU_BO_RD); + nvc0_buffer_adjust_score(nvc0, buf, 1); + } +} - nvc0_bufctx_add_resident(nvc0, NVC0_BUFCTX_VERTEX, - nvc0_resource(vb->buffer), NOUVEAU_BO_RD); +static void +nvc0_update_user_vbufs(struct nvc0_context *nvc0) +{ + struct nouveau_channel *chan = nvc0->screen->base.channel; + const uint32_t vertex_count = nvc0->vbo_max_index - nvc0->vbo_min_index + 1; + uint32_t base, offset, size; + int i; + uint32_t written = 0; + + for (i = 0; i < nvc0->vertex->num_elements; ++i) { + struct pipe_vertex_element *ve = &nvc0->vertex->element[i].pipe; + const int b = ve->vertex_buffer_index; + struct pipe_vertex_buffer *vb = &nvc0->vtxbuf[b]; + struct nvc0_resource *buf = nvc0_resource(vb->buffer); + + if (!(nvc0->vbo_user & (1 << b))) + continue; + + if (!vb->stride) { + nvc0_emit_vtxattr(nvc0, vb, ve, i); + continue; + } + size = vb->stride * vertex_count; + base = vb->stride * nvc0->vbo_min_index; + + if (!(written & (1 << b))) { + written |= 1 << b; + nvc0_user_buffer_upload(buf, base, size); + } + offset = vb->buffer_offset + ve->src_offset; + + BEGIN_RING_1I(chan, RING_3D(VERTEX_ARRAY_SELECT), 5); + OUT_RING (chan, i); + OUT_RESRCh(chan, buf, size - 1, NOUVEAU_BO_RD); + OUT_RESRCl(chan, buf, size - 1, NOUVEAU_BO_RD); + OUT_RESRCh(chan, buf, offset, NOUVEAU_BO_RD); + OUT_RESRCl(chan, buf, offset, NOUVEAU_BO_RD); } + nvc0->vbo_dirty = TRUE; +} + +void +nvc0_vertex_arrays_validate(struct nvc0_context *nvc0) +{ + struct nouveau_channel *chan = nvc0->screen->base.channel; + struct nvc0_vertex_stateobj *vertex = nvc0->vertex; + struct pipe_vertex_buffer *vb; + struct nvc0_vertex_element *ve; + unsigned i; + + nvc0_prevalidate_vbufs(nvc0); BEGIN_RING(chan, RING_3D(VERTEX_ATTRIB_FORMAT(0)), vertex->num_elements); for (i = 0; i < vertex->num_elements; ++i) { ve = &vertex->element[i]; vb = &nvc0->vtxbuf[ve->pipe.vertex_buffer_index]; - if (push) - nvc0->vbo_fifo |= 1 << i; - - if (likely(vb->stride) || push) { + if (likely(vb->stride) || nvc0->vbo_fifo) { OUT_RING(chan, ve->state); } else { OUT_RING(chan, ve->state | NVC0_3D_VERTEX_ATTRIB_FORMAT_CONST); + nvc0->vbo_fifo &= ~(1 << i); } } @@ -210,8 +265,8 @@ nvc0_vertex_arrays_validate(struct nvc0_context *nvc0) res = nvc0_resource(vb->buffer); - if (push || unlikely(vb->stride == 0)) { - if (!push) + if (nvc0->vbo_fifo || unlikely(vb->stride == 0)) { + if (!nvc0->vbo_fifo) nvc0_emit_vtxattr(nvc0, vb, &ve->pipe, i); BEGIN_RING(chan, RING_3D(VERTEX_ARRAY_FETCH(i)), 1); OUT_RING (chan, 0); @@ -540,6 +595,9 @@ nvc0_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info) nvc0->vbo_min_index = info->min_index; nvc0->vbo_max_index = info->max_index; + if (nvc0->vbo_user && !(nvc0->dirty & (NVC0_NEW_VERTEX | NVC0_NEW_ARRAYS))) + nvc0_update_user_vbufs(nvc0); + nvc0_state_validate(nvc0); if (nvc0->state.instance_base != info->start_instance) { @@ -554,7 +612,7 @@ nvc0_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info) } if (nvc0->vbo_dirty) { - BEGIN_RING(chan, RING_3D_(0x142c), 1); + BEGIN_RING(chan, RING_3D(VERTEX_ARRAY_FLUSH), 1); OUT_RING (chan, 0); nvc0->vbo_dirty = FALSE; } diff --git a/src/gallium/drivers/r600/eg_asm.c b/src/gallium/drivers/r600/eg_asm.c index 1881e633d54..4f86e3b4c38 100644 --- a/src/gallium/drivers/r600/eg_asm.c +++ b/src/gallium/drivers/r600/eg_asm.c @@ -36,6 +36,8 @@ int eg_bc_cf_build(struct r600_bc *bc, struct r600_bc_cf *cf) switch (cf->inst) { case (EG_V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU << 3): + case (EG_V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_POP_AFTER << 3): + case (EG_V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_POP2_AFTER << 3): case (EG_V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_PUSH_BEFORE << 3): assert(!end_of_program); bc->bytecode[id++] = S_SQ_CF_ALU_WORD0_ADDR(cf->addr >> 1) | diff --git a/src/gallium/drivers/r600/eg_state_inlines.h b/src/gallium/drivers/r600/eg_state_inlines.h index ecea1db4f15..5a39d7cdeec 100644 --- a/src/gallium/drivers/r600/eg_state_inlines.h +++ b/src/gallium/drivers/r600/eg_state_inlines.h @@ -506,139 +506,4 @@ static INLINE boolean r600_is_vertex_format_supported(enum pipe_format format) return r600_translate_colorformat(format) != ~0; } -static INLINE uint32_t r600_translate_vertex_data_type(enum pipe_format format) -{ - uint32_t result = 0; - const struct util_format_description *desc; - unsigned i; - - desc = util_format_description(format); - if (desc->layout != UTIL_FORMAT_LAYOUT_PLAIN) { - goto out_unknown; - } - - /* Find the first non-VOID channel. */ - for (i = 0; i < 4; i++) { - if (desc->channel[i].type != UTIL_FORMAT_TYPE_VOID) { - break; - } - } - - switch (desc->channel[i].type) { - /* Half-floats, floats, doubles */ - case UTIL_FORMAT_TYPE_FLOAT: - switch (desc->channel[i].size) { - case 16: - switch (desc->nr_channels) { - case 1: - result = FMT_16_FLOAT; - break; - case 2: - result = FMT_16_16_FLOAT; - break; - case 3: - result = FMT_16_16_16_FLOAT; - break; - case 4: - result = FMT_16_16_16_16_FLOAT; - break; - } - break; - case 32: - switch (desc->nr_channels) { - case 1: - result = FMT_32_FLOAT; - break; - case 2: - result = FMT_32_32_FLOAT; - break; - case 3: - result = FMT_32_32_32_FLOAT; - break; - case 4: - result = FMT_32_32_32_32_FLOAT; - break; - } - break; - default: - goto out_unknown; - } - break; - /* Unsigned ints */ - case UTIL_FORMAT_TYPE_UNSIGNED: - /* Signed ints */ - case UTIL_FORMAT_TYPE_SIGNED: - switch (desc->channel[i].size) { - case 8: - switch (desc->nr_channels) { - case 1: - result = FMT_8; - break; - case 2: - result = FMT_8_8; - break; - case 3: -// result = V_038008_FMT_8_8_8; /* fails piglit draw-vertices test */ -// break; - case 4: - result = FMT_8_8_8_8; - break; - } - break; - case 16: - switch (desc->nr_channels) { - case 1: - result = FMT_16; - break; - case 2: - result = FMT_16_16; - break; - case 3: -// result = V_038008_FMT_16_16_16; /* fails piglit draw-vertices test */ -// break; - case 4: - result = FMT_16_16_16_16; - break; - } - break; - case 32: - switch (desc->nr_channels) { - case 1: - result = FMT_32; - break; - case 2: - result = FMT_32_32; - break; - case 3: - result = FMT_32_32_32; - break; - case 4: - result = FMT_32_32_32_32; - break; - } - break; - default: - goto out_unknown; - } - break; - default: - goto out_unknown; - } - - result = S_030008_DATA_FORMAT(result); - - if (desc->channel[i].type == UTIL_FORMAT_TYPE_SIGNED) { - result |= S_030008_FORMAT_COMP_ALL(1); - } - if (desc->channel[i].normalized) { - result |= S_030008_NUM_FORMAT_ALL(0); - } else { - result |= S_030008_NUM_FORMAT_ALL(2); - } - return result; -out_unknown: - R600_ERR("unsupported vertex format %s\n", util_format_name(format)); - return ~0; -} - #endif diff --git a/src/gallium/drivers/r600/evergreen_state.c b/src/gallium/drivers/r600/evergreen_state.c index 94eef77945b..306ca03234f 100644 --- a/src/gallium/drivers/r600/evergreen_state.c +++ b/src/gallium/drivers/r600/evergreen_state.c @@ -409,7 +409,7 @@ static struct pipe_sampler_view *evergreen_create_sampler_view(struct pipe_conte (tmp->offset[1] + r600_bo_offset(bo[1])) >> 8, 0xFFFFFFFF, bo[1]); r600_pipe_state_add_reg(rstate, R_030010_RESOURCE0_WORD4, word4 | S_030010_NUM_FORMAT_ALL(V_030010_SQ_NUM_FORMAT_NORM) | - S_030010_SRF_MODE_ALL(V_030010_SFR_MODE_NO_ZERO) | + S_030010_SRF_MODE_ALL(V_030010_SRF_MODE_NO_ZERO) | S_030010_BASE_LEVEL(state->u.tex.first_level), 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, R_030014_RESOURCE0_WORD5, S_030014_LAST_LEVEL(state->u.tex.last_level) | diff --git a/src/gallium/drivers/r600/evergreend.h b/src/gallium/drivers/r600/evergreend.h index e67254b2560..e09e02ca000 100644 --- a/src/gallium/drivers/r600/evergreend.h +++ b/src/gallium/drivers/r600/evergreend.h @@ -988,8 +988,8 @@ #define S_030010_SRF_MODE_ALL(x) (((x) & 0x1) << 10) #define G_030010_SRF_MODE_ALL(x) (((x) >> 10) & 0x1) #define C_030010_SRF_MODE_ALL 0xFFFFFBFF -#define V_030010_SFR_MODE_ZERO_CLAMP_MINUS_ONE 0x00000000 -#define V_030010_SFR_MODE_NO_ZERO 0x00000001 +#define V_030010_SRF_MODE_ZERO_CLAMP_MINUS_ONE 0x00000000 +#define V_030010_SRF_MODE_NO_ZERO 0x00000001 #define S_030010_FORCE_DEGAMMA(x) (((x) & 0x1) << 11) #define G_030010_FORCE_DEGAMMA(x) (((x) >> 11) & 0x1) #define C_030010_FORCE_DEGAMMA 0xFFFFF7FF diff --git a/src/gallium/drivers/r600/r600_asm.c b/src/gallium/drivers/r600/r600_asm.c index 31f386964a1..61de24b31ae 100644 --- a/src/gallium/drivers/r600/r600_asm.c +++ b/src/gallium/drivers/r600/r600_asm.c @@ -38,52 +38,109 @@ #define PREV_ALU(alu) LIST_ENTRY(struct r600_bc_alu, alu->list.prev, list) #define NEXT_ALU(alu) LIST_ENTRY(struct r600_bc_alu, alu->list.next, list) -static inline unsigned int r600_bc_get_num_operands(struct r600_bc_alu *alu) +static inline unsigned int r600_bc_get_num_operands(struct r600_bc *bc, struct r600_bc_alu *alu) { if(alu->is_op3) return 3; - switch (alu->inst) { - case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP: - return 0; - case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_ADD: - case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLE: - case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLGT: - case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLGE: - case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLNE: - case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MUL: - case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MAX: - case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MIN: - case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SETE: - case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SETNE: - case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SETGT: - case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SETGE: - case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETE: - case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGT: - case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGE: - case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETNE: - case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_DOT4: - case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_DOT4_IEEE: - case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_CUBE: - return 2; - - case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOV: - case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOVA_FLOOR: - case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_FRACT: - case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_FLOOR: - case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_TRUNC: - case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_EXP_IEEE: - case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_LOG_CLAMPED: - case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_LOG_IEEE: - case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIP_IEEE: - case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIPSQRT_IEEE: - case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_FLT_TO_INT: - case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SIN: - case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_COS: - return 1; - default: R600_ERR( - "Need instruction operand number for 0x%x.\n", alu->inst); - }; + switch (bc->chiprev) { + case CHIPREV_R600: + case CHIPREV_R700: + switch (alu->inst) { + case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP: + return 0; + case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_ADD: + case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLE: + case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLGT: + case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLGE: + case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLNE: + case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MUL: + case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MAX: + case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MIN: + case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SETE: + case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SETNE: + case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SETGT: + case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SETGE: + case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETE: + case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGT: + case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGE: + case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETNE: + case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_DOT4: + case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_DOT4_IEEE: + case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_CUBE: + return 2; + + case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOV: + case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOVA: + case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOVA_FLOOR: + case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOVA_INT: + case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_FRACT: + case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_FLOOR: + case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_TRUNC: + case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_EXP_IEEE: + case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_LOG_CLAMPED: + case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_LOG_IEEE: + case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIP_CLAMPED: + case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIP_IEEE: + case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIPSQRT_CLAMPED: + case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIPSQRT_IEEE: + case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_FLT_TO_INT: + case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SIN: + case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_COS: + return 1; + default: R600_ERR( + "Need instruction operand number for 0x%x.\n", alu->inst); + } + break; + case CHIPREV_EVERGREEN: + switch (alu->inst) { + case EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP: + return 0; + case EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_ADD: + case EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLE: + case EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLGT: + case EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLGE: + case EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLNE: + case EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MUL: + case EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MAX: + case EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MIN: + case EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SETE: + case EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SETNE: + case EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SETGT: + case EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SETGE: + case EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETE: + case EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGT: + case EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGE: + case EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETNE: + case EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_DOT4: + case EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_DOT4_IEEE: + case EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_CUBE: + case EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INTERP_XY: + case EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INTERP_ZW: + return 2; + + case EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOV: + case EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOVA_INT: + case EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_FRACT: + case EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_FLOOR: + case EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_TRUNC: + case EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_EXP_IEEE: + case EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_LOG_CLAMPED: + case EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_LOG_IEEE: + case EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIP_CLAMPED: + case EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIP_IEEE: + case EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIPSQRT_CLAMPED: + case EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIPSQRT_IEEE: + case EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_FLT_TO_INT: + case EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_FLT_TO_INT_FLOOR: + case EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SIN: + case EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_COS: + return 1; + default: R600_ERR( + "Need instruction operand number for 0x%x.\n", alu->inst); + } + break; + } return 3; } @@ -241,125 +298,226 @@ int r600_bc_add_output(struct r600_bc *bc, const struct r600_bc_output *output) } /* alu predicate instructions */ -static int is_alu_pred_inst(struct r600_bc_alu *alu) -{ - return !alu->is_op3 && ( - alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGT_UINT || - alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGE_UINT || - alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETE || - alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGT || - alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGE || - alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETNE || - alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SET_INV || - alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SET_POP || - alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SET_CLR || - alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SET_RESTORE || - alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETE_PUSH || - alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGT_PUSH || - alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGE_PUSH || - alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETNE_PUSH || - alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETE_INT || - alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGT_INT || - alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGE_INT || - alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETNE_INT || - alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETE_PUSH_INT || - alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGT_PUSH_INT || - alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGE_PUSH_INT || - alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETNE_PUSH_INT || - alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETLT_PUSH_INT || - alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETLE_PUSH_INT); +static int is_alu_pred_inst(struct r600_bc *bc, struct r600_bc_alu *alu) +{ + switch (bc->chiprev) { + case CHIPREV_R600: + case CHIPREV_R700: + return !alu->is_op3 && ( + alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGT_UINT || + alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGE_UINT || + alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETE || + alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGT || + alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGE || + alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETNE || + alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SET_INV || + alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SET_POP || + alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SET_CLR || + alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SET_RESTORE || + alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETE_PUSH || + alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGT_PUSH || + alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGE_PUSH || + alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETNE_PUSH || + alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETE_INT || + alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGT_INT || + alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGE_INT || + alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETNE_INT || + alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETE_PUSH_INT || + alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGT_PUSH_INT || + alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGE_PUSH_INT || + alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETNE_PUSH_INT || + alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETLT_PUSH_INT || + alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETLE_PUSH_INT); + case CHIPREV_EVERGREEN: + default: + return !alu->is_op3 && ( + alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGT_UINT || + alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGE_UINT || + alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETE || + alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGT || + alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGE || + alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETNE || + alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SET_INV || + alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SET_POP || + alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SET_CLR || + alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SET_RESTORE || + alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETE_PUSH || + alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGT_PUSH || + alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGE_PUSH || + alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETNE_PUSH || + alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETE_INT || + alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGT_INT || + alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGE_INT || + alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETNE_INT || + alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETE_PUSH_INT || + alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGT_PUSH_INT || + alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGE_PUSH_INT || + alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETNE_PUSH_INT || + alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETLT_PUSH_INT || + alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETLE_PUSH_INT); + } } /* alu kill instructions */ -static int is_alu_kill_inst(struct r600_bc_alu *alu) +static int is_alu_kill_inst(struct r600_bc *bc, struct r600_bc_alu *alu) { - return !alu->is_op3 && ( - alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLE || - alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLGT || - alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLGE || - alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLNE || - alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLGT_UINT || - alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLGE_UINT || - alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLE_INT || - alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLGT_INT || - alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLGE_INT || - alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLNE_INT); + switch (bc->chiprev) { + case CHIPREV_R600: + case CHIPREV_R700: + return !alu->is_op3 && ( + alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLE || + alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLGT || + alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLGE || + alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLNE || + alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLGT_UINT || + alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLGE_UINT || + alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLE_INT || + alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLGT_INT || + alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLGE_INT || + alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLNE_INT); + case CHIPREV_EVERGREEN: + default: + return !alu->is_op3 && ( + alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLE || + alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLGT || + alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLGE || + alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLNE || + alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLGT_UINT || + alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLGE_UINT || + alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLE_INT || + alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLGT_INT || + alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLGE_INT || + alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLNE_INT); + } } /* alu instructions that can ony exits once per group */ -static int is_alu_once_inst(struct r600_bc_alu *alu) +static int is_alu_once_inst(struct r600_bc *bc, struct r600_bc_alu *alu) { - return is_alu_kill_inst(alu) || - is_alu_pred_inst(alu); + return is_alu_kill_inst(bc, alu) || + is_alu_pred_inst(bc, alu); } -static int is_alu_reduction_inst(struct r600_bc_alu *alu) +static int is_alu_reduction_inst(struct r600_bc *bc, struct r600_bc_alu *alu) { - return !alu->is_op3 && ( - alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_CUBE || - alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_DOT4 || - alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_DOT4_IEEE || - alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MAX4); + switch (bc->chiprev) { + case CHIPREV_R600: + case CHIPREV_R700: + return !alu->is_op3 && ( + alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_CUBE || + alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_DOT4 || + alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_DOT4_IEEE || + alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MAX4); + case CHIPREV_EVERGREEN: + default: + return !alu->is_op3 && ( + alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_CUBE || + alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_DOT4 || + alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_DOT4_IEEE || + alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MAX4); + } } -static int is_alu_mova_inst(struct r600_bc_alu *alu) +static int is_alu_mova_inst(struct r600_bc *bc, struct r600_bc_alu *alu) { - return !alu->is_op3 && ( - alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOVA || - alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOVA_FLOOR || - alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOVA_INT); + switch (bc->chiprev) { + case CHIPREV_R600: + case CHIPREV_R700: + return !alu->is_op3 && ( + alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOVA || + alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOVA_FLOOR || + alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOVA_INT); + case CHIPREV_EVERGREEN: + default: + return !alu->is_op3 && ( + alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOVA_INT); + } } /* alu instructions that can only execute on the vector unit */ -static int is_alu_vec_unit_inst(struct r600_bc_alu *alu) +static int is_alu_vec_unit_inst(struct r600_bc *bc, struct r600_bc_alu *alu) { - return is_alu_reduction_inst(alu) || - is_alu_mova_inst(alu); + return is_alu_reduction_inst(bc, alu) || + is_alu_mova_inst(bc, alu); } /* alu instructions that can only execute on the trans unit */ -static int is_alu_trans_unit_inst(struct r600_bc_alu *alu) -{ - if(!alu->is_op3) - return alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_ASHR_INT || - alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_FLT_TO_INT || - alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_INT_TO_FLT || - alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_LSHL_INT || - alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_LSHR_INT || - alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MULHI_INT || - alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MULHI_UINT || - alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MULLO_INT || - alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MULLO_UINT || - alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIP_INT || - alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIP_UINT || - alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_UINT_TO_FLT || - alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_COS || - alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_EXP_IEEE || - alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_LOG_CLAMPED || - alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_LOG_IEEE || - alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIP_CLAMPED || - alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIP_FF || - alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIP_IEEE || - alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIPSQRT_CLAMPED || - alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIPSQRT_FF || - alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIPSQRT_IEEE || - alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SIN || - alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SQRT_IEEE; - else - return alu->inst == V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_MUL_LIT || - alu->inst == V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_MUL_LIT_D2 || - alu->inst == V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_MUL_LIT_M2 || - alu->inst == V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_MUL_LIT_M4; +static int is_alu_trans_unit_inst(struct r600_bc *bc, struct r600_bc_alu *alu) +{ + switch (bc->chiprev) { + case CHIPREV_R600: + case CHIPREV_R700: + if (!alu->is_op3) + return alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_ASHR_INT || + alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_FLT_TO_INT || + alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_INT_TO_FLT || + alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_LSHL_INT || + alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_LSHR_INT || + alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MULHI_INT || + alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MULHI_UINT || + alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MULLO_INT || + alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MULLO_UINT || + alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIP_INT || + alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIP_UINT || + alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_UINT_TO_FLT || + alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_COS || + alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_EXP_IEEE || + alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_LOG_CLAMPED || + alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_LOG_IEEE || + alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIP_CLAMPED || + alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIP_FF || + alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIP_IEEE || + alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIPSQRT_CLAMPED || + alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIPSQRT_FF || + alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIPSQRT_IEEE || + alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SIN || + alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SQRT_IEEE; + else + return alu->inst == V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_MUL_LIT || + alu->inst == V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_MUL_LIT_D2 || + alu->inst == V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_MUL_LIT_M2 || + alu->inst == V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_MUL_LIT_M4; + case CHIPREV_EVERGREEN: + default: + if (!alu->is_op3) + return alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_ASHR_INT || + alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_FLT_TO_INT || + alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_INT_TO_FLT || + alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_LSHL_INT || + alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_LSHR_INT || + alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MULHI_INT || + alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MULHI_UINT || + alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MULLO_INT || + alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MULLO_UINT || + alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIP_INT || + alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIP_UINT || + alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_UINT_TO_FLT || + alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_COS || + alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_EXP_IEEE || + alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_LOG_CLAMPED || + alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_LOG_IEEE || + alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIP_CLAMPED || + alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIP_FF || + alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIP_IEEE || + alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIPSQRT_CLAMPED || + alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIPSQRT_FF || + alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIPSQRT_IEEE || + alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SIN || + alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SQRT_IEEE; + else + return alu->inst == EG_V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_MUL_LIT; + } } /* alu instructions that can execute on any unit */ -static int is_alu_any_unit_inst(struct r600_bc_alu *alu) +static int is_alu_any_unit_inst(struct r600_bc *bc, struct r600_bc_alu *alu) { - return !is_alu_vec_unit_inst(alu) && - !is_alu_trans_unit_inst(alu); + return !is_alu_vec_unit_inst(bc, alu) && + !is_alu_trans_unit_inst(bc, alu); } -static int assign_alu_units(struct r600_bc_alu *alu_first, struct r600_bc_alu *assignment[5]) +static int assign_alu_units(struct r600_bc *bc, struct r600_bc_alu *alu_first, + struct r600_bc_alu *assignment[5]) { struct r600_bc_alu *alu; unsigned i, chan, trans; @@ -367,11 +525,11 @@ static int assign_alu_units(struct r600_bc_alu *alu_first, struct r600_bc_alu *a for (i = 0; i < 5; i++) assignment[i] = NULL; - for (alu = alu_first; alu; alu = NEXT_ALU(alu)) { + for (alu = alu_first; alu; alu = LIST_ENTRY(struct r600_bc_alu, alu->list.next, list)) { chan = alu->dst.chan; - if (is_alu_trans_unit_inst(alu)) + if (is_alu_trans_unit_inst(bc, alu)) trans = 1; - else if (is_alu_vec_unit_inst(alu)) + else if (is_alu_vec_unit_inst(bc, alu)) trans = 0; else if (assignment[chan]) trans = 1; // assume ALU_INST_PREFER_VECTOR @@ -471,34 +629,29 @@ static int is_gpr(unsigned sel) return (sel >= 0 && sel <= 127); } -static int is_cfile(unsigned sel) -{ - return (sel > 255 && sel < 512); -} - /* CB constants start at 512, and get translated to a kcache index when ALU * clauses are constructed. Note that we handle kcache constants the same way * as (the now gone) cfile constants, is that really required? */ -static int is_cb_const(int sel) +static int is_cfile(unsigned sel) { - if (sel > 511 && sel < 4607) - return 1; - return 0; + return (sel > 255 && sel < 512) || + (sel > 511 && sel < 4607) || // Kcache before translate + (sel > 127 && sel < 192); // Kcache after translate } static int is_const(int sel) { return is_cfile(sel) || - is_cb_const(sel) || (sel >= V_SQ_ALU_SRC_0 && sel <= V_SQ_ALU_SRC_LITERAL); } -static int check_vector(struct r600_bc_alu *alu, struct alu_bank_swizzle *bs, int bank_swizzle) +static int check_vector(struct r600_bc *bc, struct r600_bc_alu *alu, + struct alu_bank_swizzle *bs, int bank_swizzle) { int r, src, num_src, sel, elem, cycle; - num_src = r600_bc_get_num_operands(alu); + num_src = r600_bc_get_num_operands(bc, alu); for (src = 0; src < num_src; src++) { sel = alu->src[src].sel; elem = alu->src[src].chan; @@ -523,11 +676,12 @@ static int check_vector(struct r600_bc_alu *alu, struct alu_bank_swizzle *bs, in return 0; } -static int check_scalar(struct r600_bc_alu *alu, struct alu_bank_swizzle *bs, int bank_swizzle) +static int check_scalar(struct r600_bc *bc, struct r600_bc_alu *alu, + struct alu_bank_swizzle *bs, int bank_swizzle) { int r, src, num_src, const_count, sel, elem, cycle; - num_src = r600_bc_get_num_operands(alu); + num_src = r600_bc_get_num_operands(bc, alu); for (const_count = 0, src = 0; src < num_src; ++src) { sel = alu->src[src].sel; elem = alu->src[src].chan; @@ -564,7 +718,8 @@ static int check_scalar(struct r600_bc_alu *alu, struct alu_bank_swizzle *bs, in return 0; } -static int check_and_set_bank_swizzle(struct r600_bc_alu *slots[5]) +static int check_and_set_bank_swizzle(struct r600_bc *bc, + struct r600_bc_alu *slots[5]) { struct alu_bank_swizzle bs; int bank_swizzle[5]; @@ -588,13 +743,13 @@ static int check_and_set_bank_swizzle(struct r600_bc_alu *slots[5]) init_bank_swizzle(&bs); for (i = 0; i < 4; i++) { if (slots[i]) { - r = check_vector(slots[i], &bs, bank_swizzle[i]); + r = check_vector(bc, slots[i], &bs, bank_swizzle[i]); if (r) break; } } if (!r && slots[4]) { - r = check_scalar(slots[4], &bs, bank_swizzle[4]); + r = check_scalar(bc, slots[4], &bs, bank_swizzle[4]); } if (!r) { for (i = 0; i < 5; i++) { @@ -617,20 +772,21 @@ static int check_and_set_bank_swizzle(struct r600_bc_alu *slots[5]) return -1; } -static int replace_gpr_with_pv_ps(struct r600_bc_alu *slots[5], struct r600_bc_alu *alu_prev) +static int replace_gpr_with_pv_ps(struct r600_bc *bc, + struct r600_bc_alu *slots[5], struct r600_bc_alu *alu_prev) { struct r600_bc_alu *prev[5]; int gpr[5], chan[5]; int i, j, r, src, num_src; - r = assign_alu_units(alu_prev, prev); + r = assign_alu_units(bc, alu_prev, prev); if (r) return r; for (i = 0; i < 5; ++i) { if(prev[i] && prev[i]->dst.write && !prev[i]->dst.rel) { gpr[i] = prev[i]->dst.sel; - if (is_alu_reduction_inst(prev[i])) + if (is_alu_reduction_inst(bc, prev[i])) chan[i] = 0; else chan[i] = prev[i]->dst.chan; @@ -643,7 +799,7 @@ static int replace_gpr_with_pv_ps(struct r600_bc_alu *slots[5], struct r600_bc_a if(!alu) continue; - num_src = r600_bc_get_num_operands(alu); + num_src = r600_bc_get_num_operands(bc, alu); for (src = 0; src < num_src; ++src) { if (!is_gpr(alu->src[src].sel) || alu->src[src].rel) continue; @@ -702,9 +858,10 @@ void r600_bc_special_constants(u32 value, unsigned *sel, unsigned *neg) } /* compute how many literal are needed */ -static int r600_bc_alu_nliterals(struct r600_bc_alu *alu, uint32_t literal[4], unsigned *nliteral) +static int r600_bc_alu_nliterals(struct r600_bc *bc, struct r600_bc_alu *alu, + uint32_t literal[4], unsigned *nliteral) { - unsigned num_src = r600_bc_get_num_operands(alu); + unsigned num_src = r600_bc_get_num_operands(bc, alu); unsigned i, j; for (i = 0; i < num_src; ++i) { @@ -727,9 +884,11 @@ static int r600_bc_alu_nliterals(struct r600_bc_alu *alu, uint32_t literal[4], u return 0; } -static void r600_bc_alu_adjust_literals(struct r600_bc_alu *alu, uint32_t literal[4], unsigned nliteral) +static void r600_bc_alu_adjust_literals(struct r600_bc *bc, + struct r600_bc_alu *alu, + uint32_t literal[4], unsigned nliteral) { - unsigned num_src = r600_bc_get_num_operands(alu); + unsigned num_src = r600_bc_get_num_operands(bc, alu); unsigned i, j; for (i = 0; i < num_src; ++i) { @@ -745,40 +904,47 @@ static void r600_bc_alu_adjust_literals(struct r600_bc_alu *alu, uint32_t litera } } -static int merge_inst_groups(struct r600_bc *bc, struct r600_bc_alu *slots[5], struct r600_bc_alu *alu_prev) +static int merge_inst_groups(struct r600_bc *bc, struct r600_bc_alu *slots[5], + struct r600_bc_alu *alu_prev) { struct r600_bc_alu *prev[5]; struct r600_bc_alu *result[5] = { NULL }; - uint32_t literal[4]; - unsigned nliteral = 0; + uint32_t literal[4], prev_literal[4]; + unsigned nliteral = 0, prev_nliteral = 0; int i, j, r, src, num_src; int num_once_inst = 0; - r = assign_alu_units(alu_prev, prev); + r = assign_alu_units(bc, alu_prev, prev); if (r) return r; for (i = 0; i < 5; ++i) { + struct r600_bc_alu *alu; + /* check number of literals */ - if (prev[i] && r600_bc_alu_nliterals(prev[i], literal, &nliteral)) - return 0; - if (slots[i] && r600_bc_alu_nliterals(slots[i], literal, &nliteral)) + if (prev[i]) { + if (r600_bc_alu_nliterals(bc, prev[i], literal, &nliteral)) + return 0; + if (r600_bc_alu_nliterals(bc, prev[i], prev_literal, &prev_nliteral)) + return 0; + } + if (slots[i] && r600_bc_alu_nliterals(bc, slots[i], literal, &nliteral)) return 0; // let's check used slots if (prev[i] && !slots[i]) { result[i] = prev[i]; - num_once_inst += is_alu_once_inst(prev[i]); + num_once_inst += is_alu_once_inst(bc, prev[i]); continue; } else if (prev[i] && slots[i]) { if (result[4] == NULL && prev[4] == NULL && slots[4] == NULL) { // trans unit is still free try to use it - if (is_alu_any_unit_inst(slots[i])) { + if (is_alu_any_unit_inst(bc, slots[i])) { result[i] = prev[i]; result[4] = slots[i]; - } else if (is_alu_any_unit_inst(prev[i])) { + } else if (is_alu_any_unit_inst(bc, prev[i])) { result[i] = slots[i]; result[4] = prev[i]; } else @@ -791,10 +957,10 @@ static int merge_inst_groups(struct r600_bc *bc, struct r600_bc_alu *slots[5], s result[i] = slots[i]; // let's check source gprs - struct r600_bc_alu *alu = slots[i]; - num_once_inst += is_alu_once_inst(alu); + alu = slots[i]; + num_once_inst += is_alu_once_inst(bc, alu); - num_src = r600_bc_get_num_operands(alu); + num_src = r600_bc_get_num_operands(bc, alu); for (src = 0; src < num_src; ++src) { // constants doesn't matter if (!is_gpr(alu->src[src].sel)) @@ -818,12 +984,15 @@ static int merge_inst_groups(struct r600_bc *bc, struct r600_bc_alu *slots[5], s return 0; /* check if the result can still be swizzlet */ - r = check_and_set_bank_swizzle(result); + r = check_and_set_bank_swizzle(bc, result); if (r) return 0; /* looks like everything worked out right, apply the changes */ + /* undo adding previus literals */ + bc->cf_last->ndw -= align(prev_nliteral, 2); + /* sort instructions */ for (i = 0; i < 5; ++i) { slots[i] = result[i]; @@ -1009,11 +1178,6 @@ int r600_bc_add_alu_type(struct r600_bc *bc, const struct r600_bc_alu *alu, int if (!bc->cf_last->curr_bs_head) { bc->cf_last->curr_bs_head = nalu; } - /* at most 128 slots, one add alu can add 5 slots + 4 constants(2 slots) - * worst case */ - if (nalu->last && (bc->cf_last->ndw >> 1) >= 120) { - bc->force_add_cf = 1; - } /* replace special constants */ for (i = 0; i < 3; i++) { if (nalu->src[i].sel == V_SQ_ALU_SRC_LITERAL) @@ -1036,8 +1200,10 @@ int r600_bc_add_alu_type(struct r600_bc *bc, const struct r600_bc_alu *alu, int /* process cur ALU instructions for bank swizzle */ if (nalu->last) { + uint32_t literal[4]; + unsigned nliteral; struct r600_bc_alu *slots[5]; - r = assign_alu_units(bc->cf_last->curr_bs_head, slots); + r = assign_alu_units(bc, bc->cf_last->curr_bs_head, slots); if (r) return r; @@ -1048,15 +1214,30 @@ int r600_bc_add_alu_type(struct r600_bc *bc, const struct r600_bc_alu *alu, int } if (bc->cf_last->prev_bs_head) { - r = replace_gpr_with_pv_ps(slots, bc->cf_last->prev_bs_head); + r = replace_gpr_with_pv_ps(bc, slots, bc->cf_last->prev_bs_head); if (r) return r; } - r = check_and_set_bank_swizzle(slots); + r = check_and_set_bank_swizzle(bc, slots); if (r) return r; + for (i = 0, nliteral = 0; i < 5; i++) { + if (slots[i]) { + r = r600_bc_alu_nliterals(bc, slots[i], literal, &nliteral); + if (r) + return r; + } + } + bc->cf_last->ndw += align(nliteral, 2); + + /* at most 128 slots, one add alu can add 5 slots + 4 constants(2 slots) + * worst case */ + if ((bc->cf_last->ndw >> 1) >= 120) { + bc->force_add_cf = 1; + } + bc->cf_last->prev2_bs_head = bc->cf_last->prev_bs_head; bc->cf_last->prev_bs_head = bc->cf_last->curr_bs_head; bc->cf_last->curr_bs_head = NULL; @@ -1129,6 +1310,12 @@ int r600_bc_add_tex(struct r600_bc *bc, const struct r600_bc_tex *tex) } bc->cf_last->inst = V_SQ_CF_WORD1_SQ_CF_INST_TEX; } + if (ntex->src_gpr >= bc->ngpr) { + bc->ngpr = ntex->src_gpr + 1; + } + if (ntex->dst_gpr >= bc->ngpr) { + bc->ngpr = ntex->dst_gpr + 1; + } LIST_ADDTAIL(&ntex->list, &bc->cf_last->tex); /* each texture fetch use 4 dwords */ bc->cf_last->ndw += 4; @@ -1457,11 +1644,12 @@ static void notice_gpr_rel_write(struct gpr_usage usage[128], int32_t id, unsign notice_gpr_write(&usage[i], id, chan, 1, -1); } -static void notice_alu_src_gprs(struct r600_bc_alu *alu, struct gpr_usage usage[128], int32_t id) +static void notice_alu_src_gprs(struct r600_bc *bc, struct r600_bc_alu *alu, + struct gpr_usage usage[128], int32_t id) { unsigned src, num_src; - num_src = r600_bc_get_num_operands(alu); + num_src = r600_bc_get_num_operands(bc, alu); for (src = 0; src < num_src; ++src) { // constants doesn't matter if (!is_gpr(alu->src[src].sel)) @@ -1716,14 +1904,14 @@ static void find_export_replacement(struct gpr_usage usage[128], find_src_range(&usage[next->output.gpr], next_id)->replacement = range->replacement + 1; } -static void replace_alu_gprs(struct r600_bc_alu *alu, struct gpr_usage usage[128], +static void replace_alu_gprs(struct r600_bc *bc, struct r600_bc_alu *alu, struct gpr_usage usage[128], int32_t id, int32_t last_barrier, unsigned *barrier) { struct gpr_usage *cur_usage; struct gpr_usage_range *range; unsigned src, num_src; - num_src = r600_bc_get_num_operands(alu); + num_src = r600_bc_get_num_operands(bc, alu); for (src = 0; src < num_src; ++src) { // constants doesn't matter if (!is_gpr(alu->src[src].sel)) @@ -1851,7 +2039,7 @@ static void replace_export_gprs(struct r600_bc_cf *cf, struct gpr_usage usage[12 cf->output.gpr = range->replacement; } -static void optimize_alu_inst(struct r600_bc_cf *cf, struct r600_bc_alu *alu) +static void optimize_alu_inst(struct r600_bc *bc, struct r600_bc_cf *cf, struct r600_bc_alu *alu) { struct r600_bc_alu *alu_next; unsigned chan; @@ -1877,9 +2065,9 @@ static void optimize_alu_inst(struct r600_bc_cf *cf, struct r600_bc_alu *alu) for (alu_next = alu; !alu_next->last; alu_next = NEXT_ALU(alu_next)); if (alu_next->list.next != &cf->alu) { - chan = is_alu_reduction_inst(alu) ? 0 : alu->dst.chan; + chan = is_alu_reduction_inst(bc, alu) ? 0 : alu->dst.chan; for (alu_next = NEXT_ALU(alu_next); alu_next; alu_next = NEXT_ALU(alu_next)) { - num_src = r600_bc_get_num_operands(alu_next); + num_src = r600_bc_get_num_operands(bc, alu_next); for (src = 0; src < num_src; ++src) { if (alu_next->src[src].sel == V_SQ_ALU_SRC_PV && alu_next->src[src].chan == chan) @@ -1963,13 +2151,13 @@ static void r600_bc_optimize(struct r600_bc *bc) LIST_FOR_EACH_ENTRY(alu, &cf->alu, list) { if (!first) first = alu; - notice_alu_src_gprs(alu, usage, id); + notice_alu_src_gprs(bc, alu, usage, id); if (alu->last) { notice_alu_dst_gprs(first, usage, id, predicate || stack > 0); first = NULL; ++id; } - if (is_alu_pred_inst(alu)) + if (is_alu_pred_inst(bc, alu)) predicate++; } if (cf->inst == V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_PUSH_BEFORE << 3) @@ -2058,15 +2246,15 @@ static void r600_bc_optimize(struct r600_bc *bc) first = NULL; cf->barrier = 0; LIST_FOR_EACH_ENTRY_SAFE(alu, next_alu, &cf->alu, list) { - replace_alu_gprs(alu, usage, id, barrier[stack], &cf->barrier); + replace_alu_gprs(bc, alu, usage, id, barrier[stack], &cf->barrier); if (alu->last) ++id; - if (is_alu_pred_inst(alu)) + if (is_alu_pred_inst(bc, alu)) predicate++; if (cf->inst == V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU << 3) - optimize_alu_inst(cf, alu); + optimize_alu_inst(bc, cf, alu); } if (cf->inst == V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_PUSH_BEFORE << 3) stack += predicate; @@ -2159,16 +2347,6 @@ int r600_bc_build(struct r600_bc *bc) LIST_FOR_EACH_ENTRY(cf, &bc->cf, list) { switch (get_cf_class(cf)) { case CF_CLASS_ALU: - nliteral = 0; - LIST_FOR_EACH_ENTRY(alu, &cf->alu, list) { - r = r600_bc_alu_nliterals(alu, literal, &nliteral); - if (r) - return r; - if (alu->last) { - cf->ndw += align(nliteral, 2); - nliteral = 0; - } - } break; case CF_CLASS_TEXTURE: case CF_CLASS_VERTEX: @@ -2214,11 +2392,12 @@ int r600_bc_build(struct r600_bc *bc) switch (get_cf_class(cf)) { case CF_CLASS_ALU: nliteral = 0; + memset(literal, 0, sizeof(literal)); LIST_FOR_EACH_ENTRY(alu, &cf->alu, list) { - r = r600_bc_alu_nliterals(alu, literal, &nliteral); + r = r600_bc_alu_nliterals(bc, alu, literal, &nliteral); if (r) return r; - r600_bc_alu_adjust_literals(alu, literal, nliteral); + r600_bc_alu_adjust_literals(bc, alu, literal, nliteral); switch(bc->chiprev) { case CHIPREV_R600: r = r600_bc_alu_build(bc, alu, addr); @@ -2239,6 +2418,7 @@ int r600_bc_build(struct r600_bc *bc) bc->bytecode[addr++] = literal[i]; } nliteral = 0; + memset(literal, 0, sizeof(literal)); } } break; @@ -2307,10 +2487,10 @@ void r600_bc_clear(struct r600_bc *bc) void r600_bc_dump(struct r600_bc *bc) { - struct r600_bc_cf *cf; - struct r600_bc_alu *alu; - struct r600_bc_vtx *vtx; - struct r600_bc_tex *tex; + struct r600_bc_cf *cf = NULL; + struct r600_bc_alu *alu = NULL; + struct r600_bc_vtx *vtx = NULL; + struct r600_bc_tex *tex = NULL; unsigned i, id; uint32_t literal[4]; @@ -2329,7 +2509,7 @@ void r600_bc_dump(struct r600_bc *bc) chip = '6'; break; } - fprintf(stderr, "bytecode %d dw -- %d gprs -----------------------\n", bc->ndw, bc->ngpr); + fprintf(stderr, "bytecode %d dw -- %d gprs ---------------------\n", bc->ndw, bc->ngpr); fprintf(stderr, " %c\n", chip); LIST_FOR_EACH_ENTRY(cf, &bc->cf, list) { @@ -2393,7 +2573,7 @@ void r600_bc_dump(struct r600_bc *bc) id = cf->addr; nliteral = 0; LIST_FOR_EACH_ENTRY(alu, &cf->alu, list) { - r600_bc_alu_nliterals(alu, literal, &nliteral); + r600_bc_alu_nliterals(bc, alu, literal, &nliteral); fprintf(stderr, "%04d %08X ", id, bc->bytecode[id]); fprintf(stderr, "SRC0(SEL:%d ", alu->src[0].sel); @@ -2431,7 +2611,7 @@ void r600_bc_dump(struct r600_bc *bc) if (alu->last) { for (i = 0; i < nliteral; i++, id++) { float *f = (float*)(bc->bytecode + id); - fprintf(stderr, "%04d %08X %f\n", id, bc->bytecode[id], *f); + fprintf(stderr, "%04d %08X\t%f\n", id, bc->bytecode[id], *f); } id += nliteral & 1; nliteral = 0; diff --git a/src/gallium/drivers/r600/r600_opcodes.h b/src/gallium/drivers/r600/r600_opcodes.h index 2ee0c83e5d3..a85d0bbf1e1 100644 --- a/src/gallium/drivers/r600/r600_opcodes.h +++ b/src/gallium/drivers/r600/r600_opcodes.h @@ -330,10 +330,14 @@ #define EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIPSQRT_CLAMPED_64 0x00000098 #define EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SQRT_64 0x00000099 /* TODO Fill in more ALU */ +#define EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_INT_TO_FLT 0x0000009B +#define EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_UINT_TO_FLT 0x0000009C +/* TODO Fill in more ALU */ #define EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_FLT_TO_INT_FLOOR 0x000000B1 #define EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_DOT4 0x000000BE #define EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_DOT4_IEEE 0x000000BF #define EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_CUBE 0x000000C0 +#define EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MAX4 0x000000C1 #define EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOVA_INT 0x000000CC #define EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INTERP_XY 0x000000D6 diff --git a/src/gallium/drivers/r600/r600_shader.c b/src/gallium/drivers/r600/r600_shader.c index 95367d7c536..106852c1082 100644 --- a/src/gallium/drivers/r600/r600_shader.c +++ b/src/gallium/drivers/r600/r600_shader.c @@ -228,12 +228,20 @@ int r600_pipe_shader(struct pipe_context *ctx, struct r600_pipe_shader *shader) int r600_shader_from_tgsi(const struct tgsi_token *tokens, struct r600_shader *shader, u32 **literals); int r600_pipe_shader_create(struct pipe_context *ctx, struct r600_pipe_shader *shader, const struct tgsi_token *tokens) { + static int dump_shaders = -1; struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; u32 *literals; int r; -//fprintf(stderr, "--------------------------------------------------------------\n"); -//tgsi_dump(tokens, 0); + /* Would like some magic "get_bool_option_once" routine. + */ + if (dump_shaders == -1) + dump_shaders = debug_get_bool_option("R600_DUMP_SHADERS", FALSE); + + if (dump_shaders) { + fprintf(stderr, "--------------------------------------------------------------\n"); + tgsi_dump(tokens, 0); + } shader->shader.family = r600_get_family(rctx->radeon); r = r600_shader_from_tgsi(tokens, &shader->shader, &literals); if (r) { @@ -246,8 +254,10 @@ int r600_pipe_shader_create(struct pipe_context *ctx, struct r600_pipe_shader *s R600_ERR("building bytecode failed !\n"); return r; } -//r600_bc_dump(&shader->shader.bc); -//fprintf(stderr, "______________________________________________________________\n"); + if (dump_shaders) { + r600_bc_dump(&shader->shader.bc); + fprintf(stderr, "______________________________________________________________\n"); + } return r600_pipe_shader(ctx, shader); } @@ -974,7 +984,7 @@ static int tgsi_setup_trig(struct r600_shader_ctx *ctx, alu.src[1].chan = 0; alu.src[1].value = (uint32_t *)&half_inv_pi; alu.src[2].sel = V_SQ_ALU_SRC_0_5; - alu.src[2].chan = 1; + alu.src[2].chan = 0; alu.last = 1; r = r600_bc_add_alu(ctx->bc, &alu); if (r) @@ -1008,7 +1018,7 @@ static int tgsi_setup_trig(struct r600_shader_ctx *ctx, alu.src[1].sel = V_SQ_ALU_SRC_LITERAL; alu.src[1].chan = 0; alu.src[2].sel = V_SQ_ALU_SRC_LITERAL; - alu.src[2].chan = 1; + alu.src[2].chan = 0; if (ctx->bc->chiprev == CHIPREV_R600) { alu.src[1].value = (uint32_t *)&double_pi; @@ -1772,6 +1782,7 @@ static int tgsi_tex(struct r600_shader_ctx *ctx) alu.src[2].sel = V_SQ_ALU_SRC_LITERAL; alu.src[2].chan = 0; + alu.src[2].value = (u32*)&one_point_five; alu.dst.sel = ctx->temp_reg; alu.dst.chan = 0; diff --git a/src/gallium/drivers/r600/r600_state.c b/src/gallium/drivers/r600/r600_state.c index 9572ff9a1a2..de2668cee16 100644 --- a/src/gallium/drivers/r600/r600_state.c +++ b/src/gallium/drivers/r600/r600_state.c @@ -678,7 +678,7 @@ static struct pipe_sampler_view *r600_create_sampler_view(struct pipe_context *c (tmp->offset[1] + r600_bo_offset(bo[1])) >> 8, 0xFFFFFFFF, bo[1]); r600_pipe_state_add_reg(rstate, R_038010_RESOURCE0_WORD4, word4 | S_038010_NUM_FORMAT_ALL(V_038010_SQ_NUM_FORMAT_NORM) | - S_038010_SRF_MODE_ALL(V_038010_SFR_MODE_NO_ZERO) | + S_038010_SRF_MODE_ALL(V_038010_SRF_MODE_NO_ZERO) | S_038010_REQUEST_SIZE(1) | S_038010_BASE_LEVEL(state->u.tex.first_level), 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, R_038014_RESOURCE0_WORD5, diff --git a/src/gallium/drivers/r600/r600_state_inlines.h b/src/gallium/drivers/r600/r600_state_inlines.h index 39ca0a74f3f..a0ec493fc85 100644 --- a/src/gallium/drivers/r600/r600_state_inlines.h +++ b/src/gallium/drivers/r600/r600_state_inlines.h @@ -502,139 +502,4 @@ static INLINE boolean r600_is_vertex_format_supported(enum pipe_format format) return r600_translate_colorformat(format) != ~0; } -static INLINE uint32_t r600_translate_vertex_data_type(enum pipe_format format) -{ - uint32_t result = 0; - const struct util_format_description *desc; - unsigned i; - - desc = util_format_description(format); - if (desc->layout != UTIL_FORMAT_LAYOUT_PLAIN) { - goto out_unknown; - } - - /* Find the first non-VOID channel. */ - for (i = 0; i < 4; i++) { - if (desc->channel[i].type != UTIL_FORMAT_TYPE_VOID) { - break; - } - } - - switch (desc->channel[i].type) { - /* Half-floats, floats, doubles */ - case UTIL_FORMAT_TYPE_FLOAT: - switch (desc->channel[i].size) { - case 16: - switch (desc->nr_channels) { - case 1: - result = FMT_16_FLOAT; - break; - case 2: - result = FMT_16_16_FLOAT; - break; - case 3: - result = FMT_16_16_16_FLOAT; - break; - case 4: - result = FMT_16_16_16_16_FLOAT; - break; - } - break; - case 32: - switch (desc->nr_channels) { - case 1: - result = FMT_32_FLOAT; - break; - case 2: - result = FMT_32_32_FLOAT; - break; - case 3: - result = FMT_32_32_32_FLOAT; - break; - case 4: - result = FMT_32_32_32_32_FLOAT; - break; - } - break; - default: - goto out_unknown; - } - break; - /* Unsigned ints */ - case UTIL_FORMAT_TYPE_UNSIGNED: - /* Signed ints */ - case UTIL_FORMAT_TYPE_SIGNED: - switch (desc->channel[i].size) { - case 8: - switch (desc->nr_channels) { - case 1: - result = FMT_8; - break; - case 2: - result = FMT_8_8; - break; - case 3: - // result = FMT_8_8_8; /* fails piglit draw-vertices test */ - // break; - case 4: - result = FMT_8_8_8_8; - break; - } - break; - case 16: - switch (desc->nr_channels) { - case 1: - result = FMT_16; - break; - case 2: - result = FMT_16_16; - break; - case 3: - // result = FMT_16_16_16; /* fails piglit draw-vertices test */ - // break; - case 4: - result = FMT_16_16_16_16; - break; - } - break; - case 32: - switch (desc->nr_channels) { - case 1: - result = FMT_32; - break; - case 2: - result = FMT_32_32; - break; - case 3: - result = FMT_32_32_32; - break; - case 4: - result = FMT_32_32_32_32; - break; - } - break; - default: - goto out_unknown; - } - break; - default: - goto out_unknown; - } - - result = S_038008_DATA_FORMAT(result); - - if (desc->channel[i].type == UTIL_FORMAT_TYPE_SIGNED) { - result |= S_038008_FORMAT_COMP_ALL(1); - } - if (desc->channel[i].normalized) { - result |= S_038008_NUM_FORMAT_ALL(0); - } else { - result |= S_038008_NUM_FORMAT_ALL(2); - } - return result; -out_unknown: - R600_ERR("unsupported vertex format %s\n", util_format_name(format)); - return ~0; -} - #endif diff --git a/src/gallium/drivers/r600/r600d.h b/src/gallium/drivers/r600/r600d.h index ae19bfb8285..8c391936db0 100644 --- a/src/gallium/drivers/r600/r600d.h +++ b/src/gallium/drivers/r600/r600d.h @@ -960,8 +960,8 @@ #define S_038010_SRF_MODE_ALL(x) (((x) & 0x1) << 10) #define G_038010_SRF_MODE_ALL(x) (((x) >> 10) & 0x1) #define C_038010_SRF_MODE_ALL 0xFFFFFBFF -#define V_038010_SFR_MODE_ZERO_CLAMP_MINUS_ONE 0x00000000 -#define V_038010_SFR_MODE_NO_ZERO 0x00000001 +#define V_038010_SRF_MODE_ZERO_CLAMP_MINUS_ONE 0x00000000 +#define V_038010_SRF_MODE_NO_ZERO 0x00000001 #define S_038010_FORCE_DEGAMMA(x) (((x) & 0x1) << 11) #define G_038010_FORCE_DEGAMMA(x) (((x) >> 11) & 0x1) #define C_038010_FORCE_DEGAMMA 0xFFFFF7FF diff --git a/src/gallium/drivers/softpipe/sp_screen.c b/src/gallium/drivers/softpipe/sp_screen.c index cd3b6240fe9..c433405cb66 100644 --- a/src/gallium/drivers/softpipe/sp_screen.c +++ b/src/gallium/drivers/softpipe/sp_screen.c @@ -124,6 +124,8 @@ softpipe_get_param(struct pipe_screen *screen, enum pipe_cap param) return 0; case PIPE_CAP_SHADER_STENCIL_EXPORT: return 1; + case PIPE_CAP_INSTANCED_DRAWING: + return 1; default: return 0; } |