summaryrefslogtreecommitdiff
path: root/src/gallium/drivers/r600
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/drivers/r600')
-rw-r--r--src/gallium/drivers/r600/Makefile9
-rw-r--r--src/gallium/drivers/r600/SConscript7
-rw-r--r--src/gallium/drivers/r600/r600_asm.c476
-rw-r--r--src/gallium/drivers/r600/r600_asm.h143
-rw-r--r--src/gallium/drivers/r600/r600_blit.c46
-rw-r--r--src/gallium/drivers/r600/r600_buffer.c60
-rw-r--r--src/gallium/drivers/r600/r600_compiler.c447
-rw-r--r--src/gallium/drivers/r600/r600_compiler.h320
-rw-r--r--src/gallium/drivers/r600/r600_compiler_dump.c267
-rw-r--r--src/gallium/drivers/r600/r600_compiler_r600.c972
-rw-r--r--src/gallium/drivers/r600/r600_compiler_r700.c233
-rw-r--r--src/gallium/drivers/r600/r600_compiler_tgsi.c730
-rw-r--r--src/gallium/drivers/r600/r600_context.c179
-rw-r--r--src/gallium/drivers/r600/r600_context.h152
-rw-r--r--src/gallium/drivers/r600/r600_draw.c98
-rw-r--r--src/gallium/drivers/r600/r600_helper.c88
-rw-r--r--src/gallium/drivers/r600/r600_resource.c55
-rw-r--r--src/gallium/drivers/r600/r600_resource.h35
-rw-r--r--src/gallium/drivers/r600/r600_screen.c242
-rw-r--r--src/gallium/drivers/r600/r600_screen.h21
-rw-r--r--src/gallium/drivers/r600/r600_shader.c1375
-rw-r--r--src/gallium/drivers/r600/r600_shader.h246
-rw-r--r--src/gallium/drivers/r600/r600_sq.h20
-rw-r--r--src/gallium/drivers/r600/r600_state.c1506
-rw-r--r--src/gallium/drivers/r600/r600_state_inlines.h311
-rw-r--r--src/gallium/drivers/r600/r600_texture.c432
-rw-r--r--src/gallium/drivers/r600/r600_texture.h53
-rw-r--r--src/gallium/drivers/r600/r600d.h567
-rw-r--r--src/gallium/drivers/r600/r700_asm.c69
-rw-r--r--src/gallium/drivers/r600/radeon.h61
30 files changed, 4935 insertions, 4285 deletions
diff --git a/src/gallium/drivers/r600/Makefile b/src/gallium/drivers/r600/Makefile
index aae31a6a6e..fc94ae71f4 100644
--- a/src/gallium/drivers/r600/Makefile
+++ b/src/gallium/drivers/r600/Makefile
@@ -9,6 +9,7 @@ LIBRARY_INCLUDES = \
C_SOURCES = \
r600_buffer.c \
r600_context.c \
+ r600_shader.c \
r600_draw.c \
r600_blit.c \
r600_helper.c \
@@ -17,11 +18,7 @@ C_SOURCES = \
r600_screen.c \
r600_state.c \
r600_texture.c \
- r600_shader.c \
- r600_compiler.c \
- r600_compiler_tgsi.c \
- r600_compiler_dump.c \
- r600_compiler_r600.c \
- r600_compiler_r700.c
+ r600_asm.c \
+ r700_asm.c
include ../../Makefile.template
diff --git a/src/gallium/drivers/r600/SConscript b/src/gallium/drivers/r600/SConscript
index 26e2f1941c..99c8644e02 100644
--- a/src/gallium/drivers/r600/SConscript
+++ b/src/gallium/drivers/r600/SConscript
@@ -27,11 +27,8 @@ r600 = env.ConvenienceLibrary(
'r600_state.c',
'r600_texture.c',
'r600_shader.c',
- 'r600_compiler.c',
- 'r600_compiler_tgsi.c',
- 'r600_compiler_dump.c',
- 'r600_compiler_r600.c',
- 'r600_compiler_r700.c'
+ 'r600_asm.c',
+ 'r700_asm.c',
])
Export('r600')
diff --git a/src/gallium/drivers/r600/r600_asm.c b/src/gallium/drivers/r600/r600_asm.c
new file mode 100644
index 0000000000..9ea9d4354d
--- /dev/null
+++ b/src/gallium/drivers/r600/r600_asm.c
@@ -0,0 +1,476 @@
+/*
+ * Copyright 2010 Jerome Glisse <glisse@freedesktop.org>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * on the rights to use, copy, modify, merge, publish, distribute, sub
+ * license, and/or sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#include "r600_asm.h"
+#include "r600_context.h"
+#include "util/u_memory.h"
+#include "r600_sq.h"
+#include <stdio.h>
+#include <errno.h>
+
+int r700_bc_alu_build(struct r600_bc *bc, struct r600_bc_alu *alu, unsigned id);
+
+static struct r600_bc_cf *r600_bc_cf(void)
+{
+ struct r600_bc_cf *cf = CALLOC_STRUCT(r600_bc_cf);
+
+ if (cf == NULL)
+ return NULL;
+ LIST_INITHEAD(&cf->list);
+ LIST_INITHEAD(&cf->alu);
+ LIST_INITHEAD(&cf->vtx);
+ LIST_INITHEAD(&cf->tex);
+ return cf;
+}
+
+static struct r600_bc_alu *r600_bc_alu(void)
+{
+ struct r600_bc_alu *alu = CALLOC_STRUCT(r600_bc_alu);
+
+ if (alu == NULL)
+ return NULL;
+ LIST_INITHEAD(&alu->list);
+ return alu;
+}
+
+static struct r600_bc_vtx *r600_bc_vtx(void)
+{
+ struct r600_bc_vtx *vtx = CALLOC_STRUCT(r600_bc_vtx);
+
+ if (vtx == NULL)
+ return NULL;
+ LIST_INITHEAD(&vtx->list);
+ return vtx;
+}
+
+static struct r600_bc_tex *r600_bc_tex(void)
+{
+ struct r600_bc_tex *tex = CALLOC_STRUCT(r600_bc_tex);
+
+ if (tex == NULL)
+ return NULL;
+ LIST_INITHEAD(&tex->list);
+ return tex;
+}
+
+int r600_bc_init(struct r600_bc *bc, enum radeon_family family)
+{
+ LIST_INITHEAD(&bc->cf);
+ bc->family = family;
+ return 0;
+}
+
+static int r600_bc_add_cf(struct r600_bc *bc)
+{
+ struct r600_bc_cf *cf = r600_bc_cf();
+
+ if (cf == NULL)
+ return -ENOMEM;
+ LIST_ADDTAIL(&cf->list, &bc->cf);
+ if (bc->cf_last)
+ cf->id = bc->cf_last->id + 2;
+ bc->cf_last = cf;
+ bc->ncf++;
+ bc->ndw += 2;
+ bc->force_add_cf = 0;
+ return 0;
+}
+
+int r600_bc_add_output(struct r600_bc *bc, const struct r600_bc_output *output)
+{
+ int r;
+
+ r = r600_bc_add_cf(bc);
+ if (r)
+ return r;
+ bc->cf_last->inst = output->inst;
+ memcpy(&bc->cf_last->output, output, sizeof(struct r600_bc_output));
+ return 0;
+}
+
+int r600_bc_add_alu(struct r600_bc *bc, const struct r600_bc_alu *alu)
+{
+ struct r600_bc_alu *nalu = r600_bc_alu();
+ struct r600_bc_alu *lalu;
+ int i, r;
+
+ if (nalu == NULL)
+ return -ENOMEM;
+ memcpy(nalu, alu, sizeof(struct r600_bc_alu));
+ nalu->nliteral = 0;
+
+ /* cf can contains only alu or only vtx or only tex */
+ if (bc->cf_last == NULL || bc->cf_last->inst != (V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU << 3) ||
+ bc->force_add_cf) {
+ /* at most 128 slots, one add alu can add 4 slots + 4 constant worst case */
+ r = r600_bc_add_cf(bc);
+ if (r) {
+ free(nalu);
+ return r;
+ }
+ bc->cf_last->inst = V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU << 3;
+ }
+ if (alu->last && (bc->cf_last->ndw >> 1) >= 124) {
+ bc->force_add_cf = 1;
+ }
+ /* number of gpr == the last gpr used in any alu */
+ for (i = 0; i < 3; i++) {
+ if (alu->src[i].sel >= bc->ngpr && alu->src[i].sel < 128) {
+ bc->ngpr = alu->src[i].sel + 1;
+ }
+ /* compute how many literal are needed
+ * either 2 or 4 literals
+ */
+ if (alu->src[i].sel == 253) {
+ if (((alu->src[i].chan + 2) & 0x6) > nalu->nliteral) {
+ nalu->nliteral = (alu->src[i].chan + 2) & 0x6;
+ }
+ }
+ }
+ if (!LIST_IS_EMPTY(&bc->cf_last->alu)) {
+ lalu = LIST_ENTRY(struct r600_bc_alu, bc->cf_last->alu.prev, list);
+ if (!lalu->last && lalu->nliteral > nalu->nliteral) {
+ nalu->nliteral = lalu->nliteral;
+ }
+ }
+ if (alu->dst.sel >= bc->ngpr) {
+ bc->ngpr = alu->dst.sel + 1;
+ }
+ LIST_ADDTAIL(&nalu->list, &bc->cf_last->alu);
+ /* each alu use 2 dwords */
+ bc->cf_last->ndw += 2;
+ bc->ndw += 2;
+ return 0;
+}
+
+int r600_bc_add_literal(struct r600_bc *bc, const u32 *value)
+{
+ struct r600_bc_alu *alu;
+
+ if (bc->cf_last == NULL) {
+ return 0;
+ }
+ if (bc->cf_last->inst == V_SQ_CF_WORD1_SQ_CF_INST_TEX) {
+ return 0;
+ }
+ if (bc->cf_last->inst != (V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU << 3) ||
+ LIST_IS_EMPTY(&bc->cf_last->alu)) {
+ R600_ERR("last CF is not ALU (%p)\n", bc->cf_last);
+ return -EINVAL;
+ }
+ alu = LIST_ENTRY(struct r600_bc_alu, bc->cf_last->alu.prev, list);
+ if (!alu->last || !alu->nliteral || alu->literal_added) {
+ return 0;
+ }
+ memcpy(alu->value, value, 4 * 4);
+ bc->cf_last->ndw += alu->nliteral;
+ bc->ndw += alu->nliteral;
+ alu->literal_added = 1;
+ return 0;
+}
+
+int r600_bc_add_vtx(struct r600_bc *bc, const struct r600_bc_vtx *vtx)
+{
+ struct r600_bc_vtx *nvtx = r600_bc_vtx();
+ int r;
+
+ if (nvtx == NULL)
+ return -ENOMEM;
+ memcpy(nvtx, vtx, sizeof(struct r600_bc_vtx));
+
+ /* cf can contains only alu or only vtx or only tex */
+ if (bc->cf_last == NULL ||
+ (bc->cf_last->inst != V_SQ_CF_WORD1_SQ_CF_INST_VTX &&
+ bc->cf_last->inst != V_SQ_CF_WORD1_SQ_CF_INST_VTX_TC)) {
+ r = r600_bc_add_cf(bc);
+ if (r) {
+ free(nvtx);
+ return r;
+ }
+ bc->cf_last->inst = V_SQ_CF_WORD1_SQ_CF_INST_VTX;
+ }
+ LIST_ADDTAIL(&nvtx->list, &bc->cf_last->vtx);
+ /* each fetch use 4 dwords */
+ bc->cf_last->ndw += 4;
+ bc->ndw += 4;
+ return 0;
+}
+
+int r600_bc_add_tex(struct r600_bc *bc, const struct r600_bc_tex *tex)
+{
+ struct r600_bc_tex *ntex = r600_bc_tex();
+ int r;
+
+ if (ntex == NULL)
+ return -ENOMEM;
+ memcpy(ntex, tex, sizeof(struct r600_bc_tex));
+
+ /* cf can contains only alu or only vtx or only tex */
+ if (bc->cf_last == NULL ||
+ bc->cf_last->inst != V_SQ_CF_WORD1_SQ_CF_INST_TEX) {
+ r = r600_bc_add_cf(bc);
+ if (r) {
+ free(ntex);
+ return r;
+ }
+ bc->cf_last->inst = V_SQ_CF_WORD1_SQ_CF_INST_TEX;
+ }
+ LIST_ADDTAIL(&ntex->list, &bc->cf_last->tex);
+ /* each texture fetch use 4 dwords */
+ bc->cf_last->ndw += 4;
+ bc->ndw += 4;
+ return 0;
+}
+
+static int r600_bc_vtx_build(struct r600_bc *bc, struct r600_bc_vtx *vtx, unsigned id)
+{
+ bc->bytecode[id++] = S_SQ_VTX_WORD0_BUFFER_ID(vtx->buffer_id) |
+ S_SQ_VTX_WORD0_SRC_GPR(vtx->src_gpr) |
+ S_SQ_VTX_WORD0_SRC_SEL_X(vtx->src_sel_x) |
+ S_SQ_VTX_WORD0_MEGA_FETCH_COUNT(vtx->mega_fetch_count);
+ bc->bytecode[id++] = S_SQ_VTX_WORD1_DST_SEL_X(vtx->dst_sel_x) |
+ S_SQ_VTX_WORD1_DST_SEL_Y(vtx->dst_sel_y) |
+ S_SQ_VTX_WORD1_DST_SEL_Z(vtx->dst_sel_z) |
+ S_SQ_VTX_WORD1_DST_SEL_W(vtx->dst_sel_w) |
+ S_SQ_VTX_WORD1_USE_CONST_FIELDS(1) |
+ S_SQ_VTX_WORD1_GPR_DST_GPR(vtx->dst_gpr);
+ bc->bytecode[id++] = S_SQ_VTX_WORD2_MEGA_FETCH(1);
+ bc->bytecode[id++] = 0;
+ return 0;
+}
+
+static int r600_bc_tex_build(struct r600_bc *bc, struct r600_bc_tex *tex, unsigned id)
+{
+ bc->bytecode[id++] = S_SQ_TEX_WORD0_TEX_INST(tex->inst) |
+ S_SQ_TEX_WORD0_RESOURCE_ID(tex->resource_id) |
+ S_SQ_TEX_WORD0_SRC_GPR(tex->src_gpr) |
+ S_SQ_TEX_WORD0_SRC_REL(tex->src_rel);
+ bc->bytecode[id++] = S_SQ_TEX_WORD1_DST_GPR(tex->dst_gpr) |
+ S_SQ_TEX_WORD1_DST_REL(tex->dst_rel) |
+ S_SQ_TEX_WORD1_DST_SEL_X(tex->dst_sel_x) |
+ S_SQ_TEX_WORD1_DST_SEL_Y(tex->dst_sel_y) |
+ S_SQ_TEX_WORD1_DST_SEL_Z(tex->dst_sel_z) |
+ S_SQ_TEX_WORD1_DST_SEL_W(tex->dst_sel_w) |
+ S_SQ_TEX_WORD1_LOD_BIAS(tex->lod_bias) |
+ S_SQ_TEX_WORD1_COORD_TYPE_X(tex->coord_type_x) |
+ S_SQ_TEX_WORD1_COORD_TYPE_Y(tex->coord_type_y) |
+ S_SQ_TEX_WORD1_COORD_TYPE_Z(tex->coord_type_z) |
+ S_SQ_TEX_WORD1_COORD_TYPE_W(tex->coord_type_w);
+ bc->bytecode[id++] = S_SQ_TEX_WORD2_OFFSET_X(tex->offset_x) |
+ S_SQ_TEX_WORD2_OFFSET_Y(tex->offset_y) |
+ S_SQ_TEX_WORD2_OFFSET_Z(tex->offset_z) |
+ S_SQ_TEX_WORD2_SAMPLER_ID(tex->sampler_id) |
+ S_SQ_TEX_WORD2_SRC_SEL_X(tex->src_sel_x) |
+ S_SQ_TEX_WORD2_SRC_SEL_Y(tex->src_sel_y) |
+ S_SQ_TEX_WORD2_SRC_SEL_Z(tex->src_sel_z) |
+ S_SQ_TEX_WORD2_SRC_SEL_W(tex->src_sel_w);
+ bc->bytecode[id++] = 0;
+ return 0;
+}
+
+static int r600_bc_alu_build(struct r600_bc *bc, struct r600_bc_alu *alu, unsigned id)
+{
+ unsigned i;
+
+ /* don't replace gpr by pv or ps for destination register */
+ if (alu->is_op3) {
+ bc->bytecode[id++] = S_SQ_ALU_WORD0_SRC0_SEL(alu->src[0].sel) |
+ S_SQ_ALU_WORD0_SRC0_CHAN(alu->src[0].chan) |
+ S_SQ_ALU_WORD0_SRC1_SEL(alu->src[1].sel) |
+ S_SQ_ALU_WORD0_SRC1_CHAN(alu->src[1].chan) |
+ S_SQ_ALU_WORD0_LAST(alu->last);
+ bc->bytecode[id++] = S_SQ_ALU_WORD1_DST_GPR(alu->dst.sel) |
+ S_SQ_ALU_WORD1_DST_CHAN(alu->dst.chan) |
+ S_SQ_ALU_WORD1_CLAMP(alu->dst.clamp) |
+ S_SQ_ALU_WORD1_OP3_SRC2_SEL(alu->src[2].sel) |
+ S_SQ_ALU_WORD1_OP3_SRC2_CHAN(alu->src[2].chan) |
+ S_SQ_ALU_WORD1_OP3_SRC2_NEG(alu->src[2].neg) |
+ S_SQ_ALU_WORD1_OP3_ALU_INST(alu->inst) |
+ S_SQ_ALU_WORD1_BANK_SWIZZLE(0);
+ } else {
+ bc->bytecode[id++] = S_SQ_ALU_WORD0_SRC0_SEL(alu->src[0].sel) |
+ S_SQ_ALU_WORD0_SRC0_CHAN(alu->src[0].chan) |
+ S_SQ_ALU_WORD0_SRC0_NEG(alu->src[0].neg) |
+ S_SQ_ALU_WORD0_SRC1_SEL(alu->src[1].sel) |
+ S_SQ_ALU_WORD0_SRC1_CHAN(alu->src[1].chan) |
+ S_SQ_ALU_WORD0_SRC1_NEG(alu->src[1].neg) |
+ S_SQ_ALU_WORD0_LAST(alu->last);
+ bc->bytecode[id++] = S_SQ_ALU_WORD1_DST_GPR(alu->dst.sel) |
+ S_SQ_ALU_WORD1_DST_CHAN(alu->dst.chan) |
+ S_SQ_ALU_WORD1_CLAMP(alu->dst.clamp) |
+ S_SQ_ALU_WORD1_OP2_SRC0_ABS(alu->src[0].abs) |
+ S_SQ_ALU_WORD1_OP2_SRC1_ABS(alu->src[1].abs) |
+ S_SQ_ALU_WORD1_OP2_WRITE_MASK(alu->dst.write) |
+ S_SQ_ALU_WORD1_OP2_ALU_INST(alu->inst) |
+ S_SQ_ALU_WORD1_BANK_SWIZZLE(0);
+ }
+ if (alu->last) {
+ for (i = 0; i < alu->nliteral; i++) {
+ bc->bytecode[id++] = alu->value[i];
+ }
+ }
+ return 0;
+}
+
+static int r600_bc_cf_build(struct r600_bc *bc, struct r600_bc_cf *cf)
+{
+ unsigned id = cf->id;
+
+ switch (cf->inst) {
+ case (V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU << 3):
+ bc->bytecode[id++] = S_SQ_CF_ALU_WORD0_ADDR(cf->addr >> 1);
+ bc->bytecode[id++] = S_SQ_CF_ALU_WORD1_CF_INST(cf->inst >> 3) |
+ S_SQ_CF_ALU_WORD1_BARRIER(1) |
+ S_SQ_CF_ALU_WORD1_COUNT((cf->ndw / 2) - 1);
+ break;
+ case V_SQ_CF_WORD1_SQ_CF_INST_TEX:
+ case V_SQ_CF_WORD1_SQ_CF_INST_VTX:
+ case V_SQ_CF_WORD1_SQ_CF_INST_VTX_TC:
+ bc->bytecode[id++] = S_SQ_CF_WORD0_ADDR(cf->addr >> 1);
+ bc->bytecode[id++] = S_SQ_CF_WORD1_CF_INST(cf->inst) |
+ S_SQ_CF_WORD1_BARRIER(1) |
+ S_SQ_CF_WORD1_COUNT((cf->ndw / 4) - 1);
+ break;
+ case V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT:
+ case V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT_DONE:
+ bc->bytecode[id++] = S_SQ_CF_ALLOC_EXPORT_WORD0_RW_GPR(cf->output.gpr) |
+ S_SQ_CF_ALLOC_EXPORT_WORD0_ELEM_SIZE(cf->output.elem_size) |
+ S_SQ_CF_ALLOC_EXPORT_WORD0_ARRAY_BASE(cf->output.array_base) |
+ S_SQ_CF_ALLOC_EXPORT_WORD0_TYPE(cf->output.type);
+ bc->bytecode[id++] = S_SQ_CF_ALLOC_EXPORT_WORD1_SWIZ_SEL_X(cf->output.swizzle_x) |
+ S_SQ_CF_ALLOC_EXPORT_WORD1_SWIZ_SEL_Y(cf->output.swizzle_y) |
+ S_SQ_CF_ALLOC_EXPORT_WORD1_SWIZ_SEL_Z(cf->output.swizzle_z) |
+ S_SQ_CF_ALLOC_EXPORT_WORD1_SWIZ_SEL_W(cf->output.swizzle_w) |
+ S_SQ_CF_ALLOC_EXPORT_WORD1_BARRIER(cf->output.barrier) |
+ S_SQ_CF_ALLOC_EXPORT_WORD1_CF_INST(cf->output.inst) |
+ S_SQ_CF_ALLOC_EXPORT_WORD1_END_OF_PROGRAM(cf->output.end_of_program);
+ break;
+ default:
+ R600_ERR("unsupported CF instruction (0x%X)\n", cf->inst);
+ return -EINVAL;
+ }
+ return 0;
+}
+
+int r600_bc_build(struct r600_bc *bc)
+{
+ struct r600_bc_cf *cf;
+ struct r600_bc_alu *alu;
+ struct r600_bc_vtx *vtx;
+ struct r600_bc_tex *tex;
+ unsigned addr;
+ int r;
+
+
+ /* first path compute addr of each CF block */
+ /* addr start after all the CF instructions */
+ addr = bc->cf_last->id + 2;
+ LIST_FOR_EACH_ENTRY(cf, &bc->cf, list) {
+ switch (cf->inst) {
+ case (V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU << 3):
+ break;
+ case V_SQ_CF_WORD1_SQ_CF_INST_TEX:
+ case V_SQ_CF_WORD1_SQ_CF_INST_VTX:
+ case V_SQ_CF_WORD1_SQ_CF_INST_VTX_TC:
+ /* fetch node need to be 16 bytes aligned*/
+ addr += 3;
+ addr &= 0xFFFFFFFCUL;
+ break;
+ case V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT:
+ case V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT_DONE:
+ break;
+ default:
+ R600_ERR("unsupported CF instruction (0x%X)\n", cf->inst);
+ return -EINVAL;
+ }
+ cf->addr = addr;
+ addr += cf->ndw;
+ bc->ndw = cf->addr + cf->ndw;
+ }
+ free(bc->bytecode);
+ bc->bytecode = calloc(1, bc->ndw * 4);
+ if (bc->bytecode == NULL)
+ return -ENOMEM;
+ LIST_FOR_EACH_ENTRY(cf, &bc->cf, list) {
+ addr = cf->addr;
+ r = r600_bc_cf_build(bc, cf);
+ if (r)
+ return r;
+ switch (cf->inst) {
+ case (V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU << 3):
+ LIST_FOR_EACH_ENTRY(alu, &cf->alu, list) {
+ switch (bc->family) {
+ case CHIP_R600:
+ case CHIP_RV610:
+ case CHIP_RV630:
+ case CHIP_RV670:
+ case CHIP_RV620:
+ case CHIP_RV635:
+ case CHIP_RS780:
+ case CHIP_RS880:
+ r = r600_bc_alu_build(bc, alu, addr);
+ break;
+ case CHIP_RV770:
+ case CHIP_RV730:
+ case CHIP_RV710:
+ case CHIP_RV740:
+ r = r700_bc_alu_build(bc, alu, addr);
+ break;
+ default:
+ R600_ERR("unknown family %d\n", bc->family);
+ return -EINVAL;
+ }
+ if (r)
+ return r;
+ addr += 2;
+ if (alu->last) {
+ addr += alu->nliteral;
+ }
+ }
+ break;
+ case V_SQ_CF_WORD1_SQ_CF_INST_VTX:
+ case V_SQ_CF_WORD1_SQ_CF_INST_VTX_TC:
+ LIST_FOR_EACH_ENTRY(vtx, &cf->vtx, list) {
+ r = r600_bc_vtx_build(bc, vtx, addr);
+ if (r)
+ return r;
+ addr += 4;
+ }
+ break;
+ case V_SQ_CF_WORD1_SQ_CF_INST_TEX:
+ LIST_FOR_EACH_ENTRY(tex, &cf->tex, list) {
+ r = r600_bc_tex_build(bc, tex, addr);
+ if (r)
+ return r;
+ addr += 4;
+ }
+ break;
+ case V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT:
+ case V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT_DONE:
+ break;
+ default:
+ R600_ERR("unsupported CF instruction (0x%X)\n", cf->inst);
+ return -EINVAL;
+ }
+ }
+ return 0;
+}
diff --git a/src/gallium/drivers/r600/r600_asm.h b/src/gallium/drivers/r600/r600_asm.h
new file mode 100644
index 0000000000..10d98afaf0
--- /dev/null
+++ b/src/gallium/drivers/r600/r600_asm.h
@@ -0,0 +1,143 @@
+/*
+ * Copyright 2010 Jerome Glisse <glisse@freedesktop.org>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * on the rights to use, copy, modify, merge, publish, distribute, sub
+ * license, and/or sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#ifndef R600_ASM_H
+#define R600_ASM_H
+
+#include "radeon.h"
+#include "util/u_double_list.h"
+
+struct r600_bc_alu_src {
+ unsigned sel;
+ unsigned chan;
+ unsigned neg;
+ unsigned abs;
+};
+
+struct r600_bc_alu_dst {
+ unsigned sel;
+ unsigned chan;
+ unsigned clamp;
+ unsigned write;
+};
+
+struct r600_bc_alu {
+ struct list_head list;
+ struct r600_bc_alu_src src[3];
+ struct r600_bc_alu_dst dst;
+ unsigned inst;
+ unsigned last;
+ unsigned is_op3;
+ unsigned nliteral;
+ unsigned literal_added;
+ u32 value[4];
+};
+
+struct r600_bc_tex {
+ struct list_head list;
+ unsigned inst;
+ unsigned resource_id;
+ unsigned src_gpr;
+ unsigned src_rel;
+ unsigned dst_gpr;
+ unsigned dst_rel;
+ unsigned dst_sel_x;
+ unsigned dst_sel_y;
+ unsigned dst_sel_z;
+ unsigned dst_sel_w;
+ unsigned lod_bias;
+ unsigned coord_type_x;
+ unsigned coord_type_y;
+ unsigned coord_type_z;
+ unsigned coord_type_w;
+ unsigned offset_x;
+ unsigned offset_y;
+ unsigned offset_z;
+ unsigned sampler_id;
+ unsigned src_sel_x;
+ unsigned src_sel_y;
+ unsigned src_sel_z;
+ unsigned src_sel_w;
+};
+
+struct r600_bc_vtx {
+ struct list_head list;
+ unsigned inst;
+ unsigned fetch_type;
+ unsigned buffer_id;
+ unsigned src_gpr;
+ unsigned src_sel_x;
+ unsigned mega_fetch_count;
+ unsigned dst_gpr;
+ unsigned dst_sel_x;
+ unsigned dst_sel_y;
+ unsigned dst_sel_z;
+ unsigned dst_sel_w;
+};
+
+struct r600_bc_output {
+ unsigned array_base;
+ unsigned type;
+ unsigned end_of_program;
+ unsigned inst;
+ unsigned elem_size;
+ unsigned gpr;
+ unsigned swizzle_x;
+ unsigned swizzle_y;
+ unsigned swizzle_z;
+ unsigned swizzle_w;
+ unsigned barrier;
+};
+
+struct r600_bc_cf {
+ struct list_head list;
+ unsigned inst;
+ unsigned addr;
+ unsigned ndw;
+ unsigned id;
+ struct list_head alu;
+ struct list_head tex;
+ struct list_head vtx;
+ struct r600_bc_output output;
+};
+
+struct r600_bc {
+ enum radeon_family family;
+ struct list_head cf;
+ struct r600_bc_cf *cf_last;
+ unsigned ndw;
+ unsigned ncf;
+ unsigned ngpr;
+ unsigned nresource;
+ unsigned force_add_cf;
+ u32 *bytecode;
+};
+
+int r600_bc_init(struct r600_bc *bc, enum radeon_family family);
+int r600_bc_add_alu(struct r600_bc *bc, const struct r600_bc_alu *alu);
+int r600_bc_add_literal(struct r600_bc *bc, const u32 *value);
+int r600_bc_add_vtx(struct r600_bc *bc, const struct r600_bc_vtx *vtx);
+int r600_bc_add_tex(struct r600_bc *bc, const struct r600_bc_tex *tex);
+int r600_bc_add_output(struct r600_bc *bc, const struct r600_bc_output *output);
+int r600_bc_build(struct r600_bc *bc);
+
+#endif
diff --git a/src/gallium/drivers/r600/r600_blit.c b/src/gallium/drivers/r600/r600_blit.c
index 1dcb19babc..f4eedfe4cb 100644
--- a/src/gallium/drivers/r600/r600_blit.c
+++ b/src/gallium/drivers/r600/r600_blit.c
@@ -34,31 +34,37 @@
static void r600_blitter_save_states(struct r600_context *rctx)
{
- util_blitter_save_blend(rctx->blitter,
- rctx->draw->state[R600_BLEND]);
- util_blitter_save_depth_stencil_alpha(rctx->blitter,
- rctx->draw->state[R600_DSA]);
- util_blitter_save_stencil_ref(rctx->blitter, &rctx->stencil_ref);
- util_blitter_save_rasterizer(rctx->blitter,
- rctx->draw->state[R600_RASTERIZER]);
- util_blitter_save_fragment_shader(rctx->blitter,
- rctx->ps_shader);
- util_blitter_save_vertex_shader(rctx->blitter,
- rctx->vs_shader);
- util_blitter_save_vertex_elements(rctx->blitter,
- rctx->vertex_elements);
- util_blitter_save_viewport(rctx->blitter,
- &rctx->viewport);
+ util_blitter_save_blend(rctx->blitter, rctx->blend);
+ util_blitter_save_depth_stencil_alpha(rctx->blitter, rctx->dsa);
+ if (rctx->stencil_ref) {
+ util_blitter_save_stencil_ref(rctx->blitter,
+ &rctx->stencil_ref->state.stencil_ref);
+ }
+ util_blitter_save_rasterizer(rctx->blitter, rctx->rasterizer);
+ util_blitter_save_fragment_shader(rctx->blitter, rctx->ps_shader);
+ util_blitter_save_vertex_shader(rctx->blitter, rctx->vs_shader);
+ util_blitter_save_vertex_elements(rctx->blitter, rctx->vertex_elements);
+ if (rctx->viewport) {
+ util_blitter_save_viewport(rctx->blitter, &rctx->viewport->state.viewport);
+ }
/* XXX util_blitter_save_clip(rctx->blitter, &rctx->clip); */
util_blitter_save_vertex_buffers(rctx->blitter, rctx->nvertex_buffer,
- rctx->vertex_buffer);
+ rctx->vertex_buffer);
+
+ /* remove ptr so they don't get deleted */
+ rctx->blend = NULL;
+ rctx->vs_shader = NULL;
+ rctx->ps_shader = NULL;
+ rctx->rasterizer = NULL;
+ rctx->dsa = NULL;
+ rctx->vertex_elements = NULL;
}
static void r600_clear(struct pipe_context *ctx, unsigned buffers,
const float *rgba, double depth, unsigned stencil)
{
struct r600_context *rctx = r600_context(ctx);
- struct pipe_framebuffer_state *fb = &rctx->fb_state;
+ struct pipe_framebuffer_state *fb = &rctx->framebuffer->state.framebuffer;
r600_blitter_save_states(rctx);
util_blitter_clear(rctx->blitter, fb->width, fb->height,
@@ -73,9 +79,10 @@ static void r600_clear_render_target(struct pipe_context *pipe,
unsigned width, unsigned height)
{
struct r600_context *rctx = r600_context(pipe);
+ struct pipe_framebuffer_state *fb = &rctx->framebuffer->state.framebuffer;
r600_blitter_save_states(rctx);
- util_blitter_save_framebuffer(rctx->blitter, &rctx->fb_state);
+ util_blitter_save_framebuffer(rctx->blitter, fb);
util_blitter_clear_render_target(rctx->blitter, dst, rgba,
dstx, dsty, width, height);
@@ -90,9 +97,10 @@ static void r600_clear_depth_stencil(struct pipe_context *pipe,
unsigned width, unsigned height)
{
struct r600_context *rctx = r600_context(pipe);
+ struct pipe_framebuffer_state *fb = &rctx->framebuffer->state.framebuffer;
r600_blitter_save_states(rctx);
- util_blitter_save_framebuffer(rctx->blitter, &rctx->fb_state);
+ util_blitter_save_framebuffer(rctx->blitter, fb);
util_blitter_clear_depth_stencil(rctx->blitter, dst, clear_flags, depth, stencil,
dstx, dsty, width, height);
diff --git a/src/gallium/drivers/r600/r600_buffer.c b/src/gallium/drivers/r600/r600_buffer.c
index bc6e336ba7..7829a479c2 100644
--- a/src/gallium/drivers/r600/r600_buffer.c
+++ b/src/gallium/drivers/r600/r600_buffer.c
@@ -32,10 +32,11 @@
#include "state_tracker/drm_driver.h"
#include "r600_screen.h"
#include "r600_context.h"
+#include "r600_resource.h"
extern struct u_resource_vtbl r600_buffer_vtbl;
-static u32 r600_domain_from_usage(unsigned usage)
+u32 r600_domain_from_usage(unsigned usage)
{
u32 domain = RADEON_GEM_DOMAIN_GTT;
@@ -63,47 +64,47 @@ struct pipe_resource *r600_buffer_create(struct pipe_screen *screen,
const struct pipe_resource *templ)
{
struct r600_screen *rscreen = r600_screen(screen);
- struct r600_buffer *rbuffer;
+ struct r600_resource *rbuffer;
struct radeon_bo *bo;
struct pb_desc desc;
/* XXX We probably want a different alignment for buffers and textures. */
unsigned alignment = 4096;
- rbuffer = CALLOC_STRUCT(r600_buffer);
+ rbuffer = CALLOC_STRUCT(r600_resource);
if (rbuffer == NULL)
return NULL;
- rbuffer->b.b = *templ;
- pipe_reference_init(&rbuffer->b.b.reference, 1);
- rbuffer->b.b.screen = screen;
- rbuffer->b.vtbl = &r600_buffer_vtbl;
+ rbuffer->base.b = *templ;
+ pipe_reference_init(&rbuffer->base.b.reference, 1);
+ rbuffer->base.b.screen = screen;
+ rbuffer->base.vtbl = &r600_buffer_vtbl;
- if (rbuffer->b.b.bind & PIPE_BIND_CONSTANT_BUFFER) {
+ if (rbuffer->base.b.bind & PIPE_BIND_CONSTANT_BUFFER) {
desc.alignment = alignment;
- desc.usage = rbuffer->b.b.bind;
- rbuffer->pb = pb_malloc_buffer_create(rbuffer->b.b.width0,
+ desc.usage = rbuffer->base.b.bind;
+ rbuffer->pb = pb_malloc_buffer_create(rbuffer->base.b.width0,
&desc);
if (rbuffer->pb == NULL) {
free(rbuffer);
return NULL;
}
- return &rbuffer->b.b;
+ return &rbuffer->base.b;
}
- rbuffer->domain = r600_domain_from_usage(rbuffer->b.b.bind);
- bo = radeon_bo(rscreen->rw, 0, rbuffer->b.b.width0, alignment, NULL);
+ rbuffer->domain = r600_domain_from_usage(rbuffer->base.b.bind);
+ bo = radeon_bo(rscreen->rw, 0, rbuffer->base.b.width0, alignment, NULL);
if (bo == NULL) {
FREE(rbuffer);
return NULL;
}
rbuffer->bo = bo;
- return &rbuffer->b.b;
+ return &rbuffer->base.b;
}
struct pipe_resource *r600_user_buffer_create(struct pipe_screen *screen,
void *ptr, unsigned bytes,
unsigned bind)
{
- struct r600_buffer *rbuffer;
+ struct r600_resource *rbuffer;
struct r600_screen *rscreen = r600_screen(screen);
struct pipe_resource templ;
@@ -116,20 +117,20 @@ struct pipe_resource *r600_user_buffer_create(struct pipe_screen *screen,
templ.height0 = 1;
templ.depth0 = 1;
- rbuffer = (struct r600_buffer*)r600_buffer_create(screen, &templ);
+ rbuffer = (struct r600_resource*)r600_buffer_create(screen, &templ);
if (rbuffer == NULL) {
return NULL;
}
radeon_bo_map(rscreen->rw, rbuffer->bo);
memcpy(rbuffer->bo->data, ptr, bytes);
radeon_bo_unmap(rscreen->rw, rbuffer->bo);
- return &rbuffer->b.b;
+ return &rbuffer->base.b;
}
static void r600_buffer_destroy(struct pipe_screen *screen,
struct pipe_resource *buf)
{
- struct r600_buffer *rbuffer = (struct r600_buffer*)buf;
+ struct r600_resource *rbuffer = (struct r600_resource*)buf;
struct r600_screen *rscreen = r600_screen(screen);
if (rbuffer->pb) {
@@ -140,13 +141,14 @@ static void r600_buffer_destroy(struct pipe_screen *screen,
if (rbuffer->bo) {
radeon_bo_decref(rscreen->rw, rbuffer->bo);
}
+ memset(rbuffer, 0, sizeof(struct r600_resource));
FREE(rbuffer);
}
static void *r600_buffer_transfer_map(struct pipe_context *pipe,
struct pipe_transfer *transfer)
{
- struct r600_buffer *rbuffer = (struct r600_buffer*)transfer->resource;
+ struct r600_resource *rbuffer = (struct r600_resource*)transfer->resource;
struct r600_screen *rscreen = r600_screen(pipe->screen);
int write = 0;
@@ -166,9 +168,9 @@ static void *r600_buffer_transfer_map(struct pipe_context *pipe,
}
static void r600_buffer_transfer_unmap(struct pipe_context *pipe,
- struct pipe_transfer *transfer)
+ struct pipe_transfer *transfer)
{
- struct r600_buffer *rbuffer = (struct r600_buffer*)transfer->resource;
+ struct r600_resource *rbuffer = (struct r600_resource*)transfer->resource;
struct r600_screen *rscreen = r600_screen(pipe->screen);
if (rbuffer->pb) {
@@ -188,7 +190,7 @@ unsigned r600_buffer_is_referenced_by_cs(struct pipe_context *context,
struct pipe_resource *buf,
unsigned face, unsigned level)
{
- /* XXX */
+ /* FIXME */
return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE;
}
@@ -196,7 +198,7 @@ struct pipe_resource *r600_buffer_from_handle(struct pipe_screen *screen,
struct winsys_handle *whandle)
{
struct radeon *rw = (struct radeon*)screen->winsys;
- struct r600_buffer *rbuffer;
+ struct r600_resource *rbuffer;
struct radeon_bo *bo = NULL;
bo = radeon_bo(rw, whandle->handle, 0, 0, NULL);
@@ -204,18 +206,18 @@ struct pipe_resource *r600_buffer_from_handle(struct pipe_screen *screen,
return NULL;
}
- rbuffer = CALLOC_STRUCT(r600_buffer);
+ rbuffer = CALLOC_STRUCT(r600_resource);
if (rbuffer == NULL) {
radeon_bo_decref(rw, bo);
return NULL;
}
- pipe_reference_init(&rbuffer->b.b.reference, 1);
- rbuffer->b.b.target = PIPE_BUFFER;
- rbuffer->b.b.screen = screen;
- rbuffer->b.vtbl = &r600_buffer_vtbl;
+ pipe_reference_init(&rbuffer->base.b.reference, 1);
+ rbuffer->base.b.target = PIPE_BUFFER;
+ rbuffer->base.b.screen = screen;
+ rbuffer->base.vtbl = &r600_buffer_vtbl;
rbuffer->bo = bo;
- return &rbuffer->b.b;
+ return &rbuffer->base.b;
}
struct u_resource_vtbl r600_buffer_vtbl =
diff --git a/src/gallium/drivers/r600/r600_compiler.c b/src/gallium/drivers/r600/r600_compiler.c
deleted file mode 100644
index 1804b86d24..0000000000
--- a/src/gallium/drivers/r600/r600_compiler.c
+++ /dev/null
@@ -1,447 +0,0 @@
-/*
- * Copyright 2010 Jerome Glisse <glisse@freedesktop.org>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * on the rights to use, copy, modify, merge, publish, distribute, sub
- * license, and/or sell copies of the Software, and to permit persons to whom
- * the Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
- * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
- * USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-#include <stdlib.h>
-#include <string.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <errno.h>
-#include "r600_compiler.h"
-
-struct c_vector *c_vector_new(void)
-{
- struct c_vector *v = calloc(1, sizeof(struct c_vector));
-
- if (v == NULL) {
- return NULL;
- }
- LIST_INITHEAD(&v->head);
- return v;
-}
-
-static unsigned c_opcode_is_alu(unsigned opcode)
-{
- switch (opcode) {
- case C_OPCODE_MOV:
- case C_OPCODE_MUL:
- case C_OPCODE_MAD:
- case C_OPCODE_ARL:
- case C_OPCODE_LIT:
- case C_OPCODE_RCP:
- case C_OPCODE_RSQ:
- case C_OPCODE_EXP:
- case C_OPCODE_LOG:
- case C_OPCODE_ADD:
- case C_OPCODE_DP3:
- case C_OPCODE_DP4:
- case C_OPCODE_DST:
- case C_OPCODE_MIN:
- case C_OPCODE_MAX:
- case C_OPCODE_SLT:
- case C_OPCODE_SGE:
- case C_OPCODE_SUB:
- case C_OPCODE_LRP:
- case C_OPCODE_CND:
- case C_OPCODE_DP2A:
- case C_OPCODE_FRC:
- case C_OPCODE_CLAMP:
- case C_OPCODE_FLR:
- case C_OPCODE_ROUND:
- case C_OPCODE_EX2:
- case C_OPCODE_LG2:
- case C_OPCODE_POW:
- case C_OPCODE_XPD:
- case C_OPCODE_ABS:
- case C_OPCODE_RCC:
- case C_OPCODE_DPH:
- case C_OPCODE_COS:
- case C_OPCODE_DDX:
- case C_OPCODE_DDY:
- case C_OPCODE_PK2H:
- case C_OPCODE_PK2US:
- case C_OPCODE_PK4B:
- case C_OPCODE_PK4UB:
- case C_OPCODE_RFL:
- case C_OPCODE_SEQ:
- case C_OPCODE_SFL:
- case C_OPCODE_SGT:
- case C_OPCODE_SIN:
- case C_OPCODE_SLE:
- case C_OPCODE_SNE:
- case C_OPCODE_STR:
- case C_OPCODE_UP2H:
- case C_OPCODE_UP2US:
- case C_OPCODE_UP4B:
- case C_OPCODE_UP4UB:
- case C_OPCODE_X2D:
- case C_OPCODE_ARA:
- case C_OPCODE_ARR:
- case C_OPCODE_BRA:
- case C_OPCODE_SSG:
- case C_OPCODE_CMP:
- case C_OPCODE_SCS:
- case C_OPCODE_NRM:
- case C_OPCODE_DIV:
- case C_OPCODE_DP2:
- case C_OPCODE_CEIL:
- case C_OPCODE_I2F:
- case C_OPCODE_NOT:
- case C_OPCODE_TRUNC:
- case C_OPCODE_SHL:
- case C_OPCODE_AND:
- case C_OPCODE_OR:
- case C_OPCODE_MOD:
- case C_OPCODE_XOR:
- case C_OPCODE_SAD:
- case C_OPCODE_NRM4:
- case C_OPCODE_F2I:
- case C_OPCODE_IDIV:
- case C_OPCODE_IMAX:
- case C_OPCODE_IMIN:
- case C_OPCODE_INEG:
- case C_OPCODE_ISGE:
- case C_OPCODE_ISHR:
- case C_OPCODE_ISLT:
- case C_OPCODE_F2U:
- case C_OPCODE_U2F:
- case C_OPCODE_UADD:
- case C_OPCODE_UDIV:
- case C_OPCODE_UMAD:
- case C_OPCODE_UMAX:
- case C_OPCODE_UMIN:
- case C_OPCODE_UMOD:
- case C_OPCODE_UMUL:
- case C_OPCODE_USEQ:
- case C_OPCODE_USGE:
- case C_OPCODE_USHR:
- case C_OPCODE_USLT:
- case C_OPCODE_USNE:
- return 1;
- case C_OPCODE_END:
- case C_OPCODE_VFETCH:
- case C_OPCODE_KILP:
- case C_OPCODE_CAL:
- case C_OPCODE_RET:
- case C_OPCODE_TXB:
- case C_OPCODE_TXL:
- case C_OPCODE_BRK:
- case C_OPCODE_IF:
- case C_OPCODE_BGNFOR:
- case C_OPCODE_REP:
- case C_OPCODE_ELSE:
- case C_OPCODE_ENDIF:
- case C_OPCODE_ENDFOR:
- case C_OPCODE_ENDREP:
- case C_OPCODE_PUSHA:
- case C_OPCODE_POPA:
- case C_OPCODE_TXF:
- case C_OPCODE_TXQ:
- case C_OPCODE_CONT:
- case C_OPCODE_EMIT:
- case C_OPCODE_ENDPRIM:
- case C_OPCODE_BGNLOOP:
- case C_OPCODE_BGNSUB:
- case C_OPCODE_ENDLOOP:
- case C_OPCODE_ENDSUB:
- case C_OPCODE_NOP:
- case C_OPCODE_CALLNZ:
- case C_OPCODE_IFC:
- case C_OPCODE_BREAKC:
- case C_OPCODE_KIL:
- case C_OPCODE_TEX:
- case C_OPCODE_TXD:
- case C_OPCODE_TXP:
- case C_OPCODE_SWITCH:
- case C_OPCODE_CASE:
- case C_OPCODE_DEFAULT:
- case C_OPCODE_ENDSWITCH:
- default:
- return 0;
- }
-}
-
-
-/* NEW */
-void c_node_init(struct c_node *node)
-{
- memset(node, 0, sizeof(struct c_node));
- LIST_INITHEAD(&node->predecessors);
- LIST_INITHEAD(&node->successors);
- LIST_INITHEAD(&node->childs);
- LIST_INITHEAD(&node->insts);
- node->parent = NULL;
-}
-
-static struct c_node_link *c_node_link_new(struct c_node *node)
-{
- struct c_node_link *link;
-
- link = calloc(1, sizeof(struct c_node_link));
- if (link == NULL)
- return NULL;
- LIST_INITHEAD(&link->head);
- link->node = node;
- return link;
-}
-
-int c_node_cfg_link(struct c_node *predecessor, struct c_node *successor)
-{
- struct c_node_link *pedge, *sedge;
-
- pedge = c_node_link_new(successor);
- sedge = c_node_link_new(predecessor);
- if (sedge == NULL || pedge == NULL) {
- free(sedge);
- free(pedge);
- return -ENOMEM;
- }
- LIST_ADDTAIL(&pedge->head, &predecessor->successors);
- LIST_ADDTAIL(&sedge->head, &successor->predecessors);
-
- return 0;
-}
-
-int c_node_add_new_instruction_head(struct c_node *node, struct c_instruction *instruction)
-{
- struct c_instruction *inst = malloc(sizeof(struct c_instruction));
-
- if (inst == NULL)
- return -ENOMEM;
- memcpy(inst, instruction, sizeof(struct c_instruction));
- LIST_ADD(&inst->head, &node->insts);
- return 0;
-}
-
-int c_node_add_new_instruction(struct c_node *node, struct c_instruction *instruction)
-{
- struct c_instruction *inst = malloc(sizeof(struct c_instruction));
-
- if (inst == NULL)
- return -ENOMEM;
- memcpy(inst, instruction, sizeof(struct c_instruction));
- LIST_ADDTAIL(&inst->head, &node->insts);
- return 0;
-}
-
-struct c_node *c_shader_cfg_new_node_after(struct c_shader *shader, struct c_node *predecessor)
-{
- struct c_node *node = calloc(1, sizeof(struct c_node));
-
- if (node == NULL)
- return NULL;
- c_node_init(node);
- if (c_node_cfg_link(predecessor, node)) {
- free(node);
- return NULL;
- }
- LIST_ADDTAIL(&node->head, &shader->nodes);
- return node;
-}
-
-int c_shader_init(struct c_shader *shader, unsigned type)
-{
- unsigned i;
- int r;
-
- shader->type = type;
- for (i = 0; i < C_FILE_COUNT; i++) {
- shader->files[i].nvectors = 0;
- LIST_INITHEAD(&shader->files[i].vectors);
- }
- LIST_INITHEAD(&shader->nodes);
- c_node_init(&shader->entry);
- c_node_init(&shader->end);
- shader->entry.opcode = C_OPCODE_ENTRY;
- shader->end.opcode = C_OPCODE_END;
- r = c_node_cfg_link(&shader->entry, &shader->end);
- if (r)
- return r;
- return 0;
-}
-
-struct c_vector *c_shader_vector_new(struct c_shader *shader, unsigned file, unsigned name, int sid)
-{
- struct c_vector *v = calloc(1, sizeof(struct c_vector));
- int i;
-
- if (v == NULL) {
- return NULL;
- }
- for (i = 0; i < 4; i++) {
- v->channel[i] = calloc(1, sizeof(struct c_channel));
- if (v->channel[i] == NULL)
- goto out_err;
- v->channel[i]->vindex = i;
- v->channel[i]->vector = v;
- }
- v->file = file;
- v->name = name;
- v->sid = sid;
- shader->files[v->file].nvectors++;
- v->id = shader->nvectors++;
- LIST_ADDTAIL(&v->head, &shader->files[v->file].vectors);
- return v;
-out_err:
- for (i = 0; i < 4; i++) {
- free(v->channel[i]);
- }
- free(v);
- return NULL;
-}
-
-static void c_node_remove_link(struct list_head *head, struct c_node *node)
-{
- struct c_node_link *link, *tmp;
-
- LIST_FOR_EACH_ENTRY_SAFE(link, tmp, head, head) {
- if (link->node == node) {
- LIST_DEL(&link->head);
- free(link);
- }
- }
-}
-
-static void c_node_destroy(struct c_node *node)
-{
- struct c_instruction *i, *ni;
- struct c_node_link *link, *tmp;
-
- LIST_FOR_EACH_ENTRY_SAFE(i, ni, &node->insts, head) {
- LIST_DEL(&i->head);
- free(i);
- }
- if (node->parent)
- c_node_remove_link(&node->parent->childs, node);
- node->parent = NULL;
- LIST_FOR_EACH_ENTRY_SAFE(link, tmp, &node->predecessors, head) {
- c_node_remove_link(&link->node->successors, node);
- LIST_DEL(&link->head);
- free(link);
- }
- LIST_FOR_EACH_ENTRY_SAFE(link, tmp, &node->successors, head) {
- c_node_remove_link(&link->node->predecessors, node);
- LIST_DEL(&link->head);
- free(link);
- }
- LIST_FOR_EACH_ENTRY_SAFE(link, tmp, &node->childs, head) {
- link->node->parent = NULL;
- LIST_DEL(&link->head);
- free(link);
- }
-}
-
-void c_shader_destroy(struct c_shader *shader)
-{
- struct c_node *n, *nn;
- struct c_vector *v, *nv;
- unsigned i;
-
- for (i = 0; i < C_FILE_COUNT; i++) {
- shader->files[i].nvectors = 0;
- LIST_FOR_EACH_ENTRY_SAFE(v, nv, &shader->files[i].vectors, head) {
- LIST_DEL(&v->head);
- free(v->channel[0]);
- free(v->channel[1]);
- free(v->channel[2]);
- free(v->channel[3]);
- free(v);
- }
- }
- LIST_FOR_EACH_ENTRY_SAFE(n, nn, &shader->nodes, head) {
- LIST_DEL(&n->head);
- c_node_destroy(n);
- }
- memset(shader, 0, sizeof(struct c_shader));
-}
-
-static void c_shader_dfs_without_rec(struct c_node *entry, struct c_node *node)
-{
- struct c_node_link *link;
-
- if (entry == node || entry->visited)
- return;
- entry->visited = 1;
- LIST_FOR_EACH_ENTRY(link, &entry->successors, head) {
- c_shader_dfs_without_rec(link->node, node);
- }
-}
-
-static void c_shader_dfs_without(struct c_shader *shader, struct c_node *node)
-{
- struct c_node *n;
-
- shader->entry.visited = 0;
- shader->end.visited = 0;
- LIST_FOR_EACH_ENTRY(n, &shader->nodes, head) {
- n->visited = 0;
- }
- c_shader_dfs_without_rec(&shader->entry, node);
-}
-
-static int c_shader_build_dominator_tree_rec(struct c_shader *shader, struct c_node *node)
-{
- struct c_node_link *link, *nlink;
- unsigned found = 0;
- int r;
-
- if (node->done)
- return 0;
- node->done = 1;
- LIST_FOR_EACH_ENTRY(link, &node->predecessors, head) {
- /* if we remove this predecessor can we reach the current node ? */
- c_shader_dfs_without(shader, link->node);
- if (node->visited == 0) {
- /* we were unable to visit current node thus current
- * predecessor is the immediate dominator of node, as
- * their can be only one immediate dominator we break
- */
- node->parent = link->node;
- nlink = c_node_link_new(node);
- if (nlink == NULL)
- return -ENOMEM;
- LIST_ADDTAIL(&nlink->head, &link->node->childs);
- found = 1;
- break;
- }
- }
- /* this shouldn't happen there should at least be 1 denominator for each node */
- if (!found && node->opcode != C_OPCODE_ENTRY) {
- fprintf(stderr, "invalid flow control graph node %p (%d) has no immediate dominator\n",
- node, node->opcode);
- return -EINVAL;
- }
- LIST_FOR_EACH_ENTRY(link, &node->predecessors, head) {
- r = c_shader_build_dominator_tree_rec(shader, link->node);
- if (r)
- return r;
- }
- return 0;
-}
-
-int c_shader_build_dominator_tree(struct c_shader *shader)
-{
- struct c_node *node;
- LIST_FOR_EACH_ENTRY(node, &shader->nodes, head) {
- node->done = 0;
- }
- return c_shader_build_dominator_tree_rec(shader, &shader->end);
-}
diff --git a/src/gallium/drivers/r600/r600_compiler.h b/src/gallium/drivers/r600/r600_compiler.h
deleted file mode 100644
index 77230aed73..0000000000
--- a/src/gallium/drivers/r600/r600_compiler.h
+++ /dev/null
@@ -1,320 +0,0 @@
-/*
- * Copyright 2010 Jerome Glisse <glisse@freedesktop.org>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * on the rights to use, copy, modify, merge, publish, distribute, sub
- * license, and/or sell copies of the Software, and to permit persons to whom
- * the Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
- * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
- * USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-#ifndef R600_COMPILER_H
-#define R600_COMPILER_H
-
-#include "util/u_double_list.h"
-
-struct c_vector;
-
-/* operand are the basic source/destination of each operation */
-struct c_channel {
- struct list_head head;
- unsigned vindex; /**< index in vector X,Y,Z,W (0,1,2,3) */
- unsigned value; /**< immediate value 32bits */
- struct c_vector *vector; /**< vector to which it belongs */
-};
-
-/* in GPU world most of the time operand are grouped into vector
- * of 4 component this structure is mostly and handler to group
- * operand into a same vector
- */
-struct c_vector {
- struct list_head head;
- unsigned id; /**< vector uniq id */
- unsigned name; /**< semantic name */
- unsigned file; /**< operand file C_FILE_* */
- int sid; /**< semantic id */
- struct c_channel *channel[4]; /**< operands */
-};
-
-#define C_PROGRAM_TYPE_VS 0
-#define C_PROGRAM_TYPE_FS 1
-#define C_PROGRAM_TYPE_COUNT 2
-
-#define C_NODE_FLAG_ALU 1
-#define C_NODE_FLAG_FETCH 2
-
-#define C_SWIZZLE_X 0
-#define C_SWIZZLE_Y 1
-#define C_SWIZZLE_Z 2
-#define C_SWIZZLE_W 3
-#define C_SWIZZLE_0 4
-#define C_SWIZZLE_1 5
-#define C_SWIZZLE_D 6
-
-#define C_FILE_NULL 0
-#define C_FILE_CONSTANT 1
-#define C_FILE_INPUT 2
-#define C_FILE_OUTPUT 3
-#define C_FILE_TEMPORARY 4
-#define C_FILE_SAMPLER 5
-#define C_FILE_ADDRESS 6
-#define C_FILE_IMMEDIATE 7
-#define C_FILE_LOOP 8
-#define C_FILE_PREDICATE 9
-#define C_FILE_SYSTEM_VALUE 10
-#define C_FILE_RESOURCE 11
-#define C_FILE_COUNT 12
-
-#define C_SEMANTIC_POSITION 0
-#define C_SEMANTIC_COLOR 1
-#define C_SEMANTIC_BCOLOR 2 /**< back-face color */
-#define C_SEMANTIC_FOG 3
-#define C_SEMANTIC_PSIZE 4
-#define C_SEMANTIC_GENERIC 5
-#define C_SEMANTIC_NORMAL 6
-#define C_SEMANTIC_FACE 7
-#define C_SEMANTIC_EDGEFLAG 8
-#define C_SEMANTIC_PRIMID 9
-#define C_SEMANTIC_INSTANCEID 10
-#define C_SEMANTIC_VERTEXID 11
-#define C_SEMANTIC_COUNT 12 /**< number of semantic values */
-
-#define C_OPCODE_NOP 0
-#define C_OPCODE_MOV 1
-#define C_OPCODE_LIT 2
-#define C_OPCODE_RCP 3
-#define C_OPCODE_RSQ 4
-#define C_OPCODE_EXP 5
-#define C_OPCODE_LOG 6
-#define C_OPCODE_MUL 7
-#define C_OPCODE_ADD 8
-#define C_OPCODE_DP3 9
-#define C_OPCODE_DP4 10
-#define C_OPCODE_DST 11
-#define C_OPCODE_MIN 12
-#define C_OPCODE_MAX 13
-#define C_OPCODE_SLT 14
-#define C_OPCODE_SGE 15
-#define C_OPCODE_MAD 16
-#define C_OPCODE_SUB 17
-#define C_OPCODE_LRP 18
-#define C_OPCODE_CND 19
-/* gap */
-#define C_OPCODE_DP2A 21
-/* gap */
-#define C_OPCODE_FRC 24
-#define C_OPCODE_CLAMP 25
-#define C_OPCODE_FLR 26
-#define C_OPCODE_ROUND 27
-#define C_OPCODE_EX2 28
-#define C_OPCODE_LG2 29
-#define C_OPCODE_POW 30
-#define C_OPCODE_XPD 31
-/* gap */
-#define C_OPCODE_ABS 33
-#define C_OPCODE_RCC 34
-#define C_OPCODE_DPH 35
-#define C_OPCODE_COS 36
-#define C_OPCODE_DDX 37
-#define C_OPCODE_DDY 38
-#define C_OPCODE_KILP 39 /* predicated kill */
-#define C_OPCODE_PK2H 40
-#define C_OPCODE_PK2US 41
-#define C_OPCODE_PK4B 42
-#define C_OPCODE_PK4UB 43
-#define C_OPCODE_RFL 44
-#define C_OPCODE_SEQ 45
-#define C_OPCODE_SFL 46
-#define C_OPCODE_SGT 47
-#define C_OPCODE_SIN 48
-#define C_OPCODE_SLE 49
-#define C_OPCODE_SNE 50
-#define C_OPCODE_STR 51
-#define C_OPCODE_TEX 52
-#define C_OPCODE_TXD 53
-#define C_OPCODE_TXP 54
-#define C_OPCODE_UP2H 55
-#define C_OPCODE_UP2US 56
-#define C_OPCODE_UP4B 57
-#define C_OPCODE_UP4UB 58
-#define C_OPCODE_X2D 59
-#define C_OPCODE_ARA 60
-#define C_OPCODE_ARR 61
-#define C_OPCODE_BRA 62
-#define C_OPCODE_CAL 63
-#define C_OPCODE_RET 64
-#define C_OPCODE_SSG 65 /* SGN */
-#define C_OPCODE_CMP 66
-#define C_OPCODE_SCS 67
-#define C_OPCODE_TXB 68
-#define C_OPCODE_NRM 69
-#define C_OPCODE_DIV 70
-#define C_OPCODE_DP2 71
-#define C_OPCODE_TXL 72
-#define C_OPCODE_BRK 73
-#define C_OPCODE_IF 74
-#define C_OPCODE_BGNFOR 75
-#define C_OPCODE_REP 76
-#define C_OPCODE_ELSE 77
-#define C_OPCODE_ENDIF 78
-#define C_OPCODE_ENDFOR 79
-#define C_OPCODE_ENDREP 80
-#define C_OPCODE_PUSHA 81
-#define C_OPCODE_POPA 82
-#define C_OPCODE_CEIL 83
-#define C_OPCODE_I2F 84
-#define C_OPCODE_NOT 85
-#define C_OPCODE_TRUNC 86
-#define C_OPCODE_SHL 87
-/* gap */
-#define C_OPCODE_AND 89
-#define C_OPCODE_OR 90
-#define C_OPCODE_MOD 91
-#define C_OPCODE_XOR 92
-#define C_OPCODE_SAD 93
-#define C_OPCODE_TXF 94
-#define C_OPCODE_TXQ 95
-#define C_OPCODE_CONT 96
-#define C_OPCODE_EMIT 97
-#define C_OPCODE_ENDPRIM 98
-#define C_OPCODE_BGNLOOP 99
-#define C_OPCODE_BGNSUB 100
-#define C_OPCODE_ENDLOOP 101
-#define C_OPCODE_ENDSUB 102
-/* gap */
-#define C_OPCODE_NRM4 112
-#define C_OPCODE_CALLNZ 113
-#define C_OPCODE_IFC 114
-#define C_OPCODE_BREAKC 115
-#define C_OPCODE_KIL 116 /* conditional kill */
-#define C_OPCODE_END 117 /* aka HALT */
-/* gap */
-#define C_OPCODE_F2I 119
-#define C_OPCODE_IDIV 120
-#define C_OPCODE_IMAX 121
-#define C_OPCODE_IMIN 122
-#define C_OPCODE_INEG 123
-#define C_OPCODE_ISGE 124
-#define C_OPCODE_ISHR 125
-#define C_OPCODE_ISLT 126
-#define C_OPCODE_F2U 127
-#define C_OPCODE_U2F 128
-#define C_OPCODE_UADD 129
-#define C_OPCODE_UDIV 130
-#define C_OPCODE_UMAD 131
-#define C_OPCODE_UMAX 132
-#define C_OPCODE_UMIN 133
-#define C_OPCODE_UMOD 134
-#define C_OPCODE_UMUL 135
-#define C_OPCODE_USEQ 136
-#define C_OPCODE_USGE 137
-#define C_OPCODE_USHR 138
-#define C_OPCODE_USLT 139
-#define C_OPCODE_USNE 140
-#define C_OPCODE_SWITCH 141
-#define C_OPCODE_CASE 142
-#define C_OPCODE_DEFAULT 143
-#define C_OPCODE_ENDSWITCH 144
-#define C_OPCODE_VFETCH 145
-#define C_OPCODE_ENTRY 146
-#define C_OPCODE_ARL 147
-#define C_OPCODE_LAST 148
-
-#define C_OPERAND_FLAG_ABS (1 << 0)
-#define C_OPERAND_FLAG_NEG (1 << 1)
-
-struct c_operand {
- struct c_vector *vector;
- unsigned swizzle;
- unsigned flag;
-};
-
-struct c_op {
- unsigned ninput;
- struct c_operand input[3];
- struct c_operand output;
- unsigned opcode;
-};
-
-struct c_instruction {
- struct list_head head;
- unsigned nop;
- struct c_op op[5];
-};
-
-struct c_node;
-
-struct c_node_link {
- struct list_head head;
- struct c_node *node;
-};
-
-/**
- * struct c_node
- *
- * @next: all node are in a double linked list, this point to
- * next node
- * @next: all node are in a double linked list, this point to
- * previous node
- * @predecessors: list of all predecessor nodes in the flow graph
- * @successors: list of all sucessor nodes in the flow graph
- * @parent: parent node in the depth first walk tree
- * @childs: child nodes in the depth first walk tree
- */
-struct c_node {
- struct list_head head;
- struct list_head predecessors;
- struct list_head successors;
- struct list_head childs;
- struct c_node *parent;
- struct list_head insts;
- unsigned opcode;
- unsigned visited;
- unsigned done;
- void *backend;
-};
-
-struct c_file {
- unsigned nvectors;
- struct list_head vectors;
-};
-
-struct c_shader {
- unsigned nvectors;
- struct c_file files[C_FILE_COUNT];
- struct list_head nodes;
- struct c_node entry;
- struct c_node end;
- unsigned type;
-};
-
-int c_shader_init(struct c_shader *shader, unsigned type);
-void c_shader_destroy(struct c_shader *shader);
-struct c_vector *c_shader_vector_new(struct c_shader *shader, unsigned file, unsigned name, int sid);
-int c_shader_build_dominator_tree(struct c_shader *shader);
-void c_shader_dump(struct c_shader *shader);
-
-void c_node_init(struct c_node *node);
-int c_node_add_new_instruction(struct c_node *node, struct c_instruction *instruction);
-int c_node_add_new_instruction_head(struct c_node *node, struct c_instruction *instruction);
-
-/* control flow graph functions */
-int c_node_cfg_link(struct c_node *predecessor, struct c_node *successor);
-struct c_node *c_node_cfg_new_after(struct c_node *predecessor);
-struct c_node *c_shader_cfg_new_node_after(struct c_shader *shader, struct c_node *predecessor);
-
-struct c_vector *c_vector_new(void);
-
-#endif
diff --git a/src/gallium/drivers/r600/r600_compiler_dump.c b/src/gallium/drivers/r600/r600_compiler_dump.c
deleted file mode 100644
index bb022b7c29..0000000000
--- a/src/gallium/drivers/r600/r600_compiler_dump.c
+++ /dev/null
@@ -1,267 +0,0 @@
-/*
- * Copyright 2010 Jerome Glisse <glisse@freedesktop.org>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * on the rights to use, copy, modify, merge, publish, distribute, sub
- * license, and/or sell copies of the Software, and to permit persons to whom
- * the Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
- * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
- * USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-#include <stdlib.h>
-#include <string.h>
-#include <stdint.h>
-#include <stdio.h>
-#include "r600_compiler.h"
-
-static const char *c_file_swz[] = {
- "x",
- "y",
- "z",
- "w",
- "0",
- "1",
- ".",
-};
-
-static const char *c_file_str[] = {
- "NULL",
- "CONSTANT",
- "INPUT",
- "OUTPUT",
- "TEMPORARY",
- "SAMPLER",
- "ADDRESS",
- "IMMEDIATE",
- "LOOP",
- "PREDICATE",
- "SYSTEM_VALUE",
-};
-
-static const char *c_semantic_str[] = {
- "POSITION",
- "COLOR",
- "BCOLOR",
- "FOG",
- "PSIZE",
- "GENERIC",
- "NORMAL",
- "FACE",
- "EDGEFLAG",
- "PRIMID",
- "INSTANCEID",
-};
-
-static const char *c_opcode_str[] = {
- "ARL",
- "MOV",
- "LIT",
- "RCP",
- "RSQ",
- "EXP",
- "LOG",
- "MUL",
- "ADD",
- "DP3",
- "DP4",
- "DST",
- "MIN",
- "MAX",
- "SLT",
- "SGE",
- "MAD",
- "SUB",
- "LRP",
- "CND",
- "(INVALID)",
- "DP2A",
- "(INVALID)",
- "(INVALID)",
- "FRC",
- "CLAMP",
- "FLR",
- "ROUND",
- "EX2",
- "LG2",
- "POW",
- "XPD",
- "(INVALID)",
- "ABS",
- "RCC",
- "DPH",
- "COS",
- "DDX",
- "DDY",
- "KILP",
- "PK2H",
- "PK2US",
- "PK4B",
- "PK4UB",
- "RFL",
- "SEQ",
- "SFL",
- "SGT",
- "SIN",
- "SLE",
- "SNE",
- "STR",
- "TEX",
- "TXD",
- "TXP",
- "UP2H",
- "UP2US",
- "UP4B",
- "UP4UB",
- "X2D",
- "ARA",
- "ARR",
- "BRA",
- "CAL",
- "RET",
- "SSG",
- "CMP",
- "SCS",
- "TXB",
- "NRM",
- "DIV",
- "DP2",
- "TXL",
- "BRK",
- "IF",
- "BGNFOR",
- "REP",
- "ELSE",
- "ENDIF",
- "ENDFOR",
- "ENDREP",
- "PUSHA",
- "POPA",
- "CEIL",
- "I2F",
- "NOT",
- "TRUNC",
- "SHL",
- "(INVALID)",
- "AND",
- "OR",
- "MOD",
- "XOR",
- "SAD",
- "TXF",
- "TXQ",
- "CONT",
- "EMIT",
- "ENDPRIM",
- "BGNLOOP",
- "BGNSUB",
- "ENDLOOP",
- "ENDSUB",
- "(INVALID)",
- "(INVALID)",
- "(INVALID)",
- "(INVALID)",
- "NOP",
- "(INVALID)",
- "(INVALID)",
- "(INVALID)",
- "(INVALID)",
- "NRM4",
- "CALLNZ",
- "IFC",
- "BREAKC",
- "KIL",
- "END",
- "(INVALID)",
- "F2I",
- "IDIV",
- "IMAX",
- "IMIN",
- "INEG",
- "ISGE",
- "ISHR",
- "ISLT",
- "F2U",
- "U2F",
- "UADD",
- "UDIV",
- "UMAD",
- "UMAX",
- "UMIN",
- "UMOD",
- "UMUL",
- "USEQ",
- "USGE",
- "USHR",
- "USLT",
- "USNE",
- "SWITCH",
- "CASE",
- "DEFAULT",
- "ENDSWITCH",
- "VFETCH",
- "ENTRY",
-};
-
-static inline const char *c_get_name(const char *name[], unsigned i)
-{
- return name[i];
-}
-
-static void pindent(unsigned indent)
-{
- unsigned i;
- for (i = 0; i < indent; i++)
- fprintf(stderr, " ");
-}
-
-static void c_node_dump(struct c_node *node, unsigned indent)
-{
- struct c_instruction *i;
- unsigned j, k;
-
- pindent(indent); fprintf(stderr, "# node %s\n", c_get_name(c_opcode_str, node->opcode));
- LIST_FOR_EACH_ENTRY(i, &node->insts, head) {
- for (k = 0; k < i->nop; k++) {
- pindent(indent);
- fprintf(stderr, "%s", c_get_name(c_opcode_str, i->op[k].opcode));
- fprintf(stderr, " %s[%d][%s]",
- c_get_name(c_file_str, i->op[k].output.vector->file),
- i->op[k].output.vector->id,
- c_get_name(c_file_swz, i->op[k].output.swizzle));
- for (j = 0; j < i->op[k].ninput; j++) {
- fprintf(stderr, " %s[%d][%s]",
- c_get_name(c_file_str, i->op[k].input[j].vector->file),
- i->op[k].input[j].vector->id,
- c_get_name(c_file_swz, i->op[k].input[j].swizzle));
- }
- fprintf(stderr, ";\n");
- }
- }
-}
-
-static void c_shader_dump_rec(struct c_shader *shader, struct c_node *node, unsigned indent)
-{
- struct c_node_link *link;
-
- c_node_dump(node, indent);
- LIST_FOR_EACH_ENTRY(link, &node->childs, head) {
- c_shader_dump_rec(shader, link->node, indent + 1);
- }
-}
-
-void c_shader_dump(struct c_shader *shader)
-{
- c_shader_dump_rec(shader, &shader->entry, 0);
-}
diff --git a/src/gallium/drivers/r600/r600_compiler_r600.c b/src/gallium/drivers/r600/r600_compiler_r600.c
deleted file mode 100644
index 27ad8f1a18..0000000000
--- a/src/gallium/drivers/r600/r600_compiler_r600.c
+++ /dev/null
@@ -1,972 +0,0 @@
-/*
- * Copyright 2010 Jerome Glisse <glisse@freedesktop.org>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * on the rights to use, copy, modify, merge, publish, distribute, sub
- * license, and/or sell copies of the Software, and to permit persons to whom
- * the Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
- * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
- * USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-#include <stdlib.h>
-#include <string.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <errno.h>
-#include <util/u_format.h>
-#include "r600_screen.h"
-#include "r600_context.h"
-#include "r600_sq.h"
-
-
-struct r600_alu_instruction {
- unsigned copcode;
- enum r600_instruction instruction;
-};
-
-static int r600_shader_alu_translate(struct r600_shader *rshader,
- struct r600_shader_node *node,
- struct c_instruction *instruction);
-struct r600_alu_instruction r600_alu_instruction[C_OPCODE_LAST];
-struct r600_instruction_info r600_instruction_info[];
-
-int r600_shader_insert_fetch(struct c_shader *shader)
-{
- struct c_vector *vi, *vr, *v, *nv;
- struct c_instruction instruction;
- int r;
-
- if (shader->type != C_PROGRAM_TYPE_VS)
- return 0;
- vi = c_shader_vector_new(shader, C_FILE_INPUT, C_SEMANTIC_VERTEXID, -1);
- if (vi == NULL)
- return -ENOMEM;
- LIST_FOR_EACH_ENTRY_SAFE(v, nv, &shader->files[C_FILE_INPUT].vectors, head) {
- if (v == vi)
- continue;
- vr = c_shader_vector_new(shader, C_FILE_RESOURCE, C_SEMANTIC_GENERIC, -1);
- if (vr == NULL)
- return -ENOMEM;
- memset(&instruction, 0, sizeof(struct c_instruction));
- instruction.nop = 4;
- instruction.op[0].opcode = C_OPCODE_VFETCH;
- instruction.op[1].opcode = C_OPCODE_VFETCH;
- instruction.op[2].opcode = C_OPCODE_VFETCH;
- instruction.op[3].opcode = C_OPCODE_VFETCH;
- instruction.op[0].ninput = 2;
- instruction.op[1].ninput = 2;
- instruction.op[2].ninput = 2;
- instruction.op[3].ninput = 2;
- instruction.op[0].output.vector = v;
- instruction.op[1].output.vector = v;
- instruction.op[2].output.vector = v;
- instruction.op[3].output.vector = v;
- instruction.op[0].input[0].vector = vi;
- instruction.op[0].input[1].vector = vr;
- instruction.op[1].input[0].vector = vi;
- instruction.op[1].input[1].vector = vr;
- instruction.op[2].input[0].vector = vi;
- instruction.op[2].input[1].vector = vr;
- instruction.op[3].input[0].vector = vi;
- instruction.op[3].input[1].vector = vr;
- instruction.op[0].output.swizzle = C_SWIZZLE_X;
- instruction.op[1].output.swizzle = C_SWIZZLE_Y;
- instruction.op[2].output.swizzle = C_SWIZZLE_Z;
- instruction.op[3].output.swizzle = C_SWIZZLE_W;
- r = c_node_add_new_instruction_head(&shader->entry, &instruction);
- if (r)
- return r;
- LIST_DEL(&v->head);
- shader->files[C_FILE_INPUT].nvectors--;
- LIST_ADDTAIL(&v->head, &shader->files[C_FILE_TEMPORARY].vectors);
- shader->files[C_FILE_TEMPORARY].nvectors++;
- v->file = C_FILE_TEMPORARY;
- }
- return 0;
-}
-
-void r600_shader_cleanup(struct r600_shader *rshader)
-{
- struct r600_shader_node *n, *nn;
- struct r600_shader_vfetch *vf, *nvf;
- struct r600_shader_alu *alu, *nalu;
- int i;
-
- if (rshader == NULL)
- return;
- if (rshader->gpr) {
- for (i = 0; i < rshader->nvector; i++) {
- free(rshader->gpr[i]);
- }
- free(rshader->gpr);
- rshader->gpr = NULL;
- }
- LIST_FOR_EACH_ENTRY_SAFE(n, nn, &rshader->nodes, head) {
- LIST_DEL(&n->head);
- LIST_FOR_EACH_ENTRY_SAFE(vf, nvf, &n->vfetch, head) {
- LIST_DEL(&vf->head);
- free(vf);
- }
- LIST_FOR_EACH_ENTRY_SAFE(alu, nalu, &n->alu, head) {
- LIST_DEL(&alu->head);
- free(alu);
- }
- free(n);
- }
- free(rshader->bcode);
- return;
-}
-
-int r600_shader_vfetch_bytecode(struct r600_shader *rshader,
- struct r600_shader_node *rnode,
- struct r600_shader_vfetch *vfetch,
- unsigned *cid)
-{
- unsigned id = *cid;
-
- vfetch->cf_addr = id;
- rshader->bcode[id++] = S_SQ_VTX_WORD0_BUFFER_ID(vfetch->src[1].sel) |
- S_SQ_VTX_WORD0_SRC_GPR(vfetch->src[0].sel) |
- S_SQ_VTX_WORD0_SRC_SEL_X(vfetch->src[0].sel) |
- S_SQ_VTX_WORD0_MEGA_FETCH_COUNT(0x1F);
- rshader->bcode[id++] = S_SQ_VTX_WORD1_DST_SEL_X(vfetch->dst[0].chan) |
- S_SQ_VTX_WORD1_DST_SEL_Y(vfetch->dst[1].chan) |
- S_SQ_VTX_WORD1_DST_SEL_Z(vfetch->dst[2].chan) |
- S_SQ_VTX_WORD1_DST_SEL_W(vfetch->dst[3].chan) |
- S_SQ_VTX_WORD1_USE_CONST_FIELDS(1) |
- S_SQ_VTX_WORD1_GPR_DST_GPR(vfetch->dst[0].sel);
- rshader->bcode[id++] = S_SQ_VTX_WORD2_MEGA_FETCH(1);
- rshader->bcode[id++] = 0;
- *cid = id;
- return 0;
-}
-
-int r600_shader_update(struct r600_shader *rshader, enum pipe_format *resource_format)
-{
- struct r600_shader_node *rnode;
- struct r600_shader_vfetch *vfetch;
- unsigned i;
-
- memcpy(rshader->resource_format, resource_format,
- rshader->nresource * sizeof(enum pipe_format));
- LIST_FOR_EACH_ENTRY(rnode, &rshader->nodes, head) {
- LIST_FOR_EACH_ENTRY(vfetch, &rnode->vfetch, head) {
- const struct util_format_description *desc;
- i = vfetch->cf_addr + 1;
- rshader->bcode[i] &= C_SQ_VTX_WORD1_DST_SEL_X;
- rshader->bcode[i] &= C_SQ_VTX_WORD1_DST_SEL_Y;
- rshader->bcode[i] &= C_SQ_VTX_WORD1_DST_SEL_Z;
- rshader->bcode[i] &= C_SQ_VTX_WORD1_DST_SEL_W;
- desc = util_format_description(resource_format[vfetch->src[1].sel]);
- if (desc == NULL) {
- fprintf(stderr, "%s unknown format %d\n", __func__, resource_format[vfetch->src[1].sel]);
- continue;
- }
- /* WARNING so far TGSI swizzle match R600 ones */
- rshader->bcode[i] |= S_SQ_VTX_WORD1_DST_SEL_X(desc->swizzle[0]);
- rshader->bcode[i] |= S_SQ_VTX_WORD1_DST_SEL_Y(desc->swizzle[1]);
- rshader->bcode[i] |= S_SQ_VTX_WORD1_DST_SEL_Z(desc->swizzle[2]);
- rshader->bcode[i] |= S_SQ_VTX_WORD1_DST_SEL_W(desc->swizzle[3]);
- }
- }
- return 0;
-}
-
-int r600_shader_register(struct r600_shader *rshader)
-{
- struct c_vector *v, *nv;
- unsigned tid, cid, rid, i;
-
- rshader->nvector = rshader->cshader.nvectors;
- rshader->gpr = calloc(rshader->nvector, sizeof(void*));
- if (rshader->gpr == NULL)
- return -ENOMEM;
- tid = 0;
- cid = 0;
- rid = 0;
- /* alloc input first */
- LIST_FOR_EACH_ENTRY(v, &rshader->cshader.files[C_FILE_INPUT].vectors, head) {
- nv = c_vector_new();
- if (nv == NULL) {
- return -ENOMEM;
- }
- memcpy(nv, v, sizeof(struct c_vector));
- nv->id = tid++;
- rshader->gpr[v->id] = nv;
- }
- for (i = 0; i < C_FILE_COUNT; i++) {
- if (i == C_FILE_INPUT || i == C_FILE_IMMEDIATE)
- continue;
- LIST_FOR_EACH_ENTRY(v, &rshader->cshader.files[i].vectors, head) {
- switch (v->file) {
- case C_FILE_OUTPUT:
- case C_FILE_TEMPORARY:
- nv = c_vector_new();
- if (nv == NULL) {
- return -ENOMEM;
- }
- memcpy(nv, v, sizeof(struct c_vector));
- nv->id = tid++;
- rshader->gpr[v->id] = nv;
- break;
- case C_FILE_CONSTANT:
- nv = c_vector_new();
- if (nv == NULL) {
- return -ENOMEM;
- }
- memcpy(nv, v, sizeof(struct c_vector));
- nv->id = (cid++) + 256;
- rshader->gpr[v->id] = nv;
- break;
- case C_FILE_RESOURCE:
- nv = c_vector_new();
- if (nv == NULL) {
- return -ENOMEM;
- }
- memcpy(nv, v, sizeof(struct c_vector));
- nv->id = (rid++);
- rshader->gpr[v->id] = nv;
- break;
- default:
- fprintf(stderr, "%s:%d unsupported file %d\n", __func__, __LINE__, v->file);
- return -EINVAL;
- }
- }
- }
- rshader->ngpr = tid;
- rshader->nconstant = cid;
- rshader->nresource = rid;
- return 0;
-}
-
-int r600_shader_find_gpr(struct r600_shader *rshader, struct c_vector *v, unsigned swizzle,
- struct r600_shader_operand *operand)
-{
- struct c_vector *tmp;
-
- /* Values [0,127] correspond to GPR[0..127].
- * Values [256,511] correspond to cfile constants c[0..255].
- * Other special values are shown in the list below.
- * 248 SQ_ALU_SRC_0: special constant 0.0.
- * 249 SQ_ALU_SRC_1: special constant 1.0 float.
- * 250 SQ_ALU_SRC_1_INT: special constant 1 integer.
- * 251 SQ_ALU_SRC_M_1_INT: special constant -1 integer.
- * 252 SQ_ALU_SRC_0_5: special constant 0.5 float.
- * 253 SQ_ALU_SRC_LITERAL: literal constant.
- * 254 SQ_ALU_SRC_PV: previous vector result.
- * 255 SQ_ALU_SRC_PS: previous scalar result.
- */
- operand->vector = v;
- operand->sel = 248;
- operand->chan = 0;
- operand->neg = 0;
- operand->abs = 0;
- if (v == NULL)
- return 0;
- if (v->file == C_FILE_IMMEDIATE) {
- operand->sel = 253;
- } else {
- tmp = rshader->gpr[v->id];
- if (tmp == NULL) {
- fprintf(stderr, "%s %d unknown register\n", __FILE__, __LINE__);
- return -EINVAL;
- }
- operand->sel = tmp->id;
- }
- operand->chan = swizzle;
- switch (swizzle) {
- case C_SWIZZLE_X:
- case C_SWIZZLE_Y:
- case C_SWIZZLE_Z:
- case C_SWIZZLE_W:
- break;
- case C_SWIZZLE_0:
- operand->sel = 248;
- operand->chan = 0;
- break;
- case C_SWIZZLE_1:
- operand->sel = 249;
- operand->chan = 0;
- break;
- default:
- fprintf(stderr, "%s %d invalid swizzle %d\n", __FILE__, __LINE__, swizzle);
- return -EINVAL;
- }
- return 0;
-}
-
-static struct r600_shader_node *r600_shader_new_node(struct r600_shader *rshader, struct c_node *node)
-{
- struct r600_shader_node *rnode;
-
- rnode = CALLOC_STRUCT(r600_shader_node);
- if (rnode == NULL)
- return NULL;
- rnode->node = node;
- LIST_INITHEAD(&rnode->vfetch);
-fprintf(stderr, "------------------------ new node (%p %p)\n", &rnode->vfetch, rnode->vfetch.next);
- LIST_INITHEAD(&rnode->alu);
- LIST_ADDTAIL(&rnode->head, &rshader->nodes);
- return rnode;
-}
-
-static int r600_shader_add_vfetch(struct r600_shader *rshader,
- struct r600_shader_node *node,
- struct c_instruction *instruction)
-{
- struct r600_shader_vfetch *vfetch;
- struct r600_shader_node *rnode;
- int r;
-
- if (instruction == NULL)
- return 0;
- if (instruction->op[0].opcode != C_OPCODE_VFETCH)
- return 0;
- if (!LIST_IS_EMPTY(&node->alu)) {
- rnode = r600_shader_new_node(rshader, node->node);
- if (rnode == NULL)
- return -ENOMEM;
- node = rnode;
- }
- vfetch = calloc(1, sizeof(struct r600_shader_vfetch));
- if (vfetch == NULL)
- return -ENOMEM;
- r = r600_shader_find_gpr(rshader, instruction->op[0].output.vector, 0, &vfetch->dst[0]);
- if (r)
- return r;
- r = r600_shader_find_gpr(rshader, instruction->op[0].input[0].vector, 0, &vfetch->src[0]);
- if (r)
- return r;
- r = r600_shader_find_gpr(rshader, instruction->op[0].input[1].vector, 0, &vfetch->src[1]);
- if (r)
- return r;
- vfetch->dst[0].chan = C_SWIZZLE_X;
- vfetch->dst[1].chan = C_SWIZZLE_Y;
- vfetch->dst[2].chan = C_SWIZZLE_Z;
- vfetch->dst[3].chan = C_SWIZZLE_W;
- LIST_ADDTAIL(&vfetch->head, &node->vfetch);
- node->nslot += 2;
- return 0;
-}
-
-static int r600_node_translate(struct r600_shader *rshader, struct c_node *node)
-{
- struct c_instruction *instruction;
- struct r600_shader_node *rnode;
- int r;
-
- rnode = r600_shader_new_node(rshader, node);
- if (rnode == NULL)
- return -ENOMEM;
- LIST_FOR_EACH_ENTRY(instruction, &node->insts, head) {
- switch (instruction->op[0].opcode) {
- case C_OPCODE_VFETCH:
- r = r600_shader_add_vfetch(rshader, rnode, instruction);
- if (r) {
- fprintf(stderr, "%s %d vfetch failed\n", __func__, __LINE__);
- return r;
- }
- break;
- default:
- r = r600_shader_alu_translate(rshader, rnode, instruction);
- if (r) {
- fprintf(stderr, "%s %d alu failed\n", __func__, __LINE__);
- return r;
- }
- break;
- }
- }
- return 0;
-}
-
-int r600_shader_translate_rec(struct r600_shader *rshader, struct c_node *node)
-{
- struct c_node_link *link;
- int r;
-
- if (node->opcode == C_OPCODE_END)
- return 0;
- r = r600_node_translate(rshader, node);
- if (r)
- return r;
- LIST_FOR_EACH_ENTRY(link, &node->childs, head) {
- r = r600_shader_translate_rec(rshader, link->node);
- if (r)
- return r;
- }
- return 0;
-}
-
-static struct r600_shader_alu *r600_shader_insert_alu(struct r600_shader *rshader, struct r600_shader_node *node)
-{
- struct r600_shader_alu *alu;
-
- alu = CALLOC_STRUCT(r600_shader_alu);
- if (alu == NULL)
- return NULL;
- alu->alu[0].inst = INST_NOP;
- alu->alu[1].inst = INST_NOP;
- alu->alu[2].inst = INST_NOP;
- alu->alu[3].inst = INST_NOP;
- alu->alu[4].inst = INST_NOP;
- alu->alu[0].opcode = V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP;
- alu->alu[1].opcode = V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP;
- alu->alu[2].opcode = V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP;
- alu->alu[3].opcode = V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP;
- alu->alu[4].opcode = V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP;
- alu->alu[1].dst.chan = 1;
- alu->alu[2].dst.chan = 2;
- alu->alu[3].dst.chan = 3;
- LIST_ADDTAIL(&alu->head, &node->alu);
- return alu;
-}
-
-static int r600_shader_alu_translate(struct r600_shader *rshader,
- struct r600_shader_node *node,
- struct c_instruction *instruction)
-{
- struct r600_shader_node *rnode;
- struct r600_shader_alu *alu;
- int i, j, r, litteral_lastcomp = -1;
-
- if (!LIST_IS_EMPTY(&node->vfetch)) {
-fprintf(stderr, "------------------------ add node (%p %p)\n", &node->vfetch, node->vfetch.next);
- rnode = r600_shader_new_node(rshader, node->node);
- if (rnode == NULL) {
- fprintf(stderr, "%s %d new node failed\n", __func__, __LINE__);
- return -ENOMEM;
- }
- node = rnode;
- }
-
- /* initialize alu */
- alu = r600_shader_insert_alu(rshader, node);
-
- /* check special operation like lit */
-
- /* go through operation */
- for (i = 0; i < instruction->nop; i++) {
- struct r600_alu_instruction *ainfo = &r600_alu_instruction[instruction->op[i].opcode];
- struct r600_instruction_info *iinfo = &r600_instruction_info[ainfo->instruction];
- unsigned comp;
-
- /* check that output is a valid component */
- comp = instruction->op[i].output.swizzle;
- switch (comp) {
- case C_SWIZZLE_X:
- case C_SWIZZLE_Y:
- case C_SWIZZLE_Z:
- case C_SWIZZLE_W:
- break;
- case C_SWIZZLE_0:
- case C_SWIZZLE_1:
- default:
- fprintf(stderr, "%s %d invalid output %d\n", __func__, __LINE__, comp);
- return -EINVAL;
- }
- alu->alu[comp].inst = ainfo->instruction;
- alu->alu[comp].opcode = iinfo->opcode;
- alu->alu[comp].is_op3 = iinfo->is_op3;
- for (j = 0; j < instruction->op[i].ninput; j++) {
- r = r600_shader_find_gpr(rshader, instruction->op[i].input[j].vector,
- instruction->op[i].input[j].swizzle, &alu->alu[comp].src[j]);
- if (r) {
- fprintf(stderr, "%s %d register failed\n", __FILE__, __LINE__);
- return r;
- }
- if (instruction->op[i].input[j].vector->file == C_FILE_IMMEDIATE) {
- r = instruction->op[i].input[j].swizzle;
- switch (r) {
- case C_SWIZZLE_X:
- case C_SWIZZLE_Y:
- case C_SWIZZLE_Z:
- case C_SWIZZLE_W:
- break;
- case C_SWIZZLE_0:
- case C_SWIZZLE_1:
- default:
- fprintf(stderr, "%s %d invalid input\n", __func__, __LINE__);
- return -EINVAL;
- }
- alu->literal[r] = instruction->op[i].input[j].vector->channel[r]->value;
- if (r > litteral_lastcomp) {
- litteral_lastcomp = r;
- }
- }
- }
- r = r600_shader_find_gpr(rshader, instruction->op[i].output.vector,
- instruction->op[i].output.swizzle, &alu->alu[comp].dst);
- if (r) {
- fprintf(stderr, "%s %d register failed\n", __FILE__, __LINE__);
- return r;
- }
- }
- switch (litteral_lastcomp) {
- case 0:
- case 1:
- alu->nliteral = 2;
- break;
- case 2:
- case 3:
- alu->nliteral = 4;
- break;
- case -1:
- default:
- break;
- }
- for (i = 4; i >= 0; i--) {
- if (alu->alu[i].inst != INST_NOP) {
- alu->alu[i].last = 1;
- alu->nalu = i + 1;
- break;
- }
- }
- return 0;
-}
-
-void r600_shader_node_place(struct r600_shader *rshader)
-{
- struct r600_shader_node *node, *nnode;
- struct r600_shader_alu *alu, *nalu;
- struct r600_shader_vfetch *vfetch, *nvfetch;
- unsigned cf_id = 0, cf_addr = 0;
-
- rshader->ncf = 0;
- rshader->nslot = 0;
- LIST_FOR_EACH_ENTRY_SAFE(node, nnode, &rshader->nodes, head) {
- LIST_FOR_EACH_ENTRY_SAFE(alu, nalu, &node->alu, head) {
- node->nslot += alu->nalu;
- node->nslot += alu->nliteral >> 1;
- }
- node->nfetch = 0;
- LIST_FOR_EACH_ENTRY_SAFE(vfetch, nvfetch, &node->vfetch, head) {
- node->nslot += 2;
- node->nfetch += 1;
- }
- if (!LIST_IS_EMPTY(&node->vfetch)) {
- /* fetch node need to be 16 bytes aligned*/
- cf_addr += 1;
- cf_addr &= 0xFFFFFFFEUL;
- }
- node->cf_id = cf_id;
- node->cf_addr = cf_addr;
- cf_id += 2;
- cf_addr += node->nslot * 2;
- rshader->ncf++;
- }
- rshader->nslot = cf_addr;
- LIST_FOR_EACH_ENTRY_SAFE(node, nnode, &rshader->nodes, head) {
- node->cf_addr += cf_id * 2;
- }
- rshader->ncf += rshader->cshader.files[C_FILE_OUTPUT].nvectors;
- rshader->ndw = rshader->ncf * 2 + rshader->nslot * 2;
-}
-
-int r600_shader_legalize(struct r600_shader *rshader)
-{
- return 0;
-}
-
-
-static int r600_cshader_legalize_rec(struct c_shader *shader, struct c_node *node)
-{
- struct c_node_link *link;
- struct c_instruction *i, *n;
- struct c_operand operand;
- unsigned k, inst;
- int r;
-
- LIST_FOR_EACH_ENTRY(i, &node->insts, head) {
- for (k = 0; k < i->nop; k++) {
- switch (i->op[k].opcode) {
- case C_OPCODE_SLT:
- i->op[k].opcode = C_OPCODE_SGT;
- memcpy(&operand, &i->op[k].input[0], sizeof(struct c_operand));
- memcpy(&i->op[k].input[0], &i->op[k].input[1], sizeof(struct c_operand));
- memcpy(&i->op[k].input[1], &operand, sizeof(struct c_operand));
- break;
- default:
- break;
- }
- inst = r600_alu_instruction[i->op[k].opcode].instruction;
- if (r600_instruction_info[inst].is_trans && k < (i->nop -1)) {
- /* split trans opcode */
- n = CALLOC_STRUCT(c_instruction);
- if (n == NULL)
- return -ENOMEM;
- for (n->nop = 0, k = k + 1; k < i->nop; k++, n->nop++) {
- memcpy(&n->op[n->nop - 0], &i->op[k], sizeof(struct c_op));
- }
- i->nop -= n->nop;
- LIST_ADD(&n->head, &i->head);
- }
- }
- }
- LIST_FOR_EACH_ENTRY(link, &node->childs, head) {
- r = r600_cshader_legalize_rec(shader, link->node);
- if (r) {
- return r;
- }
- }
- return 0;
-}
-
-int r600_cshader_legalize(struct c_shader *shader)
-{
- return r600_cshader_legalize_rec(shader, &shader->entry);
-}
-
-
-struct r600_instruction_info r600_instruction_info[] = {
- {INST_ADD, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_ADD, 0, 0},
- {INST_MUL, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MUL, 0, 0},
- {INST_MUL_IEEE, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MUL_IEEE, 0, 0},
- {INST_MAX, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MAX, 0, 0},
- {INST_MIN, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MIN, 0, 0},
- {INST_MAX_DX10, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MAX_DX10, 0, 0},
- {INST_MIN_DX10, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MIN_DX10, 0, 0},
- {INST_SETE, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SETE, 0, 0},
- {INST_SETGT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SETGT, 0, 0},
- {INST_SETGE, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SETGE, 0, 0},
- {INST_SETNE, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SETNE, 0, 0},
- {INST_SETE_DX10, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SETE_DX10, 0, 0},
- {INST_SETGT_DX10, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SETGT_DX10, 0, 0},
- {INST_SETGE_DX10, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SETGE_DX10, 0, 0},
- {INST_SETNE_DX10, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SETNE_DX10, 0, 0},
- {INST_FRACT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_FRACT, 0, 0},
- {INST_TRUNC, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_TRUNC, 0, 0},
- {INST_CEIL, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_CEIL, 0, 0},
- {INST_RNDNE, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RNDNE, 0, 0},
- {INST_FLOOR, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_FLOOR, 0, 0},
- {INST_MOVA, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOVA, 0, 0},
- {INST_MOVA_FLOOR, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOVA_FLOOR, 0, 0},
- {INST_MOVA_INT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOVA_INT, 0, 0},
- {INST_MOV, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOV, 0, 0},
- {INST_NOP, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, 0, 0},
- {INST_PRED_SETGT_UINT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGT_UINT, 0, 0},
- {INST_PRED_SETGE_UINT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGE_UINT, 0, 0},
- {INST_PRED_SETE, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETE, 0, 0},
- {INST_PRED_SETGT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGT, 0, 0},
- {INST_PRED_SETGE, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGE, 0, 0},
- {INST_PRED_SETNE, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETNE, 0, 0},
- {INST_PRED_SET_INV, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SET_INV, 0, 0},
- {INST_PRED_SET_POP, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SET_POP, 0, 0},
- {INST_PRED_SET_CLR, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SET_CLR, 0, 0},
- {INST_PRED_SET_RESTORE, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SET_RESTORE, 0, 0},
- {INST_PRED_SETE_PUSH, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETE_PUSH, 0, 0},
- {INST_PRED_SETGT_PUSH, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGT_PUSH, 0, 0},
- {INST_PRED_SETGE_PUSH, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGE_PUSH, 0, 0},
- {INST_PRED_SETNE_PUSH, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETNE_PUSH, 0, 0},
- {INST_KILLE, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLE, 0, 0},
- {INST_KILLGT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLGT, 0, 0},
- {INST_KILLGE, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLGE, 0, 0},
- {INST_KILLNE, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLNE, 0, 0},
- {INST_AND_INT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_AND_INT, 0, 0},
- {INST_OR_INT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_OR_INT, 0, 0},
- {INST_XOR_INT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_XOR_INT, 0, 0},
- {INST_NOT_INT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOT_INT, 0, 0},
- {INST_ADD_INT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_ADD_INT, 0, 0},
- {INST_SUB_INT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SUB_INT, 0, 0},
- {INST_MAX_INT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MAX_INT, 0, 0},
- {INST_MIN_INT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MIN_INT, 0, 0},
- {INST_MAX_UINT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MAX_UINT, 0, 0},
- {INST_MIN_UINT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MIN_UINT, 0, 0},
- {INST_SETE_INT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SETE_INT, 0, 0},
- {INST_SETGT_INT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SETGT_INT, 0, 0},
- {INST_SETGE_INT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SETGE_INT, 0, 0},
- {INST_SETNE_INT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SETNE_INT, 0, 0},
- {INST_SETGT_UINT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SETGT_UINT, 0, 0},
- {INST_SETGE_UINT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SETGE_UINT, 0, 0},
- {INST_KILLGT_UINT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLGT_UINT, 0, 0},
- {INST_KILLGE_UINT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLGE_UINT, 0, 0},
- {INST_PRED_SETE_INT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETE_INT, 0, 0},
- {INST_PRED_SETGT_INT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGT_INT, 0, 0},
- {INST_PRED_SETGE_INT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGE_INT, 0, 0},
- {INST_PRED_SETNE_INT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETNE_INT, 0, 0},
- {INST_KILLE_INT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLE_INT, 0, 0},
- {INST_KILLGT_INT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLGT_INT, 0, 0},
- {INST_KILLGE_INT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLGE_INT, 0, 0},
- {INST_KILLNE_INT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLNE_INT, 0, 0},
- {INST_PRED_SETE_PUSH_INT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETE_PUSH_INT, 0, 0},
- {INST_PRED_SETGT_PUSH_INT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGT_PUSH_INT, 0, 0},
- {INST_PRED_SETGE_PUSH_INT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGE_PUSH_INT, 0, 0},
- {INST_PRED_SETNE_PUSH_INT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETNE_PUSH_INT, 0, 0},
- {INST_PRED_SETLT_PUSH_INT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETLT_PUSH_INT, 0, 0},
- {INST_PRED_SETLE_PUSH_INT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETLE_PUSH_INT, 0, 0},
- {INST_DOT4, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_DOT4, 0, 0},
- {INST_DOT4_IEEE, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_DOT4_IEEE, 0, 0},
- {INST_CUBE, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_CUBE, 0, 0},
- {INST_MAX4, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MAX4, 0, 0},
- {INST_MOVA_GPR_INT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOVA_GPR_INT, 0, 0},
- {INST_EXP_IEEE, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_EXP_IEEE, 1, 0},
- {INST_LOG_CLAMPED, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_LOG_CLAMPED, 1, 0},
- {INST_LOG_IEEE, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_LOG_IEEE, 1, 0},
- {INST_RECIP_CLAMPED, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIP_CLAMPED, 1, 0},
- {INST_RECIP_FF, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIP_FF, 1, 0},
- {INST_RECIP_IEEE, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIP_IEEE, 1, 0},
- {INST_RECIPSQRT_CLAMPED, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIPSQRT_CLAMPED, 1, 0},
- {INST_RECIPSQRT_FF, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIPSQRT_FF, 1, 0},
- {INST_RECIPSQRT_IEEE, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIPSQRT_IEEE, 1, 0},
- {INST_SQRT_IEEE, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SQRT_IEEE, 1, 0},
- {INST_FLT_TO_INT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_FLT_TO_INT, 1, 0},
- {INST_INT_TO_FLT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_INT_TO_FLT, 1, 0},
- {INST_UINT_TO_FLT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_UINT_TO_FLT, 1, 0},
- {INST_SIN, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SIN, 1, 0},
- {INST_COS, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_COS, 1, 0},
- {INST_ASHR_INT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_ASHR_INT, 1, 0},
- {INST_LSHR_INT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_LSHR_INT, 1, 0},
- {INST_LSHL_INT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_LSHL_INT, 1, 0},
- {INST_MULLO_INT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MULLO_INT, 1, 0},
- {INST_MULHI_INT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MULHI_INT, 1, 0},
- {INST_MULLO_UINT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MULLO_UINT, 1, 0},
- {INST_MULHI_UINT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MULHI_UINT, 1, 0},
- {INST_RECIP_INT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIP_INT, 1, 0},
- {INST_RECIP_UINT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIP_UINT, 1, 0},
- {INST_FLT_TO_UINT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_FLT_TO_UINT, 1, 0},
- {INST_MUL_LIT, V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_MUL_LIT, 1, 1},
- {INST_MUL_LIT_M2, V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_MUL_LIT_M2, 1, 1},
- {INST_MUL_LIT_M4, V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_MUL_LIT_M4, 1, 1},
- {INST_MUL_LIT_D2, V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_MUL_LIT_D2, 1, 1},
- {INST_MULADD, V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_MULADD, 0, 1},
- {INST_MULADD_M2, V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_MULADD_M2, 0, 1},
- {INST_MULADD_M4, V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_MULADD_M4, 0, 1},
- {INST_MULADD_D2, V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_MULADD_D2, 0, 1},
- {INST_MULADD_IEEE, V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_MULADD_IEEE, 0, 1},
- {INST_MULADD_IEEE_M2, V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_MULADD_IEEE_M2, 0, 1},
- {INST_MULADD_IEEE_M4, V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_MULADD_IEEE_M4, 0, 1},
- {INST_MULADD_IEEE_D2, V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_MULADD_IEEE_D2, 0, 1},
- {INST_CNDE, V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_CNDE, 0, 1},
- {INST_CNDGT, V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_CNDGT, 0, 1},
- {INST_CNDGE, V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_CNDGE, 0, 1},
- {INST_CNDE_INT, V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_CNDE_INT, 0, 1},
- {INST_CNDGT_INT, V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_CNDGT_INT, 0, 1},
- {INST_CNDGE_INT, V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_CNDGE_INT, 0, 1},
-};
-
-struct r600_alu_instruction r600_alu_instruction[C_OPCODE_LAST] = {
- {C_OPCODE_NOP, INST_NOP},
- {C_OPCODE_MOV, INST_MOV},
- {C_OPCODE_LIT, INST_NOP},
- {C_OPCODE_RCP, INST_RECIP_IEEE},
- {C_OPCODE_RSQ, INST_RECIPSQRT_IEEE},
- {C_OPCODE_EXP, INST_EXP_IEEE},
- {C_OPCODE_LOG, INST_LOG_IEEE},
- {C_OPCODE_MUL, INST_MUL},
- {C_OPCODE_ADD, INST_ADD},
- {C_OPCODE_DP3, INST_DOT4},
- {C_OPCODE_DP4, INST_DOT4},
- {C_OPCODE_DST, INST_NOP},
- {C_OPCODE_MIN, INST_MIN},
- {C_OPCODE_MAX, INST_MAX},
- {C_OPCODE_SLT, INST_NOP},
- {C_OPCODE_SGE, INST_NOP},
- {C_OPCODE_MAD, INST_MULADD},
- {C_OPCODE_SUB, INST_COUNT},
- {C_OPCODE_LRP, INST_NOP},
- {C_OPCODE_CND, INST_NOP},
- {20, INST_NOP},
- {C_OPCODE_DP2A, INST_NOP},
- {22, INST_NOP},
- {23, INST_NOP},
- {C_OPCODE_FRC, INST_NOP},
- {C_OPCODE_CLAMP, INST_NOP},
- {C_OPCODE_FLR, INST_NOP},
- {C_OPCODE_ROUND, INST_NOP},
- {C_OPCODE_EX2, INST_NOP},
- {C_OPCODE_LG2, INST_NOP},
- {C_OPCODE_POW, INST_NOP},
- {C_OPCODE_XPD, INST_NOP},
- {32, INST_NOP},
- {C_OPCODE_ABS, INST_COUNT},
- {C_OPCODE_RCC, INST_NOP},
- {C_OPCODE_DPH, INST_NOP},
- {C_OPCODE_COS, INST_COS},
- {C_OPCODE_DDX, INST_NOP},
- {C_OPCODE_DDY, INST_NOP},
- {C_OPCODE_KILP, INST_NOP},
- {C_OPCODE_PK2H, INST_NOP},
- {C_OPCODE_PK2US, INST_NOP},
- {C_OPCODE_PK4B, INST_NOP},
- {C_OPCODE_PK4UB, INST_NOP},
- {C_OPCODE_RFL, INST_NOP},
- {C_OPCODE_SEQ, INST_NOP},
- {C_OPCODE_SFL, INST_NOP},
- {C_OPCODE_SGT, INST_SETGT},
- {C_OPCODE_SIN, INST_SIN},
- {C_OPCODE_SLE, INST_NOP},
- {C_OPCODE_SNE, INST_NOP},
- {C_OPCODE_STR, INST_NOP},
- {C_OPCODE_TEX, INST_NOP},
- {C_OPCODE_TXD, INST_NOP},
- {C_OPCODE_TXP, INST_NOP},
- {C_OPCODE_UP2H, INST_NOP},
- {C_OPCODE_UP2US, INST_NOP},
- {C_OPCODE_UP4B, INST_NOP},
- {C_OPCODE_UP4UB, INST_NOP},
- {C_OPCODE_X2D, INST_NOP},
- {C_OPCODE_ARA, INST_NOP},
- {C_OPCODE_ARR, INST_NOP},
- {C_OPCODE_BRA, INST_NOP},
- {C_OPCODE_CAL, INST_NOP},
- {C_OPCODE_RET, INST_NOP},
- {C_OPCODE_SSG, INST_NOP},
- {C_OPCODE_CMP, INST_NOP},
- {C_OPCODE_SCS, INST_NOP},
- {C_OPCODE_TXB, INST_NOP},
- {C_OPCODE_NRM, INST_NOP},
- {C_OPCODE_DIV, INST_NOP},
- {C_OPCODE_DP2, INST_NOP},
- {C_OPCODE_TXL, INST_NOP},
- {C_OPCODE_BRK, INST_NOP},
- {C_OPCODE_IF, INST_NOP},
- {C_OPCODE_BGNFOR, INST_NOP},
- {C_OPCODE_REP, INST_NOP},
- {C_OPCODE_ELSE, INST_NOP},
- {C_OPCODE_ENDIF, INST_NOP},
- {C_OPCODE_ENDFOR, INST_NOP},
- {C_OPCODE_ENDREP, INST_NOP},
- {C_OPCODE_PUSHA, INST_NOP},
- {C_OPCODE_POPA, INST_NOP},
- {C_OPCODE_CEIL, INST_NOP},
- {C_OPCODE_I2F, INST_NOP},
- {C_OPCODE_NOT, INST_NOP},
- {C_OPCODE_TRUNC, INST_NOP},
- {C_OPCODE_SHL, INST_NOP},
- {88, INST_NOP},
- {C_OPCODE_AND, INST_NOP},
- {C_OPCODE_OR, INST_NOP},
- {C_OPCODE_MOD, INST_NOP},
- {C_OPCODE_XOR, INST_NOP},
- {C_OPCODE_SAD, INST_NOP},
- {C_OPCODE_TXF, INST_NOP},
- {C_OPCODE_TXQ, INST_NOP},
- {C_OPCODE_CONT, INST_NOP},
- {C_OPCODE_EMIT, INST_NOP},
- {C_OPCODE_ENDPRIM, INST_NOP},
- {C_OPCODE_BGNLOOP, INST_NOP},
- {C_OPCODE_BGNSUB, INST_NOP},
- {C_OPCODE_ENDLOOP, INST_NOP},
- {C_OPCODE_ENDSUB, INST_NOP},
- {103, INST_NOP},
- {104, INST_NOP},
- {105, INST_NOP},
- {106, INST_NOP},
- {107, INST_NOP},
- {108, INST_NOP},
- {109, INST_NOP},
- {110, INST_NOP},
- {111, INST_NOP},
- {C_OPCODE_NRM4, INST_NOP},
- {C_OPCODE_CALLNZ, INST_NOP},
- {C_OPCODE_IFC, INST_NOP},
- {C_OPCODE_BREAKC, INST_NOP},
- {C_OPCODE_KIL, INST_NOP},
- {C_OPCODE_END, INST_NOP},
- {118, INST_NOP},
- {C_OPCODE_F2I, INST_NOP},
- {C_OPCODE_IDIV, INST_NOP},
- {C_OPCODE_IMAX, INST_NOP},
- {C_OPCODE_IMIN, INST_NOP},
- {C_OPCODE_INEG, INST_NOP},
- {C_OPCODE_ISGE, INST_NOP},
- {C_OPCODE_ISHR, INST_NOP},
- {C_OPCODE_ISLT, INST_NOP},
- {C_OPCODE_F2U, INST_NOP},
- {C_OPCODE_U2F, INST_NOP},
- {C_OPCODE_UADD, INST_NOP},
- {C_OPCODE_UDIV, INST_NOP},
- {C_OPCODE_UMAD, INST_NOP},
- {C_OPCODE_UMAX, INST_NOP},
- {C_OPCODE_UMIN, INST_NOP},
- {C_OPCODE_UMOD, INST_NOP},
- {C_OPCODE_UMUL, INST_NOP},
- {C_OPCODE_USEQ, INST_NOP},
- {C_OPCODE_USGE, INST_NOP},
- {C_OPCODE_USHR, INST_NOP},
- {C_OPCODE_USLT, INST_NOP},
- {C_OPCODE_USNE, INST_NOP},
- {C_OPCODE_SWITCH, INST_NOP},
- {C_OPCODE_CASE, INST_NOP},
- {C_OPCODE_DEFAULT, INST_NOP},
- {C_OPCODE_ENDSWITCH, INST_NOP},
- {C_OPCODE_VFETCH, INST_NOP},
- {C_OPCODE_ENTRY, INST_NOP},
- {C_OPCODE_ARL, INST_NOP},
-};
-
-
-static int r600_shader_alu_bytecode(struct r600_shader *rshader,
- struct r600_shader_node *rnode,
- struct r600_shader_inst *alu,
- unsigned *cid)
-{
- unsigned id = *cid;
-
- /* don't replace gpr by pv or ps for destination register */
- if (alu->is_op3) {
- rshader->bcode[id++] = S_SQ_ALU_WORD0_SRC0_SEL(alu->src[0].sel) |
- S_SQ_ALU_WORD0_SRC0_CHAN(alu->src[0].chan) |
- S_SQ_ALU_WORD0_SRC1_SEL(alu->src[1].sel) |
- S_SQ_ALU_WORD0_SRC1_CHAN(alu->src[1].chan) |
- S_SQ_ALU_WORD0_LAST(alu->last);
- rshader->bcode[id++] = S_SQ_ALU_WORD1_DST_GPR(alu->dst.sel) |
- S_SQ_ALU_WORD1_DST_CHAN(alu->dst.chan) |
- S_SQ_ALU_WORD1_OP3_SRC2_SEL(alu->src[2].sel) |
- S_SQ_ALU_WORD1_OP3_SRC2_CHAN(alu->src[2].chan) |
- S_SQ_ALU_WORD1_OP3_SRC2_NEG(alu->src[2].neg) |
- S_SQ_ALU_WORD1_OP3_ALU_INST(alu->opcode) |
- S_SQ_ALU_WORD1_BANK_SWIZZLE(0);
- } else {
- rshader->bcode[id++] = S_SQ_ALU_WORD0_SRC0_SEL(alu->src[0].sel) |
- S_SQ_ALU_WORD0_SRC0_CHAN(alu->src[0].chan) |
- S_SQ_ALU_WORD0_SRC0_NEG(alu->src[0].neg) |
- S_SQ_ALU_WORD0_SRC1_SEL(alu->src[1].sel) |
- S_SQ_ALU_WORD0_SRC1_CHAN(alu->src[1].chan) |
- S_SQ_ALU_WORD0_SRC1_NEG(alu->src[1].neg) |
- S_SQ_ALU_WORD0_LAST(alu->last);
- rshader->bcode[id++] = S_SQ_ALU_WORD1_DST_GPR(alu->dst.sel) |
- S_SQ_ALU_WORD1_DST_CHAN(alu->dst.chan) |
- S_SQ_ALU_WORD1_OP2_SRC0_ABS(alu->src[0].abs) |
- S_SQ_ALU_WORD1_OP2_SRC1_ABS(alu->src[1].abs) |
- S_SQ_ALU_WORD1_OP2_WRITE_MASK(1) |
- S_SQ_ALU_WORD1_OP2_ALU_INST(alu->opcode) |
- S_SQ_ALU_WORD1_BANK_SWIZZLE(0);
- }
- *cid = id;
- return 0;
-}
-
-int r6xx_shader_alu_translate(struct r600_shader *rshader,
- struct r600_shader_node *rnode,
- unsigned *cid)
-{
- struct r600_shader_alu *alu;
- unsigned id = *cid;
- int i;
- int r = 0;
- LIST_FOR_EACH_ENTRY(alu, &rnode->alu, head) {
- for (i = 0; i < alu->nalu; i++) {
- r = r600_shader_alu_bytecode(rshader, rnode, &alu->alu[i], &id);
- if (r)
- goto out;
- }
- for (i = 0; i < alu->nliteral; i++) {
- rshader->bcode[id++] = alu->literal[i];
- }
- }
-out:
- *cid = id;
- return r;
-}
diff --git a/src/gallium/drivers/r600/r600_compiler_r700.c b/src/gallium/drivers/r600/r600_compiler_r700.c
deleted file mode 100644
index 0b43942866..0000000000
--- a/src/gallium/drivers/r600/r600_compiler_r700.c
+++ /dev/null
@@ -1,233 +0,0 @@
-/*
- * Copyright 2010 Jerome Glisse <glisse@freedesktop.org>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * on the rights to use, copy, modify, merge, publish, distribute, sub
- * license, and/or sell copies of the Software, and to permit persons to whom
- * the Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
- * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
- * USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-#include <stdlib.h>
-#include <string.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <errno.h>
-#include "r600_context.h"
-#include "r700_sq.h"
-
-static int r700_shader_cf_node_bytecode(struct r600_shader *rshader,
- struct r600_shader_node *rnode,
- unsigned *cid)
-{
- unsigned id = *cid;
-
- if (rnode->nfetch) {
- rshader->bcode[id++] = S_SQ_CF_WORD0_ADDR(rnode->cf_addr >> 1);
- rshader->bcode[id++] = S_SQ_CF_WORD1_CF_INST(V_SQ_CF_WORD1_SQ_CF_INST_VTX) |
- S_SQ_CF_WORD1_BARRIER(1) |
- S_SQ_CF_WORD1_COUNT(rnode->nfetch - 1);
- } else {
- rshader->bcode[id++] = S_SQ_CF_ALU_WORD0_ADDR(rnode->cf_addr >> 1);
- rshader->bcode[id++] = S_SQ_CF_ALU_WORD1_CF_INST(V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU) |
- S_SQ_CF_ALU_WORD1_BARRIER(1) |
- S_SQ_CF_ALU_WORD1_COUNT(rnode->nslot - 1);
- }
- *cid = id;
- return 0;
-}
-
-static int r700_shader_cf_output_bytecode(struct r600_shader *rshader,
- struct c_vector *v,
- unsigned *cid,
- unsigned end)
-{
- struct r600_shader_operand out;
- unsigned id = *cid;
- int r;
-
- r = r600_shader_find_gpr(rshader, v, 0, &out);
- if (r)
- return r;
- rshader->bcode[id + 0] = S_SQ_CF_ALLOC_EXPORT_WORD0_RW_GPR(out.sel) |
- S_SQ_CF_ALLOC_EXPORT_WORD0_ELEM_SIZE(3);
- rshader->bcode[id + 1] = S_SQ_CF_ALLOC_EXPORT_WORD1_SWIZ_SEL_X(0) |
- S_SQ_CF_ALLOC_EXPORT_WORD1_SWIZ_SEL_Y(1) |
- S_SQ_CF_ALLOC_EXPORT_WORD1_SWIZ_SEL_Z(2) |
- S_SQ_CF_ALLOC_EXPORT_WORD1_SWIZ_SEL_W(3) |
- S_SQ_CF_ALLOC_EXPORT_WORD1_BARRIER(1) |
- S_SQ_CF_ALLOC_EXPORT_WORD1_CF_INST(V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT_DONE) |
- S_SQ_CF_ALLOC_EXPORT_WORD1_END_OF_PROGRAM(end);
- switch (v->name) {
- case C_SEMANTIC_POSITION:
- rshader->bcode[id + 0] |= S_SQ_CF_ALLOC_EXPORT_WORD0_ARRAY_BASE(60) |
- S_SQ_CF_ALLOC_EXPORT_WORD0_TYPE(V_SQ_CF_ALLOC_EXPORT_WORD0_SQ_EXPORT_POS);
- break;
- case C_SEMANTIC_COLOR:
- if (rshader->cshader.type == C_PROGRAM_TYPE_VS) {
- rshader->output[rshader->noutput].gpr = out.sel;
- rshader->output[rshader->noutput].sid = v->sid;
- rshader->output[rshader->noutput].name = v->name;
- rshader->bcode[id + 0] |= S_SQ_CF_ALLOC_EXPORT_WORD0_ARRAY_BASE(rshader->noutput++) |
- S_SQ_CF_ALLOC_EXPORT_WORD0_TYPE(V_SQ_CF_ALLOC_EXPORT_WORD0_SQ_EXPORT_PARAM);
- } else {
- rshader->bcode[id + 0] |= S_SQ_CF_ALLOC_EXPORT_WORD0_ARRAY_BASE(0) |
- S_SQ_CF_ALLOC_EXPORT_WORD0_TYPE(V_SQ_CF_ALLOC_EXPORT_WORD0_SQ_EXPORT_PIXEL);
- }
- break;
- case C_SEMANTIC_GENERIC:
- rshader->output[rshader->noutput].gpr = out.sel;
- rshader->output[rshader->noutput].sid = v->sid;
- rshader->output[rshader->noutput].name = v->name;
- rshader->bcode[id + 0] |= S_SQ_CF_ALLOC_EXPORT_WORD0_ARRAY_BASE(rshader->noutput++) |
- S_SQ_CF_ALLOC_EXPORT_WORD0_TYPE(V_SQ_CF_ALLOC_EXPORT_WORD0_SQ_EXPORT_PARAM);
- break;
- default:
- fprintf(stderr, "%s:%d unsupported\n", __func__, __LINE__);
- return -EINVAL;
- }
- *cid = id + 2;
- return 0;
-}
-
-static int r700_shader_alu_bytecode(struct r600_shader *rshader,
- struct r600_shader_node *rnode,
- struct r600_shader_inst *alu,
- unsigned *cid)
-{
- unsigned id = *cid;
-
- /* don't replace gpr by pv or ps for destination register */
- if (alu->is_op3) {
- rshader->bcode[id++] = S_SQ_ALU_WORD0_SRC0_SEL(alu->src[0].sel) |
- S_SQ_ALU_WORD0_SRC0_CHAN(alu->src[0].chan) |
- S_SQ_ALU_WORD0_SRC1_SEL(alu->src[1].sel) |
- S_SQ_ALU_WORD0_SRC1_CHAN(alu->src[1].chan) |
- S_SQ_ALU_WORD0_LAST(alu->last);
- rshader->bcode[id++] = S_SQ_ALU_WORD1_DST_GPR(alu->dst.sel) |
- S_SQ_ALU_WORD1_DST_CHAN(alu->dst.chan) |
- S_SQ_ALU_WORD1_OP3_SRC2_SEL(alu->src[2].sel) |
- S_SQ_ALU_WORD1_OP3_SRC2_CHAN(alu->src[2].chan) |
- S_SQ_ALU_WORD1_OP3_SRC2_NEG(alu->src[2].neg) |
- S_SQ_ALU_WORD1_OP3_ALU_INST(alu->opcode) |
- S_SQ_ALU_WORD1_BANK_SWIZZLE(0);
- } else {
- rshader->bcode[id++] = S_SQ_ALU_WORD0_SRC0_SEL(alu->src[0].sel) |
- S_SQ_ALU_WORD0_SRC0_CHAN(alu->src[0].chan) |
- S_SQ_ALU_WORD0_SRC0_NEG(alu->src[0].neg) |
- S_SQ_ALU_WORD0_SRC1_SEL(alu->src[1].sel) |
- S_SQ_ALU_WORD0_SRC1_CHAN(alu->src[1].chan) |
- S_SQ_ALU_WORD0_SRC1_NEG(alu->src[1].neg) |
- S_SQ_ALU_WORD0_LAST(alu->last);
- rshader->bcode[id++] = S_SQ_ALU_WORD1_DST_GPR(alu->dst.sel) |
- S_SQ_ALU_WORD1_DST_CHAN(alu->dst.chan) |
- S_SQ_ALU_WORD1_OP2_SRC0_ABS(alu->src[0].abs) |
- S_SQ_ALU_WORD1_OP2_SRC1_ABS(alu->src[1].abs) |
- S_SQ_ALU_WORD1_OP2_WRITE_MASK(1) |
- S_SQ_ALU_WORD1_OP2_ALU_INST(alu->opcode) |
- S_SQ_ALU_WORD1_BANK_SWIZZLE(0);
- }
- *cid = id;
- return 0;
-}
-
-static int r700_shader_alu_translate(struct r600_shader *rshader,
- struct r600_shader_node *rnode,
- unsigned *cid)
-
-{
- struct r600_shader_alu *alu;
- unsigned id = *cid;
- int i;
- int r = 0;
- LIST_FOR_EACH_ENTRY(alu, &rnode->alu, head) {
- for (i = 0; i < alu->nalu; i++) {
- r = r700_shader_alu_bytecode(rshader, rnode, &alu->alu[i], &id);
- if (r)
- goto out;
- }
- for (i = 0; i < alu->nliteral; i++) {
- rshader->bcode[id++] = alu->literal[i];
- }
- }
- out:
- *cid = id;
- return r;
-}
-
-int r700_shader_translate(struct r600_shader *rshader)
-{
- struct c_shader *shader = &rshader->cshader;
- struct r600_shader_node *rnode;
- struct r600_shader_vfetch *vfetch;
- struct c_vector *v;
- unsigned id, end;
- int r;
-
- r = r600_shader_register(rshader);
- if (r) {
- fprintf(stderr, "%s %d register allocation failed\n", __FILE__, __LINE__);
- return r;
- }
- r = r600_shader_translate_rec(rshader, &shader->entry);
- if (r) {
- fprintf(stderr, "%s %d translation failed\n", __FILE__, __LINE__);
- return r;
- }
- r = r600_shader_legalize(rshader);
- if (r) {
- fprintf(stderr, "%s %d legalize failed\n", __FILE__, __LINE__);
- return r;
- }
- r600_shader_node_place(rshader);
- rshader->bcode = malloc(rshader->ndw * 4);
- if (rshader->bcode == NULL)
- return -ENOMEM;
- LIST_FOR_EACH_ENTRY(rnode, &rshader->nodes, head) {
- id = rnode->cf_addr;
- LIST_FOR_EACH_ENTRY(vfetch, &rnode->vfetch, head) {
- r = r600_shader_vfetch_bytecode(rshader, rnode, vfetch, &id);
- if (r)
- return r;
- }
- if (rshader->r6xx_compile)
- r = r6xx_shader_alu_translate(rshader, rnode, &id);
- else
- r = r700_shader_alu_translate(rshader, rnode, &id);
- if (r)
- return r;
- }
- id = 0;
- LIST_FOR_EACH_ENTRY(rnode, &rshader->nodes, head) {
- r = r700_shader_cf_node_bytecode(rshader, rnode, &id);
- if (r)
- return r;
- }
- LIST_FOR_EACH_ENTRY(v, &rshader->cshader.files[C_FILE_OUTPUT].vectors, head) {
- end = 0;
- if (v->head.next == &rshader->cshader.files[C_FILE_OUTPUT].vectors)
- end = 1;
- r = r700_shader_cf_output_bytecode(rshader, v, &id, end);
- if (r)
- return r;
- }
- LIST_FOR_EACH_ENTRY(v, &rshader->cshader.files[C_FILE_INPUT].vectors, head) {
- rshader->input[rshader->ninput].gpr = rshader->ninput;
- rshader->input[rshader->ninput].sid = v->sid;
- rshader->input[rshader->ninput].name = v->name;
- rshader->ninput++;
- }
- return 0;
-}
diff --git a/src/gallium/drivers/r600/r600_compiler_tgsi.c b/src/gallium/drivers/r600/r600_compiler_tgsi.c
deleted file mode 100644
index 172cf154a3..0000000000
--- a/src/gallium/drivers/r600/r600_compiler_tgsi.c
+++ /dev/null
@@ -1,730 +0,0 @@
-/*
- * Copyright 2010 Jerome Glisse <glisse@freedesktop.org>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * on the rights to use, copy, modify, merge, publish, distribute, sub
- * license, and/or sell copies of the Software, and to permit persons to whom
- * the Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
- * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
- * USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-#include <stdlib.h>
-#include <string.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <errno.h>
-#include <tgsi/tgsi_parse.h>
-#include <tgsi/tgsi_scan.h>
-#include "r600_shader.h"
-#include "r600_context.h"
-
-struct tgsi_shader {
- struct c_vector **v[TGSI_FILE_COUNT];
- struct tgsi_shader_info info;
- struct tgsi_parse_context parser;
- const struct tgsi_token *tokens;
- struct c_shader *shader;
- struct c_node *node;
-};
-
-static unsigned tgsi_file_to_c_file(unsigned file);
-static unsigned tgsi_sname_to_c_sname(unsigned sname);
-static int tgsi_opcode_to_c_opcode(unsigned opcode, unsigned *copcode);
-
-static int tgsi_shader_init(struct tgsi_shader *ts,
- const struct tgsi_token *tokens,
- struct c_shader *shader)
-{
- int i;
-
- ts->shader = shader;
- ts->tokens = tokens;
- tgsi_scan_shader(ts->tokens, &ts->info);
- tgsi_parse_init(&ts->parser, ts->tokens);
- /* initialize to NULL in case of error */
- for (i = 0; i < C_FILE_COUNT; i++) {
- ts->v[i] = NULL;
- }
- for (i = 0; i < TGSI_FILE_COUNT; i++) {
- if (ts->info.file_count[i] > 0) {
- ts->v[i] = calloc(ts->info.file_count[i], sizeof(void*));
- if (ts->v[i] == NULL) {
- fprintf(stderr, "%s:%d unsupported %d %d\n", __func__, __LINE__, i, ts->info.file_count[i]);
- return -ENOMEM;
- }
- }
- }
- return 0;
-}
-
-static void tgsi_shader_destroy(struct tgsi_shader *ts)
-{
- int i;
-
- for (i = 0; i < TGSI_FILE_COUNT; i++) {
- free(ts->v[i]);
- }
- tgsi_parse_free(&ts->parser);
-}
-
-static int ntransform_declaration(struct tgsi_shader *ts)
-{
- struct tgsi_full_declaration *fd = &ts->parser.FullToken.FullDeclaration;
- struct c_vector *v;
- unsigned file;
- unsigned name;
- int sid;
- int i;
-
- if (fd->Declaration.Dimension) {
- fprintf(stderr, "%s:%d unsupported\n", __func__, __LINE__);
- return -EINVAL;
- }
- for (i = fd->Range.First ; i <= fd->Range.Last; i++) {
- sid = i;
- name = C_SEMANTIC_GENERIC;
- file = tgsi_file_to_c_file(fd->Declaration.File);
- if (file == TGSI_FILE_NULL) {
- fprintf(stderr, "%s:%d unsupported\n", __func__, __LINE__);
- return -EINVAL;
- }
- if (fd->Declaration.Semantic) {
- name = tgsi_sname_to_c_sname(fd->Semantic.Name);
- sid = fd->Semantic.Index;
- }
- v = c_shader_vector_new(ts->shader, file, name, sid);
- if (v == NULL) {
- fprintf(stderr, "%s:%d unsupported\n", __func__, __LINE__);
- return -ENOMEM;
- }
- ts->v[fd->Declaration.File][i] = v;
- }
- return 0;
-}
-
-static int ntransform_immediate(struct tgsi_shader *ts)
-{
- struct tgsi_full_immediate *fd = &ts->parser.FullToken.FullImmediate;
- struct c_vector *v;
- unsigned file;
- unsigned name;
-
- if (fd->Immediate.DataType != TGSI_IMM_FLOAT32) {
- fprintf(stderr, "%s:%d unsupported\n", __func__, __LINE__);
- return -EINVAL;
- }
- name = C_SEMANTIC_GENERIC;
- file = C_FILE_IMMEDIATE;
- v = c_shader_vector_new(ts->shader, file, name, 0);
- if (v == NULL) {
- fprintf(stderr, "%s:%d unsupported\n", __func__, __LINE__);
- return -ENOMEM;
- }
- v->channel[0]->value = fd->u[0].Uint;
- v->channel[1]->value = fd->u[1].Uint;
- v->channel[2]->value = fd->u[2].Uint;
- v->channel[3]->value = fd->u[3].Uint;
- ts->v[TGSI_FILE_IMMEDIATE][0] = v;
- return 0;
-}
-
-static int ntransform_instruction(struct tgsi_shader *ts)
-{
- struct tgsi_full_instruction *fi = &ts->parser.FullToken.FullInstruction;
- struct c_shader *shader = ts->shader;
- struct c_instruction instruction;
- unsigned opcode;
- int i, j, r;
-
- if (fi->Instruction.NumDstRegs > 1) {
- fprintf(stderr, "%s %d unsupported\n", __func__, __LINE__);
- return -EINVAL;
- }
- if (fi->Instruction.Saturate) {
- fprintf(stderr, "%s %d unsupported\n", __func__, __LINE__);
- return -EINVAL;
- }
- if (fi->Instruction.Predicate) {
- fprintf(stderr, "%s %d unsupported\n", __func__, __LINE__);
- return -EINVAL;
- }
- if (fi->Instruction.Label) {
- fprintf(stderr, "%s %d unsupported\n", __func__, __LINE__);
- return -EINVAL;
- }
- if (fi->Instruction.Texture) {
- fprintf(stderr, "%s %d unsupported\n", __func__, __LINE__);
- return -EINVAL;
- }
- for (i = 0; i < fi->Instruction.NumSrcRegs; i++) {
- if (fi->Src[i].Register.Indirect ||
- fi->Src[i].Register.Dimension ||
- fi->Src[i].Register.Absolute) {
- fprintf(stderr, "%s %d unsupported\n", __func__, __LINE__);
- return -EINVAL;
- }
- }
- for (i = 0; i < fi->Instruction.NumDstRegs; i++) {
- if (fi->Dst[i].Register.Indirect || fi->Dst[i].Register.Dimension) {
- fprintf(stderr, "%s %d unsupported\n", __func__, __LINE__);
- return -EINVAL;
- }
- }
- r = tgsi_opcode_to_c_opcode(fi->Instruction.Opcode, &opcode);
- if (r) {
- fprintf(stderr, "%s:%d unsupported\n", __func__, __LINE__);
- return r;
- }
- if (opcode == C_OPCODE_END) {
- return c_node_cfg_link(ts->node, &shader->end);
- }
- /* FIXME add flow instruction handling */
- memset(&instruction, 0, sizeof(struct c_instruction));
- instruction.nop = 0;
- for (j = 0; j < 4; j++) {
- instruction.op[instruction.nop].opcode = opcode;
- instruction.op[instruction.nop].ninput = fi->Instruction.NumSrcRegs;
- for (i = 0; i < fi->Instruction.NumSrcRegs; i++) {
- instruction.op[instruction.nop].input[i].vector = ts->v[fi->Src[i].Register.File][fi->Src[i].Register.Index];
- switch (j) {
- case 0:
- instruction.op[instruction.nop].input[i].swizzle = fi->Src[i].Register.SwizzleX;
- break;
- case 1:
- instruction.op[instruction.nop].input[i].swizzle = fi->Src[i].Register.SwizzleY;
- break;
- case 2:
- instruction.op[instruction.nop].input[i].swizzle = fi->Src[i].Register.SwizzleZ;
- break;
- case 3:
- instruction.op[instruction.nop].input[i].swizzle = fi->Src[i].Register.SwizzleW;
- break;
- default:
- return -EINVAL;
- }
- }
- instruction.op[instruction.nop].output.vector = ts->v[fi->Dst[0].Register.File][fi->Dst[0].Register.Index];
- switch (j) {
- case 0:
- instruction.op[instruction.nop].output.swizzle = (fi->Dst[0].Register.WriteMask & 0x1) ? C_SWIZZLE_X : C_SWIZZLE_D;
- break;
- case 1:
- instruction.op[instruction.nop].output.swizzle = (fi->Dst[0].Register.WriteMask & 0x1) ? C_SWIZZLE_Y : C_SWIZZLE_D;
- break;
- case 2:
- instruction.op[instruction.nop].output.swizzle = (fi->Dst[0].Register.WriteMask & 0x1) ? C_SWIZZLE_Z : C_SWIZZLE_D;
- break;
- case 3:
- instruction.op[instruction.nop].output.swizzle = (fi->Dst[0].Register.WriteMask & 0x1) ? C_SWIZZLE_W : C_SWIZZLE_D;
- break;
- default:
- return -EINVAL;
- }
- instruction.nop++;
- }
- return c_node_add_new_instruction(ts->node, &instruction);
-}
-
-int c_shader_from_tgsi(struct c_shader *shader, unsigned type,
- const struct tgsi_token *tokens)
-{
- struct tgsi_shader ts;
- int r = 0;
-
- c_shader_init(shader, type);
- r = tgsi_shader_init(&ts, tokens, shader);
- if (r)
- goto out_err;
- ts.shader = shader;
- ts.node = &shader->entry;
- while (!tgsi_parse_end_of_tokens(&ts.parser)) {
- tgsi_parse_token(&ts.parser);
- switch (ts.parser.FullToken.Token.Type) {
- case TGSI_TOKEN_TYPE_IMMEDIATE:
- r = ntransform_immediate(&ts);
- if (r)
- goto out_err;
- break;
- case TGSI_TOKEN_TYPE_DECLARATION:
- r = ntransform_declaration(&ts);
- if (r)
- goto out_err;
- break;
- case TGSI_TOKEN_TYPE_INSTRUCTION:
- r = ntransform_instruction(&ts);
- if (r)
- goto out_err;
- break;
- default:
- r = -EINVAL;
- goto out_err;
- }
- }
- tgsi_shader_destroy(&ts);
- return 0;
-out_err:
- c_shader_destroy(shader);
- tgsi_shader_destroy(&ts);
- return r;
-}
-
-static unsigned tgsi_file_to_c_file(unsigned file)
-{
- switch (file) {
- case TGSI_FILE_CONSTANT:
- return C_FILE_CONSTANT;
- case TGSI_FILE_INPUT:
- return C_FILE_INPUT;
- case TGSI_FILE_OUTPUT:
- return C_FILE_OUTPUT;
- case TGSI_FILE_TEMPORARY:
- return C_FILE_TEMPORARY;
- case TGSI_FILE_SAMPLER:
- return C_FILE_SAMPLER;
- case TGSI_FILE_ADDRESS:
- return C_FILE_ADDRESS;
- case TGSI_FILE_IMMEDIATE:
- return C_FILE_IMMEDIATE;
- case TGSI_FILE_PREDICATE:
- return C_FILE_PREDICATE;
- case TGSI_FILE_SYSTEM_VALUE:
- return C_FILE_SYSTEM_VALUE;
- case TGSI_FILE_NULL:
- return C_FILE_NULL;
- default:
- fprintf(stderr, "%s:%d unsupported file %d\n", __func__, __LINE__, file);
- return C_FILE_NULL;
- }
-}
-
-static unsigned tgsi_sname_to_c_sname(unsigned sname)
-{
- switch (sname) {
- case TGSI_SEMANTIC_POSITION:
- return C_SEMANTIC_POSITION;
- case TGSI_SEMANTIC_COLOR:
- return C_SEMANTIC_COLOR;
- case TGSI_SEMANTIC_BCOLOR:
- return C_SEMANTIC_BCOLOR;
- case TGSI_SEMANTIC_FOG:
- return C_SEMANTIC_FOG;
- case TGSI_SEMANTIC_PSIZE:
- return C_SEMANTIC_PSIZE;
- case TGSI_SEMANTIC_GENERIC:
- return C_SEMANTIC_GENERIC;
- case TGSI_SEMANTIC_NORMAL:
- return C_SEMANTIC_NORMAL;
- case TGSI_SEMANTIC_FACE:
- return C_SEMANTIC_FACE;
- case TGSI_SEMANTIC_EDGEFLAG:
- return C_SEMANTIC_EDGEFLAG;
- case TGSI_SEMANTIC_PRIMID:
- return C_SEMANTIC_PRIMID;
- case TGSI_SEMANTIC_INSTANCEID:
- return C_SEMANTIC_INSTANCEID;
- default:
- return C_SEMANTIC_GENERIC;
- }
-}
-
-static int tgsi_opcode_to_c_opcode(unsigned opcode, unsigned *copcode)
-{
- switch (opcode) {
- case TGSI_OPCODE_MOV:
- *copcode = C_OPCODE_MOV;
- return 0;
- case TGSI_OPCODE_MUL:
- *copcode = C_OPCODE_MUL;
- return 0;
- case TGSI_OPCODE_MAD:
- *copcode = C_OPCODE_MAD;
- return 0;
- case TGSI_OPCODE_END:
- *copcode = C_OPCODE_END;
- return 0;
- case TGSI_OPCODE_ARL:
- *copcode = C_OPCODE_ARL;
- return 0;
- case TGSI_OPCODE_LIT:
- *copcode = C_OPCODE_LIT;
- return 0;
- case TGSI_OPCODE_RCP:
- *copcode = C_OPCODE_RCP;
- return 0;
- case TGSI_OPCODE_RSQ:
- *copcode = C_OPCODE_RSQ;
- return 0;
- case TGSI_OPCODE_EXP:
- *copcode = C_OPCODE_EXP;
- return 0;
- case TGSI_OPCODE_LOG:
- *copcode = C_OPCODE_LOG;
- return 0;
- case TGSI_OPCODE_ADD:
- *copcode = C_OPCODE_ADD;
- return 0;
- case TGSI_OPCODE_DP3:
- *copcode = C_OPCODE_DP3;
- return 0;
- case TGSI_OPCODE_DP4:
- *copcode = C_OPCODE_DP4;
- return 0;
- case TGSI_OPCODE_DST:
- *copcode = C_OPCODE_DST;
- return 0;
- case TGSI_OPCODE_MIN:
- *copcode = C_OPCODE_MIN;
- return 0;
- case TGSI_OPCODE_MAX:
- *copcode = C_OPCODE_MAX;
- return 0;
- case TGSI_OPCODE_SLT:
- *copcode = C_OPCODE_SLT;
- return 0;
- case TGSI_OPCODE_SGE:
- *copcode = C_OPCODE_SGE;
- return 0;
- case TGSI_OPCODE_SUB:
- *copcode = C_OPCODE_SUB;
- return 0;
- case TGSI_OPCODE_LRP:
- *copcode = C_OPCODE_LRP;
- return 0;
- case TGSI_OPCODE_CND:
- *copcode = C_OPCODE_CND;
- return 0;
- case TGSI_OPCODE_DP2A:
- *copcode = C_OPCODE_DP2A;
- return 0;
- case TGSI_OPCODE_FRC:
- *copcode = C_OPCODE_FRC;
- return 0;
- case TGSI_OPCODE_CLAMP:
- *copcode = C_OPCODE_CLAMP;
- return 0;
- case TGSI_OPCODE_FLR:
- *copcode = C_OPCODE_FLR;
- return 0;
- case TGSI_OPCODE_ROUND:
- *copcode = C_OPCODE_ROUND;
- return 0;
- case TGSI_OPCODE_EX2:
- *copcode = C_OPCODE_EX2;
- return 0;
- case TGSI_OPCODE_LG2:
- *copcode = C_OPCODE_LG2;
- return 0;
- case TGSI_OPCODE_POW:
- *copcode = C_OPCODE_POW;
- return 0;
- case TGSI_OPCODE_XPD:
- *copcode = C_OPCODE_XPD;
- return 0;
- case TGSI_OPCODE_ABS:
- *copcode = C_OPCODE_ABS;
- return 0;
- case TGSI_OPCODE_RCC:
- *copcode = C_OPCODE_RCC;
- return 0;
- case TGSI_OPCODE_DPH:
- *copcode = C_OPCODE_DPH;
- return 0;
- case TGSI_OPCODE_COS:
- *copcode = C_OPCODE_COS;
- return 0;
- case TGSI_OPCODE_DDX:
- *copcode = C_OPCODE_DDX;
- return 0;
- case TGSI_OPCODE_DDY:
- *copcode = C_OPCODE_DDY;
- return 0;
- case TGSI_OPCODE_KILP:
- *copcode = C_OPCODE_KILP;
- return 0;
- case TGSI_OPCODE_PK2H:
- *copcode = C_OPCODE_PK2H;
- return 0;
- case TGSI_OPCODE_PK2US:
- *copcode = C_OPCODE_PK2US;
- return 0;
- case TGSI_OPCODE_PK4B:
- *copcode = C_OPCODE_PK4B;
- return 0;
- case TGSI_OPCODE_PK4UB:
- *copcode = C_OPCODE_PK4UB;
- return 0;
- case TGSI_OPCODE_RFL:
- *copcode = C_OPCODE_RFL;
- return 0;
- case TGSI_OPCODE_SEQ:
- *copcode = C_OPCODE_SEQ;
- return 0;
- case TGSI_OPCODE_SFL:
- *copcode = C_OPCODE_SFL;
- return 0;
- case TGSI_OPCODE_SGT:
- *copcode = C_OPCODE_SGT;
- return 0;
- case TGSI_OPCODE_SIN:
- *copcode = C_OPCODE_SIN;
- return 0;
- case TGSI_OPCODE_SLE:
- *copcode = C_OPCODE_SLE;
- return 0;
- case TGSI_OPCODE_SNE:
- *copcode = C_OPCODE_SNE;
- return 0;
- case TGSI_OPCODE_STR:
- *copcode = C_OPCODE_STR;
- return 0;
- case TGSI_OPCODE_TEX:
- *copcode = C_OPCODE_TEX;
- return 0;
- case TGSI_OPCODE_TXD:
- *copcode = C_OPCODE_TXD;
- return 0;
- case TGSI_OPCODE_TXP:
- *copcode = C_OPCODE_TXP;
- return 0;
- case TGSI_OPCODE_UP2H:
- *copcode = C_OPCODE_UP2H;
- return 0;
- case TGSI_OPCODE_UP2US:
- *copcode = C_OPCODE_UP2US;
- return 0;
- case TGSI_OPCODE_UP4B:
- *copcode = C_OPCODE_UP4B;
- return 0;
- case TGSI_OPCODE_UP4UB:
- *copcode = C_OPCODE_UP4UB;
- return 0;
- case TGSI_OPCODE_X2D:
- *copcode = C_OPCODE_X2D;
- return 0;
- case TGSI_OPCODE_ARA:
- *copcode = C_OPCODE_ARA;
- return 0;
- case TGSI_OPCODE_ARR:
- *copcode = C_OPCODE_ARR;
- return 0;
- case TGSI_OPCODE_BRA:
- *copcode = C_OPCODE_BRA;
- return 0;
- case TGSI_OPCODE_CAL:
- *copcode = C_OPCODE_CAL;
- return 0;
- case TGSI_OPCODE_RET:
- *copcode = C_OPCODE_RET;
- return 0;
- case TGSI_OPCODE_SSG:
- *copcode = C_OPCODE_SSG;
- return 0;
- case TGSI_OPCODE_CMP:
- *copcode = C_OPCODE_CMP;
- return 0;
- case TGSI_OPCODE_SCS:
- *copcode = C_OPCODE_SCS;
- return 0;
- case TGSI_OPCODE_TXB:
- *copcode = C_OPCODE_TXB;
- return 0;
- case TGSI_OPCODE_NRM:
- *copcode = C_OPCODE_NRM;
- return 0;
- case TGSI_OPCODE_DIV:
- *copcode = C_OPCODE_DIV;
- return 0;
- case TGSI_OPCODE_DP2:
- *copcode = C_OPCODE_DP2;
- return 0;
- case TGSI_OPCODE_TXL:
- *copcode = C_OPCODE_TXL;
- return 0;
- case TGSI_OPCODE_BRK:
- *copcode = C_OPCODE_BRK;
- return 0;
- case TGSI_OPCODE_IF:
- *copcode = C_OPCODE_IF;
- return 0;
- case TGSI_OPCODE_ELSE:
- *copcode = C_OPCODE_ELSE;
- return 0;
- case TGSI_OPCODE_ENDIF:
- *copcode = C_OPCODE_ENDIF;
- return 0;
- case TGSI_OPCODE_PUSHA:
- *copcode = C_OPCODE_PUSHA;
- return 0;
- case TGSI_OPCODE_POPA:
- *copcode = C_OPCODE_POPA;
- return 0;
- case TGSI_OPCODE_CEIL:
- *copcode = C_OPCODE_CEIL;
- return 0;
- case TGSI_OPCODE_I2F:
- *copcode = C_OPCODE_I2F;
- return 0;
- case TGSI_OPCODE_NOT:
- *copcode = C_OPCODE_NOT;
- return 0;
- case TGSI_OPCODE_TRUNC:
- *copcode = C_OPCODE_TRUNC;
- return 0;
- case TGSI_OPCODE_SHL:
- *copcode = C_OPCODE_SHL;
- return 0;
- case TGSI_OPCODE_AND:
- *copcode = C_OPCODE_AND;
- return 0;
- case TGSI_OPCODE_OR:
- *copcode = C_OPCODE_OR;
- return 0;
- case TGSI_OPCODE_MOD:
- *copcode = C_OPCODE_MOD;
- return 0;
- case TGSI_OPCODE_XOR:
- *copcode = C_OPCODE_XOR;
- return 0;
- case TGSI_OPCODE_SAD:
- *copcode = C_OPCODE_SAD;
- return 0;
- case TGSI_OPCODE_TXF:
- *copcode = C_OPCODE_TXF;
- return 0;
- case TGSI_OPCODE_TXQ:
- *copcode = C_OPCODE_TXQ;
- return 0;
- case TGSI_OPCODE_CONT:
- *copcode = C_OPCODE_CONT;
- return 0;
- case TGSI_OPCODE_EMIT:
- *copcode = C_OPCODE_EMIT;
- return 0;
- case TGSI_OPCODE_ENDPRIM:
- *copcode = C_OPCODE_ENDPRIM;
- return 0;
- case TGSI_OPCODE_BGNLOOP:
- *copcode = C_OPCODE_BGNLOOP;
- return 0;
- case TGSI_OPCODE_BGNSUB:
- *copcode = C_OPCODE_BGNSUB;
- return 0;
- case TGSI_OPCODE_ENDLOOP:
- *copcode = C_OPCODE_ENDLOOP;
- return 0;
- case TGSI_OPCODE_ENDSUB:
- *copcode = C_OPCODE_ENDSUB;
- return 0;
- case TGSI_OPCODE_NOP:
- *copcode = C_OPCODE_NOP;
- return 0;
- case TGSI_OPCODE_NRM4:
- *copcode = C_OPCODE_NRM4;
- return 0;
- case TGSI_OPCODE_CALLNZ:
- *copcode = C_OPCODE_CALLNZ;
- return 0;
- case TGSI_OPCODE_IFC:
- *copcode = C_OPCODE_IFC;
- return 0;
- case TGSI_OPCODE_BREAKC:
- *copcode = C_OPCODE_BREAKC;
- return 0;
- case TGSI_OPCODE_KIL:
- *copcode = C_OPCODE_KIL;
- return 0;
- case TGSI_OPCODE_F2I:
- *copcode = C_OPCODE_F2I;
- return 0;
- case TGSI_OPCODE_IDIV:
- *copcode = C_OPCODE_IDIV;
- return 0;
- case TGSI_OPCODE_IMAX:
- *copcode = C_OPCODE_IMAX;
- return 0;
- case TGSI_OPCODE_IMIN:
- *copcode = C_OPCODE_IMIN;
- return 0;
- case TGSI_OPCODE_INEG:
- *copcode = C_OPCODE_INEG;
- return 0;
- case TGSI_OPCODE_ISGE:
- *copcode = C_OPCODE_ISGE;
- return 0;
- case TGSI_OPCODE_ISHR:
- *copcode = C_OPCODE_ISHR;
- return 0;
- case TGSI_OPCODE_ISLT:
- *copcode = C_OPCODE_ISLT;
- return 0;
- case TGSI_OPCODE_F2U:
- *copcode = C_OPCODE_F2U;
- return 0;
- case TGSI_OPCODE_U2F:
- *copcode = C_OPCODE_U2F;
- return 0;
- case TGSI_OPCODE_UADD:
- *copcode = C_OPCODE_UADD;
- return 0;
- case TGSI_OPCODE_UDIV:
- *copcode = C_OPCODE_UDIV;
- return 0;
- case TGSI_OPCODE_UMAD:
- *copcode = C_OPCODE_UMAD;
- return 0;
- case TGSI_OPCODE_UMAX:
- *copcode = C_OPCODE_UMAX;
- return 0;
- case TGSI_OPCODE_UMIN:
- *copcode = C_OPCODE_UMIN;
- return 0;
- case TGSI_OPCODE_UMOD:
- *copcode = C_OPCODE_UMOD;
- return 0;
- case TGSI_OPCODE_UMUL:
- *copcode = C_OPCODE_UMUL;
- return 0;
- case TGSI_OPCODE_USEQ:
- *copcode = C_OPCODE_USEQ;
- return 0;
- case TGSI_OPCODE_USGE:
- *copcode = C_OPCODE_USGE;
- return 0;
- case TGSI_OPCODE_USHR:
- *copcode = C_OPCODE_USHR;
- return 0;
- case TGSI_OPCODE_USLT:
- *copcode = C_OPCODE_USLT;
- return 0;
- case TGSI_OPCODE_USNE:
- *copcode = C_OPCODE_USNE;
- return 0;
- case TGSI_OPCODE_SWITCH:
- *copcode = C_OPCODE_SWITCH;
- return 0;
- case TGSI_OPCODE_CASE:
- *copcode = C_OPCODE_CASE;
- return 0;
- case TGSI_OPCODE_DEFAULT:
- *copcode = C_OPCODE_DEFAULT;
- return 0;
- case TGSI_OPCODE_ENDSWITCH:
- *copcode = C_OPCODE_ENDSWITCH;
- return 0;
- default:
- fprintf(stderr, "%s:%d unsupported opcode %d\n", __func__, __LINE__, opcode);
- return -EINVAL;
- }
-}
diff --git a/src/gallium/drivers/r600/r600_context.c b/src/gallium/drivers/r600/r600_context.c
index 05575b5767..edde80c660 100644
--- a/src/gallium/drivers/r600/r600_context.c
+++ b/src/gallium/drivers/r600/r600_context.c
@@ -29,9 +29,9 @@
#include <util/u_format.h>
#include <util/u_memory.h>
#include <util/u_blitter.h>
-#include "r600_resource.h"
#include "r600_screen.h"
#include "r600_context.h"
+#include "r600_resource.h"
#include "r600d.h"
static void r600_destroy_context(struct pipe_context *context)
@@ -41,26 +41,31 @@ static void r600_destroy_context(struct pipe_context *context)
FREE(rctx);
}
-static void r600_flush(struct pipe_context *ctx, unsigned flags,
+void r600_flush(struct pipe_context *ctx, unsigned flags,
struct pipe_fence_handle **fence)
{
struct r600_context *rctx = r600_context(ctx);
struct r600_screen *rscreen = rctx->screen;
static int dc = 0;
+ char dname[256];
if (radeon_ctx_pm4(rctx->ctx))
return;
/* FIXME dumping should be removed once shader support instructions
* without throwing bad code
*/
- if (!dc)
- radeon_ctx_dump_bof(rctx->ctx, "gallium.bof");
-#if 0
+ if (!rctx->ctx->cpm4)
+ goto out;
+ sprintf(dname, "gallium-%08d.bof", dc);
+ if (dc < 1)
+ radeon_ctx_dump_bof(rctx->ctx, dname);
+#if 1
radeon_ctx_submit(rctx->ctx);
#endif
+ dc++;
+out:
rctx->ctx = radeon_ctx_decref(rctx->ctx);
rctx->ctx = radeon_ctx(rscreen->rw);
- dc++;
}
static void r600_init_config(struct r600_context *rctx)
@@ -202,27 +207,9 @@ static void r600_init_config(struct r600_context *rctx)
num_es_stack_entries = 0;
break;
}
- printf("ps_prio : %d\n", ps_prio);
- printf("vs_prio : %d\n", vs_prio);
- printf("gs_prio : %d\n", gs_prio);
- printf("es_prio : %d\n", es_prio);
- printf("num_ps_gprs : %d\n", num_ps_gprs);
- printf("num_vs_gprs : %d\n", num_vs_gprs);
- printf("num_gs_gprs : %d\n", num_gs_gprs);
- printf("num_es_gprs : %d\n", num_es_gprs);
- printf("num_temp_gprs : %d\n", num_temp_gprs);
- printf("num_ps_threads : %d\n", num_ps_threads);
- printf("num_vs_threads : %d\n", num_vs_threads);
- printf("num_gs_threads : %d\n", num_gs_threads);
- printf("num_es_threads : %d\n", num_es_threads);
- printf("num_ps_stack_entries : %d\n", num_ps_stack_entries);
- printf("num_vs_stack_entries : %d\n", num_vs_stack_entries);
- printf("num_gs_stack_entries : %d\n", num_gs_stack_entries);
- printf("num_es_stack_entries : %d\n", num_es_stack_entries);
-
- rctx->config = radeon_state(rctx->rw, R600_CONFIG_TYPE, R600_CONFIG);
+ rctx->hw_states.config = radeon_state(rctx->rw, R600_CONFIG_TYPE, R600_CONFIG);
- rctx->config->states[R600_CONFIG__SQ_CONFIG] = 0x00000000;
+ rctx->hw_states.config->states[R600_CONFIG__SQ_CONFIG] = 0x00000000;
switch (family) {
case CHIP_RV610:
case CHIP_RV620:
@@ -231,75 +218,75 @@ static void r600_init_config(struct r600_context *rctx)
case CHIP_RV710:
break;
default:
- rctx->config->states[R600_CONFIG__SQ_CONFIG] |= S_008C00_VC_ENABLE(1);
+ rctx->hw_states.config->states[R600_CONFIG__SQ_CONFIG] |= S_008C00_VC_ENABLE(1);
break;
}
- rctx->config->states[R600_CONFIG__SQ_CONFIG] |= S_008C00_DX9_CONSTS(1);
- rctx->config->states[R600_CONFIG__SQ_CONFIG] |= S_008C00_ALU_INST_PREFER_VECTOR(1);
- rctx->config->states[R600_CONFIG__SQ_CONFIG] |= S_008C00_PS_PRIO(ps_prio);
- rctx->config->states[R600_CONFIG__SQ_CONFIG] |= S_008C00_VS_PRIO(vs_prio);
- rctx->config->states[R600_CONFIG__SQ_CONFIG] |= S_008C00_GS_PRIO(gs_prio);
- rctx->config->states[R600_CONFIG__SQ_CONFIG] |= S_008C00_ES_PRIO(es_prio);
+ rctx->hw_states.config->states[R600_CONFIG__SQ_CONFIG] |= S_008C00_DX9_CONSTS(1);
+ rctx->hw_states.config->states[R600_CONFIG__SQ_CONFIG] |= S_008C00_ALU_INST_PREFER_VECTOR(1);
+ rctx->hw_states.config->states[R600_CONFIG__SQ_CONFIG] |= S_008C00_PS_PRIO(ps_prio);
+ rctx->hw_states.config->states[R600_CONFIG__SQ_CONFIG] |= S_008C00_VS_PRIO(vs_prio);
+ rctx->hw_states.config->states[R600_CONFIG__SQ_CONFIG] |= S_008C00_GS_PRIO(gs_prio);
+ rctx->hw_states.config->states[R600_CONFIG__SQ_CONFIG] |= S_008C00_ES_PRIO(es_prio);
- rctx->config->states[R600_CONFIG__SQ_GPR_RESOURCE_MGMT_1] = 0;
- rctx->config->states[R600_CONFIG__SQ_GPR_RESOURCE_MGMT_1] |= S_008C04_NUM_PS_GPRS(num_ps_gprs);
- rctx->config->states[R600_CONFIG__SQ_GPR_RESOURCE_MGMT_1] |= S_008C04_NUM_VS_GPRS(num_vs_gprs);
- rctx->config->states[R600_CONFIG__SQ_GPR_RESOURCE_MGMT_1] |= S_008C04_NUM_CLAUSE_TEMP_GPRS(num_temp_gprs);
+ rctx->hw_states.config->states[R600_CONFIG__SQ_GPR_RESOURCE_MGMT_1] = 0;
+ rctx->hw_states.config->states[R600_CONFIG__SQ_GPR_RESOURCE_MGMT_1] |= S_008C04_NUM_PS_GPRS(num_ps_gprs);
+ rctx->hw_states.config->states[R600_CONFIG__SQ_GPR_RESOURCE_MGMT_1] |= S_008C04_NUM_VS_GPRS(num_vs_gprs);
+ rctx->hw_states.config->states[R600_CONFIG__SQ_GPR_RESOURCE_MGMT_1] |= S_008C04_NUM_CLAUSE_TEMP_GPRS(num_temp_gprs);
- rctx->config->states[R600_CONFIG__SQ_GPR_RESOURCE_MGMT_2] = 0;
- rctx->config->states[R600_CONFIG__SQ_GPR_RESOURCE_MGMT_2] |= S_008C08_NUM_GS_GPRS(num_gs_gprs);
- rctx->config->states[R600_CONFIG__SQ_GPR_RESOURCE_MGMT_2] |= S_008C08_NUM_GS_GPRS(num_es_gprs);
+ rctx->hw_states.config->states[R600_CONFIG__SQ_GPR_RESOURCE_MGMT_2] = 0;
+ rctx->hw_states.config->states[R600_CONFIG__SQ_GPR_RESOURCE_MGMT_2] |= S_008C08_NUM_GS_GPRS(num_gs_gprs);
+ rctx->hw_states.config->states[R600_CONFIG__SQ_GPR_RESOURCE_MGMT_2] |= S_008C08_NUM_GS_GPRS(num_es_gprs);
- rctx->config->states[R600_CONFIG__SQ_THREAD_RESOURCE_MGMT] = 0;
- rctx->config->states[R600_CONFIG__SQ_THREAD_RESOURCE_MGMT] |= S_008C0C_NUM_PS_THREADS(num_ps_threads);
- rctx->config->states[R600_CONFIG__SQ_THREAD_RESOURCE_MGMT] |= S_008C0C_NUM_VS_THREADS(num_vs_threads);
- rctx->config->states[R600_CONFIG__SQ_THREAD_RESOURCE_MGMT] |= S_008C0C_NUM_GS_THREADS(num_gs_threads);
- rctx->config->states[R600_CONFIG__SQ_THREAD_RESOURCE_MGMT] |= S_008C0C_NUM_ES_THREADS(num_es_threads);
+ rctx->hw_states.config->states[R600_CONFIG__SQ_THREAD_RESOURCE_MGMT] = 0;
+ rctx->hw_states.config->states[R600_CONFIG__SQ_THREAD_RESOURCE_MGMT] |= S_008C0C_NUM_PS_THREADS(num_ps_threads);
+ rctx->hw_states.config->states[R600_CONFIG__SQ_THREAD_RESOURCE_MGMT] |= S_008C0C_NUM_VS_THREADS(num_vs_threads);
+ rctx->hw_states.config->states[R600_CONFIG__SQ_THREAD_RESOURCE_MGMT] |= S_008C0C_NUM_GS_THREADS(num_gs_threads);
+ rctx->hw_states.config->states[R600_CONFIG__SQ_THREAD_RESOURCE_MGMT] |= S_008C0C_NUM_ES_THREADS(num_es_threads);
- rctx->config->states[R600_CONFIG__SQ_STACK_RESOURCE_MGMT_1] = 0;
- rctx->config->states[R600_CONFIG__SQ_STACK_RESOURCE_MGMT_1] |= S_008C10_NUM_PS_STACK_ENTRIES(num_ps_stack_entries);
- rctx->config->states[R600_CONFIG__SQ_STACK_RESOURCE_MGMT_1] |= S_008C10_NUM_VS_STACK_ENTRIES(num_vs_stack_entries);
+ rctx->hw_states.config->states[R600_CONFIG__SQ_STACK_RESOURCE_MGMT_1] = 0;
+ rctx->hw_states.config->states[R600_CONFIG__SQ_STACK_RESOURCE_MGMT_1] |= S_008C10_NUM_PS_STACK_ENTRIES(num_ps_stack_entries);
+ rctx->hw_states.config->states[R600_CONFIG__SQ_STACK_RESOURCE_MGMT_1] |= S_008C10_NUM_VS_STACK_ENTRIES(num_vs_stack_entries);
- rctx->config->states[R600_CONFIG__SQ_STACK_RESOURCE_MGMT_2] = 0;
- rctx->config->states[R600_CONFIG__SQ_STACK_RESOURCE_MGMT_2] |= S_008C14_NUM_GS_STACK_ENTRIES(num_gs_stack_entries);
- rctx->config->states[R600_CONFIG__SQ_STACK_RESOURCE_MGMT_2] |= S_008C14_NUM_ES_STACK_ENTRIES(num_es_stack_entries);
+ rctx->hw_states.config->states[R600_CONFIG__SQ_STACK_RESOURCE_MGMT_2] = 0;
+ rctx->hw_states.config->states[R600_CONFIG__SQ_STACK_RESOURCE_MGMT_2] |= S_008C14_NUM_GS_STACK_ENTRIES(num_gs_stack_entries);
+ rctx->hw_states.config->states[R600_CONFIG__SQ_STACK_RESOURCE_MGMT_2] |= S_008C14_NUM_ES_STACK_ENTRIES(num_es_stack_entries);
- rctx->config->states[R600_CONFIG__SQ_DYN_GPR_CNTL_PS_FLUSH_REQ] = 0x00004000;
- rctx->config->states[R600_CONFIG__TA_CNTL_AUX] = 0x07000002;
- rctx->config->states[R600_CONFIG__VC_ENHANCE] = 0x00000000;
- rctx->config->states[R600_CONFIG__DB_DEBUG] = 0x00000000;
- rctx->config->states[R600_CONFIG__DB_WATERMARKS] = 0x00420204;
- rctx->config->states[R600_CONFIG__SX_MISC] = 0x00000000;
- rctx->config->states[R600_CONFIG__SPI_THREAD_GROUPING] = 0x00000001;
- rctx->config->states[R600_CONFIG__CB_SHADER_CONTROL] = 0x00000003;
- rctx->config->states[R600_CONFIG__SQ_ESGS_RING_ITEMSIZE] = 0x00000000;
- rctx->config->states[R600_CONFIG__SQ_GSVS_RING_ITEMSIZE] = 0x00000000;
- rctx->config->states[R600_CONFIG__SQ_ESTMP_RING_ITEMSIZE] = 0x00000000;
- rctx->config->states[R600_CONFIG__SQ_GSTMP_RING_ITEMSIZE] = 0x00000000;
- rctx->config->states[R600_CONFIG__SQ_VSTMP_RING_ITEMSIZE] = 0x00000000;
- rctx->config->states[R600_CONFIG__SQ_PSTMP_RING_ITEMSIZE] = 0x00000000;
- rctx->config->states[R600_CONFIG__SQ_FBUF_RING_ITEMSIZE] = 0x00000000;
- rctx->config->states[R600_CONFIG__SQ_REDUC_RING_ITEMSIZE] = 0x00000000;
- rctx->config->states[R600_CONFIG__SQ_GS_VERT_ITEMSIZE] = 0x00000000;
- rctx->config->states[R600_CONFIG__VGT_OUTPUT_PATH_CNTL] = 0x00000000;
- rctx->config->states[R600_CONFIG__VGT_HOS_CNTL] = 0x00000000;
- rctx->config->states[R600_CONFIG__VGT_HOS_MAX_TESS_LEVEL] = 0x00000000;
- rctx->config->states[R600_CONFIG__VGT_HOS_MIN_TESS_LEVEL] = 0x00000000;
- rctx->config->states[R600_CONFIG__VGT_HOS_REUSE_DEPTH] = 0x00000000;
- rctx->config->states[R600_CONFIG__VGT_GROUP_PRIM_TYPE] = 0x00000000;
- rctx->config->states[R600_CONFIG__VGT_GROUP_FIRST_DECR] = 0x00000000;
- rctx->config->states[R600_CONFIG__VGT_GROUP_DECR] = 0x00000000;
- rctx->config->states[R600_CONFIG__VGT_GROUP_VECT_0_CNTL] = 0x00000000;
- rctx->config->states[R600_CONFIG__VGT_GROUP_VECT_1_CNTL] = 0x00000000;
- rctx->config->states[R600_CONFIG__VGT_GROUP_VECT_0_FMT_CNTL] = 0x00000000;
- rctx->config->states[R600_CONFIG__VGT_GROUP_VECT_1_FMT_CNTL] = 0x00000000;
- rctx->config->states[R600_CONFIG__VGT_GS_MODE] = 0x00000000;
- rctx->config->states[R600_CONFIG__PA_SC_MODE_CNTL] = 0x00514000;
- rctx->config->states[R600_CONFIG__VGT_STRMOUT_EN] = 0x00000000;
- rctx->config->states[R600_CONFIG__VGT_REUSE_OFF] = 0x00000001;
- rctx->config->states[R600_CONFIG__VGT_VTX_CNT_EN] = 0x00000000;
- rctx->config->states[R600_CONFIG__VGT_STRMOUT_BUFFER_EN] = 0x00000000;
- radeon_state_pm4(rctx->config);
+ rctx->hw_states.config->states[R600_CONFIG__SQ_DYN_GPR_CNTL_PS_FLUSH_REQ] = 0x00004000;
+ rctx->hw_states.config->states[R600_CONFIG__TA_CNTL_AUX] = 0x07000002;
+ rctx->hw_states.config->states[R600_CONFIG__VC_ENHANCE] = 0x00000000;
+ rctx->hw_states.config->states[R600_CONFIG__DB_DEBUG] = 0x00000000;
+ rctx->hw_states.config->states[R600_CONFIG__DB_WATERMARKS] = 0x00420204;
+ rctx->hw_states.config->states[R600_CONFIG__SX_MISC] = 0x00000000;
+ rctx->hw_states.config->states[R600_CONFIG__SPI_THREAD_GROUPING] = 0x00000001;
+ rctx->hw_states.config->states[R600_CONFIG__CB_SHADER_CONTROL] = 0x00000003;
+ rctx->hw_states.config->states[R600_CONFIG__SQ_ESGS_RING_ITEMSIZE] = 0x00000000;
+ rctx->hw_states.config->states[R600_CONFIG__SQ_GSVS_RING_ITEMSIZE] = 0x00000000;
+ rctx->hw_states.config->states[R600_CONFIG__SQ_ESTMP_RING_ITEMSIZE] = 0x00000000;
+ rctx->hw_states.config->states[R600_CONFIG__SQ_GSTMP_RING_ITEMSIZE] = 0x00000000;
+ rctx->hw_states.config->states[R600_CONFIG__SQ_VSTMP_RING_ITEMSIZE] = 0x00000000;
+ rctx->hw_states.config->states[R600_CONFIG__SQ_PSTMP_RING_ITEMSIZE] = 0x00000000;
+ rctx->hw_states.config->states[R600_CONFIG__SQ_FBUF_RING_ITEMSIZE] = 0x00000000;
+ rctx->hw_states.config->states[R600_CONFIG__SQ_REDUC_RING_ITEMSIZE] = 0x00000000;
+ rctx->hw_states.config->states[R600_CONFIG__SQ_GS_VERT_ITEMSIZE] = 0x00000000;
+ rctx->hw_states.config->states[R600_CONFIG__VGT_OUTPUT_PATH_CNTL] = 0x00000000;
+ rctx->hw_states.config->states[R600_CONFIG__VGT_HOS_CNTL] = 0x00000000;
+ rctx->hw_states.config->states[R600_CONFIG__VGT_HOS_MAX_TESS_LEVEL] = 0x00000000;
+ rctx->hw_states.config->states[R600_CONFIG__VGT_HOS_MIN_TESS_LEVEL] = 0x00000000;
+ rctx->hw_states.config->states[R600_CONFIG__VGT_HOS_REUSE_DEPTH] = 0x00000000;
+ rctx->hw_states.config->states[R600_CONFIG__VGT_GROUP_PRIM_TYPE] = 0x00000000;
+ rctx->hw_states.config->states[R600_CONFIG__VGT_GROUP_FIRST_DECR] = 0x00000000;
+ rctx->hw_states.config->states[R600_CONFIG__VGT_GROUP_DECR] = 0x00000000;
+ rctx->hw_states.config->states[R600_CONFIG__VGT_GROUP_VECT_0_CNTL] = 0x00000000;
+ rctx->hw_states.config->states[R600_CONFIG__VGT_GROUP_VECT_1_CNTL] = 0x00000000;
+ rctx->hw_states.config->states[R600_CONFIG__VGT_GROUP_VECT_0_FMT_CNTL] = 0x00000000;
+ rctx->hw_states.config->states[R600_CONFIG__VGT_GROUP_VECT_1_FMT_CNTL] = 0x00000000;
+ rctx->hw_states.config->states[R600_CONFIG__VGT_GS_MODE] = 0x00000000;
+ rctx->hw_states.config->states[R600_CONFIG__PA_SC_MODE_CNTL] = 0x00514000;
+ rctx->hw_states.config->states[R600_CONFIG__VGT_STRMOUT_EN] = 0x00000000;
+ rctx->hw_states.config->states[R600_CONFIG__VGT_REUSE_OFF] = 0x00000001;
+ rctx->hw_states.config->states[R600_CONFIG__VGT_VTX_CNT_EN] = 0x00000000;
+ rctx->hw_states.config->states[R600_CONFIG__VGT_STRMOUT_BUFFER_EN] = 0x00000000;
+ radeon_state_pm4(rctx->hw_states.config);
}
struct pipe_context *r600_create_context(struct pipe_screen *screen, void *priv)
@@ -313,9 +300,7 @@ struct pipe_context *r600_create_context(struct pipe_screen *screen, void *priv)
rctx->context.screen = screen;
rctx->context.priv = priv;
rctx->context.destroy = r600_destroy_context;
- rctx->context.draw_arrays = r600_draw_arrays;
- rctx->context.draw_elements = r600_draw_elements;
- rctx->context.draw_range_elements = r600_draw_range_elements;
+ rctx->context.draw_vbo = r600_draw_vbo;
rctx->context.flush = r600_flush;
/* Easy accessing of screen/winsys. */
@@ -333,20 +318,6 @@ struct pipe_context *r600_create_context(struct pipe_screen *screen, void *priv)
return NULL;
}
- rctx->cb_cntl = radeon_state(rscreen->rw, R600_CB_CNTL_TYPE, R600_CB_CNTL);
- rctx->cb_cntl->states[R600_CB_CNTL__CB_SHADER_MASK] = 0x0000000F;
- rctx->cb_cntl->states[R600_CB_CNTL__CB_TARGET_MASK] = 0x0000000F;
- rctx->cb_cntl->states[R600_CB_CNTL__CB_COLOR_CONTROL] = 0x00CC0000;
- rctx->cb_cntl->states[R600_CB_CNTL__PA_SC_AA_CONFIG] = 0x00000000;
- rctx->cb_cntl->states[R600_CB_CNTL__PA_SC_AA_SAMPLE_LOCS_MCTX] = 0x00000000;
- rctx->cb_cntl->states[R600_CB_CNTL__PA_SC_AA_SAMPLE_LOCS_8S_WD1_MCTX] = 0x00000000;
- rctx->cb_cntl->states[R600_CB_CNTL__CB_CLRCMP_CONTROL] = 0x01000000;
- rctx->cb_cntl->states[R600_CB_CNTL__CB_CLRCMP_SRC] = 0x00000000;
- rctx->cb_cntl->states[R600_CB_CNTL__CB_CLRCMP_DST] = 0x000000FF;
- rctx->cb_cntl->states[R600_CB_CNTL__CB_CLRCMP_MSK] = 0xFFFFFFFF;
- rctx->cb_cntl->states[R600_CB_CNTL__PA_SC_AA_MASK] = 0xFFFFFFFF;
- radeon_state_pm4(rctx->cb_cntl);
-
r600_init_config(rctx);
rctx->ctx = radeon_ctx(rscreen->rw);
diff --git a/src/gallium/drivers/r600/r600_context.h b/src/gallium/drivers/r600/r600_context.h
index f27ff58ed4..76d5de8653 100644
--- a/src/gallium/drivers/r600/r600_context.h
+++ b/src/gallium/drivers/r600/r600_context.h
@@ -23,6 +23,7 @@
#ifndef R600_CONTEXT_H
#define R600_CONTEXT_H
+#include <stdio.h>
#include <pipe/p_state.h>
#include <pipe/p_context.h>
#include <tgsi/tgsi_scan.h>
@@ -33,17 +34,74 @@
#include "r600_shader.h"
/* XXX move this to a more appropriate place */
-struct r600_vertex_elements_state
+union pipe_states {
+ struct pipe_rasterizer_state rasterizer;
+ struct pipe_poly_stipple poly_stipple;
+ struct pipe_scissor_state scissor;
+ struct pipe_clip_state clip;
+ struct pipe_shader_state shader;
+ struct pipe_depth_state depth;
+ struct pipe_stencil_state stencil;
+ struct pipe_alpha_state alpha;
+ struct pipe_depth_stencil_alpha_state dsa;
+ struct pipe_blend_state blend;
+ struct pipe_blend_color blend_color;
+ struct pipe_stencil_ref stencil_ref;
+ struct pipe_framebuffer_state framebuffer;
+ struct pipe_sampler_state sampler;
+ struct pipe_sampler_view sampler_view;
+ struct pipe_viewport_state viewport;
+};
+
+enum pipe_state_type {
+ pipe_rasterizer_type = 1,
+ pipe_poly_stipple_type,
+ pipe_scissor_type,
+ pipe_clip_type,
+ pipe_shader_type,
+ pipe_depth_type,
+ pipe_stencil_type,
+ pipe_alpha_type,
+ pipe_dsa_type,
+ pipe_blend_type,
+ pipe_stencil_ref_type,
+ pipe_framebuffer_type,
+ pipe_sampler_type,
+ pipe_sampler_view_type,
+ pipe_viewport_type,
+ pipe_type_count
+};
+
+struct r600_context_state {
+ union pipe_states state;
+ unsigned refcount;
+ unsigned type;
+ struct radeon_state *rstate;
+ struct r600_shader shader;
+ struct radeon_bo *bo;
+};
+
+struct r600_vertex_element
{
- unsigned count;
- struct pipe_vertex_element elements[32];
+ unsigned refcount;
+ unsigned count;
+ struct pipe_vertex_element elements[32];
};
-struct r600_pipe_shader {
- unsigned type;
- struct r600_shader shader;
- struct radeon_bo *bo;
- struct radeon_state *state;
+struct r600_context_hw_states {
+ struct radeon_state *rasterizer;
+ struct radeon_state *scissor;
+ struct radeon_state *dsa;
+ struct radeon_state *blend;
+ struct radeon_state *viewport;
+ struct radeon_state *cb[8];
+ struct radeon_state *config;
+ struct radeon_state *cb_cntl;
+ struct radeon_state *db;
+ unsigned ps_nresource;
+ unsigned ps_nsampler;
+ struct radeon_state *ps_resource[160];
+ struct radeon_state *ps_sampler[16];
};
struct r600_context {
@@ -51,20 +109,39 @@ struct r600_context {
struct r600_screen *screen;
struct radeon *rw;
struct radeon_ctx *ctx;
- struct radeon_state *cb_cntl;
- struct radeon_state *db;
- struct radeon_state *config;
- struct r600_pipe_shader *ps_shader;
- struct r600_pipe_shader *vs_shader;
+ struct blitter_context *blitter;
+ struct radeon_draw *draw;
+ /* hw states */
+ struct r600_context_hw_states hw_states;
+ /* pipe states */
unsigned flat_shade;
+ unsigned ps_nsampler;
+ unsigned vs_nsampler;
+ unsigned ps_nsampler_view;
+ unsigned vs_nsampler_view;
unsigned nvertex_buffer;
- struct r600_vertex_elements_state *vertex_elements;
+ struct r600_context_state *rasterizer;
+ struct r600_context_state *poly_stipple;
+ struct r600_context_state *scissor;
+ struct r600_context_state *clip;
+ struct r600_context_state *ps_shader;
+ struct r600_context_state *vs_shader;
+ struct r600_context_state *depth;
+ struct r600_context_state *stencil;
+ struct r600_context_state *alpha;
+ struct r600_context_state *dsa;
+ struct r600_context_state *blend;
+ struct r600_context_state *stencil_ref;
+ struct r600_context_state *viewport;
+ struct r600_context_state *framebuffer;
+ struct r600_context_state *ps_sampler[PIPE_MAX_ATTRIBS];
+ struct r600_context_state *vs_sampler[PIPE_MAX_ATTRIBS];
+ struct r600_context_state *ps_sampler_view[PIPE_MAX_ATTRIBS];
+ struct r600_context_state *vs_sampler_view[PIPE_MAX_ATTRIBS];
+ struct r600_vertex_element *vertex_elements;
struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS];
- struct blitter_context *blitter;
- struct pipe_stencil_ref stencil_ref;
- struct pipe_framebuffer_state fb_state;
- struct radeon_draw *draw;
- struct pipe_viewport_state viewport;
+ struct pipe_index_buffer index_buffer;
+ struct pipe_blend_color blend_color;
};
/* Convenience cast wrapper. */
@@ -73,27 +150,32 @@ static INLINE struct r600_context *r600_context(struct pipe_context *pipe)
return (struct r600_context*)pipe;
}
-void r600_draw_arrays(struct pipe_context *ctx, unsigned mode,
- unsigned start, unsigned count);
-void r600_draw_elements(struct pipe_context *ctx,
- struct pipe_resource *index_buffer,
- unsigned index_size, int index_bias, unsigned mode,
- unsigned start, unsigned count);
-void r600_draw_range_elements(struct pipe_context *ctx,
- struct pipe_resource *index_buffer,
- unsigned index_size, int index_bias, unsigned min_index,
- unsigned max_index, unsigned mode,
- unsigned start, unsigned count);
+struct r600_context_state *r600_context_state(struct r600_context *rctx, unsigned type, const void *state);
+struct r600_context_state *r600_context_state_incref(struct r600_context_state *rstate);
+struct r600_context_state *r600_context_state_decref(struct r600_context_state *rstate);
+void r600_flush(struct pipe_context *ctx, unsigned flags,
+ struct pipe_fence_handle **fence);
+
+int r600_context_hw_states(struct r600_context *rctx);
+
+void r600_draw_vbo(struct pipe_context *ctx,
+ const struct pipe_draw_info *info);
void r600_init_blit_functions(struct r600_context *rctx);
void r600_init_state_functions(struct r600_context *rctx);
void r600_init_query_functions(struct r600_context* rctx);
struct pipe_context *r600_create_context(struct pipe_screen *screen, void *priv);
-void r600_pipe_shader_destroy(struct pipe_context *ctx, struct r600_pipe_shader *rpshader);
-struct r600_pipe_shader *r600_pipe_shader_create(struct pipe_context *ctx,
- unsigned type,
- const struct tgsi_token *tokens);
-int r600_pipe_shader_update(struct pipe_context *ctx, struct r600_pipe_shader *rpshader);
+extern int r600_pipe_shader_create(struct pipe_context *ctx,
+ struct r600_context_state *rstate,
+ const struct tgsi_token *tokens);
+extern int r600_pipe_shader_update(struct pipe_context *ctx,
+ struct r600_context_state *rstate);
+
+#define R600_ERR(fmt, args...) \
+ fprintf(stderr, "EE %s/%s:%d - "fmt, __FILE__, __func__, __LINE__, ##args)
+uint32_t r600_translate_texformat(enum pipe_format format,
+ const unsigned char *swizzle_view,
+ uint32_t *word4_p, uint32_t *yuv_format_p);
#endif
diff --git a/src/gallium/drivers/r600/r600_draw.c b/src/gallium/drivers/r600/r600_draw.c
index 724fb6c988..f058455162 100644
--- a/src/gallium/drivers/r600/r600_draw.c
+++ b/src/gallium/drivers/r600/r600_draw.c
@@ -33,7 +33,8 @@
#include <util/u_memory.h>
#include "r600_screen.h"
#include "r600_context.h"
-#include "r600d.h"
+#include "r600_resource.h"
+#include "r600_state_inlines.h"
struct r600_draw {
struct pipe_context *ctx;
@@ -51,11 +52,15 @@ static int r600_draw_common(struct r600_draw *draw)
struct r600_context *rctx = r600_context(draw->ctx);
struct r600_screen *rscreen = rctx->screen;
struct radeon_state *vs_resource;
- struct r600_buffer *rbuffer;
+ struct r600_resource *rbuffer;
unsigned i, j, offset, format, prim;
u32 vgt_dma_index_type, vgt_draw_initiator;
+ struct pipe_vertex_buffer *vertex_buffer;
int r;
+ r = r600_context_hw_states(rctx);
+ if (r)
+ return r;
switch (draw->index_size) {
case 2:
vgt_draw_initiator = 0;
@@ -83,29 +88,19 @@ static int r600_draw_common(struct r600_draw *draw)
r = r600_pipe_shader_update(draw->ctx, rctx->ps_shader);
if (r)
return r;
- r = radeon_draw_set(rctx->draw, rctx->vs_shader->state);
- if (r)
- return r;
- r = radeon_draw_set(rctx->draw, rctx->ps_shader->state);
+ r = radeon_draw_set(rctx->draw, rctx->vs_shader->rstate);
if (r)
return r;
- r = radeon_draw_set(rctx->draw, rctx->cb_cntl);
- if (r)
- return r;
- r = radeon_draw_set(rctx->draw, rctx->db);
- if (r)
- return r;
- r = radeon_draw_set(rctx->draw, rctx->config);
+ r = radeon_draw_set(rctx->draw, rctx->ps_shader->rstate);
if (r)
return r;
for (i = 0 ; i < rctx->vertex_elements->count; i++) {
j = rctx->vertex_elements->elements[i].vertex_buffer_index;
- rbuffer = (struct r600_buffer*)rctx->vertex_buffer[j].buffer;
- offset = rctx->vertex_elements->elements[i].src_offset + rctx->vertex_buffer[j].buffer_offset;
- r = r600_conv_pipe_format(rctx->vertex_elements->elements[i].src_format, &format);
- if (r)
- return r;
+ vertex_buffer = &rctx->vertex_buffer[j];
+ rbuffer = (struct r600_resource*)vertex_buffer->buffer;
+ offset = rctx->vertex_elements->elements[i].src_offset + vertex_buffer->buffer_offset;
+ format = r600_translate_colorformat(rctx->vertex_elements->elements[i].src_format);
vs_resource = radeon_state(rscreen->rw, R600_VS_RESOURCE_TYPE, R600_VS_RESOURCE + i);
if (vs_resource == NULL)
return -ENOMEM;
@@ -113,7 +108,7 @@ static int r600_draw_common(struct r600_draw *draw)
vs_resource->nbo = 1;
vs_resource->states[R600_PS_RESOURCE__RESOURCE0_WORD0] = offset;
vs_resource->states[R600_PS_RESOURCE__RESOURCE0_WORD1] = rbuffer->bo->size - offset;
- vs_resource->states[R600_PS_RESOURCE__RESOURCE0_WORD2] = S_038008_STRIDE(rctx->vertex_buffer[j].stride) |
+ vs_resource->states[R600_PS_RESOURCE__RESOURCE0_WORD2] = S_038008_STRIDE(vertex_buffer->stride) |
S_038008_DATA_FORMAT(format);
vs_resource->states[R600_PS_RESOURCE__RESOURCE0_WORD3] = 0x00000000;
vs_resource->states[R600_PS_RESOURCE__RESOURCE0_WORD4] = 0x00000000;
@@ -132,7 +127,7 @@ static int r600_draw_common(struct r600_draw *draw)
draw->draw->states[R600_DRAW__VGT_NUM_INDICES] = draw->count;
draw->draw->states[R600_DRAW__VGT_DRAW_INITIATOR] = vgt_draw_initiator;
if (draw->index_buffer) {
- rbuffer = (struct r600_buffer*)draw->index_buffer;
+ rbuffer = (struct r600_resource*)draw->index_buffer;
draw->draw->bo[0] = radeon_bo_incref(rscreen->rw, rbuffer->bo);
draw->draw->placement[0] = RADEON_GEM_DOMAIN_GTT;
draw->draw->placement[1] = RADEON_GEM_DOMAIN_GTT;
@@ -160,58 +155,39 @@ static int r600_draw_common(struct r600_draw *draw)
return r;
/* FIXME */
r = radeon_ctx_set_draw_new(rctx->ctx, rctx->draw);
+ if (r == -EBUSY) {
+ r600_flush(draw->ctx, 0, NULL);
+ r = radeon_ctx_set_draw_new(rctx->ctx, rctx->draw);
+ }
if (r)
return r;
rctx->draw = radeon_draw_duplicate(rctx->draw);
return 0;
}
-void r600_draw_range_elements(struct pipe_context *ctx,
- struct pipe_resource *index_buffer,
- unsigned index_size, int index_bias, unsigned min_index,
- unsigned max_index, unsigned mode,
- unsigned start, unsigned count)
+void r600_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *info)
{
+ struct r600_context *rctx = r600_context(ctx);
struct r600_draw draw;
- assert(index_bias == 0);
- draw.ctx = ctx;
- draw.mode = mode;
- draw.start = start;
- draw.count = count;
- draw.index_size = index_size;
- draw.index_buffer = index_buffer;
-printf("index_size %d min %d max %d start %d count %d\n", index_size, min_index, max_index, start, count);
- r600_draw_common(&draw);
-}
-
-void r600_draw_elements(struct pipe_context *ctx,
- struct pipe_resource *index_buffer,
- unsigned index_size, int index_bias, unsigned mode,
- unsigned start, unsigned count)
-{
- struct r600_draw draw;
- assert(index_bias == 0);
+ assert(info->index_bias == 0);
draw.ctx = ctx;
- draw.mode = mode;
- draw.start = start;
- draw.count = count;
- draw.index_size = index_size;
- draw.index_buffer = index_buffer;
- r600_draw_common(&draw);
-}
+ draw.mode = info->mode;
+ draw.start = info->start;
+ draw.count = info->count;
+ if (info->indexed && rctx->index_buffer.buffer) {
+ draw.index_size = rctx->index_buffer.index_size;
+ draw.index_buffer = rctx->index_buffer.buffer;
-void r600_draw_arrays(struct pipe_context *ctx, unsigned mode,
- unsigned start, unsigned count)
-{
- struct r600_draw draw;
-
- draw.ctx = ctx;
- draw.mode = mode;
- draw.start = start;
- draw.count = count;
- draw.index_size = 0;
- draw.index_buffer = NULL;
+ assert(rctx->index_buffer.offset %
+ rctx->index_buffer.index_size == 0);
+ draw.start += rctx->index_buffer.offset /
+ rctx->index_buffer.index_size;
+ }
+ else {
+ draw.index_size = 0;
+ draw.index_buffer = NULL;
+ }
r600_draw_common(&draw);
}
diff --git a/src/gallium/drivers/r600/r600_helper.c b/src/gallium/drivers/r600/r600_helper.c
index e3175b627a..5e0e0aab57 100644
--- a/src/gallium/drivers/r600/r600_helper.c
+++ b/src/gallium/drivers/r600/r600_helper.c
@@ -27,95 +27,9 @@
#include <errno.h>
#include <util/u_inlines.h>
#include "r600_screen.h"
+#include "r600_context.h"
#include "r600d.h"
-int r600_conv_pipe_format(unsigned pformat, unsigned *format)
-{
- switch (pformat) {
- case PIPE_FORMAT_R32G32B32_FLOAT:
- *format = 0x30;
- return 0;
- case PIPE_FORMAT_R32G32B32A32_FLOAT:
- *format = V_0280A0_COLOR_32_32_32_32_FLOAT;
- return 0;
- case PIPE_FORMAT_A8R8G8B8_UNORM:
- case PIPE_FORMAT_X8R8G8B8_UNORM:
- case PIPE_FORMAT_B8G8R8A8_UNORM:
- case PIPE_FORMAT_B8G8R8X8_UNORM:
- case PIPE_FORMAT_R8G8B8A8_UNORM:
- case PIPE_FORMAT_R8G8B8X8_UNORM:
- case PIPE_FORMAT_R8G8B8A8_USCALED:
- case PIPE_FORMAT_R8G8B8A8_SNORM:
- case PIPE_FORMAT_R8G8B8A8_SSCALED:
- *format = V_0280A0_COLOR_8_8_8_8;
- return 0;
- case PIPE_FORMAT_L8_UNORM:
- case PIPE_FORMAT_A8_UNORM:
- case PIPE_FORMAT_I8_UNORM:
- case PIPE_FORMAT_L16_UNORM:
- case PIPE_FORMAT_Z16_UNORM:
- case PIPE_FORMAT_Z32_UNORM:
- case PIPE_FORMAT_Z32_FLOAT:
- case PIPE_FORMAT_R64_FLOAT:
- case PIPE_FORMAT_R64G64_FLOAT:
- case PIPE_FORMAT_R64G64B64_FLOAT:
- case PIPE_FORMAT_R64G64B64A64_FLOAT:
- case PIPE_FORMAT_R32_FLOAT:
- case PIPE_FORMAT_R32G32_FLOAT:
- case PIPE_FORMAT_R32_UNORM:
- case PIPE_FORMAT_R32G32_UNORM:
- case PIPE_FORMAT_R32G32B32_UNORM:
- case PIPE_FORMAT_R32G32B32A32_UNORM:
- case PIPE_FORMAT_R32_USCALED:
- case PIPE_FORMAT_R32G32_USCALED:
- case PIPE_FORMAT_R32G32B32_USCALED:
- case PIPE_FORMAT_R32G32B32A32_USCALED:
- case PIPE_FORMAT_R32_SNORM:
- case PIPE_FORMAT_R32G32_SNORM:
- case PIPE_FORMAT_R32G32B32_SNORM:
- case PIPE_FORMAT_R32G32B32A32_SNORM:
- case PIPE_FORMAT_R32_SSCALED:
- case PIPE_FORMAT_R32G32_SSCALED:
- case PIPE_FORMAT_R32G32B32_SSCALED:
- case PIPE_FORMAT_R32G32B32A32_SSCALED:
- case PIPE_FORMAT_R16_UNORM:
- case PIPE_FORMAT_R16G16_UNORM:
- case PIPE_FORMAT_R16G16B16_UNORM:
- case PIPE_FORMAT_R16G16B16A16_UNORM:
- case PIPE_FORMAT_R16_USCALED:
- case PIPE_FORMAT_R16G16_USCALED:
- case PIPE_FORMAT_R16G16B16_USCALED:
- case PIPE_FORMAT_R16G16B16A16_USCALED:
- case PIPE_FORMAT_R16_SNORM:
- case PIPE_FORMAT_R16G16_SNORM:
- case PIPE_FORMAT_R16G16B16_SNORM:
- case PIPE_FORMAT_R16G16B16A16_SNORM:
- case PIPE_FORMAT_R16_SSCALED:
- case PIPE_FORMAT_R16G16_SSCALED:
- case PIPE_FORMAT_R16G16B16_SSCALED:
- case PIPE_FORMAT_R16G16B16A16_SSCALED:
- case PIPE_FORMAT_R8_UNORM:
- case PIPE_FORMAT_R8G8_UNORM:
- case PIPE_FORMAT_R8G8B8_UNORM:
- case PIPE_FORMAT_R8_USCALED:
- case PIPE_FORMAT_R8G8_USCALED:
- case PIPE_FORMAT_R8G8B8_USCALED:
- case PIPE_FORMAT_R8_SNORM:
- case PIPE_FORMAT_R8G8_SNORM:
- case PIPE_FORMAT_R8G8B8_SNORM:
- case PIPE_FORMAT_R8_SSCALED:
- case PIPE_FORMAT_R8G8_SSCALED:
- case PIPE_FORMAT_R8G8B8_SSCALED:
- case PIPE_FORMAT_R32_FIXED:
- case PIPE_FORMAT_R32G32_FIXED:
- case PIPE_FORMAT_R32G32B32_FIXED:
- case PIPE_FORMAT_R32G32B32A32_FIXED:
- default:
- fprintf(stderr, "%s:%d unsupported %d\n", __func__, __LINE__, pformat);
- return -EINVAL;
- }
-}
-
int r600_conv_pipe_prim(unsigned pprim, unsigned *prim)
{
switch (pprim) {
diff --git a/src/gallium/drivers/r600/r600_resource.c b/src/gallium/drivers/r600/r600_resource.c
index d9aa1df04f..8dc411ef40 100644
--- a/src/gallium/drivers/r600/r600_resource.c
+++ b/src/gallium/drivers/r600/r600_resource.c
@@ -24,45 +24,44 @@
#include "r600_context.h"
#include "r600_resource.h"
#include "r600_screen.h"
-#include "r600_texture.h"
-static struct pipe_resource *
-r600_resource_create(struct pipe_screen *screen,
- const struct pipe_resource *templ)
+static struct pipe_resource *r600_resource_create(struct pipe_screen *screen,
+ const struct pipe_resource *templ)
{
- if (templ->target == PIPE_BUFFER)
- return r600_buffer_create(screen, templ);
- else
- return r600_texture_create(screen, templ);
+ if (templ->target == PIPE_BUFFER) {
+ return r600_buffer_create(screen, templ);
+ } else {
+ return r600_texture_create(screen, templ);
+ }
}
-static struct pipe_resource *
-r600_resource_from_handle(struct pipe_screen * screen,
- const struct pipe_resource *templ,
- struct winsys_handle *whandle)
+static struct pipe_resource *r600_resource_from_handle(struct pipe_screen * screen,
+ const struct pipe_resource *templ,
+ struct winsys_handle *whandle)
{
- if (templ->target == PIPE_BUFFER)
- return NULL;
- else
- return r600_texture_from_handle(screen, templ, whandle);
+ if (templ->target == PIPE_BUFFER) {
+ return NULL;
+ } else {
+ return r600_texture_from_handle(screen, templ, whandle);
+ }
}
void r600_init_context_resource_functions(struct r600_context *r600)
{
- r600->context.get_transfer = u_get_transfer_vtbl;
- r600->context.transfer_map = u_transfer_map_vtbl;
- r600->context.transfer_flush_region = u_transfer_flush_region_vtbl;
- r600->context.transfer_unmap = u_transfer_unmap_vtbl;
- r600->context.transfer_destroy = u_transfer_destroy_vtbl;
- r600->context.transfer_inline_write = u_transfer_inline_write_vtbl;
- r600->context.is_resource_referenced = u_is_resource_referenced_vtbl;
+ r600->context.get_transfer = u_get_transfer_vtbl;
+ r600->context.transfer_map = u_transfer_map_vtbl;
+ r600->context.transfer_flush_region = u_transfer_flush_region_vtbl;
+ r600->context.transfer_unmap = u_transfer_unmap_vtbl;
+ r600->context.transfer_destroy = u_transfer_destroy_vtbl;
+ r600->context.transfer_inline_write = u_transfer_inline_write_vtbl;
+ r600->context.is_resource_referenced = u_is_resource_referenced_vtbl;
}
void r600_init_screen_resource_functions(struct r600_screen *r600screen)
{
- r600screen->screen.resource_create = r600_resource_create;
- r600screen->screen.resource_from_handle = r600_resource_from_handle;
- r600screen->screen.resource_get_handle = u_resource_get_handle_vtbl;
- r600screen->screen.resource_destroy = u_resource_destroy_vtbl;
- r600screen->screen.user_buffer_create = r600_user_buffer_create;
+ r600screen->screen.resource_create = r600_resource_create;
+ r600screen->screen.resource_from_handle = r600_resource_from_handle;
+ r600screen->screen.resource_get_handle = u_resource_get_handle_vtbl;
+ r600screen->screen.resource_destroy = u_resource_destroy_vtbl;
+ r600screen->screen.user_buffer_create = r600_user_buffer_create;
}
diff --git a/src/gallium/drivers/r600/r600_resource.h b/src/gallium/drivers/r600/r600_resource.h
index 95084a371b..bb90e76fb7 100644
--- a/src/gallium/drivers/r600/r600_resource.h
+++ b/src/gallium/drivers/r600/r600_resource.h
@@ -20,14 +20,47 @@
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
* USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
-
#ifndef R600_RESOURCE_H
#define R600_RESOURCE_H
+#include "util/u_transfer.h"
+
struct r600_context;
struct r600_screen;
+/* This gets further specialized into either buffer or texture
+ * structures. Use the vtbl struct to choose between the two
+ * underlying implementations.
+ */
+struct r600_resource {
+ struct u_resource base;
+ struct radeon_bo *bo;
+ u32 domain;
+ u32 flink;
+ struct pb_buffer *pb;
+};
+
+struct r600_resource_texture {
+ struct r600_resource resource;
+ unsigned long offset[PIPE_MAX_TEXTURE_LEVELS];
+ unsigned long pitch[PIPE_MAX_TEXTURE_LEVELS];
+ unsigned long layer_size[PIPE_MAX_TEXTURE_LEVELS];
+ unsigned long pitch_override;
+ unsigned long bpt;
+ unsigned long size;
+};
+
void r600_init_context_resource_functions(struct r600_context *r600);
void r600_init_screen_resource_functions(struct r600_screen *r600screen);
+/* r600_buffer */
+u32 r600_domain_from_usage(unsigned usage);
+
+/* r600_texture */
+struct pipe_resource *r600_texture_create(struct pipe_screen *screen,
+ const struct pipe_resource *templ);
+struct pipe_resource *r600_texture_from_handle(struct pipe_screen *screen,
+ const struct pipe_resource *base,
+ struct winsys_handle *whandle);
+
#endif
diff --git a/src/gallium/drivers/r600/r600_screen.c b/src/gallium/drivers/r600/r600_screen.c
index dec6fa8d27..cdaca9ed7d 100644
--- a/src/gallium/drivers/r600/r600_screen.c
+++ b/src/gallium/drivers/r600/r600_screen.c
@@ -24,15 +24,15 @@
* Jerome Glisse
* Corbin Simpson
*/
-#include <util/u_inlines.h>
-#include <util/u_format.h>
-#include <util/u_memory.h>
-#include "r600_resource.h"
+#include <stdio.h>
+#include "util/u_inlines.h"
+#include "util/u_format.h"
+#include "util/u_memory.h"
#include "r600_screen.h"
-#include "r600_texture.h"
#include "r600_context.h"
#include "r600_public.h"
-#include <stdio.h>
+#include "r600_resource.h"
+#include "r600_state_inlines.h"
static const char* r600_get_vendor(struct pipe_screen* pscreen)
{
@@ -53,61 +53,102 @@ static const char* r600_get_name(struct pipe_screen* pscreen)
static int r600_get_param(struct pipe_screen* pscreen, enum pipe_cap param)
{
switch (param) {
- case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS:
- case PIPE_CAP_MAX_COMBINED_SAMPLERS:
- return 16;
+ /* Supported features (boolean caps). */
case PIPE_CAP_NPOT_TEXTURES:
- return 1;
case PIPE_CAP_TWO_SIDED_STENCIL:
- return 1;
case PIPE_CAP_GLSL:
- return 1;
case PIPE_CAP_DUAL_SOURCE_BLEND:
- return 1;
case PIPE_CAP_ANISOTROPIC_FILTER:
- return 1;
case PIPE_CAP_POINT_SPRITE:
- return 1;
- case PIPE_CAP_MAX_RENDER_TARGETS:
- /* FIXME some r6xx are buggy and can only do 4 */
- return 8;
case PIPE_CAP_OCCLUSION_QUERY:
- return 1;
case PIPE_CAP_TEXTURE_SHADOW_MAP:
- return 1;
- case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
- case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
- case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
- /* FIXME not sure here */
- return 13;
case PIPE_CAP_TEXTURE_MIRROR_CLAMP:
- return 1;
case PIPE_CAP_TEXTURE_MIRROR_REPEAT:
- return 1;
- case PIPE_CAP_MAX_VERTEX_TEXTURE_UNITS:
- /* FIXME allow this once infrastructure is there */
- return 0;
- case PIPE_CAP_TGSI_CONT_SUPPORTED:
- return 0;
case PIPE_CAP_BLEND_EQUATION_SEPARATE:
- return 1;
case PIPE_CAP_SM3:
- return 1;
+ case PIPE_CAP_TEXTURE_SWIZZLE:
case PIPE_CAP_INDEP_BLEND_ENABLE:
- return 1;
- case PIPE_CAP_INDEP_BLEND_FUNC:
- /* FIXME allow this */
- return 0;
case PIPE_CAP_DEPTHSTENCIL_CLEAR_SEPARATE:
return 1;
+
+ /* Unsupported features (boolean caps). */
+ case PIPE_CAP_TIMER_QUERY:
+ case PIPE_CAP_TGSI_CONT_SUPPORTED:
+ case PIPE_CAP_STREAM_OUTPUT:
+ case PIPE_CAP_INDEP_BLEND_FUNC: /* FIXME allow this */
+ case PIPE_CAP_GEOMETRY_SHADER4:
+ case PIPE_CAP_DEPTH_CLAMP: /* FIXME allow this */
+ return 0;
+
+ /* Texturing. */
+ case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
+ case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
+ case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
+ return 14;
+ case PIPE_CAP_MAX_VERTEX_TEXTURE_UNITS:
+ /* FIXME allow this once infrastructure is there */
+ return 0;
+ case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS:
+ case PIPE_CAP_MAX_COMBINED_SAMPLERS:
+ return 16;
+
+ /* Render targets. */
+ case PIPE_CAP_MAX_RENDER_TARGETS:
+ /* FIXME some r6xx are buggy and can only do 4 */
+ return 8;
+
+ /* Fragment coordinate conventions. */
case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT:
case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER:
return 1;
case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT:
case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER:
return 0;
+
+ /* Shader limits. */
+ case PIPE_CAP_MAX_VS_INSTRUCTIONS:
+ return 16384; //max native instructions, not greater than max instructions
+ case PIPE_CAP_MAX_VS_ALU_INSTRUCTIONS:
+ case PIPE_CAP_MAX_VS_TEX_INSTRUCTIONS:
+ case PIPE_CAP_MAX_VS_TEX_INDIRECTIONS:
+ return 16384;
+ case PIPE_CAP_MAX_FS_INSTRUCTIONS:
+ return 16384; //max program native instructions
+ case PIPE_CAP_MAX_FS_ALU_INSTRUCTIONS:
+ return 16384; //max program native ALU instructions
+ case PIPE_CAP_MAX_FS_TEX_INSTRUCTIONS:
+ return 16384; //max program native texture instructions
+ case PIPE_CAP_MAX_FS_TEX_INDIRECTIONS:
+ return 2048; //max program native texture indirections
+ case PIPE_CAP_MAX_VS_CONTROL_FLOW_DEPTH:
+ case PIPE_CAP_MAX_FS_CONTROL_FLOW_DEPTH:
+ return 8; /* FIXME */
+ case PIPE_CAP_MAX_VS_INPUTS:
+ return 16; //max native attributes
+ case PIPE_CAP_MAX_FS_INPUTS:
+ return 10; //max native attributes
+ case PIPE_CAP_MAX_VS_TEMPS:
+ return 256; //max native temporaries
+ case PIPE_CAP_MAX_FS_TEMPS:
+ return 256; //max native temporaries
+ case PIPE_CAP_MAX_VS_ADDRS:
+ case PIPE_CAP_MAX_FS_ADDRS:
+ return 1; //max native address registers/* FIXME Isn't this equal to TEMPS? */
+ case PIPE_CAP_MAX_VS_CONSTS:
+ return 256; //max native parameters
+ case PIPE_CAP_MAX_FS_CONSTS:
+ return 256; //max program native parameters
+ case PIPE_CAP_MAX_CONST_BUFFERS:
+ return 1;
+ case PIPE_CAP_MAX_CONST_BUFFER_SIZE: /* in bytes */
+ return 4096;
+ case PIPE_CAP_MAX_PREDICATE_REGISTERS:
+ case PIPE_CAP_MAX_VS_PREDS:
+ case PIPE_CAP_MAX_FS_PREDS:
+ return 0; /* FIXME */
+
default:
- debug_printf("r600: unknown param %d\n", param);
+ R600_ERR("r600: unknown param %d\n", param);
return 0;
}
}
@@ -125,7 +166,7 @@ static float r600_get_paramf(struct pipe_screen* pscreen, enum pipe_cap param)
case PIPE_CAP_MAX_TEXTURE_LOD_BIAS:
return 16.0f;
default:
- debug_printf("r600: unsupported paramf %d\n", param);
+ R600_ERR("r600: unsupported paramf %d\n", param);
return 0.0f;
}
}
@@ -134,108 +175,51 @@ static boolean r600_is_format_supported(struct pipe_screen* screen,
enum pipe_format format,
enum pipe_texture_target target,
unsigned sample_count,
- unsigned bindings,
+ unsigned usage,
unsigned geom_flags)
{
+ unsigned retval = 0;
if (target >= PIPE_MAX_TEXTURE_TYPES) {
- debug_printf("r600: unsupported texture type %d\n", target);
+ R600_ERR("r600: unsupported texture type %d\n", target);
return FALSE;
}
- switch (format) {
- case PIPE_FORMAT_B4G4R4A4_UNORM:
- case PIPE_FORMAT_B5G6R5_UNORM:
- case PIPE_FORMAT_B5G5R5A1_UNORM:
- case PIPE_FORMAT_A8_UNORM:
- case PIPE_FORMAT_L8_UNORM:
- case PIPE_FORMAT_A8R8G8B8_SRGB:
- case PIPE_FORMAT_R8G8B8A8_SRGB:
- case PIPE_FORMAT_DXT1_RGB:
- case PIPE_FORMAT_DXT1_RGBA:
- case PIPE_FORMAT_DXT3_RGBA:
- case PIPE_FORMAT_DXT5_RGBA:
- case PIPE_FORMAT_UYVY:
- case PIPE_FORMAT_L8_SRGB:
- case PIPE_FORMAT_L8A8_SRGB:
- case PIPE_FORMAT_L8A8_UNORM:
- case PIPE_FORMAT_A8R8G8B8_UNORM:
- case PIPE_FORMAT_X8R8G8B8_UNORM:
- case PIPE_FORMAT_R8G8B8A8_UNORM:
- case PIPE_FORMAT_R8G8B8X8_UNORM:
- case PIPE_FORMAT_B8G8R8A8_UNORM:
- case PIPE_FORMAT_B8G8R8X8_UNORM:
- case PIPE_FORMAT_A8B8G8R8_SRGB:
- case PIPE_FORMAT_B8G8R8A8_SRGB:
- case PIPE_FORMAT_I8_UNORM:
- case PIPE_FORMAT_Z16_UNORM:
- case PIPE_FORMAT_X8Z24_UNORM:
- case PIPE_FORMAT_S8_USCALED_Z24_UNORM:
- case PIPE_FORMAT_Z32_UNORM:
- case PIPE_FORMAT_Z24_UNORM_S8_USCALED:
- case PIPE_FORMAT_Z24X8_UNORM:
- return TRUE;
- default:
- /* Unknown format... */
- break;
- }
- return FALSE;
-}
-
-struct pipe_transfer* r600_texture_get_transfer(struct pipe_context *ctx,
- struct pipe_resource *texture,
- struct pipe_subresource sr,
- unsigned usage,
- const struct pipe_box *box)
-{
- struct r600_texture *rtex = (struct r600_texture*)texture;
- struct r600_transfer *trans;
- trans = CALLOC_STRUCT(r600_transfer);
- if (trans == NULL)
- return NULL;
- pipe_resource_reference(&trans->transfer.resource, texture);
- trans->transfer.sr = sr;
- trans->transfer.usage = usage;
- trans->transfer.box = *box;
- trans->transfer.stride = rtex->stride[sr.level];
- trans->offset = r600_texture_get_offset(rtex, sr.level, box->z, sr.face);
- return &trans->transfer;
-}
-
-void r600_texture_transfer_destroy(struct pipe_context *ctx,
- struct pipe_transfer *trans)
-{
- pipe_resource_reference(&trans->resource, NULL);
- FREE(trans);
-}
+ /* Multisample */
+ if (sample_count > 1)
+ return FALSE;
-void* r600_texture_transfer_map(struct pipe_context *ctx,
- struct pipe_transfer* transfer)
-{
- struct r600_transfer *rtransfer = (struct r600_transfer*)transfer;
- struct r600_texture *rtex = (struct r600_texture*)transfer->resource;
- char *map;
- enum pipe_format format = rtex->b.b.format;
+ if ((usage & PIPE_BIND_SAMPLER_VIEW) &&
+ r600_is_sampler_format_supported(format)) {
+ retval |= PIPE_BIND_SAMPLER_VIEW;
+ }
- map = pipe_buffer_map(ctx, rtex->buffer,
- transfer->usage,
- &rtransfer->buffer_transfer);
+ if ((usage & (PIPE_BIND_RENDER_TARGET |
+ PIPE_BIND_DISPLAY_TARGET |
+ PIPE_BIND_SCANOUT |
+ PIPE_BIND_SHARED)) &&
+ r600_is_colorbuffer_format_supported(format)) {
+ retval |= usage &
+ (PIPE_BIND_RENDER_TARGET |
+ PIPE_BIND_DISPLAY_TARGET |
+ PIPE_BIND_SCANOUT |
+ PIPE_BIND_SHARED);
+ }
- if (!map) {
- return NULL;
+ if ((usage & PIPE_BIND_DEPTH_STENCIL) &&
+ r600_is_zs_format_supported(format)) {
+ retval |= PIPE_BIND_DEPTH_STENCIL;
}
- return map + rtransfer->offset +
- transfer->box.y / util_format_get_blockheight(format) * transfer->stride +
- transfer->box.x / util_format_get_blockwidth(format) * util_format_get_blocksize(format);
-}
+ if ((usage & PIPE_BIND_VERTEX_BUFFER) &&
+ r600_is_vertex_format_supported(format))
+ retval |= PIPE_BIND_VERTEX_BUFFER;
-void r600_texture_transfer_unmap(struct pipe_context *ctx,
- struct pipe_transfer* transfer)
-{
- struct r600_transfer *rtransfer = (struct r600_transfer*)transfer;
- struct r600_texture *rtex = (struct r600_texture*)transfer->resource;
+ if (usage & PIPE_BIND_TRANSFER_READ)
+ retval |= PIPE_BIND_TRANSFER_READ;
+ if (usage & PIPE_BIND_TRANSFER_WRITE)
+ retval |= PIPE_BIND_TRANSFER_WRITE;
- pipe_buffer_unmap(ctx, rtex->buffer, rtransfer->buffer_transfer);
+ return retval == usage;
}
static void r600_destroy_screen(struct pipe_screen* pscreen)
diff --git a/src/gallium/drivers/r600/r600_screen.h b/src/gallium/drivers/r600/r600_screen.h
index 0a0286d96b..53b560c617 100644
--- a/src/gallium/drivers/r600/r600_screen.h
+++ b/src/gallium/drivers/r600/r600_screen.h
@@ -40,14 +40,6 @@ struct r600_transfer {
unsigned offset;
};
-struct r600_buffer {
- struct u_resource b;
- struct radeon_bo *bo;
- u32 domain;
- u32 flink;
- struct pb_buffer *pb;
-};
-
struct r600_screen {
struct pipe_screen screen;
struct radeon *rw;
@@ -88,17 +80,6 @@ void r600_texture_transfer_unmap(struct pipe_context *ctx,
int r600_conv_pipe_format(unsigned pformat, unsigned *format);
int r600_conv_pipe_prim(unsigned pprim, unsigned *prim);
-union r600_float_to_u32_u {
- u32 u;
- float f;
-};
-
-static inline u32 r600_float_to_u32(float f)
-{
- union r600_float_to_u32_u c;
-
- c.f = f;
- return c.u;
-}
+void r600_init_screen_texture_functions(struct pipe_screen *screen);
#endif
diff --git a/src/gallium/drivers/r600/r600_shader.c b/src/gallium/drivers/r600/r600_shader.c
index f7d6e10663..956c7e7930 100644
--- a/src/gallium/drivers/r600/r600_shader.c
+++ b/src/gallium/drivers/r600/r600_shader.c
@@ -19,78 +19,190 @@
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
* USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- * Jerome Glisse
*/
-#include <stdio.h>
-#include <errno.h>
-#include <util/u_inlines.h>
-#include <util/u_format.h>
-#include <util/u_memory.h>
-#include <tgsi/tgsi_dump.h>
+#include "pipe/p_shader_tokens.h"
+#include "tgsi/tgsi_parse.h"
+#include "tgsi/tgsi_scan.h"
+#include "tgsi/tgsi_dump.h"
+#include "util/u_format.h"
#include "r600_screen.h"
#include "r600_context.h"
+#include "r600_shader.h"
+#include "r600_asm.h"
+#include "r600_sq.h"
#include "r600d.h"
+#include <stdio.h>
+#include <errno.h>
+
+
+struct r600_shader_tgsi_instruction;
+
+struct r600_shader_ctx {
+ struct tgsi_shader_info info;
+ struct tgsi_parse_context parse;
+ const struct tgsi_token *tokens;
+ unsigned type;
+ unsigned file_offset[TGSI_FILE_COUNT];
+ unsigned temp_reg;
+ struct r600_shader_tgsi_instruction *inst_info;
+ struct r600_bc *bc;
+ struct r600_shader *shader;
+ u32 value[4];
+};
+
+struct r600_shader_tgsi_instruction {
+ unsigned tgsi_opcode;
+ unsigned is_op3;
+ unsigned r600_opcode;
+ int (*process)(struct r600_shader_ctx *ctx);
+};
+
+static struct r600_shader_tgsi_instruction r600_shader_tgsi_instruction[];
+static int r600_shader_from_tgsi(const struct tgsi_token *tokens, struct r600_shader *shader);
+
+static int r600_shader_update(struct pipe_context *ctx, struct r600_shader *shader)
+{
+ struct r600_context *rctx = r600_context(ctx);
+ const struct util_format_description *desc;
+ enum pipe_format resource_format[160];
+ unsigned i, nresources = 0;
+ struct r600_bc *bc = &shader->bc;
+ struct r600_bc_cf *cf;
+ struct r600_bc_vtx *vtx;
+
+ if (shader->processor_type != TGSI_PROCESSOR_VERTEX)
+ return 0;
+ for (i = 0; i < rctx->vertex_elements->count; i++) {
+ resource_format[nresources++] = rctx->vertex_elements->elements[i].src_format;
+ }
+ LIST_FOR_EACH_ENTRY(cf, &bc->cf, list) {
+ switch (cf->inst) {
+ case V_SQ_CF_WORD1_SQ_CF_INST_VTX:
+ case V_SQ_CF_WORD1_SQ_CF_INST_VTX_TC:
+ LIST_FOR_EACH_ENTRY(vtx, &cf->vtx, list) {
+ desc = util_format_description(resource_format[vtx->buffer_id]);
+ if (desc == NULL) {
+ R600_ERR("unknown format %d\n", resource_format[vtx->buffer_id]);
+ return -EINVAL;
+ }
+ vtx->dst_sel_x = desc->swizzle[0];
+ vtx->dst_sel_y = desc->swizzle[1];
+ vtx->dst_sel_z = desc->swizzle[2];
+ vtx->dst_sel_w = desc->swizzle[3];
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ return r600_bc_build(&shader->bc);
+}
+
+int r600_pipe_shader_create(struct pipe_context *ctx,
+ struct r600_context_state *rpshader,
+ const struct tgsi_token *tokens)
+{
+ struct r600_screen *rscreen = r600_screen(ctx->screen);
+ int r;
+
+fprintf(stderr, "--------------------------------------------------------------\n");
+tgsi_dump(tokens, 0);
+ if (rpshader == NULL)
+ return -ENOMEM;
+ rpshader->shader.family = radeon_get_family(rscreen->rw);
+ r = r600_shader_from_tgsi(tokens, &rpshader->shader);
+ if (r) {
+ R600_ERR("translation from TGSI failed !\n");
+ return r;
+ }
+ r = r600_bc_build(&rpshader->shader.bc);
+ if (r) {
+ R600_ERR("building bytecode failed !\n");
+ return r;
+ }
+fprintf(stderr, "______________________________________________________________\n");
+ return 0;
+}
-static int r600_pipe_shader_vs(struct pipe_context *ctx, struct r600_pipe_shader *rpshader)
+static int r600_pipe_shader_vs(struct pipe_context *ctx, struct r600_context_state *rpshader)
{
struct r600_screen *rscreen = r600_screen(ctx->screen);
struct r600_shader *rshader = &rpshader->shader;
struct radeon_state *state;
unsigned i, tmp;
- rpshader->state = radeon_state_decref(rpshader->state);
+ rpshader->rstate = radeon_state_decref(rpshader->rstate);
state = radeon_state(rscreen->rw, R600_VS_SHADER_TYPE, R600_VS_SHADER);
if (state == NULL)
return -ENOMEM;
- for (i = 0; i < rshader->noutput; i += 4) {
- tmp = rshader->output[i].sid;
- tmp |= rshader->output[i + 1].sid << 8;
- tmp |= rshader->output[i + 2].sid << 16;
- tmp |= rshader->output[i + 3].sid << 24;
- state->states[R600_VS_SHADER__SPI_VS_OUT_ID_0 + i / 4] = tmp;
- }
- state->states[R600_VS_SHADER__SPI_VS_OUT_CONFIG] = S_0286C4_VS_EXPORT_COUNT(rshader->noutput - 1);
- state->states[R600_VS_SHADER__SQ_PGM_RESOURCES_VS] = S_028868_NUM_GPRS(rshader->ngpr);
- rpshader->state = state;
- rpshader->state->bo[0] = radeon_bo_incref(rscreen->rw, rpshader->bo);
- rpshader->state->bo[1] = radeon_bo_incref(rscreen->rw, rpshader->bo);
- rpshader->state->nbo = 2;
- rpshader->state->placement[0] = RADEON_GEM_DOMAIN_GTT;
+ for (i = 0; i < 10; i++) {
+ state->states[R600_VS_SHADER__SPI_VS_OUT_ID_0 + i] = 0;
+ }
+ /* so far never got proper semantic id from tgsi */
+ for (i = 0; i < 32; i++) {
+ tmp = i << ((i & 3) * 8);
+ state->states[R600_VS_SHADER__SPI_VS_OUT_ID_0 + i / 4] |= tmp;
+ }
+ state->states[R600_VS_SHADER__SPI_VS_OUT_CONFIG] = S_0286C4_VS_EXPORT_COUNT(rshader->noutput - 2);
+ state->states[R600_VS_SHADER__SQ_PGM_RESOURCES_VS] = S_028868_NUM_GPRS(rshader->bc.ngpr);
+ rpshader->rstate = state;
+ rpshader->rstate->bo[0] = radeon_bo_incref(rscreen->rw, rpshader->bo);
+ rpshader->rstate->bo[1] = radeon_bo_incref(rscreen->rw, rpshader->bo);
+ rpshader->rstate->nbo = 2;
+ rpshader->rstate->placement[0] = RADEON_GEM_DOMAIN_GTT;
return radeon_state_pm4(state);
}
-static int r600_pipe_shader_ps(struct pipe_context *ctx, struct r600_pipe_shader *rpshader)
+static int r600_pipe_shader_ps(struct pipe_context *ctx, struct r600_context_state *rpshader)
{
+ const struct pipe_rasterizer_state *rasterizer;
struct r600_screen *rscreen = r600_screen(ctx->screen);
struct r600_shader *rshader = &rpshader->shader;
+ struct r600_context *rctx = r600_context(ctx);
struct radeon_state *state;
- unsigned i, tmp;
+ unsigned i, tmp, exports_ps, num_cout;
- rpshader->state = radeon_state_decref(rpshader->state);
+ rasterizer = &rctx->rasterizer->state.rasterizer;
+ rpshader->rstate = radeon_state_decref(rpshader->rstate);
state = radeon_state(rscreen->rw, R600_PS_SHADER_TYPE, R600_PS_SHADER);
if (state == NULL)
return -ENOMEM;
for (i = 0; i < rshader->ninput; i++) {
- tmp = S_028644_SEMANTIC(rshader->input[i].sid);
+ tmp = S_028644_SEMANTIC(i);
tmp |= S_028644_SEL_CENTROID(1);
- tmp |= S_028644_FLAT_SHADE(rshader->flat_shade);
+ if (rshader->input[i].name == TGSI_SEMANTIC_COLOR ||
+ rshader->input[i].name == TGSI_SEMANTIC_BCOLOR) {
+ tmp |= S_028644_FLAT_SHADE(rshader->flat_shade);
+ }
+ if (rasterizer->sprite_coord_enable & (1 << i)) {
+ tmp |= S_028644_PT_SPRITE_TEX(1);
+ }
state->states[R600_PS_SHADER__SPI_PS_INPUT_CNTL_0 + i] = tmp;
}
+
+ exports_ps = 0;
+ num_cout = 0;
+ for (i = 0; i < rshader->noutput; i++) {
+ if (rshader->output[i].name == TGSI_SEMANTIC_POSITION)
+ exports_ps |= 1;
+ else if (rshader->output[i].name == TGSI_SEMANTIC_COLOR) {
+ exports_ps |= (1 << (num_cout+1));
+ num_cout++;
+ }
+ }
state->states[R600_PS_SHADER__SPI_PS_IN_CONTROL_0] = S_0286CC_NUM_INTERP(rshader->ninput) |
S_0286CC_PERSP_GRADIENT_ENA(1);
state->states[R600_PS_SHADER__SPI_PS_IN_CONTROL_1] = 0x00000000;
- state->states[R600_PS_SHADER__SQ_PGM_RESOURCES_PS] = S_028868_NUM_GPRS(rshader->ngpr);
- state->states[R600_PS_SHADER__SQ_PGM_EXPORTS_PS] = 0x00000002;
- rpshader->state = state;
- rpshader->state->bo[0] = radeon_bo_incref(rscreen->rw, rpshader->bo);
- rpshader->state->nbo = 1;
- rpshader->state->placement[0] = RADEON_GEM_DOMAIN_GTT;
+ state->states[R600_PS_SHADER__SQ_PGM_RESOURCES_PS] = S_028868_NUM_GPRS(rshader->bc.ngpr);
+ state->states[R600_PS_SHADER__SQ_PGM_EXPORTS_PS] = exports_ps;
+ rpshader->rstate = state;
+ rpshader->rstate->bo[0] = radeon_bo_incref(rscreen->rw, rpshader->bo);
+ rpshader->rstate->nbo = 1;
+ rpshader->rstate->placement[0] = RADEON_GEM_DOMAIN_GTT;
return radeon_state_pm4(state);
}
-static int r600_pipe_shader(struct pipe_context *ctx, struct r600_pipe_shader *rpshader)
+static int r600_pipe_shader(struct pipe_context *ctx, struct r600_context_state *rpshader)
{
struct r600_screen *rscreen = r600_screen(ctx->screen);
struct r600_context *rctx = r600_context(ctx);
@@ -100,21 +212,21 @@ static int r600_pipe_shader(struct pipe_context *ctx, struct r600_pipe_shader *r
/* copy new shader */
radeon_bo_decref(rscreen->rw, rpshader->bo);
rpshader->bo = NULL;
- rpshader->bo = radeon_bo(rscreen->rw, 0, rshader->ndw * 4,
+ rpshader->bo = radeon_bo(rscreen->rw, 0, rshader->bc.ndw * 4,
4096, NULL);
if (rpshader->bo == NULL) {
return -ENOMEM;
}
radeon_bo_map(rscreen->rw, rpshader->bo);
- memcpy(rpshader->bo->data, rshader->bcode, rshader->ndw * 4);
+ memcpy(rpshader->bo->data, rshader->bc.bytecode, rshader->bc.ndw * 4);
radeon_bo_unmap(rscreen->rw, rpshader->bo);
/* build state */
rshader->flat_shade = rctx->flat_shade;
- switch (rpshader->type) {
- case C_PROGRAM_TYPE_VS:
+ switch (rshader->processor_type) {
+ case TGSI_PROCESSOR_VERTEX:
r = r600_pipe_shader_vs(ctx, rpshader);
break;
- case C_PROGRAM_TYPE_FS:
+ case TGSI_PROCESSOR_FRAGMENT:
r = r600_pipe_shader_ps(ctx, rpshader);
break;
default:
@@ -124,104 +236,1129 @@ static int r600_pipe_shader(struct pipe_context *ctx, struct r600_pipe_shader *r
return r;
}
-struct r600_pipe_shader *r600_pipe_shader_create(struct pipe_context *ctx, unsigned type, const struct tgsi_token *tokens)
+int r600_pipe_shader_update(struct pipe_context *ctx, struct r600_context_state *rpshader)
{
- struct r600_screen *rscreen = r600_screen(ctx->screen);
- struct r600_pipe_shader *rpshader = CALLOC_STRUCT(r600_pipe_shader);
- struct r600_shader *rshader = &rpshader->shader;
+ struct r600_context *rctx = r600_context(ctx);
int r;
- enum radeon_family family;
if (rpshader == NULL)
- return NULL;
- rpshader->type = type;
- family = radeon_get_family(rscreen->rw);
- rshader->r6xx_compile = (family >= CHIP_R600 && family < CHIP_RV770);
- LIST_INITHEAD(&rshader->nodes);
- fprintf(stderr, "<< %s\n", rshader->r6xx_compile ? "R600" : "R700");
- tgsi_dump(tokens, 0);
- fprintf(stderr, "--------------------------------------------------------------\n");
- r = c_shader_from_tgsi(&rshader->cshader, type, tokens);
- if (r) {
- r600_pipe_shader_destroy(ctx, rpshader);
- fprintf(stderr, "ERROR(%s %d)>>\n\n", __func__, __LINE__);
- return NULL;
+ return -EINVAL;
+ /* there should be enough input */
+ if (rctx->vertex_elements->count < rpshader->shader.bc.nresource) {
+ R600_ERR("%d resources provided, expecting %d\n",
+ rctx->vertex_elements->count, rpshader->shader.bc.nresource);
+ return -EINVAL;
}
- r = r600_shader_insert_fetch(&rshader->cshader);
- if (r) {
- r600_pipe_shader_destroy(ctx, rpshader);
- fprintf(stderr, "ERROR(%s %d)>>\n\n", __func__, __LINE__);
- return NULL;
+ r = r600_shader_update(ctx, &rpshader->shader);
+ if (r)
+ return r;
+ return r600_pipe_shader(ctx, rpshader);
+}
+
+static int tgsi_is_supported(struct r600_shader_ctx *ctx)
+{
+ struct tgsi_full_instruction *i = &ctx->parse.FullToken.FullInstruction;
+ int j;
+
+ if (i->Instruction.NumDstRegs > 1) {
+ R600_ERR("too many dst (%d)\n", i->Instruction.NumDstRegs);
+ return -EINVAL;
}
- r = c_shader_build_dominator_tree(&rshader->cshader);
- if (r) {
- r600_pipe_shader_destroy(ctx, rpshader);
- fprintf(stderr, "ERROR(%s %d)>>\n\n", __func__, __LINE__);
- return NULL;
+ if (i->Instruction.Predicate) {
+ R600_ERR("predicate unsupported\n");
+ return -EINVAL;
}
- r = r600_cshader_legalize(&rshader->cshader);
- if (r) {
- r600_pipe_shader_destroy(ctx, rpshader);
- fprintf(stderr, "ERROR(%s %d)>>\n\n", __func__, __LINE__);
- return NULL;
+ if (i->Instruction.Label) {
+ R600_ERR("label unsupported\n");
+ return -EINVAL;
}
- c_shader_dump(&rshader->cshader);
- r = r700_shader_translate(rshader);
- if (r) {
- r600_pipe_shader_destroy(ctx, rpshader);
- fprintf(stderr, "ERROR(%s %d)>>\n\n", __func__, __LINE__);
- return NULL;
+ for (j = 0; j < i->Instruction.NumSrcRegs; j++) {
+ if (i->Src[j].Register.Indirect ||
+ i->Src[j].Register.Dimension ||
+ i->Src[j].Register.Absolute) {
+ R600_ERR("unsupported src (indirect|dimension|absolute)\n");
+ return -EINVAL;
+ }
}
-#if 1
-#if 0
- fprintf(stderr, "--------------------------------------------------------------\n");
- for (int i = 0; i < rshader->ndw; i++) {
- fprintf(stderr, "0x%08X\n", rshader->bcode[i]);
+ for (j = 0; j < i->Instruction.NumDstRegs; j++) {
+ if (i->Dst[j].Register.Indirect || i->Dst[j].Register.Dimension) {
+ R600_ERR("unsupported dst (indirect|dimension)\n");
+ return -EINVAL;
+ }
}
-#endif
- fprintf(stderr, ">>\n\n");
-#endif
- return rpshader;
+ return 0;
}
-void r600_pipe_shader_destroy(struct pipe_context *ctx, struct r600_pipe_shader *rpshader)
+static int tgsi_declaration(struct r600_shader_ctx *ctx)
{
- struct r600_screen *rscreen = r600_screen(ctx->screen);
+ struct tgsi_full_declaration *d = &ctx->parse.FullToken.FullDeclaration;
+ struct r600_bc_vtx vtx;
+ unsigned i;
+ int r;
- if (rpshader == NULL)
- return;
- radeon_bo_decref(rscreen->rw, rpshader->bo);
- rpshader->bo = NULL;
- r600_shader_cleanup(&rpshader->shader);
- FREE(rpshader);
+ switch (d->Declaration.File) {
+ case TGSI_FILE_INPUT:
+ i = ctx->shader->ninput++;
+ ctx->shader->input[i].name = d->Semantic.Name;
+ ctx->shader->input[i].sid = d->Semantic.Index;
+ ctx->shader->input[i].interpolate = d->Declaration.Interpolate;
+ ctx->shader->input[i].gpr = ctx->file_offset[TGSI_FILE_INPUT] + i;
+ if (ctx->type == TGSI_PROCESSOR_VERTEX) {
+ /* turn input into fetch */
+ memset(&vtx, 0, sizeof(struct r600_bc_vtx));
+ vtx.inst = 0;
+ vtx.fetch_type = 0;
+ vtx.buffer_id = i;
+ /* register containing the index into the buffer */
+ vtx.src_gpr = 0;
+ vtx.src_sel_x = 0;
+ vtx.mega_fetch_count = 0x1F;
+ vtx.dst_gpr = ctx->shader->input[i].gpr;
+ vtx.dst_sel_x = 0;
+ vtx.dst_sel_y = 1;
+ vtx.dst_sel_z = 2;
+ vtx.dst_sel_w = 3;
+ r = r600_bc_add_vtx(ctx->bc, &vtx);
+ if (r)
+ return r;
+ }
+ break;
+ case TGSI_FILE_OUTPUT:
+ i = ctx->shader->noutput++;
+ ctx->shader->output[i].name = d->Semantic.Name;
+ ctx->shader->output[i].sid = d->Semantic.Index;
+ ctx->shader->output[i].gpr = ctx->file_offset[TGSI_FILE_OUTPUT] + i;
+ ctx->shader->output[i].interpolate = d->Declaration.Interpolate;
+ break;
+ case TGSI_FILE_CONSTANT:
+ case TGSI_FILE_TEMPORARY:
+ case TGSI_FILE_SAMPLER:
+ break;
+ default:
+ R600_ERR("unsupported file %d declaration\n", d->Declaration.File);
+ return -EINVAL;
+ }
+ return 0;
}
-int r600_pipe_shader_update(struct pipe_context *ctx, struct r600_pipe_shader *rpshader)
+int r600_shader_from_tgsi(const struct tgsi_token *tokens, struct r600_shader *shader)
{
- struct r600_context *rctx = r600_context(ctx);
- struct r600_shader *rshader;
- enum pipe_format resource_format[160];
- unsigned i, nresources = 0;
- int r;
+ struct tgsi_full_immediate *immediate;
+ struct r600_shader_ctx ctx;
+ struct r600_bc_output output[32];
+ unsigned output_done, noutput;
+ unsigned opcode;
+ int i, r = 0, pos0;
- if (rpshader == NULL)
- return -EINVAL;
- rshader = &rpshader->shader;
- switch (rpshader->type) {
- case C_PROGRAM_TYPE_VS:
- for (i = 0; i < rctx->vertex_elements->count; i++) {
- resource_format[nresources++] = rctx->vertex_elements->elements[i].src_format;
+ ctx.bc = &shader->bc;
+ ctx.shader = shader;
+ r = r600_bc_init(ctx.bc, shader->family);
+ if (r)
+ return r;
+ ctx.tokens = tokens;
+ tgsi_scan_shader(tokens, &ctx.info);
+ tgsi_parse_init(&ctx.parse, tokens);
+ ctx.type = ctx.parse.FullHeader.Processor.Processor;
+ shader->processor_type = ctx.type;
+
+ /* register allocations */
+ /* Values [0,127] correspond to GPR[0..127].
+ * Values [256,511] correspond to cfile constants c[0..255].
+ * Other special values are shown in the list below.
+ * 248 SQ_ALU_SRC_0: special constant 0.0.
+ * 249 SQ_ALU_SRC_1: special constant 1.0 float.
+ * 250 SQ_ALU_SRC_1_INT: special constant 1 integer.
+ * 251 SQ_ALU_SRC_M_1_INT: special constant -1 integer.
+ * 252 SQ_ALU_SRC_0_5: special constant 0.5 float.
+ * 253 SQ_ALU_SRC_LITERAL: literal constant.
+ * 254 SQ_ALU_SRC_PV: previous vector result.
+ * 255 SQ_ALU_SRC_PS: previous scalar result.
+ */
+ for (i = 0; i < TGSI_FILE_COUNT; i++) {
+ ctx.file_offset[i] = 0;
+ }
+ if (ctx.type == TGSI_PROCESSOR_VERTEX) {
+ ctx.file_offset[TGSI_FILE_INPUT] = 1;
+ }
+ ctx.file_offset[TGSI_FILE_OUTPUT] = ctx.file_offset[TGSI_FILE_INPUT] +
+ ctx.info.file_count[TGSI_FILE_INPUT];
+ ctx.file_offset[TGSI_FILE_TEMPORARY] = ctx.file_offset[TGSI_FILE_OUTPUT] +
+ ctx.info.file_count[TGSI_FILE_OUTPUT];
+ ctx.file_offset[TGSI_FILE_CONSTANT] = 256;
+ ctx.file_offset[TGSI_FILE_IMMEDIATE] = 253;
+ ctx.temp_reg = ctx.file_offset[TGSI_FILE_TEMPORARY] +
+ ctx.info.file_count[TGSI_FILE_TEMPORARY];
+
+ while (!tgsi_parse_end_of_tokens(&ctx.parse)) {
+ tgsi_parse_token(&ctx.parse);
+ switch (ctx.parse.FullToken.Token.Type) {
+ case TGSI_TOKEN_TYPE_IMMEDIATE:
+ immediate = &ctx.parse.FullToken.FullImmediate;
+ ctx.value[0] = immediate->u[0].Uint;
+ ctx.value[1] = immediate->u[1].Uint;
+ ctx.value[2] = immediate->u[2].Uint;
+ ctx.value[3] = immediate->u[3].Uint;
+ break;
+ case TGSI_TOKEN_TYPE_DECLARATION:
+ r = tgsi_declaration(&ctx);
+ if (r)
+ goto out_err;
+ break;
+ case TGSI_TOKEN_TYPE_INSTRUCTION:
+ r = tgsi_is_supported(&ctx);
+ if (r)
+ goto out_err;
+ opcode = ctx.parse.FullToken.FullInstruction.Instruction.Opcode;
+ ctx.inst_info = &r600_shader_tgsi_instruction[opcode];
+ r = ctx.inst_info->process(&ctx);
+ if (r)
+ goto out_err;
+ r = r600_bc_add_literal(ctx.bc, ctx.value);
+ if (r)
+ goto out_err;
+ break;
+ default:
+ R600_ERR("unsupported token type %d\n", ctx.parse.FullToken.Token.Type);
+ r = -EINVAL;
+ goto out_err;
}
- break;
+ }
+ /* export output */
+ noutput = shader->noutput;
+ for (i = 0, pos0 = 0; i < noutput; i++) {
+ memset(&output[i], 0, sizeof(struct r600_bc_output));
+ output[i].gpr = shader->output[i].gpr;
+ output[i].elem_size = 3;
+ output[i].swizzle_x = 0;
+ output[i].swizzle_y = 1;
+ output[i].swizzle_z = 2;
+ output[i].swizzle_w = 3;
+ output[i].barrier = 1;
+ output[i].type = V_SQ_CF_ALLOC_EXPORT_WORD0_SQ_EXPORT_PARAM;
+ output[i].array_base = i - pos0;
+ output[i].inst = V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT;
+ switch (ctx.type) {
+ case TGSI_PROCESSOR_VERTEX:
+ if (shader->output[i].name == TGSI_SEMANTIC_POSITION) {
+ output[i].array_base = 60;
+ output[i].type = V_SQ_CF_ALLOC_EXPORT_WORD0_SQ_EXPORT_POS;
+ /* position doesn't count in array_base */
+ pos0++;
+ }
+ if (shader->output[i].name == TGSI_SEMANTIC_PSIZE) {
+ output[i].array_base = 61;
+ output[i].type = V_SQ_CF_ALLOC_EXPORT_WORD0_SQ_EXPORT_POS;
+ /* position doesn't count in array_base */
+ pos0++;
+ }
+ break;
+ case TGSI_PROCESSOR_FRAGMENT:
+ if (shader->output[i].name == TGSI_SEMANTIC_COLOR) {
+ output[i].array_base = shader->output[i].sid;
+ output[i].type = V_SQ_CF_ALLOC_EXPORT_WORD0_SQ_EXPORT_PIXEL;
+ } else if (shader->output[i].name == TGSI_SEMANTIC_POSITION) {
+ output[i].array_base = 61;
+ output[i].type = V_SQ_CF_ALLOC_EXPORT_WORD0_SQ_EXPORT_PIXEL;
+ } else {
+ R600_ERR("unsupported fragment output name %d\n", shader->output[i].name);
+ r = -EINVAL;
+ goto out_err;
+ }
+ break;
+ default:
+ R600_ERR("unsupported processor type %d\n", ctx.type);
+ r = -EINVAL;
+ goto out_err;
+ }
+ }
+ /* add fake param output for vertex shader if no param is exported */
+ if (ctx.type == TGSI_PROCESSOR_VERTEX) {
+ for (i = 0, pos0 = 0; i < noutput; i++) {
+ if (output[i].type == V_SQ_CF_ALLOC_EXPORT_WORD0_SQ_EXPORT_PARAM) {
+ pos0 = 1;
+ break;
+ }
+ }
+ if (!pos0) {
+ memset(&output[i], 0, sizeof(struct r600_bc_output));
+ output[i].gpr = 0;
+ output[i].elem_size = 3;
+ output[i].swizzle_x = 0;
+ output[i].swizzle_y = 1;
+ output[i].swizzle_z = 2;
+ output[i].swizzle_w = 3;
+ output[i].barrier = 1;
+ output[i].type = V_SQ_CF_ALLOC_EXPORT_WORD0_SQ_EXPORT_PARAM;
+ output[i].array_base = 0;
+ output[i].inst = V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT;
+ noutput++;
+ }
+ }
+ /* add fake pixel export */
+ if (ctx.type == TGSI_PROCESSOR_FRAGMENT && !noutput) {
+ memset(&output[0], 0, sizeof(struct r600_bc_output));
+ output[0].gpr = 0;
+ output[0].elem_size = 3;
+ output[0].swizzle_x = 7;
+ output[0].swizzle_y = 7;
+ output[0].swizzle_z = 7;
+ output[0].swizzle_w = 7;
+ output[0].barrier = 1;
+ output[0].type = V_SQ_CF_ALLOC_EXPORT_WORD0_SQ_EXPORT_PARAM;
+ output[0].array_base = 0;
+ output[0].inst = V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT;
+ noutput++;
+ }
+ /* set export done on last export of each type */
+ for (i = noutput - 1, output_done = 0; i >= 0; i--) {
+ if (i == (noutput - 1)) {
+ output[i].end_of_program = 1;
+ }
+ if (!(output_done & (1 << output[i].type))) {
+ output_done |= (1 << output[i].type);
+ output[i].inst = V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT_DONE;
+ }
+ }
+ /* add output to bytecode */
+ for (i = 0; i < noutput; i++) {
+ r = r600_bc_add_output(ctx.bc, &output[i]);
+ if (r)
+ goto out_err;
+ }
+ tgsi_parse_free(&ctx.parse);
+ return 0;
+out_err:
+ tgsi_parse_free(&ctx.parse);
+ return r;
+}
+
+static int tgsi_unsupported(struct r600_shader_ctx *ctx)
+{
+ R600_ERR("%d tgsi opcode unsupported\n", ctx->inst_info->tgsi_opcode);
+ return -EINVAL;
+}
+
+static int tgsi_end(struct r600_shader_ctx *ctx)
+{
+ return 0;
+}
+
+static int tgsi_src(struct r600_shader_ctx *ctx,
+ const struct tgsi_full_src_register *tgsi_src,
+ struct r600_bc_alu_src *r600_src)
+{
+ memset(r600_src, 0, sizeof(struct r600_bc_alu_src));
+ r600_src->sel = tgsi_src->Register.Index;
+ if (tgsi_src->Register.File == TGSI_FILE_IMMEDIATE) {
+ r600_src->sel = 0;
+ }
+ r600_src->neg = tgsi_src->Register.Negate;
+ r600_src->sel += ctx->file_offset[tgsi_src->Register.File];
+ return 0;
+}
+
+static int tgsi_dst(struct r600_shader_ctx *ctx,
+ const struct tgsi_full_dst_register *tgsi_dst,
+ unsigned swizzle,
+ struct r600_bc_alu_dst *r600_dst)
+{
+ struct tgsi_full_instruction *inst = &ctx->parse.FullToken.FullInstruction;
+
+ r600_dst->sel = tgsi_dst->Register.Index;
+ r600_dst->sel += ctx->file_offset[tgsi_dst->Register.File];
+ r600_dst->chan = swizzle;
+ r600_dst->write = 1;
+ if (inst->Instruction.Saturate) {
+ r600_dst->clamp = 1;
+ }
+ return 0;
+}
+
+static unsigned tgsi_chan(const struct tgsi_full_src_register *tgsi_src, unsigned swizzle)
+{
+ switch (swizzle) {
+ case 0:
+ return tgsi_src->Register.SwizzleX;
+ case 1:
+ return tgsi_src->Register.SwizzleY;
+ case 2:
+ return tgsi_src->Register.SwizzleZ;
+ case 3:
+ return tgsi_src->Register.SwizzleW;
default:
- break;
+ return 0;
}
- /* there should be enough input */
- if (nresources < rshader->nresource)
- return -EINVAL;
- /* FIXME compare resources */
- r = r600_shader_update(rshader, resource_format);
+}
+
+static int tgsi_split_constant(struct r600_shader_ctx *ctx, struct r600_bc_alu_src r600_src[3])
+{
+ struct tgsi_full_instruction *inst = &ctx->parse.FullToken.FullInstruction;
+ struct r600_bc_alu alu;
+ int i, j, k, nconst, r;
+
+ for (i = 0, nconst = 0; i < inst->Instruction.NumSrcRegs; i++) {
+ if (inst->Src[i].Register.File == TGSI_FILE_CONSTANT) {
+ nconst++;
+ }
+ r = tgsi_src(ctx, &inst->Src[i], &r600_src[i]);
+ if (r) {
+ return r;
+ }
+ }
+ for (i = 0, j = nconst - 1; i < inst->Instruction.NumSrcRegs; i++) {
+ if (inst->Src[j].Register.File == TGSI_FILE_CONSTANT && j > 0) {
+ for (k = 0; k < 4; k++) {
+ memset(&alu, 0, sizeof(struct r600_bc_alu));
+ alu.inst = V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOV;
+ alu.src[0].sel = r600_src[0].sel;
+ alu.src[0].chan = k;
+ alu.dst.sel = ctx->temp_reg + j;
+ alu.dst.chan = k;
+ alu.dst.write = 1;
+ if (k == 3)
+ alu.last = 1;
+ r = r600_bc_add_alu(ctx->bc, &alu);
+ if (r)
+ return r;
+ }
+ r600_src[0].sel = ctx->temp_reg + j;
+ j--;
+ }
+ }
+ return 0;
+}
+
+static int tgsi_op2(struct r600_shader_ctx *ctx)
+{
+ struct tgsi_full_instruction *inst = &ctx->parse.FullToken.FullInstruction;
+ struct r600_bc_alu_src r600_src[3];
+ struct r600_bc_alu alu;
+ int i, j, r;
+
+ r = tgsi_split_constant(ctx, r600_src);
if (r)
return r;
- return r600_pipe_shader(ctx, rpshader);
+ for (i = 0; i < 4; i++) {
+ memset(&alu, 0, sizeof(struct r600_bc_alu));
+ if (!(inst->Dst[0].Register.WriteMask & (1 << i))) {
+ alu.inst = V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP;
+ alu.dst.chan = i;
+ } else {
+ alu.inst = ctx->inst_info->r600_opcode;
+ for (j = 0; j < inst->Instruction.NumSrcRegs; j++) {
+ alu.src[j] = r600_src[j];
+ alu.src[j].chan = tgsi_chan(&inst->Src[j], i);
+ }
+ r = tgsi_dst(ctx, &inst->Dst[0], i, &alu.dst);
+ if (r)
+ return r;
+ }
+ /* handle some special cases */
+ switch (ctx->inst_info->tgsi_opcode) {
+ case TGSI_OPCODE_SUB:
+ alu.src[1].neg = 1;
+ break;
+ case TGSI_OPCODE_ABS:
+ alu.src[0].abs = 1;
+ break;
+ default:
+ break;
+ }
+ if (i == 3) {
+ alu.last = 1;
+ }
+ r = r600_bc_add_alu(ctx->bc, &alu);
+ if (r)
+ return r;
+ }
+ return 0;
+}
+
+static int tgsi_kill(struct r600_shader_ctx *ctx)
+{
+ struct tgsi_full_instruction *inst = &ctx->parse.FullToken.FullInstruction;
+ struct r600_bc_alu alu;
+ int i, r;
+
+ for (i = 0; i < 4; i++) {
+ memset(&alu, 0, sizeof(struct r600_bc_alu));
+ alu.inst = ctx->inst_info->r600_opcode;
+ alu.dst.chan = i;
+ alu.src[0].sel = 248;
+ r = tgsi_src(ctx, &inst->Src[0], &alu.src[1]);
+ if (r)
+ return r;
+ alu.src[1].chan = tgsi_chan(&inst->Src[0], i);
+ if (i == 3) {
+ alu.last = 1;
+ }
+ r = r600_bc_add_alu(ctx->bc, &alu);
+ if (r)
+ return r;
+ }
+ return 0;
+}
+
+static int tgsi_slt(struct r600_shader_ctx *ctx)
+{
+ struct tgsi_full_instruction *inst = &ctx->parse.FullToken.FullInstruction;
+ struct r600_bc_alu_src r600_src[3];
+ struct r600_bc_alu alu;
+ int i, r;
+
+ r = tgsi_split_constant(ctx, r600_src);
+ if (r)
+ return r;
+ for (i = 0; i < 4; i++) {
+ memset(&alu, 0, sizeof(struct r600_bc_alu));
+ if (!(inst->Dst[0].Register.WriteMask & (1 << i))) {
+ alu.inst = V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP;
+ alu.dst.chan = i;
+ } else {
+ alu.inst = ctx->inst_info->r600_opcode;
+ alu.src[1] = r600_src[0];
+ alu.src[1].chan = tgsi_chan(&inst->Src[0], i);
+ alu.src[0] = r600_src[1];
+ alu.src[0].chan = tgsi_chan(&inst->Src[1], i);
+ r = tgsi_dst(ctx, &inst->Dst[0], i, &alu.dst);
+ if (r)
+ return r;
+ }
+ if (i == 3) {
+ alu.last = 1;
+ }
+ r = r600_bc_add_alu(ctx->bc, &alu);
+ if (r)
+ return r;
+ }
+ return 0;
+}
+
+static int tgsi_lit(struct r600_shader_ctx *ctx)
+{
+ struct tgsi_full_instruction *inst = &ctx->parse.FullToken.FullInstruction;
+ struct r600_bc_alu alu;
+ int r;
+
+ /* dst.x, <- 1.0 */
+ memset(&alu, 0, sizeof(struct r600_bc_alu));
+ alu.inst = V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOV;
+ alu.src[0].sel = 249; /*1.0*/
+ alu.src[0].chan = 0;
+ r = tgsi_dst(ctx, &inst->Dst[0], 0, &alu.dst);
+ if (r)
+ return r;
+ alu.dst.write = (inst->Dst[0].Register.WriteMask >> 0) & 1;
+ r = r600_bc_add_alu(ctx->bc, &alu);
+ if (r)
+ return r;
+
+ /* dst.y = max(src.x, 0.0) */
+ memset(&alu, 0, sizeof(struct r600_bc_alu));
+ alu.inst = V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MAX;
+ r = tgsi_src(ctx, &inst->Src[0], &alu.src[0]);
+ if (r)
+ return r;
+ alu.src[1].sel = 248; /*0.0*/
+ alu.src[1].chan = tgsi_chan(&inst->Src[0], 0);
+ r = tgsi_dst(ctx, &inst->Dst[0], 1, &alu.dst);
+ if (r)
+ return r;
+ alu.dst.write = (inst->Dst[0].Register.WriteMask >> 1) & 1;
+ r = r600_bc_add_alu(ctx->bc, &alu);
+ if (r)
+ return r;
+
+ /* dst.z = NOP - fill Z slot */
+ memset(&alu, 0, sizeof(struct r600_bc_alu));
+ alu.inst = V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP;
+ alu.dst.chan = 2;
+ r = r600_bc_add_alu(ctx->bc, &alu);
+ if (r)
+ return r;
+
+ /* dst.w, <- 1.0 */
+ memset(&alu, 0, sizeof(struct r600_bc_alu));
+ alu.inst = V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOV;
+ alu.src[0].sel = 249;
+ alu.src[0].chan = 0;
+ r = tgsi_dst(ctx, &inst->Dst[0], 3, &alu.dst);
+ if (r)
+ return r;
+ alu.dst.write = (inst->Dst[0].Register.WriteMask >> 3) & 1;
+ alu.last = 1;
+ r = r600_bc_add_alu(ctx->bc, &alu);
+ if (r)
+ return r;
+
+ if (inst->Dst[0].Register.WriteMask & (1 << 2))
+ {
+ int chan;
+ int sel;
+
+ /* dst.z = log(src.y) */
+ memset(&alu, 0, sizeof(struct r600_bc_alu));
+ alu.inst = V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_LOG_CLAMPED;
+ r = tgsi_src(ctx, &inst->Src[0], &alu.src[0]);
+ if (r)
+ return r;
+ alu.src[0].chan = tgsi_chan(&inst->Src[0], 1);
+ r = tgsi_dst(ctx, &inst->Dst[0], 2, &alu.dst);
+ if (r)
+ return r;
+ alu.last = 1;
+ r = r600_bc_add_alu(ctx->bc, &alu);
+ if (r)
+ return r;
+
+ chan = alu.dst.chan;
+ sel = alu.dst.sel;
+
+ /* tmp.x = amd MUL_LIT(src.w, dst.z, src.x ) */
+ memset(&alu, 0, sizeof(struct r600_bc_alu));
+ alu.inst = V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_MUL_LIT;
+ r = tgsi_src(ctx, &inst->Src[0], &alu.src[0]);
+ if (r)
+ return r;
+ alu.src[0].chan = tgsi_chan(&inst->Src[0], 3);
+ alu.src[1].sel = sel;
+ alu.src[1].chan = chan;
+ r = tgsi_src(ctx, &inst->Src[0], &alu.src[2]);
+ if (r)
+ return r;
+ alu.src[2].chan = tgsi_chan(&inst->Src[0], 0);
+ alu.dst.sel = ctx->temp_reg;
+ alu.dst.chan = 0;
+ alu.dst.write = 1;
+ alu.is_op3 = 1;
+ alu.last = 1;
+ r = r600_bc_add_alu(ctx->bc, &alu);
+ if (r)
+ return r;
+
+ /* dst.z = exp(tmp.x) */
+ memset(&alu, 0, sizeof(struct r600_bc_alu));
+ alu.inst = V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_EXP_IEEE;
+ alu.src[0].sel = ctx->temp_reg;
+ alu.src[0].chan = 0;
+ r = tgsi_dst(ctx, &inst->Dst[0], 2, &alu.dst);
+ if (r)
+ return r;
+ alu.last = 1;
+ r = r600_bc_add_alu(ctx->bc, &alu);
+ if (r)
+ return r;
+ }
+ return 0;
+}
+
+static int tgsi_trans(struct r600_shader_ctx *ctx)
+{
+ struct tgsi_full_instruction *inst = &ctx->parse.FullToken.FullInstruction;
+ struct r600_bc_alu alu;
+ int i, j, r;
+
+ for (i = 0; i < 4; i++) {
+ memset(&alu, 0, sizeof(struct r600_bc_alu));
+ if (inst->Dst[0].Register.WriteMask & (1 << i)) {
+ alu.inst = ctx->inst_info->r600_opcode;
+ for (j = 0; j < inst->Instruction.NumSrcRegs; j++) {
+ r = tgsi_src(ctx, &inst->Src[j], &alu.src[j]);
+ if (r)
+ return r;
+ alu.src[j].chan = tgsi_chan(&inst->Src[j], i);
+ }
+ r = tgsi_dst(ctx, &inst->Dst[0], i, &alu.dst);
+ if (r)
+ return r;
+ alu.last = 1;
+ r = r600_bc_add_alu(ctx->bc, &alu);
+ if (r)
+ return r;
+ }
+ }
+ return 0;
+}
+
+static int tgsi_trans_srcx_replicate(struct r600_shader_ctx *ctx)
+{
+ struct tgsi_full_instruction *inst = &ctx->parse.FullToken.FullInstruction;
+ struct r600_bc_alu alu;
+ int i, j, r;
+
+ memset(&alu, 0, sizeof(struct r600_bc_alu));
+ alu.inst = ctx->inst_info->r600_opcode;
+ for (j = 0; j < inst->Instruction.NumSrcRegs; j++) {
+ r = tgsi_src(ctx, &inst->Src[j], &alu.src[j]);
+ if (r)
+ return r;
+ alu.src[j].chan = tgsi_chan(&inst->Src[j], 0);
+ }
+ alu.dst.sel = ctx->temp_reg;
+ alu.dst.write = 1;
+ alu.last = 1;
+ r = r600_bc_add_alu(ctx->bc, &alu);
+ if (r)
+ return r;
+ /* replicate result */
+ for (i = 0; i < 4; i++) {
+ memset(&alu, 0, sizeof(struct r600_bc_alu));
+ alu.src[0].sel = ctx->temp_reg;
+ alu.inst = V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOV;
+ alu.dst.chan = i;
+ r = tgsi_dst(ctx, &inst->Dst[0], i, &alu.dst);
+ if (r)
+ return r;
+ alu.dst.write = (inst->Dst[0].Register.WriteMask >> i) & 1;
+ if (i == 3)
+ alu.last = 1;
+ r = r600_bc_add_alu(ctx->bc, &alu);
+ if (r)
+ return r;
+ }
+ return 0;
+}
+
+static int tgsi_helper_copy(struct r600_shader_ctx *ctx, struct tgsi_full_instruction *inst)
+{
+ struct r600_bc_alu alu;
+ int i, r;
+
+ r = r600_bc_add_literal(ctx->bc, ctx->value);
+ if (r)
+ return r;
+ for (i = 0; i < 4; i++) {
+ memset(&alu, 0, sizeof(struct r600_bc_alu));
+ if (!(inst->Dst[0].Register.WriteMask & (1 << i))) {
+ alu.inst = V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP;
+ alu.dst.chan = i;
+ } else {
+ alu.inst = V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOV;
+ r = tgsi_dst(ctx, &inst->Dst[0], i, &alu.dst);
+ if (r)
+ return r;
+ alu.src[0].sel = ctx->temp_reg;
+ alu.src[0].chan = i;
+ }
+ if (i == 3) {
+ alu.last = 1;
+ }
+ r = r600_bc_add_alu(ctx->bc, &alu);
+ if (r)
+ return r;
+ }
+ return 0;
+}
+
+static int tgsi_op3(struct r600_shader_ctx *ctx)
+{
+ struct tgsi_full_instruction *inst = &ctx->parse.FullToken.FullInstruction;
+ struct r600_bc_alu_src r600_src[3];
+ struct r600_bc_alu alu;
+ int i, j, r;
+
+ r = tgsi_split_constant(ctx, r600_src);
+ if (r)
+ return r;
+ /* do it in 2 step as op3 doesn't support writemask */
+ for (i = 0; i < 4; i++) {
+ memset(&alu, 0, sizeof(struct r600_bc_alu));
+ alu.inst = ctx->inst_info->r600_opcode;
+ for (j = 0; j < inst->Instruction.NumSrcRegs; j++) {
+ alu.src[j] = r600_src[j];
+ alu.src[j].chan = tgsi_chan(&inst->Src[j], i);
+ }
+ alu.dst.sel = ctx->temp_reg;
+ alu.dst.chan = i;
+ alu.dst.write = 1;
+ alu.is_op3 = 1;
+ if (i == 3) {
+ alu.last = 1;
+ }
+ r = r600_bc_add_alu(ctx->bc, &alu);
+ if (r)
+ return r;
+ }
+ return tgsi_helper_copy(ctx, inst);
}
+
+static int tgsi_dp(struct r600_shader_ctx *ctx)
+{
+ struct tgsi_full_instruction *inst = &ctx->parse.FullToken.FullInstruction;
+ struct r600_bc_alu_src r600_src[3];
+ struct r600_bc_alu alu;
+ int i, j, r;
+
+ r = tgsi_split_constant(ctx, r600_src);
+ if (r)
+ return r;
+ for (i = 0; i < 4; i++) {
+ memset(&alu, 0, sizeof(struct r600_bc_alu));
+ alu.inst = ctx->inst_info->r600_opcode;
+ for (j = 0; j < inst->Instruction.NumSrcRegs; j++) {
+ alu.src[j] = r600_src[j];
+ alu.src[j].chan = tgsi_chan(&inst->Src[j], i);
+ }
+ alu.dst.sel = ctx->temp_reg;
+ alu.dst.chan = i;
+ alu.dst.write = 1;
+ /* handle some special cases */
+ switch (ctx->inst_info->tgsi_opcode) {
+ case TGSI_OPCODE_DP2:
+ if (i > 1) {
+ alu.src[0].sel = alu.src[1].sel = 248;
+ alu.src[0].chan = alu.src[1].chan = 0;
+ }
+ break;
+ case TGSI_OPCODE_DP3:
+ if (i > 2) {
+ alu.src[0].sel = alu.src[1].sel = 248;
+ alu.src[0].chan = alu.src[1].chan = 0;
+ }
+ break;
+ default:
+ break;
+ }
+ if (i == 3) {
+ alu.last = 1;
+ }
+ r = r600_bc_add_alu(ctx->bc, &alu);
+ if (r)
+ return r;
+ }
+ return tgsi_helper_copy(ctx, inst);
+}
+
+static int tgsi_tex(struct r600_shader_ctx *ctx)
+{
+ struct tgsi_full_instruction *inst = &ctx->parse.FullToken.FullInstruction;
+ struct r600_bc_tex tex;
+ struct r600_bc_alu alu;
+ unsigned src_gpr;
+ int r;
+
+ src_gpr = ctx->file_offset[inst->Src[0].Register.File] + inst->Src[0].Register.Index;
+
+ /* Add perspective divide */
+ memset(&alu, 0, sizeof(struct r600_bc_alu));
+ alu.inst = V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIP_IEEE;
+ alu.src[0].sel = src_gpr;
+ alu.src[0].chan = tgsi_chan(&inst->Src[0], 3);
+ alu.dst.sel = ctx->temp_reg;
+ alu.dst.chan = 3;
+ alu.last = 1;
+ alu.dst.write = 1;
+ r = r600_bc_add_alu(ctx->bc, &alu);
+ if (r)
+ return r;
+
+ memset(&alu, 0, sizeof(struct r600_bc_alu));
+ alu.inst = V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MUL;
+ alu.src[0].sel = ctx->temp_reg;
+ alu.src[0].chan = 3;
+ alu.src[1].sel = src_gpr;
+ alu.src[1].chan = tgsi_chan(&inst->Src[0], 0);
+ alu.dst.sel = ctx->temp_reg;
+ alu.dst.chan = 0;
+ alu.dst.write = 1;
+ r = r600_bc_add_alu(ctx->bc, &alu);
+ if (r)
+ return r;
+ memset(&alu, 0, sizeof(struct r600_bc_alu));
+ alu.inst = V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MUL;
+ alu.src[0].sel = ctx->temp_reg;
+ alu.src[0].chan = 3;
+ alu.src[1].sel = src_gpr;
+ alu.src[1].chan = tgsi_chan(&inst->Src[0], 1);
+ alu.dst.sel = ctx->temp_reg;
+ alu.dst.chan = 1;
+ alu.dst.write = 1;
+ r = r600_bc_add_alu(ctx->bc, &alu);
+ if (r)
+ return r;
+ memset(&alu, 0, sizeof(struct r600_bc_alu));
+ alu.inst = V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MUL;
+ alu.src[0].sel = ctx->temp_reg;
+ alu.src[0].chan = 3;
+ alu.src[1].sel = src_gpr;
+ alu.src[1].chan = tgsi_chan(&inst->Src[0], 2);
+ alu.dst.sel = ctx->temp_reg;
+ alu.dst.chan = 2;
+ alu.dst.write = 1;
+ r = r600_bc_add_alu(ctx->bc, &alu);
+ if (r)
+ return r;
+ memset(&alu, 0, sizeof(struct r600_bc_alu));
+ alu.inst = V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOV;
+ alu.src[0].sel = 249;
+ alu.src[0].chan = 0;
+ alu.dst.sel = ctx->temp_reg;
+ alu.dst.chan = 3;
+ alu.last = 1;
+ alu.dst.write = 1;
+ r = r600_bc_add_alu(ctx->bc, &alu);
+ if (r)
+ return r;
+ src_gpr = ctx->temp_reg;
+
+ /* TODO use temp if src_gpr is not a temporary reg (File != TEMPORARY) */
+ memset(&tex, 0, sizeof(struct r600_bc_tex));
+ tex.inst = ctx->inst_info->r600_opcode;
+ tex.resource_id = ctx->file_offset[inst->Src[1].Register.File] + inst->Src[1].Register.Index;
+ tex.sampler_id = tex.resource_id;
+ tex.src_gpr = src_gpr;
+ tex.dst_gpr = ctx->file_offset[inst->Dst[0].Register.File] + inst->Dst[0].Register.Index;
+ tex.dst_sel_x = 0;
+ tex.dst_sel_y = 1;
+ tex.dst_sel_z = 2;
+ tex.dst_sel_w = 3;
+ tex.src_sel_x = 0;
+ tex.src_sel_y = 1;
+ tex.src_sel_z = 2;
+ tex.src_sel_w = 3;
+
+ if (inst->Texture.Texture != TGSI_TEXTURE_RECT) {
+ tex.coord_type_x = 1;
+ tex.coord_type_y = 1;
+ tex.coord_type_z = 1;
+ tex.coord_type_w = 1;
+ }
+ return r600_bc_add_tex(ctx->bc, &tex);
+}
+
+static int tgsi_lrp(struct r600_shader_ctx *ctx)
+{
+ struct tgsi_full_instruction *inst = &ctx->parse.FullToken.FullInstruction;
+ struct r600_bc_alu_src r600_src[3];
+ struct r600_bc_alu alu;
+ unsigned i;
+ int r;
+
+ r = tgsi_split_constant(ctx, r600_src);
+ if (r)
+ return r;
+ /* 1 - src0 */
+ for (i = 0; i < 4; i++) {
+ memset(&alu, 0, sizeof(struct r600_bc_alu));
+ alu.inst = V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_ADD;
+ alu.src[0].sel = 249;
+ alu.src[0].chan = 0;
+ alu.src[1] = r600_src[0];
+ alu.src[1].chan = tgsi_chan(&inst->Src[0], i);
+ alu.src[1].neg = 1;
+ alu.dst.sel = ctx->temp_reg;
+ alu.dst.chan = i;
+ if (i == 3) {
+ alu.last = 1;
+ }
+ alu.dst.write = 1;
+ r = r600_bc_add_alu(ctx->bc, &alu);
+ if (r)
+ return r;
+ }
+ r = r600_bc_add_literal(ctx->bc, ctx->value);
+ if (r)
+ return r;
+
+ /* (1 - src0) * src2 */
+ for (i = 0; i < 4; i++) {
+ memset(&alu, 0, sizeof(struct r600_bc_alu));
+ alu.inst = V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MUL;
+ alu.src[0].sel = ctx->temp_reg;
+ alu.src[0].chan = i;
+ alu.src[1] = r600_src[2];
+ alu.src[1].chan = tgsi_chan(&inst->Src[2], i);
+ alu.dst.sel = ctx->temp_reg;
+ alu.dst.chan = i;
+ if (i == 3) {
+ alu.last = 1;
+ }
+ alu.dst.write = 1;
+ r = r600_bc_add_alu(ctx->bc, &alu);
+ if (r)
+ return r;
+ }
+ r = r600_bc_add_literal(ctx->bc, ctx->value);
+ if (r)
+ return r;
+
+ /* src0 * src1 + (1 - src0) * src2 */
+ for (i = 0; i < 4; i++) {
+ memset(&alu, 0, sizeof(struct r600_bc_alu));
+ alu.inst = V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_MULADD;
+ alu.is_op3 = 1;
+ alu.src[0] = r600_src[0];
+ alu.src[0].chan = tgsi_chan(&inst->Src[0], i);
+ alu.src[1] = r600_src[1];
+ alu.src[1].chan = tgsi_chan(&inst->Src[1], i);
+ alu.src[2].sel = ctx->temp_reg;
+ alu.src[2].chan = i;
+ alu.dst.sel = ctx->temp_reg;
+ alu.dst.chan = i;
+ if (i == 3) {
+ alu.last = 1;
+ }
+ r = r600_bc_add_alu(ctx->bc, &alu);
+ if (r)
+ return r;
+ }
+ return tgsi_helper_copy(ctx, inst);
+}
+
+static struct r600_shader_tgsi_instruction r600_shader_tgsi_instruction[] = {
+ {TGSI_OPCODE_ARL, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+ {TGSI_OPCODE_MOV, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOV, tgsi_op2},
+ {TGSI_OPCODE_LIT, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_lit},
+ {TGSI_OPCODE_RCP, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIP_IEEE, tgsi_trans_srcx_replicate},
+ {TGSI_OPCODE_RSQ, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIPSQRT_IEEE, tgsi_trans_srcx_replicate},
+ {TGSI_OPCODE_EXP, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+ {TGSI_OPCODE_LOG, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+ {TGSI_OPCODE_MUL, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MUL, tgsi_op2},
+ {TGSI_OPCODE_ADD, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_ADD, tgsi_op2},
+ {TGSI_OPCODE_DP3, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_DOT4, tgsi_dp},
+ {TGSI_OPCODE_DP4, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_DOT4, tgsi_dp},
+ {TGSI_OPCODE_DST, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+ {TGSI_OPCODE_MIN, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MIN, tgsi_op2},
+ {TGSI_OPCODE_MAX, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MAX, tgsi_op2},
+ {TGSI_OPCODE_SLT, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SETGT, tgsi_slt},
+ {TGSI_OPCODE_SGE, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+ {TGSI_OPCODE_MAD, 1, V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_MULADD, tgsi_op3},
+ {TGSI_OPCODE_SUB, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_ADD, tgsi_op2},
+ {TGSI_OPCODE_LRP, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_lrp},
+ {TGSI_OPCODE_CND, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+ /* gap */
+ {20, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+ {TGSI_OPCODE_DP2A, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+ /* gap */
+ {22, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+ {23, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+ {TGSI_OPCODE_FRC, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+ {TGSI_OPCODE_CLAMP, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+ {TGSI_OPCODE_FLR, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+ {TGSI_OPCODE_ROUND, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+ {TGSI_OPCODE_EX2, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_EXP_IEEE, tgsi_trans_srcx_replicate},
+ {TGSI_OPCODE_LG2, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+ {TGSI_OPCODE_POW, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+ {TGSI_OPCODE_XPD, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+ /* gap */
+ {32, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+ {TGSI_OPCODE_ABS, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOV, tgsi_op2},
+ {TGSI_OPCODE_RCC, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+ {TGSI_OPCODE_DPH, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+ {TGSI_OPCODE_COS, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+ {TGSI_OPCODE_DDX, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+ {TGSI_OPCODE_DDY, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+ {TGSI_OPCODE_KILP, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, /* predicated kill */
+ {TGSI_OPCODE_PK2H, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+ {TGSI_OPCODE_PK2US, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+ {TGSI_OPCODE_PK4B, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+ {TGSI_OPCODE_PK4UB, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+ {TGSI_OPCODE_RFL, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+ {TGSI_OPCODE_SEQ, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+ {TGSI_OPCODE_SFL, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+ {TGSI_OPCODE_SGT, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+ {TGSI_OPCODE_SIN, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+ {TGSI_OPCODE_SLE, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+ {TGSI_OPCODE_SNE, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+ {TGSI_OPCODE_STR, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+ {TGSI_OPCODE_TEX, 0, 0x10, tgsi_tex},
+ {TGSI_OPCODE_TXD, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+ {TGSI_OPCODE_TXP, 0, 0x10, tgsi_tex},
+ {TGSI_OPCODE_UP2H, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+ {TGSI_OPCODE_UP2US, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+ {TGSI_OPCODE_UP4B, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+ {TGSI_OPCODE_UP4UB, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+ {TGSI_OPCODE_X2D, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+ {TGSI_OPCODE_ARA, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+ {TGSI_OPCODE_ARR, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+ {TGSI_OPCODE_BRA, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+ {TGSI_OPCODE_CAL, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+ {TGSI_OPCODE_RET, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+ {TGSI_OPCODE_SSG, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, /* SGN */
+ {TGSI_OPCODE_CMP, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+ {TGSI_OPCODE_SCS, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+ {TGSI_OPCODE_TXB, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+ {TGSI_OPCODE_NRM, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+ {TGSI_OPCODE_DIV, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+ {TGSI_OPCODE_DP2, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_DOT4, tgsi_dp},
+ {TGSI_OPCODE_TXL, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+ {TGSI_OPCODE_BRK, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+ {TGSI_OPCODE_IF, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+ /* gap */
+ {75, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+ {76, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+ {TGSI_OPCODE_ELSE, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+ {TGSI_OPCODE_ENDIF, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+ /* gap */
+ {79, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+ {80, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+ {TGSI_OPCODE_PUSHA, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+ {TGSI_OPCODE_POPA, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+ {TGSI_OPCODE_CEIL, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+ {TGSI_OPCODE_I2F, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+ {TGSI_OPCODE_NOT, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+ {TGSI_OPCODE_TRUNC, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+ {TGSI_OPCODE_SHL, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+ /* gap */
+ {88, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+ {TGSI_OPCODE_AND, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+ {TGSI_OPCODE_OR, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+ {TGSI_OPCODE_MOD, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+ {TGSI_OPCODE_XOR, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+ {TGSI_OPCODE_SAD, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+ {TGSI_OPCODE_TXF, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+ {TGSI_OPCODE_TXQ, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+ {TGSI_OPCODE_CONT, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+ {TGSI_OPCODE_EMIT, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+ {TGSI_OPCODE_ENDPRIM, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+ {TGSI_OPCODE_BGNLOOP, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+ {TGSI_OPCODE_BGNSUB, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+ {TGSI_OPCODE_ENDLOOP, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+ {TGSI_OPCODE_ENDSUB, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+ /* gap */
+ {103, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+ {104, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+ {105, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+ {106, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+ {TGSI_OPCODE_NOP, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+ /* gap */
+ {108, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+ {109, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+ {110, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+ {111, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+ {TGSI_OPCODE_NRM4, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+ {TGSI_OPCODE_CALLNZ, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+ {TGSI_OPCODE_IFC, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+ {TGSI_OPCODE_BREAKC, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+ {TGSI_OPCODE_KIL, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLGT, tgsi_kill}, /* conditional kill */
+ {TGSI_OPCODE_END, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_end}, /* aka HALT */
+ /* gap */
+ {118, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+ {TGSI_OPCODE_F2I, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+ {TGSI_OPCODE_IDIV, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+ {TGSI_OPCODE_IMAX, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+ {TGSI_OPCODE_IMIN, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+ {TGSI_OPCODE_INEG, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+ {TGSI_OPCODE_ISGE, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+ {TGSI_OPCODE_ISHR, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+ {TGSI_OPCODE_ISLT, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+ {TGSI_OPCODE_F2U, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+ {TGSI_OPCODE_U2F, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+ {TGSI_OPCODE_UADD, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+ {TGSI_OPCODE_UDIV, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+ {TGSI_OPCODE_UMAD, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+ {TGSI_OPCODE_UMAX, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+ {TGSI_OPCODE_UMIN, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+ {TGSI_OPCODE_UMOD, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+ {TGSI_OPCODE_UMUL, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+ {TGSI_OPCODE_USEQ, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+ {TGSI_OPCODE_USGE, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+ {TGSI_OPCODE_USHR, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+ {TGSI_OPCODE_USLT, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+ {TGSI_OPCODE_USNE, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+ {TGSI_OPCODE_SWITCH, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+ {TGSI_OPCODE_CASE, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+ {TGSI_OPCODE_DEFAULT, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+ {TGSI_OPCODE_ENDSWITCH, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+ {TGSI_OPCODE_LAST, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+};
diff --git a/src/gallium/drivers/r600/r600_shader.h b/src/gallium/drivers/r600/r600_shader.h
index 40064ba8a9..2ee7780ead 100644
--- a/src/gallium/drivers/r600/r600_shader.h
+++ b/src/gallium/drivers/r600/r600_shader.h
@@ -23,243 +23,25 @@
#ifndef R600_SHADER_H
#define R600_SHADER_H
-#include "r600_compiler.h"
-#include "radeon.h"
-
-struct r600_shader_operand {
- struct c_vector *vector;
- unsigned sel;
- unsigned chan;
- unsigned neg;
- unsigned abs;
-};
-
-struct r600_shader_vfetch {
- struct list_head head;
- unsigned cf_addr;
- struct r600_shader_operand src[2];
- struct r600_shader_operand dst[4];
-};
-
-struct r600_shader_inst {
- unsigned is_op3;
- unsigned opcode;
- unsigned inst;
- struct r600_shader_operand src[3];
- struct r600_shader_operand dst;
- unsigned last;
-};
-
-struct r600_shader_alu {
- struct list_head head;
- unsigned nalu;
- unsigned nliteral;
- unsigned nconstant;
- struct r600_shader_inst alu[5];
- u32 literal[4];
-};
-
-struct r600_shader_node {
- struct list_head head;
- unsigned cf_id; /**< cf index (in dw) in byte code */
- unsigned cf_addr; /**< instructions index (in dw) in byte code */
- unsigned nslot; /**< number of slot (2 dw) needed by this node */
- unsigned nfetch;
- struct c_node *node; /**< compiler node from which this node originate */
- struct list_head vfetch; /**< list of vfetch instructions */
- struct list_head alu; /**< list of alu instructions */
-};
+#include "r600_asm.h"
struct r600_shader_io {
- unsigned name;
- unsigned gpr;
- int sid;
+ unsigned name;
+ unsigned gpr;
+ unsigned done;
+ int sid;
+ unsigned interpolate;
};
struct r600_shader {
- unsigned stack_size; /**< stack size needed by this shader */
- unsigned ngpr; /**< number of GPR needed by this shader */
- unsigned nconstant; /**< number of constants used by this shader */
- unsigned nresource; /**< number of resources used by this shader */
- unsigned noutput;
- unsigned ninput;
- unsigned nvector;
- unsigned ncf; /**< total number of cf clauses */
- unsigned nslot; /**< total number of slots (2 dw) */
- unsigned flat_shade; /**< are we flat shading */
- struct list_head nodes; /**< list of node */
- struct r600_shader_io input[32];
- struct r600_shader_io output[32];
- /* TODO replace GPR by some better register allocator */
- struct c_vector **gpr;
- unsigned ndw; /**< bytes code size in dw */
- u32 *bcode; /**< bytes code */
- enum pipe_format resource_format[160]; /**< format of resource */
- struct c_shader cshader;
- boolean r6xx_compile;
+ unsigned processor_type;
+ struct r600_bc bc;
+ boolean flat_shade;
+ unsigned ninput;
+ unsigned noutput;
+ struct r600_shader_io input[32];
+ struct r600_shader_io output[32];
+ enum radeon_family family;
};
-void r600_shader_cleanup(struct r600_shader *rshader);
-int r600_shader_register(struct r600_shader *rshader);
-int r600_shader_node(struct r600_shader *shader);
-void r600_shader_node_place(struct r600_shader *rshader);
-int r600_shader_find_gpr(struct r600_shader *rshader, struct c_vector *v, unsigned swizzle,
- struct r600_shader_operand *operand);
-int r600_shader_vfetch_bytecode(struct r600_shader *rshader,
- struct r600_shader_node *rnode,
- struct r600_shader_vfetch *vfetch,
- unsigned *cid);
-int r600_shader_update(struct r600_shader *rshader,
- enum pipe_format *resource_format);
-int r600_shader_legalize(struct r600_shader *rshader);
-int r600_cshader_legalize(struct c_shader *shader);
-
-int r700_shader_translate(struct r600_shader *rshader);
-
-int c_shader_from_tgsi(struct c_shader *shader, unsigned type,
- const struct tgsi_token *tokens);
-int r600_shader_register(struct r600_shader *rshader);
-int r600_shader_translate_rec(struct r600_shader *rshader, struct c_node *node);
-int r700_shader_translate(struct r600_shader *rshader);
-int r600_shader_insert_fetch(struct c_shader *shader);
-
-int r6xx_shader_alu_translate(struct r600_shader *rshader,
- struct r600_shader_node *rnode,
- unsigned *cid);
-
-enum r600_instruction {
- INST_ADD = 0,
- INST_MUL = 1,
- INST_MUL_IEEE = 2,
- INST_MAX = 3,
- INST_MIN = 4,
- INST_MAX_DX10 = 5,
- INST_MIN_DX10 = 6,
- INST_SETE = 7,
- INST_SETGT = 8,
- INST_SETGE = 9,
- INST_SETNE = 10,
- INST_SETE_DX10 = 11,
- INST_SETGT_DX10 = 12,
- INST_SETGE_DX10 = 13,
- INST_SETNE_DX10 = 14,
- INST_FRACT = 15,
- INST_TRUNC = 16,
- INST_CEIL = 17,
- INST_RNDNE = 18,
- INST_FLOOR = 19,
- INST_MOVA = 20,
- INST_MOVA_FLOOR = 21,
- INST_MOVA_INT = 22,
- INST_MOV = 23,
- INST_NOP = 24,
- INST_PRED_SETGT_UINT = 25,
- INST_PRED_SETGE_UINT = 26,
- INST_PRED_SETE = 27,
- INST_PRED_SETGT = 28,
- INST_PRED_SETGE = 29,
- INST_PRED_SETNE = 30,
- INST_PRED_SET_INV = 31,
- INST_PRED_SET_POP = 32,
- INST_PRED_SET_CLR = 33,
- INST_PRED_SET_RESTORE = 34,
- INST_PRED_SETE_PUSH = 35,
- INST_PRED_SETGT_PUSH = 36,
- INST_PRED_SETGE_PUSH = 37,
- INST_PRED_SETNE_PUSH = 38,
- INST_KILLE = 39,
- INST_KILLGT = 40,
- INST_KILLGE = 41,
- INST_KILLNE = 42,
- INST_AND_INT = 43,
- INST_OR_INT = 44,
- INST_XOR_INT = 45,
- INST_NOT_INT = 46,
- INST_ADD_INT = 47,
- INST_SUB_INT = 48,
- INST_MAX_INT = 49,
- INST_MIN_INT = 50,
- INST_MAX_UINT = 51,
- INST_MIN_UINT = 52,
- INST_SETE_INT = 53,
- INST_SETGT_INT = 54,
- INST_SETGE_INT = 55,
- INST_SETNE_INT = 56,
- INST_SETGT_UINT = 57,
- INST_SETGE_UINT = 58,
- INST_KILLGT_UINT = 59,
- INST_KILLGE_UINT = 60,
- INST_PRED_SETE_INT = 61,
- INST_PRED_SETGT_INT = 62,
- INST_PRED_SETGE_INT = 63,
- INST_PRED_SETNE_INT = 64,
- INST_KILLE_INT = 65,
- INST_KILLGT_INT = 66,
- INST_KILLGE_INT = 67,
- INST_KILLNE_INT = 68,
- INST_PRED_SETE_PUSH_INT = 69,
- INST_PRED_SETGT_PUSH_INT = 70,
- INST_PRED_SETGE_PUSH_INT = 71,
- INST_PRED_SETNE_PUSH_INT = 72,
- INST_PRED_SETLT_PUSH_INT = 73,
- INST_PRED_SETLE_PUSH_INT = 74,
- INST_DOT4 = 75,
- INST_DOT4_IEEE = 76,
- INST_CUBE = 77,
- INST_MAX4 = 78,
- INST_MOVA_GPR_INT = 79,
- INST_EXP_IEEE = 80,
- INST_LOG_CLAMPED = 81,
- INST_LOG_IEEE = 82,
- INST_RECIP_CLAMPED = 83,
- INST_RECIP_FF = 84,
- INST_RECIP_IEEE = 85,
- INST_RECIPSQRT_CLAMPED = 86,
- INST_RECIPSQRT_FF = 87,
- INST_RECIPSQRT_IEEE = 88,
- INST_SQRT_IEEE = 89,
- INST_FLT_TO_INT = 90,
- INST_INT_TO_FLT = 91,
- INST_UINT_TO_FLT = 92,
- INST_SIN = 93,
- INST_COS = 94,
- INST_ASHR_INT = 95,
- INST_LSHR_INT = 96,
- INST_LSHL_INT = 97,
- INST_MULLO_INT = 98,
- INST_MULHI_INT = 99,
- INST_MULLO_UINT = 100,
- INST_MULHI_UINT = 101,
- INST_RECIP_INT = 102,
- INST_RECIP_UINT = 103,
- INST_FLT_TO_UINT = 104,
- INST_MUL_LIT = 105,
- INST_MUL_LIT_M2 = 106,
- INST_MUL_LIT_M4 = 107,
- INST_MUL_LIT_D2 = 108,
- INST_MULADD = 109,
- INST_MULADD_M2 = 110,
- INST_MULADD_M4 = 111,
- INST_MULADD_D2 = 112,
- INST_MULADD_IEEE = 113,
- INST_MULADD_IEEE_M2 = 114,
- INST_MULADD_IEEE_M4 = 115,
- INST_MULADD_IEEE_D2 = 116,
- INST_CNDE = 117,
- INST_CNDGT = 118,
- INST_CNDGE = 119,
- INST_CNDE_INT = 120,
- INST_CNDGT_INT = 121,
- INST_CNDGE_INT = 122,
- INST_COUNT
-};
-
-struct r600_instruction_info {
- enum r600_instruction instruction;
- unsigned opcode;
- unsigned is_trans;
- unsigned is_op3;
-};
-
-
#endif
diff --git a/src/gallium/drivers/r600/r600_sq.h b/src/gallium/drivers/r600/r600_sq.h
index 447ba98f00..002660c654 100644
--- a/src/gallium/drivers/r600/r600_sq.h
+++ b/src/gallium/drivers/r600/r600_sq.h
@@ -87,9 +87,9 @@
#define G_SQ_CF_WORD1_BARRIER(x) (((x) >> 31) & 0x1)
#define C_SQ_CF_WORD1_BARRIER 0x7FFFFFFF
#define P_SQ_CF_ALU_WORD0
-#define S_SQ_CF_ALU_WORD0_ALU_ADDR(x) (((x) & 0x3FFFFF) << 0)
-#define G_SQ_CF_ALU_WORD0_ALU_ADDR(x) (((x) >> 0) & 0x3FFFFF)
-#define C_SQ_CF_ALU_WORD0_ALU_ADDR 0xFFC00000
+#define S_SQ_CF_ALU_WORD0_ADDR(x) (((x) & 0x3FFFFF) << 0)
+#define G_SQ_CF_ALU_WORD0_ADDR(x) (((x) >> 0) & 0x3FFFFF)
+#define C_SQ_CF_ALU_WORD0_ADDR 0xFFC00000
#define S_SQ_CF_ALU_WORD0_KCACHE_BANK0(x) (((x) & 0xF) << 22)
#define G_SQ_CF_ALU_WORD0_KCACHE_BANK0(x) (((x) >> 22) & 0xF)
#define C_SQ_CF_ALU_WORD0_KCACHE_BANK0 0xFC3FFFFF
@@ -109,15 +109,15 @@
#define S_SQ_CF_ALU_WORD1_KCACHE_ADDR1(x) (((x) & 0xFF) << 10)
#define G_SQ_CF_ALU_WORD1_KCACHE_ADDR1(x) (((x) >> 10) & 0xFF)
#define C_SQ_CF_ALU_WORD1_KCACHE_ADDR1 0xFFFC03FF
-#define S_SQ_CF_ALU_WORD1_ALU_COUNT(x) (((x) & 0x7F) << 18)
-#define G_SQ_CF_ALU_WORD1_ALU_COUNT(x) (((x) >> 18) & 0x7F)
-#define C_SQ_CF_ALU_WORD1_ALU_COUNT 0xFE03FFFF
+#define S_SQ_CF_ALU_WORD1_COUNT(x) (((x) & 0x7F) << 18)
+#define G_SQ_CF_ALU_WORD1_COUNT(x) (((x) >> 18) & 0x7F)
+#define C_SQ_CF_ALU_WORD1_COUNT 0xFE03FFFF
#define S_SQ_CF_ALU_WORD1_USES_WATERFALL(x) (((x) & 0x1) << 25)
#define G_SQ_CF_ALU_WORD1_USES_WATERFALL(x) (((x) >> 25) & 0x1)
#define C_SQ_CF_ALU_WORD1_USES_WATERFALL 0xFDFFFFFF
-#define S_SQ_CF_ALU_WORD1_CF_ALU_INST(x) (((x) & 0xF) << 26)
-#define G_SQ_CF_ALU_WORD1_CF_ALU_INST(x) (((x) >> 26) & 0xF)
-#define C_SQ_CF_ALU_WORD1_CF_ALU_INST 0xC3FFFFFF
+#define S_SQ_CF_ALU_WORD1_CF_INST(x) (((x) & 0xF) << 26)
+#define G_SQ_CF_ALU_WORD1_CF_INST(x) (((x) >> 26) & 0xF)
+#define C_SQ_CF_ALU_WORD1_CF_INST 0xC3FFFFFF
#define V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU 0x00000008
#define V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_PUSH_BEFORE 0x00000009
#define V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_POP_AFTER 0x0000000A
@@ -546,6 +546,8 @@
#define S_SQ_TEX_WORD1_COORD_TYPE_X(x) (((x) & 0x1) << 28)
#define G_SQ_TEX_WORD1_COORD_TYPE_X(x) (((x) >> 28) & 0x1)
#define C_SQ_TEX_WORD1_COORD_TYPE_X 0xEFFFFFFF
+#define V_SQ_TEX_WORD1_COORD_UNNORMALIZED 0x00000000
+#define V_SQ_TEX_WORD1_COORD_NORMALIZED 0x00000001
#define S_SQ_TEX_WORD1_COORD_TYPE_Y(x) (((x) & 0x1) << 29)
#define G_SQ_TEX_WORD1_COORD_TYPE_Y(x) (((x) >> 29) & 0x1)
#define C_SQ_TEX_WORD1_COORD_TYPE_Y 0xDFFFFFFF
diff --git a/src/gallium/drivers/r600/r600_state.c b/src/gallium/drivers/r600/r600_state.c
index 4150f88785..3efd409ae0 100644
--- a/src/gallium/drivers/r600/r600_state.c
+++ b/src/gallium/drivers/r600/r600_state.c
@@ -24,36 +24,605 @@
* Jerome Glisse
*/
#include <stdio.h>
-#include <util/u_inlines.h>
-#include <util/u_format.h>
-#include <util/u_memory.h>
+#include <errno.h>
+#include "util/u_inlines.h"
+#include "util/u_format.h"
+#include "util/u_memory.h"
#include "r600_screen.h"
-#include "r600_texture.h"
#include "r600_context.h"
+#include "r600_resource.h"
#include "r600d.h"
+#include "r600_state_inlines.h"
+static void *r600_create_blend_state(struct pipe_context *ctx,
+ const struct pipe_blend_state *state)
+{
+ struct r600_context *rctx = r600_context(ctx);
+
+ return r600_context_state(rctx, pipe_blend_type, state);
+}
+
+static void *r600_create_dsa_state(struct pipe_context *ctx,
+ const struct pipe_depth_stencil_alpha_state *state)
+{
+ struct r600_context *rctx = r600_context(ctx);
+
+ return r600_context_state(rctx, pipe_dsa_type, state);
+}
+
+static void *r600_create_rs_state(struct pipe_context *ctx,
+ const struct pipe_rasterizer_state *state)
+{
+ struct r600_context *rctx = r600_context(ctx);
+
+ return r600_context_state(rctx, pipe_rasterizer_type, state);
+}
+
+static void *r600_create_sampler_state(struct pipe_context *ctx,
+ const struct pipe_sampler_state *state)
+{
+ struct r600_context *rctx = r600_context(ctx);
+
+ return r600_context_state(rctx, pipe_sampler_type, state);
+}
+
+static void r600_sampler_view_destroy(struct pipe_context *ctx,
+ struct pipe_sampler_view *state)
+{
+ struct r600_context_state *rstate = (struct r600_context_state *)state;
+
+ r600_context_state_decref(rstate);
+}
+
+static struct pipe_sampler_view *r600_create_sampler_view(struct pipe_context *ctx,
+ struct pipe_resource *texture,
+ const struct pipe_sampler_view *state)
+{
+ struct r600_context *rctx = r600_context(ctx);
+ struct r600_context_state *rstate;
+
+ rstate = r600_context_state(rctx, pipe_sampler_type, state);
+ pipe_reference(NULL, &texture->reference);
+ rstate->state.sampler_view.texture = texture;
+ rstate->state.sampler_view.reference.count = 1;
+ rstate->state.sampler_view.context = ctx;
+ return &rstate->state.sampler_view;
+}
+
+static void *r600_create_shader_state(struct pipe_context *ctx,
+ const struct pipe_shader_state *state)
+{
+ struct r600_context *rctx = r600_context(ctx);
+
+ return r600_context_state(rctx, pipe_shader_type, state);
+}
+
+static void *r600_create_vertex_elements(struct pipe_context *ctx,
+ unsigned count,
+ const struct pipe_vertex_element *elements)
+{
+ struct r600_vertex_element *v = CALLOC_STRUCT(r600_vertex_element);
+
+ assert(count < 32);
+ v->count = count;
+ memcpy(v->elements, elements, count * sizeof(struct pipe_vertex_element));
+ v->refcount = 1;
+ return v;
+}
+
+static void r600_bind_state(struct pipe_context *ctx, void *state)
+{
+ struct r600_context *rctx = r600_context(ctx);
+ struct r600_context_state *rstate = (struct r600_context_state *)state;
+
+ if (state == NULL)
+ return;
+ switch (rstate->type) {
+ case pipe_rasterizer_type:
+ rctx->rasterizer = r600_context_state_decref(rctx->rasterizer);
+ rctx->rasterizer = r600_context_state_incref(rstate);
+ break;
+ case pipe_poly_stipple_type:
+ rctx->poly_stipple = r600_context_state_decref(rctx->poly_stipple);
+ rctx->poly_stipple = r600_context_state_incref(rstate);
+ break;
+ case pipe_scissor_type:
+ rctx->scissor = r600_context_state_decref(rctx->scissor);
+ rctx->scissor = r600_context_state_incref(rstate);
+ break;
+ case pipe_clip_type:
+ rctx->clip = r600_context_state_decref(rctx->clip);
+ rctx->clip = r600_context_state_incref(rstate);
+ break;
+ case pipe_depth_type:
+ rctx->depth = r600_context_state_decref(rctx->depth);
+ rctx->depth = r600_context_state_incref(rstate);
+ break;
+ case pipe_stencil_type:
+ rctx->stencil = r600_context_state_decref(rctx->stencil);
+ rctx->stencil = r600_context_state_incref(rstate);
+ break;
+ case pipe_alpha_type:
+ rctx->alpha = r600_context_state_decref(rctx->alpha);
+ rctx->alpha = r600_context_state_incref(rstate);
+ break;
+ case pipe_dsa_type:
+ rctx->dsa = r600_context_state_decref(rctx->dsa);
+ rctx->dsa = r600_context_state_incref(rstate);
+ break;
+ case pipe_blend_type:
+ rctx->blend = r600_context_state_decref(rctx->blend);
+ rctx->blend = r600_context_state_incref(rstate);
+ break;
+ case pipe_framebuffer_type:
+ rctx->framebuffer = r600_context_state_decref(rctx->framebuffer);
+ rctx->framebuffer = r600_context_state_incref(rstate);
+ break;
+ case pipe_stencil_ref_type:
+ rctx->stencil_ref = r600_context_state_decref(rctx->stencil_ref);
+ rctx->stencil_ref = r600_context_state_incref(rstate);
+ break;
+ case pipe_viewport_type:
+ rctx->viewport = r600_context_state_decref(rctx->viewport);
+ rctx->viewport = r600_context_state_incref(rstate);
+ break;
+ case pipe_shader_type:
+ case pipe_sampler_type:
+ case pipe_sampler_view_type:
+ default:
+ R600_ERR("invalid type %d\n", rstate->type);
+ return;
+ }
+}
+
+static void r600_bind_ps_shader(struct pipe_context *ctx, void *state)
+{
+ struct r600_context *rctx = r600_context(ctx);
+ struct r600_context_state *rstate = (struct r600_context_state *)state;
+
+ rctx->ps_shader = r600_context_state_decref(rctx->ps_shader);
+ rctx->ps_shader = r600_context_state_incref(rstate);
+}
+
+static void r600_bind_vs_shader(struct pipe_context *ctx, void *state)
+{
+ struct r600_context *rctx = r600_context(ctx);
+ struct r600_context_state *rstate = (struct r600_context_state *)state;
+
+ rctx->vs_shader = r600_context_state_decref(rctx->vs_shader);
+ rctx->vs_shader = r600_context_state_incref(rstate);
+}
+
+static void r600_delete_vertex_element(struct pipe_context *ctx, void *state)
+{
+ struct r600_vertex_element *v = (struct r600_vertex_element*)state;
+
+ if (v == NULL)
+ return;
+ if (--v->refcount)
+ return;
+ free(v);
+}
+
+static void r600_bind_vertex_elements(struct pipe_context *ctx, void *state)
+{
+ struct r600_context *rctx = r600_context(ctx);
+ struct r600_vertex_element *v = (struct r600_vertex_element*)state;
+
+ r600_delete_vertex_element(ctx, rctx->vertex_elements);
+ rctx->vertex_elements = v;
+ if (v) {
+ v->refcount++;
+ }
+}
+
+static void r600_bind_ps_sampler(struct pipe_context *ctx,
+ unsigned count, void **states)
+{
+ struct r600_context *rctx = r600_context(ctx);
+ struct r600_context_state *rstate;
+ unsigned i;
+
+ for (i = 0; i < rctx->ps_nsampler; i++) {
+ rctx->ps_sampler[i] = r600_context_state_decref(rctx->ps_sampler[i]);
+ }
+ for (i = 0; i < count; i++) {
+ rstate = (struct r600_context_state *)states[i];
+ rctx->ps_sampler[i] = r600_context_state_incref(rstate);
+ }
+ rctx->ps_nsampler = count;
+}
+
+static void r600_bind_vs_sampler(struct pipe_context *ctx,
+ unsigned count, void **states)
+{
+ struct r600_context *rctx = r600_context(ctx);
+ struct r600_context_state *rstate;
+ unsigned i;
+
+ for (i = 0; i < rctx->vs_nsampler; i++) {
+ rctx->vs_sampler[i] = r600_context_state_decref(rctx->vs_sampler[i]);
+ }
+ for (i = 0; i < count; i++) {
+ rstate = (struct r600_context_state *)states[i];
+ rctx->vs_sampler[i] = r600_context_state_incref(rstate);
+ }
+ rctx->vs_nsampler = count;
+}
static void r600_delete_state(struct pipe_context *ctx, void *state)
{
- struct radeon_state *rstate = state;
+ struct r600_context_state *rstate = (struct r600_context_state *)state;
- radeon_state_decref(rstate);
+ r600_context_state_decref(rstate);
}
-static void *r600_create_blend_state(struct pipe_context *ctx,
- const struct pipe_blend_state *state)
+static void r600_set_blend_color(struct pipe_context *ctx,
+ const struct pipe_blend_color *color)
+{
+ struct r600_context *rctx = r600_context(ctx);
+
+ rctx->blend_color = *color;
+}
+
+static void r600_set_clip_state(struct pipe_context *ctx,
+ const struct pipe_clip_state *state)
+{
+}
+
+static void r600_set_constant_buffer(struct pipe_context *ctx,
+ uint shader, uint index,
+ struct pipe_resource *buffer)
{
struct r600_screen *rscreen = r600_screen(ctx->screen);
+ struct r600_context *rctx = r600_context(ctx);
+ unsigned nconstant = 0, i, type, id;
+ struct radeon_state *rstate;
+ struct pipe_transfer *transfer;
+ u32 *ptr;
+
+ switch (shader) {
+ case PIPE_SHADER_VERTEX:
+ id = R600_VS_CONSTANT;
+ type = R600_VS_CONSTANT_TYPE;
+ break;
+ case PIPE_SHADER_FRAGMENT:
+ id = R600_PS_CONSTANT;
+ type = R600_PS_CONSTANT_TYPE;
+ break;
+ default:
+ R600_ERR("unsupported %d\n", shader);
+ return;
+ }
+ if (buffer && buffer->width0 > 0) {
+ nconstant = buffer->width0 / 16;
+ ptr = pipe_buffer_map(ctx, buffer, PIPE_TRANSFER_READ, &transfer);
+ if (ptr == NULL)
+ return;
+ for (i = 0; i < nconstant; i++) {
+ rstate = radeon_state(rscreen->rw, type, id + i);
+ if (rstate == NULL)
+ return;
+ rstate->states[R600_PS_CONSTANT__SQ_ALU_CONSTANT0_0] = ptr[i * 4 + 0];
+ rstate->states[R600_PS_CONSTANT__SQ_ALU_CONSTANT1_0] = ptr[i * 4 + 1];
+ rstate->states[R600_PS_CONSTANT__SQ_ALU_CONSTANT2_0] = ptr[i * 4 + 2];
+ rstate->states[R600_PS_CONSTANT__SQ_ALU_CONSTANT3_0] = ptr[i * 4 + 3];
+ if (radeon_state_pm4(rstate))
+ return;
+ if (radeon_draw_set_new(rctx->draw, rstate))
+ return;
+ }
+ pipe_buffer_unmap(ctx, buffer, transfer);
+ }
+}
+
+static void r600_set_ps_sampler_view(struct pipe_context *ctx,
+ unsigned count,
+ struct pipe_sampler_view **views)
+{
+ struct r600_context *rctx = r600_context(ctx);
+ struct r600_context_state *rstate;
+ unsigned i;
+
+ for (i = 0; i < rctx->ps_nsampler_view; i++) {
+ rctx->ps_sampler_view[i] = r600_context_state_decref(rctx->ps_sampler_view[i]);
+ }
+ for (i = 0; i < count; i++) {
+ rstate = (struct r600_context_state *)views[i];
+ rctx->ps_sampler_view[i] = r600_context_state_incref(rstate);
+ }
+ rctx->ps_nsampler_view = count;
+}
+
+static void r600_set_vs_sampler_view(struct pipe_context *ctx,
+ unsigned count,
+ struct pipe_sampler_view **views)
+{
+ struct r600_context *rctx = r600_context(ctx);
+ struct r600_context_state *rstate;
+ unsigned i;
+
+ for (i = 0; i < rctx->vs_nsampler_view; i++) {
+ rctx->vs_sampler_view[i] = r600_context_state_decref(rctx->vs_sampler_view[i]);
+ }
+ for (i = 0; i < count; i++) {
+ rstate = (struct r600_context_state *)views[i];
+ rctx->vs_sampler_view[i] = r600_context_state_incref(rstate);
+ }
+ rctx->vs_nsampler_view = count;
+}
+
+static void r600_set_framebuffer_state(struct pipe_context *ctx,
+ const struct pipe_framebuffer_state *state)
+{
+ struct r600_context *rctx = r600_context(ctx);
+ struct r600_context_state *rstate;
+
+ rstate = r600_context_state(rctx, pipe_framebuffer_type, state);
+ r600_bind_state(ctx, rstate);
+}
+
+static void r600_set_polygon_stipple(struct pipe_context *ctx,
+ const struct pipe_poly_stipple *state)
+{
+}
+
+static void r600_set_sample_mask(struct pipe_context *pipe, unsigned sample_mask)
+{
+}
+
+static void r600_set_scissor_state(struct pipe_context *ctx,
+ const struct pipe_scissor_state *state)
+{
+ struct r600_context *rctx = r600_context(ctx);
+ struct r600_context_state *rstate;
+
+ rstate = r600_context_state(rctx, pipe_scissor_type, state);
+ r600_bind_state(ctx, rstate);
+ /* refcount is taken care of this */
+ r600_delete_state(ctx, rstate);
+}
+
+static void r600_set_stencil_ref(struct pipe_context *ctx,
+ const struct pipe_stencil_ref *state)
+{
+ struct r600_context *rctx = r600_context(ctx);
+ struct r600_context_state *rstate;
+
+ rstate = r600_context_state(rctx, pipe_stencil_ref_type, state);
+ r600_bind_state(ctx, rstate);
+ /* refcount is taken care of this */
+ r600_delete_state(ctx, rstate);
+}
+
+static void r600_set_vertex_buffers(struct pipe_context *ctx,
+ unsigned count,
+ const struct pipe_vertex_buffer *buffers)
+{
+ struct r600_context *rctx = r600_context(ctx);
+ unsigned i;
+
+ for (i = 0; i < rctx->nvertex_buffer; i++) {
+ pipe_resource_reference(&rctx->vertex_buffer[i].buffer, NULL);
+ }
+ memcpy(rctx->vertex_buffer, buffers, sizeof(struct pipe_vertex_buffer) * count);
+ for (i = 0; i < count; i++) {
+ rctx->vertex_buffer[i].buffer = NULL;
+ pipe_resource_reference(&rctx->vertex_buffer[i].buffer, buffers[i].buffer);
+ }
+ rctx->nvertex_buffer = count;
+}
+
+static void r600_set_index_buffer(struct pipe_context *ctx,
+ const struct pipe_index_buffer *ib)
+{
+ struct r600_context *rctx = r600_context(ctx);
+
+ if (ib) {
+ pipe_resource_reference(&rctx->index_buffer.buffer, ib->buffer);
+ memcpy(&rctx->index_buffer, ib, sizeof(rctx->index_buffer));
+ } else {
+ pipe_resource_reference(&rctx->index_buffer.buffer, NULL);
+ memset(&rctx->index_buffer, 0, sizeof(rctx->index_buffer));
+ }
+
+ /* TODO make this more like a state */
+}
+
+static void r600_set_viewport_state(struct pipe_context *ctx,
+ const struct pipe_viewport_state *state)
+{
+ struct r600_context *rctx = r600_context(ctx);
+ struct r600_context_state *rstate;
+
+ rstate = r600_context_state(rctx, pipe_viewport_type, state);
+ r600_bind_state(ctx, rstate);
+ r600_delete_state(ctx, rstate);
+}
+
+void r600_init_state_functions(struct r600_context *rctx)
+{
+ rctx->context.create_blend_state = r600_create_blend_state;
+ rctx->context.create_depth_stencil_alpha_state = r600_create_dsa_state;
+ rctx->context.create_fs_state = r600_create_shader_state;
+ rctx->context.create_rasterizer_state = r600_create_rs_state;
+ rctx->context.create_sampler_state = r600_create_sampler_state;
+ rctx->context.create_sampler_view = r600_create_sampler_view;
+ rctx->context.create_vertex_elements_state = r600_create_vertex_elements;
+ rctx->context.create_vs_state = r600_create_shader_state;
+ rctx->context.bind_blend_state = r600_bind_state;
+ rctx->context.bind_depth_stencil_alpha_state = r600_bind_state;
+ rctx->context.bind_fragment_sampler_states = r600_bind_ps_sampler;
+ rctx->context.bind_fs_state = r600_bind_ps_shader;
+ rctx->context.bind_rasterizer_state = r600_bind_state;
+ rctx->context.bind_vertex_elements_state = r600_bind_vertex_elements;
+ rctx->context.bind_vertex_sampler_states = r600_bind_vs_sampler;
+ rctx->context.bind_vs_state = r600_bind_vs_shader;
+ rctx->context.delete_blend_state = r600_delete_state;
+ rctx->context.delete_depth_stencil_alpha_state = r600_delete_state;
+ rctx->context.delete_fs_state = r600_delete_state;
+ rctx->context.delete_rasterizer_state = r600_delete_state;
+ rctx->context.delete_sampler_state = r600_delete_state;
+ rctx->context.delete_vertex_elements_state = r600_delete_vertex_element;
+ rctx->context.delete_vs_state = r600_delete_state;
+ rctx->context.set_blend_color = r600_set_blend_color;
+ rctx->context.set_clip_state = r600_set_clip_state;
+ rctx->context.set_constant_buffer = r600_set_constant_buffer;
+ rctx->context.set_fragment_sampler_views = r600_set_ps_sampler_view;
+ rctx->context.set_framebuffer_state = r600_set_framebuffer_state;
+ rctx->context.set_polygon_stipple = r600_set_polygon_stipple;
+ rctx->context.set_sample_mask = r600_set_sample_mask;
+ rctx->context.set_scissor_state = r600_set_scissor_state;
+ rctx->context.set_stencil_ref = r600_set_stencil_ref;
+ rctx->context.set_vertex_buffers = r600_set_vertex_buffers;
+ rctx->context.set_index_buffer = r600_set_index_buffer;
+ rctx->context.set_vertex_sampler_views = r600_set_vs_sampler_view;
+ rctx->context.set_viewport_state = r600_set_viewport_state;
+ rctx->context.sampler_view_destroy = r600_sampler_view_destroy;
+}
+
+struct r600_context_state *r600_context_state_incref(struct r600_context_state *rstate)
+{
+ if (rstate == NULL)
+ return NULL;
+ rstate->refcount++;
+ return rstate;
+}
+
+struct r600_context_state *r600_context_state_decref(struct r600_context_state *rstate)
+{
+ unsigned i;
+
+ if (rstate == NULL)
+ return NULL;
+ if (--rstate->refcount)
+ return NULL;
+ switch (rstate->type) {
+ case pipe_sampler_view_type:
+ pipe_resource_reference(&rstate->state.sampler_view.texture, NULL);
+ break;
+ case pipe_framebuffer_type:
+ for (i = 0; i < rstate->state.framebuffer.nr_cbufs; i++) {
+ pipe_surface_reference(&rstate->state.framebuffer.cbufs[i], NULL);
+ }
+ pipe_surface_reference(&rstate->state.framebuffer.zsbuf, NULL);
+ break;
+ case pipe_viewport_type:
+ case pipe_depth_type:
+ case pipe_rasterizer_type:
+ case pipe_poly_stipple_type:
+ case pipe_scissor_type:
+ case pipe_clip_type:
+ case pipe_stencil_type:
+ case pipe_alpha_type:
+ case pipe_dsa_type:
+ case pipe_blend_type:
+ case pipe_stencil_ref_type:
+ case pipe_shader_type:
+ case pipe_sampler_type:
+ break;
+ default:
+ R600_ERR("invalid type %d\n", rstate->type);
+ return NULL;
+ }
+ radeon_state_decref(rstate->rstate);
+ FREE(rstate);
+ return NULL;
+}
+
+struct r600_context_state *r600_context_state(struct r600_context *rctx, unsigned type, const void *state)
+{
+ struct r600_context_state *rstate = CALLOC_STRUCT(r600_context_state);
+ const union pipe_states *states = state;
+ unsigned i;
+ int r;
+
+ if (rstate == NULL)
+ return NULL;
+ rstate->type = type;
+ rstate->refcount = 1;
+
+ switch (rstate->type) {
+ case pipe_sampler_view_type:
+ rstate->state.sampler_view = (*states).sampler_view;
+ rstate->state.sampler_view.texture = NULL;
+ break;
+ case pipe_framebuffer_type:
+ rstate->state.framebuffer = (*states).framebuffer;
+ for (i = 0; i < rstate->state.framebuffer.nr_cbufs; i++) {
+ pipe_surface_reference(&rstate->state.framebuffer.cbufs[i],
+ (*states).framebuffer.cbufs[i]);
+ }
+ pipe_surface_reference(&rstate->state.framebuffer.zsbuf,
+ (*states).framebuffer.zsbuf);
+ break;
+ case pipe_viewport_type:
+ rstate->state.viewport = (*states).viewport;
+ break;
+ case pipe_depth_type:
+ rstate->state.depth = (*states).depth;
+ break;
+ case pipe_rasterizer_type:
+ rstate->state.rasterizer = (*states).rasterizer;
+ break;
+ case pipe_poly_stipple_type:
+ rstate->state.poly_stipple = (*states).poly_stipple;
+ break;
+ case pipe_scissor_type:
+ rstate->state.scissor = (*states).scissor;
+ break;
+ case pipe_clip_type:
+ rstate->state.clip = (*states).clip;
+ break;
+ case pipe_stencil_type:
+ rstate->state.stencil = (*states).stencil;
+ break;
+ case pipe_alpha_type:
+ rstate->state.alpha = (*states).alpha;
+ break;
+ case pipe_dsa_type:
+ rstate->state.dsa = (*states).dsa;
+ break;
+ case pipe_blend_type:
+ rstate->state.blend = (*states).blend;
+ break;
+ case pipe_stencil_ref_type:
+ rstate->state.stencil_ref = (*states).stencil_ref;
+ break;
+ case pipe_shader_type:
+ rstate->state.shader = (*states).shader;
+ r = r600_pipe_shader_create(&rctx->context, rstate, rstate->state.shader.tokens);
+ if (r) {
+ r600_context_state_decref(rstate);
+ return NULL;
+ }
+ break;
+ case pipe_sampler_type:
+ rstate->state.sampler = (*states).sampler;
+ break;
+ default:
+ R600_ERR("invalid type %d\n", rstate->type);
+ FREE(rstate);
+ return NULL;
+ }
+ return rstate;
+}
+
+static struct radeon_state *r600_blend(struct r600_context *rctx)
+{
+ struct r600_screen *rscreen = rctx->screen;
struct radeon_state *rstate;
+ const struct pipe_blend_state *state = &rctx->blend->state.blend;
+ int i;
rstate = radeon_state(rscreen->rw, R600_BLEND_TYPE, R600_BLEND);
if (rstate == NULL)
return NULL;
- rstate->states[R600_BLEND__CB_BLEND_RED] = 0x00000000;
- rstate->states[R600_BLEND__CB_BLEND_GREEN] = 0x00000000;
- rstate->states[R600_BLEND__CB_BLEND_BLUE] = 0x00000000;
- rstate->states[R600_BLEND__CB_BLEND_ALPHA] = 0x00000000;
- rstate->states[R600_BLEND__CB_BLEND0_CONTROL] = 0x00010001;
+ rstate->states[R600_BLEND__CB_BLEND_RED] = fui(rctx->blend_color.color[0]);
+ rstate->states[R600_BLEND__CB_BLEND_GREEN] = fui(rctx->blend_color.color[1]);
+ rstate->states[R600_BLEND__CB_BLEND_BLUE] = fui(rctx->blend_color.color[2]);
+ rstate->states[R600_BLEND__CB_BLEND_ALPHA] = fui(rctx->blend_color.color[3]);
+ rstate->states[R600_BLEND__CB_BLEND0_CONTROL] = 0x00000000;
rstate->states[R600_BLEND__CB_BLEND1_CONTROL] = 0x00000000;
rstate->states[R600_BLEND__CB_BLEND2_CONTROL] = 0x00000000;
rstate->states[R600_BLEND__CB_BLEND3_CONTROL] = 0x00000000;
@@ -62,6 +631,36 @@ static void *r600_create_blend_state(struct pipe_context *ctx,
rstate->states[R600_BLEND__CB_BLEND6_CONTROL] = 0x00000000;
rstate->states[R600_BLEND__CB_BLEND7_CONTROL] = 0x00000000;
rstate->states[R600_BLEND__CB_BLEND_CONTROL] = 0x00000000;
+
+ for (i = 0; i < 8; i++) {
+ unsigned eqRGB = state->rt[i].rgb_func;
+ unsigned srcRGB = state->rt[i].rgb_src_factor;
+ unsigned dstRGB = state->rt[i].rgb_dst_factor;
+
+ unsigned eqA = state->rt[i].alpha_func;
+ unsigned srcA = state->rt[i].alpha_src_factor;
+ unsigned dstA = state->rt[i].alpha_dst_factor;
+ uint32_t bc = 0;
+
+ if (!state->rt[i].blend_enable)
+ continue;
+
+ bc |= S_028804_COLOR_COMB_FCN(r600_translate_blend_function(eqRGB));
+ bc |= S_028804_COLOR_SRCBLEND(r600_translate_blend_factor(srcRGB));
+ bc |= S_028804_COLOR_DESTBLEND(r600_translate_blend_factor(dstRGB));
+
+ if (srcA != srcRGB || dstA != dstRGB || eqA != eqRGB) {
+ bc |= S_028804_SEPARATE_ALPHA_BLEND(1);
+ bc |= S_028804_ALPHA_COMB_FCN(r600_translate_blend_function(eqA));
+ bc |= S_028804_ALPHA_SRCBLEND(r600_translate_blend_factor(srcA));
+ bc |= S_028804_ALPHA_DESTBLEND(r600_translate_blend_factor(dstA));
+ }
+
+ rstate->states[R600_BLEND__CB_BLEND0_CONTROL + i] = bc;
+ if (i == 0)
+ rstate->states[R600_BLEND__CB_BLEND_CONTROL] = bc;
+ }
+
if (radeon_state_pm4(rstate)) {
radeon_state_decref(rstate);
return NULL;
@@ -69,38 +668,24 @@ static void *r600_create_blend_state(struct pipe_context *ctx,
return rstate;
}
-static void r600_bind_blend_state(struct pipe_context *ctx, void *state)
-{
- struct r600_context *rctx = r600_context(ctx);
- radeon_draw_set(rctx->draw, state);
-}
-
-static void r600_set_blend_color(struct pipe_context *ctx,
- const struct pipe_blend_color *color)
+static struct radeon_state *r600_cb(struct r600_context *rctx, int cb)
{
-}
-
-static void r600_set_clip_state(struct pipe_context *ctx,
- const struct pipe_clip_state *state)
-{
-}
-
-static void r600_set_framebuffer_state(struct pipe_context *ctx,
- const struct pipe_framebuffer_state *state)
-{
- struct r600_screen *rscreen = r600_screen(ctx->screen);
- struct r600_context *rctx = r600_context(ctx);
- struct r600_texture *rtex;
- struct r600_buffer *rbuffer;
+ struct r600_screen *rscreen = rctx->screen;
+ struct r600_resource_texture *rtex;
+ struct r600_resource *rbuffer;
struct radeon_state *rstate;
- unsigned level = state->cbufs[0]->level;
+ const struct pipe_framebuffer_state *state = &rctx->framebuffer->state.framebuffer;
+ unsigned level = state->cbufs[cb]->level;
unsigned pitch, slice;
+ unsigned color_info;
+ unsigned format, swap, ntype;
+ const struct util_format_description *desc;
- rstate = radeon_state(rscreen->rw, R600_CB0_TYPE, R600_CB0);
+ rstate = radeon_state(rscreen->rw, R600_CB0_TYPE + cb, R600_CB0 + cb);
if (rstate == NULL)
- return;
- rtex = (struct r600_texture*)state->cbufs[0]->texture;
- rbuffer = (struct r600_buffer*)rtex->buffer;
+ return NULL;
+ rtex = (struct r600_resource_texture*)state->cbufs[cb]->texture;
+ rbuffer = &rtex->resource;
rstate->bo[0] = radeon_bo_incref(rscreen->rw, rbuffer->bo);
rstate->bo[1] = radeon_bo_incref(rscreen->rw, rbuffer->bo);
rstate->bo[2] = radeon_bo_incref(rscreen->rw, rbuffer->bo);
@@ -108,10 +693,25 @@ static void r600_set_framebuffer_state(struct pipe_context *ctx,
rstate->placement[2] = RADEON_GEM_DOMAIN_GTT;
rstate->placement[4] = RADEON_GEM_DOMAIN_GTT;
rstate->nbo = 3;
- pitch = rtex->pitch[level] / 8 - 1;
- slice = rtex->pitch[level] * state->cbufs[0]->height / 64 - 1;
+ pitch = (rtex->pitch[level] / rtex->bpt) / 8 - 1;
+ slice = (rtex->pitch[level] / rtex->bpt) * state->cbufs[cb]->height / 64 - 1;
+
+ ntype = 0;
+ desc = util_format_description(rtex->resource.base.b.format);
+ if (desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB)
+ ntype = V_0280A0_NUMBER_SRGB;
+
+ format = r600_translate_colorformat(rtex->resource.base.b.format);
+ swap = r600_translate_colorswap(rtex->resource.base.b.format);
+
+ color_info = S_0280A0_FORMAT(format) |
+ S_0280A0_COMP_SWAP(swap) |
+ S_0280A0_BLEND_CLAMP(1) |
+ S_0280A0_SOURCE_FORMAT(1) |
+ S_0280A0_NUMBER_TYPE(ntype);
+
rstate->states[R600_CB0__CB_COLOR0_BASE] = 0x00000000;
- rstate->states[R600_CB0__CB_COLOR0_INFO] = 0x08110068;
+ rstate->states[R600_CB0__CB_COLOR0_INFO] = color_info;
rstate->states[R600_CB0__CB_COLOR0_SIZE] = S_028060_PITCH_TILE_MAX(pitch) |
S_028060_SLICE_TILE_MAX(slice);
rstate->states[R600_CB0__CB_COLOR0_VIEW] = 0x00000000;
@@ -120,83 +720,124 @@ static void r600_set_framebuffer_state(struct pipe_context *ctx,
rstate->states[R600_CB0__CB_COLOR0_MASK] = 0x00000000;
if (radeon_state_pm4(rstate)) {
radeon_state_decref(rstate);
- return;
+ return NULL;
}
- radeon_draw_set_new(rctx->draw, rstate);
- rctx->db = radeon_state_decref(rctx->db);
- if(state->zsbuf) {
- rtex = (struct r600_texture*)state->zsbuf->texture;
- rbuffer = (struct r600_buffer*)rtex->buffer;
- rctx->db = radeon_state(rscreen->rw, R600_DB_TYPE, R600_DB);
- if(rctx->db == NULL)
- return;
- rctx->db->bo[0] = radeon_bo_incref(rscreen->rw, rbuffer->bo);
- rctx->db->nbo = 1;
- rctx->db->placement[0] = RADEON_GEM_DOMAIN_VRAM;
- level = state->zsbuf->level;
- pitch = rtex->pitch[level] / 8 - 1;
- slice = rtex->pitch[level] * state->zsbuf->height / 64 - 1;
-
- rctx->db->states[R600_DB__DB_DEPTH_BASE] = 0x00000000;
- rctx->db->states[R600_DB__DB_DEPTH_INFO] = 0x00010006;
- rctx->db->states[R600_DB__DB_DEPTH_VIEW] = 0x00000000;
- rctx->db->states[R600_DB__DB_PREFETCH_LIMIT] = (state->zsbuf->height / 8) -1;
- rctx->db->states[R600_DB__DB_DEPTH_SIZE] = S_028000_PITCH_TILE_MAX(pitch) |
- S_028000_SLICE_TILE_MAX(slice);
- } else
- rctx->db = NULL;
- rctx->fb_state = *state;
-}
-
-static void *r600_create_fs_state(struct pipe_context *ctx,
- const struct pipe_shader_state *shader)
-{
- return r600_pipe_shader_create(ctx, C_PROGRAM_TYPE_FS, shader->tokens);
-}
-
-static void r600_bind_fs_state(struct pipe_context *ctx, void *state)
-{
- struct r600_context *rctx = r600_context(ctx);
-
- rctx->ps_shader = state;
+ return rstate;
}
-static void *r600_create_vs_state(struct pipe_context *ctx,
- const struct pipe_shader_state *shader)
+static struct radeon_state *r600_db(struct r600_context *rctx)
{
- return r600_pipe_shader_create(ctx, C_PROGRAM_TYPE_VS, shader->tokens);
-}
+ struct r600_screen *rscreen = rctx->screen;
+ struct r600_resource_texture *rtex;
+ struct r600_resource *rbuffer;
+ struct radeon_state *rstate;
+ const struct pipe_framebuffer_state *state = &rctx->framebuffer->state.framebuffer;
+ unsigned level;
+ unsigned pitch, slice, format;
-static void r600_bind_vs_state(struct pipe_context *ctx, void *state)
-{
- struct r600_context *rctx = r600_context(ctx);
+ if (state->zsbuf == NULL)
+ return NULL;
- rctx->vs_shader = state;
-}
+ rstate = radeon_state(rscreen->rw, R600_DB_TYPE, R600_DB);
+ if (rstate == NULL)
+ return NULL;
-static void r600_set_polygon_stipple(struct pipe_context *ctx,
- const struct pipe_poly_stipple *state)
-{
+ rtex = (struct r600_resource_texture*)state->zsbuf->texture;
+ rbuffer = &rtex->resource;
+ rstate->bo[0] = radeon_bo_incref(rscreen->rw, rbuffer->bo);
+ rstate->nbo = 1;
+ rstate->placement[0] = RADEON_GEM_DOMAIN_VRAM;
+ level = state->zsbuf->level;
+ pitch = (rtex->pitch[level] / rtex->bpt) / 8 - 1;
+ slice = (rtex->pitch[level] / rtex->bpt) * state->zsbuf->height / 64 - 1;
+ format = r600_translate_dbformat(state->zsbuf->texture->format);
+ rstate->states[R600_DB__DB_DEPTH_BASE] = 0x00000000;
+ rstate->states[R600_DB__DB_DEPTH_INFO] = 0x00010000 |
+ S_028010_FORMAT(format);
+ rstate->states[R600_DB__DB_DEPTH_VIEW] = 0x00000000;
+ rstate->states[R600_DB__DB_PREFETCH_LIMIT] = (state->zsbuf->height / 8) -1;
+ rstate->states[R600_DB__DB_DEPTH_SIZE] = S_028000_PITCH_TILE_MAX(pitch) |
+ S_028000_SLICE_TILE_MAX(slice);
+ if (radeon_state_pm4(rstate)) {
+ radeon_state_decref(rstate);
+ return NULL;
+ }
+ return rstate;
}
-static void *r600_create_rs_state(struct pipe_context *ctx,
- const struct pipe_rasterizer_state *state)
+static struct radeon_state *r600_rasterizer(struct r600_context *rctx)
{
- struct r600_screen *rscreen = r600_screen(ctx->screen);
- struct r600_context *rctx = r600_context(ctx);
+ const struct pipe_rasterizer_state *state = &rctx->rasterizer->state.rasterizer;
+ const struct pipe_framebuffer_state *fb = &rctx->framebuffer->state.framebuffer;
+ struct r600_screen *rscreen = rctx->screen;
struct radeon_state *rstate;
+ float offset_units = 0, offset_scale = 0;
+ char depth = 0;
+ unsigned offset_db_fmt_cntl = 0;
+ unsigned tmp;
+ unsigned prov_vtx = 1;
+ if (fb->zsbuf) {
+ offset_units = state->offset_units;
+ offset_scale = state->offset_scale * 12.0f;
+ switch (fb->zsbuf->texture->format) {
+ case PIPE_FORMAT_Z24X8_UNORM:
+ case PIPE_FORMAT_Z24_UNORM_S8_USCALED:
+ depth = -24;
+ offset_units *= 2.0f;
+ break;
+ case PIPE_FORMAT_Z32_FLOAT:
+ depth = -23;
+ offset_units *= 1.0f;
+ offset_db_fmt_cntl |= S_028DF8_POLY_OFFSET_DB_IS_FLOAT_FMT(1);
+ break;
+ case PIPE_FORMAT_Z16_UNORM:
+ depth = -16;
+ offset_units *= 4.0f;
+ break;
+ default:
+ R600_ERR("unsupported %d\n", fb->zsbuf->texture->format);
+ return NULL;
+ }
+ }
+ offset_db_fmt_cntl |= S_028DF8_POLY_OFFSET_NEG_NUM_DB_BITS(depth);
+
+ if (state->flatshade_first)
+ prov_vtx = 0;
rctx->flat_shade = state->flatshade;
rstate = radeon_state(rscreen->rw, R600_RASTERIZER_TYPE, R600_RASTERIZER);
if (rstate == NULL)
return NULL;
rstate->states[R600_RASTERIZER__SPI_INTERP_CONTROL_0] = 0x00000001;
+ if (state->sprite_coord_enable) {
+ rstate->states[R600_RASTERIZER__SPI_INTERP_CONTROL_0] |=
+ S_0286D4_PNT_SPRITE_ENA(1) |
+ S_0286D4_PNT_SPRITE_OVRD_X(2) |
+ S_0286D4_PNT_SPRITE_OVRD_Y(3) |
+ S_0286D4_PNT_SPRITE_OVRD_Z(0) |
+ S_0286D4_PNT_SPRITE_OVRD_W(1);
+ if (state->sprite_coord_mode != PIPE_SPRITE_COORD_UPPER_LEFT) {
+ rstate->states[R600_RASTERIZER__SPI_INTERP_CONTROL_0] |=
+ S_0286D4_PNT_SPRITE_TOP_1(1);
+ }
+ }
rstate->states[R600_RASTERIZER__PA_CL_CLIP_CNTL] = 0x00000000;
- rstate->states[R600_RASTERIZER__PA_SU_SC_MODE_CNTL] = 0x00080000;
- rstate->states[R600_RASTERIZER__PA_CL_VS_OUT_CNTL] = 0x00000000;
+ rstate->states[R600_RASTERIZER__PA_SU_SC_MODE_CNTL] =
+ S_028814_PROVOKING_VTX_LAST(prov_vtx) |
+ S_028814_CULL_FRONT((state->cull_face & PIPE_FACE_FRONT) ? 1 : 0) |
+ S_028814_CULL_BACK((state->cull_face & PIPE_FACE_BACK) ? 1 : 0) |
+ S_028814_FACE(!state->front_ccw) |
+ S_028814_POLY_OFFSET_FRONT_ENABLE(state->offset_tri) |
+ S_028814_POLY_OFFSET_BACK_ENABLE(state->offset_tri) |
+ S_028814_POLY_OFFSET_PARA_ENABLE(state->offset_tri);
+ rstate->states[R600_RASTERIZER__PA_CL_VS_OUT_CNTL] =
+ S_02881C_USE_VTX_POINT_SIZE(state->point_size_per_vertex) |
+ S_02881C_VS_OUT_MISC_VEC_ENA(state->point_size_per_vertex);
rstate->states[R600_RASTERIZER__PA_CL_NANINF_CNTL] = 0x00000000;
- rstate->states[R600_RASTERIZER__PA_SU_POINT_SIZE] = 0x00080008;
- rstate->states[R600_RASTERIZER__PA_SU_POINT_MINMAX] = 0x00000000;
+ /* point size 12.4 fixed point */
+ tmp = (unsigned)(state->point_size * 8.0 / 2.0);
+ rstate->states[R600_RASTERIZER__PA_SU_POINT_SIZE] = S_028A00_HEIGHT(tmp) | S_028A00_WIDTH(tmp);
+ rstate->states[R600_RASTERIZER__PA_SU_POINT_MINMAX] = 0x80000000;
rstate->states[R600_RASTERIZER__PA_SU_LINE_CNTL] = 0x00000008;
rstate->states[R600_RASTERIZER__PA_SC_LINE_STIPPLE] = 0x00000005;
rstate->states[R600_RASTERIZER__PA_SC_MPASS_PS_CNTL] = 0x00000000;
@@ -205,12 +846,12 @@ static void *r600_create_rs_state(struct pipe_context *ctx,
rstate->states[R600_RASTERIZER__PA_CL_GB_VERT_DISC_ADJ] = 0x3F800000;
rstate->states[R600_RASTERIZER__PA_CL_GB_HORZ_CLIP_ADJ] = 0x3F800000;
rstate->states[R600_RASTERIZER__PA_CL_GB_HORZ_DISC_ADJ] = 0x3F800000;
- rstate->states[R600_RASTERIZER__PA_SU_POLY_OFFSET_DB_FMT_CNTL] = 0x00000000;
+ rstate->states[R600_RASTERIZER__PA_SU_POLY_OFFSET_DB_FMT_CNTL] = offset_db_fmt_cntl;
rstate->states[R600_RASTERIZER__PA_SU_POLY_OFFSET_CLAMP] = 0x00000000;
- rstate->states[R600_RASTERIZER__PA_SU_POLY_OFFSET_FRONT_SCALE] = 0x00000000;
- rstate->states[R600_RASTERIZER__PA_SU_POLY_OFFSET_FRONT_OFFSET] = 0x00000000;
- rstate->states[R600_RASTERIZER__PA_SU_POLY_OFFSET_BACK_SCALE] = 0x00000000;
- rstate->states[R600_RASTERIZER__PA_SU_POLY_OFFSET_BACK_OFFSET] = 0x00000000;
+ rstate->states[R600_RASTERIZER__PA_SU_POLY_OFFSET_FRONT_SCALE] = fui(offset_scale);
+ rstate->states[R600_RASTERIZER__PA_SU_POLY_OFFSET_FRONT_OFFSET] = fui(offset_units);
+ rstate->states[R600_RASTERIZER__PA_SU_POLY_OFFSET_BACK_SCALE] = fui(offset_scale);
+ rstate->states[R600_RASTERIZER__PA_SU_POLY_OFFSET_BACK_OFFSET] = fui(offset_units);
if (radeon_state_pm4(rstate)) {
radeon_state_decref(rstate);
return NULL;
@@ -218,64 +859,31 @@ static void *r600_create_rs_state(struct pipe_context *ctx,
return rstate;
}
-static void r600_bind_rs_state(struct pipe_context *ctx, void *state)
+static struct radeon_state *r600_scissor(struct r600_context *rctx)
{
- struct r600_context *rctx = r600_context(ctx);
- radeon_draw_set(rctx->draw, state);
-}
-
-static void *r600_create_sampler_state(struct pipe_context *ctx,
- const struct pipe_sampler_state *state)
-{
- return NULL;
-}
-
-static void r600_bind_sampler_states(struct pipe_context *ctx,
- unsigned count, void **states)
-{
-}
-
-static struct pipe_sampler_view *r600_create_sampler_view(struct pipe_context *ctx,
- struct pipe_resource *texture,
- const struct pipe_sampler_view *templ)
-{
- struct pipe_sampler_view *view = CALLOC_STRUCT(pipe_sampler_view);
-
- *view = *templ;
- return view;
-}
-
-static void r600_sampler_view_destroy(struct pipe_context *ctx,
- struct pipe_sampler_view *view)
-{
- FREE(view);
-}
-
-static void r600_set_fragment_sampler_views(struct pipe_context *ctx,
- unsigned count,
- struct pipe_sampler_view **views)
-{
-}
-
-static void r600_set_vertex_sampler_views(struct pipe_context *ctx,
- unsigned count,
- struct pipe_sampler_view **views)
-{
-}
-
-static void r600_set_scissor_state(struct pipe_context *ctx,
- const struct pipe_scissor_state *state)
-{
- struct r600_screen *rscreen = r600_screen(ctx->screen);
- struct r600_context *rctx = r600_context(ctx);
+ const struct pipe_scissor_state *state = &rctx->scissor->state.scissor;
+ const struct pipe_framebuffer_state *fb = &rctx->framebuffer->state.framebuffer;
+ struct r600_screen *rscreen = rctx->screen;
struct radeon_state *rstate;
+ unsigned minx, maxx, miny, maxy;
u32 tl, br;
- tl = S_028240_TL_X(state->minx) | S_028240_TL_Y(state->miny) | S_028240_WINDOW_OFFSET_DISABLE(1);
- br = S_028244_BR_X(state->maxx) | S_028244_BR_Y(state->maxy);
+ if (state == NULL) {
+ minx = 0;
+ miny = 0;
+ maxx = fb->cbufs[0]->width;
+ maxy = fb->cbufs[0]->height;
+ } else {
+ minx = state->minx;
+ miny = state->miny;
+ maxx = state->maxx;
+ maxy = state->maxy;
+ }
+ tl = S_028240_TL_X(minx) | S_028240_TL_Y(miny) | S_028240_WINDOW_OFFSET_DISABLE(1);
+ br = S_028244_BR_X(maxx) | S_028244_BR_Y(maxy);
rstate = radeon_state(rscreen->rw, R600_SCISSOR_TYPE, R600_SCISSOR);
if (rstate == NULL)
- return;
+ return NULL;
rstate->states[R600_SCISSOR__PA_SC_SCREEN_SCISSOR_TL] = tl;
rstate->states[R600_SCISSOR__PA_SC_SCREEN_SCISSOR_BR] = br;
rstate->states[R600_SCISSOR__PA_SC_WINDOW_OFFSET] = 0x00000000;
@@ -297,97 +905,104 @@ static void r600_set_scissor_state(struct pipe_context *ctx,
rstate->states[R600_SCISSOR__PA_SC_VPORT_SCISSOR_0_BR] = br;
if (radeon_state_pm4(rstate)) {
radeon_state_decref(rstate);
- return;
+ return NULL;
}
- radeon_draw_set_new(rctx->draw, rstate);
+ return rstate;
}
-static void r600_set_viewport_state(struct pipe_context *ctx,
- const struct pipe_viewport_state *state)
+static struct radeon_state *r600_viewport(struct r600_context *rctx)
{
- struct r600_screen *rscreen = r600_screen(ctx->screen);
- struct r600_context *rctx = r600_context(ctx);
+ const struct pipe_viewport_state *state = &rctx->viewport->state.viewport;
+ struct r600_screen *rscreen = rctx->screen;
struct radeon_state *rstate;
rstate = radeon_state(rscreen->rw, R600_VIEWPORT_TYPE, R600_VIEWPORT);
if (rstate == NULL)
- return;
+ return NULL;
rstate->states[R600_VIEWPORT__PA_SC_VPORT_ZMIN_0] = 0x00000000;
rstate->states[R600_VIEWPORT__PA_SC_VPORT_ZMAX_0] = 0x3F800000;
- rstate->states[R600_VIEWPORT__PA_CL_VPORT_XSCALE_0] = r600_float_to_u32(state->scale[0]);
- rstate->states[R600_VIEWPORT__PA_CL_VPORT_YSCALE_0] = r600_float_to_u32(state->scale[1]);
- rstate->states[R600_VIEWPORT__PA_CL_VPORT_ZSCALE_0] = r600_float_to_u32(state->scale[2]);
- rstate->states[R600_VIEWPORT__PA_CL_VPORT_XOFFSET_0] = r600_float_to_u32(state->translate[0]);
- rstate->states[R600_VIEWPORT__PA_CL_VPORT_YOFFSET_0] = r600_float_to_u32(state->translate[1]);
- rstate->states[R600_VIEWPORT__PA_CL_VPORT_ZOFFSET_0] = r600_float_to_u32(state->translate[2]);
+ rstate->states[R600_VIEWPORT__PA_CL_VPORT_XSCALE_0] = fui(state->scale[0]);
+ rstate->states[R600_VIEWPORT__PA_CL_VPORT_YSCALE_0] = fui(state->scale[1]);
+ rstate->states[R600_VIEWPORT__PA_CL_VPORT_ZSCALE_0] = fui(state->scale[2]);
+ rstate->states[R600_VIEWPORT__PA_CL_VPORT_XOFFSET_0] = fui(state->translate[0]);
+ rstate->states[R600_VIEWPORT__PA_CL_VPORT_YOFFSET_0] = fui(state->translate[1]);
+ rstate->states[R600_VIEWPORT__PA_CL_VPORT_ZOFFSET_0] = fui(state->translate[2]);
rstate->states[R600_VIEWPORT__PA_CL_VTE_CNTL] = 0x0000043F;
if (radeon_state_pm4(rstate)) {
radeon_state_decref(rstate);
- return;
+ return NULL;
}
- radeon_draw_set_new(rctx->draw, rstate);
- rctx->viewport = *state;
-}
-
-static void r600_set_vertex_buffers(struct pipe_context *ctx,
- unsigned count,
- const struct pipe_vertex_buffer *buffers)
-{
- struct r600_context *rctx = r600_context(ctx);
-
- memcpy(rctx->vertex_buffer, buffers, sizeof(struct pipe_vertex_buffer) * count);
- rctx->nvertex_buffer = count;
+ return rstate;
}
-
-static void *r600_create_vertex_elements_state(struct pipe_context *ctx,
- unsigned count,
- const struct pipe_vertex_element *elements)
+static struct radeon_state *r600_dsa(struct r600_context *rctx)
{
- struct r600_vertex_elements_state *v = CALLOC_STRUCT(r600_vertex_elements_state);
+ const struct pipe_depth_stencil_alpha_state *state = &rctx->dsa->state.dsa;
+ const struct pipe_stencil_ref *stencil_ref = &rctx->stencil_ref->state.stencil_ref;
+ struct r600_screen *rscreen = rctx->screen;
+ unsigned db_depth_control, alpha_test_control, alpha_ref, db_shader_control;
+ unsigned stencil_ref_mask, stencil_ref_mask_bf;
+ struct r600_shader *rshader = &rctx->ps_shader->shader;
+ struct radeon_state *rstate;
+ int i;
- assert(count < 32);
- v->count = count;
- memcpy(v->elements, elements, count * sizeof(struct pipe_vertex_element));
- return v;
-}
+ rstate = radeon_state(rscreen->rw, R600_DSA_TYPE, R600_DSA);
+ if (rstate == NULL)
+ return NULL;
-static void r600_bind_vertex_elements_state(struct pipe_context *ctx, void *state)
-{
- struct r600_context *rctx = r600_context(ctx);
- struct r600_vertex_elements_state *v = (struct r600_vertex_elements_state*)state;
+ db_shader_control = 0x210;
+ for (i = 0; i < rshader->noutput; i++) {
+ if (rshader->output[i].name == TGSI_SEMANTIC_POSITION)
+ db_shader_control |= 1;
+ }
+ stencil_ref_mask = 0;
+ stencil_ref_mask_bf = 0;
+ db_depth_control = S_028800_Z_ENABLE(state->depth.enabled) |
+ S_028800_Z_WRITE_ENABLE(state->depth.writemask) |
+ S_028800_ZFUNC(state->depth.func);
+ /* set stencil enable */
- rctx->vertex_elements = v;
-}
+ if (state->stencil[0].enabled) {
+ db_depth_control |= S_028800_STENCIL_ENABLE(1);
+ db_depth_control |= S_028800_STENCILFUNC(r600_translate_ds_func(state->stencil[0].func));
+ db_depth_control |= S_028800_STENCILFAIL(r600_translate_stencil_op(state->stencil[0].fail_op));
+ db_depth_control |= S_028800_STENCILZPASS(r600_translate_stencil_op(state->stencil[0].zpass_op));
+ db_depth_control |= S_028800_STENCILZFAIL(r600_translate_stencil_op(state->stencil[0].zfail_op));
-static void r600_delete_vertex_elements_state(struct pipe_context *ctx, void *state)
-{
- FREE(state);
-}
+ stencil_ref_mask = S_028430_STENCILMASK(state->stencil[0].valuemask) |
+ S_028430_STENCILWRITEMASK(state->stencil[0].writemask);
+ stencil_ref_mask |= S_028430_STENCILREF(stencil_ref->ref_value[0]);
+ if (state->stencil[1].enabled) {
+ db_depth_control |= S_028800_BACKFACE_ENABLE(1);
+ db_depth_control |= S_028800_STENCILFUNC_BF(r600_translate_ds_func(state->stencil[1].func));
+ db_depth_control |= S_028800_STENCILFAIL_BF(r600_translate_stencil_op(state->stencil[1].fail_op));
+ db_depth_control |= S_028800_STENCILZPASS_BF(r600_translate_stencil_op(state->stencil[1].zpass_op));
+ db_depth_control |= S_028800_STENCILZFAIL_BF(r600_translate_stencil_op(state->stencil[1].zfail_op));
+ stencil_ref_mask_bf = S_028434_STENCILMASK_BF(state->stencil[1].valuemask) |
+ S_028434_STENCILWRITEMASK_BF(state->stencil[1].writemask);
+ stencil_ref_mask_bf |= S_028430_STENCILREF(stencil_ref->ref_value[1]);
+ }
+ }
-static void *r600_create_dsa_state(struct pipe_context *ctx,
- const struct pipe_depth_stencil_alpha_state *state)
-{
- struct r600_screen *rscreen = r600_screen(ctx->screen);
- struct radeon_state *rstate;
- unsigned db_depth_control;
+ alpha_test_control = 0;
+ alpha_ref = 0;
+ if (state->alpha.enabled) {
+ alpha_test_control = S_028410_ALPHA_FUNC(state->alpha.func);
+ alpha_test_control |= S_028410_ALPHA_TEST_ENABLE(1);
+ alpha_ref = fui(state->alpha.ref_value);
+ }
- rstate = radeon_state(rscreen->rw, R600_DSA_TYPE, R600_DSA);
- if (rstate == NULL)
- return NULL;
- db_depth_control = 0x00700700 | S_028800_Z_ENABLE(state->depth.enabled) | S_028800_Z_WRITE_ENABLE(state->depth.writemask) | S_028800_ZFUNC(state->depth.func);
-
rstate->states[R600_DSA__DB_STENCIL_CLEAR] = 0x00000000;
rstate->states[R600_DSA__DB_DEPTH_CLEAR] = 0x3F800000;
- rstate->states[R600_DSA__SX_ALPHA_TEST_CONTROL] = 0x00000000;
- rstate->states[R600_DSA__DB_STENCILREFMASK] = 0xFFFFFF00;
- rstate->states[R600_DSA__DB_STENCILREFMASK_BF] = 0xFFFFFF00;
- rstate->states[R600_DSA__SX_ALPHA_REF] = 0x00000000;
+ rstate->states[R600_DSA__SX_ALPHA_TEST_CONTROL] = alpha_test_control;
+ rstate->states[R600_DSA__DB_STENCILREFMASK] = stencil_ref_mask;
+ rstate->states[R600_DSA__DB_STENCILREFMASK_BF] = stencil_ref_mask_bf;
+ rstate->states[R600_DSA__SX_ALPHA_REF] = alpha_ref;
rstate->states[R600_DSA__SPI_FOG_FUNC_SCALE] = 0x00000000;
rstate->states[R600_DSA__SPI_FOG_FUNC_BIAS] = 0x00000000;
rstate->states[R600_DSA__SPI_FOG_CNTL] = 0x00000000;
rstate->states[R600_DSA__DB_DEPTH_CONTROL] = db_depth_control;
- rstate->states[R600_DSA__DB_SHADER_CONTROL] = 0x00000210;
+ rstate->states[R600_DSA__DB_SHADER_CONTROL] = db_shader_control;
rstate->states[R600_DSA__DB_RENDER_CONTROL] = 0x00000060;
rstate->states[R600_DSA__DB_RENDER_OVERRIDE] = 0x0000002A;
rstate->states[R600_DSA__DB_SRESULTS_COMPARE_STATE1] = 0x00000000;
@@ -400,105 +1015,390 @@ static void *r600_create_dsa_state(struct pipe_context *ctx,
return rstate;
}
-static void r600_bind_dsa_state(struct pipe_context *ctx, void *state)
+static inline unsigned r600_tex_wrap(unsigned wrap)
{
- struct r600_context *rctx = r600_context(ctx);
- radeon_draw_set(rctx->draw, state);
+ switch (wrap) {
+ default:
+ case PIPE_TEX_WRAP_REPEAT:
+ return V_03C000_SQ_TEX_WRAP;
+ case PIPE_TEX_WRAP_CLAMP:
+ return V_03C000_SQ_TEX_CLAMP_LAST_TEXEL;
+ case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
+ return V_03C000_SQ_TEX_CLAMP_HALF_BORDER;
+ case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
+ return V_03C000_SQ_TEX_CLAMP_BORDER;
+ case PIPE_TEX_WRAP_MIRROR_REPEAT:
+ return V_03C000_SQ_TEX_MIRROR;
+ case PIPE_TEX_WRAP_MIRROR_CLAMP:
+ return V_03C000_SQ_TEX_MIRROR_ONCE_LAST_TEXEL;
+ case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE:
+ return V_03C000_SQ_TEX_MIRROR_ONCE_HALF_BORDER;
+ case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER:
+ return V_03C000_SQ_TEX_MIRROR_ONCE_BORDER;
+ }
}
-static void r600_set_constant_buffer(struct pipe_context *ctx,
- uint shader, uint index,
- struct pipe_resource *buffer)
+static inline unsigned r600_tex_filter(unsigned filter)
{
- struct r600_screen *rscreen = r600_screen(ctx->screen);
- struct r600_context *rctx = r600_context(ctx);
- unsigned nconstant = 0, i, type, id;
+ switch (filter) {
+ default:
+ case PIPE_TEX_FILTER_NEAREST:
+ return V_03C000_SQ_TEX_XY_FILTER_POINT;
+ case PIPE_TEX_FILTER_LINEAR:
+ return V_03C000_SQ_TEX_XY_FILTER_BILINEAR;
+ }
+}
+
+static inline unsigned r600_tex_mipfilter(unsigned filter)
+{
+ switch (filter) {
+ case PIPE_TEX_MIPFILTER_NEAREST:
+ return V_03C000_SQ_TEX_Z_FILTER_POINT;
+ case PIPE_TEX_MIPFILTER_LINEAR:
+ return V_03C000_SQ_TEX_Z_FILTER_LINEAR;
+ default:
+ case PIPE_TEX_MIPFILTER_NONE:
+ return V_03C000_SQ_TEX_Z_FILTER_NONE;
+ }
+}
+
+static inline unsigned r600_tex_compare(unsigned compare)
+{
+ switch (compare) {
+ default:
+ case PIPE_FUNC_NEVER:
+ return V_03C000_SQ_TEX_DEPTH_COMPARE_NEVER;
+ case PIPE_FUNC_LESS:
+ return V_03C000_SQ_TEX_DEPTH_COMPARE_LESS;
+ case PIPE_FUNC_EQUAL:
+ return V_03C000_SQ_TEX_DEPTH_COMPARE_EQUAL;
+ case PIPE_FUNC_LEQUAL:
+ return V_03C000_SQ_TEX_DEPTH_COMPARE_LESSEQUAL;
+ case PIPE_FUNC_GREATER:
+ return V_03C000_SQ_TEX_DEPTH_COMPARE_GREATER;
+ case PIPE_FUNC_NOTEQUAL:
+ return V_03C000_SQ_TEX_DEPTH_COMPARE_NOTEQUAL;
+ case PIPE_FUNC_GEQUAL:
+ return V_03C000_SQ_TEX_DEPTH_COMPARE_GREATEREQUAL;
+ case PIPE_FUNC_ALWAYS:
+ return V_03C000_SQ_TEX_DEPTH_COMPARE_ALWAYS;
+ }
+}
+
+static INLINE u32 S_FIXED(float value, u32 frac_bits)
+{
+ return value * (1 << frac_bits);
+}
+
+static struct radeon_state *r600_sampler(struct r600_context *rctx,
+ const struct pipe_sampler_state *state,
+ unsigned id)
+{
+ struct r600_screen *rscreen = rctx->screen;
struct radeon_state *rstate;
- struct pipe_transfer *transfer;
- u32 *ptr;
- switch (shader) {
- case PIPE_SHADER_VERTEX:
- id = R600_VS_CONSTANT;
- type = R600_VS_CONSTANT_TYPE;
- break;
- case PIPE_SHADER_FRAGMENT:
- id = R600_PS_CONSTANT;
- type = R600_PS_CONSTANT_TYPE;
- break;
+ rstate = radeon_state(rscreen->rw, R600_PS_SAMPLER_TYPE, id);
+ if (rstate == NULL)
+ return NULL;
+ rstate->states[R600_PS_SAMPLER__SQ_TEX_SAMPLER_WORD0_0] =
+ S_03C000_CLAMP_X(r600_tex_wrap(state->wrap_s)) |
+ S_03C000_CLAMP_Y(r600_tex_wrap(state->wrap_t)) |
+ S_03C000_CLAMP_Z(r600_tex_wrap(state->wrap_r)) |
+ S_03C000_XY_MAG_FILTER(r600_tex_filter(state->mag_img_filter)) |
+ S_03C000_XY_MIN_FILTER(r600_tex_filter(state->min_img_filter)) |
+ S_03C000_MIP_FILTER(r600_tex_mipfilter(state->min_mip_filter)) |
+ S_03C000_DEPTH_COMPARE_FUNCTION(r600_tex_compare(state->compare_func));
+ /* FIXME LOD it depends on texture base level ... */
+ rstate->states[R600_PS_SAMPLER__SQ_TEX_SAMPLER_WORD1_0] =
+ S_03C004_MIN_LOD(S_FIXED(CLAMP(state->min_lod, 0, 15), 6)) |
+ S_03C004_MAX_LOD(S_FIXED(CLAMP(state->max_lod, 0, 15), 6)) |
+ S_03C004_LOD_BIAS(S_FIXED(CLAMP(state->lod_bias, -16, 16), 6));
+ rstate->states[R600_PS_SAMPLER__SQ_TEX_SAMPLER_WORD2_0] = S_03C008_TYPE(1);
+ if (radeon_state_pm4(rstate)) {
+ radeon_state_decref(rstate);
+ return NULL;
+ }
+ return rstate;
+}
+
+static inline unsigned r600_tex_swizzle(unsigned swizzle)
+{
+ switch (swizzle) {
+ case PIPE_SWIZZLE_RED:
+ return V_038010_SQ_SEL_X;
+ case PIPE_SWIZZLE_GREEN:
+ return V_038010_SQ_SEL_Y;
+ case PIPE_SWIZZLE_BLUE:
+ return V_038010_SQ_SEL_Z;
+ case PIPE_SWIZZLE_ALPHA:
+ return V_038010_SQ_SEL_W;
+ case PIPE_SWIZZLE_ZERO:
+ return V_038010_SQ_SEL_0;
default:
- fprintf(stderr, "%s:%d unsupported %d\n", __func__, __LINE__, shader);
- return;
+ case PIPE_SWIZZLE_ONE:
+ return V_038010_SQ_SEL_1;
}
- if (buffer && buffer->width0 > 0) {
- nconstant = buffer->width0 / 16;
- ptr = pipe_buffer_map(ctx, buffer, PIPE_TRANSFER_READ, &transfer);
- if (ptr == NULL)
- return;
- for (i = 0; i < nconstant; i++) {
- rstate = radeon_state(rscreen->rw, type, id + i);
- if (rstate == NULL)
- return;
- rstate->states[R600_PS_CONSTANT__SQ_ALU_CONSTANT0_0] = ptr[i * 4 + 0];
- rstate->states[R600_PS_CONSTANT__SQ_ALU_CONSTANT1_0] = ptr[i * 4 + 1];
- rstate->states[R600_PS_CONSTANT__SQ_ALU_CONSTANT2_0] = ptr[i * 4 + 2];
- rstate->states[R600_PS_CONSTANT__SQ_ALU_CONSTANT3_0] = ptr[i * 4 + 3];
- if (radeon_state_pm4(rstate))
- return;
- if (radeon_draw_set_new(rctx->draw, rstate))
- return;
- }
- pipe_buffer_unmap(ctx, buffer, transfer);
+}
+
+static inline unsigned r600_format_type(unsigned format_type)
+{
+ switch (format_type) {
+ default:
+ case UTIL_FORMAT_TYPE_UNSIGNED:
+ return V_038010_SQ_FORMAT_COMP_UNSIGNED;
+ case UTIL_FORMAT_TYPE_SIGNED:
+ return V_038010_SQ_FORMAT_COMP_SIGNED;
+ case UTIL_FORMAT_TYPE_FIXED:
+ return V_038010_SQ_FORMAT_COMP_UNSIGNED_BIASED;
}
}
-static void r600_set_stencil_ref(struct pipe_context *ctx,
- const struct pipe_stencil_ref *sr)
+static inline unsigned r600_tex_dim(unsigned dim)
{
- struct r600_context *rctx = r600_context(ctx);
- rctx->stencil_ref = *sr;
+ switch (dim) {
+ default:
+ case PIPE_TEXTURE_1D:
+ return V_038000_SQ_TEX_DIM_1D;
+ case PIPE_TEXTURE_2D:
+ return V_038000_SQ_TEX_DIM_2D;
+ case PIPE_TEXTURE_3D:
+ return V_038000_SQ_TEX_DIM_3D;
+ case PIPE_TEXTURE_CUBE:
+ return V_038000_SQ_TEX_DIM_CUBEMAP;
+ }
}
-static void r600_set_sample_mask(struct pipe_context *pipe, unsigned sample_mask)
+static struct radeon_state *r600_resource(struct r600_context *rctx,
+ const struct pipe_sampler_view *view,
+ unsigned id)
{
+ struct r600_screen *rscreen = rctx->screen;
+ const struct util_format_description *desc;
+ struct r600_resource_texture *tmp;
+ struct r600_resource *rbuffer;
+ struct radeon_state *rstate;
+ unsigned format;
+ uint32_t word4 = 0, yuv_format = 0;
+ unsigned char swizzle[4];
+
+ swizzle[0] = view->swizzle_r;
+ swizzle[1] = view->swizzle_g;
+ swizzle[2] = view->swizzle_b;
+ swizzle[3] = view->swizzle_a;
+ format = r600_translate_texformat(view->texture->format,
+ swizzle,
+ &word4, &yuv_format);
+ if (format == ~0)
+ return NULL;
+ desc = util_format_description(view->texture->format);
+ if (desc == NULL) {
+ R600_ERR("unknow format %d\n", view->texture->format);
+ return NULL;
+ }
+ rstate = radeon_state(rscreen->rw, R600_PS_RESOURCE_TYPE, id);
+ if (rstate == NULL) {
+ return NULL;
+ }
+ tmp = (struct r600_resource_texture*)view->texture;
+ rbuffer = &tmp->resource;
+ rstate->bo[0] = radeon_bo_incref(rscreen->rw, rbuffer->bo);
+ rstate->bo[1] = radeon_bo_incref(rscreen->rw, rbuffer->bo);
+ rstate->nbo = 2;
+ rstate->placement[0] = RADEON_GEM_DOMAIN_GTT;
+ rstate->placement[1] = RADEON_GEM_DOMAIN_GTT;
+ rstate->placement[2] = RADEON_GEM_DOMAIN_GTT;
+ rstate->placement[3] = RADEON_GEM_DOMAIN_GTT;
+
+ /* FIXME properly handle first level != 0 */
+ rstate->states[R600_PS_RESOURCE__RESOURCE0_WORD0] =
+ S_038000_DIM(r600_tex_dim(view->texture->target)) |
+ S_038000_PITCH(((tmp->pitch[0] / tmp->bpt) / 8) - 1) |
+ S_038000_TEX_WIDTH(view->texture->width0 - 1);
+ rstate->states[R600_PS_RESOURCE__RESOURCE0_WORD1] =
+ S_038004_TEX_HEIGHT(view->texture->height0 - 1) |
+ S_038004_TEX_DEPTH(view->texture->depth0 - 1) |
+ S_038004_DATA_FORMAT(format);
+ rstate->states[R600_PS_RESOURCE__RESOURCE0_WORD2] = 0;
+ rstate->states[R600_PS_RESOURCE__RESOURCE0_WORD3] = tmp->offset[1] >> 8;
+ rstate->states[R600_PS_RESOURCE__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_REQUEST_SIZE(1) |
+ S_038010_BASE_LEVEL(view->first_level);
+ rstate->states[R600_PS_RESOURCE__RESOURCE0_WORD5] =
+ S_038014_LAST_LEVEL(view->last_level) |
+ S_038014_BASE_ARRAY(0) |
+ S_038014_LAST_ARRAY(0);
+ rstate->states[R600_PS_RESOURCE__RESOURCE0_WORD6] =
+ S_038018_TYPE(V_038010_SQ_TEX_VTX_VALID_TEXTURE);
+ if (radeon_state_pm4(rstate)) {
+ radeon_state_decref(rstate);
+ return NULL;
+ }
+ return rstate;
}
-void r600_init_state_functions(struct r600_context *rctx)
+static struct radeon_state *r600_cb_cntl(struct r600_context *rctx)
{
- rctx->context.set_sample_mask = r600_set_sample_mask;
- rctx->context.create_blend_state = r600_create_blend_state;
- rctx->context.bind_blend_state = r600_bind_blend_state;
- rctx->context.delete_blend_state = r600_delete_state;
- rctx->context.set_blend_color = r600_set_blend_color;
- rctx->context.set_clip_state = r600_set_clip_state;
- rctx->context.set_constant_buffer = r600_set_constant_buffer;
- rctx->context.create_depth_stencil_alpha_state = r600_create_dsa_state;
- rctx->context.bind_depth_stencil_alpha_state = r600_bind_dsa_state;
- rctx->context.delete_depth_stencil_alpha_state = r600_delete_state;
- rctx->context.set_framebuffer_state = r600_set_framebuffer_state;
- rctx->context.create_fs_state = r600_create_fs_state;
- rctx->context.bind_fs_state = r600_bind_fs_state;
- rctx->context.delete_fs_state = r600_delete_state;
- rctx->context.set_polygon_stipple = r600_set_polygon_stipple;
- rctx->context.create_rasterizer_state = r600_create_rs_state;
- rctx->context.bind_rasterizer_state = r600_bind_rs_state;
- rctx->context.delete_rasterizer_state = r600_delete_state;
- rctx->context.create_sampler_state = r600_create_sampler_state;
- rctx->context.bind_fragment_sampler_states = r600_bind_sampler_states;
- rctx->context.bind_vertex_sampler_states = r600_bind_sampler_states;
- rctx->context.delete_sampler_state = r600_delete_state;
- rctx->context.create_sampler_view = r600_create_sampler_view;
- rctx->context.sampler_view_destroy = r600_sampler_view_destroy;
- rctx->context.set_fragment_sampler_views = r600_set_fragment_sampler_views;
- rctx->context.set_vertex_sampler_views = r600_set_vertex_sampler_views;
- rctx->context.set_scissor_state = r600_set_scissor_state;
- rctx->context.set_viewport_state = r600_set_viewport_state;
- rctx->context.set_vertex_buffers = r600_set_vertex_buffers;
- rctx->context.create_vertex_elements_state = r600_create_vertex_elements_state;
- rctx->context.bind_vertex_elements_state = r600_bind_vertex_elements_state;
- rctx->context.delete_vertex_elements_state = r600_delete_vertex_elements_state;
- rctx->context.create_vs_state = r600_create_vs_state;
- rctx->context.bind_vs_state = r600_bind_vs_state;
- rctx->context.delete_vs_state = r600_delete_state;
- rctx->context.set_stencil_ref = r600_set_stencil_ref;
+ struct r600_screen *rscreen = rctx->screen;
+ struct radeon_state *rstate;
+ const struct pipe_blend_state *pbs = &rctx->blend->state.blend;
+ int nr_cbufs = rctx->framebuffer->state.framebuffer.nr_cbufs;
+ uint32_t color_control, target_mask, shader_mask;
+ int i;
+
+ target_mask = 0;
+ shader_mask = 0;
+ color_control = S_028808_PER_MRT_BLEND(1);
+
+ for (i = 0; i < nr_cbufs; i++) {
+ shader_mask |= 0xf << (i * 4);
+ }
+
+ if (pbs->logicop_enable) {
+ color_control |= (pbs->logicop_func) << 16;
+ } else {
+ color_control |= (0xcc << 16);
+ }
+
+ if (pbs->independent_blend_enable) {
+ for (i = 0; i < nr_cbufs; i++) {
+ if (pbs->rt[i].blend_enable) {
+ color_control |= S_028808_TARGET_BLEND_ENABLE(1 << i);
+ }
+ target_mask |= (pbs->rt[i].colormask << (4 * i));
+ }
+ } else {
+ for (i = 0; i < nr_cbufs; i++) {
+ if (pbs->rt[0].blend_enable) {
+ color_control |= S_028808_TARGET_BLEND_ENABLE(1 << i);
+ }
+ target_mask |= (pbs->rt[0].colormask << (4 * i));
+ }
+ }
+ rstate = radeon_state(rscreen->rw, R600_CB_CNTL_TYPE, R600_CB_CNTL);
+ rstate->states[R600_CB_CNTL__CB_SHADER_MASK] = shader_mask;
+ rstate->states[R600_CB_CNTL__CB_TARGET_MASK] = target_mask;
+ rstate->states[R600_CB_CNTL__CB_COLOR_CONTROL] = color_control;
+ rstate->states[R600_CB_CNTL__PA_SC_AA_CONFIG] = 0x00000000;
+ rstate->states[R600_CB_CNTL__PA_SC_AA_SAMPLE_LOCS_MCTX] = 0x00000000;
+ rstate->states[R600_CB_CNTL__PA_SC_AA_SAMPLE_LOCS_8S_WD1_MCTX] = 0x00000000;
+ rstate->states[R600_CB_CNTL__CB_CLRCMP_CONTROL] = 0x01000000;
+ rstate->states[R600_CB_CNTL__CB_CLRCMP_SRC] = 0x00000000;
+ rstate->states[R600_CB_CNTL__CB_CLRCMP_DST] = 0x000000FF;
+ rstate->states[R600_CB_CNTL__CB_CLRCMP_MSK] = 0xFFFFFFFF;
+ rstate->states[R600_CB_CNTL__PA_SC_AA_MASK] = 0xFFFFFFFF;
+ if (radeon_state_pm4(rstate)) {
+ radeon_state_decref(rstate);
+ return NULL;
+ }
+ return rstate;
+}
+
+int r600_context_hw_states(struct r600_context *rctx)
+{
+ unsigned i;
+ int r;
+ int nr_cbufs = rctx->framebuffer->state.framebuffer.nr_cbufs;
+
+ /* free previous TODO determine what need to be updated, what
+ * doesn't
+ */
+ //radeon_state_decref(rctx->hw_states.config);
+ rctx->hw_states.cb_cntl = radeon_state_decref(rctx->hw_states.cb_cntl);
+ rctx->hw_states.db = radeon_state_decref(rctx->hw_states.db);
+ rctx->hw_states.rasterizer = radeon_state_decref(rctx->hw_states.rasterizer);
+ rctx->hw_states.scissor = radeon_state_decref(rctx->hw_states.scissor);
+ rctx->hw_states.dsa = radeon_state_decref(rctx->hw_states.dsa);
+ rctx->hw_states.blend = radeon_state_decref(rctx->hw_states.blend);
+ rctx->hw_states.viewport = radeon_state_decref(rctx->hw_states.viewport);
+ for (i = 0; i < 8; i++) {
+ rctx->hw_states.cb[i] = radeon_state_decref(rctx->hw_states.cb[i]);
+ }
+ for (i = 0; i < rctx->hw_states.ps_nresource; i++) {
+ radeon_state_decref(rctx->hw_states.ps_resource[i]);
+ rctx->hw_states.ps_resource[i] = NULL;
+ }
+ rctx->hw_states.ps_nresource = 0;
+ for (i = 0; i < rctx->hw_states.ps_nsampler; i++) {
+ radeon_state_decref(rctx->hw_states.ps_sampler[i]);
+ rctx->hw_states.ps_sampler[i] = NULL;
+ }
+ rctx->hw_states.ps_nsampler = 0;
+
+ /* build new states */
+ rctx->hw_states.rasterizer = r600_rasterizer(rctx);
+ rctx->hw_states.scissor = r600_scissor(rctx);
+ rctx->hw_states.dsa = r600_dsa(rctx);
+ rctx->hw_states.blend = r600_blend(rctx);
+ rctx->hw_states.viewport = r600_viewport(rctx);
+ for (i = 0; i < nr_cbufs; i++) {
+ rctx->hw_states.cb[i] = r600_cb(rctx, i);
+ }
+ rctx->hw_states.db = r600_db(rctx);
+ rctx->hw_states.cb_cntl = r600_cb_cntl(rctx);
+
+ for (i = 0; i < rctx->ps_nsampler; i++) {
+ if (rctx->ps_sampler[i]) {
+ rctx->hw_states.ps_sampler[i] = r600_sampler(rctx,
+ &rctx->ps_sampler[i]->state.sampler,
+ R600_PS_SAMPLER + i);
+ }
+ }
+ rctx->hw_states.ps_nsampler = rctx->ps_nsampler;
+ for (i = 0; i < rctx->ps_nsampler_view; i++) {
+ if (rctx->ps_sampler_view[i]) {
+ rctx->hw_states.ps_resource[i] = r600_resource(rctx,
+ &rctx->ps_sampler_view[i]->state.sampler_view,
+ R600_PS_RESOURCE + i);
+ }
+ }
+ rctx->hw_states.ps_nresource = rctx->ps_nsampler_view;
+
+ /* bind states */
+ r = radeon_draw_set(rctx->draw, rctx->hw_states.db);
+ if (r)
+ return r;
+ r = radeon_draw_set(rctx->draw, rctx->hw_states.rasterizer);
+ if (r)
+ return r;
+ r = radeon_draw_set(rctx->draw, rctx->hw_states.scissor);
+ if (r)
+ return r;
+ r = radeon_draw_set(rctx->draw, rctx->hw_states.dsa);
+ if (r)
+ return r;
+ r = radeon_draw_set(rctx->draw, rctx->hw_states.blend);
+ if (r)
+ return r;
+ r = radeon_draw_set(rctx->draw, rctx->hw_states.viewport);
+ if (r)
+ return r;
+ for (i = 0; i < nr_cbufs; i++) {
+ r = radeon_draw_set(rctx->draw, rctx->hw_states.cb[i]);
+ if (r)
+ return r;
+ }
+ r = radeon_draw_set(rctx->draw, rctx->hw_states.config);
+ if (r)
+ return r;
+ r = radeon_draw_set(rctx->draw, rctx->hw_states.cb_cntl);
+ if (r)
+ return r;
+ for (i = 0; i < rctx->hw_states.ps_nresource; i++) {
+ if (rctx->hw_states.ps_resource[i]) {
+ r = radeon_draw_set(rctx->draw, rctx->hw_states.ps_resource[i]);
+ if (r)
+ return r;
+ }
+ }
+ for (i = 0; i < rctx->hw_states.ps_nsampler; i++) {
+ if (rctx->hw_states.ps_sampler[i]) {
+ r = radeon_draw_set(rctx->draw, rctx->hw_states.ps_sampler[i]);
+ if (r)
+ return r;
+ }
+ }
+ return 0;
}
diff --git a/src/gallium/drivers/r600/r600_state_inlines.h b/src/gallium/drivers/r600/r600_state_inlines.h
new file mode 100644
index 0000000000..f93c20da35
--- /dev/null
+++ b/src/gallium/drivers/r600/r600_state_inlines.h
@@ -0,0 +1,311 @@
+/*
+ * Copyright 2010 Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * on the rights to use, copy, modify, merge, publish, distribute, sub
+ * license, and/or sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#ifndef R600_STATE_INLINES_H
+#define R600_STATE_INLINES_H
+
+#include "util/u_format.h"
+#include "r600d.h"
+
+static INLINE uint32_t r600_translate_blend_function(int blend_func)
+{
+ switch (blend_func) {
+ case PIPE_BLEND_ADD:
+ return V_028804_COMB_DST_PLUS_SRC;
+ case PIPE_BLEND_SUBTRACT:
+ return V_028804_COMB_SRC_MINUS_DST;
+ case PIPE_BLEND_REVERSE_SUBTRACT:
+ return V_028804_COMB_DST_MINUS_SRC;
+ case PIPE_BLEND_MIN:
+ return V_028804_COMB_MIN_DST_SRC;
+ case PIPE_BLEND_MAX:
+ return V_028804_COMB_MAX_DST_SRC;
+ default:
+ R600_ERR("Unknown blend function %d\n", blend_func);
+ assert(0);
+ break;
+ }
+ return 0;
+}
+
+static INLINE uint32_t r600_translate_blend_factor(int blend_fact)
+{
+ switch (blend_fact) {
+ case PIPE_BLENDFACTOR_ONE:
+ return V_028804_BLEND_ONE;
+ case PIPE_BLENDFACTOR_SRC_COLOR:
+ return V_028804_BLEND_SRC_COLOR;
+ case PIPE_BLENDFACTOR_SRC_ALPHA:
+ return V_028804_BLEND_SRC_ALPHA;
+ case PIPE_BLENDFACTOR_DST_ALPHA:
+ return V_028804_BLEND_DST_ALPHA;
+ case PIPE_BLENDFACTOR_DST_COLOR:
+ return V_028804_BLEND_DST_COLOR;
+ case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE:
+ return V_028804_BLEND_SRC_ALPHA_SATURATE;
+ case PIPE_BLENDFACTOR_CONST_COLOR:
+ return V_028804_BLEND_CONST_COLOR;
+ case PIPE_BLENDFACTOR_CONST_ALPHA:
+ return V_028804_BLEND_CONST_ALPHA;
+ case PIPE_BLENDFACTOR_ZERO:
+ return V_028804_BLEND_ZERO;
+ case PIPE_BLENDFACTOR_INV_SRC_COLOR:
+ return V_028804_BLEND_ONE_MINUS_SRC_COLOR;
+ case PIPE_BLENDFACTOR_INV_SRC_ALPHA:
+ return V_028804_BLEND_ONE_MINUS_SRC_ALPHA;
+ case PIPE_BLENDFACTOR_INV_DST_ALPHA:
+ return V_028804_BLEND_ONE_MINUS_DST_ALPHA;
+ case PIPE_BLENDFACTOR_INV_DST_COLOR:
+ return V_028804_BLEND_ONE_MINUS_DST_COLOR;
+ case PIPE_BLENDFACTOR_INV_CONST_COLOR:
+ return V_028804_BLEND_ONE_MINUS_CONST_COLOR;
+ case PIPE_BLENDFACTOR_INV_CONST_ALPHA:
+ return V_028804_BLEND_ONE_MINUS_CONST_ALPHA;
+ case PIPE_BLENDFACTOR_SRC1_COLOR:
+ return V_028804_BLEND_SRC1_COLOR;
+ case PIPE_BLENDFACTOR_SRC1_ALPHA:
+ return V_028804_BLEND_SRC1_ALPHA;
+ case PIPE_BLENDFACTOR_INV_SRC1_COLOR:
+ return V_028804_BLEND_INV_SRC1_COLOR;
+ case PIPE_BLENDFACTOR_INV_SRC1_ALPHA:
+ return V_028804_BLEND_INV_SRC1_ALPHA;
+ default:
+ R600_ERR("Bad blend factor %d not supported!\n", blend_fact);
+ assert(0);
+ break;
+ }
+ return 0;
+}
+
+static INLINE uint32_t r600_translate_stencil_op(int s_op)
+{
+ switch (s_op) {
+ case PIPE_STENCIL_OP_KEEP:
+ return V_028800_STENCIL_KEEP;
+ case PIPE_STENCIL_OP_ZERO:
+ return V_028800_STENCIL_ZERO;
+ case PIPE_STENCIL_OP_REPLACE:
+ return V_028800_STENCIL_REPLACE;
+ case PIPE_STENCIL_OP_INCR:
+ return V_028800_STENCIL_INCR;
+ case PIPE_STENCIL_OP_DECR:
+ return V_028800_STENCIL_DECR;
+ case PIPE_STENCIL_OP_INCR_WRAP:
+ return V_028800_STENCIL_INCR_WRAP;
+ case PIPE_STENCIL_OP_DECR_WRAP:
+ return V_028800_STENCIL_DECR_WRAP;
+ case PIPE_STENCIL_OP_INVERT:
+ return V_028800_STENCIL_INVERT;
+ default:
+ R600_ERR("Unknown stencil op %d", s_op);
+ assert(0);
+ break;
+ }
+ return 0;
+}
+
+/* translates straight */
+static INLINE uint32_t r600_translate_ds_func(int func)
+{
+ return func;
+}
+
+static uint32_t r600_translate_dbformat(enum pipe_format format)
+{
+ switch (format) {
+ case PIPE_FORMAT_Z16_UNORM:
+ return V_028010_DEPTH_16;
+ case PIPE_FORMAT_Z24X8_UNORM:
+ return V_028010_DEPTH_X8_24;
+ case PIPE_FORMAT_Z24_UNORM_S8_USCALED:
+ return V_028010_DEPTH_8_24;
+ default:
+ return ~0;
+ }
+}
+
+static uint32_t r600_translate_colorswap(enum pipe_format format)
+{
+ switch (format) {
+ /* 8-bit buffers. */
+ case PIPE_FORMAT_A8_UNORM:
+ case PIPE_FORMAT_I8_UNORM:
+ case PIPE_FORMAT_L8_UNORM:
+ case PIPE_FORMAT_R8_UNORM:
+ case PIPE_FORMAT_R8_SNORM:
+ return V_0280A0_SWAP_STD;
+
+ /* 16-bit buffers. */
+ case PIPE_FORMAT_B5G6R5_UNORM:
+ return V_0280A0_SWAP_STD_REV;
+
+ case PIPE_FORMAT_B5G5R5A1_UNORM:
+ case PIPE_FORMAT_B5G5R5X1_UNORM:
+ return V_0280A0_SWAP_ALT;
+
+ case PIPE_FORMAT_B4G4R4A4_UNORM:
+ case PIPE_FORMAT_B4G4R4X4_UNORM:
+ return V_0280A0_SWAP_ALT;
+ /* 32-bit buffers. */
+
+ case PIPE_FORMAT_A8B8G8R8_SRGB:
+ return V_0280A0_SWAP_STD_REV;
+ case PIPE_FORMAT_B8G8R8A8_SRGB:
+ return V_0280A0_SWAP_ALT;
+
+ case PIPE_FORMAT_B8G8R8A8_UNORM:
+ case PIPE_FORMAT_B8G8R8X8_UNORM:
+ return V_0280A0_SWAP_ALT;
+
+ case PIPE_FORMAT_A8R8G8B8_UNORM:
+ case PIPE_FORMAT_X8R8G8B8_UNORM:
+ return V_0280A0_SWAP_ALT_REV;
+ case PIPE_FORMAT_R8G8B8A8_SNORM:
+ case PIPE_FORMAT_R8G8B8X8_UNORM:
+ return V_0280A0_SWAP_STD;
+
+ case PIPE_FORMAT_A8B8G8R8_UNORM:
+ case PIPE_FORMAT_X8B8G8R8_UNORM:
+ // case PIPE_FORMAT_R8SG8SB8UX8U_NORM:
+ return V_0280A0_SWAP_STD_REV;
+
+ case PIPE_FORMAT_Z24X8_UNORM:
+ case PIPE_FORMAT_Z24_UNORM_S8_USCALED:
+ return V_0280A0_SWAP_STD;
+
+ case PIPE_FORMAT_R10G10B10A2_UNORM:
+ case PIPE_FORMAT_R10G10B10X2_SNORM:
+ case PIPE_FORMAT_B10G10R10A2_UNORM:
+ case PIPE_FORMAT_R10SG10SB10SA2U_NORM:
+ return V_0280A0_SWAP_STD_REV;
+
+ /* 64-bit buffers. */
+ case PIPE_FORMAT_R16G16B16A16_UNORM:
+ case PIPE_FORMAT_R16G16B16A16_SNORM:
+ // return V_0280A0_COLOR_16_16_16_16;
+ case PIPE_FORMAT_R16G16B16A16_FLOAT:
+ // return V_0280A0_COLOR_16_16_16_16_FLOAT;
+
+ /* 128-bit buffers. */
+ case PIPE_FORMAT_R32G32B32A32_FLOAT:
+ // return V_0280A0_COLOR_32_32_32_32_FLOAT;
+ return 0;
+ default:
+ R600_ERR("unsupported colorswap format %d\n", format);
+ return ~0;
+ }
+ return ~0;
+}
+
+static INLINE uint32_t r600_translate_colorformat(enum pipe_format format)
+{
+ switch (format) {
+ /* 8-bit buffers. */
+ case PIPE_FORMAT_A8_UNORM:
+ case PIPE_FORMAT_I8_UNORM:
+ case PIPE_FORMAT_L8_UNORM:
+ case PIPE_FORMAT_R8_UNORM:
+ case PIPE_FORMAT_R8_SNORM:
+ return V_0280A0_COLOR_8;
+
+ /* 16-bit buffers. */
+ case PIPE_FORMAT_B5G6R5_UNORM:
+ return V_0280A0_COLOR_5_6_5;
+
+ case PIPE_FORMAT_B5G5R5A1_UNORM:
+ case PIPE_FORMAT_B5G5R5X1_UNORM:
+ return V_0280A0_COLOR_1_5_5_5;
+
+ case PIPE_FORMAT_B4G4R4A4_UNORM:
+ case PIPE_FORMAT_B4G4R4X4_UNORM:
+ return V_0280A0_COLOR_4_4_4_4;
+
+ /* 32-bit buffers. */
+ case PIPE_FORMAT_A8B8G8R8_SRGB:
+ case PIPE_FORMAT_A8B8G8R8_UNORM:
+ case PIPE_FORMAT_A8R8G8B8_UNORM:
+ case PIPE_FORMAT_B8G8R8A8_SRGB:
+ case PIPE_FORMAT_B8G8R8A8_UNORM:
+ case PIPE_FORMAT_B8G8R8X8_UNORM:
+ case PIPE_FORMAT_R8G8B8A8_SNORM:
+ case PIPE_FORMAT_R8G8B8A8_UNORM:
+ case PIPE_FORMAT_R8G8B8X8_UNORM:
+ case PIPE_FORMAT_R8SG8SB8UX8U_NORM:
+ case PIPE_FORMAT_X8B8G8R8_UNORM:
+ case PIPE_FORMAT_X8R8G8B8_UNORM:
+ return V_0280A0_COLOR_8_8_8_8;
+
+ case PIPE_FORMAT_R10G10B10A2_UNORM:
+ case PIPE_FORMAT_R10G10B10X2_SNORM:
+ case PIPE_FORMAT_B10G10R10A2_UNORM:
+ case PIPE_FORMAT_R10SG10SB10SA2U_NORM:
+ return V_0280A0_COLOR_10_10_10_2;
+
+ case PIPE_FORMAT_Z24X8_UNORM:
+ case PIPE_FORMAT_Z24_UNORM_S8_USCALED:
+ return V_0280A0_COLOR_24_8;
+
+ /* 64-bit buffers. */
+ case PIPE_FORMAT_R16G16B16A16_UNORM:
+ case PIPE_FORMAT_R16G16B16A16_SNORM:
+ return V_0280A0_COLOR_16_16_16_16;
+ case PIPE_FORMAT_R16G16B16A16_FLOAT:
+ return V_0280A0_COLOR_16_16_16_16_FLOAT;
+ case PIPE_FORMAT_R32G32_FLOAT:
+ return V_0280A0_COLOR_32_32_FLOAT;
+
+ /* 128-bit buffers. */
+ case PIPE_FORMAT_R32G32B32_FLOAT:
+ case PIPE_FORMAT_R32G32B32A32_FLOAT:
+ return V_0280A0_COLOR_32_32_32_32_FLOAT;
+
+ /* YUV buffers. */
+ case PIPE_FORMAT_UYVY:
+ case PIPE_FORMAT_YUYV:
+ default:
+ R600_ERR("unsupported color format %d\n", format);
+ return ~0; /* Unsupported. */
+ }
+}
+
+static INLINE boolean r600_is_sampler_format_supported(enum pipe_format format)
+{
+ return r600_translate_texformat(format, NULL, NULL, NULL) != ~0;
+}
+
+static INLINE boolean r600_is_colorbuffer_format_supported(enum pipe_format format)
+{
+ return r600_translate_colorformat(format) != ~0 &&
+ r600_translate_colorswap(format) != ~0;
+}
+
+static INLINE boolean r600_is_zs_format_supported(enum pipe_format format)
+{
+ return r600_translate_dbformat(format) != ~0;
+}
+
+static INLINE boolean r600_is_vertex_format_supported(enum pipe_format format)
+{
+ return r600_translate_colorformat(format) != ~0;
+}
+
+#endif
diff --git a/src/gallium/drivers/r600/r600_texture.c b/src/gallium/drivers/r600/r600_texture.c
index 903cfad80a..30d79ebdd6 100644
--- a/src/gallium/drivers/r600/r600_texture.c
+++ b/src/gallium/drivers/r600/r600_texture.c
@@ -31,15 +31,19 @@
#include <util/u_memory.h>
#include "state_tracker/drm_driver.h"
#include "r600_screen.h"
-#include "r600_texture.h"
+#include "r600_context.h"
+#include "r600_resource.h"
+#include "r600d.h"
extern struct u_resource_vtbl r600_texture_vtbl;
-unsigned long r600_texture_get_offset(struct r600_texture *rtex, unsigned level, unsigned zslice, unsigned face)
+static unsigned long r600_texture_get_offset(struct r600_resource_texture *rtex,
+ unsigned level, unsigned zslice,
+ unsigned face)
{
unsigned long offset = rtex->offset[level];
- switch (rtex->b.b.target) {
+ switch (rtex->resource.base.b.target) {
case PIPE_TEXTURE_3D:
assert(face == 0);
return offset + zslice * rtex->layer_size[level];
@@ -52,67 +56,68 @@ unsigned long r600_texture_get_offset(struct r600_texture *rtex, unsigned level,
}
}
-static void r600_setup_miptree(struct r600_screen *rscreen, struct r600_texture *rtex)
+static void r600_setup_miptree(struct r600_screen *rscreen, struct r600_resource_texture *rtex)
{
- struct pipe_resource *ptex = &rtex->b.b;
- unsigned long w, h, stride, size, layer_size, i, offset;
+ struct pipe_resource *ptex = &rtex->resource.base.b;
+ unsigned long w, h, pitch, size, layer_size, i, offset;
+ rtex->bpt = util_format_get_blocksize(ptex->format);
for (i = 0, offset = 0; i <= ptex->last_level; i++) {
w = u_minify(ptex->width0, i);
h = u_minify(ptex->height0, i);
- stride = align(util_format_get_stride(ptex->format, w), 32);
- layer_size = stride * h;
+ pitch = util_format_get_stride(ptex->format, align(w, 64));
+ layer_size = pitch * h;
if (ptex->target == PIPE_TEXTURE_CUBE)
size = layer_size * 6;
else
size = layer_size * u_minify(ptex->depth0, i);
rtex->offset[i] = offset;
rtex->layer_size[i] = layer_size;
- rtex->pitch[i] = stride / util_format_get_blocksize(ptex->format);
- rtex->stride[i] = stride;
- offset += align(size, 32);
+ rtex->pitch[i] = pitch;
+ offset += size;
}
rtex->size = offset;
}
struct pipe_resource *r600_texture_create(struct pipe_screen *screen,
- const struct pipe_resource *templ)
+ const struct pipe_resource *templ)
{
- struct r600_texture *rtex = CALLOC_STRUCT(r600_texture);
+ struct r600_resource_texture *rtex;
+ struct r600_resource *resource;
struct r600_screen *rscreen = r600_screen(screen);
- struct pipe_resource templ_buf;
+ rtex = CALLOC_STRUCT(r600_resource_texture);
if (!rtex) {
return NULL;
}
- rtex->b.b = *templ;
- rtex->b.vtbl = &r600_texture_vtbl;
- pipe_reference_init(&rtex->b.b.reference, 1);
- rtex->b.b.screen = screen;
+ resource = &rtex->resource;
+ resource->base.b = *templ;
+ resource->base.vtbl = &r600_texture_vtbl;
+ pipe_reference_init(&resource->base.b.reference, 1);
+ resource->base.b.screen = screen;
r600_setup_miptree(rscreen, rtex);
- memset(&templ_buf, 0, sizeof(struct pipe_resource));
- templ_buf.target = PIPE_BUFFER;
- templ_buf.format = PIPE_FORMAT_R8_UNORM;
- templ_buf.usage = templ->usage;
- templ_buf.bind = templ->bind;
- templ_buf.width0 = rtex->size;
- templ_buf.height0 = 1;
- templ_buf.depth0 = 1;
-
- rtex->buffer = screen->resource_create(screen, &templ_buf);
- if (!rtex->buffer) {
+ /* FIXME alignment 4096 enought ? too much ? */
+ resource->domain = r600_domain_from_usage(resource->base.b.bind);
+ resource->bo = radeon_bo(rscreen->rw, 0, rtex->size, 4096, NULL);
+ if (resource->bo == NULL) {
FREE(rtex);
return NULL;
}
- return &rtex->b.b;
+
+ return &resource->base.b;
}
static void r600_texture_destroy(struct pipe_screen *screen,
struct pipe_resource *ptex)
{
- struct r600_texture *rtex = (struct r600_texture*)ptex;
+ struct r600_resource_texture *rtex = (struct r600_resource_texture*)ptex;
+ struct r600_resource *resource = &rtex->resource;
+ struct r600_screen *rscreen = r600_screen(screen);
+ if (resource->bo) {
+ radeon_bo_decref(rscreen->rw, resource->bo);
+ }
FREE(rtex);
}
@@ -121,7 +126,7 @@ static struct pipe_surface *r600_get_tex_surface(struct pipe_screen *screen,
unsigned face, unsigned level,
unsigned zslice, unsigned flags)
{
- struct r600_texture *rtex = (struct r600_texture*)texture;
+ struct r600_resource_texture *rtex = (struct r600_resource_texture*)texture;
struct pipe_surface *surface = CALLOC_STRUCT(pipe_surface);
unsigned long offset;
@@ -149,71 +154,115 @@ static void r600_tex_surface_destroy(struct pipe_surface *surface)
}
struct pipe_resource *r600_texture_from_handle(struct pipe_screen *screen,
- const struct pipe_resource *base,
+ const struct pipe_resource *templ,
struct winsys_handle *whandle)
{
- struct pipe_resource *buffer;
- struct r600_texture *rtex;
+ struct radeon *rw = (struct radeon*)screen->winsys;
+ struct r600_resource_texture *rtex;
+ struct r600_resource *resource;
+ struct radeon_bo *bo = NULL;
- buffer = r600_buffer_from_handle(screen, whandle);
- if (buffer == NULL) {
+ bo = radeon_bo(rw, whandle->handle, 0, 0, NULL);
+ if (bo == NULL) {
return NULL;
}
/* Support only 2D textures without mipmaps */
- if (base->target != PIPE_TEXTURE_2D || base->depth0 != 1 || base->last_level != 0)
+ if (templ->target != PIPE_TEXTURE_2D || templ->depth0 != 1 || templ->last_level != 0)
return NULL;
- rtex = CALLOC_STRUCT(r600_texture);
+ rtex = CALLOC_STRUCT(r600_resource_texture);
if (rtex == NULL)
return NULL;
- /* one ref already taken */
- rtex->buffer = buffer;
-
- rtex->b.b = *base;
- rtex->b.vtbl = &r600_texture_vtbl;
- pipe_reference_init(&rtex->b.b.reference, 1);
- rtex->b.b.screen = screen;
- rtex->stride_override = whandle->stride;
- rtex->pitch[0] = whandle->stride / util_format_get_blocksize(base->format);
- rtex->stride[0] = whandle->stride;
+ resource = &rtex->resource;
+ resource->base.b = *templ;
+ resource->base.vtbl = &r600_texture_vtbl;
+ pipe_reference_init(&resource->base.b.reference, 1);
+ resource->base.b.screen = screen;
+ resource->bo = bo;
+ rtex->pitch_override = whandle->stride;
+ rtex->bpt = util_format_get_blocksize(templ->format);
+ rtex->pitch[0] = whandle->stride;
rtex->offset[0] = 0;
- rtex->size = align(rtex->stride[0] * base->height0, 32);
+ rtex->size = align(rtex->pitch[0] * templ->height0, 64);
- return &rtex->b.b;
+ return &resource->base.b;
}
-static boolean r600_texture_get_handle(struct pipe_screen* screen,
- struct pipe_resource *texture,
- struct winsys_handle *whandle)
+static unsigned int r600_texture_is_referenced(struct pipe_context *context,
+ struct pipe_resource *texture,
+ unsigned face, unsigned level)
{
- struct r600_screen *rscreen = r600_screen(screen);
- struct r600_texture* rtex = (struct r600_texture*)texture;
+ /* FIXME */
+ return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE;
+}
- if (!rtex) {
- return FALSE;
- }
+struct pipe_transfer* r600_texture_get_transfer(struct pipe_context *ctx,
+ struct pipe_resource *texture,
+ struct pipe_subresource sr,
+ unsigned usage,
+ const struct pipe_box *box)
+{
+ struct r600_resource_texture *rtex = (struct r600_resource_texture*)texture;
+ struct r600_transfer *trans;
- whandle->stride = rtex->stride[0];
+ trans = CALLOC_STRUCT(r600_transfer);
+ if (trans == NULL)
+ return NULL;
+ pipe_resource_reference(&trans->transfer.resource, texture);
+ trans->transfer.sr = sr;
+ trans->transfer.usage = usage;
+ trans->transfer.box = *box;
+ trans->transfer.stride = rtex->pitch[sr.level];
+ trans->offset = r600_texture_get_offset(rtex, sr.level, box->z, sr.face);
+ return &trans->transfer;
+}
- r600_buffer_get_handle(rscreen->rw, rtex->buffer, whandle);
+void r600_texture_transfer_destroy(struct pipe_context *ctx,
+ struct pipe_transfer *trans)
+{
+ pipe_resource_reference(&trans->resource, NULL);
+ FREE(trans);
+}
- return TRUE;
+void* r600_texture_transfer_map(struct pipe_context *ctx,
+ struct pipe_transfer* transfer)
+{
+ struct r600_transfer *rtransfer = (struct r600_transfer*)transfer;
+ struct r600_resource *resource;
+ enum pipe_format format = transfer->resource->format;
+ struct r600_screen *rscreen = r600_screen(ctx->screen);
+ char *map;
+
+ r600_flush(ctx, 0, NULL);
+
+ resource = (struct r600_resource *)transfer->resource;
+ if (radeon_bo_map(rscreen->rw, resource->bo)) {
+ return NULL;
+ }
+ radeon_bo_wait(rscreen->rw, resource->bo);
+
+ map = resource->bo->data;
+
+ return map + rtransfer->offset +
+ transfer->box.y / util_format_get_blockheight(format) * transfer->stride +
+ transfer->box.x / util_format_get_blockwidth(format) * util_format_get_blocksize(format);
}
-static unsigned int r600_texture_is_referenced(struct pipe_context *context,
- struct pipe_resource *texture,
- unsigned face, unsigned level)
+void r600_texture_transfer_unmap(struct pipe_context *ctx,
+ struct pipe_transfer* transfer)
{
- struct r600_texture *rtex = (struct r600_texture*)texture;
+ struct r600_screen *rscreen = r600_screen(ctx->screen);
+ struct r600_resource *resource;
- return r600_buffer_is_referenced_by_cs(context, rtex->buffer, face, level);
+ resource = (struct r600_resource *)transfer->resource;
+ radeon_bo_unmap(rscreen->rw, resource->bo);
}
struct u_resource_vtbl r600_texture_vtbl =
{
- r600_texture_get_handle, /* get_handle */
+ u_default_resource_get_handle, /* get_handle */
r600_texture_destroy, /* resource_destroy */
r600_texture_is_referenced, /* is_resource_referenced */
r600_texture_get_transfer, /* get_transfer */
@@ -229,3 +278,250 @@ void r600_init_screen_texture_functions(struct pipe_screen *screen)
screen->get_tex_surface = r600_get_tex_surface;
screen->tex_surface_destroy = r600_tex_surface_destroy;
}
+
+static unsigned r600_get_swizzle_combined(const unsigned char *swizzle_format,
+ const unsigned char *swizzle_view)
+{
+ unsigned i;
+ unsigned char swizzle[4];
+ unsigned result = 0;
+ const uint32_t swizzle_shift[4] = {
+ 16, 19, 22, 25,
+ };
+ const uint32_t swizzle_bit[4] = {
+ 0, 1, 2, 3,
+ };
+
+ if (swizzle_view) {
+ /* Combine two sets of swizzles. */
+ for (i = 0; i < 4; i++) {
+ swizzle[i] = swizzle_view[i] <= UTIL_FORMAT_SWIZZLE_W ?
+ swizzle_format[swizzle_view[i]] : swizzle_view[i];
+ }
+ } else {
+ memcpy(swizzle, swizzle_format, 4);
+ }
+
+ /* Get swizzle. */
+ for (i = 0; i < 4; i++) {
+ switch (swizzle[i]) {
+ case UTIL_FORMAT_SWIZZLE_Y:
+ result |= swizzle_bit[1] << swizzle_shift[i];
+ break;
+ case UTIL_FORMAT_SWIZZLE_Z:
+ result |= swizzle_bit[2] << swizzle_shift[i];
+ break;
+ case UTIL_FORMAT_SWIZZLE_W:
+ result |= swizzle_bit[3] << swizzle_shift[i];
+ break;
+ case UTIL_FORMAT_SWIZZLE_0:
+ result |= V_038010_SQ_SEL_0 << swizzle_shift[i];
+ break;
+ case UTIL_FORMAT_SWIZZLE_1:
+ result |= V_038010_SQ_SEL_1 << swizzle_shift[i];
+ break;
+ default: /* UTIL_FORMAT_SWIZZLE_X */
+ result |= swizzle_bit[0] << swizzle_shift[i];
+ }
+ }
+ return result;
+}
+
+/* texture format translate */
+uint32_t r600_translate_texformat(enum pipe_format format,
+ const unsigned char *swizzle_view,
+ uint32_t *word4_p, uint32_t *yuv_format_p)
+{
+ uint32_t result = 0, word4 = 0, yuv_format = 0;
+ const struct util_format_description *desc;
+ boolean uniform = TRUE;
+ int i;
+ const uint32_t sign_bit[4] = {
+ S_038010_FORMAT_COMP_X(V_038010_SQ_FORMAT_COMP_SIGNED),
+ S_038010_FORMAT_COMP_Y(V_038010_SQ_FORMAT_COMP_SIGNED),
+ S_038010_FORMAT_COMP_Z(V_038010_SQ_FORMAT_COMP_SIGNED),
+ S_038010_FORMAT_COMP_W(V_038010_SQ_FORMAT_COMP_SIGNED)
+ };
+ desc = util_format_description(format);
+
+ /* Colorspace (return non-RGB formats directly). */
+ switch (desc->colorspace) {
+ /* Depth stencil formats */
+ case UTIL_FORMAT_COLORSPACE_ZS:
+ switch (format) {
+ case PIPE_FORMAT_Z16_UNORM:
+ result = V_028010_DEPTH_16;
+ goto out_word4;
+ case PIPE_FORMAT_Z24X8_UNORM:
+ result = V_028010_DEPTH_X8_24;
+ goto out_word4;
+ case PIPE_FORMAT_Z24_UNORM_S8_USCALED:
+ result = V_028010_DEPTH_8_24;
+ goto out_word4;
+ default:
+ goto out_unknown;
+ }
+
+ case UTIL_FORMAT_COLORSPACE_YUV:
+ yuv_format |= (1 << 30);
+ switch (format) {
+ case PIPE_FORMAT_UYVY:
+ case PIPE_FORMAT_YUYV:
+ default:
+ break;
+ }
+ goto out_unknown; /* TODO */
+
+ case UTIL_FORMAT_COLORSPACE_SRGB:
+ word4 |= S_038010_FORCE_DEGAMMA(1);
+ if (format == PIPE_FORMAT_L8A8_SRGB || format == PIPE_FORMAT_L8_SRGB)
+ goto out_unknown; /* fails for some reason - TODO */
+ break;
+
+ default:
+ break;
+ }
+
+ word4 |= r600_get_swizzle_combined(desc->swizzle, swizzle_view);
+
+ /* S3TC formats. TODO */
+ if (desc->layout == UTIL_FORMAT_LAYOUT_S3TC) {
+ goto out_unknown;
+ }
+
+
+ for (i = 0; i < desc->nr_channels; i++) {
+ if (desc->channel[i].type == UTIL_FORMAT_TYPE_SIGNED) {
+ word4 |= sign_bit[i];
+ }
+ }
+
+ /* R8G8Bx_SNORM - TODO CxV8U8 */
+
+ /* RGTC - TODO */
+
+ /* See whether the components are of the same size. */
+ for (i = 1; i < desc->nr_channels; i++) {
+ uniform = uniform && desc->channel[0].size == desc->channel[i].size;
+ }
+
+ /* Non-uniform formats. */
+ if (!uniform) {
+ switch(desc->nr_channels) {
+ case 3:
+ if (desc->channel[0].size == 5 &&
+ desc->channel[1].size == 6 &&
+ desc->channel[2].size == 5) {
+ result |= V_0280A0_COLOR_5_6_5;
+ goto out_word4;
+ }
+ goto out_unknown;
+ case 4:
+ if (desc->channel[0].size == 5 &&
+ desc->channel[1].size == 5 &&
+ desc->channel[2].size == 5 &&
+ desc->channel[3].size == 1) {
+ result |= V_0280A0_COLOR_1_5_5_5;
+ goto out_word4;
+ }
+ if (desc->channel[0].size == 10 &&
+ desc->channel[1].size == 10 &&
+ desc->channel[2].size == 10 &&
+ desc->channel[3].size == 2) {
+ result |= V_0280A0_COLOR_10_10_10_2;
+ goto out_word4;
+ }
+ goto out_unknown;
+ }
+ goto out_unknown;
+ }
+
+ /* uniform formats */
+ switch (desc->channel[0].type) {
+ case UTIL_FORMAT_TYPE_UNSIGNED:
+ case UTIL_FORMAT_TYPE_SIGNED:
+ if (!desc->channel[0].normalized &&
+ desc->colorspace != UTIL_FORMAT_COLORSPACE_SRGB) {
+ goto out_unknown;
+ }
+
+ switch (desc->channel[0].size) {
+ case 4:
+ switch (desc->nr_channels) {
+ case 2:
+ result |= V_0280A0_COLOR_4_4;
+ goto out_word4;
+ case 4:
+ result |= V_0280A0_COLOR_4_4_4_4;
+ goto out_word4;
+ }
+ goto out_unknown;
+ case 8:
+ switch (desc->nr_channels) {
+ case 1:
+ result |= V_0280A0_COLOR_8;
+ goto out_word4;
+ case 2:
+ result |= V_0280A0_COLOR_8_8;
+ goto out_word4;
+ case 4:
+ result |= V_0280A0_COLOR_8_8_8_8;
+ goto out_word4;
+ }
+ goto out_unknown;
+ case 16:
+ switch (desc->nr_channels) {
+ case 1:
+ result |= V_0280A0_COLOR_16;
+ goto out_word4;
+ case 2:
+ result |= V_0280A0_COLOR_16_16;
+ goto out_word4;
+ case 4:
+ result |= V_0280A0_COLOR_16_16_16_16;
+ goto out_word4;
+ }
+ }
+ goto out_unknown;
+
+ case UTIL_FORMAT_TYPE_FLOAT:
+ switch (desc->channel[0].size) {
+ case 16:
+ switch (desc->nr_channels) {
+ case 1:
+ result |= V_0280A0_COLOR_16_FLOAT;
+ goto out_word4;
+ case 2:
+ result |= V_0280A0_COLOR_16_16_FLOAT;
+ goto out_word4;
+ case 4:
+ result |= V_0280A0_COLOR_16_16_16_16_FLOAT;
+ goto out_word4;
+ }
+ goto out_unknown;
+ case 32:
+ switch (desc->nr_channels) {
+ case 1:
+ result |= V_0280A0_COLOR_32_FLOAT;
+ goto out_word4;
+ case 2:
+ result |= V_0280A0_COLOR_32_32_FLOAT;
+ goto out_word4;
+ case 4:
+ result |= V_0280A0_COLOR_32_32_32_32_FLOAT;
+ goto out_word4;
+ }
+ }
+
+ }
+out_word4:
+ if (word4_p)
+ *word4_p = word4;
+ if (yuv_format_p)
+ *yuv_format_p = yuv_format;
+// fprintf(stderr,"returning %08x %08x %08x\n", result, word4, yuv_format);
+ return result;
+out_unknown:
+// R600_ERR("Unable to handle texformat %d %s\n", format, util_format_name(format));
+ return ~0;
+}
diff --git a/src/gallium/drivers/r600/r600_texture.h b/src/gallium/drivers/r600/r600_texture.h
deleted file mode 100644
index 9bc08d6b04..0000000000
--- a/src/gallium/drivers/r600/r600_texture.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright 2010 Jerome Glisse <glisse@freedesktop.org>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * on the rights to use, copy, modify, merge, publish, distribute, sub
- * license, and/or sell copies of the Software, and to permit persons to whom
- * the Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
- * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
- * USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-#ifndef R600_TEXTURE_H
-#define R600_TEXTURE_H
-
-#include <pipe/p_state.h>
-
-struct r600_texture {
- struct u_resource b;
- unsigned long offset[PIPE_MAX_TEXTURE_LEVELS];
- unsigned long pitch[PIPE_MAX_TEXTURE_LEVELS];
- unsigned long stride[PIPE_MAX_TEXTURE_LEVELS];
- unsigned long layer_size[PIPE_MAX_TEXTURE_LEVELS];
- unsigned long stride_override;
- unsigned long size;
- struct pipe_resource *buffer;
-};
-
-struct pipe_resource *r600_texture_create(struct pipe_screen *screen,
- const struct pipe_resource *templ);
-unsigned long r600_texture_get_offset(struct r600_texture *rtex, unsigned level, unsigned zslice, unsigned face);
-struct pipe_resource *r600_texture_from_handle(struct pipe_screen *screen,
- const struct pipe_resource *base,
- struct winsys_handle *whandle);
-void r600_init_screen_texture_functions(struct pipe_screen *screen);
-
-/* This should be implemented by winsys. */
-boolean r600_buffer_get_handle(struct radeon *rw,
- struct pipe_resource *buf,
- struct winsys_handle *whandle);
-
-
-#endif
diff --git a/src/gallium/drivers/r600/r600d.h b/src/gallium/drivers/r600/r600d.h
index 44834984c6..53388f822e 100644
--- a/src/gallium/drivers/r600/r600d.h
+++ b/src/gallium/drivers/r600/r600d.h
@@ -26,6 +26,8 @@
#ifndef R600D_H
#define R600D_H
+#define R600_TEXEL_PITCH_ALIGNMENT_MASK 0x7
+
#define PKT3_NOP 0x10
#define PKT3_INDIRECT_BUFFER_END 0x17
#define PKT3_SET_PREDICATION 0x20
@@ -207,12 +209,24 @@
#define S_0280A0_NUMBER_TYPE(x) (((x) & 0x7) << 12)
#define G_0280A0_NUMBER_TYPE(x) (((x) >> 12) & 0x7)
#define C_0280A0_NUMBER_TYPE 0xFFFF8FFF
+#define V_0280A0_NUMBER_UNORM 0x00000000
+#define V_0280A0_NUMBER_SNORM 0x00000001
+#define V_0280A0_NUMBER_USCALED 0x00000002
+#define V_0280A0_NUMBER_SSCALED 0x00000003
+#define V_0280A0_NUMBER_UINT 0x00000004
+#define V_0280A0_NUMBER_SINT 0x00000005
+#define V_0280A0_NUMBER_SRGB 0x00000006
+#define V_0280A0_NUMBER_FLOAT 0x00000007
#define S_0280A0_READ_SIZE(x) (((x) & 0x1) << 15)
#define G_0280A0_READ_SIZE(x) (((x) >> 15) & 0x1)
#define C_0280A0_READ_SIZE 0xFFFF7FFF
#define S_0280A0_COMP_SWAP(x) (((x) & 0x3) << 16)
#define G_0280A0_COMP_SWAP(x) (((x) >> 16) & 0x3)
#define C_0280A0_COMP_SWAP 0xFFFCFFFF
+#define V_0280A0_SWAP_STD 0x00000000
+#define V_0280A0_SWAP_ALT 0x00000001
+#define V_0280A0_SWAP_STD_REV 0x00000002
+#define V_0280A0_SWAP_ALT_REV 0x00000003
#define S_0280A0_TILE_MODE(x) (((x) & 0x3) << 18)
#define G_0280A0_TILE_MODE(x) (((x) >> 18) & 0x3)
#define C_0280A0_TILE_MODE 0xFFF3FFFF
@@ -247,6 +261,16 @@
#define S_028060_SLICE_TILE_MAX(x) (((x) & 0xFFFFF) << 10)
#define G_028060_SLICE_TILE_MAX(x) (((x) >> 10) & 0xFFFFF)
#define C_028060_SLICE_TILE_MAX 0xC00003FF
+#define R_028410_SX_ALPHA_TEST_CONTROL 0x028410
+#define S_028410_ALPHA_FUNC(x) (((x) & 0x7) << 0)
+#define G_028410_ALPHA_FUNC(x) (((x) >> 0) & 0x7)
+#define C_028410_ALPHA_FUNC 0xFFFFFFF8
+#define S_028410_ALPHA_TEST_ENABLE(x) (((x) & 0x1) << 3)
+#define G_028410_ALPHA_TEST_ENABLE(x) (((x) >> 3) & 0x1)
+#define C_028410_ALPHA_TEST_ENABLE 0xFFFFFFF7
+#define S_028410_ALPHA_TEST_BYPASS(x) (((x) & 0x1) << 8)
+#define G_028410_ALPHA_TEST_BYPASS(x) (((x) >> 8) & 0x1)
+#define C_028410_ALPHA_TEST_BYPASS 0xFFFFFEFF
#define R_028800_DB_DEPTH_CONTROL 0x028800
#define S_028800_STENCIL_ENABLE(x) (((x) & 0x1) << 0)
#define G_028800_STENCIL_ENABLE(x) (((x) >> 0) & 0x1)
@@ -266,9 +290,25 @@
#define S_028800_STENCILFUNC(x) (((x) & 0x7) << 8)
#define G_028800_STENCILFUNC(x) (((x) >> 8) & 0x7)
#define C_028800_STENCILFUNC 0xFFFFF8FF
+#define V_028800_STENCILFUNC_NEVER 0x00000000
+#define V_028800_STENCILFUNC_LESS 0x00000001
+#define V_028800_STENCILFUNC_EQUAL 0x00000002
+#define V_028800_STENCILFUNC_LEQUAL 0x00000003
+#define V_028800_STENCILFUNC_GREATER 0x00000004
+#define V_028800_STENCILFUNC_NOTEQUAL 0x00000005
+#define V_028800_STENCILFUNC_GEQUAL 0x00000006
+#define V_028800_STENCILFUNC_ALWAYS 0x00000007
#define S_028800_STENCILFAIL(x) (((x) & 0x7) << 11)
#define G_028800_STENCILFAIL(x) (((x) >> 11) & 0x7)
#define C_028800_STENCILFAIL 0xFFFFC7FF
+#define V_028800_STENCIL_KEEP 0x00000000
+#define V_028800_STENCIL_ZERO 0x00000001
+#define V_028800_STENCIL_REPLACE 0x00000002
+#define V_028800_STENCIL_INCR 0x00000003
+#define V_028800_STENCIL_DECR 0x00000004
+#define V_028800_STENCIL_INVERT 0x00000005
+#define V_028800_STENCIL_INCR_WRAP 0x00000006
+#define V_028800_STENCIL_DECR_WRAP 0x00000007
#define S_028800_STENCILZPASS(x) (((x) & 0x7) << 14)
#define G_028800_STENCILZPASS(x) (((x) >> 14) & 0x7)
#define C_028800_STENCILZPASS 0xFFFE3FFF
@@ -287,6 +327,86 @@
#define S_028800_STENCILZFAIL_BF(x) (((x) & 0x7) << 29)
#define G_028800_STENCILZFAIL_BF(x) (((x) >> 29) & 0x7)
#define C_028800_STENCILZFAIL_BF 0x1FFFFFFF
+#define R_028808_CB_COLOR_CONTROL 0x028808
+#define S_028808_FOG_ENABLE(x) (((x) & 0x1) << 0)
+#define G_028808_FOG_ENABLE(x) (((x) >> 0) & 0x1)
+#define C_028808_FOG_ENABLE 0xFFFFFFFE
+#define S_028808_MULTIWRITE_ENABLE(x) (((x) & 0x1) << 1)
+#define G_028808_MULTIWRITE_ENABLE(x) (((x) >> 1) & 0x1)
+#define C_028808_MULTIWRITE_ENABLE 0xFFFFFFFD
+#define S_028808_DITHER_ENABLE(x) (((x) & 0x1) << 2)
+#define G_028808_DITHER_ENABLE(x) (((x) >> 2) & 0x1)
+#define C_028808_DITHER_ENABLE 0xFFFFFFFB
+#define S_028808_DEGAMMA_ENABLE(x) (((x) & 0x1) << 3)
+#define G_028808_DEGAMMA_ENABLE(x) (((x) >> 3) & 0x1)
+#define C_028808_DEGAMMA_ENABLE 0xFFFFFFF7
+#define S_028808_SPECIAL_OP(x) (((x) & 0x7) << 4)
+#define G_028808_SPECIAL_OP(x) (((x) >> 4) & 0x7)
+#define C_028808_SPECIAL_OP 0xFFFFFF8F
+#define S_028808_PER_MRT_BLEND(x) (((x) & 0x1) << 7)
+#define G_028808_PER_MRT_BLEND(x) (((x) >> 7) & 0x1)
+#define C_028808_PER_MRT_BLEND 0xFFFFFF7F
+#define S_028808_TARGET_BLEND_ENABLE(x) (((x) & 0xFF) << 8)
+#define G_028808_TARGET_BLEND_ENABLE(x) (((x) >> 8) & 0xFF)
+#define C_028808_TARGET_BLEND_ENABLE 0xFFFF00FF
+#define S_028808_ROP3(x) (((x) & 0xFF) << 16)
+#define G_028808_ROP3(x) (((x) >> 16) & 0xFF)
+#define C_028808_ROP3 0xFF00FFFF
+#define R_028810_PA_CL_CLIP_CNTL 0x028810
+#define S_028810_UCP_ENA_0(x) (((x) & 0x1) << 0)
+#define G_028810_UCP_ENA_0(x) (((x) >> 0) & 0x1)
+#define C_028810_UCP_ENA_0 0xFFFFFFFE
+#define S_028810_UCP_ENA_1(x) (((x) & 0x1) << 1)
+#define G_028810_UCP_ENA_1(x) (((x) >> 1) & 0x1)
+#define C_028810_UCP_ENA_1 0xFFFFFFFD
+#define S_028810_UCP_ENA_2(x) (((x) & 0x1) << 2)
+#define G_028810_UCP_ENA_2(x) (((x) >> 2) & 0x1)
+#define C_028810_UCP_ENA_2 0xFFFFFFFB
+#define S_028810_UCP_ENA_3(x) (((x) & 0x1) << 3)
+#define G_028810_UCP_ENA_3(x) (((x) >> 3) & 0x1)
+#define C_028810_UCP_ENA_3 0xFFFFFFF7
+#define S_028810_UCP_ENA_4(x) (((x) & 0x1) << 4)
+#define G_028810_UCP_ENA_4(x) (((x) >> 4) & 0x1)
+#define C_028810_UCP_ENA_4 0xFFFFFFEF
+#define S_028810_UCP_ENA_5(x) (((x) & 0x1) << 5)
+#define G_028810_UCP_ENA_5(x) (((x) >> 5) & 0x1)
+#define C_028810_UCP_ENA_5 0xFFFFFFDF
+#define S_028810_PS_UCP_Y_SCALE_NEG(x) (((x) & 0x1) << 13)
+#define G_028810_PS_UCP_Y_SCALE_NEG(x) (((x) >> 13) & 0x1)
+#define C_028810_PS_UCP_Y_SCALE_NEG 0xFFFFDFFF
+#define S_028810_PS_UCP_MODE(x) (((x) & 0x3) << 14)
+#define G_028810_PS_UCP_MODE(x) (((x) >> 14) & 0x3)
+#define C_028810_PS_UCP_MODE 0xFFFF3FFF
+#define S_028810_CLIP_DISABLE(x) (((x) & 0x1) << 16)
+#define G_028810_CLIP_DISABLE(x) (((x) >> 16) & 0x1)
+#define C_028810_CLIP_DISABLE 0xFFFEFFFF
+#define S_028810_UCP_CULL_ONLY_ENA(x) (((x) & 0x1) << 17)
+#define G_028810_UCP_CULL_ONLY_ENA(x) (((x) >> 17) & 0x1)
+#define C_028810_UCP_CULL_ONLY_ENA 0xFFFDFFFF
+#define S_028810_BOUNDARY_EDGE_FLAG_ENA(x) (((x) & 0x1) << 18)
+#define G_028810_BOUNDARY_EDGE_FLAG_ENA(x) (((x) >> 18) & 0x1)
+#define C_028810_BOUNDARY_EDGE_FLAG_ENA 0xFFFBFFFF
+#define S_028810_DX_CLIP_SPACE_DEF(x) (((x) & 0x1) << 19)
+#define G_028810_DX_CLIP_SPACE_DEF(x) (((x) >> 19) & 0x1)
+#define C_028810_DX_CLIP_SPACE_DEF 0xFFF7FFFF
+#define S_028810_DIS_CLIP_ERR_DETECT(x) (((x) & 0x1) << 20)
+#define G_028810_DIS_CLIP_ERR_DETECT(x) (((x) >> 20) & 0x1)
+#define C_028810_DIS_CLIP_ERR_DETECT 0xFFEFFFFF
+#define S_028810_VTX_KILL_OR(x) (((x) & 0x1) << 21)
+#define G_028810_VTX_KILL_OR(x) (((x) >> 21) & 0x1)
+#define C_028810_VTX_KILL_OR 0xFFDFFFFF
+#define S_028810_DX_LINEAR_ATTR_CLIP_ENA(x) (((x) & 0x1) << 24)
+#define G_028810_DX_LINEAR_ATTR_CLIP_ENA(x) (((x) >> 24) & 0x1)
+#define C_028810_DX_LINEAR_ATTR_CLIP_ENA 0xFEFFFFFF
+#define S_028810_VTE_VPORT_PROVOKE_DISABLE(x) (((x) & 0x1) << 25)
+#define G_028810_VTE_VPORT_PROVOKE_DISABLE(x) (((x) >> 25) & 0x1)
+#define C_028810_VTE_VPORT_PROVOKE_DISABLE 0xFDFFFFFF
+#define S_028810_ZCLIP_NEAR_DISABLE(x) (((x) & 0x1) << 26)
+#define G_028810_ZCLIP_NEAR_DISABLE(x) (((x) >> 26) & 0x1)
+#define C_028810_ZCLIP_NEAR_DISABLE 0xFBFFFFFF
+#define S_028810_ZCLIP_FAR_DISABLE(x) (((x) & 0x1) << 27)
+#define G_028810_ZCLIP_FAR_DISABLE(x) (((x) >> 27) & 0x1)
+#define C_028810_ZCLIP_FAR_DISABLE 0xF7FFFFFF
#define R_028010_DB_DEPTH_INFO 0x028010
#define S_028010_FORMAT(x) (((x) & 0x7) << 0)
#define G_028010_FORMAT(x) (((x) >> 0) & 0x7)
@@ -314,6 +434,117 @@
#define S_028010_ZRANGE_PRECISION(x) (((x) & 0x1) << 31)
#define G_028010_ZRANGE_PRECISION(x) (((x) >> 31) & 0x1)
#define C_028010_ZRANGE_PRECISION 0x7FFFFFFF
+#define R_028430_DB_STENCILREFMASK 0x028430
+#define S_028430_STENCILREF(x) (((x) & 0xFF) << 0)
+#define G_028430_STENCILREF(x) (((x) >> 0) & 0xFF)
+#define C_028430_STENCILREF 0xFFFFFF00
+#define S_028430_STENCILMASK(x) (((x) & 0xFF) << 8)
+#define G_028430_STENCILMASK(x) (((x) >> 8) & 0xFF)
+#define C_028430_STENCILMASK 0xFFFF00FF
+#define S_028430_STENCILWRITEMASK(x) (((x) & 0xFF) << 16)
+#define G_028430_STENCILWRITEMASK(x) (((x) >> 16) & 0xFF)
+#define C_028430_STENCILWRITEMASK 0xFF00FFFF
+#define R_028434_DB_STENCILREFMASK_BF 0x028434
+#define S_028434_STENCILREF_BF(x) (((x) & 0xFF) << 0)
+#define G_028434_STENCILREF_BF(x) (((x) >> 0) & 0xFF)
+#define C_028434_STENCILREF_BF 0xFFFFFF00
+#define S_028434_STENCILMASK_BF(x) (((x) & 0xFF) << 8)
+#define G_028434_STENCILMASK_BF(x) (((x) >> 8) & 0xFF)
+#define C_028434_STENCILMASK_BF 0xFFFF00FF
+#define S_028434_STENCILWRITEMASK_BF(x) (((x) & 0xFF) << 16)
+#define G_028434_STENCILWRITEMASK_BF(x) (((x) >> 16) & 0xFF)
+#define C_028434_STENCILWRITEMASK_BF 0xFF00FFFF
+#define R_028804_CB_BLEND_CONTROL 0x028804
+#define S_028804_COLOR_SRCBLEND(x) (((x) & 0x1F) << 0)
+#define G_028804_COLOR_SRCBLEND(x) (((x) >> 0) & 0x1F)
+#define C_028804_COLOR_SRCBLEND 0xFFFFFFE0
+#define V_028804_BLEND_ZERO 0x00000000
+#define V_028804_BLEND_ONE 0x00000001
+#define V_028804_BLEND_SRC_COLOR 0x00000002
+#define V_028804_BLEND_ONE_MINUS_SRC_COLOR 0x00000003
+#define V_028804_BLEND_SRC_ALPHA 0x00000004
+#define V_028804_BLEND_ONE_MINUS_SRC_ALPHA 0x00000005
+#define V_028804_BLEND_DST_ALPHA 0x00000006
+#define V_028804_BLEND_ONE_MINUS_DST_ALPHA 0x00000007
+#define V_028804_BLEND_DST_COLOR 0x00000008
+#define V_028804_BLEND_ONE_MINUS_DST_COLOR 0x00000009
+#define V_028804_BLEND_SRC_ALPHA_SATURATE 0x0000000A
+#define V_028804_BLEND_BOTH_SRC_ALPHA 0x0000000B
+#define V_028804_BLEND_BOTH_INV_SRC_ALPHA 0x0000000C
+#define V_028804_BLEND_CONST_COLOR 0x0000000D
+#define V_028804_BLEND_ONE_MINUS_CONST_COLOR 0x0000000E
+#define V_028804_BLEND_SRC1_COLOR 0x0000000F
+#define V_028804_BLEND_INV_SRC1_COLOR 0x00000010
+#define V_028804_BLEND_SRC1_ALPHA 0x00000011
+#define V_028804_BLEND_INV_SRC1_ALPHA 0x00000012
+#define V_028804_BLEND_CONST_ALPHA 0x00000013
+#define V_028804_BLEND_ONE_MINUS_CONST_ALPHA 0x00000014
+#define S_028804_COLOR_COMB_FCN(x) (((x) & 0x7) << 5)
+#define G_028804_COLOR_COMB_FCN(x) (((x) >> 5) & 0x7)
+#define C_028804_COLOR_COMB_FCN 0xFFFFFF1F
+#define V_028804_COMB_DST_PLUS_SRC 0x00000000
+#define V_028804_COMB_SRC_MINUS_DST 0x00000001
+#define V_028804_COMB_MIN_DST_SRC 0x00000002
+#define V_028804_COMB_MAX_DST_SRC 0x00000003
+#define V_028804_COMB_DST_MINUS_SRC 0x00000004
+#define S_028804_COLOR_DESTBLEND(x) (((x) & 0x1F) << 8)
+#define G_028804_COLOR_DESTBLEND(x) (((x) >> 8) & 0x1F)
+#define C_028804_COLOR_DESTBLEND 0xFFFFE0FF
+#define S_028804_OPACITY_WEIGHT(x) (((x) & 0x1) << 13)
+#define G_028804_OPACITY_WEIGHT(x) (((x) >> 13) & 0x1)
+#define C_028804_OPACITY_WEIGHT 0xFFFFDFFF
+#define S_028804_ALPHA_SRCBLEND(x) (((x) & 0x1F) << 16)
+#define G_028804_ALPHA_SRCBLEND(x) (((x) >> 16) & 0x1F)
+#define C_028804_ALPHA_SRCBLEND 0xFFE0FFFF
+#define S_028804_ALPHA_COMB_FCN(x) (((x) & 0x7) << 21)
+#define G_028804_ALPHA_COMB_FCN(x) (((x) >> 21) & 0x7)
+#define C_028804_ALPHA_COMB_FCN 0xFF1FFFFF
+#define S_028804_ALPHA_DESTBLEND(x) (((x) & 0x1F) << 24)
+#define G_028804_ALPHA_DESTBLEND(x) (((x) >> 24) & 0x1F)
+#define C_028804_ALPHA_DESTBLEND 0xE0FFFFFF
+#define S_028804_SEPARATE_ALPHA_BLEND(x) (((x) & 0x1) << 29)
+#define G_028804_SEPARATE_ALPHA_BLEND(x) (((x) >> 29) & 0x1)
+#define C_028804_SEPARATE_ALPHA_BLEND 0xDFFFFFFF
+#define R_028814_PA_SU_SC_MODE_CNTL 0x028814
+#define S_028814_CULL_FRONT(x) (((x) & 0x1) << 0)
+#define G_028814_CULL_FRONT(x) (((x) >> 0) & 0x1)
+#define C_028814_CULL_FRONT 0xFFFFFFFE
+#define S_028814_CULL_BACK(x) (((x) & 0x1) << 1)
+#define G_028814_CULL_BACK(x) (((x) >> 1) & 0x1)
+#define C_028814_CULL_BACK 0xFFFFFFFD
+#define S_028814_FACE(x) (((x) & 0x1) << 2)
+#define G_028814_FACE(x) (((x) >> 2) & 0x1)
+#define C_028814_FACE 0xFFFFFFFB
+#define S_028814_POLY_MODE(x) (((x) & 0x3) << 3)
+#define G_028814_POLY_MODE(x) (((x) >> 3) & 0x3)
+#define C_028814_POLY_MODE 0xFFFFFFE7
+#define S_028814_POLYMODE_FRONT_PTYPE(x) (((x) & 0x7) << 5)
+#define G_028814_POLYMODE_FRONT_PTYPE(x) (((x) >> 5) & 0x7)
+#define C_028814_POLYMODE_FRONT_PTYPE 0xFFFFFF1F
+#define S_028814_POLYMODE_BACK_PTYPE(x) (((x) & 0x7) << 8)
+#define G_028814_POLYMODE_BACK_PTYPE(x) (((x) >> 8) & 0x7)
+#define C_028814_POLYMODE_BACK_PTYPE 0xFFFFF8FF
+#define S_028814_POLY_OFFSET_FRONT_ENABLE(x) (((x) & 0x1) << 11)
+#define G_028814_POLY_OFFSET_FRONT_ENABLE(x) (((x) >> 11) & 0x1)
+#define C_028814_POLY_OFFSET_FRONT_ENABLE 0xFFFFF7FF
+#define S_028814_POLY_OFFSET_BACK_ENABLE(x) (((x) & 0x1) << 12)
+#define G_028814_POLY_OFFSET_BACK_ENABLE(x) (((x) >> 12) & 0x1)
+#define C_028814_POLY_OFFSET_BACK_ENABLE 0xFFFFEFFF
+#define S_028814_POLY_OFFSET_PARA_ENABLE(x) (((x) & 0x1) << 13)
+#define G_028814_POLY_OFFSET_PARA_ENABLE(x) (((x) >> 13) & 0x1)
+#define C_028814_POLY_OFFSET_PARA_ENABLE 0xFFFFDFFF
+#define S_028814_VTX_WINDOW_OFFSET_ENABLE(x) (((x) & 0x1) << 16)
+#define G_028814_VTX_WINDOW_OFFSET_ENABLE(x) (((x) >> 16) & 0x1)
+#define C_028814_VTX_WINDOW_OFFSET_ENABLE 0xFFFEFFFF
+#define S_028814_PROVOKING_VTX_LAST(x) (((x) & 0x1) << 19)
+#define G_028814_PROVOKING_VTX_LAST(x) (((x) >> 19) & 0x1)
+#define C_028814_PROVOKING_VTX_LAST 0xFFF7FFFF
+#define S_028814_PERSP_CORR_DIS(x) (((x) & 0x1) << 20)
+#define G_028814_PERSP_CORR_DIS(x) (((x) >> 20) & 0x1)
+#define C_028814_PERSP_CORR_DIS 0xFFEFFFFF
+#define S_028814_MULTI_PRIM_IB_ENA(x) (((x) & 0x1) << 21)
+#define G_028814_MULTI_PRIM_IB_ENA(x) (((x) >> 21) & 0x1)
+#define C_028814_MULTI_PRIM_IB_ENA 0xFFDFFFFF
#define R_028000_DB_DEPTH_SIZE 0x028000
#define S_028000_PITCH_TILE_MAX(x) (((x) & 0x3FF) << 0)
#define G_028000_PITCH_TILE_MAX(x) (((x) >> 0) & 0x3FF)
@@ -400,6 +631,36 @@
#define S_028D10_IGNORE_SC_ZRANGE(x) (((x) & 0x1) << 17)
#define G_028D10_IGNORE_SC_ZRANGE(x) (((x) >> 17) & 0x1)
#define C_028D10_IGNORE_SC_ZRANGE 0xFFFDFFFF
+#define R_028DF8_PA_SU_POLY_OFFSET_DB_FMT_CNTL 0x028DF8
+#define S_028DF8_POLY_OFFSET_NEG_NUM_DB_BITS(x) (((x) & 0xFF) << 0)
+#define G_028DF8_POLY_OFFSET_NEG_NUM_DB_BITS(x) (((x) >> 0) & 0xFF)
+#define C_028DF8_POLY_OFFSET_NEG_NUM_DB_BITS 0xFFFFFF00
+#define S_028DF8_POLY_OFFSET_DB_IS_FLOAT_FMT(x) (((x) & 0x1) << 8)
+#define G_028DF8_POLY_OFFSET_DB_IS_FLOAT_FMT(x) (((x) >> 8) & 0x1)
+#define C_028DF8_POLY_OFFSET_DB_IS_FLOAT_FMT 0xFFFFFEFF
+#define R_028E00_PA_SU_POLY_OFFSET_FRONT_SCALE 0x028E00
+#define S_028E00_SCALE(x) (((x) & 0xFFFFFFFF) << 0)
+#define G_028E00_SCALE(x) (((x) >> 0) & 0xFFFFFFFF)
+#define C_028E00_SCALE 0x00000000
+#define R_028E04_PA_SU_POLY_OFFSET_FRONT_OFFSET 0x028E04
+#define S_028E04_OFFSET(x) (((x) & 0xFFFFFFFF) << 0)
+#define G_028E04_OFFSET(x) (((x) >> 0) & 0xFFFFFFFF)
+#define C_028E04_OFFSET 0x00000000
+#define R_028E08_PA_SU_POLY_OFFSET_BACK_SCALE 0x028E08
+#define S_028E08_SCALE(x) (((x) & 0xFFFFFFFF) << 0)
+#define G_028E08_SCALE(x) (((x) >> 0) & 0xFFFFFFFF)
+#define C_028E08_SCALE 0x00000000
+#define R_028E0C_PA_SU_POLY_OFFSET_BACK_OFFSET 0x028E0C
+#define S_028E0C_OFFSET(x) (((x) & 0xFFFFFFFF) << 0)
+#define G_028E0C_OFFSET(x) (((x) >> 0) & 0xFFFFFFFF)
+#define C_028E0C_OFFSET 0x00000000
+#define R_028A00_PA_SU_POINT_SIZE 0x028A00
+#define S_028A00_HEIGHT(x) (((x) & 0xFFFF) << 0)
+#define G_028A00_HEIGHT(x) (((x) >> 0) & 0xFFFF)
+#define C_028A00_HEIGHT 0xFFFF0000
+#define S_028A00_WIDTH(x) (((x) & 0xFFFF) << 16)
+#define G_028A00_WIDTH(x) (((x) >> 16) & 0xFFFF)
+#define C_028A00_WIDTH 0x0000FFFF
#define R_028A40_VGT_GS_MODE 0x028A40
#define S_028A40_MODE(x) (((x) & 0x3) << 0)
#define G_028A40_MODE(x) (((x) >> 0) & 0x3)
@@ -574,6 +835,132 @@
#define S_0287F0_USE_OPAQUE(x) (((x) & 0x1) << 6)
#define G_0287F0_USE_OPAQUE(x) (((x) >> 6) & 0x1)
#define C_0287F0_USE_OPAQUE 0xFFFFFFBF
+#define R_038000_SQ_TEX_RESOURCE_WORD0_0 0x038000
+#define S_038000_DIM(x) (((x) & 0x7) << 0)
+#define G_038000_DIM(x) (((x) >> 0) & 0x7)
+#define C_038000_DIM 0xFFFFFFF8
+#define V_038000_SQ_TEX_DIM_1D 0x00000000
+#define V_038000_SQ_TEX_DIM_2D 0x00000001
+#define V_038000_SQ_TEX_DIM_3D 0x00000002
+#define V_038000_SQ_TEX_DIM_CUBEMAP 0x00000003
+#define V_038000_SQ_TEX_DIM_1D_ARRAY 0x00000004
+#define V_038000_SQ_TEX_DIM_2D_ARRAY 0x00000005
+#define V_038000_SQ_TEX_DIM_2D_MSAA 0x00000006
+#define V_038000_SQ_TEX_DIM_2D_ARRAY_MSAA 0x00000007
+#define S_038000_TILE_MODE(x) (((x) & 0xF) << 3)
+#define G_038000_TILE_MODE(x) (((x) >> 3) & 0xF)
+#define C_038000_TILE_MODE 0xFFFFFF87
+#define S_038000_TILE_TYPE(x) (((x) & 0x1) << 7)
+#define G_038000_TILE_TYPE(x) (((x) >> 7) & 0x1)
+#define C_038000_TILE_TYPE 0xFFFFFF7F
+#define S_038000_PITCH(x) (((x) & 0x7FF) << 8)
+#define G_038000_PITCH(x) (((x) >> 8) & 0x7FF)
+#define C_038000_PITCH 0xFFF800FF
+#define S_038000_TEX_WIDTH(x) (((x) & 0x1FFF) << 19)
+#define G_038000_TEX_WIDTH(x) (((x) >> 19) & 0x1FFF)
+#define C_038000_TEX_WIDTH 0x0007FFFF
+#define R_038004_SQ_TEX_RESOURCE_WORD1_0 0x038004
+#define S_038004_TEX_HEIGHT(x) (((x) & 0x1FFF) << 0)
+#define G_038004_TEX_HEIGHT(x) (((x) >> 0) & 0x1FFF)
+#define C_038004_TEX_HEIGHT 0xFFFFE000
+#define S_038004_TEX_DEPTH(x) (((x) & 0x1FFF) << 13)
+#define G_038004_TEX_DEPTH(x) (((x) >> 13) & 0x1FFF)
+#define C_038004_TEX_DEPTH 0xFC001FFF
+#define S_038004_DATA_FORMAT(x) (((x) & 0x3F) << 26)
+#define G_038004_DATA_FORMAT(x) (((x) >> 26) & 0x3F)
+#define C_038004_DATA_FORMAT 0x03FFFFFF
+#define R_038008_SQ_TEX_RESOURCE_WORD2_0 0x038008
+#define S_038008_BASE_ADDRESS(x) (((x) & 0xFFFFFFFF) << 0)
+#define G_038008_BASE_ADDRESS(x) (((x) >> 0) & 0xFFFFFFFF)
+#define C_038008_BASE_ADDRESS 0x00000000
+#define R_03800C_SQ_TEX_RESOURCE_WORD3_0 0x03800C
+#define S_03800C_MIP_ADDRESS(x) (((x) & 0xFFFFFFFF) << 0)
+#define G_03800C_MIP_ADDRESS(x) (((x) >> 0) & 0xFFFFFFFF)
+#define C_03800C_MIP_ADDRESS 0x00000000
+#define R_038010_SQ_TEX_RESOURCE_WORD4_0 0x038010
+#define S_038010_FORMAT_COMP_X(x) (((x) & 0x3) << 0)
+#define G_038010_FORMAT_COMP_X(x) (((x) >> 0) & 0x3)
+#define C_038010_FORMAT_COMP_X 0xFFFFFFFC
+#define V_038010_SQ_FORMAT_COMP_UNSIGNED 0x00000000
+#define V_038010_SQ_FORMAT_COMP_SIGNED 0x00000001
+#define V_038010_SQ_FORMAT_COMP_UNSIGNED_BIASED 0x00000002
+#define S_038010_FORMAT_COMP_Y(x) (((x) & 0x3) << 2)
+#define G_038010_FORMAT_COMP_Y(x) (((x) >> 2) & 0x3)
+#define C_038010_FORMAT_COMP_Y 0xFFFFFFF3
+#define S_038010_FORMAT_COMP_Z(x) (((x) & 0x3) << 4)
+#define G_038010_FORMAT_COMP_Z(x) (((x) >> 4) & 0x3)
+#define C_038010_FORMAT_COMP_Z 0xFFFFFFCF
+#define S_038010_FORMAT_COMP_W(x) (((x) & 0x3) << 6)
+#define G_038010_FORMAT_COMP_W(x) (((x) >> 6) & 0x3)
+#define C_038010_FORMAT_COMP_W 0xFFFFFF3F
+#define S_038010_NUM_FORMAT_ALL(x) (((x) & 0x3) << 8)
+#define G_038010_NUM_FORMAT_ALL(x) (((x) >> 8) & 0x3)
+#define C_038010_NUM_FORMAT_ALL 0xFFFFFCFF
+#define V_038010_SQ_NUM_FORMAT_NORM 0x00000000
+#define V_038010_SQ_NUM_FORMAT_INT 0x00000001
+#define V_038010_SQ_NUM_FORMAT_SCALED 0x00000002
+#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 S_038010_FORCE_DEGAMMA(x) (((x) & 0x1) << 11)
+#define G_038010_FORCE_DEGAMMA(x) (((x) >> 11) & 0x1)
+#define C_038010_FORCE_DEGAMMA 0xFFFFF7FF
+#define S_038010_ENDIAN_SWAP(x) (((x) & 0x3) << 12)
+#define G_038010_ENDIAN_SWAP(x) (((x) >> 12) & 0x3)
+#define C_038010_ENDIAN_SWAP 0xFFFFCFFF
+#define S_038010_REQUEST_SIZE(x) (((x) & 0x3) << 14)
+#define G_038010_REQUEST_SIZE(x) (((x) >> 14) & 0x3)
+#define C_038010_REQUEST_SIZE 0xFFFF3FFF
+#define S_038010_DST_SEL_X(x) (((x) & 0x7) << 16)
+#define G_038010_DST_SEL_X(x) (((x) >> 16) & 0x7)
+#define C_038010_DST_SEL_X 0xFFF8FFFF
+#define V_038010_SQ_SEL_X 0x00000000
+#define V_038010_SQ_SEL_Y 0x00000001
+#define V_038010_SQ_SEL_Z 0x00000002
+#define V_038010_SQ_SEL_W 0x00000003
+#define V_038010_SQ_SEL_0 0x00000004
+#define V_038010_SQ_SEL_1 0x00000005
+#define S_038010_DST_SEL_Y(x) (((x) & 0x7) << 19)
+#define G_038010_DST_SEL_Y(x) (((x) >> 19) & 0x7)
+#define C_038010_DST_SEL_Y 0xFFC7FFFF
+#define S_038010_DST_SEL_Z(x) (((x) & 0x7) << 22)
+#define G_038010_DST_SEL_Z(x) (((x) >> 22) & 0x7)
+#define C_038010_DST_SEL_Z 0xFE3FFFFF
+#define S_038010_DST_SEL_W(x) (((x) & 0x7) << 25)
+#define G_038010_DST_SEL_W(x) (((x) >> 25) & 0x7)
+#define C_038010_DST_SEL_W 0xF1FFFFFF
+#define S_038010_BASE_LEVEL(x) (((x) & 0xF) << 28)
+#define G_038010_BASE_LEVEL(x) (((x) >> 28) & 0xF)
+#define C_038010_BASE_LEVEL 0x0FFFFFFF
+#define R_038014_SQ_TEX_RESOURCE_WORD5_0 0x038014
+#define S_038014_LAST_LEVEL(x) (((x) & 0xF) << 0)
+#define G_038014_LAST_LEVEL(x) (((x) >> 0) & 0xF)
+#define C_038014_LAST_LEVEL 0xFFFFFFF0
+#define S_038014_BASE_ARRAY(x) (((x) & 0x1FFF) << 4)
+#define G_038014_BASE_ARRAY(x) (((x) >> 4) & 0x1FFF)
+#define C_038014_BASE_ARRAY 0xFFFE000F
+#define S_038014_LAST_ARRAY(x) (((x) & 0x1FFF) << 17)
+#define G_038014_LAST_ARRAY(x) (((x) >> 17) & 0x1FFF)
+#define C_038014_LAST_ARRAY 0xC001FFFF
+#define R_038018_SQ_TEX_RESOURCE_WORD6_0 0x038018
+#define S_038018_MPEG_CLAMP(x) (((x) & 0x3) << 0)
+#define G_038018_MPEG_CLAMP(x) (((x) >> 0) & 0x3)
+#define C_038018_MPEG_CLAMP 0xFFFFFFFC
+#define S_038018_PERF_MODULATION(x) (((x) & 0x7) << 5)
+#define G_038018_PERF_MODULATION(x) (((x) >> 5) & 0x7)
+#define C_038018_PERF_MODULATION 0xFFFFFF1F
+#define S_038018_INTERLACED(x) (((x) & 0x1) << 8)
+#define G_038018_INTERLACED(x) (((x) >> 8) & 0x1)
+#define C_038018_INTERLACED 0xFFFFFEFF
+#define S_038018_TYPE(x) (((x) & 0x3) << 30)
+#define G_038018_TYPE(x) (((x) >> 30) & 0x3)
+#define C_038018_TYPE 0x3FFFFFFF
+#define V_038010_SQ_TEX_VTX_INVALID_TEXTURE 0x00000000
+#define V_038010_SQ_TEX_VTX_INVALID_BUFFER 0x00000001
+#define V_038010_SQ_TEX_VTX_VALID_TEXTURE 0x00000002
+#define V_038010_SQ_TEX_VTX_VALID_BUFFER 0x00000003
#define R_038008_SQ_VTX_CONSTANT_WORD2_0 0x038008
#define S_038008_BASE_ADDRESS_HI(x) (((x) & 0xFF) << 0)
#define G_038008_BASE_ADDRESS_HI(x) (((x) >> 0) & 0xFF)
@@ -633,6 +1020,113 @@
#define S_038008_ENDIAN_SWAP(x) (((x) & 0x3) << 30)
#define G_038008_ENDIAN_SWAP(x) (((x) >> 30) & 0x3)
#define C_038008_ENDIAN_SWAP 0x3FFFFFFF
+#define R_03C000_SQ_TEX_SAMPLER_WORD0_0 0x03C000
+#define S_03C000_CLAMP_X(x) (((x) & 0x7) << 0)
+#define G_03C000_CLAMP_X(x) (((x) >> 0) & 0x7)
+#define C_03C000_CLAMP_X 0xFFFFFFF8
+#define V_03C000_SQ_TEX_WRAP 0x00000000
+#define V_03C000_SQ_TEX_MIRROR 0x00000001
+#define V_03C000_SQ_TEX_CLAMP_LAST_TEXEL 0x00000002
+#define V_03C000_SQ_TEX_MIRROR_ONCE_LAST_TEXEL 0x00000003
+#define V_03C000_SQ_TEX_CLAMP_HALF_BORDER 0x00000004
+#define V_03C000_SQ_TEX_MIRROR_ONCE_HALF_BORDER 0x00000005
+#define V_03C000_SQ_TEX_CLAMP_BORDER 0x00000006
+#define V_03C000_SQ_TEX_MIRROR_ONCE_BORDER 0x00000007
+#define S_03C000_CLAMP_Y(x) (((x) & 0x7) << 3)
+#define G_03C000_CLAMP_Y(x) (((x) >> 3) & 0x7)
+#define C_03C000_CLAMP_Y 0xFFFFFFC7
+#define S_03C000_CLAMP_Z(x) (((x) & 0x7) << 6)
+#define G_03C000_CLAMP_Z(x) (((x) >> 6) & 0x7)
+#define C_03C000_CLAMP_Z 0xFFFFFE3F
+#define S_03C000_XY_MAG_FILTER(x) (((x) & 0x7) << 9)
+#define G_03C000_XY_MAG_FILTER(x) (((x) >> 9) & 0x7)
+#define C_03C000_XY_MAG_FILTER 0xFFFFF1FF
+#define V_03C000_SQ_TEX_XY_FILTER_POINT 0x00000000
+#define V_03C000_SQ_TEX_XY_FILTER_BILINEAR 0x00000001
+#define V_03C000_SQ_TEX_XY_FILTER_BICUBIC 0x00000002
+#define S_03C000_XY_MIN_FILTER(x) (((x) & 0x7) << 12)
+#define G_03C000_XY_MIN_FILTER(x) (((x) >> 12) & 0x7)
+#define C_03C000_XY_MIN_FILTER 0xFFFF8FFF
+#define S_03C000_Z_FILTER(x) (((x) & 0x3) << 15)
+#define G_03C000_Z_FILTER(x) (((x) >> 15) & 0x3)
+#define C_03C000_Z_FILTER 0xFFFE7FFF
+#define V_03C000_SQ_TEX_Z_FILTER_NONE 0x00000000
+#define V_03C000_SQ_TEX_Z_FILTER_POINT 0x00000001
+#define V_03C000_SQ_TEX_Z_FILTER_LINEAR 0x00000002
+#define S_03C000_MIP_FILTER(x) (((x) & 0x3) << 17)
+#define G_03C000_MIP_FILTER(x) (((x) >> 17) & 0x3)
+#define C_03C000_MIP_FILTER 0xFFF9FFFF
+#define S_03C000_BORDER_COLOR_TYPE(x) (((x) & 0x3) << 22)
+#define G_03C000_BORDER_COLOR_TYPE(x) (((x) >> 22) & 0x3)
+#define C_03C000_BORDER_COLOR_TYPE 0xFF3FFFFF
+#define V_03C000_SQ_TEX_BORDER_COLOR_TRANS_BLACK 0x00000000
+#define V_03C000_SQ_TEX_BORDER_COLOR_OPAQUE_BLACK 0x00000001
+#define V_03C000_SQ_TEX_BORDER_COLOR_OPAQUE_WHITE 0x00000002
+#define V_03C000_SQ_TEX_BORDER_COLOR_REGISTER 0x00000003
+#define S_03C000_POINT_SAMPLING_CLAMP(x) (((x) & 0x1) << 24)
+#define G_03C000_POINT_SAMPLING_CLAMP(x) (((x) >> 24) & 0x1)
+#define C_03C000_POINT_SAMPLING_CLAMP 0xFEFFFFFF
+#define S_03C000_TEX_ARRAY_OVERRIDE(x) (((x) & 0x1) << 25)
+#define G_03C000_TEX_ARRAY_OVERRIDE(x) (((x) >> 25) & 0x1)
+#define C_03C000_TEX_ARRAY_OVERRIDE 0xFDFFFFFF
+#define S_03C000_DEPTH_COMPARE_FUNCTION(x) (((x) & 0x7) << 26)
+#define G_03C000_DEPTH_COMPARE_FUNCTION(x) (((x) >> 26) & 0x7)
+#define C_03C000_DEPTH_COMPARE_FUNCTION 0xE3FFFFFF
+#define V_03C000_SQ_TEX_DEPTH_COMPARE_NEVER 0x00000000
+#define V_03C000_SQ_TEX_DEPTH_COMPARE_LESS 0x00000001
+#define V_03C000_SQ_TEX_DEPTH_COMPARE_EQUAL 0x00000002
+#define V_03C000_SQ_TEX_DEPTH_COMPARE_LESSEQUAL 0x00000003
+#define V_03C000_SQ_TEX_DEPTH_COMPARE_GREATER 0x00000004
+#define V_03C000_SQ_TEX_DEPTH_COMPARE_NOTEQUAL 0x00000005
+#define V_03C000_SQ_TEX_DEPTH_COMPARE_GREATEREQUAL 0x00000006
+#define V_03C000_SQ_TEX_DEPTH_COMPARE_ALWAYS 0x00000007
+#define S_03C000_CHROMA_KEY(x) (((x) & 0x3) << 29)
+#define G_03C000_CHROMA_KEY(x) (((x) >> 29) & 0x3)
+#define C_03C000_CHROMA_KEY 0x9FFFFFFF
+#define V_03C000_SQ_TEX_CHROMA_KEY_DISABLE 0x00000000
+#define V_03C000_SQ_TEX_CHROMA_KEY_KILL 0x00000001
+#define V_03C000_SQ_TEX_CHROMA_KEY_BLEND 0x00000002
+#define S_03C000_LOD_USES_MINOR_AXIS(x) (((x) & 0x1) << 31)
+#define G_03C000_LOD_USES_MINOR_AXIS(x) (((x) >> 31) & 0x1)
+#define C_03C000_LOD_USES_MINOR_AXIS 0x7FFFFFFF
+#define R_03C004_SQ_TEX_SAMPLER_WORD1_0 0x03C004
+#define S_03C004_MIN_LOD(x) (((x) & 0x3FF) << 0)
+#define G_03C004_MIN_LOD(x) (((x) >> 0) & 0x3FF)
+#define C_03C004_MIN_LOD 0xFFFFFC00
+#define S_03C004_MAX_LOD(x) (((x) & 0x3FF) << 10)
+#define G_03C004_MAX_LOD(x) (((x) >> 10) & 0x3FF)
+#define C_03C004_MAX_LOD 0xFFF003FF
+#define S_03C004_LOD_BIAS(x) (((x) & 0xFFF) << 20)
+#define G_03C004_LOD_BIAS(x) (((x) >> 20) & 0xFFF)
+#define C_03C004_LOD_BIAS 0x000FFFFF
+#define R_03C008_SQ_TEX_SAMPLER_WORD2_0 0x03C008
+#define S_03C008_LOD_BIAS_SEC(x) (((x) & 0xFFF) << 0)
+#define G_03C008_LOD_BIAS_SEC(x) (((x) >> 0) & 0xFFF)
+#define C_03C008_LOD_BIAS_SEC 0xFFFFF000
+#define S_03C008_MC_COORD_TRUNCATE(x) (((x) & 0x1) << 12)
+#define G_03C008_MC_COORD_TRUNCATE(x) (((x) >> 12) & 0x1)
+#define C_03C008_MC_COORD_TRUNCATE 0xFFFFEFFF
+#define S_03C008_FORCE_DEGAMMA(x) (((x) & 0x1) << 13)
+#define G_03C008_FORCE_DEGAMMA(x) (((x) >> 13) & 0x1)
+#define C_03C008_FORCE_DEGAMMA 0xFFFFDFFF
+#define S_03C008_HIGH_PRECISION_FILTER(x) (((x) & 0x1) << 14)
+#define G_03C008_HIGH_PRECISION_FILTER(x) (((x) >> 14) & 0x1)
+#define C_03C008_HIGH_PRECISION_FILTER 0xFFFFBFFF
+#define S_03C008_PERF_MIP(x) (((x) & 0x7) << 15)
+#define G_03C008_PERF_MIP(x) (((x) >> 15) & 0x7)
+#define C_03C008_PERF_MIP 0xFFFC7FFF
+#define S_03C008_PERF_Z(x) (((x) & 0x3) << 18)
+#define G_03C008_PERF_Z(x) (((x) >> 18) & 0x3)
+#define C_03C008_PERF_Z 0xFFF3FFFF
+#define S_03C008_FETCH_4(x) (((x) & 0x1) << 26)
+#define G_03C008_FETCH_4(x) (((x) >> 26) & 0x1)
+#define C_03C008_FETCH_4 0xFBFFFFFF
+#define S_03C008_SAMPLE_IS_PCF(x) (((x) & 0x1) << 27)
+#define G_03C008_SAMPLE_IS_PCF(x) (((x) >> 27) & 0x1)
+#define C_03C008_SAMPLE_IS_PCF 0xF7FFFFFF
+#define S_03C008_TYPE(x) (((x) & 0x1) << 31)
+#define G_03C008_TYPE(x) (((x) >> 31) & 0x1)
+#define C_03C008_TYPE 0x7FFFFFFF
#define R_008958_VGT_PRIMITIVE_TYPE 0x008958
#define S_008958_PRIM_TYPE(x) (((x) & 0x3F) << 0)
#define G_008958_PRIM_TYPE(x) (((x) >> 0) & 0x3F)
@@ -666,6 +1160,79 @@
#define V_008958_DI_PT_2D_FILL_RECT_LIST 0x0000001A
#define V_008958_DI_PT_2D_LINE_STRIP 0x0000001B
#define V_008958_DI_PT_2D_TRI_STRIP 0x0000001C
+#define R_02881C_PA_CL_VS_OUT_CNTL 0x02881C
+#define S_02881C_CLIP_DIST_ENA_0(x) (((x) & 0x1) << 0)
+#define G_02881C_CLIP_DIST_ENA_0(x) (((x) >> 0) & 0x1)
+#define C_02881C_CLIP_DIST_ENA_0 0xFFFFFFFE
+#define S_02881C_CLIP_DIST_ENA_1(x) (((x) & 0x1) << 1)
+#define G_02881C_CLIP_DIST_ENA_1(x) (((x) >> 1) & 0x1)
+#define C_02881C_CLIP_DIST_ENA_1 0xFFFFFFFD
+#define S_02881C_CLIP_DIST_ENA_2(x) (((x) & 0x1) << 2)
+#define G_02881C_CLIP_DIST_ENA_2(x) (((x) >> 2) & 0x1)
+#define C_02881C_CLIP_DIST_ENA_2 0xFFFFFFFB
+#define S_02881C_CLIP_DIST_ENA_3(x) (((x) & 0x1) << 3)
+#define G_02881C_CLIP_DIST_ENA_3(x) (((x) >> 3) & 0x1)
+#define C_02881C_CLIP_DIST_ENA_3 0xFFFFFFF7
+#define S_02881C_CLIP_DIST_ENA_4(x) (((x) & 0x1) << 4)
+#define G_02881C_CLIP_DIST_ENA_4(x) (((x) >> 4) & 0x1)
+#define C_02881C_CLIP_DIST_ENA_4 0xFFFFFFEF
+#define S_02881C_CLIP_DIST_ENA_5(x) (((x) & 0x1) << 5)
+#define G_02881C_CLIP_DIST_ENA_5(x) (((x) >> 5) & 0x1)
+#define C_02881C_CLIP_DIST_ENA_5 0xFFFFFFDF
+#define S_02881C_CLIP_DIST_ENA_6(x) (((x) & 0x1) << 6)
+#define G_02881C_CLIP_DIST_ENA_6(x) (((x) >> 6) & 0x1)
+#define C_02881C_CLIP_DIST_ENA_6 0xFFFFFFBF
+#define S_02881C_CLIP_DIST_ENA_7(x) (((x) & 0x1) << 7)
+#define G_02881C_CLIP_DIST_ENA_7(x) (((x) >> 7) & 0x1)
+#define C_02881C_CLIP_DIST_ENA_7 0xFFFFFF7F
+#define S_02881C_CULL_DIST_ENA_0(x) (((x) & 0x1) << 8)
+#define G_02881C_CULL_DIST_ENA_0(x) (((x) >> 8) & 0x1)
+#define C_02881C_CULL_DIST_ENA_0 0xFFFFFEFF
+#define S_02881C_CULL_DIST_ENA_1(x) (((x) & 0x1) << 9)
+#define G_02881C_CULL_DIST_ENA_1(x) (((x) >> 9) & 0x1)
+#define C_02881C_CULL_DIST_ENA_1 0xFFFFFDFF
+#define S_02881C_CULL_DIST_ENA_2(x) (((x) & 0x1) << 10)
+#define G_02881C_CULL_DIST_ENA_2(x) (((x) >> 10) & 0x1)
+#define C_02881C_CULL_DIST_ENA_2 0xFFFFFBFF
+#define S_02881C_CULL_DIST_ENA_3(x) (((x) & 0x1) << 11)
+#define G_02881C_CULL_DIST_ENA_3(x) (((x) >> 11) & 0x1)
+#define C_02881C_CULL_DIST_ENA_3 0xFFFFF7FF
+#define S_02881C_CULL_DIST_ENA_4(x) (((x) & 0x1) << 12)
+#define G_02881C_CULL_DIST_ENA_4(x) (((x) >> 12) & 0x1)
+#define C_02881C_CULL_DIST_ENA_4 0xFFFFEFFF
+#define S_02881C_CULL_DIST_ENA_5(x) (((x) & 0x1) << 13)
+#define G_02881C_CULL_DIST_ENA_5(x) (((x) >> 13) & 0x1)
+#define C_02881C_CULL_DIST_ENA_5 0xFFFFDFFF
+#define S_02881C_CULL_DIST_ENA_6(x) (((x) & 0x1) << 14)
+#define G_02881C_CULL_DIST_ENA_6(x) (((x) >> 14) & 0x1)
+#define C_02881C_CULL_DIST_ENA_6 0xFFFFBFFF
+#define S_02881C_CULL_DIST_ENA_7(x) (((x) & 0x1) << 15)
+#define G_02881C_CULL_DIST_ENA_7(x) (((x) >> 15) & 0x1)
+#define C_02881C_CULL_DIST_ENA_7 0xFFFF7FFF
+#define S_02881C_USE_VTX_POINT_SIZE(x) (((x) & 0x1) << 16)
+#define G_02881C_USE_VTX_POINT_SIZE(x) (((x) >> 16) & 0x1)
+#define C_02881C_USE_VTX_POINT_SIZE 0xFFFEFFFF
+#define S_02881C_USE_VTX_EDGE_FLAG(x) (((x) & 0x1) << 17)
+#define G_02881C_USE_VTX_EDGE_FLAG(x) (((x) >> 17) & 0x1)
+#define C_02881C_USE_VTX_EDGE_FLAG 0xFFFDFFFF
+#define S_02881C_USE_VTX_RENDER_TARGET_INDX(x) (((x) & 0x1) << 18)
+#define G_02881C_USE_VTX_RENDER_TARGET_INDX(x) (((x) >> 18) & 0x1)
+#define C_02881C_USE_VTX_RENDER_TARGET_INDX 0xFFFBFFFF
+#define S_02881C_USE_VTX_VIEWPORT_INDX(x) (((x) & 0x1) << 19)
+#define G_02881C_USE_VTX_VIEWPORT_INDX(x) (((x) >> 19) & 0x1)
+#define C_02881C_USE_VTX_VIEWPORT_INDX 0xFFF7FFFF
+#define S_02881C_USE_VTX_KILL_FLAG(x) (((x) & 0x1) << 20)
+#define G_02881C_USE_VTX_KILL_FLAG(x) (((x) >> 20) & 0x1)
+#define C_02881C_USE_VTX_KILL_FLAG 0xFFEFFFFF
+#define S_02881C_VS_OUT_MISC_VEC_ENA(x) (((x) & 0x1) << 21)
+#define G_02881C_VS_OUT_MISC_VEC_ENA(x) (((x) >> 21) & 0x1)
+#define C_02881C_VS_OUT_MISC_VEC_ENA 0xFFDFFFFF
+#define S_02881C_VS_OUT_CCDIST0_VEC_ENA(x) (((x) & 0x1) << 22)
+#define G_02881C_VS_OUT_CCDIST0_VEC_ENA(x) (((x) >> 22) & 0x1)
+#define C_02881C_VS_OUT_CCDIST0_VEC_ENA 0xFFBFFFFF
+#define S_02881C_VS_OUT_CCDIST1_VEC_ENA(x) (((x) & 0x1) << 23)
+#define G_02881C_VS_OUT_CCDIST1_VEC_ENA(x) (((x) >> 23) & 0x1)
+#define C_02881C_VS_OUT_CCDIST1_VEC_ENA 0xFF7FFFFF
#define R_028868_SQ_PGM_RESOURCES_VS 0x028868
#define S_028868_NUM_GPRS(x) (((x) & 0xFF) << 0)
#define G_028868_NUM_GPRS(x) (((x) >> 0) & 0xFF)
diff --git a/src/gallium/drivers/r600/r700_asm.c b/src/gallium/drivers/r600/r700_asm.c
new file mode 100644
index 0000000000..1ebe20d6ab
--- /dev/null
+++ b/src/gallium/drivers/r600/r700_asm.c
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2010 Jerome Glisse <glisse@freedesktop.org>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * on the rights to use, copy, modify, merge, publish, distribute, sub
+ * license, and/or sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#include "r600_asm.h"
+#include "r600_context.h"
+#include "util/u_memory.h"
+#include "r700_sq.h"
+#include <stdio.h>
+
+int r700_bc_alu_build(struct r600_bc *bc, struct r600_bc_alu *alu, unsigned id)
+{
+ unsigned i;
+
+ /* don't replace gpr by pv or ps for destination register */
+ if (alu->is_op3) {
+ bc->bytecode[id++] = S_SQ_ALU_WORD0_SRC0_SEL(alu->src[0].sel) |
+ S_SQ_ALU_WORD0_SRC0_CHAN(alu->src[0].chan) |
+ S_SQ_ALU_WORD0_SRC1_SEL(alu->src[1].sel) |
+ S_SQ_ALU_WORD0_SRC1_CHAN(alu->src[1].chan) |
+ S_SQ_ALU_WORD0_LAST(alu->last);
+ bc->bytecode[id++] = S_SQ_ALU_WORD1_DST_GPR(alu->dst.sel) |
+ S_SQ_ALU_WORD1_DST_CHAN(alu->dst.chan) |
+ S_SQ_ALU_WORD1_OP3_SRC2_SEL(alu->src[2].sel) |
+ S_SQ_ALU_WORD1_OP3_SRC2_CHAN(alu->src[2].chan) |
+ S_SQ_ALU_WORD1_OP3_SRC2_NEG(alu->src[2].neg) |
+ S_SQ_ALU_WORD1_OP3_ALU_INST(alu->inst) |
+ S_SQ_ALU_WORD1_BANK_SWIZZLE(0);
+ } else {
+ bc->bytecode[id++] = S_SQ_ALU_WORD0_SRC0_SEL(alu->src[0].sel) |
+ S_SQ_ALU_WORD0_SRC0_CHAN(alu->src[0].chan) |
+ S_SQ_ALU_WORD0_SRC0_NEG(alu->src[0].neg) |
+ S_SQ_ALU_WORD0_SRC1_SEL(alu->src[1].sel) |
+ S_SQ_ALU_WORD0_SRC1_CHAN(alu->src[1].chan) |
+ S_SQ_ALU_WORD0_SRC1_NEG(alu->src[1].neg) |
+ S_SQ_ALU_WORD0_LAST(alu->last);
+ bc->bytecode[id++] = S_SQ_ALU_WORD1_DST_GPR(alu->dst.sel) |
+ S_SQ_ALU_WORD1_DST_CHAN(alu->dst.chan) |
+ S_SQ_ALU_WORD1_OP2_SRC0_ABS(alu->src[0].abs) |
+ S_SQ_ALU_WORD1_OP2_SRC1_ABS(alu->src[1].abs) |
+ S_SQ_ALU_WORD1_OP2_WRITE_MASK(alu->dst.write) |
+ S_SQ_ALU_WORD1_OP2_ALU_INST(alu->inst) |
+ S_SQ_ALU_WORD1_BANK_SWIZZLE(0);
+ }
+ if (alu->last) {
+ for (i = 0; i < alu->nliteral; i++) {
+ bc->bytecode[id++] = alu->value[i];
+ }
+ }
+ return 0;
+}
diff --git a/src/gallium/drivers/r600/radeon.h b/src/gallium/drivers/r600/radeon.h
index 3a8405f9b4..8f00a4895a 100644
--- a/src/gallium/drivers/r600/radeon.h
+++ b/src/gallium/drivers/r600/radeon.h
@@ -157,11 +157,42 @@ int radeon_ctx_submit(struct radeon_ctx *ctx);
void radeon_ctx_dump_bof(struct radeon_ctx *ctx, const char *file);
/*
+ * radeon context functions
+ */
+#pragma pack(1)
+struct radeon_cs_reloc {
+ uint32_t handle;
+ uint32_t read_domain;
+ uint32_t write_domain;
+ uint32_t flags;
+};
+#pragma pack()
+
+struct radeon_ctx {
+ int refcount;
+ struct radeon *radeon;
+ u32 *pm4;
+ u32 cpm4;
+ u32 draw_cpm4;
+ unsigned id;
+ unsigned next_id;
+ unsigned nreloc;
+ struct radeon_cs_reloc *reloc;
+ unsigned nbo;
+ struct radeon_bo **bo;
+ unsigned ndraw;
+ struct radeon_draw *cdraw;
+ struct radeon_draw **draw;
+ unsigned nstate;
+ struct radeon_state **state;
+};
+
+/*
* R600/R700
*/
-#define R600_NSTATE 1273
-#define R600_NTYPE 25
+#define R600_NSTATE 1280
+#define R600_NTYPE 32
#define R600_CONFIG 0
#define R600_CONFIG_TYPE 0
@@ -207,12 +238,26 @@ void radeon_ctx_dump_bof(struct radeon_ctx *ctx, const char *file);
#define R600_GS_SAMPLER_BORDER_TYPE 20
#define R600_CB0 1269
#define R600_CB0_TYPE 21
-#define R600_DB 1270
-#define R600_DB_TYPE 22
-#define R600_VGT 1271
-#define R600_VGT_TYPE 23
-#define R600_DRAW 1272
-#define R600_DRAW_TYPE 24
+#define R600_CB1 1270
+#define R600_CB1_TYPE 22
+#define R600_CB2 1271
+#define R600_CB2_TYPE 23
+#define R600_CB3 1272
+#define R600_CB3_TYPE 24
+#define R600_CB4 1273
+#define R600_CB4_TYPE 25
+#define R600_CB5 1274
+#define R600_CB5_TYPE 26
+#define R600_CB6 1275
+#define R600_CB6_TYPE 27
+#define R600_CB7 1276
+#define R600_CB7_TYPE 28
+#define R600_DB 1277
+#define R600_DB_TYPE 29
+#define R600_VGT 1278
+#define R600_VGT_TYPE 30
+#define R600_DRAW 1279
+#define R600_DRAW_TYPE 31
/* R600_CONFIG */
#define R600_CONFIG__SQ_CONFIG 0
#define R600_CONFIG__SQ_GPR_RESOURCE_MGMT_1 1