{R_02884C_SQ_PGM_EXPORTS_PS, 0, 0},
{R_02885C_SQ_PGM_START_VS, REG_FLAG_NEED_BO, 0},
{R_028860_SQ_PGM_RESOURCES_VS, 0, 0},
- {R_0288A4_SQ_PGM_START_FS, REG_FLAG_NEED_BO, 0},
{R_0288EC_SQ_LDS_ALLOC_PS, 0, 0},
{R_028A00_PA_SU_POINT_SIZE, 0, 0},
{R_028A04_PA_SU_POINT_MINMAX, 0, 0},
{R_02884C_SQ_PGM_EXPORTS_PS, 0, 0},
{R_02885C_SQ_PGM_START_VS, REG_FLAG_NEED_BO, 0},
{R_028860_SQ_PGM_RESOURCES_VS, 0, 0},
- {R_0288A4_SQ_PGM_START_FS, REG_FLAG_NEED_BO, 0},
{R_028900_SQ_ESGS_RING_ITEMSIZE, 0, 0},
{R_028904_SQ_GSVS_RING_ITEMSIZE, 0, 0},
{R_028908_SQ_ESTMP_RING_ITEMSIZE, 0, 0},
r600_write_value(cs, mask | (mask << 16)); /* X0Y1_X1Y1 */
}
+static void evergreen_emit_vertex_fetch_shader(struct r600_context *rctx, struct r600_atom *a)
+{
+ struct radeon_winsys_cs *cs = rctx->cs;
+ struct r600_cso_state *state = (struct r600_cso_state*)a;
+ struct r600_resource *shader = (struct r600_resource*)state->cso;
+
+ r600_write_context_reg(cs, R_0288A4_SQ_PGM_START_FS,
+ r600_resource_va(rctx->context.screen, &shader->b.b) >> 8);
+ r600_write_value(cs, PKT3(PKT3_NOP, 0, 0));
+ r600_write_value(cs, r600_context_bo_reloc(rctx, shader, RADEON_USAGE_READ));
+}
+
void evergreen_init_state_functions(struct r600_context *rctx)
{
unsigned id = 4;
r600_init_atom(rctx, &rctx->db_misc_state.atom, id++, evergreen_emit_db_misc_state, 7);
r600_init_atom(rctx, &rctx->stencil_ref.atom, id++, r600_emit_stencil_ref, 4);
r600_init_atom(rctx, &rctx->viewport.atom, id++, r600_emit_viewport_state, 8);
+ r600_init_atom(rctx, &rctx->vertex_fetch_shader.atom, id++, evergreen_emit_vertex_fetch_shader, 5);
rctx->context.create_blend_state = evergreen_create_blend_state;
rctx->context.create_depth_stencil_alpha_state = evergreen_create_dsa_state;
S_02881C_USE_VTX_POINT_SIZE(rshader->vs_out_point_size);
}
-void evergreen_fetch_shader(struct pipe_context *ctx,
- struct r600_vertex_element *ve)
-{
- struct r600_context *rctx = (struct r600_context *)ctx;
- struct r600_pipe_state *rstate = &ve->rstate;
- rstate->id = R600_PIPE_STATE_FETCH_SHADER;
- rstate->nregs = 0;
- r600_pipe_state_add_reg_bo(rstate, R_0288A4_SQ_PGM_START_FS,
- r600_resource_va(ctx->screen, (void *)ve->fetch_shader) >> 8,
- ve->fetch_shader, RADEON_USAGE_READ);
-}
-
void *evergreen_create_resolve_blend(struct r600_context *rctx)
{
struct pipe_blend_state blend;
R600_ERR("unsupported vertex format %s\n", util_format_name(pformat));
}
-int r600_vertex_elements_build_fetch_shader(struct r600_context *rctx, struct r600_vertex_element *ve)
+void *r600_create_vertex_fetch_shader(struct pipe_context *ctx,
+ unsigned count,
+ const struct pipe_vertex_element *elements)
{
+ struct r600_context *rctx = (struct r600_context *)ctx;
static int dump_shaders = -1;
-
struct r600_bytecode bc;
struct r600_bytecode_vtx vtx;
- struct pipe_vertex_element *elements = ve->elements;
const struct util_format_description *desc;
unsigned fetch_resource_start = rctx->chip_class >= EVERGREEN ? 0 : 160;
unsigned format, num_format, format_comp, endian;
uint32_t *bytecode;
- int i, j, r;
+ int i, j, r, fs_size;
+ struct r600_resource *fetch_shader;
+
+ assert(count < 32);
memset(&bc, 0, sizeof(bc));
r600_bytecode_init(&bc, rctx->chip_class, rctx->family);
- for (i = 0; i < ve->count; i++) {
+ for (i = 0; i < count; i++) {
if (elements[i].instance_divisor > 1) {
if (rctx->chip_class == CAYMAN) {
for (j = 0; j < 4; j++) {
alu.last = j == 3;
if ((r = r600_bytecode_add_alu(&bc, &alu))) {
r600_bytecode_clear(&bc);
- return r;
+ return NULL;
}
}
} else {
alu.last = 1;
if ((r = r600_bytecode_add_alu(&bc, &alu))) {
r600_bytecode_clear(&bc);
- return r;
+ return NULL;
}
}
}
}
- for (i = 0; i < ve->count; i++) {
- r600_vertex_data_type(ve->elements[i].src_format,
+ for (i = 0; i < count; i++) {
+ r600_vertex_data_type(elements[i].src_format,
&format, &num_format, &format_comp, &endian);
- desc = util_format_description(ve->elements[i].src_format);
+ desc = util_format_description(elements[i].src_format);
if (desc == NULL) {
r600_bytecode_clear(&bc);
- R600_ERR("unknown format %d\n", ve->elements[i].src_format);
- return -EINVAL;
+ R600_ERR("unknown format %d\n", elements[i].src_format);
+ return NULL;
}
if (elements[i].src_offset > 65535) {
r600_bytecode_clear(&bc);
R600_ERR("too big src_offset: %u\n", elements[i].src_offset);
- return -EINVAL;
+ return NULL;
}
memset(&vtx, 0, sizeof(vtx));
if ((r = r600_bytecode_add_vtx(&bc, &vtx))) {
r600_bytecode_clear(&bc);
- return r;
+ return NULL;
}
}
if ((r = r600_bytecode_build(&bc))) {
r600_bytecode_clear(&bc);
- return r;
+ return NULL;
}
if (dump_shaders == -1)
fprintf(stderr, "______________________________________________________________\n");
}
- ve->fs_size = bc.ndw*4;
+ fs_size = bc.ndw*4;
- ve->fetch_shader = (struct r600_resource*)
+ fetch_shader = (struct r600_resource*)
pipe_buffer_create(rctx->context.screen,
PIPE_BIND_CUSTOM,
- PIPE_USAGE_IMMUTABLE, ve->fs_size);
- if (ve->fetch_shader == NULL) {
+ PIPE_USAGE_IMMUTABLE, fs_size);
+ if (fetch_shader == NULL) {
r600_bytecode_clear(&bc);
- return -ENOMEM;
+ return NULL;
}
- bytecode = rctx->ws->buffer_map(ve->fetch_shader->cs_buf, rctx->cs, PIPE_TRANSFER_WRITE);
+ bytecode = rctx->ws->buffer_map(fetch_shader->cs_buf, rctx->cs, PIPE_TRANSFER_WRITE);
if (bytecode == NULL) {
r600_bytecode_clear(&bc);
- pipe_resource_reference((struct pipe_resource**)&ve->fetch_shader, NULL);
- return -ENOMEM;
+ pipe_resource_reference((struct pipe_resource**)&fetch_shader, NULL);
+ return NULL;
}
if (R600_BIG_ENDIAN) {
- for (i = 0; i < ve->fs_size / 4; ++i) {
+ for (i = 0; i < fs_size / 4; ++i) {
bytecode[i] = bswap_32(bc.bytecode[i]);
}
} else {
- memcpy(bytecode, bc.bytecode, ve->fs_size);
+ memcpy(bytecode, bc.bytecode, fs_size);
}
- rctx->ws->buffer_unmap(ve->fetch_shader->cs_buf);
+ rctx->ws->buffer_unmap(fetch_shader->cs_buf);
r600_bytecode_clear(&bc);
- if (rctx->chip_class >= EVERGREEN)
- evergreen_fetch_shader(&rctx->context, ve);
- else
- r600_fetch_shader(&rctx->context, ve);
-
- return 0;
+ return fetch_shader;
}
void r600_bytecode_alu_read(struct r600_bytecode_alu *alu, uint32_t word0, uint32_t word1)
#include "r600.h"
-struct r600_vertex_element;
struct r600_context;
struct r600_bytecode_alu_src {
int cm_bytecode_add_cf_end(struct r600_bytecode *bc);
-int r600_vertex_elements_build_fetch_shader(struct r600_context *rctx, struct r600_vertex_element *ve);
+void *r600_create_vertex_fetch_shader(struct pipe_context *ctx,
+ unsigned count,
+ const struct pipe_vertex_element *elements);
/* r700_asm.c */
void r700_bytecode_cf_vtx_build(uint32_t *bytecode, const struct r600_bytecode_cf *cf);
util_blitter_save_vertex_buffers(rctx->blitter,
util_last_bit(rctx->vertex_buffer_state.enabled_mask),
rctx->vertex_buffer_state.vb);
- util_blitter_save_vertex_elements(rctx->blitter, rctx->vertex_elements);
+ util_blitter_save_vertex_elements(rctx->blitter, rctx->vertex_fetch_shader.cso);
util_blitter_save_vertex_shader(rctx->blitter, rctx->vs_shader);
util_blitter_save_so_targets(rctx->blitter, rctx->num_so_targets,
(struct pipe_stream_output_target**)rctx->so_targets);
{GROUP_FORCE_NEW_BLOCK, 0, 0},
{R_028868_SQ_PGM_RESOURCES_VS, 0, 0},
{GROUP_FORCE_NEW_BLOCK, 0, 0},
- {R_028894_SQ_PGM_START_FS, REG_FLAG_NEED_BO, 0},
- {GROUP_FORCE_NEW_BLOCK, 0, 0},
{R_0288A4_SQ_PGM_RESOURCES_FS, 0, 0},
{R_0288DC_SQ_PGM_CF_OFFSET_FS, 0, 0},
{R_028644_SPI_PS_INPUT_CNTL_0, 0, 0},
ctx->vgt2_state.atom.dirty = true;
ctx->sample_mask.atom.dirty = true;
ctx->stencil_ref.atom.dirty = true;
+ ctx->vertex_fetch_shader.atom.dirty = true;
ctx->viewport.atom.dirty = true;
if (ctx->blend_state.cso)
#include "r600_resource.h"
#include "evergreen_compute.h"
-#define R600_NUM_ATOMS 30
+#define R600_NUM_ATOMS 31
#define R600_MAX_CONST_BUFFERS 2
#define R600_MAX_CONST_BUFFER_SIZE 4096
R600_PIPE_STATE_RASTERIZER,
R600_PIPE_STATE_DSA,
R600_PIPE_STATE_POLYGON_OFFSET,
- R600_PIPE_STATE_FETCH_SHADER,
R600_PIPE_NSTATES
};
unsigned sx_alpha_test_control;
};
-struct r600_vertex_element
-{
- unsigned count;
- struct pipe_vertex_element elements[PIPE_MAX_ATTRIBS];
- struct r600_resource *fetch_shader;
- unsigned fs_size;
- struct r600_pipe_state rstate;
-};
-
struct r600_pipe_shader;
struct r600_pipe_shader_selector {
struct r600_shader shader;
struct r600_pipe_state rstate;
struct r600_resource *bo;
- struct r600_resource *bo_fetch;
- struct r600_vertex_element vertex_elements;
unsigned sprite_coord_enable;
unsigned flatshade;
unsigned pa_cl_vs_out_cntl;
struct r600_screen *screen;
struct radeon_winsys *ws;
struct r600_pipe_state *states[R600_PIPE_NSTATES];
- struct r600_vertex_element *vertex_elements;
unsigned compute_cb_target_mask;
unsigned db_shader_control;
unsigned pa_sc_line_stipple;
struct r600_clip_state clip_state;
struct r600_db_misc_state db_misc_state;
struct r600_framebuffer framebuffer;
+ struct r600_sample_mask sample_mask;
struct r600_seamless_cube_map seamless_cube_map;
struct r600_stencil_ref_state stencil_ref;
struct r600_vgt_state vgt_state;
struct r600_vgt2_state vgt2_state;
- struct r600_sample_mask sample_mask;
struct r600_viewport_state viewport;
/* Shaders and shader resources. */
+ struct r600_cso_state vertex_fetch_shader;
struct r600_cs_shader_state cs_shader_state;
struct r600_constbuf_state constbuf_state[PIPE_SHADER_TYPES];
struct r600_textures_info samplers[PIPE_SHADER_TYPES];
void evergreen_init_atom_start_cs(struct r600_context *rctx);
void evergreen_pipe_shader_ps(struct pipe_context *ctx, struct r600_pipe_shader *shader);
void evergreen_pipe_shader_vs(struct pipe_context *ctx, struct r600_pipe_shader *shader);
-void evergreen_fetch_shader(struct pipe_context *ctx, struct r600_vertex_element *ve);
void *evergreen_create_db_flush_dsa(struct r600_context *rctx);
void *evergreen_create_resolve_blend(struct r600_context *rctx);
void *evergreen_create_decompress_blend(struct r600_context *rctx);
void r600_init_atom_start_cs(struct r600_context *rctx);
void r600_pipe_shader_ps(struct pipe_context *ctx, struct r600_pipe_shader *shader);
void r600_pipe_shader_vs(struct pipe_context *ctx, struct r600_pipe_shader *shader);
-void r600_fetch_shader(struct pipe_context *ctx, struct r600_vertex_element *ve);
void *r600_create_db_flush_dsa(struct r600_context *rctx);
void *r600_create_resolve_blend(struct r600_context *rctx);
void *r700_create_resolve_blend(struct r600_context *rctx);
mask | (mask << 8) | (mask << 16) | (mask << 24));
}
+static void r600_emit_vertex_fetch_shader(struct r600_context *rctx, struct r600_atom *a)
+{
+ struct radeon_winsys_cs *cs = rctx->cs;
+ struct r600_cso_state *state = (struct r600_cso_state*)a;
+ struct r600_resource *shader = (struct r600_resource*)state->cso;
+
+ r600_write_context_reg(cs, R_028894_SQ_PGM_START_FS, 0);
+ r600_write_value(cs, PKT3(PKT3_NOP, 0, 0));
+ r600_write_value(cs, r600_context_bo_reloc(rctx, shader, RADEON_USAGE_READ));
+}
+
void r600_init_state_functions(struct r600_context *rctx)
{
unsigned id = 4;
r600_init_atom(rctx, &rctx->db_misc_state.atom, id++, r600_emit_db_misc_state, 4);
r600_init_atom(rctx, &rctx->stencil_ref.atom, id++, r600_emit_stencil_ref, 4);
r600_init_atom(rctx, &rctx->viewport.atom, id++, r600_emit_viewport_state, 8);
+ r600_init_atom(rctx, &rctx->vertex_fetch_shader.atom, id++, r600_emit_vertex_fetch_shader, 5);
rctx->context.create_blend_state = r600_create_blend_state;
rctx->context.create_depth_stencil_alpha_state = r600_create_dsa_state;
S_02881C_USE_VTX_POINT_SIZE(rshader->vs_out_point_size);
}
-void r600_fetch_shader(struct pipe_context *ctx,
- struct r600_vertex_element *ve)
-{
- struct r600_pipe_state *rstate;
- struct r600_context *rctx = (struct r600_context *)ctx;
-
- rstate = &ve->rstate;
- rstate->id = R600_PIPE_STATE_FETCH_SHADER;
- rstate->nregs = 0;
- r600_pipe_state_add_reg_bo(rstate, R_028894_SQ_PGM_START_FS,
- 0,
- ve->fetch_shader, RADEON_USAGE_READ);
-}
-
void *r600_create_resolve_blend(struct r600_context *rctx)
{
struct pipe_blend_state blend;
static void r600_bind_vertex_elements(struct pipe_context *ctx, void *state)
{
struct r600_context *rctx = (struct r600_context *)ctx;
- struct r600_vertex_element *v = (struct r600_vertex_element*)state;
- rctx->vertex_elements = v;
- if (v) {
- rctx->states[v->rstate.id] = &v->rstate;
- r600_context_pipe_state_set(rctx, &v->rstate);
- }
+ r600_set_cso_state(&rctx->vertex_fetch_shader, state);
}
static void r600_delete_vertex_elements(struct pipe_context *ctx, void *state)
{
- struct r600_context *rctx = (struct r600_context *)ctx;
- struct r600_vertex_element *v = (struct r600_vertex_element*)state;
-
- if (rctx->states[v->rstate.id] == &v->rstate) {
- rctx->states[v->rstate.id] = NULL;
- }
- if (rctx->vertex_elements == state)
- rctx->vertex_elements = NULL;
-
- pipe_resource_reference((struct pipe_resource**)&v->fetch_shader, NULL);
- FREE(state);
+ pipe_resource_reference((struct pipe_resource**)&state, NULL);
}
static void r600_set_index_buffer(struct pipe_context *ctx,
r600_write_value(cs, fui(state->translate[2])); /* R_028450_PA_CL_VPORT_ZOFFSET_0 */
}
-static void *r600_create_vertex_elements(struct pipe_context *ctx, unsigned count,
- const struct pipe_vertex_element *elements)
-{
- struct r600_context *rctx = (struct r600_context *)ctx;
- struct r600_vertex_element *v = CALLOC_STRUCT(r600_vertex_element);
-
- assert(count < 32);
- if (!v)
- return NULL;
-
- v->count = count;
- memcpy(v->elements, elements, sizeof(struct pipe_vertex_element) * count);
-
- if (r600_vertex_elements_build_fetch_shader(rctx, v)) {
- FREE(v);
- return NULL;
- }
-
- return v;
-}
-
/* Compute the key for the hw shader variant */
static INLINE struct r600_shader_key r600_shader_selector_key(struct pipe_context * ctx,
struct r600_pipe_shader_selector * sel)
{
rctx->context.create_fs_state = r600_create_ps_state;
rctx->context.create_vs_state = r600_create_vs_state;
- rctx->context.create_vertex_elements_state = r600_create_vertex_elements;
+ rctx->context.create_vertex_elements_state = r600_create_vertex_fetch_shader;
rctx->context.bind_blend_state = r600_bind_blend_state;
rctx->context.bind_depth_stencil_alpha_state = r600_bind_dsa_state;
rctx->context.bind_fragment_sampler_states = r600_bind_ps_sampler_states;