OSDN Git Service

Fixed erroneous filtering
authorAlexis Hetu <sugoi@google.com>
Thu, 21 Mar 2019 22:04:29 +0000 (18:04 -0400)
committerAlexis Hétu <sugoi@google.com>
Mon, 25 Mar 2019 13:42:37 +0000 (13:42 +0000)
Even if all the coordinates are within the bounds, if filtering is
enabled and the coordinates are closer to the edge than the center
of the pixel, we have to enable clamping to the edge so that the
samples used for filtering don't get invalid/negative factors.

Bug b/119620767 b/129258757

Change-Id: I0ba50fff2c2873e4a852e34878883c2e707d9886
Tests: dEQP-VK.api.copy_and_blit.core.blit_image.simple_tests.scaling_whole2.*
Tests: dEQP-VK.api.copy_and_blit.dedicated_allocation.blit_image.simple_tests.scaling_whole2.*
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/27808
Tested-by: Alexis Hétu <sugoi@google.com>
Reviewed-by: Nicolas Capens <nicolascapens@google.com>
src/Device/Blitter.cpp

index 06aa87d..9f59d88 100644 (file)
@@ -1543,12 +1543,21 @@ namespace sw
                VkImageAspectFlagBits srcAspect = static_cast<VkImageAspectFlagBits>(region.srcSubresource.aspectMask);
                VkImageAspectFlagBits dstAspect = static_cast<VkImageAspectFlagBits>(region.dstSubresource.aspectMask);
 
+               float widthRatio = static_cast<float>(region.srcOffsets[1].x - region.srcOffsets[0].x) /
+                                  static_cast<float>(region.dstOffsets[1].x - region.dstOffsets[0].x);
+               float heightRatio = static_cast<float>(region.srcOffsets[1].y - region.srcOffsets[0].y) /
+                                   static_cast<float>(region.dstOffsets[1].y - region.dstOffsets[0].y);
+               float x0 = region.srcOffsets[0].x + (0.5f - region.dstOffsets[0].x) * widthRatio;
+               float y0 = region.srcOffsets[0].y + (0.5f - region.dstOffsets[0].y) * heightRatio;
+
+               bool doFilter = (filter != VK_FILTER_NEAREST);
                State state(src->getFormat(srcAspect), dst->getFormat(dstAspect), dst->getSampleCountFlagBits(),
-                           { filter != VK_FILTER_NEAREST, srcAspect == VK_IMAGE_ASPECT_STENCIL_BIT, filter != VK_FILTER_NEAREST });
+                           { doFilter, srcAspect == VK_IMAGE_ASPECT_STENCIL_BIT, doFilter });
                state.clampToEdge = (region.srcOffsets[0].x < 0) ||
                                    (region.srcOffsets[0].y < 0) ||
                                    (static_cast<uint32_t>(region.srcOffsets[1].x) > srcExtent.width) ||
-                                   (static_cast<uint32_t>(region.srcOffsets[1].y) > srcExtent.height);
+                                   (static_cast<uint32_t>(region.srcOffsets[1].y) > srcExtent.height) ||
+                                   (doFilter && ((x0 < 0.5f) || (y0 < 0.5f)));
 
                Routine *blitRoutine = getRoutine(state);
                if(!blitRoutine)
@@ -1558,26 +1567,27 @@ namespace sw
 
                void(*blitFunction)(const BlitData *data) = (void(*)(const BlitData*))blitRoutine->getEntry();
 
-               BlitData data;
-
-               data.sPitchB = src->rowPitchBytes(srcAspect, region.srcSubresource.mipLevel);
-               data.dPitchB = dst->rowPitchBytes(dstAspect, region.dstSubresource.mipLevel);
-               data.dSliceB = dst->slicePitchBytes(dstAspect, region.dstSubresource.mipLevel);
-
-               data.w = static_cast<float>(region.srcOffsets[1].x - region.srcOffsets[0].x) /
-                        static_cast<float>(region.dstOffsets[1].x - region.dstOffsets[0].x);
-               data.h = static_cast<float>(region.srcOffsets[1].y - region.srcOffsets[0].y) /
-                        static_cast<float>(region.dstOffsets[1].y - region.dstOffsets[0].y);
-               data.x0 = region.srcOffsets[0].x + (0.5f - region.dstOffsets[0].x) * data.w;
-               data.y0 = region.srcOffsets[0].y + (0.5f - region.dstOffsets[0].y) * data.h;
-
-               data.x0d = region.dstOffsets[0].x;
-               data.x1d = region.dstOffsets[1].x;
-               data.y0d = region.dstOffsets[0].y;
-               data.y1d = region.dstOffsets[1].y;
-
-               data.sWidth = srcExtent.width;
-               data.sHeight = srcExtent.height;
+               BlitData data =
+               {
+                       nullptr, // source
+                       nullptr, // dest
+                       src->rowPitchBytes(srcAspect, region.srcSubresource.mipLevel),   // sPitchB
+                       dst->rowPitchBytes(dstAspect, region.dstSubresource.mipLevel),   // dPitchB
+                       dst->slicePitchBytes(dstAspect, region.dstSubresource.mipLevel), // dSliceB
+
+                       x0,
+                       y0,
+                       widthRatio,
+                       heightRatio,
+
+                       region.dstOffsets[0].y, // y0d
+                       region.dstOffsets[1].y, // y1d
+                       region.dstOffsets[0].x, // x0d
+                       region.dstOffsets[1].x, // x1d
+
+                       static_cast<int>(srcExtent.width), // sWidth
+                       static_cast<int>(srcExtent.height) // sHeight;
+               };
 
                VkOffset3D srcOffset = { 0, 0, region.srcOffsets[0].z };
                VkOffset3D dstOffset = { 0, 0, region.dstOffsets[0].z };