{R_028418_CB_BLEND_GREEN, 0, 0},
{R_02841C_CB_BLEND_BLUE, 0, 0},
{R_028420_CB_BLEND_ALPHA, 0, 0},
- {R_028430_DB_STENCILREFMASK, 0, 0},
- {R_028434_DB_STENCILREFMASK_BF, 0, 0},
{R_02843C_PA_CL_VPORT_XSCALE_0, 0, 0},
{R_028440_PA_CL_VPORT_XOFFSET_0, 0, 0},
{R_028444_PA_CL_VPORT_YSCALE_0, 0, 0},
{R_028418_CB_BLEND_GREEN, 0, 0},
{R_02841C_CB_BLEND_BLUE, 0, 0},
{R_028420_CB_BLEND_ALPHA, 0, 0},
- {R_028430_DB_STENCILREFMASK, 0, 0},
- {R_028434_DB_STENCILREFMASK_BF, 0, 0},
{R_02843C_PA_CL_VPORT_XSCALE_0, 0, 0},
{R_028440_PA_CL_VPORT_XOFFSET_0, 0, 0},
{R_028444_PA_CL_VPORT_YSCALE_0, 0, 0},
r600_init_atom(rctx, &rctx->cb_misc_state.atom, id++, evergreen_emit_cb_misc_state, 0);
r600_init_atom(rctx, &rctx->alphatest_state.atom, id++, r600_emit_alphatest_state, 6);
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);
rctx->context.create_blend_state = evergreen_create_blend_state;
rctx->context.create_depth_stencil_alpha_state = evergreen_create_dsa_state;
util_blitter_save_fragment_shader(rctx->blitter, rctx->ps_shader);
util_blitter_save_blend(rctx->blitter, rctx->states[R600_PIPE_STATE_BLEND]);
util_blitter_save_depth_stencil_alpha(rctx->blitter, rctx->states[R600_PIPE_STATE_DSA]);
- if (rctx->states[R600_PIPE_STATE_STENCIL_REF]) {
- util_blitter_save_stencil_ref(rctx->blitter, &rctx->stencil_ref);
- }
+ util_blitter_save_stencil_ref(rctx->blitter, &rctx->stencil_ref.pipe_state);
util_blitter_save_sample_mask(rctx->blitter, rctx->sample_mask.sample_mask);
}
{R_028424_CB_FOG_RED, 0, 0},
{R_028428_CB_FOG_GREEN, 0, 0},
{R_02842C_CB_FOG_BLUE, 0, 0},
- {R_028430_DB_STENCILREFMASK, 0, 0},
- {R_028434_DB_STENCILREFMASK_BF, 0, 0},
{R_028780_CB_BLEND0_CONTROL, REG_FLAG_NOT_R600, 0},
{R_028784_CB_BLEND1_CONTROL, REG_FLAG_NOT_R600, 0},
{R_028788_CB_BLEND2_CONTROL, REG_FLAG_NOT_R600, 0},
unsigned i;
/* The number of dwords all the dirty states would take. */
- for (i = 0; i < R600_MAX_ATOM; i++) {
+ for (i = 0; i < R600_NUM_ATOMS; i++) {
if (ctx->atoms[i] && ctx->atoms[i]->dirty) {
num_dw += ctx->atoms[i]->num_dw;
}
r600_atom_dirty(ctx, &ctx->alphatest_state.atom);
r600_atom_dirty(ctx, &ctx->cb_misc_state.atom);
r600_atom_dirty(ctx, &ctx->db_misc_state.atom);
+ r600_atom_dirty(ctx, &ctx->sample_mask.atom);
+ r600_atom_dirty(ctx, &ctx->stencil_ref.atom);
if (ctx->chip_class <= R700) {
r600_atom_dirty(ctx, &ctx->seamless_cube_map.atom);
}
- r600_atom_dirty(ctx, &ctx->sample_mask.atom);
ctx->vertex_buffer_state.dirty_mask = ctx->vertex_buffer_state.enabled_mask;
r600_vertex_buffers_dirty(ctx);
#include "r600_resource.h"
#include "evergreen_compute.h"
-#define R600_MAX_ATOM 20
+#define R600_NUM_ATOMS 21
#define R600_MAX_CONST_BUFFERS 2
#define R600_MAX_CONST_BUFFER_SIZE 4096
uint16_t sample_mask; /* there are only 8 bits on EG, 16 bits on Cayman */
};
+struct r600_stencil_ref
+{
+ ubyte ref_value[2];
+ ubyte valuemask[2];
+ ubyte writemask[2];
+};
+
+struct r600_stencil_ref_state {
+ struct r600_atom atom;
+ struct r600_stencil_ref state;
+ struct pipe_stencil_ref pipe_state;
+};
+
enum r600_pipe_state_id {
R600_PIPE_STATE_BLEND = 0,
R600_PIPE_STATE_BLEND_COLOR,
R600_PIPE_STATE_VGT,
R600_PIPE_STATE_FRAMEBUFFER,
R600_PIPE_STATE_DSA,
- R600_PIPE_STATE_STENCIL_REF,
R600_PIPE_STATE_POLYGON_OFFSET,
R600_PIPE_STATE_FETCH_SHADER,
R600_PIPE_NSTATES
#define R600_CONSTANT_ARRAY_SIZE 256
#define R600_RESOURCE_ARRAY_SIZE 160
-struct r600_stencil_ref
-{
- ubyte ref_value[2];
- ubyte valuemask[2];
- ubyte writemask[2];
-};
-
struct r600_constbuf_state
{
struct r600_atom atom;
unsigned pa_sc_line_stipple;
unsigned pa_cl_clip_cntl;
/* for saving when using blitter */
- struct pipe_stencil_ref stencil_ref;
struct pipe_viewport_state viewport;
struct pipe_clip_state clip;
struct r600_pipe_shader_selector *ps_shader;
unsigned default_ps_gprs, default_vs_gprs;
+ /******************************/
/* States based on r600_atom. */
+ struct r600_atom *atoms[R600_NUM_ATOMS];
+ /* States for CS initialization. */
struct r600_command_buffer start_cs_cmd; /* invariant state mostly */
- struct r600_atom *atoms[R600_MAX_ATOM];
/** Compute specific registers initializations. The start_cs_cmd atom
* must be emitted before start_compute_cs_cmd. */
- struct r600_command_buffer start_compute_cs_cmd;
+ struct r600_command_buffer start_compute_cs_cmd;
+ /* Register states. */
struct r600_alphatest_state alphatest_state;
struct r600_cb_misc_state cb_misc_state;
struct r600_db_misc_state db_misc_state;
+ struct r600_seamless_cube_map seamless_cube_map;
+ struct r600_stencil_ref_state stencil_ref;
+ struct r600_sample_mask sample_mask;
+ /* Shaders and shader resources. */
+ 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];
/** Vertex buffers for fetch shaders */
struct r600_vertexbuf_state vertex_buffer_state;
/** Vertex buffers for compute shaders */
struct r600_vertexbuf_state cs_vertex_buffer_state;
- struct r600_constbuf_state constbuf_state[PIPE_SHADER_TYPES];
- struct r600_textures_info samplers[PIPE_SHADER_TYPES];
- struct r600_seamless_cube_map seamless_cube_map;
- struct r600_cs_shader_state cs_shader_state;
- struct r600_sample_mask sample_mask;
+ /******************************/
/* current external blend state (from state tracker) */
struct r600_pipe_blend *blend;
/* r600_state_common.c */
void r600_init_common_state_functions(struct r600_context *rctx);
void r600_emit_alphatest_state(struct r600_context *rctx, struct r600_atom *atom);
+void r600_emit_stencil_ref(struct r600_context *rctx, struct r600_atom *atom);
void r600_init_atom(struct r600_context *rctx, struct r600_atom *atom, unsigned id,
void (*emit)(struct r600_context *ctx, struct r600_atom *state),
unsigned num_dw);
r600_init_atom(rctx, &rctx->cb_misc_state.atom, id++, r600_emit_cb_misc_state, 0);
r600_init_atom(rctx, &rctx->alphatest_state.atom, id++, r600_emit_alphatest_state, 6);
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);
rctx->context.create_blend_state = r600_create_blend_state;
rctx->context.create_depth_stencil_alpha_state = r600_create_dsa_state;
void (*emit)(struct r600_context *ctx, struct r600_atom *state),
unsigned num_dw)
{
- assert(id < R600_MAX_ATOM);
+ assert(id < R600_NUM_ATOMS);
assert(rctx->atoms[id] == NULL);
rctx->atoms[id] = atom;
atom->id = id;
const struct r600_stencil_ref *state)
{
struct r600_context *rctx = (struct r600_context *)ctx;
- struct r600_pipe_state *rstate = CALLOC_STRUCT(r600_pipe_state);
- if (rstate == NULL)
- return;
+ rctx->stencil_ref.state = *state;
+ r600_atom_dirty(rctx, &rctx->stencil_ref.atom);
+}
- rstate->id = R600_PIPE_STATE_STENCIL_REF;
- r600_pipe_state_add_reg(rstate,
- R_028430_DB_STENCILREFMASK,
- S_028430_STENCILREF(state->ref_value[0]) |
- S_028430_STENCILMASK(state->valuemask[0]) |
- S_028430_STENCILWRITEMASK(state->writemask[0]));
- r600_pipe_state_add_reg(rstate,
- R_028434_DB_STENCILREFMASK_BF,
- S_028434_STENCILREF_BF(state->ref_value[1]) |
- S_028434_STENCILMASK_BF(state->valuemask[1]) |
- S_028434_STENCILWRITEMASK_BF(state->writemask[1]));
-
- free(rctx->states[R600_PIPE_STATE_STENCIL_REF]);
- rctx->states[R600_PIPE_STATE_STENCIL_REF] = rstate;
- r600_context_pipe_state_set(rctx, rstate);
+void r600_emit_stencil_ref(struct r600_context *rctx, struct r600_atom *atom)
+{
+ struct radeon_winsys_cs *cs = rctx->cs;
+ struct r600_stencil_ref_state *a = (struct r600_stencil_ref_state*)atom;
+
+ r600_write_context_reg_seq(cs, R_028430_DB_STENCILREFMASK, 2);
+ r600_write_value(cs, /* R_028430_DB_STENCILREFMASK */
+ S_028430_STENCILREF(a->state.ref_value[0]) |
+ S_028430_STENCILMASK(a->state.valuemask[0]) |
+ S_028430_STENCILWRITEMASK(a->state.writemask[0]));
+ r600_write_value(cs, /* R_028434_DB_STENCILREFMASK_BF */
+ S_028434_STENCILREF_BF(a->state.ref_value[1]) |
+ S_028434_STENCILMASK_BF(a->state.valuemask[1]) |
+ S_028434_STENCILWRITEMASK_BF(a->state.writemask[1]));
}
static void r600_set_pipe_stencil_ref(struct pipe_context *ctx,
struct r600_pipe_dsa *dsa = (struct r600_pipe_dsa*)rctx->states[R600_PIPE_STATE_DSA];
struct r600_stencil_ref ref;
- rctx->stencil_ref = *state;
+ rctx->stencil_ref.pipe_state = *state;
if (!dsa)
return;
rctx->states[rstate->id] = rstate;
r600_context_pipe_state_set(rctx, rstate);
- ref.ref_value[0] = rctx->stencil_ref.ref_value[0];
- ref.ref_value[1] = rctx->stencil_ref.ref_value[1];
+ ref.ref_value[0] = rctx->stencil_ref.pipe_state.ref_value[0];
+ ref.ref_value[1] = rctx->stencil_ref.pipe_state.ref_value[1];
ref.valuemask[0] = dsa->valuemask[0];
ref.valuemask[1] = dsa->valuemask[1];
ref.writemask[0] = dsa->writemask[0];
r600_need_cs_space(rctx, 0, TRUE);
r600_flush_emit(rctx);
- for (i = 0; i < R600_MAX_ATOM; i++) {
+ for (i = 0; i < R600_NUM_ATOMS; i++) {
if (rctx->atoms[i] == NULL || !rctx->atoms[i]->dirty) {
continue;
}