v3d,v3dv: fix viewport offset for negative viewport center

If the viewport center is not positive we can't express it
through the fine coordinates, which are unsigned, and we
need to use the coarse coordinates too.

Fixes new crashes in Vulkan CTS 1.3.6.0:
dEQP-VK.draw.renderpass.offscreen_viewport.*negative*

Reviewed-by: Alejandro Piñeiro <apinheiro@igalia.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/23489>
This commit is contained in:
Iago Toral Quiroga
2023-06-06 10:39:37 +02:00
committed by Marge Bot
parent 78dc0bc589
commit c5b6a65f81
2 changed files with 48 additions and 4 deletions

View File

@@ -1103,8 +1103,28 @@ v3dX(cmd_buffer_emit_viewport)(struct v3dv_cmd_buffer *cmd_buffer)
}
cl_emit(&job->bcl, VIEWPORT_OFFSET, vp) {
vp.fine_x = vptranslate[0];
vp.fine_y = vptranslate[1];
float vp_fine_x = vptranslate[0];
float vp_fine_y = vptranslate[1];
int32_t vp_coarse_x = 0;
int32_t vp_coarse_y = 0;
/* The fine coordinates must be unsigned, but coarse can be signed */
if (unlikely(vp_fine_x < 0)) {
int32_t blocks_64 = DIV_ROUND_UP(fabsf(vp_fine_x), 64);
vp_fine_x += 64.0f * blocks_64;
vp_coarse_x -= blocks_64;
}
if (unlikely(vp_fine_y < 0)) {
int32_t blocks_64 = DIV_ROUND_UP(fabsf(vp_fine_y), 64);
vp_fine_y += 64.0f * blocks_64;
vp_coarse_y -= blocks_64;
}
vp.fine_x = vp_fine_x;
vp.fine_y = vp_fine_y;
vp.coarse_x = vp_coarse_x;
vp.coarse_y = vp_coarse_y;
}
cmd_buffer->state.dirty &= ~V3DV_CMD_DIRTY_VIEWPORT;

View File

@@ -593,8 +593,32 @@ v3dX(emit_state)(struct pipe_context *pctx)
vp.viewport_centre_y_coordinate =
v3d->viewport.translate[1];
#else
vp.fine_x = v3d->viewport.translate[0];
vp.fine_y = v3d->viewport.translate[1];
float vp_fine_x = v3d->viewport.translate[0];
float vp_fine_y = v3d->viewport.translate[1];
int32_t vp_coarse_x = 0;
int32_t vp_coarse_y = 0;
/* The fine coordinates must be unsigned, but coarse
* can be signed.
*/
if (unlikely(vp_fine_x < 0)) {
int32_t blocks_64 =
DIV_ROUND_UP(fabsf(vp_fine_x), 64);
vp_fine_x += 64.0f * blocks_64;
vp_coarse_x -= blocks_64;
}
if (unlikely(vp_fine_y < 0)) {
int32_t blocks_64 =
DIV_ROUND_UP(fabsf(vp_fine_y), 64);
vp_fine_y += 64.0f * blocks_64;
vp_coarse_y -= blocks_64;
}
vp.fine_x = vp_fine_x;
vp.fine_y = vp_fine_y;
vp.coarse_x = vp_coarse_x;
vp.coarse_y = vp_coarse_y;
#endif
}
}