|
@@ -8988,22 +8988,7 @@ TEST_F(ExecutionTest, CBufferTestHalf) {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-TEST_F(ExecutionTest, BarycentricsTest) {
|
|
|
- WEX::TestExecution::SetVerifyOutput verifySettings(WEX::TestExecution::VerifyOutputSettings::LogOnlyFailures);
|
|
|
- CComPtr<IStream> pStream;
|
|
|
- ReadHlslDataIntoNewStream(L"ShaderOpArith.xml", &pStream);
|
|
|
-
|
|
|
- CComPtr<ID3D12Device> pDevice;
|
|
|
- if (!CreateDevice(&pDevice, D3D_SHADER_MODEL_6_1))
|
|
|
- return;
|
|
|
-
|
|
|
- if (!DoesDeviceSupportBarycentrics(pDevice)) {
|
|
|
- WEX::Logging::Log::Comment(L"Device does not support barycentrics.");
|
|
|
- WEX::Logging::Log::Result(WEX::Logging::TestResults::Skipped);
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- std::shared_ptr<ShaderOpTestResult> test = RunShaderOpTest(pDevice, m_support, pStream, "Barycentrics", nullptr);
|
|
|
+void TestBarycentricVariant(bool checkOrdering, std::shared_ptr<ShaderOpTestResult> test){
|
|
|
MappedData data;
|
|
|
D3D12_RESOURCE_DESC &D = test->ShaderOp->GetResourceByName("RTarget")->Desc;
|
|
|
UINT width = (UINT)D.Width;
|
|
@@ -9011,7 +8996,7 @@ TEST_F(ExecutionTest, BarycentricsTest) {
|
|
|
UINT pixelSize = GetByteSizeForFormat(D.Format);
|
|
|
|
|
|
test->Test->GetReadBackData("RTarget", &data);
|
|
|
- //const uint8_t *pPixels = (uint8_t *)data.data();
|
|
|
+
|
|
|
const float *pPixels = (float *)data.data();
|
|
|
// Get the vertex of barycentric coordinate using VBuffer
|
|
|
MappedData triangleData;
|
|
@@ -9025,15 +9010,16 @@ TEST_F(ExecutionTest, BarycentricsTest) {
|
|
|
XMFLOAT2 p0(pTriangleData[0], pTriangleData[1]);
|
|
|
XMFLOAT2 p1(pTriangleData[triangleVertexSizeInFloat], pTriangleData[triangleVertexSizeInFloat + 1]);
|
|
|
XMFLOAT2 p2(pTriangleData[triangleVertexSizeInFloat * 2], pTriangleData[triangleVertexSizeInFloat * 2 + 1]);
|
|
|
-
|
|
|
+
|
|
|
+ // Seems like the 3 floats must add up to 1 to get accurate results.
|
|
|
XMFLOAT3 barycentricWeights[4] = {
|
|
|
- XMFLOAT3(0.3333f, 0.3333f, 0.3333f),
|
|
|
+ XMFLOAT3(0.4f, 0.2f, 0.4f),
|
|
|
XMFLOAT3(0.5f, 0.25f, 0.25f),
|
|
|
XMFLOAT3(0.25f, 0.5f, 0.25f),
|
|
|
XMFLOAT3(0.25f, 0.25f, 0.50f)
|
|
|
- };
|
|
|
+ };
|
|
|
|
|
|
- float tolerance = 0.001f;
|
|
|
+ float tolerance = 0.02f;
|
|
|
for (unsigned i = 0; i < sizeof(barycentricWeights) / sizeof(XMFLOAT3); ++i) {
|
|
|
float w0 = barycentricWeights[i].x;
|
|
|
float w1 = barycentricWeights[i].y;
|
|
@@ -9041,17 +9027,89 @@ TEST_F(ExecutionTest, BarycentricsTest) {
|
|
|
float x1 = w0 * p0.x + w1 * p1.x + w2 * p2.x;
|
|
|
float y1 = w0 * p0.y + w1 * p1.y + w2 * p2.y;
|
|
|
// map from x1 y1 to rtv pixels
|
|
|
- int pixelX = (int)((x1 + 1) * (width - 1) / 2);
|
|
|
- int pixelY = (int)((1 - y1) * (height - 1) / 2);
|
|
|
+ int pixelX = (int)round((x1 + 1) * (width - 1) / 2.0);
|
|
|
+ int pixelY = (int)round((1 - y1) * (height - 1) / 2.0);
|
|
|
int offset = pixelSize * (pixelX + pixelY * width) / sizeof(pPixels[0]);
|
|
|
LogCommentFmt(L"location %u %u, value %f, %f, %f", pixelX, pixelY, pPixels[offset], pPixels[offset + 1], pPixels[offset + 2]);
|
|
|
- VERIFY_IS_TRUE(CompareFloatEpsilon(pPixels[offset], w0, tolerance));
|
|
|
- VERIFY_IS_TRUE(CompareFloatEpsilon(pPixels[offset + 1], w1, tolerance));
|
|
|
- VERIFY_IS_TRUE(CompareFloatEpsilon(pPixels[offset + 2], w2, tolerance));
|
|
|
+ if (!checkOrdering){
|
|
|
+ VERIFY_IS_TRUE(CompareFloatEpsilon(pPixels[offset], w0, tolerance));
|
|
|
+ VERIFY_IS_TRUE(CompareFloatEpsilon(pPixels[offset + 1], w1, tolerance));
|
|
|
+ VERIFY_IS_TRUE(CompareFloatEpsilon(pPixels[offset + 2], w2, tolerance));
|
|
|
+ }
|
|
|
+ else{
|
|
|
+ // If the ordering constraint is met, then this pixel's RGBA should be all 1.0's
|
|
|
+ // since the shader only returns float4<1.0,1.0,1.0,1.0> when this condition is met.
|
|
|
+ VERIFY_IS_TRUE(CompareFloatEpsilon(pPixels[offset] , 0.0, tolerance));
|
|
|
+ VERIFY_IS_TRUE(CompareFloatEpsilon(pPixels[offset + 1], 0.5, tolerance));
|
|
|
+ VERIFY_IS_TRUE(CompareFloatEpsilon(pPixels[offset + 2], 1.0, tolerance));
|
|
|
+ VERIFY_IS_TRUE(CompareFloatEpsilon(pPixels[offset + 3], 1.0, tolerance));
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+st::ShaderOpTest::TInitCallbackFn MakeBarycentricsResourceInitCallbackFn(int &vertexShift){
|
|
|
+ return [&](LPCSTR Name, std::vector<BYTE>& Data, st::ShaderOp* pShaderOp) {
|
|
|
+ std::vector<float> bary = { 0.0f, 1.0f , 0.0f, 1.0f, 0.0f, 0.0f, 1.0f,
|
|
|
+ 1.0f, -1.0f , 0.0f, 0.0f, 1.0f, 0.0f, 1.0f,
|
|
|
+ -1.0f, -1.0f , 0.0f, 0.0f, 0.0f, 1.0f, 1.0f };
|
|
|
+ const int barysize = 21;
|
|
|
+
|
|
|
+ UNREFERENCED_PARAMETER(pShaderOp);
|
|
|
+ VERIFY_IS_TRUE(0 == _stricmp(Name, "VBuffer"));
|
|
|
+ size_t size = sizeof(float) * barysize;
|
|
|
+ Data.resize(size);
|
|
|
+ float* vb = (float*)Data.data();
|
|
|
+ for (size_t i = 0; i < barysize; ++i) {
|
|
|
+ float* p = &vb[i];
|
|
|
+ float tempfloat = bary[(i + (7 * vertexShift)) % barysize];
|
|
|
+ *p = tempfloat;
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+TEST_F(ExecutionTest, BarycentricsTest) {
|
|
|
+ WEX::TestExecution::SetVerifyOutput verifySettings(WEX::TestExecution::VerifyOutputSettings::LogOnlyFailures);
|
|
|
+ CComPtr<IStream> pStream;
|
|
|
+ ReadHlslDataIntoNewStream(L"ShaderOpArith.xml", &pStream);
|
|
|
+
|
|
|
+ CComPtr<ID3D12Device> pDevice;
|
|
|
+ if (!CreateDevice(&pDevice, D3D_SHADER_MODEL_6_1))
|
|
|
+ return;
|
|
|
+
|
|
|
+ if (!DoesDeviceSupportBarycentrics(pDevice)) {
|
|
|
+ WEX::Logging::Log::Comment(L"Device does not support barycentrics.");
|
|
|
+ WEX::Logging::Log::Result(WEX::Logging::TestResults::Skipped);
|
|
|
+ return;
|
|
|
}
|
|
|
- //SavePixelsToFile(pPixels, DXGI_FORMAT_R32G32B32A32_FLOAT, width, height, L"barycentric.bmp");
|
|
|
+
|
|
|
+ DXASSERT_NOMSG(pStream != nullptr);
|
|
|
+ std::shared_ptr<st::ShaderOpSet> ShaderOpSet =
|
|
|
+ std::make_shared<st::ShaderOpSet>();
|
|
|
+ st::ParseShaderOpSetFromStream(pStream, ShaderOpSet.get());
|
|
|
+ st::ShaderOp* pShaderOp =
|
|
|
+ ShaderOpSet->GetShaderOp("Barycentrics");
|
|
|
+
|
|
|
+ int test_iteration = 0;
|
|
|
+ auto ResourceCallbackFnNoShift = MakeBarycentricsResourceInitCallbackFn(test_iteration);
|
|
|
+
|
|
|
+ std::shared_ptr<ShaderOpTestResult> test = RunShaderOpTestAfterParse(pDevice, m_support, "Barycentrics", ResourceCallbackFnNoShift, ShaderOpSet);
|
|
|
+ TestBarycentricVariant(false, test);
|
|
|
+
|
|
|
+ // Now test that barycentric ordering is consistent
|
|
|
+ LogCommentFmt(L"Now testing that the barycentric ordering constraint is upheld for each pixel...");
|
|
|
+ pShaderOp->VS = pShaderOp->GetString("VSordering");
|
|
|
+ pShaderOp->PS = pShaderOp->GetString("PSordering");
|
|
|
+ for(; test_iteration < 3; test_iteration++)
|
|
|
+ {
|
|
|
+ auto ResourceCallbackFn = MakeBarycentricsResourceInitCallbackFn(test_iteration);
|
|
|
+
|
|
|
+ std::shared_ptr<ShaderOpTestResult> test2 = RunShaderOpTestAfterParse(pDevice, m_support, "Barycentrics", ResourceCallbackFn, ShaderOpSet);
|
|
|
+ TestBarycentricVariant(true, test2);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
+
|
|
|
static const char RawBufferTestShaderDeclarations[] =
|
|
|
"// Note: COMPONENT_TYPE and COMPONENT_SIZE will be defined via compiler option -D\r\n"
|
|
|
"typedef COMPONENT_TYPE scalar; \r\n"
|
|
@@ -11488,7 +11546,12 @@ TEST_F(ExecutionTest, IsNormalTest) {
|
|
|
st::ParseShaderOpSetFromStream(pStream, ShaderOpSet.get());
|
|
|
st::ShaderOp *pShaderOp = ShaderOpSet->GetShaderOp("IsNormal");
|
|
|
vector<st::ShaderOpRootValue> fallbackRootValues = pShaderOp->RootValues;
|
|
|
-
|
|
|
+
|
|
|
+ D3D_SHADER_MODEL sm = D3D_SHADER_MODEL_6_0;
|
|
|
+ LogCommentFmt(L"\r\nVerifying isNormal in shader "
|
|
|
+ L"model 6.%1u",
|
|
|
+ ((UINT)sm & 0x0f));
|
|
|
+
|
|
|
size_t count = Validation_Input->size();
|
|
|
|
|
|
auto ShaderInitFn = MakeShaderReplacementCallback(
|