summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/drivers')
-rw-r--r--src/gallium/drivers/llvmpipe/lp_screen.c2
-rw-r--r--src/gallium/drivers/llvmpipe/lp_state_fs.c3
-rw-r--r--src/gallium/drivers/noop/noop_pipe.c2
-rw-r--r--src/gallium/drivers/nvc0/nvc0_3d.xml.h48
-rw-r--r--src/gallium/drivers/nvc0/nvc0_buffer.c36
-rw-r--r--src/gallium/drivers/nvc0/nvc0_context.h3
-rw-r--r--src/gallium/drivers/nvc0/nvc0_pc.c7
-rw-r--r--src/gallium/drivers/nvc0/nvc0_pc.h1
-rw-r--r--src/gallium/drivers/nvc0/nvc0_pc_optimize.c44
-rw-r--r--src/gallium/drivers/nvc0/nvc0_program.c7
-rw-r--r--src/gallium/drivers/nvc0/nvc0_program.h6
-rw-r--r--src/gallium/drivers/nvc0/nvc0_resource.h11
-rw-r--r--src/gallium/drivers/nvc0/nvc0_screen.c18
-rw-r--r--src/gallium/drivers/nvc0/nvc0_shader_state.c2
-rw-r--r--src/gallium/drivers/nvc0/nvc0_state.c1
-rw-r--r--src/gallium/drivers/nvc0/nvc0_stateobj.h2
-rw-r--r--src/gallium/drivers/nvc0/nvc0_vbo.c112
-rw-r--r--src/gallium/drivers/r600/eg_asm.c2
-rw-r--r--src/gallium/drivers/r600/eg_state_inlines.h135
-rw-r--r--src/gallium/drivers/r600/evergreen_state.c2
-rw-r--r--src/gallium/drivers/r600/evergreend.h4
-rw-r--r--src/gallium/drivers/r600/r600_asm.c610
-rw-r--r--src/gallium/drivers/r600/r600_opcodes.h4
-rw-r--r--src/gallium/drivers/r600/r600_shader.c23
-rw-r--r--src/gallium/drivers/r600/r600_state.c2
-rw-r--r--src/gallium/drivers/r600/r600_state_inlines.h135
-rw-r--r--src/gallium/drivers/r600/r600d.h4
-rw-r--r--src/gallium/drivers/softpipe/sp_screen.c2
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;
}