#include <util/u_format.h>
#include <pipebuffer/pb_buffer.h>
#include "pipe/p_shader_tokens.h"
+#include "tgsi/tgsi_parse.h"
#include "r600_formats.h"
#include "r600_pipe.h"
#include "r600d.h"
if (state == NULL)
return;
+ rctx->clamp_vertex_color = rs->clamp_vertex_color;
+ rctx->clamp_fragment_color = rs->clamp_fragment_color;
rctx->flatshade = rs->flatshade;
rctx->sprite_coord_enable = rs->sprite_coord_enable;
rctx->rasterizer = rs;
rctx->states[rs->rstate.id] = &rs->rstate;
r600_context_pipe_state_set(&rctx->ctx, &rs->rstate);
- if (rctx->family >= CHIP_CEDAR) {
+ if (rctx->chip_class >= EVERGREEN) {
evergreen_polygon_offset_update(rctx);
} else {
r600_polygon_offset_update(rctx);
}
if (rctx->ps_shader && rctx->vs_shader)
- r600_spi_update(rctx);
+ rctx->spi_dirty = true;
}
void r600_delete_rs_state(struct pipe_context *ctx, void *state)
rctx->states[rstate->id] = NULL;
}
for (int i = 0; i < rstate->nregs; i++) {
- r600_bo_reference(rctx->radeon, &rstate->regs[i].bo, NULL);
+ r600_bo_reference(&rstate->regs[i].bo, NULL);
}
free(rstate);
}
if (rctx->vertex_elements == state)
rctx->vertex_elements = NULL;
- r600_bo_reference(rctx->radeon, &v->fetch_shader, NULL);
+ r600_bo_reference(&v->fetch_shader, NULL);
u_vbuf_mgr_destroy_vertex_elements(rctx->vbuf_mgr, v->vmgr_elements);
FREE(state);
}
/* Zero states. */
for (i = 0; i < count; i++) {
if (!buffers[i].buffer) {
- if (rctx->family >= CHIP_CEDAR) {
+ if (rctx->chip_class >= EVERGREEN) {
evergreen_context_pipe_state_set_fs_resource(&rctx->ctx, NULL, i);
} else {
r600_context_pipe_state_set_fs_resource(&rctx->ctx, NULL, i);
}
}
for (; i < rctx->vbuf_mgr->nr_real_vertex_buffers; i++) {
- if (rctx->family >= CHIP_CEDAR) {
+ if (rctx->chip_class >= EVERGREEN) {
evergreen_context_pipe_state_set_fs_resource(&rctx->ctx, NULL, i);
} else {
r600_context_pipe_state_set_fs_resource(&rctx->ctx, NULL, i);
struct r600_pipe_shader *shader = CALLOC_STRUCT(r600_pipe_shader);
int r;
- r = r600_pipe_shader_create(ctx, shader, state->tokens);
+ shader->tokens = tgsi_dup_tokens(state->tokens);
+
+ r = r600_pipe_shader_create(ctx, shader);
if (r) {
return NULL;
}
r600_context_pipe_state_set(&rctx->ctx, &rctx->ps_shader->rstate);
}
if (rctx->ps_shader && rctx->vs_shader) {
- r600_spi_update(rctx);
+ rctx->spi_dirty = true;
r600_adjust_gprs(rctx);
}
}
r600_context_pipe_state_set(&rctx->ctx, &rctx->vs_shader->rstate);
}
if (rctx->ps_shader && rctx->vs_shader) {
- r600_spi_update(rctx);
+ rctx->spi_dirty = true;
r600_adjust_gprs(rctx);
}
}
rctx->ps_shader = NULL;
}
+ free(shader->tokens);
r600_pipe_shader_destroy(ctx, shader);
free(shader);
}
rctx->vs_shader = NULL;
}
+ free(shader->tokens);
r600_pipe_shader_destroy(ctx, shader);
free(shader);
}
rstate.nregs = 0;
if (rctx->export_16bpc)
alpha_ref &= ~0x1FFF;
- r600_pipe_state_add_reg(&rstate, R_028438_SX_ALPHA_REF, alpha_ref, 0xFFFFFFFF, NULL);
+ r600_pipe_state_add_reg(&rstate, R_028438_SX_ALPHA_REF, alpha_ref, 0xFFFFFFFF, NULL, 0);
r600_context_pipe_state_set(&rctx->ctx, &rstate);
rctx->alpha_ref_dirty = false;
rstate->nregs = 0;
rstate->id = R600_PIPE_STATE_SPI;
for (i = 0; i < 32; i++) {
- r600_pipe_state_add_reg(rstate, R_028644_SPI_PS_INPUT_CNTL_0 + i * 4, 0, 0xFFFFFFFF, NULL);
+ r600_pipe_state_add_reg(rstate, R_028644_SPI_PS_INPUT_CNTL_0 + i * 4, 0, 0xFFFFFFFF, NULL, 0);
}
}
for (i = 0; i < rshader->ninput; i++) {
if (rshader->input[i].name == TGSI_SEMANTIC_POSITION ||
rshader->input[i].name == TGSI_SEMANTIC_FACE)
- if (rctx->family >= CHIP_CEDAR)
+ if (rctx->chip_class >= EVERGREEN)
continue;
else
sid=0;
tmp |= S_028644_PT_SPRITE_TEX(1);
}
- if (rctx->family < CHIP_CEDAR) {
+ if (rctx->chip_class < EVERGREEN) {
if (rshader->input[i].centroid)
tmp |= S_028644_SEL_CENTROID(1);
r600_pipe_state_mod_reg(rstate, tmp);
}
+ rctx->spi_dirty = false;
r600_context_pipe_state_set(&rctx->ctx, rstate);
}
}
r600_upload_const_buffer(rctx, &rbuffer, &offset);
- offset += r600_bo_offset(rbuffer->r.bo);
switch (shader) {
case PIPE_SHADER_VERTEX:
r600_pipe_state_add_reg(&rctx->vs_const_buffer,
R_028180_ALU_CONST_BUFFER_SIZE_VS_0,
ALIGN_DIVUP(buffer->width0 >> 4, 16),
- 0xFFFFFFFF, NULL);
+ 0xFFFFFFFF, NULL, 0);
r600_pipe_state_add_reg(&rctx->vs_const_buffer,
R_028980_ALU_CONST_CACHE_VS_0,
- offset >> 8, 0xFFFFFFFF, rbuffer->r.bo);
+ offset >> 8, 0xFFFFFFFF, rbuffer->r.bo, RADEON_USAGE_READ);
r600_context_pipe_state_set(&rctx->ctx, &rctx->vs_const_buffer);
rstate = &rctx->vs_const_buffer_resource[index];
if (!rstate->id) {
- if (rctx->family >= CHIP_CEDAR) {
+ if (rctx->chip_class >= EVERGREEN) {
evergreen_pipe_init_buffer_resource(rctx, rstate);
} else {
r600_pipe_init_buffer_resource(rctx, rstate);
}
}
- if (rctx->family >= CHIP_CEDAR) {
- evergreen_pipe_mod_buffer_resource(rstate, &rbuffer->r, offset, 16);
+ if (rctx->chip_class >= EVERGREEN) {
+ evergreen_pipe_mod_buffer_resource(rstate, &rbuffer->r, offset, 16, RADEON_USAGE_READ);
evergreen_context_pipe_state_set_vs_resource(&rctx->ctx, rstate, index);
} else {
- r600_pipe_mod_buffer_resource(rstate, &rbuffer->r, offset, 16);
+ r600_pipe_mod_buffer_resource(rstate, &rbuffer->r, offset, 16, RADEON_USAGE_READ);
r600_context_pipe_state_set_vs_resource(&rctx->ctx, rstate, index);
}
break;
r600_pipe_state_add_reg(&rctx->ps_const_buffer,
R_028140_ALU_CONST_BUFFER_SIZE_PS_0,
ALIGN_DIVUP(buffer->width0 >> 4, 16),
- 0xFFFFFFFF, NULL);
+ 0xFFFFFFFF, NULL, 0);
r600_pipe_state_add_reg(&rctx->ps_const_buffer,
R_028940_ALU_CONST_CACHE_PS_0,
- offset >> 8, 0xFFFFFFFF, rbuffer->r.bo);
+ offset >> 8, 0xFFFFFFFF, rbuffer->r.bo, RADEON_USAGE_READ);
r600_context_pipe_state_set(&rctx->ctx, &rctx->ps_const_buffer);
rstate = &rctx->ps_const_buffer_resource[index];
if (!rstate->id) {
- if (rctx->family >= CHIP_CEDAR) {
+ if (rctx->chip_class >= EVERGREEN) {
evergreen_pipe_init_buffer_resource(rctx, rstate);
} else {
r600_pipe_init_buffer_resource(rctx, rstate);
}
}
- if (rctx->family >= CHIP_CEDAR) {
- evergreen_pipe_mod_buffer_resource(rstate, &rbuffer->r, offset, 16);
+ if (rctx->chip_class >= EVERGREEN) {
+ evergreen_pipe_mod_buffer_resource(rstate, &rbuffer->r, offset, 16, RADEON_USAGE_READ);
evergreen_context_pipe_state_set_ps_resource(&rctx->ctx, rstate, index);
} else {
- r600_pipe_mod_buffer_resource(rstate, &rbuffer->r, offset, 16);
+ r600_pipe_mod_buffer_resource(rstate, &rbuffer->r, offset, 16, RADEON_USAGE_READ);
r600_context_pipe_state_set_ps_resource(&rctx->ctx, rstate, index);
}
break;
}
if (vertex_buffer == NULL || rbuffer == NULL)
continue;
- offset += vertex_buffer->buffer_offset + r600_bo_offset(rbuffer->bo);
+ offset += vertex_buffer->buffer_offset;
if (!rstate->id) {
- if (rctx->family >= CHIP_CEDAR) {
+ if (rctx->chip_class >= EVERGREEN) {
evergreen_pipe_init_buffer_resource(rctx, rstate);
} else {
r600_pipe_init_buffer_resource(rctx, rstate);
}
}
- if (rctx->family >= CHIP_CEDAR) {
- evergreen_pipe_mod_buffer_resource(rstate, rbuffer, offset, vertex_buffer->stride);
+ if (rctx->chip_class >= EVERGREEN) {
+ evergreen_pipe_mod_buffer_resource(rstate, rbuffer, offset, vertex_buffer->stride, RADEON_USAGE_READ);
evergreen_context_pipe_state_set_fs_resource(&rctx->ctx, rstate, i);
} else {
- r600_pipe_mod_buffer_resource(rstate, rbuffer, offset, vertex_buffer->stride);
+ r600_pipe_mod_buffer_resource(rstate, rbuffer, offset, vertex_buffer->stride, RADEON_USAGE_READ);
r600_context_pipe_state_set_fs_resource(&rctx->ctx, rstate, i);
}
}
}
+static int r600_shader_rebuild(struct pipe_context * ctx, struct r600_pipe_shader * shader)
+{
+ struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx;
+ int r;
+
+ r600_pipe_shader_destroy(ctx, shader);
+ r = r600_pipe_shader_create(ctx, shader);
+ if (r) {
+ return r;
+ }
+ r600_context_pipe_state_set(&rctx->ctx, &shader->rstate);
+
+ return 0;
+}
+
void r600_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *info)
{
struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx;
if (r600_conv_pipe_prim(draw.info.mode, &prim))
return;
+ if (rctx->vs_shader->shader.clamp_color != rctx->clamp_vertex_color)
+ r600_shader_rebuild(ctx, rctx->vs_shader);
+
+ if ((rctx->ps_shader->shader.clamp_color != rctx->clamp_fragment_color) ||
+ ((rctx->chip_class >= EVERGREEN) && rctx->ps_shader->shader.fs_write_all &&
+ (rctx->ps_shader->shader.nr_cbufs != rctx->nr_cbufs)))
+ r600_shader_rebuild(ctx, rctx->ps_shader);
+
+ if (rctx->spi_dirty)
+ r600_spi_update(rctx);
+
if (rctx->alpha_ref_dirty)
r600_update_alpha_ref(rctx);
if (rctx->vgt.id != R600_PIPE_STATE_VGT) {
rctx->vgt.id = R600_PIPE_STATE_VGT;
rctx->vgt.nregs = 0;
- r600_pipe_state_add_reg(&rctx->vgt, R_008958_VGT_PRIMITIVE_TYPE, prim, 0xFFFFFFFF, NULL);
- r600_pipe_state_add_reg(&rctx->vgt, R_028238_CB_TARGET_MASK, rctx->cb_target_mask & mask, 0xFFFFFFFF, NULL);
- r600_pipe_state_add_reg(&rctx->vgt, R_028400_VGT_MAX_VTX_INDX, draw.info.max_index, 0xFFFFFFFF, NULL);
- r600_pipe_state_add_reg(&rctx->vgt, R_028404_VGT_MIN_VTX_INDX, draw.info.min_index, 0xFFFFFFFF, NULL);
- r600_pipe_state_add_reg(&rctx->vgt, R_028408_VGT_INDX_OFFSET, draw.info.index_bias, 0xFFFFFFFF, NULL);
- r600_pipe_state_add_reg(&rctx->vgt, R_03CFF0_SQ_VTX_BASE_VTX_LOC, 0, 0xFFFFFFFF, NULL);
- r600_pipe_state_add_reg(&rctx->vgt, R_03CFF4_SQ_VTX_START_INST_LOC, draw.info.start_instance, 0xFFFFFFFF, NULL);
+ r600_pipe_state_add_reg(&rctx->vgt, R_008958_VGT_PRIMITIVE_TYPE, prim, 0xFFFFFFFF, NULL, 0);
+ r600_pipe_state_add_reg(&rctx->vgt, R_028238_CB_TARGET_MASK, rctx->cb_target_mask & mask, 0xFFFFFFFF, NULL, 0);
+ r600_pipe_state_add_reg(&rctx->vgt, R_028400_VGT_MAX_VTX_INDX, draw.info.max_index, 0xFFFFFFFF, NULL, 0);
+ r600_pipe_state_add_reg(&rctx->vgt, R_028404_VGT_MIN_VTX_INDX, draw.info.min_index, 0xFFFFFFFF, NULL, 0);
+ r600_pipe_state_add_reg(&rctx->vgt, R_028408_VGT_INDX_OFFSET, draw.info.index_bias, 0xFFFFFFFF, NULL, 0);
+ r600_pipe_state_add_reg(&rctx->vgt, R_03CFF0_SQ_VTX_BASE_VTX_LOC, 0, 0xFFFFFFFF, NULL, 0);
+ r600_pipe_state_add_reg(&rctx->vgt, R_03CFF4_SQ_VTX_START_INST_LOC, draw.info.start_instance, 0xFFFFFFFF, NULL, 0);
r600_pipe_state_add_reg(&rctx->vgt, R_028814_PA_SU_SC_MODE_CNTL,
0,
- S_028814_PROVOKING_VTX_LAST(1), NULL);
+ S_028814_PROVOKING_VTX_LAST(1), NULL, 0);
}
rdraw.indices_bo_offset = draw.index_buffer_offset;
}
- if (rctx->family >= CHIP_CEDAR) {
+ if (rctx->chip_class >= EVERGREEN) {
evergreen_context_draw(&rctx->ctx, &rdraw);
} else {
r600_context_draw(&rctx->ctx, &rdraw);
struct r600_pipe_state *state,
u32 offset, u32 value, u32 mask,
u32 range_id, u32 block_id,
- struct r600_bo *bo)
+ struct r600_bo *bo,
+ enum radeon_bo_usage usage)
{
struct r600_range *range;
struct r600_block *block;
+ if (bo) assert(usage);
+
range = &ctx->range[range_id];
block = range->blocks[block_id];
state->regs[state->nregs].block = block;
state->regs[state->nregs].value = value;
state->regs[state->nregs].mask = mask;
state->regs[state->nregs].bo = bo;
+ state->regs[state->nregs].bo_usage = usage;
state->nregs++;
assert(state->nregs < R600_BLOCK_MAX_REG);
void r600_pipe_state_add_reg_noblock(struct r600_pipe_state *state,
u32 offset, u32 value, u32 mask,
- struct r600_bo *bo)
+ struct r600_bo *bo,
+ enum radeon_bo_usage usage)
{
+ if (bo) assert(usage);
+
state->regs[state->nregs].id = offset;
state->regs[state->nregs].block = NULL;
state->regs[state->nregs].value = value;
state->regs[state->nregs].mask = mask;
state->regs[state->nregs].bo = bo;
+ state->regs[state->nregs].bo_usage = usage;
state->nregs++;
assert(state->nregs < R600_BLOCK_MAX_REG);