diff options
| -rw-r--r-- | src/gallium/drivers/r600/r600_asm.c | 91 | ||||
| -rw-r--r-- | src/gallium/drivers/r600/r600_asm.h | 29 | ||||
| -rw-r--r-- | src/gallium/drivers/r600/r600_context.c | 2 | ||||
| -rw-r--r-- | src/gallium/drivers/r600/r600_helper.c | 11 | ||||
| -rw-r--r-- | src/gallium/drivers/r600/r600_shader.c | 31 | ||||
| -rw-r--r-- | src/gallium/drivers/r600/r600_sq.h | 2 | 
6 files changed, 152 insertions, 14 deletions
| diff --git a/src/gallium/drivers/r600/r600_asm.c b/src/gallium/drivers/r600/r600_asm.c index 6e48703a57..e678a2fdf2 100644 --- a/src/gallium/drivers/r600/r600_asm.c +++ b/src/gallium/drivers/r600/r600_asm.c @@ -38,6 +38,7 @@ static struct r600_bc_cf *r600_bc_cf(void)  	LIST_INITHEAD(&cf->list);  	LIST_INITHEAD(&cf->alu);  	LIST_INITHEAD(&cf->vtx); +	LIST_INITHEAD(&cf->tex);  	return cf;  } @@ -61,6 +62,16 @@ static struct r600_bc_vtx *r600_bc_vtx(void)  	return vtx;  } +static struct r600_bc_tex *r600_bc_tex(void) +{ +	struct r600_bc_tex *tex = CALLOC_STRUCT(r600_bc_tex); + +	if (tex == NULL) +		return NULL; +	LIST_INITHEAD(&tex->list); +	return tex; +} +  int r600_bc_init(struct r600_bc *bc, enum radeon_family family)  {  	LIST_INITHEAD(&bc->cf); @@ -149,8 +160,14 @@ 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) || +	if (bc->cf_last == NULL) { +		R600_ERR("no last CF\n"); +		return -EINVAL; +	} +	if (bc->cf_last->inst == V_SQ_CF_WORD1_SQ_CF_INST_TEX) { +		return 0; +	} +	if (bc->cf_last->inst != (V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU << 3) ||  		LIST_IS_EMPTY(&bc->cf_last->alu)) {  		R600_ERR("last CF is not ALU (%p)\n", bc->cf_last);  		return -EINVAL; @@ -186,13 +203,39 @@ int r600_bc_add_vtx(struct r600_bc *bc, const struct r600_bc_vtx *vtx)  		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 */ +	/* each fetch use 4 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) +int r600_bc_add_tex(struct r600_bc *bc, const struct r600_bc_tex *tex) +{ +	struct r600_bc_tex *ntex = r600_bc_tex(); +	int r; + +	if (ntex == NULL) +		return -ENOMEM; +	memcpy(ntex, tex, sizeof(struct r600_bc_tex)); + +	/* cf can contains only alu or only vtx or only tex */ +	if (bc->cf_last == NULL || +		bc->cf_last->inst != V_SQ_CF_WORD1_SQ_CF_INST_TEX) { +		r = r600_bc_add_cf(bc); +		if (r) { +			free(ntex); +			return r; +		} +		bc->cf_last->inst = V_SQ_CF_WORD1_SQ_CF_INST_TEX; +	} +	LIST_ADDTAIL(&ntex->list, &bc->cf_last->tex); +	/* each texture fetch use 4 dwords */ +	bc->cf_last->ndw += 4; +	bc->ndw += 4; +	return 0; +} + +static int r600_bc_vtx_build(struct r600_bc *bc, struct r600_bc_vtx *vtx, unsigned id)  {  	bc->bytecode[id++] = S_SQ_VTX_WORD0_BUFFER_ID(vtx->buffer_id) |  				S_SQ_VTX_WORD0_SRC_GPR(vtx->src_gpr) | @@ -209,6 +252,35 @@ int r600_bc_vtx_build(struct r600_bc *bc, struct r600_bc_vtx *vtx, unsigned id)  	return 0;  } +static int r600_bc_tex_build(struct r600_bc *bc, struct r600_bc_tex *tex, unsigned id) +{ +	bc->bytecode[id++] = S_SQ_TEX_WORD0_TEX_INST(tex->inst) | +				S_SQ_TEX_WORD0_RESOURCE_ID(tex->resource_id) | +				S_SQ_TEX_WORD0_SRC_GPR(tex->src_gpr) | +				S_SQ_TEX_WORD0_SRC_REL(tex->src_rel); +	bc->bytecode[id++] = S_SQ_TEX_WORD1_DST_GPR(tex->dst_gpr) | +				S_SQ_TEX_WORD1_DST_REL(tex->dst_rel) | +				S_SQ_TEX_WORD1_DST_SEL_X(tex->dst_sel_x) | +				S_SQ_TEX_WORD1_DST_SEL_Y(tex->dst_sel_y) | +				S_SQ_TEX_WORD1_DST_SEL_Z(tex->dst_sel_z) | +				S_SQ_TEX_WORD1_DST_SEL_W(tex->dst_sel_w) | +				S_SQ_TEX_WORD1_LOD_BIAS(tex->lod_bias) | +				S_SQ_TEX_WORD1_COORD_TYPE_X(tex->coord_type_x) | +				S_SQ_TEX_WORD1_COORD_TYPE_Y(tex->coord_type_y) | +				S_SQ_TEX_WORD1_COORD_TYPE_Z(tex->coord_type_z) | +				S_SQ_TEX_WORD1_COORD_TYPE_W(tex->coord_type_w); +	bc->bytecode[id++] = S_SQ_TEX_WORD2_OFFSET_X(tex->offset_x) | +				S_SQ_TEX_WORD2_OFFSET_Y(tex->offset_y) | +				S_SQ_TEX_WORD2_OFFSET_Z(tex->offset_z) | +				S_SQ_TEX_WORD2_SAMPLER_ID(tex->sampler_id) | +				S_SQ_TEX_WORD2_SRC_SEL_X(tex->src_sel_x) | +				S_SQ_TEX_WORD2_SRC_SEL_Y(tex->src_sel_y) | +				S_SQ_TEX_WORD2_SRC_SEL_Z(tex->src_sel_z) | +				S_SQ_TEX_WORD2_SRC_SEL_W(tex->src_sel_w); +	bc->bytecode[id++] = 0; +	return 0; +} +  int r600_bc_alu_build(struct r600_bc *bc, struct r600_bc_alu *alu, unsigned id)  {  	unsigned i; @@ -262,6 +334,7 @@ int r600_bc_cf_build(struct r600_bc *bc, struct r600_bc_cf *cf)  					S_SQ_CF_ALU_WORD1_BARRIER(1) |  					S_SQ_CF_ALU_WORD1_COUNT((cf->ndw / 2) - 1);  		break; +	case V_SQ_CF_WORD1_SQ_CF_INST_TEX:  	case V_SQ_CF_WORD1_SQ_CF_INST_VTX:  	case V_SQ_CF_WORD1_SQ_CF_INST_VTX_TC:  		bc->bytecode[id++] = S_SQ_CF_WORD0_ADDR(cf->addr >> 1); @@ -295,6 +368,7 @@ int r600_bc_build(struct r600_bc *bc)  	struct r600_bc_cf *cf;  	struct r600_bc_alu *alu;  	struct r600_bc_vtx *vtx; +	struct r600_bc_tex *tex;  	unsigned addr;  	int r; @@ -306,6 +380,7 @@ int r600_bc_build(struct r600_bc *bc)  		switch (cf->inst) {  		case (V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU << 3):  			break; +		case V_SQ_CF_WORD1_SQ_CF_INST_TEX:  		case V_SQ_CF_WORD1_SQ_CF_INST_VTX:  		case V_SQ_CF_WORD1_SQ_CF_INST_VTX_TC:  			/* fetch node need to be 16 bytes aligned*/ @@ -373,6 +448,14 @@ int r600_bc_build(struct r600_bc *bc)  				addr += 4;  			}  			break; +		case V_SQ_CF_WORD1_SQ_CF_INST_TEX: +			LIST_FOR_EACH_ENTRY(tex, &cf->tex, list) { +				r = r600_bc_tex_build(bc, tex, addr); +				if (r) +					return r; +				addr += 4; +			} +			break;  		case V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT:  		case V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT_DONE:  			break; diff --git a/src/gallium/drivers/r600/r600_asm.h b/src/gallium/drivers/r600/r600_asm.h index 8a874a9df5..88fb957440 100644 --- a/src/gallium/drivers/r600/r600_asm.h +++ b/src/gallium/drivers/r600/r600_asm.h @@ -51,6 +51,33 @@ struct r600_bc_alu {  	u32				value[4];  }; +struct r600_bc_tex { +	struct list_head		list; +	unsigned			inst; +	unsigned			resource_id; +	unsigned			src_gpr; +	unsigned			src_rel; +	unsigned			dst_gpr; +	unsigned			dst_rel; +	unsigned			dst_sel_x; +	unsigned			dst_sel_y; +	unsigned			dst_sel_z; +	unsigned			dst_sel_w; +	unsigned			lod_bias; +	unsigned			coord_type_x; +	unsigned			coord_type_y; +	unsigned			coord_type_z; +	unsigned			coord_type_w; +	unsigned			offset_x; +	unsigned			offset_y; +	unsigned			offset_z; +	unsigned			sampler_id; +	unsigned			src_sel_x; +	unsigned			src_sel_y; +	unsigned			src_sel_z; +	unsigned			src_sel_w; +}; +  struct r600_bc_vtx {  	struct list_head		list;  	unsigned			inst; @@ -87,6 +114,7 @@ struct r600_bc_cf {  	unsigned			ndw;  	unsigned			id;  	struct list_head		alu; +	struct list_head		tex;  	struct list_head		vtx;  	struct r600_bc_output		output;  }; @@ -106,6 +134,7 @@ int r600_bc_init(struct r600_bc *bc, enum radeon_family family);  int r600_bc_add_alu(struct r600_bc *bc, const struct r600_bc_alu *alu);  int r600_bc_add_literal(struct r600_bc *bc, const u32 *value);  int r600_bc_add_vtx(struct r600_bc *bc, const struct r600_bc_vtx *vtx); +int r600_bc_add_tex(struct r600_bc *bc, const struct r600_bc_tex *tex);  int r600_bc_add_output(struct r600_bc *bc, const struct r600_bc_output *output);  int r600_bc_build(struct r600_bc *bc); diff --git a/src/gallium/drivers/r600/r600_context.c b/src/gallium/drivers/r600/r600_context.c index 3c5195f79e..05575b5767 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 1 +#if 0  	radeon_ctx_submit(rctx->ctx);  #endif  	rctx->ctx = radeon_ctx_decref(rctx->ctx); diff --git a/src/gallium/drivers/r600/r600_helper.c b/src/gallium/drivers/r600/r600_helper.c index e3175b627a..7241ab1c17 100644 --- a/src/gallium/drivers/r600/r600_helper.c +++ b/src/gallium/drivers/r600/r600_helper.c @@ -27,6 +27,7 @@  #include <errno.h>  #include <util/u_inlines.h>  #include "r600_screen.h" +#include "r600_context.h"  #include "r600d.h"  int r600_conv_pipe_format(unsigned pformat, unsigned *format) @@ -49,6 +50,12 @@ int r600_conv_pipe_format(unsigned pformat, unsigned *format)  	case PIPE_FORMAT_R8G8B8A8_SSCALED:  		*format = V_0280A0_COLOR_8_8_8_8;  		return 0; +	case PIPE_FORMAT_R32_FLOAT: +		*format = V_0280A0_COLOR_32_FLOAT; +		return 0; +	case PIPE_FORMAT_R32G32_FLOAT: +		*format = V_0280A0_COLOR_32_32_FLOAT; +		return 0;  	case PIPE_FORMAT_L8_UNORM:  	case PIPE_FORMAT_A8_UNORM:  	case PIPE_FORMAT_I8_UNORM: @@ -60,8 +67,6 @@ int r600_conv_pipe_format(unsigned pformat, unsigned *format)  	case PIPE_FORMAT_R64G64_FLOAT:  	case PIPE_FORMAT_R64G64B64_FLOAT:  	case PIPE_FORMAT_R64G64B64A64_FLOAT: -	case PIPE_FORMAT_R32_FLOAT: -	case PIPE_FORMAT_R32G32_FLOAT:  	case PIPE_FORMAT_R32_UNORM:  	case PIPE_FORMAT_R32G32_UNORM:  	case PIPE_FORMAT_R32G32B32_UNORM: @@ -111,7 +116,7 @@ int r600_conv_pipe_format(unsigned pformat, unsigned *format)  	case PIPE_FORMAT_R32G32B32_FIXED:  	case PIPE_FORMAT_R32G32B32A32_FIXED:  	default: -		fprintf(stderr, "%s:%d unsupported %d\n", __func__, __LINE__, pformat); +		R600_ERR("unsupported %d\n", pformat);  		return -EINVAL;  	}  } diff --git a/src/gallium/drivers/r600/r600_shader.c b/src/gallium/drivers/r600/r600_shader.c index d788ab88be..e865f013f7 100644 --- a/src/gallium/drivers/r600/r600_shader.c +++ b/src/gallium/drivers/r600/r600_shader.c @@ -23,6 +23,7 @@  #include "pipe/p_shader_tokens.h"  #include "tgsi/tgsi_parse.h"  #include "tgsi/tgsi_scan.h" +#include "tgsi/tgsi_dump.h"  #include "util/u_format.h"  #include "r600_screen.h"  #include "r600_context.h" @@ -259,10 +260,6 @@ static int tgsi_is_supported(struct r600_shader_ctx *ctx)  		R600_ERR("label unsupported\n");  		return -EINVAL;  	} -	if (i->Instruction.Texture) { -		R600_ERR("texture unsupported\n"); -		return -EINVAL; -	}  	for (j = 0; j < i->Instruction.NumSrcRegs; j++) {  		if (i->Src[j].Register.Indirect ||  			i->Src[j].Register.Dimension || @@ -321,6 +318,7 @@ static int tgsi_declaration(struct r600_shader_ctx *ctx)  		break;  	case TGSI_FILE_CONSTANT:  	case TGSI_FILE_TEMPORARY: +	case TGSI_FILE_SAMPLER:  		break;  	default:  		R600_ERR("unsupported file %d declaration\n", d->Declaration.File); @@ -381,7 +379,6 @@ int r600_shader_from_tgsi(const struct tgsi_token *tokens, struct r600_shader *s  		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; @@ -713,6 +710,28 @@ static int tgsi_dp(struct r600_shader_ctx *ctx)  	return tgsi_helper_copy(ctx, inst);  } +static int tgsi_tex(struct r600_shader_ctx *ctx) +{ +	struct tgsi_full_instruction *inst = &ctx->parse.FullToken.FullInstruction; +	struct r600_bc_tex tex; + +	memset(&tex, 0, sizeof(struct r600_bc_tex)); +	tex.inst = ctx->inst_info->r600_opcode; +	tex.resource_id = ctx->file_offset[inst->Src[1].Register.File] + inst->Src[1].Register.Index; +	tex.sampler_id = tex.resource_id; +	tex.src_gpr = ctx->file_offset[inst->Src[0].Register.File] + inst->Src[0].Register.Index; +	tex.dst_gpr = ctx->file_offset[inst->Dst[0].Register.File] + inst->Src[0].Register.Index; +	tex.dst_sel_x = 0; +	tex.dst_sel_y = 1; +	tex.dst_sel_z = 2; +	tex.dst_sel_w = 3; +	tex.src_sel_x = 0; +	tex.src_sel_y = 1; +	tex.src_sel_z = 2; +	tex.src_sel_w = 3; +	return r600_bc_add_tex(ctx->bc, &tex); +} +  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}, @@ -771,7 +790,7 @@ static struct r600_shader_tgsi_instruction r600_shader_tgsi_instruction[] = {  	{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_TXP,	0, 0x10, tgsi_tex},  	{TGSI_OPCODE_UP2H,	0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},  	{TGSI_OPCODE_UP2US,	0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},  	{TGSI_OPCODE_UP4B,	0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, diff --git a/src/gallium/drivers/r600/r600_sq.h b/src/gallium/drivers/r600/r600_sq.h index 4770ab0bf7..002660c654 100644 --- a/src/gallium/drivers/r600/r600_sq.h +++ b/src/gallium/drivers/r600/r600_sq.h @@ -546,6 +546,8 @@  #define   S_SQ_TEX_WORD1_COORD_TYPE_X(x)                             (((x) & 0x1) << 28)  #define   G_SQ_TEX_WORD1_COORD_TYPE_X(x)                             (((x) >> 28) & 0x1)  #define   C_SQ_TEX_WORD1_COORD_TYPE_X                                0xEFFFFFFF +#define     V_SQ_TEX_WORD1_COORD_UNNORMALIZED                        0x00000000 +#define     V_SQ_TEX_WORD1_COORD_NORMALIZED                          0x00000001  #define   S_SQ_TEX_WORD1_COORD_TYPE_Y(x)                             (((x) & 0x1) << 29)  #define   G_SQ_TEX_WORD1_COORD_TYPE_Y(x)                             (((x) >> 29) & 0x1)  #define   C_SQ_TEX_WORD1_COORD_TYPE_Y                                0xDFFFFFFF | 
