@@ -8988,30 +8988,15 @@ TEST_F(ExecutionTest, CBufferTestHalf) {
89888988 }
89898989}
89908990
8991- TEST_F (ExecutionTest, BarycentricsTest) {
8992- WEX::TestExecution::SetVerifyOutput verifySettings (WEX::TestExecution::VerifyOutputSettings::LogOnlyFailures);
8993- CComPtr<IStream> pStream;
8994- ReadHlslDataIntoNewStream (L" ShaderOpArith.xml" , &pStream);
8995-
8996- CComPtr<ID3D12Device> pDevice;
8997- if (!CreateDevice (&pDevice, D3D_SHADER_MODEL_6_1))
8998- return ;
8999-
9000- if (!DoesDeviceSupportBarycentrics (pDevice)) {
9001- WEX::Logging::Log::Comment (L" Device does not support barycentrics." );
9002- WEX::Logging::Log::Result (WEX::Logging::TestResults::Skipped);
9003- return ;
9004- }
9005-
9006- std::shared_ptr<ShaderOpTestResult> test = RunShaderOpTest (pDevice, m_support, pStream, " Barycentrics" , nullptr );
8991+ void TestBarycentricVariant (bool checkOrdering, std::shared_ptr<ShaderOpTestResult> test){
90078992 MappedData data;
90088993 D3D12_RESOURCE_DESC &D = test->ShaderOp ->GetResourceByName (" RTarget" )->Desc ;
90098994 UINT width = (UINT)D.Width ;
90108995 UINT height = D.Height ;
90118996 UINT pixelSize = GetByteSizeForFormat (D.Format );
90128997
90138998 test->Test ->GetReadBackData (" RTarget" , &data);
9014- // const uint8_t *pPixels = (uint8_t *)data.data();
8999+
90159000 const float *pPixels = (float *)data.data ();
90169001 // Get the vertex of barycentric coordinate using VBuffer
90179002 MappedData triangleData;
@@ -9025,33 +9010,106 @@ TEST_F(ExecutionTest, BarycentricsTest) {
90259010 XMFLOAT2 p0 (pTriangleData[0 ], pTriangleData[1 ]);
90269011 XMFLOAT2 p1 (pTriangleData[triangleVertexSizeInFloat], pTriangleData[triangleVertexSizeInFloat + 1 ]);
90279012 XMFLOAT2 p2 (pTriangleData[triangleVertexSizeInFloat * 2 ], pTriangleData[triangleVertexSizeInFloat * 2 + 1 ]);
9028-
9013+
9014+ // Seems like the 3 floats must add up to 1 to get accurate results.
90299015 XMFLOAT3 barycentricWeights[4 ] = {
9030- XMFLOAT3 (0 .3333f , 0 .3333f , 0 .3333f ),
9016+ XMFLOAT3 (0 .4f , 0 .2f , 0 .4f ),
90319017 XMFLOAT3 (0 .5f , 0 .25f , 0 .25f ),
90329018 XMFLOAT3 (0 .25f , 0 .5f , 0 .25f ),
90339019 XMFLOAT3 (0 .25f , 0 .25f , 0 .50f )
9034- };
9020+ };
90359021
9036- float tolerance = 0 .001f ;
9022+ float tolerance = 0 .02f ;
90379023 for (unsigned i = 0 ; i < sizeof (barycentricWeights) / sizeof (XMFLOAT3); ++i) {
90389024 float w0 = barycentricWeights[i].x ;
90399025 float w1 = barycentricWeights[i].y ;
90409026 float w2 = barycentricWeights[i].z ;
90419027 float x1 = w0 * p0.x + w1 * p1.x + w2 * p2.x ;
90429028 float y1 = w0 * p0.y + w1 * p1.y + w2 * p2.y ;
90439029 // map from x1 y1 to rtv pixels
9044- int pixelX = (int )((x1 + 1 ) * (width - 1 ) / 2 );
9045- int pixelY = (int )((1 - y1) * (height - 1 ) / 2 );
9030+ int pixelX = (int )round ((x1 + 1 ) * (width - 1 ) / 2.0 );
9031+ int pixelY = (int )round ((1 - y1) * (height - 1 ) / 2.0 );
90469032 int offset = pixelSize * (pixelX + pixelY * width) / sizeof (pPixels[0 ]);
90479033 LogCommentFmt (L" location %u %u, value %f, %f, %f" , pixelX, pixelY, pPixels[offset], pPixels[offset + 1 ], pPixels[offset + 2 ]);
9048- VERIFY_IS_TRUE (CompareFloatEpsilon (pPixels[offset], w0, tolerance));
9049- VERIFY_IS_TRUE (CompareFloatEpsilon (pPixels[offset + 1 ], w1, tolerance));
9050- VERIFY_IS_TRUE (CompareFloatEpsilon (pPixels[offset + 2 ], w2, tolerance));
9034+ if (!checkOrdering){
9035+ VERIFY_IS_TRUE (CompareFloatEpsilon (pPixels[offset], w0, tolerance));
9036+ VERIFY_IS_TRUE (CompareFloatEpsilon (pPixels[offset + 1 ], w1, tolerance));
9037+ VERIFY_IS_TRUE (CompareFloatEpsilon (pPixels[offset + 2 ], w2, tolerance));
9038+ }
9039+ else {
9040+ // If the ordering constraint is met, then this pixel's RGBA should be all 1.0's
9041+ // since the shader only returns float4<1.0,1.0,1.0,1.0> when this condition is met.
9042+ VERIFY_IS_TRUE (CompareFloatEpsilon (pPixels[offset] , 0.0 , tolerance));
9043+ VERIFY_IS_TRUE (CompareFloatEpsilon (pPixels[offset + 1 ], 0.5 , tolerance));
9044+ VERIFY_IS_TRUE (CompareFloatEpsilon (pPixels[offset + 2 ], 1.0 , tolerance));
9045+ VERIFY_IS_TRUE (CompareFloatEpsilon (pPixels[offset + 3 ], 1.0 , tolerance));
9046+ }
9047+ }
9048+ }
9049+
9050+ st::ShaderOpTest::TInitCallbackFn MakeBarycentricsResourceInitCallbackFn (int &vertexShift){
9051+ return [&](LPCSTR Name, std::vector<BYTE>& Data, st::ShaderOp* pShaderOp) {
9052+ std::vector<float > bary = { 0 .0f , 1 .0f , 0 .0f , 1 .0f , 0 .0f , 0 .0f , 1 .0f ,
9053+ 1 .0f , -1 .0f , 0 .0f , 0 .0f , 1 .0f , 0 .0f , 1 .0f ,
9054+ -1 .0f , -1 .0f , 0 .0f , 0 .0f , 0 .0f , 1 .0f , 1 .0f };
9055+ const int barysize = 21 ;
9056+
9057+ UNREFERENCED_PARAMETER (pShaderOp);
9058+ VERIFY_IS_TRUE (0 == _stricmp (Name, " VBuffer" ));
9059+ size_t size = sizeof (float ) * barysize;
9060+ Data.resize (size);
9061+ float * vb = (float *)Data.data ();
9062+ for (size_t i = 0 ; i < barysize; ++i) {
9063+ float * p = &vb[i];
9064+ float tempfloat = bary[(i + (7 * vertexShift)) % barysize];
9065+ *p = tempfloat;
9066+ }
9067+ };
9068+
9069+ }
9070+
9071+ TEST_F (ExecutionTest, BarycentricsTest) {
9072+ WEX::TestExecution::SetVerifyOutput verifySettings (WEX::TestExecution::VerifyOutputSettings::LogOnlyFailures);
9073+ CComPtr<IStream> pStream;
9074+ ReadHlslDataIntoNewStream (L" ShaderOpArith.xml" , &pStream);
9075+
9076+ CComPtr<ID3D12Device> pDevice;
9077+ if (!CreateDevice (&pDevice, D3D_SHADER_MODEL_6_1))
9078+ return ;
9079+
9080+ if (!DoesDeviceSupportBarycentrics (pDevice)) {
9081+ WEX::Logging::Log::Comment (L" Device does not support barycentrics." );
9082+ WEX::Logging::Log::Result (WEX::Logging::TestResults::Skipped);
9083+ return ;
90519084 }
9052- // SavePixelsToFile(pPixels, DXGI_FORMAT_R32G32B32A32_FLOAT, width, height, L"barycentric.bmp");
9085+
9086+ DXASSERT_NOMSG (pStream != nullptr );
9087+ std::shared_ptr<st::ShaderOpSet> ShaderOpSet =
9088+ std::make_shared<st::ShaderOpSet>();
9089+ st::ParseShaderOpSetFromStream (pStream, ShaderOpSet.get ());
9090+ st::ShaderOp* pShaderOp =
9091+ ShaderOpSet->GetShaderOp (" Barycentrics" );
9092+
9093+ int test_iteration = 0 ;
9094+ auto ResourceCallbackFnNoShift = MakeBarycentricsResourceInitCallbackFn (test_iteration);
9095+
9096+ std::shared_ptr<ShaderOpTestResult> test = RunShaderOpTestAfterParse (pDevice, m_support, " Barycentrics" , ResourceCallbackFnNoShift, ShaderOpSet);
9097+ TestBarycentricVariant (false , test);
9098+
9099+ // Now test that barycentric ordering is consistent
9100+ LogCommentFmt (L" Now testing that the barycentric ordering constraint is upheld for each pixel..." );
9101+ pShaderOp->VS = pShaderOp->GetString (" VSordering" );
9102+ pShaderOp->PS = pShaderOp->GetString (" PSordering" );
9103+ for (; test_iteration < 3 ; test_iteration++)
9104+ {
9105+ auto ResourceCallbackFn = MakeBarycentricsResourceInitCallbackFn (test_iteration);
9106+
9107+ std::shared_ptr<ShaderOpTestResult> test2 = RunShaderOpTestAfterParse (pDevice, m_support, " Barycentrics" , ResourceCallbackFn, ShaderOpSet);
9108+ TestBarycentricVariant (true , test2);
9109+ }
90539110}
90549111
9112+
90559113static const char RawBufferTestShaderDeclarations[] =
90569114" // Note: COMPONENT_TYPE and COMPONENT_SIZE will be defined via compiler option -D\r\n "
90579115" typedef COMPONENT_TYPE scalar; \r\n "
@@ -11488,7 +11546,12 @@ TEST_F(ExecutionTest, IsNormalTest) {
1148811546 st::ParseShaderOpSetFromStream (pStream, ShaderOpSet.get ());
1148911547 st::ShaderOp *pShaderOp = ShaderOpSet->GetShaderOp (" IsNormal" );
1149011548 vector<st::ShaderOpRootValue> fallbackRootValues = pShaderOp->RootValues ;
11491-
11549+
11550+ D3D_SHADER_MODEL sm = D3D_SHADER_MODEL_6_0;
11551+ LogCommentFmt (L" \r\n Verifying isNormal in shader "
11552+ L" model 6.%1u" ,
11553+ ((UINT)sm & 0x0f ));
11554+
1149211555 size_t count = Validation_Input->size ();
1149311556
1149411557 auto ShaderInitFn = MakeShaderReplacementCallback (
0 commit comments