Merge vk-gl-cts/vulkan-cts-1.1.5 into vk-gl-cts/vulkan-cts-1.1.6
Change-Id: Ib3cab2c6bc13dee32caf2403b9dc52492f660082
diff --git a/android/cts/master/vk-master.txt b/android/cts/master/vk-master.txt
index bd32617..f9edce0 100644
--- a/android/cts/master/vk-master.txt
+++ b/android/cts/master/vk-master.txt
Binary files differ
diff --git a/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmGraphicsShaderTestUtil.cpp b/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmGraphicsShaderTestUtil.cpp
index b412949..7810c40 100644
--- a/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmGraphicsShaderTestUtil.cpp
+++ b/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmGraphicsShaderTestUtil.cpp
@@ -4605,25 +4605,9 @@
vector<deUint8> expectedBytes;
expected->getBytes(expectedBytes);
- // Same vertex shader may be executed for multiple times, the output value should be expected value + non-negative integer N
- if (instance.customizedStages == VK_SHADER_STAGE_VERTEX_BIT)
- {
- const size_t numExpectedEntries = expectedBytes.size() / sizeof(float);
- const float* expectedFloats = reinterpret_cast<const float*>(&expectedBytes.front());
- const float* outputFloats = reinterpret_cast<const float*>(outResourceMemories[outputNdx]->getHostPtr());
+ if (deMemCmp(&expectedBytes.front(), outResourceMemories[outputNdx]->getHostPtr(), expectedBytes.size()))
+ return tcu::TestStatus::fail("Resource returned doesn't match bitwisely with expected");
- for (size_t expectedNdx = 0; expectedNdx < numExpectedEntries; ++expectedNdx)
- {
- float diff = outputFloats[expectedNdx] - expectedFloats[expectedNdx];
- if ((diff < 0) || (deFloatFloor(diff) != diff))
- return tcu::TestStatus::fail("Value returned should be equal to expected value plus non-negative integer");
- }
- }
- else
- {
- if (deMemCmp(&expectedBytes.front(), outResourceMemories[outputNdx]->getHostPtr(), expectedBytes.size()))
- return tcu::TestStatus::fail("Resource returned doesn't match bitwisely with expected");
- }
}
}
diff --git a/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmInstructionTests.cpp b/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmInstructionTests.cpp
index c03c5b6..31c626b 100644
--- a/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmInstructionTests.cpp
+++ b/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmInstructionTests.cpp
@@ -11296,396 +11296,6 @@
return testGroup.release();
}
-struct getV_ { deUint32 inline operator()(deUint32 v) const { return v; } getV_(){} };
-struct getV0 { deUint32 inline operator()(deUint32 v) const { return v & (~1); } getV0(){} };
-struct getV1 { deUint32 inline operator()(deUint32 v) const { return v | ( 1); } getV1(){} };
-
-template<deUint32 R, deUint32 N>
-inline static deUint32 getOffset(deUint32 x, deUint32 y, deUint32 n)
-{
- return N * ((R * y) + x) + n;
-}
-
-template<deUint32 R, deUint32 N, class X0, class X1, class Y0, class Y1>
-struct getFDelta
-{
- float operator() (const deFloat16* data, deUint32 x, deUint32 y, deUint32 n, deUint32 flavor) const
- {
- DE_STATIC_ASSERT(R%2 == 0);
- DE_ASSERT(flavor == 0);
- DE_UNREF(flavor);
-
- const X0 x0;
- const X1 x1;
- const Y0 y0;
- const Y1 y1;
- const deFloat16 v0 = data[getOffset<R, N>(x0(x), y0(y), n)];
- const deFloat16 v1 = data[getOffset<R, N>(x1(x), y1(y), n)];
- const tcu::Float16 f0 = tcu::Float16(v0);
- const tcu::Float16 f1 = tcu::Float16(v1);
- const float d0 = f0.asFloat();
- const float d1 = f1.asFloat();
- const float d = d1 - d0;
-
- return d;
- }
-
- getFDelta(){}
-};
-
-template<deUint32 F, class Class0, class Class1>
-struct getFOneOf
-{
- float operator() (const deFloat16* data, deUint32 x, deUint32 y, deUint32 n, deUint32 flavor) const
- {
- DE_ASSERT(flavor < F);
-
- if (flavor == 0)
- {
- Class0 c;
-
- return c(data, x, y, n, flavor);
- }
- else
- {
- Class1 c;
-
- return c(data, x, y, n, flavor - 1);
- }
- }
-
- getFOneOf(){}
-};
-
-template<class FineX0, class FineX1, class FineY0, class FineY1>
-struct calcWidthOf4
-{
- float operator() (const deFloat16* data, deUint32 x, deUint32 y, deUint32 n, deUint32 flavor) const
- {
- DE_ASSERT(flavor < 4);
-
- const deUint32 flavorX = (flavor & 1) == 0 ? 0 : 1;
- const deUint32 flavorY = (flavor & 2) == 0 ? 0 : 1;
- const getFOneOf<2, FineX0, FineX1> cx;
- const getFOneOf<2, FineY0, FineY1> cy;
- float v = 0;
-
- v += fabsf(cx(data, x, y, n, flavorX));
- v += fabsf(cy(data, x, y, n, flavorY));
-
- return v;
- }
-
- calcWidthOf4(){}
-};
-
-template<deUint32 R, deUint32 N, class Derivative>
-bool compareDerivativeWithFlavor (const deFloat16* inputAsFP16, const deFloat16* outputAsFP16, deUint32 flavor, std::string& error)
-{
- const deUint32 numDataPointsByAxis = R;
- const Derivative derivativeFunc;
-
- for (deUint32 y = 0; y < numDataPointsByAxis; ++y)
- for (deUint32 x = 0; x < numDataPointsByAxis; ++x)
- for (deUint32 n = 0; n < N; ++n)
- {
- const float expectedFloat = derivativeFunc(inputAsFP16, x, y, n, flavor);
- deFloat16 expected = deFloat32To16Round(expectedFloat, DE_ROUNDINGMODE_TO_NEAREST_EVEN);
- const deFloat16 output = outputAsFP16[getOffset<R, N>(x, y, n)];
-
- bool reportError = !compare16BitFloat(expected, output, error);
-
- if (reportError)
- {
- expected = deFloat32To16Round(expectedFloat, DE_ROUNDINGMODE_TO_ZERO);
- reportError = !compare16BitFloat(expected, output, error);
- }
-
- if (reportError)
- {
- error = "subcase at " + de::toString(x) + "," + de::toString(y) + "," + de::toString(n) + ": " + error;
-
- return false;
- }
- }
-
- return true;
-}
-
-template<deUint32 R, deUint32 N, deUint32 FLAVOUR_COUNT, class Derivative>
-bool compareDerivative (const std::vector<Resource>& inputs, const vector<AllocationSp>& outputAllocs, const std::vector<Resource>&, TestLog& log)
-{
- if (inputs.size() != 1 || outputAllocs.size() != 1)
- return false;
-
- deUint32 successfulRuns = FLAVOUR_COUNT;
- std::string results[FLAVOUR_COUNT];
- vector<deUint8> inputBytes;
-
- inputs[0].getBytes(inputBytes);
-
- const deFloat16* inputAsFP16 = reinterpret_cast<deFloat16* const>(&inputBytes.front());
- const deFloat16* outputAsFP16 = static_cast<deFloat16*>(outputAllocs[0]->getHostPtr());
-
- DE_ASSERT(inputBytes.size() == R * R * N * sizeof(deFloat16));
-
- for (deUint32 flavor = 0; flavor < FLAVOUR_COUNT; ++flavor)
- if (compareDerivativeWithFlavor<R, N, Derivative> (inputAsFP16, outputAsFP16, flavor, results[flavor]))
- {
- break;
- }
- else
- {
- successfulRuns--;
- }
-
- if (successfulRuns == 0)
- for (deUint32 flavor = 0; flavor < FLAVOUR_COUNT; flavor++)
- log << TestLog::Message << "At flavor #" << flavor << " " << results[flavor] << TestLog::EndMessage;
-
- return successfulRuns > 0;
-}
-
-template<deUint32 R, deUint32 N>
-tcu::TestCaseGroup* createDerivativeTests (tcu::TestContext& testCtx)
-{
- typedef getFDelta<R, N, getV0, getV1, getV_, getV_> getFDxFine;
- typedef getFDelta<R, N, getV_, getV_, getV0, getV1> getFDyFine;
-
- typedef getFDelta<R, N, getV0, getV1, getV0, getV0> getFdxCoarse0;
- typedef getFDelta<R, N, getV0, getV1, getV1, getV1> getFdxCoarse1;
- typedef getFDelta<R, N, getV0, getV0, getV0, getV1> getFdyCoarse0;
- typedef getFDelta<R, N, getV1, getV1, getV0, getV1> getFdyCoarse1;
- typedef getFOneOf<2, getFdxCoarse0, getFdxCoarse1> getFDxCoarse;
- typedef getFOneOf<2, getFdyCoarse0, getFdyCoarse1> getFDyCoarse;
-
- typedef calcWidthOf4<getFDxFine, getFDxFine, getFDyFine, getFDyFine> getFWidthFine;
- typedef calcWidthOf4<getFdxCoarse0, getFdxCoarse1, getFdyCoarse0, getFdyCoarse1> getFWidthCoarse;
-
- typedef getFOneOf<3, getFDxFine, getFDxCoarse> getFDx;
- typedef getFOneOf<3, getFDyFine, getFDyCoarse> getFDy;
- typedef getFOneOf<5, getFWidthFine, getFWidthCoarse> getFWidth;
-
- const std::string testGroupName (std::string("derivative_") + de::toString(N));
- de::MovePtr<tcu::TestCaseGroup> testGroup (new tcu::TestCaseGroup(testCtx, testGroupName.c_str(), "Derivative instruction tests"));
-
- de::Random rnd (deStringHash(testGroup->getName()));
- const deUint32 numDataPointsByAxis = R;
- const deUint32 numDataPoints = N * numDataPointsByAxis * numDataPointsByAxis;
- vector<deFloat16> float16InputX;
- vector<deFloat16> float16InputY;
- vector<deFloat16> float16InputW;
- vector<deFloat16> float16OutputDummy (numDataPoints, 0);
- RGBA defaultColors[4];
-
- getDefaultColors(defaultColors);
-
- float16InputX.reserve(numDataPoints);
- for (deUint32 y = 0; y < numDataPointsByAxis; ++y)
- for (deUint32 x = 0; x < numDataPointsByAxis; ++x)
- for (deUint32 n = 0; n < N; ++n)
- {
- const float arg = static_cast<float>(2 * DE_PI) * static_cast<float>(x * (n + 1)) / static_cast<float>(1 * numDataPointsByAxis);
-
- if (y%2 == 0)
- float16InputX.push_back(tcu::Float16(sin(arg)).bits());
- else
- float16InputX.push_back(tcu::Float16(cos(arg)).bits());
- }
-
- float16InputY.reserve(numDataPoints);
- for (deUint32 y = 0; y < numDataPointsByAxis; ++y)
- for (deUint32 x = 0; x < numDataPointsByAxis; ++x)
- for (deUint32 n = 0; n < N; ++n)
- {
- const float arg = static_cast<float>(2 * DE_PI) * static_cast<float>(y * (n + 1)) / static_cast<float>(1 * numDataPointsByAxis);
-
- if (x%2 == 0)
- float16InputY.push_back(tcu::Float16(sin(arg)).bits());
- else
- float16InputY.push_back(tcu::Float16(cos(arg)).bits());
- }
-
- const deFloat16 testNumbers[] =
- {
- tcu::Float16( 2.0 ).bits(),
- tcu::Float16( 4.0 ).bits(),
- tcu::Float16( 8.0 ).bits(),
- tcu::Float16( 16.0 ).bits(),
- tcu::Float16( 32.0 ).bits(),
- tcu::Float16( 64.0 ).bits(),
- tcu::Float16( 128.0).bits(),
- tcu::Float16( 256.0).bits(),
- tcu::Float16( 512.0).bits(),
- tcu::Float16(-2.0 ).bits(),
- tcu::Float16(-4.0 ).bits(),
- tcu::Float16(-8.0 ).bits(),
- tcu::Float16(-16.0 ).bits(),
- tcu::Float16(-32.0 ).bits(),
- tcu::Float16(-64.0 ).bits(),
- tcu::Float16(-128.0).bits(),
- tcu::Float16(-256.0).bits(),
- tcu::Float16(-512.0).bits(),
- };
-
- float16InputW.reserve(numDataPoints);
- for (deUint32 y = 0; y < numDataPointsByAxis; ++y)
- for (deUint32 x = 0; x < numDataPointsByAxis; ++x)
- for (deUint32 n = 0; n < N; ++n)
- float16InputW.push_back(testNumbers[rnd.getInt(0, DE_LENGTH_OF_ARRAY(testNumbers) - 1)]);
-
- struct TestOp
- {
- const char* opCode;
- vector<deFloat16>& inputData;
- VerifyIOFunc verifyFunc;
- };
-
- const TestOp testOps[] =
- {
- { "OpDPdxFine" , float16InputX , compareDerivative<R, N, 1, getFDxFine > },
- { "OpDPdyFine" , float16InputY , compareDerivative<R, N, 1, getFDyFine > },
- { "OpFwidthFine" , float16InputW , compareDerivative<R, N, 1, getFWidthFine > },
- { "OpDPdxCoarse" , float16InputX , compareDerivative<R, N, 3, getFDx > },
- { "OpDPdyCoarse" , float16InputY , compareDerivative<R, N, 3, getFDy > },
- { "OpFwidthCoarse" , float16InputW , compareDerivative<R, N, 5, getFWidth > },
- { "OpDPdx" , float16InputX , compareDerivative<R, N, 3, getFDx > },
- { "OpDPdy" , float16InputY , compareDerivative<R, N, 3, getFDy > },
- { "OpFwidth" , float16InputW , compareDerivative<R, N, 5, getFWidth > },
- };
-
- struct TestType
- {
- const deUint32 typeComponents;
- const char* typeName;
- const char* typeDecls;
- };
-
- const TestType testTypes[] =
- {
- {
- 1,
- "f16",
- ""
- },
- {
- 2,
- "v2f16",
- " %v2f16 = OpTypeVector %f16 2\n"
- },
- {
- 4,
- "v4f16",
- " %v4f16 = OpTypeVector %f16 4\n"
- },
- };
-
- const deUint32 testTypeNdx = (N == 1) ? 0
- : (N == 2) ? 1
- : (N == 4) ? 2
- : DE_LENGTH_OF_ARRAY(testTypes);
- const TestType& testType = testTypes[testTypeNdx];
-
- DE_ASSERT(testTypeNdx < DE_LENGTH_OF_ARRAY(testTypes));
- DE_ASSERT(testType.typeComponents == N);
-
- const StringTemplate preMain
- (
- "%c_i32_ndp = OpConstant %i32 ${num_data_points}\n"
- " %c_u32_xw = OpConstant %u32 ${items_by_x}\n"
- " %f16 = OpTypeFloat 16\n"
- "${type_decls}"
- " %up_${tt} = OpTypePointer Uniform %${tt}\n"
- " %ra_${tt} = OpTypeArray %${tt} %c_i32_ndp\n"
- " %SSBO16 = OpTypeStruct %ra_${tt}\n"
- "%up_SSBO16 = OpTypePointer Uniform %SSBO16\n"
- " %ssbo_src = OpVariable %up_SSBO16 Uniform\n"
- " %ssbo_dst = OpVariable %up_SSBO16 Uniform\n"
- );
-
- const StringTemplate decoration
- (
- "OpDecorate %ra_${tt} ArrayStride ${tt_stride}\n"
- "OpMemberDecorate %SSBO16 0 Offset 0\n"
- "OpDecorate %SSBO16 BufferBlock\n"
- "OpDecorate %ssbo_src DescriptorSet 0\n"
- "OpDecorate %ssbo_src Binding 0\n"
- "OpDecorate %ssbo_dst DescriptorSet 0\n"
- "OpDecorate %ssbo_dst Binding 1\n"
- );
-
- const StringTemplate testFun
- (
- "%test_code = OpFunction %v4f32 None %v4f32_v4f32_function\n"
- " %param = OpFunctionParameter %v4f32\n"
- " %entry = OpLabel\n"
-
- " %loc_x_c = OpAccessChain %ip_f32 %BP_gl_FragCoord %c_i32_0\n"
- " %loc_y_c = OpAccessChain %ip_f32 %BP_gl_FragCoord %c_i32_1\n"
- " %x_c = OpLoad %f32 %loc_x_c\n"
- " %y_c = OpLoad %f32 %loc_y_c\n"
- " %x_idx = OpConvertFToU %u32 %x_c\n"
- " %y_idx = OpConvertFToU %u32 %y_c\n"
- " %ndx_y = OpIMul %u32 %y_idx %c_u32_xw\n"
- " %ndx = OpIAdd %u32 %ndx_y %x_idx\n"
-
- " %src = OpAccessChain %up_${tt} %ssbo_src %c_i32_0 %ndx\n"
- " %val_src = OpLoad %${tt} %src\n"
- " %val_dst = ${op_code} %${tt} %val_src\n"
- " %dst = OpAccessChain %up_${tt} %ssbo_dst %c_i32_0 %ndx\n"
- " OpStore %dst %val_dst\n"
- " OpBranch %merge\n"
-
- " %merge = OpLabel\n"
- " OpReturnValue %param\n"
-
- " OpFunctionEnd\n"
- );
-
- for (deUint32 testOpsIdx = 0; testOpsIdx < DE_LENGTH_OF_ARRAY(testOps); ++testOpsIdx)
- {
- const TestOp& testOp = testOps[testOpsIdx];
- const string testName = de::toLower(string(testOp.opCode));
- const size_t typeStride = N * sizeof(deFloat16);
- GraphicsResources specResource;
- map<string, string> specs;
- VulkanFeatures features;
- vector<string> extensions;
- map<string, string> fragments;
- SpecConstants noSpecConstants;
- PushConstants noPushConstants;
- GraphicsInterfaces noInterfaces;
-
- specs["op_code"] = testOp.opCode;
- specs["num_data_points"] = de::toString(testOp.inputData.size() / N);
- specs["items_by_x"] = de::toString(numDataPointsByAxis);
- specs["tt"] = testType.typeName;
- specs["tt_stride"] = de::toString(typeStride);
- specs["type_decls"] = testType.typeDecls;
-
- fragments["extension"] = "OpExtension \"SPV_KHR_16bit_storage\"";
- fragments["capability"] = "OpCapability DerivativeControl\nOpCapability StorageUniformBufferBlock16\nOpCapability Float16\n";
- fragments["decoration"] = decoration.specialize(specs);
- fragments["pre_main"] = preMain.specialize(specs);
- fragments["testfun"] = testFun.specialize(specs);
-
- specResource.inputs.push_back(Resource(BufferSp(new Float16Buffer(testOp.inputData)), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER));
- specResource.outputs.push_back(Resource(BufferSp(new Float16Buffer(float16OutputDummy)), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER));
- specResource.verifyIO = testOp.verifyFunc;
-
- extensions.push_back("VK_KHR_16bit_storage");
- extensions.push_back("VK_KHR_shader_float16_int8");
-
- features.extFloat16Int8 = EXTFLOAT16INT8FEATURES_FLOAT16;
- features.ext16BitStorage = EXT16BITSTORAGEFEATURES_UNIFORM_BUFFER_BLOCK;
-
- createTestForStage(VK_SHADER_STAGE_FRAGMENT_BIT, testName.c_str(), defaultColors, defaultColors, fragments, noSpecConstants,
- noPushConstants, specResource, noInterfaces, extensions, features, testGroup.get(), QP_TEST_RESULT_FAIL, string(), true);
- }
-
- return testGroup.release();
-}
-
bool compareFP16VectorExtractFunc (const std::vector<Resource>& inputs, const vector<AllocationSp>& outputAllocs, const std::vector<Resource>&, TestLog& log)
{
if (inputs.size() != 2 || outputAllocs.size() != 1)
@@ -18592,9 +18202,6 @@
testGroup->addChild(createFloat16LogicalSet<GraphicsResources>(testCtx, TEST_WITH_NAN));
testGroup->addChild(createFloat16LogicalSet<GraphicsResources>(testCtx, TEST_WITHOUT_NAN));
testGroup->addChild(createFloat16FuncSet<GraphicsResources>(testCtx));
- testGroup->addChild(createDerivativeTests<256, 1>(testCtx));
- testGroup->addChild(createDerivativeTests<256, 2>(testCtx));
- testGroup->addChild(createDerivativeTests<256, 4>(testCtx));
testGroup->addChild(createFloat16VectorExtractSet<GraphicsResources>(testCtx));
testGroup->addChild(createFloat16VectorInsertSet<GraphicsResources>(testCtx));
testGroup->addChild(createFloat16VectorShuffleSet<GraphicsResources>(testCtx));
diff --git a/external/vulkancts/modules/vulkan/texture/vktTextureFilteringAnisotropyTests.cpp b/external/vulkancts/modules/vulkan/texture/vktTextureFilteringAnisotropyTests.cpp
index f987a81..aa31693 100644
--- a/external/vulkancts/modules/vulkan/texture/vktTextureFilteringAnisotropyTests.cpp
+++ b/external/vulkancts/modules/vulkan/texture/vktTextureFilteringAnisotropyTests.cpp
@@ -137,10 +137,12 @@
return tcu::TestStatus::fail("Fail");
// Anisotropic filtering is implementation dependent. Expecting differences with minification/magnification filter set to NEAREST is too strict.
+ // The specification does not require that your aniso & bi-linear filtering are different even in LINEAR, but this check is 'generally' going
+ // to detect *some* difference and possibly be useful in catching issues where an implementation hasn't setup their filtering modes correctly.
if (m_refParams.minFilter != tcu::Sampler::NEAREST && m_refParams.magFilter != tcu::Sampler::NEAREST)
{
if (floatThresholdCompare (m_context.getTestContext().getLog(), "Expecting comparison to fail", "Expecting comparison to fail",
- renderedFrame.getAccess(), renderedAnisotropyFrame.getAccess(), Vec4(0.05f), tcu::COMPARE_LOG_RESULT))
+ renderedFrame.getAccess(), renderedAnisotropyFrame.getAccess(), Vec4(0.02f), tcu::COMPARE_LOG_RESULT))
return tcu::TestStatus::fail("Fail");
}
}
diff --git a/external/vulkancts/mustpass/master/vk-default-no-waivers.txt b/external/vulkancts/mustpass/master/vk-default-no-waivers.txt
index 06e3384..dab01dc 100644
--- a/external/vulkancts/mustpass/master/vk-default-no-waivers.txt
+++ b/external/vulkancts/mustpass/master/vk-default-no-waivers.txt
Binary files differ
diff --git a/external/vulkancts/mustpass/master/vk-default.txt b/external/vulkancts/mustpass/master/vk-default.txt
index 02b0f42..b7d2c08 100644
--- a/external/vulkancts/mustpass/master/vk-default.txt
+++ b/external/vulkancts/mustpass/master/vk-default.txt
Binary files differ
diff --git a/framework/common/tcuRasterizationVerifier.cpp b/framework/common/tcuRasterizationVerifier.cpp
index a8d7125..bac16e3 100644
--- a/framework/common/tcuRasterizationVerifier.cpp
+++ b/framework/common/tcuRasterizationVerifier.cpp
@@ -2206,7 +2206,7 @@
typedef tcu::Vector<deInt64, 2> I64Vec2;
const deUint64 numSubPixels = ((deUint64)1) << subpixelBits;
- const deUint64 pixelHitBoxSize = (multisample) ? (numSubPixels) : (2+2); //!< allow 4 central (2x2) for non-multisample pixels. Rounding may move edges 1 subpixel to any direction.
+ const deUint64 pixelHitBoxSize = (multisample) ? (numSubPixels) : 5; //!< 5 = ceil(6 * sqrt(2) / 2) to account for a 3 subpixel fuzz around pixel center
const bool order = isTriangleClockwise(p0, p1, p2); //!< clockwise / counter-clockwise
const tcu::Vec4& orderedP0 = p0; //!< vertices of a clockwise triangle
const tcu::Vec4& orderedP1 = (order) ? (p1) : (p2);
@@ -2240,12 +2240,13 @@
// Broad triangle - pixel area intersection
{
- const I64Vec2 pixelCenterPosition = I64Vec2(pixel.x(), pixel.y()) * I64Vec2(numSubPixels, numSubPixels) + I64Vec2(numSubPixels / 2, numSubPixels / 2);
- const I64Vec2 triangleSubPixelSpaceRound[3] =
+ const DVec2 pixelCenterPosition = DVec2((double)pixel.x(), (double)pixel.y()) * DVec2((double)numSubPixels, (double)numSubPixels) +
+ DVec2((double)numSubPixels / 2, (double)numSubPixels / 2);
+ const DVec2 triangleSubPixelSpace[3] =
{
- I64Vec2(deRoundFloatToInt32(triangleScreenSpace[0].x() * (float)numSubPixels), deRoundFloatToInt32(triangleScreenSpace[0].y() * (float)numSubPixels)),
- I64Vec2(deRoundFloatToInt32(triangleScreenSpace[1].x() * (float)numSubPixels), deRoundFloatToInt32(triangleScreenSpace[1].y() * (float)numSubPixels)),
- I64Vec2(deRoundFloatToInt32(triangleScreenSpace[2].x() * (float)numSubPixels), deRoundFloatToInt32(triangleScreenSpace[2].y() * (float)numSubPixels)),
+ DVec2(triangleScreenSpace[0].x() * (double)numSubPixels, triangleScreenSpace[0].y() * (double)numSubPixels),
+ DVec2(triangleScreenSpace[1].x() * (double)numSubPixels, triangleScreenSpace[1].y() * (double)numSubPixels),
+ DVec2(triangleScreenSpace[2].x() * (double)numSubPixels, triangleScreenSpace[2].y() * (double)numSubPixels),
};
// Check (using cross product) if pixel center is
@@ -2255,10 +2256,10 @@
for (int vtxNdx = 0; vtxNdx < 3; ++vtxNdx)
{
const int otherVtxNdx = (vtxNdx + 1) % 3;
- const deInt64 maxPixelDistanceSquared = pixelHitBoxSize*pixelHitBoxSize; // Max distance from the pixel center from within the pixel is (sqrt(2) * boxWidth/2). Use 2x value for rounding tolerance
- const I64Vec2 edge = triangleSubPixelSpaceRound[otherVtxNdx] - triangleSubPixelSpaceRound[vtxNdx];
- const I64Vec2 v = pixelCenterPosition - triangleSubPixelSpaceRound[vtxNdx];
- const deInt64 crossProduct = (edge.x() * v.y() - edge.y() * v.x());
+ const double maxPixelDistanceSquared = (double)(pixelHitBoxSize * pixelHitBoxSize); // Max distance from the pixel center from within the pixel is (sqrt(2) * boxWidth/2). Use 2x value for rounding tolerance
+ const DVec2 edge = triangleSubPixelSpace[otherVtxNdx] - triangleSubPixelSpace[vtxNdx];
+ const DVec2 v = pixelCenterPosition - triangleSubPixelSpace[vtxNdx];
+ const double crossProduct = (edge.x() * v.y() - edge.y() * v.x());
// distance from edge: (edge x v) / |edge|
// (edge x v) / |edge| > maxPixelDistance
@@ -2284,12 +2285,14 @@
I64Vec2((pixel.x()+1) * numSubPixels, (pixel.y()+1) * numSubPixels),
I64Vec2((pixel.x()+0) * numSubPixels, (pixel.y()+1) * numSubPixels),
};
+
+ // 3 subpixel tolerance around pixel center to account for accumulated errors during various line rasterization methods
const I64Vec2 pixelCenterCorners[4] =
{
- I64Vec2(pixel.x() * numSubPixels + numSubPixels/2 + 0, pixel.y() * numSubPixels + numSubPixels/2 + 0),
- I64Vec2(pixel.x() * numSubPixels + numSubPixels/2 + 1, pixel.y() * numSubPixels + numSubPixels/2 + 0),
- I64Vec2(pixel.x() * numSubPixels + numSubPixels/2 + 1, pixel.y() * numSubPixels + numSubPixels/2 + 1),
- I64Vec2(pixel.x() * numSubPixels + numSubPixels/2 + 0, pixel.y() * numSubPixels + numSubPixels/2 + 1),
+ I64Vec2(pixel.x() * numSubPixels + numSubPixels/2 - 3, pixel.y() * numSubPixels + numSubPixels/2 - 3),
+ I64Vec2(pixel.x() * numSubPixels + numSubPixels/2 + 3, pixel.y() * numSubPixels + numSubPixels/2 - 3),
+ I64Vec2(pixel.x() * numSubPixels + numSubPixels/2 + 3, pixel.y() * numSubPixels + numSubPixels/2 + 3),
+ I64Vec2(pixel.x() * numSubPixels + numSubPixels/2 - 3, pixel.y() * numSubPixels + numSubPixels/2 + 3),
};
// both rounding directions