r600_shader.c revision c6131879eb7dfdf26cd068109f6680608d608ab4
172128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse/*
272128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse * Copyright 2010 Jerome Glisse <glisse@freedesktop.org>
372128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse *
472128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse * Permission is hereby granted, free of charge, to any person obtaining a
572128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse * copy of this software and associated documentation files (the "Software"),
672128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse * to deal in the Software without restriction, including without limitation
772128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse * on the rights to use, copy, modify, merge, publish, distribute, sub
872128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse * license, and/or sell copies of the Software, and to permit persons to whom
972128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse * the Software is furnished to do so, subject to the following conditions:
1072128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse *
1172128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse * The above copyright notice and this permission notice (including the next
1272128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse * paragraph) shall be included in all copies or substantial portions of the
1372128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse * Software.
1472128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse *
1572128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1672128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1772128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
1872128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
1972128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
2072128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
2172128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse * USE OR OTHER DEALINGS IN THE SOFTWARE.
2272128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse *
2372128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse * Authors:
2472128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse *      Jerome Glisse
2572128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse */
2672128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse#include <stdio.h>
2772128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse#include <errno.h>
2872128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse#include <util/u_inlines.h>
2972128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse#include <util/u_format.h>
3072128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse#include <util/u_memory.h>
3172128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse#include <tgsi/tgsi_dump.h>
3272128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse#include "r600_screen.h"
3372128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse#include "r600_context.h"
3472128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse#include "r600d.h"
3572128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse
3672128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glissestatic int r600_pipe_shader_vs(struct pipe_context *ctx, struct r600_pipe_shader *rpshader)
3772128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse{
38ffd0a2e215d83222f5e1e148b8e7cddeac6025d2Marek Olšák	struct r600_screen *rscreen = r600_screen(ctx->screen);
3972128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse	struct r600_shader *rshader = &rpshader->shader;
4072128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse	struct radeon_state *state;
4172128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse	unsigned i, tmp;
4272128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse
4372128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse	rpshader->state = radeon_state_decref(rpshader->state);
4472128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse	state = radeon_state(rscreen->rw, R600_VS_SHADER_TYPE, R600_VS_SHADER);
4572128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse	if (state == NULL)
4672128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse		return -ENOMEM;
4772128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse	for (i = 0; i < rshader->noutput; i += 4) {
4872128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse		tmp = rshader->output[i].sid;
4972128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse		tmp |= rshader->output[i + 1].sid << 8;
5072128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse		tmp |= rshader->output[i + 2].sid << 16;
5172128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse		tmp |= rshader->output[i + 3].sid << 24;
5272128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse		state->states[R600_VS_SHADER__SPI_VS_OUT_ID_0 + i / 4] = tmp;
5372128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse	}
5472128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse	state->states[R600_VS_SHADER__SPI_VS_OUT_CONFIG] = S_0286C4_VS_EXPORT_COUNT(rshader->noutput - 1);
5572128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse	state->states[R600_VS_SHADER__SQ_PGM_RESOURCES_VS] = S_028868_NUM_GPRS(rshader->ngpr);
5672128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse	rpshader->state = state;
5772128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse	rpshader->state->bo[0] = radeon_bo_incref(rscreen->rw, rpshader->bo);
5872128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse	rpshader->state->bo[1] = radeon_bo_incref(rscreen->rw, rpshader->bo);
5972128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse	rpshader->state->nbo = 2;
6072128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse	rpshader->state->placement[0] = RADEON_GEM_DOMAIN_GTT;
6172128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse	return radeon_state_pm4(state);
6272128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse}
6372128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse
6472128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glissestatic int r600_pipe_shader_ps(struct pipe_context *ctx, struct r600_pipe_shader *rpshader)
6572128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse{
66ffd0a2e215d83222f5e1e148b8e7cddeac6025d2Marek Olšák	struct r600_screen *rscreen = r600_screen(ctx->screen);
6772128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse	struct r600_shader *rshader = &rpshader->shader;
6872128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse	struct radeon_state *state;
6972128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse	unsigned i, tmp;
7072128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse
7172128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse	rpshader->state = radeon_state_decref(rpshader->state);
7272128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse	state = radeon_state(rscreen->rw, R600_PS_SHADER_TYPE, R600_PS_SHADER);
7372128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse	if (state == NULL)
7472128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse		return -ENOMEM;
7572128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse	for (i = 0; i < rshader->ninput; i++) {
7672128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse		tmp = S_028644_SEMANTIC(rshader->input[i].sid);
7772128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse		tmp |= S_028644_SEL_CENTROID(1);
7872128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse		tmp |= S_028644_FLAT_SHADE(rshader->flat_shade);
7972128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse		state->states[R600_PS_SHADER__SPI_PS_INPUT_CNTL_0 + i] = tmp;
8072128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse	}
8172128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse	state->states[R600_PS_SHADER__SPI_PS_IN_CONTROL_0] = S_0286CC_NUM_INTERP(rshader->ninput) |
8272128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse							S_0286CC_PERSP_GRADIENT_ENA(1);
8372128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse	state->states[R600_PS_SHADER__SPI_PS_IN_CONTROL_1] = 0x00000000;
8472128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse	state->states[R600_PS_SHADER__SQ_PGM_RESOURCES_PS] = S_028868_NUM_GPRS(rshader->ngpr);
8572128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse	state->states[R600_PS_SHADER__SQ_PGM_EXPORTS_PS] = 0x00000002;
8672128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse	rpshader->state = state;
8772128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse	rpshader->state->bo[0] = radeon_bo_incref(rscreen->rw, rpshader->bo);
8872128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse	rpshader->state->nbo = 1;
8972128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse	rpshader->state->placement[0] = RADEON_GEM_DOMAIN_GTT;
9072128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse	return radeon_state_pm4(state);
9172128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse}
9272128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse
9372128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glissestatic int r600_pipe_shader(struct pipe_context *ctx, struct r600_pipe_shader *rpshader)
9472128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse{
95ffd0a2e215d83222f5e1e148b8e7cddeac6025d2Marek Olšák	struct r600_screen *rscreen = r600_screen(ctx->screen);
96ffd0a2e215d83222f5e1e148b8e7cddeac6025d2Marek Olšák	struct r600_context *rctx = r600_context(ctx);
9772128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse	struct r600_shader *rshader = &rpshader->shader;
9872128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse	int r;
9972128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse
10072128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse	/* copy new shader */
10172128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse	radeon_bo_decref(rscreen->rw, rpshader->bo);
10272128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse	rpshader->bo = NULL;
10372128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse	rpshader->bo = radeon_bo(rscreen->rw, 0, rshader->ndw * 4,
10472128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse				4096, NULL);
10572128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse	if (rpshader->bo == NULL) {
10672128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse		return -ENOMEM;
10772128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse	}
10872128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse	radeon_bo_map(rscreen->rw, rpshader->bo);
10972128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse	memcpy(rpshader->bo->data, rshader->bcode, rshader->ndw * 4);
11072128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse	radeon_bo_unmap(rscreen->rw, rpshader->bo);
11172128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse	/* build state */
11272128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse	rshader->flat_shade = rctx->flat_shade;
11372128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse	switch (rpshader->type) {
11472128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse	case C_PROGRAM_TYPE_VS:
11572128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse		r = r600_pipe_shader_vs(ctx, rpshader);
11672128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse		break;
11772128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse	case C_PROGRAM_TYPE_FS:
11872128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse		r = r600_pipe_shader_ps(ctx, rpshader);
11972128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse		break;
12072128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse	default:
12172128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse		r = -EINVAL;
12272128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse		break;
12372128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse	}
12472128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse	return r;
12572128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse}
12672128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse
12772128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glissestruct r600_pipe_shader *r600_pipe_shader_create(struct pipe_context *ctx, unsigned type, const struct tgsi_token *tokens)
12872128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse{
12972128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse	struct r600_pipe_shader *rpshader = CALLOC_STRUCT(r600_pipe_shader);
13072128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse	struct r600_shader *rshader = &rpshader->shader;
13172128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse	int r;
13272128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse
13372128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse	if (rpshader == NULL)
13472128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse		return NULL;
13572128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse	rpshader->type = type;
13672128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse	c_list_init(&rshader->nodes);
13772128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse	fprintf(stderr, "<<\n");
13872128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse	tgsi_dump(tokens, 0);
13972128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse	fprintf(stderr, "--------------------------------------------------------------\n");
14072128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse	r = c_shader_from_tgsi(&rshader->cshader, type, tokens);
14172128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse	if (r) {
14272128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse		r600_pipe_shader_destroy(ctx, rpshader);
14372128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse		fprintf(stderr, "ERROR(%s %d)>>\n\n", __func__, __LINE__);
14472128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse		return NULL;
14572128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse	}
14672128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse	r = r600_shader_insert_fetch(&rshader->cshader);
14772128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse	if (r) {
14872128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse		r600_pipe_shader_destroy(ctx, rpshader);
14972128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse		fprintf(stderr, "ERROR(%s %d)>>\n\n", __func__, __LINE__);
15072128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse		return NULL;
15172128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse	}
15272128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse	r = c_shader_build_dominator_tree(&rshader->cshader);
15372128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse	if (r) {
15472128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse		r600_pipe_shader_destroy(ctx, rpshader);
15572128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse		fprintf(stderr, "ERROR(%s %d)>>\n\n", __func__, __LINE__);
15672128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse		return NULL;
15772128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse	}
15872128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse	c_shader_dump(&rshader->cshader);
159c6131879eb7dfdf26cd068109f6680608d608ab4Jerome Glisse	r = r600_cshader_legalize(&rshader->cshader);
160c6131879eb7dfdf26cd068109f6680608d608ab4Jerome Glisse	if (r) {
161c6131879eb7dfdf26cd068109f6680608d608ab4Jerome Glisse		r600_pipe_shader_destroy(ctx, rpshader);
162c6131879eb7dfdf26cd068109f6680608d608ab4Jerome Glisse		fprintf(stderr, "ERROR(%s %d)>>\n\n", __func__, __LINE__);
163c6131879eb7dfdf26cd068109f6680608d608ab4Jerome Glisse		return NULL;
164c6131879eb7dfdf26cd068109f6680608d608ab4Jerome Glisse	}
16572128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse	r = r700_shader_translate(rshader);
16672128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse	if (r) {
16772128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse		r600_pipe_shader_destroy(ctx, rpshader);
16872128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse		fprintf(stderr, "ERROR(%s %d)>>\n\n", __func__, __LINE__);
16972128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse		return NULL;
17072128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse	}
17172128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse#if 1
17272128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse#if 0
17372128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse	fprintf(stderr, "--------------------------------------------------------------\n");
17472128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse	for (int i = 0; i < rshader->ndw; i++) {
17572128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse		fprintf(stderr, "0x%08X\n", rshader->bcode[i]);
17672128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse	}
17772128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse#endif
17872128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse	fprintf(stderr, ">>\n\n");
17972128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse#endif
18072128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse	return rpshader;
18172128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse}
18272128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse
18372128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glissevoid r600_pipe_shader_destroy(struct pipe_context *ctx, struct r600_pipe_shader *rpshader)
18472128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse{
185ffd0a2e215d83222f5e1e148b8e7cddeac6025d2Marek Olšák	struct r600_screen *rscreen = r600_screen(ctx->screen);
18672128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse
18772128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse	if (rpshader == NULL)
18872128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse		return;
18972128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse	radeon_bo_decref(rscreen->rw, rpshader->bo);
19072128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse	rpshader->bo = NULL;
19172128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse	r600_shader_cleanup(&rpshader->shader);
19272128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse	FREE(rpshader);
19372128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse}
19472128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse
19572128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisseint r600_pipe_shader_update(struct pipe_context *ctx, struct r600_pipe_shader *rpshader)
19672128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse{
197ffd0a2e215d83222f5e1e148b8e7cddeac6025d2Marek Olšák	struct r600_context *rctx = r600_context(ctx);
19872128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse	struct r600_shader *rshader;
19972128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse	enum pipe_format resource_format[160];
20072128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse	unsigned i, nresources = 0;
20172128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse	int r;
20272128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse
20372128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse	if (rpshader == NULL)
20472128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse		return -EINVAL;
20572128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse	rshader = &rpshader->shader;
20672128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse	switch (rpshader->type) {
20772128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse	case C_PROGRAM_TYPE_VS:
2089e8a6f801d360f85cc7bb53b85f15129b07b26daBas Nieuwenhuizen		for (i = 0; i < rctx->vertex_elements->count; i++) {
2099e8a6f801d360f85cc7bb53b85f15129b07b26daBas Nieuwenhuizen			resource_format[nresources++] = rctx->vertex_elements->elements[i].src_format;
21072128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse		}
21172128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse		break;
21272128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse	default:
21372128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse		break;
21472128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse	}
21572128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse	/* there should be enough input */
21672128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse	if (nresources < rshader->nresource)
21772128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse		return -EINVAL;
21872128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse	/* FIXME compare resources */
21972128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse	r = r600_shader_update(rshader, resource_format);
22072128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse	if (r)
22172128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse		return r;
22272128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse	return r600_pipe_shader(ctx, rpshader);
22372128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse}
224