diff options
| author | lucy96chen <47800040+lucy96chen@users.noreply.github.com> | 2022-10-12 14:41:22 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-10-12 14:41:22 -0700 |
| commit | 53b180a9383668246a152af41aec8f6e565904a4 (patch) | |
| tree | c034dc6584dd7dd7b5451d9fd8b3972e6b5d0106 | |
| parent | f0cd62b37c5dfbbdb3fb205f1be2b8beba0dfed4 (diff) | |
Add specialization args test (#2444)
* Added specialization args test; small cleanup changes to slang-digest.h
* Moved slang::Digest inside namespace Slang
| -rw-r--r-- | source/core/slang-digest.h | 8 | ||||
| -rw-r--r-- | source/slang/slang-hash-utils.h | 11 | ||||
| -rw-r--r-- | source/slang/slang.cpp | 9 | ||||
| -rw-r--r-- | tools/gfx-unit-test/shader-cache-tests.cpp | 125 |
4 files changed, 135 insertions, 18 deletions
diff --git a/source/core/slang-digest.h b/source/core/slang-digest.h index d1bc80b40..47c0cd8f7 100644 --- a/source/core/slang-digest.h +++ b/source/core/slang-digest.h @@ -4,6 +4,8 @@ namespace Slang { + using slang::Digest; + // Wrapper struct that holds objects necessary for hashing. struct DigestBuilder { @@ -19,9 +21,11 @@ namespace Slang hashGen.update(&context, item); } - void finalize(slang::Digest* outHash) + Digest finalize() { - hashGen.finalize(&context, outHash); + Digest hash; + hashGen.finalize(&context, &hash); + return hash; } private: diff --git a/source/slang/slang-hash-utils.h b/source/slang/slang-hash-utils.h index d0d610cb8..62232dd21 100644 --- a/source/slang/slang-hash-utils.h +++ b/source/slang/slang-hash-utils.h @@ -12,11 +12,7 @@ namespace Slang { DigestBuilder builder; builder.addToDigest(text); - - slang::Digest textHash; - builder.finalize(&textHash); - - return textHash; + return builder.finalize(); } // Combines the two provided hashes. @@ -25,10 +21,7 @@ namespace Slang DigestBuilder builder; builder.addToDigest(hashA); builder.addToDigest(hashB); - - slang::Digest combined; - builder.finalize(&combined); - return combined; + return builder.finalize(); } // Returns the stored hash in checksum as a String. diff --git a/source/slang/slang.cpp b/source/slang/slang.cpp index a6dcf8ab2..20cad2465 100644 --- a/source/slang/slang.cpp +++ b/source/slang/slang.cpp @@ -3482,19 +3482,14 @@ SLANG_NO_THROW void SLANG_MCALL ComponentType::computeDependencyBasedHash( auto entryPointNameOverride = getEntryPointNameOverride(entryPointIndex); builder.addToDigest(entryPointNameOverride); - slang::Digest hash; - builder.finalize(&hash); - *outHash = hash; + *outHash = builder.finalize(); } SLANG_NO_THROW void SLANG_MCALL ComponentType::computeASTBasedHash(slang::Digest* outHash) { DigestBuilder builder; updateASTBasedHash(builder); - - slang::Digest hash; - builder.finalize(&hash); - *outHash = hash; + *outHash = builder.finalize(); } SLANG_NO_THROW SlangResult SLANG_MCALL ComponentType::getEntryPointHostCallable( diff --git a/tools/gfx-unit-test/shader-cache-tests.cpp b/tools/gfx-unit-test/shader-cache-tests.cpp index 184b71c06..67d7289aa 100644 --- a/tools/gfx-unit-test/shader-cache-tests.cpp +++ b/tools/gfx-unit-test/shader-cache-tests.cpp @@ -574,6 +574,121 @@ namespace gfx_test } }; + // One shader featuring multiple kinds of shader objects that can be bound. + struct SpecializationArgsEntries : BaseShaderCacheTest + { + slang::ProgramLayout* slangReflection; + + void createAddTransformer(IShaderObject** transformer) + { + slang::TypeReflection* addTransformerType = + slangReflection->findTypeByName("AddTransformer"); + GFX_CHECK_CALL_ABORT(device->createShaderObject( + addTransformerType, ShaderObjectContainerType::None, transformer)); + + float c = 1.0f; + ShaderCursor(*transformer).getPath("c").setData(&c, sizeof(float)); + } + + void createMulTransformer(IShaderObject** transformer) + { + slang::TypeReflection* mulTransformerType = + slangReflection->findTypeByName("MulTransformer"); + GFX_CHECK_CALL_ABORT(device->createShaderObject( + mulTransformerType, ShaderObjectContainerType::None, transformer)); + + float c = 1.0f; + ShaderCursor(*transformer).getPath("c").setData(&c, sizeof(float)); + } + + void submitGPUWork(GfxIndex transformerType) + { + Slang::ComPtr<ITransientResourceHeap> transientHeap; + ITransientResourceHeap::Desc transientHeapDesc = {}; + transientHeapDesc.constantBufferSize = 4096; + GFX_CHECK_CALL_ABORT( + device->createTransientResourceHeap(transientHeapDesc, transientHeap.writeRef())); + + ICommandQueue::Desc queueDesc = { ICommandQueue::QueueType::Graphics }; + auto queue = device->createCommandQueue(queueDesc); + + auto commandBuffer = transientHeap->createCommandBuffer(); + auto encoder = commandBuffer->encodeComputeCommands(); + + auto rootObject = encoder->bindPipeline(pipelineState); + + ComPtr<IShaderObject> transformer; + switch (transformerType) + { + case 0: + createAddTransformer(transformer.writeRef()); + break; + case 1: + createMulTransformer(transformer.writeRef()); + break; + default: + /* Should not get here */ + SLANG_IGNORE_TEST; + } + + ShaderCursor entryPointCursor(rootObject->getEntryPoint(0)); + entryPointCursor.getPath("buffer").setResource(bufferView); + + entryPointCursor.getPath("transformer").setObject(transformer); + + encoder->dispatchCompute(1, 1, 1); + encoder->endEncoding(); + commandBuffer->close(); + queue->executeCommandBuffer(commandBuffer); + queue->waitOnHost(); + } + + void generateNewPipelineState() + { + ComPtr<IShaderProgram> shaderProgram; + + GFX_CHECK_CALL_ABORT(loadComputeProgram(device, shaderProgram, "compute-smoke", "computeMain", slangReflection)); + + ComputePipelineStateDesc pipelineDesc = {}; + pipelineDesc.program = shaderProgram.get(); + GFX_CHECK_CALL_ABORT( + device->createComputePipelineState(pipelineDesc, pipelineState.writeRef())); + } + + void run() + { + ComPtr<IShaderCacheStatistics> shaderCacheStats; + + // Due to needing a workaround to prevent loading old, outdated modules, we need to + // recreate the device between each segment of the test. However, we need to maintain the + // same cache filesystem for the duration of the test, so the device is immediately recreated + // to ensure we can pass the filesystem all the way through. + // + // TODO: Remove the repeated generateNewDevice() and createRequiredResources() calls once + // a solution exists that allows source code changes under the same module name to be picked + // up on load. + generateNewDevice(); + createRequiredResources(); + generateNewPipelineState(); + submitGPUWork(0); + + device->queryInterface(SLANG_UUID_IShaderCacheStatistics, (void**)shaderCacheStats.writeRef()); + SLANG_CHECK(shaderCacheStats->getCacheMissCount() == 1); + SLANG_CHECK(shaderCacheStats->getCacheHitCount() == 0); + SLANG_CHECK(shaderCacheStats->getCacheEntryDirtyCount() == 0); + + generateNewDevice(); + createRequiredResources(); + generateNewPipelineState(); + submitGPUWork(1); + + device->queryInterface(SLANG_UUID_IShaderCacheStatistics, (void**)shaderCacheStats.writeRef()); + SLANG_CHECK(shaderCacheStats->getCacheMissCount() == 1); + SLANG_CHECK(shaderCacheStats->getCacheHitCount() == 0); + SLANG_CHECK(shaderCacheStats->getCacheEntryDirtyCount() == 0); + } + }; + template <typename T> void shaderCacheTestImpl(ComPtr<IDevice> device, UnitTestContext* context) { @@ -621,4 +736,14 @@ namespace gfx_test { runTestImpl(shaderCacheTestImpl<ShaderFileImportsShaderCache>, unitTestContext, Slang::RenderApiFlag::Vulkan); } + + SLANG_UNIT_TEST(specializationArgsShaderCacheD3D12) + { + runTestImpl(shaderCacheTestImpl<SpecializationArgsEntries>, unitTestContext, Slang::RenderApiFlag::D3D12); + } + + SLANG_UNIT_TEST(specializationArgsShaderCacheVulkan) + { + runTestImpl(shaderCacheTestImpl<SpecializationArgsEntries>, unitTestContext, Slang::RenderApiFlag::Vulkan); + } } |
