@@ -8988,30 +8988,15 @@ TEST_F(ExecutionTest, CBufferTestHalf) {
8988
8988
}
8989
8989
}
8990
8990
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){
9007
8992
MappedData data;
9008
8993
D3D12_RESOURCE_DESC &D = test->ShaderOp ->GetResourceByName (" RTarget" )->Desc ;
9009
8994
UINT width = (UINT)D.Width ;
9010
8995
UINT height = D.Height ;
9011
8996
UINT pixelSize = GetByteSizeForFormat (D.Format );
9012
8997
9013
8998
test->Test ->GetReadBackData (" RTarget" , &data);
9014
- // const uint8_t *pPixels = (uint8_t *)data.data();
8999
+
9015
9000
const float *pPixels = (float *)data.data ();
9016
9001
// Get the vertex of barycentric coordinate using VBuffer
9017
9002
MappedData triangleData;
@@ -9025,33 +9010,106 @@ TEST_F(ExecutionTest, BarycentricsTest) {
9025
9010
XMFLOAT2 p0 (pTriangleData[0 ], pTriangleData[1 ]);
9026
9011
XMFLOAT2 p1 (pTriangleData[triangleVertexSizeInFloat], pTriangleData[triangleVertexSizeInFloat + 1 ]);
9027
9012
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.
9029
9015
XMFLOAT3 barycentricWeights[4 ] = {
9030
- XMFLOAT3 (0 .3333f , 0 .3333f , 0 .3333f ),
9016
+ XMFLOAT3 (0 .4f , 0 .2f , 0 .4f ),
9031
9017
XMFLOAT3 (0 .5f , 0 .25f , 0 .25f ),
9032
9018
XMFLOAT3 (0 .25f , 0 .5f , 0 .25f ),
9033
9019
XMFLOAT3 (0 .25f , 0 .25f , 0 .50f )
9034
- };
9020
+ };
9035
9021
9036
- float tolerance = 0 .001f ;
9022
+ float tolerance = 0 .02f ;
9037
9023
for (unsigned i = 0 ; i < sizeof (barycentricWeights) / sizeof (XMFLOAT3); ++i) {
9038
9024
float w0 = barycentricWeights[i].x ;
9039
9025
float w1 = barycentricWeights[i].y ;
9040
9026
float w2 = barycentricWeights[i].z ;
9041
9027
float x1 = w0 * p0.x + w1 * p1.x + w2 * p2.x ;
9042
9028
float y1 = w0 * p0.y + w1 * p1.y + w2 * p2.y ;
9043
9029
// 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 );
9046
9032
int offset = pixelSize * (pixelX + pixelY * width) / sizeof (pPixels[0 ]);
9047
9033
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 ;
9051
9084
}
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
+ }
9053
9110
}
9054
9111
9112
+
9055
9113
static const char RawBufferTestShaderDeclarations[] =
9056
9114
" // Note: COMPONENT_TYPE and COMPONENT_SIZE will be defined via compiler option -D\r\n "
9057
9115
" typedef COMPONENT_TYPE scalar; \r\n "
@@ -11488,7 +11546,12 @@ TEST_F(ExecutionTest, IsNormalTest) {
11488
11546
st::ParseShaderOpSetFromStream (pStream, ShaderOpSet.get ());
11489
11547
st::ShaderOp *pShaderOp = ShaderOpSet->GetShaderOp (" IsNormal" );
11490
11548
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
+
11492
11555
size_t count = Validation_Input->size ();
11493
11556
11494
11557
auto ShaderInitFn = MakeShaderReplacementCallback (
0 commit comments