diff options
| -rw-r--r-- | src/gallium/drivers/r600/Makefile | 7 | ||||
| -rw-r--r-- | src/gallium/drivers/r600/r600_asm.c | 385 | ||||
| -rw-r--r-- | src/gallium/drivers/r600/r600_asm.h | 112 | ||||
| -rw-r--r-- | src/gallium/drivers/r600/r600_compiler.c | 447 | ||||
| -rw-r--r-- | src/gallium/drivers/r600/r600_compiler.h | 320 | ||||
| -rw-r--r-- | src/gallium/drivers/r600/r600_compiler_dump.c | 267 | ||||
| -rw-r--r-- | src/gallium/drivers/r600/r600_compiler_r600.c | 972 | ||||
| -rw-r--r-- | src/gallium/drivers/r600/r600_compiler_r700.c | 233 | ||||
| -rw-r--r-- | src/gallium/drivers/r600/r600_compiler_tgsi.c | 730 | ||||
| -rw-r--r-- | src/gallium/drivers/r600/r600_context.c | 2 | ||||
| -rw-r--r-- | src/gallium/drivers/r600/r600_context.h | 5 | ||||
| -rw-r--r-- | src/gallium/drivers/r600/r600_shader.c | 782 | ||||
| -rw-r--r-- | src/gallium/drivers/r600/r600_shader.h | 244 | ||||
| -rw-r--r-- | src/gallium/drivers/r600/r600_sq.h | 18 | ||||
| -rw-r--r-- | src/gallium/drivers/r600/r600_state.c | 4 | ||||
| -rw-r--r-- | src/gallium/drivers/r600/r700_asm.c | 70 | 
16 files changed, 1276 insertions, 3322 deletions
diff --git a/src/gallium/drivers/r600/Makefile b/src/gallium/drivers/r600/Makefile index aae31a6a6e..8f1e1366b5 100644 --- a/src/gallium/drivers/r600/Makefile +++ b/src/gallium/drivers/r600/Makefile @@ -18,10 +18,7 @@ C_SOURCES = \  	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/r600_asm.c b/src/gallium/drivers/r600/r600_asm.c new file mode 100644 index 0000000000..6e48703a57 --- /dev/null +++ b/src/gallium/drivers/r600/r600_asm.c @@ -0,0 +1,385 @@ +/* + * 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); +	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; +} + +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; +	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)) { +		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; +	} +	/* 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 || +		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) { +		return 0; +	} +	memcpy(alu->value, value, 4 * 4); +	bc->cf_last->ndw += alu->nliteral; +	bc->ndw += alu->nliteral; +	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 6 dwords */ +	bc->cf_last->ndw += 4; +	bc->ndw += 4; +	return 0; +} + +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; +} + +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_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; +} + +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_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; +	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_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_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..8a874a9df5 --- /dev/null +++ b/src/gallium/drivers/r600/r600_asm.h @@ -0,0 +1,112 @@ +/* + * 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; +	u32				value[4]; +}; + +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		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; +	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_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_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..3c5195f79e 100644 --- a/src/gallium/drivers/r600/r600_context.c +++ b/src/gallium/drivers/r600/r600_context.c @@ -55,7 +55,7 @@ static void r600_flush(struct pipe_context *ctx, unsigned flags,  	 */  	if (!dc)  		radeon_ctx_dump_bof(rctx->ctx, "gallium.bof"); -#if 0 +#if 1  	radeon_ctx_submit(rctx->ctx);  #endif  	rctx->ctx = radeon_ctx_decref(rctx->ctx); diff --git a/src/gallium/drivers/r600/r600_context.h b/src/gallium/drivers/r600/r600_context.h index f27ff58ed4..669aaec0b2 100644 --- a/src/gallium/drivers/r600/r600_context.h +++ b/src/gallium/drivers/r600/r600_context.h @@ -40,7 +40,6 @@ struct r600_vertex_elements_state  };  struct r600_pipe_shader { -	unsigned				type;  	struct r600_shader			shader;  	struct radeon_bo			*bo;  	struct radeon_state			*state; @@ -92,8 +91,10 @@ 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); +#define R600_ERR(fmt, args...) \ +	fprintf(stderr, "EE %s/%s:%d - "fmt, __FILE__, __func__, __LINE__, ##args) +  #endif diff --git a/src/gallium/drivers/r600/r600_shader.c b/src/gallium/drivers/r600/r600_shader.c index f7d6e10663..4a6cf40c26 100644 --- a/src/gallium/drivers/r600/r600_shader.c +++ b/src/gallium/drivers/r600/r600_shader.c @@ -19,40 +19,112 @@   * 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 "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> + +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); +} + +struct r600_pipe_shader *r600_pipe_shader_create(struct pipe_context *ctx, +						const struct tgsi_token *tokens) +{ +	struct r600_screen *rscreen = r600_screen(ctx->screen); +	struct r600_pipe_shader *rpshader = CALLOC_STRUCT(r600_pipe_shader); +	int r; + +fprintf(stderr, "--------------------------------------------------------------\n"); +tgsi_dump(tokens, 0); +	if (rpshader == NULL) +		return NULL; +	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"); +		goto out_err; +	} +	r = r600_bc_build(&rpshader->shader.bc); +	if (r) { +		R600_ERR("building bytecode failed !\n"); +		goto out_err; +	} +fprintf(stderr, "______________________________________________________________\n"); +	return rpshader; +out_err: +	free(rpshader); +	return NULL; +}  static int r600_pipe_shader_vs(struct pipe_context *ctx, struct r600_pipe_shader *rpshader)  {  	struct r600_screen *rscreen = r600_screen(ctx->screen);  	struct r600_shader *rshader = &rpshader->shader;  	struct radeon_state *state; -	unsigned i, tmp; +	unsigned i, j, tmp;  	rpshader->state = radeon_state_decref(rpshader->state);  	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; +	for (i = 0; i < 10; i++) { +		state->states[R600_VS_SHADER__SPI_VS_OUT_ID_0 + i] = 0;  	} -	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); +	for (i = 0, j = 0; i < rshader->noutput; i++) { +		if (rshader->output[i].name != TGSI_SEMANTIC_POSITION) { +			tmp = rshader->output[i].sid << ((j & 3) * 8); +			state->states[R600_VS_SHADER__SPI_VS_OUT_ID_0 + j / 4] |= tmp; +			j++; +		} +	} +	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->state = state;  	rpshader->state->bo[0] = radeon_bo_incref(rscreen->rw, rpshader->bo);  	rpshader->state->bo[1] = radeon_bo_incref(rscreen->rw, rpshader->bo); @@ -81,7 +153,7 @@ static int r600_pipe_shader_ps(struct pipe_context *ctx, struct r600_pipe_shader  	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_RESOURCES_PS] = S_028868_NUM_GPRS(rshader->bc.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); @@ -100,21 +172,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 +196,610 @@ 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_pipe_shader *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); +} + +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; +}; + +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 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.Saturate) { +		R600_ERR("staturate 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.Predicate) { +		R600_ERR("predicate 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; +	if (i->Instruction.Label) { +		R600_ERR("label unsupported\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]); +	if (i->Instruction.Texture) { +		R600_ERR("texture unsupported\n"); +		return -EINVAL;  	} -#endif -	fprintf(stderr, ">>\n\n"); -#endif -	return rpshader; +	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; +		} +	} +	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; +		} +	} +	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].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; +		break; +	case TGSI_FILE_CONSTANT: +	case TGSI_FILE_TEMPORARY: +		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; +	unsigned opcode; +	int i, r = 0, pos0; +	u32 value[4]; -	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: +//			R600_ERR("TGSI_TOKEN_TYPE_IMMEDIATE unsupported\n"); +			immediate = &ctx.parse.FullToken.FullImmediate; +			value[0] = immediate->u[0].Uint; +			value[1] = immediate->u[1].Uint; +			value[2] = immediate->u[2].Uint; +			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, 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; +		} +	} +	/* export output */ +	for (i = 0, pos0 = 0; i < shader->noutput; i++) { +		memset(&output, 0, sizeof(struct r600_bc_output)); +		output.gpr = shader->output[i].gpr; +		output.elem_size = 3; +		output.swizzle_x = 0; +		output.swizzle_y = 1; +		output.swizzle_z = 2; +		output.swizzle_w = 3; +		output.barrier = 1; +		output.type = V_SQ_CF_ALLOC_EXPORT_WORD0_SQ_EXPORT_PARAM; +		output.array_base = i - pos0; +		output.inst = V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT_DONE; +		switch (ctx.type == TGSI_PROCESSOR_VERTEX) { +		case TGSI_PROCESSOR_VERTEX: +			if (shader->output[i].name == TGSI_SEMANTIC_POSITION) { +				output.array_base = 60; +				output.type = V_SQ_CF_ALLOC_EXPORT_WORD0_SQ_EXPORT_POS; +				/* position doesn't count in array_base */ +				pos0 = 1; +			} +			break; +		case TGSI_PROCESSOR_FRAGMENT: +			if (shader->output[i].name == TGSI_SEMANTIC_COLOR) { +				output.array_base = 0; +				output.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;  		} +		if (i == (shader->noutput - 1)) { +			output.end_of_program = 1; +		} +		r = r600_bc_add_output(ctx.bc, &output); +		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, +			unsigned swizzle, +			struct r600_bc_alu_src *r600_src) +{ +	r600_src->sel = tgsi_src->Register.Index; +	if (tgsi_src->Register.File == TGSI_FILE_IMMEDIATE) { +		r600_src->sel = 0; +	} +	r600_src->sel += ctx->file_offset[tgsi_src->Register.File]; +	switch (swizzle) { +	case 0: +		r600_src->chan = tgsi_src->Register.SwizzleX;  		break; -	default: +	case 1: +		r600_src->chan = tgsi_src->Register.SwizzleY;  		break; -	} -	/* there should be enough input */ -	if (nresources < rshader->nresource) +	case 2: +		r600_src->chan = tgsi_src->Register.SwizzleZ; +		break; +	case 3: +		r600_src->chan = tgsi_src->Register.SwizzleW; +		break; +	default:  		return -EINVAL; -	/* FIXME compare resources */ -	r = r600_shader_update(rshader, resource_format); -	if (r) -		return r; -	return r600_pipe_shader(ctx, rpshader); +	} +	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) +{ +	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; +	return 0; +} + +static int tgsi_op2(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 = V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP; +		} else { +			alu.inst = ctx->inst_info->r600_opcode; +			for (j = 0; j < inst->Instruction.NumSrcRegs; j++) { +				r = tgsi_src(ctx, &inst->Src[j], i, &alu.src[j]); +				if (r) +					return r; +			} +			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_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; +		} +		alu.nliteral = 0; +		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 alu; +	int i, 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; +		} else { +			alu.inst = ctx->inst_info->r600_opcode; +			r = tgsi_src(ctx, &inst->Src[0], i, &alu.src[1]); +			if (r) +				return r; +			r = tgsi_src(ctx, &inst->Src[1], i, &alu.src[0]); +			if (r) +				return r; +			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_op3(struct r600_shader_ctx *ctx) +{ +	struct tgsi_full_instruction *inst = &ctx->parse.FullToken.FullInstruction; +	struct r600_bc_alu alu; +	int i, j, 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++) { +			r = tgsi_src(ctx, &inst->Src[j], i, &alu.src[j]); +			if (r) +				return r; +		} +		alu.dst.sel = ctx->temp_reg; +		alu.dst.chan = i; +		alu.is_op3 = 1; +		if (i == 3) { +			alu.last = 1; +		} +		r = r600_bc_add_alu(ctx->bc, &alu); +		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; +		} 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 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_unsupported}, +	{TGSI_OPCODE_RCP,	0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, +	{TGSI_OPCODE_RSQ,	0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, +	{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_op2}, +	{TGSI_OPCODE_DP4,	0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_DOT4, tgsi_op2}, +	{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_NOP, tgsi_unsupported}, +	{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_unsupported}, +	{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_NOP, tgsi_unsupported}, +	{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_NOP, tgsi_unsupported}, +	{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, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, +	{TGSI_OPCODE_TXD,	0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, +	{TGSI_OPCODE_TXP,	0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, +	{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_op2}, +	{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_NOP, tgsi_unsupported},  /* 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..23b6a83b9a 100644 --- a/src/gallium/drivers/r600/r600_shader.h +++ b/src/gallium/drivers/r600/r600_shader.h @@ -23,243 +23,23 @@  #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; +	int			sid;  };  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..4770ab0bf7 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 diff --git a/src/gallium/drivers/r600/r600_state.c b/src/gallium/drivers/r600/r600_state.c index 4150f88785..84a13e4ef7 100644 --- a/src/gallium/drivers/r600/r600_state.c +++ b/src/gallium/drivers/r600/r600_state.c @@ -151,7 +151,7 @@ static void r600_set_framebuffer_state(struct pipe_context *ctx,  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); +	return r600_pipe_shader_create(ctx, shader->tokens);  }  static void r600_bind_fs_state(struct pipe_context *ctx, void *state) @@ -164,7 +164,7 @@ static void r600_bind_fs_state(struct pipe_context *ctx, void *state)  static void *r600_create_vs_state(struct pipe_context *ctx,  					const struct pipe_shader_state *shader)  { -	return r600_pipe_shader_create(ctx, C_PROGRAM_TYPE_VS, shader->tokens); +	return r600_pipe_shader_create(ctx, shader->tokens);  }  static void r600_bind_vs_state(struct pipe_context *ctx, void *state) diff --git a/src/gallium/drivers/r600/r700_asm.c b/src/gallium/drivers/r600/r700_asm.c new file mode 100644 index 0000000000..3532ba5b0c --- /dev/null +++ b/src/gallium/drivers/r600/r700_asm.c @@ -0,0 +1,70 @@ +/* + * 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> +#include <errno.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; +}  | 
