r300: program explicit scissor around viewport
Signed-off-by: Pavel Ondračka <pavel.ondracka@gmail.com> Reviewed-by: Marek Olšák <marek.olsak@amd.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/37977>
This commit is contained in:
committed by
Marge Bot
parent
94093488eb
commit
4d36c637dd
@@ -416,6 +416,9 @@ struct pipe_context* r300_create_context(struct pipe_screen* screen,
|
||||
r300_init_render_functions(r300);
|
||||
r300_init_states(&r300->context);
|
||||
|
||||
r300->viewport_scissor.maxx = 16384;
|
||||
r300->viewport_scissor.maxy = 16384;
|
||||
|
||||
r300->uploader = u_upload_create(&r300->context, 128 * 1024,
|
||||
PIPE_BIND_CUSTOM, PIPE_USAGE_STREAM, 0);
|
||||
r300->context.stream_uploader = u_upload_create(&r300->context, 1024 * 1024,
|
||||
|
||||
@@ -545,6 +545,7 @@ struct r300_context {
|
||||
|
||||
struct pipe_stencil_ref stencil_ref;
|
||||
struct pipe_viewport_state viewport;
|
||||
struct pipe_scissor_state viewport_scissor;
|
||||
|
||||
/* Stream locations for SWTCL. */
|
||||
int stream_loc_notcl[16];
|
||||
@@ -563,6 +564,7 @@ struct r300_context {
|
||||
int sprite_coord_enable;
|
||||
/* Whether we are drawing points, to disable sprite coord if not */
|
||||
bool is_point;
|
||||
bool scissor_enabled;
|
||||
/* Whether two-sided color selection is enabled (AKA light_twoside). */
|
||||
bool two_sided_color;
|
||||
bool flatshade;
|
||||
|
||||
@@ -863,20 +863,28 @@ void r300_emit_scissor_state(struct r300_context* r300,
|
||||
unsigned size, void* state)
|
||||
{
|
||||
struct pipe_scissor_state* scissor = (struct pipe_scissor_state*)state;
|
||||
struct pipe_scissor_state final = r300->viewport_scissor;
|
||||
CS_LOCALS(r300);
|
||||
|
||||
if (r300->scissor_enabled && scissor) {
|
||||
final.minx = MAX2(final.minx, scissor->minx);
|
||||
final.miny = MAX2(final.miny, scissor->miny);
|
||||
final.maxx = MIN2(final.maxx, scissor->maxx);
|
||||
final.maxy = MIN2(final.maxy, scissor->maxy);
|
||||
}
|
||||
|
||||
BEGIN_CS(size);
|
||||
OUT_CS_REG_SEQ(R300_SC_CLIPRECT_TL_0, 2);
|
||||
if (r300->screen->caps.is_r500) {
|
||||
OUT_CS((scissor->minx << R300_CLIPRECT_X_SHIFT) |
|
||||
(scissor->miny << R300_CLIPRECT_Y_SHIFT));
|
||||
OUT_CS(((scissor->maxx - 1) << R300_CLIPRECT_X_SHIFT) |
|
||||
((scissor->maxy - 1) << R300_CLIPRECT_Y_SHIFT));
|
||||
OUT_CS((final.minx << R300_CLIPRECT_X_SHIFT) |
|
||||
(final.miny << R300_CLIPRECT_Y_SHIFT));
|
||||
OUT_CS(((final.maxx - 1) << R300_CLIPRECT_X_SHIFT) |
|
||||
((final.maxy - 1) << R300_CLIPRECT_Y_SHIFT));
|
||||
} else {
|
||||
OUT_CS(((scissor->minx + 1440) << R300_CLIPRECT_X_SHIFT) |
|
||||
((scissor->miny + 1440) << R300_CLIPRECT_Y_SHIFT));
|
||||
OUT_CS(((scissor->maxx + 1440-1) << R300_CLIPRECT_X_SHIFT) |
|
||||
((scissor->maxy + 1440-1) << R300_CLIPRECT_Y_SHIFT));
|
||||
OUT_CS(((final.minx + 1440) << R300_CLIPRECT_X_SHIFT) |
|
||||
((final.miny + 1440) << R300_CLIPRECT_Y_SHIFT));
|
||||
OUT_CS(((final.maxx + 1440-1) << R300_CLIPRECT_X_SHIFT) |
|
||||
((final.maxy + 1440-1) << R300_CLIPRECT_Y_SHIFT));
|
||||
}
|
||||
END_CS;
|
||||
}
|
||||
|
||||
@@ -1160,10 +1160,13 @@ void r300_blitter_draw_rectangle(struct blitter_context *blitter,
|
||||
struct r300_context *r300 = r300_context(util_blitter_get_pipe(blitter));
|
||||
unsigned last_sprite_coord_enable = r300->sprite_coord_enable;
|
||||
unsigned last_is_point = r300->is_point;
|
||||
/* We othewise always scissor to the viewport, but blits ignore it. */
|
||||
struct pipe_scissor_state last_vp_scissor = r300->viewport_scissor;
|
||||
r300->viewport_scissor = (struct pipe_scissor_state){0, 0, 16384, 16384};
|
||||
unsigned width = x2 - x1;
|
||||
unsigned height = y2 - y1;
|
||||
unsigned vertex_size = !r300->draw ? 8 : 4;
|
||||
unsigned dwords = 13 + vertex_size +
|
||||
unsigned dwords = 15 + vertex_size +
|
||||
(type == UTIL_BLITTER_ATTRIB_TEXCOORD_XY ? 7 : 0);
|
||||
CS_LOCALS(r300);
|
||||
|
||||
@@ -1202,6 +1205,7 @@ void r300_blitter_draw_rectangle(struct blitter_context *blitter,
|
||||
BEGIN_CS(dwords);
|
||||
/* Set up GA. */
|
||||
OUT_CS_REG(R300_GA_POINT_SIZE, (height * 6) | ((width * 6) << 16));
|
||||
OUT_CS_REG(R300_SC_CLIP_RULE, r300->scissor_enabled ? 0xAAAA : 0xFFFF);
|
||||
|
||||
if (type == UTIL_BLITTER_ATTRIB_TEXCOORD_XY) {
|
||||
/* Set up the GA to generate texcoords. */
|
||||
@@ -1242,9 +1246,11 @@ done:
|
||||
/* Restore the state. */
|
||||
r300_mark_atom_dirty(r300, &r300->rs_state);
|
||||
r300_mark_atom_dirty(r300, &r300->viewport_state);
|
||||
r300_mark_atom_dirty(r300, &r300->scissor_state);
|
||||
|
||||
r300->sprite_coord_enable = last_sprite_coord_enable;
|
||||
r300->is_point = last_is_point;
|
||||
r300->viewport_scissor = last_vp_scissor;
|
||||
}
|
||||
|
||||
void r300_init_render_functions(struct r300_context *r300)
|
||||
|
||||
@@ -41,6 +41,20 @@
|
||||
r300_mark_atom_dirty(r300, &(atom)); \
|
||||
}
|
||||
|
||||
static void
|
||||
r300_get_scissor_from_viewport(const struct pipe_viewport_state *vp,
|
||||
struct pipe_scissor_state *scissor)
|
||||
{
|
||||
/* SC_CLIP_*_A/B fields are 13 bits. */
|
||||
unsigned max_scissor = 16384;
|
||||
float half_w = fabsf(vp->scale[0]);
|
||||
float half_h = fabsf(vp->scale[1]);
|
||||
scissor->minx = CLAMP(-half_w + vp->translate[0], 0, max_scissor);
|
||||
scissor->maxx = CLAMP(half_w + vp->translate[0], 0, max_scissor);
|
||||
scissor->miny = CLAMP(-half_h + vp->translate[1], 0, max_scissor);
|
||||
scissor->maxy = CLAMP(half_h + vp->translate[1], 0, max_scissor);
|
||||
}
|
||||
|
||||
static void r300_delete_vs_state(struct pipe_context* pipe, void* shader);
|
||||
static void r300_delete_fs_state(struct pipe_context* pipe, void* shader);
|
||||
|
||||
@@ -1329,7 +1343,8 @@ static void* r300_create_rs_state(struct pipe_context* pipe,
|
||||
rs->color_control = R300_SHADE_MODEL_SMOOTH;
|
||||
}
|
||||
|
||||
clip_rule = state->scissor ? 0xAAAA : 0xFFFF;
|
||||
/* We always clip, either to the user specified settings or the viewport. */
|
||||
clip_rule = 0xAAAA;
|
||||
|
||||
/* Point sprites coord mode */
|
||||
if (rs->rs.sprite_coord_enable) {
|
||||
@@ -1419,6 +1434,7 @@ static void r300_bind_rs_state(struct pipe_context* pipe, void* state)
|
||||
bool last_msaa_enable = r300->msaa_enable;
|
||||
bool last_flatshade = r300->flatshade;
|
||||
bool last_clip_halfz = r300->clip_halfz;
|
||||
bool last_scissor_enabled = r300->scissor_enabled;
|
||||
|
||||
if (r300->draw && rs) {
|
||||
draw_set_rasterizer_state(r300->draw, &rs->rs_draw, state);
|
||||
@@ -1431,6 +1447,7 @@ static void r300_bind_rs_state(struct pipe_context* pipe, void* state)
|
||||
r300->msaa_enable = rs->rs.multisample;
|
||||
r300->flatshade = rs->rs.flatshade;
|
||||
r300->clip_halfz = rs->rs.clip_halfz;
|
||||
r300->scissor_enabled = rs->rs.scissor;
|
||||
} else {
|
||||
r300->polygon_offset_enabled = false;
|
||||
r300->sprite_coord_enable = 0;
|
||||
@@ -1438,6 +1455,7 @@ static void r300_bind_rs_state(struct pipe_context* pipe, void* state)
|
||||
r300->msaa_enable = false;
|
||||
r300->flatshade = false;
|
||||
r300->clip_halfz = false;
|
||||
r300->scissor_enabled = false;
|
||||
}
|
||||
|
||||
UPDATE_STATE(state, r300->rs_state);
|
||||
@@ -1463,6 +1481,10 @@ static void r300_bind_rs_state(struct pipe_context* pipe, void* state)
|
||||
if (r300->screen->caps.has_tcl && last_clip_halfz != r300->clip_halfz) {
|
||||
r300_mark_atom_dirty(r300, &r300->vs_state);
|
||||
}
|
||||
|
||||
if (last_scissor_enabled != r300->scissor_enabled) {
|
||||
r300_mark_atom_dirty(r300, &r300->scissor_state);
|
||||
}
|
||||
}
|
||||
|
||||
/* Free rasterizer state. */
|
||||
@@ -1769,6 +1791,13 @@ static void r300_set_viewport_states(struct pipe_context* pipe,
|
||||
|
||||
r300->viewport = *state;
|
||||
|
||||
struct pipe_scissor_state vp_scissor;
|
||||
r300_get_scissor_from_viewport(state, &vp_scissor);
|
||||
if (memcmp(&vp_scissor, &r300->viewport_scissor, sizeof(vp_scissor)) != 0) {
|
||||
r300->viewport_scissor = vp_scissor;
|
||||
r300_mark_atom_dirty(r300, &r300->scissor_state);
|
||||
}
|
||||
|
||||
if (r300->draw) {
|
||||
draw_set_viewport_states(r300->draw, start_slot, num_viewports, state);
|
||||
viewport->vte_control = R300_VTX_XY_FMT | R300_VTX_Z_FMT;
|
||||
|
||||
Reference in New Issue
Block a user