Mesa (master): radv: Rework guard band calculation.

Bas Nieuwenhuizen bnieuwenhuizen at kemper.freedesktop.org
Mon Apr 3 21:05:43 UTC 2017


Module: Mesa
Branch: master
Commit: a4c4efad89eceb26cf82f4643ce6a4eb656072a6
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=a4c4efad89eceb26cf82f4643ce6a4eb656072a6

Author: Bas Nieuwenhuizen <bas at basnieuwenhuizen.nl>
Date:   Sun Apr  2 12:32:39 2017 +0200

radv: Rework guard band calculation.

We want the guardband_x/y to be the largerst scalars such that each
viewport scaled by that amount is still a subrange of [-32767, 32767].

The old code has a couple of issues:
1) It used scissor instead of viewport_scissor, potentially taking into
   account a viewport that is too small and therefore selecting a scale
   that is too large.
2) Merging the viewports isn't ideal, as for example viewports with
   boundaries [0,1] and [1000, 1001] would allow a guardband scale of ~30k,
   while their union [0, 1001] only allows a scale of ~32.

The new code just determines the guardband per viewport and takes the minimum.

Signed-off-by: Bas Nieuwenhuizen <basni at google.com>
Acked-by: Dave Airlie <airlied at redhat.com>

---

 src/amd/vulkan/si_cmd_buffer.c | 55 ++++++++++++------------------------------
 1 file changed, 15 insertions(+), 40 deletions(-)

diff --git a/src/amd/vulkan/si_cmd_buffer.c b/src/amd/vulkan/si_cmd_buffer.c
index e176abe386..711dbde0ac 100644
--- a/src/amd/vulkan/si_cmd_buffer.c
+++ b/src/amd/vulkan/si_cmd_buffer.c
@@ -504,22 +504,6 @@ get_viewport_xform(const VkViewport *viewport,
 	translate[2] = n;
 }
 
-static void
-get_viewport_xform_scissor(const VkRect2D *scissor,
-                           float scale[2], float translate[2])
-{
-	float x = scissor->offset.x;
-	float y = scissor->offset.y;
-	float half_width = 0.5f * scissor->extent.width;
-	float half_height = 0.5f * scissor->extent.height;
-
-	scale[0] = half_width;
-	translate[0] = half_width + x;
-	scale[1] = half_height;
-	translate[1] = half_height + y;
-
-}
-
 void
 si_write_viewport(struct radeon_winsys_cs *cs, int first_vp,
                   int count, const VkViewport *viewports)
@@ -579,26 +563,13 @@ static VkRect2D si_intersect_scissor(const VkRect2D *a, const VkRect2D *b) {
 	return ret;
 }
 
-static VkRect2D si_union_scissor(const VkRect2D *a, const VkRect2D *b) {
-	VkRect2D ret;
-	ret.offset.x = MIN2(a->offset.x, b->offset.x);
-	ret.offset.y = MIN2(a->offset.y, b->offset.y);
-	ret.extent.width = MAX2(a->offset.x + a->extent.width,
-	                        b->offset.x + b->extent.width) - ret.offset.x;
-	ret.extent.height = MAX2(a->offset.y + a->extent.height,
-	                         b->offset.y + b->extent.height) - ret.offset.y;
-	return ret;
-}
-
-
 void
 si_write_scissors(struct radeon_winsys_cs *cs, int first,
                   int count, const VkRect2D *scissors,
                   const VkViewport *viewports, bool can_use_guardband)
 {
 	int i;
-	VkRect2D merged;
-	float scale[2], translate[2], guardband_x = 1.0, guardband_y = 1.0;
+	float scale[3], translate[3], guardband_x = INFINITY, guardband_y = INFINITY;
 	const float max_range = 32767.0f;
 	assert(count);
 
@@ -607,10 +578,17 @@ si_write_scissors(struct radeon_winsys_cs *cs, int first,
 		VkRect2D viewport_scissor = si_scissor_from_viewport(viewports + i);
 		VkRect2D scissor = si_intersect_scissor(&scissors[i], &viewport_scissor);
 
-		if (i)
-			merged = si_union_scissor(&merged, &scissor);
-		else
-			merged = scissor;
+		get_viewport_xform(viewports + i, scale, translate);
+		scale[0] = abs(scale[0]);
+		scale[1] = abs(scale[1]);
+
+		if (scale[0] < 0.5)
+			scale[0] = 0.5;
+		if (scale[1] < 0.5)
+			scale[1] = 0.5;
+
+		guardband_x = MIN2(guardband_x, (max_range - abs(translate[0])) / scale[0]);
+		guardband_y = MIN2(guardband_y, (max_range - abs(translate[1])) / scale[1]);
 
 		radeon_emit(cs, S_028250_TL_X(scissor.offset.x) |
 			    S_028250_TL_Y(scissor.offset.y) |
@@ -618,12 +596,9 @@ si_write_scissors(struct radeon_winsys_cs *cs, int first,
 		radeon_emit(cs, S_028254_BR_X(scissor.offset.x + scissor.extent.width) |
 			    S_028254_BR_Y(scissor.offset.y + scissor.extent.height));
 	}
-
-	get_viewport_xform_scissor(&merged, scale, translate);
-
-	if (can_use_guardband) {
-		guardband_x = (max_range - abs(translate[0])) / scale[0];
-		guardband_y = (max_range - abs(translate[1])) / scale[1];
+	if (!can_use_guardband) {
+		guardband_x = 1.0;
+		guardband_y = 1.0;
 	}
 
 	radeon_set_context_reg_seq(cs, R_028BE8_PA_CL_GB_VERT_CLIP_ADJ, 4);




More information about the mesa-commit mailing list