summaryrefslogtreecommitdiff
path: root/tools/gfx-unit-test
diff options
context:
space:
mode:
authorEllie Hermaszewska <ellieh@nvidia.com>2024-10-29 14:49:26 +0800
committerGitHub <noreply@github.com>2024-10-29 14:49:26 +0800
commitf65d756bff8d4c5cbc15bd0322a2ae8e6b896a21 (patch)
treeea1d61342cd29368e19135000ec2948813096205 /tools/gfx-unit-test
parenta729c15e9dce9f5116a38afc66329ab2ca4cea54 (diff)
format
* format * Minor test fixes * enable checking cpp format in ci
Diffstat (limited to 'tools/gfx-unit-test')
-rw-r--r--tools/gfx-unit-test/buffer-barrier-test.cpp298
-rw-r--r--tools/gfx-unit-test/clear-texture-test.cpp141
-rw-r--r--tools/gfx-unit-test/compute-smoke.cpp202
-rw-r--r--tools/gfx-unit-test/compute-trivial.cpp169
-rw-r--r--tools/gfx-unit-test/copy-texture-tests.cpp1642
-rw-r--r--tools/gfx-unit-test/create-buffer-from-handle.cpp178
-rw-r--r--tools/gfx-unit-test/existing-device-handle-test.cpp254
-rw-r--r--tools/gfx-unit-test/format-unit-tests.cpp2524
-rw-r--r--tools/gfx-unit-test/get-buffer-resource-handle-test.cpp159
-rw-r--r--tools/gfx-unit-test/get-cmd-buffer-handle-test.cpp154
-rw-r--r--tools/gfx-unit-test/get-cmd-queue-handle-test.cpp125
-rw-r--r--tools/gfx-unit-test/get-supported-resource-states-test.cpp325
-rw-r--r--tools/gfx-unit-test/get-texture-resource-handle-test.cpp146
-rw-r--r--tools/gfx-unit-test/gfx-test-texture-util.cpp418
-rw-r--r--tools/gfx-unit-test/gfx-test-texture-util.h332
-rw-r--r--tools/gfx-unit-test/gfx-test-util.cpp618
-rw-r--r--tools/gfx-unit-test/gfx-test-util.h252
-rw-r--r--tools/gfx-unit-test/instanced-draw-tests.cpp990
-rw-r--r--tools/gfx-unit-test/link-time-constant.cpp285
-rw-r--r--tools/gfx-unit-test/link-time-default.cpp340
-rw-r--r--tools/gfx-unit-test/link-time-options.cpp274
-rw-r--r--tools/gfx-unit-test/link-time-type.cpp269
-rw-r--r--tools/gfx-unit-test/mutable-shader-object.cpp247
-rw-r--r--tools/gfx-unit-test/nested-parameter-block.cpp284
-rw-r--r--tools/gfx-unit-test/precompiled-module-2.cpp361
-rw-r--r--tools/gfx-unit-test/precompiled-module-cache.cpp336
-rw-r--r--tools/gfx-unit-test/precompiled-module.cpp273
-rw-r--r--tools/gfx-unit-test/ray-tracing-tests.cpp910
-rw-r--r--tools/gfx-unit-test/resolve-resource-tests.cpp619
-rw-r--r--tools/gfx-unit-test/root-mutable-shader-object.cpp208
-rw-r--r--tools/gfx-unit-test/root-shader-parameter.cpp244
-rw-r--r--tools/gfx-unit-test/sampler-array.cpp261
-rw-r--r--tools/gfx-unit-test/shader-cache-tests.cpp1857
-rw-r--r--tools/gfx-unit-test/shared-buffers-tests.cpp222
-rw-r--r--tools/gfx-unit-test/shared-textures-tests.cpp440
-rw-r--r--tools/gfx-unit-test/swap-chain-resize-test.cpp427
-rw-r--r--tools/gfx-unit-test/texture-types-tests.cpp1143
-rw-r--r--tools/gfx-unit-test/uint16-structured-buffer.cpp161
38 files changed, 9415 insertions, 8673 deletions
diff --git a/tools/gfx-unit-test/buffer-barrier-test.cpp b/tools/gfx-unit-test/buffer-barrier-test.cpp
index 007a0d180..80723d2e4 100644
--- a/tools/gfx-unit-test/buffer-barrier-test.cpp
+++ b/tools/gfx-unit-test/buffer-barrier-test.cpp
@@ -1,159 +1,179 @@
-#include "tools/unit-test/slang-unit-test.h"
-
-#include "slang-gfx.h"
#include "gfx-test-util.h"
-#include "tools/gfx-util/shader-cursor.h"
+#include "slang-gfx.h"
#include "source/core/slang-basic.h"
+#include "tools/gfx-util/shader-cursor.h"
+#include "tools/unit-test/slang-unit-test.h"
using namespace gfx;
namespace gfx_test
{
- struct Shader
- {
- ComPtr<IShaderProgram> program;
- slang::ProgramLayout* reflection = nullptr;
- ComputePipelineStateDesc pipelineDesc = {};
- ComPtr<gfx::IPipelineState> pipelineState;
- };
+struct Shader
+{
+ ComPtr<IShaderProgram> program;
+ slang::ProgramLayout* reflection = nullptr;
+ ComputePipelineStateDesc pipelineDesc = {};
+ ComPtr<gfx::IPipelineState> pipelineState;
+};
- struct Buffer
- {
- IBufferResource::Desc desc;
- ComPtr<IBufferResource> buffer;
- ComPtr<IResourceView> view;
- };
+struct Buffer
+{
+ IBufferResource::Desc desc;
+ ComPtr<IBufferResource> buffer;
+ ComPtr<IResourceView> view;
+};
+
+void createFloatBuffer(
+ IDevice* device,
+ Buffer& outBuffer,
+ bool unorderedAccess,
+ float* initialData,
+ size_t elementCount)
+{
+ outBuffer = {};
+ IBufferResource::Desc& bufferDesc = outBuffer.desc;
+ bufferDesc.sizeInBytes = elementCount * sizeof(float);
+ bufferDesc.format = gfx::Format::Unknown;
+ bufferDesc.elementSize = sizeof(float);
+ bufferDesc.defaultState =
+ unorderedAccess ? ResourceState::UnorderedAccess : ResourceState::ShaderResource;
+ bufferDesc.memoryType = MemoryType::DeviceLocal;
+ bufferDesc.allowedStates = ResourceStateSet(
+ ResourceState::ShaderResource,
+ ResourceState::CopyDestination,
+ ResourceState::CopySource);
+ if (unorderedAccess)
+ bufferDesc.allowedStates.add(ResourceState::UnorderedAccess);
+
+ GFX_CHECK_CALL_ABORT(
+ device->createBufferResource(bufferDesc, (void*)initialData, outBuffer.buffer.writeRef()));
+
+ IResourceView::Desc viewDesc = {};
+ viewDesc.type = unorderedAccess ? IResourceView::Type::UnorderedAccess
+ : IResourceView::Type::ShaderResource;
+ viewDesc.format = Format::Unknown;
+ GFX_CHECK_CALL_ABORT(
+ device->createBufferView(outBuffer.buffer, nullptr, viewDesc, outBuffer.view.writeRef()));
+}
- void createFloatBuffer(IDevice* device, Buffer& outBuffer, bool unorderedAccess, float* initialData, size_t elementCount)
+void barrierTestImpl(IDevice* device, UnitTestContext* context)
+{
+ Slang::ComPtr<ITransientResourceHeap> transientHeap;
+ ITransientResourceHeap::Desc transientHeapDesc = {};
+ transientHeapDesc.constantBufferSize = 4096;
+ GFX_CHECK_CALL_ABORT(
+ device->createTransientResourceHeap(transientHeapDesc, transientHeap.writeRef()));
+
+ Shader programA;
+ Shader programB;
+ GFX_CHECK_CALL_ABORT(loadComputeProgram(
+ device,
+ programA.program,
+ "buffer-barrier-test",
+ "computeA",
+ programA.reflection));
+ GFX_CHECK_CALL_ABORT(loadComputeProgram(
+ device,
+ programB.program,
+ "buffer-barrier-test",
+ "computeB",
+ programB.reflection));
+ programA.pipelineDesc.program = programA.program.get();
+ programB.pipelineDesc.program = programB.program.get();
+ GFX_CHECK_CALL_ABORT(device->createComputePipelineState(
+ programA.pipelineDesc,
+ programA.pipelineState.writeRef()));
+ GFX_CHECK_CALL_ABORT(device->createComputePipelineState(
+ programB.pipelineDesc,
+ programB.pipelineState.writeRef()));
+
+ float initialData[] = {1.0f, 2.0f, 3.0f, 4.0f};
+ Buffer inputBuffer;
+ createFloatBuffer(device, inputBuffer, false, initialData, 4);
+
+ Buffer intermediateBuffer;
+ createFloatBuffer(device, intermediateBuffer, true, nullptr, 4);
+
+ Buffer outputBuffer;
+ createFloatBuffer(device, outputBuffer, true, nullptr, 4);
+
+ // We have done all the set up work, now it is time to start recording a command buffer for
+ // GPU execution.
{
- outBuffer = {};
- IBufferResource::Desc& bufferDesc = outBuffer.desc;
- bufferDesc.sizeInBytes = elementCount * sizeof(float);
- bufferDesc.format = gfx::Format::Unknown;
- bufferDesc.elementSize = sizeof(float);
- bufferDesc.defaultState = unorderedAccess ? ResourceState::UnorderedAccess : ResourceState::ShaderResource;
- bufferDesc.memoryType = MemoryType::DeviceLocal;
- bufferDesc.allowedStates = ResourceStateSet(
- ResourceState::ShaderResource,
- ResourceState::CopyDestination,
- ResourceState::CopySource);
- if (unorderedAccess) bufferDesc.allowedStates.add(ResourceState::UnorderedAccess);
-
- GFX_CHECK_CALL_ABORT(device->createBufferResource(
- bufferDesc,
- (void*)initialData,
- outBuffer.buffer.writeRef()));
-
- IResourceView::Desc viewDesc = {};
- viewDesc.type = unorderedAccess ? IResourceView::Type::UnorderedAccess : IResourceView::Type::ShaderResource;
- viewDesc.format = Format::Unknown;
- GFX_CHECK_CALL_ABORT(device->createBufferView(
- outBuffer.buffer, nullptr, viewDesc, outBuffer.view.writeRef()));
+ ICommandQueue::Desc queueDesc = {ICommandQueue::QueueType::Graphics};
+ auto queue = device->createCommandQueue(queueDesc);
+
+ auto commandBuffer = transientHeap->createCommandBuffer();
+ auto encoder = commandBuffer->encodeComputeCommands();
+ auto resourceEncoder = commandBuffer->encodeResourceCommands();
+
+ // Write inputBuffer data to intermediateBuffer
+ auto rootObjectA = encoder->bindPipeline(programA.pipelineState);
+ ShaderCursor entryPointCursorA(rootObjectA->getEntryPoint(0));
+ entryPointCursorA.getPath("inBuffer").setResource(inputBuffer.view);
+ entryPointCursorA.getPath("outBuffer").setResource(intermediateBuffer.view);
+
+ encoder->dispatchCompute(1, 1, 1);
+
+ // Insert barrier to ensure writes to intermediateBuffer are complete before the next shader
+ // starts executing
+ auto bufferPtr = intermediateBuffer.buffer.get();
+ resourceEncoder->bufferBarrier(
+ 1,
+ &bufferPtr,
+ ResourceState::UnorderedAccess,
+ ResourceState::ShaderResource);
+ resourceEncoder->endEncoding();
+
+ // Write intermediateBuffer to outputBuffer
+ auto rootObjectB = encoder->bindPipeline(programB.pipelineState);
+ ShaderCursor entryPointCursorB(rootObjectB->getEntryPoint(0));
+ entryPointCursorB.getPath("inBuffer").setResource(intermediateBuffer.view);
+ entryPointCursorB.getPath("outBuffer").setResource(outputBuffer.view);
+
+ encoder->dispatchCompute(1, 1, 1);
+ encoder->endEncoding();
+ commandBuffer->close();
+ queue->executeCommandBuffer(commandBuffer);
+ queue->waitOnHost();
}
- void barrierTestImpl(IDevice* device, UnitTestContext* context)
+ compareComputeResult(
+ device,
+ outputBuffer.buffer,
+ Slang::makeArray<float>(11.0f, 12.0f, 13.0f, 14.0f));
+}
+
+void barrierTestAPI(UnitTestContext* context, Slang::RenderApiFlag::Enum api)
+{
+ if ((api & context->enabledApis) == 0)
{
- Slang::ComPtr<ITransientResourceHeap> transientHeap;
- ITransientResourceHeap::Desc transientHeapDesc = {};
- transientHeapDesc.constantBufferSize = 4096;
- GFX_CHECK_CALL_ABORT(device->createTransientResourceHeap(transientHeapDesc, transientHeap.writeRef()));
-
- Shader programA;
- Shader programB;
- GFX_CHECK_CALL_ABORT(loadComputeProgram(device, programA.program, "buffer-barrier-test", "computeA", programA.reflection));
- GFX_CHECK_CALL_ABORT(loadComputeProgram(device, programB.program, "buffer-barrier-test", "computeB", programB.reflection));
- programA.pipelineDesc.program = programA.program.get();
- programB.pipelineDesc.program = programB.program.get();
- GFX_CHECK_CALL_ABORT(device->createComputePipelineState(programA.pipelineDesc, programA.pipelineState.writeRef()));
- GFX_CHECK_CALL_ABORT(device->createComputePipelineState(programB.pipelineDesc, programB.pipelineState.writeRef()));
-
- float initialData[] = { 1.0f, 2.0f, 3.0f, 4.0f };
- Buffer inputBuffer;
- createFloatBuffer(device, inputBuffer, false, initialData, 4);
-
- Buffer intermediateBuffer;
- createFloatBuffer(device, intermediateBuffer, true, nullptr, 4);
-
- Buffer outputBuffer;
- createFloatBuffer(device, outputBuffer, true, nullptr, 4);
-
- // We have done all the set up work, now it is time to start recording a command buffer for
- // GPU execution.
- {
- ICommandQueue::Desc queueDesc = { ICommandQueue::QueueType::Graphics };
- auto queue = device->createCommandQueue(queueDesc);
-
- auto commandBuffer = transientHeap->createCommandBuffer();
- auto encoder = commandBuffer->encodeComputeCommands();
- auto resourceEncoder = commandBuffer->encodeResourceCommands();
-
- // Write inputBuffer data to intermediateBuffer
- auto rootObjectA = encoder->bindPipeline(programA.pipelineState);
- ShaderCursor entryPointCursorA(rootObjectA->getEntryPoint(0));
- entryPointCursorA.getPath("inBuffer").setResource(inputBuffer.view);
- entryPointCursorA.getPath("outBuffer").setResource(intermediateBuffer.view);
-
- encoder->dispatchCompute(1, 1, 1);
-
- // Insert barrier to ensure writes to intermediateBuffer are complete before the next shader starts executing
- auto bufferPtr = intermediateBuffer.buffer.get();
- resourceEncoder->bufferBarrier(1, &bufferPtr, ResourceState::UnorderedAccess, ResourceState::ShaderResource);
- resourceEncoder->endEncoding();
-
- // Write intermediateBuffer to outputBuffer
- auto rootObjectB = encoder->bindPipeline(programB.pipelineState);
- ShaderCursor entryPointCursorB(rootObjectB->getEntryPoint(0));
- entryPointCursorB.getPath("inBuffer").setResource(intermediateBuffer.view);
- entryPointCursorB.getPath("outBuffer").setResource(outputBuffer.view);
-
- encoder->dispatchCompute(1, 1, 1);
- encoder->endEncoding();
- commandBuffer->close();
- queue->executeCommandBuffer(commandBuffer);
- queue->waitOnHost();
- }
-
- compareComputeResult(
- device,
- outputBuffer.buffer,
- Slang::makeArray<float>(11.0f, 12.0f, 13.0f, 14.0f));
+ SLANG_IGNORE_TEST
}
-
- void barrierTestAPI(UnitTestContext* context, Slang::RenderApiFlag::Enum api)
+ Slang::ComPtr<IDevice> device;
+ IDevice::Desc deviceDesc = {};
+ switch (api)
{
- if ((api & context->enabledApis) == 0)
- {
- SLANG_IGNORE_TEST
- }
- Slang::ComPtr<IDevice> device;
- IDevice::Desc deviceDesc = {};
- switch (api)
- {
- case Slang::RenderApiFlag::D3D12:
- deviceDesc.deviceType = gfx::DeviceType::DirectX12;
- break;
- case Slang::RenderApiFlag::Vulkan:
- deviceDesc.deviceType = gfx::DeviceType::Vulkan;
- break;
- default:
- SLANG_IGNORE_TEST
- }
- deviceDesc.slang.slangGlobalSession = context->slangGlobalSession;
- const char* searchPaths[] = { "", "../../tools/gfx-unit-test", "tools/gfx-unit-test" };
- deviceDesc.slang.searchPathCount = (SlangInt)SLANG_COUNT_OF(searchPaths);
- deviceDesc.slang.searchPaths = searchPaths;
- auto createDeviceResult = gfxCreateDevice(&deviceDesc, device.writeRef());
- if (SLANG_FAILED(createDeviceResult))
- {
- SLANG_IGNORE_TEST
- }
-
- barrierTestImpl(device, context);
+ case Slang::RenderApiFlag::D3D12: deviceDesc.deviceType = gfx::DeviceType::DirectX12; break;
+ case Slang::RenderApiFlag::Vulkan: deviceDesc.deviceType = gfx::DeviceType::Vulkan; break;
+ default: SLANG_IGNORE_TEST
}
-
- SLANG_UNIT_TEST(bufferBarrierVulkan)
+ deviceDesc.slang.slangGlobalSession = context->slangGlobalSession;
+ const char* searchPaths[] = {"", "../../tools/gfx-unit-test", "tools/gfx-unit-test"};
+ deviceDesc.slang.searchPathCount = (SlangInt)SLANG_COUNT_OF(searchPaths);
+ deviceDesc.slang.searchPaths = searchPaths;
+ auto createDeviceResult = gfxCreateDevice(&deviceDesc, device.writeRef());
+ if (SLANG_FAILED(createDeviceResult))
{
- barrierTestAPI(unitTestContext, Slang::RenderApiFlag::Vulkan);
+ SLANG_IGNORE_TEST
}
+ barrierTestImpl(device, context);
}
+
+SLANG_UNIT_TEST(bufferBarrierVulkan)
+{
+ barrierTestAPI(unitTestContext, Slang::RenderApiFlag::Vulkan);
+}
+
+} // namespace gfx_test
diff --git a/tools/gfx-unit-test/clear-texture-test.cpp b/tools/gfx-unit-test/clear-texture-test.cpp
index 4ad82f313..ed9d12f0d 100644
--- a/tools/gfx-unit-test/clear-texture-test.cpp
+++ b/tools/gfx-unit-test/clear-texture-test.cpp
@@ -1,89 +1,92 @@
-#include "tools/unit-test/slang-unit-test.h"
-
-#include "slang-gfx.h"
#include "gfx-test-util.h"
-#include "tools/gfx-util/shader-cursor.h"
+#include "slang-gfx.h"
#include "source/core/slang-basic.h"
+#include "tools/gfx-util/shader-cursor.h"
+#include "tools/unit-test/slang-unit-test.h"
using namespace Slang;
using namespace gfx;
namespace gfx_test
{
- void clearTextureTestImpl(IDevice* device, UnitTestContext* context)
- {
- Slang::ComPtr<ITransientResourceHeap> transientHeap;
- ITransientResourceHeap::Desc transientHeapDesc = {};
- transientHeapDesc.constantBufferSize = 4096;
- GFX_CHECK_CALL_ABORT(
- device->createTransientResourceHeap(transientHeapDesc, transientHeap.writeRef()));
+void clearTextureTestImpl(IDevice* device, UnitTestContext* context)
+{
+ Slang::ComPtr<ITransientResourceHeap> transientHeap;
+ ITransientResourceHeap::Desc transientHeapDesc = {};
+ transientHeapDesc.constantBufferSize = 4096;
+ GFX_CHECK_CALL_ABORT(
+ device->createTransientResourceHeap(transientHeapDesc, transientHeap.writeRef()));
- ITextureResource::Desc srcTexDesc = {};
- srcTexDesc.type = IResource::Type::Texture2D;
- srcTexDesc.numMipLevels = 1;
- srcTexDesc.arraySize = 1;
- srcTexDesc.size.width = 4;
- srcTexDesc.size.height = 4;
- srcTexDesc.size.depth = 1;
- srcTexDesc.defaultState = ResourceState::RenderTarget;
- srcTexDesc.allowedStates = ResourceStateSet(
- ResourceState::RenderTarget,
- ResourceState::CopySource,
- ResourceState::CopyDestination);
- srcTexDesc.format = Format::R32G32B32A32_FLOAT;
+ ITextureResource::Desc srcTexDesc = {};
+ srcTexDesc.type = IResource::Type::Texture2D;
+ srcTexDesc.numMipLevels = 1;
+ srcTexDesc.arraySize = 1;
+ srcTexDesc.size.width = 4;
+ srcTexDesc.size.height = 4;
+ srcTexDesc.size.depth = 1;
+ srcTexDesc.defaultState = ResourceState::RenderTarget;
+ srcTexDesc.allowedStates = ResourceStateSet(
+ ResourceState::RenderTarget,
+ ResourceState::CopySource,
+ ResourceState::CopyDestination);
+ srcTexDesc.format = Format::R32G32B32A32_FLOAT;
- Slang::ComPtr<ITextureResource> srcTexture;
- GFX_CHECK_CALL_ABORT(device->createTextureResource(
- srcTexDesc, nullptr, srcTexture.writeRef()));
+ Slang::ComPtr<ITextureResource> srcTexture;
+ GFX_CHECK_CALL_ABORT(device->createTextureResource(srcTexDesc, nullptr, srcTexture.writeRef()));
- Slang::ComPtr<IResourceView> rtv;
- IResourceView::Desc rtvDesc = {};
- rtvDesc.type = IResourceView::Type::RenderTarget;
- rtvDesc.format = Format::R32G32B32A32_FLOAT;
- rtvDesc.renderTarget.shape = IResource::Type::Texture2D;
- rtvDesc.subresourceRange.layerCount = 1;
- rtvDesc.subresourceRange.mipLevelCount = 1;
- rtv = device->createTextureView(srcTexture, rtvDesc);
+ Slang::ComPtr<IResourceView> rtv;
+ IResourceView::Desc rtvDesc = {};
+ rtvDesc.type = IResourceView::Type::RenderTarget;
+ rtvDesc.format = Format::R32G32B32A32_FLOAT;
+ rtvDesc.renderTarget.shape = IResource::Type::Texture2D;
+ rtvDesc.subresourceRange.layerCount = 1;
+ rtvDesc.subresourceRange.mipLevelCount = 1;
+ rtv = device->createTextureView(srcTexture, rtvDesc);
- {
- ICommandQueue::Desc queueDesc = {ICommandQueue::QueueType::Graphics};
- auto queue = device->createCommandQueue(queueDesc);
+ {
+ ICommandQueue::Desc queueDesc = {ICommandQueue::QueueType::Graphics};
+ auto queue = device->createCommandQueue(queueDesc);
- auto commandBuffer = transientHeap->createCommandBuffer();
- auto resourceEncoder = commandBuffer->encodeResourceCommands();
- ClearValue clearValue = {};
- clearValue.color.floatValues[0] = 0.5f;
- clearValue.color.floatValues[1] = 1.0f;
- clearValue.color.floatValues[2] = 0.2f;
- clearValue.color.floatValues[3] = 0.1f;
- resourceEncoder->clearResourceView(rtv, &clearValue, ClearResourceViewFlags::FloatClearValues);
- resourceEncoder->textureBarrier(
- srcTexture, ResourceState::RenderTarget, ResourceState::CopySource);
- resourceEncoder->endEncoding();
+ auto commandBuffer = transientHeap->createCommandBuffer();
+ auto resourceEncoder = commandBuffer->encodeResourceCommands();
+ ClearValue clearValue = {};
+ clearValue.color.floatValues[0] = 0.5f;
+ clearValue.color.floatValues[1] = 1.0f;
+ clearValue.color.floatValues[2] = 0.2f;
+ clearValue.color.floatValues[3] = 0.1f;
+ resourceEncoder->clearResourceView(
+ rtv,
+ &clearValue,
+ ClearResourceViewFlags::FloatClearValues);
+ resourceEncoder->textureBarrier(
+ srcTexture,
+ ResourceState::RenderTarget,
+ ResourceState::CopySource);
+ resourceEncoder->endEncoding();
- commandBuffer->close();
- queue->executeCommandBuffer(commandBuffer);
+ commandBuffer->close();
+ queue->executeCommandBuffer(commandBuffer);
- queue->waitOnHost();
+ queue->waitOnHost();
- Slang::ComPtr<ISlangBlob> blob;
- size_t rowPitch, pixelSize;
- device->readTextureResource(
- srcTexture,
- ResourceState::CopySource,
- blob.writeRef(),
- &rowPitch,
- &pixelSize);
- float* data = (float*)blob->getBufferPointer();
- for (int i = 0; i < 4; i++)
- {
- SLANG_CHECK(data[i] == clearValue.color.floatValues[i]);
- }
+ Slang::ComPtr<ISlangBlob> blob;
+ size_t rowPitch, pixelSize;
+ device->readTextureResource(
+ srcTexture,
+ ResourceState::CopySource,
+ blob.writeRef(),
+ &rowPitch,
+ &pixelSize);
+ float* data = (float*)blob->getBufferPointer();
+ for (int i = 0; i < 4; i++)
+ {
+ SLANG_CHECK(data[i] == clearValue.color.floatValues[i]);
}
}
+}
- SLANG_UNIT_TEST(clearTextureTestVulkan)
- {
- runTestImpl(clearTextureTestImpl, unitTestContext, Slang::RenderApiFlag::Vulkan);
- }
+SLANG_UNIT_TEST(clearTextureTestVulkan)
+{
+ runTestImpl(clearTextureTestImpl, unitTestContext, Slang::RenderApiFlag::Vulkan);
}
+} // namespace gfx_test
diff --git a/tools/gfx-unit-test/compute-smoke.cpp b/tools/gfx-unit-test/compute-smoke.cpp
index 5e14a2e00..da8357591 100644
--- a/tools/gfx-unit-test/compute-smoke.cpp
+++ b/tools/gfx-unit-test/compute-smoke.cpp
@@ -1,115 +1,115 @@
-#include "tools/unit-test/slang-unit-test.h"
-
-#include "slang-gfx.h"
#include "gfx-test-util.h"
-#include "tools/gfx-util/shader-cursor.h"
+#include "slang-gfx.h"
#include "source/core/slang-basic.h"
+#include "tools/gfx-util/shader-cursor.h"
+#include "tools/unit-test/slang-unit-test.h"
using namespace gfx;
namespace gfx_test
{
- void computeSmokeTestImpl(IDevice* device, UnitTestContext* context)
+void computeSmokeTestImpl(IDevice* device, UnitTestContext* context)
+{
+ Slang::ComPtr<ITransientResourceHeap> transientHeap;
+ ITransientResourceHeap::Desc transientHeapDesc = {};
+ transientHeapDesc.constantBufferSize = 4096;
+ GFX_CHECK_CALL_ABORT(
+ device->createTransientResourceHeap(transientHeapDesc, transientHeap.writeRef()));
+
+ ComPtr<IShaderProgram> shaderProgram;
+ slang::ProgramLayout* slangReflection;
+ GFX_CHECK_CALL_ABORT(
+ loadComputeProgram(device, shaderProgram, "compute-smoke", "computeMain", slangReflection));
+
+ ComputePipelineStateDesc pipelineDesc = {};
+ pipelineDesc.program = shaderProgram.get();
+ ComPtr<gfx::IPipelineState> pipelineState;
+ GFX_CHECK_CALL_ABORT(
+ device->createComputePipelineState(pipelineDesc, pipelineState.writeRef()));
+
+ const int numberCount = 4;
+ float initialData[] = {0.0f, 1.0f, 2.0f, 3.0f};
+ IBufferResource::Desc bufferDesc = {};
+ bufferDesc.sizeInBytes = numberCount * sizeof(float);
+ bufferDesc.format = gfx::Format::Unknown;
+ bufferDesc.elementSize = sizeof(float);
+ bufferDesc.allowedStates = ResourceStateSet(
+ ResourceState::ShaderResource,
+ ResourceState::UnorderedAccess,
+ ResourceState::CopyDestination,
+ ResourceState::CopySource);
+ bufferDesc.defaultState = ResourceState::UnorderedAccess;
+ bufferDesc.memoryType = MemoryType::DeviceLocal;
+
+ ComPtr<IBufferResource> numbersBuffer;
+ GFX_CHECK_CALL_ABORT(
+ device->createBufferResource(bufferDesc, (void*)initialData, numbersBuffer.writeRef()));
+
+ ComPtr<IResourceView> bufferView;
+ IResourceView::Desc viewDesc = {};
+ viewDesc.type = IResourceView::Type::UnorderedAccess;
+ viewDesc.format = Format::Unknown;
+ GFX_CHECK_CALL_ABORT(
+ device->createBufferView(numbersBuffer, nullptr, viewDesc, bufferView.writeRef()));
+
+ // We have done all the set up work, now it is time to start recording a command buffer for
+ // GPU execution.
{
- Slang::ComPtr<ITransientResourceHeap> transientHeap;
- ITransientResourceHeap::Desc transientHeapDesc = {};
- transientHeapDesc.constantBufferSize = 4096;
- GFX_CHECK_CALL_ABORT(
- device->createTransientResourceHeap(transientHeapDesc, transientHeap.writeRef()));
-
- ComPtr<IShaderProgram> shaderProgram;
- slang::ProgramLayout* slangReflection;
- GFX_CHECK_CALL_ABORT(loadComputeProgram(device, shaderProgram, "compute-smoke", "computeMain", slangReflection));
-
- ComputePipelineStateDesc pipelineDesc = {};
- pipelineDesc.program = shaderProgram.get();
- ComPtr<gfx::IPipelineState> pipelineState;
- GFX_CHECK_CALL_ABORT(
- device->createComputePipelineState(pipelineDesc, pipelineState.writeRef()));
-
- const int numberCount = 4;
- float initialData[] = { 0.0f, 1.0f, 2.0f, 3.0f };
- IBufferResource::Desc bufferDesc = {};
- bufferDesc.sizeInBytes = numberCount * sizeof(float);
- bufferDesc.format = gfx::Format::Unknown;
- bufferDesc.elementSize = sizeof(float);
- bufferDesc.allowedStates = ResourceStateSet(
- ResourceState::ShaderResource,
- ResourceState::UnorderedAccess,
- ResourceState::CopyDestination,
- ResourceState::CopySource);
- bufferDesc.defaultState = ResourceState::UnorderedAccess;
- bufferDesc.memoryType = MemoryType::DeviceLocal;
-
- ComPtr<IBufferResource> numbersBuffer;
- GFX_CHECK_CALL_ABORT(device->createBufferResource(
- bufferDesc,
- (void*)initialData,
- numbersBuffer.writeRef()));
-
- ComPtr<IResourceView> bufferView;
- IResourceView::Desc viewDesc = {};
- viewDesc.type = IResourceView::Type::UnorderedAccess;
- viewDesc.format = Format::Unknown;
- GFX_CHECK_CALL_ABORT(
- device->createBufferView(numbersBuffer, nullptr, viewDesc, bufferView.writeRef()));
-
- // We have done all the set up work, now it is time to start recording a command buffer for
- // GPU execution.
- {
- ICommandQueue::Desc queueDesc = { ICommandQueue::QueueType::Graphics };
- auto queue = device->createCommandQueue(queueDesc);
-
- auto commandBuffer = transientHeap->createCommandBuffer();
- auto encoder = commandBuffer->encodeComputeCommands();
-
- auto rootObject = encoder->bindPipeline(pipelineState);
-
- slang::TypeReflection* addTransformerType =
- slangReflection->findTypeByName("AddTransformer");
-
- // Now we can use this type to create a shader object that can be bound to the root object.
- ComPtr<IShaderObject> transformer;
- GFX_CHECK_CALL_ABORT(device->createShaderObject(
- addTransformerType, ShaderObjectContainerType::None, transformer.writeRef()));
- // Set the `c` field of the `AddTransformer`.
- float c = 1.0f;
- ShaderCursor(transformer).getPath("c").setData(&c, sizeof(float));
-
- ShaderCursor entryPointCursor(
- rootObject->getEntryPoint(0)); // get a cursor the the first entry-point.
- // Bind buffer view to the entry point.
- entryPointCursor.getPath("buffer").setResource(bufferView);
-
- // Bind the previously created transformer object to root object.
- entryPointCursor.getPath("transformer").setObject(transformer);
-
- encoder->dispatchCompute(1, 1, 1);
- encoder->endEncoding();
- commandBuffer->close();
- queue->executeCommandBuffer(commandBuffer);
- queue->waitOnHost();
- }
-
- compareComputeResult(
- device,
- numbersBuffer,
- Slang::makeArray<float>(11.0f, 12.0f, 13.0f, 14.0f));
+ ICommandQueue::Desc queueDesc = {ICommandQueue::QueueType::Graphics};
+ auto queue = device->createCommandQueue(queueDesc);
+
+ auto commandBuffer = transientHeap->createCommandBuffer();
+ auto encoder = commandBuffer->encodeComputeCommands();
+
+ auto rootObject = encoder->bindPipeline(pipelineState);
+
+ slang::TypeReflection* addTransformerType =
+ slangReflection->findTypeByName("AddTransformer");
+
+ // Now we can use this type to create a shader object that can be bound to the root object.
+ ComPtr<IShaderObject> transformer;
+ GFX_CHECK_CALL_ABORT(device->createShaderObject(
+ addTransformerType,
+ ShaderObjectContainerType::None,
+ transformer.writeRef()));
+ // Set the `c` field of the `AddTransformer`.
+ float c = 1.0f;
+ ShaderCursor(transformer).getPath("c").setData(&c, sizeof(float));
+
+ ShaderCursor entryPointCursor(
+ rootObject->getEntryPoint(0)); // get a cursor the the first entry-point.
+ // Bind buffer view to the entry point.
+ entryPointCursor.getPath("buffer").setResource(bufferView);
+
+ // Bind the previously created transformer object to root object.
+ entryPointCursor.getPath("transformer").setObject(transformer);
+
+ encoder->dispatchCompute(1, 1, 1);
+ encoder->endEncoding();
+ commandBuffer->close();
+ queue->executeCommandBuffer(commandBuffer);
+ queue->waitOnHost();
}
- SLANG_UNIT_TEST(computeSmokeD3D12)
- {
- runTestImpl(computeSmokeTestImpl, unitTestContext, Slang::RenderApiFlag::D3D12);
- }
+ compareComputeResult(
+ device,
+ numbersBuffer,
+ Slang::makeArray<float>(11.0f, 12.0f, 13.0f, 14.0f));
+}
- SLANG_UNIT_TEST(computeSmokeD3D11)
- {
- runTestImpl(computeSmokeTestImpl, unitTestContext, Slang::RenderApiFlag::D3D11);
- }
+SLANG_UNIT_TEST(computeSmokeD3D12)
+{
+ runTestImpl(computeSmokeTestImpl, unitTestContext, Slang::RenderApiFlag::D3D12);
+}
- SLANG_UNIT_TEST(computeSmokeVulkan)
- {
- runTestImpl(computeSmokeTestImpl, unitTestContext, Slang::RenderApiFlag::Vulkan);
- }
+SLANG_UNIT_TEST(computeSmokeD3D11)
+{
+ runTestImpl(computeSmokeTestImpl, unitTestContext, Slang::RenderApiFlag::D3D11);
+}
+SLANG_UNIT_TEST(computeSmokeVulkan)
+{
+ runTestImpl(computeSmokeTestImpl, unitTestContext, Slang::RenderApiFlag::Vulkan);
}
+
+} // namespace gfx_test
diff --git a/tools/gfx-unit-test/compute-trivial.cpp b/tools/gfx-unit-test/compute-trivial.cpp
index 5674dd1a7..341593d04 100644
--- a/tools/gfx-unit-test/compute-trivial.cpp
+++ b/tools/gfx-unit-test/compute-trivial.cpp
@@ -1,99 +1,98 @@
-#include "tools/unit-test/slang-unit-test.h"
-
-#include "slang-gfx.h"
#include "gfx-test-util.h"
-#include "tools/gfx-util/shader-cursor.h"
+#include "slang-gfx.h"
#include "source/core/slang-basic.h"
+#include "tools/gfx-util/shader-cursor.h"
+#include "tools/unit-test/slang-unit-test.h"
using namespace gfx;
namespace gfx_test
{
- void computeTrivialTestImpl(IDevice* device, UnitTestContext* context)
+void computeTrivialTestImpl(IDevice* device, UnitTestContext* context)
+{
+ Slang::ComPtr<ITransientResourceHeap> transientHeap;
+ ITransientResourceHeap::Desc transientHeapDesc = {};
+ transientHeapDesc.constantBufferSize = 4096;
+ GFX_CHECK_CALL_ABORT(
+ device->createTransientResourceHeap(transientHeapDesc, transientHeap.writeRef()));
+
+ ComPtr<IShaderProgram> shaderProgram;
+ slang::ProgramLayout* slangReflection;
+ GFX_CHECK_CALL_ABORT(loadComputeProgram(
+ device,
+ shaderProgram,
+ "compute-trivial",
+ "computeMain",
+ slangReflection));
+
+ ComputePipelineStateDesc pipelineDesc = {};
+ pipelineDesc.program = shaderProgram.get();
+ ComPtr<gfx::IPipelineState> pipelineState;
+ GFX_CHECK_CALL_ABORT(
+ device->createComputePipelineState(pipelineDesc, pipelineState.writeRef()));
+
+ const int numberCount = 4;
+ float initialData[] = {0.0f, 1.0f, 2.0f, 3.0f};
+ IBufferResource::Desc bufferDesc = {};
+ bufferDesc.sizeInBytes = numberCount * sizeof(float);
+ bufferDesc.format = gfx::Format::Unknown;
+ bufferDesc.elementSize = sizeof(float);
+ bufferDesc.allowedStates = ResourceStateSet(
+ ResourceState::ShaderResource,
+ ResourceState::UnorderedAccess,
+ ResourceState::CopyDestination,
+ ResourceState::CopySource);
+ bufferDesc.defaultState = ResourceState::UnorderedAccess;
+ bufferDesc.memoryType = MemoryType::DeviceLocal;
+
+ ComPtr<IBufferResource> numbersBuffer;
+ GFX_CHECK_CALL_ABORT(
+ device->createBufferResource(bufferDesc, (void*)initialData, numbersBuffer.writeRef()));
+
+ ComPtr<IResourceView> bufferView;
+ IResourceView::Desc viewDesc = {};
+ viewDesc.type = IResourceView::Type::UnorderedAccess;
+ viewDesc.format = Format::Unknown;
+ GFX_CHECK_CALL_ABORT(
+ device->createBufferView(numbersBuffer, nullptr, viewDesc, bufferView.writeRef()));
+
+ // We have done all the set up work, now it is time to start recording a command buffer for
+ // GPU execution.
{
- Slang::ComPtr<ITransientResourceHeap> transientHeap;
- ITransientResourceHeap::Desc transientHeapDesc = {};
- transientHeapDesc.constantBufferSize = 4096;
- GFX_CHECK_CALL_ABORT(
- device->createTransientResourceHeap(transientHeapDesc, transientHeap.writeRef()));
-
- ComPtr<IShaderProgram> shaderProgram;
- slang::ProgramLayout* slangReflection;
- GFX_CHECK_CALL_ABORT(loadComputeProgram(device, shaderProgram, "compute-trivial", "computeMain", slangReflection));
-
- ComputePipelineStateDesc pipelineDesc = {};
- pipelineDesc.program = shaderProgram.get();
- ComPtr<gfx::IPipelineState> pipelineState;
- GFX_CHECK_CALL_ABORT(
- device->createComputePipelineState(pipelineDesc, pipelineState.writeRef()));
-
- const int numberCount = 4;
- float initialData[] = { 0.0f, 1.0f, 2.0f, 3.0f };
- IBufferResource::Desc bufferDesc = {};
- bufferDesc.sizeInBytes = numberCount * sizeof(float);
- bufferDesc.format = gfx::Format::Unknown;
- bufferDesc.elementSize = sizeof(float);
- bufferDesc.allowedStates = ResourceStateSet(
- ResourceState::ShaderResource,
- ResourceState::UnorderedAccess,
- ResourceState::CopyDestination,
- ResourceState::CopySource);
- bufferDesc.defaultState = ResourceState::UnorderedAccess;
- bufferDesc.memoryType = MemoryType::DeviceLocal;
-
- ComPtr<IBufferResource> numbersBuffer;
- GFX_CHECK_CALL_ABORT(device->createBufferResource(
- bufferDesc,
- (void*)initialData,
- numbersBuffer.writeRef()));
-
- ComPtr<IResourceView> bufferView;
- IResourceView::Desc viewDesc = {};
- viewDesc.type = IResourceView::Type::UnorderedAccess;
- viewDesc.format = Format::Unknown;
- GFX_CHECK_CALL_ABORT(
- device->createBufferView(numbersBuffer, nullptr, viewDesc, bufferView.writeRef()));
-
- // We have done all the set up work, now it is time to start recording a command buffer for
- // GPU execution.
- {
- ICommandQueue::Desc queueDesc = { ICommandQueue::QueueType::Graphics };
- auto queue = device->createCommandQueue(queueDesc);
-
- auto commandBuffer = transientHeap->createCommandBuffer();
- auto encoder = commandBuffer->encodeComputeCommands();
-
- auto rootObject = encoder->bindPipeline(pipelineState);
-
- // Bind buffer view to the entry point.
- ShaderCursor(rootObject).getPath("buffer").setResource(bufferView);
-
- encoder->dispatchCompute(1, 1, 1);
- encoder->endEncoding();
- commandBuffer->close();
- queue->executeCommandBuffer(commandBuffer);
- queue->waitOnHost();
- }
-
- compareComputeResult(
- device,
- numbersBuffer,
- Slang::makeArray<float>(1.0f, 2.0f, 3.0f, 4.0f));
- }
+ ICommandQueue::Desc queueDesc = {ICommandQueue::QueueType::Graphics};
+ auto queue = device->createCommandQueue(queueDesc);
- SLANG_UNIT_TEST(computeTrivialD3D12)
- {
- runTestImpl(computeTrivialTestImpl, unitTestContext, Slang::RenderApiFlag::D3D12);
- }
+ auto commandBuffer = transientHeap->createCommandBuffer();
+ auto encoder = commandBuffer->encodeComputeCommands();
- SLANG_UNIT_TEST(computeTrivialD3D11)
- {
- runTestImpl(computeTrivialTestImpl, unitTestContext, Slang::RenderApiFlag::D3D11);
- }
+ auto rootObject = encoder->bindPipeline(pipelineState);
- SLANG_UNIT_TEST(computeTrivialVulkan)
- {
- runTestImpl(computeTrivialTestImpl, unitTestContext, Slang::RenderApiFlag::Vulkan);
+ // Bind buffer view to the entry point.
+ ShaderCursor(rootObject).getPath("buffer").setResource(bufferView);
+
+ encoder->dispatchCompute(1, 1, 1);
+ encoder->endEncoding();
+ commandBuffer->close();
+ queue->executeCommandBuffer(commandBuffer);
+ queue->waitOnHost();
}
+ compareComputeResult(device, numbersBuffer, Slang::makeArray<float>(1.0f, 2.0f, 3.0f, 4.0f));
+}
+
+SLANG_UNIT_TEST(computeTrivialD3D12)
+{
+ runTestImpl(computeTrivialTestImpl, unitTestContext, Slang::RenderApiFlag::D3D12);
+}
+
+SLANG_UNIT_TEST(computeTrivialD3D11)
+{
+ runTestImpl(computeTrivialTestImpl, unitTestContext, Slang::RenderApiFlag::D3D11);
+}
+
+SLANG_UNIT_TEST(computeTrivialVulkan)
+{
+ runTestImpl(computeTrivialTestImpl, unitTestContext, Slang::RenderApiFlag::Vulkan);
}
+
+} // namespace gfx_test
diff --git a/tools/gfx-unit-test/copy-texture-tests.cpp b/tools/gfx-unit-test/copy-texture-tests.cpp
index 68ca193ae..babe0bcf1 100644
--- a/tools/gfx-unit-test/copy-texture-tests.cpp
+++ b/tools/gfx-unit-test/copy-texture-tests.cpp
@@ -1,10 +1,9 @@
-#include "tools/unit-test/slang-unit-test.h"
-
-#include "slang-gfx.h"
-#include "gfx-test-util.h"
#include "gfx-test-texture-util.h"
-#include "tools/gfx-util/shader-cursor.h"
+#include "gfx-test-util.h"
+#include "slang-gfx.h"
#include "source/core/slang-basic.h"
+#include "tools/gfx-util/shader-cursor.h"
+#include "tools/unit-test/slang-unit-test.h"
#if SLANG_WINDOWS_FAMILY
#include <d3d12.h>
@@ -15,810 +14,943 @@ using namespace gfx;
namespace gfx_test
{
- struct TextureToTextureCopyInfo
- {
- SubresourceRange srcSubresource;
- SubresourceRange dstSubresource;
- ITextureResource::Extents extent;
- ITextureResource::Offset3D srcOffset;
- ITextureResource::Offset3D dstOffset;
- };
-
- struct TextureToBufferCopyInfo
- {
- SubresourceRange srcSubresource;
- ITextureResource::Extents extent;
- ITextureResource::Offset3D textureOffset;
- Offset bufferOffset;
- Offset bufferSize;
- };
-
- struct BaseCopyTextureTest
+struct TextureToTextureCopyInfo
+{
+ SubresourceRange srcSubresource;
+ SubresourceRange dstSubresource;
+ ITextureResource::Extents extent;
+ ITextureResource::Offset3D srcOffset;
+ ITextureResource::Offset3D dstOffset;
+};
+
+struct TextureToBufferCopyInfo
+{
+ SubresourceRange srcSubresource;
+ ITextureResource::Extents extent;
+ ITextureResource::Offset3D textureOffset;
+ Offset bufferOffset;
+ Offset bufferSize;
+};
+
+struct BaseCopyTextureTest
+{
+ IDevice* device;
+ UnitTestContext* context;
+
+ Size alignedRowStride;
+
+ RefPtr<TextureInfo> srcTextureInfo;
+ RefPtr<TextureInfo> dstTextureInfo;
+ TextureToTextureCopyInfo texCopyInfo;
+ TextureToBufferCopyInfo bufferCopyInfo;
+
+ ComPtr<ITextureResource> srcTexture;
+ ComPtr<ITextureResource> dstTexture;
+ ComPtr<IBufferResource> resultsBuffer;
+
+ RefPtr<ValidationTextureFormatBase> validationFormat;
+
+ void init(
+ IDevice* device,
+ UnitTestContext* context,
+ Format format,
+ RefPtr<ValidationTextureFormatBase> validationFormat,
+ ITextureResource::Type type)
{
- IDevice* device;
- UnitTestContext* context;
-
- Size alignedRowStride;
-
- RefPtr<TextureInfo> srcTextureInfo;
- RefPtr<TextureInfo> dstTextureInfo;
- TextureToTextureCopyInfo texCopyInfo;
- TextureToBufferCopyInfo bufferCopyInfo;
-
- ComPtr<ITextureResource> srcTexture;
- ComPtr<ITextureResource> dstTexture;
- ComPtr<IBufferResource> resultsBuffer;
-
- RefPtr<ValidationTextureFormatBase> validationFormat;
-
- void init(
- IDevice* device,
- UnitTestContext* context,
- Format format,
- RefPtr<ValidationTextureFormatBase> validationFormat,
- ITextureResource::Type type)
- {
- this->device = device;
- this->context = context;
- this->validationFormat = validationFormat;
+ this->device = device;
+ this->context = context;
+ this->validationFormat = validationFormat;
- this->srcTextureInfo = new TextureInfo();
- this->srcTextureInfo->format = format;
- this->srcTextureInfo->textureType = type;
+ this->srcTextureInfo = new TextureInfo();
+ this->srcTextureInfo->format = format;
+ this->srcTextureInfo->textureType = type;
- this->dstTextureInfo = new TextureInfo();
- this->dstTextureInfo->format = format;
- this->dstTextureInfo->textureType = type;
- }
+ this->dstTextureInfo = new TextureInfo();
+ this->dstTextureInfo->format = format;
+ this->dstTextureInfo->textureType = type;
+ }
- void createRequiredResources()
+ void createRequiredResources()
+ {
+ ITextureResource::Desc srcTexDesc = {};
+ srcTexDesc.type = srcTextureInfo->textureType;
+ srcTexDesc.numMipLevels = srcTextureInfo->mipLevelCount;
+ srcTexDesc.arraySize = srcTextureInfo->arrayLayerCount;
+ srcTexDesc.size = srcTextureInfo->extents;
+ srcTexDesc.defaultState = ResourceState::ShaderResource;
+ srcTexDesc.allowedStates =
+ ResourceStateSet(ResourceState::ShaderResource, ResourceState::CopySource);
+ if (srcTextureInfo->format == Format::D32_FLOAT ||
+ srcTextureInfo->format == Format::D16_UNORM)
{
- ITextureResource::Desc srcTexDesc = {};
- srcTexDesc.type = srcTextureInfo->textureType;
- srcTexDesc.numMipLevels = srcTextureInfo->mipLevelCount;
- srcTexDesc.arraySize = srcTextureInfo->arrayLayerCount;
- srcTexDesc.size = srcTextureInfo->extents;
- srcTexDesc.defaultState = ResourceState::ShaderResource;
- srcTexDesc.allowedStates = ResourceStateSet(
- ResourceState::ShaderResource,
- ResourceState::CopySource);
- if (srcTextureInfo->format == Format::D32_FLOAT || srcTextureInfo->format == Format::D16_UNORM)
- {
- srcTexDesc.allowedStates.add(ResourceState::DepthWrite);
- srcTexDesc.allowedStates.add(ResourceState::DepthRead);
- }
- srcTexDesc.format = srcTextureInfo->format;
-
- GFX_CHECK_CALL_ABORT(device->createTextureResource(
- srcTexDesc,
- srcTextureInfo->subresourceDatas.getBuffer(),
- srcTexture.writeRef()));
-
- ITextureResource::Desc dstTexDesc = {};
- dstTexDesc.type = dstTextureInfo->textureType;
- dstTexDesc.numMipLevels = dstTextureInfo->mipLevelCount;
- dstTexDesc.arraySize = dstTextureInfo->arrayLayerCount;
- dstTexDesc.size = dstTextureInfo->extents;
- dstTexDesc.defaultState = ResourceState::CopyDestination;
- dstTexDesc.allowedStates = ResourceStateSet(
- ResourceState::ShaderResource,
- ResourceState::CopyDestination,
- ResourceState::CopySource);
- if (dstTextureInfo->format == Format::D32_FLOAT || dstTextureInfo->format == Format::D16_UNORM)
- {
- dstTexDesc.allowedStates.add(ResourceState::DepthWrite);
- dstTexDesc.allowedStates.add(ResourceState::DepthRead);
- }
- dstTexDesc.format = dstTextureInfo->format;
-
- GFX_CHECK_CALL_ABORT(device->createTextureResource(
- dstTexDesc,
- dstTextureInfo->subresourceDatas.getBuffer(),
- dstTexture.writeRef()));
-
- auto bufferCopyExtents = bufferCopyInfo.extent;
- auto texelSize = getTexelSize(dstTextureInfo->format);
- size_t alignment;
- device->getTextureRowAlignment(&alignment);
- alignedRowStride = (bufferCopyExtents.width * texelSize + alignment - 1) & ~(alignment - 1);
- IBufferResource::Desc bufferDesc = {};
- bufferDesc.sizeInBytes = bufferCopyExtents.height * bufferCopyExtents.depth * alignedRowStride;
- bufferDesc.format = Format::Unknown;
- bufferDesc.elementSize = 0;
- bufferDesc.allowedStates = ResourceStateSet(
- ResourceState::ShaderResource,
- ResourceState::UnorderedAccess,
- ResourceState::CopyDestination,
- ResourceState::CopySource);
- bufferDesc.defaultState = ResourceState::CopyDestination;
- bufferDesc.memoryType = MemoryType::DeviceLocal;
-
- GFX_CHECK_CALL_ABORT(device->createBufferResource(
- bufferDesc,
- nullptr,
- resultsBuffer.writeRef()));
-
- bufferCopyInfo.bufferSize = bufferDesc.sizeInBytes;
+ srcTexDesc.allowedStates.add(ResourceState::DepthWrite);
+ srcTexDesc.allowedStates.add(ResourceState::DepthRead);
}
-
- void submitGPUWork()
+ srcTexDesc.format = srcTextureInfo->format;
+
+ GFX_CHECK_CALL_ABORT(device->createTextureResource(
+ srcTexDesc,
+ srcTextureInfo->subresourceDatas.getBuffer(),
+ srcTexture.writeRef()));
+
+ ITextureResource::Desc dstTexDesc = {};
+ dstTexDesc.type = dstTextureInfo->textureType;
+ dstTexDesc.numMipLevels = dstTextureInfo->mipLevelCount;
+ dstTexDesc.arraySize = dstTextureInfo->arrayLayerCount;
+ dstTexDesc.size = dstTextureInfo->extents;
+ dstTexDesc.defaultState = ResourceState::CopyDestination;
+ dstTexDesc.allowedStates = ResourceStateSet(
+ ResourceState::ShaderResource,
+ ResourceState::CopyDestination,
+ ResourceState::CopySource);
+ if (dstTextureInfo->format == Format::D32_FLOAT ||
+ dstTextureInfo->format == Format::D16_UNORM)
{
- 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->encodeResourceCommands();
-
- encoder->textureSubresourceBarrier(srcTexture, texCopyInfo.srcSubresource, ResourceState::ShaderResource, ResourceState::CopySource);
- encoder->copyTexture(
- dstTexture,
- ResourceState::CopyDestination,
- texCopyInfo.dstSubresource,
- texCopyInfo.dstOffset,
- srcTexture,
- ResourceState::CopySource,
- texCopyInfo.srcSubresource,
- texCopyInfo.srcOffset,
- texCopyInfo.extent);
-
- encoder->textureSubresourceBarrier(dstTexture, bufferCopyInfo.srcSubresource, ResourceState::CopyDestination, ResourceState::CopySource);
- encoder->copyTextureToBuffer(
- resultsBuffer,
- bufferCopyInfo.bufferOffset,
- bufferCopyInfo.bufferSize,
- alignedRowStride,
- dstTexture,
- ResourceState::CopySource,
- bufferCopyInfo.srcSubresource,
- bufferCopyInfo.textureOffset,
- bufferCopyInfo.extent);
-
- encoder->endEncoding();
- commandBuffer->close();
- queue->executeCommandBuffer(commandBuffer);
- queue->waitOnHost();
+ dstTexDesc.allowedStates.add(ResourceState::DepthWrite);
+ dstTexDesc.allowedStates.add(ResourceState::DepthRead);
}
+ dstTexDesc.format = dstTextureInfo->format;
+
+ GFX_CHECK_CALL_ABORT(device->createTextureResource(
+ dstTexDesc,
+ dstTextureInfo->subresourceDatas.getBuffer(),
+ dstTexture.writeRef()));
+
+ auto bufferCopyExtents = bufferCopyInfo.extent;
+ auto texelSize = getTexelSize(dstTextureInfo->format);
+ size_t alignment;
+ device->getTextureRowAlignment(&alignment);
+ alignedRowStride = (bufferCopyExtents.width * texelSize + alignment - 1) & ~(alignment - 1);
+ IBufferResource::Desc bufferDesc = {};
+ bufferDesc.sizeInBytes =
+ bufferCopyExtents.height * bufferCopyExtents.depth * alignedRowStride;
+ bufferDesc.format = Format::Unknown;
+ bufferDesc.elementSize = 0;
+ bufferDesc.allowedStates = ResourceStateSet(
+ ResourceState::ShaderResource,
+ ResourceState::UnorderedAccess,
+ ResourceState::CopyDestination,
+ ResourceState::CopySource);
+ bufferDesc.defaultState = ResourceState::CopyDestination;
+ bufferDesc.memoryType = MemoryType::DeviceLocal;
+
+ GFX_CHECK_CALL_ABORT(
+ device->createBufferResource(bufferDesc, nullptr, resultsBuffer.writeRef()));
+
+ bufferCopyInfo.bufferSize = bufferDesc.sizeInBytes;
+ }
- bool isWithinCopyBounds(GfxIndex x, GfxIndex y, GfxIndex z)
- {
- auto copyExtents = texCopyInfo.extent;
- auto copyOffset = texCopyInfo.dstOffset;
-
- auto xLowerBound = copyOffset.x;
- auto xUpperBound = copyOffset.x + copyExtents.width;
- auto yLowerBound = copyOffset.y;
- auto yUpperBound = copyOffset.y + copyExtents.height;
- auto zLowerBound = copyOffset.z;
- auto zUpperBound = copyOffset.z + copyExtents.depth;
-
- if (x < xLowerBound || x >= xUpperBound || y < yLowerBound || y >= yUpperBound || z < zLowerBound || z >= zUpperBound)
- return false;
- else
- return true;
- }
+ void submitGPUWork()
+ {
+ 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->encodeResourceCommands();
+
+ encoder->textureSubresourceBarrier(
+ srcTexture,
+ texCopyInfo.srcSubresource,
+ ResourceState::ShaderResource,
+ ResourceState::CopySource);
+ encoder->copyTexture(
+ dstTexture,
+ ResourceState::CopyDestination,
+ texCopyInfo.dstSubresource,
+ texCopyInfo.dstOffset,
+ srcTexture,
+ ResourceState::CopySource,
+ texCopyInfo.srcSubresource,
+ texCopyInfo.srcOffset,
+ texCopyInfo.extent);
+
+ encoder->textureSubresourceBarrier(
+ dstTexture,
+ bufferCopyInfo.srcSubresource,
+ ResourceState::CopyDestination,
+ ResourceState::CopySource);
+ encoder->copyTextureToBuffer(
+ resultsBuffer,
+ bufferCopyInfo.bufferOffset,
+ bufferCopyInfo.bufferSize,
+ alignedRowStride,
+ dstTexture,
+ ResourceState::CopySource,
+ bufferCopyInfo.srcSubresource,
+ bufferCopyInfo.textureOffset,
+ bufferCopyInfo.extent);
+
+ encoder->endEncoding();
+ commandBuffer->close();
+ queue->executeCommandBuffer(commandBuffer);
+ queue->waitOnHost();
+ }
- void validateTestResults(
- ValidationTextureData actual,
- ValidationTextureData expectedCopied,
- ValidationTextureData expectedOriginal)
- {
- auto actualExtents = actual.extents;
- auto copyExtent = texCopyInfo.extent;
- auto srcTexOffset = texCopyInfo.srcOffset;
- auto dstTexOffset = texCopyInfo.dstOffset;
+ bool isWithinCopyBounds(GfxIndex x, GfxIndex y, GfxIndex z)
+ {
+ auto copyExtents = texCopyInfo.extent;
+ auto copyOffset = texCopyInfo.dstOffset;
+
+ auto xLowerBound = copyOffset.x;
+ auto xUpperBound = copyOffset.x + copyExtents.width;
+ auto yLowerBound = copyOffset.y;
+ auto yUpperBound = copyOffset.y + copyExtents.height;
+ auto zLowerBound = copyOffset.z;
+ auto zUpperBound = copyOffset.z + copyExtents.depth;
+
+ if (x < xLowerBound || x >= xUpperBound || y < yLowerBound || y >= yUpperBound ||
+ z < zLowerBound || z >= zUpperBound)
+ return false;
+ else
+ return true;
+ }
+
+ void validateTestResults(
+ ValidationTextureData actual,
+ ValidationTextureData expectedCopied,
+ ValidationTextureData expectedOriginal)
+ {
+ auto actualExtents = actual.extents;
+ auto copyExtent = texCopyInfo.extent;
+ auto srcTexOffset = texCopyInfo.srcOffset;
+ auto dstTexOffset = texCopyInfo.dstOffset;
- for (GfxIndex x = 0; x < actualExtents.width; ++x)
+ for (GfxIndex x = 0; x < actualExtents.width; ++x)
+ {
+ for (GfxIndex y = 0; y < actualExtents.height; ++y)
{
- for (GfxIndex y = 0; y < actualExtents.height; ++y)
+ for (GfxIndex z = 0; z < actualExtents.depth; ++z)
{
- for (GfxIndex z = 0; z < actualExtents.depth; ++z)
+ auto actualBlock = actual.getBlockAt(x, y, z);
+ if (isWithinCopyBounds(x, y, z))
+ {
+ // Block is located within the bounds of the source texture
+ auto xSource = x + srcTexOffset.x - dstTexOffset.x;
+ auto ySource = y + srcTexOffset.y - dstTexOffset.y;
+ auto zSource = z + srcTexOffset.z - dstTexOffset.z;
+ auto expectedBlock = expectedCopied.getBlockAt(xSource, ySource, zSource);
+ validationFormat->validateBlocksEqual(actualBlock, expectedBlock);
+ }
+ else
{
- auto actualBlock = actual.getBlockAt(x, y, z);
- if (isWithinCopyBounds(x, y, z))
- {
- // Block is located within the bounds of the source texture
- auto xSource = x + srcTexOffset.x - dstTexOffset.x;
- auto ySource = y + srcTexOffset.y - dstTexOffset.y;
- auto zSource = z + srcTexOffset.z - dstTexOffset.z;
- auto expectedBlock = expectedCopied.getBlockAt(xSource, ySource, zSource);
- validationFormat->validateBlocksEqual(actualBlock, expectedBlock);
- }
- else
- {
- // Block is located outside the bounds of the source texture and should be compared
- // against known expected values for the destination texture.
- auto expectedBlock = expectedOriginal.getBlockAt(x, y, z);
- validationFormat->validateBlocksEqual(actualBlock, expectedBlock);
- }
+ // Block is located outside the bounds of the source texture and should be
+ // compared against known expected values for the destination texture.
+ auto expectedBlock = expectedOriginal.getBlockAt(x, y, z);
+ validationFormat->validateBlocksEqual(actualBlock, expectedBlock);
}
}
}
}
+ }
- void checkTestResults(ITextureResource::Extents srcMipExtent, const void* expectedCopiedData, const void* expectedOriginalData)
+ void checkTestResults(
+ ITextureResource::Extents srcMipExtent,
+ const void* expectedCopiedData,
+ const void* expectedOriginalData)
+ {
+ ComPtr<ISlangBlob> resultBlob;
+ GFX_CHECK_CALL_ABORT(device->readBufferResource(
+ resultsBuffer,
+ 0,
+ bufferCopyInfo.bufferSize,
+ resultBlob.writeRef()));
+ auto results = resultBlob->getBufferPointer();
+
+ ValidationTextureData actual;
+ actual.extents = bufferCopyInfo.extent;
+ actual.textureData = results;
+ actual.strides.x = getTexelSize(dstTextureInfo->format);
+ actual.strides.y = alignedRowStride;
+ actual.strides.z = actual.extents.height * actual.strides.y;
+
+ ValidationTextureData expectedCopied;
+ expectedCopied.extents = srcMipExtent;
+ expectedCopied.textureData = expectedCopiedData;
+ expectedCopied.strides.x = getTexelSize(srcTextureInfo->format);
+ expectedCopied.strides.y = expectedCopied.extents.width * expectedCopied.strides.x;
+ expectedCopied.strides.z = expectedCopied.extents.height * expectedCopied.strides.y;
+
+ ValidationTextureData expectedOriginal;
+ if (expectedOriginalData)
{
- ComPtr<ISlangBlob> resultBlob;
- GFX_CHECK_CALL_ABORT(device->readBufferResource(resultsBuffer, 0, bufferCopyInfo.bufferSize, resultBlob.writeRef()));
- auto results = resultBlob->getBufferPointer();
-
- ValidationTextureData actual;
- actual.extents = bufferCopyInfo.extent;
- actual.textureData = results;
- actual.strides.x = getTexelSize(dstTextureInfo->format);
- actual.strides.y = alignedRowStride;
- actual.strides.z = actual.extents.height * actual.strides.y;
-
- ValidationTextureData expectedCopied;
- expectedCopied.extents = srcMipExtent;
- expectedCopied.textureData = expectedCopiedData;
- expectedCopied.strides.x = getTexelSize(srcTextureInfo->format);
- expectedCopied.strides.y = expectedCopied.extents.width * expectedCopied.strides.x;
- expectedCopied.strides.z = expectedCopied.extents.height * expectedCopied.strides.y;
-
- ValidationTextureData expectedOriginal;
- if (expectedOriginalData)
- {
- expectedOriginal.extents = bufferCopyInfo.extent;
- expectedOriginal.textureData = expectedOriginalData;
- expectedOriginal.strides.x = getTexelSize(dstTextureInfo->format);
- expectedOriginal.strides.y = expectedOriginal.extents.width * expectedOriginal.strides.x;
- expectedOriginal.strides.z = expectedOriginal.extents.height * expectedOriginal.strides.y;
- }
-
- validateTestResults(actual, expectedCopied, expectedOriginal);
+ expectedOriginal.extents = bufferCopyInfo.extent;
+ expectedOriginal.textureData = expectedOriginalData;
+ expectedOriginal.strides.x = getTexelSize(dstTextureInfo->format);
+ expectedOriginal.strides.y =
+ expectedOriginal.extents.width * expectedOriginal.strides.x;
+ expectedOriginal.strides.z =
+ expectedOriginal.extents.height * expectedOriginal.strides.y;
}
- };
- struct SimpleCopyTexture : BaseCopyTextureTest
+ validateTestResults(actual, expectedCopied, expectedOriginal);
+ }
+};
+
+struct SimpleCopyTexture : BaseCopyTextureTest
+{
+ void run()
{
- void run()
- {
- auto textureType = srcTextureInfo->textureType;
- auto format = srcTextureInfo->format;
-
- srcTextureInfo->extents.width = 4;
- srcTextureInfo->extents.height = (textureType == ITextureResource::Type::Texture1D) ? 1 : 4;
- srcTextureInfo->extents.depth = (textureType == ITextureResource::Type::Texture3D) ? 2 : 1;
- srcTextureInfo->mipLevelCount = 1;
- srcTextureInfo->arrayLayerCount = 1;
-
- dstTextureInfo = srcTextureInfo;
-
- generateTextureData(srcTextureInfo, validationFormat);
-
- SubresourceRange srcSubresource = {};
- srcSubresource.aspectMask = getTextureAspect(format);
- srcSubresource.mipLevel = 0;
- srcSubresource.mipLevelCount = 1;
- srcSubresource.baseArrayLayer = 0;
- srcSubresource.layerCount = 1;
-
- SubresourceRange dstSubresource = {};
- dstSubresource.aspectMask = getTextureAspect(format);
- dstSubresource.mipLevel = 0;
- dstSubresource.mipLevelCount = 1;
- dstSubresource.baseArrayLayer = 0;
- dstSubresource.layerCount = 1;
-
- texCopyInfo.srcSubresource = srcSubresource;
- texCopyInfo.dstSubresource = dstSubresource;
- texCopyInfo.extent = srcTextureInfo->extents;
- texCopyInfo.srcOffset = { 0, 0, 0 };
- texCopyInfo.dstOffset = { 0, 0, 0 };
-
- bufferCopyInfo.srcSubresource = dstSubresource;
- bufferCopyInfo.extent = dstTextureInfo->extents;
- bufferCopyInfo.textureOffset = { 0, 0, 0 };
- bufferCopyInfo.bufferOffset = 0;
-
- createRequiredResources();
- submitGPUWork();
-
- auto subresourceIndex = getSubresourceIndex(srcSubresource.mipLevel, srcTextureInfo->mipLevelCount, srcSubresource.baseArrayLayer);
- auto expectedData = srcTextureInfo->subresourceDatas[subresourceIndex];
- checkTestResults(srcTextureInfo->extents, expectedData.data, nullptr);
- }
- };
+ auto textureType = srcTextureInfo->textureType;
+ auto format = srcTextureInfo->format;
+
+ srcTextureInfo->extents.width = 4;
+ srcTextureInfo->extents.height = (textureType == ITextureResource::Type::Texture1D) ? 1 : 4;
+ srcTextureInfo->extents.depth = (textureType == ITextureResource::Type::Texture3D) ? 2 : 1;
+ srcTextureInfo->mipLevelCount = 1;
+ srcTextureInfo->arrayLayerCount = 1;
+
+ dstTextureInfo = srcTextureInfo;
+
+ generateTextureData(srcTextureInfo, validationFormat);
+
+ SubresourceRange srcSubresource = {};
+ srcSubresource.aspectMask = getTextureAspect(format);
+ srcSubresource.mipLevel = 0;
+ srcSubresource.mipLevelCount = 1;
+ srcSubresource.baseArrayLayer = 0;
+ srcSubresource.layerCount = 1;
+
+ SubresourceRange dstSubresource = {};
+ dstSubresource.aspectMask = getTextureAspect(format);
+ dstSubresource.mipLevel = 0;
+ dstSubresource.mipLevelCount = 1;
+ dstSubresource.baseArrayLayer = 0;
+ dstSubresource.layerCount = 1;
+
+ texCopyInfo.srcSubresource = srcSubresource;
+ texCopyInfo.dstSubresource = dstSubresource;
+ texCopyInfo.extent = srcTextureInfo->extents;
+ texCopyInfo.srcOffset = {0, 0, 0};
+ texCopyInfo.dstOffset = {0, 0, 0};
+
+ bufferCopyInfo.srcSubresource = dstSubresource;
+ bufferCopyInfo.extent = dstTextureInfo->extents;
+ bufferCopyInfo.textureOffset = {0, 0, 0};
+ bufferCopyInfo.bufferOffset = 0;
+
+ createRequiredResources();
+ submitGPUWork();
+
+ auto subresourceIndex = getSubresourceIndex(
+ srcSubresource.mipLevel,
+ srcTextureInfo->mipLevelCount,
+ srcSubresource.baseArrayLayer);
+ auto expectedData = srcTextureInfo->subresourceDatas[subresourceIndex];
+ checkTestResults(srcTextureInfo->extents, expectedData.data, nullptr);
+ }
+};
- struct CopyTextureSection : BaseCopyTextureTest
+struct CopyTextureSection : BaseCopyTextureTest
+{
+ void run()
{
- void run()
- {
- auto textureType = srcTextureInfo->textureType;
- auto format = srcTextureInfo->format;
-
- srcTextureInfo->extents.width = 4;
- srcTextureInfo->extents.height = (textureType == ITextureResource::Type::Texture1D) ? 1 : 4;
- srcTextureInfo->extents.depth = (textureType == ITextureResource::Type::Texture3D) ? 2 : 1;
- srcTextureInfo->mipLevelCount = 2;
- srcTextureInfo->arrayLayerCount = (textureType == ITextureResource::Type::Texture3D) ? 1 : 2;
-
- dstTextureInfo = srcTextureInfo;
-
- generateTextureData(srcTextureInfo, validationFormat);
-
- SubresourceRange srcSubresource = {};
- srcSubresource.aspectMask = getTextureAspect(format);
- srcSubresource.mipLevel = 0;
- srcSubresource.mipLevelCount = 1;
- srcSubresource.baseArrayLayer = (textureType == ITextureResource::Type::Texture3D) ? 0 : 1;
- srcSubresource.layerCount = 1;
-
- SubresourceRange dstSubresource = {};
- dstSubresource.aspectMask = getTextureAspect(format);
- dstSubresource.mipLevel = 0;
- dstSubresource.mipLevelCount = 1;
- dstSubresource.baseArrayLayer = 0;
- dstSubresource.layerCount = 1;
-
- texCopyInfo.srcSubresource = srcSubresource;
- texCopyInfo.dstSubresource = dstSubresource;
- texCopyInfo.extent = srcTextureInfo->extents;
- texCopyInfo.srcOffset = { 0, 0, 0 };
- texCopyInfo.dstOffset = { 0, 0, 0 };
-
- bufferCopyInfo.srcSubresource = dstSubresource;
- bufferCopyInfo.extent = dstTextureInfo->extents;
- bufferCopyInfo.textureOffset = { 0, 0, 0 };
- bufferCopyInfo.bufferOffset = 0;
-
- createRequiredResources();
- submitGPUWork();
-
- auto subresourceIndex = getSubresourceIndex(srcSubresource.mipLevel, srcTextureInfo->mipLevelCount, srcSubresource.baseArrayLayer);
- ITextureResource::SubresourceData expectedData = srcTextureInfo->subresourceDatas[subresourceIndex];
- checkTestResults(srcTextureInfo->extents, expectedData.data, nullptr);
- }
- };
+ auto textureType = srcTextureInfo->textureType;
+ auto format = srcTextureInfo->format;
+
+ srcTextureInfo->extents.width = 4;
+ srcTextureInfo->extents.height = (textureType == ITextureResource::Type::Texture1D) ? 1 : 4;
+ srcTextureInfo->extents.depth = (textureType == ITextureResource::Type::Texture3D) ? 2 : 1;
+ srcTextureInfo->mipLevelCount = 2;
+ srcTextureInfo->arrayLayerCount =
+ (textureType == ITextureResource::Type::Texture3D) ? 1 : 2;
+
+ dstTextureInfo = srcTextureInfo;
+
+ generateTextureData(srcTextureInfo, validationFormat);
+
+ SubresourceRange srcSubresource = {};
+ srcSubresource.aspectMask = getTextureAspect(format);
+ srcSubresource.mipLevel = 0;
+ srcSubresource.mipLevelCount = 1;
+ srcSubresource.baseArrayLayer = (textureType == ITextureResource::Type::Texture3D) ? 0 : 1;
+ srcSubresource.layerCount = 1;
+
+ SubresourceRange dstSubresource = {};
+ dstSubresource.aspectMask = getTextureAspect(format);
+ dstSubresource.mipLevel = 0;
+ dstSubresource.mipLevelCount = 1;
+ dstSubresource.baseArrayLayer = 0;
+ dstSubresource.layerCount = 1;
+
+ texCopyInfo.srcSubresource = srcSubresource;
+ texCopyInfo.dstSubresource = dstSubresource;
+ texCopyInfo.extent = srcTextureInfo->extents;
+ texCopyInfo.srcOffset = {0, 0, 0};
+ texCopyInfo.dstOffset = {0, 0, 0};
+
+ bufferCopyInfo.srcSubresource = dstSubresource;
+ bufferCopyInfo.extent = dstTextureInfo->extents;
+ bufferCopyInfo.textureOffset = {0, 0, 0};
+ bufferCopyInfo.bufferOffset = 0;
+
+ createRequiredResources();
+ submitGPUWork();
+
+ auto subresourceIndex = getSubresourceIndex(
+ srcSubresource.mipLevel,
+ srcTextureInfo->mipLevelCount,
+ srcSubresource.baseArrayLayer);
+ ITextureResource::SubresourceData expectedData =
+ srcTextureInfo->subresourceDatas[subresourceIndex];
+ checkTestResults(srcTextureInfo->extents, expectedData.data, nullptr);
+ }
+};
- struct LargeSrcToSmallDst : BaseCopyTextureTest
+struct LargeSrcToSmallDst : BaseCopyTextureTest
+{
+ void run()
{
- void run()
- {
- auto textureType = srcTextureInfo->textureType;
- auto format = srcTextureInfo->format;
-
- srcTextureInfo->extents.width = 8;
- srcTextureInfo->extents.height = (textureType == ITextureResource::Type::Texture1D) ? 1 : 8;
- srcTextureInfo->extents.depth = (textureType == ITextureResource::Type::Texture3D) ? 2 : 1;
- srcTextureInfo->mipLevelCount = 1;
- srcTextureInfo->arrayLayerCount = 1;
-
- generateTextureData(srcTextureInfo, validationFormat);
-
- dstTextureInfo->extents.width = 4;
- dstTextureInfo->extents.height = (textureType == ITextureResource::Type::Texture1D) ? 1 : 4;
- dstTextureInfo->extents.depth = (textureType == ITextureResource::Type::Texture3D) ? 2 : 1;
- dstTextureInfo->mipLevelCount = 1;
- dstTextureInfo->arrayLayerCount = 1;
-
- SubresourceRange srcSubresource = {};
- srcSubresource.aspectMask = getTextureAspect(format);
- srcSubresource.mipLevel = 0;
- srcSubresource.mipLevelCount = 1;
- srcSubresource.baseArrayLayer = 0;
- srcSubresource.layerCount = 1;
-
- SubresourceRange dstSubresource = {};
- dstSubresource.aspectMask = getTextureAspect(format);
- dstSubresource.mipLevel = 0;
- dstSubresource.mipLevelCount = 1;
- dstSubresource.baseArrayLayer = 0;
- dstSubresource.layerCount = 1;
-
- texCopyInfo.srcSubresource = srcSubresource;
- texCopyInfo.dstSubresource = dstSubresource;
- texCopyInfo.extent = dstTextureInfo->extents;
- texCopyInfo.srcOffset = { 0, 0, 0 };
- texCopyInfo.dstOffset = { 0, 0, 0 };
-
- bufferCopyInfo.srcSubresource = dstSubresource;
- bufferCopyInfo.extent = dstTextureInfo->extents;
- bufferCopyInfo.textureOffset = { 0, 0, 0 };
- bufferCopyInfo.bufferOffset = 0;
-
- createRequiredResources();
- submitGPUWork();
-
- auto subresourceIndex = getSubresourceIndex(srcSubresource.mipLevel, srcTextureInfo->mipLevelCount, srcSubresource.baseArrayLayer);
- ITextureResource::SubresourceData expectedData = srcTextureInfo->subresourceDatas[subresourceIndex];
- checkTestResults(srcTextureInfo->extents, expectedData.data, nullptr);
- }
- };
+ auto textureType = srcTextureInfo->textureType;
+ auto format = srcTextureInfo->format;
+
+ srcTextureInfo->extents.width = 8;
+ srcTextureInfo->extents.height = (textureType == ITextureResource::Type::Texture1D) ? 1 : 8;
+ srcTextureInfo->extents.depth = (textureType == ITextureResource::Type::Texture3D) ? 2 : 1;
+ srcTextureInfo->mipLevelCount = 1;
+ srcTextureInfo->arrayLayerCount = 1;
+
+ generateTextureData(srcTextureInfo, validationFormat);
+
+ dstTextureInfo->extents.width = 4;
+ dstTextureInfo->extents.height = (textureType == ITextureResource::Type::Texture1D) ? 1 : 4;
+ dstTextureInfo->extents.depth = (textureType == ITextureResource::Type::Texture3D) ? 2 : 1;
+ dstTextureInfo->mipLevelCount = 1;
+ dstTextureInfo->arrayLayerCount = 1;
+
+ SubresourceRange srcSubresource = {};
+ srcSubresource.aspectMask = getTextureAspect(format);
+ srcSubresource.mipLevel = 0;
+ srcSubresource.mipLevelCount = 1;
+ srcSubresource.baseArrayLayer = 0;
+ srcSubresource.layerCount = 1;
+
+ SubresourceRange dstSubresource = {};
+ dstSubresource.aspectMask = getTextureAspect(format);
+ dstSubresource.mipLevel = 0;
+ dstSubresource.mipLevelCount = 1;
+ dstSubresource.baseArrayLayer = 0;
+ dstSubresource.layerCount = 1;
+
+ texCopyInfo.srcSubresource = srcSubresource;
+ texCopyInfo.dstSubresource = dstSubresource;
+ texCopyInfo.extent = dstTextureInfo->extents;
+ texCopyInfo.srcOffset = {0, 0, 0};
+ texCopyInfo.dstOffset = {0, 0, 0};
+
+ bufferCopyInfo.srcSubresource = dstSubresource;
+ bufferCopyInfo.extent = dstTextureInfo->extents;
+ bufferCopyInfo.textureOffset = {0, 0, 0};
+ bufferCopyInfo.bufferOffset = 0;
+
+ createRequiredResources();
+ submitGPUWork();
+
+ auto subresourceIndex = getSubresourceIndex(
+ srcSubresource.mipLevel,
+ srcTextureInfo->mipLevelCount,
+ srcSubresource.baseArrayLayer);
+ ITextureResource::SubresourceData expectedData =
+ srcTextureInfo->subresourceDatas[subresourceIndex];
+ checkTestResults(srcTextureInfo->extents, expectedData.data, nullptr);
+ }
+};
- struct SmallSrcToLargeDst : BaseCopyTextureTest
+struct SmallSrcToLargeDst : BaseCopyTextureTest
+{
+ void run()
{
- void run()
- {
- auto textureType = srcTextureInfo->textureType;
- auto format = srcTextureInfo->format;
-
- srcTextureInfo->extents.width = 4;
- srcTextureInfo->extents.height = (textureType == ITextureResource::Type::Texture1D) ? 1 : 4;
- srcTextureInfo->extents.depth = (textureType == ITextureResource::Type::Texture3D) ? 2 : 1;
- srcTextureInfo->mipLevelCount = 1;
- srcTextureInfo->arrayLayerCount = 1;
-
- generateTextureData(srcTextureInfo, validationFormat);
-
- dstTextureInfo->extents.width = 8;
- dstTextureInfo->extents.height = (textureType == ITextureResource::Type::Texture1D) ? 1 : 8;
- dstTextureInfo->extents.depth = (textureType == ITextureResource::Type::Texture3D) ? 2 : 1;
- dstTextureInfo->mipLevelCount = 1;
- dstTextureInfo->arrayLayerCount = 1;
-
- generateTextureData(dstTextureInfo, validationFormat);
-
- SubresourceRange srcSubresource = {};
- srcSubresource.aspectMask = getTextureAspect(format);
- srcSubresource.mipLevel = 0;
- srcSubresource.mipLevelCount = 1;
- srcSubresource.baseArrayLayer = 0;
- srcSubresource.layerCount = 1;
-
- SubresourceRange dstSubresource = {};
- dstSubresource.aspectMask = getTextureAspect(format);
- dstSubresource.mipLevel = 0;
- dstSubresource.mipLevelCount = 1;
- dstSubresource.baseArrayLayer = 0;
- dstSubresource.layerCount = 1;
-
- texCopyInfo.srcSubresource = srcSubresource;
- texCopyInfo.dstSubresource = dstSubresource;
- texCopyInfo.extent = srcTextureInfo->extents;
- texCopyInfo.srcOffset = { 0, 0, 0 };
- texCopyInfo.dstOffset = { 0, 0, 0 };
-
- bufferCopyInfo.srcSubresource = dstSubresource;
- bufferCopyInfo.extent = dstTextureInfo->extents;
- bufferCopyInfo.textureOffset = { 0, 0, 0 };
- bufferCopyInfo.bufferOffset = 0;
-
- createRequiredResources();
- submitGPUWork();
-
- auto copiedSubresourceIndex = getSubresourceIndex(srcSubresource.mipLevel, srcTextureInfo->mipLevelCount, srcSubresource.baseArrayLayer);
- ITextureResource::SubresourceData expectedCopiedData = srcTextureInfo->subresourceDatas[copiedSubresourceIndex];
- auto originalSubresourceIndex = getSubresourceIndex(dstSubresource.mipLevel, dstTextureInfo->mipLevelCount, dstSubresource.baseArrayLayer);
- ITextureResource::SubresourceData expectedOriginalData = dstTextureInfo->subresourceDatas[originalSubresourceIndex];
- checkTestResults(srcTextureInfo->extents, expectedCopiedData.data, expectedOriginalData.data);
- }
- };
+ auto textureType = srcTextureInfo->textureType;
+ auto format = srcTextureInfo->format;
+
+ srcTextureInfo->extents.width = 4;
+ srcTextureInfo->extents.height = (textureType == ITextureResource::Type::Texture1D) ? 1 : 4;
+ srcTextureInfo->extents.depth = (textureType == ITextureResource::Type::Texture3D) ? 2 : 1;
+ srcTextureInfo->mipLevelCount = 1;
+ srcTextureInfo->arrayLayerCount = 1;
+
+ generateTextureData(srcTextureInfo, validationFormat);
+
+ dstTextureInfo->extents.width = 8;
+ dstTextureInfo->extents.height = (textureType == ITextureResource::Type::Texture1D) ? 1 : 8;
+ dstTextureInfo->extents.depth = (textureType == ITextureResource::Type::Texture3D) ? 2 : 1;
+ dstTextureInfo->mipLevelCount = 1;
+ dstTextureInfo->arrayLayerCount = 1;
+
+ generateTextureData(dstTextureInfo, validationFormat);
+
+ SubresourceRange srcSubresource = {};
+ srcSubresource.aspectMask = getTextureAspect(format);
+ srcSubresource.mipLevel = 0;
+ srcSubresource.mipLevelCount = 1;
+ srcSubresource.baseArrayLayer = 0;
+ srcSubresource.layerCount = 1;
+
+ SubresourceRange dstSubresource = {};
+ dstSubresource.aspectMask = getTextureAspect(format);
+ dstSubresource.mipLevel = 0;
+ dstSubresource.mipLevelCount = 1;
+ dstSubresource.baseArrayLayer = 0;
+ dstSubresource.layerCount = 1;
+
+ texCopyInfo.srcSubresource = srcSubresource;
+ texCopyInfo.dstSubresource = dstSubresource;
+ texCopyInfo.extent = srcTextureInfo->extents;
+ texCopyInfo.srcOffset = {0, 0, 0};
+ texCopyInfo.dstOffset = {0, 0, 0};
+
+ bufferCopyInfo.srcSubresource = dstSubresource;
+ bufferCopyInfo.extent = dstTextureInfo->extents;
+ bufferCopyInfo.textureOffset = {0, 0, 0};
+ bufferCopyInfo.bufferOffset = 0;
+
+ createRequiredResources();
+ submitGPUWork();
+
+ auto copiedSubresourceIndex = getSubresourceIndex(
+ srcSubresource.mipLevel,
+ srcTextureInfo->mipLevelCount,
+ srcSubresource.baseArrayLayer);
+ ITextureResource::SubresourceData expectedCopiedData =
+ srcTextureInfo->subresourceDatas[copiedSubresourceIndex];
+ auto originalSubresourceIndex = getSubresourceIndex(
+ dstSubresource.mipLevel,
+ dstTextureInfo->mipLevelCount,
+ dstSubresource.baseArrayLayer);
+ ITextureResource::SubresourceData expectedOriginalData =
+ dstTextureInfo->subresourceDatas[originalSubresourceIndex];
+ checkTestResults(
+ srcTextureInfo->extents,
+ expectedCopiedData.data,
+ expectedOriginalData.data);
+ }
+};
- struct CopyBetweenMips : BaseCopyTextureTest
+struct CopyBetweenMips : BaseCopyTextureTest
+{
+ void run()
{
- void run()
- {
- auto textureType = srcTextureInfo->textureType;
- auto format = srcTextureInfo->format;
-
- srcTextureInfo->extents.width = 16;
- srcTextureInfo->extents.height = (textureType == ITextureResource::Type::Texture1D) ? 1 : 16;
- srcTextureInfo->extents.depth = (textureType == ITextureResource::Type::Texture3D) ? 2 : 1;
- srcTextureInfo->mipLevelCount = 4;
- srcTextureInfo->arrayLayerCount = 1;
-
- generateTextureData(srcTextureInfo, validationFormat);
-
- dstTextureInfo->extents.width = 16;
- dstTextureInfo->extents.height = (textureType == ITextureResource::Type::Texture1D) ? 1 : 16;
- dstTextureInfo->extents.depth = (textureType == ITextureResource::Type::Texture3D) ? 2 : 1;
- dstTextureInfo->mipLevelCount = 4;
- dstTextureInfo->arrayLayerCount = 1;
-
- generateTextureData(dstTextureInfo, validationFormat);
-
- SubresourceRange srcSubresource = {};
- srcSubresource.aspectMask = getTextureAspect(format);
- srcSubresource.mipLevel = 2;
- srcSubresource.mipLevelCount = 1;
- srcSubresource.baseArrayLayer = 0;
- srcSubresource.layerCount = 1;
-
- SubresourceRange dstSubresource = {};
- dstSubresource.aspectMask = getTextureAspect(format);
- dstSubresource.mipLevel = 1;
- dstSubresource.mipLevelCount = 1;
- dstSubresource.baseArrayLayer = 0;
- dstSubresource.layerCount = 1;
-
- auto copiedSubresourceIndex = getSubresourceIndex(srcSubresource.mipLevel, srcTextureInfo->mipLevelCount, srcSubresource.baseArrayLayer);
- auto originalSubresourceIndex = getSubresourceIndex(dstSubresource.mipLevel, dstTextureInfo->mipLevelCount, dstSubresource.baseArrayLayer);
-
- texCopyInfo.srcSubresource = srcSubresource;
- texCopyInfo.dstSubresource = dstSubresource;
- texCopyInfo.extent = srcTextureInfo->subresourceObjects[copiedSubresourceIndex]->extents;
- texCopyInfo.srcOffset = { 0, 0, 0 };
- texCopyInfo.dstOffset = { 0, 0, 0 };
-
- bufferCopyInfo.srcSubresource = dstSubresource;
- bufferCopyInfo.extent = dstTextureInfo->subresourceObjects[originalSubresourceIndex]->extents;
- bufferCopyInfo.textureOffset = { 0, 0, 0 };
- bufferCopyInfo.bufferOffset = 0;
-
- createRequiredResources();
- submitGPUWork();
-
- ITextureResource::SubresourceData expectedCopiedData = srcTextureInfo->subresourceDatas[copiedSubresourceIndex];
- ITextureResource::SubresourceData expectedOriginalData = dstTextureInfo->subresourceDatas[originalSubresourceIndex];
- auto srcMipExtent = srcTextureInfo->subresourceObjects[2]->extents;
- checkTestResults(srcMipExtent, expectedCopiedData.data, expectedOriginalData.data);
- }
- };
+ auto textureType = srcTextureInfo->textureType;
+ auto format = srcTextureInfo->format;
+
+ srcTextureInfo->extents.width = 16;
+ srcTextureInfo->extents.height =
+ (textureType == ITextureResource::Type::Texture1D) ? 1 : 16;
+ srcTextureInfo->extents.depth = (textureType == ITextureResource::Type::Texture3D) ? 2 : 1;
+ srcTextureInfo->mipLevelCount = 4;
+ srcTextureInfo->arrayLayerCount = 1;
+
+ generateTextureData(srcTextureInfo, validationFormat);
+
+ dstTextureInfo->extents.width = 16;
+ dstTextureInfo->extents.height =
+ (textureType == ITextureResource::Type::Texture1D) ? 1 : 16;
+ dstTextureInfo->extents.depth = (textureType == ITextureResource::Type::Texture3D) ? 2 : 1;
+ dstTextureInfo->mipLevelCount = 4;
+ dstTextureInfo->arrayLayerCount = 1;
+
+ generateTextureData(dstTextureInfo, validationFormat);
+
+ SubresourceRange srcSubresource = {};
+ srcSubresource.aspectMask = getTextureAspect(format);
+ srcSubresource.mipLevel = 2;
+ srcSubresource.mipLevelCount = 1;
+ srcSubresource.baseArrayLayer = 0;
+ srcSubresource.layerCount = 1;
+
+ SubresourceRange dstSubresource = {};
+ dstSubresource.aspectMask = getTextureAspect(format);
+ dstSubresource.mipLevel = 1;
+ dstSubresource.mipLevelCount = 1;
+ dstSubresource.baseArrayLayer = 0;
+ dstSubresource.layerCount = 1;
+
+ auto copiedSubresourceIndex = getSubresourceIndex(
+ srcSubresource.mipLevel,
+ srcTextureInfo->mipLevelCount,
+ srcSubresource.baseArrayLayer);
+ auto originalSubresourceIndex = getSubresourceIndex(
+ dstSubresource.mipLevel,
+ dstTextureInfo->mipLevelCount,
+ dstSubresource.baseArrayLayer);
+
+ texCopyInfo.srcSubresource = srcSubresource;
+ texCopyInfo.dstSubresource = dstSubresource;
+ texCopyInfo.extent = srcTextureInfo->subresourceObjects[copiedSubresourceIndex]->extents;
+ texCopyInfo.srcOffset = {0, 0, 0};
+ texCopyInfo.dstOffset = {0, 0, 0};
+
+ bufferCopyInfo.srcSubresource = dstSubresource;
+ bufferCopyInfo.extent =
+ dstTextureInfo->subresourceObjects[originalSubresourceIndex]->extents;
+ bufferCopyInfo.textureOffset = {0, 0, 0};
+ bufferCopyInfo.bufferOffset = 0;
+
+ createRequiredResources();
+ submitGPUWork();
+
+ ITextureResource::SubresourceData expectedCopiedData =
+ srcTextureInfo->subresourceDatas[copiedSubresourceIndex];
+ ITextureResource::SubresourceData expectedOriginalData =
+ dstTextureInfo->subresourceDatas[originalSubresourceIndex];
+ auto srcMipExtent = srcTextureInfo->subresourceObjects[2]->extents;
+ checkTestResults(srcMipExtent, expectedCopiedData.data, expectedOriginalData.data);
+ }
+};
- struct CopyBetweenLayers : BaseCopyTextureTest
+struct CopyBetweenLayers : BaseCopyTextureTest
+{
+ void run()
{
- void run()
- {
- auto textureType = srcTextureInfo->textureType;
- auto format = srcTextureInfo->format;
-
- srcTextureInfo->extents.width = 4;
- srcTextureInfo->extents.height = (textureType == ITextureResource::Type::Texture1D) ? 1 : 4;
- srcTextureInfo->extents.depth = (textureType == ITextureResource::Type::Texture3D) ? 2 : 1;
- srcTextureInfo->mipLevelCount = 1;
- srcTextureInfo->arrayLayerCount = (textureType == ITextureResource::Type::Texture3D) ? 1 : 2;
-
- generateTextureData(srcTextureInfo, validationFormat);
- dstTextureInfo = srcTextureInfo;
-
- SubresourceRange srcSubresource = {};
- srcSubresource.aspectMask = getTextureAspect(format);
- srcSubresource.mipLevel = 0;
- srcSubresource.mipLevelCount = 1;
- srcSubresource.baseArrayLayer = 0;
- srcSubresource.layerCount = 1;
-
- SubresourceRange dstSubresource = {};
- dstSubresource.aspectMask = getTextureAspect(format);
- dstSubresource.mipLevel = 0;
- dstSubresource.mipLevelCount = 1;
- dstSubresource.baseArrayLayer = (textureType == ITextureResource::Type::Texture3D) ? 0 : 1;
- dstSubresource.layerCount = 1;
-
- texCopyInfo.srcSubresource = srcSubresource;
- texCopyInfo.dstSubresource = dstSubresource;
- texCopyInfo.extent = srcTextureInfo->extents;
- texCopyInfo.srcOffset = { 0, 0, 0 };
- texCopyInfo.dstOffset = { 0, 0, 0 };
-
- bufferCopyInfo.srcSubresource = dstSubresource;
- bufferCopyInfo.extent = dstTextureInfo->extents;
- bufferCopyInfo.textureOffset = { 0, 0, 0 };
- bufferCopyInfo.bufferOffset = 0;
-
- createRequiredResources();
- submitGPUWork();
-
- auto copiedSubresourceIndex = getSubresourceIndex(srcSubresource.mipLevel, srcTextureInfo->mipLevelCount, srcSubresource.baseArrayLayer);
- ITextureResource::SubresourceData expectedCopiedData = srcTextureInfo->subresourceDatas[copiedSubresourceIndex];
- auto originalSubresourceIndex = getSubresourceIndex(dstSubresource.mipLevel, dstTextureInfo->mipLevelCount, dstSubresource.baseArrayLayer);
- ITextureResource::SubresourceData expectedOriginalData = dstTextureInfo->subresourceDatas[originalSubresourceIndex];
- checkTestResults(srcTextureInfo->extents, expectedCopiedData.data, expectedOriginalData.data);
- }
- };
+ auto textureType = srcTextureInfo->textureType;
+ auto format = srcTextureInfo->format;
+
+ srcTextureInfo->extents.width = 4;
+ srcTextureInfo->extents.height = (textureType == ITextureResource::Type::Texture1D) ? 1 : 4;
+ srcTextureInfo->extents.depth = (textureType == ITextureResource::Type::Texture3D) ? 2 : 1;
+ srcTextureInfo->mipLevelCount = 1;
+ srcTextureInfo->arrayLayerCount =
+ (textureType == ITextureResource::Type::Texture3D) ? 1 : 2;
+
+ generateTextureData(srcTextureInfo, validationFormat);
+ dstTextureInfo = srcTextureInfo;
+
+ SubresourceRange srcSubresource = {};
+ srcSubresource.aspectMask = getTextureAspect(format);
+ srcSubresource.mipLevel = 0;
+ srcSubresource.mipLevelCount = 1;
+ srcSubresource.baseArrayLayer = 0;
+ srcSubresource.layerCount = 1;
+
+ SubresourceRange dstSubresource = {};
+ dstSubresource.aspectMask = getTextureAspect(format);
+ dstSubresource.mipLevel = 0;
+ dstSubresource.mipLevelCount = 1;
+ dstSubresource.baseArrayLayer = (textureType == ITextureResource::Type::Texture3D) ? 0 : 1;
+ dstSubresource.layerCount = 1;
+
+ texCopyInfo.srcSubresource = srcSubresource;
+ texCopyInfo.dstSubresource = dstSubresource;
+ texCopyInfo.extent = srcTextureInfo->extents;
+ texCopyInfo.srcOffset = {0, 0, 0};
+ texCopyInfo.dstOffset = {0, 0, 0};
+
+ bufferCopyInfo.srcSubresource = dstSubresource;
+ bufferCopyInfo.extent = dstTextureInfo->extents;
+ bufferCopyInfo.textureOffset = {0, 0, 0};
+ bufferCopyInfo.bufferOffset = 0;
+
+ createRequiredResources();
+ submitGPUWork();
+
+ auto copiedSubresourceIndex = getSubresourceIndex(
+ srcSubresource.mipLevel,
+ srcTextureInfo->mipLevelCount,
+ srcSubresource.baseArrayLayer);
+ ITextureResource::SubresourceData expectedCopiedData =
+ srcTextureInfo->subresourceDatas[copiedSubresourceIndex];
+ auto originalSubresourceIndex = getSubresourceIndex(
+ dstSubresource.mipLevel,
+ dstTextureInfo->mipLevelCount,
+ dstSubresource.baseArrayLayer);
+ ITextureResource::SubresourceData expectedOriginalData =
+ dstTextureInfo->subresourceDatas[originalSubresourceIndex];
+ checkTestResults(
+ srcTextureInfo->extents,
+ expectedCopiedData.data,
+ expectedOriginalData.data);
+ }
+};
- struct CopyWithOffsets : BaseCopyTextureTest
+struct CopyWithOffsets : BaseCopyTextureTest
+{
+ void run()
{
- void run()
+ auto textureType = srcTextureInfo->textureType;
+ auto format = srcTextureInfo->format;
+
+ srcTextureInfo->extents.width = 8;
+ srcTextureInfo->extents.height = (textureType == ITextureResource::Type::Texture1D) ? 1 : 8;
+ srcTextureInfo->extents.depth = (textureType == ITextureResource::Type::Texture3D) ? 2 : 1;
+ srcTextureInfo->mipLevelCount = 1;
+ srcTextureInfo->arrayLayerCount = 1;
+
+ generateTextureData(srcTextureInfo, validationFormat);
+
+ dstTextureInfo->extents.width = 16;
+ dstTextureInfo->extents.height =
+ (textureType == ITextureResource::Type::Texture1D) ? 1 : 16;
+ dstTextureInfo->extents.depth = (textureType == ITextureResource::Type::Texture3D) ? 4 : 1;
+ dstTextureInfo->mipLevelCount = 1;
+ dstTextureInfo->arrayLayerCount = 1;
+
+ generateTextureData(dstTextureInfo, validationFormat);
+
+ SubresourceRange srcSubresource = {};
+ srcSubresource.aspectMask = getTextureAspect(format);
+ srcSubresource.mipLevel = 0;
+ srcSubresource.mipLevelCount = 1;
+ srcSubresource.baseArrayLayer = 0;
+ srcSubresource.layerCount = 1;
+
+ SubresourceRange dstSubresource = {};
+ dstSubresource.aspectMask = getTextureAspect(format);
+ dstSubresource.mipLevel = 0;
+ dstSubresource.mipLevelCount = 1;
+ dstSubresource.baseArrayLayer = 0;
+ dstSubresource.layerCount = 1;
+
+ texCopyInfo.srcSubresource = srcSubresource;
+ texCopyInfo.dstSubresource = dstSubresource;
+ texCopyInfo.extent.width = 4;
+ texCopyInfo.extent.height = 4;
+ texCopyInfo.extent.depth = 1;
+ texCopyInfo.srcOffset = {2, 2, 0};
+ texCopyInfo.dstOffset = {4, 4, 0};
+
+ if (textureType == ITextureResource::Type::Texture1D)
{
- auto textureType = srcTextureInfo->textureType;
- auto format = srcTextureInfo->format;
-
- srcTextureInfo->extents.width = 8;
- srcTextureInfo->extents.height = (textureType == ITextureResource::Type::Texture1D) ? 1 : 8;
- srcTextureInfo->extents.depth = (textureType == ITextureResource::Type::Texture3D) ? 2 : 1;
- srcTextureInfo->mipLevelCount = 1;
- srcTextureInfo->arrayLayerCount = 1;
-
- generateTextureData(srcTextureInfo, validationFormat);
-
- dstTextureInfo->extents.width = 16;
- dstTextureInfo->extents.height = (textureType == ITextureResource::Type::Texture1D) ? 1 : 16;
- dstTextureInfo->extents.depth = (textureType == ITextureResource::Type::Texture3D) ? 4 : 1;
- dstTextureInfo->mipLevelCount = 1;
- dstTextureInfo->arrayLayerCount = 1;
-
- generateTextureData(dstTextureInfo, validationFormat);
-
- SubresourceRange srcSubresource = {};
- srcSubresource.aspectMask = getTextureAspect(format);
- srcSubresource.mipLevel = 0;
- srcSubresource.mipLevelCount = 1;
- srcSubresource.baseArrayLayer = 0;
- srcSubresource.layerCount = 1;
-
- SubresourceRange dstSubresource = {};
- dstSubresource.aspectMask = getTextureAspect(format);
- dstSubresource.mipLevel = 0;
- dstSubresource.mipLevelCount = 1;
- dstSubresource.baseArrayLayer = 0;
- dstSubresource.layerCount = 1;
-
- texCopyInfo.srcSubresource = srcSubresource;
- texCopyInfo.dstSubresource = dstSubresource;
- texCopyInfo.extent.width = 4;
- texCopyInfo.extent.height = 4;
- texCopyInfo.extent.depth = 1;
- texCopyInfo.srcOffset = { 2, 2, 0 };
- texCopyInfo.dstOffset = { 4, 4, 0 };
-
- if (textureType == ITextureResource::Type::Texture1D)
- {
- texCopyInfo.extent.height = 1;
- texCopyInfo.srcOffset.y = 0;
- texCopyInfo.dstOffset.y = 0;
- }
- else if (textureType == ITextureResource::Type::Texture3D)
- {
- texCopyInfo.extent.depth = srcTextureInfo->extents.depth;
- texCopyInfo.dstOffset.z = 1;
- }
-
- bufferCopyInfo.srcSubresource = dstSubresource;
- bufferCopyInfo.extent = dstTextureInfo->extents;
- bufferCopyInfo.textureOffset = { 0, 0, 0 };
- bufferCopyInfo.bufferOffset = 0;
-
- createRequiredResources();
- submitGPUWork();
-
- auto copiedSubresourceIndex = getSubresourceIndex(srcSubresource.mipLevel, srcTextureInfo->mipLevelCount, srcSubresource.baseArrayLayer);
- ITextureResource::SubresourceData expectedCopiedData = srcTextureInfo->subresourceDatas[copiedSubresourceIndex];
- auto originalSubresourceIndex = getSubresourceIndex(dstSubresource.mipLevel, dstTextureInfo->mipLevelCount, dstSubresource.baseArrayLayer);
- ITextureResource::SubresourceData expectedOriginalData = dstTextureInfo->subresourceDatas[originalSubresourceIndex];
- checkTestResults(srcTextureInfo->extents, expectedCopiedData.data, expectedOriginalData.data);
+ texCopyInfo.extent.height = 1;
+ texCopyInfo.srcOffset.y = 0;
+ texCopyInfo.dstOffset.y = 0;
}
- };
-
- struct CopySectionWithSetExtent : BaseCopyTextureTest
- {
- void run()
+ else if (textureType == ITextureResource::Type::Texture3D)
{
- auto textureType = srcTextureInfo->textureType;
- auto format = srcTextureInfo->format;
-
- srcTextureInfo->extents.width = 8;
- srcTextureInfo->extents.height = (textureType == ITextureResource::Type::Texture1D) ? 1 : 8;
- srcTextureInfo->extents.depth = (textureType == ITextureResource::Type::Texture3D) ? 2 : 1;
- srcTextureInfo->mipLevelCount = 1;
- srcTextureInfo->arrayLayerCount = 1;
-
- generateTextureData(srcTextureInfo, validationFormat);
- dstTextureInfo = srcTextureInfo;
-
- SubresourceRange srcSubresource = {};
- srcSubresource.aspectMask = getTextureAspect(format);
- srcSubresource.mipLevel = 0;
- srcSubresource.mipLevelCount = 1;
- srcSubresource.baseArrayLayer = 0;
- srcSubresource.layerCount = 1;
-
- SubresourceRange dstSubresource = {};
- dstSubresource.aspectMask = getTextureAspect(format);
- dstSubresource.mipLevel = 0;
- dstSubresource.mipLevelCount = 1;
- dstSubresource.baseArrayLayer = 0;
- dstSubresource.layerCount = 1;
-
- texCopyInfo.srcSubresource = srcSubresource;
- texCopyInfo.dstSubresource = dstSubresource;
- texCopyInfo.extent.width = 4;
- texCopyInfo.extent.height = 4;
- texCopyInfo.extent.depth = 1;
- texCopyInfo.srcOffset = { 0, 0, 0 };
- texCopyInfo.dstOffset = { 4, 4, 0 };
-
- if (textureType == ITextureResource::Type::Texture1D)
- {
- texCopyInfo.extent.height = 1;
- texCopyInfo.dstOffset.y = 0;
- }
- else if (textureType == ITextureResource::Type::Texture3D)
- {
- texCopyInfo.extent.depth = srcTextureInfo->extents.depth;
- }
-
- bufferCopyInfo.srcSubresource = dstSubresource;
- bufferCopyInfo.extent = dstTextureInfo->extents;
- bufferCopyInfo.textureOffset = { 0, 0, 0 };
- bufferCopyInfo.bufferOffset = 0;
+ texCopyInfo.extent.depth = srcTextureInfo->extents.depth;
+ texCopyInfo.dstOffset.z = 1;
+ }
- createRequiredResources();
- submitGPUWork();
+ bufferCopyInfo.srcSubresource = dstSubresource;
+ bufferCopyInfo.extent = dstTextureInfo->extents;
+ bufferCopyInfo.textureOffset = {0, 0, 0};
+ bufferCopyInfo.bufferOffset = 0;
+
+ createRequiredResources();
+ submitGPUWork();
+
+ auto copiedSubresourceIndex = getSubresourceIndex(
+ srcSubresource.mipLevel,
+ srcTextureInfo->mipLevelCount,
+ srcSubresource.baseArrayLayer);
+ ITextureResource::SubresourceData expectedCopiedData =
+ srcTextureInfo->subresourceDatas[copiedSubresourceIndex];
+ auto originalSubresourceIndex = getSubresourceIndex(
+ dstSubresource.mipLevel,
+ dstTextureInfo->mipLevelCount,
+ dstSubresource.baseArrayLayer);
+ ITextureResource::SubresourceData expectedOriginalData =
+ dstTextureInfo->subresourceDatas[originalSubresourceIndex];
+ checkTestResults(
+ srcTextureInfo->extents,
+ expectedCopiedData.data,
+ expectedOriginalData.data);
+ }
+};
- auto copiedSubresourceIndex = getSubresourceIndex(srcSubresource.mipLevel, srcTextureInfo->mipLevelCount, srcSubresource.baseArrayLayer);
- ITextureResource::SubresourceData expectedCopiedData = srcTextureInfo->subresourceDatas[copiedSubresourceIndex];
- auto originalSubresourceIndex = getSubresourceIndex(dstSubresource.mipLevel, dstTextureInfo->mipLevelCount, dstSubresource.baseArrayLayer);
- ITextureResource::SubresourceData expectedOriginalData = dstTextureInfo->subresourceDatas[originalSubresourceIndex];
- checkTestResults(srcTextureInfo->extents, expectedCopiedData.data, expectedOriginalData.data);
+struct CopySectionWithSetExtent : BaseCopyTextureTest
+{
+ void run()
+ {
+ auto textureType = srcTextureInfo->textureType;
+ auto format = srcTextureInfo->format;
+
+ srcTextureInfo->extents.width = 8;
+ srcTextureInfo->extents.height = (textureType == ITextureResource::Type::Texture1D) ? 1 : 8;
+ srcTextureInfo->extents.depth = (textureType == ITextureResource::Type::Texture3D) ? 2 : 1;
+ srcTextureInfo->mipLevelCount = 1;
+ srcTextureInfo->arrayLayerCount = 1;
+
+ generateTextureData(srcTextureInfo, validationFormat);
+ dstTextureInfo = srcTextureInfo;
+
+ SubresourceRange srcSubresource = {};
+ srcSubresource.aspectMask = getTextureAspect(format);
+ srcSubresource.mipLevel = 0;
+ srcSubresource.mipLevelCount = 1;
+ srcSubresource.baseArrayLayer = 0;
+ srcSubresource.layerCount = 1;
+
+ SubresourceRange dstSubresource = {};
+ dstSubresource.aspectMask = getTextureAspect(format);
+ dstSubresource.mipLevel = 0;
+ dstSubresource.mipLevelCount = 1;
+ dstSubresource.baseArrayLayer = 0;
+ dstSubresource.layerCount = 1;
+
+ texCopyInfo.srcSubresource = srcSubresource;
+ texCopyInfo.dstSubresource = dstSubresource;
+ texCopyInfo.extent.width = 4;
+ texCopyInfo.extent.height = 4;
+ texCopyInfo.extent.depth = 1;
+ texCopyInfo.srcOffset = {0, 0, 0};
+ texCopyInfo.dstOffset = {4, 4, 0};
+
+ if (textureType == ITextureResource::Type::Texture1D)
+ {
+ texCopyInfo.extent.height = 1;
+ texCopyInfo.dstOffset.y = 0;
+ }
+ else if (textureType == ITextureResource::Type::Texture3D)
+ {
+ texCopyInfo.extent.depth = srcTextureInfo->extents.depth;
}
- };
- template<typename T>
- void copyTextureTestImpl(IDevice* device, UnitTestContext* context)
- {
- const bool isVkd3d = SLANG_ENABLE_VKD3D &&
- strcmp(device->getDeviceInfo().apiName, "Direct3D 12") == 0;
+ bufferCopyInfo.srcSubresource = dstSubresource;
+ bufferCopyInfo.extent = dstTextureInfo->extents;
+ bufferCopyInfo.textureOffset = {0, 0, 0};
+ bufferCopyInfo.bufferOffset = 0;
+
+ createRequiredResources();
+ submitGPUWork();
+
+ auto copiedSubresourceIndex = getSubresourceIndex(
+ srcSubresource.mipLevel,
+ srcTextureInfo->mipLevelCount,
+ srcSubresource.baseArrayLayer);
+ ITextureResource::SubresourceData expectedCopiedData =
+ srcTextureInfo->subresourceDatas[copiedSubresourceIndex];
+ auto originalSubresourceIndex = getSubresourceIndex(
+ dstSubresource.mipLevel,
+ dstTextureInfo->mipLevelCount,
+ dstSubresource.baseArrayLayer);
+ ITextureResource::SubresourceData expectedOriginalData =
+ dstTextureInfo->subresourceDatas[originalSubresourceIndex];
+ checkTestResults(
+ srcTextureInfo->extents,
+ expectedCopiedData.data,
+ expectedOriginalData.data);
+ }
+};
- // Skip Type::Unknown and Type::Buffer as well as Format::Unknown
- // TODO: Add support for TextureCube
- Format formats[] = { Format::R8G8B8A8_UNORM, Format::R16_FLOAT, Format::R16G16_FLOAT, Format::R10G10B10A2_UNORM, Format::B5G5R5A1_UNORM };
- for (uint32_t i = 2; i < (uint32_t)ITextureResource::Type::_Count - 1; ++i)
+template<typename T>
+void copyTextureTestImpl(IDevice* device, UnitTestContext* context)
+{
+ const bool isVkd3d =
+ SLANG_ENABLE_VKD3D && strcmp(device->getDeviceInfo().apiName, "Direct3D 12") == 0;
+
+ // Skip Type::Unknown and Type::Buffer as well as Format::Unknown
+ // TODO: Add support for TextureCube
+ Format formats[] = {
+ Format::R8G8B8A8_UNORM,
+ Format::R16_FLOAT,
+ Format::R16G16_FLOAT,
+ Format::R10G10B10A2_UNORM,
+ Format::B5G5R5A1_UNORM};
+ for (uint32_t i = 2; i < (uint32_t)ITextureResource::Type::_Count - 1; ++i)
+ {
+ for (auto format : formats)
{
- for (auto format : formats)
+ // Fails validation VUID-VkImageCreateInfo-imageCreateMaxMipLevels-02251
+ if (isVkd3d &&
+ (format == Format::R32G32B32_TYPELESS || format == Format::R32G32B32_FLOAT ||
+ format == Format::R32G32B32_UINT || format == Format::R32G32B32_SINT))
{
- // Fails validation VUID-VkImageCreateInfo-imageCreateMaxMipLevels-02251
- if(isVkd3d && (format == Format::R32G32B32_TYPELESS ||
- format == Format::R32G32B32_FLOAT ||
- format == Format::R32G32B32_UINT ||
- format == Format::R32G32B32_SINT))
- {
- continue;
- }
- auto type = (ITextureResource::Type)i;
- auto validationFormat = getValidationTextureFormat(format);
- if (!validationFormat)
- continue;
-
- T test;
- test.init(device, context, format, validationFormat, type);
- test.run();
+ continue;
}
+ auto type = (ITextureResource::Type)i;
+ auto validationFormat = getValidationTextureFormat(format);
+ if (!validationFormat)
+ continue;
+
+ T test;
+ test.init(device, context, format, validationFormat, type);
+ test.run();
}
}
+}
- SLANG_UNIT_TEST(copyTextureSimple)
- {
- runTestImpl(copyTextureTestImpl<SimpleCopyTexture>, unitTestContext, Slang::RenderApiFlag::D3D12);
- runTestImpl(copyTextureTestImpl<SimpleCopyTexture>, unitTestContext, Slang::RenderApiFlag::Vulkan);
- }
+SLANG_UNIT_TEST(copyTextureSimple)
+{
+ runTestImpl(
+ copyTextureTestImpl<SimpleCopyTexture>,
+ unitTestContext,
+ Slang::RenderApiFlag::D3D12);
+ runTestImpl(
+ copyTextureTestImpl<SimpleCopyTexture>,
+ unitTestContext,
+ Slang::RenderApiFlag::Vulkan);
+}
- SLANG_UNIT_TEST(copyTextureSection)
- {
- runTestImpl(copyTextureTestImpl<CopyTextureSection>, unitTestContext, Slang::RenderApiFlag::D3D12);
- runTestImpl(copyTextureTestImpl<CopyTextureSection>, unitTestContext, Slang::RenderApiFlag::Vulkan);
- }
+SLANG_UNIT_TEST(copyTextureSection)
+{
+ runTestImpl(
+ copyTextureTestImpl<CopyTextureSection>,
+ unitTestContext,
+ Slang::RenderApiFlag::D3D12);
+ runTestImpl(
+ copyTextureTestImpl<CopyTextureSection>,
+ unitTestContext,
+ Slang::RenderApiFlag::Vulkan);
+}
- SLANG_UNIT_TEST(copyLargeToSmallTexture)
- {
- runTestImpl(copyTextureTestImpl<LargeSrcToSmallDst>, unitTestContext, Slang::RenderApiFlag::D3D12);
- runTestImpl(copyTextureTestImpl<LargeSrcToSmallDst>, unitTestContext, Slang::RenderApiFlag::Vulkan);
- }
+SLANG_UNIT_TEST(copyLargeToSmallTexture)
+{
+ runTestImpl(
+ copyTextureTestImpl<LargeSrcToSmallDst>,
+ unitTestContext,
+ Slang::RenderApiFlag::D3D12);
+ runTestImpl(
+ copyTextureTestImpl<LargeSrcToSmallDst>,
+ unitTestContext,
+ Slang::RenderApiFlag::Vulkan);
+}
- SLANG_UNIT_TEST(copySmallToLargeTexture)
- {
- runTestImpl(copyTextureTestImpl<SmallSrcToLargeDst>, unitTestContext, Slang::RenderApiFlag::D3D12);
- runTestImpl(copyTextureTestImpl<SmallSrcToLargeDst>, unitTestContext, Slang::RenderApiFlag::Vulkan);
- }
+SLANG_UNIT_TEST(copySmallToLargeTexture)
+{
+ runTestImpl(
+ copyTextureTestImpl<SmallSrcToLargeDst>,
+ unitTestContext,
+ Slang::RenderApiFlag::D3D12);
+ runTestImpl(
+ copyTextureTestImpl<SmallSrcToLargeDst>,
+ unitTestContext,
+ Slang::RenderApiFlag::Vulkan);
+}
- SLANG_UNIT_TEST(copyBetweenMips)
- {
- runTestImpl(copyTextureTestImpl<CopyBetweenMips>, unitTestContext, Slang::RenderApiFlag::D3D12);
- runTestImpl(copyTextureTestImpl<CopyBetweenMips>, unitTestContext, Slang::RenderApiFlag::Vulkan);
- }
+SLANG_UNIT_TEST(copyBetweenMips)
+{
+ runTestImpl(copyTextureTestImpl<CopyBetweenMips>, unitTestContext, Slang::RenderApiFlag::D3D12);
+ runTestImpl(
+ copyTextureTestImpl<CopyBetweenMips>,
+ unitTestContext,
+ Slang::RenderApiFlag::Vulkan);
+}
- SLANG_UNIT_TEST(copyBetweenLayers)
- {
- runTestImpl(copyTextureTestImpl<CopyBetweenLayers>, unitTestContext, Slang::RenderApiFlag::D3D12);
- runTestImpl(copyTextureTestImpl<CopyBetweenLayers>, unitTestContext, Slang::RenderApiFlag::Vulkan);
- }
+SLANG_UNIT_TEST(copyBetweenLayers)
+{
+ runTestImpl(
+ copyTextureTestImpl<CopyBetweenLayers>,
+ unitTestContext,
+ Slang::RenderApiFlag::D3D12);
+ runTestImpl(
+ copyTextureTestImpl<CopyBetweenLayers>,
+ unitTestContext,
+ Slang::RenderApiFlag::Vulkan);
+}
- SLANG_UNIT_TEST(copyWithOffsets)
- {
- runTestImpl(copyTextureTestImpl<CopyWithOffsets>, unitTestContext, Slang::RenderApiFlag::D3D12);
- runTestImpl(copyTextureTestImpl<CopyWithOffsets>, unitTestContext, Slang::RenderApiFlag::Vulkan);
- }
+SLANG_UNIT_TEST(copyWithOffsets)
+{
+ runTestImpl(copyTextureTestImpl<CopyWithOffsets>, unitTestContext, Slang::RenderApiFlag::D3D12);
+ runTestImpl(
+ copyTextureTestImpl<CopyWithOffsets>,
+ unitTestContext,
+ Slang::RenderApiFlag::Vulkan);
+}
- SLANG_UNIT_TEST(copySectionWithSetExtent)
- {
- runTestImpl(copyTextureTestImpl<CopySectionWithSetExtent>, unitTestContext, Slang::RenderApiFlag::D3D12);
- runTestImpl(copyTextureTestImpl<CopySectionWithSetExtent>, unitTestContext, Slang::RenderApiFlag::Vulkan);
- }
+SLANG_UNIT_TEST(copySectionWithSetExtent)
+{
+ runTestImpl(
+ copyTextureTestImpl<CopySectionWithSetExtent>,
+ unitTestContext,
+ Slang::RenderApiFlag::D3D12);
+ runTestImpl(
+ copyTextureTestImpl<CopySectionWithSetExtent>,
+ unitTestContext,
+ Slang::RenderApiFlag::Vulkan);
}
+} // namespace gfx_test
diff --git a/tools/gfx-unit-test/create-buffer-from-handle.cpp b/tools/gfx-unit-test/create-buffer-from-handle.cpp
index 4e2261465..a4e743196 100644
--- a/tools/gfx-unit-test/create-buffer-from-handle.cpp
+++ b/tools/gfx-unit-test/create-buffer-from-handle.cpp
@@ -1,101 +1,103 @@
-#include "tools/unit-test/slang-unit-test.h"
-
-#include "slang-gfx.h"
#include "gfx-test-util.h"
-#include "tools/gfx-util/shader-cursor.h"
+#include "slang-gfx.h"
#include "source/core/slang-basic.h"
+#include "tools/gfx-util/shader-cursor.h"
+#include "tools/unit-test/slang-unit-test.h"
using namespace gfx;
namespace gfx_test
{
- void createBufferFromHandleTestImpl(IDevice* device, UnitTestContext* context)
+void createBufferFromHandleTestImpl(IDevice* device, UnitTestContext* context)
+{
+ Slang::ComPtr<ITransientResourceHeap> transientHeap;
+ ITransientResourceHeap::Desc transientHeapDesc = {};
+ transientHeapDesc.constantBufferSize = 4096;
+ GFX_CHECK_CALL_ABORT(
+ device->createTransientResourceHeap(transientHeapDesc, transientHeap.writeRef()));
+
+ ComPtr<IShaderProgram> shaderProgram;
+ slang::ProgramLayout* slangReflection;
+ GFX_CHECK_CALL_ABORT(loadComputeProgram(
+ device,
+ shaderProgram,
+ "compute-trivial",
+ "computeMain",
+ slangReflection));
+
+ ComputePipelineStateDesc pipelineDesc = {};
+ pipelineDesc.program = shaderProgram.get();
+ ComPtr<gfx::IPipelineState> pipelineState;
+ GFX_CHECK_CALL_ABORT(
+ device->createComputePipelineState(pipelineDesc, pipelineState.writeRef()));
+
+ const int numberCount = 4;
+ float initialData[] = {0.0f, 1.0f, 2.0f, 3.0f};
+ IBufferResource::Desc bufferDesc = {};
+ bufferDesc.sizeInBytes = numberCount * sizeof(float);
+ bufferDesc.format = gfx::Format::Unknown;
+ bufferDesc.elementSize = sizeof(float);
+ bufferDesc.allowedStates = ResourceStateSet(
+ ResourceState::ShaderResource,
+ ResourceState::UnorderedAccess,
+ ResourceState::CopyDestination,
+ ResourceState::CopySource);
+ bufferDesc.defaultState = ResourceState::UnorderedAccess;
+ bufferDesc.memoryType = MemoryType::DeviceLocal;
+
+ ComPtr<IBufferResource> originalNumbersBuffer;
+ GFX_CHECK_CALL_ABORT(device->createBufferResource(
+ bufferDesc,
+ (void*)initialData,
+ originalNumbersBuffer.writeRef()));
+
+ InteropHandle handle;
+ originalNumbersBuffer->getNativeResourceHandle(&handle);
+ ComPtr<IBufferResource> numbersBuffer;
+ GFX_CHECK_CALL_ABORT(
+ device->createBufferFromNativeHandle(handle, bufferDesc, numbersBuffer.writeRef()));
+ compareComputeResult(device, numbersBuffer, Slang::makeArray<float>(0.0f, 1.0f, 2.0f, 3.0f));
+
+ ComPtr<IResourceView> bufferView;
+ IResourceView::Desc viewDesc = {};
+ viewDesc.type = IResourceView::Type::UnorderedAccess;
+ viewDesc.format = Format::Unknown;
+ GFX_CHECK_CALL_ABORT(
+ device->createBufferView(numbersBuffer, nullptr, viewDesc, bufferView.writeRef()));
+
+ // We have done all the set up work, now it is time to start recording a command buffer for
+ // GPU execution.
{
- Slang::ComPtr<ITransientResourceHeap> transientHeap;
- ITransientResourceHeap::Desc transientHeapDesc = {};
- transientHeapDesc.constantBufferSize = 4096;
- GFX_CHECK_CALL_ABORT(
- device->createTransientResourceHeap(transientHeapDesc, transientHeap.writeRef()));
-
- ComPtr<IShaderProgram> shaderProgram;
- slang::ProgramLayout* slangReflection;
- GFX_CHECK_CALL_ABORT(loadComputeProgram(device, shaderProgram, "compute-trivial", "computeMain", slangReflection));
-
- ComputePipelineStateDesc pipelineDesc = {};
- pipelineDesc.program = shaderProgram.get();
- ComPtr<gfx::IPipelineState> pipelineState;
- GFX_CHECK_CALL_ABORT(
- device->createComputePipelineState(pipelineDesc, pipelineState.writeRef()));
-
- const int numberCount = 4;
- float initialData[] = { 0.0f, 1.0f, 2.0f, 3.0f };
- IBufferResource::Desc bufferDesc = {};
- bufferDesc.sizeInBytes = numberCount * sizeof(float);
- bufferDesc.format = gfx::Format::Unknown;
- bufferDesc.elementSize = sizeof(float);
- bufferDesc.allowedStates = ResourceStateSet(
- ResourceState::ShaderResource,
- ResourceState::UnorderedAccess,
- ResourceState::CopyDestination,
- ResourceState::CopySource);
- bufferDesc.defaultState = ResourceState::UnorderedAccess;
- bufferDesc.memoryType = MemoryType::DeviceLocal;
-
- ComPtr<IBufferResource> originalNumbersBuffer;
- GFX_CHECK_CALL_ABORT(device->createBufferResource(
- bufferDesc,
- (void*)initialData,
- originalNumbersBuffer.writeRef()));
-
- InteropHandle handle;
- originalNumbersBuffer->getNativeResourceHandle(&handle);
- ComPtr<IBufferResource> numbersBuffer;
- GFX_CHECK_CALL_ABORT(device->createBufferFromNativeHandle(handle, bufferDesc, numbersBuffer.writeRef()));
- compareComputeResult(device, numbersBuffer, Slang::makeArray<float>(0.0f, 1.0f, 2.0f, 3.0f));
-
- ComPtr<IResourceView> bufferView;
- IResourceView::Desc viewDesc = {};
- viewDesc.type = IResourceView::Type::UnorderedAccess;
- viewDesc.format = Format::Unknown;
- GFX_CHECK_CALL_ABORT(
- device->createBufferView(numbersBuffer, nullptr, viewDesc, bufferView.writeRef()));
-
- // We have done all the set up work, now it is time to start recording a command buffer for
- // GPU execution.
- {
- ICommandQueue::Desc queueDesc = { ICommandQueue::QueueType::Graphics };
- auto queue = device->createCommandQueue(queueDesc);
-
- auto commandBuffer = transientHeap->createCommandBuffer();
- auto encoder = commandBuffer->encodeComputeCommands();
-
- auto rootObject = encoder->bindPipeline(pipelineState);
-
- ShaderCursor rootCursor(rootObject);
- // Bind buffer view to the entry point.
- rootCursor.getPath("buffer").setResource(bufferView);
-
- encoder->dispatchCompute(1, 1, 1);
- encoder->endEncoding();
- commandBuffer->close();
- queue->executeCommandBuffer(commandBuffer);
- queue->waitOnHost();
- }
-
- compareComputeResult(
- device,
- numbersBuffer,
- Slang::makeArray<float>(1.0f, 2.0f, 3.0f, 4.0f));
- }
+ ICommandQueue::Desc queueDesc = {ICommandQueue::QueueType::Graphics};
+ auto queue = device->createCommandQueue(queueDesc);
- SLANG_UNIT_TEST(createBufferFromHandleD3D12)
- {
- runTestImpl(createBufferFromHandleTestImpl, unitTestContext, Slang::RenderApiFlag::D3D12);
- }
+ auto commandBuffer = transientHeap->createCommandBuffer();
+ auto encoder = commandBuffer->encodeComputeCommands();
- SLANG_UNIT_TEST(createBufferFromHandleVulkan)
- {
- runTestImpl(createBufferFromHandleTestImpl, unitTestContext, Slang::RenderApiFlag::Vulkan);
+ auto rootObject = encoder->bindPipeline(pipelineState);
+
+ ShaderCursor rootCursor(rootObject);
+ // Bind buffer view to the entry point.
+ rootCursor.getPath("buffer").setResource(bufferView);
+
+ encoder->dispatchCompute(1, 1, 1);
+ encoder->endEncoding();
+ commandBuffer->close();
+ queue->executeCommandBuffer(commandBuffer);
+ queue->waitOnHost();
}
+ compareComputeResult(device, numbersBuffer, Slang::makeArray<float>(1.0f, 2.0f, 3.0f, 4.0f));
+}
+
+SLANG_UNIT_TEST(createBufferFromHandleD3D12)
+{
+ runTestImpl(createBufferFromHandleTestImpl, unitTestContext, Slang::RenderApiFlag::D3D12);
}
+
+SLANG_UNIT_TEST(createBufferFromHandleVulkan)
+{
+ runTestImpl(createBufferFromHandleTestImpl, unitTestContext, Slang::RenderApiFlag::Vulkan);
+}
+
+} // namespace gfx_test
diff --git a/tools/gfx-unit-test/existing-device-handle-test.cpp b/tools/gfx-unit-test/existing-device-handle-test.cpp
index d6f66af84..03f924b5c 100644
--- a/tools/gfx-unit-test/existing-device-handle-test.cpp
+++ b/tools/gfx-unit-test/existing-device-handle-test.cpp
@@ -1,151 +1,143 @@
-#include "tools/unit-test/slang-unit-test.h"
-
-#include "slang-gfx.h"
#include "gfx-test-util.h"
-#include "tools/gfx-util/shader-cursor.h"
+#include "slang-gfx.h"
#include "source/core/slang-basic.h"
+#include "tools/gfx-util/shader-cursor.h"
+#include "tools/unit-test/slang-unit-test.h"
using namespace gfx;
namespace gfx_test
{
- void existingDeviceHandleTestImpl(IDevice* device, UnitTestContext* context)
+void existingDeviceHandleTestImpl(IDevice* device, UnitTestContext* context)
+{
+ Slang::ComPtr<ITransientResourceHeap> transientHeap;
+ ITransientResourceHeap::Desc transientHeapDesc = {};
+ transientHeapDesc.constantBufferSize = 4096;
+ GFX_CHECK_CALL_ABORT(
+ device->createTransientResourceHeap(transientHeapDesc, transientHeap.writeRef()));
+
+ ComPtr<IShaderProgram> shaderProgram;
+ slang::ProgramLayout* slangReflection;
+ GFX_CHECK_CALL_ABORT(loadComputeProgram(
+ device,
+ shaderProgram,
+ "compute-trivial",
+ "computeMain",
+ slangReflection));
+
+ ComputePipelineStateDesc pipelineDesc = {};
+ pipelineDesc.program = shaderProgram.get();
+ ComPtr<gfx::IPipelineState> pipelineState;
+ GFX_CHECK_CALL_ABORT(
+ device->createComputePipelineState(pipelineDesc, pipelineState.writeRef()));
+
+ const int numberCount = 4;
+ float initialData[] = {0.0f, 1.0f, 2.0f, 3.0f};
+ IBufferResource::Desc bufferDesc = {};
+ bufferDesc.sizeInBytes = numberCount * sizeof(float);
+ bufferDesc.format = gfx::Format::Unknown;
+ bufferDesc.elementSize = sizeof(float);
+ bufferDesc.allowedStates = ResourceStateSet(
+ ResourceState::ShaderResource,
+ ResourceState::UnorderedAccess,
+ ResourceState::CopyDestination,
+ ResourceState::CopySource);
+ bufferDesc.defaultState = ResourceState::UnorderedAccess;
+ bufferDesc.memoryType = MemoryType::DeviceLocal;
+
+ ComPtr<IBufferResource> numbersBuffer;
+ GFX_CHECK_CALL_ABORT(
+ device->createBufferResource(bufferDesc, (void*)initialData, numbersBuffer.writeRef()));
+
+ ComPtr<IResourceView> bufferView;
+ IResourceView::Desc viewDesc = {};
+ viewDesc.type = IResourceView::Type::UnorderedAccess;
+ viewDesc.format = Format::Unknown;
+ GFX_CHECK_CALL_ABORT(
+ device->createBufferView(numbersBuffer, nullptr, viewDesc, bufferView.writeRef()));
+
+ // We have done all the set up work, now it is time to start recording a command buffer for
+ // GPU execution.
{
- Slang::ComPtr<ITransientResourceHeap> transientHeap;
- ITransientResourceHeap::Desc transientHeapDesc = {};
- transientHeapDesc.constantBufferSize = 4096;
- GFX_CHECK_CALL_ABORT(
- device->createTransientResourceHeap(transientHeapDesc, transientHeap.writeRef()));
-
- ComPtr<IShaderProgram> shaderProgram;
- slang::ProgramLayout* slangReflection;
- GFX_CHECK_CALL_ABORT(loadComputeProgram(device, shaderProgram, "compute-trivial", "computeMain", slangReflection));
-
- ComputePipelineStateDesc pipelineDesc = {};
- pipelineDesc.program = shaderProgram.get();
- ComPtr<gfx::IPipelineState> pipelineState;
- GFX_CHECK_CALL_ABORT(
- device->createComputePipelineState(pipelineDesc, pipelineState.writeRef()));
-
- const int numberCount = 4;
- float initialData[] = { 0.0f, 1.0f, 2.0f, 3.0f };
- IBufferResource::Desc bufferDesc = {};
- bufferDesc.sizeInBytes = numberCount * sizeof(float);
- bufferDesc.format = gfx::Format::Unknown;
- bufferDesc.elementSize = sizeof(float);
- bufferDesc.allowedStates = ResourceStateSet(
- ResourceState::ShaderResource,
- ResourceState::UnorderedAccess,
- ResourceState::CopyDestination,
- ResourceState::CopySource);
- bufferDesc.defaultState = ResourceState::UnorderedAccess;
- bufferDesc.memoryType = MemoryType::DeviceLocal;
-
- ComPtr<IBufferResource> numbersBuffer;
- GFX_CHECK_CALL_ABORT(device->createBufferResource(
- bufferDesc,
- (void*)initialData,
- numbersBuffer.writeRef()));
-
- ComPtr<IResourceView> bufferView;
- IResourceView::Desc viewDesc = {};
- viewDesc.type = IResourceView::Type::UnorderedAccess;
- viewDesc.format = Format::Unknown;
- GFX_CHECK_CALL_ABORT(
- device->createBufferView(numbersBuffer, nullptr, viewDesc, bufferView.writeRef()));
-
- // We have done all the set up work, now it is time to start recording a command buffer for
- // GPU execution.
- {
- ICommandQueue::Desc queueDesc = { ICommandQueue::QueueType::Graphics };
- auto queue = device->createCommandQueue(queueDesc);
-
- auto commandBuffer = transientHeap->createCommandBuffer();
- auto encoder = commandBuffer->encodeComputeCommands();
-
- auto rootObject = encoder->bindPipeline(pipelineState);
-
- ShaderCursor rootCursor(rootObject);
- // Bind buffer view to the root.
- rootCursor.getPath("buffer").setResource(bufferView);
-
- encoder->dispatchCompute(1, 1, 1);
- encoder->endEncoding();
- commandBuffer->close();
- queue->executeCommandBuffer(commandBuffer);
- queue->waitOnHost();
- }
-
- compareComputeResult(
- device,
- numbersBuffer,
- Slang::makeArray<float>(1.0f, 2.0f, 3.0f, 4.0f));
+ ICommandQueue::Desc queueDesc = {ICommandQueue::QueueType::Graphics};
+ auto queue = device->createCommandQueue(queueDesc);
+
+ auto commandBuffer = transientHeap->createCommandBuffer();
+ auto encoder = commandBuffer->encodeComputeCommands();
+
+ auto rootObject = encoder->bindPipeline(pipelineState);
+
+ ShaderCursor rootCursor(rootObject);
+ // Bind buffer view to the root.
+ rootCursor.getPath("buffer").setResource(bufferView);
+
+ encoder->dispatchCompute(1, 1, 1);
+ encoder->endEncoding();
+ commandBuffer->close();
+ queue->executeCommandBuffer(commandBuffer);
+ queue->waitOnHost();
}
- void existingDeviceHandleTestAPI(UnitTestContext* context, Slang::RenderApiFlag::Enum api)
+ compareComputeResult(device, numbersBuffer, Slang::makeArray<float>(1.0f, 2.0f, 3.0f, 4.0f));
+}
+
+void existingDeviceHandleTestAPI(UnitTestContext* context, Slang::RenderApiFlag::Enum api)
+{
+ if ((api & context->enabledApis) == 0)
{
- if ((api & context->enabledApis) == 0)
- {
- SLANG_IGNORE_TEST;
- }
- Slang::ComPtr<IDevice> device;
- IDevice::Desc deviceDesc = {};
- switch (api)
- {
- case Slang::RenderApiFlag::D3D12:
- deviceDesc.deviceType = gfx::DeviceType::DirectX12;
- break;
- case Slang::RenderApiFlag::Vulkan:
- deviceDesc.deviceType = gfx::DeviceType::Vulkan;
- break;
- case Slang::RenderApiFlag::CUDA:
- deviceDesc.deviceType = gfx::DeviceType::CUDA;
- break;
- default:
- SLANG_IGNORE_TEST;
- }
- deviceDesc.slang.slangGlobalSession = context->slangGlobalSession;
- const char* searchPaths[] = { "", "../../tools/gfx-unit-test", "tools/gfx-unit-test" };
- deviceDesc.slang.searchPathCount = (SlangInt)SLANG_COUNT_OF(searchPaths);
- deviceDesc.slang.searchPaths = searchPaths;
- auto createDeviceResult = gfxCreateDevice(&deviceDesc, device.writeRef());
- if (SLANG_FAILED(createDeviceResult) || !device)
- {
- SLANG_IGNORE_TEST;
- }
-
- IDevice::InteropHandles handles;
- GFX_CHECK_CALL_ABORT(device->getNativeDeviceHandles(&handles));
- Slang::ComPtr<IDevice> testDevice;
- IDevice::Desc testDeviceDesc = deviceDesc;
- testDeviceDesc.existingDeviceHandles.handles[0] = handles.handles[0];
- if (api == Slang::RenderApiFlag::Vulkan)
- {
- testDeviceDesc.existingDeviceHandles.handles[1] = handles.handles[1];
- testDeviceDesc.existingDeviceHandles.handles[2] = handles.handles[2];
- }
- auto createTestDeviceResult = gfxCreateDevice(&testDeviceDesc, testDevice.writeRef());
- if (SLANG_FAILED(createTestDeviceResult) || !device)
- {
- SLANG_IGNORE_TEST;
- }
-
- existingDeviceHandleTestImpl(device, context);
+ SLANG_IGNORE_TEST;
}
-
- SLANG_UNIT_TEST(existingDeviceHandleD3D12)
+ Slang::ComPtr<IDevice> device;
+ IDevice::Desc deviceDesc = {};
+ switch (api)
{
- return existingDeviceHandleTestAPI(unitTestContext, Slang::RenderApiFlag::D3D12);
+ case Slang::RenderApiFlag::D3D12: deviceDesc.deviceType = gfx::DeviceType::DirectX12; break;
+ case Slang::RenderApiFlag::Vulkan: deviceDesc.deviceType = gfx::DeviceType::Vulkan; break;
+ case Slang::RenderApiFlag::CUDA: deviceDesc.deviceType = gfx::DeviceType::CUDA; break;
+ default: SLANG_IGNORE_TEST;
+ }
+ deviceDesc.slang.slangGlobalSession = context->slangGlobalSession;
+ const char* searchPaths[] = {"", "../../tools/gfx-unit-test", "tools/gfx-unit-test"};
+ deviceDesc.slang.searchPathCount = (SlangInt)SLANG_COUNT_OF(searchPaths);
+ deviceDesc.slang.searchPaths = searchPaths;
+ auto createDeviceResult = gfxCreateDevice(&deviceDesc, device.writeRef());
+ if (SLANG_FAILED(createDeviceResult) || !device)
+ {
+ SLANG_IGNORE_TEST;
}
- SLANG_UNIT_TEST(existingDeviceHandleVulkan)
+ IDevice::InteropHandles handles;
+ GFX_CHECK_CALL_ABORT(device->getNativeDeviceHandles(&handles));
+ Slang::ComPtr<IDevice> testDevice;
+ IDevice::Desc testDeviceDesc = deviceDesc;
+ testDeviceDesc.existingDeviceHandles.handles[0] = handles.handles[0];
+ if (api == Slang::RenderApiFlag::Vulkan)
{
- return existingDeviceHandleTestAPI(unitTestContext, Slang::RenderApiFlag::Vulkan);
+ testDeviceDesc.existingDeviceHandles.handles[1] = handles.handles[1];
+ testDeviceDesc.existingDeviceHandles.handles[2] = handles.handles[2];
}
-#if SLANG_WIN64
- SLANG_UNIT_TEST(existingDeviceHandleCUDA)
+ auto createTestDeviceResult = gfxCreateDevice(&testDeviceDesc, testDevice.writeRef());
+ if (SLANG_FAILED(createTestDeviceResult) || !device)
{
- return existingDeviceHandleTestAPI(unitTestContext, Slang::RenderApiFlag::CUDA);
+ SLANG_IGNORE_TEST;
}
-#endif
+
+ existingDeviceHandleTestImpl(device, context);
+}
+
+SLANG_UNIT_TEST(existingDeviceHandleD3D12)
+{
+ return existingDeviceHandleTestAPI(unitTestContext, Slang::RenderApiFlag::D3D12);
}
+
+SLANG_UNIT_TEST(existingDeviceHandleVulkan)
+{
+ return existingDeviceHandleTestAPI(unitTestContext, Slang::RenderApiFlag::Vulkan);
+}
+#if SLANG_WIN64
+SLANG_UNIT_TEST(existingDeviceHandleCUDA)
+{
+ return existingDeviceHandleTestAPI(unitTestContext, Slang::RenderApiFlag::CUDA);
+}
+#endif
+} // namespace gfx_test
diff --git a/tools/gfx-unit-test/format-unit-tests.cpp b/tools/gfx-unit-test/format-unit-tests.cpp
index 5755e03cd..6ce38a26a 100644
--- a/tools/gfx-unit-test/format-unit-tests.cpp
+++ b/tools/gfx-unit-test/format-unit-tests.cpp
@@ -1,1119 +1,1489 @@
-#include "tools/unit-test/slang-unit-test.h"
-
-#include "slang-gfx.h"
#include "gfx-test-util.h"
-#include "tools/gfx-util/shader-cursor.h"
+#include "slang-gfx.h"
#include "source/core/slang-basic.h"
+#include "tools/gfx-util/shader-cursor.h"
+#include "tools/unit-test/slang-unit-test.h"
using namespace gfx;
namespace gfx_test
{
- gfx::Format convertTypelessFormat(gfx::Format format)
+gfx::Format convertTypelessFormat(gfx::Format format)
+{
+ switch (format)
+ {
+ case gfx::Format::R32G32B32A32_TYPELESS: return gfx::Format::R32G32B32A32_FLOAT;
+ case gfx::Format::R32G32B32_TYPELESS: return gfx::Format::R32G32B32_FLOAT;
+ case gfx::Format::R32G32_TYPELESS: return gfx::Format::R32G32_FLOAT;
+ case gfx::Format::R32_TYPELESS: return gfx::Format::R32_FLOAT;
+ case gfx::Format::R16G16B16A16_TYPELESS: return gfx::Format::R16G16B16A16_FLOAT;
+ case gfx::Format::R16G16_TYPELESS: return gfx::Format::R16G16_FLOAT;
+ case gfx::Format::R16_TYPELESS: return gfx::Format::R16_FLOAT;
+ case gfx::Format::R8G8B8A8_TYPELESS: return gfx::Format::R8G8B8A8_UNORM;
+ case gfx::Format::R8G8_TYPELESS: return gfx::Format::R8G8_UNORM;
+ case gfx::Format::R8_TYPELESS: return gfx::Format::R8_UNORM;
+ case gfx::Format::B8G8R8A8_TYPELESS: return gfx::Format::B8G8R8A8_UNORM;
+ case gfx::Format::R10G10B10A2_TYPELESS: return gfx::Format::R10G10B10A2_UINT;
+ default: return gfx::Format::Unknown;
+ }
+}
+
+void setUpAndRunTest(
+ IDevice* device,
+ ComPtr<IResourceView> texView,
+ ComPtr<IResourceView> bufferView,
+ const char* entryPoint,
+ ComPtr<ISamplerState> sampler = nullptr)
+{
+ Slang::ComPtr<ITransientResourceHeap> transientHeap;
+ ITransientResourceHeap::Desc transientHeapDesc = {};
+ transientHeapDesc.constantBufferSize = 4096;
+ GFX_CHECK_CALL_ABORT(
+ device->createTransientResourceHeap(transientHeapDesc, transientHeap.writeRef()));
+
+ ComPtr<IShaderProgram> shaderProgram;
+ slang::ProgramLayout* slangReflection;
+ GFX_CHECK_CALL_ABORT(loadComputeProgram(
+ device,
+ shaderProgram,
+ "format-test-shaders",
+ entryPoint,
+ slangReflection));
+
+ ComputePipelineStateDesc pipelineDesc = {};
+ pipelineDesc.program = shaderProgram.get();
+ ComPtr<gfx::IPipelineState> pipelineState;
+ GFX_CHECK_CALL_ABORT(
+ device->createComputePipelineState(pipelineDesc, pipelineState.writeRef()));
+
+ // We have done all the set up work, now it is time to start recording a command buffer for
+ // GPU execution.
+ {
+ ICommandQueue::Desc queueDesc = {ICommandQueue::QueueType::Graphics};
+ auto queue = device->createCommandQueue(queueDesc);
+
+ auto commandBuffer = transientHeap->createCommandBuffer();
+ auto encoder = commandBuffer->encodeComputeCommands();
+
+ auto rootObject = encoder->bindPipeline(pipelineState);
+
+ ShaderCursor entryPointCursor(
+ rootObject->getEntryPoint(0)); // get a cursor the the first entry-point.
+
+ // Bind texture view to the entry point
+ entryPointCursor.getPath("tex").setResource(texView);
+
+ if (sampler)
+ entryPointCursor.getPath("sampler").setSampler(sampler);
+
+ // Bind buffer view to the entry point.
+ entryPointCursor.getPath("buffer").setResource(bufferView);
+
+ encoder->dispatchCompute(1, 1, 1);
+ encoder->endEncoding();
+ commandBuffer->close();
+ queue->executeCommandBuffer(commandBuffer);
+ queue->waitOnHost();
+ }
+}
+
+ComPtr<IResourceView> createTexView(
+ IDevice* device,
+ ITextureResource::Extents size,
+ gfx::Format format,
+ ITextureResource::SubresourceData* data,
+ int mips = 1)
+{
+ ITextureResource::Desc texDesc = {};
+ texDesc.type = IResource::Type::Texture2D;
+ texDesc.numMipLevels = mips;
+ texDesc.arraySize = 1;
+ texDesc.size = size;
+ texDesc.defaultState = ResourceState::ShaderResource;
+ texDesc.format = format;
+
+ ComPtr<ITextureResource> inTex;
+ GFX_CHECK_CALL_ABORT(device->createTextureResource(texDesc, data, inTex.writeRef()));
+
+ ComPtr<IResourceView> texView;
+ IResourceView::Desc texViewDesc = {};
+ texViewDesc.type = IResourceView::Type::ShaderResource;
+ texViewDesc.format = gfxIsTypelessFormat(format) ? convertTypelessFormat(format) : format;
+ GFX_CHECK_CALL_ABORT(device->createTextureView(inTex, texViewDesc, texView.writeRef()));
+ return texView;
+}
+
+template<typename T>
+ComPtr<IBufferResource> createBuffer(IDevice* device, int size, void* initialData)
+{
+ IBufferResource::Desc bufferDesc = {};
+ bufferDesc.sizeInBytes = size * sizeof(T);
+ bufferDesc.format = gfx::Format::Unknown;
+ bufferDesc.elementSize = sizeof(T);
+ bufferDesc.allowedStates = ResourceStateSet(
+ ResourceState::ShaderResource,
+ ResourceState::UnorderedAccess,
+ ResourceState::CopyDestination,
+ ResourceState::CopySource);
+ bufferDesc.defaultState = ResourceState::UnorderedAccess;
+ bufferDesc.memoryType = MemoryType::DeviceLocal;
+
+ ComPtr<IBufferResource> outBuffer;
+ GFX_CHECK_CALL_ABORT(
+ device->createBufferResource(bufferDesc, initialData, outBuffer.writeRef()));
+ return outBuffer;
+}
+
+ComPtr<IResourceView> createBufferView(IDevice* device, ComPtr<IBufferResource> outBuffer)
+{
+ ComPtr<IResourceView> bufferView;
+ IResourceView::Desc viewDesc = {};
+ viewDesc.type = IResourceView::Type::UnorderedAccess;
+ viewDesc.format = Format::Unknown;
+ GFX_CHECK_CALL_ABORT(
+ device->createBufferView(outBuffer, nullptr, viewDesc, bufferView.writeRef()));
+ return bufferView;
+}
+
+void formatTestsImpl(IDevice* device, UnitTestContext* context)
+{
+ ISamplerState::Desc samplerDesc;
+ auto sampler = device->createSamplerState(samplerDesc);
+
+ float initFloatData[16] = {0.0f};
+ auto floatResults = createBuffer<float>(device, 16, initFloatData);
+ auto floatBufferView = createBufferView(device, floatResults);
+
+ uint32_t initUintData[16] = {0u};
+ auto uintResults = createBuffer<uint32_t>(device, 16, initUintData);
+ auto uintBufferView = createBufferView(device, uintResults);
+
+ int32_t initIntData[16] = {0};
+ auto intResults = createBuffer<uint32_t>(device, 16, initIntData);
+ auto intBufferView = createBufferView(device, intResults);
+
+ ITextureResource::Extents size = {};
+ size.width = 2;
+ size.height = 2;
+ size.depth = 1;
+
+ ITextureResource::Extents bcSize = {};
+ bcSize.width = 4;
+ bcSize.height = 4;
+ bcSize.depth = 1;
+
+ // Note: D32_FLOAT and D16_UNORM are not directly tested as they are only used for raster. These
+ // are the same as R32_FLOAT and R16_UNORM, respectively, when passed to a shader.
+ {
+ float texData[] = {
+ 1.0f,
+ 0.0f,
+ 0.0f,
+ 1.0f,
+ 0.0f,
+ 1.0f,
+ 0.0f,
+ 1.0f,
+ 0.0f,
+ 0.0f,
+ 1.0f,
+ 1.0f,
+ 0.5f,
+ 0.5f,
+ 0.5f,
+ 1.0f};
+ ITextureResource::SubresourceData subData = {(void*)texData, 32, 0};
+
+ auto texView = createTexView(device, size, gfx::Format::R32G32B32A32_FLOAT, &subData);
+ setUpAndRunTest(device, texView, floatBufferView, "copyTexFloat4");
+ compareComputeResult(
+ device,
+ floatResults,
+ Slang::makeArray<float>(
+ 1.0f,
+ 0.0f,
+ 0.0f,
+ 1.0f,
+ 0.0f,
+ 1.0f,
+ 0.0f,
+ 1.0f,
+ 0.0f,
+ 0.0f,
+ 1.0f,
+ 1.0f,
+ 0.5f,
+ 0.5f,
+ 0.5f,
+ 1.0f));
+
+ texView = createTexView(device, size, gfx::Format::R32G32B32A32_TYPELESS, &subData);
+ setUpAndRunTest(device, texView, floatBufferView, "copyTexFloat4");
+ compareComputeResult(
+ device,
+ floatResults,
+ Slang::makeArray<float>(
+ 1.0f,
+ 0.0f,
+ 0.0f,
+ 1.0f,
+ 0.0f,
+ 1.0f,
+ 0.0f,
+ 1.0f,
+ 0.0f,
+ 0.0f,
+ 1.0f,
+ 1.0f,
+ 0.5f,
+ 0.5f,
+ 0.5f,
+ 1.0f));
+ }
+
+ // Ignore this test since it is not supported by swiftshader and nvidia's driver.
+ if (false)
+ {
+ float texData[] = {1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.5f, 0.5f, 0.5f};
+ ITextureResource::SubresourceData subData = {(void*)texData, 24, 0};
+
+ auto texView = createTexView(device, size, gfx::Format::R32G32B32_FLOAT, &subData);
+ setUpAndRunTest(device, texView, floatBufferView, "copyTexFloat3");
+ compareComputeResult(
+ device,
+ floatResults,
+ Slang::makeArray<
+ float>(1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.5f, 0.5f, 0.5f));
+
+ texView = createTexView(device, size, gfx::Format::R32G32B32_TYPELESS, &subData);
+ setUpAndRunTest(device, texView, floatBufferView, "copyTexFloat3");
+ compareComputeResult(
+ device,
+ floatResults,
+ Slang::makeArray<
+ float>(1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.5f, 0.5f, 0.5f));
+ }
+
+ {
+ float texData[] = {1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.5f, 0.5f};
+ ITextureResource::SubresourceData subData = {(void*)texData, 16, 0};
+
+ auto texView = createTexView(device, size, gfx::Format::R32G32_FLOAT, &subData);
+ setUpAndRunTest(device, texView, floatBufferView, "copyTexFloat2");
+ compareComputeResult(
+ device,
+ floatResults,
+ Slang::makeArray<float>(1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.5f, 0.5f));
+
+ texView = createTexView(device, size, gfx::Format::R32G32_TYPELESS, &subData);
+ setUpAndRunTest(device, texView, floatBufferView, "copyTexFloat2");
+ compareComputeResult(
+ device,
+ floatResults,
+ Slang::makeArray<float>(1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.5f, 0.5f));
+ }
+
+ {
+ float texData[] = {1.0f, 0.0f, 0.5f, 0.25f};
+ ITextureResource::SubresourceData subData = {(void*)texData, 8, 0};
+
+ auto texView = createTexView(device, size, gfx::Format::R32_FLOAT, &subData);
+ setUpAndRunTest(device, texView, floatBufferView, "copyTexFloat");
+ compareComputeResult(
+ device,
+ floatResults,
+ Slang::makeArray<float>(1.0f, 0.0f, 0.5f, 0.25f));
+
+ texView = createTexView(device, size, gfx::Format::R32_TYPELESS, &subData);
+ setUpAndRunTest(device, texView, floatBufferView, "copyTexFloat");
+ compareComputeResult(
+ device,
+ floatResults,
+ Slang::makeArray<float>(1.0f, 0.0f, 0.5f, 0.25f));
+ }
+
+ {
+ uint16_t texData[] = {
+ 15360u,
+ 0u,
+ 0u,
+ 15360u,
+ 0u,
+ 15360u,
+ 0u,
+ 15360u,
+ 0u,
+ 0u,
+ 15360u,
+ 15360u,
+ 14336u,
+ 14336u,
+ 14336u,
+ 15360u};
+ ITextureResource::SubresourceData subData = {(void*)texData, 16, 0};
+
+ auto texView = createTexView(device, size, gfx::Format::R16G16B16A16_FLOAT, &subData);
+ setUpAndRunTest(device, texView, floatBufferView, "copyTexFloat4");
+ compareComputeResult(
+ device,
+ floatResults,
+ Slang::makeArray<float>(
+ 1.0f,
+ 0.0f,
+ 0.0f,
+ 1.0f,
+ 0.0f,
+ 1.0f,
+ 0.0f,
+ 1.0f,
+ 0.0f,
+ 0.0f,
+ 1.0f,
+ 1.0f,
+ 0.5f,
+ 0.5f,
+ 0.5f,
+ 1.0f));
+
+ texView = createTexView(device, size, gfx::Format::R16G16B16A16_TYPELESS, &subData);
+ setUpAndRunTest(device, texView, floatBufferView, "copyTexFloat4");
+ compareComputeResult(
+ device,
+ floatResults,
+ Slang::makeArray<float>(
+ 1.0f,
+ 0.0f,
+ 0.0f,
+ 1.0f,
+ 0.0f,
+ 1.0f,
+ 0.0f,
+ 1.0f,
+ 0.0f,
+ 0.0f,
+ 1.0f,
+ 1.0f,
+ 0.5f,
+ 0.5f,
+ 0.5f,
+ 1.0f));
+ }
+
+ {
+ uint16_t texData[] = {15360u, 0u, 0u, 15360u, 15360u, 15360u, 14336u, 14336u};
+ ITextureResource::SubresourceData subData = {(void*)texData, 8, 0};
+
+ auto texView = createTexView(device, size, gfx::Format::R16G16_FLOAT, &subData);
+ setUpAndRunTest(device, texView, floatBufferView, "copyTexFloat2");
+ compareComputeResult(
+ device,
+ floatResults,
+ Slang::makeArray<float>(1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.5f, 0.5f));
+
+ texView = createTexView(device, size, gfx::Format::R16G16_TYPELESS, &subData);
+ setUpAndRunTest(device, texView, floatBufferView, "copyTexFloat2");
+ compareComputeResult(
+ device,
+ floatResults,
+ Slang::makeArray<float>(1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.5f, 0.5f));
+ }
+
+ {
+ uint16_t texData[] = {15360u, 0u, 14336u, 13312u};
+ ITextureResource::SubresourceData subData = {(void*)texData, 4, 0};
+
+ auto texView = createTexView(device, size, gfx::Format::R16_FLOAT, &subData);
+ setUpAndRunTest(device, texView, floatBufferView, "copyTexFloat");
+ compareComputeResult(
+ device,
+ floatResults,
+ Slang::makeArray<float>(1.0f, 0.0f, 0.5f, 0.25f));
+
+ texView = createTexView(device, size, gfx::Format::R16_TYPELESS, &subData);
+ setUpAndRunTest(device, texView, floatBufferView, "copyTexFloat");
+ compareComputeResult(
+ device,
+ floatResults,
+ Slang::makeArray<float>(1.0f, 0.0f, 0.5f, 0.25f));
+ }
+
+ {
+ uint32_t texData[] =
+ {255u, 0u, 0u, 255u, 0u, 255u, 0u, 255u, 0u, 0u, 255u, 255u, 127u, 127u, 127u, 255u};
+ ITextureResource::SubresourceData subData = {(void*)texData, 32, 0};
+
+ auto texView = createTexView(device, size, gfx::Format::R32G32B32A32_UINT, &subData);
+ setUpAndRunTest(device, texView, uintBufferView, "copyTexUint4");
+ compareComputeResult(
+ device,
+ uintResults,
+ Slang::makeArray<uint32_t>(
+ 255u,
+ 0u,
+ 0u,
+ 255u,
+ 0u,
+ 255u,
+ 0u,
+ 255u,
+ 0u,
+ 0u,
+ 255u,
+ 255u,
+ 127u,
+ 127u,
+ 127u,
+ 255u));
+ }
+
+ // Ignore this test since validation layer reports that it is unsupported.
+ if (false)
{
- switch (format)
- {
- case gfx::Format::R32G32B32A32_TYPELESS:
- return gfx::Format::R32G32B32A32_FLOAT;
- case gfx::Format::R32G32B32_TYPELESS:
- return gfx::Format::R32G32B32_FLOAT;
- case gfx::Format::R32G32_TYPELESS:
- return gfx::Format::R32G32_FLOAT;
- case gfx::Format::R32_TYPELESS:
- return gfx::Format::R32_FLOAT;
- case gfx::Format::R16G16B16A16_TYPELESS:
- return gfx::Format::R16G16B16A16_FLOAT;
- case gfx::Format::R16G16_TYPELESS:
- return gfx::Format::R16G16_FLOAT;
- case gfx::Format::R16_TYPELESS:
- return gfx::Format::R16_FLOAT;
- case gfx::Format::R8G8B8A8_TYPELESS:
- return gfx::Format::R8G8B8A8_UNORM;
- case gfx::Format::R8G8_TYPELESS:
- return gfx::Format::R8G8_UNORM;
- case gfx::Format::R8_TYPELESS:
- return gfx::Format::R8_UNORM;
- case gfx::Format::B8G8R8A8_TYPELESS:
- return gfx::Format::B8G8R8A8_UNORM;
- case gfx::Format::R10G10B10A2_TYPELESS:
- return gfx::Format::R10G10B10A2_UINT;
- default:
- return gfx::Format::Unknown;
- }
+ uint32_t texData[] = {255u, 0u, 0u, 0u, 255u, 0u, 0u, 0u, 255u, 127u, 127u, 127u};
+ ITextureResource::SubresourceData subData = {(void*)texData, 24, 0};
+
+ auto texView = createTexView(device, size, gfx::Format::R32G32B32_UINT, &subData);
+ setUpAndRunTest(device, texView, uintBufferView, "copyTexUint3");
+ compareComputeResult(
+ device,
+ uintResults,
+ Slang::makeArray<uint32_t>(255u, 0u, 0u, 0u, 255u, 0u, 0u, 0u, 255u, 127u, 127u, 127u));
}
- void setUpAndRunTest(
- IDevice* device,
- ComPtr<IResourceView> texView,
- ComPtr<IResourceView> bufferView,
- const char* entryPoint,
- ComPtr<ISamplerState> sampler = nullptr)
{
- Slang::ComPtr<ITransientResourceHeap> transientHeap;
- ITransientResourceHeap::Desc transientHeapDesc = {};
- transientHeapDesc.constantBufferSize = 4096;
- GFX_CHECK_CALL_ABORT(
- device->createTransientResourceHeap(transientHeapDesc, transientHeap.writeRef()));
-
- ComPtr<IShaderProgram> shaderProgram;
- slang::ProgramLayout* slangReflection;
- GFX_CHECK_CALL_ABORT(loadComputeProgram(device, shaderProgram, "format-test-shaders", entryPoint, slangReflection));
-
- ComputePipelineStateDesc pipelineDesc = {};
- pipelineDesc.program = shaderProgram.get();
- ComPtr<gfx::IPipelineState> pipelineState;
- GFX_CHECK_CALL_ABORT(
- device->createComputePipelineState(pipelineDesc, pipelineState.writeRef()));
-
- // We have done all the set up work, now it is time to start recording a command buffer for
- // GPU execution.
- {
- ICommandQueue::Desc queueDesc = { ICommandQueue::QueueType::Graphics };
- auto queue = device->createCommandQueue(queueDesc);
-
- auto commandBuffer = transientHeap->createCommandBuffer();
- auto encoder = commandBuffer->encodeComputeCommands();
-
- auto rootObject = encoder->bindPipeline(pipelineState);
-
- ShaderCursor entryPointCursor(
- rootObject->getEntryPoint(0)); // get a cursor the the first entry-point.
-
- // Bind texture view to the entry point
- entryPointCursor.getPath("tex").setResource(texView);
-
- if (sampler) entryPointCursor.getPath("sampler").setSampler(sampler);
-
- // Bind buffer view to the entry point.
- entryPointCursor.getPath("buffer").setResource(bufferView);
-
- encoder->dispatchCompute(1, 1, 1);
- encoder->endEncoding();
- commandBuffer->close();
- queue->executeCommandBuffer(commandBuffer);
- queue->waitOnHost();
- }
+ uint32_t texData[] = {255u, 0u, 0u, 255u, 255u, 255u, 127u, 127u};
+ ITextureResource::SubresourceData subData = {(void*)texData, 16, 0};
+
+ auto texView = createTexView(device, size, gfx::Format::R32G32_UINT, &subData);
+ setUpAndRunTest(device, texView, uintBufferView, "copyTexUint2");
+ compareComputeResult(
+ device,
+ uintResults,
+ Slang::makeArray<uint32_t>(255u, 0u, 0u, 255u, 255u, 255u, 127u, 127u));
}
- ComPtr<IResourceView> createTexView(
- IDevice* device,
- ITextureResource::Extents size,
- gfx::Format format,
- ITextureResource::SubresourceData* data,
- int mips = 1)
{
- ITextureResource::Desc texDesc = {};
- texDesc.type = IResource::Type::Texture2D;
- texDesc.numMipLevels = mips;
- texDesc.arraySize = 1;
- texDesc.size = size;
- texDesc.defaultState = ResourceState::ShaderResource;
- texDesc.format = format;
-
- ComPtr<ITextureResource> inTex;
- GFX_CHECK_CALL_ABORT(device->createTextureResource(
- texDesc,
- data,
- inTex.writeRef()));
-
- ComPtr<IResourceView> texView;
- IResourceView::Desc texViewDesc = {};
- texViewDesc.type = IResourceView::Type::ShaderResource;
- texViewDesc.format = gfxIsTypelessFormat(format) ? convertTypelessFormat(format) : format;
- GFX_CHECK_CALL_ABORT(device->createTextureView(inTex, texViewDesc, texView.writeRef()));
- return texView;
+ uint32_t texData[] = {255u, 0u, 127u, 73u};
+ ITextureResource::SubresourceData subData = {(void*)texData, 8, 0};
+
+ auto texView = createTexView(device, size, gfx::Format::R32_UINT, &subData);
+ setUpAndRunTest(device, texView, uintBufferView, "copyTexUint");
+ compareComputeResult(device, uintResults, Slang::makeArray<uint32_t>(255u, 0u, 127u, 73u));
}
- template <typename T>
- ComPtr<IBufferResource> createBuffer(IDevice* device, int size, void* initialData)
{
- IBufferResource::Desc bufferDesc = {};
- bufferDesc.sizeInBytes = size * sizeof(T);
- bufferDesc.format = gfx::Format::Unknown;
- bufferDesc.elementSize = sizeof(T);
- bufferDesc.allowedStates = ResourceStateSet(
- ResourceState::ShaderResource,
- ResourceState::UnorderedAccess,
- ResourceState::CopyDestination,
- ResourceState::CopySource);
- bufferDesc.defaultState = ResourceState::UnorderedAccess;
- bufferDesc.memoryType = MemoryType::DeviceLocal;
-
- ComPtr<IBufferResource> outBuffer;
- GFX_CHECK_CALL_ABORT(device->createBufferResource(
- bufferDesc,
- initialData,
- outBuffer.writeRef()));
- return outBuffer;
+ uint16_t texData[] =
+ {255u, 0u, 0u, 255u, 0u, 255u, 0u, 255u, 0u, 0u, 255u, 255u, 127u, 127u, 127u, 255u};
+ ITextureResource::SubresourceData subData = {(void*)texData, 16, 0};
+
+ auto texView = createTexView(device, size, gfx::Format::R16G16B16A16_UINT, &subData);
+ setUpAndRunTest(device, texView, uintBufferView, "copyTexUint4");
+ compareComputeResult(
+ device,
+ uintResults,
+ Slang::makeArray<uint32_t>(
+ 255u,
+ 0u,
+ 0u,
+ 255u,
+ 0u,
+ 255u,
+ 0u,
+ 255u,
+ 0u,
+ 0u,
+ 255u,
+ 255u,
+ 127u,
+ 127u,
+ 127u,
+ 255u));
}
- ComPtr<IResourceView> createBufferView(IDevice* device, ComPtr<IBufferResource> outBuffer)
{
- ComPtr<IResourceView> bufferView;
- IResourceView::Desc viewDesc = {};
- viewDesc.type = IResourceView::Type::UnorderedAccess;
- viewDesc.format = Format::Unknown;
- GFX_CHECK_CALL_ABORT(
- device->createBufferView(outBuffer, nullptr, viewDesc, bufferView.writeRef()));
- return bufferView;
+ uint16_t texData[] = {255u, 0u, 0u, 255u, 255u, 255u, 127u, 127u};
+ ITextureResource::SubresourceData subData = {(void*)texData, 8, 0};
+
+ auto texView = createTexView(device, size, gfx::Format::R16G16_UINT, &subData);
+ setUpAndRunTest(device, texView, uintBufferView, "copyTexUint2");
+ compareComputeResult(
+ device,
+ uintResults,
+ Slang::makeArray<uint32_t>(255u, 0u, 0u, 255u, 255u, 255u, 127u, 127u));
}
- void formatTestsImpl(IDevice* device, UnitTestContext* context)
{
- ISamplerState::Desc samplerDesc;
- auto sampler = device->createSamplerState(samplerDesc);
+ uint16_t texData[] = {255u, 0u, 127u, 73u};
+ ITextureResource::SubresourceData subData = {(void*)texData, 4, 0};
- float initFloatData[16] = { 0.0f };
- auto floatResults = createBuffer<float>(device, 16, initFloatData);
- auto floatBufferView = createBufferView(device, floatResults);
+ auto texView = createTexView(device, size, gfx::Format::R16_UINT, &subData);
+ setUpAndRunTest(device, texView, uintBufferView, "copyTexUint");
+ compareComputeResult(device, uintResults, Slang::makeArray<uint32_t>(255u, 0u, 127u, 73u));
+ }
- uint32_t initUintData[16] = { 0u };
- auto uintResults = createBuffer<uint32_t>(device, 16, initUintData);
- auto uintBufferView = createBufferView(device, uintResults);
+ {
+ uint8_t texData[] =
+ {255u, 0u, 0u, 255u, 0u, 255u, 0u, 255u, 0u, 0u, 255u, 255u, 127u, 127u, 127u, 255u};
+ ITextureResource::SubresourceData subData = {(void*)texData, 8, 0};
+
+ auto texView = createTexView(device, size, gfx::Format::R8G8B8A8_UINT, &subData);
+ setUpAndRunTest(device, texView, uintBufferView, "copyTexUint4");
+ compareComputeResult(
+ device,
+ uintResults,
+ Slang::makeArray<uint32_t>(
+ 255u,
+ 0u,
+ 0u,
+ 255u,
+ 0u,
+ 255u,
+ 0u,
+ 255u,
+ 0u,
+ 0u,
+ 255u,
+ 255u,
+ 127u,
+ 127u,
+ 127u,
+ 255u));
+ }
- int32_t initIntData[16] = { 0 };
- auto intResults = createBuffer<uint32_t>(device, 16, initIntData);
- auto intBufferView = createBufferView(device, intResults);
+ {
+ uint8_t texData[] = {255u, 0u, 0u, 255u, 255u, 255u, 127u, 127u};
+ ITextureResource::SubresourceData subData = {(void*)texData, 4, 0};
+
+ auto texView = createTexView(device, size, gfx::Format::R8G8_UINT, &subData);
+ setUpAndRunTest(device, texView, uintBufferView, "copyTexUint2");
+ compareComputeResult(
+ device,
+ uintResults,
+ Slang::makeArray<uint32_t>(255u, 0u, 0u, 255u, 255u, 255u, 127u, 127u));
+ }
+ {
+ uint8_t texData[] = {255u, 0u, 127u, 73u};
+ ITextureResource::SubresourceData subData = {(void*)texData, 2, 0};
+
+ auto texView = createTexView(device, size, gfx::Format::R8_UINT, &subData);
+ setUpAndRunTest(device, texView, uintBufferView, "copyTexUint");
+ compareComputeResult(device, uintResults, Slang::makeArray<uint32_t>(255u, 0u, 127u, 73u));
+ }
+
+ {
+ int32_t texData[] = {255, 0, 0, 255, 0, 255, 0, 255, 0, 0, 255, 255, 127, 127, 127, 255};
+ ITextureResource::SubresourceData subData = {(void*)texData, 32, 0};
+
+ auto texView = createTexView(device, size, gfx::Format::R32G32B32A32_SINT, &subData);
+ setUpAndRunTest(device, texView, intBufferView, "copyTexInt4");
+ compareComputeResult(
+ device,
+ intResults,
+ Slang::makeArray<
+ int32_t>(255, 0, 0, 255, 0, 255, 0, 255, 0, 0, 255, 255, 127, 127, 127, 255));
+ }
+
+ // Ignore this test on swiftshader. Swiftshader produces unsupported format warnings for this
+ // test.
+ if (false)
+ {
+ int32_t texData[] = {255, 0, 0, 0, 255, 0, 0, 0, 255, 127, 127, 127};
+ ITextureResource::SubresourceData subData = {(void*)texData, 24, 0};
+
+ auto texView = createTexView(device, size, gfx::Format::R32G32B32_SINT, &subData);
+ setUpAndRunTest(device, texView, intBufferView, "copyTexInt3");
+ compareComputeResult(
+ device,
+ intResults,
+ Slang::makeArray<int32_t>(255, 0, 0, 0, 255, 0, 0, 0, 255, 127, 127, 127));
+ }
+
+ {
+ int32_t texData[] = {255, 0, 0, 255, 255, 255, 127, 127};
+ ITextureResource::SubresourceData subData = {(void*)texData, 16, 0};
+
+ auto texView = createTexView(device, size, gfx::Format::R32G32_SINT, &subData);
+ setUpAndRunTest(device, texView, intBufferView, "copyTexInt2");
+ compareComputeResult(
+ device,
+ intResults,
+ Slang::makeArray<int32_t>(255, 0, 0, 255, 255, 255, 127, 127));
+ }
+
+ {
+ int32_t texData[] = {255, 0, 127, 73};
+ ITextureResource::SubresourceData subData = {(void*)texData, 8, 0};
+
+ auto texView = createTexView(device, size, gfx::Format::R32_SINT, &subData);
+ setUpAndRunTest(device, texView, intBufferView, "copyTexInt");
+ compareComputeResult(device, intResults, Slang::makeArray<int32_t>(255, 0, 127, 73));
+ }
+
+ {
+ int16_t texData[] = {255, 0, 0, 255, 0, 255, 0, 255, 0, 0, 255, 255, 127, 127, 127, 255};
+ ITextureResource::SubresourceData subData = {(void*)texData, 16, 0};
+
+ auto texView = createTexView(device, size, gfx::Format::R16G16B16A16_SINT, &subData);
+ setUpAndRunTest(device, texView, intBufferView, "copyTexInt4");
+ compareComputeResult(
+ device,
+ intResults,
+ Slang::makeArray<
+ int32_t>(255, 0, 0, 255, 0, 255, 0, 255, 0, 0, 255, 255, 127, 127, 127, 255));
+ }
+
+ {
+ int16_t texData[] = {255, 0, 0, 255, 255, 255, 127, 127};
+ ITextureResource::SubresourceData subData = {(void*)texData, 8, 0};
+
+ auto texView = createTexView(device, size, gfx::Format::R16G16_SINT, &subData);
+ setUpAndRunTest(device, texView, intBufferView, "copyTexInt2");
+ compareComputeResult(
+ device,
+ intResults,
+ Slang::makeArray<int32_t>(255, 0, 0, 255, 255, 255, 127, 127));
+ }
+
+ {
+ int16_t texData[] = {255, 0, 127, 73};
+ ITextureResource::SubresourceData subData = {(void*)texData, 4, 0};
+
+ auto texView = createTexView(device, size, gfx::Format::R16_SINT, &subData);
+ setUpAndRunTest(device, texView, intBufferView, "copyTexInt");
+ compareComputeResult(device, intResults, Slang::makeArray<int32_t>(255, 0, 127, 73));
+ }
+
+ {
+ int8_t texData[] = {127, 0, 0, 127, 0, 127, 0, 127, 0, 0, 127, 127, 0, 0, 0, 127};
+ ITextureResource::SubresourceData subData = {(void*)texData, 8, 0};
+
+ auto texView = createTexView(device, size, gfx::Format::R8G8B8A8_SINT, &subData);
+ setUpAndRunTest(device, texView, intBufferView, "copyTexInt4");
+ compareComputeResult(
+ device,
+ intResults,
+ Slang::makeArray<
+ int32_t>(127, 0, 0, 127, 0, 127, 0, 127, 0, 0, 127, 127, 0, 0, 0, 127));
+ }
+
+ {
+ int8_t texData[] = {127, 0, 0, 127, 127, 127, 73, 73};
+ ITextureResource::SubresourceData subData = {(void*)texData, 4, 0};
+
+ auto texView = createTexView(device, size, gfx::Format::R8G8_SINT, &subData);
+ setUpAndRunTest(device, texView, intBufferView, "copyTexInt2");
+ compareComputeResult(
+ device,
+ intResults,
+ Slang::makeArray<int32_t>(127, 0, 0, 127, 127, 127, 73, 73));
+ }
+
+ {
+ int8_t texData[] = {127, 0, 73, 25};
+ ITextureResource::SubresourceData subData = {(void*)texData, 2, 0};
+
+ auto texView = createTexView(device, size, gfx::Format::R8_SINT, &subData);
+ setUpAndRunTest(device, texView, intBufferView, "copyTexInt");
+ compareComputeResult(device, intResults, Slang::makeArray<int32_t>(127, 0, 73, 25));
+ }
+
+ {
+ uint16_t texData[] = {
+ 65535u,
+ 0u,
+ 0u,
+ 65535u,
+ 0u,
+ 65535u,
+ 0u,
+ 65535u,
+ 0u,
+ 0u,
+ 65535u,
+ 65535u,
+ 32767u,
+ 32767u,
+ 32767u,
+ 32767u};
+ ITextureResource::SubresourceData subData = {(void*)texData, 16, 0};
+
+ auto texView = createTexView(device, size, gfx::Format::R16G16B16A16_UNORM, &subData);
+ setUpAndRunTest(device, texView, floatBufferView, "copyTexFloat4");
+ compareComputeResult(
+ device,
+ floatResults,
+ Slang::makeArray<float>(
+ 1.0f,
+ 0.0f,
+ 0.0f,
+ 1.0f,
+ 0.0f,
+ 1.0f,
+ 0.0f,
+ 1.0f,
+ 0.0f,
+ 0.0f,
+ 1.0f,
+ 1.0f,
+ 0.499992371f,
+ 0.499992371f,
+ 0.499992371f,
+ 0.499992371f));
+ }
+
+ {
+ uint16_t texData[] = {65535u, 0u, 0u, 65535u, 65535u, 65535u, 32767u, 32767u};
+ ITextureResource::SubresourceData subData = {(void*)texData, 8, 0};
+
+ auto texView = createTexView(device, size, gfx::Format::R16G16_UNORM, &subData);
+ setUpAndRunTest(device, texView, floatBufferView, "copyTexFloat2");
+ compareComputeResult(
+ device,
+ floatResults,
+ Slang::makeArray<
+ float>(1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.499992371f, 0.499992371f));
+ }
+
+ {
+ uint16_t texData[] = {65535u, 0u, 32767u, 16383u};
+ ITextureResource::SubresourceData subData = {(void*)texData, 4, 0};
+
+ auto texView = createTexView(device, size, gfx::Format::R16_UNORM, &subData);
+ setUpAndRunTest(device, texView, floatBufferView, "copyTexFloat");
+ compareComputeResult(
+ device,
+ floatResults,
+ Slang::makeArray<float>(1.0f, 0.0f, 0.499992371f, 0.249988556f));
+ }
+
+ // Ignore this test on swiftshader. Swiftshader produces different results than expected.
+ if (!Slang::String(device->getDeviceInfo().adapterName).toLower().contains("swiftshader"))
+ {
+ uint8_t texData[] =
+ {0u, 0u, 0u, 255u, 127u, 127u, 127u, 255u, 255u, 255u, 255u, 255u, 0u, 0u, 0u, 0u};
+ ITextureResource::SubresourceData subData = {(void*)texData, 8, 0};
+
+ auto texView = createTexView(device, size, gfx::Format::R8G8B8A8_TYPELESS, &subData);
+ setUpAndRunTest(device, texView, floatBufferView, "copyTexFloat4");
+ compareComputeResult(
+ device,
+ floatResults,
+ Slang::makeArray<float>(
+ 0.0f,
+ 0.0f,
+ 0.0f,
+ 1.0f,
+ 0.498039216f,
+ 0.498039216f,
+ 0.498039216f,
+ 1.0f,
+ 1.0f,
+ 1.0f,
+ 1.0f,
+ 1.0f,
+ 0.0f,
+ 0.0f,
+ 0.0f,
+ 0.0f));
+
+ texView = createTexView(device, size, gfx::Format::R8G8B8A8_UNORM, &subData);
+ setUpAndRunTest(device, texView, floatBufferView, "copyTexFloat4");
+ compareComputeResult(
+ device,
+ floatResults,
+ Slang::makeArray<float>(
+ 0.0f,
+ 0.0f,
+ 0.0f,
+ 1.0f,
+ 0.498039216f,
+ 0.498039216f,
+ 0.498039216f,
+ 1.0f,
+ 1.0f,
+ 1.0f,
+ 1.0f,
+ 1.0f,
+ 0.0f,
+ 0.0f,
+ 0.0f,
+ 0.0f));
+
+ texView = createTexView(device, size, gfx::Format::R8G8B8A8_UNORM_SRGB, &subData);
+ setUpAndRunTest(device, texView, floatBufferView, "copyTexFloat4");
+ compareComputeResult(
+ device,
+ floatResults,
+ Slang::makeArray<float>(
+ 0.0f,
+ 0.0f,
+ 0.0f,
+ 1.0f,
+ 0.211914062f,
+ 0.211914062f,
+ 0.211914062f,
+ 1.0f,
+ 1.0f,
+ 1.0f,
+ 1.0f,
+ 1.0f,
+ 0.0f,
+ 0.0f,
+ 0.0f,
+ 0.0f));
+ }
+
+ // Ignore this test on swiftshader. Swiftshader produces different results than expected.
+ if (!Slang::String(device->getDeviceInfo().adapterName).toLower().contains("swiftshader"))
+ {
+ uint8_t texData[] = {255u, 0u, 0u, 255u, 255u, 255u, 127u, 127u};
+ ITextureResource::SubresourceData subData = {(void*)texData, 4, 0};
+
+ auto texView = createTexView(device, size, gfx::Format::R8G8_TYPELESS, &subData);
+ setUpAndRunTest(device, texView, floatBufferView, "copyTexFloat2");
+ compareComputeResult(
+ device,
+ floatResults,
+ Slang::makeArray<
+ float>(1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.498039216f, 0.498039216f));
+
+ texView = createTexView(device, size, gfx::Format::R8G8_UNORM, &subData);
+ setUpAndRunTest(device, texView, floatBufferView, "copyTexFloat2");
+ compareComputeResult(
+ device,
+ floatResults,
+ Slang::makeArray<
+ float>(1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.498039216f, 0.498039216f));
+ }
+
+ // Ignore this test on swiftshader. Swiftshader produces different results than expected.
+ if (!Slang::String(device->getDeviceInfo().adapterName).toLower().contains("swiftshader"))
+ {
+ uint8_t texData[] = {255u, 0u, 127u, 63u};
+ ITextureResource::SubresourceData subData = {(void*)texData, 2, 0};
+
+ auto texView = createTexView(device, size, gfx::Format::R8_TYPELESS, &subData);
+ setUpAndRunTest(device, texView, floatBufferView, "copyTexFloat");
+ compareComputeResult(
+ device,
+ floatResults,
+ Slang::makeArray<float>(1.0f, 0.0f, 0.498039216f, 0.247058824f));
+
+ texView = createTexView(device, size, gfx::Format::R8_UNORM, &subData);
+ setUpAndRunTest(device, texView, floatBufferView, "copyTexFloat");
+ compareComputeResult(
+ device,
+ floatResults,
+ Slang::makeArray<float>(1.0f, 0.0f, 0.498039216f, 0.247058824f));
+ }
+
+ // Ignore this test on swiftshader. Swiftshader produces different results than expected.
+ if (!Slang::String(device->getDeviceInfo().adapterName).toLower().contains("swiftshader"))
+ {
+ uint8_t texData[] =
+ {0u, 0u, 0u, 255u, 127u, 127u, 127u, 255u, 255u, 255u, 255u, 255u, 0u, 0u, 0u, 0u};
+ ITextureResource::SubresourceData subData = {(void*)texData, 8, 0};
+
+ auto texView = createTexView(device, size, gfx::Format::B8G8R8A8_TYPELESS, &subData);
+ setUpAndRunTest(device, texView, floatBufferView, "copyTexFloat4");
+ compareComputeResult(
+ device,
+ floatResults,
+ Slang::makeArray<float>(
+ 0.0f,
+ 0.0f,
+ 0.0f,
+ 1.0f,
+ 0.498039216f,
+ 0.498039216f,
+ 0.498039216f,
+ 1.0f,
+ 1.0f,
+ 1.0f,
+ 1.0f,
+ 1.0f,
+ 0.0f,
+ 0.0f,
+ 0.0f,
+ 0.0f));
+
+ texView = createTexView(device, size, gfx::Format::B8G8R8A8_UNORM, &subData);
+ setUpAndRunTest(device, texView, floatBufferView, "copyTexFloat4");
+ compareComputeResult(
+ device,
+ floatResults,
+ Slang::makeArray<float>(
+ 0.0f,
+ 0.0f,
+ 0.0f,
+ 1.0f,
+ 0.498039216f,
+ 0.498039216f,
+ 0.498039216f,
+ 1.0f,
+ 1.0f,
+ 1.0f,
+ 1.0f,
+ 1.0f,
+ 0.0f,
+ 0.0f,
+ 0.0f,
+ 0.0f));
+
+ texView = createTexView(device, size, gfx::Format::B8G8R8A8_UNORM_SRGB, &subData);
+ setUpAndRunTest(device, texView, floatBufferView, "copyTexFloat4");
+ compareComputeResult(
+ device,
+ floatResults,
+ Slang::makeArray<float>(
+ 0.0f,
+ 0.0f,
+ 0.0f,
+ 1.0f,
+ 0.211914062f,
+ 0.211914062f,
+ 0.211914062f,
+ 1.0f,
+ 1.0f,
+ 1.0f,
+ 1.0f,
+ 1.0f,
+ 0.0f,
+ 0.0f,
+ 0.0f,
+ 0.0f));
+ }
+
+ {
+ int16_t texData[] =
+ {32767, 0, 0, 32767, 0, 32767, 0, 32767, 0, 0, 32767, 32767, -32768, -32768, 0, 32767};
+ ITextureResource::SubresourceData subData = {(void*)texData, 16, 0};
+
+ auto texView = createTexView(device, size, gfx::Format::R16G16B16A16_SNORM, &subData);
+ setUpAndRunTest(device, texView, floatBufferView, "copyTexFloat4");
+ compareComputeResult(
+ device,
+ floatResults,
+ Slang::makeArray<float>(
+ 1.0f,
+ 0.0f,
+ 0.0f,
+ 1.0f,
+ 0.0f,
+ 1.0f,
+ 0.0f,
+ 1.0f,
+ 0.0f,
+ 0.0f,
+ 1.0f,
+ 1.0f,
+ -1.0f,
+ -1.0f,
+ 0.0f,
+ 1.0f));
+ }
+
+ {
+ int16_t texData[] = {32767, 0, 0, 32767, 32767, 32767, -32768, -32768};
+ ITextureResource::SubresourceData subData = {(void*)texData, 8, 0};
+
+ auto texView = createTexView(device, size, gfx::Format::R16G16_SNORM, &subData);
+ setUpAndRunTest(device, texView, floatBufferView, "copyTexFloat2");
+ compareComputeResult(
+ device,
+ floatResults,
+ Slang::makeArray<float>(1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, -1.0f, -1.0f));
+ }
+
+ {
+ int16_t texData[] = {32767, 0, -32768, 0};
+ ITextureResource::SubresourceData subData = {(void*)texData, 4, 0};
+
+ auto texView = createTexView(device, size, gfx::Format::R16_SNORM, &subData);
+ setUpAndRunTest(device, texView, floatBufferView, "copyTexFloat");
+ compareComputeResult(
+ device,
+ floatResults,
+ Slang::makeArray<float>(1.0f, 0.0f, -1.0f, 0.0f));
+ }
+
+ {
+ int8_t texData[] = {127, 0, 0, 127, 0, 127, 0, 127, 0, 0, 127, 127, -128, -128, 0, 127};
+ ITextureResource::SubresourceData subData = {(void*)texData, 8, 0};
+
+ auto texView = createTexView(device, size, gfx::Format::R8G8B8A8_SNORM, &subData);
+ setUpAndRunTest(device, texView, floatBufferView, "copyTexFloat4");
+ compareComputeResult(
+ device,
+ floatResults,
+ Slang::makeArray<float>(
+ 1.0f,
+ 0.0f,
+ 0.0f,
+ 1.0f,
+ 0.0f,
+ 1.0f,
+ 0.0f,
+ 1.0f,
+ 0.0f,
+ 0.0f,
+ 1.0f,
+ 1.0f,
+ -1.0f,
+ -1.0f,
+ 0.0f,
+ 1.0f));
+ }
+
+ {
+ int8_t texData[] = {127, 0, 0, 127, 127, 127, -128, -128};
+ ITextureResource::SubresourceData subData = {(void*)texData, 4, 0};
+
+ auto texView = createTexView(device, size, gfx::Format::R8G8_SNORM, &subData);
+ setUpAndRunTest(device, texView, floatBufferView, "copyTexFloat2");
+ compareComputeResult(
+ device,
+ floatResults,
+ Slang::makeArray<float>(1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, -1.0f, -1.0f));
+ }
+
+ {
+ int8_t texData[] = {127, 0, -128, 0};
+ ITextureResource::SubresourceData subData = {(void*)texData, 2, 0};
+
+ auto texView = createTexView(device, size, gfx::Format::R8_SNORM, &subData);
+ setUpAndRunTest(device, texView, floatBufferView, "copyTexFloat");
+ compareComputeResult(
+ device,
+ floatResults,
+ Slang::makeArray<float>(1.0f, 0.0f, -1.0f, 0.0f));
+ }
+
+ // Ignore this test on swiftshader. Swiftshader produces unsupported format warnings for this
+ // test.
+ if (!Slang::String(device->getDeviceInfo().adapterName).toLower().contains("swiftshader"))
+ {
+ uint8_t texData[] = {15u, 240u, 240u, 240u, 0u, 255u, 119u, 119u};
+ ITextureResource::SubresourceData subData = {(void*)texData, 4, 0};
+
+ auto texView = createTexView(device, size, gfx::Format::B4G4R4A4_UNORM, &subData);
+ setUpAndRunTest(device, texView, floatBufferView, "copyTexFloat4");
+ compareComputeResult(
+ device,
+ floatResults,
+ Slang::makeArray<float>(
+ 0.0f,
+ 0.0f,
+ 1.0f,
+ 1.0f,
+ 0.0f,
+ 1.0f,
+ 0.0f,
+ 1.0f,
+ 1.0f,
+ 0.0f,
+ 0.0f,
+ 1.0f,
+ 0.466666669f,
+ 0.466666669f,
+ 0.466666669f,
+ 0.466666669f));
+ }
+
+ // Ignore this test on swiftshader. Swiftshader produces different results than expected.
+ if (!Slang::String(device->getDeviceInfo().adapterName).toLower().contains("swiftshader"))
+ {
+ uint16_t texData[] = {31u, 2016u, 63488u, 31727u};
+ ITextureResource::SubresourceData subData = {(void*)texData, 4, 0};
+
+ auto texView = createTexView(device, size, gfx::Format::B5G6R5_UNORM, &subData);
+ setUpAndRunTest(device, texView, floatBufferView, "copyTexFloat3");
+ compareComputeResult(
+ device,
+ floatResults,
+ Slang::makeArray<float>(
+ 0.0f,
+ 0.0f,
+ 1.0f,
+ 0.0f,
+ 1.0f,
+ 0.0f,
+ 1.0f,
+ 0.0f,
+ 0.0f,
+ 0.482352942f,
+ 0.490196079f,
+ 0.482352942f));
+
+ texView = createTexView(device, size, gfx::Format::B5G5R5A1_UNORM, &subData);
+ setUpAndRunTest(device, texView, floatBufferView, "copyTexFloat4");
+ compareComputeResult(
+ device,
+ floatResults,
+ Slang::makeArray<float>(
+ 0.0f,
+ 0.0f,
+ 1.0f,
+ 0.0f,
+ 0.0313725509f,
+ 1.0f,
+ 0.0f,
+ 0.0f,
+ 0.968627453f,
+ 0.0f,
+ 0.0f,
+ 1.0f,
+ 0.968627453f,
+ 1.0f,
+ 0.482352942f,
+ 0.0f));
+ }
+
+ {
+ uint32_t texData[] = {2950951416u, 2013265920u, 3086219772u, 3087007228u};
+ ITextureResource::SubresourceData subData = {(void*)texData, 8, 0};
+
+ auto texView = createTexView(device, size, gfx::Format::R9G9B9E5_SHAREDEXP, &subData);
+ setUpAndRunTest(device, texView, floatBufferView, "copyTexFloat3");
+ compareComputeResult(
+ device,
+ floatResults,
+ Slang::makeArray<float>(
+ 63.0f,
+ 63.0f,
+ 63.0f,
+ 0.0f,
+ 0.0f,
+ 0.0f,
+ 127.0f,
+ 127.0f,
+ 127.0f,
+ 127.0f,
+ 127.5f,
+ 127.75f));
+ }
+
+ // Ignore this test on swiftshader. Swiftshader produces different results than expected.
+ if (!Slang::String(device->getDeviceInfo().adapterName).toLower().contains("swiftshader"))
+ {
+ uint32_t texData[] = {4294967295u, 0u, 2683829759u, 1193046471u};
+ ITextureResource::SubresourceData subData = {(void*)texData, 8, 0};
+
+ auto texView = createTexView(device, size, gfx::Format::R10G10B10A2_TYPELESS, &subData);
+ setUpAndRunTest(device, texView, uintBufferView, "copyTexUint4");
+ compareComputeResult(
+ device,
+ uintResults,
+ Slang::makeArray<uint32_t>(
+ 1023u,
+ 1023u,
+ 1023u,
+ 3u,
+ 0u,
+ 0u,
+ 0u,
+ 0u,
+ 511u,
+ 511u,
+ 511u,
+ 2u,
+ 455u,
+ 796u,
+ 113u,
+ 1u));
+
+ texView = createTexView(device, size, gfx::Format::R10G10B10A2_UNORM, &subData);
+ setUpAndRunTest(device, texView, floatBufferView, "copyTexFloat4");
+ compareComputeResult(
+ device,
+ floatResults,
+ Slang::makeArray<float>(
+ 1.0f,
+ 1.0f,
+ 1.0f,
+ 1.0f,
+ 0.0f,
+ 0.0f,
+ 0.0f,
+ 0.0f,
+ 0.499511242f,
+ 0.499511242f,
+ 0.499511242f,
+ 0.666666687f,
+ 0.444770277f,
+ 0.778103590f,
+ 0.110459432f,
+ 0.333333343f));
+
+ texView = createTexView(device, size, gfx::Format::R10G10B10A2_UINT, &subData);
+ setUpAndRunTest(device, texView, uintBufferView, "copyTexUint4");
+ compareComputeResult(
+ device,
+ uintResults,
+ Slang::makeArray<uint32_t>(
+ 1023u,
+ 1023u,
+ 1023u,
+ 3u,
+ 0u,
+ 0u,
+ 0u,
+ 0u,
+ 511u,
+ 511u,
+ 511u,
+ 2u,
+ 455u,
+ 796u,
+ 113u,
+ 1u));
+ }
+
+ {
+ uint32_t texData[] = {3085827519u, 0u, 2951478655u, 1880884096u};
+ ITextureResource::SubresourceData subData = {(void*)texData, 8, 0};
+
+ auto texView = createTexView(device, size, gfx::Format::R11G11B10_FLOAT, &subData);
+ setUpAndRunTest(device, texView, floatBufferView, "copyTexFloat3");
+ compareComputeResult(
+ device,
+ floatResults,
+ Slang::makeArray<float>(
+ 254.0f,
+ 254.0f,
+ 252.0f,
+ 0.0f,
+ 0.0f,
+ 0.0f,
+ 127.0f,
+ 127.0f,
+ 126.0f,
+ 0.5f,
+ 0.5f,
+ 0.5f));
+ }
+
+ // These BC1 tests also check that mipmaps are working correctly for compressed formats.
+ // Ignore this test on swiftshader. Swiftshader produces different results than expected.
+ if (!Slang::String(device->getDeviceInfo().adapterName).toLower().contains("swiftshader"))
+ {
+ uint8_t texData[] = {16u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 16u, 0u, 0u, 0u, 0u, 0u,
+ 0u, 0u, 16u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 16u, 0u, 0u, 0u,
+ 0u, 0u, 0u, 0u, 255u, 255u, 255u, 255u, 0u, 0u, 0u, 0u};
+ ITextureResource::SubresourceData subData[] = {
+ ITextureResource::SubresourceData{(void*)texData, 16, 32},
+ ITextureResource::SubresourceData{(void*)(texData + 32), 8, 0}};
ITextureResource::Extents size = {};
- size.width = 2;
- size.height = 2;
+ size.width = 8;
+ size.height = 8;
size.depth = 1;
- ITextureResource::Extents bcSize = {};
- bcSize.width = 4;
- bcSize.height = 4;
- bcSize.depth = 1;
-
- // Note: D32_FLOAT and D16_UNORM are not directly tested as they are only used for raster. These
- // are the same as R32_FLOAT and R16_UNORM, respectively, when passed to a shader.
- {
- float texData[] = { 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f,
- 0.0f, 0.0f, 1.0f, 1.0f, 0.5f, 0.5f, 0.5f, 1.0f };
- ITextureResource::SubresourceData subData = { (void*)texData, 32, 0 };
-
- auto texView = createTexView(device, size, gfx::Format::R32G32B32A32_FLOAT, &subData);
- setUpAndRunTest(device, texView, floatBufferView, "copyTexFloat4");
- compareComputeResult(
- device,
- floatResults,
- Slang::makeArray<float>(1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f,
- 0.0f, 0.0f, 1.0f, 1.0f, 0.5f, 0.5f, 0.5f, 1.0f));
-
- texView = createTexView(device, size, gfx::Format::R32G32B32A32_TYPELESS, &subData);
- setUpAndRunTest(device, texView, floatBufferView, "copyTexFloat4");
- compareComputeResult(
- device,
- floatResults,
- Slang::makeArray<float>(1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f,
- 0.0f, 0.0f, 1.0f, 1.0f, 0.5f, 0.5f, 0.5f, 1.0f));
- }
-
- // Ignore this test since it is not supported by swiftshader and nvidia's driver.
- if (false)
- {
- float texData[] = { 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f,
- 0.0f, 0.0f, 1.0f, 0.5f, 0.5f, 0.5f };
- ITextureResource::SubresourceData subData = { (void*)texData, 24, 0 };
-
- auto texView = createTexView(device, size, gfx::Format::R32G32B32_FLOAT, &subData);
- setUpAndRunTest(device, texView, floatBufferView, "copyTexFloat3");
- compareComputeResult(
- device,
- floatResults,
- Slang::makeArray<float>(1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f,
- 0.0f, 0.0f, 1.0f, 0.5f, 0.5f, 0.5f));
-
- texView = createTexView(device, size, gfx::Format::R32G32B32_TYPELESS, &subData);
- setUpAndRunTest(device, texView, floatBufferView, "copyTexFloat3");
- compareComputeResult(
- device,
- floatResults,
- Slang::makeArray<float>(1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f,
- 0.0f, 0.0f, 1.0f, 0.5f, 0.5f, 0.5f));
- }
-
- {
- float texData[] = { 1.0f, 0.0f, 0.0f, 1.0f,
- 1.0f, 1.0f, 0.5f, 0.5f };
- ITextureResource::SubresourceData subData = { (void*)texData, 16, 0 };
-
- auto texView = createTexView(device, size, gfx::Format::R32G32_FLOAT, &subData);
- setUpAndRunTest(device, texView, floatBufferView, "copyTexFloat2");
- compareComputeResult(
- device,
- floatResults,
- Slang::makeArray<float>(1.0f, 0.0f, 0.0f, 1.0f,
- 1.0f, 1.0f, 0.5f, 0.5f));
-
- texView = createTexView(device, size, gfx::Format::R32G32_TYPELESS, &subData);
- setUpAndRunTest(device, texView, floatBufferView, "copyTexFloat2");
- compareComputeResult(
- device,
- floatResults,
- Slang::makeArray<float>(1.0f, 0.0f, 0.0f, 1.0f,
- 1.0f, 1.0f, 0.5f, 0.5f));
- }
-
- {
- float texData[] = { 1.0f, 0.0f, 0.5f, 0.25f };
- ITextureResource::SubresourceData subData = { (void*)texData, 8, 0 };
-
- auto texView = createTexView(device, size, gfx::Format::R32_FLOAT, &subData);
- setUpAndRunTest(device, texView, floatBufferView, "copyTexFloat");
- compareComputeResult(
- device,
- floatResults,
- Slang::makeArray<float>(1.0f, 0.0f, 0.5f, 0.25f));
-
- texView = createTexView(device, size, gfx::Format::R32_TYPELESS, &subData);
- setUpAndRunTest(device, texView, floatBufferView, "copyTexFloat");
- compareComputeResult(
- device,
- floatResults,
- Slang::makeArray<float>(1.0f, 0.0f, 0.5f, 0.25f));
- }
-
- {
- uint16_t texData[] = { 15360u, 0u, 0u, 15360u, 0u, 15360u, 0u, 15360u,
- 0u, 0u, 15360u, 15360u, 14336u, 14336u, 14336u, 15360u };
- ITextureResource::SubresourceData subData = { (void*)texData, 16, 0 };
-
- auto texView = createTexView(device, size, gfx::Format::R16G16B16A16_FLOAT, &subData);
- setUpAndRunTest(device, texView, floatBufferView, "copyTexFloat4");
- compareComputeResult(
- device,
- floatResults,
- Slang::makeArray<float>(1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f,
- 0.0f, 0.0f, 1.0f, 1.0f, 0.5f, 0.5f, 0.5f, 1.0f));
-
- texView = createTexView(device, size, gfx::Format::R16G16B16A16_TYPELESS, &subData);
- setUpAndRunTest(device, texView, floatBufferView, "copyTexFloat4");
- compareComputeResult(
- device,
- floatResults,
- Slang::makeArray<float>(1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f,
- 0.0f, 0.0f, 1.0f, 1.0f, 0.5f, 0.5f, 0.5f, 1.0f));
- }
-
- {
- uint16_t texData[] = { 15360u, 0u, 0u, 15360u,
- 15360u, 15360u, 14336u, 14336u };
- ITextureResource::SubresourceData subData = { (void*)texData, 8, 0 };
-
- auto texView = createTexView(device, size, gfx::Format::R16G16_FLOAT, &subData);
- setUpAndRunTest(device, texView, floatBufferView, "copyTexFloat2");
- compareComputeResult(
- device,
- floatResults,
- Slang::makeArray<float>(1.0f, 0.0f, 0.0f, 1.0f,
- 1.0f, 1.0f, 0.5f, 0.5f));
-
- texView = createTexView(device, size, gfx::Format::R16G16_TYPELESS, &subData);
- setUpAndRunTest(device, texView, floatBufferView, "copyTexFloat2");
- compareComputeResult(
- device,
- floatResults,
- Slang::makeArray<float>(1.0f, 0.0f, 0.0f, 1.0f,
- 1.0f, 1.0f, 0.5f, 0.5f));
- }
-
- {
- uint16_t texData[] = { 15360u, 0u, 14336u, 13312u };
- ITextureResource::SubresourceData subData = { (void*)texData, 4, 0 };
-
- auto texView = createTexView(device, size, gfx::Format::R16_FLOAT, &subData);
- setUpAndRunTest(device, texView, floatBufferView, "copyTexFloat");
- compareComputeResult(
- device,
- floatResults,
- Slang::makeArray<float>(1.0f, 0.0f, 0.5f, 0.25f));
-
- texView = createTexView(device, size, gfx::Format::R16_TYPELESS, &subData);
- setUpAndRunTest(device, texView, floatBufferView, "copyTexFloat");
- compareComputeResult(
- device,
- floatResults,
- Slang::makeArray<float>(1.0f, 0.0f, 0.5f, 0.25f));
- }
-
- {
- uint32_t texData[] = { 255u, 0u, 0u, 255u, 0u, 255u, 0u, 255u,
- 0u, 0u, 255u, 255u, 127u, 127u, 127u, 255u };
- ITextureResource::SubresourceData subData = { (void*)texData, 32, 0 };
-
- auto texView = createTexView(device, size, gfx::Format::R32G32B32A32_UINT, &subData);
- setUpAndRunTest(device, texView, uintBufferView, "copyTexUint4");
- compareComputeResult(
- device,
- uintResults,
- Slang::makeArray<uint32_t>(255u, 0u, 0u, 255u, 0u, 255u, 0u, 255u,
- 0u, 0u, 255u, 255u, 127u, 127u, 127u, 255u));
- }
-
- // Ignore this test since validation layer reports that it is unsupported.
- if (false)
- {
- uint32_t texData[] = { 255u, 0u, 0u, 0u, 255u, 0u,
- 0u, 0u, 255u, 127u, 127u, 127u };
- ITextureResource::SubresourceData subData = { (void*)texData, 24, 0 };
-
- auto texView = createTexView(device, size, gfx::Format::R32G32B32_UINT, &subData);
- setUpAndRunTest(device, texView, uintBufferView, "copyTexUint3");
- compareComputeResult(
- device,
- uintResults,
- Slang::makeArray<uint32_t>(255u, 0u, 0u, 0u, 255u, 0u,
- 0u, 0u, 255u, 127u, 127u, 127u));
- }
-
- {
- uint32_t texData[] = { 255u, 0u, 0u, 255u,
- 255u, 255u, 127u, 127u };
- ITextureResource::SubresourceData subData = { (void*)texData, 16, 0 };
-
- auto texView = createTexView(device, size, gfx::Format::R32G32_UINT, &subData);
- setUpAndRunTest(device, texView, uintBufferView, "copyTexUint2");
- compareComputeResult(
- device,
- uintResults,
- Slang::makeArray<uint32_t>(255u, 0u, 0u, 255u,
- 255u, 255u, 127u, 127u));
- }
-
- {
- uint32_t texData[] = { 255u, 0u, 127u, 73u };
- ITextureResource::SubresourceData subData = { (void*)texData, 8, 0 };
-
- auto texView = createTexView(device, size, gfx::Format::R32_UINT, &subData);
- setUpAndRunTest(device, texView, uintBufferView, "copyTexUint");
- compareComputeResult(
- device,
- uintResults,
- Slang::makeArray<uint32_t>(255u, 0u, 127u, 73u));
- }
-
- {
- uint16_t texData[] = { 255u, 0u, 0u, 255u, 0u, 255u, 0u, 255u,
- 0u, 0u, 255u, 255u, 127u, 127u, 127u, 255u };
- ITextureResource::SubresourceData subData = { (void*)texData, 16, 0 };
-
- auto texView = createTexView(device, size, gfx::Format::R16G16B16A16_UINT, &subData);
- setUpAndRunTest(device, texView, uintBufferView, "copyTexUint4");
- compareComputeResult(
- device,
- uintResults,
- Slang::makeArray<uint32_t>(255u, 0u, 0u, 255u, 0u, 255u, 0u, 255u,
- 0u, 0u, 255u, 255u, 127u, 127u, 127u, 255u));
- }
-
- {
- uint16_t texData[] = { 255u, 0u, 0u, 255u,
- 255u, 255u, 127u, 127u };
- ITextureResource::SubresourceData subData = { (void*)texData, 8, 0 };
-
- auto texView = createTexView(device, size, gfx::Format::R16G16_UINT, &subData);
- setUpAndRunTest(device, texView, uintBufferView, "copyTexUint2");
- compareComputeResult(
- device,
- uintResults,
- Slang::makeArray<uint32_t>(255u, 0u, 0u, 255u,
- 255u, 255u, 127u, 127u));
- }
-
- {
- uint16_t texData[] = { 255u, 0u, 127u, 73u };
- ITextureResource::SubresourceData subData = { (void*)texData, 4, 0 };
-
- auto texView = createTexView(device, size, gfx::Format::R16_UINT, &subData);
- setUpAndRunTest(device, texView, uintBufferView, "copyTexUint");
- compareComputeResult(
- device,
- uintResults,
- Slang::makeArray<uint32_t>(255u, 0u, 127u, 73u));
- }
-
- {
- uint8_t texData[] = { 255u, 0u, 0u, 255u, 0u, 255u, 0u, 255u,
- 0u, 0u, 255u, 255u, 127u, 127u, 127u, 255u };
- ITextureResource::SubresourceData subData = { (void*)texData, 8, 0 };
-
- auto texView = createTexView(device, size, gfx::Format::R8G8B8A8_UINT, &subData);
- setUpAndRunTest(device, texView, uintBufferView, "copyTexUint4");
- compareComputeResult(
- device,
- uintResults,
- Slang::makeArray<uint32_t>(255u, 0u, 0u, 255u, 0u, 255u, 0u, 255u,
- 0u, 0u, 255u, 255u, 127u, 127u, 127u, 255u));
- }
-
- {
- uint8_t texData[] = { 255u, 0u, 0u, 255u,
- 255u, 255u, 127u, 127u };
- ITextureResource::SubresourceData subData = { (void*)texData, 4, 0 };
-
- auto texView = createTexView(device, size, gfx::Format::R8G8_UINT, &subData);
- setUpAndRunTest(device, texView, uintBufferView, "copyTexUint2");
- compareComputeResult(
- device,
- uintResults,
- Slang::makeArray<uint32_t>(255u, 0u, 0u, 255u,
- 255u, 255u, 127u, 127u));
- }
-
- {
- uint8_t texData[] = { 255u, 0u, 127u, 73u };
- ITextureResource::SubresourceData subData = { (void*)texData, 2, 0 };
-
- auto texView = createTexView(device, size, gfx::Format::R8_UINT, &subData);
- setUpAndRunTest(device, texView, uintBufferView, "copyTexUint");
- compareComputeResult(
- device,
- uintResults,
- Slang::makeArray<uint32_t>(255u, 0u, 127u, 73u));
- }
-
- {
- int32_t texData[] = { 255, 0, 0, 255, 0, 255, 0, 255,
- 0, 0, 255, 255, 127, 127, 127, 255 };
- ITextureResource::SubresourceData subData = { (void*)texData, 32, 0 };
-
- auto texView = createTexView(device, size, gfx::Format::R32G32B32A32_SINT, &subData);
- setUpAndRunTest(device, texView, intBufferView, "copyTexInt4");
- compareComputeResult(
- device,
- intResults,
- Slang::makeArray<int32_t>(255, 0, 0, 255, 0, 255, 0, 255,
- 0, 0, 255, 255, 127, 127, 127, 255));
- }
-
- // Ignore this test on swiftshader. Swiftshader produces unsupported format warnings for this test.
- if (false)
- {
- int32_t texData[] = { 255, 0, 0, 0, 255, 0,
- 0, 0, 255, 127, 127, 127 };
- ITextureResource::SubresourceData subData = { (void*)texData, 24, 0 };
-
- auto texView = createTexView(device, size, gfx::Format::R32G32B32_SINT, &subData);
- setUpAndRunTest(device, texView, intBufferView, "copyTexInt3");
- compareComputeResult(
- device,
- intResults,
- Slang::makeArray<int32_t>(255, 0, 0, 0, 255, 0,
- 0, 0, 255, 127, 127, 127));
- }
-
- {
- int32_t texData[] = { 255, 0, 0, 255,
- 255, 255, 127, 127 };
- ITextureResource::SubresourceData subData = { (void*)texData, 16, 0 };
-
- auto texView = createTexView(device, size, gfx::Format::R32G32_SINT, &subData);
- setUpAndRunTest(device, texView, intBufferView, "copyTexInt2");
- compareComputeResult(
- device,
- intResults,
- Slang::makeArray<int32_t>(255, 0, 0, 255,
- 255, 255, 127, 127));
- }
-
- {
- int32_t texData[] = { 255, 0, 127, 73 };
- ITextureResource::SubresourceData subData = { (void*)texData, 8, 0 };
-
- auto texView = createTexView(device, size, gfx::Format::R32_SINT, &subData);
- setUpAndRunTest(device, texView, intBufferView, "copyTexInt");
- compareComputeResult(
- device,
- intResults,
- Slang::makeArray<int32_t>(255, 0, 127, 73));
- }
-
- {
- int16_t texData[] = { 255, 0, 0, 255, 0, 255, 0, 255,
- 0, 0, 255, 255, 127, 127, 127, 255 };
- ITextureResource::SubresourceData subData = { (void*)texData, 16, 0 };
-
- auto texView = createTexView(device, size, gfx::Format::R16G16B16A16_SINT, &subData);
- setUpAndRunTest(device, texView, intBufferView, "copyTexInt4");
- compareComputeResult(
- device,
- intResults,
- Slang::makeArray<int32_t>(255, 0, 0, 255, 0, 255, 0, 255,
- 0, 0, 255, 255, 127, 127, 127, 255));
- }
-
- {
- int16_t texData[] = { 255, 0, 0, 255,
- 255, 255, 127, 127 };
- ITextureResource::SubresourceData subData = { (void*)texData, 8, 0 };
-
- auto texView = createTexView(device, size, gfx::Format::R16G16_SINT, &subData);
- setUpAndRunTest(device, texView, intBufferView, "copyTexInt2");
- compareComputeResult(
- device,
- intResults,
- Slang::makeArray<int32_t>(255, 0, 0, 255,
- 255, 255, 127, 127));
- }
-
- {
- int16_t texData[] = { 255, 0, 127, 73 };
- ITextureResource::SubresourceData subData = { (void*)texData, 4, 0 };
-
- auto texView = createTexView(device, size, gfx::Format::R16_SINT, &subData);
- setUpAndRunTest(device, texView, intBufferView, "copyTexInt");
- compareComputeResult(
- device,
- intResults,
- Slang::makeArray<int32_t>(255, 0, 127, 73));
- }
-
- {
- int8_t texData[] = { 127, 0, 0, 127, 0, 127, 0, 127,
- 0, 0, 127, 127, 0, 0, 0, 127 };
- ITextureResource::SubresourceData subData = { (void*)texData, 8, 0 };
-
- auto texView = createTexView(device, size, gfx::Format::R8G8B8A8_SINT, &subData);
- setUpAndRunTest(device, texView, intBufferView, "copyTexInt4");
- compareComputeResult(
- device,
- intResults,
- Slang::makeArray<int32_t>(127, 0, 0, 127, 0, 127, 0, 127,
- 0, 0, 127, 127, 0, 0, 0, 127));
- }
-
- {
- int8_t texData[] = { 127, 0, 0, 127,
- 127, 127, 73, 73 };
- ITextureResource::SubresourceData subData = { (void*)texData, 4, 0 };
-
- auto texView = createTexView(device, size, gfx::Format::R8G8_SINT, &subData);
- setUpAndRunTest(device, texView, intBufferView, "copyTexInt2");
- compareComputeResult(
- device,
- intResults,
- Slang::makeArray<int32_t>(127, 0, 0, 127,
- 127, 127, 73, 73));
- }
-
- {
- int8_t texData[] = { 127, 0, 73, 25 };
- ITextureResource::SubresourceData subData = { (void*)texData, 2, 0 };
-
- auto texView = createTexView(device, size, gfx::Format::R8_SINT, &subData);
- setUpAndRunTest(device, texView, intBufferView, "copyTexInt");
- compareComputeResult(
- device,
- intResults,
- Slang::makeArray<int32_t>(127, 0, 73, 25));
- }
-
- {
- uint16_t texData[] = { 65535u, 0u, 0u, 65535u, 0u, 65535u, 0u, 65535u,
- 0u, 0u, 65535u, 65535u, 32767u, 32767u, 32767u, 32767u };
- ITextureResource::SubresourceData subData = { (void*)texData, 16, 0 };
-
- auto texView = createTexView(device, size, gfx::Format::R16G16B16A16_UNORM, &subData);
- setUpAndRunTest(device, texView, floatBufferView, "copyTexFloat4");
- compareComputeResult(
- device,
- floatResults,
- Slang::makeArray<float>(1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f,
- 0.0f, 0.0f, 1.0f, 1.0f, 0.499992371f, 0.499992371f, 0.499992371f, 0.499992371f));
- }
-
- {
- uint16_t texData[] = { 65535u, 0u, 0u, 65535u,
- 65535u, 65535u, 32767u, 32767u };
- ITextureResource::SubresourceData subData = { (void*)texData, 8, 0 };
-
- auto texView = createTexView(device, size, gfx::Format::R16G16_UNORM, &subData);
- setUpAndRunTest(device, texView, floatBufferView, "copyTexFloat2");
- compareComputeResult(
- device,
- floatResults,
- Slang::makeArray<float>(1.0f, 0.0f, 0.0f, 1.0f,
- 1.0f, 1.0f, 0.499992371f, 0.499992371f));
- }
-
- {
- uint16_t texData[] = { 65535u, 0u, 32767u, 16383u };
- ITextureResource::SubresourceData subData = { (void*)texData, 4, 0 };
-
- auto texView = createTexView(device, size, gfx::Format::R16_UNORM, &subData);
- setUpAndRunTest(device, texView, floatBufferView, "copyTexFloat");
- compareComputeResult(
- device,
- floatResults,
- Slang::makeArray<float>(1.0f, 0.0f, 0.499992371f, 0.249988556f));
- }
-
- // Ignore this test on swiftshader. Swiftshader produces different results than expected.
- if (!Slang::String(device->getDeviceInfo().adapterName).toLower().contains("swiftshader"))
- {
- uint8_t texData[] = { 0u, 0u, 0u, 255u, 127u, 127u, 127u, 255u,
- 255u, 255u, 255u, 255u, 0u, 0u, 0u, 0u };
- ITextureResource::SubresourceData subData = { (void*)texData, 8, 0};
-
- auto texView = createTexView(device, size, gfx::Format::R8G8B8A8_TYPELESS, &subData);
- setUpAndRunTest(device, texView, floatBufferView, "copyTexFloat4");
- compareComputeResult(
- device,
- floatResults,
- Slang::makeArray<float>(0.0f, 0.0f, 0.0f, 1.0f, 0.498039216f, 0.498039216f, 0.498039216f, 1.0f,
- 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f));
-
- texView = createTexView(device, size, gfx::Format::R8G8B8A8_UNORM, &subData);
- setUpAndRunTest(device, texView, floatBufferView, "copyTexFloat4");
- compareComputeResult(
- device,
- floatResults,
- Slang::makeArray<float>(0.0f, 0.0f, 0.0f, 1.0f, 0.498039216f, 0.498039216f, 0.498039216f, 1.0f,
- 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f));
-
- texView = createTexView(device, size, gfx::Format::R8G8B8A8_UNORM_SRGB, &subData);
- setUpAndRunTest(device, texView, floatBufferView, "copyTexFloat4");
- compareComputeResult(
- device,
- floatResults,
- Slang::makeArray<float>(0.0f, 0.0f, 0.0f, 1.0f, 0.211914062f, 0.211914062f, 0.211914062f,
- 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f));
- }
-
- // Ignore this test on swiftshader. Swiftshader produces different results than expected.
- if (!Slang::String(device->getDeviceInfo().adapterName).toLower().contains("swiftshader"))
- {
- uint8_t texData[] = { 255u, 0u, 0u, 255u, 255u, 255u, 127u, 127u };
- ITextureResource::SubresourceData subData = { (void*)texData, 4, 0 };
-
- auto texView = createTexView(device, size, gfx::Format::R8G8_TYPELESS, &subData);
- setUpAndRunTest(device, texView, floatBufferView, "copyTexFloat2");
- compareComputeResult(
- device,
- floatResults,
- Slang::makeArray<float>(1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.498039216f, 0.498039216f));
-
- texView = createTexView(device, size, gfx::Format::R8G8_UNORM, &subData);
- setUpAndRunTest(device, texView, floatBufferView, "copyTexFloat2");
- compareComputeResult(
- device,
- floatResults,
- Slang::makeArray<float>(1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.498039216f, 0.498039216f));
- }
-
- // Ignore this test on swiftshader. Swiftshader produces different results than expected.
- if (!Slang::String(device->getDeviceInfo().adapterName).toLower().contains("swiftshader"))
- {
- uint8_t texData[] = { 255u, 0u, 127u, 63u };
- ITextureResource::SubresourceData subData = { (void*)texData, 2, 0 };
-
- auto texView = createTexView(device, size, gfx::Format::R8_TYPELESS, &subData);
- setUpAndRunTest(device, texView, floatBufferView, "copyTexFloat");
- compareComputeResult(
- device,
- floatResults,
- Slang::makeArray<float>(1.0f, 0.0f, 0.498039216f, 0.247058824f));
-
- texView = createTexView(device, size, gfx::Format::R8_UNORM, &subData);
- setUpAndRunTest(device, texView, floatBufferView, "copyTexFloat");
- compareComputeResult(
- device,
- floatResults,
- Slang::makeArray<float>(1.0f, 0.0f, 0.498039216f, 0.247058824f));
- }
-
- // Ignore this test on swiftshader. Swiftshader produces different results than expected.
- if (!Slang::String(device->getDeviceInfo().adapterName).toLower().contains("swiftshader"))
- {
- uint8_t texData[] = { 0u, 0u, 0u, 255u, 127u, 127u, 127u, 255u,
- 255u, 255u, 255u, 255u, 0u, 0u, 0u, 0u };
- ITextureResource::SubresourceData subData = { (void*)texData, 8, 0 };
-
- auto texView = createTexView(device, size, gfx::Format::B8G8R8A8_TYPELESS, &subData);
- setUpAndRunTest(device, texView, floatBufferView, "copyTexFloat4");
- compareComputeResult(
- device,
- floatResults,
- Slang::makeArray<float>(0.0f, 0.0f, 0.0f, 1.0f, 0.498039216f, 0.498039216f, 0.498039216f, 1.0f,
- 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f));
-
- texView = createTexView(device, size, gfx::Format::B8G8R8A8_UNORM, &subData);
- setUpAndRunTest(device, texView, floatBufferView, "copyTexFloat4");
- compareComputeResult(
- device,
- floatResults,
- Slang::makeArray<float>(0.0f, 0.0f, 0.0f, 1.0f, 0.498039216f, 0.498039216f, 0.498039216f, 1.0f,
- 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f));
-
- texView = createTexView(device, size, gfx::Format::B8G8R8A8_UNORM_SRGB, &subData);
- setUpAndRunTest(device, texView, floatBufferView, "copyTexFloat4");
- compareComputeResult(
- device,
- floatResults,
- Slang::makeArray<float>(0.0f, 0.0f, 0.0f, 1.0f, 0.211914062f, 0.211914062f, 0.211914062f,
- 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f));
- }
-
- {
- int16_t texData[] = { 32767, 0, 0, 32767, 0, 32767, 0, 32767,
- 0, 0, 32767, 32767, -32768, -32768, 0, 32767 };
- ITextureResource::SubresourceData subData = { (void*)texData, 16, 0 };
-
- auto texView = createTexView(device, size, gfx::Format::R16G16B16A16_SNORM, &subData);
- setUpAndRunTest(device, texView, floatBufferView, "copyTexFloat4");
- compareComputeResult(
- device,
- floatResults,
- Slang::makeArray<float>(1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f,
- 0.0f, 0.0f, 1.0f, 1.0f, -1.0f, -1.0f, 0.0f, 1.0f));
- }
-
- {
- int16_t texData[] = { 32767, 0, 0, 32767,
- 32767, 32767, -32768, -32768 };
- ITextureResource::SubresourceData subData = { (void*)texData, 8, 0 };
-
- auto texView = createTexView(device, size, gfx::Format::R16G16_SNORM, &subData);
- setUpAndRunTest(device, texView, floatBufferView, "copyTexFloat2");
- compareComputeResult(
- device,
- floatResults,
- Slang::makeArray<float>(1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, -1.0f, -1.0f));
- }
-
- {
- int16_t texData[] = { 32767, 0, -32768, 0};
- ITextureResource::SubresourceData subData = { (void*)texData, 4, 0 };
-
- auto texView = createTexView(device, size, gfx::Format::R16_SNORM, &subData);
- setUpAndRunTest(device, texView, floatBufferView, "copyTexFloat");
- compareComputeResult(
- device,
- floatResults,
- Slang::makeArray<float>(1.0f, 0.0f, -1.0f, 0.0f));
- }
-
- {
- int8_t texData[] = { 127, 0, 0, 127, 0, 127, 0, 127,
- 0, 0, 127, 127, -128, -128, 0, 127 };
- ITextureResource::SubresourceData subData = { (void*)texData, 8, 0 };
-
- auto texView = createTexView(device, size, gfx::Format::R8G8B8A8_SNORM, &subData);
- setUpAndRunTest(device, texView, floatBufferView, "copyTexFloat4");
- compareComputeResult(
- device,
- floatResults,
- Slang::makeArray<float>(1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f,
- 0.0f, 0.0f, 1.0f, 1.0f, -1.0f, -1.0f, 0.0f, 1.0f));
- }
-
- {
- int8_t texData[] = { 127, 0, 0, 127,
- 127, 127, -128, -128 };
- ITextureResource::SubresourceData subData = { (void*)texData, 4, 0 };
-
- auto texView = createTexView(device, size, gfx::Format::R8G8_SNORM, &subData);
- setUpAndRunTest(device, texView, floatBufferView, "copyTexFloat2");
- compareComputeResult(
- device,
- floatResults,
- Slang::makeArray<float>(1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, -1.0f, -1.0f));
- }
-
- {
- int8_t texData[] = { 127, 0, -128, 0 };
- ITextureResource::SubresourceData subData = { (void*)texData, 2, 0 };
-
- auto texView = createTexView(device, size, gfx::Format::R8_SNORM, &subData);
- setUpAndRunTest(device, texView, floatBufferView, "copyTexFloat");
- compareComputeResult(
- device,
- floatResults,
- Slang::makeArray<float>(1.0f, 0.0f, -1.0f, 0.0f));
- }
-
- // Ignore this test on swiftshader. Swiftshader produces unsupported format warnings for this test.
- if (!Slang::String(device->getDeviceInfo().adapterName).toLower().contains("swiftshader"))
- {
- uint8_t texData[] = { 15u, 240u, 240u, 240u, 0u, 255u, 119u, 119u };
- ITextureResource::SubresourceData subData = { (void*)texData, 4, 0 };
-
- auto texView = createTexView(device, size, gfx::Format::B4G4R4A4_UNORM, &subData);
- setUpAndRunTest(device, texView, floatBufferView, "copyTexFloat4");
- compareComputeResult(
- device,
- floatResults,
- Slang::makeArray<float>(0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f,
- 1.0f, 0.0f, 0.0f, 1.0f, 0.466666669f, 0.466666669f, 0.466666669f, 0.466666669f));
- }
-
- // Ignore this test on swiftshader. Swiftshader produces different results than expected.
- if (!Slang::String(device->getDeviceInfo().adapterName).toLower().contains("swiftshader"))
- {
- uint16_t texData[] = { 31u, 2016u, 63488u, 31727u };
- ITextureResource::SubresourceData subData = { (void*)texData, 4, 0 };
-
- auto texView = createTexView(device, size, gfx::Format::B5G6R5_UNORM, &subData);
- setUpAndRunTest(device, texView, floatBufferView, "copyTexFloat3");
- compareComputeResult(
- device,
- floatResults,
- Slang::makeArray<float>(0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f,
- 1.0f, 0.0f, 0.0f, 0.482352942f, 0.490196079f, 0.482352942f));
-
- texView = createTexView(device, size, gfx::Format::B5G5R5A1_UNORM, &subData);
- setUpAndRunTest(device, texView, floatBufferView, "copyTexFloat4");
- compareComputeResult(
- device,
- floatResults,
- Slang::makeArray<float>(0.0f, 0.0f, 1.0f, 0.0f, 0.0313725509f, 1.0f, 0.0f, 0.0f,
- 0.968627453f, 0.0f, 0.0f, 1.0f, 0.968627453f, 1.0f, 0.482352942f, 0.0f));
- }
-
- {
- uint32_t texData[] = { 2950951416u, 2013265920u, 3086219772u, 3087007228u };
- ITextureResource::SubresourceData subData = { (void*)texData, 8, 0 };
-
- auto texView = createTexView(device, size, gfx::Format::R9G9B9E5_SHAREDEXP, &subData);
- setUpAndRunTest(device, texView, floatBufferView, "copyTexFloat3");
- compareComputeResult(
- device,
- floatResults,
- Slang::makeArray<float>(63.0f, 63.0f, 63.0f, 0.0f, 0.0f, 0.0f,
- 127.0f, 127.0f, 127.0f, 127.0f, 127.5f, 127.75f));
- }
-
- // Ignore this test on swiftshader. Swiftshader produces different results than expected.
- if (!Slang::String(device->getDeviceInfo().adapterName).toLower().contains("swiftshader"))
- {
- uint32_t texData[] = { 4294967295u, 0u, 2683829759u, 1193046471u };
- ITextureResource::SubresourceData subData = { (void*)texData, 8, 0 };
-
- auto texView = createTexView(device, size, gfx::Format::R10G10B10A2_TYPELESS, &subData);
- setUpAndRunTest(device, texView, uintBufferView, "copyTexUint4");
- compareComputeResult(
- device,
- uintResults,
- Slang::makeArray<uint32_t>(1023u, 1023u, 1023u, 3u, 0u, 0u, 0u, 0u,
- 511u, 511u, 511u, 2u, 455u, 796u, 113u, 1u));
-
- texView = createTexView(device, size, gfx::Format::R10G10B10A2_UNORM, &subData);
- setUpAndRunTest(device, texView, floatBufferView, "copyTexFloat4");
- compareComputeResult(
- device,
- floatResults,
- Slang::makeArray<float>(1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f,
- 0.499511242f, 0.499511242f, 0.499511242f, 0.666666687f,
- 0.444770277f, 0.778103590f, 0.110459432f, 0.333333343f));
-
- texView = createTexView(device, size, gfx::Format::R10G10B10A2_UINT, &subData);
- setUpAndRunTest(device, texView, uintBufferView, "copyTexUint4");
- compareComputeResult(
- device,
- uintResults,
- Slang::makeArray<uint32_t>(1023u, 1023u, 1023u, 3u, 0u, 0u, 0u, 0u,
- 511u, 511u, 511u, 2u, 455u, 796u, 113u, 1u));
- }
-
- {
- uint32_t texData[] = { 3085827519u, 0u, 2951478655u, 1880884096u };
- ITextureResource::SubresourceData subData = { (void*)texData, 8, 0 };
-
- auto texView = createTexView(device, size, gfx::Format::R11G11B10_FLOAT, &subData);
- setUpAndRunTest(device, texView, floatBufferView, "copyTexFloat3");
- compareComputeResult(
- device,
- floatResults,
- Slang::makeArray<float>(254.0f, 254.0f, 252.0f, 0.0f, 0.0f, 0.0f, 127.0f, 127.0f, 126.0f, 0.5f, 0.5f, 0.5f));
- }
-
- // These BC1 tests also check that mipmaps are working correctly for compressed formats.
- // Ignore this test on swiftshader. Swiftshader produces different results than expected.
- if (!Slang::String(device->getDeviceInfo().adapterName).toLower().contains("swiftshader"))
- {
- uint8_t texData[] = { 16u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 16u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
- 16u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 16u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
- 255u, 255u, 255u, 255u, 0u, 0u, 0u, 0u };
- ITextureResource::SubresourceData subData[] = {
- ITextureResource::SubresourceData {(void*)texData, 16, 32},
- ITextureResource::SubresourceData {(void*)(texData + 32), 8, 0}
- };
- ITextureResource::Extents size = {};
- size.width = 8;
- size.height = 8;
- size.depth = 1;
-
- auto texView = createTexView(device, size, gfx::Format::BC1_UNORM, subData, 2);
- setUpAndRunTest(device, texView, floatBufferView, "sampleMips", sampler);
- compareComputeResult(
- device,
- floatResults,
- Slang::makeArray<float>(0.0f, 0.0f, 0.517647088f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f));
-
- texView = createTexView(device, size, gfx::Format::BC1_UNORM_SRGB, subData, 2);
- setUpAndRunTest(device, texView, floatBufferView, "sampleMips", sampler);
- compareComputeResult(
- device,
- floatResults,
- Slang::makeArray<float>(0.0f, 0.0f, 0.230468750f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f));
- }
-
- // Ignore this test on swiftshader. Swiftshader produces different results than expected.
- if (!Slang::String(device->getDeviceInfo().adapterName).toLower().contains("swiftshader"))
- {
- uint8_t texData[] = { 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u,
- 16u, 0u, 0u, 0u, 0u, 0u, 0u, 0u };
- ITextureResource::SubresourceData subData = { (void*)texData, 16, 0 };
-
- auto texView = createTexView(device, bcSize, gfx::Format::BC2_UNORM, &subData);
- setUpAndRunTest(device, texView, floatBufferView, "sampleTex", sampler);
- compareComputeResult(
- device,
- floatResults,
- Slang::makeArray<float>(0.0f, 0.0f, 0.517647088f, 1.0f));
-
- texView = createTexView(device, bcSize, gfx::Format::BC2_UNORM_SRGB, &subData);
- setUpAndRunTest(device, texView, floatBufferView, "sampleTex", sampler);
- compareComputeResult(
- device,
- floatResults,
- Slang::makeArray<float>(0.0f, 0.0f, 0.230468750f, 1.0f));
- }
-
- // Ignore this test on swiftshader. Swiftshader produces different results than expected.
- if (!Slang::String(device->getDeviceInfo().adapterName).toLower().contains("swiftshader"))
- {
- uint8_t texData[] = { 0u, 255u, 255u, 255u, 255u, 255u, 255u, 255u,
- 16u, 0u, 0u, 0u, 0u, 0u, 0u, 0u };
- ITextureResource::SubresourceData subData = { (void*)texData, 16, 0 };
-
- auto texView = createTexView(device, bcSize, gfx::Format::BC3_UNORM, &subData);
- setUpAndRunTest(device, texView, floatBufferView, "sampleTex", sampler);
- compareComputeResult(
- device,
- floatResults,
- Slang::makeArray<float>(0.0f, 0.0f, 0.517647088f, 1.0f));
-
- texView = createTexView(device, bcSize, gfx::Format::BC3_UNORM_SRGB, &subData);
- setUpAndRunTest(device, texView, floatBufferView, "sampleTex", sampler);
- compareComputeResult(
- device,
- floatResults,
- Slang::makeArray<float>(0.0f, 0.0f, 0.230468750f, 1.0f));
- }
-
- // Ignore this test on swiftshader. Swiftshader produces different results than expected.
- if (!Slang::String(device->getDeviceInfo().adapterName).toLower().contains("swiftshader"))
- {
- uint8_t texData[] = { 127u, 0u, 0u, 0u, 0u, 0u, 0u, 0u };
- ITextureResource::SubresourceData subData = { (void*)texData, 8, 0 };
-
- auto texView = createTexView(device, bcSize, gfx::Format::BC4_UNORM, &subData);
- setUpAndRunTest(device, texView, floatBufferView, "sampleTex", sampler);
- compareComputeResult(
- device,
- floatResults,
- Slang::makeArray<float>(0.498039216f, 0.0f, 0.0f, 1.0f));
-
- texView = createTexView(device, bcSize, gfx::Format::BC4_SNORM, &subData);
- setUpAndRunTest(device, texView, floatBufferView, "sampleTex", sampler);
- compareComputeResult(
- device,
- floatResults,
- Slang::makeArray<float>(1.0f, 0.0f, 0.0f, 1.0f));
- }
-
- // Ignore this test on swiftshader. Swiftshader produces different results than expected.
- if (!Slang::String(device->getDeviceInfo().adapterName).toLower().contains("swiftshader"))
- {
- uint8_t texData[] = { 127u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 127u, 0u, 0u, 0u, 0u, 0u, 0u, 0u };
- ITextureResource::SubresourceData subData = { (void*)texData, 16, 0 };
-
- auto texView = createTexView(device, bcSize, gfx::Format::BC5_UNORM, &subData);
- setUpAndRunTest(device, texView, floatBufferView, "sampleTex", sampler);
- compareComputeResult(
- device,
- floatResults,
- Slang::makeArray<float>(0.498039216f, 0.498039216f, 0.0f, 1.0f, 0.498039216f, 0.498039216f, 0.0f, 1.0f));
-
- texView = createTexView(device, bcSize, gfx::Format::BC5_SNORM, &subData);
- setUpAndRunTest(device, texView, floatBufferView, "sampleTex", sampler);
- compareComputeResult(
- device,
- floatResults,
- Slang::makeArray<float>(1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f));
- }
-
- // BC6H_UF16 and BC6H_SF16 are tested separately due to requiring different texture data.
- // Ignore this test on swiftshader. Swiftshader produces different results than expected.
- if (!Slang::String(device->getDeviceInfo().adapterName).toLower().contains("swiftshader"))
- {
- uint8_t texData[] = { 98u, 238u, 232u, 77u, 240u, 66u, 148u, 31u,
- 124u, 95u, 2u, 224u, 255u, 107u, 77u, 250u };
- ITextureResource::SubresourceData subData = { (void*)texData, 16, 0 };
-
- auto texView = createTexView(device, bcSize, gfx::Format::BC6H_UF16, &subData);
- setUpAndRunTest(device, texView, floatBufferView, "sampleTex", sampler);
- compareComputeResult(
- device,
- floatResults,
- Slang::makeArray<float>(0.336669922f, 0.911132812f, 2.13867188f, 1.0f));
- }
-
- // Ignore this test on swiftshader. Swiftshader produces different results than expected.
- if (!Slang::String(device->getDeviceInfo().adapterName).toLower().contains("swiftshader"))
- {
- uint8_t texData[] = { 107u, 238u, 232u, 77u, 240u, 71u, 128u, 127u,
- 1u, 0u, 255u, 255u, 170u, 218u, 221u, 254u };
- ITextureResource::SubresourceData subData = { (void*)texData, 16, 0 };
-
- auto texView = createTexView(device, bcSize, gfx::Format::BC6H_SF16, &subData);
- setUpAndRunTest(device, texView, floatBufferView, "sampleTex", sampler);
- compareComputeResult(
- device,
- floatResults,
- Slang::makeArray<float>(0.336914062f, 0.910644531f, 2.14062500f, 1.0f));
- }
-
- // Ignore this test on swiftshader. Swiftshader produces different results than expected.
- if (!Slang::String(device->getDeviceInfo().adapterName).toLower().contains("swiftshader"))
- {
- uint8_t texData[] = { 104u, 0u, 0u, 0u, 64u, 163u, 209u, 104u,
- 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u };
- ITextureResource::SubresourceData subData = { (void*)texData, 16, 0 };
-
- auto texView = createTexView(device, bcSize, gfx::Format::BC7_UNORM, &subData);
- setUpAndRunTest(device, texView, floatBufferView, "sampleTex", sampler);
- compareComputeResult(
- device,
- floatResults,
- Slang::makeArray<float>(0.0f, 0.101960786f, 0.0f, 1.0f));
-
- texView = createTexView(device, bcSize, gfx::Format::BC7_UNORM_SRGB, &subData);
- setUpAndRunTest(device, texView, floatBufferView, "sampleTex", sampler);
- compareComputeResult(
- device,
- floatResults,
- Slang::makeArray<float>(0.0f, 0.0103149414f, 0.0f, 1.0f));
- }
+ auto texView = createTexView(device, size, gfx::Format::BC1_UNORM, subData, 2);
+ setUpAndRunTest(device, texView, floatBufferView, "sampleMips", sampler);
+ compareComputeResult(
+ device,
+ floatResults,
+ Slang::makeArray<float>(0.0f, 0.0f, 0.517647088f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f));
+
+ texView = createTexView(device, size, gfx::Format::BC1_UNORM_SRGB, subData, 2);
+ setUpAndRunTest(device, texView, floatBufferView, "sampleMips", sampler);
+ compareComputeResult(
+ device,
+ floatResults,
+ Slang::makeArray<float>(0.0f, 0.0f, 0.230468750f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f));
}
- SLANG_UNIT_TEST(FormatTestsD3D11)
+ // Ignore this test on swiftshader. Swiftshader produces different results than expected.
+ if (!Slang::String(device->getDeviceInfo().adapterName).toLower().contains("swiftshader"))
{
- runTestImpl(formatTestsImpl, unitTestContext, Slang::RenderApiFlag::D3D11);
+ uint8_t texData[] =
+ {255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 16u, 0u, 0u, 0u, 0u, 0u, 0u, 0u};
+ ITextureResource::SubresourceData subData = {(void*)texData, 16, 0};
+
+ auto texView = createTexView(device, bcSize, gfx::Format::BC2_UNORM, &subData);
+ setUpAndRunTest(device, texView, floatBufferView, "sampleTex", sampler);
+ compareComputeResult(
+ device,
+ floatResults,
+ Slang::makeArray<float>(0.0f, 0.0f, 0.517647088f, 1.0f));
+
+ texView = createTexView(device, bcSize, gfx::Format::BC2_UNORM_SRGB, &subData);
+ setUpAndRunTest(device, texView, floatBufferView, "sampleTex", sampler);
+ compareComputeResult(
+ device,
+ floatResults,
+ Slang::makeArray<float>(0.0f, 0.0f, 0.230468750f, 1.0f));
}
-#if SLANG_WINDOWS_FAMILY
- SLANG_UNIT_TEST(FormatTestsD3D12)
+ // Ignore this test on swiftshader. Swiftshader produces different results than expected.
+ if (!Slang::String(device->getDeviceInfo().adapterName).toLower().contains("swiftshader"))
{
- runTestImpl(formatTestsImpl, unitTestContext, Slang::RenderApiFlag::D3D12);
+ uint8_t texData[] =
+ {0u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 16u, 0u, 0u, 0u, 0u, 0u, 0u, 0u};
+ ITextureResource::SubresourceData subData = {(void*)texData, 16, 0};
+
+ auto texView = createTexView(device, bcSize, gfx::Format::BC3_UNORM, &subData);
+ setUpAndRunTest(device, texView, floatBufferView, "sampleTex", sampler);
+ compareComputeResult(
+ device,
+ floatResults,
+ Slang::makeArray<float>(0.0f, 0.0f, 0.517647088f, 1.0f));
+
+ texView = createTexView(device, bcSize, gfx::Format::BC3_UNORM_SRGB, &subData);
+ setUpAndRunTest(device, texView, floatBufferView, "sampleTex", sampler);
+ compareComputeResult(
+ device,
+ floatResults,
+ Slang::makeArray<float>(0.0f, 0.0f, 0.230468750f, 1.0f));
}
-#endif
- SLANG_UNIT_TEST(FormatTestsVulkan)
+ // Ignore this test on swiftshader. Swiftshader produces different results than expected.
+ if (!Slang::String(device->getDeviceInfo().adapterName).toLower().contains("swiftshader"))
{
- runTestImpl(formatTestsImpl, unitTestContext, Slang::RenderApiFlag::Vulkan);
+ uint8_t texData[] = {127u, 0u, 0u, 0u, 0u, 0u, 0u, 0u};
+ ITextureResource::SubresourceData subData = {(void*)texData, 8, 0};
+
+ auto texView = createTexView(device, bcSize, gfx::Format::BC4_UNORM, &subData);
+ setUpAndRunTest(device, texView, floatBufferView, "sampleTex", sampler);
+ compareComputeResult(
+ device,
+ floatResults,
+ Slang::makeArray<float>(0.498039216f, 0.0f, 0.0f, 1.0f));
+
+ texView = createTexView(device, bcSize, gfx::Format::BC4_SNORM, &subData);
+ setUpAndRunTest(device, texView, floatBufferView, "sampleTex", sampler);
+ compareComputeResult(device, floatResults, Slang::makeArray<float>(1.0f, 0.0f, 0.0f, 1.0f));
}
+ // Ignore this test on swiftshader. Swiftshader produces different results than expected.
+ if (!Slang::String(device->getDeviceInfo().adapterName).toLower().contains("swiftshader"))
+ {
+ uint8_t texData[] = {127u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 127u, 0u, 0u, 0u, 0u, 0u, 0u, 0u};
+ ITextureResource::SubresourceData subData = {(void*)texData, 16, 0};
+
+ auto texView = createTexView(device, bcSize, gfx::Format::BC5_UNORM, &subData);
+ setUpAndRunTest(device, texView, floatBufferView, "sampleTex", sampler);
+ compareComputeResult(
+ device,
+ floatResults,
+ Slang::makeArray<float>(
+ 0.498039216f,
+ 0.498039216f,
+ 0.0f,
+ 1.0f,
+ 0.498039216f,
+ 0.498039216f,
+ 0.0f,
+ 1.0f));
+
+ texView = createTexView(device, bcSize, gfx::Format::BC5_SNORM, &subData);
+ setUpAndRunTest(device, texView, floatBufferView, "sampleTex", sampler);
+ compareComputeResult(
+ device,
+ floatResults,
+ Slang::makeArray<float>(1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f));
+ }
+
+ // BC6H_UF16 and BC6H_SF16 are tested separately due to requiring different texture data.
+ // Ignore this test on swiftshader. Swiftshader produces different results than expected.
+ if (!Slang::String(device->getDeviceInfo().adapterName).toLower().contains("swiftshader"))
+ {
+ uint8_t texData[] = {
+ 98u,
+ 238u,
+ 232u,
+ 77u,
+ 240u,
+ 66u,
+ 148u,
+ 31u,
+ 124u,
+ 95u,
+ 2u,
+ 224u,
+ 255u,
+ 107u,
+ 77u,
+ 250u};
+ ITextureResource::SubresourceData subData = {(void*)texData, 16, 0};
+
+ auto texView = createTexView(device, bcSize, gfx::Format::BC6H_UF16, &subData);
+ setUpAndRunTest(device, texView, floatBufferView, "sampleTex", sampler);
+ compareComputeResult(
+ device,
+ floatResults,
+ Slang::makeArray<float>(0.336669922f, 0.911132812f, 2.13867188f, 1.0f));
+ }
+
+ // Ignore this test on swiftshader. Swiftshader produces different results than expected.
+ if (!Slang::String(device->getDeviceInfo().adapterName).toLower().contains("swiftshader"))
+ {
+ uint8_t texData[] = {
+ 107u,
+ 238u,
+ 232u,
+ 77u,
+ 240u,
+ 71u,
+ 128u,
+ 127u,
+ 1u,
+ 0u,
+ 255u,
+ 255u,
+ 170u,
+ 218u,
+ 221u,
+ 254u};
+ ITextureResource::SubresourceData subData = {(void*)texData, 16, 0};
+
+ auto texView = createTexView(device, bcSize, gfx::Format::BC6H_SF16, &subData);
+ setUpAndRunTest(device, texView, floatBufferView, "sampleTex", sampler);
+ compareComputeResult(
+ device,
+ floatResults,
+ Slang::makeArray<float>(0.336914062f, 0.910644531f, 2.14062500f, 1.0f));
+ }
+
+ // Ignore this test on swiftshader. Swiftshader produces different results than expected.
+ if (!Slang::String(device->getDeviceInfo().adapterName).toLower().contains("swiftshader"))
+ {
+ uint8_t texData[] =
+ {104u, 0u, 0u, 0u, 64u, 163u, 209u, 104u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u};
+ ITextureResource::SubresourceData subData = {(void*)texData, 16, 0};
+
+ auto texView = createTexView(device, bcSize, gfx::Format::BC7_UNORM, &subData);
+ setUpAndRunTest(device, texView, floatBufferView, "sampleTex", sampler);
+ compareComputeResult(
+ device,
+ floatResults,
+ Slang::makeArray<float>(0.0f, 0.101960786f, 0.0f, 1.0f));
+
+ texView = createTexView(device, bcSize, gfx::Format::BC7_UNORM_SRGB, &subData);
+ setUpAndRunTest(device, texView, floatBufferView, "sampleTex", sampler);
+ compareComputeResult(
+ device,
+ floatResults,
+ Slang::makeArray<float>(0.0f, 0.0103149414f, 0.0f, 1.0f));
+ }
}
+
+SLANG_UNIT_TEST(FormatTestsD3D11)
+{
+ runTestImpl(formatTestsImpl, unitTestContext, Slang::RenderApiFlag::D3D11);
+}
+
+#if SLANG_WINDOWS_FAMILY
+SLANG_UNIT_TEST(FormatTestsD3D12)
+{
+ runTestImpl(formatTestsImpl, unitTestContext, Slang::RenderApiFlag::D3D12);
+}
+#endif
+
+SLANG_UNIT_TEST(FormatTestsVulkan)
+{
+ runTestImpl(formatTestsImpl, unitTestContext, Slang::RenderApiFlag::Vulkan);
+}
+
+} // namespace gfx_test
diff --git a/tools/gfx-unit-test/get-buffer-resource-handle-test.cpp b/tools/gfx-unit-test/get-buffer-resource-handle-test.cpp
index 36b6b3cad..a143ac135 100644
--- a/tools/gfx-unit-test/get-buffer-resource-handle-test.cpp
+++ b/tools/gfx-unit-test/get-buffer-resource-handle-test.cpp
@@ -1,9 +1,8 @@
-#include "tools/unit-test/slang-unit-test.h"
-
-#include "slang-gfx.h"
#include "gfx-test-util.h"
-#include "tools/gfx-util/shader-cursor.h"
+#include "slang-gfx.h"
#include "source/core/slang-basic.h"
+#include "tools/gfx-util/shader-cursor.h"
+#include "tools/unit-test/slang-unit-test.h"
#if SLANG_WINDOWS_FAMILY
#include <d3d12.h>
@@ -13,97 +12,87 @@ using namespace gfx;
namespace gfx_test
{
- void getBufferResourceHandleTestImpl(IDevice* device, UnitTestContext* context)
- {
- const int numberCount = 1;
- IBufferResource::Desc bufferDesc = {};
- bufferDesc.sizeInBytes = numberCount * sizeof(float);
- bufferDesc.format = gfx::Format::Unknown;
- bufferDesc.elementSize = sizeof(float);
- bufferDesc.allowedStates = ResourceStateSet(
- ResourceState::ShaderResource,
- ResourceState::UnorderedAccess,
- ResourceState::CopyDestination,
- ResourceState::CopySource);
- bufferDesc.defaultState = ResourceState::UnorderedAccess;
- bufferDesc.memoryType = MemoryType::DeviceLocal;
+void getBufferResourceHandleTestImpl(IDevice* device, UnitTestContext* context)
+{
+ const int numberCount = 1;
+ IBufferResource::Desc bufferDesc = {};
+ bufferDesc.sizeInBytes = numberCount * sizeof(float);
+ bufferDesc.format = gfx::Format::Unknown;
+ bufferDesc.elementSize = sizeof(float);
+ bufferDesc.allowedStates = ResourceStateSet(
+ ResourceState::ShaderResource,
+ ResourceState::UnorderedAccess,
+ ResourceState::CopyDestination,
+ ResourceState::CopySource);
+ bufferDesc.defaultState = ResourceState::UnorderedAccess;
+ bufferDesc.memoryType = MemoryType::DeviceLocal;
- ComPtr<IBufferResource> buffer;
- GFX_CHECK_CALL_ABORT(device->createBufferResource(
- bufferDesc,
- nullptr,
- buffer.writeRef()));
+ ComPtr<IBufferResource> buffer;
+ GFX_CHECK_CALL_ABORT(device->createBufferResource(bufferDesc, nullptr, buffer.writeRef()));
- InteropHandle handle;
- GFX_CHECK_CALL_ABORT(buffer->getNativeResourceHandle(&handle));
- if (device->getDeviceInfo().deviceType == gfx::DeviceType::Vulkan)
- {
- SLANG_CHECK(handle.handleValue != 0);
- SLANG_CHECK(handle.api == InteropHandleAPI::Vulkan);
- }
+ InteropHandle handle;
+ GFX_CHECK_CALL_ABORT(buffer->getNativeResourceHandle(&handle));
+ if (device->getDeviceInfo().deviceType == gfx::DeviceType::Vulkan)
+ {
+ SLANG_CHECK(handle.handleValue != 0);
+ SLANG_CHECK(handle.api == InteropHandleAPI::Vulkan);
+ }
#if SLANG_WINDOWS_FAMILY
- else
- {
- SLANG_CHECK(handle.api == InteropHandleAPI::D3D12);
- auto d3d12Handle = (ID3D12Resource*)handle.handleValue;
- Slang::ComPtr<IUnknown> testHandle1;
- GFX_CHECK_CALL_ABORT(d3d12Handle->QueryInterface<IUnknown>(testHandle1.writeRef()));
- Slang::ComPtr<ID3D12Resource> testHandle2;
- GFX_CHECK_CALL_ABORT(testHandle1->QueryInterface<ID3D12Resource>(testHandle2.writeRef()));
- SLANG_CHECK(d3d12Handle == testHandle2.get());
- }
-#endif
+ else
+ {
+ SLANG_CHECK(handle.api == InteropHandleAPI::D3D12);
+ auto d3d12Handle = (ID3D12Resource*)handle.handleValue;
+ Slang::ComPtr<IUnknown> testHandle1;
+ GFX_CHECK_CALL_ABORT(d3d12Handle->QueryInterface<IUnknown>(testHandle1.writeRef()));
+ Slang::ComPtr<ID3D12Resource> testHandle2;
+ GFX_CHECK_CALL_ABORT(testHandle1->QueryInterface<ID3D12Resource>(testHandle2.writeRef()));
+ SLANG_CHECK(d3d12Handle == testHandle2.get());
}
+#endif
+}
- void getBufferResourceHandleTestAPI(UnitTestContext* context, Slang::RenderApiFlag::Enum api)
+void getBufferResourceHandleTestAPI(UnitTestContext* context, Slang::RenderApiFlag::Enum api)
+{
+ if ((api & context->enabledApis) == 0)
{
- if ((api & context->enabledApis) == 0)
- {
- SLANG_IGNORE_TEST;
- }
- Slang::ComPtr<IDevice> device;
- IDevice::Desc deviceDesc = {};
- switch (api)
- {
- case Slang::RenderApiFlag::D3D11:
- deviceDesc.deviceType = gfx::DeviceType::DirectX11;
- break;
- case Slang::RenderApiFlag::D3D12:
- deviceDesc.deviceType = gfx::DeviceType::DirectX12;
- break;
- case Slang::RenderApiFlag::Vulkan:
- deviceDesc.deviceType = gfx::DeviceType::Vulkan;
- break;
- default:
- SLANG_IGNORE_TEST;
- }
- deviceDesc.slang.slangGlobalSession = context->slangGlobalSession;
- const char* searchPaths[] = { "", "../../tools/gfx-unit-test", "tools/gfx-unit-test" };
- deviceDesc.slang.searchPathCount = (SlangInt)SLANG_COUNT_OF(searchPaths);
- deviceDesc.slang.searchPaths = searchPaths;
- auto createDeviceResult = gfxCreateDevice(&deviceDesc, device.writeRef());
- if (SLANG_FAILED(createDeviceResult))
- {
- SLANG_IGNORE_TEST;
- }
- // Ignore this test on swiftshader. Swiftshader seems to have a bug that causes the test
- // to crash.
- if (Slang::String(device->getDeviceInfo().adapterName).toLower().contains("swiftshader"))
- {
- SLANG_IGNORE_TEST;
- }
-
- getBufferResourceHandleTestImpl(device, context);
+ SLANG_IGNORE_TEST;
}
-
- SLANG_UNIT_TEST(getBufferResourceHandleD3D12)
+ Slang::ComPtr<IDevice> device;
+ IDevice::Desc deviceDesc = {};
+ switch (api)
{
- return getBufferResourceHandleTestAPI(unitTestContext, Slang::RenderApiFlag::D3D12);
+ case Slang::RenderApiFlag::D3D11: deviceDesc.deviceType = gfx::DeviceType::DirectX11; break;
+ case Slang::RenderApiFlag::D3D12: deviceDesc.deviceType = gfx::DeviceType::DirectX12; break;
+ case Slang::RenderApiFlag::Vulkan: deviceDesc.deviceType = gfx::DeviceType::Vulkan; break;
+ default: SLANG_IGNORE_TEST;
}
-
- SLANG_UNIT_TEST(getBufferResourceHandleVulkan)
+ deviceDesc.slang.slangGlobalSession = context->slangGlobalSession;
+ const char* searchPaths[] = {"", "../../tools/gfx-unit-test", "tools/gfx-unit-test"};
+ deviceDesc.slang.searchPathCount = (SlangInt)SLANG_COUNT_OF(searchPaths);
+ deviceDesc.slang.searchPaths = searchPaths;
+ auto createDeviceResult = gfxCreateDevice(&deviceDesc, device.writeRef());
+ if (SLANG_FAILED(createDeviceResult))
+ {
+ SLANG_IGNORE_TEST;
+ }
+ // Ignore this test on swiftshader. Swiftshader seems to have a bug that causes the test
+ // to crash.
+ if (Slang::String(device->getDeviceInfo().adapterName).toLower().contains("swiftshader"))
{
- return getBufferResourceHandleTestAPI(unitTestContext, Slang::RenderApiFlag::Vulkan);
+ SLANG_IGNORE_TEST;
}
+ getBufferResourceHandleTestImpl(device, context);
}
+
+SLANG_UNIT_TEST(getBufferResourceHandleD3D12)
+{
+ return getBufferResourceHandleTestAPI(unitTestContext, Slang::RenderApiFlag::D3D12);
+}
+
+SLANG_UNIT_TEST(getBufferResourceHandleVulkan)
+{
+ return getBufferResourceHandleTestAPI(unitTestContext, Slang::RenderApiFlag::Vulkan);
+}
+
+} // namespace gfx_test
diff --git a/tools/gfx-unit-test/get-cmd-buffer-handle-test.cpp b/tools/gfx-unit-test/get-cmd-buffer-handle-test.cpp
index 120c331ed..cd9a401f7 100644
--- a/tools/gfx-unit-test/get-cmd-buffer-handle-test.cpp
+++ b/tools/gfx-unit-test/get-cmd-buffer-handle-test.cpp
@@ -1,9 +1,8 @@
-#include "tools/unit-test/slang-unit-test.h"
-
-#include "slang-gfx.h"
#include "gfx-test-util.h"
-#include "tools/gfx-util/shader-cursor.h"
+#include "slang-gfx.h"
#include "source/core/slang-basic.h"
+#include "tools/gfx-util/shader-cursor.h"
+#include "tools/unit-test/slang-unit-test.h"
#if SLANG_WINDOWS_FAMILY
#include <d3d12.h>
@@ -13,93 +12,84 @@ using namespace gfx;
namespace gfx_test
{
- void getBufferHandleTestImpl(IDevice* device, UnitTestContext* context)
- {
- // We need to create a transient heap in order to create a command buffer.
- Slang::ComPtr<ITransientResourceHeap> transientHeap;
- ITransientResourceHeap::Desc transientHeapDesc = {};
- transientHeapDesc.constantBufferSize = 4096;
- GFX_CHECK_CALL_ABORT(
- device->createTransientResourceHeap(transientHeapDesc, transientHeap.writeRef()));
-
- auto commandBuffer = transientHeap->createCommandBuffer();
- struct CloseComandBufferRAII
- {
- ICommandBuffer* m_commandBuffer;
- ~CloseComandBufferRAII()
- {
- m_commandBuffer->close();
- }
- } closeCommandBufferRAII{ commandBuffer };
- InteropHandle handle = {};
- GFX_CHECK_CALL_ABORT(commandBuffer->getNativeHandle(&handle));
- if (device->getDeviceInfo().deviceType == gfx::DeviceType::Vulkan)
- {
- SLANG_CHECK(handle.handleValue != 0);
- }
-#if SLANG_WINDOWS_FAMILY
- else
- {
- auto d3d12Handle = (ID3D12GraphicsCommandList*)handle.handleValue;
- Slang::ComPtr<IUnknown> testHandle1;
- GFX_CHECK_CALL_ABORT(d3d12Handle->QueryInterface<IUnknown>(testHandle1.writeRef()));
- Slang::ComPtr<ID3D12GraphicsCommandList> testHandle2;
- GFX_CHECK_CALL_ABORT(d3d12Handle->QueryInterface<ID3D12GraphicsCommandList>(testHandle2.writeRef()));
- SLANG_CHECK(d3d12Handle == testHandle2.get());
- }
-#endif
- }
+void getBufferHandleTestImpl(IDevice* device, UnitTestContext* context)
+{
+ // We need to create a transient heap in order to create a command buffer.
+ Slang::ComPtr<ITransientResourceHeap> transientHeap;
+ ITransientResourceHeap::Desc transientHeapDesc = {};
+ transientHeapDesc.constantBufferSize = 4096;
+ GFX_CHECK_CALL_ABORT(
+ device->createTransientResourceHeap(transientHeapDesc, transientHeap.writeRef()));
- void getBufferHandleTestAPI(UnitTestContext* context, Slang::RenderApiFlag::Enum api)
+ auto commandBuffer = transientHeap->createCommandBuffer();
+ struct CloseComandBufferRAII
+ {
+ ICommandBuffer* m_commandBuffer;
+ ~CloseComandBufferRAII() { m_commandBuffer->close(); }
+ } closeCommandBufferRAII{commandBuffer};
+ InteropHandle handle = {};
+ GFX_CHECK_CALL_ABORT(commandBuffer->getNativeHandle(&handle));
+ if (device->getDeviceInfo().deviceType == gfx::DeviceType::Vulkan)
{
- if ((api & context->enabledApis) == 0)
- {
- SLANG_IGNORE_TEST;
- }
- Slang::ComPtr<IDevice> device;
- IDevice::Desc deviceDesc = {};
- switch (api)
- {
- case Slang::RenderApiFlag::D3D11:
- deviceDesc.deviceType = gfx::DeviceType::DirectX11;
- break;
- case Slang::RenderApiFlag::D3D12:
- deviceDesc.deviceType = gfx::DeviceType::DirectX12;
- break;
- case Slang::RenderApiFlag::Vulkan:
- deviceDesc.deviceType = gfx::DeviceType::Vulkan;
- break;
- default:
- SLANG_IGNORE_TEST;
- }
- deviceDesc.slang.slangGlobalSession = context->slangGlobalSession;
- const char* searchPaths[] = { "", "../../tools/gfx-unit-test", "tools/gfx-unit-test" };
- deviceDesc.slang.searchPathCount = (SlangInt)SLANG_COUNT_OF(searchPaths);
- deviceDesc.slang.searchPaths = searchPaths;
- auto createDeviceResult = gfxCreateDevice(&deviceDesc, device.writeRef());
- if (SLANG_FAILED(createDeviceResult))
- {
- SLANG_IGNORE_TEST;
- }
- // Ignore this test on swiftshader. Swiftshader seems to have a bug that causes the test
- // to crash.
- if (Slang::String(device->getDeviceInfo().adapterName).toLower().contains("swiftshader"))
- {
- SLANG_IGNORE_TEST;
- }
- getBufferHandleTestImpl(device, context);
+ SLANG_CHECK(handle.handleValue != 0);
}
-
#if SLANG_WINDOWS_FAMILY
- SLANG_UNIT_TEST(getCmdBufferHandleD3D12)
+ else
{
- return getBufferHandleTestAPI(unitTestContext, Slang::RenderApiFlag::D3D12);
+ auto d3d12Handle = (ID3D12GraphicsCommandList*)handle.handleValue;
+ Slang::ComPtr<IUnknown> testHandle1;
+ GFX_CHECK_CALL_ABORT(d3d12Handle->QueryInterface<IUnknown>(testHandle1.writeRef()));
+ Slang::ComPtr<ID3D12GraphicsCommandList> testHandle2;
+ GFX_CHECK_CALL_ABORT(
+ d3d12Handle->QueryInterface<ID3D12GraphicsCommandList>(testHandle2.writeRef()));
+ SLANG_CHECK(d3d12Handle == testHandle2.get());
}
#endif
+}
- SLANG_UNIT_TEST(getCmdBufferHandleVulkan)
+void getBufferHandleTestAPI(UnitTestContext* context, Slang::RenderApiFlag::Enum api)
+{
+ if ((api & context->enabledApis) == 0)
+ {
+ SLANG_IGNORE_TEST;
+ }
+ Slang::ComPtr<IDevice> device;
+ IDevice::Desc deviceDesc = {};
+ switch (api)
+ {
+ case Slang::RenderApiFlag::D3D11: deviceDesc.deviceType = gfx::DeviceType::DirectX11; break;
+ case Slang::RenderApiFlag::D3D12: deviceDesc.deviceType = gfx::DeviceType::DirectX12; break;
+ case Slang::RenderApiFlag::Vulkan: deviceDesc.deviceType = gfx::DeviceType::Vulkan; break;
+ default: SLANG_IGNORE_TEST;
+ }
+ deviceDesc.slang.slangGlobalSession = context->slangGlobalSession;
+ const char* searchPaths[] = {"", "../../tools/gfx-unit-test", "tools/gfx-unit-test"};
+ deviceDesc.slang.searchPathCount = (SlangInt)SLANG_COUNT_OF(searchPaths);
+ deviceDesc.slang.searchPaths = searchPaths;
+ auto createDeviceResult = gfxCreateDevice(&deviceDesc, device.writeRef());
+ if (SLANG_FAILED(createDeviceResult))
+ {
+ SLANG_IGNORE_TEST;
+ }
+ // Ignore this test on swiftshader. Swiftshader seems to have a bug that causes the test
+ // to crash.
+ if (Slang::String(device->getDeviceInfo().adapterName).toLower().contains("swiftshader"))
{
- return getBufferHandleTestAPI(unitTestContext, Slang::RenderApiFlag::Vulkan);
+ SLANG_IGNORE_TEST;
}
+ getBufferHandleTestImpl(device, context);
+}
+
+#if SLANG_WINDOWS_FAMILY
+SLANG_UNIT_TEST(getCmdBufferHandleD3D12)
+{
+ return getBufferHandleTestAPI(unitTestContext, Slang::RenderApiFlag::D3D12);
+}
+#endif
+SLANG_UNIT_TEST(getCmdBufferHandleVulkan)
+{
+ return getBufferHandleTestAPI(unitTestContext, Slang::RenderApiFlag::Vulkan);
}
+
+} // namespace gfx_test
diff --git a/tools/gfx-unit-test/get-cmd-queue-handle-test.cpp b/tools/gfx-unit-test/get-cmd-queue-handle-test.cpp
index e14729718..8e589a899 100644
--- a/tools/gfx-unit-test/get-cmd-queue-handle-test.cpp
+++ b/tools/gfx-unit-test/get-cmd-queue-handle-test.cpp
@@ -1,9 +1,8 @@
-#include "tools/unit-test/slang-unit-test.h"
-
-#include "slang-gfx.h"
#include "gfx-test-util.h"
-#include "tools/gfx-util/shader-cursor.h"
+#include "slang-gfx.h"
#include "source/core/slang-basic.h"
+#include "tools/gfx-util/shader-cursor.h"
+#include "tools/unit-test/slang-unit-test.h"
#if SLANG_WINDOWS_FAMILY
#include <d3d12.h>
@@ -13,77 +12,71 @@ using namespace gfx;
namespace gfx_test
{
- void getQueueHandleTestImpl(IDevice* device, UnitTestContext* context)
+void getQueueHandleTestImpl(IDevice* device, UnitTestContext* context)
+{
+ ICommandQueue::Desc queueDesc = {ICommandQueue::QueueType::Graphics};
+ auto queue = device->createCommandQueue(queueDesc);
+ InteropHandle handle;
+ GFX_CHECK_CALL_ABORT(queue->getNativeHandle(&handle));
+ if (device->getDeviceInfo().deviceType == gfx::DeviceType::Vulkan)
{
- ICommandQueue::Desc queueDesc = { ICommandQueue::QueueType::Graphics };
- auto queue = device->createCommandQueue(queueDesc);
- InteropHandle handle;
- GFX_CHECK_CALL_ABORT(queue->getNativeHandle(&handle));
- if (device->getDeviceInfo().deviceType == gfx::DeviceType::Vulkan)
- {
- SLANG_CHECK(handle.handleValue != 0);
- }
+ SLANG_CHECK(handle.handleValue != 0);
+ }
#if SLANG_WINDOWS_FAMILY
- else
- {
- auto d3d12Queue = (ID3D12CommandQueue*)handle.handleValue;
- Slang::ComPtr<IUnknown> testHandle1;
- GFX_CHECK_CALL_ABORT(d3d12Queue->QueryInterface<IUnknown>(testHandle1.writeRef()));
- Slang::ComPtr<ID3D12CommandQueue> testHandle2;
- GFX_CHECK_CALL_ABORT(testHandle1->QueryInterface<ID3D12CommandQueue>(testHandle2.writeRef()));
- SLANG_CHECK(d3d12Queue == testHandle2.get());
- }
-#endif
+ else
+ {
+ auto d3d12Queue = (ID3D12CommandQueue*)handle.handleValue;
+ Slang::ComPtr<IUnknown> testHandle1;
+ GFX_CHECK_CALL_ABORT(d3d12Queue->QueryInterface<IUnknown>(testHandle1.writeRef()));
+ Slang::ComPtr<ID3D12CommandQueue> testHandle2;
+ GFX_CHECK_CALL_ABORT(
+ testHandle1->QueryInterface<ID3D12CommandQueue>(testHandle2.writeRef()));
+ SLANG_CHECK(d3d12Queue == testHandle2.get());
}
+#endif
+}
- void getQueueHandleTestAPI(UnitTestContext* context, Slang::RenderApiFlag::Enum api)
+void getQueueHandleTestAPI(UnitTestContext* context, Slang::RenderApiFlag::Enum api)
+{
+ if ((api & context->enabledApis) == 0)
{
- if ((api & context->enabledApis) == 0)
- {
- SLANG_IGNORE_TEST;
- }
- Slang::ComPtr<IDevice> device;
- IDevice::Desc deviceDesc = {};
- switch (api)
- {
- case Slang::RenderApiFlag::D3D11:
- deviceDesc.deviceType = gfx::DeviceType::DirectX11;
- break;
- case Slang::RenderApiFlag::D3D12:
- deviceDesc.deviceType = gfx::DeviceType::DirectX12;
- break;
- case Slang::RenderApiFlag::Vulkan:
- deviceDesc.deviceType = gfx::DeviceType::Vulkan;
- break;
- default:
- SLANG_IGNORE_TEST;
- }
- deviceDesc.slang.slangGlobalSession = context->slangGlobalSession;
- const char* searchPaths[] = { "", "../../tools/gfx-unit-test", "tools/gfx-unit-test" };
- deviceDesc.slang.searchPathCount = (SlangInt)SLANG_COUNT_OF(searchPaths);
- deviceDesc.slang.searchPaths = searchPaths;
- auto createDeviceResult = gfxCreateDevice(&deviceDesc, device.writeRef());
- if (SLANG_FAILED(createDeviceResult))
- {
- SLANG_IGNORE_TEST;
- }
- // Ignore this test on swiftshader. Swiftshader seems to have a bug that causes the test
- // to crash.
- if (Slang::String(device->getDeviceInfo().adapterName).toLower().contains("swiftshader"))
- {
- SLANG_IGNORE_TEST;
- }
- getQueueHandleTestImpl(device, context);
+ SLANG_IGNORE_TEST;
}
-
- SLANG_UNIT_TEST(getCmdQueueHandleD3D12)
+ Slang::ComPtr<IDevice> device;
+ IDevice::Desc deviceDesc = {};
+ switch (api)
{
- return getQueueHandleTestAPI(unitTestContext, Slang::RenderApiFlag::D3D12);
+ case Slang::RenderApiFlag::D3D11: deviceDesc.deviceType = gfx::DeviceType::DirectX11; break;
+ case Slang::RenderApiFlag::D3D12: deviceDesc.deviceType = gfx::DeviceType::DirectX12; break;
+ case Slang::RenderApiFlag::Vulkan: deviceDesc.deviceType = gfx::DeviceType::Vulkan; break;
+ default: SLANG_IGNORE_TEST;
}
-
- SLANG_UNIT_TEST(getCmdQueueHandleVulkan)
+ deviceDesc.slang.slangGlobalSession = context->slangGlobalSession;
+ const char* searchPaths[] = {"", "../../tools/gfx-unit-test", "tools/gfx-unit-test"};
+ deviceDesc.slang.searchPathCount = (SlangInt)SLANG_COUNT_OF(searchPaths);
+ deviceDesc.slang.searchPaths = searchPaths;
+ auto createDeviceResult = gfxCreateDevice(&deviceDesc, device.writeRef());
+ if (SLANG_FAILED(createDeviceResult))
+ {
+ SLANG_IGNORE_TEST;
+ }
+ // Ignore this test on swiftshader. Swiftshader seems to have a bug that causes the test
+ // to crash.
+ if (Slang::String(device->getDeviceInfo().adapterName).toLower().contains("swiftshader"))
{
- return getQueueHandleTestAPI(unitTestContext, Slang::RenderApiFlag::Vulkan);
+ SLANG_IGNORE_TEST;
}
+ getQueueHandleTestImpl(device, context);
+}
+
+SLANG_UNIT_TEST(getCmdQueueHandleD3D12)
+{
+ return getQueueHandleTestAPI(unitTestContext, Slang::RenderApiFlag::D3D12);
+}
+SLANG_UNIT_TEST(getCmdQueueHandleVulkan)
+{
+ return getQueueHandleTestAPI(unitTestContext, Slang::RenderApiFlag::Vulkan);
}
+
+} // namespace gfx_test
diff --git a/tools/gfx-unit-test/get-supported-resource-states-test.cpp b/tools/gfx-unit-test/get-supported-resource-states-test.cpp
index fc7c57771..a3f331384 100644
--- a/tools/gfx-unit-test/get-supported-resource-states-test.cpp
+++ b/tools/gfx-unit-test/get-supported-resource-states-test.cpp
@@ -1,9 +1,8 @@
-#include "tools/unit-test/slang-unit-test.h"
-
-#include "slang-gfx.h"
#include "gfx-test-util.h"
-#include "tools/gfx-util/shader-cursor.h"
+#include "slang-gfx.h"
#include "source/core/slang-basic.h"
+#include "tools/gfx-util/shader-cursor.h"
+#include "tools/unit-test/slang-unit-test.h"
#if SLANG_WINDOWS_FAMILY
#include <d3d12.h>
@@ -14,195 +13,181 @@ using namespace gfx;
namespace
{
- using namespace gfx_test;
+using namespace gfx_test;
- struct GetSupportedResourceStatesBase
- {
- IDevice* device;
- UnitTestContext* context;
+struct GetSupportedResourceStatesBase
+{
+ IDevice* device;
+ UnitTestContext* context;
- ResourceStateSet formatSupportedStates;
- ResourceStateSet textureAllowedStates;
- ResourceStateSet bufferAllowedStates;
+ ResourceStateSet formatSupportedStates;
+ ResourceStateSet textureAllowedStates;
+ ResourceStateSet bufferAllowedStates;
- ComPtr<ITextureResource> texture;
- ComPtr<IBufferResource> buffer;
+ ComPtr<ITextureResource> texture;
+ ComPtr<IBufferResource> buffer;
- void init(IDevice* device, UnitTestContext* context)
- {
- this->device = device;
- this->context = context;
- }
+ void init(IDevice* device, UnitTestContext* context)
+ {
+ this->device = device;
+ this->context = context;
+ }
- Format convertTypelessFormat(Format format)
+ Format convertTypelessFormat(Format format)
+ {
+ switch (format)
{
- switch (format)
- {
- case Format::R32G32B32A32_TYPELESS:
- return Format::R32G32B32A32_FLOAT;
- case Format::R32G32B32_TYPELESS:
- return Format::R32G32B32_FLOAT;
- case Format::R32G32_TYPELESS:
- return Format::R32G32_FLOAT;
- case Format::R32_TYPELESS:
- return Format::R32_FLOAT;
- case Format::R16G16B16A16_TYPELESS:
- return Format::R16G16B16A16_FLOAT;
- case Format::R16G16_TYPELESS:
- return Format::R16G16_FLOAT;
- case Format::R16_TYPELESS:
- return Format::R16_FLOAT;
- case Format::R8G8B8A8_TYPELESS:
- return Format::R8G8B8A8_UNORM;
- case Format::R8G8_TYPELESS:
- return Format::R8G8_UNORM;
- case Format::R8_TYPELESS:
- return Format::R8_UNORM;
- case Format::B8G8R8A8_TYPELESS:
- return Format::B8G8R8A8_UNORM;
- case Format::R10G10B10A2_TYPELESS:
- return Format::R10G10B10A2_UINT;
- default:
- return Format::Unknown;
- }
+ case Format::R32G32B32A32_TYPELESS: return Format::R32G32B32A32_FLOAT;
+ case Format::R32G32B32_TYPELESS: return Format::R32G32B32_FLOAT;
+ case Format::R32G32_TYPELESS: return Format::R32G32_FLOAT;
+ case Format::R32_TYPELESS: return Format::R32_FLOAT;
+ case Format::R16G16B16A16_TYPELESS: return Format::R16G16B16A16_FLOAT;
+ case Format::R16G16_TYPELESS: return Format::R16G16_FLOAT;
+ case Format::R16_TYPELESS: return Format::R16_FLOAT;
+ case Format::R8G8B8A8_TYPELESS: return Format::R8G8B8A8_UNORM;
+ case Format::R8G8_TYPELESS: return Format::R8G8_UNORM;
+ case Format::R8_TYPELESS: return Format::R8_UNORM;
+ case Format::B8G8R8A8_TYPELESS: return Format::B8G8R8A8_UNORM;
+ case Format::R10G10B10A2_TYPELESS: return Format::R10G10B10A2_UINT;
+ default: return Format::Unknown;
}
+ }
- void transitionResourceStates(IDevice* device)
- {
- Slang::ComPtr<ITransientResourceHeap> transientHeap;
- ITransientResourceHeap::Desc transientHeapDesc = {};
- transientHeapDesc.constantBufferSize = 4096;
- GFX_CHECK_CALL_ABORT(
- device->createTransientResourceHeap(transientHeapDesc, transientHeap.writeRef()));
+ void transitionResourceStates(IDevice* device)
+ {
+ 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);
+ ICommandQueue::Desc queueDesc = {ICommandQueue::QueueType::Graphics};
+ auto queue = device->createCommandQueue(queueDesc);
- auto commandBuffer = transientHeap->createCommandBuffer();
- auto encoder = commandBuffer->encodeResourceCommands();
- ResourceState currentTextureState = texture->getDesc()->defaultState;
- ResourceState currentBufferState = buffer->getDesc()->defaultState;
+ auto commandBuffer = transientHeap->createCommandBuffer();
+ auto encoder = commandBuffer->encodeResourceCommands();
+ ResourceState currentTextureState = texture->getDesc()->defaultState;
+ ResourceState currentBufferState = buffer->getDesc()->defaultState;
- for (uint32_t i = 0; i < (uint32_t)ResourceState::_Count; ++i)
+ for (uint32_t i = 0; i < (uint32_t)ResourceState::_Count; ++i)
+ {
+ auto nextState = (ResourceState)i;
+ if (formatSupportedStates.contains(nextState))
{
- auto nextState = (ResourceState)i;
- if (formatSupportedStates.contains(nextState))
+ if (bufferAllowedStates.contains(nextState))
+ {
+ encoder->bufferBarrier(buffer, currentBufferState, nextState);
+ currentBufferState = nextState;
+ }
+ if (textureAllowedStates.contains(nextState))
{
- if (bufferAllowedStates.contains(nextState))
- {
- encoder->bufferBarrier(buffer, currentBufferState, nextState);
- currentBufferState = nextState;
- }
- if (textureAllowedStates.contains(nextState))
- {
- encoder->textureBarrier(texture, currentTextureState, nextState);
- currentTextureState = nextState;
- }
+ encoder->textureBarrier(texture, currentTextureState, nextState);
+ currentTextureState = nextState;
}
}
- encoder->endEncoding();
- commandBuffer->close();
- queue->executeCommandBuffer(commandBuffer);
- queue->waitOnHost();
}
+ encoder->endEncoding();
+ commandBuffer->close();
+ queue->executeCommandBuffer(commandBuffer);
+ queue->waitOnHost();
+ }
- void run()
+ void run()
+ {
+ // Skip Format::Unknown
+ for (uint32_t i = 1; i < (uint32_t)Format::_Count; ++i)
{
- // Skip Format::Unknown
- for (uint32_t i = 1; i < (uint32_t)Format::_Count; ++i)
- {
- auto baseFormat = (Format)i;
- FormatInfo info;
- gfxGetFormatInfo(baseFormat, &info);
- // Ignore 3-channel textures for now since validation layer seem to report unsupported errors there.
- if (info.channelCount == 3)
- continue;
-
- auto format = gfxIsTypelessFormat(baseFormat) ? convertTypelessFormat(baseFormat) : baseFormat;
- GFX_CHECK_CALL_ABORT(device->getFormatSupportedResourceStates(format, &formatSupportedStates));
-
- textureAllowedStates.add(
- ResourceState::RenderTarget,
- ResourceState::DepthRead,
- ResourceState::DepthWrite,
- ResourceState::Present,
- ResourceState::ResolveSource,
- ResourceState::ResolveDestination,
- ResourceState::Undefined,
- ResourceState::ShaderResource,
- ResourceState::UnorderedAccess,
- ResourceState::CopySource,
- ResourceState::CopyDestination);
-
- bufferAllowedStates.add(
- ResourceState::VertexBuffer,
- ResourceState::IndexBuffer,
- ResourceState::ConstantBuffer,
- ResourceState::StreamOutput,
- ResourceState::IndirectArgument,
- ResourceState::AccelerationStructure,
- ResourceState::Undefined,
- ResourceState::ShaderResource,
- ResourceState::UnorderedAccess,
- ResourceState::CopySource,
- ResourceState::CopyDestination);
-
- ResourceState currentState = ResourceState::CopySource;
- ITextureResource::Extents extent;
- extent.width = 4;
- extent.height = 4;
- extent.depth = 1;
-
- ITextureResource::Desc texDesc = {};
- texDesc.type = IResource::Type::Texture2D;
- texDesc.numMipLevels = 1;
- texDesc.arraySize = 1;
- texDesc.size = extent;
- texDesc.defaultState = currentState;
- texDesc.allowedStates = formatSupportedStates & textureAllowedStates;
- texDesc.memoryType = MemoryType::DeviceLocal;
- texDesc.format = format;
-
- GFX_CHECK_CALL_ABORT(device->createTextureResource(
- texDesc,
- nullptr,
- texture.writeRef()));
-
- IBufferResource::Desc bufferDesc = {};
- bufferDesc.sizeInBytes = 256;
- bufferDesc.format = gfx::Format::Unknown;
- bufferDesc.elementSize = sizeof(float);
- bufferDesc.allowedStates = formatSupportedStates & bufferAllowedStates;
- bufferDesc.defaultState = currentState;
- bufferDesc.memoryType = MemoryType::DeviceLocal;
-
- GFX_CHECK_CALL_ABORT(device->createBufferResource(
- bufferDesc,
- nullptr,
- buffer.writeRef()));
-
- transitionResourceStates(device);
- }
- }
- };
+ auto baseFormat = (Format)i;
+ FormatInfo info;
+ gfxGetFormatInfo(baseFormat, &info);
+ // Ignore 3-channel textures for now since validation layer seem to report unsupported
+ // errors there.
+ if (info.channelCount == 3)
+ continue;
+
+ auto format =
+ gfxIsTypelessFormat(baseFormat) ? convertTypelessFormat(baseFormat) : baseFormat;
+ GFX_CHECK_CALL_ABORT(
+ device->getFormatSupportedResourceStates(format, &formatSupportedStates));
+
+ textureAllowedStates.add(
+ ResourceState::RenderTarget,
+ ResourceState::DepthRead,
+ ResourceState::DepthWrite,
+ ResourceState::Present,
+ ResourceState::ResolveSource,
+ ResourceState::ResolveDestination,
+ ResourceState::Undefined,
+ ResourceState::ShaderResource,
+ ResourceState::UnorderedAccess,
+ ResourceState::CopySource,
+ ResourceState::CopyDestination);
+
+ bufferAllowedStates.add(
+ ResourceState::VertexBuffer,
+ ResourceState::IndexBuffer,
+ ResourceState::ConstantBuffer,
+ ResourceState::StreamOutput,
+ ResourceState::IndirectArgument,
+ ResourceState::AccelerationStructure,
+ ResourceState::Undefined,
+ ResourceState::ShaderResource,
+ ResourceState::UnorderedAccess,
+ ResourceState::CopySource,
+ ResourceState::CopyDestination);
+
+ ResourceState currentState = ResourceState::CopySource;
+ ITextureResource::Extents extent;
+ extent.width = 4;
+ extent.height = 4;
+ extent.depth = 1;
+
+ ITextureResource::Desc texDesc = {};
+ texDesc.type = IResource::Type::Texture2D;
+ texDesc.numMipLevels = 1;
+ texDesc.arraySize = 1;
+ texDesc.size = extent;
+ texDesc.defaultState = currentState;
+ texDesc.allowedStates = formatSupportedStates & textureAllowedStates;
+ texDesc.memoryType = MemoryType::DeviceLocal;
+ texDesc.format = format;
- void supportedResourceStatesTestImpl(IDevice* device, UnitTestContext* context)
- {
- GetSupportedResourceStatesBase test;
- test.init(device, context);
- test.run();
+ GFX_CHECK_CALL_ABORT(
+ device->createTextureResource(texDesc, nullptr, texture.writeRef()));
+
+ IBufferResource::Desc bufferDesc = {};
+ bufferDesc.sizeInBytes = 256;
+ bufferDesc.format = gfx::Format::Unknown;
+ bufferDesc.elementSize = sizeof(float);
+ bufferDesc.allowedStates = formatSupportedStates & bufferAllowedStates;
+ bufferDesc.defaultState = currentState;
+ bufferDesc.memoryType = MemoryType::DeviceLocal;
+
+ GFX_CHECK_CALL_ABORT(
+ device->createBufferResource(bufferDesc, nullptr, buffer.writeRef()));
+
+ transitionResourceStates(device);
+ }
}
+};
+
+void supportedResourceStatesTestImpl(IDevice* device, UnitTestContext* context)
+{
+ GetSupportedResourceStatesBase test;
+ test.init(device, context);
+ test.run();
}
+} // namespace
namespace gfx_test
{
- SLANG_UNIT_TEST(getSupportedResourceStatesD3D12)
- {
- runTestImpl(supportedResourceStatesTestImpl, unitTestContext, Slang::RenderApiFlag::D3D12);
- }
+SLANG_UNIT_TEST(getSupportedResourceStatesD3D12)
+{
+ runTestImpl(supportedResourceStatesTestImpl, unitTestContext, Slang::RenderApiFlag::D3D12);
+}
- SLANG_UNIT_TEST(getSupportedResourceStatesVulkan)
- {
- runTestImpl(supportedResourceStatesTestImpl, unitTestContext, Slang::RenderApiFlag::Vulkan);
- }
+SLANG_UNIT_TEST(getSupportedResourceStatesVulkan)
+{
+ runTestImpl(supportedResourceStatesTestImpl, unitTestContext, Slang::RenderApiFlag::Vulkan);
}
+} // namespace gfx_test
diff --git a/tools/gfx-unit-test/get-texture-resource-handle-test.cpp b/tools/gfx-unit-test/get-texture-resource-handle-test.cpp
index 6b4862707..238d5a4fe 100644
--- a/tools/gfx-unit-test/get-texture-resource-handle-test.cpp
+++ b/tools/gfx-unit-test/get-texture-resource-handle-test.cpp
@@ -1,9 +1,8 @@
-#include "tools/unit-test/slang-unit-test.h"
-
-#include "slang-gfx.h"
#include "gfx-test-util.h"
-#include "tools/gfx-util/shader-cursor.h"
+#include "slang-gfx.h"
#include "source/core/slang-basic.h"
+#include "tools/gfx-util/shader-cursor.h"
+#include "tools/unit-test/slang-unit-test.h"
#if SLANG_WINDOWS_FAMILY
#include <d3d12.h>
@@ -13,90 +12,83 @@ using namespace gfx;
namespace gfx_test
{
- void getTextureResourceHandleTestImpl(IDevice* device, UnitTestContext* context)
- {
- ITextureResource::Desc desc = {};
- desc.type = IResource::Type::Texture2D;
- desc.numMipLevels = 1;
- desc.size.width = 1;
- desc.size.height = 1;
- desc.size.depth = 1;
- desc.defaultState = ResourceState::UnorderedAccess;
- desc.format = Format::R16G16B16A16_FLOAT;
+void getTextureResourceHandleTestImpl(IDevice* device, UnitTestContext* context)
+{
+ ITextureResource::Desc desc = {};
+ desc.type = IResource::Type::Texture2D;
+ desc.numMipLevels = 1;
+ desc.size.width = 1;
+ desc.size.height = 1;
+ desc.size.depth = 1;
+ desc.defaultState = ResourceState::UnorderedAccess;
+ desc.format = Format::R16G16B16A16_FLOAT;
- Slang::ComPtr<ITextureResource> buffer;
- buffer = device->createTextureResource(desc);
+ Slang::ComPtr<ITextureResource> buffer;
+ buffer = device->createTextureResource(desc);
- InteropHandle handle;
- GFX_CHECK_CALL_ABORT(buffer->getNativeResourceHandle(&handle));
- if (device->getDeviceInfo().deviceType == gfx::DeviceType::Vulkan)
- {
- SLANG_CHECK(handle.handleValue != 0);
- SLANG_CHECK(handle.api == InteropHandleAPI::Vulkan);
- }
+ InteropHandle handle;
+ GFX_CHECK_CALL_ABORT(buffer->getNativeResourceHandle(&handle));
+ if (device->getDeviceInfo().deviceType == gfx::DeviceType::Vulkan)
+ {
+ SLANG_CHECK(handle.handleValue != 0);
+ SLANG_CHECK(handle.api == InteropHandleAPI::Vulkan);
+ }
#if SLANG_WINDOWS_FAMILY
- else
- {
- SLANG_CHECK(handle.api == InteropHandleAPI::D3D12);
- auto d3d12Handle = (ID3D12Resource*)handle.handleValue;
- Slang::ComPtr<IUnknown> testHandle1;
- GFX_CHECK_CALL_ABORT(d3d12Handle->QueryInterface<IUnknown>(testHandle1.writeRef()));
- Slang::ComPtr<ID3D12Resource> testHandle2;
- GFX_CHECK_CALL_ABORT(testHandle1->QueryInterface<ID3D12Resource>(testHandle2.writeRef()));
- SLANG_CHECK(d3d12Handle == testHandle2.get());
- }
-#endif
+ else
+ {
+ SLANG_CHECK(handle.api == InteropHandleAPI::D3D12);
+ auto d3d12Handle = (ID3D12Resource*)handle.handleValue;
+ Slang::ComPtr<IUnknown> testHandle1;
+ GFX_CHECK_CALL_ABORT(d3d12Handle->QueryInterface<IUnknown>(testHandle1.writeRef()));
+ Slang::ComPtr<ID3D12Resource> testHandle2;
+ GFX_CHECK_CALL_ABORT(testHandle1->QueryInterface<ID3D12Resource>(testHandle2.writeRef()));
+ SLANG_CHECK(d3d12Handle == testHandle2.get());
}
+#endif
+}
- void getTextureResourceHandleTestAPI(UnitTestContext* context, Slang::RenderApiFlag::Enum api)
+void getTextureResourceHandleTestAPI(UnitTestContext* context, Slang::RenderApiFlag::Enum api)
+{
+ if ((api & context->enabledApis) == 0)
{
- if ((api & context->enabledApis) == 0)
- {
- SLANG_IGNORE_TEST;
- }
- Slang::ComPtr<IDevice> device;
- IDevice::Desc deviceDesc = {};
- switch (api)
- {
- case Slang::RenderApiFlag::D3D11:
- deviceDesc.deviceType = gfx::DeviceType::DirectX11;
- break;
- case Slang::RenderApiFlag::D3D12:
- deviceDesc.deviceType = gfx::DeviceType::DirectX12;
- break;
- case Slang::RenderApiFlag::Vulkan:
- deviceDesc.deviceType = gfx::DeviceType::Vulkan;
- break;
- default:
- SLANG_IGNORE_TEST;
- }
- deviceDesc.slang.slangGlobalSession = context->slangGlobalSession;
- const char* searchPaths[] = { "", "../../tools/gfx-unit-test", "tools/gfx-unit-test" };
- deviceDesc.slang.searchPathCount = (SlangInt)SLANG_COUNT_OF(searchPaths);
- deviceDesc.slang.searchPaths = searchPaths;
- auto createDeviceResult = gfxCreateDevice(&deviceDesc, device.writeRef());
- if (SLANG_FAILED(createDeviceResult))
- {
- SLANG_IGNORE_TEST;
- }
- // Ignore this test on swiftshader. Swiftshader seems to have a bug that causes the test
- // to crash.
- if (Slang::String(device->getDeviceInfo().adapterName).toLower().contains("swiftshader"))
- {
- SLANG_IGNORE_TEST;
- }
- getTextureResourceHandleTestImpl(device, context);
+ SLANG_IGNORE_TEST;
}
-
- SLANG_UNIT_TEST(getTextureResourceHandleD3D12)
+ Slang::ComPtr<IDevice> device;
+ IDevice::Desc deviceDesc = {};
+ switch (api)
{
- return getTextureResourceHandleTestAPI(unitTestContext, Slang::RenderApiFlag::D3D12);
+ case Slang::RenderApiFlag::D3D11: deviceDesc.deviceType = gfx::DeviceType::DirectX11; break;
+ case Slang::RenderApiFlag::D3D12: deviceDesc.deviceType = gfx::DeviceType::DirectX12; break;
+ case Slang::RenderApiFlag::Vulkan: deviceDesc.deviceType = gfx::DeviceType::Vulkan; break;
+ default: SLANG_IGNORE_TEST;
}
-
- SLANG_UNIT_TEST(getTextureResourceHandleVulkan)
+ deviceDesc.slang.slangGlobalSession = context->slangGlobalSession;
+ const char* searchPaths[] = {"", "../../tools/gfx-unit-test", "tools/gfx-unit-test"};
+ deviceDesc.slang.searchPathCount = (SlangInt)SLANG_COUNT_OF(searchPaths);
+ deviceDesc.slang.searchPaths = searchPaths;
+ auto createDeviceResult = gfxCreateDevice(&deviceDesc, device.writeRef());
+ if (SLANG_FAILED(createDeviceResult))
+ {
+ SLANG_IGNORE_TEST;
+ }
+ // Ignore this test on swiftshader. Swiftshader seems to have a bug that causes the test
+ // to crash.
+ if (Slang::String(device->getDeviceInfo().adapterName).toLower().contains("swiftshader"))
{
- return getTextureResourceHandleTestAPI(unitTestContext, Slang::RenderApiFlag::Vulkan);
+ SLANG_IGNORE_TEST;
}
+ getTextureResourceHandleTestImpl(device, context);
+}
+
+SLANG_UNIT_TEST(getTextureResourceHandleD3D12)
+{
+ return getTextureResourceHandleTestAPI(unitTestContext, Slang::RenderApiFlag::D3D12);
+}
+SLANG_UNIT_TEST(getTextureResourceHandleVulkan)
+{
+ return getTextureResourceHandleTestAPI(unitTestContext, Slang::RenderApiFlag::Vulkan);
}
+
+} // namespace gfx_test
diff --git a/tools/gfx-unit-test/gfx-test-texture-util.cpp b/tools/gfx-unit-test/gfx-test-texture-util.cpp
index 21e82ab22..a4f86d1d8 100644
--- a/tools/gfx-unit-test/gfx-test-texture-util.cpp
+++ b/tools/gfx-unit-test/gfx-test-texture-util.cpp
@@ -1,15 +1,15 @@
#include "gfx-test-texture-util.h"
-#include "gfx-test-util.h"
-#include "tools/unit-test/slang-unit-test.h"
+#include "gfx-test-util.h"
#include "slang-com-ptr.h"
+#include "tools/unit-test/slang-unit-test.h"
-#include <stdlib.h>
#include <stdio.h>
+#include <stdlib.h>
#ifdef _MSC_VER
#pragma warning(push)
-#pragma warning(disable: 4996)
+#pragma warning(disable : 4996)
#endif
#define STB_IMAGE_WRITE_IMPLEMENTATION
#include "external/stb/stb_image_write.h"
@@ -20,8 +20,9 @@
#define GFX_ENABLE_RENDERDOC_INTEGRATION 0
#if GFX_ENABLE_RENDERDOC_INTEGRATION
-# include "external/renderdoc_app.h"
-# include <windows.h>
+#include "external/renderdoc_app.h"
+
+#include <windows.h>
#endif
using namespace Slang;
@@ -29,232 +30,235 @@ using namespace gfx;
namespace gfx_test
{
- TextureAspect getTextureAspect(Format format)
+TextureAspect getTextureAspect(Format format)
+{
+ switch (format)
{
- switch (format)
- {
- case Format::D16_UNORM:
- case Format::D32_FLOAT:
- return TextureAspect::Depth;
- default:
- return TextureAspect::Color;
- }
+ case Format::D16_UNORM:
+ case Format::D32_FLOAT: return TextureAspect::Depth;
+ default: return TextureAspect::Color;
}
+}
- Size getTexelSize(Format format)
- {
- FormatInfo info;
- GFX_CHECK_CALL_ABORT(gfxGetFormatInfo(format, &info));
- return info.blockSizeInBytes / info.pixelsPerBlock;
- }
+Size getTexelSize(Format format)
+{
+ FormatInfo info;
+ GFX_CHECK_CALL_ABORT(gfxGetFormatInfo(format, &info));
+ return info.blockSizeInBytes / info.pixelsPerBlock;
+}
- GfxIndex getSubresourceIndex(GfxIndex mipLevel, GfxCount mipLevelCount, GfxIndex baseArrayLayer)
- {
- return baseArrayLayer * mipLevelCount + mipLevel;
- }
+GfxIndex getSubresourceIndex(GfxIndex mipLevel, GfxCount mipLevelCount, GfxIndex baseArrayLayer)
+{
+ return baseArrayLayer * mipLevelCount + mipLevel;
+}
- RefPtr<ValidationTextureFormatBase> getValidationTextureFormat(Format format)
+RefPtr<ValidationTextureFormatBase> getValidationTextureFormat(Format format)
+{
+ switch (format)
{
- switch (format)
- {
- case Format::R32G32B32A32_TYPELESS: return new ValidationTextureFormat<uint32_t>(4);
- case Format::R32G32B32_TYPELESS: return new ValidationTextureFormat<uint32_t>(3);
- case Format::R32G32_TYPELESS: return new ValidationTextureFormat<uint32_t>(2);
- case Format::R32_TYPELESS: return new ValidationTextureFormat<uint32_t>(1);
-
- case Format::R16G16B16A16_TYPELESS: return new ValidationTextureFormat<uint16_t>(4);
- case Format::R16G16_TYPELESS: return new ValidationTextureFormat<uint16_t>(2);
- case Format::R16_TYPELESS: return new ValidationTextureFormat<uint16_t>(1);
-
- case Format::R8G8B8A8_TYPELESS: return new ValidationTextureFormat<uint8_t>(4);
- case Format::R8G8_TYPELESS: return new ValidationTextureFormat<uint8_t>(2);
- case Format::R8_TYPELESS: return new ValidationTextureFormat<uint8_t>(1);
- case Format::B8G8R8A8_TYPELESS: return new ValidationTextureFormat<uint8_t>(4);
-
- case Format::R32G32B32A32_FLOAT: return new ValidationTextureFormat<float>(4);
- case Format::R32G32B32_FLOAT: return new ValidationTextureFormat<float>(3);
- case Format::R32G32_FLOAT: return new ValidationTextureFormat<float>(2);
- case Format::R32_FLOAT: return new ValidationTextureFormat<float>(1);
-
- case Format::R16G16B16A16_FLOAT: return new ValidationTextureFormat<uint16_t>(4);
- case Format::R16G16_FLOAT: return new ValidationTextureFormat<uint16_t>(2);
- case Format::R16_FLOAT: return new ValidationTextureFormat<uint16_t>(1);
-
- case Format::R64_UINT: return new ValidationTextureFormat<uint64_t>(1);
-
- case Format::R32G32B32A32_UINT: return new ValidationTextureFormat<uint32_t>(4);
- case Format::R32G32B32_UINT: return new ValidationTextureFormat<uint32_t>(3);
- case Format::R32G32_UINT: return new ValidationTextureFormat<uint32_t>(2);
- case Format::R32_UINT: return new ValidationTextureFormat<uint32_t>(1);
-
- case Format::R16G16B16A16_UINT: return new ValidationTextureFormat<uint16_t>(4);
- case Format::R16G16_UINT: return new ValidationTextureFormat<uint16_t>(2);
- case Format::R16_UINT: return new ValidationTextureFormat<uint16_t>(1);
-
- case Format::R8G8B8A8_UINT: return new ValidationTextureFormat<uint8_t>(4);
- case Format::R8G8_UINT: return new ValidationTextureFormat<uint8_t>(2);
- case Format::R8_UINT: return new ValidationTextureFormat<uint8_t>(1);
-
- case Format::R64_SINT: return new ValidationTextureFormat<int64_t>(1);
-
- case Format::R32G32B32A32_SINT: return new ValidationTextureFormat<int32_t>(4);
- case Format::R32G32B32_SINT: return new ValidationTextureFormat<int32_t>(3);
- case Format::R32G32_SINT: return new ValidationTextureFormat<int32_t>(2);
- case Format::R32_SINT: return new ValidationTextureFormat<int32_t>(1);
-
- case Format::R16G16B16A16_SINT: return new ValidationTextureFormat<int16_t>(4);
- case Format::R16G16_SINT: return new ValidationTextureFormat<int16_t>(2);
- case Format::R16_SINT: return new ValidationTextureFormat<int16_t>(1);
-
- case Format::R8G8B8A8_SINT: return new ValidationTextureFormat<int8_t>(4);
- case Format::R8G8_SINT: return new ValidationTextureFormat<int8_t>(2);
- case Format::R8_SINT: return new ValidationTextureFormat<int8_t>(1);
-
- case Format::R16G16B16A16_UNORM: return new ValidationTextureFormat<uint16_t>(4);
- case Format::R16G16_UNORM: return new ValidationTextureFormat<uint16_t>(2);
- case Format::R16_UNORM: return new ValidationTextureFormat<uint16_t>(1);
-
- case Format::R8G8B8A8_UNORM: return new ValidationTextureFormat<uint8_t>(4);
- case Format::R8G8B8A8_UNORM_SRGB: return new ValidationTextureFormat<uint8_t>(4);
- case Format::R8G8_UNORM: return new ValidationTextureFormat<uint8_t>(2);
- case Format::R8_UNORM: return new ValidationTextureFormat<uint8_t>(1);
- case Format::B8G8R8A8_UNORM: return new ValidationTextureFormat<uint8_t>(4);
- case Format::B8G8R8A8_UNORM_SRGB: return new ValidationTextureFormat<uint8_t>(4);
- case Format::B8G8R8X8_UNORM: return new ValidationTextureFormat<uint8_t>(3);
- case Format::B8G8R8X8_UNORM_SRGB: return new ValidationTextureFormat<uint8_t>(3);
-
- case Format::R16G16B16A16_SNORM: return new ValidationTextureFormat<int16_t>(4);
- case Format::R16G16_SNORM: return new ValidationTextureFormat<int16_t>(2);
- case Format::R16_SNORM: return new ValidationTextureFormat<int16_t>(1);
-
- case Format::R8G8B8A8_SNORM: return new ValidationTextureFormat<int8_t>(4);
- case Format::R8G8_SNORM: return new ValidationTextureFormat<int8_t>(2);
- case Format::R8_SNORM: return new ValidationTextureFormat<int8_t>(1);
-
- case Format::D32_FLOAT: return new ValidationTextureFormat<float>(1);
- case Format::D16_UNORM: return new ValidationTextureFormat<uint16_t>(1);
-
- case Format::B4G4R4A4_UNORM: return new PackedValidationTextureFormat<uint16_t>(4, 4, 4, 4);
- case Format::B5G6R5_UNORM: return new PackedValidationTextureFormat<uint16_t>(5, 6, 5, 0);
- case Format::B5G5R5A1_UNORM: return new PackedValidationTextureFormat<uint16_t>(5, 5, 5, 1);
-
- case Format::R9G9B9E5_SHAREDEXP: return new ValidationTextureFormat<uint32_t>(1);
- case Format::R10G10B10A2_TYPELESS: return new PackedValidationTextureFormat<uint32_t>(10, 10, 10, 2);
- case Format::R10G10B10A2_UNORM: return new PackedValidationTextureFormat<uint32_t>(10, 10, 10, 2);
- case Format::R10G10B10A2_UINT: return new PackedValidationTextureFormat<uint32_t>(10, 10, 10, 2);
- case Format::R11G11B10_FLOAT: return new PackedValidationTextureFormat<uint32_t>(11, 11, 10, 0);
-
- // TODO: Add testing support for BC formats
-// BC1_UNORM,
-// BC1_UNORM_SRGB,
-// BC2_UNORM,
-// BC2_UNORM_SRGB,
-// BC3_UNORM,
-// BC3_UNORM_SRGB,
-// BC4_UNORM,
-// BC4_SNORM,
-// BC5_UNORM,
-// BC5_SNORM,
-// BC6H_UF16,
-// BC6H_SF16,
-// BC7_UNORM,
-// BC7_UNORM_SRGB,
- default:
- return nullptr;
- }
+ case Format::R32G32B32A32_TYPELESS: return new ValidationTextureFormat<uint32_t>(4);
+ case Format::R32G32B32_TYPELESS: return new ValidationTextureFormat<uint32_t>(3);
+ case Format::R32G32_TYPELESS: return new ValidationTextureFormat<uint32_t>(2);
+ case Format::R32_TYPELESS: return new ValidationTextureFormat<uint32_t>(1);
+
+ case Format::R16G16B16A16_TYPELESS: return new ValidationTextureFormat<uint16_t>(4);
+ case Format::R16G16_TYPELESS: return new ValidationTextureFormat<uint16_t>(2);
+ case Format::R16_TYPELESS: return new ValidationTextureFormat<uint16_t>(1);
+
+ case Format::R8G8B8A8_TYPELESS: return new ValidationTextureFormat<uint8_t>(4);
+ case Format::R8G8_TYPELESS: return new ValidationTextureFormat<uint8_t>(2);
+ case Format::R8_TYPELESS: return new ValidationTextureFormat<uint8_t>(1);
+ case Format::B8G8R8A8_TYPELESS: return new ValidationTextureFormat<uint8_t>(4);
+
+ case Format::R32G32B32A32_FLOAT: return new ValidationTextureFormat<float>(4);
+ case Format::R32G32B32_FLOAT: return new ValidationTextureFormat<float>(3);
+ case Format::R32G32_FLOAT: return new ValidationTextureFormat<float>(2);
+ case Format::R32_FLOAT: return new ValidationTextureFormat<float>(1);
+
+ case Format::R16G16B16A16_FLOAT: return new ValidationTextureFormat<uint16_t>(4);
+ case Format::R16G16_FLOAT: return new ValidationTextureFormat<uint16_t>(2);
+ case Format::R16_FLOAT: return new ValidationTextureFormat<uint16_t>(1);
+
+ case Format::R64_UINT: return new ValidationTextureFormat<uint64_t>(1);
+
+ case Format::R32G32B32A32_UINT: return new ValidationTextureFormat<uint32_t>(4);
+ case Format::R32G32B32_UINT: return new ValidationTextureFormat<uint32_t>(3);
+ case Format::R32G32_UINT: return new ValidationTextureFormat<uint32_t>(2);
+ case Format::R32_UINT: return new ValidationTextureFormat<uint32_t>(1);
+
+ case Format::R16G16B16A16_UINT: return new ValidationTextureFormat<uint16_t>(4);
+ case Format::R16G16_UINT: return new ValidationTextureFormat<uint16_t>(2);
+ case Format::R16_UINT: return new ValidationTextureFormat<uint16_t>(1);
+
+ case Format::R8G8B8A8_UINT: return new ValidationTextureFormat<uint8_t>(4);
+ case Format::R8G8_UINT: return new ValidationTextureFormat<uint8_t>(2);
+ case Format::R8_UINT: return new ValidationTextureFormat<uint8_t>(1);
+
+ case Format::R64_SINT: return new ValidationTextureFormat<int64_t>(1);
+
+ case Format::R32G32B32A32_SINT: return new ValidationTextureFormat<int32_t>(4);
+ case Format::R32G32B32_SINT: return new ValidationTextureFormat<int32_t>(3);
+ case Format::R32G32_SINT: return new ValidationTextureFormat<int32_t>(2);
+ case Format::R32_SINT: return new ValidationTextureFormat<int32_t>(1);
+
+ case Format::R16G16B16A16_SINT: return new ValidationTextureFormat<int16_t>(4);
+ case Format::R16G16_SINT: return new ValidationTextureFormat<int16_t>(2);
+ case Format::R16_SINT: return new ValidationTextureFormat<int16_t>(1);
+
+ case Format::R8G8B8A8_SINT: return new ValidationTextureFormat<int8_t>(4);
+ case Format::R8G8_SINT: return new ValidationTextureFormat<int8_t>(2);
+ case Format::R8_SINT: return new ValidationTextureFormat<int8_t>(1);
+
+ case Format::R16G16B16A16_UNORM: return new ValidationTextureFormat<uint16_t>(4);
+ case Format::R16G16_UNORM: return new ValidationTextureFormat<uint16_t>(2);
+ case Format::R16_UNORM: return new ValidationTextureFormat<uint16_t>(1);
+
+ case Format::R8G8B8A8_UNORM: return new ValidationTextureFormat<uint8_t>(4);
+ case Format::R8G8B8A8_UNORM_SRGB: return new ValidationTextureFormat<uint8_t>(4);
+ case Format::R8G8_UNORM: return new ValidationTextureFormat<uint8_t>(2);
+ case Format::R8_UNORM: return new ValidationTextureFormat<uint8_t>(1);
+ case Format::B8G8R8A8_UNORM: return new ValidationTextureFormat<uint8_t>(4);
+ case Format::B8G8R8A8_UNORM_SRGB: return new ValidationTextureFormat<uint8_t>(4);
+ case Format::B8G8R8X8_UNORM: return new ValidationTextureFormat<uint8_t>(3);
+ case Format::B8G8R8X8_UNORM_SRGB: return new ValidationTextureFormat<uint8_t>(3);
+
+ case Format::R16G16B16A16_SNORM: return new ValidationTextureFormat<int16_t>(4);
+ case Format::R16G16_SNORM: return new ValidationTextureFormat<int16_t>(2);
+ case Format::R16_SNORM: return new ValidationTextureFormat<int16_t>(1);
+
+ case Format::R8G8B8A8_SNORM: return new ValidationTextureFormat<int8_t>(4);
+ case Format::R8G8_SNORM: return new ValidationTextureFormat<int8_t>(2);
+ case Format::R8_SNORM: return new ValidationTextureFormat<int8_t>(1);
+
+ case Format::D32_FLOAT: return new ValidationTextureFormat<float>(1);
+ case Format::D16_UNORM: return new ValidationTextureFormat<uint16_t>(1);
+
+ case Format::B4G4R4A4_UNORM: return new PackedValidationTextureFormat<uint16_t>(4, 4, 4, 4);
+ case Format::B5G6R5_UNORM: return new PackedValidationTextureFormat<uint16_t>(5, 6, 5, 0);
+ case Format::B5G5R5A1_UNORM: return new PackedValidationTextureFormat<uint16_t>(5, 5, 5, 1);
+
+ case Format::R9G9B9E5_SHAREDEXP: return new ValidationTextureFormat<uint32_t>(1);
+ case Format::R10G10B10A2_TYPELESS:
+ return new PackedValidationTextureFormat<uint32_t>(10, 10, 10, 2);
+ case Format::R10G10B10A2_UNORM:
+ return new PackedValidationTextureFormat<uint32_t>(10, 10, 10, 2);
+ case Format::R10G10B10A2_UINT:
+ return new PackedValidationTextureFormat<uint32_t>(10, 10, 10, 2);
+ case Format::R11G11B10_FLOAT:
+ return new PackedValidationTextureFormat<uint32_t>(11, 11, 10, 0);
+
+ // TODO: Add testing support for BC formats
+ // BC1_UNORM,
+ // BC1_UNORM_SRGB,
+ // BC2_UNORM,
+ // BC2_UNORM_SRGB,
+ // BC3_UNORM,
+ // BC3_UNORM_SRGB,
+ // BC4_UNORM,
+ // BC4_SNORM,
+ // BC5_UNORM,
+ // BC5_SNORM,
+ // BC6H_UF16,
+ // BC6H_SF16,
+ // BC7_UNORM,
+ // BC7_UNORM_SRGB,
+ default: return nullptr;
}
+}
- void generateTextureData(RefPtr<TextureInfo> texture, ValidationTextureFormatBase* validationFormat)
- {
- auto extents = texture->extents;
- auto arrayLayers = texture->arrayLayerCount;
- auto mipLevels = texture->mipLevelCount;
- auto texelSize = getTexelSize(texture->format);
+void generateTextureData(RefPtr<TextureInfo> texture, ValidationTextureFormatBase* validationFormat)
+{
+ auto extents = texture->extents;
+ auto arrayLayers = texture->arrayLayerCount;
+ auto mipLevels = texture->mipLevelCount;
+ auto texelSize = getTexelSize(texture->format);
- for (GfxIndex layer = 0; layer < arrayLayers; ++layer)
+ for (GfxIndex layer = 0; layer < arrayLayers; ++layer)
+ {
+ for (GfxIndex mip = 0; mip < mipLevels; ++mip)
{
- for (GfxIndex mip = 0; mip < mipLevels; ++mip)
+ RefPtr<ValidationTextureData> subresource = new ValidationTextureData();
+
+ auto mipWidth = Math::Max(extents.width >> mip, 1);
+ auto mipHeight = Math::Max(extents.height >> mip, 1);
+ auto mipDepth = Math::Max(extents.depth >> mip, 1);
+ auto mipSize = mipWidth * mipHeight * mipDepth * texelSize;
+ subresource->textureData = malloc(mipSize);
+ SLANG_CHECK_ABORT(subresource->textureData);
+
+ subresource->extents.width = mipWidth;
+ subresource->extents.height = mipHeight;
+ subresource->extents.depth = mipDepth;
+ subresource->strides.x = texelSize;
+ subresource->strides.y = mipWidth * texelSize;
+ subresource->strides.z = mipHeight * subresource->strides.y;
+ texture->subresourceObjects.add(subresource);
+
+ for (int z = 0; z < mipDepth; ++z)
{
- RefPtr<ValidationTextureData> subresource = new ValidationTextureData();
-
- auto mipWidth = Math::Max(extents.width >> mip, 1);
- auto mipHeight = Math::Max(extents.height >> mip, 1);
- auto mipDepth = Math::Max(extents.depth >> mip, 1);
- auto mipSize = mipWidth * mipHeight * mipDepth * texelSize;
- subresource->textureData = malloc(mipSize);
- SLANG_CHECK_ABORT(subresource->textureData);
-
- subresource->extents.width = mipWidth;
- subresource->extents.height = mipHeight;
- subresource->extents.depth = mipDepth;
- subresource->strides.x = texelSize;
- subresource->strides.y = mipWidth * texelSize;
- subresource->strides.z = mipHeight * subresource->strides.y;
- texture->subresourceObjects.add(subresource);
-
- for (int z = 0; z < mipDepth; ++z)
+ for (int y = 0; y < mipHeight; ++y)
{
- for (int y = 0; y < mipHeight; ++y)
+ for (int x = 0; x < mipWidth; ++x)
{
- for (int x = 0; x < mipWidth; ++x)
- {
- auto texel = subresource->getBlockAt(x, y, z);
- validationFormat->initializeTexel(texel, x, y, z, mip, layer);
- }
+ auto texel = subresource->getBlockAt(x, y, z);
+ validationFormat->initializeTexel(texel, x, y, z, mip, layer);
}
}
-
- ITextureResource::SubresourceData subData = {};
- subData.data = subresource->textureData;
- subData.strideY = subresource->strides.y;
- subData.strideZ = subresource->strides.z;
- texture->subresourceDatas.add(subData);
}
+
+ ITextureResource::SubresourceData subData = {};
+ subData.data = subresource->textureData;
+ subData.strideY = subresource->strides.y;
+ subData.strideZ = subresource->strides.z;
+ texture->subresourceDatas.add(subData);
}
}
+}
- List<uint8_t> removePadding(ISlangBlob* pixels, GfxCount width, GfxCount height, Size rowPitch, Size pixelSize)
+List<uint8_t> removePadding(
+ ISlangBlob* pixels,
+ GfxCount width,
+ GfxCount height,
+ Size rowPitch,
+ Size pixelSize)
+{
+ List<uint8_t> buffer;
+ buffer.setCount(height * rowPitch);
+ for (GfxIndex i = 0; i < height; ++i)
{
- List<uint8_t> buffer;
- buffer.setCount(height * rowPitch);
- for (GfxIndex i = 0; i < height; ++i)
- {
- Offset srcOffset = i * rowPitch;
- Offset dstOffset = i * width * pixelSize;
- memcpy(buffer.getBuffer() + dstOffset, (char*)pixels->getBufferPointer() + srcOffset, width * pixelSize);
- }
-
- return buffer;
+ Offset srcOffset = i * rowPitch;
+ Offset dstOffset = i * width * pixelSize;
+ memcpy(
+ buffer.getBuffer() + dstOffset,
+ (char*)pixels->getBufferPointer() + srcOffset,
+ width * pixelSize);
}
- Slang::Result writeImage(
- const char* filename,
- ISlangBlob* pixels,
- uint32_t width,
- uint32_t height)
- {
- int stbResult =
- stbi_write_hdr(filename, width, height, 4, (float*)pixels->getBufferPointer());
+ return buffer;
+}
- return stbResult ? SLANG_OK : SLANG_FAIL;
- }
+Slang::Result writeImage(const char* filename, ISlangBlob* pixels, uint32_t width, uint32_t height)
+{
+ int stbResult = stbi_write_hdr(filename, width, height, 4, (float*)pixels->getBufferPointer());
- Slang::Result writeImage(
- const char* filename,
- ISlangBlob* pixels,
- uint32_t width,
- uint32_t height,
- uint32_t rowPitch,
- uint32_t pixelSize)
- {
- if (rowPitch == width * pixelSize)
- return writeImage(filename, pixels, width, height);
+ return stbResult ? SLANG_OK : SLANG_FAIL;
+}
- List<uint8_t> buffer = removePadding(pixels, width, height, rowPitch, pixelSize);
+Slang::Result writeImage(
+ const char* filename,
+ ISlangBlob* pixels,
+ uint32_t width,
+ uint32_t height,
+ uint32_t rowPitch,
+ uint32_t pixelSize)
+{
+ if (rowPitch == width * pixelSize)
+ return writeImage(filename, pixels, width, height);
- int stbResult =
- stbi_write_hdr(filename, width, height, 4, (float*)buffer.getBuffer());
+ List<uint8_t> buffer = removePadding(pixels, width, height, rowPitch, pixelSize);
- return stbResult ? SLANG_OK : SLANG_FAIL;
- }
+ int stbResult = stbi_write_hdr(filename, width, height, 4, (float*)buffer.getBuffer());
+
+ return stbResult ? SLANG_OK : SLANG_FAIL;
}
+} // namespace gfx_test
diff --git a/tools/gfx-unit-test/gfx-test-texture-util.h b/tools/gfx-unit-test/gfx-test-texture-util.h
index 7069ff667..7c6b9443f 100644
--- a/tools/gfx-unit-test/gfx-test-texture-util.h
+++ b/tools/gfx-unit-test/gfx-test-texture-util.h
@@ -10,187 +10,205 @@ using namespace gfx;
namespace gfx_test
{
- struct Strides
- {
- Size x;
- Size y;
- Size z;
- };
+struct Strides
+{
+ Size x;
+ Size y;
+ Size z;
+};
- struct ValidationTextureFormatBase : RefObject
- {
- virtual void validateBlocksEqual(const void* actual, const void* expected) = 0;
+struct ValidationTextureFormatBase : RefObject
+{
+ virtual void validateBlocksEqual(const void* actual, const void* expected) = 0;
+
+ virtual void initializeTexel(
+ void* texel,
+ GfxIndex x,
+ GfxIndex y,
+ GfxIndex z,
+ GfxIndex mipLevel,
+ GfxIndex arrayLayer) = 0;
+};
+
+template<typename T>
+struct ValidationTextureFormat : ValidationTextureFormatBase
+{
+ int componentCount;
- virtual void initializeTexel(void* texel, GfxIndex x, GfxIndex y, GfxIndex z, GfxIndex mipLevel, GfxIndex arrayLayer) = 0;
- };
+ ValidationTextureFormat(int componentCount)
+ : componentCount(componentCount){};
- template <typename T>
- struct ValidationTextureFormat : ValidationTextureFormatBase
+ virtual void validateBlocksEqual(const void* actual, const void* expected) override
{
- int componentCount;
-
- ValidationTextureFormat(int componentCount) : componentCount(componentCount) {};
+ auto a = (const T*)actual;
+ auto e = (const T*)expected;
- virtual void validateBlocksEqual(const void* actual, const void* expected) override
+ for (Int i = 0; i < componentCount; ++i)
{
- auto a = (const T*)actual;
- auto e = (const T*)expected;
-
- for (Int i = 0; i < componentCount; ++i)
- {
- SLANG_CHECK(a[i] == e[i]);
- }
+ SLANG_CHECK(a[i] == e[i]);
}
+ }
+
+ virtual void initializeTexel(
+ void* texel,
+ GfxIndex x,
+ GfxIndex y,
+ GfxIndex z,
+ GfxIndex mipLevel,
+ GfxIndex arrayLayer) override
+ {
+ auto temp = (T*)texel;
- virtual void initializeTexel(void* texel, GfxIndex x, GfxIndex y, GfxIndex z, GfxIndex mipLevel, GfxIndex arrayLayer) override
+ switch (componentCount)
{
- auto temp = (T*)texel;
-
- switch (componentCount)
- {
- case 1:
- temp[0] = T(x + y + z + mipLevel + arrayLayer);
- break;
- case 2:
- temp[0] = T(x + z + arrayLayer);
- temp[1] = T(y + mipLevel);
- break;
- case 3:
- temp[0] = T(x + mipLevel);
- temp[1] = T(y + arrayLayer);
- temp[2] = T(z);
- break;
- case 4:
- temp[0] = T(x + arrayLayer);
- temp[1] = (T)y;
- temp[2] = (T)z;
- temp[3] = (T)mipLevel;
- break;
- default:
- assert(!"component count should be no greater than 4");
- SLANG_CHECK_ABORT(false);
- }
+ case 1: temp[0] = T(x + y + z + mipLevel + arrayLayer); break;
+ case 2:
+ temp[0] = T(x + z + arrayLayer);
+ temp[1] = T(y + mipLevel);
+ break;
+ case 3:
+ temp[0] = T(x + mipLevel);
+ temp[1] = T(y + arrayLayer);
+ temp[2] = T(z);
+ break;
+ case 4:
+ temp[0] = T(x + arrayLayer);
+ temp[1] = (T)y;
+ temp[2] = (T)z;
+ temp[3] = (T)mipLevel;
+ break;
+ default: assert(!"component count should be no greater than 4"); SLANG_CHECK_ABORT(false);
}
- };
+ }
+};
- template <typename T>
- struct PackedValidationTextureFormat : ValidationTextureFormatBase
- {
- int rBits;
- int gBits;
- int bBits;
- int aBits;
+template<typename T>
+struct PackedValidationTextureFormat : ValidationTextureFormatBase
+{
+ int rBits;
+ int gBits;
+ int bBits;
+ int aBits;
+
+ PackedValidationTextureFormat(int rBits, int gBits, int bBits, int aBits)
+ : rBits(rBits), gBits(gBits), bBits(bBits), aBits(aBits){};
- PackedValidationTextureFormat(int rBits, int gBits, int bBits, int aBits)
- : rBits(rBits), gBits(gBits), bBits(bBits), aBits(aBits) {};
+ virtual void validateBlocksEqual(const void* actual, const void* expected) override
+ {
+ T a[4];
+ T e[4];
+ unpackTexel(*(const T*)actual, a);
+ unpackTexel(*(const T*)expected, e);
- virtual void validateBlocksEqual(const void* actual, const void* expected) override
+ for (Int i = 0; i < 4; ++i)
{
- T a[4];
- T e[4];
- unpackTexel(*(const T*)actual, a);
- unpackTexel(*(const T*)expected, e);
-
- for (Int i = 0; i < 4; ++i)
- {
- SLANG_CHECK(a[i] == e[i]);
- }
+ SLANG_CHECK(a[i] == e[i]);
}
+ }
+
+ virtual void initializeTexel(
+ void* texel,
+ GfxIndex x,
+ GfxIndex y,
+ GfxIndex z,
+ GfxIndex mipLevel,
+ GfxIndex arrayLayer) override
+ {
+ T temp = 0;
- virtual void initializeTexel(void* texel, GfxIndex x, GfxIndex y, GfxIndex z, GfxIndex mipLevel, GfxIndex arrayLayer) override
+ // The only formats which currently use this have either 3 or 4 channels. TODO: BC formats?
+ if (aBits == 0)
{
- T temp = 0;
-
- // The only formats which currently use this have either 3 or 4 channels. TODO: BC formats?
- if (aBits == 0)
- {
- temp |= z;
- temp <<= gBits;
- temp |= (y + arrayLayer);
- temp <<= rBits;
- temp |= (x + mipLevel);
- }
- else
- {
- temp |= mipLevel;
- temp <<= bBits;
- temp |= z;
- temp <<= gBits;
- temp |= y;
- temp <<= rBits;
- temp |= (x + arrayLayer);
- }
-
- *(T*)texel = temp;
+ temp |= z;
+ temp <<= gBits;
+ temp |= (y + arrayLayer);
+ temp <<= rBits;
+ temp |= (x + mipLevel);
}
-
- void unpackTexel(T texel, T* outComponents)
+ else
{
- outComponents[0] = texel & ((1 << rBits) - 1);
- texel >>= rBits;
+ temp |= mipLevel;
+ temp <<= bBits;
+ temp |= z;
+ temp <<= gBits;
+ temp |= y;
+ temp <<= rBits;
+ temp |= (x + arrayLayer);
+ }
- outComponents[1] = texel & ((1 << gBits) - 1);
- texel >>= gBits;
+ *(T*)texel = temp;
+ }
- outComponents[2] = texel & ((1 << bBits) - 1);
- texel >>= bBits;
+ void unpackTexel(T texel, T* outComponents)
+ {
+ outComponents[0] = texel & ((1 << rBits) - 1);
+ texel >>= rBits;
- outComponents[3] = texel & ((1 << aBits) - 1);
- texel >>= aBits;
- }
- };
+ outComponents[1] = texel & ((1 << gBits) - 1);
+ texel >>= gBits;
- // Struct containing texture data and information for a specific subresource.
- struct ValidationTextureData : RefObject
- {
- const void* textureData;
- ITextureResource::Extents extents;
- Strides strides;
+ outComponents[2] = texel & ((1 << bBits) - 1);
+ texel >>= bBits;
- void* getBlockAt(GfxIndex x, GfxIndex y, GfxIndex z)
- {
- assert(x >= 0 && x < extents.width);
- assert(y >= 0 && y < extents.height);
- assert(z >= 0 && z < extents.depth);
+ outComponents[3] = texel & ((1 << aBits) - 1);
+ texel >>= aBits;
+ }
+};
- char* layerData = (char*)textureData + z * strides.z;
- char* rowData = layerData + y * strides.y;
- return rowData + x * strides.x;
- }
- };
+// Struct containing texture data and information for a specific subresource.
+struct ValidationTextureData : RefObject
+{
+ const void* textureData;
+ ITextureResource::Extents extents;
+ Strides strides;
- // Struct containing relevant information for a texture, including a list of its subresources
- // and all relevant information for each subresource.
- struct TextureInfo : RefObject
+ void* getBlockAt(GfxIndex x, GfxIndex y, GfxIndex z)
{
- Format format;
- ITextureResource::Type textureType;
-
- ITextureResource::Extents extents;
- GfxCount mipLevelCount;
- GfxCount arrayLayerCount;
-
- List<RefPtr<ValidationTextureData>> subresourceObjects;
- List<ITextureResource::SubresourceData> subresourceDatas;
- };
-
- TextureAspect getTextureAspect(Format format);
- Size getTexelSize(Format format);
- GfxIndex getSubresourceIndex(GfxIndex mipLevel, GfxCount mipLevelCount, GfxIndex baseArrayLayer);
- RefPtr<ValidationTextureFormatBase> getValidationTextureFormat(Format format);
- void generateTextureData(RefPtr<TextureInfo> texture, ValidationTextureFormatBase* validationFormat);
-
- List<uint8_t> removePadding(ISlangBlob* pixels, GfxCount width, GfxCount height, Size rowPitch, Size pixelSize);
- Slang::Result writeImage(
- const char* filename,
- ISlangBlob* pixels,
- uint32_t width,
- uint32_t height);
- Slang::Result writeImage(
- const char* filename,
- ISlangBlob* pixels,
- uint32_t width,
- uint32_t height,
- uint32_t rowPitch,
- uint32_t pixelSize);
-}
+ assert(x >= 0 && x < extents.width);
+ assert(y >= 0 && y < extents.height);
+ assert(z >= 0 && z < extents.depth);
+
+ char* layerData = (char*)textureData + z * strides.z;
+ char* rowData = layerData + y * strides.y;
+ return rowData + x * strides.x;
+ }
+};
+
+// Struct containing relevant information for a texture, including a list of its subresources
+// and all relevant information for each subresource.
+struct TextureInfo : RefObject
+{
+ Format format;
+ ITextureResource::Type textureType;
+
+ ITextureResource::Extents extents;
+ GfxCount mipLevelCount;
+ GfxCount arrayLayerCount;
+
+ List<RefPtr<ValidationTextureData>> subresourceObjects;
+ List<ITextureResource::SubresourceData> subresourceDatas;
+};
+
+TextureAspect getTextureAspect(Format format);
+Size getTexelSize(Format format);
+GfxIndex getSubresourceIndex(GfxIndex mipLevel, GfxCount mipLevelCount, GfxIndex baseArrayLayer);
+RefPtr<ValidationTextureFormatBase> getValidationTextureFormat(Format format);
+void generateTextureData(
+ RefPtr<TextureInfo> texture,
+ ValidationTextureFormatBase* validationFormat);
+
+List<uint8_t> removePadding(
+ ISlangBlob* pixels,
+ GfxCount width,
+ GfxCount height,
+ Size rowPitch,
+ Size pixelSize);
+Slang::Result writeImage(const char* filename, ISlangBlob* pixels, uint32_t width, uint32_t height);
+Slang::Result writeImage(
+ const char* filename,
+ ISlangBlob* pixels,
+ uint32_t width,
+ uint32_t height,
+ uint32_t rowPitch,
+ uint32_t pixelSize);
+} // namespace gfx_test
diff --git a/tools/gfx-unit-test/gfx-test-util.cpp b/tools/gfx-unit-test/gfx-test-util.cpp
index 1c7289325..18aaabdaf 100644
--- a/tools/gfx-unit-test/gfx-test-util.cpp
+++ b/tools/gfx-unit-test/gfx-test-util.cpp
@@ -1,350 +1,360 @@
#include "gfx-test-util.h"
-#include "tools/unit-test/slang-unit-test.h"
#include "slang-com-ptr.h"
+#include "tools/unit-test/slang-unit-test.h"
#define GFX_ENABLE_RENDERDOC_INTEGRATION 0
#define GFX_ENABLE_SPIRV_DEBUG 0
#if GFX_ENABLE_RENDERDOC_INTEGRATION
-# include "external/renderdoc_app.h"
-# include <windows.h>
+#include "external/renderdoc_app.h"
+
+#include <windows.h>
#endif
using Slang::ComPtr;
namespace gfx_test
{
- void diagnoseIfNeeded(slang::IBlob* diagnosticsBlob)
+void diagnoseIfNeeded(slang::IBlob* diagnosticsBlob)
+{
+ if (diagnosticsBlob != nullptr)
{
- if (diagnosticsBlob != nullptr)
- {
- getTestReporter()->message(TestMessageType::Info, (const char*)diagnosticsBlob->getBufferPointer());
- }
+ getTestReporter()->message(
+ TestMessageType::Info,
+ (const char*)diagnosticsBlob->getBufferPointer());
}
+}
- Slang::Result loadComputeProgram(
- gfx::IDevice* device,
- Slang::ComPtr<gfx::IShaderProgram>& outShaderProgram,
- const char* shaderModuleName,
- const char* entryPointName,
- slang::ProgramLayout*& slangReflection)
- {
- Slang::ComPtr<slang::ISession> slangSession;
- SLANG_RETURN_ON_FAIL(device->getSlangSession(slangSession.writeRef()));
- Slang::ComPtr<slang::IBlob> diagnosticsBlob;
- slang::IModule* module = slangSession->loadModule(shaderModuleName, diagnosticsBlob.writeRef());
- diagnoseIfNeeded(diagnosticsBlob);
- if (!module)
- return SLANG_FAIL;
-
- ComPtr<slang::IEntryPoint> computeEntryPoint;
- SLANG_RETURN_ON_FAIL(
- module->findEntryPointByName(entryPointName, computeEntryPoint.writeRef()));
-
- Slang::List<slang::IComponentType*> componentTypes;
- componentTypes.add(module);
- componentTypes.add(computeEntryPoint);
-
- Slang::ComPtr<slang::IComponentType> composedProgram;
- SlangResult result = slangSession->createCompositeComponentType(
- componentTypes.getBuffer(),
- componentTypes.getCount(),
- composedProgram.writeRef(),
- diagnosticsBlob.writeRef());
- diagnoseIfNeeded(diagnosticsBlob);
- SLANG_RETURN_ON_FAIL(result);
-
- ComPtr<slang::IComponentType> linkedProgram;
- result = composedProgram->link(linkedProgram.writeRef(), diagnosticsBlob.writeRef());
- diagnoseIfNeeded(diagnosticsBlob);
- SLANG_RETURN_ON_FAIL(result);
-
- composedProgram = linkedProgram;
- slangReflection = composedProgram->getLayout();
-
- gfx::IShaderProgram::Desc programDesc = {};
- programDesc.slangGlobalScope = composedProgram.get();
-
- auto shaderProgram = device->createProgram(programDesc);
-
- outShaderProgram = shaderProgram;
- return SLANG_OK;
- }
+Slang::Result loadComputeProgram(
+ gfx::IDevice* device,
+ Slang::ComPtr<gfx::IShaderProgram>& outShaderProgram,
+ const char* shaderModuleName,
+ const char* entryPointName,
+ slang::ProgramLayout*& slangReflection)
+{
+ Slang::ComPtr<slang::ISession> slangSession;
+ SLANG_RETURN_ON_FAIL(device->getSlangSession(slangSession.writeRef()));
+ Slang::ComPtr<slang::IBlob> diagnosticsBlob;
+ slang::IModule* module = slangSession->loadModule(shaderModuleName, diagnosticsBlob.writeRef());
+ diagnoseIfNeeded(diagnosticsBlob);
+ if (!module)
+ return SLANG_FAIL;
+
+ ComPtr<slang::IEntryPoint> computeEntryPoint;
+ SLANG_RETURN_ON_FAIL(
+ module->findEntryPointByName(entryPointName, computeEntryPoint.writeRef()));
+
+ Slang::List<slang::IComponentType*> componentTypes;
+ componentTypes.add(module);
+ componentTypes.add(computeEntryPoint);
+
+ Slang::ComPtr<slang::IComponentType> composedProgram;
+ SlangResult result = slangSession->createCompositeComponentType(
+ componentTypes.getBuffer(),
+ componentTypes.getCount(),
+ composedProgram.writeRef(),
+ diagnosticsBlob.writeRef());
+ diagnoseIfNeeded(diagnosticsBlob);
+ SLANG_RETURN_ON_FAIL(result);
+
+ ComPtr<slang::IComponentType> linkedProgram;
+ result = composedProgram->link(linkedProgram.writeRef(), diagnosticsBlob.writeRef());
+ diagnoseIfNeeded(diagnosticsBlob);
+ SLANG_RETURN_ON_FAIL(result);
+
+ composedProgram = linkedProgram;
+ slangReflection = composedProgram->getLayout();
+
+ gfx::IShaderProgram::Desc programDesc = {};
+ programDesc.slangGlobalScope = composedProgram.get();
+
+ auto shaderProgram = device->createProgram(programDesc);
+
+ outShaderProgram = shaderProgram;
+ return SLANG_OK;
+}
- Slang::Result loadComputeProgram(
- gfx::IDevice* device,
- slang::ISession* slangSession,
- Slang::ComPtr<gfx::IShaderProgram>& outShaderProgram,
- const char* shaderModuleName,
- const char* entryPointName,
- slang::ProgramLayout*& slangReflection)
- {
- Slang::ComPtr<slang::IBlob> diagnosticsBlob;
- slang::IModule* module = slangSession->loadModule(shaderModuleName, diagnosticsBlob.writeRef());
- diagnoseIfNeeded(diagnosticsBlob);
- if (!module)
- return SLANG_FAIL;
-
- ComPtr<slang::IEntryPoint> computeEntryPoint;
- SLANG_RETURN_ON_FAIL(
- module->findEntryPointByName(entryPointName, computeEntryPoint.writeRef()));
-
- Slang::List<slang::IComponentType*> componentTypes;
- componentTypes.add(module);
- componentTypes.add(computeEntryPoint);
-
- Slang::ComPtr<slang::IComponentType> composedProgram;
- SlangResult result = slangSession->createCompositeComponentType(
- componentTypes.getBuffer(),
- componentTypes.getCount(),
- composedProgram.writeRef(),
- diagnosticsBlob.writeRef());
- diagnoseIfNeeded(diagnosticsBlob);
- SLANG_RETURN_ON_FAIL(result);
-
- ComPtr<slang::IComponentType> linkedProgram;
- result = composedProgram->link(linkedProgram.writeRef(), diagnosticsBlob.writeRef());
- diagnoseIfNeeded(diagnosticsBlob);
- SLANG_RETURN_ON_FAIL(result);
-
- composedProgram = linkedProgram;
- slangReflection = composedProgram->getLayout();
-
- gfx::IShaderProgram::Desc programDesc = {};
- programDesc.slangGlobalScope = composedProgram.get();
-
- auto shaderProgram = device->createProgram(programDesc);
-
- outShaderProgram = shaderProgram;
- return SLANG_OK;
- }
+Slang::Result loadComputeProgram(
+ gfx::IDevice* device,
+ slang::ISession* slangSession,
+ Slang::ComPtr<gfx::IShaderProgram>& outShaderProgram,
+ const char* shaderModuleName,
+ const char* entryPointName,
+ slang::ProgramLayout*& slangReflection)
+{
+ Slang::ComPtr<slang::IBlob> diagnosticsBlob;
+ slang::IModule* module = slangSession->loadModule(shaderModuleName, diagnosticsBlob.writeRef());
+ diagnoseIfNeeded(diagnosticsBlob);
+ if (!module)
+ return SLANG_FAIL;
+
+ ComPtr<slang::IEntryPoint> computeEntryPoint;
+ SLANG_RETURN_ON_FAIL(
+ module->findEntryPointByName(entryPointName, computeEntryPoint.writeRef()));
+
+ Slang::List<slang::IComponentType*> componentTypes;
+ componentTypes.add(module);
+ componentTypes.add(computeEntryPoint);
+
+ Slang::ComPtr<slang::IComponentType> composedProgram;
+ SlangResult result = slangSession->createCompositeComponentType(
+ componentTypes.getBuffer(),
+ componentTypes.getCount(),
+ composedProgram.writeRef(),
+ diagnosticsBlob.writeRef());
+ diagnoseIfNeeded(diagnosticsBlob);
+ SLANG_RETURN_ON_FAIL(result);
+
+ ComPtr<slang::IComponentType> linkedProgram;
+ result = composedProgram->link(linkedProgram.writeRef(), diagnosticsBlob.writeRef());
+ diagnoseIfNeeded(diagnosticsBlob);
+ SLANG_RETURN_ON_FAIL(result);
+
+ composedProgram = linkedProgram;
+ slangReflection = composedProgram->getLayout();
+
+ gfx::IShaderProgram::Desc programDesc = {};
+ programDesc.slangGlobalScope = composedProgram.get();
+
+ auto shaderProgram = device->createProgram(programDesc);
+
+ outShaderProgram = shaderProgram;
+ return SLANG_OK;
+}
- Slang::Result loadComputeProgramFromSource(
- gfx::IDevice* device,
- Slang::ComPtr<gfx::IShaderProgram>& outShaderProgram,
- Slang::String source)
- {
- Slang::ComPtr<slang::IBlob> diagnosticsBlob;
+Slang::Result loadComputeProgramFromSource(
+ gfx::IDevice* device,
+ Slang::ComPtr<gfx::IShaderProgram>& outShaderProgram,
+ Slang::String source)
+{
+ Slang::ComPtr<slang::IBlob> diagnosticsBlob;
- gfx::IShaderProgram::CreateDesc2 programDesc = {};
- programDesc.sourceType = gfx::ShaderModuleSourceType::SlangSource;
- programDesc.sourceData = (void*)source.getBuffer();
- programDesc.sourceDataSize = source.getLength();
+ gfx::IShaderProgram::CreateDesc2 programDesc = {};
+ programDesc.sourceType = gfx::ShaderModuleSourceType::SlangSource;
+ programDesc.sourceData = (void*)source.getBuffer();
+ programDesc.sourceDataSize = source.getLength();
- return device->createProgram2(programDesc, outShaderProgram.writeRef(), diagnosticsBlob.writeRef());
- }
+ return device->createProgram2(
+ programDesc,
+ outShaderProgram.writeRef(),
+ diagnosticsBlob.writeRef());
+}
- Slang::Result loadGraphicsProgram(
- gfx::IDevice* device,
- Slang::ComPtr<gfx::IShaderProgram>& outShaderProgram,
- const char* shaderModuleName,
- const char* vertexEntryPointName,
- const char* fragmentEntryPointName,
- slang::ProgramLayout*& slangReflection)
- {
- Slang::ComPtr<slang::ISession> slangSession;
- SLANG_RETURN_ON_FAIL(device->getSlangSession(slangSession.writeRef()));
- Slang::ComPtr<slang::IBlob> diagnosticsBlob;
- slang::IModule* module = slangSession->loadModule(shaderModuleName, diagnosticsBlob.writeRef());
- diagnoseIfNeeded(diagnosticsBlob);
- if (!module)
- return SLANG_FAIL;
-
- ComPtr<slang::IEntryPoint> vertexEntryPoint;
- SLANG_RETURN_ON_FAIL(
- module->findEntryPointByName(vertexEntryPointName, vertexEntryPoint.writeRef()));
-
- ComPtr<slang::IEntryPoint> fragmentEntryPoint;
- SLANG_RETURN_ON_FAIL(
- module->findEntryPointByName(fragmentEntryPointName, fragmentEntryPoint.writeRef()));
-
- Slang::List<slang::IComponentType*> componentTypes;
- componentTypes.add(module);
- componentTypes.add(vertexEntryPoint);
- componentTypes.add(fragmentEntryPoint);
-
- Slang::ComPtr<slang::IComponentType> composedProgram;
- SlangResult result = slangSession->createCompositeComponentType(
- componentTypes.getBuffer(),
- componentTypes.getCount(),
- composedProgram.writeRef(),
- diagnosticsBlob.writeRef());
- diagnoseIfNeeded(diagnosticsBlob);
- SLANG_RETURN_ON_FAIL(result);
- slangReflection = composedProgram->getLayout();
-
- gfx::IShaderProgram::Desc programDesc = {};
- programDesc.slangGlobalScope = composedProgram.get();
-
- auto shaderProgram = device->createProgram(programDesc);
-
- outShaderProgram = shaderProgram;
- return SLANG_OK;
- }
+Slang::Result loadGraphicsProgram(
+ gfx::IDevice* device,
+ Slang::ComPtr<gfx::IShaderProgram>& outShaderProgram,
+ const char* shaderModuleName,
+ const char* vertexEntryPointName,
+ const char* fragmentEntryPointName,
+ slang::ProgramLayout*& slangReflection)
+{
+ Slang::ComPtr<slang::ISession> slangSession;
+ SLANG_RETURN_ON_FAIL(device->getSlangSession(slangSession.writeRef()));
+ Slang::ComPtr<slang::IBlob> diagnosticsBlob;
+ slang::IModule* module = slangSession->loadModule(shaderModuleName, diagnosticsBlob.writeRef());
+ diagnoseIfNeeded(diagnosticsBlob);
+ if (!module)
+ return SLANG_FAIL;
+
+ ComPtr<slang::IEntryPoint> vertexEntryPoint;
+ SLANG_RETURN_ON_FAIL(
+ module->findEntryPointByName(vertexEntryPointName, vertexEntryPoint.writeRef()));
+
+ ComPtr<slang::IEntryPoint> fragmentEntryPoint;
+ SLANG_RETURN_ON_FAIL(
+ module->findEntryPointByName(fragmentEntryPointName, fragmentEntryPoint.writeRef()));
+
+ Slang::List<slang::IComponentType*> componentTypes;
+ componentTypes.add(module);
+ componentTypes.add(vertexEntryPoint);
+ componentTypes.add(fragmentEntryPoint);
+
+ Slang::ComPtr<slang::IComponentType> composedProgram;
+ SlangResult result = slangSession->createCompositeComponentType(
+ componentTypes.getBuffer(),
+ componentTypes.getCount(),
+ composedProgram.writeRef(),
+ diagnosticsBlob.writeRef());
+ diagnoseIfNeeded(diagnosticsBlob);
+ SLANG_RETURN_ON_FAIL(result);
+ slangReflection = composedProgram->getLayout();
+
+ gfx::IShaderProgram::Desc programDesc = {};
+ programDesc.slangGlobalScope = composedProgram.get();
+
+ auto shaderProgram = device->createProgram(programDesc);
+
+ outShaderProgram = shaderProgram;
+ return SLANG_OK;
+}
- void compareComputeResult(
- gfx::IDevice* device,
- gfx::ITextureResource* texture,
- gfx::ResourceState state,
- void* expectedResult,
- size_t expectedResultRowPitch,
- size_t rowCount)
+void compareComputeResult(
+ gfx::IDevice* device,
+ gfx::ITextureResource* texture,
+ gfx::ResourceState state,
+ void* expectedResult,
+ size_t expectedResultRowPitch,
+ size_t rowCount)
+{
+ // Read back the results.
+ ComPtr<ISlangBlob> resultBlob;
+ size_t rowPitch = 0;
+ size_t pixelSize = 0;
+ GFX_CHECK_CALL_ABORT(
+ device->readTextureResource(texture, state, resultBlob.writeRef(), &rowPitch, &pixelSize));
+ // Compare results.
+ for (size_t row = 0; row < rowCount; row++)
{
- // Read back the results.
- ComPtr<ISlangBlob> resultBlob;
- size_t rowPitch = 0;
- size_t pixelSize = 0;
- GFX_CHECK_CALL_ABORT(device->readTextureResource(
- texture, state, resultBlob.writeRef(), &rowPitch, &pixelSize));
- // Compare results.
- for (size_t row = 0; row < rowCount; row++)
- {
- SLANG_CHECK(
- memcmp(
- (uint8_t*)resultBlob->getBufferPointer() + rowPitch * row,
- (uint8_t*)expectedResult + expectedResultRowPitch * row,
- expectedResultRowPitch) == 0);
- }
+ SLANG_CHECK(
+ memcmp(
+ (uint8_t*)resultBlob->getBufferPointer() + rowPitch * row,
+ (uint8_t*)expectedResult + expectedResultRowPitch * row,
+ expectedResultRowPitch) == 0);
}
+}
- void compareComputeResult(gfx::IDevice* device, gfx::IBufferResource* buffer, size_t offset, const void* expectedResult, size_t expectedBufferSize)
- {
- // Read back the results.
- ComPtr<ISlangBlob> resultBlob;
- GFX_CHECK_CALL_ABORT(device->readBufferResource(
- buffer, offset, expectedBufferSize, resultBlob.writeRef()));
- SLANG_CHECK(resultBlob->getBufferSize() == expectedBufferSize);
- // Compare results.
- SLANG_CHECK(memcmp(resultBlob->getBufferPointer(), (uint8_t*)expectedResult, expectedBufferSize) == 0);
- }
+void compareComputeResult(
+ gfx::IDevice* device,
+ gfx::IBufferResource* buffer,
+ size_t offset,
+ const void* expectedResult,
+ size_t expectedBufferSize)
+{
+ // Read back the results.
+ ComPtr<ISlangBlob> resultBlob;
+ GFX_CHECK_CALL_ABORT(
+ device->readBufferResource(buffer, offset, expectedBufferSize, resultBlob.writeRef()));
+ SLANG_CHECK(resultBlob->getBufferSize() == expectedBufferSize);
+ // Compare results.
+ SLANG_CHECK(
+ memcmp(resultBlob->getBufferPointer(), (uint8_t*)expectedResult, expectedBufferSize) == 0);
+}
- void compareComputeResultFuzzy(const float* result, float* expectedResult, size_t expectedBufferSize)
+void compareComputeResultFuzzy(
+ const float* result,
+ float* expectedResult,
+ size_t expectedBufferSize)
+{
+ for (size_t i = 0; i < expectedBufferSize / sizeof(float); ++i)
{
- for (size_t i = 0; i < expectedBufferSize / sizeof(float); ++i)
- {
- SLANG_CHECK(abs(result[i] - expectedResult[i]) <= 0.01);
- }
+ SLANG_CHECK(abs(result[i] - expectedResult[i]) <= 0.01);
}
+}
- void compareComputeResultFuzzy(gfx::IDevice* device, gfx::IBufferResource* buffer, float* expectedResult, size_t expectedBufferSize)
- {
- // Read back the results.
- ComPtr<ISlangBlob> resultBlob;
- GFX_CHECK_CALL_ABORT(device->readBufferResource(
- buffer, 0, expectedBufferSize, resultBlob.writeRef()));
- SLANG_CHECK(resultBlob->getBufferSize() == expectedBufferSize);
- // Compare results with a tolerance of 0.01.
- auto result = (float*)resultBlob->getBufferPointer();
- compareComputeResultFuzzy(result, expectedResult, expectedBufferSize);
- }
+void compareComputeResultFuzzy(
+ gfx::IDevice* device,
+ gfx::IBufferResource* buffer,
+ float* expectedResult,
+ size_t expectedBufferSize)
+{
+ // Read back the results.
+ ComPtr<ISlangBlob> resultBlob;
+ GFX_CHECK_CALL_ABORT(
+ device->readBufferResource(buffer, 0, expectedBufferSize, resultBlob.writeRef()));
+ SLANG_CHECK(resultBlob->getBufferSize() == expectedBufferSize);
+ // Compare results with a tolerance of 0.01.
+ auto result = (float*)resultBlob->getBufferPointer();
+ compareComputeResultFuzzy(result, expectedResult, expectedBufferSize);
+}
- Slang::ComPtr<gfx::IDevice> createTestingDevice(
- UnitTestContext* context,
- Slang::RenderApiFlag::Enum api,
- Slang::List<const char*> additionalSearchPaths,
- gfx::IDevice::ShaderCacheDesc shaderCache)
+Slang::ComPtr<gfx::IDevice> createTestingDevice(
+ UnitTestContext* context,
+ Slang::RenderApiFlag::Enum api,
+ Slang::List<const char*> additionalSearchPaths,
+ gfx::IDevice::ShaderCacheDesc shaderCache)
+{
+ Slang::ComPtr<gfx::IDevice> device;
+ gfx::IDevice::Desc deviceDesc = {};
+ switch (api)
{
- Slang::ComPtr<gfx::IDevice> device;
- gfx::IDevice::Desc deviceDesc = {};
- switch (api)
- {
- case Slang::RenderApiFlag::D3D11:
- deviceDesc.deviceType = gfx::DeviceType::DirectX11;
- break;
- case Slang::RenderApiFlag::D3D12:
- deviceDesc.deviceType = gfx::DeviceType::DirectX12;
- break;
- case Slang::RenderApiFlag::Vulkan:
- deviceDesc.deviceType = gfx::DeviceType::Vulkan;
- break;
- case Slang::RenderApiFlag::CPU:
- deviceDesc.deviceType = gfx::DeviceType::CPU;
- break;
- case Slang::RenderApiFlag::CUDA:
- deviceDesc.deviceType = gfx::DeviceType::CUDA;
- break;
- default:
- SLANG_IGNORE_TEST
- }
- deviceDesc.slang.slangGlobalSession = context->slangGlobalSession;
- Slang::List<const char*> searchPaths = getSlangSearchPaths();
- searchPaths.addRange(additionalSearchPaths);
- deviceDesc.slang.searchPaths = searchPaths.getBuffer();
- deviceDesc.slang.searchPathCount = (gfx::GfxCount)searchPaths.getCount();
- deviceDesc.shaderCache = shaderCache;
-
- gfx::D3D12DeviceExtendedDesc extDesc = {};
- extDesc.rootParameterShaderAttributeName = "root";
-
- gfx::SlangSessionExtendedDesc slangExtDesc = {};
- Slang::List<slang::CompilerOptionEntry> entries;
- slang::CompilerOptionEntry emitSpirvDirectlyEntry;
- emitSpirvDirectlyEntry.name = slang::CompilerOptionName::EmitSpirvDirectly;
- emitSpirvDirectlyEntry.value.intValue0 = 1;
- entries.add(emitSpirvDirectlyEntry);
+ case Slang::RenderApiFlag::D3D11: deviceDesc.deviceType = gfx::DeviceType::DirectX11; break;
+ case Slang::RenderApiFlag::D3D12: deviceDesc.deviceType = gfx::DeviceType::DirectX12; break;
+ case Slang::RenderApiFlag::Vulkan: deviceDesc.deviceType = gfx::DeviceType::Vulkan; break;
+ case Slang::RenderApiFlag::CPU: deviceDesc.deviceType = gfx::DeviceType::CPU; break;
+ case Slang::RenderApiFlag::CUDA: deviceDesc.deviceType = gfx::DeviceType::CUDA; break;
+ default: SLANG_IGNORE_TEST
+ }
+ deviceDesc.slang.slangGlobalSession = context->slangGlobalSession;
+ Slang::List<const char*> searchPaths = getSlangSearchPaths();
+ searchPaths.addRange(additionalSearchPaths);
+ deviceDesc.slang.searchPaths = searchPaths.getBuffer();
+ deviceDesc.slang.searchPathCount = (gfx::GfxCount)searchPaths.getCount();
+ deviceDesc.shaderCache = shaderCache;
+
+ gfx::D3D12DeviceExtendedDesc extDesc = {};
+ extDesc.rootParameterShaderAttributeName = "root";
+
+ gfx::SlangSessionExtendedDesc slangExtDesc = {};
+ Slang::List<slang::CompilerOptionEntry> entries;
+ slang::CompilerOptionEntry emitSpirvDirectlyEntry;
+ emitSpirvDirectlyEntry.name = slang::CompilerOptionName::EmitSpirvDirectly;
+ emitSpirvDirectlyEntry.value.intValue0 = 1;
+ entries.add(emitSpirvDirectlyEntry);
#if GFX_ENABLE_SPIRV_DEBUG
- slang::CompilerOptionEntry debugLevelCompilerOptionEntry;
- debugLevelCompilerOptionEntry.name = slang::CompilerOptionName::DebugInformation;
- debugLevelCompilerOptionEntry.value.intValue0 = SLANG_DEBUG_INFO_LEVEL_STANDARD;
- entries.add(debugLevelCompilerOptionEntry);
+ slang::CompilerOptionEntry debugLevelCompilerOptionEntry;
+ debugLevelCompilerOptionEntry.name = slang::CompilerOptionName::DebugInformation;
+ debugLevelCompilerOptionEntry.value.intValue0 = SLANG_DEBUG_INFO_LEVEL_STANDARD;
+ entries.add(debugLevelCompilerOptionEntry);
#endif
- slangExtDesc.compilerOptionEntries = entries.getBuffer();
- slangExtDesc.compilerOptionEntryCount = (uint32_t)entries.getCount();
+ slangExtDesc.compilerOptionEntries = entries.getBuffer();
+ slangExtDesc.compilerOptionEntryCount = (uint32_t)entries.getCount();
- deviceDesc.extendedDescCount = 2;
- void* extDescPtrs[2] = { &extDesc, &slangExtDesc };
- deviceDesc.extendedDescs = extDescPtrs;
+ deviceDesc.extendedDescCount = 2;
+ void* extDescPtrs[2] = {&extDesc, &slangExtDesc};
+ deviceDesc.extendedDescs = extDescPtrs;
- // TODO: We should also set the debug callback
- // (And in general reduce the differences (and duplication) between
- // here and render-test-main.cpp)
+ // TODO: We should also set the debug callback
+ // (And in general reduce the differences (and duplication) between
+ // here and render-test-main.cpp)
#ifdef _DEBUG
- gfx::gfxEnableDebugLayer();
+ gfx::gfxEnableDebugLayer();
#endif
- auto createDeviceResult = gfxCreateDevice(&deviceDesc, device.writeRef());
- if (SLANG_FAILED(createDeviceResult))
- {
- SLANG_IGNORE_TEST
- }
- return device;
- }
-
- Slang::List<const char*> getSlangSearchPaths()
+ auto createDeviceResult = gfxCreateDevice(&deviceDesc, device.writeRef());
+ if (SLANG_FAILED(createDeviceResult))
{
- Slang::List<const char*> searchPaths;
- searchPaths.add("");
- searchPaths.add("../../tools/gfx-unit-test");
- searchPaths.add("tools/gfx-unit-test");
- return searchPaths;
+ SLANG_IGNORE_TEST
}
+ return device;
+}
+
+Slang::List<const char*> getSlangSearchPaths()
+{
+ Slang::List<const char*> searchPaths;
+ searchPaths.add("");
+ searchPaths.add("../../tools/gfx-unit-test");
+ searchPaths.add("tools/gfx-unit-test");
+ return searchPaths;
+}
#if GFX_ENABLE_RENDERDOC_INTEGRATION
- RENDERDOC_API_1_1_2* rdoc_api = NULL;
- void initializeRenderDoc()
- {
- if (HMODULE mod = GetModuleHandleA("renderdoc.dll"))
- {
- pRENDERDOC_GetAPI RENDERDOC_GetAPI =
- (pRENDERDOC_GetAPI)GetProcAddress(mod, "RENDERDOC_GetAPI");
- int ret = RENDERDOC_GetAPI(eRENDERDOC_API_Version_1_1_2, (void**)&rdoc_api);
- assert(ret == 1);
- }
- }
- void renderDocBeginFrame()
- {
- if (!rdoc_api) initializeRenderDoc();
- if (rdoc_api) rdoc_api->StartFrameCapture(nullptr, nullptr);
- }
- void renderDocEndFrame()
+RENDERDOC_API_1_1_2* rdoc_api = NULL;
+void initializeRenderDoc()
+{
+ if (HMODULE mod = GetModuleHandleA("renderdoc.dll"))
{
- if (rdoc_api)
- rdoc_api->EndFrameCapture(nullptr, nullptr);
- _fgetchar();
+ pRENDERDOC_GetAPI RENDERDOC_GetAPI =
+ (pRENDERDOC_GetAPI)GetProcAddress(mod, "RENDERDOC_GetAPI");
+ int ret = RENDERDOC_GetAPI(eRENDERDOC_API_Version_1_1_2, (void**)&rdoc_api);
+ assert(ret == 1);
}
+}
+void renderDocBeginFrame()
+{
+ if (!rdoc_api)
+ initializeRenderDoc();
+ if (rdoc_api)
+ rdoc_api->StartFrameCapture(nullptr, nullptr);
+}
+void renderDocEndFrame()
+{
+ if (rdoc_api)
+ rdoc_api->EndFrameCapture(nullptr, nullptr);
+ _fgetchar();
+}
#else
- void initializeRenderDoc() {}
- void renderDocBeginFrame() {}
- void renderDocEndFrame() {}
+void initializeRenderDoc() {}
+void renderDocBeginFrame() {}
+void renderDocEndFrame() {}
#endif
-}
+} // namespace gfx_test
diff --git a/tools/gfx-unit-test/gfx-test-util.h b/tools/gfx-unit-test/gfx-test-util.h
index 643830413..51b1feb1f 100644
--- a/tools/gfx-unit-test/gfx-test-util.h
+++ b/tools/gfx-unit-test/gfx-test-util.h
@@ -7,137 +7,143 @@
namespace gfx_test
{
- /// Helper function for print out diagnostic messages output by Slang compiler.
- void diagnoseIfNeeded(slang::IBlob* diagnosticsBlob);
-
- /// Loads a compute shader module and produces a `gfx::IShaderProgram`.
- Slang::Result loadComputeProgram(
- gfx::IDevice* device,
- Slang::ComPtr<gfx::IShaderProgram>& outShaderProgram,
- const char* shaderModuleName,
- const char* entryPointName,
- slang::ProgramLayout*& slangReflection);
-
- Slang::Result loadComputeProgram(
- gfx::IDevice* device,
- slang::ISession* slangSession,
- Slang::ComPtr<gfx::IShaderProgram>& outShaderProgram,
- const char* shaderModuleName,
- const char* entryPointName,
- slang::ProgramLayout*& slangReflection);
-
- Slang::Result loadComputeProgramFromSource(
- gfx::IDevice* device,
- Slang::ComPtr<gfx::IShaderProgram>& outShaderProgram,
- Slang::String source);
-
- Slang::Result loadGraphicsProgram(
- gfx::IDevice* device,
- Slang::ComPtr<gfx::IShaderProgram>& outShaderProgram,
- const char* shaderModuleName,
- const char* vertexEntryPointName,
- const char* fragmentEntryPointName,
- slang::ProgramLayout*& slangReflection);
-
- /// Reads back the content of `buffer` and compares it against `expectedResult`.
- void compareComputeResult(
- gfx::IDevice* device,
- gfx::IBufferResource* buffer,
- size_t offset,
- const void* expectedResult,
- size_t expectedBufferSize);
-
- /// Reads back the content of `texture` and compares it against `expectedResult`.
- void compareComputeResult(
- gfx::IDevice* device,
- gfx::ITextureResource* texture,
- gfx::ResourceState state,
- void* expectedResult,
- size_t expectedResultRowPitch,
- size_t rowCount);
-
- void compareComputeResultFuzzy(
- const float* result,
- float* expectedResult,
- size_t expectedBufferSize);
-
- /// Reads back the content of `buffer` and compares it against `expectedResult` with a set tolerance.
- void compareComputeResultFuzzy(
- gfx::IDevice* device,
- gfx::IBufferResource* buffer,
- float* expectedResult,
- size_t expectedBufferSize);
-
- template<typename T, Slang::Index count>
- void compareComputeResult(
- gfx::IDevice* device,
- gfx::IBufferResource* buffer,
- Slang::Array<T, count> expectedResult)
+/// Helper function for print out diagnostic messages output by Slang compiler.
+void diagnoseIfNeeded(slang::IBlob* diagnosticsBlob);
+
+/// Loads a compute shader module and produces a `gfx::IShaderProgram`.
+Slang::Result loadComputeProgram(
+ gfx::IDevice* device,
+ Slang::ComPtr<gfx::IShaderProgram>& outShaderProgram,
+ const char* shaderModuleName,
+ const char* entryPointName,
+ slang::ProgramLayout*& slangReflection);
+
+Slang::Result loadComputeProgram(
+ gfx::IDevice* device,
+ slang::ISession* slangSession,
+ Slang::ComPtr<gfx::IShaderProgram>& outShaderProgram,
+ const char* shaderModuleName,
+ const char* entryPointName,
+ slang::ProgramLayout*& slangReflection);
+
+Slang::Result loadComputeProgramFromSource(
+ gfx::IDevice* device,
+ Slang::ComPtr<gfx::IShaderProgram>& outShaderProgram,
+ Slang::String source);
+
+Slang::Result loadGraphicsProgram(
+ gfx::IDevice* device,
+ Slang::ComPtr<gfx::IShaderProgram>& outShaderProgram,
+ const char* shaderModuleName,
+ const char* vertexEntryPointName,
+ const char* fragmentEntryPointName,
+ slang::ProgramLayout*& slangReflection);
+
+/// Reads back the content of `buffer` and compares it against `expectedResult`.
+void compareComputeResult(
+ gfx::IDevice* device,
+ gfx::IBufferResource* buffer,
+ size_t offset,
+ const void* expectedResult,
+ size_t expectedBufferSize);
+
+/// Reads back the content of `texture` and compares it against `expectedResult`.
+void compareComputeResult(
+ gfx::IDevice* device,
+ gfx::ITextureResource* texture,
+ gfx::ResourceState state,
+ void* expectedResult,
+ size_t expectedResultRowPitch,
+ size_t rowCount);
+
+void compareComputeResultFuzzy(
+ const float* result,
+ float* expectedResult,
+ size_t expectedBufferSize);
+
+/// Reads back the content of `buffer` and compares it against `expectedResult` with a set
+/// tolerance.
+void compareComputeResultFuzzy(
+ gfx::IDevice* device,
+ gfx::IBufferResource* buffer,
+ float* expectedResult,
+ size_t expectedBufferSize);
+
+template<typename T, Slang::Index count>
+void compareComputeResult(
+ gfx::IDevice* device,
+ gfx::IBufferResource* buffer,
+ Slang::Array<T, count> expectedResult)
+{
+ Slang::List<uint8_t> expectedBuffer;
+ size_t bufferSize = sizeof(T) * count;
+ expectedBuffer.setCount(bufferSize);
+ memcpy(expectedBuffer.getBuffer(), expectedResult.begin(), bufferSize);
+ if (std::is_same<T, float>::value)
+ return compareComputeResultFuzzy(
+ device,
+ buffer,
+ (float*)expectedBuffer.getBuffer(),
+ bufferSize);
+ return compareComputeResult(device, buffer, 0, expectedBuffer.getBuffer(), bufferSize);
+}
+
+Slang::ComPtr<gfx::IDevice> createTestingDevice(
+ UnitTestContext* context,
+ Slang::RenderApiFlag::Enum api,
+ Slang::List<const char*> additionalSearchPaths = {},
+ gfx::IDevice::ShaderCacheDesc shaderCache = {});
+
+Slang::List<const char*> getSlangSearchPaths();
+
+void initializeRenderDoc();
+void renderDocBeginFrame();
+void renderDocEndFrame();
+
+template<typename ImplFunc>
+void runTestImpl(
+ const ImplFunc& f,
+ UnitTestContext* context,
+ Slang::RenderApiFlag::Enum api,
+ Slang::List<const char*> searchPaths = {},
+ gfx::IDevice::ShaderCacheDesc shaderCache = {})
+{
+ if ((api & context->enabledApis) == 0)
{
- Slang::List<uint8_t> expectedBuffer;
- size_t bufferSize = sizeof(T) * count;
- expectedBuffer.setCount(bufferSize);
- memcpy(expectedBuffer.getBuffer(), expectedResult.begin(), bufferSize);
- if (std::is_same<T, float>::value) return compareComputeResultFuzzy(device, buffer, (float*)expectedBuffer.getBuffer(), bufferSize);
- return compareComputeResult(device, buffer, 0, expectedBuffer.getBuffer(), bufferSize);
+ SLANG_IGNORE_TEST
}
-
- Slang::ComPtr<gfx::IDevice> createTestingDevice(
- UnitTestContext* context,
- Slang::RenderApiFlag::Enum api,
- Slang::List<const char*> additionalSearchPaths = {},
- gfx::IDevice::ShaderCacheDesc shaderCache = {});
-
- Slang::List<const char*> getSlangSearchPaths();
-
- void initializeRenderDoc();
- void renderDocBeginFrame();
- void renderDocEndFrame();
-
- template<typename ImplFunc>
- void runTestImpl(
- const ImplFunc& f,
- UnitTestContext* context,
- Slang::RenderApiFlag::Enum api,
- Slang::List<const char*> searchPaths = {},
- gfx::IDevice::ShaderCacheDesc shaderCache = {})
+ auto device = createTestingDevice(context, api, searchPaths, shaderCache);
+ if (!device)
{
- if ((api & context->enabledApis) == 0)
- {
- SLANG_IGNORE_TEST
- }
- auto device = createTestingDevice(context, api, searchPaths, shaderCache);
- if (!device)
- {
- SLANG_IGNORE_TEST
- }
+ SLANG_IGNORE_TEST
+ }
#if SLANG_WIN32
- // Skip d3d12 tests on x86 now since dxc doesn't function correctly there on Windows 11.
- if (api == Slang::RenderApiFlag::D3D12)
- {
- SLANG_IGNORE_TEST
- }
+ // Skip d3d12 tests on x86 now since dxc doesn't function correctly there on Windows 11.
+ if (api == Slang::RenderApiFlag::D3D12)
+ {
+ SLANG_IGNORE_TEST
+ }
#endif
- // Skip d3d11 tests when we don't have DXBC support as they're bound to
- // fail without a backend compiler
- if (api == Slang::RenderApiFlag::D3D11 && !SLANG_ENABLE_DXBC_SUPPORT)
- {
- SLANG_IGNORE_TEST
- }
- try
- {
- renderDocBeginFrame();
- f(device, context);
- }
- catch (AbortTestException& e)
- {
- renderDocEndFrame();
- throw e;
- }
+ // Skip d3d11 tests when we don't have DXBC support as they're bound to
+ // fail without a backend compiler
+ if (api == Slang::RenderApiFlag::D3D11 && !SLANG_ENABLE_DXBC_SUPPORT)
+ {
+ SLANG_IGNORE_TEST
+ }
+ try
+ {
+ renderDocBeginFrame();
+ f(device, context);
+ }
+ catch (AbortTestException& e)
+ {
renderDocEndFrame();
+ throw e;
}
+ renderDocEndFrame();
+}
#define GFX_CHECK_CALL(x) SLANG_CHECK(!SLANG_FAILED(x))
#define GFX_CHECK_CALL_ABORT(x) SLANG_CHECK_ABORT(!SLANG_FAILED(x))
-}
+} // namespace gfx_test
diff --git a/tools/gfx-unit-test/instanced-draw-tests.cpp b/tools/gfx-unit-test/instanced-draw-tests.cpp
index 6491e8944..adb1a1df1 100644
--- a/tools/gfx-unit-test/instanced-draw-tests.cpp
+++ b/tools/gfx-unit-test/instanced-draw-tests.cpp
@@ -1,550 +1,604 @@
-#include "tools/unit-test/slang-unit-test.h"
-
-#include "slang-gfx.h"
#include "gfx-test-util.h"
-#include "tools/gfx-util/shader-cursor.h"
+#include "slang-gfx.h"
#include "source/core/slang-basic.h"
+#include "tools/gfx-util/shader-cursor.h"
+#include "tools/unit-test/slang-unit-test.h"
using namespace gfx;
namespace gfx_test
{
- struct Vertex
- {
- float position[3];
- };
-
- struct Instance
- {
- float position[3];
- float color[3];
- };
+struct Vertex
+{
+ float position[3];
+};
- static const int kVertexCount = 6;
- static const Vertex kVertexData[kVertexCount] =
- {
- // Triangle 1
- { 0, 0, 0.5 },
- { 1, 0, 0.5 },
- { 0, 1, 0.5 },
-
- // Triangle 2
- { -1, 0, 0.5 },
- { 0, 0, 0.5 },
- { -1, 1, 0.5 },
- };
+struct Instance
+{
+ float position[3];
+ float color[3];
+};
+
+static const int kVertexCount = 6;
+static const Vertex kVertexData[kVertexCount] = {
+ // Triangle 1
+ {0, 0, 0.5},
+ {1, 0, 0.5},
+ {0, 1, 0.5},
+
+ // Triangle 2
+ {-1, 0, 0.5},
+ {0, 0, 0.5},
+ {-1, 1, 0.5},
+};
+
+static const int kInstanceCount = 2;
+static const Instance kInstanceData[kInstanceCount] = {
+ {{0, 0, 0}, {1, 0, 0}},
+ {{0, -1, 0}, {0, 0, 1}},
+};
+
+static const int kIndexCount = 6;
+static const uint32_t kIndexData[kIndexCount] = {
+ 0,
+ 2,
+ 5,
+ 0,
+ 1,
+ 2,
+};
+
+const int kWidth = 256;
+const int kHeight = 256;
+const Format format = Format::R32G32B32A32_FLOAT;
+
+ComPtr<IBufferResource> createVertexBuffer(IDevice* device)
+{
+ IBufferResource::Desc vertexBufferDesc;
+ vertexBufferDesc.type = IResource::Type::Buffer;
+ vertexBufferDesc.sizeInBytes = kVertexCount * sizeof(Vertex);
+ vertexBufferDesc.defaultState = ResourceState::VertexBuffer;
+ vertexBufferDesc.allowedStates = ResourceState::VertexBuffer;
+ ComPtr<IBufferResource> vertexBuffer =
+ device->createBufferResource(vertexBufferDesc, &kVertexData[0]);
+ SLANG_CHECK_ABORT(vertexBuffer != nullptr);
+ return vertexBuffer;
+}
- static const int kInstanceCount = 2;
- static const Instance kInstanceData[kInstanceCount] =
- {
- { { 0, 0, 0 }, { 1, 0, 0 } },
- { { 0, -1, 0 }, { 0, 0, 1 } },
- };
+ComPtr<IBufferResource> createInstanceBuffer(IDevice* device)
+{
+ IBufferResource::Desc instanceBufferDesc;
+ instanceBufferDesc.type = IResource::Type::Buffer;
+ instanceBufferDesc.sizeInBytes = kInstanceCount * sizeof(Instance);
+ instanceBufferDesc.defaultState = ResourceState::VertexBuffer;
+ instanceBufferDesc.allowedStates = ResourceState::VertexBuffer;
+ ComPtr<IBufferResource> instanceBuffer =
+ device->createBufferResource(instanceBufferDesc, &kInstanceData[0]);
+ SLANG_CHECK_ABORT(instanceBuffer != nullptr);
+ return instanceBuffer;
+}
- static const int kIndexCount = 6;
- static const uint32_t kIndexData[kIndexCount] =
- {
- 0, 2, 5,
- 0, 1, 2,
- };
+ComPtr<IBufferResource> createIndexBuffer(IDevice* device)
+{
+ IBufferResource::Desc indexBufferDesc;
+ indexBufferDesc.type = IResource::Type::Buffer;
+ indexBufferDesc.sizeInBytes = kIndexCount * sizeof(uint32_t);
+ indexBufferDesc.defaultState = ResourceState::IndexBuffer;
+ indexBufferDesc.allowedStates = ResourceState::IndexBuffer;
+ ComPtr<IBufferResource> indexBuffer =
+ device->createBufferResource(indexBufferDesc, &kIndexData[0]);
+ SLANG_CHECK_ABORT(indexBuffer != nullptr);
+ return indexBuffer;
+}
- const int kWidth = 256;
- const int kHeight = 256;
- const Format format = Format::R32G32B32A32_FLOAT;
+ComPtr<ITextureResource> createColorBuffer(IDevice* device)
+{
+ gfx::ITextureResource::Desc colorBufferDesc;
+ colorBufferDesc.type = IResource::Type::Texture2D;
+ colorBufferDesc.size.width = kWidth;
+ colorBufferDesc.size.height = kHeight;
+ colorBufferDesc.size.depth = 1;
+ colorBufferDesc.numMipLevels = 1;
+ colorBufferDesc.format = format;
+ colorBufferDesc.defaultState = ResourceState::RenderTarget;
+ colorBufferDesc.allowedStates = {ResourceState::RenderTarget, ResourceState::CopySource};
+ ComPtr<ITextureResource> colorBuffer = device->createTextureResource(colorBufferDesc, nullptr);
+ SLANG_CHECK_ABORT(colorBuffer != nullptr);
+ return colorBuffer;
+}
- ComPtr<IBufferResource> createVertexBuffer(IDevice* device)
- {
- IBufferResource::Desc vertexBufferDesc;
- vertexBufferDesc.type = IResource::Type::Buffer;
- vertexBufferDesc.sizeInBytes = kVertexCount * sizeof(Vertex);
- vertexBufferDesc.defaultState = ResourceState::VertexBuffer;
- vertexBufferDesc.allowedStates = ResourceState::VertexBuffer;
- ComPtr<IBufferResource> vertexBuffer = device->createBufferResource(vertexBufferDesc, &kVertexData[0]);
- SLANG_CHECK_ABORT(vertexBuffer != nullptr);
- return vertexBuffer;
- }
+class BaseDrawTest
+{
+public:
+ ComPtr<IDevice> device;
+ UnitTestContext* context;
- ComPtr<IBufferResource> createInstanceBuffer(IDevice* device)
- {
- IBufferResource::Desc instanceBufferDesc;
- instanceBufferDesc.type = IResource::Type::Buffer;
- instanceBufferDesc.sizeInBytes = kInstanceCount * sizeof(Instance);
- instanceBufferDesc.defaultState = ResourceState::VertexBuffer;
- instanceBufferDesc.allowedStates = ResourceState::VertexBuffer;
- ComPtr<IBufferResource> instanceBuffer = device->createBufferResource(instanceBufferDesc, &kInstanceData[0]);
- SLANG_CHECK_ABORT(instanceBuffer != nullptr);
- return instanceBuffer;
- }
+ ComPtr<ITransientResourceHeap> transientHeap;
+ ComPtr<IPipelineState> pipelineState;
+ ComPtr<IRenderPassLayout> renderPass;
+ ComPtr<IFramebuffer> framebuffer;
- ComPtr<IBufferResource> createIndexBuffer(IDevice* device)
- {
- IBufferResource::Desc indexBufferDesc;
- indexBufferDesc.type = IResource::Type::Buffer;
- indexBufferDesc.sizeInBytes = kIndexCount * sizeof(uint32_t);
- indexBufferDesc.defaultState = ResourceState::IndexBuffer;
- indexBufferDesc.allowedStates = ResourceState::IndexBuffer;
- ComPtr<IBufferResource> indexBuffer = device->createBufferResource(indexBufferDesc, &kIndexData[0]);
- SLANG_CHECK_ABORT(indexBuffer != nullptr);
- return indexBuffer;
- }
+ ComPtr<IBufferResource> vertexBuffer;
+ ComPtr<IBufferResource> instanceBuffer;
+ ComPtr<ITextureResource> colorBuffer;
- ComPtr<ITextureResource> createColorBuffer(IDevice* device)
+ void init(IDevice* device, UnitTestContext* context)
{
- gfx::ITextureResource::Desc colorBufferDesc;
- colorBufferDesc.type = IResource::Type::Texture2D;
- colorBufferDesc.size.width = kWidth;
- colorBufferDesc.size.height = kHeight;
- colorBufferDesc.size.depth = 1;
- colorBufferDesc.numMipLevels = 1;
- colorBufferDesc.format = format;
- colorBufferDesc.defaultState = ResourceState::RenderTarget;
- colorBufferDesc.allowedStates = { ResourceState::RenderTarget, ResourceState::CopySource };
- ComPtr<ITextureResource> colorBuffer = device->createTextureResource(colorBufferDesc, nullptr);
- SLANG_CHECK_ABORT(colorBuffer != nullptr);
- return colorBuffer;
+ this->device = device;
+ this->context = context;
}
- class BaseDrawTest
+ void createRequiredResources()
{
- public:
- ComPtr<IDevice> device;
- UnitTestContext* context;
-
- ComPtr<ITransientResourceHeap> transientHeap;
- ComPtr<IPipelineState> pipelineState;
- ComPtr<IRenderPassLayout> renderPass;
- ComPtr<IFramebuffer> framebuffer;
+ VertexStreamDesc vertexStreams[] = {
+ {sizeof(Vertex), InputSlotClass::PerVertex, 0},
+ {sizeof(Instance), InputSlotClass::PerInstance, 1},
+ };
- ComPtr<IBufferResource> vertexBuffer;
- ComPtr<IBufferResource> instanceBuffer;
- ComPtr<ITextureResource> colorBuffer;
+ InputElementDesc inputElements[] = {
+ // Vertex buffer data
+ {"POSITIONA", 0, Format::R32G32B32_FLOAT, offsetof(Vertex, position), 0},
- void init(IDevice* device, UnitTestContext* context)
- {
- this->device = device;
- this->context = context;
- }
-
- void createRequiredResources()
- {
- VertexStreamDesc vertexStreams[] = {
- { sizeof(Vertex), InputSlotClass::PerVertex, 0 },
- { sizeof(Instance), InputSlotClass::PerInstance, 1 },
- };
-
- InputElementDesc inputElements[] = {
- // Vertex buffer data
- { "POSITIONA", 0, Format::R32G32B32_FLOAT, offsetof(Vertex, position), 0 },
-
- // Instance buffer data
- { "POSITIONB", 0, Format::R32G32B32_FLOAT, offsetof(Instance, position), 1 },
- { "COLOR", 0, Format::R32G32B32_FLOAT, offsetof(Instance, color), 1 },
- };
- IInputLayout::Desc inputLayoutDesc = {};
- inputLayoutDesc.inputElementCount = SLANG_COUNT_OF(inputElements);
- inputLayoutDesc.inputElements = inputElements;
- inputLayoutDesc.vertexStreamCount = SLANG_COUNT_OF(vertexStreams);
- inputLayoutDesc.vertexStreams = vertexStreams;
- auto inputLayout = device->createInputLayout(inputLayoutDesc);
- SLANG_CHECK_ABORT(inputLayout != nullptr);
-
- vertexBuffer = createVertexBuffer(device);
- instanceBuffer = createInstanceBuffer(device);
- colorBuffer = createColorBuffer(device);
-
- ITransientResourceHeap::Desc transientHeapDesc = {};
- transientHeapDesc.constantBufferSize = 4096;
- GFX_CHECK_CALL_ABORT(
- device->createTransientResourceHeap(transientHeapDesc, transientHeap.writeRef()));
-
- ComPtr<IShaderProgram> shaderProgram;
- slang::ProgramLayout* slangReflection;
- GFX_CHECK_CALL_ABORT(loadGraphicsProgram(device, shaderProgram, "graphics-smoke", "vertexMain", "fragmentMain", slangReflection));
-
- IFramebufferLayout::TargetLayout targetLayout;
- targetLayout.format = format;
- targetLayout.sampleCount = 1;
-
- IFramebufferLayout::Desc framebufferLayoutDesc;
- framebufferLayoutDesc.renderTargetCount = 1;
- framebufferLayoutDesc.renderTargets = &targetLayout;
- ComPtr<gfx::IFramebufferLayout> framebufferLayout = device->createFramebufferLayout(framebufferLayoutDesc);
- SLANG_CHECK_ABORT(framebufferLayout != nullptr);
-
- GraphicsPipelineStateDesc pipelineDesc = {};
- pipelineDesc.program = shaderProgram.get();
- pipelineDesc.inputLayout = inputLayout;
- pipelineDesc.framebufferLayout = framebufferLayout;
- pipelineDesc.depthStencil.depthTestEnable = false;
- pipelineDesc.depthStencil.depthWriteEnable = false;
- GFX_CHECK_CALL_ABORT(
- device->createGraphicsPipelineState(pipelineDesc, pipelineState.writeRef()));
-
- IRenderPassLayout::Desc renderPassDesc = {};
- renderPassDesc.framebufferLayout = framebufferLayout;
- renderPassDesc.renderTargetCount = 1;
- IRenderPassLayout::TargetAccessDesc renderTargetAccess = {};
- renderTargetAccess.loadOp = IRenderPassLayout::TargetLoadOp::Clear;
- renderTargetAccess.storeOp = IRenderPassLayout::TargetStoreOp::Store;
- renderTargetAccess.initialState = ResourceState::RenderTarget;
- renderTargetAccess.finalState = ResourceState::CopySource;
- renderPassDesc.renderTargetAccess = &renderTargetAccess;
- GFX_CHECK_CALL_ABORT(device->createRenderPassLayout(renderPassDesc, renderPass.writeRef()));
-
- gfx::IResourceView::Desc colorBufferViewDesc;
- memset(&colorBufferViewDesc, 0, sizeof(colorBufferViewDesc));
- colorBufferViewDesc.format = format;
- colorBufferViewDesc.renderTarget.shape = gfx::IResource::Type::Texture2D;
- colorBufferViewDesc.type = gfx::IResourceView::Type::RenderTarget;
- auto rtv = device->createTextureView(colorBuffer, colorBufferViewDesc);
-
- gfx::IFramebuffer::Desc framebufferDesc;
- framebufferDesc.renderTargetCount = 1;
- framebufferDesc.depthStencilView = nullptr;
- framebufferDesc.renderTargetViews = rtv.readRef();
- framebufferDesc.layout = framebufferLayout;
- GFX_CHECK_CALL_ABORT(device->createFramebuffer(framebufferDesc, framebuffer.writeRef()));
- }
+ // Instance buffer data
+ {"POSITIONB", 0, Format::R32G32B32_FLOAT, offsetof(Instance, position), 1},
+ {"COLOR", 0, Format::R32G32B32_FLOAT, offsetof(Instance, color), 1},
+ };
+ IInputLayout::Desc inputLayoutDesc = {};
+ inputLayoutDesc.inputElementCount = SLANG_COUNT_OF(inputElements);
+ inputLayoutDesc.inputElements = inputElements;
+ inputLayoutDesc.vertexStreamCount = SLANG_COUNT_OF(vertexStreams);
+ inputLayoutDesc.vertexStreams = vertexStreams;
+ auto inputLayout = device->createInputLayout(inputLayoutDesc);
+ SLANG_CHECK_ABORT(inputLayout != nullptr);
+
+ vertexBuffer = createVertexBuffer(device);
+ instanceBuffer = createInstanceBuffer(device);
+ colorBuffer = createColorBuffer(device);
+
+ ITransientResourceHeap::Desc transientHeapDesc = {};
+ transientHeapDesc.constantBufferSize = 4096;
+ GFX_CHECK_CALL_ABORT(
+ device->createTransientResourceHeap(transientHeapDesc, transientHeap.writeRef()));
+
+ ComPtr<IShaderProgram> shaderProgram;
+ slang::ProgramLayout* slangReflection;
+ GFX_CHECK_CALL_ABORT(loadGraphicsProgram(
+ device,
+ shaderProgram,
+ "graphics-smoke",
+ "vertexMain",
+ "fragmentMain",
+ slangReflection));
+
+ IFramebufferLayout::TargetLayout targetLayout;
+ targetLayout.format = format;
+ targetLayout.sampleCount = 1;
+
+ IFramebufferLayout::Desc framebufferLayoutDesc;
+ framebufferLayoutDesc.renderTargetCount = 1;
+ framebufferLayoutDesc.renderTargets = &targetLayout;
+ ComPtr<gfx::IFramebufferLayout> framebufferLayout =
+ device->createFramebufferLayout(framebufferLayoutDesc);
+ SLANG_CHECK_ABORT(framebufferLayout != nullptr);
+
+ GraphicsPipelineStateDesc pipelineDesc = {};
+ pipelineDesc.program = shaderProgram.get();
+ pipelineDesc.inputLayout = inputLayout;
+ pipelineDesc.framebufferLayout = framebufferLayout;
+ pipelineDesc.depthStencil.depthTestEnable = false;
+ pipelineDesc.depthStencil.depthWriteEnable = false;
+ GFX_CHECK_CALL_ABORT(
+ device->createGraphicsPipelineState(pipelineDesc, pipelineState.writeRef()));
+
+ IRenderPassLayout::Desc renderPassDesc = {};
+ renderPassDesc.framebufferLayout = framebufferLayout;
+ renderPassDesc.renderTargetCount = 1;
+ IRenderPassLayout::TargetAccessDesc renderTargetAccess = {};
+ renderTargetAccess.loadOp = IRenderPassLayout::TargetLoadOp::Clear;
+ renderTargetAccess.storeOp = IRenderPassLayout::TargetStoreOp::Store;
+ renderTargetAccess.initialState = ResourceState::RenderTarget;
+ renderTargetAccess.finalState = ResourceState::CopySource;
+ renderPassDesc.renderTargetAccess = &renderTargetAccess;
+ GFX_CHECK_CALL_ABORT(device->createRenderPassLayout(renderPassDesc, renderPass.writeRef()));
+
+ gfx::IResourceView::Desc colorBufferViewDesc;
+ memset(&colorBufferViewDesc, 0, sizeof(colorBufferViewDesc));
+ colorBufferViewDesc.format = format;
+ colorBufferViewDesc.renderTarget.shape = gfx::IResource::Type::Texture2D;
+ colorBufferViewDesc.type = gfx::IResourceView::Type::RenderTarget;
+ auto rtv = device->createTextureView(colorBuffer, colorBufferViewDesc);
+
+ gfx::IFramebuffer::Desc framebufferDesc;
+ framebufferDesc.renderTargetCount = 1;
+ framebufferDesc.depthStencilView = nullptr;
+ framebufferDesc.renderTargetViews = rtv.readRef();
+ framebufferDesc.layout = framebufferLayout;
+ GFX_CHECK_CALL_ABORT(device->createFramebuffer(framebufferDesc, framebuffer.writeRef()));
+ }
- void checkTestResults(int pixelCount, int channelCount, const int* testXCoords, const int* testYCoords, float* testResults)
+ void checkTestResults(
+ int pixelCount,
+ int channelCount,
+ const int* testXCoords,
+ const int* testYCoords,
+ float* testResults)
+ {
+ // Read texture values back from four specific pixels located within the triangles
+ // and compare against expected values (because testing every single pixel will be too long
+ // and tedious and requires maintaining reference images).
+ ComPtr<ISlangBlob> resultBlob;
+ size_t rowPitch = 0;
+ size_t pixelSize = 0;
+ GFX_CHECK_CALL_ABORT(device->readTextureResource(
+ colorBuffer,
+ ResourceState::CopySource,
+ resultBlob.writeRef(),
+ &rowPitch,
+ &pixelSize));
+ auto result = (float*)resultBlob->getBufferPointer();
+
+ int cursor = 0;
+ for (int i = 0; i < pixelCount; ++i)
{
- // Read texture values back from four specific pixels located within the triangles
- // and compare against expected values (because testing every single pixel will be too long and tedious
- // and requires maintaining reference images).
- ComPtr<ISlangBlob> resultBlob;
- size_t rowPitch = 0;
- size_t pixelSize = 0;
- GFX_CHECK_CALL_ABORT(device->readTextureResource(
- colorBuffer, ResourceState::CopySource, resultBlob.writeRef(), &rowPitch, &pixelSize));
- auto result = (float*)resultBlob->getBufferPointer();
-
- int cursor = 0;
- for (int i = 0; i < pixelCount; ++i)
+ auto x = testXCoords[i];
+ auto y = testYCoords[i];
+ auto pixelPtr = result + x * channelCount + y * rowPitch / sizeof(float);
+ for (int j = 0; j < channelCount; ++j)
{
- auto x = testXCoords[i];
- auto y = testYCoords[i];
- auto pixelPtr = result + x * channelCount + y * rowPitch / sizeof(float);
- for (int j = 0; j < channelCount; ++j)
- {
- testResults[cursor] = pixelPtr[j];
- cursor++;
- }
+ testResults[cursor] = pixelPtr[j];
+ cursor++;
}
-
- float expectedResult[] = { 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f,
- 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f };
- compareComputeResultFuzzy(testResults, expectedResult, sizeof(expectedResult));
}
- };
- struct DrawInstancedTest : BaseDrawTest
+ float expectedResult[] = {
+ 1.0f,
+ 0.0f,
+ 0.0f,
+ 1.0f,
+ 1.0f,
+ 0.0f,
+ 0.0f,
+ 1.0f,
+ 0.0f,
+ 0.0f,
+ 1.0f,
+ 1.0f,
+ 0.0f,
+ 0.0f,
+ 1.0f,
+ 1.0f};
+ compareComputeResultFuzzy(testResults, expectedResult, sizeof(expectedResult));
+ }
+};
+
+struct DrawInstancedTest : BaseDrawTest
+{
+ void setUpAndDraw()
{
- void setUpAndDraw()
- {
- createRequiredResources();
+ createRequiredResources();
- ICommandQueue::Desc queueDesc = { ICommandQueue::QueueType::Graphics };
- auto queue = device->createCommandQueue(queueDesc);
- auto commandBuffer = transientHeap->createCommandBuffer();
+ ICommandQueue::Desc queueDesc = {ICommandQueue::QueueType::Graphics};
+ auto queue = device->createCommandQueue(queueDesc);
+ auto commandBuffer = transientHeap->createCommandBuffer();
- auto encoder = commandBuffer->encodeRenderCommands(renderPass, framebuffer);
- auto rootObject = encoder->bindPipeline(pipelineState);
+ auto encoder = commandBuffer->encodeRenderCommands(renderPass, framebuffer);
+ auto rootObject = encoder->bindPipeline(pipelineState);
- gfx::Viewport viewport = {};
- viewport.maxZ = 1.0f;
- viewport.extentX = kWidth;
- viewport.extentY = kHeight;
- encoder->setViewportAndScissor(viewport);
+ gfx::Viewport viewport = {};
+ viewport.maxZ = 1.0f;
+ viewport.extentX = kWidth;
+ viewport.extentY = kHeight;
+ encoder->setViewportAndScissor(viewport);
- uint32_t startVertex = 0;
- uint32_t startInstanceLocation = 0;
+ uint32_t startVertex = 0;
+ uint32_t startInstanceLocation = 0;
- encoder->setVertexBuffer(0, vertexBuffer);
- encoder->setVertexBuffer(1, instanceBuffer);
- encoder->setPrimitiveTopology(PrimitiveTopology::TriangleList);
+ encoder->setVertexBuffer(0, vertexBuffer);
+ encoder->setVertexBuffer(1, instanceBuffer);
+ encoder->setPrimitiveTopology(PrimitiveTopology::TriangleList);
- encoder->drawInstanced(kVertexCount, kInstanceCount, startVertex, startInstanceLocation);
- encoder->endEncoding();
- commandBuffer->close();
- queue->executeCommandBuffer(commandBuffer);
- queue->waitOnHost();
- }
+ encoder->drawInstanced(kVertexCount, kInstanceCount, startVertex, startInstanceLocation);
+ encoder->endEncoding();
+ commandBuffer->close();
+ queue->executeCommandBuffer(commandBuffer);
+ queue->waitOnHost();
+ }
- void run()
- {
- setUpAndDraw();
+ void run()
+ {
+ setUpAndDraw();
- const int kPixelCount = 4;
- const int kChannelCount = 4;
- int testXCoords[kPixelCount] = { 64, 192, 64, 192 };
- int testYCoords[kPixelCount] = { 100, 100, 250, 250 };
- float testResults[kPixelCount * kChannelCount];
+ const int kPixelCount = 4;
+ const int kChannelCount = 4;
+ int testXCoords[kPixelCount] = {64, 192, 64, 192};
+ int testYCoords[kPixelCount] = {100, 100, 250, 250};
+ float testResults[kPixelCount * kChannelCount];
- checkTestResults(kPixelCount, kChannelCount, testXCoords, testYCoords, testResults);
- }
- };
+ checkTestResults(kPixelCount, kChannelCount, testXCoords, testYCoords, testResults);
+ }
+};
+
+struct DrawIndexedInstancedTest : BaseDrawTest
+{
+ ComPtr<IBufferResource> indexBuffer;
- struct DrawIndexedInstancedTest : BaseDrawTest
+ void setUpAndDraw()
{
- ComPtr<IBufferResource> indexBuffer;
+ createRequiredResources();
+
+ ICommandQueue::Desc queueDesc = {ICommandQueue::QueueType::Graphics};
+ auto queue = device->createCommandQueue(queueDesc);
+ auto commandBuffer = transientHeap->createCommandBuffer();
+
+ auto encoder = commandBuffer->encodeRenderCommands(renderPass, framebuffer);
+ auto rootObject = encoder->bindPipeline(pipelineState);
+
+ gfx::Viewport viewport = {};
+ viewport.maxZ = 1.0f;
+ viewport.extentX = kWidth;
+ viewport.extentY = kHeight;
+ encoder->setViewportAndScissor(viewport);
+
+ uint32_t startIndex = 0;
+ int32_t startVertex = 0;
+ uint32_t startInstanceLocation = 0;
+
+ encoder->setVertexBuffer(0, vertexBuffer);
+ encoder->setVertexBuffer(1, instanceBuffer);
+ encoder->setIndexBuffer(indexBuffer, Format::R32_UINT);
+ encoder->setPrimitiveTopology(PrimitiveTopology::TriangleList);
+
+ encoder->drawIndexedInstanced(
+ kIndexCount,
+ kInstanceCount,
+ startIndex,
+ startVertex,
+ startInstanceLocation);
+ encoder->endEncoding();
+ commandBuffer->close();
+ queue->executeCommandBuffer(commandBuffer);
+ queue->waitOnHost();
+ }
- void setUpAndDraw()
- {
- createRequiredResources();
-
- ICommandQueue::Desc queueDesc = { ICommandQueue::QueueType::Graphics };
- auto queue = device->createCommandQueue(queueDesc);
- auto commandBuffer = transientHeap->createCommandBuffer();
-
- auto encoder = commandBuffer->encodeRenderCommands(renderPass, framebuffer);
- auto rootObject = encoder->bindPipeline(pipelineState);
-
- gfx::Viewport viewport = {};
- viewport.maxZ = 1.0f;
- viewport.extentX = kWidth;
- viewport.extentY = kHeight;
- encoder->setViewportAndScissor(viewport);
-
- uint32_t startIndex = 0;
- int32_t startVertex = 0;
- uint32_t startInstanceLocation = 0;
-
- encoder->setVertexBuffer(0, vertexBuffer);
- encoder->setVertexBuffer(1, instanceBuffer);
- encoder->setIndexBuffer(indexBuffer, Format::R32_UINT);
- encoder->setPrimitiveTopology(PrimitiveTopology::TriangleList);
-
- encoder->drawIndexedInstanced(kIndexCount, kInstanceCount, startIndex, startVertex, startInstanceLocation);
- encoder->endEncoding();
- commandBuffer->close();
- queue->executeCommandBuffer(commandBuffer);
- queue->waitOnHost();
- }
+ void run()
+ {
+ indexBuffer = createIndexBuffer(device);
- void run()
- {
- indexBuffer = createIndexBuffer(device);
+ setUpAndDraw();
- setUpAndDraw();
+ const int kPixelCount = 4;
+ const int kChannelCount = 4;
+ int testXCoords[kPixelCount] = {64, 192, 64, 192};
+ int testYCoords[kPixelCount] = {32, 100, 150, 250};
+ float testResults[kPixelCount * kChannelCount];
- const int kPixelCount = 4;
- const int kChannelCount = 4;
- int testXCoords[kPixelCount] = { 64, 192, 64, 192 };
- int testYCoords[kPixelCount] = { 32, 100, 150, 250 };
- float testResults[kPixelCount * kChannelCount];
+ checkTestResults(kPixelCount, kChannelCount, testXCoords, testYCoords, testResults);
+ }
+};
- checkTestResults(kPixelCount, kChannelCount, testXCoords, testYCoords, testResults);
- }
- };
+struct DrawIndirectTest : BaseDrawTest
+{
+ ComPtr<IBufferResource> indirectBuffer;
- struct DrawIndirectTest : BaseDrawTest
+ struct IndirectArgData
{
- ComPtr<IBufferResource> indirectBuffer;
+ float padding; // Ensure args and count don't start at 0 offset for testing purposes
+ IndirectDrawArguments args;
+ };
- struct IndirectArgData
- {
- float padding; // Ensure args and count don't start at 0 offset for testing purposes
- IndirectDrawArguments args;
+ ComPtr<IBufferResource> createIndirectBuffer(IDevice* device)
+ {
+ static const IndirectArgData kIndirectData = {
+ 42.0f, // padding
+ {6, 2, 0, 0}, // args
};
- ComPtr<IBufferResource> createIndirectBuffer(IDevice* device)
- {
- static const IndirectArgData kIndirectData =
- {
- 42.0f, // padding
- {6, 2, 0, 0}, // args
- };
-
- IBufferResource::Desc indirectBufferDesc;
- indirectBufferDesc.type = IResource::Type::Buffer;
- indirectBufferDesc.sizeInBytes = sizeof(IndirectArgData);
- indirectBufferDesc.defaultState = ResourceState::IndirectArgument;
- indirectBufferDesc.allowedStates = ResourceState::IndirectArgument;
- ComPtr<IBufferResource> indirectBuffer = device->createBufferResource(indirectBufferDesc, &kIndirectData);
- SLANG_CHECK_ABORT(indirectBuffer != nullptr);
- return indirectBuffer;
- }
-
- void setUpAndDraw()
- {
- createRequiredResources();
-
- ICommandQueue::Desc queueDesc = { ICommandQueue::QueueType::Graphics };
- auto queue = device->createCommandQueue(queueDesc);
- auto commandBuffer = transientHeap->createCommandBuffer();
+ IBufferResource::Desc indirectBufferDesc;
+ indirectBufferDesc.type = IResource::Type::Buffer;
+ indirectBufferDesc.sizeInBytes = sizeof(IndirectArgData);
+ indirectBufferDesc.defaultState = ResourceState::IndirectArgument;
+ indirectBufferDesc.allowedStates = ResourceState::IndirectArgument;
+ ComPtr<IBufferResource> indirectBuffer =
+ device->createBufferResource(indirectBufferDesc, &kIndirectData);
+ SLANG_CHECK_ABORT(indirectBuffer != nullptr);
+ return indirectBuffer;
+ }
- auto encoder = commandBuffer->encodeRenderCommands(renderPass, framebuffer);
- auto rootObject = encoder->bindPipeline(pipelineState);
+ void setUpAndDraw()
+ {
+ createRequiredResources();
- gfx::Viewport viewport = {};
- viewport.maxZ = 1.0f;
- viewport.extentX = kWidth;
- viewport.extentY = kHeight;
- encoder->setViewportAndScissor(viewport);
+ ICommandQueue::Desc queueDesc = {ICommandQueue::QueueType::Graphics};
+ auto queue = device->createCommandQueue(queueDesc);
+ auto commandBuffer = transientHeap->createCommandBuffer();
- encoder->setVertexBuffer(0, vertexBuffer);
- encoder->setVertexBuffer(1, instanceBuffer);
- encoder->setPrimitiveTopology(PrimitiveTopology::TriangleList);
+ auto encoder = commandBuffer->encodeRenderCommands(renderPass, framebuffer);
+ auto rootObject = encoder->bindPipeline(pipelineState);
- uint32_t maxDrawCount = 1;
- Offset argOffset = offsetof(IndirectArgData, args);
+ gfx::Viewport viewport = {};
+ viewport.maxZ = 1.0f;
+ viewport.extentX = kWidth;
+ viewport.extentY = kHeight;
+ encoder->setViewportAndScissor(viewport);
- encoder->drawIndirect(maxDrawCount, indirectBuffer, argOffset);
- encoder->endEncoding();
- commandBuffer->close();
- queue->executeCommandBuffer(commandBuffer);
- queue->waitOnHost();
- }
-
- void run()
- {
- indirectBuffer = createIndirectBuffer(device);
+ encoder->setVertexBuffer(0, vertexBuffer);
+ encoder->setVertexBuffer(1, instanceBuffer);
+ encoder->setPrimitiveTopology(PrimitiveTopology::TriangleList);
- setUpAndDraw();
+ uint32_t maxDrawCount = 1;
+ Offset argOffset = offsetof(IndirectArgData, args);
- const int kPixelCount = 4;
- const int kChannelCount = 4;
- int testXCoords[kPixelCount] = { 64, 192, 64, 192 };
- int testYCoords[kPixelCount] = { 100, 100, 250, 250 };
- float testResults[kPixelCount * kChannelCount];
-
- checkTestResults(kPixelCount, kChannelCount, testXCoords, testYCoords, testResults);
- }
- };
+ encoder->drawIndirect(maxDrawCount, indirectBuffer, argOffset);
+ encoder->endEncoding();
+ commandBuffer->close();
+ queue->executeCommandBuffer(commandBuffer);
+ queue->waitOnHost();
+ }
- struct DrawIndexedIndirectTest : BaseDrawTest
+ void run()
{
- ComPtr<IBufferResource> indexBuffer;
- ComPtr<IBufferResource> indirectBuffer;
-
- struct IndexedIndirectArgData
- {
- float padding; // Ensure args and count don't start at 0 offset for testing purposes
- IndirectDrawIndexedArguments args;
- };
-
- ComPtr<IBufferResource> createIndirectBuffer(IDevice* device)
- {
- static const IndexedIndirectArgData kIndexedIndirectData =
- {
- 42.0f, // padding
- {6, 2, 0, 0, 0}, // args
- };
-
- IBufferResource::Desc indirectBufferDesc;
- indirectBufferDesc.type = IResource::Type::Buffer;
- indirectBufferDesc.sizeInBytes = sizeof(IndexedIndirectArgData);
- indirectBufferDesc.defaultState = ResourceState::IndirectArgument;
- indirectBufferDesc.allowedStates = ResourceState::IndirectArgument;
- ComPtr<IBufferResource> indexBuffer = device->createBufferResource(indirectBufferDesc, &kIndexedIndirectData);
- SLANG_CHECK_ABORT(indexBuffer != nullptr);
- return indexBuffer;
- }
+ indirectBuffer = createIndirectBuffer(device);
- void setUpAndDraw()
- {
- createRequiredResources();
-
- ICommandQueue::Desc queueDesc = { ICommandQueue::QueueType::Graphics };
- auto queue = device->createCommandQueue(queueDesc);
- auto commandBuffer = transientHeap->createCommandBuffer();
-
- auto encoder = commandBuffer->encodeRenderCommands(renderPass, framebuffer);
- auto rootObject = encoder->bindPipeline(pipelineState);
-
- gfx::Viewport viewport = {};
- viewport.maxZ = 1.0f;
- viewport.extentX = kWidth;
- viewport.extentY = kHeight;
- encoder->setViewportAndScissor(viewport);
-
- encoder->setVertexBuffer(0, vertexBuffer);
- encoder->setVertexBuffer(1, instanceBuffer);
- encoder->setIndexBuffer(indexBuffer, Format::R32_UINT);
- encoder->setPrimitiveTopology(PrimitiveTopology::TriangleList);
-
- uint32_t maxDrawCount = 1;
- Offset argOffset = offsetof(IndexedIndirectArgData, args);
-
- encoder->drawIndexedIndirect(maxDrawCount, indirectBuffer, argOffset);
- encoder->endEncoding();
- commandBuffer->close();
- queue->executeCommandBuffer(commandBuffer);
- queue->waitOnHost();
- }
+ setUpAndDraw();
- void run()
- {
- indexBuffer = createIndexBuffer(device);
- indirectBuffer = createIndirectBuffer(device);
+ const int kPixelCount = 4;
+ const int kChannelCount = 4;
+ int testXCoords[kPixelCount] = {64, 192, 64, 192};
+ int testYCoords[kPixelCount] = {100, 100, 250, 250};
+ float testResults[kPixelCount * kChannelCount];
- setUpAndDraw();
+ checkTestResults(kPixelCount, kChannelCount, testXCoords, testYCoords, testResults);
+ }
+};
- const int kPixelCount = 4;
- const int kChannelCount = 4;
- int testXCoords[kPixelCount] = { 64, 192, 64, 192 };
- int testYCoords[kPixelCount] = { 32, 100, 150, 250 };
- float testResults[kPixelCount * kChannelCount];
+struct DrawIndexedIndirectTest : BaseDrawTest
+{
+ ComPtr<IBufferResource> indexBuffer;
+ ComPtr<IBufferResource> indirectBuffer;
- checkTestResults(kPixelCount, kChannelCount, testXCoords, testYCoords, testResults);
- }
+ struct IndexedIndirectArgData
+ {
+ float padding; // Ensure args and count don't start at 0 offset for testing purposes
+ IndirectDrawIndexedArguments args;
};
- template <typename T>
- void drawTestImpl(IDevice* device, UnitTestContext* context)
+ ComPtr<IBufferResource> createIndirectBuffer(IDevice* device)
{
- T test;
- test.init(device, context);
- test.run();
- }
+ static const IndexedIndirectArgData kIndexedIndirectData = {
+ 42.0f, // padding
+ {6, 2, 0, 0, 0}, // args
+ };
- SLANG_UNIT_TEST(drawInstancedD3D11)
- {
- runTestImpl(drawTestImpl<DrawInstancedTest>, unitTestContext, Slang::RenderApiFlag::D3D11);
+ IBufferResource::Desc indirectBufferDesc;
+ indirectBufferDesc.type = IResource::Type::Buffer;
+ indirectBufferDesc.sizeInBytes = sizeof(IndexedIndirectArgData);
+ indirectBufferDesc.defaultState = ResourceState::IndirectArgument;
+ indirectBufferDesc.allowedStates = ResourceState::IndirectArgument;
+ ComPtr<IBufferResource> indexBuffer =
+ device->createBufferResource(indirectBufferDesc, &kIndexedIndirectData);
+ SLANG_CHECK_ABORT(indexBuffer != nullptr);
+ return indexBuffer;
}
- SLANG_UNIT_TEST(drawIndexedInstancedD3D11)
+ void setUpAndDraw()
{
- runTestImpl(drawTestImpl<DrawIndexedInstancedTest>, unitTestContext, Slang::RenderApiFlag::D3D11);
+ createRequiredResources();
+
+ ICommandQueue::Desc queueDesc = {ICommandQueue::QueueType::Graphics};
+ auto queue = device->createCommandQueue(queueDesc);
+ auto commandBuffer = transientHeap->createCommandBuffer();
+
+ auto encoder = commandBuffer->encodeRenderCommands(renderPass, framebuffer);
+ auto rootObject = encoder->bindPipeline(pipelineState);
+
+ gfx::Viewport viewport = {};
+ viewport.maxZ = 1.0f;
+ viewport.extentX = kWidth;
+ viewport.extentY = kHeight;
+ encoder->setViewportAndScissor(viewport);
+
+ encoder->setVertexBuffer(0, vertexBuffer);
+ encoder->setVertexBuffer(1, instanceBuffer);
+ encoder->setIndexBuffer(indexBuffer, Format::R32_UINT);
+ encoder->setPrimitiveTopology(PrimitiveTopology::TriangleList);
+
+ uint32_t maxDrawCount = 1;
+ Offset argOffset = offsetof(IndexedIndirectArgData, args);
+
+ encoder->drawIndexedIndirect(maxDrawCount, indirectBuffer, argOffset);
+ encoder->endEncoding();
+ commandBuffer->close();
+ queue->executeCommandBuffer(commandBuffer);
+ queue->waitOnHost();
}
- SLANG_UNIT_TEST(drawInstancedD3D12)
+ void run()
{
- runTestImpl(drawTestImpl<DrawInstancedTest>, unitTestContext, Slang::RenderApiFlag::D3D12);
- }
+ indexBuffer = createIndexBuffer(device);
+ indirectBuffer = createIndirectBuffer(device);
- SLANG_UNIT_TEST(drawIndexedInstancedD3D12)
- {
- runTestImpl(drawTestImpl<DrawIndexedInstancedTest>, unitTestContext, Slang::RenderApiFlag::D3D12);
- }
+ setUpAndDraw();
- SLANG_UNIT_TEST(drawIndirectD3D12)
- {
- runTestImpl(drawTestImpl<DrawIndirectTest>, unitTestContext, Slang::RenderApiFlag::D3D12);
- }
+ const int kPixelCount = 4;
+ const int kChannelCount = 4;
+ int testXCoords[kPixelCount] = {64, 192, 64, 192};
+ int testYCoords[kPixelCount] = {32, 100, 150, 250};
+ float testResults[kPixelCount * kChannelCount];
- SLANG_UNIT_TEST(drawIndexedIndirectD3D12)
- {
- runTestImpl(drawTestImpl<DrawIndexedIndirectTest>, unitTestContext, Slang::RenderApiFlag::D3D12);
+ checkTestResults(kPixelCount, kChannelCount, testXCoords, testYCoords, testResults);
}
+};
- SLANG_UNIT_TEST(drawInstancedVulkan)
- {
- runTestImpl(drawTestImpl<DrawInstancedTest>, unitTestContext, Slang::RenderApiFlag::Vulkan);
- }
+template<typename T>
+void drawTestImpl(IDevice* device, UnitTestContext* context)
+{
+ T test;
+ test.init(device, context);
+ test.run();
+}
- SLANG_UNIT_TEST(drawIndexedInstancedVulkan)
- {
- runTestImpl(drawTestImpl<DrawIndexedInstancedTest>, unitTestContext, Slang::RenderApiFlag::Vulkan);
- }
+SLANG_UNIT_TEST(drawInstancedD3D11)
+{
+ runTestImpl(drawTestImpl<DrawInstancedTest>, unitTestContext, Slang::RenderApiFlag::D3D11);
+}
- SLANG_UNIT_TEST(drawIndirectVulkan)
- {
- runTestImpl(drawTestImpl<DrawIndirectTest>, unitTestContext, Slang::RenderApiFlag::Vulkan);
- }
+SLANG_UNIT_TEST(drawIndexedInstancedD3D11)
+{
+ runTestImpl(
+ drawTestImpl<DrawIndexedInstancedTest>,
+ unitTestContext,
+ Slang::RenderApiFlag::D3D11);
+}
- SLANG_UNIT_TEST(drawIndexedIndirectVulkan)
- {
- runTestImpl(drawTestImpl<DrawIndexedIndirectTest>, unitTestContext, Slang::RenderApiFlag::Vulkan);
- }
+SLANG_UNIT_TEST(drawInstancedD3D12)
+{
+ runTestImpl(drawTestImpl<DrawInstancedTest>, unitTestContext, Slang::RenderApiFlag::D3D12);
+}
+
+SLANG_UNIT_TEST(drawIndexedInstancedD3D12)
+{
+ runTestImpl(
+ drawTestImpl<DrawIndexedInstancedTest>,
+ unitTestContext,
+ Slang::RenderApiFlag::D3D12);
+}
+
+SLANG_UNIT_TEST(drawIndirectD3D12)
+{
+ runTestImpl(drawTestImpl<DrawIndirectTest>, unitTestContext, Slang::RenderApiFlag::D3D12);
+}
+
+SLANG_UNIT_TEST(drawIndexedIndirectD3D12)
+{
+ runTestImpl(
+ drawTestImpl<DrawIndexedIndirectTest>,
+ unitTestContext,
+ Slang::RenderApiFlag::D3D12);
+}
+
+SLANG_UNIT_TEST(drawInstancedVulkan)
+{
+ runTestImpl(drawTestImpl<DrawInstancedTest>, unitTestContext, Slang::RenderApiFlag::Vulkan);
+}
+
+SLANG_UNIT_TEST(drawIndexedInstancedVulkan)
+{
+ runTestImpl(
+ drawTestImpl<DrawIndexedInstancedTest>,
+ unitTestContext,
+ Slang::RenderApiFlag::Vulkan);
+}
+
+SLANG_UNIT_TEST(drawIndirectVulkan)
+{
+ runTestImpl(drawTestImpl<DrawIndirectTest>, unitTestContext, Slang::RenderApiFlag::Vulkan);
+}
+
+SLANG_UNIT_TEST(drawIndexedIndirectVulkan)
+{
+ runTestImpl(
+ drawTestImpl<DrawIndexedIndirectTest>,
+ unitTestContext,
+ Slang::RenderApiFlag::Vulkan);
}
+} // namespace gfx_test
diff --git a/tools/gfx-unit-test/link-time-constant.cpp b/tools/gfx-unit-test/link-time-constant.cpp
index a80a23c0c..047ecd3bc 100644
--- a/tools/gfx-unit-test/link-time-constant.cpp
+++ b/tools/gfx-unit-test/link-time-constant.cpp
@@ -1,162 +1,163 @@
-#include "tools/unit-test/slang-unit-test.h"
-
-#include "slang-gfx.h"
#include "gfx-test-util.h"
-#include "tools/gfx-util/shader-cursor.h"
+#include "slang-gfx.h"
#include "source/core/slang-basic.h"
#include "source/core/slang-blob.h"
+#include "tools/gfx-util/shader-cursor.h"
+#include "tools/unit-test/slang-unit-test.h"
using namespace gfx;
namespace gfx_test
{
- static Slang::Result loadProgram(
- gfx::IDevice* device,
- Slang::ComPtr<gfx::IShaderProgram>& outShaderProgram,
- const char* shaderModuleName,
- const char* entryPointName,
- slang::ProgramLayout*& slangReflection,
- const char* additionalModuleSource)
- {
- Slang::ComPtr<slang::ISession> slangSession;
- SLANG_RETURN_ON_FAIL(device->getSlangSession(slangSession.writeRef()));
- Slang::ComPtr<slang::IBlob> diagnosticsBlob;
- slang::IModule* module = slangSession->loadModule(shaderModuleName, diagnosticsBlob.writeRef());
- diagnoseIfNeeded(diagnosticsBlob);
- if (!module)
- return SLANG_FAIL;
-
- auto additionalModuleBlob = Slang::UnownedRawBlob::create(additionalModuleSource, strlen(additionalModuleSource));
- slang::IModule* additionalModule = slangSession->loadModuleFromSource("linkedConstants", "path",
- additionalModuleBlob);
-
- ComPtr<slang::IEntryPoint> computeEntryPoint;
- SLANG_RETURN_ON_FAIL(
- module->findEntryPointByName(entryPointName, computeEntryPoint.writeRef()));
-
- Slang::List<slang::IComponentType*> componentTypes;
- componentTypes.add(module);
- componentTypes.add(computeEntryPoint);
- componentTypes.add(additionalModule);
-
- Slang::ComPtr<slang::IComponentType> composedProgram;
- SlangResult result = slangSession->createCompositeComponentType(
- componentTypes.getBuffer(),
- componentTypes.getCount(),
- composedProgram.writeRef(),
- diagnosticsBlob.writeRef());
- diagnoseIfNeeded(diagnosticsBlob);
- SLANG_RETURN_ON_FAIL(result);
-
- ComPtr<slang::IComponentType> linkedProgram;
- result = composedProgram->link(linkedProgram.writeRef(), diagnosticsBlob.writeRef());
- diagnoseIfNeeded(diagnosticsBlob);
- SLANG_RETURN_ON_FAIL(result);
-
- composedProgram = linkedProgram;
- slangReflection = composedProgram->getLayout();
-
- gfx::IShaderProgram::Desc programDesc = {};
- programDesc.slangGlobalScope = composedProgram.get();
-
- auto shaderProgram = device->createProgram(programDesc);
-
- outShaderProgram = shaderProgram;
- return SLANG_OK;
- }
+static Slang::Result loadProgram(
+ gfx::IDevice* device,
+ Slang::ComPtr<gfx::IShaderProgram>& outShaderProgram,
+ const char* shaderModuleName,
+ const char* entryPointName,
+ slang::ProgramLayout*& slangReflection,
+ const char* additionalModuleSource)
+{
+ Slang::ComPtr<slang::ISession> slangSession;
+ SLANG_RETURN_ON_FAIL(device->getSlangSession(slangSession.writeRef()));
+ Slang::ComPtr<slang::IBlob> diagnosticsBlob;
+ slang::IModule* module = slangSession->loadModule(shaderModuleName, diagnosticsBlob.writeRef());
+ diagnoseIfNeeded(diagnosticsBlob);
+ if (!module)
+ return SLANG_FAIL;
+
+ auto additionalModuleBlob =
+ Slang::UnownedRawBlob::create(additionalModuleSource, strlen(additionalModuleSource));
+ slang::IModule* additionalModule =
+ slangSession->loadModuleFromSource("linkedConstants", "path", additionalModuleBlob);
+
+ ComPtr<slang::IEntryPoint> computeEntryPoint;
+ SLANG_RETURN_ON_FAIL(
+ module->findEntryPointByName(entryPointName, computeEntryPoint.writeRef()));
+
+ Slang::List<slang::IComponentType*> componentTypes;
+ componentTypes.add(module);
+ componentTypes.add(computeEntryPoint);
+ componentTypes.add(additionalModule);
+
+ Slang::ComPtr<slang::IComponentType> composedProgram;
+ SlangResult result = slangSession->createCompositeComponentType(
+ componentTypes.getBuffer(),
+ componentTypes.getCount(),
+ composedProgram.writeRef(),
+ diagnosticsBlob.writeRef());
+ diagnoseIfNeeded(diagnosticsBlob);
+ SLANG_RETURN_ON_FAIL(result);
+
+ ComPtr<slang::IComponentType> linkedProgram;
+ result = composedProgram->link(linkedProgram.writeRef(), diagnosticsBlob.writeRef());
+ diagnoseIfNeeded(diagnosticsBlob);
+ SLANG_RETURN_ON_FAIL(result);
+
+ composedProgram = linkedProgram;
+ slangReflection = composedProgram->getLayout();
+
+ gfx::IShaderProgram::Desc programDesc = {};
+ programDesc.slangGlobalScope = composedProgram.get();
+
+ auto shaderProgram = device->createProgram(programDesc);
+
+ outShaderProgram = shaderProgram;
+ return SLANG_OK;
+}
- void linkTimeConstantTestImpl(IDevice* device, UnitTestContext* context)
- {
- Slang::ComPtr<ITransientResourceHeap> transientHeap;
- ITransientResourceHeap::Desc transientHeapDesc = {};
- transientHeapDesc.constantBufferSize = 4096;
- GFX_CHECK_CALL_ABORT(
- device->createTransientResourceHeap(transientHeapDesc, transientHeap.writeRef()));
-
- ComPtr<IShaderProgram> shaderProgram;
- slang::ProgramLayout* slangReflection;
- GFX_CHECK_CALL_ABORT(loadProgram(device, shaderProgram, "link-time-constant", "computeMain", slangReflection,
- R"(
+void linkTimeConstantTestImpl(IDevice* device, UnitTestContext* context)
+{
+ Slang::ComPtr<ITransientResourceHeap> transientHeap;
+ ITransientResourceHeap::Desc transientHeapDesc = {};
+ transientHeapDesc.constantBufferSize = 4096;
+ GFX_CHECK_CALL_ABORT(
+ device->createTransientResourceHeap(transientHeapDesc, transientHeap.writeRef()));
+
+ ComPtr<IShaderProgram> shaderProgram;
+ slang::ProgramLayout* slangReflection;
+ GFX_CHECK_CALL_ABORT(loadProgram(
+ device,
+ shaderProgram,
+ "link-time-constant",
+ "computeMain",
+ slangReflection,
+ R"(
export static const bool turnOnFeature = true;
export static const float constValue = 2.0;
export static const uint numthread = 2;
export static const int arraySize = 4;
)"));
-
- SlangUInt threadGroupSizes[3];
- slangReflection->findEntryPointByName("computeMain")->getComputeThreadGroupSize(3, threadGroupSizes);
- SLANG_CHECK(threadGroupSizes[0] == 2 && threadGroupSizes[1] == 1 && threadGroupSizes[2] == 1);
-
- ComputePipelineStateDesc pipelineDesc = {};
- pipelineDesc.program = shaderProgram.get();
- ComPtr<gfx::IPipelineState> pipelineState;
- GFX_CHECK_CALL_ABORT(
- device->createComputePipelineState(pipelineDesc, pipelineState.writeRef()));
-
- const int numberCount = 4;
- float initialData[] = { 0.0f, 0.0f, 0.0f, 0.0f };
- IBufferResource::Desc bufferDesc = {};
- bufferDesc.sizeInBytes = numberCount * sizeof(float);
- bufferDesc.format = gfx::Format::Unknown;
- bufferDesc.elementSize = sizeof(float);
- bufferDesc.allowedStates = ResourceStateSet(
- ResourceState::ShaderResource,
- ResourceState::UnorderedAccess,
- ResourceState::CopyDestination,
- ResourceState::CopySource);
- bufferDesc.defaultState = ResourceState::UnorderedAccess;
- bufferDesc.memoryType = MemoryType::DeviceLocal;
-
- ComPtr<IBufferResource> numbersBuffer;
- GFX_CHECK_CALL_ABORT(device->createBufferResource(
- bufferDesc,
- (void*)initialData,
- numbersBuffer.writeRef()));
-
- ComPtr<IResourceView> bufferView;
- IResourceView::Desc viewDesc = {};
- viewDesc.type = IResourceView::Type::UnorderedAccess;
- viewDesc.format = Format::Unknown;
- GFX_CHECK_CALL_ABORT(
- device->createBufferView(numbersBuffer, nullptr, viewDesc, bufferView.writeRef()));
-
- // We have done all the set up work, now it is time to start recording a command buffer for
- // GPU execution.
- {
- ICommandQueue::Desc queueDesc = { ICommandQueue::QueueType::Graphics };
- auto queue = device->createCommandQueue(queueDesc);
-
- auto commandBuffer = transientHeap->createCommandBuffer();
- auto encoder = commandBuffer->encodeComputeCommands();
-
- auto rootObject = encoder->bindPipeline(pipelineState);
-
- ShaderCursor entryPointCursor(
- rootObject->getEntryPoint(0)); // get a cursor the the first entry-point.
- // Bind buffer view to the entry point.
- entryPointCursor.getPath("buffer").setResource(bufferView);
-
- encoder->dispatchCompute(1, 1, 1);
- encoder->endEncoding();
- commandBuffer->close();
- queue->executeCommandBuffer(commandBuffer);
- queue->waitOnHost();
- }
-
- compareComputeResult(
- device,
- numbersBuffer,
- Slang::makeArray<float>(2.0));
- }
- SLANG_UNIT_TEST(linkTimeConstantD3D12)
+ SlangUInt threadGroupSizes[3];
+ slangReflection->findEntryPointByName("computeMain")
+ ->getComputeThreadGroupSize(3, threadGroupSizes);
+ SLANG_CHECK(threadGroupSizes[0] == 2 && threadGroupSizes[1] == 1 && threadGroupSizes[2] == 1);
+
+ ComputePipelineStateDesc pipelineDesc = {};
+ pipelineDesc.program = shaderProgram.get();
+ ComPtr<gfx::IPipelineState> pipelineState;
+ GFX_CHECK_CALL_ABORT(
+ device->createComputePipelineState(pipelineDesc, pipelineState.writeRef()));
+
+ const int numberCount = 4;
+ float initialData[] = {0.0f, 0.0f, 0.0f, 0.0f};
+ IBufferResource::Desc bufferDesc = {};
+ bufferDesc.sizeInBytes = numberCount * sizeof(float);
+ bufferDesc.format = gfx::Format::Unknown;
+ bufferDesc.elementSize = sizeof(float);
+ bufferDesc.allowedStates = ResourceStateSet(
+ ResourceState::ShaderResource,
+ ResourceState::UnorderedAccess,
+ ResourceState::CopyDestination,
+ ResourceState::CopySource);
+ bufferDesc.defaultState = ResourceState::UnorderedAccess;
+ bufferDesc.memoryType = MemoryType::DeviceLocal;
+
+ ComPtr<IBufferResource> numbersBuffer;
+ GFX_CHECK_CALL_ABORT(
+ device->createBufferResource(bufferDesc, (void*)initialData, numbersBuffer.writeRef()));
+
+ ComPtr<IResourceView> bufferView;
+ IResourceView::Desc viewDesc = {};
+ viewDesc.type = IResourceView::Type::UnorderedAccess;
+ viewDesc.format = Format::Unknown;
+ GFX_CHECK_CALL_ABORT(
+ device->createBufferView(numbersBuffer, nullptr, viewDesc, bufferView.writeRef()));
+
+ // We have done all the set up work, now it is time to start recording a command buffer for
+ // GPU execution.
{
- runTestImpl(linkTimeConstantTestImpl, unitTestContext, Slang::RenderApiFlag::D3D12);
- }
+ ICommandQueue::Desc queueDesc = {ICommandQueue::QueueType::Graphics};
+ auto queue = device->createCommandQueue(queueDesc);
- SLANG_UNIT_TEST(linkTimeConstantVulkan)
- {
- runTestImpl(linkTimeConstantTestImpl, unitTestContext, Slang::RenderApiFlag::Vulkan);
+ auto commandBuffer = transientHeap->createCommandBuffer();
+ auto encoder = commandBuffer->encodeComputeCommands();
+
+ auto rootObject = encoder->bindPipeline(pipelineState);
+
+ ShaderCursor entryPointCursor(
+ rootObject->getEntryPoint(0)); // get a cursor the the first entry-point.
+ // Bind buffer view to the entry point.
+ entryPointCursor.getPath("buffer").setResource(bufferView);
+
+ encoder->dispatchCompute(1, 1, 1);
+ encoder->endEncoding();
+ commandBuffer->close();
+ queue->executeCommandBuffer(commandBuffer);
+ queue->waitOnHost();
}
+ compareComputeResult(device, numbersBuffer, Slang::makeArray<float>(2.0));
}
+
+SLANG_UNIT_TEST(linkTimeConstantD3D12)
+{
+ runTestImpl(linkTimeConstantTestImpl, unitTestContext, Slang::RenderApiFlag::D3D12);
+}
+
+SLANG_UNIT_TEST(linkTimeConstantVulkan)
+{
+ runTestImpl(linkTimeConstantTestImpl, unitTestContext, Slang::RenderApiFlag::Vulkan);
+}
+
+} // namespace gfx_test
diff --git a/tools/gfx-unit-test/link-time-default.cpp b/tools/gfx-unit-test/link-time-default.cpp
index be9198b82..d341e5dc0 100644
--- a/tools/gfx-unit-test/link-time-default.cpp
+++ b/tools/gfx-unit-test/link-time-default.cpp
@@ -1,22 +1,21 @@
-#include "tools/unit-test/slang-unit-test.h"
-
-#include "slang-gfx.h"
#include "gfx-test-util.h"
-#include "tools/gfx-util/shader-cursor.h"
+#include "slang-gfx.h"
#include "source/core/slang-basic.h"
#include "source/core/slang-blob.h"
+#include "tools/gfx-util/shader-cursor.h"
+#include "tools/unit-test/slang-unit-test.h"
using namespace gfx;
namespace gfx_test
{
- static Slang::Result loadProgram(
- gfx::IDevice* device,
- Slang::ComPtr<gfx::IShaderProgram>& outShaderProgram,
- slang::ProgramLayout*& slangReflection,
- bool linkSpecialization = false)
- {
- const char* moduleInterfaceSrc = R"(
+static Slang::Result loadProgram(
+ gfx::IDevice* device,
+ Slang::ComPtr<gfx::IShaderProgram>& outShaderProgram,
+ slang::ProgramLayout*& slangReflection,
+ bool linkSpecialization = false)
+{
+ const char* moduleInterfaceSrc = R"(
interface IFoo
{
static const int offset;
@@ -47,7 +46,7 @@ namespace gfx_test
}
};
)";
- const char* module0Src = R"(
+ const char* module0Src = R"(
import ifoo;
extern struct Foo : IFoo = FooImpl;
extern static const float c = 0.0;
@@ -59,179 +58,170 @@ namespace gfx_test
buffer[0] = foo.getValue() + foo.val2 + Foo.offset + c;
}
)";
- const char* module1Src = R"(
+ const char* module1Src = R"(
import ifoo;
export struct Foo : IFoo = BarImpl;
export static const float c = 1.0;
)";
- Slang::ComPtr<slang::ISession> slangSession;
- SLANG_RETURN_ON_FAIL(device->getSlangSession(slangSession.writeRef()));
- Slang::ComPtr<slang::IBlob> diagnosticsBlob;
- auto moduleInterfaceBlob = Slang::UnownedRawBlob::create(moduleInterfaceSrc, strlen(moduleInterfaceSrc));
- auto module0Blob = Slang::UnownedRawBlob::create(module0Src, strlen(module0Src));
- auto module1Blob = Slang::UnownedRawBlob::create(module1Src, strlen(module1Src));
- slang::IModule* moduleInterface = slangSession->loadModuleFromSource("ifoo", "ifoo.slang",
- moduleInterfaceBlob);
- slang::IModule* module0 = slangSession->loadModuleFromSource("module0", "path0",
- module0Blob);
- slang::IModule* module1 = slangSession->loadModuleFromSource("module1", "path1",
- module1Blob);
- ComPtr<slang::IEntryPoint> computeEntryPoint;
- SLANG_RETURN_ON_FAIL(
- module0->findEntryPointByName("computeMain", computeEntryPoint.writeRef()));
-
- Slang::List<slang::IComponentType*> componentTypes;
- componentTypes.add(moduleInterface);
- componentTypes.add(module0);
- if (linkSpecialization)
- componentTypes.add(module1);
- componentTypes.add(computeEntryPoint);
-
- Slang::ComPtr<slang::IComponentType> composedProgram;
- SlangResult result = slangSession->createCompositeComponentType(
- componentTypes.getBuffer(),
- componentTypes.getCount(),
- composedProgram.writeRef(),
- diagnosticsBlob.writeRef());
- diagnoseIfNeeded(diagnosticsBlob);
- SLANG_RETURN_ON_FAIL(result);
-
- ComPtr<slang::IComponentType> linkedProgram;
- result = composedProgram->link(linkedProgram.writeRef(), diagnosticsBlob.writeRef());
- diagnoseIfNeeded(diagnosticsBlob);
- SLANG_RETURN_ON_FAIL(result);
-
- composedProgram = linkedProgram;
- slangReflection = composedProgram->getLayout();
-
- gfx::IShaderProgram::Desc programDesc = {};
- programDesc.slangGlobalScope = composedProgram.get();
-
- auto shaderProgram = device->createProgram(programDesc);
-
- outShaderProgram = shaderProgram;
- return SLANG_OK;
- }
+ Slang::ComPtr<slang::ISession> slangSession;
+ SLANG_RETURN_ON_FAIL(device->getSlangSession(slangSession.writeRef()));
+ Slang::ComPtr<slang::IBlob> diagnosticsBlob;
+ auto moduleInterfaceBlob =
+ Slang::UnownedRawBlob::create(moduleInterfaceSrc, strlen(moduleInterfaceSrc));
+ auto module0Blob = Slang::UnownedRawBlob::create(module0Src, strlen(module0Src));
+ auto module1Blob = Slang::UnownedRawBlob::create(module1Src, strlen(module1Src));
+ slang::IModule* moduleInterface =
+ slangSession->loadModuleFromSource("ifoo", "ifoo.slang", moduleInterfaceBlob);
+ slang::IModule* module0 = slangSession->loadModuleFromSource("module0", "path0", module0Blob);
+ slang::IModule* module1 = slangSession->loadModuleFromSource("module1", "path1", module1Blob);
+ ComPtr<slang::IEntryPoint> computeEntryPoint;
+ SLANG_RETURN_ON_FAIL(
+ module0->findEntryPointByName("computeMain", computeEntryPoint.writeRef()));
+
+ Slang::List<slang::IComponentType*> componentTypes;
+ componentTypes.add(moduleInterface);
+ componentTypes.add(module0);
+ if (linkSpecialization)
+ componentTypes.add(module1);
+ componentTypes.add(computeEntryPoint);
+
+ Slang::ComPtr<slang::IComponentType> composedProgram;
+ SlangResult result = slangSession->createCompositeComponentType(
+ componentTypes.getBuffer(),
+ componentTypes.getCount(),
+ composedProgram.writeRef(),
+ diagnosticsBlob.writeRef());
+ diagnoseIfNeeded(diagnosticsBlob);
+ SLANG_RETURN_ON_FAIL(result);
+
+ ComPtr<slang::IComponentType> linkedProgram;
+ result = composedProgram->link(linkedProgram.writeRef(), diagnosticsBlob.writeRef());
+ diagnoseIfNeeded(diagnosticsBlob);
+ SLANG_RETURN_ON_FAIL(result);
+
+ composedProgram = linkedProgram;
+ slangReflection = composedProgram->getLayout();
+
+ gfx::IShaderProgram::Desc programDesc = {};
+ programDesc.slangGlobalScope = composedProgram.get();
+
+ auto shaderProgram = device->createProgram(programDesc);
+
+ outShaderProgram = shaderProgram;
+ return SLANG_OK;
+}
- void linkTimeDefaultTestImpl(IDevice* device, UnitTestContext* context)
+void linkTimeDefaultTestImpl(IDevice* device, UnitTestContext* context)
+{
+ Slang::ComPtr<ITransientResourceHeap> transientHeap;
+ ITransientResourceHeap::Desc transientHeapDesc = {};
+ transientHeapDesc.constantBufferSize = 4096;
+ GFX_CHECK_CALL_ABORT(
+ device->createTransientResourceHeap(transientHeapDesc, transientHeap.writeRef()));
+
+ // Create pipeline without linking a specialization override module, so we should
+ // see the default value of `extern Foo`.
+ ComPtr<IShaderProgram> shaderProgram;
+ slang::ProgramLayout* slangReflection;
+ GFX_CHECK_CALL_ABORT(loadProgram(device, shaderProgram, slangReflection, false));
+
+ ComputePipelineStateDesc pipelineDesc = {};
+ pipelineDesc.program = shaderProgram.get();
+ ComPtr<gfx::IPipelineState> pipelineState;
+ GFX_CHECK_CALL_ABORT(
+ device->createComputePipelineState(pipelineDesc, pipelineState.writeRef()));
+
+ // Create pipeline with a specialization override module linked in, so we should
+ // see the result of using `Bar` for `extern Foo`.
+ ComPtr<IShaderProgram> shaderProgram1;
+ GFX_CHECK_CALL_ABORT(loadProgram(device, shaderProgram1, slangReflection, true));
+
+ ComputePipelineStateDesc pipelineDesc1 = {};
+ pipelineDesc1.program = shaderProgram1.get();
+ ComPtr<gfx::IPipelineState> pipelineState1;
+ GFX_CHECK_CALL_ABORT(
+ device->createComputePipelineState(pipelineDesc1, pipelineState1.writeRef()));
+
+ const int numberCount = 4;
+ float initialData[] = {0.0f, 0.0f, 0.0f, 0.0f};
+ IBufferResource::Desc bufferDesc = {};
+ bufferDesc.sizeInBytes = numberCount * sizeof(float);
+ bufferDesc.format = gfx::Format::Unknown;
+ bufferDesc.elementSize = sizeof(float);
+ bufferDesc.allowedStates = ResourceStateSet(
+ ResourceState::ShaderResource,
+ ResourceState::UnorderedAccess,
+ ResourceState::CopyDestination,
+ ResourceState::CopySource);
+ bufferDesc.defaultState = ResourceState::UnorderedAccess;
+ bufferDesc.memoryType = MemoryType::DeviceLocal;
+
+ ComPtr<IBufferResource> numbersBuffer;
+ GFX_CHECK_CALL_ABORT(
+ device->createBufferResource(bufferDesc, (void*)initialData, numbersBuffer.writeRef()));
+
+ ComPtr<IResourceView> bufferView;
+ IResourceView::Desc viewDesc = {};
+ viewDesc.type = IResourceView::Type::UnorderedAccess;
+ viewDesc.format = Format::Unknown;
+ GFX_CHECK_CALL_ABORT(
+ device->createBufferView(numbersBuffer, nullptr, viewDesc, bufferView.writeRef()));
+
+ ICommandQueue::Desc queueDesc = {ICommandQueue::QueueType::Graphics};
+ auto queue = device->createCommandQueue(queueDesc);
+
+ // We have done all the set up work, now it is time to start recording a command buffer for
+ // GPU execution.
{
- Slang::ComPtr<ITransientResourceHeap> transientHeap;
- ITransientResourceHeap::Desc transientHeapDesc = {};
- transientHeapDesc.constantBufferSize = 4096;
- GFX_CHECK_CALL_ABORT(
- device->createTransientResourceHeap(transientHeapDesc, transientHeap.writeRef()));
-
- // Create pipeline without linking a specialization override module, so we should
- // see the default value of `extern Foo`.
- ComPtr<IShaderProgram> shaderProgram;
- slang::ProgramLayout* slangReflection;
- GFX_CHECK_CALL_ABORT(loadProgram(device, shaderProgram, slangReflection, false));
-
- ComputePipelineStateDesc pipelineDesc = {};
- pipelineDesc.program = shaderProgram.get();
- ComPtr<gfx::IPipelineState> pipelineState;
- GFX_CHECK_CALL_ABORT(
- device->createComputePipelineState(pipelineDesc, pipelineState.writeRef()));
-
- // Create pipeline with a specialization override module linked in, so we should
- // see the result of using `Bar` for `extern Foo`.
- ComPtr<IShaderProgram> shaderProgram1;
- GFX_CHECK_CALL_ABORT(loadProgram(device, shaderProgram1, slangReflection, true));
-
- ComputePipelineStateDesc pipelineDesc1 = {};
- pipelineDesc1.program = shaderProgram1.get();
- ComPtr<gfx::IPipelineState> pipelineState1;
- GFX_CHECK_CALL_ABORT(
- device->createComputePipelineState(pipelineDesc1, pipelineState1.writeRef()));
-
- const int numberCount = 4;
- float initialData[] = { 0.0f, 0.0f, 0.0f, 0.0f };
- IBufferResource::Desc bufferDesc = {};
- bufferDesc.sizeInBytes = numberCount * sizeof(float);
- bufferDesc.format = gfx::Format::Unknown;
- bufferDesc.elementSize = sizeof(float);
- bufferDesc.allowedStates = ResourceStateSet(
- ResourceState::ShaderResource,
- ResourceState::UnorderedAccess,
- ResourceState::CopyDestination,
- ResourceState::CopySource);
- bufferDesc.defaultState = ResourceState::UnorderedAccess;
- bufferDesc.memoryType = MemoryType::DeviceLocal;
-
- ComPtr<IBufferResource> numbersBuffer;
- GFX_CHECK_CALL_ABORT(device->createBufferResource(
- bufferDesc,
- (void*)initialData,
- numbersBuffer.writeRef()));
-
- ComPtr<IResourceView> bufferView;
- IResourceView::Desc viewDesc = {};
- viewDesc.type = IResourceView::Type::UnorderedAccess;
- viewDesc.format = Format::Unknown;
- GFX_CHECK_CALL_ABORT(
- device->createBufferView(numbersBuffer, nullptr, viewDesc, bufferView.writeRef()));
-
- ICommandQueue::Desc queueDesc = { ICommandQueue::QueueType::Graphics };
- auto queue = device->createCommandQueue(queueDesc);
-
- // We have done all the set up work, now it is time to start recording a command buffer for
- // GPU execution.
- {
- auto commandBuffer = transientHeap->createCommandBuffer();
- auto encoder = commandBuffer->encodeComputeCommands();
-
- auto rootObject = encoder->bindPipeline(pipelineState);
-
- ShaderCursor entryPointCursor(
- rootObject->getEntryPoint(0)); // get a cursor the the first entry-point.
- // Bind buffer view to the entry point.
- entryPointCursor.getPath("buffer").setResource(bufferView);
-
- encoder->dispatchCompute(1, 1, 1);
- encoder->endEncoding();
- commandBuffer->close();
- queue->executeCommandBuffer(commandBuffer);
- queue->waitOnHost();
- }
-
- compareComputeResult(
- device,
- numbersBuffer,
- Slang::makeArray<float>(8.0));
-
- // Now run again with the overrided program.
- {
- auto commandBuffer = transientHeap->createCommandBuffer();
- auto encoder = commandBuffer->encodeComputeCommands();
-
- auto rootObject = encoder->bindPipeline(pipelineState1);
-
- ShaderCursor entryPointCursor(
- rootObject->getEntryPoint(0)); // get a cursor the the first entry-point.
- // Bind buffer view to the entry point.
- entryPointCursor.getPath("buffer").setResource(bufferView);
-
- encoder->dispatchCompute(1, 1, 1);
- encoder->endEncoding();
- commandBuffer->close();
- queue->executeCommandBuffer(commandBuffer);
- queue->waitOnHost();
- }
-
- compareComputeResult(
- device,
- numbersBuffer,
- Slang::makeArray<float>(10.0));
- }
+ auto commandBuffer = transientHeap->createCommandBuffer();
+ auto encoder = commandBuffer->encodeComputeCommands();
- SLANG_UNIT_TEST(linkTimeDefaultD3D12)
- {
- runTestImpl(linkTimeDefaultTestImpl, unitTestContext, Slang::RenderApiFlag::D3D12);
+ auto rootObject = encoder->bindPipeline(pipelineState);
+
+ ShaderCursor entryPointCursor(
+ rootObject->getEntryPoint(0)); // get a cursor the the first entry-point.
+ // Bind buffer view to the entry point.
+ entryPointCursor.getPath("buffer").setResource(bufferView);
+
+ encoder->dispatchCompute(1, 1, 1);
+ encoder->endEncoding();
+ commandBuffer->close();
+ queue->executeCommandBuffer(commandBuffer);
+ queue->waitOnHost();
}
- SLANG_UNIT_TEST(linkTimeDefaultVulkan)
+ compareComputeResult(device, numbersBuffer, Slang::makeArray<float>(8.0));
+
+ // Now run again with the overrided program.
{
- runTestImpl(linkTimeDefaultTestImpl, unitTestContext, Slang::RenderApiFlag::Vulkan);
+ auto commandBuffer = transientHeap->createCommandBuffer();
+ auto encoder = commandBuffer->encodeComputeCommands();
+
+ auto rootObject = encoder->bindPipeline(pipelineState1);
+
+ ShaderCursor entryPointCursor(
+ rootObject->getEntryPoint(0)); // get a cursor the the first entry-point.
+ // Bind buffer view to the entry point.
+ entryPointCursor.getPath("buffer").setResource(bufferView);
+
+ encoder->dispatchCompute(1, 1, 1);
+ encoder->endEncoding();
+ commandBuffer->close();
+ queue->executeCommandBuffer(commandBuffer);
+ queue->waitOnHost();
}
+ compareComputeResult(device, numbersBuffer, Slang::makeArray<float>(10.0));
}
+
+SLANG_UNIT_TEST(linkTimeDefaultD3D12)
+{
+ runTestImpl(linkTimeDefaultTestImpl, unitTestContext, Slang::RenderApiFlag::D3D12);
+}
+
+SLANG_UNIT_TEST(linkTimeDefaultVulkan)
+{
+ runTestImpl(linkTimeDefaultTestImpl, unitTestContext, Slang::RenderApiFlag::Vulkan);
+}
+
+} // namespace gfx_test
diff --git a/tools/gfx-unit-test/link-time-options.cpp b/tools/gfx-unit-test/link-time-options.cpp
index f14a918e8..590db576e 100644
--- a/tools/gfx-unit-test/link-time-options.cpp
+++ b/tools/gfx-unit-test/link-time-options.cpp
@@ -1,152 +1,148 @@
-#include "tools/unit-test/slang-unit-test.h"
-
-#include "slang-gfx.h"
#include "gfx-test-util.h"
-#include "tools/gfx-util/shader-cursor.h"
+#include "slang-gfx.h"
#include "source/core/slang-basic.h"
#include "source/core/slang-blob.h"
+#include "tools/gfx-util/shader-cursor.h"
+#include "tools/unit-test/slang-unit-test.h"
using namespace gfx;
namespace gfx_test
{
- // In this test,
- // we will run a compute shader that compiles to HLSL with a reference to the macro "DOWNSTREAM_VALUE"
- // that will be provided to dxc through slang's link-time compiler options.
- // The test verifies that `IComponentType2::linkWithOptions()` is able to produce a linked IComponentType
- // with additional compiler options. Here we will specify a DownstreamArg compiler option to define
- // the value of DOWNSTREAM_VALUE when running dxc.
- //
- static Slang::Result loadProgram(
- gfx::IDevice* device,
- Slang::ComPtr<gfx::IShaderProgram>& outShaderProgram,
- const char* shaderModuleName,
- const char* entryPointName,
- slang::ProgramLayout*& slangReflection)
- {
- Slang::ComPtr<slang::ISession> slangSession;
- SLANG_RETURN_ON_FAIL(device->getSlangSession(slangSession.writeRef()));
- Slang::ComPtr<slang::IBlob> diagnosticsBlob;
- slang::IModule* module = slangSession->loadModule(shaderModuleName, diagnosticsBlob.writeRef());
- diagnoseIfNeeded(diagnosticsBlob);
- if (!module)
- return SLANG_FAIL;
-
- ComPtr<slang::IEntryPoint> computeEntryPoint;
- SLANG_RETURN_ON_FAIL(
- module->findEntryPointByName(entryPointName, computeEntryPoint.writeRef()));
-
- Slang::List<slang::IComponentType*> componentTypes;
- componentTypes.add(module);
- componentTypes.add(computeEntryPoint);
-
- Slang::ComPtr<slang::IComponentType> composedProgram;
- SlangResult result = slangSession->createCompositeComponentType(
- componentTypes.getBuffer(),
- componentTypes.getCount(),
- composedProgram.writeRef(),
- diagnosticsBlob.writeRef());
- diagnoseIfNeeded(diagnosticsBlob);
- SLANG_RETURN_ON_FAIL(result);
-
- ComPtr<slang::IComponentType> linkedProgram;
- slang::CompilerOptionEntry entry;
- entry.name = slang::CompilerOptionName::DownstreamArgs;
- entry.value.kind = slang::CompilerOptionValueKind::String;
- entry.value.stringValue0 = "dxc";
- entry.value.stringValue1 = "-DDOWNSTREAM_VALUE=4.0";
- result = composedProgram->linkWithOptions(linkedProgram.writeRef(), 1, &entry, diagnosticsBlob.writeRef());
- diagnoseIfNeeded(diagnosticsBlob);
- SLANG_RETURN_ON_FAIL(result);
-
- composedProgram = linkedProgram;
- slangReflection = composedProgram->getLayout();
-
- gfx::IShaderProgram::Desc programDesc = {};
- programDesc.slangGlobalScope = composedProgram.get();
-
- auto shaderProgram = device->createProgram(programDesc);
-
- outShaderProgram = shaderProgram;
- return SLANG_OK;
- }
+// In this test,
+// we will run a compute shader that compiles to HLSL with a reference to the macro
+// "DOWNSTREAM_VALUE" that will be provided to dxc through slang's link-time compiler options. The
+// test verifies that `IComponentType2::linkWithOptions()` is able to produce a linked
+// IComponentType with additional compiler options. Here we will specify a DownstreamArg compiler
+// option to define the value of DOWNSTREAM_VALUE when running dxc.
+//
+static Slang::Result loadProgram(
+ gfx::IDevice* device,
+ Slang::ComPtr<gfx::IShaderProgram>& outShaderProgram,
+ const char* shaderModuleName,
+ const char* entryPointName,
+ slang::ProgramLayout*& slangReflection)
+{
+ Slang::ComPtr<slang::ISession> slangSession;
+ SLANG_RETURN_ON_FAIL(device->getSlangSession(slangSession.writeRef()));
+ Slang::ComPtr<slang::IBlob> diagnosticsBlob;
+ slang::IModule* module = slangSession->loadModule(shaderModuleName, diagnosticsBlob.writeRef());
+ diagnoseIfNeeded(diagnosticsBlob);
+ if (!module)
+ return SLANG_FAIL;
+
+ ComPtr<slang::IEntryPoint> computeEntryPoint;
+ SLANG_RETURN_ON_FAIL(
+ module->findEntryPointByName(entryPointName, computeEntryPoint.writeRef()));
+
+ Slang::List<slang::IComponentType*> componentTypes;
+ componentTypes.add(module);
+ componentTypes.add(computeEntryPoint);
+
+ Slang::ComPtr<slang::IComponentType> composedProgram;
+ SlangResult result = slangSession->createCompositeComponentType(
+ componentTypes.getBuffer(),
+ componentTypes.getCount(),
+ composedProgram.writeRef(),
+ diagnosticsBlob.writeRef());
+ diagnoseIfNeeded(diagnosticsBlob);
+ SLANG_RETURN_ON_FAIL(result);
+
+ ComPtr<slang::IComponentType> linkedProgram;
+ slang::CompilerOptionEntry entry;
+ entry.name = slang::CompilerOptionName::DownstreamArgs;
+ entry.value.kind = slang::CompilerOptionValueKind::String;
+ entry.value.stringValue0 = "dxc";
+ entry.value.stringValue1 = "-DDOWNSTREAM_VALUE=4.0";
+ result = composedProgram
+ ->linkWithOptions(linkedProgram.writeRef(), 1, &entry, diagnosticsBlob.writeRef());
+ diagnoseIfNeeded(diagnosticsBlob);
+ SLANG_RETURN_ON_FAIL(result);
+
+ composedProgram = linkedProgram;
+ slangReflection = composedProgram->getLayout();
+
+ gfx::IShaderProgram::Desc programDesc = {};
+ programDesc.slangGlobalScope = composedProgram.get();
+
+ auto shaderProgram = device->createProgram(programDesc);
+
+ outShaderProgram = shaderProgram;
+ return SLANG_OK;
+}
- void linkTimeOptionTestImpl(IDevice* device, UnitTestContext* context)
+void linkTimeOptionTestImpl(IDevice* device, UnitTestContext* context)
+{
+ Slang::ComPtr<ITransientResourceHeap> transientHeap;
+ ITransientResourceHeap::Desc transientHeapDesc = {};
+ transientHeapDesc.constantBufferSize = 4096;
+ GFX_CHECK_CALL_ABORT(
+ device->createTransientResourceHeap(transientHeapDesc, transientHeap.writeRef()));
+
+ ComPtr<IShaderProgram> shaderProgram;
+ slang::ProgramLayout* slangReflection;
+ GFX_CHECK_CALL_ABORT(
+ loadProgram(device, shaderProgram, "link-time-options", "computeMain", slangReflection));
+
+ ComputePipelineStateDesc pipelineDesc = {};
+ pipelineDesc.program = shaderProgram.get();
+ ComPtr<gfx::IPipelineState> pipelineState;
+ GFX_CHECK_CALL_ABORT(
+ device->createComputePipelineState(pipelineDesc, pipelineState.writeRef()));
+
+ const int numberCount = 4;
+ float initialData[] = {0.0f, 0.0f, 0.0f, 0.0f};
+ IBufferResource::Desc bufferDesc = {};
+ bufferDesc.sizeInBytes = numberCount * sizeof(float);
+ bufferDesc.format = gfx::Format::Unknown;
+ bufferDesc.elementSize = sizeof(float);
+ bufferDesc.allowedStates = ResourceStateSet(
+ ResourceState::ShaderResource,
+ ResourceState::UnorderedAccess,
+ ResourceState::CopyDestination,
+ ResourceState::CopySource);
+ bufferDesc.defaultState = ResourceState::UnorderedAccess;
+ bufferDesc.memoryType = MemoryType::DeviceLocal;
+
+ ComPtr<IBufferResource> numbersBuffer;
+ GFX_CHECK_CALL_ABORT(
+ device->createBufferResource(bufferDesc, (void*)initialData, numbersBuffer.writeRef()));
+
+ ComPtr<IResourceView> bufferView;
+ IResourceView::Desc viewDesc = {};
+ viewDesc.type = IResourceView::Type::UnorderedAccess;
+ viewDesc.format = Format::Unknown;
+ GFX_CHECK_CALL_ABORT(
+ device->createBufferView(numbersBuffer, nullptr, viewDesc, bufferView.writeRef()));
+
+ // We have done all the set up work, now it is time to start recording a command buffer for
+ // GPU execution.
{
- Slang::ComPtr<ITransientResourceHeap> transientHeap;
- ITransientResourceHeap::Desc transientHeapDesc = {};
- transientHeapDesc.constantBufferSize = 4096;
- GFX_CHECK_CALL_ABORT(
- device->createTransientResourceHeap(transientHeapDesc, transientHeap.writeRef()));
-
- ComPtr<IShaderProgram> shaderProgram;
- slang::ProgramLayout* slangReflection;
- GFX_CHECK_CALL_ABORT(loadProgram(device, shaderProgram, "link-time-options", "computeMain", slangReflection));
-
- ComputePipelineStateDesc pipelineDesc = {};
- pipelineDesc.program = shaderProgram.get();
- ComPtr<gfx::IPipelineState> pipelineState;
- GFX_CHECK_CALL_ABORT(
- device->createComputePipelineState(pipelineDesc, pipelineState.writeRef()));
-
- const int numberCount = 4;
- float initialData[] = { 0.0f, 0.0f, 0.0f, 0.0f };
- IBufferResource::Desc bufferDesc = {};
- bufferDesc.sizeInBytes = numberCount * sizeof(float);
- bufferDesc.format = gfx::Format::Unknown;
- bufferDesc.elementSize = sizeof(float);
- bufferDesc.allowedStates = ResourceStateSet(
- ResourceState::ShaderResource,
- ResourceState::UnorderedAccess,
- ResourceState::CopyDestination,
- ResourceState::CopySource);
- bufferDesc.defaultState = ResourceState::UnorderedAccess;
- bufferDesc.memoryType = MemoryType::DeviceLocal;
-
- ComPtr<IBufferResource> numbersBuffer;
- GFX_CHECK_CALL_ABORT(device->createBufferResource(
- bufferDesc,
- (void*)initialData,
- numbersBuffer.writeRef()));
-
- ComPtr<IResourceView> bufferView;
- IResourceView::Desc viewDesc = {};
- viewDesc.type = IResourceView::Type::UnorderedAccess;
- viewDesc.format = Format::Unknown;
- GFX_CHECK_CALL_ABORT(
- device->createBufferView(numbersBuffer, nullptr, viewDesc, bufferView.writeRef()));
-
- // We have done all the set up work, now it is time to start recording a command buffer for
- // GPU execution.
- {
- ICommandQueue::Desc queueDesc = { ICommandQueue::QueueType::Graphics };
- auto queue = device->createCommandQueue(queueDesc);
-
- auto commandBuffer = transientHeap->createCommandBuffer();
- auto encoder = commandBuffer->encodeComputeCommands();
-
- auto rootObject = encoder->bindPipeline(pipelineState);
-
- ShaderCursor entryPointCursor(
- rootObject->getEntryPoint(0)); // get a cursor the the first entry-point.
- // Bind buffer view to the entry point.
- entryPointCursor.getPath("buffer").setResource(bufferView);
-
- encoder->dispatchCompute(1, 1, 1);
- encoder->endEncoding();
- commandBuffer->close();
- queue->executeCommandBuffer(commandBuffer);
- queue->waitOnHost();
- }
-
- compareComputeResult(
- device,
- numbersBuffer,
- Slang::makeArray<float>(4.0));
- }
+ ICommandQueue::Desc queueDesc = {ICommandQueue::QueueType::Graphics};
+ auto queue = device->createCommandQueue(queueDesc);
- SLANG_UNIT_TEST(linkTimeOptionD3D12)
- {
- runTestImpl(linkTimeOptionTestImpl, unitTestContext, Slang::RenderApiFlag::D3D12);
+ auto commandBuffer = transientHeap->createCommandBuffer();
+ auto encoder = commandBuffer->encodeComputeCommands();
+
+ auto rootObject = encoder->bindPipeline(pipelineState);
+
+ ShaderCursor entryPointCursor(
+ rootObject->getEntryPoint(0)); // get a cursor the the first entry-point.
+ // Bind buffer view to the entry point.
+ entryPointCursor.getPath("buffer").setResource(bufferView);
+
+ encoder->dispatchCompute(1, 1, 1);
+ encoder->endEncoding();
+ commandBuffer->close();
+ queue->executeCommandBuffer(commandBuffer);
+ queue->waitOnHost();
}
+
+ compareComputeResult(device, numbersBuffer, Slang::makeArray<float>(4.0));
+}
+
+SLANG_UNIT_TEST(linkTimeOptionD3D12)
+{
+ runTestImpl(linkTimeOptionTestImpl, unitTestContext, Slang::RenderApiFlag::D3D12);
}
+} // namespace gfx_test
diff --git a/tools/gfx-unit-test/link-time-type.cpp b/tools/gfx-unit-test/link-time-type.cpp
index 39496b3fe..81c738126 100644
--- a/tools/gfx-unit-test/link-time-type.cpp
+++ b/tools/gfx-unit-test/link-time-type.cpp
@@ -1,21 +1,20 @@
-#include "tools/unit-test/slang-unit-test.h"
-
-#include "slang-gfx.h"
#include "gfx-test-util.h"
-#include "tools/gfx-util/shader-cursor.h"
+#include "slang-gfx.h"
#include "source/core/slang-basic.h"
#include "source/core/slang-blob.h"
+#include "tools/gfx-util/shader-cursor.h"
+#include "tools/unit-test/slang-unit-test.h"
using namespace gfx;
namespace gfx_test
{
- static Slang::Result loadProgram(
- gfx::IDevice* device,
- Slang::ComPtr<gfx::IShaderProgram>& outShaderProgram,
- slang::ProgramLayout*& slangReflection)
- {
- const char* moduleInterfaceSrc = R"(
+static Slang::Result loadProgram(
+ gfx::IDevice* device,
+ Slang::ComPtr<gfx::IShaderProgram>& outShaderProgram,
+ slang::ProgramLayout*& slangReflection)
+{
+ const char* moduleInterfaceSrc = R"(
interface IBase : IDifferentiable
{
[Differentiable]
@@ -50,7 +49,7 @@ namespace gfx_test
__init(int x) { val = x; }
};
)";
- const char* module0Src = R"(
+ const char* module0Src = R"(
import ifoo;
extern struct Foo : IFoo;
@@ -62,139 +61,133 @@ namespace gfx_test
buffer[0] = foo.getValue() + foo.val2 + Foo.offset + foo.getBaseValue();
}
)";
- const char* module1Src = R"(
+ const char* module1Src = R"(
import ifoo;
export struct Foo : IFoo = FooImpl;)";
- Slang::ComPtr<slang::ISession> slangSession;
- SLANG_RETURN_ON_FAIL(device->getSlangSession(slangSession.writeRef()));
- Slang::ComPtr<slang::IBlob> diagnosticsBlob;
- auto moduleInterfaceBlob = Slang::UnownedRawBlob::create(moduleInterfaceSrc, strlen(moduleInterfaceSrc));
- auto module0Blob = Slang::UnownedRawBlob::create(module0Src, strlen(module0Src));
- auto module1Blob = Slang::UnownedRawBlob::create(module1Src, strlen(module1Src));
- slang::IModule* moduleInterface = slangSession->loadModuleFromSource("ifoo", "ifoo.slang",
- moduleInterfaceBlob);
- slang::IModule* module0 = slangSession->loadModuleFromSource("module0", "path0",
- module0Blob);
- slang::IModule* module1 = slangSession->loadModuleFromSource("module1", "path1",
- module1Blob);
- ComPtr<slang::IEntryPoint> computeEntryPoint;
- SLANG_RETURN_ON_FAIL(
- module0->findEntryPointByName("computeMain", computeEntryPoint.writeRef()));
-
- Slang::List<slang::IComponentType*> componentTypes;
- componentTypes.add(moduleInterface);
- componentTypes.add(module0);
- componentTypes.add(module1);
- componentTypes.add(computeEntryPoint);
-
- Slang::ComPtr<slang::IComponentType> composedProgram;
- SlangResult result = slangSession->createCompositeComponentType(
- componentTypes.getBuffer(),
- componentTypes.getCount(),
- composedProgram.writeRef(),
- diagnosticsBlob.writeRef());
- diagnoseIfNeeded(diagnosticsBlob);
- SLANG_RETURN_ON_FAIL(result);
-
- ComPtr<slang::IComponentType> linkedProgram;
- result = composedProgram->link(linkedProgram.writeRef(), diagnosticsBlob.writeRef());
- diagnoseIfNeeded(diagnosticsBlob);
- SLANG_RETURN_ON_FAIL(result);
-
- composedProgram = linkedProgram;
- slangReflection = composedProgram->getLayout();
-
- gfx::IShaderProgram::Desc programDesc = {};
- programDesc.slangGlobalScope = composedProgram.get();
-
- auto shaderProgram = device->createProgram(programDesc);
-
- outShaderProgram = shaderProgram;
- return SLANG_OK;
- }
+ Slang::ComPtr<slang::ISession> slangSession;
+ SLANG_RETURN_ON_FAIL(device->getSlangSession(slangSession.writeRef()));
+ Slang::ComPtr<slang::IBlob> diagnosticsBlob;
+ auto moduleInterfaceBlob =
+ Slang::UnownedRawBlob::create(moduleInterfaceSrc, strlen(moduleInterfaceSrc));
+ auto module0Blob = Slang::UnownedRawBlob::create(module0Src, strlen(module0Src));
+ auto module1Blob = Slang::UnownedRawBlob::create(module1Src, strlen(module1Src));
+ slang::IModule* moduleInterface =
+ slangSession->loadModuleFromSource("ifoo", "ifoo.slang", moduleInterfaceBlob);
+ slang::IModule* module0 = slangSession->loadModuleFromSource("module0", "path0", module0Blob);
+ slang::IModule* module1 = slangSession->loadModuleFromSource("module1", "path1", module1Blob);
+ ComPtr<slang::IEntryPoint> computeEntryPoint;
+ SLANG_RETURN_ON_FAIL(
+ module0->findEntryPointByName("computeMain", computeEntryPoint.writeRef()));
+
+ Slang::List<slang::IComponentType*> componentTypes;
+ componentTypes.add(moduleInterface);
+ componentTypes.add(module0);
+ componentTypes.add(module1);
+ componentTypes.add(computeEntryPoint);
+
+ Slang::ComPtr<slang::IComponentType> composedProgram;
+ SlangResult result = slangSession->createCompositeComponentType(
+ componentTypes.getBuffer(),
+ componentTypes.getCount(),
+ composedProgram.writeRef(),
+ diagnosticsBlob.writeRef());
+ diagnoseIfNeeded(diagnosticsBlob);
+ SLANG_RETURN_ON_FAIL(result);
+
+ ComPtr<slang::IComponentType> linkedProgram;
+ result = composedProgram->link(linkedProgram.writeRef(), diagnosticsBlob.writeRef());
+ diagnoseIfNeeded(diagnosticsBlob);
+ SLANG_RETURN_ON_FAIL(result);
+
+ composedProgram = linkedProgram;
+ slangReflection = composedProgram->getLayout();
+
+ gfx::IShaderProgram::Desc programDesc = {};
+ programDesc.slangGlobalScope = composedProgram.get();
+
+ auto shaderProgram = device->createProgram(programDesc);
+
+ outShaderProgram = shaderProgram;
+ return SLANG_OK;
+}
- void linkTimeTypeTestImpl(IDevice* device, UnitTestContext* context)
+void linkTimeTypeTestImpl(IDevice* device, UnitTestContext* context)
+{
+ Slang::ComPtr<ITransientResourceHeap> transientHeap;
+ ITransientResourceHeap::Desc transientHeapDesc = {};
+ transientHeapDesc.constantBufferSize = 4096;
+ GFX_CHECK_CALL_ABORT(
+ device->createTransientResourceHeap(transientHeapDesc, transientHeap.writeRef()));
+
+ ComPtr<IShaderProgram> shaderProgram;
+ slang::ProgramLayout* slangReflection;
+ GFX_CHECK_CALL_ABORT(loadProgram(device, shaderProgram, slangReflection));
+
+ ComputePipelineStateDesc pipelineDesc = {};
+ pipelineDesc.program = shaderProgram.get();
+ ComPtr<gfx::IPipelineState> pipelineState;
+ GFX_CHECK_CALL_ABORT(
+ device->createComputePipelineState(pipelineDesc, pipelineState.writeRef()));
+
+ const int numberCount = 4;
+ float initialData[] = {0.0f, 0.0f, 0.0f, 0.0f};
+ IBufferResource::Desc bufferDesc = {};
+ bufferDesc.sizeInBytes = numberCount * sizeof(float);
+ bufferDesc.format = gfx::Format::Unknown;
+ bufferDesc.elementSize = sizeof(float);
+ bufferDesc.allowedStates = ResourceStateSet(
+ ResourceState::ShaderResource,
+ ResourceState::UnorderedAccess,
+ ResourceState::CopyDestination,
+ ResourceState::CopySource);
+ bufferDesc.defaultState = ResourceState::UnorderedAccess;
+ bufferDesc.memoryType = MemoryType::DeviceLocal;
+
+ ComPtr<IBufferResource> numbersBuffer;
+ GFX_CHECK_CALL_ABORT(
+ device->createBufferResource(bufferDesc, (void*)initialData, numbersBuffer.writeRef()));
+
+ ComPtr<IResourceView> bufferView;
+ IResourceView::Desc viewDesc = {};
+ viewDesc.type = IResourceView::Type::UnorderedAccess;
+ viewDesc.format = Format::Unknown;
+ GFX_CHECK_CALL_ABORT(
+ device->createBufferView(numbersBuffer, nullptr, viewDesc, bufferView.writeRef()));
+
+ // We have done all the set up work, now it is time to start recording a command buffer for
+ // GPU execution.
{
- Slang::ComPtr<ITransientResourceHeap> transientHeap;
- ITransientResourceHeap::Desc transientHeapDesc = {};
- transientHeapDesc.constantBufferSize = 4096;
- GFX_CHECK_CALL_ABORT(
- device->createTransientResourceHeap(transientHeapDesc, transientHeap.writeRef()));
-
- ComPtr<IShaderProgram> shaderProgram;
- slang::ProgramLayout* slangReflection;
- GFX_CHECK_CALL_ABORT(loadProgram(device, shaderProgram, slangReflection));
-
- ComputePipelineStateDesc pipelineDesc = {};
- pipelineDesc.program = shaderProgram.get();
- ComPtr<gfx::IPipelineState> pipelineState;
- GFX_CHECK_CALL_ABORT(
- device->createComputePipelineState(pipelineDesc, pipelineState.writeRef()));
-
- const int numberCount = 4;
- float initialData[] = { 0.0f, 0.0f, 0.0f, 0.0f };
- IBufferResource::Desc bufferDesc = {};
- bufferDesc.sizeInBytes = numberCount * sizeof(float);
- bufferDesc.format = gfx::Format::Unknown;
- bufferDesc.elementSize = sizeof(float);
- bufferDesc.allowedStates = ResourceStateSet(
- ResourceState::ShaderResource,
- ResourceState::UnorderedAccess,
- ResourceState::CopyDestination,
- ResourceState::CopySource);
- bufferDesc.defaultState = ResourceState::UnorderedAccess;
- bufferDesc.memoryType = MemoryType::DeviceLocal;
-
- ComPtr<IBufferResource> numbersBuffer;
- GFX_CHECK_CALL_ABORT(device->createBufferResource(
- bufferDesc,
- (void*)initialData,
- numbersBuffer.writeRef()));
-
- ComPtr<IResourceView> bufferView;
- IResourceView::Desc viewDesc = {};
- viewDesc.type = IResourceView::Type::UnorderedAccess;
- viewDesc.format = Format::Unknown;
- GFX_CHECK_CALL_ABORT(
- device->createBufferView(numbersBuffer, nullptr, viewDesc, bufferView.writeRef()));
-
- // We have done all the set up work, now it is time to start recording a command buffer for
- // GPU execution.
- {
- ICommandQueue::Desc queueDesc = { ICommandQueue::QueueType::Graphics };
- auto queue = device->createCommandQueue(queueDesc);
-
- auto commandBuffer = transientHeap->createCommandBuffer();
- auto encoder = commandBuffer->encodeComputeCommands();
-
- auto rootObject = encoder->bindPipeline(pipelineState);
-
- ShaderCursor entryPointCursor(
- rootObject->getEntryPoint(0)); // get a cursor the the first entry-point.
- // Bind buffer view to the entry point.
- entryPointCursor.getPath("buffer").setResource(bufferView);
-
- encoder->dispatchCompute(1, 1, 1);
- encoder->endEncoding();
- commandBuffer->close();
- queue->executeCommandBuffer(commandBuffer);
- queue->waitOnHost();
- }
-
- compareComputeResult(
- device,
- numbersBuffer,
- Slang::makeArray<float>(11.0));
- }
+ ICommandQueue::Desc queueDesc = {ICommandQueue::QueueType::Graphics};
+ auto queue = device->createCommandQueue(queueDesc);
- SLANG_UNIT_TEST(linkTimeTypeD3D12)
- {
- runTestImpl(linkTimeTypeTestImpl, unitTestContext, Slang::RenderApiFlag::D3D12);
- }
+ auto commandBuffer = transientHeap->createCommandBuffer();
+ auto encoder = commandBuffer->encodeComputeCommands();
- SLANG_UNIT_TEST(linkTimeTypeVulkan)
- {
- runTestImpl(linkTimeTypeTestImpl, unitTestContext, Slang::RenderApiFlag::Vulkan);
+ auto rootObject = encoder->bindPipeline(pipelineState);
+
+ ShaderCursor entryPointCursor(
+ rootObject->getEntryPoint(0)); // get a cursor the the first entry-point.
+ // Bind buffer view to the entry point.
+ entryPointCursor.getPath("buffer").setResource(bufferView);
+
+ encoder->dispatchCompute(1, 1, 1);
+ encoder->endEncoding();
+ commandBuffer->close();
+ queue->executeCommandBuffer(commandBuffer);
+ queue->waitOnHost();
}
+ compareComputeResult(device, numbersBuffer, Slang::makeArray<float>(11.0));
+}
+
+SLANG_UNIT_TEST(linkTimeTypeD3D12)
+{
+ runTestImpl(linkTimeTypeTestImpl, unitTestContext, Slang::RenderApiFlag::D3D12);
+}
+
+SLANG_UNIT_TEST(linkTimeTypeVulkan)
+{
+ runTestImpl(linkTimeTypeTestImpl, unitTestContext, Slang::RenderApiFlag::Vulkan);
}
+
+} // namespace gfx_test
diff --git a/tools/gfx-unit-test/mutable-shader-object.cpp b/tools/gfx-unit-test/mutable-shader-object.cpp
index cc9707643..9c91a7ca3 100644
--- a/tools/gfx-unit-test/mutable-shader-object.cpp
+++ b/tools/gfx-unit-test/mutable-shader-object.cpp
@@ -1,136 +1,141 @@
-#include "tools/unit-test/slang-unit-test.h"
-
-#include "slang-gfx.h"
#include "gfx-test-util.h"
-#include "tools/gfx-util/shader-cursor.h"
+#include "slang-gfx.h"
#include "source/core/slang-basic.h"
+#include "tools/gfx-util/shader-cursor.h"
+#include "tools/unit-test/slang-unit-test.h"
using namespace gfx;
namespace gfx_test
{
- void mutableShaderObjectTestImpl(IDevice* device, UnitTestContext* context)
+void mutableShaderObjectTestImpl(IDevice* device, UnitTestContext* context)
+{
+ Slang::ComPtr<ITransientResourceHeap> transientHeap;
+ ITransientResourceHeap::Desc transientHeapDesc = {};
+ transientHeapDesc.constantBufferSize = 4096;
+ GFX_CHECK_CALL_ABORT(
+ device->createTransientResourceHeap(transientHeapDesc, transientHeap.writeRef()));
+
+ ComPtr<IShaderProgram> shaderProgram;
+ slang::ProgramLayout* slangReflection;
+ GFX_CHECK_CALL_ABORT(loadComputeProgram(
+ device,
+ shaderProgram,
+ "mutable-shader-object",
+ "computeMain",
+ slangReflection));
+
+ ComputePipelineStateDesc pipelineDesc = {};
+ pipelineDesc.program = shaderProgram.get();
+ ComPtr<gfx::IPipelineState> pipelineState;
+ GFX_CHECK_CALL_ABORT(
+ device->createComputePipelineState(pipelineDesc, pipelineState.writeRef()));
+
+ float initialData[] = {0.0f, 1.0f, 2.0f, 3.0f};
+ const int numberCount = SLANG_COUNT_OF(initialData);
+ IBufferResource::Desc bufferDesc = {};
+ bufferDesc.sizeInBytes = sizeof(initialData);
+ bufferDesc.format = gfx::Format::Unknown;
+ bufferDesc.elementSize = sizeof(float);
+ bufferDesc.allowedStates = ResourceStateSet(
+ ResourceState::ShaderResource,
+ ResourceState::UnorderedAccess,
+ ResourceState::CopyDestination,
+ ResourceState::CopySource);
+ bufferDesc.defaultState = ResourceState::UnorderedAccess;
+ bufferDesc.memoryType = MemoryType::DeviceLocal;
+
+ ComPtr<IBufferResource> numbersBuffer;
+ GFX_CHECK_CALL_ABORT(
+ device->createBufferResource(bufferDesc, (void*)initialData, numbersBuffer.writeRef()));
+
+ ComPtr<IResourceView> bufferView;
+ IResourceView::Desc viewDesc = {};
+ viewDesc.type = IResourceView::Type::UnorderedAccess;
+ viewDesc.format = Format::Unknown;
+ GFX_CHECK_CALL_ABORT(
+ device->createBufferView(numbersBuffer, nullptr, viewDesc, bufferView.writeRef()));
+
{
- Slang::ComPtr<ITransientResourceHeap> transientHeap;
- ITransientResourceHeap::Desc transientHeapDesc = {};
- transientHeapDesc.constantBufferSize = 4096;
- GFX_CHECK_CALL_ABORT(
- device->createTransientResourceHeap(transientHeapDesc, transientHeap.writeRef()));
-
- ComPtr<IShaderProgram> shaderProgram;
- slang::ProgramLayout* slangReflection;
- GFX_CHECK_CALL_ABORT(loadComputeProgram(device, shaderProgram, "mutable-shader-object", "computeMain", slangReflection));
-
- ComputePipelineStateDesc pipelineDesc = {};
- pipelineDesc.program = shaderProgram.get();
- ComPtr<gfx::IPipelineState> pipelineState;
- GFX_CHECK_CALL_ABORT(
- device->createComputePipelineState(pipelineDesc, pipelineState.writeRef()));
-
- float initialData[] = { 0.0f, 1.0f, 2.0f, 3.0f };
- const int numberCount = SLANG_COUNT_OF(initialData);
- IBufferResource::Desc bufferDesc = {};
- bufferDesc.sizeInBytes = sizeof(initialData);
- bufferDesc.format = gfx::Format::Unknown;
- bufferDesc.elementSize = sizeof(float);
- bufferDesc.allowedStates = ResourceStateSet(
- ResourceState::ShaderResource,
+ slang::TypeReflection* addTransformerType =
+ slangReflection->findTypeByName("AddTransformer");
+
+ ComPtr<IShaderObject> transformer;
+ GFX_CHECK_CALL_ABORT(device->createMutableShaderObject(
+ addTransformerType,
+ ShaderObjectContainerType::None,
+ transformer.writeRef()));
+ // Set the `c` field of the `AddTransformer`.
+ float c = 1.0f;
+ ShaderCursor(transformer).getPath("c").setData(&c, sizeof(float));
+
+ ICommandQueue::Desc queueDesc = {ICommandQueue::QueueType::Graphics};
+ auto queue = device->createCommandQueue(queueDesc);
+
+ auto commandBuffer = transientHeap->createCommandBuffer();
+ auto encoder = commandBuffer->encodeComputeCommands();
+
+ auto rootObject = encoder->bindPipeline(pipelineState);
+
+ auto entryPointCursor = ShaderCursor(rootObject->getEntryPoint(0));
+
+ entryPointCursor.getPath("buffer").setResource(bufferView);
+
+ // Bind the previously created transformer object to root object.
+ ComPtr<IShaderObject> transformerVersion;
+ transformer->getCurrentVersion(transientHeap, transformerVersion.writeRef());
+ entryPointCursor.getPath("transformer").setObject(transformerVersion);
+
+ encoder->dispatchCompute(1, 1, 1);
+ encoder->endEncoding();
+
+ auto barrierEncoder = commandBuffer->encodeResourceCommands();
+ barrierEncoder->bufferBarrier(
+ 1,
+ numbersBuffer.readRef(),
ResourceState::UnorderedAccess,
- ResourceState::CopyDestination,
- ResourceState::CopySource);
- bufferDesc.defaultState = ResourceState::UnorderedAccess;
- bufferDesc.memoryType = MemoryType::DeviceLocal;
-
- ComPtr<IBufferResource> numbersBuffer;
- GFX_CHECK_CALL_ABORT(device->createBufferResource(
- bufferDesc,
- (void*)initialData,
- numbersBuffer.writeRef()));
-
- ComPtr<IResourceView> bufferView;
- IResourceView::Desc viewDesc = {};
- viewDesc.type = IResourceView::Type::UnorderedAccess;
- viewDesc.format = Format::Unknown;
- GFX_CHECK_CALL_ABORT(
- device->createBufferView(numbersBuffer, nullptr, viewDesc, bufferView.writeRef()));
-
- {
- slang::TypeReflection* addTransformerType =
- slangReflection->findTypeByName("AddTransformer");
-
- ComPtr<IShaderObject> transformer;
- GFX_CHECK_CALL_ABORT(device->createMutableShaderObject(
- addTransformerType, ShaderObjectContainerType::None, transformer.writeRef()));
- // Set the `c` field of the `AddTransformer`.
- float c = 1.0f;
- ShaderCursor(transformer).getPath("c").setData(&c, sizeof(float));
-
- ICommandQueue::Desc queueDesc = { ICommandQueue::QueueType::Graphics };
- auto queue = device->createCommandQueue(queueDesc);
-
- auto commandBuffer = transientHeap->createCommandBuffer();
- auto encoder = commandBuffer->encodeComputeCommands();
-
- auto rootObject = encoder->bindPipeline(pipelineState);
-
- auto entryPointCursor = ShaderCursor(rootObject->getEntryPoint(0));
-
- entryPointCursor.getPath("buffer").setResource(bufferView);
-
- // Bind the previously created transformer object to root object.
- ComPtr<IShaderObject> transformerVersion;
- transformer->getCurrentVersion(transientHeap, transformerVersion.writeRef());
- entryPointCursor.getPath("transformer").setObject(transformerVersion);
-
- encoder->dispatchCompute(1, 1, 1);
- encoder->endEncoding();
-
- auto barrierEncoder = commandBuffer->encodeResourceCommands();
- barrierEncoder->bufferBarrier(1, numbersBuffer.readRef(), ResourceState::UnorderedAccess, ResourceState::UnorderedAccess);
- barrierEncoder->endEncoding();
-
- encoder = commandBuffer->encodeComputeCommands();
-
- rootObject = encoder->bindPipeline(pipelineState);
- entryPointCursor = ShaderCursor(rootObject->getEntryPoint(0));
-
- // Mutate `transformer` object and run again.
- c = 2.0f;
- ShaderCursor(transformer).getPath("c").setData(&c, sizeof(float));
- transformer->getCurrentVersion(transientHeap, transformerVersion.writeRef());
- entryPointCursor.getPath("buffer").setResource(bufferView);
- entryPointCursor.getPath("transformer").setObject(transformerVersion);
- encoder->dispatchCompute(1, 1, 1);
- encoder->endEncoding();
-
- commandBuffer->close();
- queue->executeCommandBuffer(commandBuffer);
- queue->waitOnHost();
- }
-
- compareComputeResult(
- device,
- numbersBuffer,
- Slang::makeArray<float>(3.0f, 4.0f, 5.0f, 6.0f));
+ ResourceState::UnorderedAccess);
+ barrierEncoder->endEncoding();
+
+ encoder = commandBuffer->encodeComputeCommands();
+
+ rootObject = encoder->bindPipeline(pipelineState);
+ entryPointCursor = ShaderCursor(rootObject->getEntryPoint(0));
+
+ // Mutate `transformer` object and run again.
+ c = 2.0f;
+ ShaderCursor(transformer).getPath("c").setData(&c, sizeof(float));
+ transformer->getCurrentVersion(transientHeap, transformerVersion.writeRef());
+ entryPointCursor.getPath("buffer").setResource(bufferView);
+ entryPointCursor.getPath("transformer").setObject(transformerVersion);
+ encoder->dispatchCompute(1, 1, 1);
+ encoder->endEncoding();
+
+ commandBuffer->close();
+ queue->executeCommandBuffer(commandBuffer);
+ queue->waitOnHost();
}
- //SLANG_UNIT_TEST(mutableShaderObjectCPU)
- //{
- // runTestImpl(mutableShaderObjectTestImpl, unitTestContext, Slang::RenderApiFlag::CPU);
- //}
+ compareComputeResult(device, numbersBuffer, Slang::makeArray<float>(3.0f, 4.0f, 5.0f, 6.0f));
+}
- SLANG_UNIT_TEST(mutableShaderObjectD3D11)
- {
- runTestImpl(mutableShaderObjectTestImpl, unitTestContext, Slang::RenderApiFlag::D3D11);
- }
+// SLANG_UNIT_TEST(mutableShaderObjectCPU)
+//{
+// runTestImpl(mutableShaderObjectTestImpl, unitTestContext, Slang::RenderApiFlag::CPU);
+// }
- SLANG_UNIT_TEST(mutableShaderObjectD3D12)
- {
- runTestImpl(mutableShaderObjectTestImpl, unitTestContext, Slang::RenderApiFlag::D3D12);
- }
+SLANG_UNIT_TEST(mutableShaderObjectD3D11)
+{
+ runTestImpl(mutableShaderObjectTestImpl, unitTestContext, Slang::RenderApiFlag::D3D11);
+}
- SLANG_UNIT_TEST(mutableShaderObjectVulkan)
- {
- runTestImpl(mutableShaderObjectTestImpl, unitTestContext, Slang::RenderApiFlag::Vulkan);
- }
+SLANG_UNIT_TEST(mutableShaderObjectD3D12)
+{
+ runTestImpl(mutableShaderObjectTestImpl, unitTestContext, Slang::RenderApiFlag::D3D12);
+}
+
+SLANG_UNIT_TEST(mutableShaderObjectVulkan)
+{
+ runTestImpl(mutableShaderObjectTestImpl, unitTestContext, Slang::RenderApiFlag::Vulkan);
}
+} // namespace gfx_test
diff --git a/tools/gfx-unit-test/nested-parameter-block.cpp b/tools/gfx-unit-test/nested-parameter-block.cpp
index 98df615af..e904226ae 100644
--- a/tools/gfx-unit-test/nested-parameter-block.cpp
+++ b/tools/gfx-unit-test/nested-parameter-block.cpp
@@ -1,150 +1,162 @@
-#include "tools/unit-test/slang-unit-test.h"
-
-#include "slang-gfx.h"
#include "gfx-test-util.h"
-#include "tools/gfx-util/shader-cursor.h"
+#include "slang-gfx.h"
#include "source/core/slang-basic.h"
+#include "tools/gfx-util/shader-cursor.h"
+#include "tools/unit-test/slang-unit-test.h"
using namespace gfx;
namespace gfx_test
{
- Slang::ComPtr<IBufferResource> createBuffer(
- IDevice* device, uint32_t data, ResourceState defaultState)
- {
- uint32_t initialData[] = {data, data, data, data};
- const int numberCount = SLANG_COUNT_OF(initialData);
- IBufferResource::Desc bufferDesc = {};
- bufferDesc.sizeInBytes = sizeof(initialData);
- bufferDesc.format = gfx::Format::Unknown;
- bufferDesc.elementSize = sizeof(uint32_t) * 4;
- bufferDesc.allowedStates = ResourceStateSet(
- ResourceState::ShaderResource,
- ResourceState::UnorderedAccess,
- ResourceState::CopyDestination,
- ResourceState::CopySource);
- bufferDesc.defaultState = defaultState;
- bufferDesc.memoryType = MemoryType::DeviceLocal;
-
- ComPtr<IBufferResource> numbersBuffer;
- GFX_CHECK_CALL_ABORT(
- device->createBufferResource(bufferDesc, (void*)initialData, numbersBuffer.writeRef()));
- return numbersBuffer;
- }
+Slang::ComPtr<IBufferResource> createBuffer(
+ IDevice* device,
+ uint32_t data,
+ ResourceState defaultState)
+{
+ uint32_t initialData[] = {data, data, data, data};
+ const int numberCount = SLANG_COUNT_OF(initialData);
+ IBufferResource::Desc bufferDesc = {};
+ bufferDesc.sizeInBytes = sizeof(initialData);
+ bufferDesc.format = gfx::Format::Unknown;
+ bufferDesc.elementSize = sizeof(uint32_t) * 4;
+ bufferDesc.allowedStates = ResourceStateSet(
+ ResourceState::ShaderResource,
+ ResourceState::UnorderedAccess,
+ ResourceState::CopyDestination,
+ ResourceState::CopySource);
+ bufferDesc.defaultState = defaultState;
+ bufferDesc.memoryType = MemoryType::DeviceLocal;
+
+ ComPtr<IBufferResource> numbersBuffer;
+ GFX_CHECK_CALL_ABORT(
+ device->createBufferResource(bufferDesc, (void*)initialData, numbersBuffer.writeRef()));
+ return numbersBuffer;
+}
- struct uint4
- {
- uint32_t x, y, z, w;
- };
+struct uint4
+{
+ uint32_t x, y, z, w;
+};
- void nestedParameterBlockTestImpl(IDevice* device, UnitTestContext* context)
+void nestedParameterBlockTestImpl(IDevice* device, UnitTestContext* context)
+{
+ Slang::ComPtr<ITransientResourceHeap> transientHeap;
+ ITransientResourceHeap::Desc transientHeapDesc = {};
+ transientHeapDesc.constantBufferSize = 4096;
+ GFX_CHECK_CALL_ABORT(
+ device->createTransientResourceHeap(transientHeapDesc, transientHeap.writeRef()));
+
+ ComPtr<IShaderProgram> shaderProgram;
+ slang::ProgramLayout* slangReflection;
+ GFX_CHECK_CALL_ABORT(loadComputeProgram(
+ device,
+ shaderProgram,
+ "nested-parameter-block",
+ "computeMain",
+ slangReflection));
+
+ ComputePipelineStateDesc pipelineDesc = {};
+ pipelineDesc.program = shaderProgram.get();
+ ComPtr<gfx::IPipelineState> pipelineState;
+ GFX_CHECK_CALL_ABORT(
+ device->createComputePipelineState(pipelineDesc, pipelineState.writeRef()));
+
+ ComPtr<IShaderObject> shaderObject;
+ SLANG_CHECK(SLANG_SUCCEEDED(
+ device->createMutableRootShaderObject(shaderProgram, shaderObject.writeRef())));
+
+ Slang::List<Slang::ComPtr<IBufferResource>> srvBuffers;
+ Slang::List<Slang::ComPtr<IResourceView>> srvs;
+
+ for (uint32_t i = 0; i < 6; i++)
{
- Slang::ComPtr<ITransientResourceHeap> transientHeap;
- ITransientResourceHeap::Desc transientHeapDesc = {};
- transientHeapDesc.constantBufferSize = 4096;
- GFX_CHECK_CALL_ABORT(
- device->createTransientResourceHeap(transientHeapDesc, transientHeap.writeRef()));
-
- ComPtr<IShaderProgram> shaderProgram;
- slang::ProgramLayout* slangReflection;
- GFX_CHECK_CALL_ABORT(loadComputeProgram(device, shaderProgram, "nested-parameter-block", "computeMain", slangReflection));
-
- ComputePipelineStateDesc pipelineDesc = {};
- pipelineDesc.program = shaderProgram.get();
- ComPtr<gfx::IPipelineState> pipelineState;
- GFX_CHECK_CALL_ABORT(
- device->createComputePipelineState(pipelineDesc, pipelineState.writeRef()));
-
- ComPtr<IShaderObject> shaderObject;
- SLANG_CHECK(SLANG_SUCCEEDED(
- device->createMutableRootShaderObject(shaderProgram, shaderObject.writeRef())));
-
- Slang::List<Slang::ComPtr<IBufferResource>> srvBuffers;
- Slang::List<Slang::ComPtr<IResourceView>> srvs;
-
- for (uint32_t i = 0; i < 6; i++)
- {
- srvBuffers.add(createBuffer(device, i, gfx::ResourceState::ShaderResource));
- IResourceView::Desc srvDesc = {};
- srvDesc.type = IResourceView::Type::ShaderResource;
- srvDesc.format = Format::Unknown;
- srvDesc.bufferRange.offset = 0;
- srvDesc.bufferRange.size = sizeof(uint32_t) * 4;
- srvs.add(device->createBufferView(srvBuffers[i], nullptr, srvDesc));
- }
- Slang::ComPtr<IBufferResource> resultBuffer =
- createBuffer(device, 0, gfx::ResourceState::UnorderedAccess);
- IResourceView::Desc resultBufferViewDesc = {};
- resultBufferViewDesc.type = IResourceView::Type::UnorderedAccess;
- resultBufferViewDesc.format = Format::Unknown;
- resultBufferViewDesc.bufferRange.offset = 0;
- resultBufferViewDesc.bufferRange.size = sizeof(uint32_t) * 4;
- Slang::ComPtr<IResourceView> resultBufferView;
- SLANG_CHECK(SLANG_SUCCEEDED(device->createBufferView(
- resultBuffer, nullptr, resultBufferViewDesc, resultBufferView.writeRef())));
-
- Slang::ComPtr<IShaderObject> materialObject;
- SLANG_CHECK(SLANG_SUCCEEDED(device->createMutableShaderObject(
- slangReflection->findTypeByName("MaterialSystem"),
- ShaderObjectContainerType::None,
- materialObject.writeRef())));
-
- Slang::ComPtr<IShaderObject> sceneObject;
- SLANG_CHECK(SLANG_SUCCEEDED(device->createMutableShaderObject(
- slangReflection->findTypeByName("Scene"),
- ShaderObjectContainerType::None,
- sceneObject.writeRef())));
-
- ShaderCursor cursor(shaderObject);
- cursor["resultBuffer"].setResource(resultBufferView);
- cursor["scene"].setObject(sceneObject);
-
- Slang::ComPtr<IShaderObject> globalCB;
- SLANG_CHECK(SLANG_SUCCEEDED(device->createShaderObject(
- cursor[0].getTypeLayout()->getType(),
- ShaderObjectContainerType::None,
- globalCB.writeRef())));
-
- cursor[0].setObject(globalCB);
- auto initialData = uint4{20, 20, 20, 20};
- globalCB->setData(ShaderOffset(), &initialData, sizeof(initialData));
-
- ShaderCursor sceneCursor(sceneObject);
- sceneCursor["sceneCb"].setData(uint4{100, 100, 100, 100});
- sceneCursor["data"].setResource(srvs[1]);
- sceneCursor["material"].setObject(materialObject);
-
- ShaderCursor materialCursor(materialObject);
- materialCursor["cb"].setData(uint4{1000, 1000, 1000, 1000});
- materialCursor["data"].setResource(srvs[2]);
-
- // We have done all the set up work, now it is time to start recording a command buffer for
- // GPU execution.
- {
- ICommandQueue::Desc queueDesc = {ICommandQueue::QueueType::Graphics};
- auto queue = device->createCommandQueue(queueDesc);
-
- auto commandBuffer = transientHeap->createCommandBuffer();
- auto encoder = commandBuffer->encodeComputeCommands();
-
- encoder->bindPipelineWithRootObject(pipelineState, shaderObject);
-
- encoder->dispatchCompute(1, 1, 1);
- encoder->endEncoding();
- commandBuffer->close();
- queue->executeCommandBuffer(commandBuffer);
- queue->waitOnHost();
- }
-
- compareComputeResult(device, resultBuffer, Slang::makeArray<uint32_t>(1123u, 1123u, 1123u, 1123u));
+ srvBuffers.add(createBuffer(device, i, gfx::ResourceState::ShaderResource));
+ IResourceView::Desc srvDesc = {};
+ srvDesc.type = IResourceView::Type::ShaderResource;
+ srvDesc.format = Format::Unknown;
+ srvDesc.bufferRange.offset = 0;
+ srvDesc.bufferRange.size = sizeof(uint32_t) * 4;
+ srvs.add(device->createBufferView(srvBuffers[i], nullptr, srvDesc));
}
-
- SLANG_UNIT_TEST(nestedParameterBlockTestD3D12)
+ Slang::ComPtr<IBufferResource> resultBuffer =
+ createBuffer(device, 0, gfx::ResourceState::UnorderedAccess);
+ IResourceView::Desc resultBufferViewDesc = {};
+ resultBufferViewDesc.type = IResourceView::Type::UnorderedAccess;
+ resultBufferViewDesc.format = Format::Unknown;
+ resultBufferViewDesc.bufferRange.offset = 0;
+ resultBufferViewDesc.bufferRange.size = sizeof(uint32_t) * 4;
+ Slang::ComPtr<IResourceView> resultBufferView;
+ SLANG_CHECK(SLANG_SUCCEEDED(device->createBufferView(
+ resultBuffer,
+ nullptr,
+ resultBufferViewDesc,
+ resultBufferView.writeRef())));
+
+ Slang::ComPtr<IShaderObject> materialObject;
+ SLANG_CHECK(SLANG_SUCCEEDED(device->createMutableShaderObject(
+ slangReflection->findTypeByName("MaterialSystem"),
+ ShaderObjectContainerType::None,
+ materialObject.writeRef())));
+
+ Slang::ComPtr<IShaderObject> sceneObject;
+ SLANG_CHECK(SLANG_SUCCEEDED(device->createMutableShaderObject(
+ slangReflection->findTypeByName("Scene"),
+ ShaderObjectContainerType::None,
+ sceneObject.writeRef())));
+
+ ShaderCursor cursor(shaderObject);
+ cursor["resultBuffer"].setResource(resultBufferView);
+ cursor["scene"].setObject(sceneObject);
+
+ Slang::ComPtr<IShaderObject> globalCB;
+ SLANG_CHECK(SLANG_SUCCEEDED(device->createShaderObject(
+ cursor[0].getTypeLayout()->getType(),
+ ShaderObjectContainerType::None,
+ globalCB.writeRef())));
+
+ cursor[0].setObject(globalCB);
+ auto initialData = uint4{20, 20, 20, 20};
+ globalCB->setData(ShaderOffset(), &initialData, sizeof(initialData));
+
+ ShaderCursor sceneCursor(sceneObject);
+ sceneCursor["sceneCb"].setData(uint4{100, 100, 100, 100});
+ sceneCursor["data"].setResource(srvs[1]);
+ sceneCursor["material"].setObject(materialObject);
+
+ ShaderCursor materialCursor(materialObject);
+ materialCursor["cb"].setData(uint4{1000, 1000, 1000, 1000});
+ materialCursor["data"].setResource(srvs[2]);
+
+ // We have done all the set up work, now it is time to start recording a command buffer for
+ // GPU execution.
{
- runTestImpl(nestedParameterBlockTestImpl, unitTestContext, Slang::RenderApiFlag::D3D12);
- }
+ ICommandQueue::Desc queueDesc = {ICommandQueue::QueueType::Graphics};
+ auto queue = device->createCommandQueue(queueDesc);
- SLANG_UNIT_TEST(nestedParameterBlockTestVulkan)
- {
- runTestImpl(nestedParameterBlockTestImpl, unitTestContext, Slang::RenderApiFlag::Vulkan);
+ auto commandBuffer = transientHeap->createCommandBuffer();
+ auto encoder = commandBuffer->encodeComputeCommands();
+
+ encoder->bindPipelineWithRootObject(pipelineState, shaderObject);
+
+ encoder->dispatchCompute(1, 1, 1);
+ encoder->endEncoding();
+ commandBuffer->close();
+ queue->executeCommandBuffer(commandBuffer);
+ queue->waitOnHost();
}
+
+ compareComputeResult(
+ device,
+ resultBuffer,
+ Slang::makeArray<uint32_t>(1123u, 1123u, 1123u, 1123u));
+}
+
+SLANG_UNIT_TEST(nestedParameterBlockTestD3D12)
+{
+ runTestImpl(nestedParameterBlockTestImpl, unitTestContext, Slang::RenderApiFlag::D3D12);
+}
+
+SLANG_UNIT_TEST(nestedParameterBlockTestVulkan)
+{
+ runTestImpl(nestedParameterBlockTestImpl, unitTestContext, Slang::RenderApiFlag::Vulkan);
}
+} // namespace gfx_test
diff --git a/tools/gfx-unit-test/precompiled-module-2.cpp b/tools/gfx-unit-test/precompiled-module-2.cpp
index f997b2a7b..0a5ea3ac0 100644
--- a/tools/gfx-unit-test/precompiled-module-2.cpp
+++ b/tools/gfx-unit-test/precompiled-module-2.cpp
@@ -1,121 +1,125 @@
-#include "tools/unit-test/slang-unit-test.h"
-
-#include "slang-gfx.h"
#include "gfx-test-util.h"
-#include "tools/gfx-util/shader-cursor.h"
+#include "slang-gfx.h"
#include "source/core/slang-basic.h"
#include "source/core/slang-blob.h"
-#include "source/core/slang-memory-file-system.h"
#include "source/core/slang-io.h"
+#include "source/core/slang-memory-file-system.h"
+#include "tools/gfx-util/shader-cursor.h"
+#include "tools/unit-test/slang-unit-test.h"
using namespace gfx;
namespace gfx_test
{
- // Test that mixing precompiled and non-precompiled modules is working.
+// Test that mixing precompiled and non-precompiled modules is working.
- static Slang::Result precompileProgram(
- gfx::IDevice* device,
- ISlangMutableFileSystem* fileSys,
- const char* shaderModuleName,
- bool precompileToTarget)
+static Slang::Result precompileProgram(
+ gfx::IDevice* device,
+ ISlangMutableFileSystem* fileSys,
+ const char* shaderModuleName,
+ bool precompileToTarget)
+{
+ Slang::ComPtr<slang::ISession> slangSession;
+ SLANG_RETURN_ON_FAIL(device->getSlangSession(slangSession.writeRef()));
+ slang::SessionDesc sessionDesc = {};
+ auto searchPaths = getSlangSearchPaths();
+ sessionDesc.searchPathCount = searchPaths.getCount();
+ sessionDesc.searchPaths = searchPaths.getBuffer();
+ auto globalSession = slangSession->getGlobalSession();
+ globalSession->createSession(sessionDesc, slangSession.writeRef());
+
+ slang::IModule* module;
{
- Slang::ComPtr<slang::ISession> slangSession;
- SLANG_RETURN_ON_FAIL(device->getSlangSession(slangSession.writeRef()));
- slang::SessionDesc sessionDesc = {};
- auto searchPaths = getSlangSearchPaths();
- sessionDesc.searchPathCount = searchPaths.getCount();
- sessionDesc.searchPaths = searchPaths.getBuffer();
- auto globalSession = slangSession->getGlobalSession();
- globalSession->createSession(sessionDesc, slangSession.writeRef());
-
- slang::IModule* module;
- {
- Slang::ComPtr<slang::IBlob> diagnosticsBlob;
- module = slangSession->loadModule(shaderModuleName, diagnosticsBlob.writeRef());
- diagnoseIfNeeded(diagnosticsBlob);
- }
- if (!module)
- return SLANG_FAIL;
+ Slang::ComPtr<slang::IBlob> diagnosticsBlob;
+ module = slangSession->loadModule(shaderModuleName, diagnosticsBlob.writeRef());
+ diagnoseIfNeeded(diagnosticsBlob);
+ }
+ if (!module)
+ return SLANG_FAIL;
- if (precompileToTarget)
+ if (precompileToTarget)
+ {
+ SlangCompileTarget target;
+ switch (device->getDeviceInfo().deviceType)
{
- SlangCompileTarget target;
- switch (device->getDeviceInfo().deviceType)
- {
- case gfx::DeviceType::DirectX12:
- target = SLANG_DXIL;
- break;
- case gfx::DeviceType::Vulkan:
- target = SLANG_SPIRV;
- break;
- default:
- return SLANG_FAIL;
- }
-
- ComPtr<slang::IModulePrecompileService_Experimental> precompileService;
- if (module->queryInterface(slang::SLANG_UUID_IModulePrecompileService_Experimental, (void**)precompileService.writeRef()) == SLANG_OK)
- {
- Slang::ComPtr<slang::IBlob> diagnosticsBlob;
- precompileService->precompileForTarget(target, diagnosticsBlob.writeRef());
- diagnoseIfNeeded(diagnosticsBlob);
- }
+ case gfx::DeviceType::DirectX12: target = SLANG_DXIL; break;
+ case gfx::DeviceType::Vulkan: target = SLANG_SPIRV; break;
+ default: return SLANG_FAIL;
}
- // Write loaded modules to memory file system.
- for (SlangInt i = 0; i < slangSession->getLoadedModuleCount(); i++)
+ ComPtr<slang::IModulePrecompileService_Experimental> precompileService;
+ if (module->queryInterface(
+ slang::SLANG_UUID_IModulePrecompileService_Experimental,
+ (void**)precompileService.writeRef()) == SLANG_OK)
{
- auto module = slangSession->getLoadedModule(i);
- auto path = module->getFilePath();
- if (path)
- {
- auto name = module->getName();
- ComPtr<ISlangBlob> outBlob;
- module->serialize(outBlob.writeRef());
- fileSys->saveFileBlob((Slang::String(name) + ".slang-module").getBuffer(), outBlob);
- }
+ Slang::ComPtr<slang::IBlob> diagnosticsBlob;
+ precompileService->precompileForTarget(target, diagnosticsBlob.writeRef());
+ diagnoseIfNeeded(diagnosticsBlob);
}
- return SLANG_OK;
}
- void precompiledModule2TestImplCommon(IDevice* device, UnitTestContext* context, bool precompileToTarget)
+ // Write loaded modules to memory file system.
+ for (SlangInt i = 0; i < slangSession->getLoadedModuleCount(); i++)
{
- Slang::ComPtr<ITransientResourceHeap> transientHeap;
- ITransientResourceHeap::Desc transientHeapDesc = {};
- transientHeapDesc.constantBufferSize = 4096;
- GFX_CHECK_CALL_ABORT(
- device->createTransientResourceHeap(transientHeapDesc, transientHeap.writeRef()));
-
- // First, load and compile the slang source.
- ComPtr<ISlangMutableFileSystem> memoryFileSystem = ComPtr<ISlangMutableFileSystem>(new Slang::MemoryFileSystem());
-
- ComPtr<IShaderProgram> shaderProgram;
- slang::ProgramLayout* slangReflection;
- GFX_CHECK_CALL_ABORT(precompileProgram(device, memoryFileSystem.get(), "precompiled-module-imported", precompileToTarget));
-
- // Next, load the precompiled slang program.
- Slang::ComPtr<slang::ISession> slangSession;
- device->getSlangSession(slangSession.writeRef());
- slang::SessionDesc sessionDesc = {};
- sessionDesc.targetCount = 1;
- slang::TargetDesc targetDesc = {};
- switch (device->getDeviceInfo().deviceType)
+ auto module = slangSession->getLoadedModule(i);
+ auto path = module->getFilePath();
+ if (path)
{
- case gfx::DeviceType::DirectX12:
- targetDesc.format = SLANG_DXIL;
- targetDesc.profile = device->getSlangSession()->getGlobalSession()->findProfile("sm_6_1");
- break;
- case gfx::DeviceType::Vulkan:
- targetDesc.format = SLANG_SPIRV;
- targetDesc.profile = device->getSlangSession()->getGlobalSession()->findProfile("GLSL_460");
- break;
+ auto name = module->getName();
+ ComPtr<ISlangBlob> outBlob;
+ module->serialize(outBlob.writeRef());
+ fileSys->saveFileBlob((Slang::String(name) + ".slang-module").getBuffer(), outBlob);
}
- sessionDesc.targets = &targetDesc;
- sessionDesc.fileSystem = memoryFileSystem.get();
- auto globalSession = slangSession->getGlobalSession();
- globalSession->createSession(sessionDesc, slangSession.writeRef());
+ }
+ return SLANG_OK;
+}
+
+void precompiledModule2TestImplCommon(
+ IDevice* device,
+ UnitTestContext* context,
+ bool precompileToTarget)
+{
+ Slang::ComPtr<ITransientResourceHeap> transientHeap;
+ ITransientResourceHeap::Desc transientHeapDesc = {};
+ transientHeapDesc.constantBufferSize = 4096;
+ GFX_CHECK_CALL_ABORT(
+ device->createTransientResourceHeap(transientHeapDesc, transientHeap.writeRef()));
+
+ // First, load and compile the slang source.
+ ComPtr<ISlangMutableFileSystem> memoryFileSystem =
+ ComPtr<ISlangMutableFileSystem>(new Slang::MemoryFileSystem());
+
+ ComPtr<IShaderProgram> shaderProgram;
+ slang::ProgramLayout* slangReflection;
+ GFX_CHECK_CALL_ABORT(precompileProgram(
+ device,
+ memoryFileSystem.get(),
+ "precompiled-module-imported",
+ precompileToTarget));
+
+ // Next, load the precompiled slang program.
+ Slang::ComPtr<slang::ISession> slangSession;
+ device->getSlangSession(slangSession.writeRef());
+ slang::SessionDesc sessionDesc = {};
+ sessionDesc.targetCount = 1;
+ slang::TargetDesc targetDesc = {};
+ switch (device->getDeviceInfo().deviceType)
+ {
+ case gfx::DeviceType::DirectX12:
+ targetDesc.format = SLANG_DXIL;
+ targetDesc.profile = device->getSlangSession()->getGlobalSession()->findProfile("sm_6_1");
+ break;
+ case gfx::DeviceType::Vulkan:
+ targetDesc.format = SLANG_SPIRV;
+ targetDesc.profile = device->getSlangSession()->getGlobalSession()->findProfile("GLSL_460");
+ break;
+ }
+ sessionDesc.targets = &targetDesc;
+ sessionDesc.fileSystem = memoryFileSystem.get();
+ auto globalSession = slangSession->getGlobalSession();
+ globalSession->createSession(sessionDesc, slangSession.writeRef());
- const char* moduleSrc = R"(
+ const char* moduleSrc = R"(
import "precompiled-module-imported";
// Main entry-point.
@@ -131,99 +135,100 @@ namespace gfx_test
buffer[sv_dispatchThreadID.x] = helperFunc() + helperFunc1();
}
)";
- memoryFileSystem->saveFile("precompiled-module.slang", moduleSrc, strlen(moduleSrc));
- GFX_CHECK_CALL_ABORT(loadComputeProgram(device, slangSession, shaderProgram, "precompiled-module", "computeMain", slangReflection));
-
- ComputePipelineStateDesc pipelineDesc = {};
- pipelineDesc.program = shaderProgram.get();
- ComPtr<gfx::IPipelineState> pipelineState;
- GFX_CHECK_CALL_ABORT(
- device->createComputePipelineState(pipelineDesc, pipelineState.writeRef()));
-
- const int numberCount = 4;
- float initialData[] = { 0.0f, 0.0f, 0.0f, 0.0f };
- IBufferResource::Desc bufferDesc = {};
- bufferDesc.sizeInBytes = numberCount * sizeof(float);
- bufferDesc.format = gfx::Format::Unknown;
- bufferDesc.elementSize = sizeof(float);
- bufferDesc.allowedStates = ResourceStateSet(
- ResourceState::ShaderResource,
- ResourceState::UnorderedAccess,
- ResourceState::CopyDestination,
- ResourceState::CopySource);
- bufferDesc.defaultState = ResourceState::UnorderedAccess;
- bufferDesc.memoryType = MemoryType::DeviceLocal;
-
- ComPtr<IBufferResource> numbersBuffer;
- GFX_CHECK_CALL_ABORT(device->createBufferResource(
- bufferDesc,
- (void*)initialData,
- numbersBuffer.writeRef()));
-
- ComPtr<IResourceView> bufferView;
- IResourceView::Desc viewDesc = {};
- viewDesc.type = IResourceView::Type::UnorderedAccess;
- viewDesc.format = Format::Unknown;
- GFX_CHECK_CALL_ABORT(
- device->createBufferView(numbersBuffer, nullptr, viewDesc, bufferView.writeRef()));
-
- // We have done all the set up work, now it is time to start recording a command buffer for
- // GPU execution.
- {
- ICommandQueue::Desc queueDesc = { ICommandQueue::QueueType::Graphics };
- auto queue = device->createCommandQueue(queueDesc);
-
- auto commandBuffer = transientHeap->createCommandBuffer();
- auto encoder = commandBuffer->encodeComputeCommands();
+ memoryFileSystem->saveFile("precompiled-module.slang", moduleSrc, strlen(moduleSrc));
+ GFX_CHECK_CALL_ABORT(loadComputeProgram(
+ device,
+ slangSession,
+ shaderProgram,
+ "precompiled-module",
+ "computeMain",
+ slangReflection));
+
+ ComputePipelineStateDesc pipelineDesc = {};
+ pipelineDesc.program = shaderProgram.get();
+ ComPtr<gfx::IPipelineState> pipelineState;
+ GFX_CHECK_CALL_ABORT(
+ device->createComputePipelineState(pipelineDesc, pipelineState.writeRef()));
+
+ const int numberCount = 4;
+ float initialData[] = {0.0f, 0.0f, 0.0f, 0.0f};
+ IBufferResource::Desc bufferDesc = {};
+ bufferDesc.sizeInBytes = numberCount * sizeof(float);
+ bufferDesc.format = gfx::Format::Unknown;
+ bufferDesc.elementSize = sizeof(float);
+ bufferDesc.allowedStates = ResourceStateSet(
+ ResourceState::ShaderResource,
+ ResourceState::UnorderedAccess,
+ ResourceState::CopyDestination,
+ ResourceState::CopySource);
+ bufferDesc.defaultState = ResourceState::UnorderedAccess;
+ bufferDesc.memoryType = MemoryType::DeviceLocal;
+
+ ComPtr<IBufferResource> numbersBuffer;
+ GFX_CHECK_CALL_ABORT(
+ device->createBufferResource(bufferDesc, (void*)initialData, numbersBuffer.writeRef()));
+
+ ComPtr<IResourceView> bufferView;
+ IResourceView::Desc viewDesc = {};
+ viewDesc.type = IResourceView::Type::UnorderedAccess;
+ viewDesc.format = Format::Unknown;
+ GFX_CHECK_CALL_ABORT(
+ device->createBufferView(numbersBuffer, nullptr, viewDesc, bufferView.writeRef()));
+
+ // We have done all the set up work, now it is time to start recording a command buffer for
+ // GPU execution.
+ {
+ ICommandQueue::Desc queueDesc = {ICommandQueue::QueueType::Graphics};
+ auto queue = device->createCommandQueue(queueDesc);
- auto rootObject = encoder->bindPipeline(pipelineState);
+ auto commandBuffer = transientHeap->createCommandBuffer();
+ auto encoder = commandBuffer->encodeComputeCommands();
- ShaderCursor entryPointCursor(
- rootObject->getEntryPoint(0)); // get a cursor the the first entry-point.
- // Bind buffer view to the entry point.
- entryPointCursor.getPath("buffer").setResource(bufferView);
+ auto rootObject = encoder->bindPipeline(pipelineState);
- encoder->dispatchCompute(1, 1, 1);
- encoder->endEncoding();
- commandBuffer->close();
- queue->executeCommandBuffer(commandBuffer);
- queue->waitOnHost();
- }
+ ShaderCursor entryPointCursor(
+ rootObject->getEntryPoint(0)); // get a cursor the the first entry-point.
+ // Bind buffer view to the entry point.
+ entryPointCursor.getPath("buffer").setResource(bufferView);
- compareComputeResult(
- device,
- numbersBuffer,
- Slang::makeArray<float>(3.0f, 3.0f, 3.0f, 3.0f));
+ encoder->dispatchCompute(1, 1, 1);
+ encoder->endEncoding();
+ commandBuffer->close();
+ queue->executeCommandBuffer(commandBuffer);
+ queue->waitOnHost();
}
- void precompiledModule2TestImpl(IDevice* device, UnitTestContext* context)
- {
- precompiledModule2TestImplCommon(device, context, false);
- }
+ compareComputeResult(device, numbersBuffer, Slang::makeArray<float>(3.0f, 3.0f, 3.0f, 3.0f));
+}
- void precompiledTargetModule2TestImpl(IDevice* device, UnitTestContext* context)
- {
- precompiledModule2TestImplCommon(device, context, true);
- }
+void precompiledModule2TestImpl(IDevice* device, UnitTestContext* context)
+{
+ precompiledModule2TestImplCommon(device, context, false);
+}
- SLANG_UNIT_TEST(precompiledModule2D3D12)
- {
- runTestImpl(precompiledModule2TestImpl, unitTestContext, Slang::RenderApiFlag::D3D12);
- }
+void precompiledTargetModule2TestImpl(IDevice* device, UnitTestContext* context)
+{
+ precompiledModule2TestImplCommon(device, context, true);
+}
- SLANG_UNIT_TEST(precompiledTargetModule2D3D12)
- {
- runTestImpl(precompiledTargetModule2TestImpl, unitTestContext, Slang::RenderApiFlag::D3D12);
- }
+SLANG_UNIT_TEST(precompiledModule2D3D12)
+{
+ runTestImpl(precompiledModule2TestImpl, unitTestContext, Slang::RenderApiFlag::D3D12);
+}
- SLANG_UNIT_TEST(precompiledModule2Vulkan)
- {
- runTestImpl(precompiledModule2TestImpl, unitTestContext, Slang::RenderApiFlag::Vulkan);
- }
+SLANG_UNIT_TEST(precompiledTargetModule2D3D12)
+{
+ runTestImpl(precompiledTargetModule2TestImpl, unitTestContext, Slang::RenderApiFlag::D3D12);
+}
- SLANG_UNIT_TEST(precompiledTargetModule2Vulkan)
- {
- runTestImpl(precompiledTargetModule2TestImpl, unitTestContext, Slang::RenderApiFlag::Vulkan);
- }
+SLANG_UNIT_TEST(precompiledModule2Vulkan)
+{
+ runTestImpl(precompiledModule2TestImpl, unitTestContext, Slang::RenderApiFlag::Vulkan);
+}
+SLANG_UNIT_TEST(precompiledTargetModule2Vulkan)
+{
+ runTestImpl(precompiledTargetModule2TestImpl, unitTestContext, Slang::RenderApiFlag::Vulkan);
}
+
+} // namespace gfx_test
diff --git a/tools/gfx-unit-test/precompiled-module-cache.cpp b/tools/gfx-unit-test/precompiled-module-cache.cpp
index 97d6e1c34..1c10f759b 100644
--- a/tools/gfx-unit-test/precompiled-module-cache.cpp
+++ b/tools/gfx-unit-test/precompiled-module-cache.cpp
@@ -1,95 +1,97 @@
-#include "tools/unit-test/slang-unit-test.h"
-
-#include "slang-gfx.h"
#include "gfx-test-util.h"
-#include "tools/gfx-util/shader-cursor.h"
+#include "slang-gfx.h"
#include "source/core/slang-basic.h"
#include "source/core/slang-blob.h"
-#include "source/core/slang-memory-file-system.h"
#include "source/core/slang-io.h"
+#include "source/core/slang-memory-file-system.h"
+#include "tools/gfx-util/shader-cursor.h"
+#include "tools/unit-test/slang-unit-test.h"
using namespace gfx;
namespace gfx_test
{
- // Test that precompiled module cache is working.
+// Test that precompiled module cache is working.
- Slang::ComPtr<slang::ISession> createSession(gfx::IDevice* device, ISlangFileSystemExt* fileSys)
+Slang::ComPtr<slang::ISession> createSession(gfx::IDevice* device, ISlangFileSystemExt* fileSys)
+{
+ Slang::ComPtr<slang::ISession> slangSession;
+ device->getSlangSession(slangSession.writeRef());
+ slang::SessionDesc sessionDesc = {};
+ sessionDesc.searchPathCount = 1;
+ const char* searchPath = "cache/";
+ sessionDesc.searchPaths = &searchPath;
+ sessionDesc.targetCount = 1;
+ sessionDesc.compilerOptionEntryCount = 1;
+ slang::CompilerOptionEntry entry;
+ entry.name = slang::CompilerOptionName::UseUpToDateBinaryModule;
+ entry.value.kind = slang::CompilerOptionValueKind::Int;
+ entry.value.intValue0 = 1;
+ sessionDesc.compilerOptionEntries = &entry;
+ slang::TargetDesc targetDesc = {};
+ switch (device->getDeviceInfo().deviceType)
{
- Slang::ComPtr<slang::ISession> slangSession;
- device->getSlangSession(slangSession.writeRef());
- slang::SessionDesc sessionDesc = {};
- sessionDesc.searchPathCount = 1;
- const char* searchPath = "cache/";
- sessionDesc.searchPaths = &searchPath;
- sessionDesc.targetCount = 1;
- sessionDesc.compilerOptionEntryCount = 1;
- slang::CompilerOptionEntry entry;
- entry.name = slang::CompilerOptionName::UseUpToDateBinaryModule;
- entry.value.kind = slang::CompilerOptionValueKind::Int;
- entry.value.intValue0 = 1;
- sessionDesc.compilerOptionEntries = &entry;
- slang::TargetDesc targetDesc = {};
- switch (device->getDeviceInfo().deviceType)
- {
- case gfx::DeviceType::DirectX12:
- targetDesc.format = SLANG_DXIL;
- targetDesc.profile = device->getSlangSession()->getGlobalSession()->findProfile("sm_6_1");
- break;
- case gfx::DeviceType::Vulkan:
- targetDesc.format = SLANG_SPIRV;
- targetDesc.profile = device->getSlangSession()->getGlobalSession()->findProfile("GLSL_460");
- break;
- }
- sessionDesc.targets = &targetDesc;
- sessionDesc.fileSystem = fileSys;
- auto globalSession = slangSession->getGlobalSession();
- globalSession->createSession(sessionDesc, slangSession.writeRef());
- return slangSession;
+ case gfx::DeviceType::DirectX12:
+ targetDesc.format = SLANG_DXIL;
+ targetDesc.profile = device->getSlangSession()->getGlobalSession()->findProfile("sm_6_1");
+ break;
+ case gfx::DeviceType::Vulkan:
+ targetDesc.format = SLANG_SPIRV;
+ targetDesc.profile = device->getSlangSession()->getGlobalSession()->findProfile("GLSL_460");
+ break;
}
+ sessionDesc.targets = &targetDesc;
+ sessionDesc.fileSystem = fileSys;
+ auto globalSession = slangSession->getGlobalSession();
+ globalSession->createSession(sessionDesc, slangSession.writeRef());
+ return slangSession;
+}
- static Slang::Result precompileProgram(
- gfx::IDevice* device,
- ISlangMutableFileSystem* fileSys,
- const char* shaderModuleName)
- {
- Slang::ComPtr<slang::ISession> slangSession = createSession(device, fileSys);
+static Slang::Result precompileProgram(
+ gfx::IDevice* device,
+ ISlangMutableFileSystem* fileSys,
+ const char* shaderModuleName)
+{
+ Slang::ComPtr<slang::ISession> slangSession = createSession(device, fileSys);
- Slang::ComPtr<slang::IBlob> diagnosticsBlob;
- slang::IModule* module = slangSession->loadModule(shaderModuleName, diagnosticsBlob.writeRef());
- diagnoseIfNeeded(diagnosticsBlob);
- if (!module)
- return SLANG_FAIL;
+ Slang::ComPtr<slang::IBlob> diagnosticsBlob;
+ slang::IModule* module = slangSession->loadModule(shaderModuleName, diagnosticsBlob.writeRef());
+ diagnoseIfNeeded(diagnosticsBlob);
+ if (!module)
+ return SLANG_FAIL;
- // Write loaded modules to memory file system.
- for (SlangInt i = 0; i < slangSession->getLoadedModuleCount(); i++)
+ // Write loaded modules to memory file system.
+ for (SlangInt i = 0; i < slangSession->getLoadedModuleCount(); i++)
+ {
+ auto module = slangSession->getLoadedModule(i);
+ auto path = module->getFilePath();
+ if (path)
{
- auto module = slangSession->getLoadedModule(i);
- auto path = module->getFilePath();
- if (path)
- {
- auto name = module->getName();
- ComPtr<ISlangBlob> outBlob;
- module->serialize(outBlob.writeRef());
- fileSys->saveFileBlob((Slang::String("cache/") + Slang::String(name) + ".slang-module").getBuffer(), outBlob);
- }
+ auto name = module->getName();
+ ComPtr<ISlangBlob> outBlob;
+ module->serialize(outBlob.writeRef());
+ fileSys->saveFileBlob(
+ (Slang::String("cache/") + Slang::String(name) + ".slang-module").getBuffer(),
+ outBlob);
}
- return SLANG_OK;
}
+ return SLANG_OK;
+}
- void precompiledModuleCacheTestImpl(IDevice* device, UnitTestContext* context)
- {
- Slang::ComPtr<ITransientResourceHeap> transientHeap;
- ITransientResourceHeap::Desc transientHeapDesc = {};
- transientHeapDesc.constantBufferSize = 4096;
- GFX_CHECK_CALL_ABORT(
- device->createTransientResourceHeap(transientHeapDesc, transientHeap.writeRef()));
-
- // First, Initialize our file system.
- ComPtr<ISlangMutableFileSystem> memoryFileSystem = ComPtr<ISlangMutableFileSystem>(new Slang::MemoryFileSystem());
- memoryFileSystem->createDirectory("cache");
-
- const char* moduleSrc = R"(
+void precompiledModuleCacheTestImpl(IDevice* device, UnitTestContext* context)
+{
+ Slang::ComPtr<ITransientResourceHeap> transientHeap;
+ ITransientResourceHeap::Desc transientHeapDesc = {};
+ transientHeapDesc.constantBufferSize = 4096;
+ GFX_CHECK_CALL_ABORT(
+ device->createTransientResourceHeap(transientHeapDesc, transientHeap.writeRef()));
+
+ // First, Initialize our file system.
+ ComPtr<ISlangMutableFileSystem> memoryFileSystem =
+ ComPtr<ISlangMutableFileSystem>(new Slang::MemoryFileSystem());
+ memoryFileSystem->createDirectory("cache");
+
+ const char* moduleSrc = R"(
import "precompiled-module-imported";
// Main entry-point.
@@ -105,9 +107,9 @@ namespace gfx_test
buffer[sv_dispatchThreadID.x] = helperFunc() + helperFunc1();
}
)";
- memoryFileSystem->saveFile("precompiled-module.slang", moduleSrc, strlen(moduleSrc));
+ memoryFileSystem->saveFile("precompiled-module.slang", moduleSrc, strlen(moduleSrc));
- const char* moduleSrc2 = R"(
+ const char* moduleSrc2 = R"(
module "precompiled-module-imported";
__include "precompiled-module-included.slang";
@@ -120,8 +122,8 @@ namespace gfx_test
}
}
)";
- memoryFileSystem->saveFile("precompiled-module-imported.slang", moduleSrc2, strlen(moduleSrc2));
- const char* moduleSrc3 = R"(
+ memoryFileSystem->saveFile("precompiled-module-imported.slang", moduleSrc2, strlen(moduleSrc2));
+ const char* moduleSrc3 = R"(
implementing "precompiled-module-imported";
namespace ns
@@ -132,85 +134,90 @@ namespace gfx_test
}
}
)";
- memoryFileSystem->saveFile("precompiled-module-included.slang", moduleSrc3, strlen(moduleSrc3));
-
- // Precompile a module.
- ComPtr<IShaderProgram> shaderProgram;
- slang::ProgramLayout* slangReflection;
- GFX_CHECK_CALL_ABORT(precompileProgram(device, memoryFileSystem.get(), "precompiled-module-imported"));
-
- // Next, load the precompiled slang program.
- Slang::ComPtr<slang::ISession> slangSession = createSession(device, memoryFileSystem);
- ComPtr<ISlangBlob> binaryBlob;
- memoryFileSystem->loadFile("cache/precompiled-module-imported.slang-module", binaryBlob.writeRef());
- auto upToDate = slangSession->isBinaryModuleUpToDate("precompiled-module-imported.slang", binaryBlob);
- SLANG_CHECK(upToDate); // The module should be up-to-date.
-
- GFX_CHECK_CALL_ABORT(loadComputeProgram(device, slangSession, shaderProgram, "precompiled-module", "computeMain", slangReflection));
-
- ComputePipelineStateDesc pipelineDesc = {};
- pipelineDesc.program = shaderProgram.get();
- ComPtr<gfx::IPipelineState> pipelineState;
- GFX_CHECK_CALL_ABORT(
- device->createComputePipelineState(pipelineDesc, pipelineState.writeRef()));
-
- const int numberCount = 4;
- float initialData[] = { 0.0f, 0.0f, 0.0f, 0.0f };
- IBufferResource::Desc bufferDesc = {};
- bufferDesc.sizeInBytes = numberCount * sizeof(float);
- bufferDesc.format = gfx::Format::Unknown;
- bufferDesc.elementSize = sizeof(float);
- bufferDesc.allowedStates = ResourceStateSet(
- ResourceState::ShaderResource,
- ResourceState::UnorderedAccess,
- ResourceState::CopyDestination,
- ResourceState::CopySource);
- bufferDesc.defaultState = ResourceState::UnorderedAccess;
- bufferDesc.memoryType = MemoryType::DeviceLocal;
-
- ComPtr<IBufferResource> numbersBuffer;
- GFX_CHECK_CALL_ABORT(device->createBufferResource(
- bufferDesc,
- (void*)initialData,
- numbersBuffer.writeRef()));
-
- ComPtr<IResourceView> bufferView;
- IResourceView::Desc viewDesc = {};
- viewDesc.type = IResourceView::Type::UnorderedAccess;
- viewDesc.format = Format::Unknown;
- GFX_CHECK_CALL_ABORT(
- device->createBufferView(numbersBuffer, nullptr, viewDesc, bufferView.writeRef()));
-
- // We have done all the set up work, now it is time to start recording a command buffer for
- // GPU execution.
- {
- ICommandQueue::Desc queueDesc = { ICommandQueue::QueueType::Graphics };
- auto queue = device->createCommandQueue(queueDesc);
+ memoryFileSystem->saveFile("precompiled-module-included.slang", moduleSrc3, strlen(moduleSrc3));
+
+ // Precompile a module.
+ ComPtr<IShaderProgram> shaderProgram;
+ slang::ProgramLayout* slangReflection;
+ GFX_CHECK_CALL_ABORT(
+ precompileProgram(device, memoryFileSystem.get(), "precompiled-module-imported"));
+
+ // Next, load the precompiled slang program.
+ Slang::ComPtr<slang::ISession> slangSession = createSession(device, memoryFileSystem);
+ ComPtr<ISlangBlob> binaryBlob;
+ memoryFileSystem->loadFile(
+ "cache/precompiled-module-imported.slang-module",
+ binaryBlob.writeRef());
+ auto upToDate =
+ slangSession->isBinaryModuleUpToDate("precompiled-module-imported.slang", binaryBlob);
+ SLANG_CHECK(upToDate); // The module should be up-to-date.
+
+ GFX_CHECK_CALL_ABORT(loadComputeProgram(
+ device,
+ slangSession,
+ shaderProgram,
+ "precompiled-module",
+ "computeMain",
+ slangReflection));
+
+ ComputePipelineStateDesc pipelineDesc = {};
+ pipelineDesc.program = shaderProgram.get();
+ ComPtr<gfx::IPipelineState> pipelineState;
+ GFX_CHECK_CALL_ABORT(
+ device->createComputePipelineState(pipelineDesc, pipelineState.writeRef()));
+
+ const int numberCount = 4;
+ float initialData[] = {0.0f, 0.0f, 0.0f, 0.0f};
+ IBufferResource::Desc bufferDesc = {};
+ bufferDesc.sizeInBytes = numberCount * sizeof(float);
+ bufferDesc.format = gfx::Format::Unknown;
+ bufferDesc.elementSize = sizeof(float);
+ bufferDesc.allowedStates = ResourceStateSet(
+ ResourceState::ShaderResource,
+ ResourceState::UnorderedAccess,
+ ResourceState::CopyDestination,
+ ResourceState::CopySource);
+ bufferDesc.defaultState = ResourceState::UnorderedAccess;
+ bufferDesc.memoryType = MemoryType::DeviceLocal;
+
+ ComPtr<IBufferResource> numbersBuffer;
+ GFX_CHECK_CALL_ABORT(
+ device->createBufferResource(bufferDesc, (void*)initialData, numbersBuffer.writeRef()));
+
+ ComPtr<IResourceView> bufferView;
+ IResourceView::Desc viewDesc = {};
+ viewDesc.type = IResourceView::Type::UnorderedAccess;
+ viewDesc.format = Format::Unknown;
+ GFX_CHECK_CALL_ABORT(
+ device->createBufferView(numbersBuffer, nullptr, viewDesc, bufferView.writeRef()));
+
+ // We have done all the set up work, now it is time to start recording a command buffer for
+ // GPU execution.
+ {
+ ICommandQueue::Desc queueDesc = {ICommandQueue::QueueType::Graphics};
+ auto queue = device->createCommandQueue(queueDesc);
- auto commandBuffer = transientHeap->createCommandBuffer();
- auto encoder = commandBuffer->encodeComputeCommands();
+ auto commandBuffer = transientHeap->createCommandBuffer();
+ auto encoder = commandBuffer->encodeComputeCommands();
- auto rootObject = encoder->bindPipeline(pipelineState);
+ auto rootObject = encoder->bindPipeline(pipelineState);
- ShaderCursor entryPointCursor(
- rootObject->getEntryPoint(0)); // get a cursor the the first entry-point.
- // Bind buffer view to the entry point.
- entryPointCursor.getPath("buffer").setResource(bufferView);
+ ShaderCursor entryPointCursor(
+ rootObject->getEntryPoint(0)); // get a cursor the the first entry-point.
+ // Bind buffer view to the entry point.
+ entryPointCursor.getPath("buffer").setResource(bufferView);
- encoder->dispatchCompute(1, 1, 1);
- encoder->endEncoding();
- commandBuffer->close();
- queue->executeCommandBuffer(commandBuffer);
- queue->waitOnHost();
- }
+ encoder->dispatchCompute(1, 1, 1);
+ encoder->endEncoding();
+ commandBuffer->close();
+ queue->executeCommandBuffer(commandBuffer);
+ queue->waitOnHost();
+ }
- compareComputeResult(
- device,
- numbersBuffer,
- Slang::makeArray<float>(3.0f, 3.0f, 3.0f, 3.0f));
+ compareComputeResult(device, numbersBuffer, Slang::makeArray<float>(3.0f, 3.0f, 3.0f, 3.0f));
- // Now we change the source and check if the precompiled module is still up-to-date.
- const char* moduleSrc4 = R"(
+ // Now we change the source and check if the precompiled module is still up-to-date.
+ const char* moduleSrc4 = R"(
implementing "precompiled-module-imported";
namespace ns {
public int helperFunc1() {
@@ -218,21 +225,22 @@ namespace gfx_test
}
}
)";
- memoryFileSystem->saveFile("precompiled-module-included.slang", moduleSrc4, strlen(moduleSrc4));
-
- slangSession = createSession(device, memoryFileSystem);
- upToDate = slangSession->isBinaryModuleUpToDate("precompiled-module-imported.slang", binaryBlob);
- SLANG_CHECK(!upToDate); // The module should not be up-to-date because the source has changed.
- }
+ memoryFileSystem->saveFile("precompiled-module-included.slang", moduleSrc4, strlen(moduleSrc4));
- SLANG_UNIT_TEST(precompiledModuleCacheD3D12)
- {
- runTestImpl(precompiledModuleCacheTestImpl, unitTestContext, Slang::RenderApiFlag::D3D12);
- }
+ slangSession = createSession(device, memoryFileSystem);
+ upToDate =
+ slangSession->isBinaryModuleUpToDate("precompiled-module-imported.slang", binaryBlob);
+ SLANG_CHECK(!upToDate); // The module should not be up-to-date because the source has changed.
+}
- SLANG_UNIT_TEST(precompiledModuleCacheVulkan)
- {
- runTestImpl(precompiledModuleCacheTestImpl, unitTestContext, Slang::RenderApiFlag::Vulkan);
- }
+SLANG_UNIT_TEST(precompiledModuleCacheD3D12)
+{
+ runTestImpl(precompiledModuleCacheTestImpl, unitTestContext, Slang::RenderApiFlag::D3D12);
+}
+SLANG_UNIT_TEST(precompiledModuleCacheVulkan)
+{
+ runTestImpl(precompiledModuleCacheTestImpl, unitTestContext, Slang::RenderApiFlag::Vulkan);
}
+
+} // namespace gfx_test
diff --git a/tools/gfx-unit-test/precompiled-module.cpp b/tools/gfx-unit-test/precompiled-module.cpp
index 026575120..2ecc412c4 100644
--- a/tools/gfx-unit-test/precompiled-module.cpp
+++ b/tools/gfx-unit-test/precompiled-module.cpp
@@ -1,160 +1,161 @@
-#include "tools/unit-test/slang-unit-test.h"
-
-#include "slang-gfx.h"
#include "gfx-test-util.h"
-#include "tools/gfx-util/shader-cursor.h"
+#include "slang-gfx.h"
#include "source/core/slang-basic.h"
#include "source/core/slang-blob.h"
#include "source/core/slang-memory-file-system.h"
+#include "tools/gfx-util/shader-cursor.h"
+#include "tools/unit-test/slang-unit-test.h"
using namespace gfx;
namespace gfx_test
{
- static Slang::Result precompileProgram(
- gfx::IDevice* device,
- ISlangMutableFileSystem* fileSys,
- const char* shaderModuleName)
+static Slang::Result precompileProgram(
+ gfx::IDevice* device,
+ ISlangMutableFileSystem* fileSys,
+ const char* shaderModuleName)
+{
+ Slang::ComPtr<slang::ISession> slangSession;
+ SLANG_RETURN_ON_FAIL(device->getSlangSession(slangSession.writeRef()));
+ slang::SessionDesc sessionDesc = {};
+ auto searchPaths = getSlangSearchPaths();
+ sessionDesc.searchPathCount = searchPaths.getCount();
+ sessionDesc.searchPaths = searchPaths.getBuffer();
+ auto globalSession = slangSession->getGlobalSession();
+ globalSession->createSession(sessionDesc, slangSession.writeRef());
+
+ Slang::ComPtr<slang::IBlob> diagnosticsBlob;
+ slang::IModule* module = slangSession->loadModule(shaderModuleName, diagnosticsBlob.writeRef());
+ diagnoseIfNeeded(diagnosticsBlob);
+ if (!module)
+ return SLANG_FAIL;
+
+ // Write loaded modules to memory file system.
+ for (SlangInt i = 0; i < slangSession->getLoadedModuleCount(); i++)
{
- Slang::ComPtr<slang::ISession> slangSession;
- SLANG_RETURN_ON_FAIL(device->getSlangSession(slangSession.writeRef()));
- slang::SessionDesc sessionDesc = {};
- auto searchPaths = getSlangSearchPaths();
- sessionDesc.searchPathCount = searchPaths.getCount();
- sessionDesc.searchPaths = searchPaths.getBuffer();
- auto globalSession = slangSession->getGlobalSession();
- globalSession->createSession(sessionDesc, slangSession.writeRef());
-
- Slang::ComPtr<slang::IBlob> diagnosticsBlob;
- slang::IModule* module = slangSession->loadModule(shaderModuleName, diagnosticsBlob.writeRef());
- diagnoseIfNeeded(diagnosticsBlob);
- if (!module)
- return SLANG_FAIL;
-
- // Write loaded modules to memory file system.
- for (SlangInt i = 0; i < slangSession->getLoadedModuleCount(); i++)
+ auto module = slangSession->getLoadedModule(i);
+ auto path = module->getFilePath();
+ if (path)
{
- auto module = slangSession->getLoadedModule(i);
- auto path = module->getFilePath();
- if (path)
- {
- auto name = module->getName();
- ComPtr<ISlangBlob> outBlob;
- module->serialize(outBlob.writeRef());
- fileSys->saveFileBlob((Slang::String(name) + ".slang-module").getBuffer(), outBlob);
- }
+ auto name = module->getName();
+ ComPtr<ISlangBlob> outBlob;
+ module->serialize(outBlob.writeRef());
+ fileSys->saveFileBlob((Slang::String(name) + ".slang-module").getBuffer(), outBlob);
}
- return SLANG_OK;
}
+ return SLANG_OK;
+}
- void precompiledModuleTestImpl(IDevice* device, UnitTestContext* context)
+void precompiledModuleTestImpl(IDevice* device, UnitTestContext* context)
+{
+ Slang::ComPtr<ITransientResourceHeap> transientHeap;
+ ITransientResourceHeap::Desc transientHeapDesc = {};
+ transientHeapDesc.constantBufferSize = 4096;
+ GFX_CHECK_CALL_ABORT(
+ device->createTransientResourceHeap(transientHeapDesc, transientHeap.writeRef()));
+
+ // First, load and compile the slang source.
+ ComPtr<ISlangMutableFileSystem> memoryFileSystem =
+ ComPtr<ISlangMutableFileSystem>(new Slang::MemoryFileSystem());
+
+ ComPtr<IShaderProgram> shaderProgram;
+ slang::ProgramLayout* slangReflection;
+ GFX_CHECK_CALL_ABORT(precompileProgram(device, memoryFileSystem.get(), "precompiled-module"));
+
+ // Next, load the precompiled slang program.
+ Slang::ComPtr<slang::ISession> slangSession;
+ device->getSlangSession(slangSession.writeRef());
+ slang::SessionDesc sessionDesc = {};
+ sessionDesc.targetCount = 1;
+ slang::TargetDesc targetDesc = {};
+ switch (device->getDeviceInfo().deviceType)
{
- Slang::ComPtr<ITransientResourceHeap> transientHeap;
- ITransientResourceHeap::Desc transientHeapDesc = {};
- transientHeapDesc.constantBufferSize = 4096;
- GFX_CHECK_CALL_ABORT(
- device->createTransientResourceHeap(transientHeapDesc, transientHeap.writeRef()));
-
- // First, load and compile the slang source.
- ComPtr<ISlangMutableFileSystem> memoryFileSystem = ComPtr<ISlangMutableFileSystem>(new Slang::MemoryFileSystem());
-
- ComPtr<IShaderProgram> shaderProgram;
- slang::ProgramLayout* slangReflection;
- GFX_CHECK_CALL_ABORT(precompileProgram(device, memoryFileSystem.get(), "precompiled-module"));
-
- // Next, load the precompiled slang program.
- Slang::ComPtr<slang::ISession> slangSession;
- device->getSlangSession(slangSession.writeRef());
- slang::SessionDesc sessionDesc = {};
- sessionDesc.targetCount = 1;
- slang::TargetDesc targetDesc = {};
- switch (device->getDeviceInfo().deviceType)
- {
- case gfx::DeviceType::DirectX12:
- targetDesc.format = SLANG_DXIL;
- targetDesc.profile = device->getSlangSession()->getGlobalSession()->findProfile("sm_6_1");
- break;
- case gfx::DeviceType::Vulkan:
- targetDesc.format = SLANG_SPIRV;
- targetDesc.profile = device->getSlangSession()->getGlobalSession()->findProfile("GLSL_460");
- break;
- }
- sessionDesc.targets = &targetDesc;
- sessionDesc.fileSystem = memoryFileSystem.get();
- auto globalSession = slangSession->getGlobalSession();
- globalSession->createSession(sessionDesc, slangSession.writeRef());
- GFX_CHECK_CALL_ABORT(loadComputeProgram(device, slangSession, shaderProgram, "precompiled-module", "computeMain", slangReflection));
-
- ComputePipelineStateDesc pipelineDesc = {};
- pipelineDesc.program = shaderProgram.get();
- ComPtr<gfx::IPipelineState> pipelineState;
- GFX_CHECK_CALL_ABORT(
- device->createComputePipelineState(pipelineDesc, pipelineState.writeRef()));
-
- const int numberCount = 4;
- float initialData[] = { 0.0f, 0.0f, 0.0f, 0.0f };
- IBufferResource::Desc bufferDesc = {};
- bufferDesc.sizeInBytes = numberCount * sizeof(float);
- bufferDesc.format = gfx::Format::Unknown;
- bufferDesc.elementSize = sizeof(float);
- bufferDesc.allowedStates = ResourceStateSet(
- ResourceState::ShaderResource,
- ResourceState::UnorderedAccess,
- ResourceState::CopyDestination,
- ResourceState::CopySource);
- bufferDesc.defaultState = ResourceState::UnorderedAccess;
- bufferDesc.memoryType = MemoryType::DeviceLocal;
-
- ComPtr<IBufferResource> numbersBuffer;
- GFX_CHECK_CALL_ABORT(device->createBufferResource(
- bufferDesc,
- (void*)initialData,
- numbersBuffer.writeRef()));
-
- ComPtr<IResourceView> bufferView;
- IResourceView::Desc viewDesc = {};
- viewDesc.type = IResourceView::Type::UnorderedAccess;
- viewDesc.format = Format::Unknown;
- GFX_CHECK_CALL_ABORT(
- device->createBufferView(numbersBuffer, nullptr, viewDesc, bufferView.writeRef()));
-
- // We have done all the set up work, now it is time to start recording a command buffer for
- // GPU execution.
- {
- ICommandQueue::Desc queueDesc = { ICommandQueue::QueueType::Graphics };
- auto queue = device->createCommandQueue(queueDesc);
-
- auto commandBuffer = transientHeap->createCommandBuffer();
- auto encoder = commandBuffer->encodeComputeCommands();
+ case gfx::DeviceType::DirectX12:
+ targetDesc.format = SLANG_DXIL;
+ targetDesc.profile = device->getSlangSession()->getGlobalSession()->findProfile("sm_6_1");
+ break;
+ case gfx::DeviceType::Vulkan:
+ targetDesc.format = SLANG_SPIRV;
+ targetDesc.profile = device->getSlangSession()->getGlobalSession()->findProfile("GLSL_460");
+ break;
+ }
+ sessionDesc.targets = &targetDesc;
+ sessionDesc.fileSystem = memoryFileSystem.get();
+ auto globalSession = slangSession->getGlobalSession();
+ globalSession->createSession(sessionDesc, slangSession.writeRef());
+ GFX_CHECK_CALL_ABORT(loadComputeProgram(
+ device,
+ slangSession,
+ shaderProgram,
+ "precompiled-module",
+ "computeMain",
+ slangReflection));
+
+ ComputePipelineStateDesc pipelineDesc = {};
+ pipelineDesc.program = shaderProgram.get();
+ ComPtr<gfx::IPipelineState> pipelineState;
+ GFX_CHECK_CALL_ABORT(
+ device->createComputePipelineState(pipelineDesc, pipelineState.writeRef()));
+
+ const int numberCount = 4;
+ float initialData[] = {0.0f, 0.0f, 0.0f, 0.0f};
+ IBufferResource::Desc bufferDesc = {};
+ bufferDesc.sizeInBytes = numberCount * sizeof(float);
+ bufferDesc.format = gfx::Format::Unknown;
+ bufferDesc.elementSize = sizeof(float);
+ bufferDesc.allowedStates = ResourceStateSet(
+ ResourceState::ShaderResource,
+ ResourceState::UnorderedAccess,
+ ResourceState::CopyDestination,
+ ResourceState::CopySource);
+ bufferDesc.defaultState = ResourceState::UnorderedAccess;
+ bufferDesc.memoryType = MemoryType::DeviceLocal;
+
+ ComPtr<IBufferResource> numbersBuffer;
+ GFX_CHECK_CALL_ABORT(
+ device->createBufferResource(bufferDesc, (void*)initialData, numbersBuffer.writeRef()));
+
+ ComPtr<IResourceView> bufferView;
+ IResourceView::Desc viewDesc = {};
+ viewDesc.type = IResourceView::Type::UnorderedAccess;
+ viewDesc.format = Format::Unknown;
+ GFX_CHECK_CALL_ABORT(
+ device->createBufferView(numbersBuffer, nullptr, viewDesc, bufferView.writeRef()));
+
+ // We have done all the set up work, now it is time to start recording a command buffer for
+ // GPU execution.
+ {
+ ICommandQueue::Desc queueDesc = {ICommandQueue::QueueType::Graphics};
+ auto queue = device->createCommandQueue(queueDesc);
- auto rootObject = encoder->bindPipeline(pipelineState);
+ auto commandBuffer = transientHeap->createCommandBuffer();
+ auto encoder = commandBuffer->encodeComputeCommands();
- ShaderCursor entryPointCursor(
- rootObject->getEntryPoint(0)); // get a cursor the the first entry-point.
- // Bind buffer view to the entry point.
- entryPointCursor.getPath("buffer").setResource(bufferView);
+ auto rootObject = encoder->bindPipeline(pipelineState);
- encoder->dispatchCompute(1, 1, 1);
- encoder->endEncoding();
- commandBuffer->close();
- queue->executeCommandBuffer(commandBuffer);
- queue->waitOnHost();
- }
+ ShaderCursor entryPointCursor(
+ rootObject->getEntryPoint(0)); // get a cursor the the first entry-point.
+ // Bind buffer view to the entry point.
+ entryPointCursor.getPath("buffer").setResource(bufferView);
- compareComputeResult(
- device,
- numbersBuffer,
- Slang::makeArray<float>(3.0f, 3.0f, 3.0f, 3.0f));
+ encoder->dispatchCompute(1, 1, 1);
+ encoder->endEncoding();
+ commandBuffer->close();
+ queue->executeCommandBuffer(commandBuffer);
+ queue->waitOnHost();
}
- SLANG_UNIT_TEST(precompiledModuleD3D12)
- {
- runTestImpl(precompiledModuleTestImpl, unitTestContext, Slang::RenderApiFlag::D3D12);
- }
+ compareComputeResult(device, numbersBuffer, Slang::makeArray<float>(3.0f, 3.0f, 3.0f, 3.0f));
+}
- SLANG_UNIT_TEST(precompiledModuleVulkan)
- {
- runTestImpl(precompiledModuleTestImpl, unitTestContext, Slang::RenderApiFlag::Vulkan);
- }
+SLANG_UNIT_TEST(precompiledModuleD3D12)
+{
+ runTestImpl(precompiledModuleTestImpl, unitTestContext, Slang::RenderApiFlag::D3D12);
+}
+SLANG_UNIT_TEST(precompiledModuleVulkan)
+{
+ runTestImpl(precompiledModuleTestImpl, unitTestContext, Slang::RenderApiFlag::Vulkan);
}
+
+} // namespace gfx_test
diff --git a/tools/gfx-unit-test/ray-tracing-tests.cpp b/tools/gfx-unit-test/ray-tracing-tests.cpp
index 97a6ad7d1..0e7fd2765 100644
--- a/tools/gfx-unit-test/ray-tracing-tests.cpp
+++ b/tools/gfx-unit-test/ray-tracing-tests.cpp
@@ -1,11 +1,10 @@
-#include "tools/unit-test/slang-unit-test.h"
-
-#include "slang-gfx.h"
-#include "gfx-test-util.h"
#include "gfx-test-texture-util.h"
+#include "gfx-test-util.h"
+#include "slang-gfx.h"
+#include "source/core/slang-basic.h"
#include "tools/gfx-util/shader-cursor.h"
#include "tools/platform/vector-math.h"
-#include "source/core/slang-basic.h"
+#include "tools/unit-test/slang-unit-test.h"
#include <chrono>
@@ -14,482 +13,495 @@ using namespace Slang;
namespace gfx_test
{
- struct Vertex
- {
- float position[3];
- };
-
- static const int kVertexCount = 9;
- static const Vertex kVertexData[kVertexCount] =
- {
- // Triangle 1
- { 0, 0, 1 },
- { 4, 0, 1 },
- { 0, 4, 1 },
-
- // Triangle 2
- { -4, 0, 1 },
- { 0, 0, 1 },
- { 0, 4, 1 },
-
- // Triangle 3
- { 0, 0, 1 },
- { 4, 0, 1 },
- { 0, -4, 1 },
- };
- static const int kIndexCount = 9;
- static const uint32_t kIndexData[kIndexCount] =
- {
- 0, 1, 2,
- 3, 4, 5,
- 6, 7, 8,
- };
-
- struct BaseRayTracingTest
+struct Vertex
+{
+ float position[3];
+};
+
+static const int kVertexCount = 9;
+static const Vertex kVertexData[kVertexCount] = {
+ // Triangle 1
+ {0, 0, 1},
+ {4, 0, 1},
+ {0, 4, 1},
+
+ // Triangle 2
+ {-4, 0, 1},
+ {0, 0, 1},
+ {0, 4, 1},
+
+ // Triangle 3
+ {0, 0, 1},
+ {4, 0, 1},
+ {0, -4, 1},
+};
+static const int kIndexCount = 9;
+static const uint32_t kIndexData[kIndexCount] = {
+ 0,
+ 1,
+ 2,
+ 3,
+ 4,
+ 5,
+ 6,
+ 7,
+ 8,
+};
+
+struct BaseRayTracingTest
+{
+ IDevice* device;
+ UnitTestContext* context;
+
+ ComPtr<IFramebufferLayout> framebufferLayout;
+ ComPtr<ITransientResourceHeap> transientHeap;
+ ComPtr<ICommandQueue> queue;
+
+ ComPtr<IPipelineState> renderPipelineState;
+ ComPtr<IBufferResource> vertexBuffer;
+ ComPtr<IBufferResource> indexBuffer;
+ ComPtr<IBufferResource> transformBuffer;
+ ComPtr<IBufferResource> instanceBuffer;
+ ComPtr<IBufferResource> BLASBuffer;
+ ComPtr<IAccelerationStructure> BLAS;
+ ComPtr<IBufferResource> TLASBuffer;
+ ComPtr<IAccelerationStructure> TLAS;
+ ComPtr<ITextureResource> resultTexture;
+ ComPtr<IResourceView> resultTextureUAV;
+ ComPtr<IShaderTable> shaderTable;
+
+ uint32_t width = 2;
+ uint32_t height = 2;
+
+ void init(IDevice* device, UnitTestContext* context)
{
- IDevice* device;
- UnitTestContext* context;
-
- ComPtr<IFramebufferLayout> framebufferLayout;
- ComPtr<ITransientResourceHeap> transientHeap;
- ComPtr<ICommandQueue> queue;
-
- ComPtr<IPipelineState> renderPipelineState;
- ComPtr<IBufferResource> vertexBuffer;
- ComPtr<IBufferResource> indexBuffer;
- ComPtr<IBufferResource> transformBuffer;
- ComPtr<IBufferResource> instanceBuffer;
- ComPtr<IBufferResource> BLASBuffer;
- ComPtr<IAccelerationStructure> BLAS;
- ComPtr<IBufferResource> TLASBuffer;
- ComPtr<IAccelerationStructure> TLAS;
- ComPtr<ITextureResource> resultTexture;
- ComPtr<IResourceView> resultTextureUAV;
- ComPtr<IShaderTable> shaderTable;
-
- uint32_t width = 2;
- uint32_t height = 2;
-
- void init(IDevice* device, UnitTestContext* context)
+ if (!device->hasFeature("ray-tracing"))
{
- if (!device->hasFeature("ray-tracing"))
- {
- SLANG_IGNORE_TEST;
- }
-
- this->device = device;
- this->context = context;
+ SLANG_IGNORE_TEST;
}
- // Load and compile shader code from source.
- gfx::Result loadShaderProgram(gfx::IDevice* device, gfx::IShaderProgram** outProgram)
- {
- ComPtr<slang::ISession> slangSession;
- slangSession = device->getSlangSession();
-
- ComPtr<slang::IBlob> diagnosticsBlob;
- slang::IModule* module = slangSession->loadModule("ray-tracing-test-shaders", diagnosticsBlob.writeRef());
- if (!module)
- return SLANG_FAIL;
-
- Slang::List<slang::IComponentType*> componentTypes;
- componentTypes.add(module);
- ComPtr<slang::IEntryPoint> entryPoint;
- SLANG_RETURN_ON_FAIL(module->findEntryPointByName("rayGenShaderA", entryPoint.writeRef()));
- componentTypes.add(entryPoint);
- SLANG_RETURN_ON_FAIL(module->findEntryPointByName("rayGenShaderB", entryPoint.writeRef()));
- componentTypes.add(entryPoint);
- SLANG_RETURN_ON_FAIL(module->findEntryPointByName("missShaderA", entryPoint.writeRef()));
- componentTypes.add(entryPoint);
- SLANG_RETURN_ON_FAIL(module->findEntryPointByName("missShaderB", entryPoint.writeRef()));
- componentTypes.add(entryPoint);
- SLANG_RETURN_ON_FAIL(
- module->findEntryPointByName("closestHitShaderA", entryPoint.writeRef()));
- componentTypes.add(entryPoint);
- SLANG_RETURN_ON_FAIL(
- module->findEntryPointByName("closestHitShaderB", entryPoint.writeRef()));
- componentTypes.add(entryPoint);
-
- ComPtr<slang::IComponentType> linkedProgram;
- SlangResult result = slangSession->createCompositeComponentType(
- componentTypes.getBuffer(),
- componentTypes.getCount(),
- linkedProgram.writeRef(),
- diagnosticsBlob.writeRef());
- SLANG_RETURN_ON_FAIL(result);
-
- gfx::IShaderProgram::Desc programDesc = {};
- programDesc.slangGlobalScope = linkedProgram;
- SLANG_RETURN_ON_FAIL(device->createProgram(programDesc, outProgram));
-
- return SLANG_OK;
- }
+ this->device = device;
+ this->context = context;
+ }
- void createResultTexture()
- {
- ITextureResource::Desc resultTextureDesc = {};
- resultTextureDesc.type = IResource::Type::Texture2D;
- resultTextureDesc.numMipLevels = 1;
- resultTextureDesc.size.width = width;
- resultTextureDesc.size.height = height;
- resultTextureDesc.size.depth = 1;
- resultTextureDesc.defaultState = ResourceState::UnorderedAccess;
- resultTextureDesc.format = Format::R32G32B32A32_FLOAT;
- resultTexture = device->createTextureResource(resultTextureDesc);
- IResourceView::Desc resultUAVDesc = {};
- resultUAVDesc.format = resultTextureDesc.format;
- resultUAVDesc.type = IResourceView::Type::UnorderedAccess;
- resultTextureUAV = device->createTextureView(resultTexture, resultUAVDesc);
- }
+ // Load and compile shader code from source.
+ gfx::Result loadShaderProgram(gfx::IDevice* device, gfx::IShaderProgram** outProgram)
+ {
+ ComPtr<slang::ISession> slangSession;
+ slangSession = device->getSlangSession();
+
+ ComPtr<slang::IBlob> diagnosticsBlob;
+ slang::IModule* module =
+ slangSession->loadModule("ray-tracing-test-shaders", diagnosticsBlob.writeRef());
+ if (!module)
+ return SLANG_FAIL;
+
+ Slang::List<slang::IComponentType*> componentTypes;
+ componentTypes.add(module);
+ ComPtr<slang::IEntryPoint> entryPoint;
+ SLANG_RETURN_ON_FAIL(module->findEntryPointByName("rayGenShaderA", entryPoint.writeRef()));
+ componentTypes.add(entryPoint);
+ SLANG_RETURN_ON_FAIL(module->findEntryPointByName("rayGenShaderB", entryPoint.writeRef()));
+ componentTypes.add(entryPoint);
+ SLANG_RETURN_ON_FAIL(module->findEntryPointByName("missShaderA", entryPoint.writeRef()));
+ componentTypes.add(entryPoint);
+ SLANG_RETURN_ON_FAIL(module->findEntryPointByName("missShaderB", entryPoint.writeRef()));
+ componentTypes.add(entryPoint);
+ SLANG_RETURN_ON_FAIL(
+ module->findEntryPointByName("closestHitShaderA", entryPoint.writeRef()));
+ componentTypes.add(entryPoint);
+ SLANG_RETURN_ON_FAIL(
+ module->findEntryPointByName("closestHitShaderB", entryPoint.writeRef()));
+ componentTypes.add(entryPoint);
+
+ ComPtr<slang::IComponentType> linkedProgram;
+ SlangResult result = slangSession->createCompositeComponentType(
+ componentTypes.getBuffer(),
+ componentTypes.getCount(),
+ linkedProgram.writeRef(),
+ diagnosticsBlob.writeRef());
+ SLANG_RETURN_ON_FAIL(result);
+
+ gfx::IShaderProgram::Desc programDesc = {};
+ programDesc.slangGlobalScope = linkedProgram;
+ SLANG_RETURN_ON_FAIL(device->createProgram(programDesc, outProgram));
+
+ return SLANG_OK;
+ }
- void createRequiredResources()
- {
- ICommandQueue::Desc queueDesc = {};
- queueDesc.type = ICommandQueue::QueueType::Graphics;
- queue = device->createCommandQueue(queueDesc);
-
- IBufferResource::Desc vertexBufferDesc;
- vertexBufferDesc.type = IResource::Type::Buffer;
- vertexBufferDesc.sizeInBytes = kVertexCount * sizeof(Vertex);
- vertexBufferDesc.defaultState = ResourceState::ShaderResource;
- vertexBuffer = device->createBufferResource(vertexBufferDesc, &kVertexData[0]);
- SLANG_CHECK_ABORT(vertexBuffer != nullptr);
-
- IBufferResource::Desc indexBufferDesc;
- indexBufferDesc.type = IResource::Type::Buffer;
- indexBufferDesc.sizeInBytes = kIndexCount * sizeof(int32_t);
- indexBufferDesc.defaultState = ResourceState::ShaderResource;
- indexBuffer = device->createBufferResource(indexBufferDesc, &kIndexData[0]);
- SLANG_CHECK_ABORT(indexBuffer != nullptr);
-
- IBufferResource::Desc transformBufferDesc;
- transformBufferDesc.type = IResource::Type::Buffer;
- transformBufferDesc.sizeInBytes = sizeof(float) * 12;
- transformBufferDesc.defaultState = ResourceState::ShaderResource;
- float transformData[12] = {
- 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f };
- transformBuffer = device->createBufferResource(transformBufferDesc, &transformData);
- SLANG_CHECK_ABORT(transformBuffer != nullptr);
-
- createResultTexture();
-
- IFramebufferLayout::TargetLayout renderTargetLayout = { Format::R8G8B8A8_UNORM, 1 };
- IFramebufferLayout::TargetLayout depthLayout = { gfx::Format::D32_FLOAT, 1 };
- IFramebufferLayout::Desc framebufferLayoutDesc;
- framebufferLayoutDesc.renderTargetCount = 1;
- framebufferLayoutDesc.renderTargets = &renderTargetLayout;
- framebufferLayoutDesc.depthStencil = &depthLayout;
- GFX_CHECK_CALL_ABORT(
- device->createFramebufferLayout(framebufferLayoutDesc, framebufferLayout.writeRef()));
+ void createResultTexture()
+ {
+ ITextureResource::Desc resultTextureDesc = {};
+ resultTextureDesc.type = IResource::Type::Texture2D;
+ resultTextureDesc.numMipLevels = 1;
+ resultTextureDesc.size.width = width;
+ resultTextureDesc.size.height = height;
+ resultTextureDesc.size.depth = 1;
+ resultTextureDesc.defaultState = ResourceState::UnorderedAccess;
+ resultTextureDesc.format = Format::R32G32B32A32_FLOAT;
+ resultTexture = device->createTextureResource(resultTextureDesc);
+ IResourceView::Desc resultUAVDesc = {};
+ resultUAVDesc.format = resultTextureDesc.format;
+ resultUAVDesc.type = IResourceView::Type::UnorderedAccess;
+ resultTextureUAV = device->createTextureView(resultTexture, resultUAVDesc);
+ }
- ITransientResourceHeap::Desc transientHeapDesc = {};
- transientHeapDesc.constantBufferSize = 4096 * 1024;
- GFX_CHECK_CALL_ABORT(
- device->createTransientResourceHeap(transientHeapDesc, transientHeap.writeRef()));
-
- // Build bottom level acceleration structure.
- {
- IAccelerationStructure::BuildInputs accelerationStructureBuildInputs;
- IAccelerationStructure::PrebuildInfo accelerationStructurePrebuildInfo;
- accelerationStructureBuildInputs.descCount = 1;
- accelerationStructureBuildInputs.kind = IAccelerationStructure::Kind::BottomLevel;
- accelerationStructureBuildInputs.flags =
- IAccelerationStructure::BuildFlags::AllowCompaction;
- IAccelerationStructure::GeometryDesc geomDesc;
- geomDesc.flags = IAccelerationStructure::GeometryFlags::Opaque;
- geomDesc.type = IAccelerationStructure::GeometryType::Triangles;
- geomDesc.content.triangles.indexCount = kIndexCount;
- geomDesc.content.triangles.indexData = indexBuffer->getDeviceAddress();
- geomDesc.content.triangles.indexFormat = Format::R32_UINT;
- geomDesc.content.triangles.vertexCount = kVertexCount;
- geomDesc.content.triangles.vertexData = vertexBuffer->getDeviceAddress();
- geomDesc.content.triangles.vertexFormat = Format::R32G32B32_FLOAT;
- geomDesc.content.triangles.vertexStride = sizeof(Vertex);
- geomDesc.content.triangles.transform3x4 = transformBuffer->getDeviceAddress();
- accelerationStructureBuildInputs.geometryDescs = &geomDesc;
-
- // Query buffer size for acceleration structure build.
- GFX_CHECK_CALL_ABORT(device->getAccelerationStructurePrebuildInfo(
- accelerationStructureBuildInputs, &accelerationStructurePrebuildInfo));
- // Allocate buffers for acceleration structure.
- IBufferResource::Desc asDraftBufferDesc;
- asDraftBufferDesc.type = IResource::Type::Buffer;
- asDraftBufferDesc.defaultState = ResourceState::AccelerationStructure;
- asDraftBufferDesc.sizeInBytes = (size_t)accelerationStructurePrebuildInfo.resultDataMaxSize;
- ComPtr<IBufferResource> draftBuffer = device->createBufferResource(asDraftBufferDesc);
- IBufferResource::Desc scratchBufferDesc;
- scratchBufferDesc.type = IResource::Type::Buffer;
- scratchBufferDesc.defaultState = ResourceState::UnorderedAccess;
- scratchBufferDesc.sizeInBytes = (size_t)accelerationStructurePrebuildInfo.scratchDataSize;
- ComPtr<IBufferResource> scratchBuffer = device->createBufferResource(scratchBufferDesc);
-
- // Build acceleration structure.
- ComPtr<IQueryPool> compactedSizeQuery;
- IQueryPool::Desc queryPoolDesc;
- queryPoolDesc.count = 1;
- queryPoolDesc.type = QueryType::AccelerationStructureCompactedSize;
- GFX_CHECK_CALL_ABORT(
- device->createQueryPool(queryPoolDesc, compactedSizeQuery.writeRef()));
-
- ComPtr<IAccelerationStructure> draftAS;
- IAccelerationStructure::CreateDesc draftCreateDesc;
- draftCreateDesc.buffer = draftBuffer;
- draftCreateDesc.kind = IAccelerationStructure::Kind::BottomLevel;
- draftCreateDesc.offset = 0;
- draftCreateDesc.size = accelerationStructurePrebuildInfo.resultDataMaxSize;
- GFX_CHECK_CALL_ABORT(
- device->createAccelerationStructure(draftCreateDesc, draftAS.writeRef()));
-
- compactedSizeQuery->reset();
-
- auto commandBuffer = transientHeap->createCommandBuffer();
- auto encoder = commandBuffer->encodeRayTracingCommands();
- IAccelerationStructure::BuildDesc buildDesc = {};
- buildDesc.dest = draftAS;
- buildDesc.inputs = accelerationStructureBuildInputs;
- buildDesc.scratchData = scratchBuffer->getDeviceAddress();
- AccelerationStructureQueryDesc compactedSizeQueryDesc = {};
- compactedSizeQueryDesc.queryPool = compactedSizeQuery;
- compactedSizeQueryDesc.queryType = QueryType::AccelerationStructureCompactedSize;
- encoder->buildAccelerationStructure(buildDesc, 1, &compactedSizeQueryDesc);
- encoder->endEncoding();
- commandBuffer->close();
- queue->executeCommandBuffer(commandBuffer);
- queue->waitOnHost();
-
- uint64_t compactedSize = 0;
- compactedSizeQuery->getResult(0, 1, &compactedSize);
- IBufferResource::Desc asBufferDesc;
- asBufferDesc.type = IResource::Type::Buffer;
- asBufferDesc.defaultState = ResourceState::AccelerationStructure;
- asBufferDesc.sizeInBytes = (size_t)compactedSize;
- BLASBuffer = device->createBufferResource(asBufferDesc);
- IAccelerationStructure::CreateDesc createDesc;
- createDesc.buffer = BLASBuffer;
- createDesc.kind = IAccelerationStructure::Kind::BottomLevel;
- createDesc.offset = 0;
- createDesc.size = (size_t)compactedSize;
- device->createAccelerationStructure(createDesc, BLAS.writeRef());
-
- commandBuffer = transientHeap->createCommandBuffer();
- encoder = commandBuffer->encodeRayTracingCommands();
- encoder->copyAccelerationStructure(BLAS, draftAS, AccelerationStructureCopyMode::Compact);
- encoder->endEncoding();
- commandBuffer->close();
- queue->executeCommandBuffer(commandBuffer);
- queue->waitOnHost();
- }
-
- // Build top level acceleration structure.
- {
- List<IAccelerationStructure::InstanceDesc> instanceDescs;
- instanceDescs.setCount(1);
- instanceDescs[0].accelerationStructure = BLAS->getDeviceAddress();
- instanceDescs[0].flags =
- IAccelerationStructure::GeometryInstanceFlags::TriangleFacingCullDisable;
- instanceDescs[0].instanceContributionToHitGroupIndex = 0;
- instanceDescs[0].instanceID = 0;
- instanceDescs[0].instanceMask = 0xFF;
- float transformMatrix[] = { 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f };
- memcpy(&instanceDescs[0].transform[0][0], transformMatrix, sizeof(float) * 12);
-
- IBufferResource::Desc instanceBufferDesc;
- instanceBufferDesc.type = IResource::Type::Buffer;
- instanceBufferDesc.sizeInBytes =
- instanceDescs.getCount() * sizeof(IAccelerationStructure::InstanceDesc);
- instanceBufferDesc.defaultState = ResourceState::ShaderResource;
- instanceBuffer = device->createBufferResource(instanceBufferDesc, instanceDescs.getBuffer());
- SLANG_CHECK_ABORT(instanceBuffer != nullptr);
-
- IAccelerationStructure::BuildInputs accelerationStructureBuildInputs = {};
- IAccelerationStructure::PrebuildInfo accelerationStructurePrebuildInfo = {};
- accelerationStructureBuildInputs.descCount = 1;
- accelerationStructureBuildInputs.kind = IAccelerationStructure::Kind::TopLevel;
- accelerationStructureBuildInputs.instanceDescs = instanceBuffer->getDeviceAddress();
-
- // Query buffer size for acceleration structure build.
- GFX_CHECK_CALL_ABORT(device->getAccelerationStructurePrebuildInfo(
- accelerationStructureBuildInputs, &accelerationStructurePrebuildInfo));
-
- IBufferResource::Desc asBufferDesc;
- asBufferDesc.type = IResource::Type::Buffer;
- asBufferDesc.defaultState = ResourceState::AccelerationStructure;
- asBufferDesc.sizeInBytes = (size_t)accelerationStructurePrebuildInfo.resultDataMaxSize;
- TLASBuffer = device->createBufferResource(asBufferDesc);
-
- IBufferResource::Desc scratchBufferDesc;
- scratchBufferDesc.type = IResource::Type::Buffer;
- scratchBufferDesc.defaultState = ResourceState::UnorderedAccess;
- scratchBufferDesc.sizeInBytes = (size_t)accelerationStructurePrebuildInfo.scratchDataSize;
- ComPtr<IBufferResource> scratchBuffer = device->createBufferResource(scratchBufferDesc);
-
- IAccelerationStructure::CreateDesc createDesc;
- createDesc.buffer = TLASBuffer;
- createDesc.kind = IAccelerationStructure::Kind::TopLevel;
- createDesc.offset = 0;
- createDesc.size = (size_t)accelerationStructurePrebuildInfo.resultDataMaxSize;
- GFX_CHECK_CALL_ABORT(device->createAccelerationStructure(createDesc, TLAS.writeRef()));
-
- auto commandBuffer = transientHeap->createCommandBuffer();
- auto encoder = commandBuffer->encodeRayTracingCommands();
- IAccelerationStructure::BuildDesc buildDesc = {};
- buildDesc.dest = TLAS;
- buildDesc.inputs = accelerationStructureBuildInputs;
- buildDesc.scratchData = scratchBuffer->getDeviceAddress();
- encoder->buildAccelerationStructure(buildDesc, 0, nullptr);
- encoder->endEncoding();
- commandBuffer->close();
- queue->executeCommandBuffer(commandBuffer);
- queue->waitOnHost();
- }
-
- const char* hitgroupNames[] = { "hitgroupA", "hitgroupB"};
-
- ComPtr<IShaderProgram> rayTracingProgram;
+ void createRequiredResources()
+ {
+ ICommandQueue::Desc queueDesc = {};
+ queueDesc.type = ICommandQueue::QueueType::Graphics;
+ queue = device->createCommandQueue(queueDesc);
+
+ IBufferResource::Desc vertexBufferDesc;
+ vertexBufferDesc.type = IResource::Type::Buffer;
+ vertexBufferDesc.sizeInBytes = kVertexCount * sizeof(Vertex);
+ vertexBufferDesc.defaultState = ResourceState::ShaderResource;
+ vertexBuffer = device->createBufferResource(vertexBufferDesc, &kVertexData[0]);
+ SLANG_CHECK_ABORT(vertexBuffer != nullptr);
+
+ IBufferResource::Desc indexBufferDesc;
+ indexBufferDesc.type = IResource::Type::Buffer;
+ indexBufferDesc.sizeInBytes = kIndexCount * sizeof(int32_t);
+ indexBufferDesc.defaultState = ResourceState::ShaderResource;
+ indexBuffer = device->createBufferResource(indexBufferDesc, &kIndexData[0]);
+ SLANG_CHECK_ABORT(indexBuffer != nullptr);
+
+ IBufferResource::Desc transformBufferDesc;
+ transformBufferDesc.type = IResource::Type::Buffer;
+ transformBufferDesc.sizeInBytes = sizeof(float) * 12;
+ transformBufferDesc.defaultState = ResourceState::ShaderResource;
+ float transformData[12] =
+ {1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f};
+ transformBuffer = device->createBufferResource(transformBufferDesc, &transformData);
+ SLANG_CHECK_ABORT(transformBuffer != nullptr);
+
+ createResultTexture();
+
+ IFramebufferLayout::TargetLayout renderTargetLayout = {Format::R8G8B8A8_UNORM, 1};
+ IFramebufferLayout::TargetLayout depthLayout = {gfx::Format::D32_FLOAT, 1};
+ IFramebufferLayout::Desc framebufferLayoutDesc;
+ framebufferLayoutDesc.renderTargetCount = 1;
+ framebufferLayoutDesc.renderTargets = &renderTargetLayout;
+ framebufferLayoutDesc.depthStencil = &depthLayout;
+ GFX_CHECK_CALL_ABORT(
+ device->createFramebufferLayout(framebufferLayoutDesc, framebufferLayout.writeRef()));
+
+ ITransientResourceHeap::Desc transientHeapDesc = {};
+ transientHeapDesc.constantBufferSize = 4096 * 1024;
+ GFX_CHECK_CALL_ABORT(
+ device->createTransientResourceHeap(transientHeapDesc, transientHeap.writeRef()));
+
+ // Build bottom level acceleration structure.
+ {
+ IAccelerationStructure::BuildInputs accelerationStructureBuildInputs;
+ IAccelerationStructure::PrebuildInfo accelerationStructurePrebuildInfo;
+ accelerationStructureBuildInputs.descCount = 1;
+ accelerationStructureBuildInputs.kind = IAccelerationStructure::Kind::BottomLevel;
+ accelerationStructureBuildInputs.flags =
+ IAccelerationStructure::BuildFlags::AllowCompaction;
+ IAccelerationStructure::GeometryDesc geomDesc;
+ geomDesc.flags = IAccelerationStructure::GeometryFlags::Opaque;
+ geomDesc.type = IAccelerationStructure::GeometryType::Triangles;
+ geomDesc.content.triangles.indexCount = kIndexCount;
+ geomDesc.content.triangles.indexData = indexBuffer->getDeviceAddress();
+ geomDesc.content.triangles.indexFormat = Format::R32_UINT;
+ geomDesc.content.triangles.vertexCount = kVertexCount;
+ geomDesc.content.triangles.vertexData = vertexBuffer->getDeviceAddress();
+ geomDesc.content.triangles.vertexFormat = Format::R32G32B32_FLOAT;
+ geomDesc.content.triangles.vertexStride = sizeof(Vertex);
+ geomDesc.content.triangles.transform3x4 = transformBuffer->getDeviceAddress();
+ accelerationStructureBuildInputs.geometryDescs = &geomDesc;
+
+ // Query buffer size for acceleration structure build.
+ GFX_CHECK_CALL_ABORT(device->getAccelerationStructurePrebuildInfo(
+ accelerationStructureBuildInputs,
+ &accelerationStructurePrebuildInfo));
+ // Allocate buffers for acceleration structure.
+ IBufferResource::Desc asDraftBufferDesc;
+ asDraftBufferDesc.type = IResource::Type::Buffer;
+ asDraftBufferDesc.defaultState = ResourceState::AccelerationStructure;
+ asDraftBufferDesc.sizeInBytes =
+ (size_t)accelerationStructurePrebuildInfo.resultDataMaxSize;
+ ComPtr<IBufferResource> draftBuffer = device->createBufferResource(asDraftBufferDesc);
+ IBufferResource::Desc scratchBufferDesc;
+ scratchBufferDesc.type = IResource::Type::Buffer;
+ scratchBufferDesc.defaultState = ResourceState::UnorderedAccess;
+ scratchBufferDesc.sizeInBytes =
+ (size_t)accelerationStructurePrebuildInfo.scratchDataSize;
+ ComPtr<IBufferResource> scratchBuffer = device->createBufferResource(scratchBufferDesc);
+
+ // Build acceleration structure.
+ ComPtr<IQueryPool> compactedSizeQuery;
+ IQueryPool::Desc queryPoolDesc;
+ queryPoolDesc.count = 1;
+ queryPoolDesc.type = QueryType::AccelerationStructureCompactedSize;
GFX_CHECK_CALL_ABORT(
- loadShaderProgram(device, rayTracingProgram.writeRef()));
- RayTracingPipelineStateDesc rtpDesc = {};
- rtpDesc.program = rayTracingProgram;
- rtpDesc.hitGroupCount = 2;
- HitGroupDesc hitGroups[2];
- hitGroups[0].closestHitEntryPoint = "closestHitShaderA";
- hitGroups[0].hitGroupName = hitgroupNames[0];
- hitGroups[1].closestHitEntryPoint = "closestHitShaderB";
- hitGroups[1].hitGroupName = hitgroupNames[1];
- rtpDesc.hitGroups = hitGroups;
- rtpDesc.maxRayPayloadSize = 64;
- rtpDesc.maxRecursion = 2;
+ device->createQueryPool(queryPoolDesc, compactedSizeQuery.writeRef()));
+
+ ComPtr<IAccelerationStructure> draftAS;
+ IAccelerationStructure::CreateDesc draftCreateDesc;
+ draftCreateDesc.buffer = draftBuffer;
+ draftCreateDesc.kind = IAccelerationStructure::Kind::BottomLevel;
+ draftCreateDesc.offset = 0;
+ draftCreateDesc.size = accelerationStructurePrebuildInfo.resultDataMaxSize;
GFX_CHECK_CALL_ABORT(
- device->createRayTracingPipelineState(rtpDesc, renderPipelineState.writeRef()));
- SLANG_CHECK_ABORT(renderPipelineState != nullptr);
-
- const char* raygenNames[] = { "rayGenShaderA", "rayGenShaderB" };
- const char* missNames[] = { "missShaderA", "missShaderB" };
-
- IShaderTable::Desc shaderTableDesc = {};
- shaderTableDesc.program = rayTracingProgram;
- shaderTableDesc.hitGroupCount = 2;
- shaderTableDesc.hitGroupNames = hitgroupNames;
- shaderTableDesc.rayGenShaderCount = 2;
- shaderTableDesc.rayGenShaderEntryPointNames = raygenNames;
- shaderTableDesc.missShaderCount = 2;
- shaderTableDesc.missShaderEntryPointNames = missNames;
- GFX_CHECK_CALL_ABORT(device->createShaderTable(shaderTableDesc, shaderTable.writeRef()));
- }
-
- void checkTestResults(float* expectedResult, uint32_t count)
- {
- ComPtr<ISlangBlob> resultBlob;
- size_t rowPitch = 0;
- size_t pixelSize = 0;
- auto cmdBuffer = transientHeap->createCommandBuffer();
- auto encoder = cmdBuffer->encodeResourceCommands();
- encoder->textureBarrier(resultTexture.get(), ResourceState::UnorderedAccess, ResourceState::CopySource);
+ device->createAccelerationStructure(draftCreateDesc, draftAS.writeRef()));
+
+ compactedSizeQuery->reset();
+
+ auto commandBuffer = transientHeap->createCommandBuffer();
+ auto encoder = commandBuffer->encodeRayTracingCommands();
+ IAccelerationStructure::BuildDesc buildDesc = {};
+ buildDesc.dest = draftAS;
+ buildDesc.inputs = accelerationStructureBuildInputs;
+ buildDesc.scratchData = scratchBuffer->getDeviceAddress();
+ AccelerationStructureQueryDesc compactedSizeQueryDesc = {};
+ compactedSizeQueryDesc.queryPool = compactedSizeQuery;
+ compactedSizeQueryDesc.queryType = QueryType::AccelerationStructureCompactedSize;
+ encoder->buildAccelerationStructure(buildDesc, 1, &compactedSizeQueryDesc);
encoder->endEncoding();
- cmdBuffer->close();
- queue->executeCommandBuffer(cmdBuffer.get());
+ commandBuffer->close();
+ queue->executeCommandBuffer(commandBuffer);
queue->waitOnHost();
- GFX_CHECK_CALL_ABORT(device->readTextureResource(
- resultTexture, ResourceState::CopySource, resultBlob.writeRef(), &rowPitch, &pixelSize));
-#if 0 // for debugging only
- writeImage("test.hdr", resultBlob, width, height, (uint32_t)rowPitch, (uint32_t)pixelSize);
-#endif
- auto buffer = removePadding(resultBlob, width, height, rowPitch, pixelSize);
- auto actualData = (float*)buffer.getBuffer();
- SLANG_CHECK(memcmp(actualData, expectedResult, count * sizeof(float)) == 0)
- }
- };
-
- struct RayTracingTestA : BaseRayTracingTest
- {
- void renderFrame()
- {
- ComPtr<ICommandBuffer> renderCommandBuffer =
- transientHeap->createCommandBuffer();
- auto renderEncoder = renderCommandBuffer->encodeRayTracingCommands();
- IShaderObject* rootObject = nullptr;
- renderEncoder->bindPipeline(renderPipelineState, &rootObject);
- auto cursor = ShaderCursor(rootObject);
- cursor["resultTexture"].setResource(resultTextureUAV);
- cursor["sceneBVH"].setResource(TLAS);
- renderEncoder->dispatchRays(0, shaderTable, width, height, 1);
- renderEncoder->endEncoding();
- renderCommandBuffer->close();
- queue->executeCommandBuffer(renderCommandBuffer);
+ uint64_t compactedSize = 0;
+ compactedSizeQuery->getResult(0, 1, &compactedSize);
+ IBufferResource::Desc asBufferDesc;
+ asBufferDesc.type = IResource::Type::Buffer;
+ asBufferDesc.defaultState = ResourceState::AccelerationStructure;
+ asBufferDesc.sizeInBytes = (size_t)compactedSize;
+ BLASBuffer = device->createBufferResource(asBufferDesc);
+ IAccelerationStructure::CreateDesc createDesc;
+ createDesc.buffer = BLASBuffer;
+ createDesc.kind = IAccelerationStructure::Kind::BottomLevel;
+ createDesc.offset = 0;
+ createDesc.size = (size_t)compactedSize;
+ device->createAccelerationStructure(createDesc, BLAS.writeRef());
+
+ commandBuffer = transientHeap->createCommandBuffer();
+ encoder = commandBuffer->encodeRayTracingCommands();
+ encoder->copyAccelerationStructure(
+ BLAS,
+ draftAS,
+ AccelerationStructureCopyMode::Compact);
+ encoder->endEncoding();
+ commandBuffer->close();
+ queue->executeCommandBuffer(commandBuffer);
queue->waitOnHost();
}
- void run()
- {
- createRequiredResources();
- renderFrame();
-
- float expectedResult[16] = { 1, 1, 1, 1,
- 0, 0, 1, 1,
- 0, 1, 0, 1,
- 1, 0, 0, 1 };
- checkTestResults(expectedResult, 16);
- }
- };
-
- struct RayTracingTestB : BaseRayTracingTest
- {
- void renderFrame()
+ // Build top level acceleration structure.
{
- ComPtr<ICommandBuffer> renderCommandBuffer =
- transientHeap->createCommandBuffer();
- auto renderEncoder = renderCommandBuffer->encodeRayTracingCommands();
- IShaderObject* rootObject = nullptr;
- renderEncoder->bindPipeline(renderPipelineState, &rootObject);
- auto cursor = ShaderCursor(rootObject);
- cursor["resultTexture"].setResource(resultTextureUAV);
- cursor["sceneBVH"].setResource(TLAS);
- renderEncoder->dispatchRays(1, shaderTable, width, height, 1);
- renderEncoder->endEncoding();
- renderCommandBuffer->close();
- queue->executeCommandBuffer(renderCommandBuffer);
+ List<IAccelerationStructure::InstanceDesc> instanceDescs;
+ instanceDescs.setCount(1);
+ instanceDescs[0].accelerationStructure = BLAS->getDeviceAddress();
+ instanceDescs[0].flags =
+ IAccelerationStructure::GeometryInstanceFlags::TriangleFacingCullDisable;
+ instanceDescs[0].instanceContributionToHitGroupIndex = 0;
+ instanceDescs[0].instanceID = 0;
+ instanceDescs[0].instanceMask = 0xFF;
+ float transformMatrix[] =
+ {1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f};
+ memcpy(&instanceDescs[0].transform[0][0], transformMatrix, sizeof(float) * 12);
+
+ IBufferResource::Desc instanceBufferDesc;
+ instanceBufferDesc.type = IResource::Type::Buffer;
+ instanceBufferDesc.sizeInBytes =
+ instanceDescs.getCount() * sizeof(IAccelerationStructure::InstanceDesc);
+ instanceBufferDesc.defaultState = ResourceState::ShaderResource;
+ instanceBuffer =
+ device->createBufferResource(instanceBufferDesc, instanceDescs.getBuffer());
+ SLANG_CHECK_ABORT(instanceBuffer != nullptr);
+
+ IAccelerationStructure::BuildInputs accelerationStructureBuildInputs = {};
+ IAccelerationStructure::PrebuildInfo accelerationStructurePrebuildInfo = {};
+ accelerationStructureBuildInputs.descCount = 1;
+ accelerationStructureBuildInputs.kind = IAccelerationStructure::Kind::TopLevel;
+ accelerationStructureBuildInputs.instanceDescs = instanceBuffer->getDeviceAddress();
+
+ // Query buffer size for acceleration structure build.
+ GFX_CHECK_CALL_ABORT(device->getAccelerationStructurePrebuildInfo(
+ accelerationStructureBuildInputs,
+ &accelerationStructurePrebuildInfo));
+
+ IBufferResource::Desc asBufferDesc;
+ asBufferDesc.type = IResource::Type::Buffer;
+ asBufferDesc.defaultState = ResourceState::AccelerationStructure;
+ asBufferDesc.sizeInBytes = (size_t)accelerationStructurePrebuildInfo.resultDataMaxSize;
+ TLASBuffer = device->createBufferResource(asBufferDesc);
+
+ IBufferResource::Desc scratchBufferDesc;
+ scratchBufferDesc.type = IResource::Type::Buffer;
+ scratchBufferDesc.defaultState = ResourceState::UnorderedAccess;
+ scratchBufferDesc.sizeInBytes =
+ (size_t)accelerationStructurePrebuildInfo.scratchDataSize;
+ ComPtr<IBufferResource> scratchBuffer = device->createBufferResource(scratchBufferDesc);
+
+ IAccelerationStructure::CreateDesc createDesc;
+ createDesc.buffer = TLASBuffer;
+ createDesc.kind = IAccelerationStructure::Kind::TopLevel;
+ createDesc.offset = 0;
+ createDesc.size = (size_t)accelerationStructurePrebuildInfo.resultDataMaxSize;
+ GFX_CHECK_CALL_ABORT(device->createAccelerationStructure(createDesc, TLAS.writeRef()));
+
+ auto commandBuffer = transientHeap->createCommandBuffer();
+ auto encoder = commandBuffer->encodeRayTracingCommands();
+ IAccelerationStructure::BuildDesc buildDesc = {};
+ buildDesc.dest = TLAS;
+ buildDesc.inputs = accelerationStructureBuildInputs;
+ buildDesc.scratchData = scratchBuffer->getDeviceAddress();
+ encoder->buildAccelerationStructure(buildDesc, 0, nullptr);
+ encoder->endEncoding();
+ commandBuffer->close();
+ queue->executeCommandBuffer(commandBuffer);
queue->waitOnHost();
}
- void run()
- {
- createRequiredResources();
- renderFrame();
-
- float expectedResult[16] = { 0, 0, 0, 1,
- 1, 1, 0, 1,
- 1, 0, 1, 1,
- 0, 1, 1, 1 };
- checkTestResults(expectedResult, 16);
- }
- };
+ const char* hitgroupNames[] = {"hitgroupA", "hitgroupB"};
+
+ ComPtr<IShaderProgram> rayTracingProgram;
+ GFX_CHECK_CALL_ABORT(loadShaderProgram(device, rayTracingProgram.writeRef()));
+ RayTracingPipelineStateDesc rtpDesc = {};
+ rtpDesc.program = rayTracingProgram;
+ rtpDesc.hitGroupCount = 2;
+ HitGroupDesc hitGroups[2];
+ hitGroups[0].closestHitEntryPoint = "closestHitShaderA";
+ hitGroups[0].hitGroupName = hitgroupNames[0];
+ hitGroups[1].closestHitEntryPoint = "closestHitShaderB";
+ hitGroups[1].hitGroupName = hitgroupNames[1];
+ rtpDesc.hitGroups = hitGroups;
+ rtpDesc.maxRayPayloadSize = 64;
+ rtpDesc.maxRecursion = 2;
+ GFX_CHECK_CALL_ABORT(
+ device->createRayTracingPipelineState(rtpDesc, renderPipelineState.writeRef()));
+ SLANG_CHECK_ABORT(renderPipelineState != nullptr);
+
+ const char* raygenNames[] = {"rayGenShaderA", "rayGenShaderB"};
+ const char* missNames[] = {"missShaderA", "missShaderB"};
+
+ IShaderTable::Desc shaderTableDesc = {};
+ shaderTableDesc.program = rayTracingProgram;
+ shaderTableDesc.hitGroupCount = 2;
+ shaderTableDesc.hitGroupNames = hitgroupNames;
+ shaderTableDesc.rayGenShaderCount = 2;
+ shaderTableDesc.rayGenShaderEntryPointNames = raygenNames;
+ shaderTableDesc.missShaderCount = 2;
+ shaderTableDesc.missShaderEntryPointNames = missNames;
+ GFX_CHECK_CALL_ABORT(device->createShaderTable(shaderTableDesc, shaderTable.writeRef()));
+ }
- template <typename T>
- void rayTracingTestImpl(IDevice* device, UnitTestContext* context)
+ void checkTestResults(float* expectedResult, uint32_t count)
{
- T test;
- test.init(device, context);
- test.run();
+ ComPtr<ISlangBlob> resultBlob;
+ size_t rowPitch = 0;
+ size_t pixelSize = 0;
+ auto cmdBuffer = transientHeap->createCommandBuffer();
+ auto encoder = cmdBuffer->encodeResourceCommands();
+ encoder->textureBarrier(
+ resultTexture.get(),
+ ResourceState::UnorderedAccess,
+ ResourceState::CopySource);
+ encoder->endEncoding();
+ cmdBuffer->close();
+ queue->executeCommandBuffer(cmdBuffer.get());
+ queue->waitOnHost();
+
+ GFX_CHECK_CALL_ABORT(device->readTextureResource(
+ resultTexture,
+ ResourceState::CopySource,
+ resultBlob.writeRef(),
+ &rowPitch,
+ &pixelSize));
+#if 0 // for debugging only
+ writeImage("test.hdr", resultBlob, width, height, (uint32_t)rowPitch, (uint32_t)pixelSize);
+#endif
+ auto buffer = removePadding(resultBlob, width, height, rowPitch, pixelSize);
+ auto actualData = (float*)buffer.getBuffer();
+ SLANG_CHECK(memcmp(actualData, expectedResult, count * sizeof(float)) == 0)
}
+};
- SLANG_UNIT_TEST(RayTracingTestAD3D12)
+struct RayTracingTestA : BaseRayTracingTest
+{
+ void renderFrame()
{
- runTestImpl(rayTracingTestImpl<RayTracingTestA>, unitTestContext, Slang::RenderApiFlag::D3D12);
+ ComPtr<ICommandBuffer> renderCommandBuffer = transientHeap->createCommandBuffer();
+ auto renderEncoder = renderCommandBuffer->encodeRayTracingCommands();
+ IShaderObject* rootObject = nullptr;
+ renderEncoder->bindPipeline(renderPipelineState, &rootObject);
+ auto cursor = ShaderCursor(rootObject);
+ cursor["resultTexture"].setResource(resultTextureUAV);
+ cursor["sceneBVH"].setResource(TLAS);
+ renderEncoder->dispatchRays(0, shaderTable, width, height, 1);
+ renderEncoder->endEncoding();
+ renderCommandBuffer->close();
+ queue->executeCommandBuffer(renderCommandBuffer);
+ queue->waitOnHost();
}
- SLANG_UNIT_TEST(RayTracingTestAVulkan)
+ void run()
{
- runTestImpl(rayTracingTestImpl<RayTracingTestA>, unitTestContext, Slang::RenderApiFlag::Vulkan);
+ createRequiredResources();
+ renderFrame();
+
+ float expectedResult[16] = {1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1};
+ checkTestResults(expectedResult, 16);
}
+};
- SLANG_UNIT_TEST(RayTracingTestBD3D12)
+struct RayTracingTestB : BaseRayTracingTest
+{
+ void renderFrame()
{
- runTestImpl(rayTracingTestImpl<RayTracingTestB>, unitTestContext, Slang::RenderApiFlag::D3D12);
+ ComPtr<ICommandBuffer> renderCommandBuffer = transientHeap->createCommandBuffer();
+ auto renderEncoder = renderCommandBuffer->encodeRayTracingCommands();
+ IShaderObject* rootObject = nullptr;
+ renderEncoder->bindPipeline(renderPipelineState, &rootObject);
+ auto cursor = ShaderCursor(rootObject);
+ cursor["resultTexture"].setResource(resultTextureUAV);
+ cursor["sceneBVH"].setResource(TLAS);
+ renderEncoder->dispatchRays(1, shaderTable, width, height, 1);
+ renderEncoder->endEncoding();
+ renderCommandBuffer->close();
+ queue->executeCommandBuffer(renderCommandBuffer);
+ queue->waitOnHost();
}
- SLANG_UNIT_TEST(RayTracingTestBVulkan)
+ void run()
{
- runTestImpl(rayTracingTestImpl<RayTracingTestB>, unitTestContext, Slang::RenderApiFlag::Vulkan);
+ createRequiredResources();
+ renderFrame();
+
+ float expectedResult[16] = {0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1};
+ checkTestResults(expectedResult, 16);
}
+};
+
+template<typename T>
+void rayTracingTestImpl(IDevice* device, UnitTestContext* context)
+{
+ T test;
+ test.init(device, context);
+ test.run();
+}
+
+SLANG_UNIT_TEST(RayTracingTestAD3D12)
+{
+ runTestImpl(rayTracingTestImpl<RayTracingTestA>, unitTestContext, Slang::RenderApiFlag::D3D12);
+}
+
+SLANG_UNIT_TEST(RayTracingTestAVulkan)
+{
+ runTestImpl(rayTracingTestImpl<RayTracingTestA>, unitTestContext, Slang::RenderApiFlag::Vulkan);
+}
+
+SLANG_UNIT_TEST(RayTracingTestBD3D12)
+{
+ runTestImpl(rayTracingTestImpl<RayTracingTestB>, unitTestContext, Slang::RenderApiFlag::D3D12);
+}
+
+SLANG_UNIT_TEST(RayTracingTestBVulkan)
+{
+ runTestImpl(rayTracingTestImpl<RayTracingTestB>, unitTestContext, Slang::RenderApiFlag::Vulkan);
}
+} // namespace gfx_test
diff --git a/tools/gfx-unit-test/resolve-resource-tests.cpp b/tools/gfx-unit-test/resolve-resource-tests.cpp
index af2bf68e9..ea25b609f 100644
--- a/tools/gfx-unit-test/resolve-resource-tests.cpp
+++ b/tools/gfx-unit-test/resolve-resource-tests.cpp
@@ -1,9 +1,8 @@
-#include "tools/unit-test/slang-unit-test.h"
-
-#include "slang-gfx.h"
#include "gfx-test-util.h"
-#include "tools/gfx-util/shader-cursor.h"
+#include "slang-gfx.h"
#include "source/core/slang-basic.h"
+#include "tools/gfx-util/shader-cursor.h"
+#include "tools/unit-test/slang-unit-test.h"
#if SLANG_WINDOWS_FAMILY
#include <d3d12.h>
@@ -14,320 +13,356 @@ using namespace gfx;
namespace
{
- using namespace gfx_test;
+using namespace gfx_test;
- struct Vertex
- {
- float position[3];
- float color[3];
- };
+struct Vertex
+{
+ float position[3];
+ float color[3];
+};
+
+static const int kVertexCount = 12;
+static const Vertex kVertexData[kVertexCount] = {
+ // Triangle 1
+ {{0, 0, 0.5}, {1, 0, 0}},
+ {{1, 1, 0.5}, {1, 0, 0}},
+ {{-1, 1, 0.5}, {1, 0, 0}},
+
+ // Triangle 2
+ {{-1, 1, 0.5}, {0, 1, 0}},
+ {{0, 0, 0.5}, {0, 1, 0}},
+ {{-1, -1, 0.5}, {0, 1, 0}},
+
+ // Triangle 3
+ {{-1, -1, 0.5}, {0, 0, 1}},
+ {{0, 0, 0.5}, {0, 0, 1}},
+ {{1, -1, 0.5}, {0, 0, 1}},
+
+ // Triangle 4
+ {{1, -1, 0.5}, {0, 0, 0}},
+ {{0, 0, 0.5}, {0, 0, 0}},
+ {{1, 1, 0.5}, {0, 0, 0}},
+};
+
+const int kWidth = 256;
+const int kHeight = 256;
+Format format = Format::R32G32B32A32_FLOAT;
+
+ComPtr<IBufferResource> createVertexBuffer(IDevice* device)
+{
+ IBufferResource::Desc vertexBufferDesc;
+ vertexBufferDesc.type = IResource::Type::Buffer;
+ vertexBufferDesc.sizeInBytes = kVertexCount * sizeof(Vertex);
+ vertexBufferDesc.defaultState = ResourceState::VertexBuffer;
+ vertexBufferDesc.allowedStates = ResourceState::VertexBuffer;
+ ComPtr<IBufferResource> vertexBuffer =
+ device->createBufferResource(vertexBufferDesc, &kVertexData[0]);
+ SLANG_CHECK_ABORT(vertexBuffer != nullptr);
+ return vertexBuffer;
+}
+
+struct BaseResolveResourceTest
+{
+ IDevice* device;
+ UnitTestContext* context;
+
+ ComPtr<ITextureResource> msaaTexture;
+ ComPtr<ITextureResource> dstTexture;
+
+ ComPtr<ITransientResourceHeap> transientHeap;
+ ComPtr<IPipelineState> pipelineState;
+ ComPtr<IRenderPassLayout> renderPass;
+ ComPtr<IFramebuffer> framebuffer;
+
+ ComPtr<IBufferResource> vertexBuffer;
- static const int kVertexCount = 12;
- static const Vertex kVertexData[kVertexCount] =
+ struct TextureInfo
{
- // Triangle 1
- { { 0, 0, 0.5 }, { 1, 0, 0 } },
- { { 1, 1, 0.5 }, { 1, 0, 0 } },
- { { -1, 1, 0.5 }, { 1, 0, 0 } },
-
- // Triangle 2
- { { -1, 1, 0.5 }, { 0, 1, 0 } },
- { { 0, 0, 0.5 }, { 0, 1, 0 } },
- { { -1, -1, 0.5 }, { 0, 1, 0 } },
-
- // Triangle 3
- { { -1, -1, 0.5 }, { 0, 0, 1 } },
- { { 0, 0, 0.5 }, { 0, 0, 1 } },
- { { 1, -1, 0.5 }, { 0, 0, 1 } },
-
- // Triangle 4
- { { 1, -1, 0.5 }, { 0, 0, 0 } },
- { { 0, 0, 0.5 }, { 0, 0, 0 } },
- { { 1, 1, 0.5 }, { 0, 0, 0 } },
+ ITextureResource::Extents extent;
+ int numMipLevels;
+ int arraySize;
+ ITextureResource::SubresourceData const* initData;
};
- const int kWidth = 256;
- const int kHeight = 256;
- Format format = Format::R32G32B32A32_FLOAT;
-
- ComPtr<IBufferResource> createVertexBuffer(IDevice* device)
+ void init(IDevice* device, UnitTestContext* context)
{
- IBufferResource::Desc vertexBufferDesc;
- vertexBufferDesc.type = IResource::Type::Buffer;
- vertexBufferDesc.sizeInBytes = kVertexCount * sizeof(Vertex);
- vertexBufferDesc.defaultState = ResourceState::VertexBuffer;
- vertexBufferDesc.allowedStates = ResourceState::VertexBuffer;
- ComPtr<IBufferResource> vertexBuffer = device->createBufferResource(vertexBufferDesc, &kVertexData[0]);
- SLANG_CHECK_ABORT(vertexBuffer != nullptr);
- return vertexBuffer;
+ this->device = device;
+ this->context = context;
}
- struct BaseResolveResourceTest
+ void createRequiredResources(
+ TextureInfo msaaTextureInfo,
+ TextureInfo dstTextureInfo,
+ Format format)
{
- IDevice* device;
- UnitTestContext* context;
-
- ComPtr<ITextureResource> msaaTexture;
- ComPtr<ITextureResource> dstTexture;
-
- ComPtr<ITransientResourceHeap> transientHeap;
- ComPtr<IPipelineState> pipelineState;
- ComPtr<IRenderPassLayout> renderPass;
- ComPtr<IFramebuffer> framebuffer;
-
- ComPtr<IBufferResource> vertexBuffer;
-
- struct TextureInfo
- {
- ITextureResource::Extents extent;
- int numMipLevels;
- int arraySize;
- ITextureResource::SubresourceData const* initData;
+ VertexStreamDesc vertexStreams[] = {
+ {sizeof(Vertex), InputSlotClass::PerVertex, 0},
};
- void init(IDevice* device, UnitTestContext* context)
- {
- this->device = device;
- this->context = context;
- }
+ InputElementDesc inputElements[] = {
+ // Vertex buffer data
+ {"POSITION", 0, Format::R32G32B32_FLOAT, offsetof(Vertex, position), 0},
+ {"COLOR", 0, Format::R32G32B32_FLOAT, offsetof(Vertex, color), 0},
+ };
- void createRequiredResources(TextureInfo msaaTextureInfo, TextureInfo dstTextureInfo, Format format)
- {
- VertexStreamDesc vertexStreams[] = {
- { sizeof(Vertex), InputSlotClass::PerVertex, 0 },
- };
-
- InputElementDesc inputElements[] = {
- // Vertex buffer data
- { "POSITION", 0, Format::R32G32B32_FLOAT, offsetof(Vertex, position), 0 },
- { "COLOR", 0, Format::R32G32B32_FLOAT, offsetof(Vertex, color), 0 },
- };
-
- ITextureResource::Desc msaaTexDesc = {};
- msaaTexDesc.type = IResource::Type::Texture2D;
- msaaTexDesc.numMipLevels = dstTextureInfo.numMipLevels;
- msaaTexDesc.arraySize = dstTextureInfo.arraySize;
- msaaTexDesc.size = dstTextureInfo.extent;
- msaaTexDesc.defaultState = ResourceState::RenderTarget;
- msaaTexDesc.allowedStates = ResourceStateSet(
- ResourceState::RenderTarget,
- ResourceState::ResolveSource);
- msaaTexDesc.format = format;
- msaaTexDesc.sampleDesc.numSamples = 4;
-
- GFX_CHECK_CALL_ABORT(device->createTextureResource(
- msaaTexDesc,
- msaaTextureInfo.initData,
- msaaTexture.writeRef()));
-
- ITextureResource::Desc dstTexDesc = {};
- dstTexDesc.type = IResource::Type::Texture2D;
- dstTexDesc.numMipLevels = dstTextureInfo.numMipLevels;
- dstTexDesc.arraySize = dstTextureInfo.arraySize;
- dstTexDesc.size = dstTextureInfo.extent;
- dstTexDesc.defaultState = ResourceState::ResolveDestination;
- dstTexDesc.allowedStates = ResourceStateSet(
- ResourceState::ResolveDestination,
- ResourceState::CopySource);
- dstTexDesc.format = format;
-
- GFX_CHECK_CALL_ABORT(device->createTextureResource(
- dstTexDesc,
- dstTextureInfo.initData,
- dstTexture.writeRef()));
-
- IInputLayout::Desc inputLayoutDesc = {};
- inputLayoutDesc.inputElementCount = SLANG_COUNT_OF(inputElements);
- inputLayoutDesc.inputElements = inputElements;
- inputLayoutDesc.vertexStreamCount = SLANG_COUNT_OF(vertexStreams);
- inputLayoutDesc.vertexStreams = vertexStreams;
- auto inputLayout = device->createInputLayout(inputLayoutDesc);
- SLANG_CHECK_ABORT(inputLayout != nullptr);
-
- vertexBuffer = createVertexBuffer(device);
-
- ITransientResourceHeap::Desc transientHeapDesc = {};
- transientHeapDesc.constantBufferSize = 4096;
- GFX_CHECK_CALL_ABORT(
- device->createTransientResourceHeap(transientHeapDesc, transientHeap.writeRef()));
-
- ComPtr<IShaderProgram> shaderProgram;
- slang::ProgramLayout* slangReflection;
- GFX_CHECK_CALL_ABORT(loadGraphicsProgram(device, shaderProgram, "resolve-resource-shader", "vertexMain", "fragmentMain", slangReflection));
-
- IFramebufferLayout::TargetLayout targetLayout;
- targetLayout.format = format;
- targetLayout.sampleCount = 4;
-
- IFramebufferLayout::Desc framebufferLayoutDesc;
- framebufferLayoutDesc.renderTargetCount = 1;
- framebufferLayoutDesc.renderTargets = &targetLayout;
- ComPtr<gfx::IFramebufferLayout> framebufferLayout = device->createFramebufferLayout(framebufferLayoutDesc);
- SLANG_CHECK_ABORT(framebufferLayout != nullptr);
-
- GraphicsPipelineStateDesc pipelineDesc = {};
- pipelineDesc.program = shaderProgram.get();
- pipelineDesc.inputLayout = inputLayout;
- pipelineDesc.framebufferLayout = framebufferLayout;
- pipelineDesc.depthStencil.depthTestEnable = false;
- pipelineDesc.depthStencil.depthWriteEnable = false;
- GFX_CHECK_CALL_ABORT(
- device->createGraphicsPipelineState(pipelineDesc, pipelineState.writeRef()));
-
- IRenderPassLayout::Desc renderPassDesc = {};
- renderPassDesc.framebufferLayout = framebufferLayout;
- renderPassDesc.renderTargetCount = 1;
- IRenderPassLayout::TargetAccessDesc renderTargetAccess = {};
- renderTargetAccess.loadOp = IRenderPassLayout::TargetLoadOp::Clear;
- renderTargetAccess.storeOp = IRenderPassLayout::TargetStoreOp::Store;
- renderTargetAccess.initialState = ResourceState::RenderTarget;
- renderTargetAccess.finalState = ResourceState::ResolveSource;
- renderPassDesc.renderTargetAccess = &renderTargetAccess;
- GFX_CHECK_CALL_ABORT(device->createRenderPassLayout(renderPassDesc, renderPass.writeRef()));
-
- gfx::IResourceView::Desc colorBufferViewDesc;
- memset(&colorBufferViewDesc, 0, sizeof(colorBufferViewDesc));
- colorBufferViewDesc.format = format;
- colorBufferViewDesc.renderTarget.shape = gfx::IResource::Type::Texture2D;
- colorBufferViewDesc.type = gfx::IResourceView::Type::RenderTarget;
- auto rtv = device->createTextureView(msaaTexture, colorBufferViewDesc);
-
- gfx::IFramebuffer::Desc framebufferDesc;
- framebufferDesc.renderTargetCount = 1;
- framebufferDesc.depthStencilView = nullptr;
- framebufferDesc.renderTargetViews = rtv.readRef();
- framebufferDesc.layout = framebufferLayout;
- GFX_CHECK_CALL_ABORT(device->createFramebuffer(framebufferDesc, framebuffer.writeRef()));
- }
+ ITextureResource::Desc msaaTexDesc = {};
+ msaaTexDesc.type = IResource::Type::Texture2D;
+ msaaTexDesc.numMipLevels = dstTextureInfo.numMipLevels;
+ msaaTexDesc.arraySize = dstTextureInfo.arraySize;
+ msaaTexDesc.size = dstTextureInfo.extent;
+ msaaTexDesc.defaultState = ResourceState::RenderTarget;
+ msaaTexDesc.allowedStates =
+ ResourceStateSet(ResourceState::RenderTarget, ResourceState::ResolveSource);
+ msaaTexDesc.format = format;
+ msaaTexDesc.sampleDesc.numSamples = 4;
+
+ GFX_CHECK_CALL_ABORT(device->createTextureResource(
+ msaaTexDesc,
+ msaaTextureInfo.initData,
+ msaaTexture.writeRef()));
+
+ ITextureResource::Desc dstTexDesc = {};
+ dstTexDesc.type = IResource::Type::Texture2D;
+ dstTexDesc.numMipLevels = dstTextureInfo.numMipLevels;
+ dstTexDesc.arraySize = dstTextureInfo.arraySize;
+ dstTexDesc.size = dstTextureInfo.extent;
+ dstTexDesc.defaultState = ResourceState::ResolveDestination;
+ dstTexDesc.allowedStates =
+ ResourceStateSet(ResourceState::ResolveDestination, ResourceState::CopySource);
+ dstTexDesc.format = format;
+
+ GFX_CHECK_CALL_ABORT(device->createTextureResource(
+ dstTexDesc,
+ dstTextureInfo.initData,
+ dstTexture.writeRef()));
+
+ IInputLayout::Desc inputLayoutDesc = {};
+ inputLayoutDesc.inputElementCount = SLANG_COUNT_OF(inputElements);
+ inputLayoutDesc.inputElements = inputElements;
+ inputLayoutDesc.vertexStreamCount = SLANG_COUNT_OF(vertexStreams);
+ inputLayoutDesc.vertexStreams = vertexStreams;
+ auto inputLayout = device->createInputLayout(inputLayoutDesc);
+ SLANG_CHECK_ABORT(inputLayout != nullptr);
+
+ vertexBuffer = createVertexBuffer(device);
+
+ ITransientResourceHeap::Desc transientHeapDesc = {};
+ transientHeapDesc.constantBufferSize = 4096;
+ GFX_CHECK_CALL_ABORT(
+ device->createTransientResourceHeap(transientHeapDesc, transientHeap.writeRef()));
+
+ ComPtr<IShaderProgram> shaderProgram;
+ slang::ProgramLayout* slangReflection;
+ GFX_CHECK_CALL_ABORT(loadGraphicsProgram(
+ device,
+ shaderProgram,
+ "resolve-resource-shader",
+ "vertexMain",
+ "fragmentMain",
+ slangReflection));
+
+ IFramebufferLayout::TargetLayout targetLayout;
+ targetLayout.format = format;
+ targetLayout.sampleCount = 4;
+
+ IFramebufferLayout::Desc framebufferLayoutDesc;
+ framebufferLayoutDesc.renderTargetCount = 1;
+ framebufferLayoutDesc.renderTargets = &targetLayout;
+ ComPtr<gfx::IFramebufferLayout> framebufferLayout =
+ device->createFramebufferLayout(framebufferLayoutDesc);
+ SLANG_CHECK_ABORT(framebufferLayout != nullptr);
+
+ GraphicsPipelineStateDesc pipelineDesc = {};
+ pipelineDesc.program = shaderProgram.get();
+ pipelineDesc.inputLayout = inputLayout;
+ pipelineDesc.framebufferLayout = framebufferLayout;
+ pipelineDesc.depthStencil.depthTestEnable = false;
+ pipelineDesc.depthStencil.depthWriteEnable = false;
+ GFX_CHECK_CALL_ABORT(
+ device->createGraphicsPipelineState(pipelineDesc, pipelineState.writeRef()));
+
+ IRenderPassLayout::Desc renderPassDesc = {};
+ renderPassDesc.framebufferLayout = framebufferLayout;
+ renderPassDesc.renderTargetCount = 1;
+ IRenderPassLayout::TargetAccessDesc renderTargetAccess = {};
+ renderTargetAccess.loadOp = IRenderPassLayout::TargetLoadOp::Clear;
+ renderTargetAccess.storeOp = IRenderPassLayout::TargetStoreOp::Store;
+ renderTargetAccess.initialState = ResourceState::RenderTarget;
+ renderTargetAccess.finalState = ResourceState::ResolveSource;
+ renderPassDesc.renderTargetAccess = &renderTargetAccess;
+ GFX_CHECK_CALL_ABORT(device->createRenderPassLayout(renderPassDesc, renderPass.writeRef()));
+
+ gfx::IResourceView::Desc colorBufferViewDesc;
+ memset(&colorBufferViewDesc, 0, sizeof(colorBufferViewDesc));
+ colorBufferViewDesc.format = format;
+ colorBufferViewDesc.renderTarget.shape = gfx::IResource::Type::Texture2D;
+ colorBufferViewDesc.type = gfx::IResourceView::Type::RenderTarget;
+ auto rtv = device->createTextureView(msaaTexture, colorBufferViewDesc);
+
+ gfx::IFramebuffer::Desc framebufferDesc;
+ framebufferDesc.renderTargetCount = 1;
+ framebufferDesc.depthStencilView = nullptr;
+ framebufferDesc.renderTargetViews = rtv.readRef();
+ framebufferDesc.layout = framebufferLayout;
+ GFX_CHECK_CALL_ABORT(device->createFramebuffer(framebufferDesc, framebuffer.writeRef()));
+ }
- void submitGPUWork(SubresourceRange msaaSubresource, SubresourceRange dstSubresource, ITextureResource::Extents extent)
- {
- 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 renderEncoder = commandBuffer->encodeRenderCommands(renderPass, framebuffer);
- auto rootObject = renderEncoder->bindPipeline(pipelineState);
-
- gfx::Viewport viewport = {};
- viewport.maxZ = 1.0f;
- viewport.extentX = kWidth;
- viewport.extentY = kHeight;
- renderEncoder->setViewportAndScissor(viewport);
-
- renderEncoder->setVertexBuffer(0, vertexBuffer);
- renderEncoder->setPrimitiveTopology(PrimitiveTopology::TriangleList);
- renderEncoder->draw(kVertexCount, 0);
- renderEncoder->endEncoding();
-
- auto resourceEncoder = commandBuffer->encodeResourceCommands();
-
- resourceEncoder->resolveResource(msaaTexture, ResourceState::ResolveSource, msaaSubresource, dstTexture, ResourceState::ResolveDestination, dstSubresource);
- resourceEncoder->textureSubresourceBarrier(dstTexture, dstSubresource, ResourceState::ResolveDestination, ResourceState::CopySource);
- resourceEncoder->endEncoding();
- commandBuffer->close();
- queue->executeCommandBuffer(commandBuffer);
- queue->waitOnHost();
- }
+ void submitGPUWork(
+ SubresourceRange msaaSubresource,
+ SubresourceRange dstSubresource,
+ ITextureResource::Extents extent)
+ {
+ 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 renderEncoder = commandBuffer->encodeRenderCommands(renderPass, framebuffer);
+ auto rootObject = renderEncoder->bindPipeline(pipelineState);
+
+ gfx::Viewport viewport = {};
+ viewport.maxZ = 1.0f;
+ viewport.extentX = kWidth;
+ viewport.extentY = kHeight;
+ renderEncoder->setViewportAndScissor(viewport);
+
+ renderEncoder->setVertexBuffer(0, vertexBuffer);
+ renderEncoder->setPrimitiveTopology(PrimitiveTopology::TriangleList);
+ renderEncoder->draw(kVertexCount, 0);
+ renderEncoder->endEncoding();
+
+ auto resourceEncoder = commandBuffer->encodeResourceCommands();
+
+ resourceEncoder->resolveResource(
+ msaaTexture,
+ ResourceState::ResolveSource,
+ msaaSubresource,
+ dstTexture,
+ ResourceState::ResolveDestination,
+ dstSubresource);
+ resourceEncoder->textureSubresourceBarrier(
+ dstTexture,
+ dstSubresource,
+ ResourceState::ResolveDestination,
+ ResourceState::CopySource);
+ resourceEncoder->endEncoding();
+ commandBuffer->close();
+ queue->executeCommandBuffer(commandBuffer);
+ queue->waitOnHost();
+ }
- void checkTestResults(int pixelCount, int channelCount, const int* testXCoords, const int* testYCoords, float* testResults)
+ void checkTestResults(
+ int pixelCount,
+ int channelCount,
+ const int* testXCoords,
+ const int* testYCoords,
+ float* testResults)
+ {
+ // Read texture values back from four specific pixels located within the triangles
+ // and compare against expected values (because testing every single pixel will be too long
+ // and tedious and requires maintaining reference images).
+ ComPtr<ISlangBlob> resultBlob;
+ size_t rowPitch = 0;
+ size_t pixelSize = 0;
+ GFX_CHECK_CALL_ABORT(device->readTextureResource(
+ dstTexture,
+ ResourceState::CopySource,
+ resultBlob.writeRef(),
+ &rowPitch,
+ &pixelSize));
+ auto result = (float*)resultBlob->getBufferPointer();
+
+ int cursor = 0;
+ for (int i = 0; i < pixelCount; ++i)
{
- // Read texture values back from four specific pixels located within the triangles
- // and compare against expected values (because testing every single pixel will be too long and tedious
- // and requires maintaining reference images).
- ComPtr<ISlangBlob> resultBlob;
- size_t rowPitch = 0;
- size_t pixelSize = 0;
- GFX_CHECK_CALL_ABORT(device->readTextureResource(
- dstTexture, ResourceState::CopySource, resultBlob.writeRef(), &rowPitch, &pixelSize));
- auto result = (float*)resultBlob->getBufferPointer();
-
- int cursor = 0;
- for (int i = 0; i < pixelCount; ++i)
+ auto x = testXCoords[i];
+ auto y = testYCoords[i];
+ auto pixelPtr = result + x * channelCount + y * rowPitch / sizeof(float);
+ for (int j = 0; j < channelCount; ++j)
{
- auto x = testXCoords[i];
- auto y = testYCoords[i];
- auto pixelPtr = result + x * channelCount + y * rowPitch / sizeof(float);
- for (int j = 0; j < channelCount; ++j)
- {
- testResults[cursor] = pixelPtr[j];
- cursor++;
- }
+ testResults[cursor] = pixelPtr[j];
+ cursor++;
}
-
- float expectedResult[] = { 0.5f, 0.5f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.5f, 0.0f, 0.0f, 1.0f,
- 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f,
- 0.0f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.5f, 1.0f };
- SLANG_CHECK(memcmp(testResults, expectedResult, 128) == 0);
}
- };
- // TODO: Add more tests?
+ float expectedResult[] = {0.5f, 0.5f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.5f, 0.0f, 0.0f,
+ 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.5f,
+ 0.5f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.5f, 1.0f};
+ SLANG_CHECK(memcmp(testResults, expectedResult, 128) == 0);
+ }
+};
- struct ResolveResourceSimple : BaseResolveResourceTest
- {
- void run()
- {
- ITextureResource::Extents extent = {};
- extent.width = kWidth;
- extent.height = kHeight;
- extent.depth = 1;
-
- TextureInfo msaaTextureInfo = { extent, 1, 1, nullptr };
- TextureInfo dstTextureInfo = { extent, 1, 1, nullptr };
-
- createRequiredResources(msaaTextureInfo, dstTextureInfo, format);
-
- SubresourceRange msaaSubresource = {};
- msaaSubresource.aspectMask = TextureAspect::Color;
- msaaSubresource.mipLevel = 0;
- msaaSubresource.mipLevelCount = 1;
- msaaSubresource.baseArrayLayer = 0;
- msaaSubresource.layerCount = 1;
-
- SubresourceRange dstSubresource = {};
- dstSubresource.aspectMask = TextureAspect::Color;
- dstSubresource.mipLevel = 0;
- dstSubresource.mipLevelCount = 1;
- dstSubresource.baseArrayLayer = 0;
- dstSubresource.layerCount = 1;
-
- submitGPUWork(msaaSubresource, dstSubresource, extent);
-
- const int kPixelCount = 8;
- const int kChannelCount = 4;
- int testXCoords[kPixelCount] = { 64, 127, 191, 64, 191, 64, 127, 191 };
- int testYCoords[kPixelCount] = { 64, 64, 64, 127, 127, 191, 191, 191 };
- float testResults[kPixelCount * kChannelCount];
-
- checkTestResults(kPixelCount, kChannelCount, testXCoords, testYCoords, testResults);
- }
- };
+// TODO: Add more tests?
- template<typename T>
- void resolveResourceTestImpl(IDevice* device, UnitTestContext* context)
+struct ResolveResourceSimple : BaseResolveResourceTest
+{
+ void run()
{
- T test;
- test.init(device, context);
- test.run();
+ ITextureResource::Extents extent = {};
+ extent.width = kWidth;
+ extent.height = kHeight;
+ extent.depth = 1;
+
+ TextureInfo msaaTextureInfo = {extent, 1, 1, nullptr};
+ TextureInfo dstTextureInfo = {extent, 1, 1, nullptr};
+
+ createRequiredResources(msaaTextureInfo, dstTextureInfo, format);
+
+ SubresourceRange msaaSubresource = {};
+ msaaSubresource.aspectMask = TextureAspect::Color;
+ msaaSubresource.mipLevel = 0;
+ msaaSubresource.mipLevelCount = 1;
+ msaaSubresource.baseArrayLayer = 0;
+ msaaSubresource.layerCount = 1;
+
+ SubresourceRange dstSubresource = {};
+ dstSubresource.aspectMask = TextureAspect::Color;
+ dstSubresource.mipLevel = 0;
+ dstSubresource.mipLevelCount = 1;
+ dstSubresource.baseArrayLayer = 0;
+ dstSubresource.layerCount = 1;
+
+ submitGPUWork(msaaSubresource, dstSubresource, extent);
+
+ const int kPixelCount = 8;
+ const int kChannelCount = 4;
+ int testXCoords[kPixelCount] = {64, 127, 191, 64, 191, 64, 127, 191};
+ int testYCoords[kPixelCount] = {64, 64, 64, 127, 127, 191, 191, 191};
+ float testResults[kPixelCount * kChannelCount];
+
+ checkTestResults(kPixelCount, kChannelCount, testXCoords, testYCoords, testResults);
}
+};
+
+template<typename T>
+void resolveResourceTestImpl(IDevice* device, UnitTestContext* context)
+{
+ T test;
+ test.init(device, context);
+ test.run();
}
+} // namespace
namespace gfx_test
{
- SLANG_UNIT_TEST(resolveResourceSimpleD3D12)
- {
- runTestImpl(resolveResourceTestImpl<ResolveResourceSimple>, unitTestContext, Slang::RenderApiFlag::D3D12);
- }
+SLANG_UNIT_TEST(resolveResourceSimpleD3D12)
+{
+ runTestImpl(
+ resolveResourceTestImpl<ResolveResourceSimple>,
+ unitTestContext,
+ Slang::RenderApiFlag::D3D12);
+}
- SLANG_UNIT_TEST(resolveResourceSimpleVulkan)
- {
- runTestImpl(resolveResourceTestImpl<ResolveResourceSimple>, unitTestContext, Slang::RenderApiFlag::Vulkan);
- }
+SLANG_UNIT_TEST(resolveResourceSimpleVulkan)
+{
+ runTestImpl(
+ resolveResourceTestImpl<ResolveResourceSimple>,
+ unitTestContext,
+ Slang::RenderApiFlag::Vulkan);
}
+} // namespace gfx_test
diff --git a/tools/gfx-unit-test/root-mutable-shader-object.cpp b/tools/gfx-unit-test/root-mutable-shader-object.cpp
index 1d489786e..fce4cc0da 100644
--- a/tools/gfx-unit-test/root-mutable-shader-object.cpp
+++ b/tools/gfx-unit-test/root-mutable-shader-object.cpp
@@ -1,119 +1,123 @@
-#include "tools/unit-test/slang-unit-test.h"
-
-#include "slang-gfx.h"
#include "gfx-test-util.h"
-#include "tools/gfx-util/shader-cursor.h"
+#include "slang-gfx.h"
#include "source/core/slang-basic.h"
+#include "tools/gfx-util/shader-cursor.h"
+#include "tools/unit-test/slang-unit-test.h"
using namespace gfx;
namespace gfx_test
{
- void mutableRootShaderObjectTestImpl(IDevice* device, UnitTestContext* context)
+void mutableRootShaderObjectTestImpl(IDevice* device, UnitTestContext* context)
+{
+ Slang::ComPtr<ITransientResourceHeap> transientHeap;
+ ITransientResourceHeap::Desc transientHeapDesc = {};
+ transientHeapDesc.constantBufferSize = 4096;
+ GFX_CHECK_CALL_ABORT(
+ device->createTransientResourceHeap(transientHeapDesc, transientHeap.writeRef()));
+
+ ComPtr<IShaderProgram> shaderProgram;
+ slang::ProgramLayout* slangReflection;
+ GFX_CHECK_CALL_ABORT(loadComputeProgram(
+ device,
+ shaderProgram,
+ "mutable-shader-object",
+ "computeMain",
+ slangReflection));
+
+ ComputePipelineStateDesc pipelineDesc = {};
+ pipelineDesc.program = shaderProgram.get();
+ ComPtr<gfx::IPipelineState> pipelineState;
+ GFX_CHECK_CALL_ABORT(
+ device->createComputePipelineState(pipelineDesc, pipelineState.writeRef()));
+
+ float initialData[] = {0.0f, 1.0f, 2.0f, 3.0f};
+ const int numberCount = SLANG_COUNT_OF(initialData);
+ IBufferResource::Desc bufferDesc = {};
+ bufferDesc.sizeInBytes = sizeof(initialData);
+ bufferDesc.format = gfx::Format::Unknown;
+ bufferDesc.elementSize = sizeof(float);
+ bufferDesc.allowedStates = ResourceStateSet(
+ ResourceState::ShaderResource,
+ ResourceState::UnorderedAccess,
+ ResourceState::CopyDestination,
+ ResourceState::CopySource);
+ bufferDesc.defaultState = ResourceState::UnorderedAccess;
+ bufferDesc.memoryType = MemoryType::DeviceLocal;
+
+ ComPtr<IBufferResource> numbersBuffer;
+ GFX_CHECK_CALL_ABORT(
+ device->createBufferResource(bufferDesc, (void*)initialData, numbersBuffer.writeRef()));
+
+ ComPtr<IResourceView> bufferView;
+ IResourceView::Desc viewDesc = {};
+ viewDesc.type = IResourceView::Type::UnorderedAccess;
+ viewDesc.format = Format::Unknown;
+ GFX_CHECK_CALL_ABORT(
+ device->createBufferView(numbersBuffer, nullptr, viewDesc, bufferView.writeRef()));
+
+ ComPtr<IShaderObject> rootObject;
+ device->createMutableRootShaderObject(shaderProgram, rootObject.writeRef());
+ auto entryPointCursor = ShaderCursor(rootObject->getEntryPoint(0));
+ entryPointCursor.getPath("buffer").setResource(bufferView);
+
+ slang::TypeReflection* addTransformerType = slangReflection->findTypeByName("AddTransformer");
+ ComPtr<IShaderObject> transformer;
+ GFX_CHECK_CALL_ABORT(device->createMutableShaderObject(
+ addTransformerType,
+ ShaderObjectContainerType::None,
+ transformer.writeRef()));
+ entryPointCursor.getPath("transformer").setObject(transformer);
+
+ // Set the `c` field of the `AddTransformer`.
+ float c = 1.0f;
+ ShaderCursor(transformer).getPath("c").setData(&c, sizeof(float));
+
{
- Slang::ComPtr<ITransientResourceHeap> transientHeap;
- ITransientResourceHeap::Desc transientHeapDesc = {};
- transientHeapDesc.constantBufferSize = 4096;
- GFX_CHECK_CALL_ABORT(
- device->createTransientResourceHeap(transientHeapDesc, transientHeap.writeRef()));
-
- ComPtr<IShaderProgram> shaderProgram;
- slang::ProgramLayout* slangReflection;
- GFX_CHECK_CALL_ABORT(loadComputeProgram(device, shaderProgram, "mutable-shader-object", "computeMain", slangReflection));
-
- ComputePipelineStateDesc pipelineDesc = {};
- pipelineDesc.program = shaderProgram.get();
- ComPtr<gfx::IPipelineState> pipelineState;
- GFX_CHECK_CALL_ABORT(
- device->createComputePipelineState(pipelineDesc, pipelineState.writeRef()));
-
- float initialData[] = { 0.0f, 1.0f, 2.0f, 3.0f };
- const int numberCount = SLANG_COUNT_OF(initialData);
- IBufferResource::Desc bufferDesc = {};
- bufferDesc.sizeInBytes = sizeof(initialData);
- bufferDesc.format = gfx::Format::Unknown;
- bufferDesc.elementSize = sizeof(float);
- bufferDesc.allowedStates = ResourceStateSet(
- ResourceState::ShaderResource,
+ ICommandQueue::Desc queueDesc = {ICommandQueue::QueueType::Graphics};
+ auto queue = device->createCommandQueue(queueDesc);
+
+ auto commandBuffer = transientHeap->createCommandBuffer();
+ {
+ auto encoder = commandBuffer->encodeComputeCommands();
+ encoder->bindPipelineWithRootObject(pipelineState, rootObject);
+ encoder->dispatchCompute(1, 1, 1);
+ encoder->endEncoding();
+ }
+
+ auto barrierEncoder = commandBuffer->encodeResourceCommands();
+ barrierEncoder->bufferBarrier(
+ 1,
+ numbersBuffer.readRef(),
ResourceState::UnorderedAccess,
- ResourceState::CopyDestination,
- ResourceState::CopySource);
- bufferDesc.defaultState = ResourceState::UnorderedAccess;
- bufferDesc.memoryType = MemoryType::DeviceLocal;
-
- ComPtr<IBufferResource> numbersBuffer;
- GFX_CHECK_CALL_ABORT(device->createBufferResource(
- bufferDesc,
- (void*)initialData,
- numbersBuffer.writeRef()));
-
- ComPtr<IResourceView> bufferView;
- IResourceView::Desc viewDesc = {};
- viewDesc.type = IResourceView::Type::UnorderedAccess;
- viewDesc.format = Format::Unknown;
- GFX_CHECK_CALL_ABORT(
- device->createBufferView(numbersBuffer, nullptr, viewDesc, bufferView.writeRef()));
-
- ComPtr<IShaderObject> rootObject;
- device->createMutableRootShaderObject(shaderProgram, rootObject.writeRef());
- auto entryPointCursor = ShaderCursor(rootObject->getEntryPoint(0));
- entryPointCursor.getPath("buffer").setResource(bufferView);
-
- slang::TypeReflection* addTransformerType =
- slangReflection->findTypeByName("AddTransformer");
- ComPtr<IShaderObject> transformer;
- GFX_CHECK_CALL_ABORT(device->createMutableShaderObject(
- addTransformerType, ShaderObjectContainerType::None, transformer.writeRef()));
- entryPointCursor.getPath("transformer").setObject(transformer);
-
- // Set the `c` field of the `AddTransformer`.
- float c = 1.0f;
- ShaderCursor(transformer).getPath("c").setData(&c, sizeof(float));
+ ResourceState::UnorderedAccess);
+ barrierEncoder->endEncoding();
+ // Mutate `transformer` object and run again.
+ c = 2.0f;
+ ShaderCursor(transformer).getPath("c").setData(&c, sizeof(float));
{
- ICommandQueue::Desc queueDesc = { ICommandQueue::QueueType::Graphics };
- auto queue = device->createCommandQueue(queueDesc);
-
- auto commandBuffer = transientHeap->createCommandBuffer();
- {
- auto encoder = commandBuffer->encodeComputeCommands();
- encoder->bindPipelineWithRootObject(pipelineState, rootObject);
- encoder->dispatchCompute(1, 1, 1);
- encoder->endEncoding();
- }
-
- auto barrierEncoder = commandBuffer->encodeResourceCommands();
- barrierEncoder->bufferBarrier(1, numbersBuffer.readRef(), ResourceState::UnorderedAccess, ResourceState::UnorderedAccess);
- barrierEncoder->endEncoding();
-
- // Mutate `transformer` object and run again.
- c = 2.0f;
- ShaderCursor(transformer).getPath("c").setData(&c, sizeof(float));
- {
- auto encoder = commandBuffer->encodeComputeCommands();
- encoder->bindPipelineWithRootObject(pipelineState, rootObject);
- encoder->dispatchCompute(1, 1, 1);
- encoder->endEncoding();
- }
-
- commandBuffer->close();
- queue->executeCommandBuffer(commandBuffer);
- queue->waitOnHost();
+ auto encoder = commandBuffer->encodeComputeCommands();
+ encoder->bindPipelineWithRootObject(pipelineState, rootObject);
+ encoder->dispatchCompute(1, 1, 1);
+ encoder->endEncoding();
}
- compareComputeResult(
- device,
- numbersBuffer,
- Slang::makeArray<float>(3.0f, 4.0f, 5.0f, 6.0f));
+ commandBuffer->close();
+ queue->executeCommandBuffer(commandBuffer);
+ queue->waitOnHost();
}
- SLANG_UNIT_TEST(mutableRootShaderObjectD3D12)
- {
- runTestImpl(mutableRootShaderObjectTestImpl, unitTestContext, Slang::RenderApiFlag::D3D12);
- }
+ compareComputeResult(device, numbersBuffer, Slang::makeArray<float>(3.0f, 4.0f, 5.0f, 6.0f));
+}
- /*SLANG_UNIT_TEST(mutableRootShaderObjectVulkan)
- {
- runTestImpl(mutableRootShaderObjectTestImpl, unitTestContext, Slang::RenderApiFlag::Vulkan);
- }*/
+SLANG_UNIT_TEST(mutableRootShaderObjectD3D12)
+{
+ runTestImpl(mutableRootShaderObjectTestImpl, unitTestContext, Slang::RenderApiFlag::D3D12);
}
+
+/*SLANG_UNIT_TEST(mutableRootShaderObjectVulkan)
+{
+ runTestImpl(mutableRootShaderObjectTestImpl, unitTestContext, Slang::RenderApiFlag::Vulkan);
+}*/
+} // namespace gfx_test
diff --git a/tools/gfx-unit-test/root-shader-parameter.cpp b/tools/gfx-unit-test/root-shader-parameter.cpp
index 1a7be91c4..f933ec48a 100644
--- a/tools/gfx-unit-test/root-shader-parameter.cpp
+++ b/tools/gfx-unit-test/root-shader-parameter.cpp
@@ -1,139 +1,151 @@
-#include "tools/unit-test/slang-unit-test.h"
-
-#include "slang-gfx.h"
#include "gfx-test-util.h"
-#include "tools/gfx-util/shader-cursor.h"
+#include "slang-gfx.h"
#include "source/core/slang-basic.h"
+#include "tools/gfx-util/shader-cursor.h"
+#include "tools/unit-test/slang-unit-test.h"
using namespace gfx;
namespace gfx_test
{
- static ComPtr<IBufferResource> createBuffer(IDevice* device, uint32_t content)
+static ComPtr<IBufferResource> createBuffer(IDevice* device, uint32_t content)
+{
+ ComPtr<IBufferResource> buffer;
+ IBufferResource::Desc bufferDesc = {};
+ bufferDesc.sizeInBytes = sizeof(uint32_t);
+ bufferDesc.format = gfx::Format::Unknown;
+ bufferDesc.elementSize = sizeof(float);
+ bufferDesc.allowedStates = ResourceStateSet(
+ ResourceState::ShaderResource,
+ ResourceState::UnorderedAccess,
+ ResourceState::CopyDestination,
+ ResourceState::CopySource);
+ bufferDesc.defaultState = ResourceState::UnorderedAccess;
+ bufferDesc.memoryType = MemoryType::DeviceLocal;
+
+ ComPtr<IBufferResource> numbersBuffer;
+ GFX_CHECK_CALL_ABORT(
+ device->createBufferResource(bufferDesc, (void*)&content, buffer.writeRef()));
+
+ return buffer;
+}
+void rootShaderParameterTestImpl(IDevice* device, UnitTestContext* context)
+{
+ Slang::ComPtr<ITransientResourceHeap> transientHeap;
+ ITransientResourceHeap::Desc transientHeapDesc = {};
+ transientHeapDesc.constantBufferSize = 4096;
+ GFX_CHECK_CALL_ABORT(
+ device->createTransientResourceHeap(transientHeapDesc, transientHeap.writeRef()));
+
+ ComPtr<IShaderProgram> shaderProgram;
+ slang::ProgramLayout* slangReflection;
+ GFX_CHECK_CALL_ABORT(loadComputeProgram(
+ device,
+ shaderProgram,
+ "root-shader-parameter",
+ "computeMain",
+ slangReflection));
+
+ ComputePipelineStateDesc pipelineDesc = {};
+ pipelineDesc.program = shaderProgram.get();
+ ComPtr<gfx::IPipelineState> pipelineState;
+ GFX_CHECK_CALL_ABORT(
+ device->createComputePipelineState(pipelineDesc, pipelineState.writeRef()));
+
+ Slang::List<ComPtr<IBufferResource>> buffers;
+ Slang::List<ComPtr<IResourceView>> srvs, uavs;
+
+ for (uint32_t i = 0; i < 9; i++)
{
- ComPtr<IBufferResource> buffer;
- IBufferResource::Desc bufferDesc = {};
- bufferDesc.sizeInBytes = sizeof(uint32_t);
- bufferDesc.format = gfx::Format::Unknown;
- bufferDesc.elementSize = sizeof(float);
- bufferDesc.allowedStates = ResourceStateSet(
- ResourceState::ShaderResource,
- ResourceState::UnorderedAccess,
- ResourceState::CopyDestination,
- ResourceState::CopySource);
- bufferDesc.defaultState = ResourceState::UnorderedAccess;
- bufferDesc.memoryType = MemoryType::DeviceLocal;
-
- ComPtr<IBufferResource> numbersBuffer;
- GFX_CHECK_CALL_ABORT(
- device->createBufferResource(bufferDesc, (void*)&content, buffer.writeRef()));
+ buffers.add(createBuffer(device, i == 0 ? 10 : i));
- return buffer;
- }
- void rootShaderParameterTestImpl(IDevice* device, UnitTestContext* context)
- {
- Slang::ComPtr<ITransientResourceHeap> transientHeap;
- ITransientResourceHeap::Desc transientHeapDesc = {};
- transientHeapDesc.constantBufferSize = 4096;
+ ComPtr<IResourceView> bufferView;
+ IResourceView::Desc viewDesc = {};
+ viewDesc.type = IResourceView::Type::UnorderedAccess;
+ viewDesc.format = Format::Unknown;
GFX_CHECK_CALL_ABORT(
- device->createTransientResourceHeap(transientHeapDesc, transientHeap.writeRef()));
-
- ComPtr<IShaderProgram> shaderProgram;
- slang::ProgramLayout* slangReflection;
- GFX_CHECK_CALL_ABORT(loadComputeProgram(device, shaderProgram, "root-shader-parameter", "computeMain", slangReflection));
+ device->createBufferView(buffers[i], nullptr, viewDesc, bufferView.writeRef()));
+ uavs.add(bufferView);
- ComputePipelineStateDesc pipelineDesc = {};
- pipelineDesc.program = shaderProgram.get();
- ComPtr<gfx::IPipelineState> pipelineState;
+ viewDesc.type = IResourceView::Type::ShaderResource;
+ viewDesc.format = Format::Unknown;
GFX_CHECK_CALL_ABORT(
- device->createComputePipelineState(pipelineDesc, pipelineState.writeRef()));
-
- Slang::List<ComPtr<IBufferResource>> buffers;
- Slang::List<ComPtr<IResourceView>> srvs, uavs;
-
- for (uint32_t i = 0; i < 9; i++)
- {
- buffers.add(createBuffer(device, i == 0 ? 10 : i));
-
- ComPtr<IResourceView> bufferView;
- IResourceView::Desc viewDesc = {};
- viewDesc.type = IResourceView::Type::UnorderedAccess;
- viewDesc.format = Format::Unknown;
- GFX_CHECK_CALL_ABORT(
- device->createBufferView(buffers[i], nullptr, viewDesc, bufferView.writeRef()));
- uavs.add(bufferView);
-
- viewDesc.type = IResourceView::Type::ShaderResource;
- viewDesc.format = Format::Unknown;
- GFX_CHECK_CALL_ABORT(
- device->createBufferView(buffers[i], nullptr, viewDesc, bufferView.writeRef()));
- srvs.add(bufferView);
- }
+ device->createBufferView(buffers[i], nullptr, viewDesc, bufferView.writeRef()));
+ srvs.add(bufferView);
+ }
- ComPtr<IShaderObject> rootObject;
- device->createMutableRootShaderObject(shaderProgram, rootObject.writeRef());
+ ComPtr<IShaderObject> rootObject;
+ device->createMutableRootShaderObject(shaderProgram, rootObject.writeRef());
+
+ ComPtr<IShaderObject> g, s1, s2;
+ device->createMutableShaderObject(
+ slangReflection->findTypeByName("S0"),
+ ShaderObjectContainerType::None,
+ g.writeRef());
+ device->createMutableShaderObject(
+ slangReflection->findTypeByName("S1"),
+ ShaderObjectContainerType::None,
+ s1.writeRef());
+ device->createMutableShaderObject(
+ slangReflection->findTypeByName("S1"),
+ ShaderObjectContainerType::None,
+ s2.writeRef());
- ComPtr<IShaderObject> g, s1, s2;
- device->createMutableShaderObject(
- slangReflection->findTypeByName("S0"), ShaderObjectContainerType::None, g.writeRef());
- device->createMutableShaderObject(
- slangReflection->findTypeByName("S1"), ShaderObjectContainerType::None, s1.writeRef());
- device->createMutableShaderObject(
- slangReflection->findTypeByName("S1"), ShaderObjectContainerType::None, s2.writeRef());
+ {
+ auto cursor = ShaderCursor(s1);
+ cursor["c0"].setResource(srvs[2]);
+ cursor["c1"].setResource(uavs[3]);
+ cursor["c2"].setResource(srvs[4]);
+ }
+ {
+ auto cursor = ShaderCursor(s2);
+ cursor["c0"].setResource(srvs[5]);
+ cursor["c1"].setResource(uavs[6]);
+ cursor["c2"].setResource(srvs[7]);
+ }
+ {
+ auto cursor = ShaderCursor(g);
+ cursor["b0"].setResource(srvs[0]);
+ cursor["b1"].setResource(srvs[1]);
+ cursor["s1"].setObject(s1);
+ cursor["s2"].setObject(s2);
+ }
+ {
+ auto cursor = ShaderCursor(rootObject);
+ cursor["g"].setObject(g);
+ cursor["buffer"].setResource(uavs[8]);
+ }
- {
- auto cursor = ShaderCursor(s1);
- cursor["c0"].setResource(srvs[2]);
- cursor["c1"].setResource(uavs[3]);
- cursor["c2"].setResource(srvs[4]);
- }
- {
- auto cursor = ShaderCursor(s2);
- cursor["c0"].setResource(srvs[5]);
- cursor["c1"].setResource(uavs[6]);
- cursor["c2"].setResource(srvs[7]);
- }
- {
- auto cursor = ShaderCursor(g);
- cursor["b0"].setResource(srvs[0]);
- cursor["b1"].setResource(srvs[1]);
- cursor["s1"].setObject(s1);
- cursor["s2"].setObject(s2);
- }
- {
- auto cursor = ShaderCursor(rootObject);
- cursor["g"].setObject(g);
- cursor["buffer"].setResource(uavs[8]);
- }
+ {
+ ICommandQueue::Desc queueDesc = {ICommandQueue::QueueType::Graphics};
+ auto queue = device->createCommandQueue(queueDesc);
+ auto commandBuffer = transientHeap->createCommandBuffer();
{
- ICommandQueue::Desc queueDesc = { ICommandQueue::QueueType::Graphics };
- auto queue = device->createCommandQueue(queueDesc);
-
- auto commandBuffer = transientHeap->createCommandBuffer();
- {
- auto encoder = commandBuffer->encodeComputeCommands();
- encoder->bindPipelineWithRootObject(pipelineState, rootObject);
- encoder->dispatchCompute(1, 1, 1);
- encoder->endEncoding();
- }
-
- commandBuffer->close();
- queue->executeCommandBuffer(commandBuffer);
- queue->waitOnHost();
+ auto encoder = commandBuffer->encodeComputeCommands();
+ encoder->bindPipelineWithRootObject(pipelineState, rootObject);
+ encoder->dispatchCompute(1, 1, 1);
+ encoder->endEncoding();
}
- compareComputeResult(
- device, buffers[8], Slang::makeArray<uint32_t>(10 - 1 + 2 - 3 + 4 + 5 - 6 + 7));
+ commandBuffer->close();
+ queue->executeCommandBuffer(commandBuffer);
+ queue->waitOnHost();
}
- SLANG_UNIT_TEST(rootShaderParameterD3D12)
- {
- runTestImpl(rootShaderParameterTestImpl, unitTestContext, Slang::RenderApiFlag::D3D12);
- }
+ compareComputeResult(
+ device,
+ buffers[8],
+ Slang::makeArray<uint32_t>(10 - 1 + 2 - 3 + 4 + 5 - 6 + 7));
+}
- SLANG_UNIT_TEST(rootShaderParameterVulkan)
- {
- runTestImpl(rootShaderParameterTestImpl, unitTestContext, Slang::RenderApiFlag::Vulkan);
- }
+SLANG_UNIT_TEST(rootShaderParameterD3D12)
+{
+ runTestImpl(rootShaderParameterTestImpl, unitTestContext, Slang::RenderApiFlag::D3D12);
+}
+
+SLANG_UNIT_TEST(rootShaderParameterVulkan)
+{
+ runTestImpl(rootShaderParameterTestImpl, unitTestContext, Slang::RenderApiFlag::Vulkan);
}
+} // namespace gfx_test
diff --git a/tools/gfx-unit-test/sampler-array.cpp b/tools/gfx-unit-test/sampler-array.cpp
index 945c31b07..720aa0a2c 100644
--- a/tools/gfx-unit-test/sampler-array.cpp
+++ b/tools/gfx-unit-test/sampler-array.cpp
@@ -1,159 +1,160 @@
-#include "tools/unit-test/slang-unit-test.h"
-
-#include "slang-gfx.h"
#include "gfx-test-util.h"
-#include "tools/gfx-util/shader-cursor.h"
+#include "slang-gfx.h"
#include "source/core/slang-basic.h"
+#include "tools/gfx-util/shader-cursor.h"
+#include "tools/unit-test/slang-unit-test.h"
using namespace gfx;
namespace gfx_test
{
- static ComPtr<IBufferResource> createBuffer(IDevice* device, uint32_t content)
- {
- ComPtr<IBufferResource> buffer;
- IBufferResource::Desc bufferDesc = {};
- bufferDesc.sizeInBytes = sizeof(uint32_t);
- bufferDesc.format = gfx::Format::Unknown;
- bufferDesc.elementSize = sizeof(float);
- bufferDesc.allowedStates = ResourceStateSet(
- ResourceState::ShaderResource,
- ResourceState::UnorderedAccess,
- ResourceState::CopyDestination,
- ResourceState::CopySource);
- bufferDesc.defaultState = ResourceState::UnorderedAccess;
- bufferDesc.memoryType = MemoryType::DeviceLocal;
-
- ComPtr<IBufferResource> numbersBuffer;
- GFX_CHECK_CALL_ABORT(
- device->createBufferResource(bufferDesc, (void*)&content, buffer.writeRef()));
+static ComPtr<IBufferResource> createBuffer(IDevice* device, uint32_t content)
+{
+ ComPtr<IBufferResource> buffer;
+ IBufferResource::Desc bufferDesc = {};
+ bufferDesc.sizeInBytes = sizeof(uint32_t);
+ bufferDesc.format = gfx::Format::Unknown;
+ bufferDesc.elementSize = sizeof(float);
+ bufferDesc.allowedStates = ResourceStateSet(
+ ResourceState::ShaderResource,
+ ResourceState::UnorderedAccess,
+ ResourceState::CopyDestination,
+ ResourceState::CopySource);
+ bufferDesc.defaultState = ResourceState::UnorderedAccess;
+ bufferDesc.memoryType = MemoryType::DeviceLocal;
+
+ ComPtr<IBufferResource> numbersBuffer;
+ GFX_CHECK_CALL_ABORT(
+ device->createBufferResource(bufferDesc, (void*)&content, buffer.writeRef()));
+
+ return buffer;
+}
+void samplerArrayTestImpl(IDevice* device, UnitTestContext* context)
+{
+ Slang::ComPtr<ITransientResourceHeap> transientHeap;
+ ITransientResourceHeap::Desc transientHeapDesc = {};
+ transientHeapDesc.constantBufferSize = 4096;
+ GFX_CHECK_CALL_ABORT(
+ device->createTransientResourceHeap(transientHeapDesc, transientHeap.writeRef()));
+
+ ComPtr<IShaderProgram> shaderProgram;
+ slang::ProgramLayout* slangReflection;
+ GFX_CHECK_CALL_ABORT(
+ loadComputeProgram(device, shaderProgram, "sampler-array", "computeMain", slangReflection));
+
+ ComputePipelineStateDesc pipelineDesc = {};
+ pipelineDesc.program = shaderProgram.get();
+ ComPtr<gfx::IPipelineState> pipelineState;
+ GFX_CHECK_CALL_ABORT(
+ device->createComputePipelineState(pipelineDesc, pipelineState.writeRef()));
+
+ Slang::List<ComPtr<ISamplerState>> samplers;
+ Slang::List<ComPtr<IResourceView>> srvs;
+ ComPtr<IResourceView> uav;
+ ComPtr<ITextureResource> texture;
+ ComPtr<IBufferResource> buffer = createBuffer(device, 0);
- return buffer;
+ {
+ IResourceView::Desc viewDesc = {};
+ viewDesc.type = IResourceView::Type::UnorderedAccess;
+ viewDesc.format = Format::Unknown;
+ GFX_CHECK_CALL_ABORT(device->createBufferView(buffer, nullptr, viewDesc, uav.writeRef()));
}
- void samplerArrayTestImpl(IDevice* device, UnitTestContext* context)
{
- Slang::ComPtr<ITransientResourceHeap> transientHeap;
- ITransientResourceHeap::Desc transientHeapDesc = {};
- transientHeapDesc.constantBufferSize = 4096;
+ ITextureResource::Desc textureDesc = {};
+ textureDesc.type = IResource::Type::Texture2D;
+ textureDesc.format = Format::R8G8B8A8_UNORM;
+ textureDesc.size.width = 2;
+ textureDesc.size.height = 2;
+ textureDesc.size.depth = 1;
+ textureDesc.numMipLevels = 2;
+ textureDesc.memoryType = MemoryType::DeviceLocal;
+ textureDesc.defaultState = ResourceState::ShaderResource;
+ textureDesc.allowedStates.add(ResourceState::CopyDestination);
+ uint32_t data[] = {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF};
+ ITextureResource::SubresourceData subResourceData[2] = {{data, 8, 16}, {data, 8, 16}};
GFX_CHECK_CALL_ABORT(
- device->createTransientResourceHeap(transientHeapDesc, transientHeap.writeRef()));
+ device->createTextureResource(textureDesc, subResourceData, texture.writeRef()));
+ }
+ for (uint32_t i = 0; i < 32; i++)
+ {
+ ComPtr<IResourceView> srv;
+ IResourceView::Desc viewDesc = {};
+ viewDesc.type = IResourceView::Type::ShaderResource;
+ viewDesc.format = Format::R8G8B8A8_UNORM;
+ viewDesc.subresourceRange.layerCount = 1;
+ viewDesc.subresourceRange.mipLevelCount = 1;
+ GFX_CHECK_CALL_ABORT(device->createTextureView(texture, viewDesc, srv.writeRef()));
+ srvs.add(srv);
+ }
- ComPtr<IShaderProgram> shaderProgram;
- slang::ProgramLayout* slangReflection;
- GFX_CHECK_CALL_ABORT(loadComputeProgram(device, shaderProgram, "sampler-array", "computeMain", slangReflection));
+ for (uint32_t i = 0; i < 32; i++)
+ {
+ ISamplerState::Desc desc = {};
+ ComPtr<ISamplerState> sampler;
+ GFX_CHECK_CALL_ABORT(device->createSamplerState(desc, sampler.writeRef()));
+ samplers.add(sampler);
+ }
- ComputePipelineStateDesc pipelineDesc = {};
- pipelineDesc.program = shaderProgram.get();
- ComPtr<gfx::IPipelineState> pipelineState;
- GFX_CHECK_CALL_ABORT(
- device->createComputePipelineState(pipelineDesc, pipelineState.writeRef()));
+ ComPtr<IShaderObject> rootObject;
+ device->createMutableRootShaderObject(shaderProgram, rootObject.writeRef());
- Slang::List<ComPtr<ISamplerState>> samplers;
- Slang::List<ComPtr<IResourceView>> srvs;
- ComPtr<IResourceView> uav;
- ComPtr<ITextureResource> texture;
- ComPtr<IBufferResource> buffer = createBuffer(device, 0);
+ ComPtr<IShaderObject> g;
+ device->createMutableShaderObject(
+ slangReflection->findTypeByName("S0"),
+ ShaderObjectContainerType::None,
+ g.writeRef());
- {
- IResourceView::Desc viewDesc = {};
- viewDesc.type = IResourceView::Type::UnorderedAccess;
- viewDesc.format = Format::Unknown;
- GFX_CHECK_CALL_ABORT(
- device->createBufferView(buffer, nullptr, viewDesc, uav.writeRef()));
- }
- {
- ITextureResource::Desc textureDesc = {};
- textureDesc.type = IResource::Type::Texture2D;
- textureDesc.format = Format::R8G8B8A8_UNORM;
- textureDesc.size.width = 2;
- textureDesc.size.height = 2;
- textureDesc.size.depth = 1;
- textureDesc.numMipLevels = 2;
- textureDesc.memoryType = MemoryType::DeviceLocal;
- textureDesc.defaultState = ResourceState::ShaderResource;
- textureDesc.allowedStates.add(ResourceState::CopyDestination);
- uint32_t data[] = {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF};
- ITextureResource::SubresourceData subResourceData[2] = {{data, 8, 16}, {data, 8, 16}};
- GFX_CHECK_CALL_ABORT(
- device->createTextureResource(textureDesc, subResourceData, texture.writeRef()));
- }
- for (uint32_t i = 0; i < 32; i++)
- {
- ComPtr<IResourceView> srv;
- IResourceView::Desc viewDesc = {};
- viewDesc.type = IResourceView::Type::ShaderResource;
- viewDesc.format = Format::R8G8B8A8_UNORM;
- viewDesc.subresourceRange.layerCount = 1;
- viewDesc.subresourceRange.mipLevelCount = 1;
- GFX_CHECK_CALL_ABORT(
- device->createTextureView(texture, viewDesc, srv.writeRef()));
- srvs.add(srv);
- }
+ ComPtr<IShaderObject> s1;
+ device->createMutableShaderObject(
+ slangReflection->findTypeByName("S1"),
+ ShaderObjectContainerType::None,
+ s1.writeRef());
+ {
+ auto cursor = ShaderCursor(s1);
for (uint32_t i = 0; i < 32; i++)
{
- ISamplerState::Desc desc = {};
- ComPtr<ISamplerState> sampler;
- GFX_CHECK_CALL_ABORT(device->createSamplerState(desc, sampler.writeRef()));
- samplers.add(sampler);
+ cursor["samplers"][i].setSampler(samplers[i]);
+ cursor["tex"][i].setResource(srvs[i]);
}
+ cursor["data"].setData(1.0f);
+ }
- ComPtr<IShaderObject> rootObject;
- device->createMutableRootShaderObject(shaderProgram, rootObject.writeRef());
-
- ComPtr<IShaderObject> g;
- device->createMutableShaderObject(
- slangReflection->findTypeByName("S0"), ShaderObjectContainerType::None, g.writeRef());
-
- ComPtr<IShaderObject> s1;
- device->createMutableShaderObject(
- slangReflection->findTypeByName("S1"), ShaderObjectContainerType::None, s1.writeRef());
-
- {
- auto cursor = ShaderCursor(s1);
- for (uint32_t i = 0; i < 32; i++)
- {
- cursor["samplers"][i].setSampler(samplers[i]);
- cursor["tex"][i].setResource(srvs[i]);
- }
- cursor["data"].setData(1.0f);
- }
+ {
+ auto cursor = ShaderCursor(g);
+ cursor["s"].setObject(s1);
+ cursor["data"].setData(2.0f);
+ }
- {
- auto cursor = ShaderCursor(g);
- cursor["s"].setObject(s1);
- cursor["data"].setData(2.0f);
- }
+ {
+ auto cursor = ShaderCursor(rootObject);
+ cursor["g"].setObject(g);
+ cursor["buffer"].setResource(uav);
+ }
- {
- auto cursor = ShaderCursor(rootObject);
- cursor["g"].setObject(g);
- cursor["buffer"].setResource(uav);
- }
+ {
+ ICommandQueue::Desc queueDesc = {ICommandQueue::QueueType::Graphics};
+ auto queue = device->createCommandQueue(queueDesc);
+ auto commandBuffer = transientHeap->createCommandBuffer();
{
- ICommandQueue::Desc queueDesc = { ICommandQueue::QueueType::Graphics };
- auto queue = device->createCommandQueue(queueDesc);
-
- auto commandBuffer = transientHeap->createCommandBuffer();
- {
- auto encoder = commandBuffer->encodeComputeCommands();
- encoder->bindPipelineWithRootObject(pipelineState, rootObject);
- encoder->dispatchCompute(1, 1, 1);
- encoder->endEncoding();
- }
-
- commandBuffer->close();
- queue->executeCommandBuffer(commandBuffer);
- queue->waitOnHost();
+ auto encoder = commandBuffer->encodeComputeCommands();
+ encoder->bindPipelineWithRootObject(pipelineState, rootObject);
+ encoder->dispatchCompute(1, 1, 1);
+ encoder->endEncoding();
}
- compareComputeResult(
- device, buffer, Slang::makeArray<float>(4.0f));
+ commandBuffer->close();
+ queue->executeCommandBuffer(commandBuffer);
+ queue->waitOnHost();
}
- SLANG_UNIT_TEST(samplerArrayVulkan)
- {
- runTestImpl(samplerArrayTestImpl, unitTestContext, Slang::RenderApiFlag::Vulkan);
- }
+ compareComputeResult(device, buffer, Slang::makeArray<float>(4.0f));
+}
+
+SLANG_UNIT_TEST(samplerArrayVulkan)
+{
+ runTestImpl(samplerArrayTestImpl, unitTestContext, Slang::RenderApiFlag::Vulkan);
}
+} // namespace gfx_test
diff --git a/tools/gfx-unit-test/shader-cache-tests.cpp b/tools/gfx-unit-test/shader-cache-tests.cpp
index 4477c4f56..8ee8d9015 100644
--- a/tools/gfx-unit-test/shader-cache-tests.cpp
+++ b/tools/gfx-unit-test/shader-cache-tests.cpp
@@ -1,44 +1,43 @@
-#include "tools/unit-test/slang-unit-test.h"
-
-#include "slang-gfx.h"
+#include "gfx-test-texture-util.h"
#include "gfx-test-util.h"
-#include "tools/gfx-util/shader-cursor.h"
+#include "slang-gfx.h"
#include "source/core/slang-basic.h"
-#include "source/core/slang-string-util.h"
-#include "source/core/slang-io.h"
#include "source/core/slang-file-system.h"
+#include "source/core/slang-io.h"
#include "source/core/slang-process.h"
-#include "gfx-test-texture-util.h"
+#include "source/core/slang-string-util.h"
+#include "tools/gfx-util/shader-cursor.h"
+#include "tools/unit-test/slang-unit-test.h"
using namespace gfx;
using namespace Slang;
namespace gfx_test
{
- // Base class for shader cache tests.
- // Slang currently does not allow reloading shaders from modified sources.
- // Because of this, the tests recreate a GFX device for each test step,
- // allowing to modify shader sources in between.
- struct ShaderCacheTest
- {
- UnitTestContext* context;
- Slang::RenderApiFlag::Enum api;
+// Base class for shader cache tests.
+// Slang currently does not allow reloading shaders from modified sources.
+// Because of this, the tests recreate a GFX device for each test step,
+// allowing to modify shader sources in between.
+struct ShaderCacheTest
+{
+ UnitTestContext* context;
+ Slang::RenderApiFlag::Enum api;
- String testDirectory;
- String cacheDirectory;
+ String testDirectory;
+ String cacheDirectory;
- ComPtr<ISlangMutableFileSystem> diskFileSystem;
+ ComPtr<ISlangMutableFileSystem> diskFileSystem;
- IDevice::ShaderCacheDesc shaderCacheDesc = {};
+ IDevice::ShaderCacheDesc shaderCacheDesc = {};
- ComPtr<IDevice> device;
- ComPtr<IShaderCache> shaderCache;
- ComPtr<IPipelineState> pipelineState;
- ComPtr<IBufferResource> bufferResource;
- ComPtr<IResourceView> bufferView;
+ ComPtr<IDevice> device;
+ ComPtr<IShaderCache> shaderCache;
+ ComPtr<IPipelineState> pipelineState;
+ ComPtr<IBufferResource> bufferResource;
+ ComPtr<IResourceView> bufferView;
- String computeShaderA = String(
- R"(
+ String computeShaderA = String(
+ R"(
[shader("compute")]
[numthreads(4, 1, 1)]
void main(
@@ -48,10 +47,10 @@ namespace gfx_test
var input = buffer[sv_dispatchThreadID.x];
buffer[sv_dispatchThreadID.x] = input + 1.0f;
}
- )");
+ )");
- String computeShaderB = String(
- R"(
+ String computeShaderB = String(
+ R"(
[shader("compute")]
[numthreads(4, 1, 1)]
void main(
@@ -63,8 +62,8 @@ namespace gfx_test
}
)");
- String computeShaderC = String(
- R"(
+ String computeShaderC = String(
+ R"(
[shader("compute")]
[numthreads(4, 1, 1)]
void main(
@@ -77,359 +76,383 @@ namespace gfx_test
)");
- void removeDirectory(const String& directory)
- {
- auto osFileSystem = OSFileSystem::getMutableSingleton();
-
- struct Context
- {
- ISlangMutableFileSystem *fileSystem;
- const String& directory;
- } context { osFileSystem, directory };
-
- osFileSystem->enumeratePathContents(
- directory.getBuffer(),
- [](SlangPathType pathType, const char* fileName, void* userData)
- {
- struct Context* context = static_cast<Context *>(userData);
- if (pathType == SlangPathType::SLANG_PATH_TYPE_FILE)
- {
- String path = Path::simplify(context->directory + "/" + fileName);
- context->fileSystem->remove(path.getBuffer());
- }
- },
- &context);
-
- osFileSystem->remove(directory.getBuffer());
- }
-
- void writeShader(const String& source, const String& fileName)
- {
- diskFileSystem->saveFile(fileName.getBuffer(), source.getBuffer(), source.getLength());
- }
-
- void init(UnitTestContext* context, Slang::RenderApiFlag::Enum api)
- {
- this->context = context;
- this->api = api;
- testDirectory = Path::simplify(Path::getParentDirectory(Path::getExecutablePath()) + "/shader-cache-test" + String(Process::getId()));
- cacheDirectory = Path::simplify(testDirectory + "/cache" + String(Process::getId()));
-
- // Cleanup if there are stale files from a previously aborted test.
- removeDirectory(cacheDirectory);
- removeDirectory(testDirectory);
-
- Path::createDirectory(testDirectory);
- diskFileSystem = new RelativeFileSystem(OSFileSystem::getMutableSingleton(), testDirectory);
- shaderCacheDesc.shaderCachePath = cacheDirectory.getBuffer();
- }
-
- void cleanup()
- {
- removeDirectory(cacheDirectory);
- removeDirectory(testDirectory);
- }
+ void removeDirectory(const String& directory)
+ {
+ auto osFileSystem = OSFileSystem::getMutableSingleton();
- template<typename Func>
- void runStep(Func func)
+ struct Context
{
- List<const char*> additionalSearchPaths;
- additionalSearchPaths.add(testDirectory.getBuffer());
+ ISlangMutableFileSystem* fileSystem;
+ const String& directory;
+ } context{osFileSystem, directory};
- runTestImpl(
- [this, func] (IDevice* device, UnitTestContext* ctx)
+ osFileSystem->enumeratePathContents(
+ directory.getBuffer(),
+ [](SlangPathType pathType, const char* fileName, void* userData)
+ {
+ struct Context* context = static_cast<Context*>(userData);
+ if (pathType == SlangPathType::SLANG_PATH_TYPE_FILE)
{
- this->device = device;
- SLANG_CHECK_ABORT(SLANG_SUCCEEDED(
- device->queryInterface(SLANG_UUID_IShaderCache, (void**)this->shaderCache.writeRef())));
- func();
- this->device = nullptr;
- this->shaderCache = nullptr;
- },
- context, api, additionalSearchPaths, shaderCacheDesc);
- }
-
- void createComputeResources()
- {
- const int numberCount = 4;
- float initialData[] = { 0.0f, 1.0f, 2.0f, 3.0f };
- IBufferResource::Desc bufferDesc = {};
- bufferDesc.sizeInBytes = numberCount * sizeof(float);
- bufferDesc.format = Format::Unknown;
- bufferDesc.elementSize = sizeof(float);
- bufferDesc.allowedStates = ResourceStateSet(
- ResourceState::ShaderResource,
- ResourceState::UnorderedAccess,
- ResourceState::CopyDestination,
- ResourceState::CopySource);
- bufferDesc.defaultState = ResourceState::UnorderedAccess;
- bufferDesc.memoryType = MemoryType::DeviceLocal;
-
- GFX_CHECK_CALL_ABORT(device->createBufferResource(
- bufferDesc,
- (void*)initialData,
- bufferResource.writeRef()));
-
- IResourceView::Desc viewDesc = {};
- viewDesc.type = IResourceView::Type::UnorderedAccess;
- viewDesc.format = Format::Unknown;
- GFX_CHECK_CALL_ABORT(
- device->createBufferView(bufferResource, nullptr, viewDesc, bufferView.writeRef()));
- }
-
- void freeComputeResources()
- {
- bufferResource = nullptr;
- bufferView = nullptr;
- pipelineState = nullptr;
- }
-
- void createComputePipeline(const char* moduleName, const char* entryPointName)
- {
- ComPtr<IShaderProgram> shaderProgram;
- slang::ProgramLayout* slangReflection;
- GFX_CHECK_CALL_ABORT(loadComputeProgram(device, shaderProgram, moduleName, entryPointName, slangReflection));
-
- ComputePipelineStateDesc pipelineDesc = {};
- pipelineDesc.program = shaderProgram.get();
- GFX_CHECK_CALL_ABORT(
- device->createComputePipelineState(pipelineDesc, pipelineState.writeRef()));
- }
-
- void createComputePipeline(Slang::String shaderSource)
- {
- ComPtr<IShaderProgram> shaderProgram;
- GFX_CHECK_CALL_ABORT(loadComputeProgramFromSource(device, shaderProgram, shaderSource));
-
- ComputePipelineStateDesc pipelineDesc = {};
- pipelineDesc.program = shaderProgram.get();
- GFX_CHECK_CALL_ABORT(
- device->createComputePipelineState(pipelineDesc, pipelineState.writeRef()));
- }
+ String path = Path::simplify(context->directory + "/" + fileName);
+ context->fileSystem->remove(path.getBuffer());
+ }
+ },
+ &context);
- void dispatchComputePipeline()
- {
- ComPtr<ITransientResourceHeap> transientHeap;
- ITransientResourceHeap::Desc transientHeapDesc = {};
- transientHeapDesc.constantBufferSize = 4096;
- GFX_CHECK_CALL_ABORT(
- device->createTransientResourceHeap(transientHeapDesc, transientHeap.writeRef()));
+ osFileSystem->remove(directory.getBuffer());
+ }
- ICommandQueue::Desc queueDesc = { ICommandQueue::QueueType::Graphics };
- auto queue = device->createCommandQueue(queueDesc);
+ void writeShader(const String& source, const String& fileName)
+ {
+ diskFileSystem->saveFile(fileName.getBuffer(), source.getBuffer(), source.getLength());
+ }
- auto commandBuffer = transientHeap->createCommandBuffer();
- auto encoder = commandBuffer->encodeComputeCommands();
+ void init(UnitTestContext* context, Slang::RenderApiFlag::Enum api)
+ {
+ this->context = context;
+ this->api = api;
+ testDirectory = Path::simplify(
+ Path::getParentDirectory(Path::getExecutablePath()) + "/shader-cache-test" +
+ String(Process::getId()));
+ cacheDirectory = Path::simplify(testDirectory + "/cache" + String(Process::getId()));
+
+ // Cleanup if there are stale files from a previously aborted test.
+ removeDirectory(cacheDirectory);
+ removeDirectory(testDirectory);
+
+ Path::createDirectory(testDirectory);
+ diskFileSystem = new RelativeFileSystem(OSFileSystem::getMutableSingleton(), testDirectory);
+ shaderCacheDesc.shaderCachePath = cacheDirectory.getBuffer();
+ }
- auto rootObject = encoder->bindPipeline(pipelineState);
+ void cleanup()
+ {
+ removeDirectory(cacheDirectory);
+ removeDirectory(testDirectory);
+ }
- // Bind buffer view to the entry point.
- ShaderCursor entryPointCursor(rootObject->getEntryPoint(0));
- entryPointCursor.getPath("buffer").setResource(bufferView);
+ template<typename Func>
+ void runStep(Func func)
+ {
+ List<const char*> additionalSearchPaths;
+ additionalSearchPaths.add(testDirectory.getBuffer());
- encoder->dispatchCompute(4, 1, 1);
- encoder->endEncoding();
- commandBuffer->close();
- queue->executeCommandBuffer(commandBuffer);
- queue->waitOnHost();
- }
+ runTestImpl(
+ [this, func](IDevice* device, UnitTestContext* ctx)
+ {
+ this->device = device;
+ SLANG_CHECK_ABORT(SLANG_SUCCEEDED(device->queryInterface(
+ SLANG_UUID_IShaderCache,
+ (void**)this->shaderCache.writeRef())));
+ func();
+ this->device = nullptr;
+ this->shaderCache = nullptr;
+ },
+ context,
+ api,
+ additionalSearchPaths,
+ shaderCacheDesc);
+ }
- bool checkOutput(const List<float>& expectedOutput)
- {
- ComPtr<ISlangBlob> bufferBlob;
- device->readBufferResource(bufferResource, 0, 4 * sizeof(float), bufferBlob.writeRef());
- SLANG_CHECK_ABORT(bufferBlob && bufferBlob->getBufferSize() == expectedOutput.getCount() * sizeof(float));
- return ::memcmp(bufferBlob->getBufferPointer(), expectedOutput.getBuffer(), bufferBlob->getBufferSize()) == 0;
- }
+ void createComputeResources()
+ {
+ const int numberCount = 4;
+ float initialData[] = {0.0f, 1.0f, 2.0f, 3.0f};
+ IBufferResource::Desc bufferDesc = {};
+ bufferDesc.sizeInBytes = numberCount * sizeof(float);
+ bufferDesc.format = Format::Unknown;
+ bufferDesc.elementSize = sizeof(float);
+ bufferDesc.allowedStates = ResourceStateSet(
+ ResourceState::ShaderResource,
+ ResourceState::UnorderedAccess,
+ ResourceState::CopyDestination,
+ ResourceState::CopySource);
+ bufferDesc.defaultState = ResourceState::UnorderedAccess;
+ bufferDesc.memoryType = MemoryType::DeviceLocal;
+
+ GFX_CHECK_CALL_ABORT(device->createBufferResource(
+ bufferDesc,
+ (void*)initialData,
+ bufferResource.writeRef()));
+
+ IResourceView::Desc viewDesc = {};
+ viewDesc.type = IResourceView::Type::UnorderedAccess;
+ viewDesc.format = Format::Unknown;
+ GFX_CHECK_CALL_ABORT(
+ device->createBufferView(bufferResource, nullptr, viewDesc, bufferView.writeRef()));
+ }
- bool runComputePipeline(const char* moduleName, const char* entryPointName, const List<float>& expectedOutput)
- {
- createComputeResources();
- createComputePipeline(moduleName, entryPointName);
- dispatchComputePipeline();
- bool hasExpectedOutput = checkOutput(expectedOutput);
- SLANG_CHECK(hasExpectedOutput);
- freeComputeResources();
- return hasExpectedOutput;
- }
-
- bool runComputePipeline(Slang::String shaderSource, const List<float>& expectedOutput)
- {
- createComputeResources();
- createComputePipeline(shaderSource);
- dispatchComputePipeline();
- bool hasExpectedOutput = checkOutput(expectedOutput);
- SLANG_CHECK(hasExpectedOutput);
- freeComputeResources();
- return hasExpectedOutput;
- }
-
- ShaderCacheStats getStats()
- {
- SLANG_ASSERT(shaderCache);
- ShaderCacheStats stats;
- shaderCache->getShaderCacheStats(&stats);
- return stats;
- }
+ void freeComputeResources()
+ {
+ bufferResource = nullptr;
+ bufferView = nullptr;
+ pipelineState = nullptr;
+ }
- void run(UnitTestContext* context, Slang::RenderApiFlag::Enum api)
- {
- init(context, api);
- runTests();
- cleanup();
- }
+ void createComputePipeline(const char* moduleName, const char* entryPointName)
+ {
+ ComPtr<IShaderProgram> shaderProgram;
+ slang::ProgramLayout* slangReflection;
+ GFX_CHECK_CALL_ABORT(
+ loadComputeProgram(device, shaderProgram, moduleName, entryPointName, slangReflection));
- virtual void runTests() = 0;
- };
+ ComputePipelineStateDesc pipelineDesc = {};
+ pipelineDesc.program = shaderProgram.get();
+ GFX_CHECK_CALL_ABORT(
+ device->createComputePipelineState(pipelineDesc, pipelineState.writeRef()));
+ }
- // Basic shader cache test using 3 different shader files stored on disk.
- struct ShaderCacheSourceFile : ShaderCacheTest
+ void createComputePipeline(Slang::String shaderSource)
{
- void runTests()
- {
- // Write shader source files.
- writeShader(computeShaderA, "shader-cache-tmp-a.slang");
- writeShader(computeShaderB, "shader-cache-tmp-b.slang");
- writeShader(computeShaderC, "shader-cache-tmp-c.slang");
-
- // Cache is cold and we expect 3 misses.
- runStep(
- [this]()
- {
- SLANG_CHECK(runComputePipeline("shader-cache-tmp-a", "main", { 1.f, 2.f, 3.f, 4.f }));
- SLANG_CHECK(runComputePipeline("shader-cache-tmp-b", "main", { 2.f, 3.f, 4.f, 5.f }));
- SLANG_CHECK(runComputePipeline("shader-cache-tmp-c", "main", { 3.f, 4.f, 5.f, 6.f }));
-
- SLANG_CHECK(getStats().missCount == 3);
- SLANG_CHECK(getStats().hitCount == 0);
- SLANG_CHECK(getStats().entryCount == 3);
- }
- );
+ ComPtr<IShaderProgram> shaderProgram;
+ GFX_CHECK_CALL_ABORT(loadComputeProgramFromSource(device, shaderProgram, shaderSource));
- // Cache is hot and we expect 3 hits.
- runStep(
- [this]()
- {
- SLANG_CHECK(runComputePipeline("shader-cache-tmp-a", "main", { 1.f, 2.f, 3.f, 4.f }));
- SLANG_CHECK(runComputePipeline("shader-cache-tmp-b", "main", { 2.f, 3.f, 4.f, 5.f }));
- SLANG_CHECK(runComputePipeline("shader-cache-tmp-c", "main", { 3.f, 4.f, 5.f, 6.f }));
+ ComputePipelineStateDesc pipelineDesc = {};
+ pipelineDesc.program = shaderProgram.get();
+ GFX_CHECK_CALL_ABORT(
+ device->createComputePipelineState(pipelineDesc, pipelineState.writeRef()));
+ }
- SLANG_CHECK(getStats().missCount == 0);
- SLANG_CHECK(getStats().hitCount == 3);
- SLANG_CHECK(getStats().entryCount == 3);
- }
- );
+ void dispatchComputePipeline()
+ {
+ ComPtr<ITransientResourceHeap> transientHeap;
+ ITransientResourceHeap::Desc transientHeapDesc = {};
+ transientHeapDesc.constantBufferSize = 4096;
+ GFX_CHECK_CALL_ABORT(
+ device->createTransientResourceHeap(transientHeapDesc, transientHeap.writeRef()));
- // Write shader source files, all rotated by one.
- writeShader(computeShaderA, "shader-cache-tmp-b.slang");
- writeShader(computeShaderB, "shader-cache-tmp-c.slang");
- writeShader(computeShaderC, "shader-cache-tmp-a.slang");
+ ICommandQueue::Desc queueDesc = {ICommandQueue::QueueType::Graphics};
+ auto queue = device->createCommandQueue(queueDesc);
- // Cache is cold again and we expect 3 misses.
- runStep(
- [this]()
- {
- SLANG_CHECK(runComputePipeline("shader-cache-tmp-b", "main", { 1.f, 2.f, 3.f, 4.f }));
- SLANG_CHECK(runComputePipeline("shader-cache-tmp-c", "main", { 2.f, 3.f, 4.f, 5.f }));
- SLANG_CHECK(runComputePipeline("shader-cache-tmp-a", "main", { 3.f, 4.f, 5.f, 6.f }));
+ auto commandBuffer = transientHeap->createCommandBuffer();
+ auto encoder = commandBuffer->encodeComputeCommands();
- SLANG_CHECK(getStats().missCount == 3);
- SLANG_CHECK(getStats().hitCount == 0);
- SLANG_CHECK(getStats().entryCount == 6);
- }
- );
+ auto rootObject = encoder->bindPipeline(pipelineState);
- // Cache is hot again and we expect 3 hits.
- runStep(
- [this]()
- {
- SLANG_CHECK(runComputePipeline("shader-cache-tmp-b", "main", { 1.f, 2.f, 3.f, 4.f }));
- SLANG_CHECK(runComputePipeline("shader-cache-tmp-c", "main", { 2.f, 3.f, 4.f, 5.f }));
- SLANG_CHECK(runComputePipeline("shader-cache-tmp-a", "main", { 3.f, 4.f, 5.f, 6.f }));
+ // Bind buffer view to the entry point.
+ ShaderCursor entryPointCursor(rootObject->getEntryPoint(0));
+ entryPointCursor.getPath("buffer").setResource(bufferView);
- SLANG_CHECK(getStats().missCount == 0);
- SLANG_CHECK(getStats().hitCount == 3);
- SLANG_CHECK(getStats().entryCount == 6);
- }
- );
- }
- };
+ encoder->dispatchCompute(4, 1, 1);
+ encoder->endEncoding();
+ commandBuffer->close();
+ queue->executeCommandBuffer(commandBuffer);
+ queue->waitOnHost();
+ }
- // Test caching of shaders that are compiled from source strings instead of files.
- struct ShaderCacheTestSourceString : ShaderCacheTest
+ bool checkOutput(const List<float>& expectedOutput)
{
- void runTests()
- {
- // Cache is cold and we expect 3 misses.
- runStep(
- [this]()
- {
- SLANG_CHECK(runComputePipeline(computeShaderA, { 1.f, 2.f, 3.f, 4.f }));
- SLANG_CHECK(runComputePipeline(computeShaderB, { 2.f, 3.f, 4.f, 5.f }));
- SLANG_CHECK(runComputePipeline(computeShaderC, { 3.f, 4.f, 5.f, 6.f }));
+ ComPtr<ISlangBlob> bufferBlob;
+ device->readBufferResource(bufferResource, 0, 4 * sizeof(float), bufferBlob.writeRef());
+ SLANG_CHECK_ABORT(
+ bufferBlob && bufferBlob->getBufferSize() == expectedOutput.getCount() * sizeof(float));
+ return ::memcmp(
+ bufferBlob->getBufferPointer(),
+ expectedOutput.getBuffer(),
+ bufferBlob->getBufferSize()) == 0;
+ }
- SLANG_CHECK(getStats().missCount == 3);
- SLANG_CHECK(getStats().hitCount == 0);
- SLANG_CHECK(getStats().entryCount == 3);
- }
- );
+ bool runComputePipeline(
+ const char* moduleName,
+ const char* entryPointName,
+ const List<float>& expectedOutput)
+ {
+ createComputeResources();
+ createComputePipeline(moduleName, entryPointName);
+ dispatchComputePipeline();
+ bool hasExpectedOutput = checkOutput(expectedOutput);
+ SLANG_CHECK(hasExpectedOutput);
+ freeComputeResources();
+ return hasExpectedOutput;
+ }
- // Cache is hot and we expect 3 hits.
- runStep(
- [this]()
- {
- SLANG_CHECK(runComputePipeline(computeShaderA, { 1.f, 2.f, 3.f, 4.f }));
- SLANG_CHECK(runComputePipeline(computeShaderB, { 2.f, 3.f, 4.f, 5.f }));
- SLANG_CHECK(runComputePipeline(computeShaderC, { 3.f, 4.f, 5.f, 6.f }));
+ bool runComputePipeline(Slang::String shaderSource, const List<float>& expectedOutput)
+ {
+ createComputeResources();
+ createComputePipeline(shaderSource);
+ dispatchComputePipeline();
+ bool hasExpectedOutput = checkOutput(expectedOutput);
+ SLANG_CHECK(hasExpectedOutput);
+ freeComputeResources();
+ return hasExpectedOutput;
+ }
- SLANG_CHECK(getStats().missCount == 0);
- SLANG_CHECK(getStats().hitCount == 3);
- SLANG_CHECK(getStats().entryCount == 3);
- }
- );
- }
- };
+ ShaderCacheStats getStats()
+ {
+ SLANG_ASSERT(shaderCache);
+ ShaderCacheStats stats;
+ shaderCache->getShaderCacheStats(&stats);
+ return stats;
+ }
- // Test one shader file on disk with multiple entry points.
- struct ShaderCacheTestEntryPoint : ShaderCacheTest
+ void run(UnitTestContext* context, Slang::RenderApiFlag::Enum api)
{
- void runTests()
- {
- // Cache is cold and we expect 3 misses, one for each entry point.
- runStep(
- [this]()
- {
- SLANG_CHECK(runComputePipeline("shader-cache-multiple-entry-points", "computeA", { 1.f, 2.f, 3.f, 4.f }));
- SLANG_CHECK(runComputePipeline("shader-cache-multiple-entry-points", "computeB", { 2.f, 3.f, 4.f, 5.f }));
- SLANG_CHECK(runComputePipeline("shader-cache-multiple-entry-points", "computeC", { 3.f, 4.f, 5.f, 6.f }));
+ init(context, api);
+ runTests();
+ cleanup();
+ }
- SLANG_CHECK(getStats().missCount == 3);
- SLANG_CHECK(getStats().hitCount == 0);
- SLANG_CHECK(getStats().entryCount == 3);
- }
- );
+ virtual void runTests() = 0;
+};
- // Cache is hot and we expect 3 hits.
- runStep(
- [this]()
- {
- SLANG_CHECK(runComputePipeline("shader-cache-multiple-entry-points", "computeA", { 1.f, 2.f, 3.f, 4.f }));
- SLANG_CHECK(runComputePipeline("shader-cache-multiple-entry-points", "computeB", { 2.f, 3.f, 4.f, 5.f }));
- SLANG_CHECK(runComputePipeline("shader-cache-multiple-entry-points", "computeC", { 3.f, 4.f, 5.f, 6.f }));
+// Basic shader cache test using 3 different shader files stored on disk.
+struct ShaderCacheSourceFile : ShaderCacheTest
+{
+ void runTests()
+ {
+ // Write shader source files.
+ writeShader(computeShaderA, "shader-cache-tmp-a.slang");
+ writeShader(computeShaderB, "shader-cache-tmp-b.slang");
+ writeShader(computeShaderC, "shader-cache-tmp-c.slang");
+
+ // Cache is cold and we expect 3 misses.
+ runStep(
+ [this]()
+ {
+ SLANG_CHECK(runComputePipeline("shader-cache-tmp-a", "main", {1.f, 2.f, 3.f, 4.f}));
+ SLANG_CHECK(runComputePipeline("shader-cache-tmp-b", "main", {2.f, 3.f, 4.f, 5.f}));
+ SLANG_CHECK(runComputePipeline("shader-cache-tmp-c", "main", {3.f, 4.f, 5.f, 6.f}));
+
+ SLANG_CHECK(getStats().missCount == 3);
+ SLANG_CHECK(getStats().hitCount == 0);
+ SLANG_CHECK(getStats().entryCount == 3);
+ });
+
+ // Cache is hot and we expect 3 hits.
+ runStep(
+ [this]()
+ {
+ SLANG_CHECK(runComputePipeline("shader-cache-tmp-a", "main", {1.f, 2.f, 3.f, 4.f}));
+ SLANG_CHECK(runComputePipeline("shader-cache-tmp-b", "main", {2.f, 3.f, 4.f, 5.f}));
+ SLANG_CHECK(runComputePipeline("shader-cache-tmp-c", "main", {3.f, 4.f, 5.f, 6.f}));
+
+ SLANG_CHECK(getStats().missCount == 0);
+ SLANG_CHECK(getStats().hitCount == 3);
+ SLANG_CHECK(getStats().entryCount == 3);
+ });
+
+ // Write shader source files, all rotated by one.
+ writeShader(computeShaderA, "shader-cache-tmp-b.slang");
+ writeShader(computeShaderB, "shader-cache-tmp-c.slang");
+ writeShader(computeShaderC, "shader-cache-tmp-a.slang");
+
+ // Cache is cold again and we expect 3 misses.
+ runStep(
+ [this]()
+ {
+ SLANG_CHECK(runComputePipeline("shader-cache-tmp-b", "main", {1.f, 2.f, 3.f, 4.f}));
+ SLANG_CHECK(runComputePipeline("shader-cache-tmp-c", "main", {2.f, 3.f, 4.f, 5.f}));
+ SLANG_CHECK(runComputePipeline("shader-cache-tmp-a", "main", {3.f, 4.f, 5.f, 6.f}));
+
+ SLANG_CHECK(getStats().missCount == 3);
+ SLANG_CHECK(getStats().hitCount == 0);
+ SLANG_CHECK(getStats().entryCount == 6);
+ });
+
+ // Cache is hot again and we expect 3 hits.
+ runStep(
+ [this]()
+ {
+ SLANG_CHECK(runComputePipeline("shader-cache-tmp-b", "main", {1.f, 2.f, 3.f, 4.f}));
+ SLANG_CHECK(runComputePipeline("shader-cache-tmp-c", "main", {2.f, 3.f, 4.f, 5.f}));
+ SLANG_CHECK(runComputePipeline("shader-cache-tmp-a", "main", {3.f, 4.f, 5.f, 6.f}));
+
+ SLANG_CHECK(getStats().missCount == 0);
+ SLANG_CHECK(getStats().hitCount == 3);
+ SLANG_CHECK(getStats().entryCount == 6);
+ });
+ }
+};
- SLANG_CHECK(getStats().missCount == 0);
- SLANG_CHECK(getStats().hitCount == 3);
- SLANG_CHECK(getStats().entryCount == 3);
- }
- );
- }
- };
+// Test caching of shaders that are compiled from source strings instead of files.
+struct ShaderCacheTestSourceString : ShaderCacheTest
+{
+ void runTests()
+ {
+ // Cache is cold and we expect 3 misses.
+ runStep(
+ [this]()
+ {
+ SLANG_CHECK(runComputePipeline(computeShaderA, {1.f, 2.f, 3.f, 4.f}));
+ SLANG_CHECK(runComputePipeline(computeShaderB, {2.f, 3.f, 4.f, 5.f}));
+ SLANG_CHECK(runComputePipeline(computeShaderC, {3.f, 4.f, 5.f, 6.f}));
+
+ SLANG_CHECK(getStats().missCount == 3);
+ SLANG_CHECK(getStats().hitCount == 0);
+ SLANG_CHECK(getStats().entryCount == 3);
+ });
+
+ // Cache is hot and we expect 3 hits.
+ runStep(
+ [this]()
+ {
+ SLANG_CHECK(runComputePipeline(computeShaderA, {1.f, 2.f, 3.f, 4.f}));
+ SLANG_CHECK(runComputePipeline(computeShaderB, {2.f, 3.f, 4.f, 5.f}));
+ SLANG_CHECK(runComputePipeline(computeShaderC, {3.f, 4.f, 5.f, 6.f}));
+
+ SLANG_CHECK(getStats().missCount == 0);
+ SLANG_CHECK(getStats().hitCount == 3);
+ SLANG_CHECK(getStats().entryCount == 3);
+ });
+ }
+};
- // Test cache invalidation due to an import/include file being changed on disk.
- struct ShaderCacheTestImportInclude : ShaderCacheTest
+// Test one shader file on disk with multiple entry points.
+struct ShaderCacheTestEntryPoint : ShaderCacheTest
+{
+ void runTests()
{
- String importedContentsA = String(
- R"(
+ // Cache is cold and we expect 3 misses, one for each entry point.
+ runStep(
+ [this]()
+ {
+ SLANG_CHECK(runComputePipeline(
+ "shader-cache-multiple-entry-points",
+ "computeA",
+ {1.f, 2.f, 3.f, 4.f}));
+ SLANG_CHECK(runComputePipeline(
+ "shader-cache-multiple-entry-points",
+ "computeB",
+ {2.f, 3.f, 4.f, 5.f}));
+ SLANG_CHECK(runComputePipeline(
+ "shader-cache-multiple-entry-points",
+ "computeC",
+ {3.f, 4.f, 5.f, 6.f}));
+
+ SLANG_CHECK(getStats().missCount == 3);
+ SLANG_CHECK(getStats().hitCount == 0);
+ SLANG_CHECK(getStats().entryCount == 3);
+ });
+
+ // Cache is hot and we expect 3 hits.
+ runStep(
+ [this]()
+ {
+ SLANG_CHECK(runComputePipeline(
+ "shader-cache-multiple-entry-points",
+ "computeA",
+ {1.f, 2.f, 3.f, 4.f}));
+ SLANG_CHECK(runComputePipeline(
+ "shader-cache-multiple-entry-points",
+ "computeB",
+ {2.f, 3.f, 4.f, 5.f}));
+ SLANG_CHECK(runComputePipeline(
+ "shader-cache-multiple-entry-points",
+ "computeC",
+ {3.f, 4.f, 5.f, 6.f}));
+
+ SLANG_CHECK(getStats().missCount == 0);
+ SLANG_CHECK(getStats().hitCount == 3);
+ SLANG_CHECK(getStats().entryCount == 3);
+ });
+ }
+};
+
+// Test cache invalidation due to an import/include file being changed on disk.
+struct ShaderCacheTestImportInclude : ShaderCacheTest
+{
+ String importedContentsA = String(
+ R"(
public void processElement(RWStructuredBuffer<float> buffer, uint index)
{
var input = buffer[index];
@@ -437,8 +460,8 @@ namespace gfx_test
}
)");
- String importedContentsB = String(
- R"(
+ String importedContentsB = String(
+ R"(
public void processElement(RWStructuredBuffer<float> buffer, uint index)
{
var input = buffer[index];
@@ -446,8 +469,8 @@ namespace gfx_test
}
)");
- String importFile = String(
- R"(
+ String importFile = String(
+ R"(
import shader_cache_tmp_imported;
[shader("compute")]
@@ -460,8 +483,8 @@ namespace gfx_test
}
)");
- String includeFile = String(
- R"(
+ String includeFile = String(
+ R"(
#include "shader-cache-tmp-imported.slang"
[shader("compute")]
@@ -473,627 +496,635 @@ namespace gfx_test
processElement(buffer, sv_dispatchThreadID.x);
})");
- void runTests()
- {
- // Write shader source files.
- writeShader(importedContentsA, "shader-cache-tmp-imported.slang");
- writeShader(importFile, "shader-cache-tmp-import.slang");
- writeShader(includeFile, "shader-cache-tmp-include.slang");
-
- // Cache is cold and we expect 2 misses.
- runStep(
- [this]()
- {
- SLANG_CHECK(runComputePipeline("shader-cache-tmp-import", "main", { 1.f, 2.f, 3.f, 4.f }));
- SLANG_CHECK(runComputePipeline("shader-cache-tmp-include", "main", { 1.f, 2.f, 3.f, 4.f }));
-
- SLANG_CHECK(getStats().missCount == 2);
- SLANG_CHECK(getStats().hitCount == 0);
- SLANG_CHECK(getStats().entryCount == 2);
- }
- );
-
- // Cache is hot and we expect 2 hits.
- runStep(
- [this]()
- {
- SLANG_CHECK(runComputePipeline("shader-cache-tmp-import", "main", { 1.f, 2.f, 3.f, 4.f }));
- SLANG_CHECK(runComputePipeline("shader-cache-tmp-include", "main", { 1.f, 2.f, 3.f, 4.f }));
-
- SLANG_CHECK(getStats().missCount == 0);
- SLANG_CHECK(getStats().hitCount == 2);
- SLANG_CHECK(getStats().entryCount == 2);
- }
- );
-
- // Change content of imported/included shader file.
- writeShader(importedContentsB, "shader-cache-tmp-imported.slang");
-
- // Cache is cold and we expect 2 misses.
- runStep(
- [this]()
- {
- SLANG_CHECK(runComputePipeline("shader-cache-tmp-import", "main", { 2.f, 3.f, 4.f, 5.f }));
- SLANG_CHECK(runComputePipeline("shader-cache-tmp-include", "main", { 2.f, 3.f, 4.f, 5.f }));
-
- SLANG_CHECK(getStats().missCount == 2);
- SLANG_CHECK(getStats().hitCount == 0);
- SLANG_CHECK(getStats().entryCount == 4);
- }
- );
-
- // Cache is hot and we expect 2 hits.
- runStep(
- [this]()
- {
- SLANG_CHECK(runComputePipeline("shader-cache-tmp-import", "main", { 2.f, 3.f, 4.f, 5.f }));
- SLANG_CHECK(runComputePipeline("shader-cache-tmp-include", "main", { 2.f, 3.f, 4.f, 5.f }));
-
- SLANG_CHECK(getStats().missCount == 0);
- SLANG_CHECK(getStats().hitCount == 2);
- SLANG_CHECK(getStats().entryCount == 4);
- }
- );
- }
- };
-
- // One shader featuring multiple kinds of shader objects that can be bound.
- struct ShaderCacheTestSpecialization : ShaderCacheTest
+ void runTests()
{
- slang::ProgramLayout* slangReflection;
-
- void createComputePipeline()
- {
- ComPtr<IShaderProgram> shaderProgram;
-
- GFX_CHECK_CALL_ABORT(
- loadComputeProgram(device, shaderProgram, "shader-cache-specialization", "computeMain", slangReflection));
-
- ComputePipelineStateDesc pipelineDesc = {};
- pipelineDesc.program = shaderProgram.get();
- GFX_CHECK_CALL_ABORT(
- device->createComputePipelineState(pipelineDesc, pipelineState.writeRef()));
- }
-
- void dispatchComputePipeline(const char* transformerTypeName)
- {
- 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);
+ // Write shader source files.
+ writeShader(importedContentsA, "shader-cache-tmp-imported.slang");
+ writeShader(importFile, "shader-cache-tmp-import.slang");
+ writeShader(includeFile, "shader-cache-tmp-include.slang");
+
+ // Cache is cold and we expect 2 misses.
+ runStep(
+ [this]()
+ {
+ SLANG_CHECK(
+ runComputePipeline("shader-cache-tmp-import", "main", {1.f, 2.f, 3.f, 4.f}));
+ SLANG_CHECK(
+ runComputePipeline("shader-cache-tmp-include", "main", {1.f, 2.f, 3.f, 4.f}));
+
+ SLANG_CHECK(getStats().missCount == 2);
+ SLANG_CHECK(getStats().hitCount == 0);
+ SLANG_CHECK(getStats().entryCount == 2);
+ });
+
+ // Cache is hot and we expect 2 hits.
+ runStep(
+ [this]()
+ {
+ SLANG_CHECK(
+ runComputePipeline("shader-cache-tmp-import", "main", {1.f, 2.f, 3.f, 4.f}));
+ SLANG_CHECK(
+ runComputePipeline("shader-cache-tmp-include", "main", {1.f, 2.f, 3.f, 4.f}));
+
+ SLANG_CHECK(getStats().missCount == 0);
+ SLANG_CHECK(getStats().hitCount == 2);
+ SLANG_CHECK(getStats().entryCount == 2);
+ });
+
+ // Change content of imported/included shader file.
+ writeShader(importedContentsB, "shader-cache-tmp-imported.slang");
+
+ // Cache is cold and we expect 2 misses.
+ runStep(
+ [this]()
+ {
+ SLANG_CHECK(
+ runComputePipeline("shader-cache-tmp-import", "main", {2.f, 3.f, 4.f, 5.f}));
+ SLANG_CHECK(
+ runComputePipeline("shader-cache-tmp-include", "main", {2.f, 3.f, 4.f, 5.f}));
+
+ SLANG_CHECK(getStats().missCount == 2);
+ SLANG_CHECK(getStats().hitCount == 0);
+ SLANG_CHECK(getStats().entryCount == 4);
+ });
+
+ // Cache is hot and we expect 2 hits.
+ runStep(
+ [this]()
+ {
+ SLANG_CHECK(
+ runComputePipeline("shader-cache-tmp-import", "main", {2.f, 3.f, 4.f, 5.f}));
+ SLANG_CHECK(
+ runComputePipeline("shader-cache-tmp-include", "main", {2.f, 3.f, 4.f, 5.f}));
+
+ SLANG_CHECK(getStats().missCount == 0);
+ SLANG_CHECK(getStats().hitCount == 2);
+ SLANG_CHECK(getStats().entryCount == 4);
+ });
+ }
+};
- Slang::ComPtr<IShaderObject> transformer;
- slang::TypeReflection* transformerType = slangReflection->findTypeByName(transformerTypeName);
- GFX_CHECK_CALL_ABORT(device->createShaderObject(
- transformerType, ShaderObjectContainerType::None, transformer.writeRef()));
+// One shader featuring multiple kinds of shader objects that can be bound.
+struct ShaderCacheTestSpecialization : ShaderCacheTest
+{
+ slang::ProgramLayout* slangReflection;
- float c = 5.f;
- ShaderCursor(transformer).getPath("c").setData(&c, sizeof(float));
+ void createComputePipeline()
+ {
+ ComPtr<IShaderProgram> shaderProgram;
+
+ GFX_CHECK_CALL_ABORT(loadComputeProgram(
+ device,
+ shaderProgram,
+ "shader-cache-specialization",
+ "computeMain",
+ slangReflection));
+
+ ComputePipelineStateDesc pipelineDesc = {};
+ pipelineDesc.program = shaderProgram.get();
+ GFX_CHECK_CALL_ABORT(
+ device->createComputePipelineState(pipelineDesc, pipelineState.writeRef()));
+ }
- ShaderCursor entryPointCursor(rootObject->getEntryPoint(0));
- entryPointCursor.getPath("buffer").setResource(bufferView);
- entryPointCursor.getPath("transformer").setObject(transformer);
+ void dispatchComputePipeline(const char* transformerTypeName)
+ {
+ 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);
+
+ Slang::ComPtr<IShaderObject> transformer;
+ slang::TypeReflection* transformerType =
+ slangReflection->findTypeByName(transformerTypeName);
+ GFX_CHECK_CALL_ABORT(device->createShaderObject(
+ transformerType,
+ ShaderObjectContainerType::None,
+ transformer.writeRef()));
+
+ float c = 5.f;
+ ShaderCursor(transformer).getPath("c").setData(&c, sizeof(float));
+
+ 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();
+ }
- encoder->dispatchCompute(1, 1, 1);
- encoder->endEncoding();
- commandBuffer->close();
- queue->executeCommandBuffer(commandBuffer);
- queue->waitOnHost();
- }
+ bool runComputePipeline(const char* transformerTypeName, const List<float>& expectedOutput)
+ {
+ createComputeResources();
+ createComputePipeline();
+ dispatchComputePipeline(transformerTypeName);
+ bool hasExpectedOutput = checkOutput(expectedOutput);
+ SLANG_CHECK(hasExpectedOutput);
+ freeComputeResources();
+ return hasExpectedOutput;
+ }
- bool runComputePipeline(const char* transformerTypeName, const List<float>& expectedOutput)
- {
- createComputeResources();
- createComputePipeline();
- dispatchComputePipeline(transformerTypeName);
- bool hasExpectedOutput = checkOutput(expectedOutput);
- SLANG_CHECK(hasExpectedOutput);
- freeComputeResources();
- return hasExpectedOutput;
- }
-
- void runTests()
- {
- // Cache is cold and we expect 2 misses.
- runStep(
- [this]()
- {
- SLANG_CHECK(runComputePipeline("AddTransformer", { 5.f, 6.f, 7.f, 8.f }));
- SLANG_CHECK(runComputePipeline("MulTransformer", { 0.f, 5.f, 10.f, 15.f }));
+ void runTests()
+ {
+ // Cache is cold and we expect 2 misses.
+ runStep(
+ [this]()
+ {
+ SLANG_CHECK(runComputePipeline("AddTransformer", {5.f, 6.f, 7.f, 8.f}));
+ SLANG_CHECK(runComputePipeline("MulTransformer", {0.f, 5.f, 10.f, 15.f}));
- SLANG_CHECK(getStats().missCount == 2);
- SLANG_CHECK(getStats().hitCount == 0);
- SLANG_CHECK(getStats().entryCount == 2);
- }
- );
+ SLANG_CHECK(getStats().missCount == 2);
+ SLANG_CHECK(getStats().hitCount == 0);
+ SLANG_CHECK(getStats().entryCount == 2);
+ });
- // Cache is hot and we expect 2 hits.
- runStep(
- [this]()
- {
- SLANG_CHECK(runComputePipeline("AddTransformer", { 5.f, 6.f, 7.f, 8.f }));
- SLANG_CHECK(runComputePipeline("MulTransformer", { 0.f, 5.f, 10.f, 15.f }));
+ // Cache is hot and we expect 2 hits.
+ runStep(
+ [this]()
+ {
+ SLANG_CHECK(runComputePipeline("AddTransformer", {5.f, 6.f, 7.f, 8.f}));
+ SLANG_CHECK(runComputePipeline("MulTransformer", {0.f, 5.f, 10.f, 15.f}));
- SLANG_CHECK(getStats().missCount == 0);
- SLANG_CHECK(getStats().hitCount == 2);
- SLANG_CHECK(getStats().entryCount == 2);
- }
- );
- }
- };
+ SLANG_CHECK(getStats().missCount == 0);
+ SLANG_CHECK(getStats().hitCount == 2);
+ SLANG_CHECK(getStats().entryCount == 2);
+ });
+ }
+};
- struct ShaderCacheTestEviction : ShaderCacheTest
+struct ShaderCacheTestEviction : ShaderCacheTest
+{
+ void runTests()
{
- void runTests()
- {
- shaderCacheDesc.maxEntryCount = 2;
+ shaderCacheDesc.maxEntryCount = 2;
- // Load shader A & B. Cache is cold and we expect 2 misses.
- runStep(
- [this]()
- {
- SLANG_CHECK(runComputePipeline(computeShaderA, { 1.f, 2.f, 3.f, 4.f }));
- SLANG_CHECK(runComputePipeline(computeShaderB, { 2.f, 3.f, 4.f, 5.f }));
-
- SLANG_CHECK(getStats().missCount == 2);
- SLANG_CHECK(getStats().hitCount == 0);
- SLANG_CHECK(getStats().entryCount == 2);
- }
- );
-
- // Load shader A & B. Cache is hot and we expect 2 hits.
- runStep(
- [this]()
- {
- SLANG_CHECK(runComputePipeline(computeShaderA, { 1.f, 2.f, 3.f, 4.f }));
- SLANG_CHECK(runComputePipeline(computeShaderB, { 2.f, 3.f, 4.f, 5.f }));
+ // Load shader A & B. Cache is cold and we expect 2 misses.
+ runStep(
+ [this]()
+ {
+ SLANG_CHECK(runComputePipeline(computeShaderA, {1.f, 2.f, 3.f, 4.f}));
+ SLANG_CHECK(runComputePipeline(computeShaderB, {2.f, 3.f, 4.f, 5.f}));
- SLANG_CHECK(getStats().missCount == 0);
- SLANG_CHECK(getStats().hitCount == 2);
- SLANG_CHECK(getStats().entryCount == 2);
- }
- );
+ SLANG_CHECK(getStats().missCount == 2);
+ SLANG_CHECK(getStats().hitCount == 0);
+ SLANG_CHECK(getStats().entryCount == 2);
+ });
- // Load shader C. Cache is cold and we expect 1 miss.
- // This will evict the least frequently used entry (shader A).
- // We expect 2 entries in the cache (shader B & C).
- runStep(
- [this]()
- {
- SLANG_CHECK(runComputePipeline(computeShaderC, { 3.f, 4.f, 5.f, 6.f }));
+ // Load shader A & B. Cache is hot and we expect 2 hits.
+ runStep(
+ [this]()
+ {
+ SLANG_CHECK(runComputePipeline(computeShaderA, {1.f, 2.f, 3.f, 4.f}));
+ SLANG_CHECK(runComputePipeline(computeShaderB, {2.f, 3.f, 4.f, 5.f}));
+
+ SLANG_CHECK(getStats().missCount == 0);
+ SLANG_CHECK(getStats().hitCount == 2);
+ SLANG_CHECK(getStats().entryCount == 2);
+ });
+
+ // Load shader C. Cache is cold and we expect 1 miss.
+ // This will evict the least frequently used entry (shader A).
+ // We expect 2 entries in the cache (shader B & C).
+ runStep(
+ [this]()
+ {
+ SLANG_CHECK(runComputePipeline(computeShaderC, {3.f, 4.f, 5.f, 6.f}));
- SLANG_CHECK(getStats().missCount == 1);
- SLANG_CHECK(getStats().hitCount == 0);
- SLANG_CHECK(getStats().entryCount == 2);
- }
- );
+ SLANG_CHECK(getStats().missCount == 1);
+ SLANG_CHECK(getStats().hitCount == 0);
+ SLANG_CHECK(getStats().entryCount == 2);
+ });
- // Load shader C. Cache is hot and we expect 1 hit.
- runStep(
- [this]()
- {
- SLANG_CHECK(runComputePipeline(computeShaderC, { 3.f, 4.f, 5.f, 6.f }));
+ // Load shader C. Cache is hot and we expect 1 hit.
+ runStep(
+ [this]()
+ {
+ SLANG_CHECK(runComputePipeline(computeShaderC, {3.f, 4.f, 5.f, 6.f}));
- SLANG_CHECK(getStats().missCount == 0);
- SLANG_CHECK(getStats().hitCount == 1);
- SLANG_CHECK(getStats().entryCount == 2);
- }
- );
+ SLANG_CHECK(getStats().missCount == 0);
+ SLANG_CHECK(getStats().hitCount == 1);
+ SLANG_CHECK(getStats().entryCount == 2);
+ });
- // Load shader B. Cache is hot and we expect 1 hit.
- runStep(
- [this]()
- {
- SLANG_CHECK(runComputePipeline(computeShaderB, { 2.f, 3.f, 4.f, 5.f }));
+ // Load shader B. Cache is hot and we expect 1 hit.
+ runStep(
+ [this]()
+ {
+ SLANG_CHECK(runComputePipeline(computeShaderB, {2.f, 3.f, 4.f, 5.f}));
- SLANG_CHECK(getStats().missCount == 0);
- SLANG_CHECK(getStats().hitCount == 1);
- SLANG_CHECK(getStats().entryCount == 2);
- }
- );
+ SLANG_CHECK(getStats().missCount == 0);
+ SLANG_CHECK(getStats().hitCount == 1);
+ SLANG_CHECK(getStats().entryCount == 2);
+ });
- // Load shader A. Cache is cold and we expect 1 miss.
- runStep(
- [this]()
- {
- SLANG_CHECK(runComputePipeline(computeShaderA, { 1.f, 2.f, 3.f, 4.f }));
+ // Load shader A. Cache is cold and we expect 1 miss.
+ runStep(
+ [this]()
+ {
+ SLANG_CHECK(runComputePipeline(computeShaderA, {1.f, 2.f, 3.f, 4.f}));
- SLANG_CHECK(getStats().missCount == 1);
- SLANG_CHECK(getStats().hitCount == 0);
- SLANG_CHECK(getStats().entryCount == 2);
- }
- );
- }
- };
+ SLANG_CHECK(getStats().missCount == 1);
+ SLANG_CHECK(getStats().hitCount == 0);
+ SLANG_CHECK(getStats().entryCount == 2);
+ });
+ }
+};
- // Similar to ShaderCacheTestEntryPoint but with a source file containing a vertex and fragment shader.
- struct ShaderCacheTestGraphics : ShaderCacheTest
+// Similar to ShaderCacheTestEntryPoint but with a source file containing a vertex and fragment
+// shader.
+struct ShaderCacheTestGraphics : ShaderCacheTest
+{
+ struct Vertex
{
- struct Vertex
- {
- float position[3];
- };
-
- static const int kWidth = 256;
- static const int kHeight = 256;
- static const Format format = Format::R32G32B32A32_FLOAT;
-
- ComPtr<IBufferResource> vertexBuffer;
- ComPtr<ITextureResource> colorBuffer;
- ComPtr<IInputLayout> inputLayout;
- ComPtr<IFramebufferLayout> framebufferLayout;
- ComPtr<IRenderPassLayout> renderPass;
- ComPtr<IFramebuffer> framebuffer;
-
- ComPtr<IBufferResource> createVertexBuffer(IDevice* device)
- {
- const Vertex vertices[] = {
- { 0, 0, 0.5 },
- { 1, 0, 0.5 },
- { 0, 1, 0.5 },
- };
-
- IBufferResource::Desc vertexBufferDesc;
- vertexBufferDesc.type = IResource::Type::Buffer;
- vertexBufferDesc.sizeInBytes = sizeof(vertices);
- vertexBufferDesc.defaultState = ResourceState::VertexBuffer;
- vertexBufferDesc.allowedStates = ResourceState::VertexBuffer;
- ComPtr<IBufferResource> vertexBuffer = device->createBufferResource(vertexBufferDesc, vertices);
- SLANG_CHECK_ABORT(vertexBuffer != nullptr);
- return vertexBuffer;
- }
-
- ComPtr<ITextureResource> createColorBuffer(IDevice* device)
- {
- gfx::ITextureResource::Desc colorBufferDesc;
- colorBufferDesc.type = IResource::Type::Texture2D;
- colorBufferDesc.size.width = kWidth;
- colorBufferDesc.size.height = kHeight;
- colorBufferDesc.size.depth = 1;
- colorBufferDesc.numMipLevels = 1;
- colorBufferDesc.format = format;
- colorBufferDesc.defaultState = ResourceState::RenderTarget;
- colorBufferDesc.allowedStates = { ResourceState::RenderTarget, ResourceState::CopySource };
- ComPtr<ITextureResource> colorBuffer = device->createTextureResource(colorBufferDesc, nullptr);
- SLANG_CHECK_ABORT(colorBuffer != nullptr);
- return colorBuffer;
- }
-
- void createGraphicsResources()
- {
- VertexStreamDesc vertexStreams[] = {
- { sizeof(Vertex), InputSlotClass::PerVertex, 0 },
- };
-
- InputElementDesc inputElements[] = {
- // Vertex buffer data
- { "POSITION", 0, Format::R32G32B32_FLOAT, offsetof(Vertex, position), 0 },
- };
- IInputLayout::Desc inputLayoutDesc = {};
- inputLayoutDesc.inputElementCount = SLANG_COUNT_OF(inputElements);
- inputLayoutDesc.inputElements = inputElements;
- inputLayoutDesc.vertexStreamCount = SLANG_COUNT_OF(vertexStreams);
- inputLayoutDesc.vertexStreams = vertexStreams;
- inputLayout = device->createInputLayout(inputLayoutDesc);
- SLANG_CHECK_ABORT(inputLayout != nullptr);
-
- vertexBuffer = createVertexBuffer(device);
- colorBuffer = createColorBuffer(device);
-
- IFramebufferLayout::TargetLayout targetLayout;
- targetLayout.format = format;
- targetLayout.sampleCount = 1;
-
- IFramebufferLayout::Desc framebufferLayoutDesc;
- framebufferLayoutDesc.renderTargetCount = 1;
- framebufferLayoutDesc.renderTargets = &targetLayout;
- framebufferLayout = device->createFramebufferLayout(framebufferLayoutDesc);
- SLANG_CHECK_ABORT(framebufferLayout != nullptr);
-
- IRenderPassLayout::Desc renderPassDesc = {};
- renderPassDesc.framebufferLayout = framebufferLayout;
- renderPassDesc.renderTargetCount = 1;
- IRenderPassLayout::TargetAccessDesc renderTargetAccess = {};
- renderTargetAccess.loadOp = IRenderPassLayout::TargetLoadOp::Clear;
- renderTargetAccess.storeOp = IRenderPassLayout::TargetStoreOp::Store;
- renderTargetAccess.initialState = ResourceState::RenderTarget;
- renderTargetAccess.finalState = ResourceState::CopySource;
- renderPassDesc.renderTargetAccess = &renderTargetAccess;
- GFX_CHECK_CALL_ABORT(device->createRenderPassLayout(renderPassDesc, renderPass.writeRef()));
-
- gfx::IResourceView::Desc colorBufferViewDesc;
- memset(&colorBufferViewDesc, 0, sizeof(colorBufferViewDesc));
- colorBufferViewDesc.format = format;
- colorBufferViewDesc.renderTarget.shape = gfx::IResource::Type::Texture2D;
- colorBufferViewDesc.type = gfx::IResourceView::Type::RenderTarget;
- auto rtv = device->createTextureView(colorBuffer, colorBufferViewDesc);
-
- gfx::IFramebuffer::Desc framebufferDesc;
- framebufferDesc.renderTargetCount = 1;
- framebufferDesc.depthStencilView = nullptr;
- framebufferDesc.renderTargetViews = rtv.readRef();
- framebufferDesc.layout = framebufferLayout;
- GFX_CHECK_CALL_ABORT(device->createFramebuffer(framebufferDesc, framebuffer.writeRef()));
- }
-
- void freeGraphicsResources()
- {
- inputLayout = nullptr;
- framebufferLayout = nullptr;
- renderPass = nullptr;
- framebuffer = nullptr;
- vertexBuffer = nullptr;
- colorBuffer = nullptr;
- pipelineState = nullptr;
- }
-
- void createGraphicsPipeline()
- {
- ComPtr<IShaderProgram> shaderProgram;
- slang::ProgramLayout* slangReflection;
- GFX_CHECK_CALL_ABORT(
- loadGraphicsProgram(device, shaderProgram, "shader-cache-graphics", "vertexMain", "fragmentMain", slangReflection));
-
- GraphicsPipelineStateDesc pipelineDesc = {};
- pipelineDesc.program = shaderProgram.get();
- pipelineDesc.inputLayout = inputLayout;
- pipelineDesc.framebufferLayout = framebufferLayout;
- pipelineDesc.depthStencil.depthTestEnable = false;
- pipelineDesc.depthStencil.depthWriteEnable = false;
- GFX_CHECK_CALL_ABORT(
- device->createGraphicsPipelineState(pipelineDesc, pipelineState.writeRef()));
- }
-
- void dispatchGraphicsPipeline()
- {
- 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->encodeRenderCommands(renderPass, framebuffer);
- auto rootObject = encoder->bindPipeline(pipelineState);
-
- gfx::Viewport viewport = {};
- viewport.maxZ = 1.0f;
- viewport.extentX = (float)kWidth;
- viewport.extentY = (float)kHeight;
- encoder->setViewportAndScissor(viewport);
-
- encoder->setVertexBuffer(0, vertexBuffer);
- encoder->setPrimitiveTopology(PrimitiveTopology::TriangleList);
-
- encoder->draw(3);
- encoder->endEncoding();
- commandBuffer->close();
- queue->executeCommandBuffer(commandBuffer);
- queue->waitOnHost();
- }
-
- void runGraphicsPipeline()
- {
- createGraphicsResources();
- createGraphicsPipeline();
- dispatchGraphicsPipeline();
- freeGraphicsResources();
- }
-
- void runTests()
- {
- // Cache is cold and we expect 2 misses (2 entry points).
- runStep(
- [this]()
- {
- runGraphicsPipeline();
-
- SLANG_CHECK(getStats().missCount == 2);
- SLANG_CHECK(getStats().hitCount == 0);
- SLANG_CHECK(getStats().entryCount == 2);
- }
- );
-
- // Cache is hot and we expect 2 hits.
- runStep(
- [this]()
- {
- runGraphicsPipeline();
-
- SLANG_CHECK(getStats().missCount == 0);
- SLANG_CHECK(getStats().hitCount == 2);
- SLANG_CHECK(getStats().entryCount == 2);
- }
- );
- }
+ float position[3];
};
- // Similar to ShaderCacheTestGraphics but with two separate shader files for the vertex and fragment shaders.
- struct ShaderCacheTestGraphicsSplit : ShaderCacheTestGraphics
- {
- void createGraphicsPipeline()
- {
- ComPtr<slang::ISession> slangSession;
- GFX_CHECK_CALL_ABORT(device->getSlangSession(slangSession.writeRef()));
- slang::IModule* vertexModule = slangSession->loadModule("shader-cache-graphics-vertex");
- SLANG_CHECK_ABORT(vertexModule);
- slang::IModule* fragmentModule = slangSession->loadModule("shader-cache-graphics-fragment");
- SLANG_CHECK_ABORT(fragmentModule);
-
- ComPtr<slang::IEntryPoint> vertexEntryPoint;
- GFX_CHECK_CALL_ABORT(
- vertexModule->findEntryPointByName("main", vertexEntryPoint.writeRef()));
-
- ComPtr<slang::IEntryPoint> fragmentEntryPoint;
- GFX_CHECK_CALL_ABORT(
- fragmentModule->findEntryPointByName("main", fragmentEntryPoint.writeRef()));
-
- Slang::List<slang::IComponentType*> componentTypes;
- componentTypes.add(vertexModule);
- componentTypes.add(fragmentModule);
-
- Slang::ComPtr<slang::IComponentType> composedProgram;
- GFX_CHECK_CALL_ABORT(
- slangSession->createCompositeComponentType(
- componentTypes.getBuffer(),
- componentTypes.getCount(),
- composedProgram.writeRef()));
-
- slang::ProgramLayout* slangReflection = composedProgram->getLayout();
-
- Slang::List<slang::IComponentType*> entryPoints;
- entryPoints.add(vertexEntryPoint);
- entryPoints.add(fragmentEntryPoint);
-
- gfx::IShaderProgram::Desc programDesc = {};
- programDesc.slangGlobalScope = composedProgram.get();
- programDesc.linkingStyle = gfx::IShaderProgram::LinkingStyle::SeparateEntryPointCompilation;
- programDesc.entryPointCount = 2;
- programDesc.slangEntryPoints = entryPoints.getBuffer();
-
- ComPtr<IShaderProgram> shaderProgram = device->createProgram(programDesc);
-
- GraphicsPipelineStateDesc pipelineDesc = {};
- pipelineDesc.program = shaderProgram.get();
- pipelineDesc.inputLayout = inputLayout;
- pipelineDesc.framebufferLayout = framebufferLayout;
- pipelineDesc.depthStencil.depthTestEnable = false;
- pipelineDesc.depthStencil.depthWriteEnable = false;
- GFX_CHECK_CALL_ABORT(
- device->createGraphicsPipelineState(pipelineDesc, pipelineState.writeRef()));
- }
-
- void runGraphicsPipeline()
- {
- createGraphicsResources();
- createGraphicsPipeline();
- dispatchGraphicsPipeline();
- freeGraphicsResources();
- }
-
- void runTests()
- {
- // Cache is cold and we expect 2 misses (2 entry points).
- runStep(
- [this]()
- {
- runGraphicsPipeline();
+ static const int kWidth = 256;
+ static const int kHeight = 256;
+ static const Format format = Format::R32G32B32A32_FLOAT;
- SLANG_CHECK(getStats().missCount == 2);
- SLANG_CHECK(getStats().hitCount == 0);
- SLANG_CHECK(getStats().entryCount == 2);
- }
- );
-
- // Cache is hot and we expect 2 hits.
- runStep(
- [this]()
- {
- runGraphicsPipeline();
-
- SLANG_CHECK(getStats().missCount == 0);
- SLANG_CHECK(getStats().hitCount == 2);
- SLANG_CHECK(getStats().entryCount == 2);
- }
- ); }
- };
+ ComPtr<IBufferResource> vertexBuffer;
+ ComPtr<ITextureResource> colorBuffer;
+ ComPtr<IInputLayout> inputLayout;
+ ComPtr<IFramebufferLayout> framebufferLayout;
+ ComPtr<IRenderPassLayout> renderPass;
+ ComPtr<IFramebuffer> framebuffer;
- template<typename T>
- void runTest(UnitTestContext* context, Slang::RenderApiFlag::Enum api)
+ ComPtr<IBufferResource> createVertexBuffer(IDevice* device)
{
- T test;
- test.run(context, api);
- }
+ const Vertex vertices[] = {
+ {0, 0, 0.5},
+ {1, 0, 0.5},
+ {0, 1, 0.5},
+ };
- SLANG_UNIT_TEST(shaderCacheSourceFileD3D12)
- {
- runTest<ShaderCacheSourceFile>(unitTestContext, Slang::RenderApiFlag::D3D12);
+ IBufferResource::Desc vertexBufferDesc;
+ vertexBufferDesc.type = IResource::Type::Buffer;
+ vertexBufferDesc.sizeInBytes = sizeof(vertices);
+ vertexBufferDesc.defaultState = ResourceState::VertexBuffer;
+ vertexBufferDesc.allowedStates = ResourceState::VertexBuffer;
+ ComPtr<IBufferResource> vertexBuffer =
+ device->createBufferResource(vertexBufferDesc, vertices);
+ SLANG_CHECK_ABORT(vertexBuffer != nullptr);
+ return vertexBuffer;
}
- SLANG_UNIT_TEST(shaderCacheSourceFileVulkan)
+ ComPtr<ITextureResource> createColorBuffer(IDevice* device)
{
- runTest<ShaderCacheSourceFile>(unitTestContext, Slang::RenderApiFlag::Vulkan);
+ gfx::ITextureResource::Desc colorBufferDesc;
+ colorBufferDesc.type = IResource::Type::Texture2D;
+ colorBufferDesc.size.width = kWidth;
+ colorBufferDesc.size.height = kHeight;
+ colorBufferDesc.size.depth = 1;
+ colorBufferDesc.numMipLevels = 1;
+ colorBufferDesc.format = format;
+ colorBufferDesc.defaultState = ResourceState::RenderTarget;
+ colorBufferDesc.allowedStates = {ResourceState::RenderTarget, ResourceState::CopySource};
+ ComPtr<ITextureResource> colorBuffer =
+ device->createTextureResource(colorBufferDesc, nullptr);
+ SLANG_CHECK_ABORT(colorBuffer != nullptr);
+ return colorBuffer;
}
- SLANG_UNIT_TEST(shaderCacheSourceStringD3D12)
+ void createGraphicsResources()
{
- runTest<ShaderCacheTestSourceString>(unitTestContext, Slang::RenderApiFlag::D3D12);
- }
+ VertexStreamDesc vertexStreams[] = {
+ {sizeof(Vertex), InputSlotClass::PerVertex, 0},
+ };
- SLANG_UNIT_TEST(shaderCacheSourceStringVulkan)
- {
- runTest<ShaderCacheTestSourceString>(unitTestContext, Slang::RenderApiFlag::Vulkan);
+ InputElementDesc inputElements[] = {
+ // Vertex buffer data
+ {"POSITION", 0, Format::R32G32B32_FLOAT, offsetof(Vertex, position), 0},
+ };
+ IInputLayout::Desc inputLayoutDesc = {};
+ inputLayoutDesc.inputElementCount = SLANG_COUNT_OF(inputElements);
+ inputLayoutDesc.inputElements = inputElements;
+ inputLayoutDesc.vertexStreamCount = SLANG_COUNT_OF(vertexStreams);
+ inputLayoutDesc.vertexStreams = vertexStreams;
+ inputLayout = device->createInputLayout(inputLayoutDesc);
+ SLANG_CHECK_ABORT(inputLayout != nullptr);
+
+ vertexBuffer = createVertexBuffer(device);
+ colorBuffer = createColorBuffer(device);
+
+ IFramebufferLayout::TargetLayout targetLayout;
+ targetLayout.format = format;
+ targetLayout.sampleCount = 1;
+
+ IFramebufferLayout::Desc framebufferLayoutDesc;
+ framebufferLayoutDesc.renderTargetCount = 1;
+ framebufferLayoutDesc.renderTargets = &targetLayout;
+ framebufferLayout = device->createFramebufferLayout(framebufferLayoutDesc);
+ SLANG_CHECK_ABORT(framebufferLayout != nullptr);
+
+ IRenderPassLayout::Desc renderPassDesc = {};
+ renderPassDesc.framebufferLayout = framebufferLayout;
+ renderPassDesc.renderTargetCount = 1;
+ IRenderPassLayout::TargetAccessDesc renderTargetAccess = {};
+ renderTargetAccess.loadOp = IRenderPassLayout::TargetLoadOp::Clear;
+ renderTargetAccess.storeOp = IRenderPassLayout::TargetStoreOp::Store;
+ renderTargetAccess.initialState = ResourceState::RenderTarget;
+ renderTargetAccess.finalState = ResourceState::CopySource;
+ renderPassDesc.renderTargetAccess = &renderTargetAccess;
+ GFX_CHECK_CALL_ABORT(device->createRenderPassLayout(renderPassDesc, renderPass.writeRef()));
+
+ gfx::IResourceView::Desc colorBufferViewDesc;
+ memset(&colorBufferViewDesc, 0, sizeof(colorBufferViewDesc));
+ colorBufferViewDesc.format = format;
+ colorBufferViewDesc.renderTarget.shape = gfx::IResource::Type::Texture2D;
+ colorBufferViewDesc.type = gfx::IResourceView::Type::RenderTarget;
+ auto rtv = device->createTextureView(colorBuffer, colorBufferViewDesc);
+
+ gfx::IFramebuffer::Desc framebufferDesc;
+ framebufferDesc.renderTargetCount = 1;
+ framebufferDesc.depthStencilView = nullptr;
+ framebufferDesc.renderTargetViews = rtv.readRef();
+ framebufferDesc.layout = framebufferLayout;
+ GFX_CHECK_CALL_ABORT(device->createFramebuffer(framebufferDesc, framebuffer.writeRef()));
}
- SLANG_UNIT_TEST(shaderCacheEntryPointD3D12)
+ void freeGraphicsResources()
{
- runTest<ShaderCacheTestEntryPoint>(unitTestContext, Slang::RenderApiFlag::D3D12);
+ inputLayout = nullptr;
+ framebufferLayout = nullptr;
+ renderPass = nullptr;
+ framebuffer = nullptr;
+ vertexBuffer = nullptr;
+ colorBuffer = nullptr;
+ pipelineState = nullptr;
}
- SLANG_UNIT_TEST(shaderCacheEntryPointVulkan)
+ void createGraphicsPipeline()
{
- runTest<ShaderCacheTestEntryPoint>(unitTestContext, Slang::RenderApiFlag::Vulkan);
+ ComPtr<IShaderProgram> shaderProgram;
+ slang::ProgramLayout* slangReflection;
+ GFX_CHECK_CALL_ABORT(loadGraphicsProgram(
+ device,
+ shaderProgram,
+ "shader-cache-graphics",
+ "vertexMain",
+ "fragmentMain",
+ slangReflection));
+
+ GraphicsPipelineStateDesc pipelineDesc = {};
+ pipelineDesc.program = shaderProgram.get();
+ pipelineDesc.inputLayout = inputLayout;
+ pipelineDesc.framebufferLayout = framebufferLayout;
+ pipelineDesc.depthStencil.depthTestEnable = false;
+ pipelineDesc.depthStencil.depthWriteEnable = false;
+ GFX_CHECK_CALL_ABORT(
+ device->createGraphicsPipelineState(pipelineDesc, pipelineState.writeRef()));
}
- SLANG_UNIT_TEST(shaderCacheImportIncludeD3D12)
+ void dispatchGraphicsPipeline()
{
- runTest<ShaderCacheTestImportInclude>(unitTestContext, Slang::RenderApiFlag::D3D12);
+ 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->encodeRenderCommands(renderPass, framebuffer);
+ auto rootObject = encoder->bindPipeline(pipelineState);
+
+ gfx::Viewport viewport = {};
+ viewport.maxZ = 1.0f;
+ viewport.extentX = (float)kWidth;
+ viewport.extentY = (float)kHeight;
+ encoder->setViewportAndScissor(viewport);
+
+ encoder->setVertexBuffer(0, vertexBuffer);
+ encoder->setPrimitiveTopology(PrimitiveTopology::TriangleList);
+
+ encoder->draw(3);
+ encoder->endEncoding();
+ commandBuffer->close();
+ queue->executeCommandBuffer(commandBuffer);
+ queue->waitOnHost();
}
- SLANG_UNIT_TEST(shaderCacheImportIncludeVulkan)
+ void runGraphicsPipeline()
{
- runTest<ShaderCacheTestImportInclude>(unitTestContext, Slang::RenderApiFlag::Vulkan);
+ createGraphicsResources();
+ createGraphicsPipeline();
+ dispatchGraphicsPipeline();
+ freeGraphicsResources();
}
- SLANG_UNIT_TEST(shaderCacheSpecializationD3D12)
+ void runTests()
{
- runTest<ShaderCacheTestSpecialization>(unitTestContext, Slang::RenderApiFlag::D3D12);
- }
+ // Cache is cold and we expect 2 misses (2 entry points).
+ runStep(
+ [this]()
+ {
+ runGraphicsPipeline();
- SLANG_UNIT_TEST(shaderCacheSpecializationVulkan)
- {
- runTest<ShaderCacheTestSpecialization>(unitTestContext, Slang::RenderApiFlag::Vulkan);
- }
+ SLANG_CHECK(getStats().missCount == 2);
+ SLANG_CHECK(getStats().hitCount == 0);
+ SLANG_CHECK(getStats().entryCount == 2);
+ });
- SLANG_UNIT_TEST(shaderCacheEvictionD3D12)
- {
- runTest<ShaderCacheTestEviction>(unitTestContext, Slang::RenderApiFlag::D3D12);
- }
+ // Cache is hot and we expect 2 hits.
+ runStep(
+ [this]()
+ {
+ runGraphicsPipeline();
- SLANG_UNIT_TEST(shaderCacheEvictionVulkan)
- {
- runTest<ShaderCacheTestEviction>(unitTestContext, Slang::RenderApiFlag::Vulkan);
+ SLANG_CHECK(getStats().missCount == 0);
+ SLANG_CHECK(getStats().hitCount == 2);
+ SLANG_CHECK(getStats().entryCount == 2);
+ });
}
+};
- SLANG_UNIT_TEST(shaderCacheGraphicsD3D12)
+// Similar to ShaderCacheTestGraphics but with two separate shader files for the vertex and fragment
+// shaders.
+struct ShaderCacheTestGraphicsSplit : ShaderCacheTestGraphics
+{
+ void createGraphicsPipeline()
{
- runTest<ShaderCacheTestGraphics>(unitTestContext, Slang::RenderApiFlag::D3D12);
+ ComPtr<slang::ISession> slangSession;
+ GFX_CHECK_CALL_ABORT(device->getSlangSession(slangSession.writeRef()));
+ slang::IModule* vertexModule = slangSession->loadModule("shader-cache-graphics-vertex");
+ SLANG_CHECK_ABORT(vertexModule);
+ slang::IModule* fragmentModule = slangSession->loadModule("shader-cache-graphics-fragment");
+ SLANG_CHECK_ABORT(fragmentModule);
+
+ ComPtr<slang::IEntryPoint> vertexEntryPoint;
+ GFX_CHECK_CALL_ABORT(
+ vertexModule->findEntryPointByName("main", vertexEntryPoint.writeRef()));
+
+ ComPtr<slang::IEntryPoint> fragmentEntryPoint;
+ GFX_CHECK_CALL_ABORT(
+ fragmentModule->findEntryPointByName("main", fragmentEntryPoint.writeRef()));
+
+ Slang::List<slang::IComponentType*> componentTypes;
+ componentTypes.add(vertexModule);
+ componentTypes.add(fragmentModule);
+
+ Slang::ComPtr<slang::IComponentType> composedProgram;
+ GFX_CHECK_CALL_ABORT(slangSession->createCompositeComponentType(
+ componentTypes.getBuffer(),
+ componentTypes.getCount(),
+ composedProgram.writeRef()));
+
+ slang::ProgramLayout* slangReflection = composedProgram->getLayout();
+
+ Slang::List<slang::IComponentType*> entryPoints;
+ entryPoints.add(vertexEntryPoint);
+ entryPoints.add(fragmentEntryPoint);
+
+ gfx::IShaderProgram::Desc programDesc = {};
+ programDesc.slangGlobalScope = composedProgram.get();
+ programDesc.linkingStyle = gfx::IShaderProgram::LinkingStyle::SeparateEntryPointCompilation;
+ programDesc.entryPointCount = 2;
+ programDesc.slangEntryPoints = entryPoints.getBuffer();
+
+ ComPtr<IShaderProgram> shaderProgram = device->createProgram(programDesc);
+
+ GraphicsPipelineStateDesc pipelineDesc = {};
+ pipelineDesc.program = shaderProgram.get();
+ pipelineDesc.inputLayout = inputLayout;
+ pipelineDesc.framebufferLayout = framebufferLayout;
+ pipelineDesc.depthStencil.depthTestEnable = false;
+ pipelineDesc.depthStencil.depthWriteEnable = false;
+ GFX_CHECK_CALL_ABORT(
+ device->createGraphicsPipelineState(pipelineDesc, pipelineState.writeRef()));
}
- SLANG_UNIT_TEST(shaderCacheGraphicsVulkan)
+ void runGraphicsPipeline()
{
- runTest<ShaderCacheTestGraphics>(unitTestContext, Slang::RenderApiFlag::Vulkan);
+ createGraphicsResources();
+ createGraphicsPipeline();
+ dispatchGraphicsPipeline();
+ freeGraphicsResources();
}
- SLANG_UNIT_TEST(shaderCacheGraphicsSplitD3D12)
+ void runTests()
{
- runTest<ShaderCacheTestGraphicsSplit>(unitTestContext, Slang::RenderApiFlag::D3D12);
- }
+ // Cache is cold and we expect 2 misses (2 entry points).
+ runStep(
+ [this]()
+ {
+ runGraphicsPipeline();
- SLANG_UNIT_TEST(shaderCacheGraphicsSplitVulkan)
- {
- runTest<ShaderCacheTestGraphicsSplit>(unitTestContext, Slang::RenderApiFlag::Vulkan);
+ SLANG_CHECK(getStats().missCount == 2);
+ SLANG_CHECK(getStats().hitCount == 0);
+ SLANG_CHECK(getStats().entryCount == 2);
+ });
+
+ // Cache is hot and we expect 2 hits.
+ runStep(
+ [this]()
+ {
+ runGraphicsPipeline();
+
+ SLANG_CHECK(getStats().missCount == 0);
+ SLANG_CHECK(getStats().hitCount == 2);
+ SLANG_CHECK(getStats().entryCount == 2);
+ });
}
+};
+
+template<typename T>
+void runTest(UnitTestContext* context, Slang::RenderApiFlag::Enum api)
+{
+ T test;
+ test.run(context, api);
+}
+
+SLANG_UNIT_TEST(shaderCacheSourceFileD3D12)
+{
+ runTest<ShaderCacheSourceFile>(unitTestContext, Slang::RenderApiFlag::D3D12);
+}
+
+SLANG_UNIT_TEST(shaderCacheSourceFileVulkan)
+{
+ runTest<ShaderCacheSourceFile>(unitTestContext, Slang::RenderApiFlag::Vulkan);
+}
+
+SLANG_UNIT_TEST(shaderCacheSourceStringD3D12)
+{
+ runTest<ShaderCacheTestSourceString>(unitTestContext, Slang::RenderApiFlag::D3D12);
+}
+
+SLANG_UNIT_TEST(shaderCacheSourceStringVulkan)
+{
+ runTest<ShaderCacheTestSourceString>(unitTestContext, Slang::RenderApiFlag::Vulkan);
+}
+
+SLANG_UNIT_TEST(shaderCacheEntryPointD3D12)
+{
+ runTest<ShaderCacheTestEntryPoint>(unitTestContext, Slang::RenderApiFlag::D3D12);
+}
+
+SLANG_UNIT_TEST(shaderCacheEntryPointVulkan)
+{
+ runTest<ShaderCacheTestEntryPoint>(unitTestContext, Slang::RenderApiFlag::Vulkan);
+}
+
+SLANG_UNIT_TEST(shaderCacheImportIncludeD3D12)
+{
+ runTest<ShaderCacheTestImportInclude>(unitTestContext, Slang::RenderApiFlag::D3D12);
+}
+
+SLANG_UNIT_TEST(shaderCacheImportIncludeVulkan)
+{
+ runTest<ShaderCacheTestImportInclude>(unitTestContext, Slang::RenderApiFlag::Vulkan);
+}
+
+SLANG_UNIT_TEST(shaderCacheSpecializationD3D12)
+{
+ runTest<ShaderCacheTestSpecialization>(unitTestContext, Slang::RenderApiFlag::D3D12);
+}
+
+SLANG_UNIT_TEST(shaderCacheSpecializationVulkan)
+{
+ runTest<ShaderCacheTestSpecialization>(unitTestContext, Slang::RenderApiFlag::Vulkan);
+}
+
+SLANG_UNIT_TEST(shaderCacheEvictionD3D12)
+{
+ runTest<ShaderCacheTestEviction>(unitTestContext, Slang::RenderApiFlag::D3D12);
+}
+
+SLANG_UNIT_TEST(shaderCacheEvictionVulkan)
+{
+ runTest<ShaderCacheTestEviction>(unitTestContext, Slang::RenderApiFlag::Vulkan);
+}
+
+SLANG_UNIT_TEST(shaderCacheGraphicsD3D12)
+{
+ runTest<ShaderCacheTestGraphics>(unitTestContext, Slang::RenderApiFlag::D3D12);
+}
+
+SLANG_UNIT_TEST(shaderCacheGraphicsVulkan)
+{
+ runTest<ShaderCacheTestGraphics>(unitTestContext, Slang::RenderApiFlag::Vulkan);
+}
+
+SLANG_UNIT_TEST(shaderCacheGraphicsSplitD3D12)
+{
+ runTest<ShaderCacheTestGraphicsSplit>(unitTestContext, Slang::RenderApiFlag::D3D12);
+}
+
+SLANG_UNIT_TEST(shaderCacheGraphicsSplitVulkan)
+{
+ runTest<ShaderCacheTestGraphicsSplit>(unitTestContext, Slang::RenderApiFlag::Vulkan);
}
+} // namespace gfx_test
diff --git a/tools/gfx-unit-test/shared-buffers-tests.cpp b/tools/gfx-unit-test/shared-buffers-tests.cpp
index ccd223fc0..4355dda99 100644
--- a/tools/gfx-unit-test/shared-buffers-tests.cpp
+++ b/tools/gfx-unit-test/shared-buffers-tests.cpp
@@ -1,124 +1,128 @@
-#include "tools/unit-test/slang-unit-test.h"
-
-#include "slang-gfx.h"
#include "gfx-test-util.h"
-#include "tools/gfx-util/shader-cursor.h"
+#include "slang-gfx.h"
#include "source/core/slang-basic.h"
+#include "tools/gfx-util/shader-cursor.h"
+#include "tools/unit-test/slang-unit-test.h"
using namespace gfx;
namespace gfx_test
{
- void sharedBufferTestImpl(IDevice* srcDevice, IDevice* dstDevice, UnitTestContext* context)
+void sharedBufferTestImpl(IDevice* srcDevice, IDevice* dstDevice, UnitTestContext* context)
+{
+ // Create a shareable buffer using srcDevice, get its handle, then create a buffer using the
+ // handle using dstDevice. Read back the buffer and check that its contents are correct.
+ const int numberCount = 4;
+ float initialData[] = {0.0f, 1.0f, 2.0f, 3.0f};
+ IBufferResource::Desc bufferDesc = {};
+ bufferDesc.sizeInBytes = numberCount * sizeof(float);
+ bufferDesc.format = gfx::Format::Unknown;
+ bufferDesc.elementSize = sizeof(float);
+ bufferDesc.allowedStates = ResourceStateSet(
+ ResourceState::ShaderResource,
+ ResourceState::UnorderedAccess,
+ ResourceState::CopyDestination,
+ ResourceState::CopySource);
+ bufferDesc.defaultState = ResourceState::UnorderedAccess;
+ bufferDesc.memoryType = MemoryType::DeviceLocal;
+ bufferDesc.isShared = true;
+
+ ComPtr<IBufferResource> srcBuffer;
+ GFX_CHECK_CALL_ABORT(
+ srcDevice->createBufferResource(bufferDesc, (void*)initialData, srcBuffer.writeRef()));
+
+ InteropHandle sharedHandle;
+ GFX_CHECK_CALL_ABORT(srcBuffer->getSharedHandle(&sharedHandle));
+ ComPtr<IBufferResource> dstBuffer;
+ GFX_CHECK_CALL_ABORT(
+ dstDevice->createBufferFromSharedHandle(sharedHandle, bufferDesc, dstBuffer.writeRef()));
+ // Reading back the buffer from srcDevice to make sure it's been filled in before reading
+ // anything back from dstDevice
+ // TODO: Implement actual synchronization (and not this hacky solution)
+ compareComputeResult(srcDevice, srcBuffer, Slang::makeArray<float>(0.0f, 1.0f, 2.0f, 3.0f));
+
+ InteropHandle testHandle;
+ GFX_CHECK_CALL_ABORT(dstBuffer->getNativeResourceHandle(&testHandle));
+ IBufferResource::Desc* testDesc = dstBuffer->getDesc();
+ SLANG_CHECK(testDesc->elementSize == sizeof(float));
+ SLANG_CHECK(testDesc->sizeInBytes == numberCount * sizeof(float));
+ compareComputeResult(dstDevice, dstBuffer, Slang::makeArray<float>(0.0f, 1.0f, 2.0f, 3.0f));
+
+ // Check that dstBuffer can be successfully used in a compute dispatch using dstDevice.
+ Slang::ComPtr<ITransientResourceHeap> transientHeap;
+ ITransientResourceHeap::Desc transientHeapDesc = {};
+ transientHeapDesc.constantBufferSize = 4096;
+ GFX_CHECK_CALL_ABORT(
+ dstDevice->createTransientResourceHeap(transientHeapDesc, transientHeap.writeRef()));
+
+ ComPtr<IShaderProgram> shaderProgram;
+ slang::ProgramLayout* slangReflection;
+ GFX_CHECK_CALL_ABORT(loadComputeProgram(
+ dstDevice,
+ shaderProgram,
+ "compute-trivial",
+ "computeMain",
+ slangReflection));
+
+ ComputePipelineStateDesc pipelineDesc = {};
+ pipelineDesc.program = shaderProgram.get();
+ ComPtr<gfx::IPipelineState> pipelineState;
+ GFX_CHECK_CALL_ABORT(
+ dstDevice->createComputePipelineState(pipelineDesc, pipelineState.writeRef()));
+
+ ComPtr<IResourceView> bufferView;
+ IResourceView::Desc viewDesc = {};
+ viewDesc.type = IResourceView::Type::UnorderedAccess;
+ viewDesc.format = Format::Unknown;
+ GFX_CHECK_CALL_ABORT(
+ dstDevice->createBufferView(dstBuffer, nullptr, viewDesc, bufferView.writeRef()));
+
{
- // Create a shareable buffer using srcDevice, get its handle, then create a buffer using the handle using
- // dstDevice. Read back the buffer and check that its contents are correct.
- const int numberCount = 4;
- float initialData[] = { 0.0f, 1.0f, 2.0f, 3.0f };
- IBufferResource::Desc bufferDesc = {};
- bufferDesc.sizeInBytes = numberCount * sizeof(float);
- bufferDesc.format = gfx::Format::Unknown;
- bufferDesc.elementSize = sizeof(float);
- bufferDesc.allowedStates = ResourceStateSet(
- ResourceState::ShaderResource,
- ResourceState::UnorderedAccess,
- ResourceState::CopyDestination,
- ResourceState::CopySource);
- bufferDesc.defaultState = ResourceState::UnorderedAccess;
- bufferDesc.memoryType = MemoryType::DeviceLocal;
- bufferDesc.isShared = true;
-
- ComPtr<IBufferResource> srcBuffer;
- GFX_CHECK_CALL_ABORT(srcDevice->createBufferResource(
- bufferDesc,
- (void*)initialData,
- srcBuffer.writeRef()));
-
- InteropHandle sharedHandle;
- GFX_CHECK_CALL_ABORT(srcBuffer->getSharedHandle(&sharedHandle));
- ComPtr<IBufferResource> dstBuffer;
- GFX_CHECK_CALL_ABORT(dstDevice->createBufferFromSharedHandle(sharedHandle, bufferDesc, dstBuffer.writeRef()));
- // Reading back the buffer from srcDevice to make sure it's been filled in before reading anything back from dstDevice
- // TODO: Implement actual synchronization (and not this hacky solution)
- compareComputeResult(srcDevice, srcBuffer, Slang::makeArray<float>(0.0f, 1.0f, 2.0f, 3.0f));
-
- InteropHandle testHandle;
- GFX_CHECK_CALL_ABORT(dstBuffer->getNativeResourceHandle(&testHandle));
- IBufferResource::Desc* testDesc = dstBuffer->getDesc();
- SLANG_CHECK(testDesc->elementSize == sizeof(float));
- SLANG_CHECK(testDesc->sizeInBytes == numberCount * sizeof(float));
- compareComputeResult(dstDevice, dstBuffer, Slang::makeArray<float>(0.0f, 1.0f, 2.0f, 3.0f));
-
- // Check that dstBuffer can be successfully used in a compute dispatch using dstDevice.
- Slang::ComPtr<ITransientResourceHeap> transientHeap;
- ITransientResourceHeap::Desc transientHeapDesc = {};
- transientHeapDesc.constantBufferSize = 4096;
- GFX_CHECK_CALL_ABORT(
- dstDevice->createTransientResourceHeap(transientHeapDesc, transientHeap.writeRef()));
-
- ComPtr<IShaderProgram> shaderProgram;
- slang::ProgramLayout* slangReflection;
- GFX_CHECK_CALL_ABORT(loadComputeProgram(dstDevice, shaderProgram, "compute-trivial", "computeMain", slangReflection));
-
- ComputePipelineStateDesc pipelineDesc = {};
- pipelineDesc.program = shaderProgram.get();
- ComPtr<gfx::IPipelineState> pipelineState;
- GFX_CHECK_CALL_ABORT(
- dstDevice->createComputePipelineState(pipelineDesc, pipelineState.writeRef()));
-
- ComPtr<IResourceView> bufferView;
- IResourceView::Desc viewDesc = {};
- viewDesc.type = IResourceView::Type::UnorderedAccess;
- viewDesc.format = Format::Unknown;
- GFX_CHECK_CALL_ABORT(
- dstDevice->createBufferView(dstBuffer, nullptr, viewDesc, bufferView.writeRef()));
-
- {
- ICommandQueue::Desc queueDesc = { ICommandQueue::QueueType::Graphics };
- auto queue = dstDevice->createCommandQueue(queueDesc);
-
- auto commandBuffer = transientHeap->createCommandBuffer();
- auto encoder = commandBuffer->encodeComputeCommands();
-
- auto rootObject = encoder->bindPipeline(pipelineState);
-
- ShaderCursor rootCursor(rootObject);
- // Bind buffer view to the entry point.
- rootCursor.getPath("buffer").setResource(bufferView);
-
- encoder->dispatchCompute(1, 1, 1);
- encoder->endEncoding();
- commandBuffer->close();
- queue->executeCommandBuffer(commandBuffer);
- queue->waitOnHost();
- }
-
- compareComputeResult(
- dstDevice,
- dstBuffer,
- Slang::makeArray<float>(1.0f, 2.0f, 3.0f, 4.0f));
+ ICommandQueue::Desc queueDesc = {ICommandQueue::QueueType::Graphics};
+ auto queue = dstDevice->createCommandQueue(queueDesc);
+
+ auto commandBuffer = transientHeap->createCommandBuffer();
+ auto encoder = commandBuffer->encodeComputeCommands();
+
+ auto rootObject = encoder->bindPipeline(pipelineState);
+
+ ShaderCursor rootCursor(rootObject);
+ // Bind buffer view to the entry point.
+ rootCursor.getPath("buffer").setResource(bufferView);
+
+ encoder->dispatchCompute(1, 1, 1);
+ encoder->endEncoding();
+ commandBuffer->close();
+ queue->executeCommandBuffer(commandBuffer);
+ queue->waitOnHost();
}
- void sharedBufferTestAPI(UnitTestContext* context, Slang::RenderApiFlag::Enum srcApi, Slang::RenderApiFlag::Enum dstApi)
+ compareComputeResult(dstDevice, dstBuffer, Slang::makeArray<float>(1.0f, 2.0f, 3.0f, 4.0f));
+}
+
+void sharedBufferTestAPI(
+ UnitTestContext* context,
+ Slang::RenderApiFlag::Enum srcApi,
+ Slang::RenderApiFlag::Enum dstApi)
+{
+ auto srcDevice = createTestingDevice(context, srcApi);
+ auto dstDevice = createTestingDevice(context, dstApi);
+ if (!srcDevice || !dstDevice)
{
- auto srcDevice = createTestingDevice(context, srcApi);
- auto dstDevice = createTestingDevice(context, dstApi);
- if (!srcDevice || !dstDevice)
- {
- SLANG_IGNORE_TEST;
- }
-
- sharedBufferTestImpl(srcDevice, dstDevice, context);
+ SLANG_IGNORE_TEST;
}
+
+ sharedBufferTestImpl(srcDevice, dstDevice, context);
+}
#if SLANG_WIN64
- SLANG_UNIT_TEST(sharedBufferD3D12ToCUDA)
- {
- sharedBufferTestAPI(unitTestContext, Slang::RenderApiFlag::D3D12, Slang::RenderApiFlag::CUDA);
- }
+SLANG_UNIT_TEST(sharedBufferD3D12ToCUDA)
+{
+ sharedBufferTestAPI(unitTestContext, Slang::RenderApiFlag::D3D12, Slang::RenderApiFlag::CUDA);
+}
- SLANG_UNIT_TEST(sharedBufferVulkanToCUDA)
- {
- sharedBufferTestAPI(unitTestContext, Slang::RenderApiFlag::Vulkan, Slang::RenderApiFlag::CUDA);
- }
-#endif
+SLANG_UNIT_TEST(sharedBufferVulkanToCUDA)
+{
+ sharedBufferTestAPI(unitTestContext, Slang::RenderApiFlag::Vulkan, Slang::RenderApiFlag::CUDA);
}
+#endif
+} // namespace gfx_test
diff --git a/tools/gfx-unit-test/shared-textures-tests.cpp b/tools/gfx-unit-test/shared-textures-tests.cpp
index 4afa23546..ee8108c39 100644
--- a/tools/gfx-unit-test/shared-textures-tests.cpp
+++ b/tools/gfx-unit-test/shared-textures-tests.cpp
@@ -1,223 +1,261 @@
-#include "tools/unit-test/slang-unit-test.h"
-
-#include "slang-gfx.h"
#include "gfx-test-util.h"
-#include "tools/gfx-util/shader-cursor.h"
+#include "slang-gfx.h"
#include "source/core/slang-basic.h"
+#include "tools/gfx-util/shader-cursor.h"
+#include "tools/unit-test/slang-unit-test.h"
using namespace gfx;
namespace gfx_test
{
- void setUpAndRunShader(
- IDevice* device,
- ComPtr<ITextureResource> tex,
- ComPtr<IResourceView> texView,
- ComPtr<IResourceView> bufferView,
- const char* entryPoint,
- ComPtr<ISamplerState> sampler = nullptr)
+void setUpAndRunShader(
+ IDevice* device,
+ ComPtr<ITextureResource> tex,
+ ComPtr<IResourceView> texView,
+ ComPtr<IResourceView> bufferView,
+ const char* entryPoint,
+ ComPtr<ISamplerState> sampler = nullptr)
+{
+ Slang::ComPtr<ITransientResourceHeap> transientHeap;
+ ITransientResourceHeap::Desc transientHeapDesc = {};
+ transientHeapDesc.constantBufferSize = 4096;
+ GFX_CHECK_CALL_ABORT(
+ device->createTransientResourceHeap(transientHeapDesc, transientHeap.writeRef()));
+
+ ComPtr<IShaderProgram> shaderProgram;
+ slang::ProgramLayout* slangReflection;
+ GFX_CHECK_CALL_ABORT(
+ loadComputeProgram(device, shaderProgram, "trivial-copy", entryPoint, slangReflection));
+
+ ComputePipelineStateDesc pipelineDesc = {};
+ pipelineDesc.program = shaderProgram.get();
+ ComPtr<gfx::IPipelineState> pipelineState;
+ GFX_CHECK_CALL_ABORT(
+ device->createComputePipelineState(pipelineDesc, pipelineState.writeRef()));
+
+ // We have done all the set up work, now it is time to start recording a command buffer for
+ // GPU execution.
{
- Slang::ComPtr<ITransientResourceHeap> transientHeap;
- ITransientResourceHeap::Desc transientHeapDesc = {};
- transientHeapDesc.constantBufferSize = 4096;
- GFX_CHECK_CALL_ABORT(
- device->createTransientResourceHeap(transientHeapDesc, transientHeap.writeRef()));
-
- ComPtr<IShaderProgram> shaderProgram;
- slang::ProgramLayout* slangReflection;
- GFX_CHECK_CALL_ABORT(loadComputeProgram(device, shaderProgram, "trivial-copy", entryPoint, slangReflection));
-
- ComputePipelineStateDesc pipelineDesc = {};
- pipelineDesc.program = shaderProgram.get();
- ComPtr<gfx::IPipelineState> pipelineState;
- GFX_CHECK_CALL_ABORT(
- device->createComputePipelineState(pipelineDesc, pipelineState.writeRef()));
-
- // We have done all the set up work, now it is time to start recording a command buffer for
- // GPU execution.
- {
- ICommandQueue::Desc queueDesc = { ICommandQueue::QueueType::Graphics };
- auto queue = device->createCommandQueue(queueDesc);
-
- auto commandBuffer = transientHeap->createCommandBuffer();
- auto encoder = commandBuffer->encodeComputeCommands();
-
- auto rootObject = encoder->bindPipeline(pipelineState);
-
- ShaderCursor entryPointCursor(
- rootObject->getEntryPoint(0)); // get a cursor the the first entry-point.
-
- auto& desc = *tex->getDesc();
- entryPointCursor["width"].setData(desc.size.width);
- entryPointCursor["height"].setData(desc.size.height);
-
- // Bind texture view to the entry point
- entryPointCursor["tex"].setResource(texView);
-
- if (sampler) entryPointCursor["sampler"].setSampler(sampler);
-
- // Bind buffer view to the entry point.
- entryPointCursor["buffer"].setResource(bufferView);
-
- encoder->dispatchCompute(1, 1, 1);
- encoder->endEncoding();
- commandBuffer->close();
- queue->executeCommandBuffer(commandBuffer);
- queue->waitOnHost();
- }
- }
+ ICommandQueue::Desc queueDesc = {ICommandQueue::QueueType::Graphics};
+ auto queue = device->createCommandQueue(queueDesc);
- ComPtr<ITextureResource> createTexture(IDevice* device, ITextureResource::Extents extents, gfx::Format format, ITextureResource::SubresourceData* initialData)
- {
- ITextureResource::Desc texDesc = {};
- texDesc.type = IResource::Type::Texture2D;
- texDesc.numMipLevels = 1;
- texDesc.arraySize = 1;
- texDesc.size = extents;
- texDesc.defaultState = ResourceState::UnorderedAccess;
- texDesc.allowedStates = ResourceStateSet(
- ResourceState::ShaderResource,
- ResourceState::UnorderedAccess,
- ResourceState::CopyDestination,
- ResourceState::CopySource);
- texDesc.format = format;
- texDesc.isShared = true;
-
- ComPtr<ITextureResource> inTex;
- GFX_CHECK_CALL_ABORT(device->createTextureResource(
- texDesc,
- initialData,
- inTex.writeRef()));
- return inTex;
- }
+ auto commandBuffer = transientHeap->createCommandBuffer();
+ auto encoder = commandBuffer->encodeComputeCommands();
- ComPtr<IResourceView> createTexView(IDevice* device, ComPtr<ITextureResource> inTexture)
- {
- ComPtr<IResourceView> texView;
- IResourceView::Desc texViewDesc = {};
- texViewDesc.type = IResourceView::Type::UnorderedAccess;
- texViewDesc.format = inTexture->getDesc()->format; // TODO: Handle typeless formats - gfxIsTypelessFormat(format) ? convertTypelessFormat(format) : format;
- GFX_CHECK_CALL_ABORT(device->createTextureView(inTexture, texViewDesc, texView.writeRef()));
- return texView;
- }
+ auto rootObject = encoder->bindPipeline(pipelineState);
- template <typename T>
- ComPtr<IBufferResource> createBuffer(IDevice* device, int size, void* initialData)
- {
- IBufferResource::Desc bufferDesc = {};
- bufferDesc.sizeInBytes = size * sizeof(T);
- bufferDesc.format = gfx::Format::Unknown;
- bufferDesc.elementSize = sizeof(T);
- bufferDesc.allowedStates = ResourceStateSet(
- ResourceState::ShaderResource,
- ResourceState::UnorderedAccess,
- ResourceState::CopyDestination,
- ResourceState::CopySource);
- bufferDesc.defaultState = ResourceState::UnorderedAccess;
- bufferDesc.memoryType = MemoryType::DeviceLocal;
-
- ComPtr<IBufferResource> outBuffer;
- GFX_CHECK_CALL_ABORT(device->createBufferResource(
- bufferDesc,
- initialData,
- outBuffer.writeRef()));
- return outBuffer;
- }
+ ShaderCursor entryPointCursor(
+ rootObject->getEntryPoint(0)); // get a cursor the the first entry-point.
- ComPtr<IResourceView> createOutBufferView(IDevice* device, ComPtr<IBufferResource> outBuffer)
- {
- ComPtr<IResourceView> bufferView;
- IResourceView::Desc viewDesc = {};
- viewDesc.type = IResourceView::Type::UnorderedAccess;
- viewDesc.format = Format::Unknown;
- GFX_CHECK_CALL_ABORT(
- device->createBufferView(outBuffer, nullptr, viewDesc, bufferView.writeRef()));
- return bufferView;
+ auto& desc = *tex->getDesc();
+ entryPointCursor["width"].setData(desc.size.width);
+ entryPointCursor["height"].setData(desc.size.height);
+
+ // Bind texture view to the entry point
+ entryPointCursor["tex"].setResource(texView);
+
+ if (sampler)
+ entryPointCursor["sampler"].setSampler(sampler);
+
+ // Bind buffer view to the entry point.
+ entryPointCursor["buffer"].setResource(bufferView);
+
+ encoder->dispatchCompute(1, 1, 1);
+ encoder->endEncoding();
+ commandBuffer->close();
+ queue->executeCommandBuffer(commandBuffer);
+ queue->waitOnHost();
}
+}
+
+ComPtr<ITextureResource> createTexture(
+ IDevice* device,
+ ITextureResource::Extents extents,
+ gfx::Format format,
+ ITextureResource::SubresourceData* initialData)
+{
+ ITextureResource::Desc texDesc = {};
+ texDesc.type = IResource::Type::Texture2D;
+ texDesc.numMipLevels = 1;
+ texDesc.arraySize = 1;
+ texDesc.size = extents;
+ texDesc.defaultState = ResourceState::UnorderedAccess;
+ texDesc.allowedStates = ResourceStateSet(
+ ResourceState::ShaderResource,
+ ResourceState::UnorderedAccess,
+ ResourceState::CopyDestination,
+ ResourceState::CopySource);
+ texDesc.format = format;
+ texDesc.isShared = true;
+
+ ComPtr<ITextureResource> inTex;
+ GFX_CHECK_CALL_ABORT(device->createTextureResource(texDesc, initialData, inTex.writeRef()));
+ return inTex;
+}
+
+ComPtr<IResourceView> createTexView(IDevice* device, ComPtr<ITextureResource> inTexture)
+{
+ ComPtr<IResourceView> texView;
+ IResourceView::Desc texViewDesc = {};
+ texViewDesc.type = IResourceView::Type::UnorderedAccess;
+ texViewDesc.format =
+ inTexture->getDesc()->format; // TODO: Handle typeless formats - gfxIsTypelessFormat(format)
+ // ? convertTypelessFormat(format) : format;
+ GFX_CHECK_CALL_ABORT(device->createTextureView(inTexture, texViewDesc, texView.writeRef()));
+ return texView;
+}
+
+template<typename T>
+ComPtr<IBufferResource> createBuffer(IDevice* device, int size, void* initialData)
+{
+ IBufferResource::Desc bufferDesc = {};
+ bufferDesc.sizeInBytes = size * sizeof(T);
+ bufferDesc.format = gfx::Format::Unknown;
+ bufferDesc.elementSize = sizeof(T);
+ bufferDesc.allowedStates = ResourceStateSet(
+ ResourceState::ShaderResource,
+ ResourceState::UnorderedAccess,
+ ResourceState::CopyDestination,
+ ResourceState::CopySource);
+ bufferDesc.defaultState = ResourceState::UnorderedAccess;
+ bufferDesc.memoryType = MemoryType::DeviceLocal;
+
+ ComPtr<IBufferResource> outBuffer;
+ GFX_CHECK_CALL_ABORT(
+ device->createBufferResource(bufferDesc, initialData, outBuffer.writeRef()));
+ return outBuffer;
+}
+
+ComPtr<IResourceView> createOutBufferView(IDevice* device, ComPtr<IBufferResource> outBuffer)
+{
+ ComPtr<IResourceView> bufferView;
+ IResourceView::Desc viewDesc = {};
+ viewDesc.type = IResourceView::Type::UnorderedAccess;
+ viewDesc.format = Format::Unknown;
+ GFX_CHECK_CALL_ABORT(
+ device->createBufferView(outBuffer, nullptr, viewDesc, bufferView.writeRef()));
+ return bufferView;
+}
+
+void sharedTextureTestImpl(IDevice* srcDevice, IDevice* dstDevice, UnitTestContext* context)
+{
+ ISamplerState::Desc samplerDesc;
+ auto sampler = dstDevice->createSamplerState(samplerDesc);
+
+ float initFloatData[16] = {0.0f};
+ auto floatResults = createBuffer<float>(dstDevice, 16, initFloatData);
+ auto floatBufferView = createOutBufferView(dstDevice, floatResults);
+
+ uint32_t initUintData[16] = {0u};
+ auto uintResults = createBuffer<uint32_t>(dstDevice, 16, initUintData);
+ auto uintBufferView = createOutBufferView(dstDevice, uintResults);
+
+ int32_t initIntData[16] = {0};
+ auto intResults = createBuffer<uint32_t>(dstDevice, 16, initIntData);
+ auto intBufferView = createOutBufferView(dstDevice, intResults);
+
+ ITextureResource::Extents size = {};
+ size.width = 2;
+ size.height = 2;
+ size.depth = 1;
+
+ ITextureResource::Extents bcSize = {};
+ bcSize.width = 4;
+ bcSize.height = 4;
+ bcSize.depth = 1;
- void sharedTextureTestImpl(IDevice* srcDevice, IDevice* dstDevice, UnitTestContext* context)
{
- ISamplerState::Desc samplerDesc;
- auto sampler = dstDevice->createSamplerState(samplerDesc);
-
- float initFloatData[16] = { 0.0f };
- auto floatResults = createBuffer<float>(dstDevice, 16, initFloatData);
- auto floatBufferView = createOutBufferView(dstDevice, floatResults);
-
- uint32_t initUintData[16] = { 0u };
- auto uintResults = createBuffer<uint32_t>(dstDevice, 16, initUintData);
- auto uintBufferView = createOutBufferView(dstDevice, uintResults);
-
- int32_t initIntData[16] = { 0 };
- auto intResults = createBuffer<uint32_t>(dstDevice, 16, initIntData);
- auto intBufferView = createOutBufferView(dstDevice, intResults);
-
- ITextureResource::Extents size = {};
- size.width = 2;
- size.height = 2;
- size.depth = 1;
-
- ITextureResource::Extents bcSize = {};
- bcSize.width = 4;
- bcSize.height = 4;
- bcSize.depth = 1;
-
- {
- float texData[] = { 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f,
- 0.0f, 0.0f, 1.0f, 1.0f, 0.5f, 0.5f, 0.5f, 1.0f };
- ITextureResource::SubresourceData subData = { (void*)texData, 32, 0 };
-
- // Create a shareable texture using srcDevice, get its handle, then create a texture using the handle using
- // dstDevice. Read back the texture and check that its contents are correct.
- auto srcTexture = createTexture(srcDevice, size, gfx::Format::R32G32B32A32_FLOAT, &subData);
-
- InteropHandle sharedHandle;
- GFX_CHECK_CALL_ABORT(srcTexture->getSharedHandle(&sharedHandle));
- ComPtr<ITextureResource> dstTexture;
- size_t sizeInBytes = 0;
- size_t alignment = 0;
- GFX_CHECK_CALL_ABORT(srcDevice->getTextureAllocationInfo(*(srcTexture->getDesc()), &sizeInBytes, &alignment));
- GFX_CHECK_CALL_ABORT(dstDevice->createTextureFromSharedHandle(sharedHandle, *(srcTexture->getDesc()), sizeInBytes, dstTexture.writeRef()));
- // Reading back the buffer from srcDevice to make sure it's been filled in before reading anything back from dstDevice
- // TODO: Implement actual synchronization (and not this hacky solution)
- compareComputeResult(
- dstDevice,
- dstTexture,
- ResourceState::ShaderResource,
- texData,
- 32,
- 2);
-
- auto texView = createTexView(dstDevice, dstTexture);
- setUpAndRunShader(dstDevice, dstTexture, texView, floatBufferView, "copyTexFloat4");
- compareComputeResult(
- dstDevice,
- floatResults,
- Slang::makeArray<float>(1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f,
- 0.0f, 0.0f, 1.0f, 1.0f, 0.5f, 0.5f, 0.5f, 1.0f));
- }
+ float texData[] = {
+ 1.0f,
+ 0.0f,
+ 0.0f,
+ 1.0f,
+ 0.0f,
+ 1.0f,
+ 0.0f,
+ 1.0f,
+ 0.0f,
+ 0.0f,
+ 1.0f,
+ 1.0f,
+ 0.5f,
+ 0.5f,
+ 0.5f,
+ 1.0f};
+ ITextureResource::SubresourceData subData = {(void*)texData, 32, 0};
+
+ // Create a shareable texture using srcDevice, get its handle, then create a texture using
+ // the handle using dstDevice. Read back the texture and check that its contents are
+ // correct.
+ auto srcTexture = createTexture(srcDevice, size, gfx::Format::R32G32B32A32_FLOAT, &subData);
+
+ InteropHandle sharedHandle;
+ GFX_CHECK_CALL_ABORT(srcTexture->getSharedHandle(&sharedHandle));
+ ComPtr<ITextureResource> dstTexture;
+ size_t sizeInBytes = 0;
+ size_t alignment = 0;
+ GFX_CHECK_CALL_ABORT(srcDevice->getTextureAllocationInfo(
+ *(srcTexture->getDesc()),
+ &sizeInBytes,
+ &alignment));
+ GFX_CHECK_CALL_ABORT(dstDevice->createTextureFromSharedHandle(
+ sharedHandle,
+ *(srcTexture->getDesc()),
+ sizeInBytes,
+ dstTexture.writeRef()));
+ // Reading back the buffer from srcDevice to make sure it's been filled in before reading
+ // anything back from dstDevice
+ // TODO: Implement actual synchronization (and not this hacky solution)
+ compareComputeResult(dstDevice, dstTexture, ResourceState::ShaderResource, texData, 32, 2);
+
+ auto texView = createTexView(dstDevice, dstTexture);
+ setUpAndRunShader(dstDevice, dstTexture, texView, floatBufferView, "copyTexFloat4");
+ compareComputeResult(
+ dstDevice,
+ floatResults,
+ Slang::makeArray<float>(
+ 1.0f,
+ 0.0f,
+ 0.0f,
+ 1.0f,
+ 0.0f,
+ 1.0f,
+ 0.0f,
+ 1.0f,
+ 0.0f,
+ 0.0f,
+ 1.0f,
+ 1.0f,
+ 0.5f,
+ 0.5f,
+ 0.5f,
+ 1.0f));
}
+}
- void sharedTextureTestAPI(UnitTestContext* context, Slang::RenderApiFlag::Enum srcApi, Slang::RenderApiFlag::Enum dstApi)
+void sharedTextureTestAPI(
+ UnitTestContext* context,
+ Slang::RenderApiFlag::Enum srcApi,
+ Slang::RenderApiFlag::Enum dstApi)
+{
+ auto srcDevice = createTestingDevice(context, srcApi);
+ auto dstDevice = createTestingDevice(context, dstApi);
+ if (!srcDevice || !dstDevice)
{
- auto srcDevice = createTestingDevice(context, srcApi);
- auto dstDevice = createTestingDevice(context, dstApi);
- if (!srcDevice || !dstDevice)
- {
- SLANG_IGNORE_TEST;
- }
-
- sharedTextureTestImpl(srcDevice, dstDevice, context);
+ SLANG_IGNORE_TEST;
}
+
+ sharedTextureTestImpl(srcDevice, dstDevice, context);
+}
#if SLANG_WIN64
- SLANG_UNIT_TEST(sharedTextureD3D12ToCUDA)
- {
- sharedTextureTestAPI(unitTestContext, Slang::RenderApiFlag::D3D12, Slang::RenderApiFlag::CUDA);
- }
+SLANG_UNIT_TEST(sharedTextureD3D12ToCUDA)
+{
+ sharedTextureTestAPI(unitTestContext, Slang::RenderApiFlag::D3D12, Slang::RenderApiFlag::CUDA);
+}
- SLANG_UNIT_TEST(sharedTextureVulkanToCUDA)
- {
- sharedTextureTestAPI(unitTestContext, Slang::RenderApiFlag::Vulkan, Slang::RenderApiFlag::CUDA);
- }
-#endif
+SLANG_UNIT_TEST(sharedTextureVulkanToCUDA)
+{
+ sharedTextureTestAPI(unitTestContext, Slang::RenderApiFlag::Vulkan, Slang::RenderApiFlag::CUDA);
}
+#endif
+} // namespace gfx_test
diff --git a/tools/gfx-unit-test/swap-chain-resize-test.cpp b/tools/gfx-unit-test/swap-chain-resize-test.cpp
index 2be690077..269f08735 100644
--- a/tools/gfx-unit-test/swap-chain-resize-test.cpp
+++ b/tools/gfx-unit-test/swap-chain-resize-test.cpp
@@ -1,242 +1,249 @@
-#include "tools/unit-test/slang-unit-test.h"
-
-#include "slang-gfx.h"
#include "gfx-test-util.h"
+#include "slang-gfx.h"
+#include "source/core/slang-basic.h"
#include "tools/gfx-util/shader-cursor.h"
#include "tools/platform/window.h"
-#include "source/core/slang-basic.h"
+#include "tools/unit-test/slang-unit-test.h"
using namespace gfx;
using namespace Slang;
namespace gfx_test
{
- struct Vertex
- {
- float position[3];
- };
-
- static const int kVertexCount = 3;
- static const Vertex kVertexData[kVertexCount] =
- {
- // Triangle 1
- { 0, 0, 1 },
- { 4, 0, 1 },
- { 0, 4, 1 },
- };
-
- struct SwapchainResizeTest
- {
- IDevice* device;
- UnitTestContext* context;
-
- RefPtr<platform::Window> window;
- ComPtr<ICommandQueue> queue;
- ComPtr<ISwapchain> swapchain;
+struct Vertex
+{
+ float position[3];
+};
+
+static const int kVertexCount = 3;
+static const Vertex kVertexData[kVertexCount] = {
+ // Triangle 1
+ {0, 0, 1},
+ {4, 0, 1},
+ {0, 4, 1},
+};
+
+struct SwapchainResizeTest
+{
+ IDevice* device;
+ UnitTestContext* context;
- ComPtr<ITransientResourceHeap> transientHeap;
- ComPtr<gfx::IFramebufferLayout> framebufferLayout;
- ComPtr<IPipelineState> pipelineState;
- ComPtr<IRenderPassLayout> renderPass;
- List<ComPtr<IFramebuffer>> framebuffers;
+ RefPtr<platform::Window> window;
+ ComPtr<ICommandQueue> queue;
+ ComPtr<ISwapchain> swapchain;
- ComPtr<IBufferResource> vertexBuffer;
+ ComPtr<ITransientResourceHeap> transientHeap;
+ ComPtr<gfx::IFramebufferLayout> framebufferLayout;
+ ComPtr<IPipelineState> pipelineState;
+ ComPtr<IRenderPassLayout> renderPass;
+ List<ComPtr<IFramebuffer>> framebuffers;
- GfxCount width = 500;
- GfxCount height = 500;
- static const int kSwapchainImageCount = 2;
- const Format desiredFormat = Format::R8G8B8A8_UNORM;
+ ComPtr<IBufferResource> vertexBuffer;
- void init(IDevice* device, UnitTestContext* context)
- {
- this->device = device;
- this->context = context;
- }
+ GfxCount width = 500;
+ GfxCount height = 500;
+ static const int kSwapchainImageCount = 2;
+ const Format desiredFormat = Format::R8G8B8A8_UNORM;
- void createSwapchainFramebuffers()
- {
- framebuffers.clear();
- for (GfxIndex i = 0; i < kSwapchainImageCount; ++i)
- {
- ComPtr<ITextureResource> colorBuffer;
- swapchain->getImage(i, colorBuffer.writeRef());
-
- gfx::IResourceView::Desc colorBufferViewDesc;
- memset(&colorBufferViewDesc, 0, sizeof(colorBufferViewDesc));
- colorBufferViewDesc.format = swapchain->getDesc().format;
- colorBufferViewDesc.renderTarget.shape = gfx::IResource::Type::Texture2D;
- colorBufferViewDesc.type = gfx::IResourceView::Type::RenderTarget;
- auto rtv = device->createTextureView(colorBuffer.get(), colorBufferViewDesc);
-
- gfx::IFramebuffer::Desc framebufferDesc;
- framebufferDesc.renderTargetCount = 1;
- framebufferDesc.depthStencilView = nullptr;
- framebufferDesc.renderTargetViews = rtv.readRef();
- framebufferDesc.layout = framebufferLayout;
- ComPtr<IFramebuffer> framebuffer;
- GFX_CHECK_CALL_ABORT(device->createFramebuffer(framebufferDesc, framebuffer.writeRef()));
-
- framebuffers.add(framebuffer);
- }
- }
+ void init(IDevice* device, UnitTestContext* context)
+ {
+ this->device = device;
+ this->context = context;
+ }
- void createRequiredResources()
+ void createSwapchainFramebuffers()
+ {
+ framebuffers.clear();
+ for (GfxIndex i = 0; i < kSwapchainImageCount; ++i)
{
- platform::Application::init();
-
- platform::WindowDesc windowDesc;
- windowDesc.title = "";
- windowDesc.width = width;
- windowDesc.height = height;
- windowDesc.style = platform::WindowStyle::Default;
- window = platform::Application::createWindow(windowDesc);
-
- ICommandQueue::Desc queueDesc = {};
- queueDesc.type = ICommandQueue::QueueType::Graphics;
- queue = device->createCommandQueue(queueDesc);
-
- ISwapchain::Desc swapchainDesc = {};
- swapchainDesc.format = desiredFormat;
- swapchainDesc.width = width;
- swapchainDesc.height = height;
- swapchainDesc.imageCount = kSwapchainImageCount;
- swapchainDesc.queue = queue;
- WindowHandle windowHandle = window->getNativeHandle().convert<WindowHandle>();
- auto createSwapchainResult = device->createSwapchain(swapchainDesc, windowHandle, swapchain.writeRef());
- if (SLANG_FAILED(createSwapchainResult))
- {
- SLANG_IGNORE_TEST;
- }
-
- VertexStreamDesc vertexStreams[] = {
- { sizeof(Vertex), InputSlotClass::PerVertex, 0 },
- };
-
- InputElementDesc inputElements[] = {
- // Vertex buffer data
- { "POSITIONA", 0, Format::R32G32B32_FLOAT, offsetof(Vertex, position), 0 },
- };
- IInputLayout::Desc inputLayoutDesc = {};
- inputLayoutDesc.inputElementCount = SLANG_COUNT_OF(inputElements);
- inputLayoutDesc.inputElements = inputElements;
- inputLayoutDesc.vertexStreamCount = SLANG_COUNT_OF(vertexStreams);
- inputLayoutDesc.vertexStreams = vertexStreams;
- auto inputLayout = device->createInputLayout(inputLayoutDesc);
- SLANG_CHECK_ABORT(inputLayout != nullptr);
-
- IBufferResource::Desc vertexBufferDesc;
- vertexBufferDesc.type = IResource::Type::Buffer;
- vertexBufferDesc.sizeInBytes = kVertexCount * sizeof(Vertex);
- vertexBufferDesc.defaultState = ResourceState::VertexBuffer;
- vertexBuffer = device->createBufferResource(vertexBufferDesc, &kVertexData[0]);
- SLANG_CHECK_ABORT(vertexBuffer != nullptr);
-
- ITransientResourceHeap::Desc transientHeapDesc = {};
- transientHeapDesc.constantBufferSize = 4096 * 1024;
- GFX_CHECK_CALL_ABORT(
- device->createTransientResourceHeap(transientHeapDesc, transientHeap.writeRef()));
-
- ComPtr<IShaderProgram> shaderProgram;
- slang::ProgramLayout* slangReflection;
- GFX_CHECK_CALL_ABORT(loadGraphicsProgram(device, shaderProgram, "swapchain-shader", "vertexMain", "fragmentMain", slangReflection));
-
- IFramebufferLayout::TargetLayout targetLayout;
- targetLayout.format = swapchain->getDesc().format;
- targetLayout.sampleCount = 1;
-
- IFramebufferLayout::Desc framebufferLayoutDesc;
- framebufferLayoutDesc.renderTargetCount = 1;
- framebufferLayoutDesc.renderTargets = &targetLayout;
- framebufferLayout = device->createFramebufferLayout(framebufferLayoutDesc);
- SLANG_CHECK_ABORT(framebufferLayout != nullptr);
-
- GraphicsPipelineStateDesc pipelineDesc = {};
- pipelineDesc.program = shaderProgram.get();
- pipelineDesc.inputLayout = inputLayout;
- pipelineDesc.framebufferLayout = framebufferLayout;
- pipelineDesc.depthStencil.depthTestEnable = false;
- pipelineDesc.depthStencil.depthWriteEnable = false;
+ ComPtr<ITextureResource> colorBuffer;
+ swapchain->getImage(i, colorBuffer.writeRef());
+
+ gfx::IResourceView::Desc colorBufferViewDesc;
+ memset(&colorBufferViewDesc, 0, sizeof(colorBufferViewDesc));
+ colorBufferViewDesc.format = swapchain->getDesc().format;
+ colorBufferViewDesc.renderTarget.shape = gfx::IResource::Type::Texture2D;
+ colorBufferViewDesc.type = gfx::IResourceView::Type::RenderTarget;
+ auto rtv = device->createTextureView(colorBuffer.get(), colorBufferViewDesc);
+
+ gfx::IFramebuffer::Desc framebufferDesc;
+ framebufferDesc.renderTargetCount = 1;
+ framebufferDesc.depthStencilView = nullptr;
+ framebufferDesc.renderTargetViews = rtv.readRef();
+ framebufferDesc.layout = framebufferLayout;
+ ComPtr<IFramebuffer> framebuffer;
GFX_CHECK_CALL_ABORT(
- device->createGraphicsPipelineState(pipelineDesc, pipelineState.writeRef()));
-
- IRenderPassLayout::Desc renderPassDesc = {};
- renderPassDesc.framebufferLayout = framebufferLayout;
- renderPassDesc.renderTargetCount = 1;
- IRenderPassLayout::TargetAccessDesc renderTargetAccess = {};
- renderTargetAccess.loadOp = IRenderPassLayout::TargetLoadOp::Clear;
- renderTargetAccess.storeOp = IRenderPassLayout::TargetStoreOp::Store;
- renderTargetAccess.initialState = ResourceState::Undefined;
- renderTargetAccess.finalState = ResourceState::Present;
- renderPassDesc.renderTargetAccess = &renderTargetAccess;
- GFX_CHECK_CALL_ABORT(device->createRenderPassLayout(renderPassDesc, renderPass.writeRef()));
-
- createSwapchainFramebuffers();
- }
+ device->createFramebuffer(framebufferDesc, framebuffer.writeRef()));
- void renderFrame(GfxIndex framebufferIndex)
- {
- auto commandBuffer = transientHeap->createCommandBuffer();
-
- auto encoder = commandBuffer->encodeRenderCommands(renderPass, framebuffers[framebufferIndex]);
- auto rootObject = encoder->bindPipeline(pipelineState);
-
- gfx::Viewport viewport = {};
- viewport.maxZ = 1.0f;
- viewport.extentX = (float)width;
- viewport.extentY = (float)height;
- encoder->setViewportAndScissor(viewport);
-
- encoder->setVertexBuffer(0, vertexBuffer);
- encoder->setPrimitiveTopology(PrimitiveTopology::TriangleList);
-
- swapchain->acquireNextImage();
- encoder->draw(kVertexCount);
- encoder->endEncoding();
- commandBuffer->close();
- queue->executeCommandBuffer(commandBuffer);
- swapchain->present();
+ framebuffers.add(framebuffer);
}
+ }
- void run()
+ void createRequiredResources()
+ {
+ platform::Application::init();
+
+ platform::WindowDesc windowDesc;
+ windowDesc.title = "";
+ windowDesc.width = width;
+ windowDesc.height = height;
+ windowDesc.style = platform::WindowStyle::Default;
+ window = platform::Application::createWindow(windowDesc);
+
+ ICommandQueue::Desc queueDesc = {};
+ queueDesc.type = ICommandQueue::QueueType::Graphics;
+ queue = device->createCommandQueue(queueDesc);
+
+ ISwapchain::Desc swapchainDesc = {};
+ swapchainDesc.format = desiredFormat;
+ swapchainDesc.width = width;
+ swapchainDesc.height = height;
+ swapchainDesc.imageCount = kSwapchainImageCount;
+ swapchainDesc.queue = queue;
+ WindowHandle windowHandle = window->getNativeHandle().convert<WindowHandle>();
+ auto createSwapchainResult =
+ device->createSwapchain(swapchainDesc, windowHandle, swapchain.writeRef());
+ if (SLANG_FAILED(createSwapchainResult))
{
- createRequiredResources();
- // Render for 5 frames then resize the swapchain and render for another 5 frames to ensure the
- // swapchain remains usable after resizing.
- for (GfxIndex i = 0; i < 5; ++i)
- {
- renderFrame(i % kSwapchainImageCount);
- }
- queue->waitOnHost();
-
- framebuffers = decltype(framebuffers)();
- GFX_CHECK_CALL(swapchain->resize(700, 700));
- createSwapchainFramebuffers();
- width = 700;
- height = 700;
-
- for (GfxIndex i = 0; i < 5; ++i)
- {
- renderFrame(i % kSwapchainImageCount);
- }
- queue->waitOnHost();
+ SLANG_IGNORE_TEST;
}
- };
- void swapchainResizeTestImpl(IDevice* device, UnitTestContext* context)
- {
- SwapchainResizeTest t;
- t.init(device, context);
- t.run();
+ VertexStreamDesc vertexStreams[] = {
+ {sizeof(Vertex), InputSlotClass::PerVertex, 0},
+ };
+
+ InputElementDesc inputElements[] = {
+ // Vertex buffer data
+ {"POSITIONA", 0, Format::R32G32B32_FLOAT, offsetof(Vertex, position), 0},
+ };
+ IInputLayout::Desc inputLayoutDesc = {};
+ inputLayoutDesc.inputElementCount = SLANG_COUNT_OF(inputElements);
+ inputLayoutDesc.inputElements = inputElements;
+ inputLayoutDesc.vertexStreamCount = SLANG_COUNT_OF(vertexStreams);
+ inputLayoutDesc.vertexStreams = vertexStreams;
+ auto inputLayout = device->createInputLayout(inputLayoutDesc);
+ SLANG_CHECK_ABORT(inputLayout != nullptr);
+
+ IBufferResource::Desc vertexBufferDesc;
+ vertexBufferDesc.type = IResource::Type::Buffer;
+ vertexBufferDesc.sizeInBytes = kVertexCount * sizeof(Vertex);
+ vertexBufferDesc.defaultState = ResourceState::VertexBuffer;
+ vertexBuffer = device->createBufferResource(vertexBufferDesc, &kVertexData[0]);
+ SLANG_CHECK_ABORT(vertexBuffer != nullptr);
+
+ ITransientResourceHeap::Desc transientHeapDesc = {};
+ transientHeapDesc.constantBufferSize = 4096 * 1024;
+ GFX_CHECK_CALL_ABORT(
+ device->createTransientResourceHeap(transientHeapDesc, transientHeap.writeRef()));
+
+ ComPtr<IShaderProgram> shaderProgram;
+ slang::ProgramLayout* slangReflection;
+ GFX_CHECK_CALL_ABORT(loadGraphicsProgram(
+ device,
+ shaderProgram,
+ "swapchain-shader",
+ "vertexMain",
+ "fragmentMain",
+ slangReflection));
+
+ IFramebufferLayout::TargetLayout targetLayout;
+ targetLayout.format = swapchain->getDesc().format;
+ targetLayout.sampleCount = 1;
+
+ IFramebufferLayout::Desc framebufferLayoutDesc;
+ framebufferLayoutDesc.renderTargetCount = 1;
+ framebufferLayoutDesc.renderTargets = &targetLayout;
+ framebufferLayout = device->createFramebufferLayout(framebufferLayoutDesc);
+ SLANG_CHECK_ABORT(framebufferLayout != nullptr);
+
+ GraphicsPipelineStateDesc pipelineDesc = {};
+ pipelineDesc.program = shaderProgram.get();
+ pipelineDesc.inputLayout = inputLayout;
+ pipelineDesc.framebufferLayout = framebufferLayout;
+ pipelineDesc.depthStencil.depthTestEnable = false;
+ pipelineDesc.depthStencil.depthWriteEnable = false;
+ GFX_CHECK_CALL_ABORT(
+ device->createGraphicsPipelineState(pipelineDesc, pipelineState.writeRef()));
+
+ IRenderPassLayout::Desc renderPassDesc = {};
+ renderPassDesc.framebufferLayout = framebufferLayout;
+ renderPassDesc.renderTargetCount = 1;
+ IRenderPassLayout::TargetAccessDesc renderTargetAccess = {};
+ renderTargetAccess.loadOp = IRenderPassLayout::TargetLoadOp::Clear;
+ renderTargetAccess.storeOp = IRenderPassLayout::TargetStoreOp::Store;
+ renderTargetAccess.initialState = ResourceState::Undefined;
+ renderTargetAccess.finalState = ResourceState::Present;
+ renderPassDesc.renderTargetAccess = &renderTargetAccess;
+ GFX_CHECK_CALL_ABORT(device->createRenderPassLayout(renderPassDesc, renderPass.writeRef()));
+
+ createSwapchainFramebuffers();
}
- SLANG_UNIT_TEST(swapchainResizeD3D12)
+ void renderFrame(GfxIndex framebufferIndex)
{
- runTestImpl(swapchainResizeTestImpl, unitTestContext, RenderApiFlag::D3D12);
+ auto commandBuffer = transientHeap->createCommandBuffer();
+
+ auto encoder =
+ commandBuffer->encodeRenderCommands(renderPass, framebuffers[framebufferIndex]);
+ auto rootObject = encoder->bindPipeline(pipelineState);
+
+ gfx::Viewport viewport = {};
+ viewport.maxZ = 1.0f;
+ viewport.extentX = (float)width;
+ viewport.extentY = (float)height;
+ encoder->setViewportAndScissor(viewport);
+
+ encoder->setVertexBuffer(0, vertexBuffer);
+ encoder->setPrimitiveTopology(PrimitiveTopology::TriangleList);
+
+ swapchain->acquireNextImage();
+ encoder->draw(kVertexCount);
+ encoder->endEncoding();
+ commandBuffer->close();
+ queue->executeCommandBuffer(commandBuffer);
+ swapchain->present();
}
- SLANG_UNIT_TEST(swapchainResizeVulkan)
+ void run()
{
- runTestImpl(swapchainResizeTestImpl, unitTestContext, RenderApiFlag::Vulkan);
+ createRequiredResources();
+ // Render for 5 frames then resize the swapchain and render for another 5 frames to ensure
+ // the swapchain remains usable after resizing.
+ for (GfxIndex i = 0; i < 5; ++i)
+ {
+ renderFrame(i % kSwapchainImageCount);
+ }
+ queue->waitOnHost();
+
+ framebuffers = decltype(framebuffers)();
+ GFX_CHECK_CALL(swapchain->resize(700, 700));
+ createSwapchainFramebuffers();
+ width = 700;
+ height = 700;
+
+ for (GfxIndex i = 0; i < 5; ++i)
+ {
+ renderFrame(i % kSwapchainImageCount);
+ }
+ queue->waitOnHost();
}
+};
+
+void swapchainResizeTestImpl(IDevice* device, UnitTestContext* context)
+{
+ SwapchainResizeTest t;
+ t.init(device, context);
+ t.run();
+}
+SLANG_UNIT_TEST(swapchainResizeD3D12)
+{
+ runTestImpl(swapchainResizeTestImpl, unitTestContext, RenderApiFlag::D3D12);
}
+
+SLANG_UNIT_TEST(swapchainResizeVulkan)
+{
+ runTestImpl(swapchainResizeTestImpl, unitTestContext, RenderApiFlag::Vulkan);
+}
+
+} // namespace gfx_test
diff --git a/tools/gfx-unit-test/texture-types-tests.cpp b/tools/gfx-unit-test/texture-types-tests.cpp
index 7f010e6fd..0aa082a1e 100644
--- a/tools/gfx-unit-test/texture-types-tests.cpp
+++ b/tools/gfx-unit-test/texture-types-tests.cpp
@@ -1,10 +1,9 @@
-#include "tools/unit-test/slang-unit-test.h"
-
-#include "slang-gfx.h"
-#include "gfx-test-util.h"
#include "gfx-test-texture-util.h"
-#include "tools/gfx-util/shader-cursor.h"
+#include "gfx-test-util.h"
+#include "slang-gfx.h"
#include "source/core/slang-basic.h"
+#include "tools/gfx-util/shader-cursor.h"
+#include "tools/unit-test/slang-unit-test.h"
#if SLANG_WINDOWS_FAMILY
#include <d3d12.h>
@@ -15,654 +14,688 @@ using namespace gfx;
namespace gfx_test
{
- struct BaseTextureViewTest
- {
- IDevice* device;
- UnitTestContext* context;
+struct BaseTextureViewTest
+{
+ IDevice* device;
+ UnitTestContext* context;
- IResourceView::Type viewType;
- size_t alignedRowStride;
+ IResourceView::Type viewType;
+ size_t alignedRowStride;
- RefPtr<TextureInfo> textureInfo;
- RefPtr<ValidationTextureFormatBase> validationFormat;
+ RefPtr<TextureInfo> textureInfo;
+ RefPtr<ValidationTextureFormatBase> validationFormat;
- ComPtr<ITextureResource> texture;
- ComPtr<IResourceView> textureView;
- ComPtr<IBufferResource> resultsBuffer;
- ComPtr<IResourceView> bufferView;
+ ComPtr<ITextureResource> texture;
+ ComPtr<IResourceView> textureView;
+ ComPtr<IBufferResource> resultsBuffer;
+ ComPtr<IResourceView> bufferView;
- ComPtr<ISamplerState> sampler;
+ ComPtr<ISamplerState> sampler;
- const void* expectedTextureData;
+ const void* expectedTextureData;
- void init(
- IDevice* device,
- UnitTestContext* context,
- Format format,
- RefPtr<ValidationTextureFormatBase> validationFormat,
- IResourceView::Type viewType,
- IResource::Type type)
+ void init(
+ IDevice* device,
+ UnitTestContext* context,
+ Format format,
+ RefPtr<ValidationTextureFormatBase> validationFormat,
+ IResourceView::Type viewType,
+ IResource::Type type)
+ {
+ this->device = device;
+ this->context = context;
+ this->validationFormat = validationFormat;
+ this->viewType = viewType;
+
+ this->textureInfo = new TextureInfo();
+ this->textureInfo->format = format;
+ this->textureInfo->textureType = type;
+ }
+
+ ResourceState getDefaultResourceStateForViewType(IResourceView::Type type)
+ {
+ switch (type)
{
- this->device = device;
- this->context = context;
- this->validationFormat = validationFormat;
- this->viewType = viewType;
-
- this->textureInfo = new TextureInfo();
- this->textureInfo->format = format;
- this->textureInfo->textureType = type;
+ case IResourceView::Type::RenderTarget: return ResourceState::RenderTarget;
+ case IResourceView::Type::DepthStencil: return ResourceState::DepthWrite;
+ case IResourceView::Type::ShaderResource: return ResourceState::ShaderResource;
+ case IResourceView::Type::UnorderedAccess: return ResourceState::UnorderedAccess;
+ case IResourceView::Type::AccelerationStructure:
+ return ResourceState::AccelerationStructure;
+ default: return ResourceState::Undefined;
}
+ }
+
+ String getShaderEntryPoint()
+ {
+ String base = "resourceViewTest";
+ String shape;
+ String view;
- ResourceState getDefaultResourceStateForViewType(IResourceView::Type type)
+ switch (textureInfo->textureType)
{
- switch (type)
- {
- case IResourceView::Type::RenderTarget:
- return ResourceState::RenderTarget;
- case IResourceView::Type::DepthStencil:
- return ResourceState::DepthWrite;
- case IResourceView::Type::ShaderResource:
- return ResourceState::ShaderResource;
- case IResourceView::Type::UnorderedAccess:
- return ResourceState::UnorderedAccess;
- case IResourceView::Type::AccelerationStructure:
- return ResourceState::AccelerationStructure;
- default:
- return ResourceState::Undefined;
- }
+ case IResource::Type::Texture1D: shape = "1D"; break;
+ case IResource::Type::Texture2D: shape = "2D"; break;
+ case IResource::Type::Texture3D: shape = "3D"; break;
+ case IResource::Type::TextureCube: shape = "Cube"; break;
+ default: assert(!"Invalid texture shape"); SLANG_CHECK_ABORT(false);
}
- String getShaderEntryPoint()
+ switch (viewType)
{
- String base = "resourceViewTest";
- String shape;
- String view;
-
- switch (textureInfo->textureType)
- {
- case IResource::Type::Texture1D:
- shape = "1D";
- break;
- case IResource::Type::Texture2D:
- shape = "2D";
- break;
- case IResource::Type::Texture3D:
- shape = "3D";
- break;
- case IResource::Type::TextureCube:
- shape = "Cube";
- break;
- default:
- assert(!"Invalid texture shape");
- SLANG_CHECK_ABORT(false);
- }
-
- switch (viewType)
- {
- case IResourceView::Type::RenderTarget:
- view = "Render";
- break;
- case IResourceView::Type::DepthStencil:
- view = "Depth";
- break;
- case IResourceView::Type::ShaderResource:
- view = "Shader";
- break;
- case IResourceView::Type::UnorderedAccess:
- view = "Unordered";
- break;
- case IResourceView::Type::AccelerationStructure:
- view = "Accel";
- break;
- default:
- assert(!"Invalid resource view");
- SLANG_CHECK_ABORT(false);
- }
-
- return base + shape + view;
+ case IResourceView::Type::RenderTarget: view = "Render"; break;
+ case IResourceView::Type::DepthStencil: view = "Depth"; break;
+ case IResourceView::Type::ShaderResource: view = "Shader"; break;
+ case IResourceView::Type::UnorderedAccess: view = "Unordered"; break;
+ case IResourceView::Type::AccelerationStructure: view = "Accel"; break;
+ default: assert(!"Invalid resource view"); SLANG_CHECK_ABORT(false);
}
-
- };
+ return base + shape + view;
+ }
+};
- // used for shaderresource and unorderedaccess
- struct ShaderAndUnorderedTests : BaseTextureViewTest
+// used for shaderresource and unorderedaccess
+struct ShaderAndUnorderedTests : BaseTextureViewTest
+{
+ void createRequiredResources()
{
- void createRequiredResources()
- {
- ITextureResource::Desc textureDesc = {};
- textureDesc.type = textureInfo->textureType;
- textureDesc.numMipLevels = textureInfo->mipLevelCount;
- textureDesc.arraySize = textureInfo->arrayLayerCount;
- textureDesc.size = textureInfo->extents;
- textureDesc.defaultState = getDefaultResourceStateForViewType(viewType);
- textureDesc.allowedStates = ResourceStateSet(
- textureDesc.defaultState,
- ResourceState::CopySource,
- ResourceState::CopyDestination);
- textureDesc.format = textureInfo->format;
-
- GFX_CHECK_CALL_ABORT(device->createTextureResource(
- textureDesc,
- textureInfo->subresourceDatas.getBuffer(),
- texture.writeRef()));
-
- IResourceView::Desc textureViewDesc = {};
- textureViewDesc.type = viewType;
- textureViewDesc.format = textureDesc.format; // TODO: Handle typeless formats - gfxIsTypelessFormat(format) ? convertTypelessFormat(format) : format;
- GFX_CHECK_CALL_ABORT(device->createTextureView(texture, textureViewDesc, textureView.writeRef()));
-
- auto texelSize = getTexelSize(textureInfo->format);
- size_t alignment;
- device->getTextureRowAlignment(&alignment);
- alignedRowStride = (textureInfo->extents.width * texelSize + alignment - 1) & ~(alignment - 1);
- IBufferResource::Desc bufferDesc = {};
- // All of the values read back from the shader will be uint32_t
- bufferDesc.sizeInBytes = textureDesc.size.width * textureDesc.size.height * textureDesc.size.depth * texelSize * sizeof(uint32_t);
- bufferDesc.format = Format::Unknown;
- bufferDesc.elementSize = sizeof(uint32_t);
- bufferDesc.defaultState = ResourceState::UnorderedAccess;
- bufferDesc.allowedStates = ResourceStateSet(
- bufferDesc.defaultState,
- ResourceState::CopyDestination,
- ResourceState::CopySource);
- bufferDesc.memoryType = MemoryType::DeviceLocal;
-
- GFX_CHECK_CALL_ABORT(device->createBufferResource(bufferDesc, nullptr, resultsBuffer.writeRef()));
-
- IResourceView::Desc bufferViewDesc = {};
- bufferViewDesc.type = IResourceView::Type::UnorderedAccess;
- bufferViewDesc.format = Format::Unknown;
- GFX_CHECK_CALL_ABORT(device->createBufferView(resultsBuffer, nullptr, bufferViewDesc, bufferView.writeRef()));
- }
+ ITextureResource::Desc textureDesc = {};
+ textureDesc.type = textureInfo->textureType;
+ textureDesc.numMipLevels = textureInfo->mipLevelCount;
+ textureDesc.arraySize = textureInfo->arrayLayerCount;
+ textureDesc.size = textureInfo->extents;
+ textureDesc.defaultState = getDefaultResourceStateForViewType(viewType);
+ textureDesc.allowedStates = ResourceStateSet(
+ textureDesc.defaultState,
+ ResourceState::CopySource,
+ ResourceState::CopyDestination);
+ textureDesc.format = textureInfo->format;
+
+ GFX_CHECK_CALL_ABORT(device->createTextureResource(
+ textureDesc,
+ textureInfo->subresourceDatas.getBuffer(),
+ texture.writeRef()));
+
+ IResourceView::Desc textureViewDesc = {};
+ textureViewDesc.type = viewType;
+ textureViewDesc.format =
+ textureDesc.format; // TODO: Handle typeless formats - gfxIsTypelessFormat(format) ?
+ // convertTypelessFormat(format) : format;
+ GFX_CHECK_CALL_ABORT(
+ device->createTextureView(texture, textureViewDesc, textureView.writeRef()));
+
+ auto texelSize = getTexelSize(textureInfo->format);
+ size_t alignment;
+ device->getTextureRowAlignment(&alignment);
+ alignedRowStride =
+ (textureInfo->extents.width * texelSize + alignment - 1) & ~(alignment - 1);
+ IBufferResource::Desc bufferDesc = {};
+ // All of the values read back from the shader will be uint32_t
+ bufferDesc.sizeInBytes = textureDesc.size.width * textureDesc.size.height *
+ textureDesc.size.depth * texelSize * sizeof(uint32_t);
+ bufferDesc.format = Format::Unknown;
+ bufferDesc.elementSize = sizeof(uint32_t);
+ bufferDesc.defaultState = ResourceState::UnorderedAccess;
+ bufferDesc.allowedStates = ResourceStateSet(
+ bufferDesc.defaultState,
+ ResourceState::CopyDestination,
+ ResourceState::CopySource);
+ bufferDesc.memoryType = MemoryType::DeviceLocal;
+
+ GFX_CHECK_CALL_ABORT(
+ device->createBufferResource(bufferDesc, nullptr, resultsBuffer.writeRef()));
+
+ IResourceView::Desc bufferViewDesc = {};
+ bufferViewDesc.type = IResourceView::Type::UnorderedAccess;
+ bufferViewDesc.format = Format::Unknown;
+ GFX_CHECK_CALL_ABORT(device->createBufferView(
+ resultsBuffer,
+ nullptr,
+ bufferViewDesc,
+ bufferView.writeRef()));
+ }
- void submitShaderWork(const char* entryPoint)
+ void submitShaderWork(const char* entryPoint)
+ {
+ Slang::ComPtr<ITransientResourceHeap> transientHeap;
+ ITransientResourceHeap::Desc transientHeapDesc = {};
+ transientHeapDesc.constantBufferSize = 4096;
+ GFX_CHECK_CALL_ABORT(
+ device->createTransientResourceHeap(transientHeapDesc, transientHeap.writeRef()));
+
+ ComPtr<IShaderProgram> shaderProgram;
+ slang::ProgramLayout* slangReflection;
+ GFX_CHECK_CALL_ABORT(loadComputeProgram(
+ device,
+ shaderProgram,
+ "trivial-copy-textures",
+ entryPoint,
+ slangReflection));
+
+ ComputePipelineStateDesc pipelineDesc = {};
+ pipelineDesc.program = shaderProgram.get();
+ ComPtr<gfx::IPipelineState> pipelineState;
+ GFX_CHECK_CALL_ABORT(
+ device->createComputePipelineState(pipelineDesc, pipelineState.writeRef()));
+
+ // We have done all the set up work, now it is time to start recording a command buffer for
+ // GPU execution.
{
- Slang::ComPtr<ITransientResourceHeap> transientHeap;
- ITransientResourceHeap::Desc transientHeapDesc = {};
- transientHeapDesc.constantBufferSize = 4096;
- GFX_CHECK_CALL_ABORT(
- device->createTransientResourceHeap(transientHeapDesc, transientHeap.writeRef()));
-
- ComPtr<IShaderProgram> shaderProgram;
- slang::ProgramLayout* slangReflection;
- GFX_CHECK_CALL_ABORT(loadComputeProgram(device, shaderProgram, "trivial-copy-textures", entryPoint, slangReflection));
-
- ComputePipelineStateDesc pipelineDesc = {};
- pipelineDesc.program = shaderProgram.get();
- ComPtr<gfx::IPipelineState> pipelineState;
- GFX_CHECK_CALL_ABORT(
- device->createComputePipelineState(pipelineDesc, pipelineState.writeRef()));
-
- // We have done all the set up work, now it is time to start recording a command buffer for
- // GPU execution.
- {
- ICommandQueue::Desc queueDesc = { ICommandQueue::QueueType::Graphics };
- auto queue = device->createCommandQueue(queueDesc);
+ ICommandQueue::Desc queueDesc = {ICommandQueue::QueueType::Graphics};
+ auto queue = device->createCommandQueue(queueDesc);
- auto commandBuffer = transientHeap->createCommandBuffer();
- auto encoder = commandBuffer->encodeComputeCommands();
+ auto commandBuffer = transientHeap->createCommandBuffer();
+ auto encoder = commandBuffer->encodeComputeCommands();
- auto rootObject = encoder->bindPipeline(pipelineState);
+ auto rootObject = encoder->bindPipeline(pipelineState);
- ShaderCursor entryPointCursor(
- rootObject->getEntryPoint(0)); // get a cursor the the first entry-point.
+ ShaderCursor entryPointCursor(
+ rootObject->getEntryPoint(0)); // get a cursor the the first entry-point.
- auto width = textureInfo->extents.width;
- auto height = textureInfo->extents.height;
- auto depth = textureInfo->extents.depth;
+ auto width = textureInfo->extents.width;
+ auto height = textureInfo->extents.height;
+ auto depth = textureInfo->extents.depth;
- entryPointCursor["width"].setData(width);
- entryPointCursor["height"].setData(height);
- entryPointCursor["depth"].setData(depth);
+ entryPointCursor["width"].setData(width);
+ entryPointCursor["height"].setData(height);
+ entryPointCursor["depth"].setData(depth);
- // Bind texture view to the entry point
- entryPointCursor["resourceView"].setResource(textureView); // TODO: Bind nullptr and make sure it doesn't splut - should be 0 everywhere
- entryPointCursor["testResults"].setResource(bufferView);
+ // Bind texture view to the entry point
+ entryPointCursor["resourceView"].setResource(
+ textureView); // TODO: Bind nullptr and make sure it doesn't splut - should be 0
+ // everywhere
+ entryPointCursor["testResults"].setResource(bufferView);
- if (sampler) entryPointCursor["sampler"].setSampler(sampler); // TODO: Bind nullptr and make sure it doesn't splut
+ if (sampler)
+ entryPointCursor["sampler"].setSampler(
+ sampler); // TODO: Bind nullptr and make sure it doesn't splut
- auto bufferElementCount = width * height * depth;
- encoder->dispatchCompute(bufferElementCount, 1, 1);
- encoder->endEncoding();
- commandBuffer->close();
- queue->executeCommandBuffer(commandBuffer);
- queue->waitOnHost();
- }
+ auto bufferElementCount = width * height * depth;
+ encoder->dispatchCompute(bufferElementCount, 1, 1);
+ encoder->endEncoding();
+ commandBuffer->close();
+ queue->executeCommandBuffer(commandBuffer);
+ queue->waitOnHost();
}
+ }
- void validateTextureValues(ValidationTextureData actual, ValidationTextureData original)
+ void validateTextureValues(ValidationTextureData actual, ValidationTextureData original)
+ {
+ // TODO: needs to be extended to cover mip levels and array layers
+ for (GfxIndex x = 0; x < actual.extents.width; ++x)
{
- // TODO: needs to be extended to cover mip levels and array layers
- for (GfxIndex x = 0; x < actual.extents.width; ++x)
+ for (GfxIndex y = 0; y < actual.extents.height; ++y)
{
- for (GfxIndex y = 0; y < actual.extents.height; ++y)
+ for (GfxIndex z = 0; z < actual.extents.depth; ++z)
{
- for (GfxIndex z = 0; z < actual.extents.depth; ++z)
+ auto actualBlock = (uint8_t*)actual.getBlockAt(x, y, z);
+ for (Int i = 0; i < 4; ++i)
{
- auto actualBlock = (uint8_t*)actual.getBlockAt(x, y, z);
- for (Int i = 0; i < 4; ++i)
- {
- SLANG_CHECK(actualBlock[i] == 1);
- }
+ SLANG_CHECK(actualBlock[i] == 1);
}
}
}
}
+ }
- void checkTestResults()
+ void checkTestResults()
+ {
+ // Shader resources are read-only, so we don't need to check that writes to the resource
+ // were correct.
+ if (viewType != IResourceView::Type::ShaderResource)
{
- // Shader resources are read-only, so we don't need to check that writes to the resource were correct.
- if (viewType != IResourceView::Type::ShaderResource)
- {
- ComPtr<ISlangBlob> textureBlob;
- size_t rowPitch;
- size_t pixelSize;
- GFX_CHECK_CALL_ABORT(device->readTextureResource(texture, ResourceState::CopySource, textureBlob.writeRef(), &rowPitch, &pixelSize));
- auto textureValues = (uint8_t*)textureBlob->getBufferPointer();
-
- ValidationTextureData textureResults;
- textureResults.extents = textureInfo->extents;
- textureResults.textureData = textureValues;
- textureResults.strides.x = (uint32_t)pixelSize;
- textureResults.strides.y = (uint32_t)rowPitch;
- textureResults.strides.z = textureResults.extents.height * textureResults.strides.y;
-
- ValidationTextureData originalData;
- originalData.extents = textureInfo->extents;
- originalData.textureData = textureInfo->subresourceDatas.getBuffer();
- originalData.strides.x = (uint32_t)pixelSize;
- originalData.strides.y = textureInfo->extents.width * originalData.strides.x;
- originalData.strides.z = textureInfo->extents.height * originalData.strides.y;
-
- validateTextureValues(textureResults, originalData);
- }
+ ComPtr<ISlangBlob> textureBlob;
+ size_t rowPitch;
+ size_t pixelSize;
+ GFX_CHECK_CALL_ABORT(device->readTextureResource(
+ texture,
+ ResourceState::CopySource,
+ textureBlob.writeRef(),
+ &rowPitch,
+ &pixelSize));
+ auto textureValues = (uint8_t*)textureBlob->getBufferPointer();
- ComPtr<ISlangBlob> bufferBlob;
- GFX_CHECK_CALL_ABORT(device->readBufferResource(resultsBuffer, 0, resultsBuffer->getDesc()->sizeInBytes, bufferBlob.writeRef()));
- auto results = (uint32_t*)bufferBlob->getBufferPointer();
+ ValidationTextureData textureResults;
+ textureResults.extents = textureInfo->extents;
+ textureResults.textureData = textureValues;
+ textureResults.strides.x = (uint32_t)pixelSize;
+ textureResults.strides.y = (uint32_t)rowPitch;
+ textureResults.strides.z = textureResults.extents.height * textureResults.strides.y;
- auto elementCount = textureInfo->extents.width * textureInfo->extents.height * textureInfo->extents.depth * 4;
- auto castedTextureData = (uint8_t*)expectedTextureData;
- for (Int i = 0; i < elementCount; ++i)
- {
- SLANG_CHECK(results[i] == castedTextureData[i]);
- }
+ ValidationTextureData originalData;
+ originalData.extents = textureInfo->extents;
+ originalData.textureData = textureInfo->subresourceDatas.getBuffer();
+ originalData.strides.x = (uint32_t)pixelSize;
+ originalData.strides.y = textureInfo->extents.width * originalData.strides.x;
+ originalData.strides.z = textureInfo->extents.height * originalData.strides.y;
+
+ validateTextureValues(textureResults, originalData);
}
- void run()
+ ComPtr<ISlangBlob> bufferBlob;
+ GFX_CHECK_CALL_ABORT(device->readBufferResource(
+ resultsBuffer,
+ 0,
+ resultsBuffer->getDesc()->sizeInBytes,
+ bufferBlob.writeRef()));
+ auto results = (uint32_t*)bufferBlob->getBufferPointer();
+
+ auto elementCount = textureInfo->extents.width * textureInfo->extents.height *
+ textureInfo->extents.depth * 4;
+ auto castedTextureData = (uint8_t*)expectedTextureData;
+ for (Int i = 0; i < elementCount; ++i)
{
- // TODO: Should test with samplers
-// ISamplerState::Desc samplerDesc;
-// sampler = device->createSamplerState(samplerDesc);
-
- // TODO: Should test multiple mip levels and array layers
- textureInfo->extents.width = 4;
- textureInfo->extents.height = (textureInfo->textureType == IResource::Type::Texture1D) ? 1 : 4;
- textureInfo->extents.depth = (textureInfo->textureType != IResource::Type::Texture3D) ? 1 : 2;
- textureInfo->mipLevelCount = 1;
- textureInfo->arrayLayerCount = 1;
- generateTextureData(textureInfo, validationFormat);
-
- // We need to save the pointer to the original texture data for results checking because the texture will be
- // overwritten during testing (if the texture can be written to).
- expectedTextureData = textureInfo->subresourceDatas[getSubresourceIndex(0, 1, 0)].data;
-
- createRequiredResources();
- auto entryPointName = getShaderEntryPoint();
- //printf("%s\n", entryPointName.getBuffer());
- submitShaderWork(entryPointName.getBuffer());
-
- checkTestResults();
+ SLANG_CHECK(results[i] == castedTextureData[i]);
}
+ }
+
+ void run()
+ {
+ // TODO: Should test with samplers
+ // ISamplerState::Desc samplerDesc;
+ // sampler = device->createSamplerState(samplerDesc);
+
+ // TODO: Should test multiple mip levels and array layers
+ textureInfo->extents.width = 4;
+ textureInfo->extents.height =
+ (textureInfo->textureType == IResource::Type::Texture1D) ? 1 : 4;
+ textureInfo->extents.depth =
+ (textureInfo->textureType != IResource::Type::Texture3D) ? 1 : 2;
+ textureInfo->mipLevelCount = 1;
+ textureInfo->arrayLayerCount = 1;
+ generateTextureData(textureInfo, validationFormat);
+
+ // We need to save the pointer to the original texture data for results checking because the
+ // texture will be overwritten during testing (if the texture can be written to).
+ expectedTextureData = textureInfo->subresourceDatas[getSubresourceIndex(0, 1, 0)].data;
+
+ createRequiredResources();
+ auto entryPointName = getShaderEntryPoint();
+ // printf("%s\n", entryPointName.getBuffer());
+ submitShaderWork(entryPointName.getBuffer());
+
+ checkTestResults();
+ }
+};
+
+// used for rendertarget and depthstencil
+struct RenderTargetTests : BaseTextureViewTest
+{
+ struct Vertex
+ {
+ float position[3];
+ float color[3];
};
- // used for rendertarget and depthstencil
- struct RenderTargetTests : BaseTextureViewTest
+ const int kVertexCount = 12;
+ const Vertex kVertexData[12] = {
+ // Triangle 1
+ {{0, 0, 0.5}, {1, 0, 0}},
+ {{1, 1, 0.5}, {1, 0, 0}},
+ {{-1, 1, 0.5}, {1, 0, 0}},
+
+ // Triangle 2
+ {{-1, 1, 0.5}, {0, 1, 0}},
+ {{0, 0, 0.5}, {0, 1, 0}},
+ {{-1, -1, 0.5}, {0, 1, 0}},
+
+ // Triangle 3
+ {{-1, -1, 0.5}, {0, 0, 1}},
+ {{0, 0, 0.5}, {0, 0, 1}},
+ {{1, -1, 0.5}, {0, 0, 1}},
+
+ // Triangle 4
+ {{1, -1, 0.5}, {0, 0, 0}},
+ {{0, 0, 0.5}, {0, 0, 0}},
+ {{1, 1, 0.5}, {0, 0, 0}},
+ };
+
+ int sampleCount = 1;
+
+ ComPtr<ITransientResourceHeap> transientHeap;
+ ComPtr<IPipelineState> pipelineState;
+ ComPtr<IRenderPassLayout> renderPass;
+ ComPtr<IFramebuffer> framebuffer;
+
+ ComPtr<ITextureResource> sampledTexture;
+ ComPtr<IBufferResource> vertexBuffer;
+
+ void createRequiredResources()
{
- struct Vertex
- {
- float position[3];
- float color[3];
+ IBufferResource::Desc vertexBufferDesc;
+ vertexBufferDesc.type = IResource::Type::Buffer;
+ vertexBufferDesc.sizeInBytes = kVertexCount * sizeof(Vertex);
+ vertexBufferDesc.defaultState = ResourceState::VertexBuffer;
+ vertexBufferDesc.allowedStates = ResourceState::VertexBuffer;
+ vertexBuffer = device->createBufferResource(vertexBufferDesc, &kVertexData[0]);
+ SLANG_CHECK_ABORT(vertexBuffer != nullptr);
+
+ VertexStreamDesc vertexStreams[] = {
+ {sizeof(Vertex), InputSlotClass::PerVertex, 0},
};
- const int kVertexCount = 12;
- const Vertex kVertexData[12] =
- {
- // Triangle 1
- { { 0, 0, 0.5 }, { 1, 0, 0 } },
- { { 1, 1, 0.5 }, { 1, 0, 0 } },
- { { -1, 1, 0.5 }, { 1, 0, 0 } },
-
- // Triangle 2
- { { -1, 1, 0.5 }, { 0, 1, 0 } },
- { { 0, 0, 0.5 }, { 0, 1, 0 } },
- { { -1, -1, 0.5 }, { 0, 1, 0 } },
-
- // Triangle 3
- { { -1, -1, 0.5 }, { 0, 0, 1 } },
- { { 0, 0, 0.5 }, { 0, 0, 1 } },
- { { 1, -1, 0.5 }, { 0, 0, 1 } },
-
- // Triangle 4
- { { 1, -1, 0.5 }, { 0, 0, 0 } },
- { { 0, 0, 0.5 }, { 0, 0, 0 } },
- { { 1, 1, 0.5 }, { 0, 0, 0 } },
+ InputElementDesc inputElements[] = {
+ // Vertex buffer data
+ {"POSITION", 0, Format::R32G32B32_FLOAT, offsetof(Vertex, position), 0},
+ {"COLOR", 0, Format::R32G32B32_FLOAT, offsetof(Vertex, color), 0},
};
- int sampleCount = 1;
+ ITextureResource::Desc sampledTexDesc = {};
+ sampledTexDesc.type = textureInfo->textureType;
+ sampledTexDesc.numMipLevels = textureInfo->mipLevelCount;
+ sampledTexDesc.arraySize = textureInfo->arrayLayerCount;
+ sampledTexDesc.size = textureInfo->extents;
+ sampledTexDesc.defaultState = getDefaultResourceStateForViewType(viewType);
+ sampledTexDesc.allowedStates = ResourceStateSet(
+ sampledTexDesc.defaultState,
+ ResourceState::ResolveSource,
+ ResourceState::CopySource);
+ sampledTexDesc.format = textureInfo->format;
+ sampledTexDesc.sampleDesc.numSamples = sampleCount;
+
+ GFX_CHECK_CALL_ABORT(device->createTextureResource(
+ sampledTexDesc,
+ textureInfo->subresourceDatas.getBuffer(),
+ sampledTexture.writeRef()));
+
+ ITextureResource::Desc texDesc = {};
+ texDesc.type = textureInfo->textureType;
+ texDesc.numMipLevels = textureInfo->mipLevelCount;
+ texDesc.arraySize = textureInfo->arrayLayerCount;
+ texDesc.size = textureInfo->extents;
+ texDesc.defaultState = ResourceState::ResolveDestination;
+ texDesc.allowedStates =
+ ResourceStateSet(ResourceState::ResolveDestination, ResourceState::CopySource);
+ texDesc.format = textureInfo->format;
+
+ GFX_CHECK_CALL_ABORT(device->createTextureResource(
+ texDesc,
+ textureInfo->subresourceDatas.getBuffer(),
+ texture.writeRef()));
+
+ IInputLayout::Desc inputLayoutDesc = {};
+ inputLayoutDesc.inputElementCount = SLANG_COUNT_OF(inputElements);
+ inputLayoutDesc.inputElements = inputElements;
+ inputLayoutDesc.vertexStreamCount = SLANG_COUNT_OF(vertexStreams);
+ inputLayoutDesc.vertexStreams = vertexStreams;
+ auto inputLayout = device->createInputLayout(inputLayoutDesc);
+ SLANG_CHECK_ABORT(inputLayout != nullptr);
+
+ ITransientResourceHeap::Desc transientHeapDesc = {};
+ transientHeapDesc.constantBufferSize = 4096;
+ GFX_CHECK_CALL_ABORT(
+ device->createTransientResourceHeap(transientHeapDesc, transientHeap.writeRef()));
+
+ ComPtr<IShaderProgram> shaderProgram;
+ slang::ProgramLayout* slangReflection;
+ GFX_CHECK_CALL_ABORT(loadGraphicsProgram(
+ device,
+ shaderProgram,
+ "trivial-copy-textures",
+ "vertexMain",
+ "fragmentMain",
+ slangReflection));
+
+ IFramebufferLayout::TargetLayout targetLayout;
+ targetLayout.format = textureInfo->format;
+ targetLayout.sampleCount = sampleCount;
+
+ IFramebufferLayout::Desc framebufferLayoutDesc;
+ framebufferLayoutDesc.renderTargetCount = 1;
+ framebufferLayoutDesc.renderTargets = &targetLayout;
+ ComPtr<gfx::IFramebufferLayout> framebufferLayout =
+ device->createFramebufferLayout(framebufferLayoutDesc);
+ SLANG_CHECK_ABORT(framebufferLayout != nullptr);
+
+ GraphicsPipelineStateDesc pipelineDesc = {};
+ pipelineDesc.program = shaderProgram.get();
+ pipelineDesc.inputLayout = inputLayout;
+ pipelineDesc.framebufferLayout = framebufferLayout;
+ pipelineDesc.depthStencil.depthTestEnable = false;
+ pipelineDesc.depthStencil.depthWriteEnable = false;
+ GFX_CHECK_CALL_ABORT(
+ device->createGraphicsPipelineState(pipelineDesc, pipelineState.writeRef()));
+
+ IRenderPassLayout::Desc renderPassDesc = {};
+ renderPassDesc.framebufferLayout = framebufferLayout;
+ renderPassDesc.renderTargetCount = 1;
+ IRenderPassLayout::TargetAccessDesc renderTargetAccess = {};
+ renderTargetAccess.loadOp = IRenderPassLayout::TargetLoadOp::Clear;
+ renderTargetAccess.storeOp = IRenderPassLayout::TargetStoreOp::Store;
+ renderTargetAccess.initialState = getDefaultResourceStateForViewType(viewType);
+ renderTargetAccess.finalState = ResourceState::ResolveSource;
+ renderPassDesc.renderTargetAccess = &renderTargetAccess;
+ GFX_CHECK_CALL_ABORT(device->createRenderPassLayout(renderPassDesc, renderPass.writeRef()));
+
+ gfx::IResourceView::Desc colorBufferViewDesc;
+ memset(&colorBufferViewDesc, 0, sizeof(colorBufferViewDesc));
+ colorBufferViewDesc.format = textureInfo->format;
+ colorBufferViewDesc.renderTarget.shape = textureInfo->textureType; // TODO: TextureCube?
+ colorBufferViewDesc.type = viewType;
+ auto rtv = device->createTextureView(sampledTexture, colorBufferViewDesc);
+
+ gfx::IFramebuffer::Desc framebufferDesc;
+ framebufferDesc.renderTargetCount = 1;
+ framebufferDesc.depthStencilView = nullptr;
+ framebufferDesc.renderTargetViews = rtv.readRef();
+ framebufferDesc.layout = framebufferLayout;
+ GFX_CHECK_CALL_ABORT(device->createFramebuffer(framebufferDesc, framebuffer.writeRef()));
+
+ auto texelSize = getTexelSize(textureInfo->format);
+ size_t alignment;
+ device->getTextureRowAlignment(&alignment);
+ alignedRowStride =
+ (textureInfo->extents.width * texelSize + alignment - 1) & ~(alignment - 1);
+ }
+
+ void submitShaderWork(const char* entryPointName)
+ {
+ ICommandQueue::Desc queueDesc = {ICommandQueue::QueueType::Graphics};
+ auto queue = device->createCommandQueue(queueDesc);
+
+ auto commandBuffer = transientHeap->createCommandBuffer();
+ auto renderEncoder = commandBuffer->encodeRenderCommands(renderPass, framebuffer);
+ auto rootObject = renderEncoder->bindPipeline(pipelineState);
- ComPtr<ITransientResourceHeap> transientHeap;
- ComPtr<IPipelineState> pipelineState;
- ComPtr<IRenderPassLayout> renderPass;
- ComPtr<IFramebuffer> framebuffer;
+ gfx::Viewport viewport = {};
+ viewport.maxZ = (float)textureInfo->extents.depth;
+ viewport.extentX = (float)textureInfo->extents.width;
+ viewport.extentY = (float)textureInfo->extents.height;
+ renderEncoder->setViewportAndScissor(viewport);
- ComPtr<ITextureResource> sampledTexture;
- ComPtr<IBufferResource> vertexBuffer;
+ renderEncoder->setVertexBuffer(0, vertexBuffer);
+ renderEncoder->setPrimitiveTopology(PrimitiveTopology::TriangleList);
+ renderEncoder->draw(kVertexCount, 0);
+ renderEncoder->endEncoding();
- void createRequiredResources()
+ auto resourceEncoder = commandBuffer->encodeResourceCommands();
+
+ if (sampleCount > 1)
{
- IBufferResource::Desc vertexBufferDesc;
- vertexBufferDesc.type = IResource::Type::Buffer;
- vertexBufferDesc.sizeInBytes = kVertexCount * sizeof(Vertex);
- vertexBufferDesc.defaultState = ResourceState::VertexBuffer;
- vertexBufferDesc.allowedStates = ResourceState::VertexBuffer;
- vertexBuffer = device->createBufferResource(vertexBufferDesc, &kVertexData[0]);
- SLANG_CHECK_ABORT(vertexBuffer != nullptr);
-
- VertexStreamDesc vertexStreams[] = {
- { sizeof(Vertex), InputSlotClass::PerVertex, 0 },
- };
-
- InputElementDesc inputElements[] = {
- // Vertex buffer data
- { "POSITION", 0, Format::R32G32B32_FLOAT, offsetof(Vertex, position), 0 },
- { "COLOR", 0, Format::R32G32B32_FLOAT, offsetof(Vertex, color), 0 },
- };
-
- ITextureResource::Desc sampledTexDesc = {};
- sampledTexDesc.type = textureInfo->textureType;
- sampledTexDesc.numMipLevels = textureInfo->mipLevelCount;
- sampledTexDesc.arraySize = textureInfo->arrayLayerCount;
- sampledTexDesc.size = textureInfo->extents;
- sampledTexDesc.defaultState = getDefaultResourceStateForViewType(viewType);
- sampledTexDesc.allowedStates = ResourceStateSet(
- sampledTexDesc.defaultState,
+ SubresourceRange msaaSubresource = {};
+ msaaSubresource.aspectMask = TextureAspect::Color;
+ msaaSubresource.mipLevel = 0;
+ msaaSubresource.mipLevelCount = 1;
+ msaaSubresource.baseArrayLayer = 0;
+ msaaSubresource.layerCount = 1;
+
+ SubresourceRange dstSubresource = {};
+ dstSubresource.aspectMask = TextureAspect::Color;
+ dstSubresource.mipLevel = 0;
+ dstSubresource.mipLevelCount = 1;
+ dstSubresource.baseArrayLayer = 0;
+ dstSubresource.layerCount = 1;
+
+ resourceEncoder->resolveResource(
+ sampledTexture,
ResourceState::ResolveSource,
- ResourceState::CopySource);
- sampledTexDesc.format = textureInfo->format;
- sampledTexDesc.sampleDesc.numSamples = sampleCount;
-
- GFX_CHECK_CALL_ABORT(device->createTextureResource(
- sampledTexDesc,
- textureInfo->subresourceDatas.getBuffer(),
- sampledTexture.writeRef()));
-
- ITextureResource::Desc texDesc = {};
- texDesc.type = textureInfo->textureType;
- texDesc.numMipLevels = textureInfo->mipLevelCount;
- texDesc.arraySize = textureInfo->arrayLayerCount;
- texDesc.size = textureInfo->extents;
- texDesc.defaultState = ResourceState::ResolveDestination;
- texDesc.allowedStates = ResourceStateSet(
+ msaaSubresource,
+ texture,
+ ResourceState::ResolveDestination,
+ dstSubresource);
+ resourceEncoder->textureBarrier(
+ texture,
ResourceState::ResolveDestination,
ResourceState::CopySource);
- texDesc.format = textureInfo->format;
-
- GFX_CHECK_CALL_ABORT(device->createTextureResource(
- texDesc,
- textureInfo->subresourceDatas.getBuffer(),
- texture.writeRef()));
-
- IInputLayout::Desc inputLayoutDesc = {};
- inputLayoutDesc.inputElementCount = SLANG_COUNT_OF(inputElements);
- inputLayoutDesc.inputElements = inputElements;
- inputLayoutDesc.vertexStreamCount = SLANG_COUNT_OF(vertexStreams);
- inputLayoutDesc.vertexStreams = vertexStreams;
- auto inputLayout = device->createInputLayout(inputLayoutDesc);
- SLANG_CHECK_ABORT(inputLayout != nullptr);
-
- ITransientResourceHeap::Desc transientHeapDesc = {};
- transientHeapDesc.constantBufferSize = 4096;
- GFX_CHECK_CALL_ABORT(
- device->createTransientResourceHeap(transientHeapDesc, transientHeap.writeRef()));
-
- ComPtr<IShaderProgram> shaderProgram;
- slang::ProgramLayout* slangReflection;
- GFX_CHECK_CALL_ABORT(loadGraphicsProgram(device, shaderProgram, "trivial-copy-textures", "vertexMain", "fragmentMain", slangReflection));
-
- IFramebufferLayout::TargetLayout targetLayout;
- targetLayout.format = textureInfo->format;
- targetLayout.sampleCount = sampleCount;
-
- IFramebufferLayout::Desc framebufferLayoutDesc;
- framebufferLayoutDesc.renderTargetCount = 1;
- framebufferLayoutDesc.renderTargets = &targetLayout;
- ComPtr<gfx::IFramebufferLayout> framebufferLayout = device->createFramebufferLayout(framebufferLayoutDesc);
- SLANG_CHECK_ABORT(framebufferLayout != nullptr);
-
- GraphicsPipelineStateDesc pipelineDesc = {};
- pipelineDesc.program = shaderProgram.get();
- pipelineDesc.inputLayout = inputLayout;
- pipelineDesc.framebufferLayout = framebufferLayout;
- pipelineDesc.depthStencil.depthTestEnable = false;
- pipelineDesc.depthStencil.depthWriteEnable = false;
- GFX_CHECK_CALL_ABORT(
- device->createGraphicsPipelineState(pipelineDesc, pipelineState.writeRef()));
-
- IRenderPassLayout::Desc renderPassDesc = {};
- renderPassDesc.framebufferLayout = framebufferLayout;
- renderPassDesc.renderTargetCount = 1;
- IRenderPassLayout::TargetAccessDesc renderTargetAccess = {};
- renderTargetAccess.loadOp = IRenderPassLayout::TargetLoadOp::Clear;
- renderTargetAccess.storeOp = IRenderPassLayout::TargetStoreOp::Store;
- renderTargetAccess.initialState = getDefaultResourceStateForViewType(viewType);
- renderTargetAccess.finalState = ResourceState::ResolveSource;
- renderPassDesc.renderTargetAccess = &renderTargetAccess;
- GFX_CHECK_CALL_ABORT(device->createRenderPassLayout(renderPassDesc, renderPass.writeRef()));
-
- gfx::IResourceView::Desc colorBufferViewDesc;
- memset(&colorBufferViewDesc, 0, sizeof(colorBufferViewDesc));
- colorBufferViewDesc.format = textureInfo->format;
- colorBufferViewDesc.renderTarget.shape = textureInfo->textureType; // TODO: TextureCube?
- colorBufferViewDesc.type = viewType;
- auto rtv = device->createTextureView(sampledTexture, colorBufferViewDesc);
-
- gfx::IFramebuffer::Desc framebufferDesc;
- framebufferDesc.renderTargetCount = 1;
- framebufferDesc.depthStencilView = nullptr;
- framebufferDesc.renderTargetViews = rtv.readRef();
- framebufferDesc.layout = framebufferLayout;
- GFX_CHECK_CALL_ABORT(device->createFramebuffer(framebufferDesc, framebuffer.writeRef()));
-
- auto texelSize = getTexelSize(textureInfo->format);
- size_t alignment;
- device->getTextureRowAlignment(&alignment);
- alignedRowStride = (textureInfo->extents.width * texelSize + alignment - 1) & ~(alignment - 1);
}
-
- void submitShaderWork(const char* entryPointName)
+ else
{
- ICommandQueue::Desc queueDesc = { ICommandQueue::QueueType::Graphics };
- auto queue = device->createCommandQueue(queueDesc);
-
- auto commandBuffer = transientHeap->createCommandBuffer();
- auto renderEncoder = commandBuffer->encodeRenderCommands(renderPass, framebuffer);
- auto rootObject = renderEncoder->bindPipeline(pipelineState);
-
- gfx::Viewport viewport = {};
- viewport.maxZ = (float)textureInfo->extents.depth;
- viewport.extentX = (float)textureInfo->extents.width;
- viewport.extentY = (float)textureInfo->extents.height;
- renderEncoder->setViewportAndScissor(viewport);
-
- renderEncoder->setVertexBuffer(0, vertexBuffer);
- renderEncoder->setPrimitiveTopology(PrimitiveTopology::TriangleList);
- renderEncoder->draw(kVertexCount, 0);
- renderEncoder->endEncoding();
-
- auto resourceEncoder = commandBuffer->encodeResourceCommands();
-
- if (sampleCount > 1)
- {
- SubresourceRange msaaSubresource = {};
- msaaSubresource.aspectMask = TextureAspect::Color;
- msaaSubresource.mipLevel = 0;
- msaaSubresource.mipLevelCount = 1;
- msaaSubresource.baseArrayLayer = 0;
- msaaSubresource.layerCount = 1;
-
- SubresourceRange dstSubresource = {};
- dstSubresource.aspectMask = TextureAspect::Color;
- dstSubresource.mipLevel = 0;
- dstSubresource.mipLevelCount = 1;
- dstSubresource.baseArrayLayer = 0;
- dstSubresource.layerCount = 1;
-
- resourceEncoder->resolveResource(sampledTexture, ResourceState::ResolveSource, msaaSubresource, texture, ResourceState::ResolveDestination, dstSubresource);
- resourceEncoder->textureBarrier(texture, ResourceState::ResolveDestination, ResourceState::CopySource);
- }
- else
- {
- resourceEncoder->textureBarrier(sampledTexture, ResourceState::ResolveSource, ResourceState::CopySource);
- }
- resourceEncoder->endEncoding();
- commandBuffer->close();
- queue->executeCommandBuffer(commandBuffer);
- queue->waitOnHost();
+ resourceEncoder->textureBarrier(
+ sampledTexture,
+ ResourceState::ResolveSource,
+ ResourceState::CopySource);
}
+ resourceEncoder->endEncoding();
+ commandBuffer->close();
+ queue->executeCommandBuffer(commandBuffer);
+ queue->waitOnHost();
+ }
- // TODO: Should take a value indicating the slice that was rendered into
- // TODO: Needs to handle either the correct slice or array layer (will not always check z)
- void validateTextureValues(ValidationTextureData actual)
+ // TODO: Should take a value indicating the slice that was rendered into
+ // TODO: Needs to handle either the correct slice or array layer (will not always check z)
+ void validateTextureValues(ValidationTextureData actual)
+ {
+ for (GfxIndex x = 0; x < actual.extents.width; ++x)
{
- for (GfxIndex x = 0; x < actual.extents.width; ++x)
+ for (GfxIndex y = 0; y < actual.extents.height; ++y)
{
- for (GfxIndex y = 0; y < actual.extents.height; ++y)
+ for (GfxIndex z = 0; z < actual.extents.depth; ++z)
{
- for (GfxIndex z = 0; z < actual.extents.depth; ++z)
+ auto actualBlock = (float*)actual.getBlockAt(x, y, z);
+ for (Int i = 0; i < 4; ++i)
{
- auto actualBlock = (float*)actual.getBlockAt(x, y, z);
- for (Int i = 0; i < 4; ++i)
+ if (z == 0)
+ {
+ // Slice being rendered into
+ SLANG_CHECK(actualBlock[i] == (float)i + 1);
+ }
+ else
{
- if (z == 0)
- {
- // Slice being rendered into
- SLANG_CHECK(actualBlock[i] == (float)i + 1);
- }
- else
- {
- SLANG_CHECK(actualBlock[i] == 0.0f);
- }
+ SLANG_CHECK(actualBlock[i] == 0.0f);
}
}
}
}
}
+ }
- void checkTestResults()
+ void checkTestResults()
+ {
+ ComPtr<ISlangBlob> textureBlob;
+ size_t rowPitch;
+ size_t pixelSize;
+ if (sampleCount > 1)
{
- ComPtr<ISlangBlob> textureBlob;
- size_t rowPitch;
- size_t pixelSize;
- if (sampleCount > 1)
- {
- GFX_CHECK_CALL_ABORT(device->readTextureResource(texture, ResourceState::CopySource, textureBlob.writeRef(), &rowPitch, &pixelSize));
- }
- else
- {
- GFX_CHECK_CALL_ABORT(device->readTextureResource(sampledTexture, ResourceState::CopySource, textureBlob.writeRef(), &rowPitch, &pixelSize));
- }
- auto textureValues = (float*)textureBlob->getBufferPointer();
-
- ValidationTextureData textureResults;
- textureResults.extents = textureInfo->extents;
- textureResults.textureData = textureValues;
- textureResults.strides.x = (uint32_t)pixelSize;
- textureResults.strides.y = (uint32_t)rowPitch;
- textureResults.strides.z = textureResults.extents.height * textureResults.strides.y;
-
- validateTextureValues(textureResults);
+ GFX_CHECK_CALL_ABORT(device->readTextureResource(
+ texture,
+ ResourceState::CopySource,
+ textureBlob.writeRef(),
+ &rowPitch,
+ &pixelSize));
}
-
- void run()
+ else
{
- auto entryPointName = getShaderEntryPoint();
-// printf("%s\n", entryPointName.getBuffer());
-
- // TODO: Sampler state and null state?
-// ISamplerState::Desc samplerDesc;
-// sampler = device->createSamplerState(samplerDesc);
-
- textureInfo->extents.width = 4;
- textureInfo->extents.height = (textureInfo->textureType == IResource::Type::Texture1D) ? 1 : 4;
- textureInfo->extents.depth = (textureInfo->textureType != IResource::Type::Texture3D) ? 1 : 2;
- textureInfo->mipLevelCount = 1;
- textureInfo->arrayLayerCount = 1;
- generateTextureData(textureInfo, validationFormat);
-
- // We need to save the pointer to the original texture data for results checking because the texture will be
- // overwritten during testing (if the texture can be written to).
- expectedTextureData = textureInfo->subresourceDatas[getSubresourceIndex(0, 1, 0)].data;
+ GFX_CHECK_CALL_ABORT(device->readTextureResource(
+ sampledTexture,
+ ResourceState::CopySource,
+ textureBlob.writeRef(),
+ &rowPitch,
+ &pixelSize));
+ }
+ auto textureValues = (float*)textureBlob->getBufferPointer();
- createRequiredResources();
- submitShaderWork(entryPointName.getBuffer());
+ ValidationTextureData textureResults;
+ textureResults.extents = textureInfo->extents;
+ textureResults.textureData = textureValues;
+ textureResults.strides.x = (uint32_t)pixelSize;
+ textureResults.strides.y = (uint32_t)rowPitch;
+ textureResults.strides.z = textureResults.extents.height * textureResults.strides.y;
- checkTestResults();
- }
- };
+ validateTextureValues(textureResults);
+ }
- void shaderAndUnorderedTestImpl(IDevice* device, UnitTestContext* context)
+ void run()
{
- // TODO: Buffer and TextureCube
- for (Int i = 2; i < (int32_t)IResource::Type::TextureCube; ++i)
- {
- for (Int j = 3; j < (int32_t)IResourceView::Type::AccelerationStructure; ++j)
- {
- auto shape = (IResource::Type)i;
- auto view = (IResourceView::Type)j;
- auto format = Format::R8G8B8A8_UINT;
- auto validationFormat = getValidationTextureFormat(format);
- if (!validationFormat)
- SLANG_CHECK_ABORT(false);
-
- ShaderAndUnorderedTests test;
- test.init(device, context, format, validationFormat, view, shape);
- test.run();
- }
- }
+ auto entryPointName = getShaderEntryPoint();
+ // printf("%s\n", entryPointName.getBuffer());
+
+ // TODO: Sampler state and null state?
+ // ISamplerState::Desc samplerDesc;
+ // sampler = device->createSamplerState(samplerDesc);
+
+ textureInfo->extents.width = 4;
+ textureInfo->extents.height =
+ (textureInfo->textureType == IResource::Type::Texture1D) ? 1 : 4;
+ textureInfo->extents.depth =
+ (textureInfo->textureType != IResource::Type::Texture3D) ? 1 : 2;
+ textureInfo->mipLevelCount = 1;
+ textureInfo->arrayLayerCount = 1;
+ generateTextureData(textureInfo, validationFormat);
+
+ // We need to save the pointer to the original texture data for results checking because the
+ // texture will be overwritten during testing (if the texture can be written to).
+ expectedTextureData = textureInfo->subresourceDatas[getSubresourceIndex(0, 1, 0)].data;
+
+ createRequiredResources();
+ submitShaderWork(entryPointName.getBuffer());
+
+ checkTestResults();
}
+};
- void renderTargetTestImpl(IDevice* device, UnitTestContext* context)
+void shaderAndUnorderedTestImpl(IDevice* device, UnitTestContext* context)
+{
+ // TODO: Buffer and TextureCube
+ for (Int i = 2; i < (int32_t)IResource::Type::TextureCube; ++i)
{
- // TODO: Buffer and TextureCube
- for (Int i = 2; i < (int32_t)IResource::Type::TextureCube; ++i)
+ for (Int j = 3; j < (int32_t)IResourceView::Type::AccelerationStructure; ++j)
{
auto shape = (IResource::Type)i;
- auto view = IResourceView::Type::RenderTarget;
- auto format = Format::R32G32B32A32_FLOAT;
+ auto view = (IResourceView::Type)j;
+ auto format = Format::R8G8B8A8_UINT;
auto validationFormat = getValidationTextureFormat(format);
if (!validationFormat)
SLANG_CHECK_ABORT(false);
- RenderTargetTests test;
+ ShaderAndUnorderedTests test;
test.init(device, context, format, validationFormat, view, shape);
test.run();
}
}
+}
- SLANG_UNIT_TEST(shaderAndUnorderedAccessTests)
+void renderTargetTestImpl(IDevice* device, UnitTestContext* context)
+{
+ // TODO: Buffer and TextureCube
+ for (Int i = 2; i < (int32_t)IResource::Type::TextureCube; ++i)
{
- runTestImpl(shaderAndUnorderedTestImpl, unitTestContext, Slang::RenderApiFlag::D3D12);
- runTestImpl(shaderAndUnorderedTestImpl, unitTestContext, Slang::RenderApiFlag::Vulkan);
+ auto shape = (IResource::Type)i;
+ auto view = IResourceView::Type::RenderTarget;
+ auto format = Format::R32G32B32A32_FLOAT;
+ auto validationFormat = getValidationTextureFormat(format);
+ if (!validationFormat)
+ SLANG_CHECK_ABORT(false);
+
+ RenderTargetTests test;
+ test.init(device, context, format, validationFormat, view, shape);
+ test.run();
}
+}
- SLANG_UNIT_TEST(renderTargetTests)
- {
- runTestImpl(renderTargetTestImpl, unitTestContext, Slang::RenderApiFlag::D3D12);
- runTestImpl(renderTargetTestImpl, unitTestContext, Slang::RenderApiFlag::Vulkan);
- }
+SLANG_UNIT_TEST(shaderAndUnorderedAccessTests)
+{
+ runTestImpl(shaderAndUnorderedTestImpl, unitTestContext, Slang::RenderApiFlag::D3D12);
+ runTestImpl(shaderAndUnorderedTestImpl, unitTestContext, Slang::RenderApiFlag::Vulkan);
+}
+
+SLANG_UNIT_TEST(renderTargetTests)
+{
+ runTestImpl(renderTargetTestImpl, unitTestContext, Slang::RenderApiFlag::D3D12);
+ runTestImpl(renderTargetTestImpl, unitTestContext, Slang::RenderApiFlag::Vulkan);
}
+} // namespace gfx_test
// 1D + array + multisample, ditto for 2D, ditto for 3D
-// one test with something bound, one test with nothing bound, one test with subset of layers (set values in SubresourceRange and assign in desc)
+// one test with something bound, one test with nothing bound, one test with subset of layers (set
+// values in SubresourceRange and assign in desc)
diff --git a/tools/gfx-unit-test/uint16-structured-buffer.cpp b/tools/gfx-unit-test/uint16-structured-buffer.cpp
index 8f2f2cb97..23fd70544 100644
--- a/tools/gfx-unit-test/uint16-structured-buffer.cpp
+++ b/tools/gfx-unit-test/uint16-structured-buffer.cpp
@@ -1,96 +1,91 @@
-#include "tools/unit-test/slang-unit-test.h"
-
-#include "slang-gfx.h"
#include "gfx-test-util.h"
-#include "tools/gfx-util/shader-cursor.h"
+#include "slang-gfx.h"
#include "source/core/slang-basic.h"
+#include "tools/gfx-util/shader-cursor.h"
+#include "tools/unit-test/slang-unit-test.h"
using namespace gfx;
namespace gfx_test
{
- void uint16BufferTestImpl(IDevice* device, UnitTestContext* context)
+void uint16BufferTestImpl(IDevice* device, UnitTestContext* context)
+{
+ Slang::ComPtr<ITransientResourceHeap> transientHeap;
+ ITransientResourceHeap::Desc transientHeapDesc = {};
+ transientHeapDesc.constantBufferSize = 4096;
+ GFX_CHECK_CALL_ABORT(
+ device->createTransientResourceHeap(transientHeapDesc, transientHeap.writeRef()));
+
+ ComPtr<IShaderProgram> shaderProgram;
+ slang::ProgramLayout* slangReflection;
+ GFX_CHECK_CALL_ABORT(
+ loadComputeProgram(device, shaderProgram, "uint16-buffer", "computeMain", slangReflection));
+
+ ComputePipelineStateDesc pipelineDesc = {};
+ pipelineDesc.program = shaderProgram.get();
+ ComPtr<gfx::IPipelineState> pipelineState;
+ GFX_CHECK_CALL_ABORT(
+ device->createComputePipelineState(pipelineDesc, pipelineState.writeRef()));
+
+ const int numberCount = 4;
+ uint16_t initialData[] = {0, 1, 2, 3};
+ IBufferResource::Desc bufferDesc = {};
+ bufferDesc.sizeInBytes = numberCount * sizeof(uint16_t);
+ bufferDesc.format = gfx::Format::Unknown;
+ // Note: we don't specify any element size here, and gfx should be able to derive the
+ // correct element size from the reflection infomation.
+ bufferDesc.elementSize = 0;
+ bufferDesc.allowedStates = ResourceStateSet(
+ ResourceState::ShaderResource,
+ ResourceState::UnorderedAccess,
+ ResourceState::CopyDestination,
+ ResourceState::CopySource);
+ bufferDesc.defaultState = ResourceState::UnorderedAccess;
+ bufferDesc.memoryType = MemoryType::DeviceLocal;
+
+ ComPtr<IBufferResource> numbersBuffer;
+ GFX_CHECK_CALL_ABORT(
+ device->createBufferResource(bufferDesc, (void*)initialData, numbersBuffer.writeRef()));
+
+ ComPtr<IResourceView> bufferView;
+ IResourceView::Desc viewDesc = {};
+ viewDesc.type = IResourceView::Type::UnorderedAccess;
+ viewDesc.format = Format::Unknown;
+ GFX_CHECK_CALL_ABORT(
+ device->createBufferView(numbersBuffer, nullptr, viewDesc, bufferView.writeRef()));
+
+ // We have done all the set up work, now it is time to start recording a command buffer for
+ // GPU execution.
{
- Slang::ComPtr<ITransientResourceHeap> transientHeap;
- ITransientResourceHeap::Desc transientHeapDesc = {};
- transientHeapDesc.constantBufferSize = 4096;
- GFX_CHECK_CALL_ABORT(
- device->createTransientResourceHeap(transientHeapDesc, transientHeap.writeRef()));
-
- ComPtr<IShaderProgram> shaderProgram;
- slang::ProgramLayout* slangReflection;
- GFX_CHECK_CALL_ABORT(loadComputeProgram(device, shaderProgram, "uint16-buffer", "computeMain", slangReflection));
-
- ComputePipelineStateDesc pipelineDesc = {};
- pipelineDesc.program = shaderProgram.get();
- ComPtr<gfx::IPipelineState> pipelineState;
- GFX_CHECK_CALL_ABORT(
- device->createComputePipelineState(pipelineDesc, pipelineState.writeRef()));
-
- const int numberCount = 4;
- uint16_t initialData[] = { 0, 1, 2, 3 };
- IBufferResource::Desc bufferDesc = {};
- bufferDesc.sizeInBytes = numberCount * sizeof(uint16_t);
- bufferDesc.format = gfx::Format::Unknown;
- // Note: we don't specify any element size here, and gfx should be able to derive the
- // correct element size from the reflection infomation.
- bufferDesc.elementSize = 0;
- bufferDesc.allowedStates = ResourceStateSet(
- ResourceState::ShaderResource,
- ResourceState::UnorderedAccess,
- ResourceState::CopyDestination,
- ResourceState::CopySource);
- bufferDesc.defaultState = ResourceState::UnorderedAccess;
- bufferDesc.memoryType = MemoryType::DeviceLocal;
-
- ComPtr<IBufferResource> numbersBuffer;
- GFX_CHECK_CALL_ABORT(device->createBufferResource(
- bufferDesc,
- (void*)initialData,
- numbersBuffer.writeRef()));
-
- ComPtr<IResourceView> bufferView;
- IResourceView::Desc viewDesc = {};
- viewDesc.type = IResourceView::Type::UnorderedAccess;
- viewDesc.format = Format::Unknown;
- GFX_CHECK_CALL_ABORT(
- device->createBufferView(numbersBuffer, nullptr, viewDesc, bufferView.writeRef()));
-
- // We have done all the set up work, now it is time to start recording a command buffer for
- // GPU execution.
- {
- ICommandQueue::Desc queueDesc = { ICommandQueue::QueueType::Graphics };
- auto queue = device->createCommandQueue(queueDesc);
-
- auto commandBuffer = transientHeap->createCommandBuffer();
- auto encoder = commandBuffer->encodeComputeCommands();
-
- auto rootObject = encoder->bindPipeline(pipelineState);
-
- // Bind buffer view to the entry point.
- ShaderCursor(rootObject).getPath("buffer").setResource(bufferView);
-
- encoder->dispatchCompute(1, 1, 1);
- encoder->endEncoding();
- commandBuffer->close();
- queue->executeCommandBuffer(commandBuffer);
- queue->waitOnHost();
- }
-
- compareComputeResult(
- device,
- numbersBuffer,
- Slang::makeArray<uint16_t>(1, 2, 3, 4));
- }
+ ICommandQueue::Desc queueDesc = {ICommandQueue::QueueType::Graphics};
+ auto queue = device->createCommandQueue(queueDesc);
- SLANG_UNIT_TEST(uint16BufferTestD3D12)
- {
- runTestImpl(uint16BufferTestImpl, unitTestContext, Slang::RenderApiFlag::D3D12);
- }
+ auto commandBuffer = transientHeap->createCommandBuffer();
+ auto encoder = commandBuffer->encodeComputeCommands();
- SLANG_UNIT_TEST(uint16BufferTestVulkan)
- {
- runTestImpl(uint16BufferTestImpl, unitTestContext, Slang::RenderApiFlag::Vulkan);
+ auto rootObject = encoder->bindPipeline(pipelineState);
+
+ // Bind buffer view to the entry point.
+ ShaderCursor(rootObject).getPath("buffer").setResource(bufferView);
+
+ encoder->dispatchCompute(1, 1, 1);
+ encoder->endEncoding();
+ commandBuffer->close();
+ queue->executeCommandBuffer(commandBuffer);
+ queue->waitOnHost();
}
+ compareComputeResult(device, numbersBuffer, Slang::makeArray<uint16_t>(1, 2, 3, 4));
+}
+
+SLANG_UNIT_TEST(uint16BufferTestD3D12)
+{
+ runTestImpl(uint16BufferTestImpl, unitTestContext, Slang::RenderApiFlag::D3D12);
}
+
+SLANG_UNIT_TEST(uint16BufferTestVulkan)
+{
+ runTestImpl(uint16BufferTestImpl, unitTestContext, Slang::RenderApiFlag::Vulkan);
+}
+
+} // namespace gfx_test