| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974 |
- #include "dxc/Support/Global.h"
- #include "dxc/Support/Unicode.h"
- #include "dxc/Support/WinIncludes.h"
- #include "dxc/dxcapi.h"
- #include "dxc/Support/dxcapi.use.h"
- #include "dxc/Support/FileIOHelper.h"
- #include "dxc/Support/dxcapi.impl.h"
- #include "dxc/dxcdxrfallbackcompiler.h"
- #include "dxc/support/dxcapi.use.h"
- #include "llvm/IR/LLVMContext.h"
- #include "llvm/IR/Module.h"
- #include "llvm/Support/FileSystem.h"
- #include "llvm/Support/MSFileSystem.h"
- #include "defaultTestFilePath.h"
- #include "ShaderTester.h"
- #undef IGNORE
- #undef OPAQUE
- #include "testFiles/testTraversal.h"
- #include <algorithm>
- #include <iomanip>
- #include <iostream>
- #include <vector>
- using namespace dxc;
- using namespace llvm;
- using namespace hlsl;
- const int DEBUG_OUTPUT_LEVEL = 1;
- std::string ws2s(const std::wstring& wide)
- {
- return std::string(wide.begin(), wide.end());
- }
- std::wstring s2ws(const std::string& str)
- {
- return std::wstring(str.begin(), str.end());
- }
- void printErrors(CComPtr<IDxcOperationResult> pResult)
- {
- CComPtr<IDxcBlobEncoding> pErrorBuffer;
- IFT(pResult->GetErrorBuffer(&pErrorBuffer));
- const char *pStart = (const char *)pErrorBuffer->GetBufferPointer();
- std::string msg(pStart);
- std::cerr << msg;
- HRESULT status;
- pResult->GetStatus(&status);
- //IFTMSG(status, msg);
- }
- void CompileToDxilFromFile(DxcDllSupport& dxcSupport, LPCWSTR pShaderTextFilePath, LPCWSTR pEntryPoint, LPCWSTR pTargetProfile, LPCWSTR* pArgs, UINT32 argCount, const DxcDefine *pDefines, UINT32 defineCount, IDxcBlob **ppBlob)
- {
- CComPtr<IDxcLibrary> pLibrary;
- IFT(dxcSupport.CreateInstance(CLSID_DxcLibrary, &pLibrary));
- CComPtr<IDxcIncludeHandler> dxcIncludeHandler;
- IFT(pLibrary->CreateIncludeHandler(&dxcIncludeHandler));
- UINT32 codePage(0);
- CComPtr<IDxcBlobEncoding> pTextBlob(nullptr);
- IFT(pLibrary->CreateBlobFromFile(pShaderTextFilePath, &codePage, &pTextBlob));
- CComPtr<IDxcCompiler> pCompiler;
- IFT(dxcSupport.CreateInstance(CLSID_DxcCompiler, &pCompiler));
- CComPtr<IDxcOperationResult> pResult;
- IFT(pCompiler->Compile(pTextBlob, pShaderTextFilePath, pEntryPoint, pTargetProfile, pArgs, argCount, pDefines, defineCount, dxcIncludeHandler, &pResult));
- HRESULT resultCode;
- CComPtr<IDxcBlobEncoding> pErrorBuffer;
- IFT(pResult->GetStatus(&resultCode));
- IFT(pResult->GetErrorBuffer(&pErrorBuffer));
- if (SUCCEEDED(resultCode))
- {
- IFT(pResult->GetResult((IDxcBlob **)ppBlob));
- }
- else
- {
- printErrors(pResult);
- }
- }
- bool DxrCompile(
- DxcDllSupport& dxrFallbackSupport,
- const std::string& entryName,
- std::vector<IDxcBlob*>& libs,
- const std::vector<std::string>& shaderNames,
- std::vector<DxcShaderInfo>& shaderIds,
- bool findCalledShaders,
- IDxcBlob** ppResultBlob)
- {
- CComPtr<IDxcDxrFallbackCompiler> pCompiler;
- IFT(dxrFallbackSupport.CreateInstance(CLSID_DxcDxrFallbackCompiler, &pCompiler));
- std::vector<std::wstring> shaderNamesW(shaderNames.size());
- std::vector<LPCWSTR> shaderNamePtrs(shaderNames.size());
- for (size_t i = 0; i < shaderNames.size(); ++i)
- {
- shaderNamesW[i] = s2ws(shaderNames[i]);
- shaderNamePtrs[i] = shaderNamesW[i].c_str();
- }
- const UINT maxAttributeSize = 32;
- shaderIds.resize(shaderNames.size());
- CComPtr<IDxcOperationResult> pCompileResult;
- CComPtr<IDxcBlob> pCompiledCollection;
- std::vector<DxcShaderBytecode> bytecode(libs.size());
- for (UINT i = 0; i < libs.size(); i++)
- {
- bytecode[i] = { (LPBYTE)libs[i]->GetBufferPointer(), (UINT32)libs[i]->GetBufferSize() };
- }
- IFT(pCompiler->SetFindCalledShaders(findCalledShaders));
- IFT(pCompiler->SetDebugOutput(DEBUG_OUTPUT_LEVEL));
- IFT(pCompiler->Compile(
- bytecode.data(), libs.size(),
- shaderNamePtrs.data(), shaderIds.data(), shaderNamePtrs.size(), maxAttributeSize,
- &pCompileResult));
- pCompileResult->GetResult(&pCompiledCollection);
- IDxcBlob *compiledCollections[] = { pCompiledCollection };
- CComPtr<IDxcOperationResult> pResult;
- IFT(pCompiler->Link(
- s2ws(entryName).c_str(),
- compiledCollections, ARRAYSIZE(compiledCollections),
- shaderNamePtrs.data(), shaderIds.data(), shaderNamePtrs.size(),
- maxAttributeSize,
- 1024,
- &pResult));
- HRESULT status;
- IFT(pResult->GetStatus(&status));
- IFT(pResult->GetResult(ppResultBlob));
- if (SUCCEEDED(status))
- {
- return true;
- }
- else
- {
- std::cerr << "Compile errors\n";
- printErrors(pResult);
- return false;
- }
- }
- class Tester
- {
- public:
- Tester(const std::string& deviceName, const std::string& path)
- : m_deviceName(s2ws(deviceName))
- , m_path(path)
- {
- dxc::EnsureEnabled(m_dxcSupport);
- m_dxrFallbackSupport.InitializeForDll(L"DxrFallbackCompiler.dll", "DxcCreateDxrFallbackCompiler");
- }
- void setFiles(const std::vector<std::string>& files)
- {
- std::vector<std::string> filesWithLib(files);
- filesWithLib.push_back(m_testLibFilename);
- m_inputBlobs.clear();
- m_inputBlobPtrs.clear();
- for (auto& filename : filesWithLib)
- {
- CComPtr<IDxcBlob> pInput;
- LPCWSTR args[] = { L"-O3" };
- CompileToDxilFromFile(m_dxcSupport, s2ws(m_path + filename).c_str(), L"", L"lib_6_3", args, _countof(args), nullptr, 0, &pInput);
- m_inputBlobs.push_back(pInput);
- m_inputBlobPtrs.push_back(pInput);
- }
- }
- protected:
- DxcDllSupport m_dxcSupport;
- DxcDllSupport m_dxrFallbackSupport;
- std::wstring m_deviceName;
- std::vector<CComPtr<IDxcBlob>> m_inputBlobs;
- std::vector<IDxcBlob*> m_inputBlobPtrs;
- std::string m_path;
- std::string m_testLibFilename = "testLib.hlsl";
- std::string m_entryName = "CSMain";
- int runTest(CComPtr<IDxcBlob> pShader, int initialShaderId, const std::vector<int>& input, const std::vector<int>& expectedOutput)
- {
- std::vector<int> output;
- std::unique_ptr<ShaderTester> tester(ShaderTester::New(pShader));
- tester->setDevice(m_deviceName);
- tester->runShader(initialShaderId, input, output);
- int numFailed = checkResult(output, expectedOutput) ? 0 : 1;
- if (numFailed)
- {
- std::cout << "input:";
- for (size_t i = 0; i < input.size(); ++i)
- std::cout << " " << input[i];
- std::cout << "\n";
- }
- std::cout << "\n";
- return numFailed;
- }
- bool checkResult(const std::vector<int>& output, const std::vector<int>& expectedOutput)
- {
- int count = output.empty() ? 0 : output[0];
- std::cout << count << ": ";
- // print result
- for (int i = 0; i < count; ++i)
- std::cout << output[i + 1] << " ";
- std::cout << "\n";
- bool passed = false;
- if (count == expectedOutput.size())
- {
- passed = true;
- for (size_t i = 0; i < expectedOutput.size(); ++i)
- {
- if (output[i + 1] != expectedOutput[i])
- {
- passed = false;
- break;
- }
- }
- }
- if (!passed)
- {
- std::cout << expectedOutput.size() << ": ";
- for (size_t i = 0; i < expectedOutput.size(); ++i)
- std::cout << expectedOutput[i] << " ";
- std::cout << "\n";
- }
- std::cout << (passed ? "PASSED" : "FAILED") << "\n";
- return passed;
- }
- };
- class RtCompilerTester : public Tester
- {
- public:
- struct TestWithEntryPoint
- {
- std::string entryPoint;
- std::vector<int> expectedOutput;
- };
- RtCompilerTester(const std::string& deviceName, const std::string& path)
- : Tester(deviceName, path)
- {}
- // Returns the number of failures
- int runTestsWithEntryPoints(const std::vector<TestWithEntryPoint>& tests)
- {
- int numFailed = 0;
- for (auto& test : tests)
- {
- std::cout << test.entryPoint << "\n";
- std::vector<std::string> shaderNames = { test.entryPoint };
- std::vector<int> input;
- std::vector<DxcShaderInfo> shaderIds;
- CComPtr<IDxcBlob> pComputeShader;
- if (DxrCompile(m_dxrFallbackSupport, m_entryName, m_inputBlobPtrs, shaderNames, shaderIds, true, &pComputeShader))
- numFailed += runTest(pComputeShader, shaderIds[0].Identifier, input, test.expectedOutput);
- }
- return numFailed;
- }
- // The first shader is the entry shader. The shaderId of the shader at
- // indirectShaderIdx is placed in const memory.
- //
- // Returns the number of failures.
- int runSingleTest(const std::vector<std::string>& shaderNames, const std::vector<int>& input, const std::vector<int>& expectedOutput)
- {
- std::vector<DxcShaderInfo> shaderIds(shaderNames.size());
- CComPtr<IDxcBlob> pComputeShader;
- if (!DxrCompile(m_dxrFallbackSupport, m_entryName, m_inputBlobPtrs, shaderNames, shaderIds, false, &pComputeShader))
- return 1;
- for (size_t i = 0; i < shaderNames.size(); ++i)
- std::cout << shaderNames[i] << ":" << shaderIds[i].Identifier << " ";
- std::cout << "\n";
- return runTest(pComputeShader, shaderIds[0].Identifier, input, expectedOutput);
- }
- void compileTest(const std::vector<std::string>& shaderNames, const std::string& entryName)
- {
- std::vector<DxcShaderInfo> shaderIds(shaderNames.size());
- CComPtr<IDxcBlob> pOutput;
- if (DxrCompile(m_dxrFallbackSupport, entryName, m_inputBlobPtrs, shaderNames, shaderIds, false, &pOutput))
- std::cout << "Compile succeeded\n";
- else
- std::cout << "Compile failed\n";
- for (size_t i = 0; i < shaderNames.size(); ++i)
- std::cout << shaderNames[i] << ":" << shaderIds[i].Identifier << " ";
- std::cout << "\n";
- }
- };
- int asint(float v)
- {
- return *(int*)&v;
- }
- float asfloat(int v)
- {
- return *(float*)&v;
- }
- class Leaf
- {
- public:
- int leafType;
- };
- class Instance : public Leaf
- {
- public:
- int instIdx;
- int instId;
- int instFlags;
- };
- class Primitive : public Leaf
- {
- public:
- int primIdx;
- int geomIdx;
- int geomOpaque;
- };
- class Triangle : public Primitive
- {
- public:
- float t, u, v, d;
- int anyHitRet;
- };
- class Custom : public Primitive
- {
- public:
- struct Hit
- {
- float t;
- int hitKind;
- int attr0, attr1;
- int anyHitRet;
- };
- std::vector<Hit> hits;
- };
- Instance* inst(int instFlags = 0, int instIdx = 0, int instId = 0)
- {
- Instance* inst = new Instance; // TODO: make this not leak
- inst->leafType = LEAF_INST;
- inst->instFlags = instFlags;
- inst->instIdx = instIdx;
- inst->instId = instId;
- return inst;
- }
- Triangle* tri(float t, float u, float v, int anyHitRet = OPAQUE, float d = 1, int primIdx = 0, int geomIdx = 0)
- {
- Triangle* tri = new Triangle; // TODO: make this not leak
- tri->leafType = LEAF_TRIS;
- tri->t = t;
- tri->u = u;
- tri->v = v;
- tri->d = d;
- tri->anyHitRet = anyHitRet;
- tri->primIdx = primIdx;
- tri->geomIdx = geomIdx;
- tri->geomOpaque = (anyHitRet == OPAQUE);
- return tri;
- }
- Custom* custom(const std::vector<Custom::Hit>& hits, int geomOpaque = 0, int primIdx = 0, int geomIdx = 0)
- {
- Custom* c = new Custom;
- c->hits = hits;
- c->leafType = LEAF_CUSTOM;
- c->primIdx = primIdx;
- c->geomIdx = geomIdx;
- c->geomOpaque = geomOpaque;
- return c;
- }
- struct Payload
- {
- int val;
- int primIdx;
- float t;
- bool operator!=(const Payload& other)
- {
- return this->val != other.val || this->primIdx != other.primIdx || this->t != other.t;
- }
- };
- std::ostream& operator<<(std::ostream& out, Payload payload)
- {
- out << "{" << payload.val << "," << payload.primIdx << "}";
- return out;
- }
- class TestData
- {
- public:
- std::string name;
- std::vector<int> input;
- std::vector<int> expected;
- std::vector<std::string> shaders;
- std::map<std::string, std::vector<int> > shaderIdSlots;
- static int count;
- TestData(const std::string& name) : name(name) { count++; }
- void setShaderIds(std::vector<DxcShaderInfo>& shaderIds)
- {
- for (size_t i = 0; i < shaders.size(); ++i)
- {
- for (auto& slot : shaderIdSlots[shaders[i]])
- input[slot] = shaderIds[i].Identifier;
- }
- }
- struct CommittedPrim
- {
- const Primitive* prim;
- float t;
- const Custom::Hit* hit;
- };
- void simulate(Payload expectedPayload, const std::vector<Leaf*>& leaves, int rayFlags = 0)
- {
- shaders = { "raygen", "chTri", "ahTri", "intersection", "ahCustom", "chCustom", "miss", "Fallback_TraceRay" };
- expect(RAYGEN);
- Payload payload = { 1000, -1 };
- traceRay(rayFlags);
- expect(TRACERAY);
- bool terminate = false;
- CommittedPrim committed = { nullptr, -1, nullptr };
- int instIdx = -1, instId = 0, instFlags = 0;
- for (Leaf* leaf : leaves)
- {
- if (leaf->leafType == LEAF_INST)
- {
- const Instance* i = (Instance*)(leaf); // TODO: Why does dynamic_cast<Instance*> not work here?
- instIdx = i->instIdx;
- instId = i->instId;
- instFlags = i->instFlags;
- leafInst(instIdx, instId, instFlags);
- }
- else
- {
- const Primitive* prim = (Primitive*)leaf;
- leafPrim(prim);
- bool opaque = isOpaque(prim->geomOpaque, instFlags, rayFlags);
- if (cull(opaque, rayFlags))
- continue;
- if (leaf->leafType == LEAF_TRIS)
- {
- const Triangle* tri = (Triangle*)leaf;
- triangle(tri);
- float d = (instFlags & INSTANCE_FLAG_TRIANGLE_FRONT_COUNTERCLOCKWISE) ? -tri->d : tri->d;
- if (committed.prim && (tri->t >= committed.t) || -d * computeCullFaceDir(instFlags, rayFlags) < 0)
- continue;
- if (opaque)
- {
- committed = { tri, tri->t, nullptr };
- }
- else
- {
- shader("ahTri");
- expect({ ANYHIT, (int)tri->u, (int)tri->v });
- payload.val += 100;
- anyHitRet(tri->anyHitRet);
- if (tri->anyHitRet == TERMINATE)
- {
- committed = { tri, tri->t, nullptr };
- terminate = true;
- break;
- }
- else if (tri->anyHitRet == IGNORE)
- {
- // do nothing
- }
- else // ACCEPT)
- {
- committed = { tri, tri->t, nullptr };
- }
- }
- }
- else if (leaf->leafType == LEAF_CUSTOM)
- {
- const Custom* c = (Custom*)leaf;
- shader("ahCustom");
- shader("intersection");
- expect(INTERSECT + 1);
- for (auto& hit : c->hits)
- {
- customHit(hit);
- if (committed.prim && hit.t >= committed.t)
- continue;
- if (!opaque)
- {
- expect({ ANYHIT + 1, hit.attr0, hit.attr1 });
- payload.val += 100;
- anyHitRet(hit.anyHitRet);
- if (hit.anyHitRet == TERMINATE)
- {
- committed = { c, hit.t, &hit };
- terminate = true;
- break;
- }
- else if (hit.anyHitRet == IGNORE)
- {
- // do nothing
- continue;
- }
- // ACCEPT - fall through
- }
- committed = { c, hit.t, &hit };
- if (rayFlags & RAY_FLAG_TERMINATE_ON_FIRST_HIT)
- {
- terminate = true;
- break;
- }
- }
- if (!terminate)
- endHits();
- }
- }
- if ((rayFlags & RAY_FLAG_TERMINATE_ON_FIRST_HIT) && committed.prim)
- {
- terminate = true;
- break;
- }
- }
- if (!terminate)
- {
- if (instIdx != -1)
- endAccel();
- endAccel();
- }
- if (!(committed.prim && (rayFlags & RAY_FLAG_SKIP_CLOSEST_HIT_SHADER)))
- {
- const char* ch = "chTri";
- if (committed.prim && committed.prim->leafType == LEAF_CUSTOM)
- ch = "chCustom";
- shade(ch, "miss");
- if (committed.prim)
- {
- if (committed.prim->leafType == LEAF_TRIS)
- {
- Triangle* tri = (Triangle*)committed.prim;
- expect({ CLOSESTHIT, (int)tri->u, (int)tri->v });
- }
- else
- {
- expect({ CLOSESTHIT + 1, committed.hit->attr0, committed.hit->attr1 });
- }
- payload.val += 10;
- payload.primIdx = committed.prim->primIdx;
- }
- else
- {
- expect(MISS);
- payload.val += 1;
- }
- }
- expect(payload.val);
- expect(payload.primIdx);
- if (payload != expectedPayload)
- std::cout << count << ": simulated payload " << payload << " does not match expected " << expectedPayload << "\n";
- }
- void traceRay(unsigned rayFlags)
- {
- input.push_back(rayFlags);
- }
- void shade(const std::string& closestHit, const std::string& miss)
- {
- shader(closestHit);
- shader(miss);
- }
- void leafPrim(const Primitive* prim)
- {
- input.push_back(prim->leafType);
- input.push_back(pack(prim->primIdx, prim->geomIdx, prim->geomOpaque));
- }
- void triangle(const Triangle* tr)
- {
- input.push_back(asint(tr->t));
- input.push_back(asint(tr->u));
- input.push_back(asint(tr->v));
- input.push_back(asint(tr->d));
- }
- void customHit(const Custom::Hit& hit)
- {
- input.push_back(asint(hit.t));
- input.push_back(hit.hitKind);
- input.push_back(hit.attr0);
- input.push_back(hit.attr1);
- }
- void leafInst(int instIdx, int instId, int instFlags)
- {
- input.push_back(LEAF_INST);
- input.push_back(instIdx);
- input.push_back(instId);
- input.push_back(instFlags);
- }
- void shader(const std::string& shaderName)
- {
- shaderIdSlots[shaderName].push_back(input.size()); // fix up later
- input.push_back(-1);
- }
- void anyHitRet(int val)
- {
- input.push_back(val);
- }
- void endHits()
- {
- input.push_back(-1);
- }
- void endAccel()
- {
- input.push_back(LEAF_DONE);
- }
- void expect(int val)
- {
- expected.push_back(val);
- }
- void expect(const std::vector<int>& vals)
- {
- expected.insert(expected.end(), vals.begin(), vals.end());
- }
- void expect(float val)
- {
- expected.push_back(asint(val));
- }
- };
- int TestData::count = -1;
- class TraversalTester : public Tester
- {
- public:
- TraversalTester(const std::string& deviceName, const std::string& path)
- : Tester(deviceName, path)
- {
- setFiles({ "testTraversal.hlsl", "testTraversal2.hlsl" });
- }
- int run(const std::vector<TestData*>& tests)
- {
- int failedTests = 0;
- int testIndex = 0;
- for (auto td : tests)
- {
- std::cout << testIndex++ << " " << td->name << std::endl;
- std::vector<DxcShaderInfo> shaderIds(td->shaders.size());
- CComPtr<IDxcBlob> pComputeShader;
- if (!DxrCompile(m_dxrFallbackSupport, m_entryName, m_inputBlobPtrs, td->shaders, shaderIds, false, &pComputeShader))
- {
- failedTests++;
- continue;
- }
- td->setShaderIds(shaderIds);
- for (size_t i = 0; i < td->shaders.size(); ++i)
- std::cout << td->shaders[i] << ":" << shaderIds[i].Identifier << " ";
- std::cout << "\n";
- failedTests += runTest(pComputeShader, shaderIds[0].Identifier, td->input, td->expected);
- delete td;
- }
- return failedTests;
- }
- };
- TestData* test_nohit(Payload expectedPayload)
- {
- TestData* td = new TestData("nohit");
- td->simulate(expectedPayload, {});
- return td;
- }
- TestData* test_instance_nohit(Payload expectedPayload)
- {
- TestData* td = new TestData("instance_nohit");
- td->simulate(expectedPayload, { inst() });
- return td;
- }
- TestData* test_tri(Payload expectedPayload, int anyHitRet, int instFlags = 0, int rayFlags = 0, float d = 1)
- {
- TestData* td = new TestData("trihit");
- td->simulate(
- expectedPayload,
- {
- inst(instFlags),
- tri(1, 55, 66, anyHitRet, d),
- },
- rayFlags
- );
- return td;
- }
- struct TriHit
- {
- int anyHitRet;
- float t;
- };
- TestData* test_2tri(Payload expectedPayload, const TriHit& tri0, const TriHit& tri1, int rayFlags = 0)
- {
- TestData* td = new TestData("trihit2");
- td->simulate(
- expectedPayload,
- {
- inst(),
- tri(tri0.t, (expectedPayload.primIdx == 0) ? 5555 : 55, 66, tri0.anyHitRet, 1, 0),
- tri(tri1.t, (expectedPayload.primIdx == 1) ? 5555 : 56, 67, tri1.anyHitRet, 1, 1),
- },
- rayFlags
- );
- return td;
- }
- struct CustomHit2
- {
- int anyHitRet;
- float t;
- };
- TestData* test_custom(Payload expectedPayload, int geomOpaque, const std::vector<CustomHit2> hits, int instFlags = 0, int rayFlags = 0)
- {
- TestData* td = new TestData("custom");
- std::vector<Custom::Hit> customHits;
- for (size_t i = 0; i < hits.size(); ++i)
- {
- const CustomHit2& h = hits[i];
- customHits.push_back({ h.t, 33, int(55 + i), int(66 + i), h.anyHitRet });
- }
- td->simulate(
- expectedPayload,
- {
- inst(instFlags),
- custom(customHits, geomOpaque),
- },
- rayFlags
- );
- return td;
- }
- void printUsageAndExit()
- {
- std::cerr
- << "Options:\n"
- << " -h | --help Print this message\n"
- << " -d | --device <name> Name of device to use. Can be a prefix, e.g. WARP, AMD, etc.\n"
- << " -p | --path <directory> Base path for test input files.\n"
- << std::endl;
- exit(1);
- }
- int main(int argc, const char* argv[])
- {
- std::string deviceName = "";
- std::string basePath = DEFAULT_TEST_FILE_PATH;
- // Parse arguments
- std::vector<std::string> args;
- for (int i = 1; i < argc; ++i)
- args.push_back(argv[i]);
- for (size_t i = 0; i < args.size(); ++i)
- {
- if (args[i] == "-h" || args[i] == "--help")
- {
- printUsageAndExit();
- }
- else if (args[i] == "-d" || args[i] == "--device")
- {
- deviceName = args[++i];
- }
- else if (args[i] == "-p" || args[i] == "--path")
- {
- basePath = args[++i];
- }
- else
- {
- std::cerr << "Bad arg:" << args[i] << std::endl;
- printUsageAndExit();
- }
- }
- try
- {
- if (!deviceName.empty())
- std::cout << "Testing on device " << deviceName << std::endl;
- int numFailed = 0;
- if (1)
- {
- RtCompilerTester tester(deviceName, basePath);
- tester.setFiles({ "testShader1.hlsl", "testShader2.hlsl" });
- numFailed += tester.runTestsWithEntryPoints({
- {"no_call", {1, 1}},
- {"no_live_values", {1, 1, -99, 2, 2}},
- {"single_call", {-99, 1, 1}},
- {"single_call_in", {10}},
- {"single_call_out", {-99, 64, 64}},
- {"single_call_inout", {10, 64, 64}},
- {"single_call_inout_passthru", {-98, 10, 64, 64}},
- {"types", {-99, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8}},
- {"multiple_calls", {-99, 1, 1, -99, 4, 4, 2, 2}},
- {"multiple_calls_with_args", {1, 1, -99, 1, 1, -99, 2, 2, 3, 3}},
- {"branch", {-99, 64, 64}},
- {"no_branch", {10, 10}},
- {"loop", {-99, 1, 1, -99, -99, -99, -99, 5, 5}},
- {"recursive", {5, 5, 4, 4, 3, 3, 2, 2, 1, 1, 0, 0, 1, 1}},
- {"use_buffer", {-99, 10, 10}},
- {"lower_intrinsics", {-99, 0, 0}},
- {"local_array", {-99, 4, 4}},
- {"dispatch_idx_and_dims", {0, 0, 1, 1}},
- });
- numFailed += tester.runSingleTest({ "indirect", "indirect_callee" }, { 1002 }, { -99 });
- numFailed += tester.runSingleTest({ "raygen_tri", "chTri", "intersection", "continuation", "Fallback_TraceRay" }, { 1002 }, { -98, -97, 555, 666, -99, 1010 });
- numFailed += tester.runSingleTest({ "raygen_custom", "chCustom1", "chCustom2", "intersection", "continuation", "Fallback_TraceRay" }, { 1003, 1005 }, { -98, -95, 19, 10, 11, 12, 13, -100, -99, 500, -96, 333, 444, -99, 1010, -98, -95, 59, 50, 51, 52, 53, -100, -99, 500, -96, 333, 444, -99, 1110 });
- tester.setFiles({ "testShader3.hlsl" });
- numFailed += tester.runSingleTest({ "pass_struct", "Fallback_TraceRay" }, {}, { -99, 1, 2, 3, 4, 5, 6, 7, 8, 11 });
- tester.setFiles({ "testShader4.hlsl" });
- numFailed += tester.runSingleTest({ "full_trace_ray", "Fallback_TraceRay" }, {}, { 1, 2, 3, 4, 5, 6, 7, 8, 11, 12, 13, 14, 15 });
- tester.setFiles({ "testShader5.hlsl" });
- numFailed += tester.runSingleTest({ "raygen", "ch1", "ch2", "miss1", "miss2", "Fallback_TraceRay" }, {1002, 1005, 1007, 1009, 1009}, {-99, 100,0, -99,101,1, -99,102,2, -99,103,3, 2, 1, 0, -99,103,4, 0, 21111});
- }
- if (1)
- {
- // Expected payload is the number of invocations in the following shader types:
- // RG AH CH MS
- // These counts are store in each digit.
- TraversalTester tester(deviceName, basePath);
- numFailed += tester.run({
- test_nohit({1001,-1}),
- test_instance_nohit({1001,-1}),
- test_tri({1010, 0}, OPAQUE),
- test_tri({1110, 0}, ACCEPT),
- test_tri({1101,-1}, IGNORE),
- test_tri({1110, 0}, TERMINATE),
- test_tri({1001,-1}, OPAQUE, 0, RAY_FLAG_CULL_OPAQUE), // culling
- test_tri({1010, 0}, OPAQUE, 0, 0, -1), // flipping direction doesn't matter without culling flags
- test_tri({1001,-1}, OPAQUE, 0, RAY_FLAG_CULL_FRONT_FACING_TRIANGLES, 1), // triangle culling
- test_tri({1001,-1}, OPAQUE, 0, RAY_FLAG_CULL_BACK_FACING_TRIANGLES, -1), // triangle culling
- test_tri({1010, 0}, OPAQUE, INSTANCE_FLAG_TRIANGLE_CULL_DISABLE, RAY_FLAG_CULL_BACK_FACING_TRIANGLES, -1), // disable triangle culling
- test_tri({1010, 0}, OPAQUE, INSTANCE_FLAG_TRIANGLE_FRONT_COUNTERCLOCKWISE, 1), // flip winding
- test_tri({1001,-1}, OPAQUE, INSTANCE_FLAG_TRIANGLE_FRONT_COUNTERCLOCKWISE, RAY_FLAG_CULL_BACK_FACING_TRIANGLES, 1),
- test_tri({1010, 0}, ACCEPT, INSTANCE_FLAG_FORCE_OPAQUE),
- test_tri({1010, 0}, ACCEPT, 0, RAY_FLAG_FORCE_OPAQUE),
- test_tri({1110, 0}, OPAQUE, INSTANCE_FLAG_FORCE_NON_OPAQUE),
- test_tri({1110, 0}, OPAQUE, 0, RAY_FLAG_FORCE_NON_OPAQUE),
- test_tri({1010, 0}, ACCEPT, INSTANCE_FLAG_FORCE_NON_OPAQUE, RAY_FLAG_FORCE_OPAQUE), // ray flags opaque overrides instance
- test_tri({1110, 0}, OPAQUE, INSTANCE_FLAG_FORCE_OPAQUE, RAY_FLAG_FORCE_NON_OPAQUE), // ray flags opaque overrides instance
- test_tri({1010, 0}, OPAQUE, INSTANCE_FLAG_TRIANGLE_CULL_DISABLE, 0, -1), // disable cull
- test_tri({1000,-1}, OPAQUE, 0, RAY_FLAG_SKIP_CLOSEST_HIT_SHADER),
- test_2tri({1010, 0}, {OPAQUE, 1}, {OPAQUE, 2}), // pick closest (first)
- test_2tri({1010, 1}, {OPAQUE, 2}, {OPAQUE, 1}), // pick closest (second)
- test_2tri({1010, 0}, {OPAQUE, 2}, {OPAQUE, 1}, RAY_FLAG_TERMINATE_ON_FIRST_HIT),
- test_2tri({1110, 0}, {ACCEPT, 1}, {ACCEPT, 2}), // pick closest (first)
- test_2tri({1210, 1}, {ACCEPT, 2}, {ACCEPT, 1}), // pick closest (second)
- test_2tri({1110, 0}, {ACCEPT, 2}, {ACCEPT, 1}, RAY_FLAG_TERMINATE_ON_FIRST_HIT),
- test_2tri({1210, 1}, {IGNORE, 1}, {ACCEPT, 2}), // ignore first (even though closer)
- test_2tri({1210, 0}, {ACCEPT, 2}, {IGNORE, 1}), // ignore second (even though closer)
- test_2tri({1110, 0}, {TERMINATE, 2}, {ACCEPT, 1}),
- test_custom({1010, 0}, 1, {{ACCEPT, 1}}),
- test_custom({1110, 0}, 0, {{ACCEPT, 1}}),
- test_custom({1101,-1}, 0, {{IGNORE, 1}}),
- test_custom({1110, 0}, 0, {{TERMINATE, 1}}),
- test_custom({1110, 0}, 0, {{ACCEPT, 1}, {ACCEPT, 2}}), // closest first - no anyhit for second
- test_custom({1210, 0}, 0, {{ACCEPT, 2}, {ACCEPT, 1}}), // closest second
- test_custom({1210, 0}, 0, {{IGNORE, 1}, {ACCEPT, 2}}), // ignore closer hit
- test_custom({1201,-1}, 0, {{IGNORE, 2}, {IGNORE, 1}}), // ignore both
- test_custom({1201,-1}, 0, {{IGNORE, 1}, {IGNORE, 2}}), // ignore both - anyhit for both
- test_custom({1110, 0}, 0, {{TERMINATE, 2}, {ACCEPT, 1}}), // terminate ==> don't handle second
- test_custom({1001,-1}, 1, {{ACCEPT, 1}}, 0, RAY_FLAG_CULL_OPAQUE),
- test_custom({1110, 0}, 0, {{ACCEPT, 1}}, 0, RAY_FLAG_CULL_OPAQUE), // no effect on non-opaque
- test_custom({1010, 0}, 1, {{ACCEPT, 1}}, 0, RAY_FLAG_CULL_NON_OPAQUE), // no effect on non-opaque
- test_custom({1001,-1}, 0, {{ACCEPT, 1}}, 0, RAY_FLAG_CULL_NON_OPAQUE),
- test_custom({1010, 0}, 0, {{IGNORE, 1}}, INSTANCE_FLAG_FORCE_OPAQUE), //no anyhit
- test_custom({1010, 0}, 0, {{IGNORE, 1}}, 0, RAY_FLAG_FORCE_OPAQUE),
- test_custom({1101,-1}, 1, {{IGNORE, 1}}, INSTANCE_FLAG_FORCE_NON_OPAQUE), // anyhit drops the hit
- test_custom({1101,-1}, 1, {{IGNORE, 1}}, 0, RAY_FLAG_FORCE_NON_OPAQUE),
- test_custom({1010, 0}, 0, {{IGNORE, 1}}, INSTANCE_FLAG_FORCE_NON_OPAQUE, RAY_FLAG_FORCE_OPAQUE), // ray flags opaque overrides instance
- test_custom({1101,-1}, 1, {{IGNORE, 1}}, INSTANCE_FLAG_FORCE_OPAQUE, RAY_FLAG_FORCE_NON_OPAQUE), // ray flags opaque overrides instance
- test_custom({1001,-1}, 0, {{ACCEPT, 1}}, INSTANCE_FLAG_FORCE_OPAQUE, RAY_FLAG_CULL_OPAQUE),
- test_custom({1100,-1}, 0, {{ACCEPT, 1}}, 0, RAY_FLAG_SKIP_CLOSEST_HIT_SHADER),
- test_custom({1210, 0}, 0, {{IGNORE, 3}, {ACCEPT,2}, {ACCEPT, 1}}, 0, RAY_FLAG_TERMINATE_ON_FIRST_HIT),
- });
- }
- std::cout << "===============================================\n";
- if (numFailed == 0)
- std::cout << "PASSED\n";
- else
- {
- std::cout << "FAILED\n";
- std::cout << numFailed << " tests failed\n";
- }
- }
- catch (...)
- {
- printf("Failed - unknown error.\n");
- return 1;
- }
- }
|