diff --git a/src/asahi/lib/agx_ppp.h b/src/asahi/lib/agx_ppp.h index bb35b2df0b1..92ec3aa2a0b 100644 --- a/src/asahi/lib/agx_ppp.h +++ b/src/asahi/lib/agx_ppp.h @@ -36,8 +36,15 @@ agx_ppp_update_size(struct AGX_PPP_HEADER *present) PPP_CASE(fragment_back_face_2, FRAGMENT_FACE_2); PPP_CASE(fragment_back_stencil, FRAGMENT_STENCIL); PPP_CASE(depth_bias_scissor, DEPTH_BIAS_SCISSOR); - PPP_CASE(region_clip, REGION_CLIP); - PPP_CASE(viewport, VIEWPORT); + + if (present->region_clip) + size += present->viewport_count * AGX_REGION_CLIP_LENGTH; + + if (present->viewport) { + size += AGX_VIEWPORT_CONTROL_LENGTH + + (present->viewport_count * AGX_VIEWPORT_LENGTH); + } + PPP_CASE(w_clamp, W_CLAMP); PPP_CASE(output_select, OUTPUT_SELECT); PPP_CASE(varying_counts_32, VARYING_COUNTS); diff --git a/src/asahi/lib/cmdbuf.xml b/src/asahi/lib/cmdbuf.xml index d1734e5bd60..ca01ffa2be3 100644 --- a/src/asahi/lib/cmdbuf.xml +++ b/src/asahi/lib/cmdbuf.xml @@ -430,6 +430,7 @@ + @@ -445,7 +446,7 @@ - + @@ -453,6 +454,11 @@ + + + + diff --git a/src/asahi/lib/decode.c b/src/asahi/lib/decode.c index ffe2295c2da..f336449a111 100644 --- a/src/asahi/lib/decode.c +++ b/src/asahi/lib/decode.c @@ -517,8 +517,38 @@ agxdecode_record(uint64_t va, size_t size, bool verbose, decoder_params *params) PPP_PRINT(map, fragment_back_face_2, FRAGMENT_FACE_2, "Back face 2"); PPP_PRINT(map, fragment_back_stencil, FRAGMENT_STENCIL, "Back stencil"); PPP_PRINT(map, depth_bias_scissor, DEPTH_BIAS_SCISSOR, "Depth bias/scissor"); - PPP_PRINT(map, region_clip, REGION_CLIP, "Region clip"); - PPP_PRINT(map, viewport, VIEWPORT, "Viewport"); + + if (hdr.region_clip) { + if (((map + (AGX_REGION_CLIP_LENGTH * hdr.viewport_count)) > + (base + size))) { + fprintf(agxdecode_dump_stream, "Buffer overrun in PPP update\n"); + return; + } + + for (unsigned i = 0; i < hdr.viewport_count; ++i) { + DUMP_CL(REGION_CLIP, map, "Region clip"); + map += AGX_REGION_CLIP_LENGTH; + fflush(agxdecode_dump_stream); + } + } + + if (hdr.viewport) { + if (((map + AGX_VIEWPORT_CONTROL_LENGTH + + (AGX_VIEWPORT_LENGTH * hdr.viewport_count)) > (base + size))) { + fprintf(agxdecode_dump_stream, "Buffer overrun in PPP update\n"); + return; + } + + DUMP_CL(VIEWPORT_CONTROL, map, "Viewport control"); + map += AGX_VIEWPORT_CONTROL_LENGTH; + + for (unsigned i = 0; i < hdr.viewport_count; ++i) { + DUMP_CL(VIEWPORT, map, "Viewport"); + map += AGX_VIEWPORT_LENGTH; + fflush(agxdecode_dump_stream); + } + } + PPP_PRINT(map, w_clamp, W_CLAMP, "W clamp"); PPP_PRINT(map, output_select, OUTPUT_SELECT, "Output select"); PPP_PRINT(map, varying_counts_32, VARYING_COUNTS, "Varying counts 32"); diff --git a/src/gallium/drivers/asahi/agx_state.c b/src/gallium/drivers/asahi/agx_state.c index d15f9242333..76f36509e40 100644 --- a/src/gallium/drivers/asahi/agx_state.c +++ b/src/gallium/drivers/asahi/agx_state.c @@ -1040,6 +1040,7 @@ agx_upload_viewport_scissor(struct agx_pool *pool, struct agx_batch *batch, .depth_bias_scissor = true, .region_clip = true, .viewport = true, + .viewport_count = 1, }); agx_ppp_push(&ppp, DEPTH_BIAS_SCISSOR, cfg) { @@ -1058,6 +1059,9 @@ agx_upload_viewport_scissor(struct agx_pool *pool, struct agx_batch *batch, cfg.max_y = DIV_ROUND_UP(MAX2(maxy, 1), 32); } + agx_ppp_push(&ppp, VIEWPORT_CONTROL, cfg) + ; + agx_ppp_push(&ppp, VIEWPORT, cfg) { cfg.translate_x = vp->translate[0]; cfg.translate_y = vp->translate[1]; @@ -2951,6 +2955,7 @@ agx_batch_init_state(struct agx_batch *batch) .occlusion_query_2 = true, .output_unknown = true, .varying_word_2 = true, + .viewport_count = 1, /* irrelevant */ }); /* clang-format off */ @@ -3139,6 +3144,7 @@ agx_encode_state(struct agx_batch *batch, uint8_t *out, bool is_lines, IS_DIRTY(FS) || varyings_dirty || IS_DIRTY(SAMPLE_MASK), .occlusion_query = IS_DIRTY(QUERY), .output_size = IS_DIRTY(VS_PROG), + .viewport_count = 1, /* irrelevant */ }; struct agx_ppp_update ppp = agx_new_ppp_update(pool, dirty);