summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGangzheng Tong <tonggangzheng@gmail.com>2025-07-08 23:44:56 -0700
committerGitHub <noreply@github.com>2025-07-09 06:44:56 +0000
commit43d0c2100ef1a5df4b54525e50eb29fe7c39ec16 (patch)
tree25ec4fb9c726115f90bdaa9878f2f4ca372ad0a6
parent00746bf09047cdf01c19dac513a532bcf3ed3ea3 (diff)
Convert gfx unit tests and examples to use slang-rhi (#7577)
* Port first gfx unit test to slang-rhi * port triangle example to use slang-rhi * port platform-test to slang-rhi * Update platform-test to throttle mouse move events * port gpu-printing example to use slang-rhi * port model-viewer example to use slang-rhi * port ray-tracing example to use slang-rhi * port ray-tracing pipeline example to use slang-rhi * port reflection parameter blocks example to use slang-rhi * port shader-object example to use slang-rhi * port shader-toy example to use slang-rhi * Port most of tests to slang-rhi * port link-time-constant-array-size to use slang-rhi * Fix tests and find matching tests in slang-rhi * port autodiff-texture * remove gfx target; port nv-aftermath-example * update include path for shader-cursor.h * Disabled 2 more ported tests * fix build error * remove gfx test * put slang-rhi (static-lib) before slang (shared) * format code (#7621) Co-authored-by: slangbot <186143334+slangbot@users.noreply.github.com> * add debug callback * format code (#7649) Co-authored-by: slangbot <186143334+slangbot@users.noreply.github.com> * Address review comments; revert back to use SLANG_CHECK_MSG --------- Co-authored-by: slangbot <ellieh+slangbot@nvidia.com> Co-authored-by: slangbot <186143334+slangbot@users.noreply.github.com>
-rw-r--r--examples/CMakeLists.txt6
-rw-r--r--examples/autodiff-texture/main.cpp662
-rw-r--r--examples/example-base/example-base.cpp255
-rw-r--r--examples/example-base/example-base.h36
-rw-r--r--examples/gpu-printing/main.cpp84
-rw-r--r--examples/hello-world/main.cpp1
-rw-r--r--examples/model-viewer/main.cpp117
-rw-r--r--examples/nv-aftermath-example/main.cpp248
-rw-r--r--examples/platform-test/main.cpp115
-rw-r--r--examples/ray-tracing-pipeline/main.cpp425
-rw-r--r--examples/ray-tracing/main.cpp421
-rw-r--r--examples/reflection-parameter-blocks/main.cpp44
-rw-r--r--examples/shader-object/main.cpp123
-rw-r--r--examples/shader-toy/main.cpp106
-rw-r--r--examples/triangle/main.cpp104
-rw-r--r--lock0
-rw-r--r--tests/cpu-program/gfx-smoke.slang101
-rw-r--r--tools/CMakeLists.txt144
-rw-r--r--tools/gfx-unit-test/buffer-barrier-test.cpp187
-rw-r--r--tools/gfx-unit-test/clear-texture-test.cpp7
-rw-r--r--tools/gfx-unit-test/compute-smoke.cpp72
-rw-r--r--tools/gfx-unit-test/compute-trivial.cpp77
-rw-r--r--tools/gfx-unit-test/copy-texture-tests.cpp188
-rw-r--r--tools/gfx-unit-test/create-buffer-from-handle.cpp93
-rw-r--r--tools/gfx-unit-test/existing-device-handle-test.cpp121
-rw-r--r--tools/gfx-unit-test/format-unit-tests.cpp7
-rw-r--r--tools/gfx-unit-test/get-buffer-resource-handle-test.cpp51
-rw-r--r--tools/gfx-unit-test/get-cmd-buffer-handle-test.cpp48
-rw-r--r--tools/gfx-unit-test/get-cmd-queue-handle-test.cpp34
-rw-r--r--tools/gfx-unit-test/get-supported-resource-states-test.cpp236
-rw-r--r--tools/gfx-unit-test/get-texture-resource-handle-test.cpp47
-rw-r--r--tools/gfx-unit-test/gfx-test-texture-util.cpp281
-rw-r--r--tools/gfx-unit-test/gfx-test-texture-util.h144
-rw-r--r--tools/gfx-unit-test/gfx-test-util.cpp355
-rw-r--r--tools/gfx-unit-test/gfx-test-util.h219
-rw-r--r--tools/gfx-unit-test/instanced-draw-tests.cpp7
-rw-r--r--tools/gfx-unit-test/link-time-constant-array-size.cpp85
-rw-r--r--tools/gfx-unit-test/link-time-constant.cpp74
-rw-r--r--tools/gfx-unit-test/link-time-default.cpp105
-rw-r--r--tools/gfx-unit-test/link-time-options.cpp77
-rw-r--r--tools/gfx-unit-test/link-time-type-layout-cache.cpp8
-rw-r--r--tools/gfx-unit-test/link-time-type-layout-nested.cpp27
-rw-r--r--tools/gfx-unit-test/link-time-type-layout.cpp27
-rw-r--r--tools/gfx-unit-test/link-time-type.cpp79
-rw-r--r--tools/gfx-unit-test/mutable-shader-object.cpp112
-rw-r--r--tools/gfx-unit-test/nested-parameter-block.cpp112
-rw-r--r--tools/gfx-unit-test/precompiled-module-2.cpp93
-rw-r--r--tools/gfx-unit-test/precompiled-module-cache.cpp80
-rw-r--r--tools/gfx-unit-test/precompiled-module.cpp85
-rw-r--r--tools/gfx-unit-test/ray-tracing-tests.cpp362
-rw-r--r--tools/gfx-unit-test/resolve-resource-tests.cpp252
-rw-r--r--tools/gfx-unit-test/root-mutable-shader-object.cpp90
-rw-r--r--tools/gfx-unit-test/root-shader-parameter.cpp111
-rw-r--r--tools/gfx-unit-test/sampler-array.cpp127
-rw-r--r--tools/gfx-unit-test/shader-cache-tests.cpp9
-rw-r--r--tools/gfx-unit-test/shared-buffers-tests.cpp101
-rw-r--r--tools/gfx-unit-test/shared-textures-tests.cpp7
-rw-r--r--tools/gfx-unit-test/span.h643
-rw-r--r--tools/gfx-unit-test/swap-chain-resize-test.cpp281
-rw-r--r--tools/gfx-unit-test/texture-types-tests.cpp356
-rw-r--r--tools/gfx-unit-test/uint16-structured-buffer.cpp77
-rw-r--r--tools/gfx-util/shader-cursor.cpp379
-rw-r--r--tools/gfx-util/shader-cursor.h146
-rw-r--r--tools/platform/gui.cpp258
-rw-r--r--tools/platform/gui.h21
-rw-r--r--tools/platform/model.cpp56
-rw-r--r--tools/platform/model.h12
-rw-r--r--tools/vk-pipeline-create/main.cpp21
68 files changed, 4282 insertions, 5157 deletions
diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt
index 87b0b39f8..e67e56ea5 100644
--- a/examples/CMakeLists.txt
+++ b/examples/CMakeLists.txt
@@ -55,12 +55,12 @@ function(example dir)
LINK_WITH_PRIVATE
core
example-base
+ slang-rhi
slang
- gfx
- gfx-util
platform
$<$<BOOL:${SLANG_ENABLE_CUDA}>:CUDA::cuda_driver>
${main_wrapper_libraries}
+ INCLUDE_DIRECTORIES_PUBLIC ${slang_SOURCE_DIR}
EXTRA_COMPILE_DEFINITIONS_PRIVATE
SLANG_EXAMPLE_NAME=${dir}
$<$<BOOL:${SLANG_ENABLE_XLIB}>:SLANG_ENABLE_XLIB>
@@ -81,8 +81,8 @@ if(SLANG_ENABLE_EXAMPLES)
STATIC
LINK_WITH_PRIVATE
core
+ slang-rhi
slang
- gfx
platform
stb
$<$<BOOL:${SLANG_ENABLE_CUDA}>:CUDA::cuda_driver>
diff --git a/examples/autodiff-texture/main.cpp b/examples/autodiff-texture/main.cpp
index d99f9f341..951d7f0ad 100644
--- a/examples/autodiff-texture/main.cpp
+++ b/examples/autodiff-texture/main.cpp
@@ -1,13 +1,13 @@
#include "core/slang-basic.h"
#include "examples/example-base/example-base.h"
-#include "gfx-util/shader-cursor.h"
#include "platform/vector-math.h"
#include "platform/window.h"
#include "slang-com-ptr.h"
-#include "slang-gfx.h"
+#include "slang-rhi.h"
+#include "slang-rhi/shader-cursor.h"
#include "slang.h"
-using namespace gfx;
+using namespace rhi;
using namespace Slang;
static const ExampleResources resourceBase("autodiff-texture");
@@ -24,6 +24,8 @@ static const Vertex kVertexData[kVertexCount] = {
{{1, 0, 0}},
{{1, 1, 0}},
};
+float clearValue[] = {0.0f, 0.0f, 0.0f, 0.0f};
+
struct AutoDiffTexture : public WindowedAppBase
{
@@ -40,11 +42,11 @@ struct AutoDiffTexture : public WindowedAppBase
}
}
- gfx::Result loadRenderProgram(
- gfx::IDevice* device,
+ Result loadRenderProgram(
+ IDevice* device,
const char* fileName,
const char* fragmentShader,
- gfx::IShaderProgram** outProgram)
+ IShaderProgram** outProgram)
{
ComPtr<slang::ISession> slangSession;
slangSession = device->getSlangSession();
@@ -87,17 +89,14 @@ struct AutoDiffTexture : public WindowedAppBase
printEntrypointHashes(componentTypes.getCount() - 1, 1, linkedProgram);
}
- gfx::IShaderProgram::Desc programDesc = {};
+ ShaderProgramDesc programDesc = {};
programDesc.slangGlobalScope = linkedProgram;
- SLANG_RETURN_ON_FAIL(device->createProgram(programDesc, outProgram));
+ SLANG_RETURN_ON_FAIL(device->createShaderProgram(programDesc, outProgram));
return SLANG_OK;
}
- gfx::Result loadComputeProgram(
- gfx::IDevice* device,
- const char* fileName,
- gfx::IShaderProgram** outProgram)
+ Result loadComputeProgram(IDevice* device, const char* fileName, IShaderProgram** outProgram)
{
ComPtr<slang::ISession> slangSession;
slangSession = device->getSlangSession();
@@ -131,161 +130,131 @@ struct AutoDiffTexture : public WindowedAppBase
printEntrypointHashes(componentTypes.getCount() - 1, 1, linkedProgram);
}
- gfx::IShaderProgram::Desc programDesc = {};
+ ShaderProgramDesc programDesc = {};
programDesc.slangGlobalScope = linkedProgram;
- SLANG_RETURN_ON_FAIL(device->createProgram(programDesc, outProgram));
+ SLANG_RETURN_ON_FAIL(device->createShaderProgram(programDesc, outProgram));
return SLANG_OK;
}
- ComPtr<gfx::IPipelineState> gRefPipelineState;
- ComPtr<gfx::IPipelineState> gIterPipelineState;
- ComPtr<gfx::IPipelineState> gReconstructPipelineState;
- ComPtr<gfx::IPipelineState> gConvertPipelineState;
- ComPtr<gfx::IPipelineState> gBuildMipPipelineState;
- ComPtr<gfx::IPipelineState> gLearnMipPipelineState;
- ComPtr<gfx::IPipelineState> gDrawQuadPipelineState;
+ ComPtr<IRenderPipeline> gRefPipeline;
+ ComPtr<IRenderPipeline> gIterPipeline;
+ ComPtr<IComputePipeline> gReconstructPipeline;
+ ComPtr<IComputePipeline> gConvertPipeline;
+ ComPtr<IComputePipeline> gBuildMipPipeline;
+ ComPtr<IComputePipeline> gLearnMipPipeline;
+ ComPtr<IRenderPipeline> gDrawQuadPipeline;
- ComPtr<gfx::ITextureResource> gLearningTexture;
- ComPtr<gfx::IResourceView> gLearningTextureSRV;
- List<ComPtr<gfx::IResourceView>> gLearningTextureUAVs;
+ ComPtr<ITexture> gLearningTexture;
+ ComPtr<ITextureView> gLearningTextureSRV;
+ List<ComPtr<ITextureView>> gLearningTextureUAVs;
- ComPtr<gfx::ITextureResource> gDiffTexture;
- ComPtr<gfx::IResourceView> gDiffTextureSRV;
- List<ComPtr<gfx::IResourceView>> gDiffTextureUAVs;
+ ComPtr<ITexture> gDiffTexture;
+ ComPtr<ITextureView> gDiffTextureSRV;
+ List<ComPtr<ITextureView>> gDiffTextureUAVs;
- ComPtr<gfx::IBufferResource> gVertexBuffer;
- ComPtr<gfx::IResourceView> gTexView;
- ComPtr<gfx::ISamplerState> gSampler;
- ComPtr<gfx::IFramebuffer> gRefFrameBuffer;
- ComPtr<gfx::IFramebuffer> gIterFrameBuffer;
+ ComPtr<IBuffer> gVertexBuffer;
+ ComPtr<ITextureView> gTexView;
+ ComPtr<ISampler> gSampler;
- ComPtr<gfx::ITextureResource> gDepthTexture;
- ComPtr<gfx::IResourceView> gDepthTextureView;
+ ComPtr<ITexture> gDepthTexture;
+ ComPtr<ITextureView> gDepthTextureView;
- ComPtr<gfx::IResourceView> gIterImageDSV;
+ ComPtr<ITexture> gIterImage;
+ ComPtr<ITextureView> gIterImageSRV;
- ComPtr<gfx::ITextureResource> gIterImage;
- ComPtr<gfx::IResourceView> gIterImageSRV;
- ComPtr<gfx::IResourceView> gIterImageRTV;
+ ComPtr<ITexture> gRefImage;
+ ComPtr<ITextureView> gRefImageSRV;
- ComPtr<gfx::ITextureResource> gRefImage;
- ComPtr<gfx::IResourceView> gRefImageSRV;
- ComPtr<gfx::IResourceView> gRefImageRTV;
+ ComPtr<IBuffer> gAccumulateBuffer;
+ ComPtr<ITextureView> gAccumulateBufferView;
+
+ ComPtr<IBuffer> gReconstructBuffer;
+ ComPtr<ITextureView> gReconstructBufferView;
- ComPtr<gfx::IBufferResource> gAccumulateBuffer;
- ComPtr<gfx::IBufferResource> gReconstructBuffer;
- ComPtr<gfx::IResourceView> gAccumulateBufferView;
- ComPtr<gfx::IResourceView> gReconstructBufferView;
- ClearValue kClearValue;
bool resetLearntTexture = false;
- ComPtr<gfx::ITextureResource> createRenderTargetTexture(
- gfx::Format format,
- int w,
- int h,
- int levels)
+ ComPtr<ITexture> createRenderTargetTexture(Format format, int w, int h, int levels)
{
- gfx::ITextureResource::Desc textureDesc = {};
- textureDesc.allowedStates.add(ResourceState::ShaderResource);
- textureDesc.allowedStates.add(ResourceState::UnorderedAccess);
- textureDesc.allowedStates.add(ResourceState::RenderTarget);
- textureDesc.defaultState = ResourceState::RenderTarget;
+ TextureDesc textureDesc = {};
textureDesc.format = format;
- textureDesc.numMipLevels = levels;
- textureDesc.type = gfx::IResource::Type::Texture2D;
textureDesc.size.width = w;
textureDesc.size.height = h;
textureDesc.size.depth = 1;
- textureDesc.optimalClearValue = &kClearValue;
- return gDevice->createTextureResource(textureDesc, nullptr);
+ textureDesc.mipCount = levels;
+ textureDesc.usage = TextureUsage::ShaderResource | TextureUsage::UnorderedAccess |
+ TextureUsage::RenderTarget;
+ textureDesc.defaultState = ResourceState::RenderTarget;
+ return gDevice->createTexture(textureDesc);
}
- ComPtr<gfx::ITextureResource> createDepthTexture()
+ ComPtr<ITexture> createDepthTexture()
{
- gfx::ITextureResource::Desc textureDesc = {};
- textureDesc.allowedStates.add(ResourceState::DepthWrite);
- textureDesc.defaultState = ResourceState::DepthWrite;
- textureDesc.format = gfx::Format::D32_FLOAT;
- textureDesc.numMipLevels = 1;
- textureDesc.type = gfx::IResource::Type::Texture2D;
+ TextureDesc textureDesc = {};
+ textureDesc.format = Format::D32Float;
textureDesc.size.width = windowWidth;
textureDesc.size.height = windowHeight;
textureDesc.size.depth = 1;
- ClearValue clearValue = {};
- textureDesc.optimalClearValue = &clearValue;
- return gDevice->createTextureResource(textureDesc, nullptr);
- }
- ComPtr<gfx::IFramebuffer> createRenderTargetFramebuffer(IResourceView* tex)
- {
- IFramebuffer::Desc desc = {};
- desc.layout = gFramebufferLayout.get();
- desc.renderTargetCount = 1;
- desc.renderTargetViews = &tex;
- desc.depthStencilView = gDepthTextureView;
- return gDevice->createFramebuffer(desc);
+ textureDesc.mipCount = 1;
+ textureDesc.usage = TextureUsage::DepthStencil;
+ textureDesc.defaultState = ResourceState::DepthWrite;
+ return gDevice->createTexture(textureDesc);
}
- ComPtr<gfx::IResourceView> createRTV(ITextureResource* tex, Format f)
+ ComPtr<ITextureView> createRTV(ITexture* tex, Format f)
{
- IResourceView::Desc rtvDesc = {};
- rtvDesc.type = IResourceView::Type::RenderTarget;
- rtvDesc.subresourceRange.mipLevelCount = 1;
+ TextureViewDesc rtvDesc = {};
rtvDesc.format = f;
- rtvDesc.renderTarget.shape = gfx::IResource::Type::Texture2D;
+ rtvDesc.subresourceRange.mipCount = 1;
return gDevice->createTextureView(tex, rtvDesc);
}
- ComPtr<gfx::IResourceView> createDSV(ITextureResource* tex)
+ ComPtr<ITextureView> createDSV(ITexture* tex)
{
- IResourceView::Desc dsvDesc = {};
- dsvDesc.type = IResourceView::Type::DepthStencil;
- dsvDesc.subresourceRange.mipLevelCount = 1;
- dsvDesc.format = Format::D32_FLOAT;
- dsvDesc.renderTarget.shape = gfx::IResource::Type::Texture2D;
+ TextureViewDesc dsvDesc = {};
+ dsvDesc.format = Format::D32Float;
+ dsvDesc.subresourceRange.mipCount = 1;
return gDevice->createTextureView(tex, dsvDesc);
}
- ComPtr<gfx::IResourceView> createSRV(ITextureResource* tex)
+ ComPtr<ITextureView> createSRV(ITexture* tex)
{
- IResourceView::Desc rtvDesc = {};
- rtvDesc.type = IResourceView::Type::ShaderResource;
- return gDevice->createTextureView(tex, rtvDesc);
+ TextureViewDesc srvDesc = {};
+ return gDevice->createTextureView(tex, srvDesc);
}
- ComPtr<gfx::IPipelineState> createRenderPipelineState(
- IInputLayout* inputLayout,
- IShaderProgram* program)
+ ComPtr<IRenderPipeline> createRenderPipeline(IInputLayout* inputLayout, IShaderProgram* program)
{
- GraphicsPipelineStateDesc desc;
+ ColorTargetDesc colorTarget;
+ colorTarget.format = Format::RGBA8Unorm;
+ RenderPipelineDesc desc;
desc.inputLayout = inputLayout;
desc.program = program;
- desc.rasterizer.cullMode = gfx::CullMode::None;
- desc.framebufferLayout = gFramebufferLayout;
- auto pipelineState = gDevice->createGraphicsPipelineState(desc);
- return pipelineState;
+ desc.targetCount = 1;
+ desc.targets = &colorTarget;
+ desc.depthStencil.depthTestEnable = true;
+ desc.depthStencil.depthWriteEnable = true;
+ desc.depthStencil.format = Format::D32Float;
+ desc.rasterizer.cullMode = CullMode::None;
+ desc.primitiveTopology = PrimitiveTopology::TriangleStrip;
+ return gDevice->createRenderPipeline(desc);
}
- ComPtr<gfx::IPipelineState> createComputePipelineState(IShaderProgram* program)
+ ComPtr<IComputePipeline> createComputePipeline(IShaderProgram* program)
{
- ComputePipelineStateDesc desc = {};
+ ComputePipelineDesc desc = {};
desc.program = program;
- auto pipelineState = gDevice->createComputePipelineState(desc);
- return pipelineState;
- }
- ComPtr<gfx::IResourceView> createUAV(IBufferResource* buffer)
- {
- IResourceView::Desc desc = {};
- desc.type = IResourceView::Type::UnorderedAccess;
- return gDevice->createBufferView(buffer, nullptr, desc);
+ return gDevice->createComputePipeline(desc);
}
- ComPtr<gfx::IResourceView> createUAV(ITextureResource* texture, int level)
+ ComPtr<ITextureView> createUAV(ITexture* texture, int level)
{
- IResourceView::Desc desc = {};
- desc.type = IResourceView::Type::UnorderedAccess;
- desc.subresourceRange.layerCount = 1;
- desc.subresourceRange.mipLevel = level;
- desc.subresourceRange.baseArrayLayer = 0;
+ TextureViewDesc desc = {};
+ SubresourceRange textureViewRange = {};
+ textureViewRange.mipCount = 1;
+ textureViewRange.mip = level; // Fixed: should be level, not 0
+ textureViewRange.layerCount = 1; // Fixed: should be 1, not level
+ textureViewRange.layer = 0;
+ desc.subresourceRange = textureViewRange;
return gDevice->createTextureView(texture, desc);
}
Slang::Result initialize()
{
- SLANG_RETURN_ON_FAIL(initializeBase("autodiff-texture", 1024, 768));
+ SLANG_RETURN_ON_FAIL(initializeBase("autodiff-texture", 1024, 768, DeviceType::Default));
srand(20421);
if (!isTestMode())
@@ -297,11 +266,6 @@ struct AutoDiffTexture : public WindowedAppBase
};
}
- kClearValue.color.floatValues[0] = 0.3f;
- kClearValue.color.floatValues[1] = 0.5f;
- kClearValue.color.floatValues[2] = 0.7f;
- kClearValue.color.floatValues[3] = 1.0f;
-
platform::Rect clientRect{};
if (isTestMode())
{
@@ -317,16 +281,16 @@ struct AutoDiffTexture : public WindowedAppBase
windowHeight = clientRect.height;
InputElementDesc inputElements[] = {
- {"POSITION", 0, Format::R32G32B32_FLOAT, offsetof(Vertex, position)}};
+ {"POSITION", 0, Format::RGB32Float, offsetof(Vertex, position)}};
auto inputLayout = gDevice->createInputLayout(sizeof(Vertex), &inputElements[0], 1);
if (!inputLayout)
return SLANG_FAIL;
- IBufferResource::Desc vertexBufferDesc;
- vertexBufferDesc.type = IResource::Type::Buffer;
- vertexBufferDesc.sizeInBytes = kVertexCount * sizeof(Vertex);
- vertexBufferDesc.defaultState = ResourceState::VertexBuffer;
- gVertexBuffer = gDevice->createBufferResource(vertexBufferDesc, &kVertexData[0]);
+ BufferDesc vertexBufferDesc;
+ vertexBufferDesc.size = kVertexCount * sizeof(Vertex);
+ vertexBufferDesc.elementSize = sizeof(Vertex);
+ vertexBufferDesc.usage = BufferUsage::VertexBuffer;
+ gVertexBuffer = gDevice->createBuffer(vertexBufferDesc, &kVertexData[0]);
if (!gVertexBuffer)
return SLANG_FAIL;
@@ -337,7 +301,7 @@ struct AutoDiffTexture : public WindowedAppBase
"train.slang",
"fragmentMain",
shaderProgram.writeRef()));
- gRefPipelineState = createRenderPipelineState(inputLayout, shaderProgram);
+ gRefPipeline = createRenderPipeline(inputLayout, shaderProgram);
}
{
ComPtr<IShaderProgram> shaderProgram;
@@ -346,7 +310,7 @@ struct AutoDiffTexture : public WindowedAppBase
"train.slang",
"diffFragmentMain",
shaderProgram.writeRef()));
- gIterPipelineState = createRenderPipelineState(inputLayout, shaderProgram);
+ gIterPipeline = createRenderPipeline(inputLayout, shaderProgram);
}
{
ComPtr<IShaderProgram> shaderProgram;
@@ -355,126 +319,92 @@ struct AutoDiffTexture : public WindowedAppBase
"draw-quad.slang",
"fragmentMain",
shaderProgram.writeRef()));
- gDrawQuadPipelineState = createRenderPipelineState(inputLayout, shaderProgram);
+ gDrawQuadPipeline = createRenderPipeline(inputLayout, shaderProgram);
}
{
ComPtr<IShaderProgram> shaderProgram;
SLANG_RETURN_ON_FAIL(
loadComputeProgram(gDevice, "reconstruct.slang", shaderProgram.writeRef()));
- gReconstructPipelineState = createComputePipelineState(shaderProgram);
+ gReconstructPipeline = createComputePipeline(shaderProgram);
}
{
ComPtr<IShaderProgram> shaderProgram;
SLANG_RETURN_ON_FAIL(
loadComputeProgram(gDevice, "convert.slang", shaderProgram.writeRef()));
- gConvertPipelineState = createComputePipelineState(shaderProgram);
+ gConvertPipeline = createComputePipeline(shaderProgram);
}
{
ComPtr<IShaderProgram> shaderProgram;
SLANG_RETURN_ON_FAIL(
loadComputeProgram(gDevice, "buildmip.slang", shaderProgram.writeRef()));
- gBuildMipPipelineState = createComputePipelineState(shaderProgram);
+ gBuildMipPipeline = createComputePipeline(shaderProgram);
}
{
ComPtr<IShaderProgram> shaderProgram;
SLANG_RETURN_ON_FAIL(
loadComputeProgram(gDevice, "learnmip.slang", shaderProgram.writeRef()));
- gLearnMipPipelineState = createComputePipelineState(shaderProgram);
+ gLearnMipPipeline = createComputePipeline(shaderProgram);
}
+ // Load texture from file - this would need to be adapted to use slang-rhi texture loading
Slang::String imagePath = resourceBase.resolveResource("checkerboard.jpg");
gTexView = createTextureFromFile(imagePath.getBuffer(), textureWidth, textureHeight);
+ textureWidth = 512; // Placeholder values
+ textureHeight = 512;
initMipOffsets(textureWidth, textureHeight);
- gfx::IBufferResource::Desc bufferDesc = {};
- bufferDesc.allowedStates.add(ResourceState::ShaderResource);
- bufferDesc.allowedStates.add(ResourceState::UnorderedAccess);
- bufferDesc.allowedStates.add(ResourceState::General);
- bufferDesc.sizeInBytes = mipMapOffset.getLast() * sizeof(uint32_t);
- bufferDesc.type = IResource::Type::Buffer;
- gAccumulateBuffer = gDevice->createBufferResource(bufferDesc);
- gReconstructBuffer = gDevice->createBufferResource(bufferDesc);
+ BufferDesc bufferDesc = {};
+ bufferDesc.size = mipMapOffset.getLast() * sizeof(uint32_t);
+ bufferDesc.usage = BufferUsage::ShaderResource | BufferUsage::UnorderedAccess;
- gAccumulateBufferView = createUAV(gAccumulateBuffer);
- gReconstructBufferView = createUAV(gReconstructBuffer);
+ gAccumulateBuffer = gDevice->createBuffer(bufferDesc);
+ if (!gAccumulateBuffer)
+ {
+ printf("ERROR: Failed to create accumulate buffer!\n");
+ return SLANG_FAIL;
+ }
+
+ gReconstructBuffer = gDevice->createBuffer(bufferDesc);
+ if (!gReconstructBuffer)
+ {
+ printf("ERROR: Failed to create reconstruct buffer!\n");
+ return SLANG_FAIL;
+ }
int mipCount = 1 + Math::Log2Ceil(Math::Max(textureWidth, textureHeight));
- gLearningTexture = createRenderTargetTexture(
- Format::R32G32B32A32_FLOAT,
- textureWidth,
- textureHeight,
- mipCount);
+ SubresourceData initialData = {};
+ initialData.data = gLearningTexture =
+ createRenderTargetTexture(Format::RGBA32Float, textureWidth, textureHeight, mipCount);
gLearningTextureSRV = createSRV(gLearningTexture);
for (int i = 0; i < mipCount; i++)
gLearningTextureUAVs.add(createUAV(gLearningTexture, i));
- gDiffTexture = createRenderTargetTexture(
- Format::R32G32B32A32_FLOAT,
- textureWidth,
- textureHeight,
- mipCount);
+ gDiffTexture =
+ createRenderTargetTexture(Format::RGBA32Float, textureWidth, textureHeight, mipCount);
gDiffTextureSRV = createSRV(gDiffTexture);
for (int i = 0; i < mipCount; i++)
gDiffTextureUAVs.add(createUAV(gDiffTexture, i));
- gfx::ISamplerState::Desc samplerDesc = {};
- // samplerDesc.maxLOD = 0.0f;
- gSampler = gDevice->createSamplerState(samplerDesc);
+ SamplerDesc samplerDesc = {};
+ gSampler = gDevice->createSampler(samplerDesc);
gDepthTexture = createDepthTexture();
gDepthTextureView = createDSV(gDepthTexture);
- gRefImage = createRenderTargetTexture(Format::R8G8B8A8_UNORM, windowWidth, windowHeight, 1);
- gRefImageRTV = createRTV(gRefImage, Format::R8G8B8A8_UNORM);
+ gRefImage = createRenderTargetTexture(Format::RGBA8Unorm, windowWidth, windowHeight, 1);
gRefImageSRV = createSRV(gRefImage);
- gIterImage =
- createRenderTargetTexture(Format::R8G8B8A8_UNORM, windowWidth, windowHeight, 1);
- gIterImageRTV = createRTV(gIterImage, Format::R8G8B8A8_UNORM);
+ gIterImage = createRenderTargetTexture(Format::RGBA8Unorm, windowWidth, windowHeight, 1);
gIterImageSRV = createSRV(gIterImage);
- gRefFrameBuffer = createRenderTargetFramebuffer(gRefImageRTV);
- gIterFrameBuffer = createRenderTargetFramebuffer(gIterImageRTV);
-
+ // Initialize textures
{
- ComPtr<ICommandBuffer> commandBuffer = gTransientHeaps[0]->createCommandBuffer();
- auto encoder = commandBuffer->encodeResourceCommands();
- encoder->textureBarrier(
- gLearningTexture,
- ResourceState::RenderTarget,
- ResourceState::UnorderedAccess);
- encoder->textureBarrier(
- gDiffTexture,
- ResourceState::RenderTarget,
- ResourceState::UnorderedAccess);
- encoder->textureBarrier(
- gRefImage,
- ResourceState::RenderTarget,
- ResourceState::ShaderResource);
- encoder->textureBarrier(
- gIterImage,
- ResourceState::RenderTarget,
- ResourceState::ShaderResource);
- for (int i = 0; i < gLearningTextureUAVs.getCount(); i++)
- {
- ClearValue clearValue = {};
- encoder->clearResourceView(
- gLearningTextureUAVs[i],
- &clearValue,
- ClearResourceViewFlags::None);
- encoder->clearResourceView(
- gDiffTextureUAVs[i],
- &clearValue,
- ClearResourceViewFlags::None);
- }
- encoder->textureBarrier(
- gLearningTexture,
- ResourceState::UnorderedAccess,
- ResourceState::ShaderResource);
-
- encoder->endEncoding();
- commandBuffer->close();
- gQueue->executeCommandBuffer(commandBuffer);
+ auto commandEncoder = gQueue->createCommandEncoder();
+ // Clear learning and diff textures
+ commandEncoder->clearTextureFloat(gLearningTexture, kEntireTexture, clearValue);
+ commandEncoder->clearTextureFloat(gDiffTexture, kEntireTexture, clearValue);
+
+ gQueue->submit(commandEncoder->finish());
}
return SLANG_OK;
@@ -518,160 +448,122 @@ struct AutoDiffTexture : public WindowedAppBase
}
template<typename SetupPipelineFunc>
- void renderImage(
- int transientHeapIndex,
- IFramebuffer* fb,
- const SetupPipelineFunc& setupPipeline)
+ void renderImage(ITexture* renderTarget, const SetupPipelineFunc& setupPipeline)
{
- ComPtr<ICommandBuffer> commandBuffer =
- gTransientHeaps[transientHeapIndex]->createCommandBuffer();
- auto renderEncoder = commandBuffer->encodeRenderCommands(gRenderPass, fb);
-
- gfx::Viewport viewport = {};
- viewport.maxZ = 1.0f;
- viewport.extentX = (float)windowWidth;
- viewport.extentY = (float)windowHeight;
- renderEncoder->setViewportAndScissor(viewport);
+ auto commandEncoder = gQueue->createCommandEncoder();
+
+ ComPtr<ITextureView> renderTargetView = createRTV(renderTarget, Format::RGBA8Unorm);
+ RenderPassColorAttachment colorAttachment = {};
+ colorAttachment.view = renderTargetView;
+ colorAttachment.loadOp = LoadOp::Clear;
+ colorAttachment.clearValue[0] = 0.3f;
+ colorAttachment.clearValue[1] = 0.5f;
+ colorAttachment.clearValue[2] = 0.7f;
+ colorAttachment.clearValue[3] = 1.0f;
+
+ RenderPassDepthStencilAttachment depthAttachment = {};
+ depthAttachment.view = gDepthTextureView;
+ depthAttachment.depthLoadOp = LoadOp::Clear;
+ depthAttachment.depthClearValue = 1.0f;
+
+ RenderPassDesc renderPass = {};
+ renderPass.colorAttachments = &colorAttachment;
+ renderPass.colorAttachmentCount = 1;
+ renderPass.depthStencilAttachment = &depthAttachment;
+
+ auto renderEncoder = commandEncoder->beginRenderPass(renderPass);
+
+ RenderState renderState = {};
+ renderState.viewports[0] = Viewport::fromSize(windowWidth, windowHeight);
+ renderState.viewportCount = 1;
+ renderState.scissorRects[0] = ScissorRect::fromSize(windowWidth, windowHeight);
+ renderState.scissorRectCount = 1;
+ renderState.vertexBuffers[0] = gVertexBuffer;
+ renderState.vertexBufferCount = 1;
setupPipeline(renderEncoder);
- renderEncoder->setVertexBuffer(0, gVertexBuffer);
- renderEncoder->setPrimitiveTopology(PrimitiveTopology::TriangleStrip);
- renderEncoder->draw(4);
- renderEncoder->endEncoding();
- commandBuffer->close();
- gQueue->executeCommandBuffer(commandBuffer);
+ renderEncoder->setRenderState(renderState);
+
+ DrawArguments drawArgs = {};
+ drawArgs.vertexCount = 4;
+ renderEncoder->draw(drawArgs);
+ renderEncoder->end();
+ gQueue->submit(commandEncoder->finish());
}
- void renderReferenceImage(int transientHeapIndex, glm::mat4x4 transformMatrix)
+ void renderReferenceImage(glm::mat4x4 transformMatrix)
{
- {
- ComPtr<ICommandBuffer> commandBuffer =
- gTransientHeaps[transientHeapIndex]->createCommandBuffer();
- auto encoder = commandBuffer->encodeResourceCommands();
- encoder->textureBarrier(
- gRefImage,
- ResourceState::ShaderResource,
- ResourceState::RenderTarget);
- encoder->endEncoding();
- commandBuffer->close();
- gQueue->executeCommandBuffer(commandBuffer);
- }
-
renderImage(
- transientHeapIndex,
- gRefFrameBuffer,
- [&](IRenderCommandEncoder* encoder)
+ gRefImage,
+ [&](IRenderPassEncoder* encoder)
{
- auto rootObject = encoder->bindPipeline(gRefPipelineState);
+ auto rootObject =
+ encoder->bindPipeline(static_cast<IRenderPipeline*>(gRefPipeline.get()));
ShaderCursor rootCursor(rootObject);
rootCursor["Uniforms"]["modelViewProjection"].setData(
&transformMatrix,
sizeof(float) * 16);
- rootCursor["Uniforms"]["bwdTexture"]["texture"].setResource(gTexView);
- rootCursor["Uniforms"]["sampler"].setSampler(gSampler);
+ rootCursor["Uniforms"]["bwdTexture"]["texture"].setBinding(gTexView);
+ rootCursor["Uniforms"]["sampler"].setBinding(gSampler);
rootCursor["Uniforms"]["mipOffset"].setData(
mipMapOffset.getBuffer(),
sizeof(uint32_t) * mipMapOffset.getCount());
- rootCursor["Uniforms"]["texRef"].setResource(gTexView);
- rootCursor["Uniforms"]["bwdTexture"]["accumulateBuffer"].setResource(
- gAccumulateBufferView);
+ rootCursor["Uniforms"]["texRef"].setBinding(gTexView);
+ rootCursor["Uniforms"]["bwdTexture"]["accumulateBuffer"].setBinding(
+ gAccumulateBuffer);
});
}
- virtual void renderFrame(int frameBufferIndex) override
+ virtual void renderFrame(ITexture* texture) override
{
static uint32_t frameCount = 0;
frameCount++;
auto transformMatrix = getTransformMatrix();
- renderReferenceImage(frameBufferIndex, transformMatrix);
+ renderReferenceImage(transformMatrix);
- // Barriers.
+ // Clear buffers
{
- ComPtr<ICommandBuffer> commandBuffer =
- gTransientHeaps[frameBufferIndex]->createCommandBuffer();
- auto resEncoder = commandBuffer->encodeResourceCommands();
- ClearValue clearValue = {};
- resEncoder->bufferBarrier(
- gAccumulateBuffer,
- ResourceState::Undefined,
- ResourceState::UnorderedAccess);
- resEncoder->bufferBarrier(
- gReconstructBuffer,
- ResourceState::Undefined,
- ResourceState::UnorderedAccess);
- resEncoder->textureBarrier(
- gRefImage,
- ResourceState::Present,
- ResourceState::ShaderResource);
- resEncoder->textureBarrier(
- gIterImage,
- ResourceState::ShaderResource,
- ResourceState::RenderTarget);
- resEncoder->clearResourceView(
- gAccumulateBufferView,
- &clearValue,
- ClearResourceViewFlags::None);
- resEncoder->clearResourceView(
- gReconstructBufferView,
- &clearValue,
- ClearResourceViewFlags::None);
+ auto commandEncoder = gQueue->createCommandEncoder();
+ commandEncoder->clearBuffer(gAccumulateBuffer, 0, gAccumulateBuffer->getDesc().size);
+ commandEncoder->clearBuffer(gReconstructBuffer, 0, gReconstructBuffer->getDesc().size);
+
if (resetLearntTexture)
{
- resEncoder->textureBarrier(
- gLearningTexture,
- ResourceState::ShaderResource,
- ResourceState::UnorderedAccess);
- for (Index i = 0; i < gLearningTextureUAVs.getCount(); i++)
- resEncoder->clearResourceView(
- gLearningTextureUAVs[i],
- &clearValue,
- ClearResourceViewFlags::None);
- resEncoder->textureBarrier(
- gLearningTexture,
- ResourceState::UnorderedAccess,
- ResourceState::ShaderResource);
+ commandEncoder->clearTextureFloat(gLearningTexture, kEntireTexture, clearValue);
resetLearntTexture = false;
}
- resEncoder->endEncoding();
- commandBuffer->close();
- gQueue->executeCommandBuffer(commandBuffer);
+ gQueue->submit(commandEncoder->finish());
}
// Render image using backward propagate shader to obtain texture-space gradients.
renderImage(
- frameBufferIndex,
- gIterFrameBuffer,
- [&](IRenderCommandEncoder* encoder)
+ gIterImage,
+ [&](IRenderPassEncoder* encoder)
{
- auto rootObject = encoder->bindPipeline(gIterPipelineState);
+ auto rootObject = encoder->bindPipeline(gIterPipeline.get());
ShaderCursor rootCursor(rootObject);
rootCursor["Uniforms"]["modelViewProjection"].setData(
&transformMatrix,
sizeof(float) * 16);
- rootCursor["Uniforms"]["bwdTexture"]["texture"].setResource(gLearningTextureSRV);
- rootCursor["Uniforms"]["sampler"].setSampler(gSampler);
+ rootCursor["Uniforms"]["bwdTexture"]["texture"].setBinding(gLearningTextureSRV);
+ rootCursor["Uniforms"]["sampler"].setBinding(gSampler);
rootCursor["Uniforms"]["mipOffset"].setData(
mipMapOffset.getBuffer(),
sizeof(uint32_t) * mipMapOffset.getCount());
- rootCursor["Uniforms"]["texRef"].setResource(gRefImageSRV);
- rootCursor["Uniforms"]["bwdTexture"]["accumulateBuffer"].setResource(
- gAccumulateBufferView);
+ rootCursor["Uniforms"]["texRef"].setBinding(gRefImageSRV);
+ rootCursor["Uniforms"]["bwdTexture"]["accumulateBuffer"].setBinding(
+ gAccumulateBuffer);
rootCursor["Uniforms"]["bwdTexture"]["minLOD"].setData(5.0);
});
// Propagete gradients through mip map layers from top (lowest res) to bottom (highest res).
{
- ComPtr<ICommandBuffer> commandBuffer =
- gTransientHeaps[frameBufferIndex]->createCommandBuffer();
- auto encoder = commandBuffer->encodeComputeCommands();
- encoder->textureBarrier(
- gLearningTexture,
- ResourceState::ShaderResource,
- ResourceState::UnorderedAccess);
- auto rootObject = encoder->bindPipeline(gReconstructPipelineState);
+ auto commandEncoder = gQueue->createCommandEncoder();
+ auto encoder = commandEncoder->beginComputePass();
+ auto rootObject = encoder->bindPipeline(gReconstructPipeline.get());
for (int i = (int)mipMapOffset.getCount() - 2; i >= 0; i--)
{
ShaderCursor rootCursor(rootObject);
@@ -682,90 +574,91 @@ struct AutoDiffTexture : public WindowedAppBase
rootCursor["Uniforms"]["layerCount"].setData(mipMapOffset.getCount() - 1);
rootCursor["Uniforms"]["width"].setData(textureWidth);
rootCursor["Uniforms"]["height"].setData(textureHeight);
- rootCursor["Uniforms"]["accumulateBuffer"].setResource(gAccumulateBufferView);
- rootCursor["Uniforms"]["dstBuffer"].setResource(gReconstructBufferView);
+ rootCursor["Uniforms"]["accumulateBuffer"].setBinding(gAccumulateBuffer);
+ rootCursor["Uniforms"]["dstBuffer"].setBinding(gReconstructBuffer);
+
encoder->dispatchCompute(
((textureWidth >> i) + 15) / 16,
((textureHeight >> i) + 15) / 16,
1);
- encoder->bufferBarrier(
- gReconstructBuffer,
- ResourceState::UnorderedAccess,
- ResourceState::UnorderedAccess);
+ }
+ encoder->end();
+ gQueue->submit(commandEncoder->finish());
+
+ commandEncoder = gQueue->createCommandEncoder();
+ // Convert bottom layer mip from buffer to texture
+ {
+ auto encoder = commandEncoder->beginComputePass();
+ auto rootObject = encoder->bindPipeline(gConvertPipeline.get());
+ ShaderCursor rootCursor(rootObject);
+ rootCursor["Uniforms"]["mipOffset"].setData(
+ mipMapOffset.getBuffer(),
+ sizeof(uint32_t) * mipMapOffset.getCount());
+ rootCursor["Uniforms"]["dstLayer"].setData(0);
+ rootCursor["Uniforms"]["width"].setData(textureWidth);
+ rootCursor["Uniforms"]["height"].setData(textureHeight);
+ rootCursor["Uniforms"]["srcBuffer"].setBinding(gReconstructBuffer);
+ rootCursor["Uniforms"]["dstTexture"].setBinding(gDiffTextureUAVs[0]);
+ encoder->dispatchCompute((textureWidth + 15) / 16, (textureHeight + 15) / 16, 1);
+ encoder->end();
}
- // Convert bottom layer mip from buffer to texture.
- rootObject = encoder->bindPipeline(gConvertPipelineState);
- ShaderCursor rootCursor(rootObject);
- rootCursor["Uniforms"]["mipOffset"].setData(
- mipMapOffset.getBuffer(),
- sizeof(uint32_t) * mipMapOffset.getCount());
- rootCursor["Uniforms"]["dstLayer"].setData(0);
- rootCursor["Uniforms"]["width"].setData(textureWidth);
- rootCursor["Uniforms"]["height"].setData(textureHeight);
- rootCursor["Uniforms"]["srcBuffer"].setResource(gReconstructBufferView);
- rootCursor["Uniforms"]["dstTexture"].setResource(gDiffTextureUAVs[0]);
- encoder->dispatchCompute((textureWidth + 15) / 16, (textureHeight + 15) / 16, 1);
- encoder->textureBarrier(
- gDiffTexture,
- ResourceState::UnorderedAccess,
- ResourceState::UnorderedAccess);
-
- // Build higher level mip map layers.
- rootObject = encoder->bindPipeline(gBuildMipPipelineState);
+ // Build higher level mip map layers
+ encoder = commandEncoder->beginComputePass();
+ rootObject = encoder->bindPipeline(gBuildMipPipeline.get());
for (int i = 1; i < (int)mipMapOffset.getCount() - 1; i++)
{
+
ShaderCursor rootCursor(rootObject);
rootCursor["Uniforms"]["dstWidth"].setData(textureWidth >> i);
rootCursor["Uniforms"]["dstHeight"].setData(textureHeight >> i);
- rootCursor["Uniforms"]["srcTexture"].setResource(gDiffTextureUAVs[i - 1]);
- rootCursor["Uniforms"]["dstTexture"].setResource(gDiffTextureUAVs[i]);
+ rootCursor["Uniforms"]["srcTexture"].setBinding(gDiffTextureUAVs[i - 1]);
+ rootCursor["Uniforms"]["dstTexture"].setBinding(gDiffTextureUAVs[i]);
encoder->dispatchCompute(
((textureWidth >> i) + 15) / 16,
((textureHeight >> i) + 15) / 16,
1);
- encoder->textureBarrier(
- gDiffTexture,
- ResourceState::UnorderedAccess,
- ResourceState::UnorderedAccess);
}
+ encoder->end();
- // Accumulate gradients to learnt texture.
- rootObject = encoder->bindPipeline(gLearnMipPipelineState);
+ // Accumulate gradients to learnt texture
+ encoder = commandEncoder->beginComputePass();
+ rootObject = encoder->bindPipeline(gLearnMipPipeline.get());
for (int i = 0; i < (int)mipMapOffset.getCount() - 1; i++)
{
ShaderCursor rootCursor(rootObject);
rootCursor["Uniforms"]["dstWidth"].setData(textureWidth >> i);
rootCursor["Uniforms"]["dstHeight"].setData(textureHeight >> i);
rootCursor["Uniforms"]["learningRate"].setData(0.1f);
- rootCursor["Uniforms"]["srcTexture"].setResource(gDiffTextureUAVs[i]);
- rootCursor["Uniforms"]["dstTexture"].setResource(gLearningTextureUAVs[i]);
+ rootCursor["Uniforms"]["srcTexture"].setBinding(gDiffTextureUAVs[i]);
+ rootCursor["Uniforms"]["dstTexture"].setBinding(gLearningTextureUAVs[i]);
encoder->dispatchCompute(
((textureWidth >> i) + 15) / 16,
((textureHeight >> i) + 15) / 16,
1);
}
- encoder->textureBarrier(
- gLearningTexture,
- ResourceState::UnorderedAccess,
- ResourceState::ShaderResource);
- encoder->textureBarrier(
- gIterImage,
- ResourceState::Present,
- ResourceState::ShaderResource);
-
- encoder->endEncoding();
- commandBuffer->close();
- gQueue->executeCommandBuffer(commandBuffer);
+ encoder->end();
+
+ gQueue->submit(commandEncoder->finish());
}
- // Draw currently learnt texture.
+ // Draw currently learnt texture
{
- ComPtr<ICommandBuffer> commandBuffer =
- gTransientHeaps[frameBufferIndex]->createCommandBuffer();
- auto renderEncoder =
- commandBuffer->encodeRenderCommands(gRenderPass, gFramebuffers[frameBufferIndex]);
+ auto commandEncoder = gQueue->createCommandEncoder();
+
+ ComPtr<ITextureView> textureView = gDevice->createTextureView(texture, {});
+ RenderPassColorAttachment colorAttachment = {};
+ colorAttachment.view = textureView;
+ colorAttachment.loadOp = LoadOp::Clear;
+
+ RenderPassDesc renderPass = {};
+ renderPass.colorAttachments = &colorAttachment;
+ renderPass.colorAttachmentCount = 1;
+
+ auto renderEncoder = commandEncoder->beginRenderPass(renderPass);
+
drawTexturedQuad(renderEncoder, 0, 0, textureWidth, textureHeight, gLearningTextureSRV);
+
int refImageWidth = windowWidth - textureWidth - 10;
int refImageHeight = refImageWidth * windowHeight / windowWidth;
drawTexturedQuad(
@@ -775,6 +668,7 @@ struct AutoDiffTexture : public WindowedAppBase
refImageWidth,
refImageHeight,
gRefImageSRV);
+
drawTexturedQuad(
renderEncoder,
textureWidth + 10,
@@ -782,32 +676,35 @@ struct AutoDiffTexture : public WindowedAppBase
refImageWidth,
refImageHeight,
gIterImageSRV);
- renderEncoder->endEncoding();
- commandBuffer->close();
- gQueue->executeCommandBuffer(commandBuffer);
+ renderEncoder->end();
+ gQueue->submit(commandEncoder->finish());
}
if (!isTestMode())
{
- gSwapchain->present();
+ gSurface->present();
}
}
void drawTexturedQuad(
- IRenderCommandEncoder* renderEncoder,
+ IRenderPassEncoder* renderEncoder,
int x,
int y,
int w,
int h,
- IResourceView* srv)
+ ITextureView* srv)
{
- gfx::Viewport viewport = {};
- viewport.maxZ = 1.0f;
- viewport.extentX = (float)windowWidth;
- viewport.extentY = (float)windowHeight;
- renderEncoder->setViewportAndScissor(viewport);
-
- auto root = renderEncoder->bindPipeline(gDrawQuadPipelineState);
+ RenderState renderState = {};
+ renderState.viewports[0] = Viewport::fromSize(windowWidth, windowHeight);
+ renderState.viewportCount = 1;
+ renderState.scissorRects[0] = ScissorRect::fromSize(windowWidth, windowHeight);
+ renderState.scissorRectCount = 1;
+ renderState.vertexBuffers[0] = gVertexBuffer;
+ renderState.vertexBufferCount = 1;
+ renderEncoder->setRenderState(renderState);
+
+ auto root =
+ renderEncoder->bindPipeline(static_cast<IRenderPipeline*>(gDrawQuadPipeline.get()));
ShaderCursor rootCursor(root);
rootCursor["Uniforms"]["x"].setData(x);
rootCursor["Uniforms"]["y"].setData(y);
@@ -815,11 +712,12 @@ struct AutoDiffTexture : public WindowedAppBase
rootCursor["Uniforms"]["height"].setData(h);
rootCursor["Uniforms"]["viewWidth"].setData(windowWidth);
rootCursor["Uniforms"]["viewHeight"].setData(windowHeight);
- rootCursor["Uniforms"]["texture"].setResource(srv);
- rootCursor["Uniforms"]["sampler"].setSampler(gSampler);
- renderEncoder->setVertexBuffer(0, gVertexBuffer);
- renderEncoder->setPrimitiveTopology(PrimitiveTopology::TriangleStrip);
- renderEncoder->draw(4);
+ rootCursor["Uniforms"]["texture"].setBinding(srv);
+ rootCursor["Uniforms"]["sampler"].setBinding(gSampler);
+
+ DrawArguments drawArgs = {};
+ drawArgs.vertexCount = 4;
+ renderEncoder->draw(drawArgs);
}
};
diff --git a/examples/example-base/example-base.cpp b/examples/example-base/example-base.cpp
index 9de47b77b..2c7dd277c 100644
--- a/examples/example-base/example-base.cpp
+++ b/examples/example-base/example-base.cpp
@@ -10,7 +10,7 @@
#include "stb_image.h"
using namespace Slang;
-using namespace gfx;
+using namespace rhi;
Slang::Result WindowedAppBase::initializeBase(
const char* title,
@@ -18,33 +18,21 @@ Slang::Result WindowedAppBase::initializeBase(
int height,
DeviceType deviceType)
{
- // Initialize the rendering layer.
+ DeviceDesc deviceDesc = {};
+ deviceDesc.deviceType = deviceType;
#ifdef _DEBUG
- // Enable debug layer in debug config.
- gfxEnableDebugLayer(true);
+ deviceDesc.enableValidation = true;
#endif
- IDevice::Desc deviceDesc = {};
- deviceDesc.deviceType = deviceType;
- gfx::Result res = gfxCreateDevice(&deviceDesc, gDevice.writeRef());
- if (SLANG_FAILED(res))
- return res;
-
- ICommandQueue::Desc queueDesc = {};
- queueDesc.type = ICommandQueue::QueueType::Graphics;
- gQueue = gDevice->createCommandQueue(queueDesc);
+ gDevice = getRHI()->createDevice(deviceDesc);
+ if (!gDevice)
+ {
+ return SLANG_FAIL;
+ }
+ gQueue = gDevice->getQueue(QueueType::Graphics);
windowWidth = width;
windowHeight = height;
- IFramebufferLayout::TargetLayout renderTargetLayout = {gfx::Format::R8G8B8A8_UNORM, 1};
- IFramebufferLayout::TargetLayout depthLayout = {gfx::Format::D32_FLOAT, 1};
- IFramebufferLayout::Desc framebufferLayoutDesc;
- framebufferLayoutDesc.renderTargetCount = 1;
- framebufferLayoutDesc.renderTargets = &renderTargetLayout;
- framebufferLayoutDesc.depthStencil = &depthLayout;
- SLANG_RETURN_ON_FAIL(
- gDevice->createFramebufferLayout(framebufferLayoutDesc, gFramebufferLayout.writeRef()));
-
// Do not create swapchain and windows in test mode, because there won't be any display.
if (!isTestMode())
{
@@ -59,155 +47,39 @@ Slang::Result WindowedAppBase::initializeBase(
gWindow->events.mainLoop = [this]() { mainLoop(); };
gWindow->events.sizeChanged = Slang::Action<>(this, &WindowedAppBase::windowSizeChanged);
- auto deviceInfo = gDevice->getDeviceInfo();
+
+ WindowHandle windowHandle = gWindow->getNativeHandle().convert<WindowHandle>();
+ gSurface = gDevice->createSurface(windowHandle);
+
+ auto deviceInfo = gDevice->getInfo();
Slang::StringBuilder titleSb;
titleSb << title << " (" << deviceInfo.apiName << ": " << deviceInfo.adapterName << ")";
gWindow->setText(titleSb.getBuffer());
- // Create swapchain and framebuffers.
- gfx::ISwapchain::Desc swapchainDesc = {};
- swapchainDesc.format = gfx::Format::R8G8B8A8_UNORM;
- swapchainDesc.width = width;
- swapchainDesc.height = height;
- swapchainDesc.imageCount = kSwapchainImageCount;
- swapchainDesc.queue = gQueue;
- gfx::WindowHandle windowHandle = gWindow->getNativeHandle().convert<gfx::WindowHandle>();
- gSwapchain = gDevice->createSwapchain(swapchainDesc, windowHandle);
- createSwapchainFramebuffers();
+ rhi::SurfaceConfig surfaceConfig = {};
+
+ surfaceConfig.format = Format::RGBA8Unorm;
+ surfaceConfig.width = width;
+ surfaceConfig.height = height;
+ surfaceConfig.desiredImageCount = kSwapchainImageCount;
+ gSurface->configure(surfaceConfig);
}
else
{
- createOfflineFramebuffers();
+ createOfflineTextures();
}
- for (uint32_t i = 0; i < kSwapchainImageCount; i++)
- {
- gfx::ITransientResourceHeap::Desc transientHeapDesc = {};
- transientHeapDesc.constantBufferSize = 4096 * 1024;
- auto transientHeap = gDevice->createTransientResourceHeap(transientHeapDesc);
- gTransientHeaps.add(transientHeap);
- }
-
- gfx::IRenderPassLayout::Desc renderPassDesc = {};
- renderPassDesc.framebufferLayout = gFramebufferLayout;
- renderPassDesc.renderTargetCount = 1;
- IRenderPassLayout::TargetAccessDesc renderTargetAccess = {};
- IRenderPassLayout::TargetAccessDesc depthStencilAccess = {};
- renderTargetAccess.loadOp = IRenderPassLayout::TargetLoadOp::Clear;
- renderTargetAccess.storeOp = IRenderPassLayout::TargetStoreOp::Store;
- renderTargetAccess.initialState = ResourceState::Undefined;
- renderTargetAccess.finalState = ResourceState::Present;
- depthStencilAccess.loadOp = IRenderPassLayout::TargetLoadOp::Clear;
- depthStencilAccess.storeOp = IRenderPassLayout::TargetStoreOp::Store;
- depthStencilAccess.initialState = ResourceState::DepthWrite;
- depthStencilAccess.finalState = ResourceState::DepthWrite;
- renderPassDesc.renderTargetAccess = &renderTargetAccess;
- renderPassDesc.depthStencilAccess = &depthStencilAccess;
- gRenderPass = gDevice->createRenderPassLayout(renderPassDesc);
-
return SLANG_OK;
}
void WindowedAppBase::mainLoop()
{
- int frameBufferIndex = gSwapchain->acquireNextImage();
-
- gTransientHeaps[frameBufferIndex]->synchronizeAndReset();
- renderFrame(frameBufferIndex);
- gTransientHeaps[frameBufferIndex]->finish();
-}
-
-void WindowedAppBase::offlineRender()
-{
- gTransientHeaps[0]->synchronizeAndReset();
- renderFrame(0);
- gTransientHeaps[0]->finish();
-}
-
-void WindowedAppBase::createFramebuffers(
- uint32_t width,
- uint32_t height,
- gfx::Format colorFormat,
- uint32_t frameBufferCount)
-{
- for (uint32_t i = 0; i < frameBufferCount; i++)
- {
- gfx::ITextureResource::Desc depthBufferDesc;
- depthBufferDesc.type = IResource::Type::Texture2D;
- depthBufferDesc.size.width = width;
- depthBufferDesc.size.height = height;
- depthBufferDesc.size.depth = 1;
- depthBufferDesc.format = gfx::Format::D32_FLOAT;
- depthBufferDesc.defaultState = ResourceState::DepthWrite;
- depthBufferDesc.allowedStates = ResourceStateSet(ResourceState::DepthWrite);
- ClearValue depthClearValue = {};
- depthBufferDesc.optimalClearValue = &depthClearValue;
- ComPtr<gfx::ITextureResource> depthBufferResource =
- gDevice->createTextureResource(depthBufferDesc, nullptr);
-
- ComPtr<gfx::ITextureResource> colorBuffer;
- if (isTestMode())
- {
- gfx::ITextureResource::Desc colorBufferDesc;
- colorBufferDesc.type = IResource::Type::Texture2D;
- colorBufferDesc.size.width = width;
- colorBufferDesc.size.height = height;
- colorBufferDesc.size.depth = 1;
- colorBufferDesc.format = colorFormat;
- colorBufferDesc.defaultState = ResourceState::RenderTarget;
- colorBufferDesc.allowedStates =
- ResourceStateSet(ResourceState::RenderTarget, ResourceState::CopyDestination);
- colorBuffer = gDevice->createTextureResource(colorBufferDesc, nullptr);
- }
- else
- {
- gSwapchain->getImage(i, colorBuffer.writeRef());
- }
-
- gfx::IResourceView::Desc colorBufferViewDesc;
- memset(&colorBufferViewDesc, 0, sizeof(colorBufferViewDesc));
- colorBufferViewDesc.format = colorFormat;
- colorBufferViewDesc.renderTarget.shape = gfx::IResource::Type::Texture2D;
- colorBufferViewDesc.type = gfx::IResourceView::Type::RenderTarget;
- ComPtr<gfx::IResourceView> rtv =
- gDevice->createTextureView(colorBuffer.get(), colorBufferViewDesc);
-
- gfx::IResourceView::Desc depthBufferViewDesc;
- memset(&depthBufferViewDesc, 0, sizeof(depthBufferViewDesc));
- depthBufferViewDesc.format = gfx::Format::D32_FLOAT;
- depthBufferViewDesc.renderTarget.shape = gfx::IResource::Type::Texture2D;
- depthBufferViewDesc.type = gfx::IResourceView::Type::DepthStencil;
- ComPtr<gfx::IResourceView> dsv =
- gDevice->createTextureView(depthBufferResource.get(), depthBufferViewDesc);
-
- gfx::IFramebuffer::Desc framebufferDesc;
- framebufferDesc.renderTargetCount = 1;
- framebufferDesc.depthStencilView = dsv.get();
- framebufferDesc.renderTargetViews = rtv.readRef();
- framebufferDesc.layout = gFramebufferLayout;
- ComPtr<gfx::IFramebuffer> frameBuffer = gDevice->createFramebuffer(framebufferDesc);
-
- gFramebuffers.add(frameBuffer);
- }
-}
-
-void WindowedAppBase::createOfflineFramebuffers()
-{
- gFramebuffers.clear();
- createFramebuffers(windowWidth, windowHeight, gfx::Format::R8G8B8A8_UNORM, 1);
+ auto texture = gSurface->acquireNextImage();
+ renderFrame(texture);
}
-void WindowedAppBase::createSwapchainFramebuffers()
-{
- gFramebuffers.clear();
- createFramebuffers(
- gSwapchain->getDesc().width,
- gSwapchain->getDesc().height,
- gSwapchain->getDesc().format,
- kSwapchainImageCount);
-}
-ComPtr<gfx::IResourceView> WindowedAppBase::createTextureFromFile(
+ComPtr<ITextureView> WindowedAppBase::createTextureFromFile(
String fileName,
int& textureWidth,
int& textureHeight)
@@ -215,24 +87,24 @@ ComPtr<gfx::IResourceView> WindowedAppBase::createTextureFromFile(
int channelsInFile = 0;
auto textureContent =
stbi_load(fileName.getBuffer(), &textureWidth, &textureHeight, &channelsInFile, 4);
- gfx::ITextureResource::Desc textureDesc = {};
- textureDesc.allowedStates.add(ResourceState::ShaderResource);
- textureDesc.format = gfx::Format::R8G8B8A8_UNORM;
- textureDesc.numMipLevels = Math::Log2Ceil(Math::Min(textureWidth, textureHeight)) + 1;
- textureDesc.type = gfx::IResource::Type::Texture2D;
+ TextureDesc textureDesc = {};
+ textureDesc.type = TextureType::Texture2D;
+ textureDesc.usage = TextureUsage::ShaderResource;
+ textureDesc.format = Format::RGBA8Unorm;
+ textureDesc.mipCount = Math::Log2Ceil(Math::Min(textureWidth, textureHeight)) + 1;
textureDesc.size.width = textureWidth;
textureDesc.size.height = textureHeight;
textureDesc.size.depth = 1;
- List<gfx::ITextureResource::SubresourceData> subresData;
+ List<SubresourceData> subresData;
List<List<uint32_t>> mipMapData;
- mipMapData.setCount(textureDesc.numMipLevels);
- subresData.setCount(textureDesc.numMipLevels);
+ mipMapData.setCount(textureDesc.mipCount);
+ subresData.setCount(textureDesc.mipCount);
mipMapData[0].setCount(textureWidth * textureHeight);
memcpy(mipMapData[0].getBuffer(), textureContent, textureWidth * textureHeight * 4);
stbi_image_free(textureContent);
subresData[0].data = mipMapData[0].getBuffer();
- subresData[0].strideY = textureWidth * 4;
- subresData[0].strideZ = textureWidth * textureHeight * 4;
+ subresData[0].rowPitch = textureWidth * 4;
+ subresData[0].slicePitch = textureWidth * textureHeight * 4;
// Build mipmaps.
struct RGBA
@@ -254,15 +126,15 @@ ComPtr<gfx::IResourceView> WindowedAppBase::createTextureFromFile(
int lastMipWidth = textureWidth;
int lastMipHeight = textureHeight;
- for (int m = 1; m < textureDesc.numMipLevels; m++)
+ for (uint32_t m = 1; m < textureDesc.mipCount; m++)
{
auto lastMipmapData = mipMapData[m - 1].getBuffer();
int w = lastMipWidth / 2;
int h = lastMipHeight / 2;
mipMapData[m].setCount(w * h);
subresData[m].data = mipMapData[m].getBuffer();
- subresData[m].strideY = w * 4;
- subresData[m].strideZ = h * w * 4;
+ subresData[m].rowPitch = w * 4;
+ subresData[m].slicePitch = h * w * 4;
for (int x = 0; x < w; x++)
{
for (int y = 0; y < h; y++)
@@ -284,13 +156,33 @@ ComPtr<gfx::IResourceView> WindowedAppBase::createTextureFromFile(
lastMipHeight = h;
}
- auto texture = gDevice->createTextureResource(textureDesc, subresData.getBuffer());
+ auto texture = gDevice->createTexture(textureDesc, subresData.getBuffer());
- gfx::IResourceView::Desc viewDesc = {};
- viewDesc.type = gfx::IResourceView::Type::ShaderResource;
+ TextureViewDesc viewDesc = {};
return gDevice->createTextureView(texture.get(), viewDesc);
}
+void WindowedAppBase::createOfflineTextures()
+{
+ for (uint32_t i = 0; i < kSwapchainImageCount; i++)
+ {
+ TextureDesc textureDesc = {};
+ textureDesc.size.width = this->windowWidth;
+ textureDesc.size.height = this->windowHeight;
+ textureDesc.format = Format::RGBA8Unorm;
+ textureDesc.mipCount = 1;
+ textureDesc.usage = TextureUsage::UnorderedAccess | TextureUsage::CopySource;
+ auto texture = gDevice->createTexture(textureDesc);
+ gOfflineTextures.add(texture);
+ }
+}
+
+void WindowedAppBase::offlineRender()
+{
+ SLANG_ASSERT(gOfflineTextures.getCount() > 0);
+ renderFrame(gOfflineTextures[0]);
+}
+
void WindowedAppBase::windowSizeChanged()
{
// Wait for the GPU to finish.
@@ -299,17 +191,12 @@ void WindowedAppBase::windowSizeChanged()
auto clientRect = gWindow->getClientRect();
if (clientRect.width > 0 && clientRect.height > 0)
{
- // Free all framebuffers before resizing swapchain.
- gFramebuffers = decltype(gFramebuffers)();
-
- // Resize swapchain.
- if (gSwapchain->resize(clientRect.width, clientRect.height) == SLANG_OK)
- {
- // Recreate framebuffers for each swapchain back buffer image.
- createSwapchainFramebuffers();
- windowWidth = clientRect.width;
- windowHeight = clientRect.height;
- }
+ SurfaceConfig config = {};
+ config.format = gSurface->getInfo().preferredFormat;
+ config.width = clientRect.width;
+ config.height = clientRect.height;
+ config.vsync = false;
+ gSurface->configure(config);
}
}
@@ -364,12 +251,6 @@ public:
}
};
-void initDebugCallback()
-{
- static DebugCallback callback = {};
- gfxSetDebugCallback(&callback);
-}
-
#ifdef _WIN32
void _Win32OutputDebugString(const char* str)
{
diff --git a/examples/example-base/example-base.h b/examples/example-base/example-base.h
index 9aabac8d4..06970aaba 100644
--- a/examples/example-base/example-base.h
+++ b/examples/example-base/example-base.h
@@ -3,7 +3,7 @@
#include "core/slang-basic.h"
#include "core/slang-io.h"
#include "platform/window.h"
-#include "slang-gfx.h"
+#include "slang-rhi.h"
#include "test-base.h"
#ifdef _WIN32
@@ -23,6 +23,8 @@ void _Win32OutputDebugString(const char* str);
#define EXAMPLE_MAIN(innerMain) PLATFORM_UI_MAIN(innerMain)
#endif // _WIN32
+static const float kIdentity[] = {1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1};
+
struct WindowedAppBase : public TestBase
{
protected:
@@ -32,39 +34,31 @@ protected:
uint32_t windowWidth;
uint32_t windowHeight;
- Slang::ComPtr<gfx::IDevice> gDevice;
+ Slang::ComPtr<rhi::IDevice> gDevice;
+ Slang::ComPtr<rhi::ICommandQueue> gQueue;
+ Slang::ComPtr<rhi::ISurface> gSurface;
- Slang::ComPtr<gfx::ISwapchain> gSwapchain;
- Slang::ComPtr<gfx::IFramebufferLayout> gFramebufferLayout;
- Slang::List<Slang::ComPtr<gfx::IFramebuffer>> gFramebuffers;
- Slang::List<Slang::ComPtr<gfx::ITransientResourceHeap>> gTransientHeaps;
- Slang::ComPtr<gfx::IRenderPassLayout> gRenderPass;
- Slang::ComPtr<gfx::ICommandQueue> gQueue;
+ Slang::List<Slang::ComPtr<rhi::ITexture>> gOfflineTextures;
Slang::Result initializeBase(
const char* title,
int width,
int height,
- gfx::DeviceType deviceType = gfx::DeviceType::Default);
-
- void createFramebuffers(
- uint32_t width,
- uint32_t height,
- gfx::Format colorFormat,
- uint32_t frameBufferCount);
- void createSwapchainFramebuffers();
- void createOfflineFramebuffers();
+ rhi::DeviceType deviceType = rhi::DeviceType::Default);
void mainLoop();
- Slang::ComPtr<gfx::IResourceView> createTextureFromFile(
+ Slang::ComPtr<rhi::ITextureView> createTextureFromFile(
Slang::String fileName,
int& textureWidth,
int& textureHeight);
+
+ void createOfflineTextures();
+
virtual void windowSizeChanged();
protected:
- virtual void renderFrame(int framebufferIndex) = 0;
+ virtual void renderFrame(rhi::ITexture* texture) = 0;
public:
platform::Window* getWindow() { return gWindow.Ptr(); }
@@ -136,13 +130,9 @@ inline void diagnoseIfNeeded(slang::IBlob* diagnosticsBlob)
}
}
-void initDebugCallback();
-
template<typename TApp>
int innerMain(int argc, char** argv)
{
- initDebugCallback();
-
TApp app;
app.parseOption(argc, argv);
diff --git a/examples/gpu-printing/main.cpp b/examples/gpu-printing/main.cpp
index 27a77a82b..ccf7838a6 100644
--- a/examples/gpu-printing/main.cpp
+++ b/examples/gpu-printing/main.cpp
@@ -7,16 +7,17 @@ using Slang::ComPtr;
#include "core/slang-basic.h"
#include "examples/example-base/example-base.h"
-#include "gfx-util/shader-cursor.h"
#include "gpu-printing.h"
#include "platform/window.h"
-#include "slang-gfx.h"
+#include "slang-rhi.h"
-using namespace gfx;
+#include <slang-rhi/shader-cursor.h>
+
+using namespace rhi;
static const ExampleResources resourceBase("gpu-printing");
-ComPtr<slang::ISession> createSlangSession(gfx::IDevice* device)
+ComPtr<slang::ISession> createSlangSession(IDevice* device)
{
ComPtr<slang::ISession> slangSession = device->getSlangSession();
return slangSession;
@@ -40,19 +41,19 @@ struct ExampleProgram : public TestBase
int gWindowWidth = 640;
int gWindowHeight = 480;
- ComPtr<gfx::IDevice> gDevice;
+ ComPtr<IDevice> gDevice;
ComPtr<slang::ISession> gSlangSession;
ComPtr<slang::IModule> gSlangModule;
- ComPtr<gfx::IShaderProgram> gProgram;
+ ComPtr<IShaderProgram> gProgram;
- ComPtr<gfx::IPipelineState> gPipelineState;
+ ComPtr<IComputePipeline> gPipelineState;
Slang::Dictionary<int, std::string> gHashedStrings;
GPUPrinting gGPUPrinting;
- ComPtr<gfx::IShaderProgram> loadComputeProgram(
+ ComPtr<IShaderProgram> loadComputeProgram(
slang::IModule* slangModule,
char const* entryPointName)
{
@@ -69,10 +70,10 @@ struct ExampleProgram : public TestBase
gGPUPrinting.loadStrings(linkedProgram->getLayout());
- gfx::IShaderProgram::Desc programDesc = {};
+ ShaderProgramDesc programDesc = {};
programDesc.slangGlobalScope = linkedProgram;
- auto shaderProgram = gDevice->createProgram(programDesc);
+ auto shaderProgram = gDevice->createShaderProgram(programDesc);
return shaderProgram;
}
@@ -80,10 +81,10 @@ struct ExampleProgram : public TestBase
Result execute(int argc, char* argv[])
{
parseOption(argc, argv);
- IDevice::Desc deviceDesc;
- Result res = gfxCreateDevice(&deviceDesc, gDevice.writeRef());
- if (SLANG_FAILED(res))
- return res;
+ DeviceDesc deviceDesc;
+ gDevice = getRHI()->createDevice(deviceDesc);
+ if (!gDevice)
+ return SLANG_FAIL;
Slang::String path = resourceBase.resolveResource("kernels.slang");
@@ -96,9 +97,9 @@ struct ExampleProgram : public TestBase
if (!gProgram)
return SLANG_FAIL;
- ComputePipelineStateDesc desc;
+ ComputePipelineDesc desc;
desc.program = gProgram;
- auto pipelineState = gDevice->createComputePipelineState(desc);
+ auto pipelineState = gDevice->createComputePipeline(desc);
if (!pipelineState)
return SLANG_FAIL;
@@ -106,45 +107,28 @@ struct ExampleProgram : public TestBase
size_t printBufferSize = 4 * 1024; // use a small-ish (4KB) buffer for print output
- IBufferResource::Desc printBufferDesc = {};
- printBufferDesc.type = IResource::Type::Buffer;
- printBufferDesc.sizeInBytes = printBufferSize;
+ BufferDesc printBufferDesc = {};
+ printBufferDesc.size = printBufferSize;
printBufferDesc.elementSize = sizeof(uint32_t);
- printBufferDesc.defaultState = ResourceState::UnorderedAccess;
- printBufferDesc.allowedStates = ResourceStateSet(
- ResourceState::CopySource,
- ResourceState::CopyDestination,
- ResourceState::UnorderedAccess);
+ printBufferDesc.usage =
+ BufferUsage::UnorderedAccess | BufferUsage::CopySource | BufferUsage::CopyDestination;
printBufferDesc.memoryType = MemoryType::DeviceLocal;
- auto printBuffer = gDevice->createBufferResource(printBufferDesc);
-
- IResourceView::Desc printBufferViewDesc = {};
- printBufferViewDesc.type = IResourceView::Type::UnorderedAccess;
- printBufferViewDesc.format = Format::Unknown;
- auto printBufferView = gDevice->createBufferView(printBuffer, nullptr, printBufferViewDesc);
-
- ITransientResourceHeap::Desc transientResourceHeapDesc = {};
- transientResourceHeapDesc.constantBufferSize = 256;
- auto transientHeap = gDevice->createTransientResourceHeap(transientResourceHeapDesc);
-
- ICommandQueue::Desc queueDesc = {ICommandQueue::QueueType::Graphics};
- auto queue = gDevice->createCommandQueue(queueDesc);
- auto commandBuffer = transientHeap->createCommandBuffer();
- auto encoder = commandBuffer->encodeComputeCommands();
- auto rootShaderObject = encoder->bindPipeline(gPipelineState);
+ auto printBuffer = gDevice->createBuffer(printBufferDesc);
+
+ auto queue = gDevice->getQueue(QueueType::Graphics);
+ auto commandEncoder = queue->createCommandEncoder();
+ auto computeEncoder = commandEncoder->beginComputePass();
+ auto rootShaderObject = computeEncoder->bindPipeline(gPipelineState);
auto cursor = ShaderCursor(rootShaderObject);
- cursor["gPrintBuffer"].setResource(printBufferView);
- encoder->dispatchCompute(1, 1, 1);
- encoder->bufferBarrier(
- printBuffer,
- ResourceState::UnorderedAccess,
- ResourceState::CopySource);
- encoder->endEncoding();
- commandBuffer->close();
- queue->executeCommandBuffer(commandBuffer);
+ cursor["gPrintBuffer"].setBinding(printBuffer);
+
+ computeEncoder->dispatchCompute(1, 1, 1);
+
+ computeEncoder->end();
+ queue->submit(commandEncoder->finish());
ComPtr<ISlangBlob> blob;
- gDevice->readBufferResource(printBuffer, 0, printBufferSize, blob.writeRef());
+ gDevice->readBuffer(printBuffer, 0, printBufferSize, blob.writeRef());
gGPUPrinting.processGPUPrintCommands(blob->getBufferPointer(), printBufferSize);
diff --git a/examples/hello-world/main.cpp b/examples/hello-world/main.cpp
index e71a02115..ece390543 100644
--- a/examples/hello-world/main.cpp
+++ b/examples/hello-world/main.cpp
@@ -69,7 +69,6 @@ struct HelloWorldExample : public TestBase
int exampleMain(int argc, char** argv)
{
- initDebugCallback();
HelloWorldExample example;
example.parseOption(argc, argv);
return example.run();
diff --git a/examples/model-viewer/main.cpp b/examples/model-viewer/main.cpp
index 8bbc8ec88..9c1c763f2 100644
--- a/examples/model-viewer/main.cpp
+++ b/examples/model-viewer/main.cpp
@@ -25,17 +25,17 @@
// and parameter binding.
//
#include "examples/example-base/example-base.h"
-#include "gfx-util/shader-cursor.h"
#include "platform/gui.h"
#include "platform/model.h"
#include "platform/vector-math.h"
#include "platform/window.h"
-#include "slang-gfx.h"
+#include "slang-rhi.h"
#include <map>
+#include <slang-rhi/shader-cursor.h>
#include <sstream>
-using namespace gfx;
+using namespace rhi;
using Slang::RefObject;
using Slang::RefPtr;
@@ -121,12 +121,12 @@ struct RendererContext
// At this point, `composedProgram` represents the shader program
// we want to run, and the compute shader there have been checked.
- // We can create a `gfx::IShaderProgram` object from `composedProgram`
+ // We can create a `IShaderProgram` object from `composedProgram`
// so it may be used by the graphics layer.
- gfx::IShaderProgram::Desc programDesc = {};
+ ShaderProgramDesc programDesc = {};
programDesc.slangGlobalScope = composedProgram.get();
- shaderProgram = device->createProgram(programDesc);
+ shaderProgram = device->createShaderProgram(programDesc);
// Get other shader types that we will use for creating shader objects.
perViewShaderType = slangReflection->findTypeByName("PerView");
@@ -175,7 +175,7 @@ struct SimpleMaterial : Material
auto program = context->slangReflection;
auto shaderType = program->findTypeByName("SimpleMaterial");
shaderObject = context->device->createShaderObject(shaderType);
- gfx::ShaderCursor cursor(shaderObject);
+ ShaderCursor cursor(shaderObject);
cursor["diffuseColor"].setData(&diffuseColor, sizeof(diffuseColor));
cursor["specularColor"].setData(&specularColor, sizeof(specularColor));
cursor["specularity"].setData(&specularity, sizeof(specularity));
@@ -201,8 +201,8 @@ struct Model : RefObject
{
typedef platform::ModelLoader::Vertex Vertex;
- ComPtr<IBufferResource> vertexBuffer;
- ComPtr<IBufferResource> indexBuffer;
+ ComPtr<IBuffer> vertexBuffer;
+ ComPtr<IBuffer> indexBuffer;
PrimitiveTopology primitiveTopology;
int vertexCount;
int indexCount;
@@ -383,16 +383,19 @@ struct LightEnvLayout : public RefObject
//
struct LightArrayLayout : RefObject
{
- Int maximumCount = 0;
+ SlangInt maximumCount = 0;
std::string typeName;
};
std::vector<LightArrayLayout> lightArrayLayouts;
- std::map<slang::TypeReflection*, Int> mapLightTypeToArrayIndex;
+ std::map<slang::TypeReflection*, SlangInt> mapLightTypeToArrayIndex;
slang::TypeReflection* shaderType = nullptr;
- void addLightType(RendererContext* context, slang::TypeReflection* lightType, Int maximumCount)
+ void addLightType(
+ RendererContext* context,
+ slang::TypeReflection* lightType,
+ SlangInt maximumCount)
{
- Int arrayIndex = (Int)lightArrayLayouts.size();
+ SlangInt arrayIndex = (SlangInt)lightArrayLayouts.size();
LightArrayLayout layout;
layout.maximumCount = maximumCount;
@@ -419,12 +422,12 @@ struct LightEnvLayout : public RefObject
}
template<typename T>
- void addLightType(RendererContext* context, Int maximumCount)
+ void addLightType(RendererContext* context, SlangInt maximumCount)
{
addLightType(context, getShaderType<T>(context), maximumCount);
}
- Int getArrayIndexForType(slang::TypeReflection* lightType)
+ SlangInt getArrayIndexForType(slang::TypeReflection* lightType)
{
auto iter = mapLightTypeToArrayIndex.find(lightType);
if (iter != mapLightTypeToArrayIndex.end())
@@ -647,7 +650,7 @@ struct ModelViewer : WindowedAppBase
RefPtr<LightEnv> lightEnv;
// The pipeline state object we will use to draw models.
- ComPtr<IPipelineState> gPipelineState;
+ ComPtr<IPipeline> gPipelineState;
// During startup the application will load one or more models and
// add them to the `gModels` list.
@@ -762,23 +765,27 @@ struct ModelViewer : WindowedAppBase
InputElementDesc inputElements[] = {
- {"POSITION", 0, Format::R32G32B32_FLOAT, offsetof(Model::Vertex, position)},
- {"NORMAL", 0, Format::R32G32B32_FLOAT, offsetof(Model::Vertex, normal)},
- {"UV", 0, Format::R32G32_FLOAT, offsetof(Model::Vertex, uv)},
+ {"POSITION", 0, Format::RGB32Float, offsetof(Model::Vertex, position)},
+ {"NORMAL", 0, Format::RGB32Float, offsetof(Model::Vertex, normal)},
+ {"UV", 0, Format::RG32Float, offsetof(Model::Vertex, uv)},
};
auto inputLayout = gDevice->createInputLayout(sizeof(Model::Vertex), &inputElements[0], 3);
if (!inputLayout)
return SLANG_FAIL;
// Create the pipeline state object for drawing models.
- GraphicsPipelineStateDesc pipelineStateDesc = {};
+ RenderPipelineDesc pipelineStateDesc = {};
pipelineStateDesc.program = context.shaderProgram;
- pipelineStateDesc.framebufferLayout = gFramebufferLayout;
pipelineStateDesc.inputLayout = inputLayout;
- pipelineStateDesc.primitiveType = PrimitiveType::Triangle;
+ pipelineStateDesc.primitiveTopology = PrimitiveTopology::TriangleList;
pipelineStateDesc.depthStencil.depthFunc = ComparisonFunc::LessEqual;
pipelineStateDesc.depthStencil.depthTestEnable = true;
- gPipelineState = gDevice->createGraphicsPipelineState(pipelineStateDesc);
+ // Set up color target
+ ColorTargetDesc colorTarget = {};
+ colorTarget.format = Format::RGBA8Unorm;
+ pipelineStateDesc.targetCount = 1;
+ pipelineStateDesc.targets = &colorTarget;
+ gPipelineState = gDevice->createRenderPipeline(pipelineStateDesc);
// We will create a lighting environment layout that can hold a few point
// and directional lights, and then initialize a lighting environment
@@ -813,7 +820,7 @@ struct ModelViewer : WindowedAppBase
// logic to see how the application will drive the `RenderContext`
// type to perform both shader parameter binding and code specialization.
//
- void renderFrame(int frameIndex) override
+ void renderFrame(ITexture* texture) override
{
// In order to see that things are rendering properly we need some
// kind of animation, so we will compute a crude delta-time value here.
@@ -871,22 +878,35 @@ struct ModelViewer : WindowedAppBase
view = glm::translate(view, -cameraPosition);
glm::mat4x4 viewProjection = projection * view;
- auto deviceInfo = gDevice->getDeviceInfo();
+ auto deviceInfo = gDevice->getInfo();
+ // Use identity matrix for correction
+ static const float kIdentity[] = {1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1};
glm::mat4x4 correctionMatrix;
- memcpy(&correctionMatrix, deviceInfo.identityProjectionMatrix, sizeof(float) * 16);
+ memcpy(&correctionMatrix, kIdentity, sizeof(float) * 16);
viewProjection = correctionMatrix * viewProjection;
// glm uses column-major layout, we need to translate it to row-major.
viewProjection = glm::transpose(viewProjection);
- auto drawCommandBuffer = gTransientHeaps[frameIndex]->createCommandBuffer();
- auto drawCommandEncoder =
- drawCommandBuffer->encodeRenderCommands(gRenderPass, gFramebuffers[frameIndex]);
- gfx::Viewport viewport = {};
- viewport.maxZ = 1.0f;
- viewport.extentX = (float)clientRect.width;
- viewport.extentY = (float)clientRect.height;
- drawCommandEncoder->setViewportAndScissor(viewport);
- drawCommandEncoder->setPrimitiveTopology(PrimitiveTopology::TriangleList);
+ auto drawCommandEncoder = gQueue->createCommandEncoder();
+
+ ComPtr<ITextureView> textureView = gDevice->createTextureView(texture, {});
+ RenderPassColorAttachment colorAttachment = {};
+ colorAttachment.view = textureView;
+ colorAttachment.loadOp = LoadOp::Clear;
+
+ RenderPassDesc renderPass = {};
+ renderPass.colorAttachments = &colorAttachment;
+ renderPass.colorAttachmentCount = 1;
+
+ auto renderEncoder = drawCommandEncoder->beginRenderPass(renderPass);
+
+ RenderState renderState = {};
+ renderState.viewports[0] =
+ Viewport::fromSize((float)clientRect.width, (float)clientRect.height);
+ renderState.viewportCount = 1;
+ renderState.scissorRects[0] =
+ ScissorRect::fromSize((float)clientRect.width, (float)clientRect.height);
+ renderState.scissorRectCount = 1;
// We are only rendering one view, so we can fill in a per-view
// shader object once and use it across all draw calls.
@@ -903,8 +923,10 @@ struct ModelViewer : WindowedAppBase
//
for (auto& model : gModels)
{
- drawCommandEncoder->setVertexBuffer(0, model->vertexBuffer);
- drawCommandEncoder->setIndexBuffer(model->indexBuffer, Format::R32_UINT);
+ renderState.vertexBuffers[0] = model->vertexBuffer;
+ renderState.vertexBufferCount = 1;
+ renderState.indexBuffer = model->indexBuffer;
+ renderState.indexFormat = IndexFormat::Uint32;
// For each model we provide a parameter
// block that holds the per-model transformation
// parameters, corresponding to the `PerModel` type
@@ -932,7 +954,12 @@ struct ModelViewer : WindowedAppBase
for (auto& mesh : model->meshes)
{
// Set the pipeline and binding state for drawing each mesh.
- auto rootObject = drawCommandEncoder->bindPipeline(gPipelineState);
+ auto rootObject = renderEncoder->bindPipeline(
+ static_cast<IRenderPipeline*>(gPipelineState.get()));
+
+ // Apply render state
+ renderEncoder->setRenderState(renderState);
+
ShaderCursor rootCursor(rootObject);
rootCursor["gViewParams"].setObject(viewShaderObject);
rootCursor["gModelParams"].setObject(modelShaderObject);
@@ -953,16 +980,20 @@ struct ModelViewer : WindowedAppBase
// All the shader parameters and pipeline states have been set up,
// we can now issue a draw call for the mesh.
- drawCommandEncoder->drawIndexed(mesh->indexCount, mesh->firstIndex);
+ DrawArguments drawArgs = {};
+ // `drawArgs.vertexCount` is actually `indexCount` for the `DrawIndexed` Graphics
+ // API
+ drawArgs.vertexCount = mesh->indexCount;
+ drawArgs.startIndexLocation = mesh->firstIndex;
+ renderEncoder->drawIndexed(drawArgs);
}
}
- drawCommandEncoder->endEncoding();
- drawCommandBuffer->close();
- gQueue->executeCommandBuffer(drawCommandBuffer);
+ renderEncoder->end();
+ gQueue->submit(drawCommandEncoder->finish());
if (!isTestMode())
{
- gSwapchain->present();
+ gSurface->present();
}
}
};
diff --git a/examples/nv-aftermath-example/main.cpp b/examples/nv-aftermath-example/main.cpp
index ed6db43a2..bd17ab096 100644
--- a/examples/nv-aftermath-example/main.cpp
+++ b/examples/nv-aftermath-example/main.cpp
@@ -5,13 +5,14 @@
#include "GFSDK_Aftermath_GpuCrashDump.h"
#include "core/slang-basic.h"
#include "examples/example-base/example-base.h"
-#include "gfx-util/shader-cursor.h"
#include "platform/window.h"
#include "slang-com-ptr.h"
-#include "slang-gfx.h"
#include "slang.h"
-using namespace gfx;
+#include <slang-rhi.h>
+#include <slang-rhi/shader-cursor.h>
+
+using namespace rhi;
using namespace Slang;
static const ExampleResources resourceBase("nv-aftermath-example");
@@ -46,11 +47,9 @@ struct AftermathCrashExample : public WindowedAppBase
{
void diagnoseIfNeeded(slang::IBlob* diagnosticsBlob);
- gfx::Result loadShaderProgram(gfx::IDevice* device, gfx::IShaderProgram** outProgram);
-
- Slang::Result initialize();
+ Result loadShaderProgram(IDevice* device, IShaderProgram** outProgram);
- virtual void renderFrame(int frameBufferIndex) override;
+ virtual void renderFrame(ITexture* texture) override;
void onAftermathCrash(const void* data, const uint32_t dataSizeInBytes);
@@ -60,23 +59,85 @@ struct AftermathCrashExample : public WindowedAppBase
void onAftermathMarker(const void* pMarker, void** resolvedMarkerData, uint32_t* markerSize);
- // Create accessors so we don't have to use g prefixed variables.
- gfx::IDevice* getDevice() { return gDevice; }
- gfx::ICommandQueue* getQueue() { return gQueue; }
- gfx::IFramebufferLayout* getFrameBufferLayout() { return gFramebufferLayout; }
- gfx::ISwapchain* getSwapChain() { return gSwapchain; }
- gfx::IRenderPassLayout* getRenderPassLayout() { return gRenderPass; }
- Slang::List<Slang::ComPtr<gfx::IFramebuffer>>& getFrameBuffers() { return gFramebuffers; }
- Slang::List<Slang::ComPtr<gfx::ITransientResourceHeap>>& getTransientHeaps()
- {
- return gTransientHeaps;
- }
-
- ComPtr<gfx::IPipelineState> m_pipelineState;
- ComPtr<gfx::IBufferResource> m_vertexBuffer;
+ ComPtr<IRenderPipeline> m_renderPipeline;
+ ComPtr<IBuffer> m_vertexBuffer;
/// A counter such that we can make aftermath dump file names unique
std::atomic<int> m_uniqueId = 0;
+
+ Slang::Result initialize()
+ {
+ // Defer shader debug information callbacks until an actual GPU crash dump
+ // is generated. Increases memory footprint.
+ const uint32_t aftermathFeatureFlags =
+ GFSDK_Aftermath_GpuCrashDumpFeatureFlags_DeferDebugInfoCallbacks;
+
+ // As per docs must be called before any device is created
+ GFSDK_Aftermath_EnableGpuCrashDumps(
+ GFSDK_Aftermath_Version_API,
+ GFSDK_Aftermath_GpuCrashDumpWatchedApiFlags_DX |
+ GFSDK_Aftermath_GpuCrashDumpWatchedApiFlags_Vulkan,
+ aftermathFeatureFlags,
+ _crashCallback,
+ _debugInfoCallback,
+ _crashDescriptionCallback,
+ _markerCallback,
+ this);
+
+ SLANG_RETURN_ON_FAIL(initializeBase("autodiff-texture", 1024, 768, DeviceType::Default));
+
+
+ // We will create objects needed to configure the "input assembler"
+ // (IA) stage of the pipeline.
+ //
+ // First, we create an input layout:
+ //
+ InputElementDesc inputElements[] = {
+ {"POSITION", 0, Format::RGB32Float, offsetof(Vertex, position)},
+ {"COLOR", 0, Format::RGB32Float, offsetof(Vertex, color)},
+ };
+ auto inputLayout = gDevice->createInputLayout(sizeof(Vertex), &inputElements[0], 2);
+ if (!inputLayout)
+ return SLANG_FAIL;
+
+ // Next we allocate a vertex buffer for our pre-initialized
+ // vertex data.
+ //
+ BufferDesc vertexBufferDesc;
+ vertexBufferDesc.size = kVertexCount * sizeof(Vertex);
+ vertexBufferDesc.usage = BufferUsage::VertexBuffer;
+ vertexBufferDesc.defaultState = ResourceState::VertexBuffer;
+ m_vertexBuffer = gDevice->createBuffer(vertexBufferDesc, &kVertexData[0]);
+ if (!m_vertexBuffer)
+ return SLANG_FAIL;
+
+ // Now we will use our `loadShaderProgram` function to load
+ // the code from `shaders.slang` into the graphics API.
+ //
+ ComPtr<IShaderProgram> shaderProgram;
+ SLANG_RETURN_ON_FAIL(loadShaderProgram(device, shaderProgram.writeRef()));
+
+ // Following the D3D12/Vulkan style of API, we need a pipeline state object
+ // (PSO) to encapsulate the configuration of the overall graphics pipeline.
+ //
+ ColorTargetDesc colorTarget;
+ colorTarget.format = Format::RGBA8Unorm;
+ RenderPipelineDesc desc;
+ desc.inputLayout = inputLayout;
+ desc.program = shaderProgram;
+ desc.targetCount = 1;
+ desc.targets = &colorTarget;
+ desc.depthStencil.depthTestEnable = false;
+ desc.depthStencil.depthWriteEnable = false;
+ desc.primitiveTopology = PrimitiveTopology::TriangleList;
+ auto pipelineState = gDevice->createRenderPipeline(desc);
+ if (!pipelineState)
+ return SLANG_FAIL;
+
+ m_renderPipeline = pipelineState;
+
+ return SLANG_OK;
+ }
};
void AftermathCrashExample::diagnoseIfNeeded(slang::IBlob* diagnosticsBlob)
@@ -264,12 +325,10 @@ static SlangResult _addCompileProducts(
return SLANG_OK;
}
-gfx::Result AftermathCrashExample::loadShaderProgram(
- gfx::IDevice* device,
- gfx::IShaderProgram** outProgram)
+Result AftermathCrashExample::loadShaderProgram(IDevice* device, IShaderProgram** outProgram)
{
ComPtr<slang::ISession> slangSession;
- slangSession = device->getSlangSession();
+ slangSession = gDevice->getSlangSession();
// This is a little bit of a work around.
//
@@ -423,9 +482,9 @@ gfx::Result AftermathCrashExample::loadShaderProgram(
// to extract compiled kernel code and load it into the API-specific
// program representation.
//
- gfx::IShaderProgram::Desc programDesc = {};
+ ShaderProgramDesc programDesc = {};
programDesc.slangGlobalScope = linkedProgram;
- SLANG_RETURN_ON_FAIL(device->createProgram(programDesc, outProgram));
+ SLANG_RETURN_ON_FAIL(gDevice->createShaderProgram(programDesc, outProgram));
return SLANG_OK;
}
@@ -465,129 +524,60 @@ static void GFSDK_AFTERMATH_CALL _markerCallback(
markerSize);
}
-Slang::Result AftermathCrashExample::initialize()
+void AftermathCrashExample::renderFrame(ITexture* texture)
{
- // Defer shader debug information callbacks until an actual GPU crash dump
- // is generated. Increases memory footprint.
- const uint32_t aftermathFeatureFlags =
- GFSDK_Aftermath_GpuCrashDumpFeatureFlags_DeferDebugInfoCallbacks;
-
- // As per docs must be called before any device is created
- GFSDK_Aftermath_EnableGpuCrashDumps(
- GFSDK_Aftermath_Version_API,
- GFSDK_Aftermath_GpuCrashDumpWatchedApiFlags_DX |
- GFSDK_Aftermath_GpuCrashDumpWatchedApiFlags_Vulkan,
- aftermathFeatureFlags,
- _crashCallback,
- _debugInfoCallback,
- _crashDescriptionCallback,
- _markerCallback,
- this);
-
- // Set to a specific render API as needed. Valid values are...
- //
- // * gfx::DeviceType::Default
- // * gfx::DeviceType::Vulkan
- // * gfx::DeviceType::DirectX12
- // * gfx::DeviceType::DirectX11
+ auto commandEncoder = gQueue->createCommandEncoder();
- const gfx::DeviceType deviceType = gfx::DeviceType::Default;
+ ComPtr<ITextureView> textureView = gDevice->createTextureView(texture, {});
+ RenderPassColorAttachment colorAttachment = {};
+ colorAttachment.view = textureView;
+ colorAttachment.loadOp = LoadOp::Clear;
- initializeBase("aftermath-crash-example", 1024, 768, deviceType);
+ RenderPassDesc renderPass = {};
+ renderPass.colorAttachments = &colorAttachment;
+ renderPass.colorAttachmentCount = 1;
- auto device = getDevice();
+ auto renderEncoder = commandEncoder->beginRenderPass(renderPass);
- // We will create objects needed to configur the "input assembler"
- // (IA) stage of the D3D pipeline.
- //
- // First, we create an input layout:
- //
- InputElementDesc inputElements[] = {
- {"POSITION", 0, Format::R32G32B32_FLOAT, offsetof(Vertex, position)},
- {"COLOR", 0, Format::R32G32B32_FLOAT, offsetof(Vertex, color)},
- };
- auto inputLayout = gDevice->createInputLayout(sizeof(Vertex), &inputElements[0], 2);
- if (!inputLayout)
- return SLANG_FAIL;
-
- // Next we allocate a vertex buffer for our pre-initialized
- // vertex data.
- //
- IBufferResource::Desc vertexBufferDesc;
- vertexBufferDesc.type = IResource::Type::Buffer;
- vertexBufferDesc.sizeInBytes = kVertexCount * sizeof(Vertex);
- vertexBufferDesc.defaultState = ResourceState::VertexBuffer;
- m_vertexBuffer = device->createBufferResource(vertexBufferDesc, &kVertexData[0]);
- if (!m_vertexBuffer)
- return SLANG_FAIL;
-
- // Now we will use our `loadShaderProgram` function to load
- // the code from `shaders.slang` into the graphics API.
- //
- ComPtr<IShaderProgram> shaderProgram;
- SLANG_RETURN_ON_FAIL(loadShaderProgram(device, shaderProgram.writeRef()));
-
- // Following the D3D12/Vulkan style of API, we need a pipeline state object
- // (PSO) to encapsulate the configuration of the overall graphics pipeline.
- //
- GraphicsPipelineStateDesc desc;
- desc.inputLayout = inputLayout;
- desc.program = shaderProgram;
- desc.framebufferLayout = getFrameBufferLayout();
- auto pipelineState = device->createGraphicsPipelineState(desc);
- if (!pipelineState)
- return SLANG_FAIL;
-
- m_pipelineState = pipelineState;
-
- return SLANG_OK;
-}
-
-void AftermathCrashExample::renderFrame(int frameBufferIndex)
-{
- ComPtr<ICommandBuffer> commandBuffer =
- getTransientHeaps()[frameBufferIndex]->createCommandBuffer();
- auto renderEncoder =
- commandBuffer->encodeRenderCommands(gRenderPass, getFrameBuffers()[frameBufferIndex]);
-
- gfx::Viewport viewport = {};
- viewport.maxZ = 1.0f;
- viewport.extentX = (float)windowWidth;
- viewport.extentY = (float)windowHeight;
- renderEncoder->setViewportAndScissor(viewport);
-
- auto rootObject = renderEncoder->bindPipeline(m_pipelineState);
-
- auto deviceInfo = getDevice()->getDeviceInfo();
+ RenderState renderState = {};
+ renderState.viewports[0] = Viewport::fromSize(windowWidth, windowHeight);
+ renderState.viewportCount = 1;
+ renderState.scissorRects[0] = ScissorRect::fromSize(windowWidth, windowHeight);
+ renderState.scissorRectCount = 1;
+ auto rootObject = renderEncoder->bindPipeline(m_renderPipeline);
ShaderCursor rootCursor(rootObject);
- rootCursor["Uniforms"]["modelViewProjection"].setData(
- deviceInfo.identityProjectionMatrix,
- sizeof(float) * 16);
+ rootCursor["Uniforms"]["modelViewProjection"].setData(kIdentity, sizeof(float) * 16);
// We are going to extra efforts to create a shader that we know will time
// out because we *want* a GPU "crash", such we can capture via nsight aftermath.
- // The failCount is just a number that is large enought to make things take too long.
+ // The failCount is just a number that is large enough to make things take too long.
int32_t failCount = 0x3fffffff;
rootCursor["Uniforms"]["failCount"].setData(&failCount, sizeof(failCount));
// We also need to set up a few pieces of fixed-function pipeline
// state that are not bound by the pipeline state above.
//
- renderEncoder->setVertexBuffer(0, m_vertexBuffer);
- renderEncoder->setPrimitiveTopology(PrimitiveTopology::TriangleList);
+ renderState.vertexBuffers[0] = m_vertexBuffer;
+ renderState.vertexBufferCount = 1;
+ renderEncoder->setRenderState(renderState);
// Finally, we are ready to issue a draw call for a single triangle.
//
- renderEncoder->draw(3);
- renderEncoder->endEncoding();
- commandBuffer->close();
- getQueue()->executeCommandBuffer(commandBuffer);
+ DrawArguments drawArgs = {};
+ drawArgs.vertexCount = 3;
+ renderEncoder->draw(drawArgs);
- // With that, we are done drawing for one frame, and ready for the next.
- //
- getSwapChain()->present();
+ renderEncoder->end();
+ gQueue->submit(commandEncoder->finish());
+
+ if (!isTestMode())
+ {
+ // With that, we are done drawing for one frame, and ready for the next.
+ //
+ gSurface()->present();
+ }
// If the id changes means we have a capture and so can quit.
// On D3D11, the first present *doesn't* appear to crash.
diff --git a/examples/platform-test/main.cpp b/examples/platform-test/main.cpp
index 865e4eab7..7949d90c1 100644
--- a/examples/platform-test/main.cpp
+++ b/examples/platform-test/main.cpp
@@ -1,62 +1,91 @@
+#include "core/slang-basic.h"
#include "examples/example-base/example-base.h"
#include "platform/window.h"
+#include "slang-com-ptr.h"
+#include "slang-rhi.h"
#include "slang.h"
-using namespace gfx;
+#include <cstdio>
+
+using namespace rhi;
using namespace Slang;
struct PlatformTest : public WindowedAppBase
{
- void onSizeChanged() { printf("onSizeChanged\n"); }
+ void onSizeChanged()
+ {
+ printf("onSizeChanged\n");
+ fflush(stdout);
+ }
- void onFocus() { printf("onFocus\n"); }
+ void onFocus()
+ {
+ printf("onFocus\n");
+ fflush(stdout);
+ }
- void onLostFocus() { printf("onLostFocus\n"); }
+ void onLostFocus()
+ {
+ printf("onLostFocus\n");
+ fflush(stdout);
+ }
void onKeyDown(platform::KeyEventArgs args)
{
printf("onKeyDown(key=0x%02x, buttons=0x%02x)\n", (uint32_t)args.key, args.buttons);
+ fflush(stdout);
}
void onKeyUp(platform::KeyEventArgs args)
{
- printf("okKeyUp(key=0x%02x, buttons=0x%02x)\n", (uint32_t)args.key, args.buttons);
+ printf("onKeyUp(key=0x%02x, buttons=0x%02x)\n", (uint32_t)args.key, args.buttons);
+ fflush(stdout);
}
void onKeyPress(platform::KeyEventArgs args)
{
printf("onKeyPress(keyChar=0x%02x)\n", args.keyChar);
+ fflush(stdout);
}
void onMouseMove(platform::MouseEventArgs args)
{
- printf(
- "onMouseMove(x=%d, y=%d, delta=%d, buttons=0x%02x\n",
- args.x,
- args.y,
- args.delta,
- args.buttons);
+ // Throttle mouse move events using a simple counter
+ static int mouseMoveCounter = 0;
+ mouseMoveCounter++;
+ if (mouseMoveCounter % 50 == 0) // Only print every 50th mouse move event
+ {
+ printf(
+ "onMouseMove(x=%d, y=%d, delta=%d, buttons=0x%02x)\n",
+ args.x,
+ args.y,
+ args.delta,
+ args.buttons);
+ fflush(stdout);
+ }
}
void onMouseDown(platform::MouseEventArgs args)
{
printf(
- "onMouseDown(x=%d, y=%d, delta=%d, buttons=0x%02x\n",
+ "onMouseDown(x=%d, y=%d, delta=%d, buttons=0x%02x)\n",
args.x,
args.y,
args.delta,
args.buttons);
+ fflush(stdout);
}
void onMouseUp(platform::MouseEventArgs args)
{
printf(
- "onMouseUp(x=%d, y=%d, delta=%d, buttons=0x%02x\n",
+ "onMouseUp(x=%d, y=%d, delta=%d, buttons=0x%02x)\n",
args.x,
args.y,
args.delta,
args.buttons);
+ fflush(stdout);
}
void onMouseWheel(platform::MouseEventArgs args)
@@ -67,6 +96,7 @@ struct PlatformTest : public WindowedAppBase
args.y,
args.delta,
args.buttons);
+ fflush(stdout);
}
Slang::Result initialize()
@@ -77,6 +107,9 @@ struct PlatformTest : public WindowedAppBase
SLANG_ASSERT(isTestMode() || gWindow);
if (gWindow)
{
+ printf("Setting up event handlers...\n");
+ fflush(stdout);
+
gWindow->events.sizeChanged = [this]() { onSizeChanged(); };
gWindow->events.focus = [this]() { onFocus(); };
gWindow->events.lostFocus = [this]() { onLostFocus(); };
@@ -90,33 +123,47 @@ struct PlatformTest : public WindowedAppBase
gWindow->events.mouseUp = [this](const platform::MouseEventArgs& e) { onMouseUp(e); };
gWindow->events.mouseWheel = [this](const platform::MouseEventArgs& e)
{ onMouseWheel(e); };
+ printf("Event handlers set up successfully.\n");
+ }
+ else
+ {
+ printf("No window available for event setup.\n");
+ fflush(stdout);
}
return SLANG_OK;
}
- virtual void renderFrame(int frameBufferIndex) override
+ virtual void renderFrame(ITexture* texture) override
{
- ComPtr<ICommandBuffer> commandBuffer =
- gTransientHeaps[frameBufferIndex]->createCommandBuffer();
-
- auto renderEncoder =
- commandBuffer->encodeRenderCommands(gRenderPass, gFramebuffers[frameBufferIndex]);
-
- gfx::Viewport viewport = {};
- viewport.maxZ = 1.0f;
- viewport.extentX = (float)windowWidth;
- viewport.extentY = (float)windowHeight;
- renderEncoder->setViewportAndScissor(viewport);
-
- renderEncoder->endEncoding();
- commandBuffer->close();
- gQueue->executeCommandBuffer(commandBuffer);
-
- // We may not have a swapchain if we're running in test mode
- SLANG_ASSERT(isTestMode() || gSwapchain);
- if (gSwapchain)
- gSwapchain->present();
+ auto commandEncoder = gQueue->createCommandEncoder();
+
+ ComPtr<ITextureView> textureView = gDevice->createTextureView(texture, {});
+ RenderPassColorAttachment colorAttachment = {};
+ colorAttachment.view = textureView;
+ colorAttachment.loadOp = LoadOp::Clear;
+
+ RenderPassDesc renderPass = {};
+ renderPass.colorAttachments = &colorAttachment;
+ renderPass.colorAttachmentCount = 1;
+
+ auto renderEncoder = commandEncoder->beginRenderPass(renderPass);
+
+ RenderState renderState = {};
+ renderState.viewports[0] = Viewport::fromSize(windowWidth, windowHeight);
+ renderState.viewportCount = 1;
+ renderState.scissorRects[0] = ScissorRect::fromSize(windowWidth, windowHeight);
+ renderState.scissorRectCount = 1;
+
+ renderEncoder->setRenderState(renderState);
+
+ renderEncoder->end();
+ gQueue->submit(commandEncoder->finish());
+
+ if (!isTestMode())
+ {
+ gSurface->present();
+ }
}
};
diff --git a/examples/ray-tracing-pipeline/main.cpp b/examples/ray-tracing-pipeline/main.cpp
index a3d468db1..19b74011a 100644
--- a/examples/ray-tracing-pipeline/main.cpp
+++ b/examples/ray-tracing-pipeline/main.cpp
@@ -1,18 +1,19 @@
// main.cpp
// This file implements an example of hardware ray-tracing using
-// Slang shaders and the `gfx` graphics API.
+// Slang shaders and the `slang-rhi` graphics API.
#include "core/slang-basic.h"
#include "examples/example-base/example-base.h"
-#include "gfx-util/shader-cursor.h"
#include "platform/vector-math.h"
#include "platform/window.h"
#include "slang-com-ptr.h"
-#include "slang-gfx.h"
+#include "slang-rhi.h"
+#include "slang-rhi/acceleration-structure-utils.h"
+#include "slang-rhi/shader-cursor.h"
#include "slang.h"
-using namespace gfx;
+using namespace rhi;
using namespace Slang;
static const ExampleResources resourceBase("ray-tracing-pipeline");
@@ -148,10 +149,10 @@ struct RayTracing : public WindowedAppBase
}
// Load and compile shader code from souce.
- gfx::Result loadShaderProgram(
- gfx::IDevice* device,
+ Result loadShaderProgram(
+ IDevice* device,
bool isRayTracingPipeline,
- gfx::IShaderProgram** outProgram)
+ IShaderProgram** outProgram)
{
ComPtr<slang::ISession> slangSession;
slangSession = device->getSlangSession();
@@ -205,29 +206,25 @@ struct RayTracing : public WindowedAppBase
printEntrypointHashes(componentTypes.getCount() - 1, 1, linkedProgram);
}
- gfx::IShaderProgram::Desc programDesc = {};
+ ShaderProgramDesc programDesc = {};
programDesc.slangGlobalScope = linkedProgram;
- SLANG_RETURN_ON_FAIL(device->createProgram(programDesc, outProgram));
+ SLANG_RETURN_ON_FAIL(device->createShaderProgram(programDesc, outProgram));
return SLANG_OK;
}
- ComPtr<gfx::IPipelineState> gPresentPipelineState;
- ComPtr<gfx::IPipelineState> gRenderPipelineState;
- ComPtr<gfx::IBufferResource> gFullScreenVertexBuffer;
- ComPtr<gfx::IBufferResource> gVertexBuffer;
- ComPtr<gfx::IBufferResource> gIndexBuffer;
- ComPtr<gfx::IBufferResource> gPrimitiveBuffer;
- ComPtr<gfx::IBufferResource> gTransformBuffer;
- ComPtr<gfx::IResourceView> gPrimitiveBufferSRV;
- ComPtr<gfx::IBufferResource> gInstanceBuffer;
- ComPtr<gfx::IBufferResource> gBLASBuffer;
- ComPtr<gfx::IAccelerationStructure> gBLAS;
- ComPtr<gfx::IBufferResource> gTLASBuffer;
- ComPtr<gfx::IAccelerationStructure> gTLAS;
- ComPtr<gfx::ITextureResource> gResultTexture;
- ComPtr<gfx::IResourceView> gResultTextureUAV;
- ComPtr<gfx::IShaderTable> gShaderTable;
+ ComPtr<IRenderPipeline> gPresentPipeline;
+ ComPtr<IRayTracingPipeline> gRenderPipeline;
+ ComPtr<IBuffer> gFullScreenVertexBuffer;
+ ComPtr<IBuffer> gVertexBuffer;
+ ComPtr<IBuffer> gIndexBuffer;
+ ComPtr<IBuffer> gPrimitiveBuffer;
+ ComPtr<IBuffer> gTransformBuffer;
+ ComPtr<IBuffer> gInstanceBuffer;
+ ComPtr<IAccelerationStructure> gBLAS;
+ ComPtr<IAccelerationStructure> gTLAS;
+ ComPtr<ITexture> gResultTexture;
+ ComPtr<IShaderTable> gShaderTable;
uint64_t lastTime = 0;
@@ -310,233 +307,199 @@ struct RayTracing : public WindowedAppBase
gWindow->events.keyUp = [this](const platform::KeyEventArgs& e) { onKeyUp(e); };
}
- IBufferResource::Desc vertexBufferDesc;
- vertexBufferDesc.type = IResource::Type::Buffer;
- vertexBufferDesc.sizeInBytes = kVertexCount * sizeof(Vertex);
- vertexBufferDesc.defaultState = ResourceState::ShaderResource;
- gVertexBuffer = gDevice->createBufferResource(vertexBufferDesc, &kVertexData[0]);
+ BufferDesc vertexBufferDesc;
+ vertexBufferDesc.size = kVertexCount * sizeof(Vertex);
+ vertexBufferDesc.usage = BufferUsage::AccelerationStructureBuildInput;
+ vertexBufferDesc.defaultState = ResourceState::AccelerationStructureBuildInput;
+ gVertexBuffer = gDevice->createBuffer(vertexBufferDesc, &kVertexData[0]);
if (!gVertexBuffer)
return SLANG_FAIL;
- IBufferResource::Desc indexBufferDesc;
- indexBufferDesc.type = IResource::Type::Buffer;
- indexBufferDesc.sizeInBytes = kIndexCount * sizeof(int32_t);
- indexBufferDesc.defaultState = ResourceState::ShaderResource;
- gIndexBuffer = gDevice->createBufferResource(indexBufferDesc, &kIndexData[0]);
+ BufferDesc indexBufferDesc;
+ indexBufferDesc.size = kIndexCount * sizeof(int32_t);
+ indexBufferDesc.usage = BufferUsage::AccelerationStructureBuildInput;
+ indexBufferDesc.defaultState = ResourceState::AccelerationStructureBuildInput;
+ gIndexBuffer = gDevice->createBuffer(indexBufferDesc, &kIndexData[0]);
if (!gIndexBuffer)
return SLANG_FAIL;
- IBufferResource::Desc primitiveBufferDesc;
- primitiveBufferDesc.type = IResource::Type::Buffer;
- primitiveBufferDesc.sizeInBytes = kPrimitiveCount * sizeof(Primitive);
+ BufferDesc primitiveBufferDesc;
+ primitiveBufferDesc.size = kPrimitiveCount * sizeof(Primitive);
primitiveBufferDesc.elementSize = sizeof(Primitive);
+ primitiveBufferDesc.usage = BufferUsage::ShaderResource;
primitiveBufferDesc.defaultState = ResourceState::ShaderResource;
- gPrimitiveBuffer = gDevice->createBufferResource(primitiveBufferDesc, &kPrimitiveData[0]);
+ gPrimitiveBuffer = gDevice->createBuffer(primitiveBufferDesc, &kPrimitiveData[0]);
if (!gPrimitiveBuffer)
return SLANG_FAIL;
- IResourceView::Desc primitiveSRVDesc = {};
- primitiveSRVDesc.format = Format::Unknown;
- primitiveSRVDesc.type = IResourceView::Type::ShaderResource;
- gPrimitiveBufferSRV =
- gDevice->createBufferView(gPrimitiveBuffer, nullptr, primitiveSRVDesc);
-
- IBufferResource::Desc transformBufferDesc;
- transformBufferDesc.type = IResource::Type::Buffer;
- transformBufferDesc.sizeInBytes = sizeof(float) * 12;
- transformBufferDesc.defaultState = ResourceState::ShaderResource;
+ BufferDesc transformBufferDesc;
+ transformBufferDesc.size = sizeof(float) * 12;
+ transformBufferDesc.usage = BufferUsage::AccelerationStructureBuildInput;
+ transformBufferDesc.defaultState = ResourceState::AccelerationStructureBuildInput;
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};
- gTransformBuffer = gDevice->createBufferResource(transformBufferDesc, &transformData);
+ gTransformBuffer = gDevice->createBuffer(transformBufferDesc, &transformData);
if (!gTransformBuffer)
return SLANG_FAIL;
// 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 = gIndexBuffer->getDeviceAddress();
- geomDesc.content.triangles.indexFormat = Format::R32_UINT;
- geomDesc.content.triangles.vertexCount = kVertexCount;
- geomDesc.content.triangles.vertexData = gVertexBuffer->getDeviceAddress();
- geomDesc.content.triangles.vertexFormat = Format::R32G32B32_FLOAT;
- geomDesc.content.triangles.vertexStride = sizeof(Vertex);
- geomDesc.content.triangles.transform3x4 = gTransformBuffer->getDeviceAddress();
- accelerationStructureBuildInputs.geometryDescs = &geomDesc;
+ AccelerationStructureBuildInput buildInput = {};
+ buildInput.type = AccelerationStructureBuildInputType::Triangles;
+ buildInput.triangles.vertexBuffers[0] = gVertexBuffer;
+ buildInput.triangles.vertexBufferCount = 1;
+ buildInput.triangles.vertexFormat = Format::RGB32Float;
+ buildInput.triangles.vertexCount = kVertexCount;
+ buildInput.triangles.vertexStride = sizeof(Vertex);
+ buildInput.triangles.indexBuffer = gIndexBuffer;
+ buildInput.triangles.indexFormat = IndexFormat::Uint32;
+ buildInput.triangles.indexCount = kIndexCount;
+ buildInput.triangles.preTransformBuffer = gTransformBuffer;
+ buildInput.triangles.flags = AccelerationStructureGeometryFlags::Opaque;
+
+ AccelerationStructureBuildDesc buildDesc = {};
+ buildDesc.inputs = &buildInput;
+ buildDesc.inputCount = 1;
+ buildDesc.flags = AccelerationStructureBuildFlags::AllowCompaction;
// Query buffer size for acceleration structure build.
- SLANG_RETURN_ON_FAIL(gDevice->getAccelerationStructurePrebuildInfo(
- accelerationStructureBuildInputs,
- &accelerationStructurePrebuildInfo));
+ AccelerationStructureSizes sizes;
+ SLANG_RETURN_ON_FAIL(gDevice->getAccelerationStructureSizes(buildDesc, &sizes));
+
// 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 = gDevice->createBufferResource(asDraftBufferDesc);
- if (!draftBuffer)
- return SLANG_FAIL;
- IBufferResource::Desc scratchBufferDesc;
- scratchBufferDesc.type = IResource::Type::Buffer;
+ BufferDesc scratchBufferDesc;
+ scratchBufferDesc.usage = BufferUsage::UnorderedAccess;
scratchBufferDesc.defaultState = ResourceState::UnorderedAccess;
- scratchBufferDesc.sizeInBytes =
- (size_t)accelerationStructurePrebuildInfo.scratchDataSize;
- ComPtr<IBufferResource> scratchBuffer =
- gDevice->createBufferResource(scratchBufferDesc);
+ scratchBufferDesc.size = sizes.scratchSize;
+ ComPtr<IBuffer> scratchBuffer = gDevice->createBuffer(scratchBufferDesc);
if (!scratchBuffer)
return SLANG_FAIL;
// Build acceleration structure.
ComPtr<IQueryPool> compactedSizeQuery;
- IQueryPool::Desc queryPoolDesc;
+ QueryPoolDesc queryPoolDesc;
queryPoolDesc.count = 1;
queryPoolDesc.type = QueryType::AccelerationStructureCompactedSize;
SLANG_RETURN_ON_FAIL(
gDevice->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;
+ AccelerationStructureDesc draftCreateDesc;
+ draftCreateDesc.size = sizes.accelerationStructureSize;
SLANG_RETURN_ON_FAIL(
gDevice->createAccelerationStructure(draftCreateDesc, draftAS.writeRef()));
compactedSizeQuery->reset();
- auto commandBuffer = gTransientHeaps[0]->createCommandBuffer();
- auto encoder = commandBuffer->encodeRayTracingCommands();
- IAccelerationStructure::BuildDesc buildDesc = {};
- buildDesc.dest = draftAS;
- buildDesc.inputs = accelerationStructureBuildInputs;
- buildDesc.scratchData = scratchBuffer->getDeviceAddress();
+ auto commandEncoder = gQueue->createCommandEncoder();
AccelerationStructureQueryDesc compactedSizeQueryDesc = {};
compactedSizeQueryDesc.queryPool = compactedSizeQuery;
compactedSizeQueryDesc.queryType = QueryType::AccelerationStructureCompactedSize;
- encoder->buildAccelerationStructure(buildDesc, 1, &compactedSizeQueryDesc);
- encoder->endEncoding();
- commandBuffer->close();
- gQueue->executeCommandBuffer(commandBuffer);
+ commandEncoder->buildAccelerationStructure(
+ buildDesc,
+ draftAS,
+ nullptr,
+ scratchBuffer,
+ 1,
+ &compactedSizeQueryDesc);
+ gQueue->submit(commandEncoder->finish());
gQueue->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;
- gBLASBuffer = gDevice->createBufferResource(asBufferDesc);
- IAccelerationStructure::CreateDesc createDesc;
- createDesc.buffer = gBLASBuffer;
- createDesc.kind = IAccelerationStructure::Kind::BottomLevel;
- createDesc.offset = 0;
- createDesc.size = (size_t)compactedSize;
+ AccelerationStructureDesc createDesc;
+ createDesc.size = compactedSize;
gDevice->createAccelerationStructure(createDesc, gBLAS.writeRef());
- commandBuffer = gTransientHeaps[0]->createCommandBuffer();
- encoder = commandBuffer->encodeRayTracingCommands();
- encoder->copyAccelerationStructure(
+ commandEncoder = gQueue->createCommandEncoder();
+ commandEncoder->copyAccelerationStructure(
gBLAS,
draftAS,
AccelerationStructureCopyMode::Compact);
- encoder->endEncoding();
- commandBuffer->close();
- gQueue->executeCommandBuffer(commandBuffer);
+ gQueue->submit(commandEncoder->finish());
gQueue->waitOnHost();
}
// Build top level acceleration structure.
{
- List<IAccelerationStructure::InstanceDesc> instanceDescs;
- instanceDescs.setCount(1);
- instanceDescs[0].accelerationStructure = gBLAS->getDeviceAddress();
- instanceDescs[0].flags =
- IAccelerationStructure::GeometryInstanceFlags::TriangleFacingCullDisable;
- instanceDescs[0].instanceContributionToHitGroupIndex = 0;
- instanceDescs[0].instanceID = 0;
- instanceDescs[0].instanceMask = 0xFF;
+ AccelerationStructureInstanceDescType nativeInstanceDescType =
+ getAccelerationStructureInstanceDescType(gDevice);
+ Size nativeInstanceDescSize =
+ getAccelerationStructureInstanceDescSize(nativeInstanceDescType);
+
+ std::vector<AccelerationStructureInstanceDescGeneric> instanceDescs;
+ instanceDescs.resize(1);
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);
+ instanceDescs[0].instanceID = 0;
+ instanceDescs[0].instanceMask = 0xFF;
+ instanceDescs[0].instanceContributionToHitGroupIndex = 0;
+ instanceDescs[0].flags = AccelerationStructureInstanceFlags::TriangleFacingCullDisable;
+ instanceDescs[0].accelerationStructure = gBLAS->getHandle();
+
+ std::vector<uint8_t> nativeInstanceDescs(instanceDescs.size() * nativeInstanceDescSize);
+ convertAccelerationStructureInstanceDescs(
+ instanceDescs.size(),
+ nativeInstanceDescType,
+ nativeInstanceDescs.data(),
+ nativeInstanceDescSize,
+ instanceDescs.data(),
+ sizeof(AccelerationStructureInstanceDescGeneric));
+
+ BufferDesc instanceBufferDesc;
+ instanceBufferDesc.size =
+ instanceDescs.size() * sizeof(AccelerationStructureInstanceDescGeneric);
+ instanceBufferDesc.usage = BufferUsage::ShaderResource;
instanceBufferDesc.defaultState = ResourceState::ShaderResource;
- gInstanceBuffer =
- gDevice->createBufferResource(instanceBufferDesc, instanceDescs.getBuffer());
+ gInstanceBuffer = gDevice->createBuffer(instanceBufferDesc, nativeInstanceDescs.data());
if (!gInstanceBuffer)
return SLANG_FAIL;
- IAccelerationStructure::BuildInputs accelerationStructureBuildInputs = {};
- IAccelerationStructure::PrebuildInfo accelerationStructurePrebuildInfo = {};
- accelerationStructureBuildInputs.descCount = 1;
- accelerationStructureBuildInputs.kind = IAccelerationStructure::Kind::TopLevel;
- accelerationStructureBuildInputs.instanceDescs = gInstanceBuffer->getDeviceAddress();
+ AccelerationStructureBuildInput buildInput = {};
+ buildInput.type = AccelerationStructureBuildInputType::Instances;
+ buildInput.instances.instanceBuffer = gInstanceBuffer;
+ buildInput.instances.instanceCount = 1;
+ buildInput.instances.instanceStride = nativeInstanceDescSize;
+
+ AccelerationStructureBuildDesc buildDesc = {};
+ buildDesc.inputs = &buildInput;
+ buildDesc.inputCount = 1;
// Query buffer size for acceleration structure build.
- SLANG_RETURN_ON_FAIL(gDevice->getAccelerationStructurePrebuildInfo(
- accelerationStructureBuildInputs,
- &accelerationStructurePrebuildInfo));
-
- IBufferResource::Desc asBufferDesc;
- asBufferDesc.type = IResource::Type::Buffer;
- asBufferDesc.defaultState = ResourceState::AccelerationStructure;
- asBufferDesc.sizeInBytes = (size_t)accelerationStructurePrebuildInfo.resultDataMaxSize;
- gTLASBuffer = gDevice->createBufferResource(asBufferDesc);
-
- IBufferResource::Desc scratchBufferDesc;
- scratchBufferDesc.type = IResource::Type::Buffer;
+ AccelerationStructureSizes sizes;
+ SLANG_RETURN_ON_FAIL(gDevice->getAccelerationStructureSizes(buildDesc, &sizes));
+
+ BufferDesc scratchBufferDesc;
+ scratchBufferDesc.usage = BufferUsage::UnorderedAccess;
scratchBufferDesc.defaultState = ResourceState::UnorderedAccess;
- scratchBufferDesc.sizeInBytes =
- (size_t)accelerationStructurePrebuildInfo.scratchDataSize;
- ComPtr<IBufferResource> scratchBuffer =
- gDevice->createBufferResource(scratchBufferDesc);
-
- IAccelerationStructure::CreateDesc createDesc;
- createDesc.buffer = gTLASBuffer;
- createDesc.kind = IAccelerationStructure::Kind::TopLevel;
- createDesc.offset = 0;
- createDesc.size = (size_t)accelerationStructurePrebuildInfo.resultDataMaxSize;
+ scratchBufferDesc.size = sizes.scratchSize;
+ ComPtr<IBuffer> scratchBuffer = gDevice->createBuffer(scratchBufferDesc);
+
+ AccelerationStructureDesc createDesc;
+ createDesc.size = sizes.accelerationStructureSize;
SLANG_RETURN_ON_FAIL(
gDevice->createAccelerationStructure(createDesc, gTLAS.writeRef()));
- auto commandBuffer = gTransientHeaps[0]->createCommandBuffer();
- auto encoder = commandBuffer->encodeRayTracingCommands();
- IAccelerationStructure::BuildDesc buildDesc = {};
- buildDesc.dest = gTLAS;
- buildDesc.inputs = accelerationStructureBuildInputs;
- buildDesc.scratchData = scratchBuffer->getDeviceAddress();
- encoder->buildAccelerationStructure(buildDesc, 0, nullptr);
- encoder->endEncoding();
- commandBuffer->close();
- gQueue->executeCommandBuffer(commandBuffer);
+ auto commandEncoder = gQueue->createCommandEncoder();
+ commandEncoder
+ ->buildAccelerationStructure(buildDesc, gTLAS, nullptr, scratchBuffer, 0, nullptr);
+ gQueue->submit(commandEncoder->finish());
gQueue->waitOnHost();
}
- IBufferResource::Desc fullScreenVertexBufferDesc;
- fullScreenVertexBufferDesc.type = IResource::Type::Buffer;
- fullScreenVertexBufferDesc.sizeInBytes =
+ BufferDesc fullScreenVertexBufferDesc;
+ fullScreenVertexBufferDesc.size =
FullScreenTriangle::kVertexCount * sizeof(FullScreenTriangle::Vertex);
+ fullScreenVertexBufferDesc.usage = BufferUsage::VertexBuffer;
fullScreenVertexBufferDesc.defaultState = ResourceState::VertexBuffer;
- gFullScreenVertexBuffer = gDevice->createBufferResource(
- fullScreenVertexBufferDesc,
- &FullScreenTriangle::kVertices[0]);
+ gFullScreenVertexBuffer =
+ gDevice->createBuffer(fullScreenVertexBufferDesc, &FullScreenTriangle::kVertices[0]);
if (!gFullScreenVertexBuffer)
return SLANG_FAIL;
InputElementDesc inputElements[] = {
- {"POSITION", 0, Format::R32G32_FLOAT, offsetof(FullScreenTriangle::Vertex, position)},
+ {"POSITION", 0, Format::RG32Float, offsetof(FullScreenTriangle::Vertex, position)},
};
auto inputLayout = gDevice->createInputLayout(
sizeof(FullScreenTriangle::Vertex),
@@ -547,19 +510,25 @@ struct RayTracing : public WindowedAppBase
ComPtr<IShaderProgram> shaderProgram;
SLANG_RETURN_ON_FAIL(loadShaderProgram(gDevice, false, shaderProgram.writeRef()));
- GraphicsPipelineStateDesc desc;
+ ColorTargetDesc colorTarget;
+ colorTarget.format = Format::RGBA16Float;
+ RenderPipelineDesc desc;
desc.inputLayout = inputLayout;
desc.program = shaderProgram;
- desc.framebufferLayout = gFramebufferLayout;
- gPresentPipelineState = gDevice->createGraphicsPipelineState(desc);
- if (!gPresentPipelineState)
+ desc.targetCount = 1;
+ desc.targets = &colorTarget;
+ desc.depthStencil.depthTestEnable = false;
+ desc.depthStencil.depthWriteEnable = false;
+ desc.primitiveTopology = PrimitiveTopology::TriangleList;
+ gPresentPipeline = gDevice->createRenderPipeline(desc);
+ if (!gPresentPipeline)
return SLANG_FAIL;
const char* hitgroupNames[] = {"hitgroup0", "hitgroup1"};
ComPtr<IShaderProgram> rayTracingProgram;
SLANG_RETURN_ON_FAIL(loadShaderProgram(gDevice, true, rayTracingProgram.writeRef()));
- RayTracingPipelineStateDesc rtpDesc = {};
+ RayTracingPipelineDesc rtpDesc = {};
rtpDesc.program = rayTracingProgram;
rtpDesc.hitGroupCount = 2;
HitGroupDesc hitGroups[2];
@@ -571,11 +540,11 @@ struct RayTracing : public WindowedAppBase
rtpDesc.maxRayPayloadSize = 64;
rtpDesc.maxRecursion = 2;
SLANG_RETURN_ON_FAIL(
- gDevice->createRayTracingPipelineState(rtpDesc, gRenderPipelineState.writeRef()));
- if (!gRenderPipelineState)
+ gDevice->createRayTracingPipeline(rtpDesc, gRenderPipeline.writeRef()));
+ if (!gRenderPipeline)
return SLANG_FAIL;
- IShaderTable::Desc shaderTableDesc = {};
+ ShaderTableDesc shaderTableDesc = {};
const char* raygenName = "rayGenShader";
const char* missName = "missShader";
shaderTableDesc.program = rayTracingProgram;
@@ -593,19 +562,16 @@ struct RayTracing : public WindowedAppBase
void createResultTexture()
{
- ITextureResource::Desc resultTextureDesc = {};
- resultTextureDesc.type = IResource::Type::Texture2D;
- resultTextureDesc.numMipLevels = 1;
+ TextureDesc resultTextureDesc = {};
+ resultTextureDesc.type = TextureType::Texture2D;
+ resultTextureDesc.mipCount = 1;
resultTextureDesc.size.width = windowWidth;
resultTextureDesc.size.height = windowHeight;
resultTextureDesc.size.depth = 1;
+ resultTextureDesc.usage = TextureUsage::UnorderedAccess | TextureUsage::ShaderResource;
resultTextureDesc.defaultState = ResourceState::UnorderedAccess;
- resultTextureDesc.format = Format::R16G16B16A16_FLOAT;
- gResultTexture = gDevice->createTextureResource(resultTextureDesc);
- IResourceView::Desc resultUAVDesc = {};
- resultUAVDesc.format = resultTextureDesc.format;
- resultUAVDesc.type = IResourceView::Type::UnorderedAccess;
- gResultTextureUAV = gDevice->createTextureView(gResultTexture, resultUAVDesc);
+ resultTextureDesc.format = Format::RGBA16Float;
+ gResultTexture = gDevice->createTexture(resultTextureDesc);
}
virtual void windowSizeChanged() override
@@ -659,53 +625,62 @@ struct RayTracing : public WindowedAppBase
memcpy(gUniforms.lightDir, &lightDir, sizeof(float) * 3);
}
- virtual void renderFrame(int frameBufferIndex) override
+ virtual void renderFrame(ITexture* texture) override
{
updateUniforms();
{
- ComPtr<ICommandBuffer> renderCommandBuffer =
- gTransientHeaps[frameBufferIndex]->createCommandBuffer();
- auto renderEncoder = renderCommandBuffer->encodeRayTracingCommands();
- IShaderObject* rootObject = nullptr;
- renderEncoder->bindPipeline(gRenderPipelineState, &rootObject);
+ auto commandEncoder = gQueue->createCommandEncoder();
+ auto rayTracingPassEncoder = commandEncoder->beginRayTracingPass();
+ auto rootObject = rayTracingPassEncoder->bindPipeline(gRenderPipeline, gShaderTable);
auto cursor = ShaderCursor(rootObject);
- cursor["resultTexture"].setResource(gResultTextureUAV);
+ cursor["resultTexture"].setBinding(gResultTexture);
cursor["uniforms"].setData(&gUniforms, sizeof(Uniforms));
- cursor["sceneBVH"].setResource(gTLAS);
- cursor["primitiveBuffer"].setResource(gPrimitiveBufferSRV);
- renderEncoder->dispatchRays(0, gShaderTable, windowWidth, windowHeight, 1);
- renderEncoder->endEncoding();
- renderCommandBuffer->close();
- gQueue->executeCommandBuffer(renderCommandBuffer);
+ cursor["sceneBVH"].setBinding(gTLAS);
+ cursor["primitiveBuffer"].setBinding(gPrimitiveBuffer);
+ rayTracingPassEncoder->dispatchRays(0, windowWidth, windowHeight, 1);
+ rayTracingPassEncoder->end();
+ gQueue->submit(commandEncoder->finish());
}
{
- ComPtr<ICommandBuffer> presentCommandBuffer =
- gTransientHeaps[frameBufferIndex]->createCommandBuffer();
- auto presentEncoder = presentCommandBuffer->encodeRenderCommands(
- gRenderPass,
- gFramebuffers[frameBufferIndex]);
- gfx::Viewport viewport = {};
- viewport.maxZ = 1.0f;
- viewport.extentX = (float)windowWidth;
- viewport.extentY = (float)windowHeight;
- presentEncoder->setViewportAndScissor(viewport);
- auto rootObject = presentEncoder->bindPipeline(gPresentPipelineState);
- auto cursor = ShaderCursor(rootObject->getEntryPoint(1));
- cursor["t"].setResource(gResultTextureUAV);
- presentEncoder->setVertexBuffer(0, gFullScreenVertexBuffer);
- presentEncoder->setPrimitiveTopology(PrimitiveTopology::TriangleList);
- presentEncoder->draw(3);
- presentEncoder->endEncoding();
- presentCommandBuffer->close();
- gQueue->executeCommandBuffer(presentCommandBuffer);
+ auto commandEncoder = gQueue->createCommandEncoder();
+
+ ComPtr<ITextureView> textureView = gDevice->createTextureView(texture, {});
+ RenderPassColorAttachment colorAttachment = {};
+ colorAttachment.view = textureView;
+ colorAttachment.loadOp = LoadOp::Clear;
+
+ RenderPassDesc renderPassDesc = {};
+ renderPassDesc.colorAttachments = &colorAttachment;
+ renderPassDesc.colorAttachmentCount = 1;
+
+ auto renderPassEncoder = commandEncoder->beginRenderPass(renderPassDesc);
+
+ RenderState renderState = {};
+ renderState.viewports[0] = Viewport::fromSize(windowWidth, windowHeight);
+ renderState.viewportCount = 1;
+ renderState.scissorRects[0] = ScissorRect::fromSize(windowWidth, windowHeight);
+ renderState.scissorRectCount = 1;
+ renderState.vertexBuffers[0] = gFullScreenVertexBuffer;
+ renderState.vertexBufferCount = 1;
+ renderPassEncoder->setRenderState(renderState);
+
+ auto rootObject = renderPassEncoder->bindPipeline(gPresentPipeline);
+ auto cursor = ShaderCursor(rootObject);
+ cursor["t"].setBinding(gResultTexture);
+
+ DrawArguments drawArgs = {};
+ drawArgs.vertexCount = 3;
+ renderPassEncoder->draw(drawArgs);
+ renderPassEncoder->end();
+ gQueue->submit(commandEncoder->finish());
}
if (!isTestMode())
{
// With that, we are done drawing for one frame, and ready for the next.
//
- gSwapchain->present();
+ gSurface->present();
}
}
};
diff --git a/examples/ray-tracing/main.cpp b/examples/ray-tracing/main.cpp
index fffe5e75f..0b14aef7e 100644
--- a/examples/ray-tracing/main.cpp
+++ b/examples/ray-tracing/main.cpp
@@ -1,18 +1,19 @@
// main.cpp
// This file implements an example of hardware ray-tracing using
-// Slang shaders and the `gfx` graphics API.
+// Slang shaders and the `slang-rhi` graphics API.
#include "core/slang-basic.h"
#include "examples/example-base/example-base.h"
-#include "gfx-util/shader-cursor.h"
#include "platform/vector-math.h"
#include "platform/window.h"
#include "slang-com-ptr.h"
-#include "slang-gfx.h"
+#include "slang-rhi.h"
+#include "slang-rhi/acceleration-structure-utils.h"
+#include "slang-rhi/shader-cursor.h"
#include "slang.h"
-using namespace gfx;
+using namespace rhi;
using namespace Slang;
static const ExampleResources resourceBase("ray-tracing");
@@ -148,10 +149,7 @@ struct RayTracing : public WindowedAppBase
}
// Load and compile shader code from souce.
- gfx::Result loadShaderProgram(
- gfx::IDevice* device,
- bool isComputePipeline,
- gfx::IShaderProgram** outProgram)
+ Result loadShaderProgram(IDevice* device, bool isComputePipeline, IShaderProgram** outProgram)
{
ComPtr<slang::ISession> slangSession;
slangSession = device->getSlangSession();
@@ -197,28 +195,24 @@ struct RayTracing : public WindowedAppBase
printEntrypointHashes(componentTypes.getCount() - 1, 1, linkedProgram);
}
- gfx::IShaderProgram::Desc programDesc = {};
+ ShaderProgramDesc programDesc = {};
programDesc.slangGlobalScope = linkedProgram;
- SLANG_RETURN_ON_FAIL(device->createProgram(programDesc, outProgram));
+ SLANG_RETURN_ON_FAIL(device->createShaderProgram(programDesc, outProgram));
return SLANG_OK;
}
- ComPtr<gfx::IPipelineState> gPresentPipelineState;
- ComPtr<gfx::IPipelineState> gRenderPipelineState;
- ComPtr<gfx::IBufferResource> gFullScreenVertexBuffer;
- ComPtr<gfx::IBufferResource> gVertexBuffer;
- ComPtr<gfx::IBufferResource> gIndexBuffer;
- ComPtr<gfx::IBufferResource> gPrimitiveBuffer;
- ComPtr<gfx::IBufferResource> gTransformBuffer;
- ComPtr<gfx::IResourceView> gPrimitiveBufferSRV;
- ComPtr<gfx::IBufferResource> gInstanceBuffer;
- ComPtr<gfx::IBufferResource> gBLASBuffer;
- ComPtr<gfx::IAccelerationStructure> gBLAS;
- ComPtr<gfx::IBufferResource> gTLASBuffer;
- ComPtr<gfx::IAccelerationStructure> gTLAS;
- ComPtr<gfx::ITextureResource> gResultTexture;
- ComPtr<gfx::IResourceView> gResultTextureUAV;
+ ComPtr<IRenderPipeline> gPresentPipeline;
+ ComPtr<IComputePipeline> gRenderPipeline;
+ ComPtr<IBuffer> gFullScreenVertexBuffer;
+ ComPtr<IBuffer> gVertexBuffer;
+ ComPtr<IBuffer> gIndexBuffer;
+ ComPtr<IBuffer> gPrimitiveBuffer;
+ ComPtr<IBuffer> gTransformBuffer;
+ ComPtr<IBuffer> gInstanceBuffer;
+ ComPtr<IAccelerationStructure> gBLAS;
+ ComPtr<IAccelerationStructure> gTLAS;
+ ComPtr<ITexture> gResultTexture;
uint64_t lastTime = 0;
@@ -302,230 +296,199 @@ struct RayTracing : public WindowedAppBase
gWindow->events.keyUp = [this](const platform::KeyEventArgs& e) { onKeyUp(e); };
}
- IBufferResource::Desc vertexBufferDesc;
- vertexBufferDesc.type = IResource::Type::Buffer;
- vertexBufferDesc.sizeInBytes = kVertexCount * sizeof(Vertex);
- vertexBufferDesc.defaultState = ResourceState::ShaderResource;
- gVertexBuffer = gDevice->createBufferResource(vertexBufferDesc, &kVertexData[0]);
+ BufferDesc vertexBufferDesc;
+ vertexBufferDesc.size = kVertexCount * sizeof(Vertex);
+ vertexBufferDesc.usage = BufferUsage::AccelerationStructureBuildInput;
+ vertexBufferDesc.defaultState = ResourceState::AccelerationStructureBuildInput;
+ gVertexBuffer = gDevice->createBuffer(vertexBufferDesc, &kVertexData[0]);
if (!gVertexBuffer)
return SLANG_FAIL;
- IBufferResource::Desc indexBufferDesc;
- indexBufferDesc.type = IResource::Type::Buffer;
- indexBufferDesc.sizeInBytes = kIndexCount * sizeof(int32_t);
- indexBufferDesc.defaultState = ResourceState::ShaderResource;
- gIndexBuffer = gDevice->createBufferResource(indexBufferDesc, &kIndexData[0]);
+ BufferDesc indexBufferDesc;
+ indexBufferDesc.size = kIndexCount * sizeof(int32_t);
+ indexBufferDesc.usage = BufferUsage::AccelerationStructureBuildInput;
+ indexBufferDesc.defaultState = ResourceState::AccelerationStructureBuildInput;
+ gIndexBuffer = gDevice->createBuffer(indexBufferDesc, &kIndexData[0]);
if (!gIndexBuffer)
return SLANG_FAIL;
- IBufferResource::Desc primitiveBufferDesc;
- primitiveBufferDesc.type = IResource::Type::Buffer;
- primitiveBufferDesc.sizeInBytes = kPrimitiveCount * sizeof(Primitive);
+ BufferDesc primitiveBufferDesc;
+ primitiveBufferDesc.size = kPrimitiveCount * sizeof(Primitive);
primitiveBufferDesc.elementSize = sizeof(Primitive);
+ primitiveBufferDesc.usage = BufferUsage::ShaderResource;
primitiveBufferDesc.defaultState = ResourceState::ShaderResource;
- gPrimitiveBuffer = gDevice->createBufferResource(primitiveBufferDesc, &kPrimitiveData[0]);
+ gPrimitiveBuffer = gDevice->createBuffer(primitiveBufferDesc, &kPrimitiveData[0]);
if (!gPrimitiveBuffer)
return SLANG_FAIL;
- IResourceView::Desc primitiveSRVDesc = {};
- primitiveSRVDesc.format = Format::Unknown;
- primitiveSRVDesc.type = IResourceView::Type::ShaderResource;
- gPrimitiveBufferSRV =
- gDevice->createBufferView(gPrimitiveBuffer, nullptr, primitiveSRVDesc);
-
- IBufferResource::Desc transformBufferDesc;
- transformBufferDesc.type = IResource::Type::Buffer;
- transformBufferDesc.sizeInBytes = sizeof(float) * 12;
- transformBufferDesc.defaultState = ResourceState::ShaderResource;
+ BufferDesc transformBufferDesc;
+ transformBufferDesc.size = sizeof(float) * 12;
+ transformBufferDesc.usage = BufferUsage::AccelerationStructureBuildInput;
+ transformBufferDesc.defaultState = ResourceState::AccelerationStructureBuildInput;
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};
- gTransformBuffer = gDevice->createBufferResource(transformBufferDesc, &transformData);
+ gTransformBuffer = gDevice->createBuffer(transformBufferDesc, &transformData);
if (!gTransformBuffer)
return SLANG_FAIL;
// 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 = gIndexBuffer->getDeviceAddress();
- geomDesc.content.triangles.indexFormat = Format::R32_UINT;
- geomDesc.content.triangles.vertexCount = kVertexCount;
- geomDesc.content.triangles.vertexData = gVertexBuffer->getDeviceAddress();
- geomDesc.content.triangles.vertexFormat = Format::R32G32B32_FLOAT;
- geomDesc.content.triangles.vertexStride = sizeof(Vertex);
- geomDesc.content.triangles.transform3x4 = gTransformBuffer->getDeviceAddress();
- accelerationStructureBuildInputs.geometryDescs = &geomDesc;
+ AccelerationStructureBuildInput buildInput = {};
+ buildInput.type = AccelerationStructureBuildInputType::Triangles;
+ buildInput.triangles.vertexBuffers[0] = gVertexBuffer;
+ buildInput.triangles.vertexBufferCount = 1;
+ buildInput.triangles.vertexFormat = Format::RGB32Float;
+ buildInput.triangles.vertexCount = kVertexCount;
+ buildInput.triangles.vertexStride = sizeof(Vertex);
+ buildInput.triangles.indexBuffer = gIndexBuffer;
+ buildInput.triangles.indexFormat = IndexFormat::Uint32;
+ buildInput.triangles.indexCount = kIndexCount;
+ buildInput.triangles.preTransformBuffer = gTransformBuffer;
+ buildInput.triangles.flags = AccelerationStructureGeometryFlags::Opaque;
+
+ AccelerationStructureBuildDesc buildDesc = {};
+ buildDesc.inputs = &buildInput;
+ buildDesc.inputCount = 1;
+ buildDesc.flags = AccelerationStructureBuildFlags::AllowCompaction;
// Query buffer size for acceleration structure build.
- SLANG_RETURN_ON_FAIL(gDevice->getAccelerationStructurePrebuildInfo(
- accelerationStructureBuildInputs,
- &accelerationStructurePrebuildInfo));
+ AccelerationStructureSizes sizes;
+ SLANG_RETURN_ON_FAIL(gDevice->getAccelerationStructureSizes(buildDesc, &sizes));
+
// Allocate buffers for acceleration structure.
- IBufferResource::Desc asDraftBufferDesc;
- asDraftBufferDesc.type = IResource::Type::Buffer;
- asDraftBufferDesc.defaultState = ResourceState::AccelerationStructure;
- asDraftBufferDesc.sizeInBytes = accelerationStructurePrebuildInfo.resultDataMaxSize;
- ComPtr<IBufferResource> draftBuffer = gDevice->createBufferResource(asDraftBufferDesc);
- if (!draftBuffer)
- return SLANG_FAIL;
- IBufferResource::Desc scratchBufferDesc;
- scratchBufferDesc.type = IResource::Type::Buffer;
+ BufferDesc scratchBufferDesc;
+ scratchBufferDesc.usage = BufferUsage::UnorderedAccess;
scratchBufferDesc.defaultState = ResourceState::UnorderedAccess;
- scratchBufferDesc.sizeInBytes = accelerationStructurePrebuildInfo.scratchDataSize;
- ComPtr<IBufferResource> scratchBuffer =
- gDevice->createBufferResource(scratchBufferDesc);
+ scratchBufferDesc.size = sizes.scratchSize;
+ ComPtr<IBuffer> scratchBuffer = gDevice->createBuffer(scratchBufferDesc);
if (!scratchBuffer)
return SLANG_FAIL;
// Build acceleration structure.
ComPtr<IQueryPool> compactedSizeQuery;
- IQueryPool::Desc queryPoolDesc;
+ QueryPoolDesc queryPoolDesc;
queryPoolDesc.count = 1;
queryPoolDesc.type = QueryType::AccelerationStructureCompactedSize;
SLANG_RETURN_ON_FAIL(
gDevice->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;
+ AccelerationStructureDesc draftCreateDesc;
+ draftCreateDesc.size = sizes.accelerationStructureSize;
SLANG_RETURN_ON_FAIL(
gDevice->createAccelerationStructure(draftCreateDesc, draftAS.writeRef()));
compactedSizeQuery->reset();
- auto commandBuffer = gTransientHeaps[0]->createCommandBuffer();
- auto encoder = commandBuffer->encodeRayTracingCommands();
- IAccelerationStructure::BuildDesc buildDesc = {};
- buildDesc.dest = draftAS;
- buildDesc.inputs = accelerationStructureBuildInputs;
- buildDesc.scratchData = scratchBuffer->getDeviceAddress();
+ auto commandEncoder = gQueue->createCommandEncoder();
AccelerationStructureQueryDesc compactedSizeQueryDesc = {};
compactedSizeQueryDesc.queryPool = compactedSizeQuery;
compactedSizeQueryDesc.queryType = QueryType::AccelerationStructureCompactedSize;
- encoder->buildAccelerationStructure(buildDesc, 1, &compactedSizeQueryDesc);
- encoder->endEncoding();
- commandBuffer->close();
- gQueue->executeCommandBuffer(commandBuffer);
+ commandEncoder->buildAccelerationStructure(
+ buildDesc,
+ draftAS,
+ nullptr,
+ scratchBuffer,
+ 1,
+ &compactedSizeQueryDesc);
+ gQueue->submit(commandEncoder->finish());
gQueue->waitOnHost();
uint64_t compactedSize = 0;
compactedSizeQuery->getResult(0, 1, &compactedSize);
- IBufferResource::Desc asBufferDesc;
- asBufferDesc.type = IResource::Type::Buffer;
- asBufferDesc.defaultState = ResourceState::AccelerationStructure;
- asBufferDesc.sizeInBytes = (gfx::Size)compactedSize;
- gBLASBuffer = gDevice->createBufferResource(asBufferDesc);
- IAccelerationStructure::CreateDesc createDesc;
- createDesc.buffer = gBLASBuffer;
- createDesc.kind = IAccelerationStructure::Kind::BottomLevel;
- createDesc.offset = 0;
- createDesc.size = (gfx::Size)compactedSize;
+ AccelerationStructureDesc createDesc;
+ createDesc.size = compactedSize;
gDevice->createAccelerationStructure(createDesc, gBLAS.writeRef());
- commandBuffer = gTransientHeaps[0]->createCommandBuffer();
- encoder = commandBuffer->encodeRayTracingCommands();
- encoder->copyAccelerationStructure(
+ commandEncoder = gQueue->createCommandEncoder();
+ commandEncoder->copyAccelerationStructure(
gBLAS,
draftAS,
AccelerationStructureCopyMode::Compact);
- encoder->endEncoding();
- commandBuffer->close();
- gQueue->executeCommandBuffer(commandBuffer);
+ gQueue->submit(commandEncoder->finish());
gQueue->waitOnHost();
}
// Build top level acceleration structure.
{
- List<IAccelerationStructure::InstanceDesc> instanceDescs;
- instanceDescs.setCount(1);
- instanceDescs[0].accelerationStructure = gBLAS->getDeviceAddress();
- instanceDescs[0].flags =
- IAccelerationStructure::GeometryInstanceFlags::TriangleFacingCullDisable;
- instanceDescs[0].instanceContributionToHitGroupIndex = 0;
- instanceDescs[0].instanceID = 0;
- instanceDescs[0].instanceMask = 0xFF;
+ AccelerationStructureInstanceDescType nativeInstanceDescType =
+ getAccelerationStructureInstanceDescType(gDevice);
+ Size nativeInstanceDescSize =
+ getAccelerationStructureInstanceDescSize(nativeInstanceDescType);
+
+ std::vector<AccelerationStructureInstanceDescGeneric> instanceDescs;
+ instanceDescs.resize(1);
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);
+ instanceDescs[0].instanceID = 0;
+ instanceDescs[0].instanceMask = 0xFF;
+ instanceDescs[0].instanceContributionToHitGroupIndex = 0;
+ instanceDescs[0].flags = AccelerationStructureInstanceFlags::TriangleFacingCullDisable;
+ instanceDescs[0].accelerationStructure = gBLAS->getHandle();
+
+ std::vector<uint8_t> nativeInstanceDescs(instanceDescs.size() * nativeInstanceDescSize);
+ convertAccelerationStructureInstanceDescs(
+ instanceDescs.size(),
+ nativeInstanceDescType,
+ nativeInstanceDescs.data(),
+ nativeInstanceDescSize,
+ instanceDescs.data(),
+ sizeof(AccelerationStructureInstanceDescGeneric));
+
+ BufferDesc instanceBufferDesc;
+ instanceBufferDesc.size =
+ instanceDescs.size() * sizeof(AccelerationStructureInstanceDescGeneric);
+ instanceBufferDesc.usage = BufferUsage::ShaderResource;
instanceBufferDesc.defaultState = ResourceState::ShaderResource;
- gInstanceBuffer =
- gDevice->createBufferResource(instanceBufferDesc, instanceDescs.getBuffer());
+ gInstanceBuffer = gDevice->createBuffer(instanceBufferDesc, nativeInstanceDescs.data());
if (!gInstanceBuffer)
return SLANG_FAIL;
- IAccelerationStructure::BuildInputs accelerationStructureBuildInputs = {};
- IAccelerationStructure::PrebuildInfo accelerationStructurePrebuildInfo = {};
- accelerationStructureBuildInputs.descCount = 1;
- accelerationStructureBuildInputs.kind = IAccelerationStructure::Kind::TopLevel;
- accelerationStructureBuildInputs.instanceDescs = gInstanceBuffer->getDeviceAddress();
+ AccelerationStructureBuildInput buildInput = {};
+ buildInput.type = AccelerationStructureBuildInputType::Instances;
+ buildInput.instances.instanceBuffer = gInstanceBuffer;
+ buildInput.instances.instanceCount = 1;
+ buildInput.instances.instanceStride = nativeInstanceDescSize;
+
+ AccelerationStructureBuildDesc buildDesc = {};
+ buildDesc.inputs = &buildInput;
+ buildDesc.inputCount = 1;
// Query buffer size for acceleration structure build.
- SLANG_RETURN_ON_FAIL(gDevice->getAccelerationStructurePrebuildInfo(
- accelerationStructureBuildInputs,
- &accelerationStructurePrebuildInfo));
-
- IBufferResource::Desc asBufferDesc;
- asBufferDesc.type = IResource::Type::Buffer;
- asBufferDesc.defaultState = ResourceState::AccelerationStructure;
- asBufferDesc.sizeInBytes = accelerationStructurePrebuildInfo.resultDataMaxSize;
- gTLASBuffer = gDevice->createBufferResource(asBufferDesc);
-
- IBufferResource::Desc scratchBufferDesc;
- scratchBufferDesc.type = IResource::Type::Buffer;
+ AccelerationStructureSizes sizes;
+ SLANG_RETURN_ON_FAIL(gDevice->getAccelerationStructureSizes(buildDesc, &sizes));
+
+ BufferDesc scratchBufferDesc;
+ scratchBufferDesc.usage = BufferUsage::UnorderedAccess;
scratchBufferDesc.defaultState = ResourceState::UnorderedAccess;
- scratchBufferDesc.sizeInBytes = accelerationStructurePrebuildInfo.scratchDataSize;
- ComPtr<IBufferResource> scratchBuffer =
- gDevice->createBufferResource(scratchBufferDesc);
-
- IAccelerationStructure::CreateDesc createDesc;
- createDesc.buffer = gTLASBuffer;
- createDesc.kind = IAccelerationStructure::Kind::TopLevel;
- createDesc.offset = 0;
- createDesc.size = accelerationStructurePrebuildInfo.resultDataMaxSize;
+ scratchBufferDesc.size = sizes.scratchSize;
+ ComPtr<IBuffer> scratchBuffer = gDevice->createBuffer(scratchBufferDesc);
+
+ AccelerationStructureDesc createDesc;
+ createDesc.size = sizes.accelerationStructureSize;
SLANG_RETURN_ON_FAIL(
gDevice->createAccelerationStructure(createDesc, gTLAS.writeRef()));
- auto commandBuffer = gTransientHeaps[0]->createCommandBuffer();
- auto encoder = commandBuffer->encodeRayTracingCommands();
- IAccelerationStructure::BuildDesc buildDesc = {};
- buildDesc.dest = gTLAS;
- buildDesc.inputs = accelerationStructureBuildInputs;
- buildDesc.scratchData = scratchBuffer->getDeviceAddress();
- encoder->buildAccelerationStructure(buildDesc, 0, nullptr);
- encoder->endEncoding();
- commandBuffer->close();
- gQueue->executeCommandBuffer(commandBuffer);
+ auto commandEncoder = gQueue->createCommandEncoder();
+ commandEncoder
+ ->buildAccelerationStructure(buildDesc, gTLAS, nullptr, scratchBuffer, 0, nullptr);
+ gQueue->submit(commandEncoder->finish());
gQueue->waitOnHost();
}
- IBufferResource::Desc fullScreenVertexBufferDesc;
- fullScreenVertexBufferDesc.type = IResource::Type::Buffer;
- fullScreenVertexBufferDesc.sizeInBytes =
+ BufferDesc fullScreenVertexBufferDesc;
+ fullScreenVertexBufferDesc.size =
FullScreenTriangle::kVertexCount * sizeof(FullScreenTriangle::Vertex);
+ fullScreenVertexBufferDesc.usage = BufferUsage::VertexBuffer;
fullScreenVertexBufferDesc.defaultState = ResourceState::VertexBuffer;
- gFullScreenVertexBuffer = gDevice->createBufferResource(
- fullScreenVertexBufferDesc,
- &FullScreenTriangle::kVertices[0]);
+ gFullScreenVertexBuffer =
+ gDevice->createBuffer(fullScreenVertexBufferDesc, &FullScreenTriangle::kVertices[0]);
if (!gFullScreenVertexBuffer)
return SLANG_FAIL;
InputElementDesc inputElements[] = {
- {"POSITION", 0, Format::R32G32_FLOAT, offsetof(FullScreenTriangle::Vertex, position)},
+ {"POSITION", 0, Format::RG32Float, offsetof(FullScreenTriangle::Vertex, position)},
};
auto inputLayout = gDevice->createInputLayout(
sizeof(FullScreenTriangle::Vertex),
@@ -536,20 +499,26 @@ struct RayTracing : public WindowedAppBase
ComPtr<IShaderProgram> shaderProgram;
SLANG_RETURN_ON_FAIL(loadShaderProgram(gDevice, false, shaderProgram.writeRef()));
- GraphicsPipelineStateDesc desc;
+ ColorTargetDesc colorTarget;
+ colorTarget.format = Format::RGBA16Float;
+ RenderPipelineDesc desc;
desc.inputLayout = inputLayout;
desc.program = shaderProgram;
- desc.framebufferLayout = gFramebufferLayout;
- gPresentPipelineState = gDevice->createGraphicsPipelineState(desc);
- if (!gPresentPipelineState)
+ desc.targetCount = 1;
+ desc.targets = &colorTarget;
+ desc.depthStencil.depthTestEnable = false;
+ desc.depthStencil.depthWriteEnable = false;
+ desc.primitiveTopology = PrimitiveTopology::TriangleList;
+ gPresentPipeline = gDevice->createRenderPipeline(desc);
+ if (!gPresentPipeline)
return SLANG_FAIL;
ComPtr<IShaderProgram> computeProgram;
SLANG_RETURN_ON_FAIL(loadShaderProgram(gDevice, true, computeProgram.writeRef()));
- ComputePipelineStateDesc computeDesc;
+ ComputePipelineDesc computeDesc;
computeDesc.program = computeProgram;
- gRenderPipelineState = gDevice->createComputePipelineState(computeDesc);
- if (!gRenderPipelineState)
+ gRenderPipeline = gDevice->createComputePipeline(computeDesc);
+ if (!gRenderPipeline)
return SLANG_FAIL;
createResultTexture();
@@ -558,19 +527,16 @@ struct RayTracing : public WindowedAppBase
void createResultTexture()
{
- ITextureResource::Desc resultTextureDesc = {};
- resultTextureDesc.type = IResource::Type::Texture2D;
- resultTextureDesc.numMipLevels = 1;
+ TextureDesc resultTextureDesc = {};
+ resultTextureDesc.type = TextureType::Texture2D;
+ resultTextureDesc.mipCount = 1;
resultTextureDesc.size.width = windowWidth;
resultTextureDesc.size.height = windowHeight;
resultTextureDesc.size.depth = 1;
+ resultTextureDesc.usage = TextureUsage::UnorderedAccess | TextureUsage::ShaderResource;
resultTextureDesc.defaultState = ResourceState::UnorderedAccess;
- resultTextureDesc.format = Format::R16G16B16A16_FLOAT;
- gResultTexture = gDevice->createTextureResource(resultTextureDesc);
- IResourceView::Desc resultUAVDesc = {};
- resultUAVDesc.format = resultTextureDesc.format;
- resultUAVDesc.type = IResourceView::Type::UnorderedAccess;
- gResultTextureUAV = gDevice->createTextureView(gResultTexture, resultUAVDesc);
+ resultTextureDesc.format = Format::RGBA16Float;
+ gResultTexture = gDevice->createTexture(resultTextureDesc);
}
virtual void windowSizeChanged() override
@@ -624,52 +590,65 @@ struct RayTracing : public WindowedAppBase
memcpy(gUniforms.lightDir, &lightDir, sizeof(float) * 3);
}
- virtual void renderFrame(int frameBufferIndex) override
+ virtual void renderFrame(ITexture* texture) override
{
updateUniforms();
{
- ComPtr<ICommandBuffer> renderCommandBuffer =
- gTransientHeaps[frameBufferIndex]->createCommandBuffer();
- auto renderEncoder = renderCommandBuffer->encodeComputeCommands();
- auto rootObject = renderEncoder->bindPipeline(gRenderPipelineState);
- auto cursor = ShaderCursor(rootObject->getEntryPoint(0));
- cursor["resultTexture"].setResource(gResultTextureUAV);
+ auto commandEncoder = gQueue->createCommandEncoder();
+ auto computePassEncoder = commandEncoder->beginComputePass();
+ auto rootObject = computePassEncoder->bindPipeline(gRenderPipeline);
+ auto cursor = ShaderCursor(rootObject);
+ cursor["resultTexture"].setBinding(gResultTexture);
cursor["uniforms"].setData(&gUniforms, sizeof(Uniforms));
- cursor["sceneBVH"].setResource(gTLAS);
- cursor["primitiveBuffer"].setResource(gPrimitiveBufferSRV);
- renderEncoder->dispatchCompute((windowWidth + 15) / 16, (windowHeight + 15) / 16, 1);
- renderEncoder->endEncoding();
- renderCommandBuffer->close();
- gQueue->executeCommandBuffer(renderCommandBuffer);
+ cursor["sceneBVH"].setBinding(gTLAS);
+ cursor["primitiveBuffer"].setBinding(gPrimitiveBuffer);
+ computePassEncoder->dispatchCompute(
+ (windowWidth + 15) / 16,
+ (windowHeight + 15) / 16,
+ 1);
+ computePassEncoder->end();
+ gQueue->submit(commandEncoder->finish());
}
{
- ComPtr<ICommandBuffer> presentCommandBuffer =
- gTransientHeaps[frameBufferIndex]->createCommandBuffer();
- auto presentEncoder = presentCommandBuffer->encodeRenderCommands(
- gRenderPass,
- gFramebuffers[frameBufferIndex]);
- gfx::Viewport viewport = {};
- viewport.maxZ = 1.0f;
- viewport.extentX = (float)windowWidth;
- viewport.extentY = (float)windowHeight;
- presentEncoder->setViewportAndScissor(viewport);
- auto rootObject = presentEncoder->bindPipeline(gPresentPipelineState);
- auto cursor = ShaderCursor(rootObject->getEntryPoint(1));
- cursor["t"].setResource(gResultTextureUAV);
- presentEncoder->setVertexBuffer(0, gFullScreenVertexBuffer);
- presentEncoder->setPrimitiveTopology(PrimitiveTopology::TriangleList);
- presentEncoder->draw(3);
- presentEncoder->endEncoding();
- presentCommandBuffer->close();
- gQueue->executeCommandBuffer(presentCommandBuffer);
+ auto commandEncoder = gQueue->createCommandEncoder();
+
+ ComPtr<ITextureView> textureView = gDevice->createTextureView(texture, {});
+ RenderPassColorAttachment colorAttachment = {};
+ colorAttachment.view = textureView;
+ colorAttachment.loadOp = LoadOp::Clear;
+
+ RenderPassDesc renderPassDesc = {};
+ renderPassDesc.colorAttachments = &colorAttachment;
+ renderPassDesc.colorAttachmentCount = 1;
+
+ auto renderPassEncoder = commandEncoder->beginRenderPass(renderPassDesc);
+
+ RenderState renderState = {};
+ renderState.viewports[0] = Viewport::fromSize(windowWidth, windowHeight);
+ renderState.viewportCount = 1;
+ renderState.scissorRects[0] = ScissorRect::fromSize(windowWidth, windowHeight);
+ renderState.scissorRectCount = 1;
+ renderState.vertexBuffers[0] = gFullScreenVertexBuffer;
+ renderState.vertexBufferCount = 1;
+ renderPassEncoder->setRenderState(renderState);
+
+ auto rootObject = renderPassEncoder->bindPipeline(gPresentPipeline);
+ auto cursor = ShaderCursor(rootObject);
+ cursor["t"].setBinding(gResultTexture);
+
+ DrawArguments drawArgs = {};
+ drawArgs.vertexCount = 3;
+ renderPassEncoder->draw(drawArgs);
+ renderPassEncoder->end();
+ gQueue->submit(commandEncoder->finish());
}
if (!isTestMode())
{
// With that, we are done drawing for one frame, and ready for the next.
//
- gSwapchain->present();
+ gSurface->present();
}
}
};
diff --git a/examples/reflection-parameter-blocks/main.cpp b/examples/reflection-parameter-blocks/main.cpp
index 873e785d0..04e2b19c0 100644
--- a/examples/reflection-parameter-blocks/main.cpp
+++ b/examples/reflection-parameter-blocks/main.cpp
@@ -21,15 +21,17 @@
// with a certain amount of boilerplate that isn't especially
// interesting to discuss.
+#include "core/slang-basic.h"
+#include "examples/example-base/example-base.h"
#include "slang-com-ptr.h"
+#include "slang-rhi.h"
#include "slang.h"
-typedef SlangResult Result;
-#include "core/slang-basic.h"
-#include "examples/example-base/example-base.h"
+typedef SlangResult Result;
using Slang::ComPtr;
using Slang::String;
using Slang::List;
+using namespace rhi;
// The example code currently only supports Vulkan, but the
// code is factored with the intention that it could be extended
@@ -47,7 +49,7 @@ static const char* kSourceFileName = "shader.slang";
struct PipelineLayoutReflectionContext
{
- gfx::IDevice* _gfxDevice = nullptr;
+ IDevice* _rhiDevice = nullptr;
slang::ISession* _slangSession = nullptr;
slang::ProgramLayout* _slangProgramLayout = nullptr;
slang::IBlob* _slangCompiledProgramBlob = nullptr;
@@ -529,16 +531,16 @@ struct PipelineLayoutReflectionContext_Vulkan : PipelineLayoutReflectionContext
Result createAndValidatePipelineLayout()
{
// Here we do a little bit of complicated interaction with
- // the `gfx` library to allow us to call raw Vulkan API
- // functions on the same device that `gfx` kindly set up
+ // the `slang-rhi` library to allow us to call raw Vulkan API
+ // functions on the same device that `slang-rhi` kindly set up
// for us.
//
- gfx::IDevice::InteropHandles handles;
- SLANG_RETURN_ON_FAIL(_gfxDevice->getNativeDeviceHandles(&handles));
+ DeviceNativeHandles handle;
+ SLANG_RETURN_ON_FAIL(_rhiDevice->getNativeDeviceHandles(&handle));
- vkAPI.instance = (VkInstance)handles.handles[0].handleValue;
- vkAPI.physicalDevice = (VkPhysicalDevice)handles.handles[1].handleValue;
- vkAPI.device = (VkDevice)handles.handles[2].handleValue;
+ vkAPI.instance = (VkInstance)handle.handles[0].value;
+ vkAPI.physicalDevice = (VkPhysicalDevice)handle.handles[1].value;
+ vkAPI.device = (VkDevice)handle.handles[2].value;
vkAPI.initGlobalProcs();
vkAPI.initInstanceProcs();
@@ -575,25 +577,23 @@ struct ReflectionParameterBlocksExampleApp : public TestBase
{
parseOption(argc, argv);
- // We start by initializing the `gfx` system, so that
+ // We start by initializing the `slang-rhi` system, so that
// it can handle most of the details of getting a
// Vulkan device up and running.
-#ifdef _DEBUG
- gfx::gfxEnableDebugLayer(true);
-#endif
- gfx::IDevice::Desc deviceDesc = {};
- deviceDesc.deviceType = gfx::DeviceType::Vulkan;
+ DeviceDesc deviceDesc = {};
+ deviceDesc.deviceType = DeviceType::Vulkan;
- ComPtr<gfx::IDevice> gfxDevice;
- SLANG_RETURN_ON_FAIL(gfxCreateDevice(&deviceDesc, gfxDevice.writeRef()));
+ ComPtr<IDevice> rhiDevice = getRHI()->createDevice(deviceDesc);
+ if (!rhiDevice)
+ return SLANG_FAIL;
- // The `gfx` library also creates a Slang session as
+ // The `slang-rhi` library also creates a Slang session as
// part of its startup, so we will use the session
// it already created for the compilation in
// this example.
//
- auto slangSession = gfxDevice->getSlangSession();
+ auto slangSession = rhiDevice->getSlangSession();
// Next we go through the fairly routine steps needed to
// compile a Slang program from source.
@@ -672,7 +672,7 @@ struct ReflectionParameterBlocksExampleApp : public TestBase
//
PipelineLayoutReflectionContext_Vulkan context;
- context._gfxDevice = gfxDevice;
+ context._rhiDevice = rhiDevice;
context._slangSession = slangSession;
context._slangProgramLayout = programLayout;
context._slangCompiledProgramBlob = programBinary;
diff --git a/examples/shader-object/main.cpp b/examples/shader-object/main.cpp
index 1010cdcb9..aafcc1505 100644
--- a/examples/shader-object/main.cpp
+++ b/examples/shader-object/main.cpp
@@ -3,8 +3,8 @@
// This file provides the application code for the `shader-object` example.
//
-// This example uses the Slang gfx layer to target different APIs.
-// The goal is to demonstrate how the Shader Object model implemented in `gfx` layer
+// This example uses the Slang slang-rhi layer to target different APIs.
+// The goal is to demonstrate how the Shader Object model implemented in `slang-rhi` layer
// simplifies shader specialization and parameter binding when using `interface` typed
// shader parameters.
//
@@ -14,29 +14,30 @@ using Slang::ComPtr;
#include "core/slang-basic.h"
#include "examples/example-base/example-base.h"
-#include "gfx-util/shader-cursor.h"
-#include "slang-gfx.h"
+#include "slang-rhi.h"
-using namespace gfx;
+#include <slang-rhi/shader-cursor.h>
+
+using namespace rhi;
static const ExampleResources resourceBase("shader-object");
static TestBase testBase;
-// Loads the shader code defined in `shader-object.slang` for use by the `gfx` layer.
+// Loads the shader code defined in `shader-object.slang` for use by the `slang-rhi` layer.
//
Result loadShaderProgram(
- gfx::IDevice* device,
- ComPtr<gfx::IShaderProgram>& outShaderProgram,
+ IDevice* device,
+ ComPtr<IShaderProgram>& outShaderProgram,
slang::ProgramLayout*& slangReflection)
{
// We need to obtain a compilation session (`slang::ISession`) that will provide
// a scope to all the compilation and loading of code we do.
//
- // Our example application uses the `gfx` graphics API abstraction layer, which already
+ // Our example application uses the `slang-rhi` graphics API abstraction layer, which already
// creates a Slang compilation session for us, so we just grab and use it here.
ComPtr<slang::ISession> slangSession;
- SLANG_RETURN_ON_FAIL(device->getSlangSession(slangSession.writeRef()));
+ slangSession = device->getSlangSession();
// Once the session has been obtained, we can start loading code into it.
//
@@ -119,12 +120,12 @@ Result loadShaderProgram(
// At this point, `composedProgram` represents the shader program
// we want to run, and the compute shader there have been checked.
- // We can create a `gfx::IShaderProgram` object from `composedProgram`
+ // We can create a `IShaderProgram` object from `composedProgram`
// so it may be used by the graphics layer.
- gfx::IShaderProgram::Desc programDesc = {};
+ ShaderProgramDesc programDesc = {};
programDesc.slangGlobalScope = composedProgram.get();
- auto shaderProgram = device->createProgram(programDesc);
+ auto shaderProgram = device->createShaderProgram(programDesc);
outShaderProgram = shaderProgram;
return SLANG_OK;
@@ -135,68 +136,53 @@ int exampleMain(int argc, char** argv)
{
testBase.parseOption(argc, argv);
- // Creates a `gfx` renderer, which provides the main interface for
+ // Creates a `slang-rhi` renderer, which provides the main interface for
// interacting with the graphics API.
- Slang::ComPtr<gfx::IDevice> device;
- IDevice::Desc deviceDesc = {};
- SLANG_RETURN_ON_FAIL(gfxCreateDevice(&deviceDesc, device.writeRef()));
-
- Slang::ComPtr<gfx::ITransientResourceHeap> transientHeap;
- ITransientResourceHeap::Desc transientHeapDesc = {};
- transientHeapDesc.constantBufferSize = 4096;
- SLANG_RETURN_ON_FAIL(
- device->createTransientResourceHeap(transientHeapDesc, transientHeap.writeRef()));
+ Slang::ComPtr<IDevice> device;
+ DeviceDesc deviceDesc = {};
+ device = getRHI()->createDevice(deviceDesc);
+ if (!device)
+ return SLANG_FAIL;
// Now we can load the shader code.
- // A `gfx::IShaderProgram` object for use in the `gfx` layer.
- ComPtr<gfx::IShaderProgram> shaderProgram;
+ // A `IShaderProgram` object for use in the `slang-rhi` layer.
+ ComPtr<IShaderProgram> shaderProgram;
// A composed `IComponentType` that gives us reflection info on the shader code.
slang::ProgramLayout* slangReflection;
SLANG_RETURN_ON_FAIL(loadShaderProgram(device, shaderProgram, slangReflection));
// Create a pipeline state with the loaded shader.
- gfx::ComputePipelineStateDesc pipelineDesc = {};
+ ComputePipelineDesc pipelineDesc = {};
pipelineDesc.program = shaderProgram.get();
- ComPtr<gfx::IPipelineState> pipelineState;
- SLANG_RETURN_ON_FAIL(
- device->createComputePipelineState(pipelineDesc, pipelineState.writeRef()));
+ ComPtr<IComputePipeline> pipelineState;
+ pipelineState = device->createComputePipeline(pipelineDesc);
+ if (!pipelineState)
+ return SLANG_FAIL;
// Create and initiate our input/output buffer.
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 bufferDesc = {};
+ bufferDesc.size = numberCount * sizeof(float);
+ bufferDesc.format = Format::Undefined;
bufferDesc.elementSize = sizeof(float);
- bufferDesc.allowedStates = ResourceStateSet(
- ResourceState::ShaderResource,
- ResourceState::UnorderedAccess,
- ResourceState::CopyDestination,
- ResourceState::CopySource);
+ bufferDesc.usage = BufferUsage::ShaderResource | BufferUsage::UnorderedAccess |
+ BufferUsage::CopyDestination | BufferUsage::CopySource;
bufferDesc.defaultState = ResourceState::UnorderedAccess;
bufferDesc.memoryType = MemoryType::DeviceLocal;
- ComPtr<gfx::IBufferResource> numbersBuffer;
- SLANG_RETURN_ON_FAIL(
- device->createBufferResource(bufferDesc, (void*)initialData, numbersBuffer.writeRef()));
-
- // Create a resource view for the buffer.
- ComPtr<gfx::IResourceView> bufferView;
- gfx::IResourceView::Desc viewDesc = {};
- viewDesc.type = gfx::IResourceView::Type::UnorderedAccess;
- viewDesc.format = gfx::Format::Unknown;
- SLANG_RETURN_ON_FAIL(
- device->createBufferView(numbersBuffer, nullptr, viewDesc, bufferView.writeRef()));
+ ComPtr<IBuffer> numbersBuffer;
+ numbersBuffer = device->createBuffer(bufferDesc, (void*)initialData);
+ if (!numbersBuffer)
+ return SLANG_FAIL;
// 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 queue = device->getQueue(QueueType::Graphics);
+ auto commandEncoder = queue->createCommandEncoder();
+ auto encoder = commandEncoder->beginComputePass();
// Now comes the interesting part: binding the shader parameter for the
// compute kernel that we about to launch. We would like to construct
@@ -213,41 +199,38 @@ int exampleMain(int argc, char** argv)
slangReflection->findTypeByName("AddTransformer");
// Now we can use this type to create a shader object that can be bound to the root object.
- ComPtr<gfx::IShaderObject> transformer;
- SLANG_RETURN_ON_FAIL(device->createShaderObject(
- addTransformerType,
- ShaderObjectContainerType::None,
- transformer.writeRef()));
+ ComPtr<IShaderObject> transformer;
+ transformer =
+ device->createShaderObject(addTransformerType, ShaderObjectContainerType::None);
+ if (!transformer)
+ return SLANG_FAIL;
+
// Set the `c` field of the `AddTransformer`.
float c = 1.0f;
- gfx::ShaderCursor(transformer).getPath("c").setData(&c, sizeof(float));
+ ShaderCursor(transformer).getPath("c").setData(&c, sizeof(float));
// We can set parameters directly with `rootObject`, but that requires us to use
// the Slang reflection API to obtain the proper offsets into the root object for each
// parameter. We implemented these logic in the `ShaderCursor` helper class, which
// simplifies the user code to find shader parameters. Here we demonstrate how to set
// parameters with `ShaderCursor`.
- gfx::ShaderCursor entryPointCursor(
+ 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 buffer to the entry point.
+ entryPointCursor.getPath("buffer").setBinding(numbersBuffer);
// 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);
+ encoder->end();
+ queue->submit(commandEncoder->finish());
queue->waitOnHost();
}
// Read back the results.
ComPtr<ISlangBlob> resultBlob;
- SLANG_RETURN_ON_FAIL(device->readBufferResource(
- numbersBuffer,
- 0,
- numberCount * sizeof(float),
- resultBlob.writeRef()));
+ SLANG_RETURN_ON_FAIL(
+ device->readBuffer(numbersBuffer, 0, numberCount * sizeof(float), resultBlob.writeRef()));
auto result = reinterpret_cast<const float*>(resultBlob->getBufferPointer());
for (int i = 0; i < numberCount; i++)
printf("%f\n", result[i]);
diff --git a/examples/shader-toy/main.cpp b/examples/shader-toy/main.cpp
index 42054beae..549dbef73 100644
--- a/examples/shader-toy/main.cpp
+++ b/examples/shader-toy/main.cpp
@@ -21,16 +21,16 @@ using Slang::ComPtr;
//
#include "core/slang-basic.h"
#include "examples/example-base/example-base.h"
-#include "gfx-util/shader-cursor.h"
#include "platform/performance-counter.h"
#include "platform/window.h"
-#include "slang-gfx.h"
+#include "slang-rhi.h"
+#include "slang-rhi/shader-cursor.h"
#include <chrono>
static const ExampleResources resourceBase("shader-toy");
-using namespace gfx;
+using namespace rhi;
// In order to display a shader toy effect using rasterization-based shader
// execution we need to render a full-screen triangle. We will define a
@@ -83,15 +83,15 @@ struct ShaderToyApp : public WindowedAppBase
// The main interesting part of the host application code is where we
// load, compile, inspect, and compose the Slang shader code.
//
- Result loadShaderProgram(gfx::IDevice* device, ComPtr<gfx::IShaderProgram>& outShaderProgram)
+ Result loadShaderProgram(IDevice* device, ComPtr<IShaderProgram>& outShaderProgram)
{
// We need to obatin a compilation session (`slang::ISession`) that will provide
// a scope to all the compilation and loading of code we do.
//
- // Our example application uses the `gfx` graphics API abstraction layer, which already
- // creates a Slang compilation session for us, so we just grab and use it here.
+ // Our example application uses the `slang-rhi` graphics API abstraction layer, which
+ // already creates a Slang compilation session for us, so we just grab and use it here.
ComPtr<slang::ISession> slangSession;
- SLANG_RETURN_ON_FAIL(device->getSlangSession(slangSession.writeRef()));
+ slangSession = device->getSlangSession();
// Once the session has been obtained, we can start loading code into it.
//
@@ -269,16 +269,17 @@ struct ShaderToyApp : public WindowedAppBase
diagnoseIfNeeded(diagnosticsBlob);
SLANG_RETURN_ON_FAIL(result);
- gfx::IShaderProgram::Desc programDesc = {};
+ ShaderProgramDesc programDesc = {};
programDesc.slangGlobalScope = linkedProgram.get();
- auto shaderProgram = device->createProgram(programDesc);
+ auto shaderProgram = device->createShaderProgram(programDesc);
outShaderProgram = shaderProgram;
return SLANG_OK;
}
ComPtr<IShaderProgram> gShaderProgram;
- ComPtr<gfx::IPipelineState> gPipelineState;
- ComPtr<gfx::IBufferResource> gVertexBuffer;
+ ComPtr<IPipeline> gPipeline;
+ ComPtr<IBuffer> gVertexBuffer;
+ const Format format = Format::RG32Float;
Result initialize()
{
@@ -296,7 +297,7 @@ struct ShaderToyApp : public WindowedAppBase
}
InputElementDesc inputElements[] = {
- {"POSITION", 0, Format::R32G32_FLOAT, offsetof(FullScreenTriangle::Vertex, position)},
+ {"POSITION", 0, format, offsetof(FullScreenTriangle::Vertex, position)},
};
auto inputLayout = gDevice->createInputLayout(
sizeof(FullScreenTriangle::Vertex),
@@ -305,29 +306,32 @@ struct ShaderToyApp : public WindowedAppBase
if (!inputLayout)
return SLANG_FAIL;
- IBufferResource::Desc vertexBufferDesc;
- vertexBufferDesc.type = IResource::Type::Buffer;
- vertexBufferDesc.sizeInBytes =
+ BufferDesc vertexBufferDesc;
+ vertexBufferDesc.size =
FullScreenTriangle::kVertexCount * sizeof(FullScreenTriangle::Vertex);
- vertexBufferDesc.defaultState = ResourceState::VertexBuffer;
- gVertexBuffer =
- gDevice->createBufferResource(vertexBufferDesc, &FullScreenTriangle::kVertices[0]);
+ vertexBufferDesc.elementSize = sizeof(FullScreenTriangle::Vertex);
+ vertexBufferDesc.usage = BufferUsage::VertexBuffer;
+ gVertexBuffer = gDevice->createBuffer(vertexBufferDesc, &FullScreenTriangle::kVertices[0]);
if (!gVertexBuffer)
return SLANG_FAIL;
SLANG_RETURN_ON_FAIL(loadShaderProgram(gDevice, gShaderProgram));
// Create pipeline.
- GraphicsPipelineStateDesc desc;
+ ColorTargetDesc colorTarget;
+ colorTarget.format = Format::RGBA8Unorm;
+ RenderPipelineDesc desc;
desc.inputLayout = inputLayout;
desc.program = gShaderProgram;
- desc.framebufferLayout = gFramebufferLayout;
- auto pipelineState = gDevice->createGraphicsPipelineState(desc);
- if (!pipelineState)
+ desc.targetCount = 1;
+ desc.targets = &colorTarget;
+ desc.depthStencil.depthTestEnable = false;
+ desc.depthStencil.depthWriteEnable = false;
+ desc.primitiveTopology = PrimitiveTopology::TriangleList;
+ gPipeline = gDevice->createRenderPipeline(desc);
+ if (!gPipeline)
return SLANG_FAIL;
- gPipelineState = pipelineState;
-
return SLANG_OK;
}
@@ -341,9 +345,9 @@ struct ShaderToyApp : public WindowedAppBase
bool firstTime = true;
platform::TimePoint startTime;
- virtual void renderFrame(int frameIndex) override
+ virtual void renderFrame(ITexture* texture) override
{
- auto commandBuffer = gTransientHeaps[frameIndex]->createCommandBuffer();
+ auto commandEncoder = gQueue->createCommandEncoder();
if (firstTime)
{
startTime = platform::PerformanceCounter::now();
@@ -373,29 +377,43 @@ struct ShaderToyApp : public WindowedAppBase
}
// Encode render commands.
- auto encoder = commandBuffer->encodeRenderCommands(gRenderPass, gFramebuffers[frameIndex]);
-
- gfx::Viewport viewport = {};
- viewport.maxZ = 1.0f;
- viewport.extentX = (float)windowWidth;
- viewport.extentY = (float)windowHeight;
- encoder->setViewportAndScissor(viewport);
- auto rootObject = encoder->bindPipeline(gPipelineState);
+ ComPtr<ITextureView> textureView = gDevice->createTextureView(texture, {});
+ RenderPassColorAttachment colorAttachment = {};
+ colorAttachment.view = textureView;
+ colorAttachment.loadOp = LoadOp::Clear;
+
+ RenderPassDesc renderPass = {};
+ renderPass.colorAttachments = &colorAttachment;
+ renderPass.colorAttachmentCount = 1;
+
+ auto encoder = commandEncoder->beginRenderPass(renderPass);
+
+ RenderState renderState = {};
+ renderState.viewports[0] = Viewport::fromSize(windowWidth, windowHeight);
+ renderState.viewportCount = 1;
+ renderState.scissorRects[0] = ScissorRect::fromSize(windowWidth, windowHeight);
+ renderState.scissorRectCount = 1;
+
+ auto rootObject = encoder->bindPipeline(static_cast<IRenderPipeline*>(gPipeline.get()));
auto constantBuffer = rootObject->getObject(ShaderOffset());
constantBuffer->setData(ShaderOffset(), &uniforms, sizeof(uniforms));
- encoder->setVertexBuffer(0, gVertexBuffer);
- encoder->setPrimitiveTopology(PrimitiveTopology::TriangleList);
- encoder->draw(3);
- encoder->endEncoding();
- commandBuffer->close();
+ renderState.vertexBuffers[0] = gVertexBuffer;
+ renderState.vertexBufferCount = 1;
+ encoder->setRenderState(renderState);
- gQueue->executeCommandBuffer(commandBuffer);
+ DrawArguments drawArgs = {};
+ drawArgs.vertexCount = 3;
+ encoder->draw(drawArgs);
- // We may not have a swapchain if we're running in test mode
- SLANG_ASSERT(isTestMode() || gSwapchain);
- if (gSwapchain)
- gSwapchain->present();
+ encoder->end();
+
+ gQueue->submit(commandEncoder->finish());
+
+ if (!isTestMode())
+ {
+ gSurface->present();
+ }
}
void handleEvent(const platform::MouseEventArgs& event)
diff --git a/examples/triangle/main.cpp b/examples/triangle/main.cpp
index 4d4779f73..6f61a6c76 100644
--- a/examples/triangle/main.cpp
+++ b/examples/triangle/main.cpp
@@ -34,12 +34,13 @@
//
#include "core/slang-basic.h"
#include "examples/example-base/example-base.h"
-#include "gfx-util/shader-cursor.h"
#include "platform/window.h"
#include "slang-com-ptr.h"
-#include "slang-gfx.h"
+#include "slang-rhi.h"
-using namespace gfx;
+#include <slang-rhi/shader-cursor.h>
+
+using namespace rhi;
using namespace Slang;
static const ExampleResources resourceBase("triangle");
@@ -88,7 +89,7 @@ struct HelloWorld : public WindowedAppBase
// In addition, an application may want to receive reflection information
// about the program, which is what a `slang::ProgramLayout` provides.
//
- gfx::Result loadShaderProgram(gfx::IDevice* device, gfx::IShaderProgram** outProgram)
+ Result loadShaderProgram(IDevice* device, IShaderProgram** outProgram)
{
// We need to obtain a compilation session (`slang::ISession`) that will provide
// a scope to all the compilation and loading of code we do.
@@ -183,9 +184,9 @@ struct HelloWorld : public WindowedAppBase
// to extract compiled kernel code and load it into the API-specific
// program representation.
//
- gfx::IShaderProgram::Desc programDesc = {};
+ ShaderProgramDesc programDesc = {};
programDesc.slangGlobalScope = linkedProgram;
- SLANG_RETURN_ON_FAIL(device->createProgram(programDesc, outProgram));
+ SLANG_RETURN_ON_FAIL(device->createShaderProgram(programDesc, outProgram));
if (isTestMode())
{
@@ -212,8 +213,9 @@ struct HelloWorld : public WindowedAppBase
// of them come from the utility library we are using to simplify
// building an example program.
//
- ComPtr<gfx::IPipelineState> gPipelineState;
- ComPtr<gfx::IBufferResource> gVertexBuffer;
+ ComPtr<IPipeline> gPipeline;
+ ComPtr<IBuffer> gVertexBuffer;
+ const Format format = Format::RGB32Float;
// Now that we've covered the function that actually loads and
// compiles our Slang shade code, we can go through the rest
@@ -231,8 +233,8 @@ struct HelloWorld : public WindowedAppBase
// First, we create an input layout:
//
InputElementDesc inputElements[] = {
- {"POSITION", 0, Format::R32G32B32_FLOAT, offsetof(Vertex, position)},
- {"COLOR", 0, Format::R32G32B32_FLOAT, offsetof(Vertex, color)},
+ {"POSITION", 0, format, offsetof(Vertex, position)},
+ {"COLOR", 0, format, offsetof(Vertex, color)},
};
auto inputLayout = gDevice->createInputLayout(sizeof(Vertex), &inputElements[0], 2);
if (!inputLayout)
@@ -241,11 +243,12 @@ struct HelloWorld : public WindowedAppBase
// Next we allocate a vertex buffer for our pre-initialized
// vertex data.
//
- IBufferResource::Desc vertexBufferDesc;
- vertexBufferDesc.type = IResource::Type::Buffer;
- vertexBufferDesc.sizeInBytes = kVertexCount * sizeof(Vertex);
- vertexBufferDesc.defaultState = ResourceState::VertexBuffer;
- gVertexBuffer = gDevice->createBufferResource(vertexBufferDesc, &kVertexData[0]);
+ BufferDesc vertexBufferDesc;
+ vertexBufferDesc.format = format;
+ vertexBufferDesc.size = kVertexCount * sizeof(Vertex);
+ vertexBufferDesc.elementSize = sizeof(Vertex);
+ vertexBufferDesc.usage = BufferUsage::VertexBuffer;
+ gVertexBuffer = gDevice->createBuffer(vertexBufferDesc, &kVertexData[0]);
if (!gVertexBuffer)
return SLANG_FAIL;
@@ -258,16 +261,20 @@ struct HelloWorld : public WindowedAppBase
// Following the D3D12/Vulkan style of API, we need a pipeline state object
// (PSO) to encapsulate the configuration of the overall graphics pipeline.
//
- GraphicsPipelineStateDesc desc;
+ ColorTargetDesc colorTarget;
+ colorTarget.format = format;
+ RenderPipelineDesc desc;
desc.inputLayout = inputLayout;
desc.program = shaderProgram;
- desc.framebufferLayout = gFramebufferLayout;
- auto pipelineState = gDevice->createGraphicsPipelineState(desc);
- if (!pipelineState)
+ desc.targetCount = 1;
+ desc.targets = &colorTarget;
+ desc.depthStencil.depthTestEnable = false;
+ desc.depthStencil.depthWriteEnable = false;
+ desc.primitiveTopology = PrimitiveTopology::TriangleList;
+ gPipeline = gDevice->createRenderPipeline(desc);
+ if (!gPipeline)
return SLANG_FAIL;
- gPipelineState = pipelineState;
-
return SLANG_OK;
}
@@ -276,18 +283,27 @@ struct HelloWorld : public WindowedAppBase
// nothing really Slang-specific here, so the commentary doesn't need
// to be very detailed.
//
- virtual void renderFrame(int frameBufferIndex) override
+ virtual void renderFrame(ITexture* texture) override
{
- ComPtr<ICommandBuffer> commandBuffer =
- gTransientHeaps[frameBufferIndex]->createCommandBuffer();
- auto renderEncoder =
- commandBuffer->encodeRenderCommands(gRenderPass, gFramebuffers[frameBufferIndex]);
+ auto commandEncoder = gQueue->createCommandEncoder();
+
+ ComPtr<ITextureView> textureView = gDevice->createTextureView(texture, {});
+ RenderPassColorAttachment colorAttachment = {};
+ colorAttachment.view = textureView;
+ colorAttachment.loadOp = LoadOp::Clear;
+
+ RenderPassDesc renderPass = {};
+ renderPass.colorAttachments = &colorAttachment;
+ renderPass.colorAttachmentCount = 1;
- gfx::Viewport viewport = {};
- viewport.maxZ = 1.0f;
- viewport.extentX = (float)windowWidth;
- viewport.extentY = (float)windowHeight;
- renderEncoder->setViewportAndScissor(viewport);
+ auto renderEncoder = commandEncoder->beginRenderPass(renderPass);
+
+
+ RenderState renderState = {};
+ renderState.viewports[0] = Viewport::fromSize(windowWidth, windowHeight);
+ renderState.viewportCount = 1;
+ renderState.scissorRects[0] = ScissorRect::fromSize(windowWidth, windowHeight);
+ renderState.scissorRectCount = 1;
// In order to bind shader parameters to the pipeline, we need
// to know how those parameters were assigned to locations/bindings/registers
@@ -319,14 +335,15 @@ struct HelloWorld : public WindowedAppBase
// This method will return a transient root shader object for us to write our
// shader parameters into.
//
- auto rootObject = renderEncoder->bindPipeline(gPipelineState);
+ auto rootObject =
+ renderEncoder->bindPipeline(static_cast<IRenderPipeline*>(gPipeline.get()));
// We will update the model-view-projection matrix that is passed
// into the shader code via the `Uniforms` buffer on a per-frame
// basis, even though the data that is loaded does not change
// per-frame (we always use an identity matrix).
//
- auto deviceInfo = gDevice->getDeviceInfo();
+ auto deviceInfo = gDevice->getInfo();
// We know that `rootObject` is a root shader object created
// from our program, and that it is set up to hold values for
@@ -361,9 +378,7 @@ struct HelloWorld : public WindowedAppBase
// Once we have formed a cursor that "points" at the
// model-view projection matrix, we can set its data directly.
//
- rootCursor["Uniforms"]["modelViewProjection"].setData(
- deviceInfo.identityProjectionMatrix,
- sizeof(float) * 16);
+ rootCursor["Uniforms"]["modelViewProjection"].setData(kIdentity, sizeof(float) * 16);
//
// Some readers might be concerned about the performance of
// the above operations because of the use of strings. For
@@ -384,21 +399,24 @@ struct HelloWorld : public WindowedAppBase
// We also need to set up a few pieces of fixed-function pipeline
// state that are not bound by the pipeline state above.
//
- renderEncoder->setVertexBuffer(0, gVertexBuffer);
- renderEncoder->setPrimitiveTopology(PrimitiveTopology::TriangleList);
+ renderState.vertexBuffers[0] = gVertexBuffer;
+ renderState.vertexBufferCount = 1;
+ renderEncoder->setRenderState(renderState);
// Finally, we are ready to issue a draw call for a single triangle.
//
- renderEncoder->draw(3);
- renderEncoder->endEncoding();
- commandBuffer->close();
- gQueue->executeCommandBuffer(commandBuffer);
+ DrawArguments drawArgs = {};
+ drawArgs.vertexCount = 3;
+ renderEncoder->draw(drawArgs);
+
+ renderEncoder->end();
+ gQueue->submit(commandEncoder->finish());
if (!isTestMode())
{
// With that, we are done drawing for one frame, and ready for the next.
//
- gSwapchain->present();
+ gSurface->present();
}
}
};
diff --git a/lock b/lock
deleted file mode 100644
index e69de29bb..000000000
--- a/lock
+++ /dev/null
diff --git a/tests/cpu-program/gfx-smoke.slang b/tests/cpu-program/gfx-smoke.slang
deleted file mode 100644
index 3ed04877e..000000000
--- a/tests/cpu-program/gfx-smoke.slang
+++ /dev/null
@@ -1,101 +0,0 @@
-//TEST:EXECUTABLE:
-import gfx;
-import slang;
-
-export __extern_cpp int main()
-{
- gfx.DeviceDesc deviceDesc = {};
- deviceDesc.deviceType = gfx.DeviceType.CPU;
- Optional<gfx.IDevice> device;
- gfx.gfxCreateDevice(&deviceDesc, device);
- if (device == none)
- {
- printf("fail\n");
- return -1;
- }
-
- gfx.CommandQueueDesc queueDesc = {gfx::QueueType::Graphics};
- queueDesc.type = gfx.QueueType.Graphics;
- Optional<gfx.ICommandQueue> queue;
- device.value.createCommandQueue(&queueDesc, queue);
-
- gfx.ShaderProgramDesc2 programDesc = {};
- NativeString s = R"(
- [shader("compute")]
- [numthreads(4, 1, 1)]
- void computeMain(
- uint3 sv_dispatchThreadID: SV_DispatchThreadID,
- uniform RWStructuredBuffer<float> buffer
- )
- {
- var input = buffer[sv_dispatchThreadID.x];
- buffer[sv_dispatchThreadID.x] = sv_dispatchThreadID.x;
- })";
- programDesc.sourceData = s;
- programDesc.sourceType = gfx.ShaderModuleSourceType.SlangSource;
- programDesc.sourceDataSize = s.length;
- programDesc.entryPointCount = 1;
- NativeString entryPointName = "computeMain";
- programDesc.entryPointNames = &entryPointName;
- Optional<gfx.IShaderProgram> program;
- Optional<slang.ISlangBlob> diagBlob;
- device.value.createProgram2(&programDesc, program, diagBlob);
-
- Optional<gfx.IPipelineState> pipeline;
- gfx.ComputePipelineStateDesc pipelineDesc;
- pipelineDesc.program = NativeRef<gfx.IShaderProgram>(program.value);
- device.value.createComputePipelineState(&pipelineDesc, pipeline);
-
- Optional<gfx.ITransientResourceHeap> transientHeap;
- gfx.TransientResourceHeapDesc transientHeapDesc;
- transientHeapDesc.constantBufferDescriptorCount = 64;
- transientHeapDesc.constantBufferSize = 1024;
- transientHeapDesc.srvDescriptorCount = 1024;
- transientHeapDesc.uavDescriptorCount = 1024;
- transientHeapDesc.samplerDescriptorCount = 256;
- transientHeapDesc.accelerationStructureDescriptorCount = 32;
- device.value.createTransientResourceHeap(&transientHeapDesc, transientHeap);
-
- Optional<gfx.IBufferResource> buffer;
- gfx.BufferResourceDesc bufferDesc = {};
- bufferDesc.memoryType = gfx.MemoryType.DeviceLocal;
- bufferDesc.allowedStates.add(gfx.ResourceState.UnorderedAccess);
- bufferDesc.defaultState = gfx.ResourceState.UnorderedAccess;
- bufferDesc.elementSize = 4;
- bufferDesc.sizeInBytes = 256;
- bufferDesc.type = gfx.ResourceType.Buffer;
- device.value.createBufferResource(&bufferDesc, nullptr, buffer);
-
- Optional<gfx.IResourceView> bufferView;
- gfx.ResourceViewDesc viewDesc;
- viewDesc.type = gfx.ResourceViewType.UnorderedAccess;
- device.value.createBufferView(buffer.value, none, &viewDesc, bufferView);
-
- Optional<gfx.ICommandBuffer> commandBuffer;
- transientHeap.value.createCommandBuffer(commandBuffer);
- Optional<gfx.IComputeCommandEncoder> encoder;
- commandBuffer.value.encodeComputeCommands(encoder);
- Optional<gfx.IShaderObject> rootObject;
- encoder.value.bindPipeline(pipeline.value, rootObject);
- Optional<gfx.IShaderObject> entryPointObject;
- rootObject.value.getEntryPoint(0, entryPointObject);
- gfx.ShaderOffset offset = {};
- entryPointObject.value.setResource(&offset, bufferView.value);
- encoder.value.dispatchCompute(1, 1, 1);
- encoder.value.endEncoding();
- commandBuffer.value.close();
-
- NativeRef<gfx.ICommandBuffer> commandBufferRef = NativeRef<gfx.ICommandBuffer>(commandBuffer.value);
- queue.value.executeCommandBuffers(1, &commandBufferRef, none, 0);
- queue.value.waitOnHost();
-
- Optional<slang.ISlangBlob> blob;
- device.value.readBufferResource(buffer.value, 0, 16, blob);
-
- for (int i = 0; i < 4; i++)
- {
- float val = ((float *)blob.value.getBufferPointer())[i];
- printf("%.1f\n", val);
- }
- return 0;
-}
diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt
index 8b954154b..a004a87ca 100644
--- a/tools/CMakeLists.txt
+++ b/tools/CMakeLists.txt
@@ -139,119 +139,47 @@ if(SLANG_ENABLE_GFX)
imgui
stb
$<$<BOOL:${SLANG_ENABLE_XLIB}>:X11::X11>
+ $<$<BOOL:${SLANG_ENABLE_SLANG_RHI}>:slang-rhi>
"$<$<PLATFORM_ID:Darwin>:-framework Cocoa>"
"$<$<PLATFORM_ID:Darwin>:-framework QuartzCore>"
${CMAKE_DL_LIBS}
LINK_WITH_FRAMEWORK Foundation Cocoa QuartzCore
EXTRA_COMPILE_DEFINITIONS_PRIVATE
$<$<BOOL:${SLANG_ENABLE_XLIB}>:SLANG_ENABLE_XLIB=1>
- INCLUDE_FROM_PRIVATE gfx
- INCLUDE_DIRECTORIES_PUBLIC . platform
- EXPORT_MACRO_PREFIX SLANG_PLATFORM
- )
-
- #
- # GFX
- #
- slang_add_target(
- gfx
- ${SLANG_LIB_TYPE}
- USE_FEWER_WARNINGS
- LINK_WITH_PRIVATE
- core
- slang
- Vulkan-Headers
- metal-cpp
- stb
- $<$<BOOL:${SLANG_ENABLE_XLIB}>:X11::X11>
- $<$<BOOL:${SLANG_ENABLE_CUDA}>:CUDA::cuda_driver>
- $<$<BOOL:${SLANG_ENABLE_NVAPI}>:${NVAPI_LIBRARIES}>
- LINK_WITH_FRAMEWORK Foundation Cocoa QuartzCore Metal
- EXTRA_COMPILE_DEFINITIONS_PRIVATE
- $<$<BOOL:${SLANG_ENABLE_CUDA}>:GFX_ENABLE_CUDA>
- $<$<BOOL:${SLANG_ENABLE_OPTIX}>:GFX_OPTIX>
- $<$<BOOL:${SLANG_ENABLE_NVAPI}>:GFX_NVAPI>
- $<$<BOOL:${SLANG_ENABLE_XLIB}>:SLANG_ENABLE_XLIB>
- # This is a shared library, so we need to set a preprocessor macro to mark
- # exported symbols
- EXPORT_MACRO_PREFIX SLANG_GFX
- # slang-gfx is in this directory, anything which depends on gfx should include
- # this
- INCLUDE_DIRECTORIES_PUBLIC
- ${slang_SOURCE_DIR}
- ${slang_SOURCE_DIR}/include
- if
- (not ${SLANG_OVERRIDE_SPIRV_TOOLS_PATH})
- INCLUDE_DIRECTORIES_PUBLIC ${slang_SOURCE_DIR}/external else ()
+ INCLUDE_FROM_PRIVATE
+ imgui
+ $<$<BOOL:${SLANG_ENABLE_SLANG_RHI}>:slang-rhi>
INCLUDE_DIRECTORIES_PUBLIC
- ${SLANG_OVERRIDE_SPIRV_TOOLS_PATH}
- endif
- ()
+ .
+ platform
if
(not ${SLANG_OVERRIDE_GLM_PATH})
INCLUDE_DIRECTORIES_PUBLIC ${slang_SOURCE_DIR}/external else ()
- INCLUDE_DIRECTORIES_PUBLIC
- ${SLANG_OVERRIDE_GLM_PATH}
- endif
- ()
- if
- (not ${SLANG_OVERRIDE_IMGUI_PATH})
- INCLUDE_DIRECTORIES_PUBLIC ${slang_SOURCE_DIR}/external else ()
- INCLUDE_DIRECTORIES_PUBLIC
- ${SLANG_OVERRIDE_IMGUI_PATH}
- endif
- ()
- if
- (not ${SLANG_OVERRIDE_TINYOBJLOADER_PATH})
- INCLUDE_DIRECTORIES_PUBLIC ${slang_SOURCE_DIR}/external else ()
- INCLUDE_DIRECTORIES_PUBLIC ${SLANG_OVERRIDE_TINYOBJLOADER_PATH} endif ()
- INCLUDE_DIRECTORIES_PRIVATE ${NVAPI_INCLUDE_DIRS}
- INSTALL
- EXPORT_SET_NAME SlangTargets
- FOLDER gfx
+ INCLUDE_DIRECTORIES_PUBLIC ${SLANG_OVERRIDE_GLM_PATH} endif ()
+ EXPORT_MACRO_PREFIX SLANG_PLATFORM
)
- if(SLANG_ENABLE_TESTS)
- set(modules_dest_dir $<TARGET_FILE_DIR:slang-test>)
- add_custom_target(
- copy-gfx-slang-modules
- COMMAND ${CMAKE_COMMAND} -E make_directory ${modules_dest_dir}
- COMMAND
- ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_LIST_DIR}/gfx/gfx.slang
- ${modules_dest_dir}/gfx.slang
- COMMAND
- ${CMAKE_COMMAND} -E copy
- ${CMAKE_CURRENT_LIST_DIR}/gfx/slang.slang
- ${modules_dest_dir}/slang.slang
- WORKING_DIRECTORY ${slang_SOURCE_DIR}
- VERBATIM
- )
- set_target_properties(
- copy-gfx-slang-modules
- PROPERTIES FOLDER generators
- )
- install(
- FILES ${modules_dest_dir}/gfx.slang ${modules_dest_dir}/slang.slang
- DESTINATION ${runtime_subdir}
- )
- add_dependencies(gfx copy-gfx-slang-modules)
- endif()
- slang_add_target(
- gfx-util
- STATIC
- LINK_WITH_PRIVATE core
- INCLUDE_FROM_PRIVATE gfx
- # The headers are included with 'include "gfx-util/blah.h"' which is found
- # in the tools directory
- INCLUDE_DIRECTORIES_PUBLIC .
- FOLDER gfx
+ set(modules_dest_dir $<TARGET_FILE_DIR:slang-test>)
+ add_custom_target(
+ copy-gfx-slang-modules
+ COMMAND ${CMAKE_COMMAND} -E make_directory ${modules_dest_dir}
+ COMMAND
+ ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_LIST_DIR}/gfx/gfx.slang
+ ${modules_dest_dir}/gfx.slang
+ COMMAND
+ ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_LIST_DIR}/gfx/slang.slang
+ ${modules_dest_dir}/slang.slang
+ WORKING_DIRECTORY ${slang_SOURCE_DIR}
+ VERBATIM
+ )
+ set_target_properties(copy-gfx-slang-modules PROPERTIES FOLDER generators)
+ install(
+ FILES ${modules_dest_dir}/gfx.slang ${modules_dest_dir}/slang.slang
+ DESTINATION ${runtime_subdir}
)
endif()
-
-#
-# The test executables and runtime-loaded modules
-#
if(SLANG_ENABLE_TESTS)
+ # The test executables and runtime-loaded modules
slang_add_target(
test-server
EXECUTABLE
@@ -292,7 +220,6 @@ if(SLANG_ENABLE_TESTS)
test-server
test-process
OPTIONAL_REQUIRES
- gfx
slang-rt
slang-glslang
slang-llvm
@@ -307,6 +234,9 @@ if(SLANG_ENABLE_TESTS)
DIRECTORY ${slang_SOURCE_DIR}
PROPERTY VS_STARTUP_PROJECT slang-test
)
+
+ add_dependencies(slang-test copy-gfx-slang-modules)
+
include(CTest)
add_test(
NAME slang-test
@@ -338,7 +268,21 @@ if(SLANG_ENABLE_TESTS)
EXCLUDE_FROM_ALL
EXTRA_COMPILE_DEFINITIONS_PRIVATE SLANG_SHARED_LIBRARY_TOOL
USE_FEWER_WARNINGS
- LINK_WITH_PRIVATE core slang unit-test gfx gfx-util platform stb
+ LINK_WITH_PRIVATE
+ core
+ slang
+ unit-test
+ stb
+ platform
+ $<$<BOOL:${SLANG_ENABLE_SLANG_RHI}>:slang-rhi>
+ INCLUDE_FROM_PRIVATE $<$<BOOL:${SLANG_ENABLE_SLANG_RHI}>:slang-rhi>
+ INCLUDE_DIRECTORIES_PUBLIC
+ .
+ platform
+ if
+ (not ${SLANG_OVERRIDE_GLM_PATH})
+ INCLUDE_DIRECTORIES_PUBLIC ${slang_SOURCE_DIR}/external else ()
+ INCLUDE_DIRECTORIES_PUBLIC ${SLANG_OVERRIDE_GLM_PATH} endif ()
OUTPUT_NAME gfx-unit-test-tool
REQUIRED_BY slang-test
FOLDER test/tools
diff --git a/tools/gfx-unit-test/buffer-barrier-test.cpp b/tools/gfx-unit-test/buffer-barrier-test.cpp
index b128448d2..1d965628a 100644
--- a/tools/gfx-unit-test/buffer-barrier-test.cpp
+++ b/tools/gfx-unit-test/buffer-barrier-test.cpp
@@ -1,10 +1,11 @@
#include "core/slang-basic.h"
#include "gfx-test-util.h"
-#include "gfx-util/shader-cursor.h"
-#include "slang-gfx.h"
+#include "slang-rhi.h"
#include "unit-test/slang-unit-test.h"
-using namespace gfx;
+#include <slang-rhi/shader-cursor.h>
+
+using namespace rhi;
namespace gfx_test
{
@@ -12,58 +13,40 @@ struct Shader
{
ComPtr<IShaderProgram> program;
slang::ProgramLayout* reflection = nullptr;
- ComputePipelineStateDesc pipelineDesc = {};
- ComPtr<gfx::IPipelineState> pipelineState;
+ ComputePipelineDesc pipelineDesc = {};
+ ComPtr<IComputePipeline> pipeline;
};
struct Buffer
{
- IBufferResource::Desc desc;
- ComPtr<IBufferResource> buffer;
- ComPtr<IResourceView> view;
+ BufferDesc desc;
+ ComPtr<IBuffer> buffer;
+ ComPtr<ITextureView> view;
};
-void createFloatBuffer(
+ComPtr<IBuffer> createFloatBuffer(
IDevice* device,
- Buffer& outBuffer,
bool unorderedAccess,
- float* initialData,
- size_t elementCount)
+ size_t elementCount,
+ float* initialData = nullptr)
{
- 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);
+ BufferDesc desc = {};
+ desc.size = elementCount * sizeof(float);
+ desc.elementSize = sizeof(float);
+ desc.format = Format::Undefined;
+ desc.memoryType = MemoryType::DeviceLocal;
+ desc.usage =
+ BufferUsage::ShaderResource | BufferUsage::CopyDestination | BufferUsage::CopySource;
if (unorderedAccess)
- bufferDesc.allowedStates.add(ResourceState::UnorderedAccess);
-
- GFX_CHECK_CALL_ABORT(
- device->createBufferResource(bufferDesc, (void*)initialData, outBuffer.buffer.writeRef()));
+ desc.usage |= BufferUsage::UnorderedAccess;
- 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()));
+ ComPtr<IBuffer> buffer;
+ GFX_CHECK_CALL_ABORT(device->createBuffer(desc, (void*)initialData, buffer.writeRef()));
+ return buffer;
}
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(
@@ -80,106 +63,74 @@ void barrierTestImpl(IDevice* device, UnitTestContext* context)
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);
+ GFX_CHECK_CALL_ABORT(
+ device->createComputePipeline(programA.pipelineDesc, programA.pipeline.writeRef()));
- Buffer intermediateBuffer;
- createFloatBuffer(device, intermediateBuffer, true, nullptr, 4);
+ GFX_CHECK_CALL_ABORT(
+ device->createComputePipeline(programB.pipelineDesc, programB.pipeline.writeRef()));
- Buffer outputBuffer;
- createFloatBuffer(device, outputBuffer, true, nullptr, 4);
+ float initialData[] = {1.0f, 2.0f, 3.0f, 4.0f};
+ ComPtr<IBuffer> inputBuffer = createFloatBuffer(device, false, 4, initialData);
+ ComPtr<IBuffer> intermediateBuffer = createFloatBuffer(device, true, 4, nullptr);
+ ComPtr<IBuffer> outputBuffer = createFloatBuffer(device, true, 4, nullptr);
// 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();
+ auto queue = device->getQueue(QueueType::Graphics);
+ auto commandEncoder = queue->createCommandEncoder();
// 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);
+ {
+ auto passEncoder = commandEncoder->beginComputePass();
+ auto rootObject = passEncoder->bindPipeline(programA.pipeline);
+
+ ShaderCursor cursor(rootObject->getEntryPoint(0));
+ cursor["inBuffer"].setBinding(inputBuffer);
+ cursor["outBuffer"].setBinding(intermediateBuffer);
+ passEncoder->dispatchCompute(1, 1, 1);
+ passEncoder->end();
+ }
+
+ // Resource transition is automatically handled.
+
+ // Write intermediateBuffer data to outputBuffer
+
+ {
+ auto passEncoder = commandEncoder->beginComputePass();
+ auto rootObject = passEncoder->bindPipeline(programB.pipeline);
+ ShaderCursor cursor(rootObject->getEntryPoint(0));
+ cursor["inBuffer"].setBinding(intermediateBuffer);
+ cursor["outBuffer"].setBinding(outputBuffer);
+ passEncoder->dispatchCompute(1, 1, 1);
+ passEncoder->end();
+ }
+
+
+ queue->submit(commandEncoder->finish());
queue->waitOnHost();
}
- compareComputeResult(
- device,
- outputBuffer.buffer,
- Slang::makeArray<float>(11.0f, 12.0f, 13.0f, 14.0f));
+
+ compareComputeResult(device, outputBuffer, makeArray<float>(11.0f, 12.0f, 13.0f, 14.0f));
}
-void barrierTestAPI(UnitTestContext* context, Slang::RenderApiFlag::Enum api)
+void barrierTestAPI(UnitTestContext* context, DeviceType deviceType)
{
- gfxEnableDebugLayer(context->enableDebugLayers);
- 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::List<const char*> searchPaths = {"", "../../tools/gfx-unit-test", "tools/gfx-unit-test"};
+ auto device = createTestingDevice(context, deviceType, searchPaths);
+
+ if (!device)
{
SLANG_IGNORE_TEST
}
- barrierTestImpl(device, context);
+ barrierTestImpl(device.get(), context);
}
SLANG_UNIT_TEST(bufferBarrierVulkan)
{
- barrierTestAPI(unitTestContext, Slang::RenderApiFlag::Vulkan);
+ barrierTestAPI(unitTestContext, DeviceType::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 3e1efae0a..8f742f132 100644
--- a/tools/gfx-unit-test/clear-texture-test.cpp
+++ b/tools/gfx-unit-test/clear-texture-test.cpp
@@ -1,7 +1,10 @@
+#if 0
+// Duplicated: this is covered by slang-rhi\tests\test-cmd-clear-texture.cpp
+
#include "core/slang-basic.h"
#include "gfx-test-util.h"
-#include "gfx-util/shader-cursor.h"
#include "slang-gfx.h"
+#include "slang-rhi/shader-cursor.h"
#include "unit-test/slang-unit-test.h"
using namespace Slang;
@@ -90,3 +93,5 @@ SLANG_UNIT_TEST(clearTextureTestVulkan)
runTestImpl(clearTextureTestImpl, unitTestContext, Slang::RenderApiFlag::Vulkan);
}
} // namespace gfx_test
+
+#endif
diff --git a/tools/gfx-unit-test/compute-smoke.cpp b/tools/gfx-unit-test/compute-smoke.cpp
index ba1da2283..da1db8185 100644
--- a/tools/gfx-unit-test/compute-smoke.cpp
+++ b/tools/gfx-unit-test/compute-smoke.cpp
@@ -1,65 +1,46 @@
#include "core/slang-basic.h"
#include "gfx-test-util.h"
-#include "gfx-util/shader-cursor.h"
-#include "slang-gfx.h"
+#include "slang-rhi.h"
+#include "slang-rhi/shader-cursor.h"
#include "unit-test/slang-unit-test.h"
-using namespace gfx;
+using namespace rhi;
namespace gfx_test
{
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 = {};
+ ComputePipelineDesc pipelineDesc = {};
pipelineDesc.program = shaderProgram.get();
- ComPtr<gfx::IPipelineState> pipelineState;
- GFX_CHECK_CALL_ABORT(
- device->createComputePipelineState(pipelineDesc, pipelineState.writeRef()));
+ ComPtr<IComputePipeline> pipelineState;
+ GFX_CHECK_CALL_ABORT(device->createComputePipeline(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 bufferDesc = {};
+ bufferDesc.size = numberCount * sizeof(float);
+ bufferDesc.format = rhi::Format::Undefined;
bufferDesc.elementSize = sizeof(float);
- bufferDesc.allowedStates = ResourceStateSet(
- ResourceState::ShaderResource,
- ResourceState::UnorderedAccess,
- ResourceState::CopyDestination,
- ResourceState::CopySource);
+ bufferDesc.usage = BufferUsage::ShaderResource | BufferUsage::UnorderedAccess |
+ BufferUsage::CopyDestination | BufferUsage::CopySource;
bufferDesc.defaultState = ResourceState::UnorderedAccess;
bufferDesc.memoryType = MemoryType::DeviceLocal;
- ComPtr<IBufferResource> numbersBuffer;
+ ComPtr<IBuffer> 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()));
+ device->createBuffer(bufferDesc, (void*)initialData, numbersBuffer.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 queue = device->getQueue(QueueType::Graphics);
+ auto commandEncoder = queue->createCommandEncoder();
+ auto encoder = commandEncoder->beginComputePass();
auto rootObject = encoder->bindPipeline(pipelineState);
@@ -78,38 +59,35 @@ void computeSmokeTestImpl(IDevice* device, UnitTestContext* context)
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 buffer to the entry point.
+ entryPointCursor.getPath("buffer").setBinding(Binding(numbersBuffer));
// 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);
+ encoder->end();
+ auto commandBuffer = commandEncoder->finish();
+ queue->submit(commandBuffer);
queue->waitOnHost();
}
- compareComputeResult(
- device,
- numbersBuffer,
- Slang::makeArray<float>(11.0f, 12.0f, 13.0f, 14.0f));
+ compareComputeResult(device, numbersBuffer, std::array{11.0f, 12.0f, 13.0f, 14.0f});
}
SLANG_UNIT_TEST(computeSmokeD3D12)
{
- runTestImpl(computeSmokeTestImpl, unitTestContext, Slang::RenderApiFlag::D3D12);
+ runTestImpl(computeSmokeTestImpl, unitTestContext, DeviceType::D3D12);
}
SLANG_UNIT_TEST(computeSmokeD3D11)
{
- runTestImpl(computeSmokeTestImpl, unitTestContext, Slang::RenderApiFlag::D3D11);
+ runTestImpl(computeSmokeTestImpl, unitTestContext, DeviceType::D3D11);
}
SLANG_UNIT_TEST(computeSmokeVulkan)
{
- runTestImpl(computeSmokeTestImpl, unitTestContext, Slang::RenderApiFlag::Vulkan);
+ runTestImpl(computeSmokeTestImpl, unitTestContext, DeviceType::Vulkan);
}
} // namespace gfx_test
diff --git a/tools/gfx-unit-test/compute-trivial.cpp b/tools/gfx-unit-test/compute-trivial.cpp
index c89748229..8521be289 100644
--- a/tools/gfx-unit-test/compute-trivial.cpp
+++ b/tools/gfx-unit-test/compute-trivial.cpp
@@ -1,21 +1,15 @@
#include "core/slang-basic.h"
#include "gfx-test-util.h"
-#include "gfx-util/shader-cursor.h"
-#include "slang-gfx.h"
+#include "slang-rhi.h"
+#include "slang-rhi/shader-cursor.h"
#include "unit-test/slang-unit-test.h"
-using namespace gfx;
+using namespace rhi;
namespace gfx_test
{
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(
@@ -25,74 +19,63 @@ void computeTrivialTestImpl(IDevice* device, UnitTestContext* context)
"computeMain",
slangReflection));
- ComputePipelineStateDesc pipelineDesc = {};
+ ComputePipelineDesc pipelineDesc = {};
pipelineDesc.program = shaderProgram.get();
- ComPtr<gfx::IPipelineState> pipelineState;
- GFX_CHECK_CALL_ABORT(
- device->createComputePipelineState(pipelineDesc, pipelineState.writeRef()));
+ ComPtr<IComputePipeline> pipelineState;
+ GFX_CHECK_CALL_ABORT(device->createComputePipeline(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 bufferDesc = {};
+ bufferDesc.size = numberCount * sizeof(float);
+ bufferDesc.format = Format::Undefined;
bufferDesc.elementSize = sizeof(float);
- bufferDesc.allowedStates = ResourceStateSet(
- ResourceState::ShaderResource,
- ResourceState::UnorderedAccess,
- ResourceState::CopyDestination,
- ResourceState::CopySource);
+ bufferDesc.usage = BufferUsage::ShaderResource | BufferUsage::UnorderedAccess |
+ BufferUsage::CopyDestination | BufferUsage::CopySource;
bufferDesc.defaultState = ResourceState::UnorderedAccess;
bufferDesc.memoryType = MemoryType::DeviceLocal;
- ComPtr<IBufferResource> numbersBuffer;
+ ComPtr<IBuffer> 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()));
+ device->createBuffer(bufferDesc, (void*)initialData, numbersBuffer.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 queue = device->getQueue(QueueType::Graphics);
+ auto commandEncoder = queue->createCommandEncoder();
+ {
+ auto encoder = commandEncoder->beginComputePass();
+ auto rootObject = encoder->bindPipeline(pipelineState);
- auto rootObject = encoder->bindPipeline(pipelineState);
+ // Bind buffer directly to the entry point.
+ ShaderCursor(rootObject).getPath("buffer").setBinding(Binding(numbersBuffer));
- // Bind buffer view to the entry point.
- ShaderCursor(rootObject).getPath("buffer").setResource(bufferView);
+ encoder->dispatchCompute(1, 1, 1);
+ encoder->end();
+ }
- encoder->dispatchCompute(1, 1, 1);
- encoder->endEncoding();
- commandBuffer->close();
- queue->executeCommandBuffer(commandBuffer);
+ auto commandBuffer = commandEncoder->finish();
+ queue->submit(commandBuffer);
queue->waitOnHost();
}
- compareComputeResult(device, numbersBuffer, Slang::makeArray<float>(1.0f, 2.0f, 3.0f, 4.0f));
+ compareComputeResult(device, numbersBuffer, std::array{1.0f, 2.0f, 3.0f, 4.0f});
}
SLANG_UNIT_TEST(computeTrivialD3D12)
{
- runTestImpl(computeTrivialTestImpl, unitTestContext, Slang::RenderApiFlag::D3D12);
+ runTestImpl(computeTrivialTestImpl, unitTestContext, DeviceType::D3D12);
}
SLANG_UNIT_TEST(computeTrivialD3D11)
{
- runTestImpl(computeTrivialTestImpl, unitTestContext, Slang::RenderApiFlag::D3D11);
+ runTestImpl(computeTrivialTestImpl, unitTestContext, DeviceType::D3D11);
}
SLANG_UNIT_TEST(computeTrivialVulkan)
{
- runTestImpl(computeTrivialTestImpl, unitTestContext, Slang::RenderApiFlag::Vulkan);
+ runTestImpl(computeTrivialTestImpl, unitTestContext, DeviceType::Vulkan);
}
-} // namespace gfx_test
+} // namespace gfx_test \ No newline at end of file
diff --git a/tools/gfx-unit-test/copy-texture-tests.cpp b/tools/gfx-unit-test/copy-texture-tests.cpp
index 02df67378..5f0366480 100644
--- a/tools/gfx-unit-test/copy-texture-tests.cpp
+++ b/tools/gfx-unit-test/copy-texture-tests.cpp
@@ -1,8 +1,11 @@
+#if 0
+// Duplicated: This test is identical to slang-rhi\tests\test-cmd-copy-texture.cpp
+
#include "core/slang-basic.h"
#include "gfx-test-texture-util.h"
#include "gfx-test-util.h"
-#include "gfx-util/shader-cursor.h"
-#include "slang-gfx.h"
+#include "slang-rhi.h"
+#include "slang-rhi/shader-cursor.h"
#include "unit-test/slang-unit-test.h"
#if SLANG_WINDOWS_FAMILY
@@ -10,7 +13,7 @@
#endif
using namespace Slang;
-using namespace gfx;
+using namespace rhi;
namespace gfx_test
{
@@ -18,16 +21,16 @@ struct TextureToTextureCopyInfo
{
SubresourceRange srcSubresource;
SubresourceRange dstSubresource;
- ITextureResource::Extents extent;
- ITextureResource::Offset3D srcOffset;
- ITextureResource::Offset3D dstOffset;
+ Extents extent;
+ Offset3D srcOffset;
+ Offset3D dstOffset;
};
struct TextureToBufferCopyInfo
{
SubresourceRange srcSubresource;
- ITextureResource::Extents extent;
- ITextureResource::Offset3D textureOffset;
+ Extents extent;
+ Offset3D textureOffset;
Offset bufferOffset;
Offset bufferSize;
};
@@ -37,16 +40,16 @@ struct BaseCopyTextureTest
IDevice* device;
UnitTestContext* context;
- gfx::Size alignedRowStride;
+ rhi::Size alignedRowStride;
RefPtr<TextureInfo> srcTextureInfo;
RefPtr<TextureInfo> dstTextureInfo;
TextureToTextureCopyInfo texCopyInfo;
TextureToBufferCopyInfo bufferCopyInfo;
- ComPtr<ITextureResource> srcTexture;
- ComPtr<ITextureResource> dstTexture;
- ComPtr<IBufferResource> resultsBuffer;
+ ComPtr<ITexture> srcTexture;
+ ComPtr<ITexture> dstTexture;
+ ComPtr<IBuffer> resultsBuffer;
RefPtr<ValidationTextureFormatBase> validationFormat;
@@ -55,7 +58,7 @@ struct BaseCopyTextureTest
UnitTestContext* context,
Format format,
RefPtr<ValidationTextureFormatBase> validationFormat,
- ITextureResource::Type type)
+ TextureType type)
{
this->device = device;
this->context = context;
@@ -72,46 +75,28 @@ struct BaseCopyTextureTest
void createRequiredResources()
{
- ITextureResource::Desc srcTexDesc = {};
+ TextureDesc srcTexDesc = {};
srcTexDesc.type = srcTextureInfo->textureType;
- srcTexDesc.numMipLevels = srcTextureInfo->mipLevelCount;
+ srcTexDesc.mipCount = srcTextureInfo->mipLevelCount;
srcTexDesc.arraySize = srcTextureInfo->arrayLayerCount;
- srcTexDesc.size = srcTextureInfo->extents;
+ srcTexDesc.extent = 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(
+ GFX_CHECK_CALL_ABORT(device->createTexture(
srcTexDesc,
srcTextureInfo->subresourceDatas.getBuffer(),
srcTexture.writeRef()));
- ITextureResource::Desc dstTexDesc = {};
+ TextureDesc dstTexDesc = {};
dstTexDesc.type = dstTextureInfo->textureType;
- dstTexDesc.numMipLevels = dstTextureInfo->mipLevelCount;
+ dstTexDesc.mipCount = dstTextureInfo->mipLevelCount;
dstTexDesc.arraySize = dstTextureInfo->arrayLayerCount;
- dstTexDesc.size = dstTextureInfo->extents;
+ dstTexDesc.extent = 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(
+ GFX_CHECK_CALL_ABORT(device->createTexture(
dstTexDesc,
dstTextureInfo->subresourceDatas.getBuffer(),
dstTexture.writeRef()));
@@ -121,56 +106,43 @@ struct BaseCopyTextureTest
size_t alignment;
device->getTextureRowAlignment(&alignment);
alignedRowStride = (bufferCopyExtents.width * texelSize + alignment - 1) & ~(alignment - 1);
- IBufferResource::Desc bufferDesc = {};
- bufferDesc.sizeInBytes =
+ BufferDesc bufferDesc = {};
+ bufferDesc.size =
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()));
+ device->createBuffer(bufferDesc, nullptr, resultsBuffer.writeRef()));
- bufferCopyInfo.bufferSize = bufferDesc.sizeInBytes;
+ bufferCopyInfo.bufferSize = bufferDesc.size;
}
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 commandBuffer = queue->createCommandBuffer();
auto encoder = commandBuffer->encodeResourceCommands();
- encoder->textureSubresourceBarrier(
+ encoder->textureBarrier(
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(
+ encoder->textureBarrier(
dstTexture,
bufferCopyInfo.srcSubresource,
ResourceState::CopyDestination,
@@ -181,7 +153,6 @@ struct BaseCopyTextureTest
bufferCopyInfo.bufferSize,
alignedRowStride,
dstTexture,
- ResourceState::CopySource,
bufferCopyInfo.srcSubresource,
bufferCopyInfo.textureOffset,
bufferCopyInfo.extent);
@@ -250,12 +221,12 @@ struct BaseCopyTextureTest
}
void checkTestResults(
- ITextureResource::Extents srcMipExtent,
+ Extents srcMipExtent,
const void* expectedCopiedData,
const void* expectedOriginalData)
{
ComPtr<ISlangBlob> resultBlob;
- GFX_CHECK_CALL_ABORT(device->readBufferResource(
+ GFX_CHECK_CALL_ABORT(device->readBuffer(
resultsBuffer,
0,
bufferCopyInfo.bufferSize,
@@ -300,8 +271,8 @@ struct SimpleCopyTexture : BaseCopyTextureTest
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->extents.height = (textureType == TextureType::Texture1D) ? 1 : 4;
+ srcTextureInfo->extents.depth = (textureType == TextureType::Texture3D) ? 2 : 1;
srcTextureInfo->mipLevelCount = 1;
srcTextureInfo->arrayLayerCount = 1;
@@ -354,11 +325,11 @@ struct CopyTextureSection : BaseCopyTextureTest
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->extents.height = (textureType == TextureType::Texture1D) ? 1 : 4;
+ srcTextureInfo->extents.depth = (textureType == TextureType::Texture3D) ? 2 : 1;
srcTextureInfo->mipLevelCount = 2;
srcTextureInfo->arrayLayerCount =
- (textureType == ITextureResource::Type::Texture3D) ? 1 : 2;
+ (textureType == TextureType::Texture3D) ? 1 : 2;
dstTextureInfo = srcTextureInfo;
@@ -368,7 +339,7 @@ struct CopyTextureSection : BaseCopyTextureTest
srcSubresource.aspectMask = getTextureAspect(format);
srcSubresource.mipLevel = 0;
srcSubresource.mipLevelCount = 1;
- srcSubresource.baseArrayLayer = (textureType == ITextureResource::Type::Texture3D) ? 0 : 1;
+ srcSubresource.baseArrayLayer = (textureType == TextureType::Texture3D) ? 0 : 1;
srcSubresource.layerCount = 1;
SubresourceRange dstSubresource = {};
@@ -396,7 +367,7 @@ struct CopyTextureSection : BaseCopyTextureTest
srcSubresource.mipLevel,
srcTextureInfo->mipLevelCount,
srcSubresource.baseArrayLayer);
- ITextureResource::SubresourceData expectedData =
+ SubresourceData expectedData =
srcTextureInfo->subresourceDatas[subresourceIndex];
checkTestResults(srcTextureInfo->extents, expectedData.data, nullptr);
}
@@ -410,16 +381,16 @@ struct LargeSrcToSmallDst : BaseCopyTextureTest
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->extents.height = (textureType == TextureType::Texture1D) ? 1 : 8;
+ srcTextureInfo->extents.depth = (textureType == TextureType::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->extents.height = (textureType == TextureType::Texture1D) ? 1 : 4;
+ dstTextureInfo->extents.depth = (textureType == TextureType::Texture3D) ? 2 : 1;
dstTextureInfo->mipLevelCount = 1;
dstTextureInfo->arrayLayerCount = 1;
@@ -455,7 +426,7 @@ struct LargeSrcToSmallDst : BaseCopyTextureTest
srcSubresource.mipLevel,
srcTextureInfo->mipLevelCount,
srcSubresource.baseArrayLayer);
- ITextureResource::SubresourceData expectedData =
+ SubresourceData expectedData =
srcTextureInfo->subresourceDatas[subresourceIndex];
checkTestResults(srcTextureInfo->extents, expectedData.data, nullptr);
}
@@ -469,16 +440,16 @@ struct SmallSrcToLargeDst : BaseCopyTextureTest
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->extents.height = (textureType == TextureType::Texture1D) ? 1 : 4;
+ srcTextureInfo->extents.depth = (textureType == TextureType::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->extents.height = (textureType == TextureType::Texture1D) ? 1 : 8;
+ dstTextureInfo->extents.depth = (textureType == TextureType::Texture3D) ? 2 : 1;
dstTextureInfo->mipLevelCount = 1;
dstTextureInfo->arrayLayerCount = 1;
@@ -516,13 +487,13 @@ struct SmallSrcToLargeDst : BaseCopyTextureTest
srcSubresource.mipLevel,
srcTextureInfo->mipLevelCount,
srcSubresource.baseArrayLayer);
- ITextureResource::SubresourceData expectedCopiedData =
+ SubresourceData expectedCopiedData =
srcTextureInfo->subresourceDatas[copiedSubresourceIndex];
auto originalSubresourceIndex = getSubresourceIndex(
dstSubresource.mipLevel,
dstTextureInfo->mipLevelCount,
dstSubresource.baseArrayLayer);
- ITextureResource::SubresourceData expectedOriginalData =
+ SubresourceData expectedOriginalData =
dstTextureInfo->subresourceDatas[originalSubresourceIndex];
checkTestResults(
srcTextureInfo->extents,
@@ -540,8 +511,8 @@ struct CopyBetweenMips : BaseCopyTextureTest
srcTextureInfo->extents.width = 16;
srcTextureInfo->extents.height =
- (textureType == ITextureResource::Type::Texture1D) ? 1 : 16;
- srcTextureInfo->extents.depth = (textureType == ITextureResource::Type::Texture3D) ? 2 : 1;
+ (textureType == TextureType::Texture1D) ? 1 : 16;
+ srcTextureInfo->extents.depth = (textureType == TextureType::Texture3D) ? 2 : 1;
srcTextureInfo->mipLevelCount = 4;
srcTextureInfo->arrayLayerCount = 1;
@@ -549,8 +520,8 @@ struct CopyBetweenMips : BaseCopyTextureTest
dstTextureInfo->extents.width = 16;
dstTextureInfo->extents.height =
- (textureType == ITextureResource::Type::Texture1D) ? 1 : 16;
- dstTextureInfo->extents.depth = (textureType == ITextureResource::Type::Texture3D) ? 2 : 1;
+ (textureType == TextureType::Texture1D) ? 1 : 16;
+ dstTextureInfo->extents.depth = (textureType == TextureType::Texture3D) ? 2 : 1;
dstTextureInfo->mipLevelCount = 4;
dstTextureInfo->arrayLayerCount = 1;
@@ -594,9 +565,9 @@ struct CopyBetweenMips : BaseCopyTextureTest
createRequiredResources();
submitGPUWork();
- ITextureResource::SubresourceData expectedCopiedData =
+ SubresourceData expectedCopiedData =
srcTextureInfo->subresourceDatas[copiedSubresourceIndex];
- ITextureResource::SubresourceData expectedOriginalData =
+ SubresourceData expectedOriginalData =
dstTextureInfo->subresourceDatas[originalSubresourceIndex];
auto srcMipExtent = srcTextureInfo->subresourceObjects[2]->extents;
checkTestResults(srcMipExtent, expectedCopiedData.data, expectedOriginalData.data);
@@ -611,11 +582,11 @@ struct CopyBetweenLayers : BaseCopyTextureTest
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->extents.height = (textureType == TextureType::Texture1D) ? 1 : 4;
+ srcTextureInfo->extents.depth = (textureType == TextureType::Texture3D) ? 2 : 1;
srcTextureInfo->mipLevelCount = 1;
srcTextureInfo->arrayLayerCount =
- (textureType == ITextureResource::Type::Texture3D) ? 1 : 2;
+ (textureType == TextureType::Texture3D) ? 1 : 2;
generateTextureData(srcTextureInfo, validationFormat);
dstTextureInfo = srcTextureInfo;
@@ -631,7 +602,7 @@ struct CopyBetweenLayers : BaseCopyTextureTest
dstSubresource.aspectMask = getTextureAspect(format);
dstSubresource.mipLevel = 0;
dstSubresource.mipLevelCount = 1;
- dstSubresource.baseArrayLayer = (textureType == ITextureResource::Type::Texture3D) ? 0 : 1;
+ dstSubresource.baseArrayLayer = (textureType == TextureType::Texture3D) ? 0 : 1;
dstSubresource.layerCount = 1;
texCopyInfo.srcSubresource = srcSubresource;
@@ -652,13 +623,13 @@ struct CopyBetweenLayers : BaseCopyTextureTest
srcSubresource.mipLevel,
srcTextureInfo->mipLevelCount,
srcSubresource.baseArrayLayer);
- ITextureResource::SubresourceData expectedCopiedData =
+ SubresourceData expectedCopiedData =
srcTextureInfo->subresourceDatas[copiedSubresourceIndex];
auto originalSubresourceIndex = getSubresourceIndex(
dstSubresource.mipLevel,
dstTextureInfo->mipLevelCount,
dstSubresource.baseArrayLayer);
- ITextureResource::SubresourceData expectedOriginalData =
+ SubresourceData expectedOriginalData =
dstTextureInfo->subresourceDatas[originalSubresourceIndex];
checkTestResults(
srcTextureInfo->extents,
@@ -675,8 +646,8 @@ struct CopyWithOffsets : BaseCopyTextureTest
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->extents.height = (textureType == TextureType::Texture1D) ? 1 : 8;
+ srcTextureInfo->extents.depth = (textureType == TextureType::Texture3D) ? 2 : 1;
srcTextureInfo->mipLevelCount = 1;
srcTextureInfo->arrayLayerCount = 1;
@@ -684,8 +655,8 @@ struct CopyWithOffsets : BaseCopyTextureTest
dstTextureInfo->extents.width = 16;
dstTextureInfo->extents.height =
- (textureType == ITextureResource::Type::Texture1D) ? 1 : 16;
- dstTextureInfo->extents.depth = (textureType == ITextureResource::Type::Texture3D) ? 4 : 1;
+ (textureType == TextureType::Texture1D) ? 1 : 16;
+ dstTextureInfo->extents.depth = (textureType == TextureType::Texture3D) ? 4 : 1;
dstTextureInfo->mipLevelCount = 1;
dstTextureInfo->arrayLayerCount = 1;
@@ -713,13 +684,13 @@ struct CopyWithOffsets : BaseCopyTextureTest
texCopyInfo.srcOffset = {2, 2, 0};
texCopyInfo.dstOffset = {4, 4, 0};
- if (textureType == ITextureResource::Type::Texture1D)
+ if (textureType == TextureType::Texture1D)
{
texCopyInfo.extent.height = 1;
texCopyInfo.srcOffset.y = 0;
texCopyInfo.dstOffset.y = 0;
}
- else if (textureType == ITextureResource::Type::Texture3D)
+ else if (textureType == TextureType::Texture3D)
{
texCopyInfo.extent.depth = srcTextureInfo->extents.depth;
texCopyInfo.dstOffset.z = 1;
@@ -737,13 +708,13 @@ struct CopyWithOffsets : BaseCopyTextureTest
srcSubresource.mipLevel,
srcTextureInfo->mipLevelCount,
srcSubresource.baseArrayLayer);
- ITextureResource::SubresourceData expectedCopiedData =
+ SubresourceData expectedCopiedData =
srcTextureInfo->subresourceDatas[copiedSubresourceIndex];
auto originalSubresourceIndex = getSubresourceIndex(
dstSubresource.mipLevel,
dstTextureInfo->mipLevelCount,
dstSubresource.baseArrayLayer);
- ITextureResource::SubresourceData expectedOriginalData =
+ SubresourceData expectedOriginalData =
dstTextureInfo->subresourceDatas[originalSubresourceIndex];
checkTestResults(
srcTextureInfo->extents,
@@ -760,8 +731,8 @@ struct CopySectionWithSetExtent : BaseCopyTextureTest
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->extents.height = (textureType == TextureType::Texture1D) ? 1 : 8;
+ srcTextureInfo->extents.depth = (textureType == TextureType::Texture3D) ? 2 : 1;
srcTextureInfo->mipLevelCount = 1;
srcTextureInfo->arrayLayerCount = 1;
@@ -790,12 +761,12 @@ struct CopySectionWithSetExtent : BaseCopyTextureTest
texCopyInfo.srcOffset = {0, 0, 0};
texCopyInfo.dstOffset = {4, 4, 0};
- if (textureType == ITextureResource::Type::Texture1D)
+ if (textureType == TextureType::Texture1D)
{
texCopyInfo.extent.height = 1;
texCopyInfo.dstOffset.y = 0;
}
- else if (textureType == ITextureResource::Type::Texture3D)
+ else if (textureType == TextureType::Texture3D)
{
texCopyInfo.extent.depth = srcTextureInfo->extents.depth;
}
@@ -812,13 +783,13 @@ struct CopySectionWithSetExtent : BaseCopyTextureTest
srcSubresource.mipLevel,
srcTextureInfo->mipLevelCount,
srcSubresource.baseArrayLayer);
- ITextureResource::SubresourceData expectedCopiedData =
+ SubresourceData expectedCopiedData =
srcTextureInfo->subresourceDatas[copiedSubresourceIndex];
auto originalSubresourceIndex = getSubresourceIndex(
dstSubresource.mipLevel,
dstTextureInfo->mipLevelCount,
dstSubresource.baseArrayLayer);
- ITextureResource::SubresourceData expectedOriginalData =
+ SubresourceData expectedOriginalData =
dstTextureInfo->subresourceDatas[originalSubresourceIndex];
checkTestResults(
srcTextureInfo->extents,
@@ -841,7 +812,7 @@ void copyTextureTestImpl(IDevice* device, UnitTestContext* context)
Format::R16G16_FLOAT,
Format::R10G10B10A2_UNORM,
Format::B5G5R5A1_UNORM};
- for (uint32_t i = 2; i < (uint32_t)ITextureResource::Type::_Count - 1; ++i)
+ for (uint32_t i = 2; i < (uint32_t)TextureType::_Count - 1; ++i)
{
for (auto format : formats)
{
@@ -852,7 +823,7 @@ void copyTextureTestImpl(IDevice* device, UnitTestContext* context)
{
continue;
}
- auto type = (ITextureResource::Type)i;
+ auto type = (TextureType)i;
auto validationFormat = getValidationTextureFormat(format);
if (!validationFormat)
continue;
@@ -954,3 +925,4 @@ SLANG_UNIT_TEST(copySectionWithSetExtent)
Slang::RenderApiFlag::Vulkan);
}
} // namespace gfx_test
+#endif \ No newline at end of file
diff --git a/tools/gfx-unit-test/create-buffer-from-handle.cpp b/tools/gfx-unit-test/create-buffer-from-handle.cpp
index f25aa5d5f..fd98fe59e 100644
--- a/tools/gfx-unit-test/create-buffer-from-handle.cpp
+++ b/tools/gfx-unit-test/create-buffer-from-handle.cpp
@@ -1,21 +1,15 @@
#include "core/slang-basic.h"
#include "gfx-test-util.h"
-#include "gfx-util/shader-cursor.h"
-#include "slang-gfx.h"
+#include "slang-rhi.h"
+#include "slang-rhi/shader-cursor.h"
#include "unit-test/slang-unit-test.h"
-using namespace gfx;
+using namespace rhi;
namespace gfx_test
{
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(
@@ -25,79 +19,66 @@ void createBufferFromHandleTestImpl(IDevice* device, UnitTestContext* context)
"computeMain",
slangReflection));
- ComputePipelineStateDesc pipelineDesc = {};
+ ComputePipelineDesc pipelineDesc = {};
pipelineDesc.program = shaderProgram.get();
- ComPtr<gfx::IPipelineState> pipelineState;
- GFX_CHECK_CALL_ABORT(
- device->createComputePipelineState(pipelineDesc, pipelineState.writeRef()));
+ ComPtr<IComputePipeline> pipelineState;
+ GFX_CHECK_CALL_ABORT(device->createComputePipeline(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 bufferDesc = {};
+ bufferDesc.size = numberCount * sizeof(float);
+ bufferDesc.format = Format::Undefined;
bufferDesc.elementSize = sizeof(float);
- bufferDesc.allowedStates = ResourceStateSet(
- ResourceState::ShaderResource,
- ResourceState::UnorderedAccess,
- ResourceState::CopyDestination,
- ResourceState::CopySource);
+ bufferDesc.usage = BufferUsage::ShaderResource | BufferUsage::UnorderedAccess |
+ BufferUsage::CopyDestination | BufferUsage::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;
+ ComPtr<IBuffer> originalNumbersBuffer;
GFX_CHECK_CALL_ABORT(
- device->createBufferFromNativeHandle(handle, bufferDesc, numbersBuffer.writeRef()));
- compareComputeResult(device, numbersBuffer, Slang::makeArray<float>(0.0f, 1.0f, 2.0f, 3.0f));
+ device->createBuffer(bufferDesc, (void*)initialData, originalNumbersBuffer.writeRef()));
- ComPtr<IResourceView> bufferView;
- IResourceView::Desc viewDesc = {};
- viewDesc.type = IResourceView::Type::UnorderedAccess;
- viewDesc.format = Format::Unknown;
+ NativeHandle handle;
+ originalNumbersBuffer->getNativeHandle(&handle);
+ ComPtr<IBuffer> numbersBuffer;
GFX_CHECK_CALL_ABORT(
- device->createBufferView(numbersBuffer, nullptr, viewDesc, bufferView.writeRef()));
+ device->createBufferFromNativeHandle(handle, bufferDesc, numbersBuffer.writeRef()));
+ compareComputeResult(device, numbersBuffer, std::array{0.0f, 1.0f, 2.0f, 3.0f});
// 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);
+ auto queue = device->getQueue(QueueType::Graphics);
+ auto commandEncoder = queue->createCommandEncoder();
+ {
+ auto encoder = commandEncoder->beginComputePass();
+ auto rootObject = encoder->bindPipeline(pipelineState);
+
+ ShaderCursor rootCursor(rootObject);
+ // Bind buffer directly to the entry point.
+ rootCursor.getPath("buffer").setBinding(Binding(numbersBuffer));
+
+ encoder->dispatchCompute(1, 1, 1);
+ encoder->end();
+ }
+
+ auto commandBuffer = commandEncoder->finish();
+ queue->submit(commandBuffer);
queue->waitOnHost();
}
- compareComputeResult(device, numbersBuffer, Slang::makeArray<float>(1.0f, 2.0f, 3.0f, 4.0f));
+ compareComputeResult(device, numbersBuffer, std::array{1.0f, 2.0f, 3.0f, 4.0f});
}
SLANG_UNIT_TEST(createBufferFromHandleD3D12)
{
- runTestImpl(createBufferFromHandleTestImpl, unitTestContext, Slang::RenderApiFlag::D3D12);
+ runTestImpl(createBufferFromHandleTestImpl, unitTestContext, DeviceType::D3D12);
}
SLANG_UNIT_TEST(createBufferFromHandleVulkan)
{
- runTestImpl(createBufferFromHandleTestImpl, unitTestContext, Slang::RenderApiFlag::Vulkan);
+ runTestImpl(createBufferFromHandleTestImpl, unitTestContext, DeviceType::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 5605bf8a5..9ceacd69e 100644
--- a/tools/gfx-unit-test/existing-device-handle-test.cpp
+++ b/tools/gfx-unit-test/existing-device-handle-test.cpp
@@ -1,21 +1,15 @@
#include "core/slang-basic.h"
#include "gfx-test-util.h"
-#include "gfx-util/shader-cursor.h"
-#include "slang-gfx.h"
+#include "slang-rhi.h"
+#include "slang-rhi/shader-cursor.h"
#include "unit-test/slang-unit-test.h"
-using namespace gfx;
+using namespace rhi;
namespace gfx_test
{
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(
@@ -25,127 +19,102 @@ void existingDeviceHandleTestImpl(IDevice* device, UnitTestContext* context)
"computeMain",
slangReflection));
- ComputePipelineStateDesc pipelineDesc = {};
+ ComputePipelineDesc pipelineDesc = {};
pipelineDesc.program = shaderProgram.get();
- ComPtr<gfx::IPipelineState> pipelineState;
- GFX_CHECK_CALL_ABORT(
- device->createComputePipelineState(pipelineDesc, pipelineState.writeRef()));
+ ComPtr<IComputePipeline> pipelineState;
+ GFX_CHECK_CALL_ABORT(device->createComputePipeline(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 bufferDesc = {};
+ bufferDesc.size = numberCount * sizeof(float);
+ bufferDesc.format = Format::Undefined;
bufferDesc.elementSize = sizeof(float);
- bufferDesc.allowedStates = ResourceStateSet(
- ResourceState::ShaderResource,
- ResourceState::UnorderedAccess,
- ResourceState::CopyDestination,
- ResourceState::CopySource);
+ bufferDesc.usage = BufferUsage::ShaderResource | BufferUsage::UnorderedAccess |
+ BufferUsage::CopyDestination | BufferUsage::CopySource;
bufferDesc.defaultState = ResourceState::UnorderedAccess;
bufferDesc.memoryType = MemoryType::DeviceLocal;
- ComPtr<IBufferResource> numbersBuffer;
+ ComPtr<IBuffer> 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()));
+ device->createBuffer(bufferDesc, (void*)initialData, numbersBuffer.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);
+ auto queue = device->getQueue(QueueType::Graphics);
+ auto commandEncoder = queue->createCommandEncoder();
+ {
+ auto encoder = commandEncoder->beginComputePass();
+ auto rootObject = encoder->bindPipeline(pipelineState);
+
+ ShaderCursor rootCursor(rootObject);
+ // Bind buffer directly to the root.
+ rootCursor.getPath("buffer").setBinding(Binding(numbersBuffer));
+
+ encoder->dispatchCompute(1, 1, 1);
+ encoder->end();
+ }
+
+ auto commandBuffer = commandEncoder->finish();
+ queue->submit(commandBuffer);
queue->waitOnHost();
}
- compareComputeResult(device, numbersBuffer, Slang::makeArray<float>(1.0f, 2.0f, 3.0f, 4.0f));
+ compareComputeResult(device, numbersBuffer, std::array{1.0f, 2.0f, 3.0f, 4.0f});
}
-void existingDeviceHandleTestAPI(UnitTestContext* context, Slang::RenderApiFlag::Enum api)
+void existingDeviceHandleTestAPI(UnitTestContext* context, DeviceType deviceType)
{
- gfxEnableDebugLayer(context->enableDebugLayers);
- if ((api & context->enabledApis) == 0)
+ if (!deviceTypeInEnabledApis(deviceType, context->enabledApis))
{
- SLANG_IGNORE_TEST;
+ 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 deviceDesc = {};
+ deviceDesc.deviceType = deviceType;
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());
+ auto createDeviceResult = getRHI()->createDevice(deviceDesc, device.writeRef());
if (SLANG_FAILED(createDeviceResult) || !device)
{
SLANG_IGNORE_TEST;
}
- IDevice::InteropHandles handles;
+ DeviceNativeHandles handles;
GFX_CHECK_CALL_ABORT(device->getNativeDeviceHandles(&handles));
Slang::ComPtr<IDevice> testDevice;
- IDevice::Desc testDeviceDesc = deviceDesc;
+ DeviceDesc testDeviceDesc = deviceDesc;
testDeviceDesc.existingDeviceHandles.handles[0] = handles.handles[0];
- if (api == Slang::RenderApiFlag::Vulkan)
+ if (deviceType == DeviceType::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)
+ auto createTestDeviceResult = getRHI()->createDevice(testDeviceDesc, testDevice.writeRef());
+ if (SLANG_FAILED(createTestDeviceResult) || !testDevice)
{
SLANG_IGNORE_TEST;
}
- existingDeviceHandleTestImpl(device, context);
+ existingDeviceHandleTestImpl(testDevice, context);
}
SLANG_UNIT_TEST(existingDeviceHandleD3D12)
{
- return existingDeviceHandleTestAPI(unitTestContext, Slang::RenderApiFlag::D3D12);
+ return existingDeviceHandleTestAPI(unitTestContext, DeviceType::D3D12);
}
SLANG_UNIT_TEST(existingDeviceHandleVulkan)
{
- return existingDeviceHandleTestAPI(unitTestContext, Slang::RenderApiFlag::Vulkan);
+ return existingDeviceHandleTestAPI(unitTestContext, DeviceType::Vulkan);
}
#if SLANG_WIN64
SLANG_UNIT_TEST(existingDeviceHandleCUDA)
{
- return existingDeviceHandleTestAPI(unitTestContext, Slang::RenderApiFlag::CUDA);
+ return existingDeviceHandleTestAPI(unitTestContext, DeviceType::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 56741854e..93cc75197 100644
--- a/tools/gfx-unit-test/format-unit-tests.cpp
+++ b/tools/gfx-unit-test/format-unit-tests.cpp
@@ -1,7 +1,10 @@
+#if 0
+// Duplicated: This test is identical to slang-rhi\tests\test-formats.cpp
+
#include "core/slang-basic.h"
#include "gfx-test-util.h"
-#include "gfx-util/shader-cursor.h"
#include "slang-gfx.h"
+#include "slang-rhi/shader-cursor.h"
#include "unit-test/slang-unit-test.h"
using namespace gfx;
@@ -1500,3 +1503,5 @@ SLANG_UNIT_TEST(FormatTestsVulkan)
}
} // namespace gfx_test
+
+#endif \ No newline at end of file
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 102986616..67b355376 100644
--- a/tools/gfx-unit-test/get-buffer-resource-handle-test.cpp
+++ b/tools/gfx-unit-test/get-buffer-resource-handle-test.cpp
@@ -1,47 +1,43 @@
#include "core/slang-basic.h"
#include "gfx-test-util.h"
-#include "gfx-util/shader-cursor.h"
-#include "slang-gfx.h"
+#include "slang-rhi/shader-cursor.h"
#include "unit-test/slang-unit-test.h"
+#include <slang-rhi.h>
+
#if SLANG_WINDOWS_FAMILY
#include <d3d12.h>
#endif
-using namespace gfx;
+using namespace rhi;
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 bufferDesc = {};
+ bufferDesc.size = numberCount * sizeof(float);
+ bufferDesc.format = rhi::Format::Undefined;
bufferDesc.elementSize = sizeof(float);
- bufferDesc.allowedStates = ResourceStateSet(
- ResourceState::ShaderResource,
- ResourceState::UnorderedAccess,
- ResourceState::CopyDestination,
- ResourceState::CopySource);
bufferDesc.defaultState = ResourceState::UnorderedAccess;
bufferDesc.memoryType = MemoryType::DeviceLocal;
+ bufferDesc.usage = BufferUsage::UnorderedAccess | BufferUsage::ShaderResource |
+ BufferUsage::CopySource | BufferUsage::CopyDestination;
- ComPtr<IBufferResource> buffer;
- GFX_CHECK_CALL_ABORT(device->createBufferResource(bufferDesc, nullptr, buffer.writeRef()));
+ ComPtr<IBuffer> buffer;
+ GFX_CHECK_CALL_ABORT(device->createBuffer(bufferDesc, nullptr, buffer.writeRef()));
- InteropHandle handle;
- GFX_CHECK_CALL_ABORT(buffer->getNativeResourceHandle(&handle));
- if (device->getDeviceInfo().deviceType == gfx::DeviceType::Vulkan)
+ NativeHandle handle;
+ GFX_CHECK_CALL_ABORT(buffer->getNativeHandle(&handle));
+ if (device->getInfo().deviceType == rhi::DeviceType::Vulkan)
{
- SLANG_CHECK(handle.handleValue != 0);
- SLANG_CHECK(handle.api == InteropHandleAPI::Vulkan);
+ SLANG_CHECK(handle.value != 0);
}
#if SLANG_WINDOWS_FAMILY
else
{
- SLANG_CHECK(handle.api == InteropHandleAPI::D3D12);
- auto d3d12Handle = (ID3D12Resource*)handle.handleValue;
+ auto d3d12Handle = (ID3D12Resource*)handle.value;
Slang::ComPtr<IUnknown> testHandle1;
GFX_CHECK_CALL_ABORT(d3d12Handle->QueryInterface<IUnknown>(testHandle1.writeRef()));
Slang::ComPtr<ID3D12Resource> testHandle2;
@@ -53,23 +49,24 @@ void getBufferResourceHandleTestImpl(IDevice* device, UnitTestContext* context)
void getBufferResourceHandleTestAPI(UnitTestContext* context, Slang::RenderApiFlag::Enum api)
{
- gfxEnableDebugLayer(context->enableDebugLayers);
+ if (context->enableDebugLayers)
+ getRHI()->enableDebugLayers();
if ((api & context->enabledApis) == 0)
{
SLANG_IGNORE_TEST;
}
Slang::ComPtr<IDevice> device;
- IDevice::Desc deviceDesc = {};
+ DeviceDesc deviceDesc = {};
switch (api)
{
case Slang::RenderApiFlag::D3D11:
- deviceDesc.deviceType = gfx::DeviceType::DirectX11;
+ deviceDesc.deviceType = rhi::DeviceType::D3D11;
break;
case Slang::RenderApiFlag::D3D12:
- deviceDesc.deviceType = gfx::DeviceType::DirectX12;
+ deviceDesc.deviceType = rhi::DeviceType::D3D12;
break;
case Slang::RenderApiFlag::Vulkan:
- deviceDesc.deviceType = gfx::DeviceType::Vulkan;
+ deviceDesc.deviceType = rhi::DeviceType::Vulkan;
break;
default:
SLANG_IGNORE_TEST;
@@ -78,14 +75,14 @@ void getBufferResourceHandleTestAPI(UnitTestContext* context, Slang::RenderApiFl
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());
+ auto createDeviceResult = getRHI()->createDevice(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"))
+ if (Slang::String(device->getInfo().adapterName).toLower().contains("swiftshader"))
{
SLANG_IGNORE_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 5c734f966..50b5bb45a 100644
--- a/tools/gfx-unit-test/get-cmd-buffer-handle-test.cpp
+++ b/tools/gfx-unit-test/get-cmd-buffer-handle-test.cpp
@@ -1,42 +1,39 @@
#include "core/slang-basic.h"
#include "gfx-test-util.h"
-#include "gfx-util/shader-cursor.h"
-#include "slang-gfx.h"
+#include "slang-rhi.h"
+#include "slang-rhi/shader-cursor.h"
#include "unit-test/slang-unit-test.h"
#if SLANG_WINDOWS_FAMILY
#include <d3d12.h>
#endif
-using namespace gfx;
+using namespace rhi;
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()));
+ // Create a command queue and encoder to get a command buffer
+ ComPtr<ICommandQueue> queue;
+ GFX_CHECK_CALL_ABORT(device->getQueue(QueueType::Graphics, queue.writeRef()));
- auto commandBuffer = transientHeap->createCommandBuffer();
- struct CloseComandBufferRAII
- {
- ICommandBuffer* m_commandBuffer;
- ~CloseComandBufferRAII() { m_commandBuffer->close(); }
- } closeCommandBufferRAII{commandBuffer};
- InteropHandle handle = {};
+ ComPtr<ICommandEncoder> encoder;
+ GFX_CHECK_CALL_ABORT(queue->createCommandEncoder(encoder.writeRef()));
+
+ ComPtr<ICommandBuffer> commandBuffer;
+ GFX_CHECK_CALL_ABORT(encoder->finish(commandBuffer.writeRef()));
+
+ NativeHandle handle = {};
GFX_CHECK_CALL_ABORT(commandBuffer->getNativeHandle(&handle));
- if (device->getDeviceInfo().deviceType == gfx::DeviceType::Vulkan)
+ if (device->getInfo().deviceType == rhi::DeviceType::Vulkan)
{
- SLANG_CHECK(handle.handleValue != 0);
+ SLANG_CHECK(handle.value != 0);
}
#if SLANG_WINDOWS_FAMILY
else
{
- auto d3d12Handle = (ID3D12GraphicsCommandList*)handle.handleValue;
+ auto d3d12Handle = (ID3D12GraphicsCommandList*)handle.value;
Slang::ComPtr<IUnknown> testHandle1;
GFX_CHECK_CALL_ABORT(d3d12Handle->QueryInterface<IUnknown>(testHandle1.writeRef()));
Slang::ComPtr<ID3D12GraphicsCommandList> testHandle2;
@@ -49,23 +46,22 @@ void getBufferHandleTestImpl(IDevice* device, UnitTestContext* context)
void getBufferHandleTestAPI(UnitTestContext* context, Slang::RenderApiFlag::Enum api)
{
- gfxEnableDebugLayer(context->enableDebugLayers);
if ((api & context->enabledApis) == 0)
{
SLANG_IGNORE_TEST;
}
Slang::ComPtr<IDevice> device;
- IDevice::Desc deviceDesc = {};
+ DeviceDesc deviceDesc = {};
switch (api)
{
case Slang::RenderApiFlag::D3D11:
- deviceDesc.deviceType = gfx::DeviceType::DirectX11;
+ deviceDesc.deviceType = rhi::DeviceType::D3D11;
break;
case Slang::RenderApiFlag::D3D12:
- deviceDesc.deviceType = gfx::DeviceType::DirectX12;
+ deviceDesc.deviceType = rhi::DeviceType::D3D12;
break;
case Slang::RenderApiFlag::Vulkan:
- deviceDesc.deviceType = gfx::DeviceType::Vulkan;
+ deviceDesc.deviceType = rhi::DeviceType::Vulkan;
break;
default:
SLANG_IGNORE_TEST;
@@ -74,14 +70,14 @@ void getBufferHandleTestAPI(UnitTestContext* context, Slang::RenderApiFlag::Enum
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());
+ auto createDeviceResult = getRHI()->createDevice(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"))
+ if (Slang::String(device->getInfo().adapterName).toLower().contains("swiftshader"))
{
SLANG_IGNORE_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 82561f4a2..57e50b74b 100644
--- a/tools/gfx-unit-test/get-cmd-queue-handle-test.cpp
+++ b/tools/gfx-unit-test/get-cmd-queue-handle-test.cpp
@@ -1,31 +1,32 @@
#include "core/slang-basic.h"
#include "gfx-test-util.h"
-#include "gfx-util/shader-cursor.h"
-#include "slang-gfx.h"
+#include "slang-rhi/shader-cursor.h"
#include "unit-test/slang-unit-test.h"
+#include <slang-rhi.h>
+
#if SLANG_WINDOWS_FAMILY
#include <d3d12.h>
#endif
-using namespace gfx;
+using namespace rhi;
namespace gfx_test
{
void getQueueHandleTestImpl(IDevice* device, UnitTestContext* context)
{
- ICommandQueue::Desc queueDesc = {ICommandQueue::QueueType::Graphics};
- auto queue = device->createCommandQueue(queueDesc);
- InteropHandle handle;
+ ComPtr<ICommandQueue> queue;
+ GFX_CHECK_CALL_ABORT(device->getQueue(QueueType::Graphics, queue.writeRef()));
+ NativeHandle handle;
GFX_CHECK_CALL_ABORT(queue->getNativeHandle(&handle));
- if (device->getDeviceInfo().deviceType == gfx::DeviceType::Vulkan)
+ if (device->getInfo().deviceType == rhi::DeviceType::Vulkan)
{
- SLANG_CHECK(handle.handleValue != 0);
+ SLANG_CHECK(handle.value != 0);
}
#if SLANG_WINDOWS_FAMILY
else
{
- auto d3d12Queue = (ID3D12CommandQueue*)handle.handleValue;
+ auto d3d12Queue = (ID3D12CommandQueue*)handle.value;
Slang::ComPtr<IUnknown> testHandle1;
GFX_CHECK_CALL_ABORT(d3d12Queue->QueryInterface<IUnknown>(testHandle1.writeRef()));
Slang::ComPtr<ID3D12CommandQueue> testHandle2;
@@ -38,23 +39,24 @@ void getQueueHandleTestImpl(IDevice* device, UnitTestContext* context)
void getQueueHandleTestAPI(UnitTestContext* context, Slang::RenderApiFlag::Enum api)
{
- gfxEnableDebugLayer(context->enableDebugLayers);
+ if (context->enableDebugLayers)
+ getRHI()->enableDebugLayers();
if ((api & context->enabledApis) == 0)
{
SLANG_IGNORE_TEST;
}
Slang::ComPtr<IDevice> device;
- IDevice::Desc deviceDesc = {};
+ DeviceDesc deviceDesc = {};
switch (api)
{
case Slang::RenderApiFlag::D3D11:
- deviceDesc.deviceType = gfx::DeviceType::DirectX11;
+ deviceDesc.deviceType = rhi::DeviceType::D3D11;
break;
case Slang::RenderApiFlag::D3D12:
- deviceDesc.deviceType = gfx::DeviceType::DirectX12;
+ deviceDesc.deviceType = rhi::DeviceType::D3D12;
break;
case Slang::RenderApiFlag::Vulkan:
- deviceDesc.deviceType = gfx::DeviceType::Vulkan;
+ deviceDesc.deviceType = rhi::DeviceType::Vulkan;
break;
default:
SLANG_IGNORE_TEST;
@@ -63,14 +65,14 @@ void getQueueHandleTestAPI(UnitTestContext* context, Slang::RenderApiFlag::Enum
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());
+ auto createDeviceResult = getRHI()->createDevice(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"))
+ if (Slang::String(device->getInfo().adapterName).toLower().contains("swiftshader"))
{
SLANG_IGNORE_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 844372eaa..8152e8d54 100644
--- a/tools/gfx-unit-test/get-supported-resource-states-test.cpp
+++ b/tools/gfx-unit-test/get-supported-resource-states-test.cpp
@@ -1,15 +1,26 @@
+/*
+ * This test has been disabled because the slang-rhi API
+ * does not provide equivalent functionality for querying format-supported
+ * resource states. The old gfx API's getFormatSupportedResourceStates() is
+ * replaced by with IDevice::getFormatSupport.
+ */
+
+#if 0
+// Disabled: no equivalent API in slang-rhi
+
#include "core/slang-basic.h"
#include "gfx-test-util.h"
-#include "gfx-util/shader-cursor.h"
-#include "slang-gfx.h"
#include "unit-test/slang-unit-test.h"
+#include <slang-rhi.h>
+#include <slang-rhi/shader-cursor.h>
+
#if SLANG_WINDOWS_FAMILY
#include <d3d12.h>
#endif
using namespace Slang;
-using namespace gfx;
+using namespace rhi;
namespace
{
@@ -24,8 +35,8 @@ struct GetSupportedResourceStatesBase
ResourceStateSet textureAllowedStates;
ResourceStateSet bufferAllowedStates;
- ComPtr<ITextureResource> texture;
- ComPtr<IBufferResource> buffer;
+ ComPtr<ITexture> texture;
+ ComPtr<IBuffer> buffer;
void init(IDevice* device, UnitTestContext* context)
{
@@ -33,160 +44,88 @@ struct GetSupportedResourceStatesBase
this->context = context;
}
- Format convertTypelessFormat(Format format)
+ void checkResult()
{
- 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;
- }
- }
+ SLANG_CHECK_ABORT(formatSupportedStates.isSubsetOf(bufferAllowedStates));
+ SLANG_CHECK_ABORT(formatSupportedStates.isSubsetOf(textureAllowedStates));
- void transitionResourceStates(IDevice* device)
- {
- Slang::ComPtr<ITransientResourceHeap> transientHeap;
- ITransientResourceHeap::Desc transientHeapDesc = {};
- transientHeapDesc.constantBufferSize = 4096;
- GFX_CHECK_CALL_ABORT(
- device->createTransientResourceHeap(transientHeapDesc, transientHeap.writeRef()));
+ auto queue = device->getQueue(QueueType::Graphics);
+ ComPtr<ICommandEncoder> encoder = queue->createCommandEncoder();
- ICommandQueue::Desc queueDesc = {ICommandQueue::QueueType::Graphics};
- auto queue = device->createCommandQueue(queueDesc);
+ encoder->setBufferState(buffer, ResourceState::UnorderedAccess);
- auto commandBuffer = transientHeap->createCommandBuffer();
- auto encoder = commandBuffer->encodeResourceCommands();
- ResourceState currentTextureState = texture->getDesc()->defaultState;
- ResourceState currentBufferState = buffer->getDesc()->defaultState;
+ encoder->setTextureState(texture, SubresourceRange{}, ResourceState::UnorderedAccess);
- for (uint32_t i = 0; i < (uint32_t)ResourceState::_Count; ++i)
- {
- auto nextState = (ResourceState)i;
- if (formatSupportedStates.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->endEncoding();
- commandBuffer->close();
- queue->executeCommandBuffer(commandBuffer);
+ ComPtr<ICommandBuffer> commandBuffer;
+ encoder->finish(commandBuffer.writeRef());
+ queue->submit(commandBuffer);
queue->waitOnHost();
}
void run()
{
- // Skip Format::Unknown
- for (uint32_t i = 1; i < (uint32_t)Format::_Count; ++i)
+ switch (format)
{
- 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);
+ case Format::R8Unorm:
+ case Format::RG8Unorm:
+ case Format::RGBA8Unorm:
+ case Format::RGBA8UnormSrgb:
+ case Format::B8G8R8A8Unorm:
+ case Format::B8G8R8A8UnormSrgb:
+ case Format::R16Float:
+ case Format::RG16Float:
+ case Format::RGB16Float:
+ case Format::RGBA16Float:
+ case Format::R32Float:
+ case Format::RG32Float:
+ case Format::RGB32Float:
+ case Format::RGBA32Float:
+ case Format::R8G8Typeless:
+ case Format::R8Typeless:
+ case Format::B8G8R8A8Typeless:
+ case Format::R10G10B10A2Typeless:
+ case Format::Undefined:
+ break;
}
+
+ auto formatInfo = getFormatInfo(format);
+
+ if (!isTypelessFormat(format))
+ {
+ GFX_CHECK_CALL_ABORT(device->getFormatSupportedResourceStates(format, &formatSupportedStates));
+ }
+
+ textureAllowedStates = ResourceStateSet(
+ ResourceState::ShaderResource, ResourceState::UnorderedAccess, ResourceState::RenderTarget);
+
+ BufferDesc bufferDesc = {};
+ bufferDesc.size = 256;
+ bufferDesc.format = format;
+ bufferDesc.defaultState = ResourceState::UnorderedAccess;
+ bufferDesc.usage = BufferUsage::UnorderedAccess;
+
+ buffer = device->createBuffer(bufferDesc, nullptr);
+
+ TextureDesc textureDesc = {};
+ textureDesc.type = TextureType::Texture2D;
+ textureDesc.mipCount = dstTextureInfo.numMipLevels;
+ textureDesc.arrayLength = dstTextureInfo.arraySize;
+ textureDesc.size = extent;
+ textureDesc.defaultState = ResourceState::UnorderedAccess;
+ textureDesc.usage = TextureUsage::UnorderedAccess;
+ textureDesc.format = format;
+ textureDesc.format = (format != Format::Undefined) ? format : Format::Undefined;
+
+ texture = device->createTexture(textureDesc, nullptr);
+
+ checkResult();
}
};
-void supportedResourceStatesTestImpl(IDevice* device, UnitTestContext* context)
+template<typename T>
+void getSupportedResourceStatesTestImpl(IDevice* device, UnitTestContext* context)
{
- GetSupportedResourceStatesBase test;
+ T test;
test.init(device, context);
test.run();
}
@@ -196,11 +135,18 @@ namespace gfx_test
{
SLANG_UNIT_TEST(getSupportedResourceStatesD3D12)
{
- runTestImpl(supportedResourceStatesTestImpl, unitTestContext, Slang::RenderApiFlag::D3D12);
+ runTestImpl(
+ getSupportedResourceStatesTestImpl<GetSupportedResourceStatesBase>,
+ unitTestContext,
+ DeviceType::D3D12);
}
SLANG_UNIT_TEST(getSupportedResourceStatesVulkan)
{
- runTestImpl(supportedResourceStatesTestImpl, unitTestContext, Slang::RenderApiFlag::Vulkan);
+ runTestImpl(
+ getSupportedResourceStatesTestImpl<GetSupportedResourceStatesBase>,
+ unitTestContext,
+ DeviceType::Vulkan);
}
} // namespace gfx_test
+#endif
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 1900b482e..8fd971065 100644
--- a/tools/gfx-unit-test/get-texture-resource-handle-test.cpp
+++ b/tools/gfx-unit-test/get-texture-resource-handle-test.cpp
@@ -1,44 +1,44 @@
#include "core/slang-basic.h"
#include "gfx-test-util.h"
-#include "gfx-util/shader-cursor.h"
-#include "slang-gfx.h"
+#include "slang-rhi/shader-cursor.h"
#include "unit-test/slang-unit-test.h"
+#include <slang-rhi.h>
+
#if SLANG_WINDOWS_FAMILY
#include <d3d12.h>
#endif
-using namespace gfx;
+using namespace rhi;
namespace gfx_test
{
void getTextureResourceHandleTestImpl(IDevice* device, UnitTestContext* context)
{
- ITextureResource::Desc desc = {};
- desc.type = IResource::Type::Texture2D;
- desc.numMipLevels = 1;
+ TextureDesc desc = {};
+ desc.type = TextureType::Texture2D;
+ desc.mipCount = 1;
desc.size.width = 1;
desc.size.height = 1;
desc.size.depth = 1;
desc.defaultState = ResourceState::UnorderedAccess;
- desc.format = Format::R16G16B16A16_FLOAT;
+ desc.format = Format::RGBA16Float;
+ desc.usage = TextureUsage::UnorderedAccess;
- Slang::ComPtr<ITextureResource> buffer;
- buffer = device->createTextureResource(desc);
+ Slang::ComPtr<ITexture> texture;
+ GFX_CHECK_CALL_ABORT(device->createTexture(desc, nullptr, texture.writeRef()));
- InteropHandle handle;
- GFX_CHECK_CALL_ABORT(buffer->getNativeResourceHandle(&handle));
- if (device->getDeviceInfo().deviceType == gfx::DeviceType::Vulkan)
+ NativeHandle handle;
+ GFX_CHECK_CALL_ABORT(texture->getNativeHandle(&handle));
+ if (device->getInfo().deviceType == rhi::DeviceType::Vulkan)
{
- SLANG_CHECK(handle.handleValue != 0);
- SLANG_CHECK(handle.api == InteropHandleAPI::Vulkan);
+ SLANG_CHECK(handle.value != 0);
}
#if SLANG_WINDOWS_FAMILY
else
{
- SLANG_CHECK(handle.api == InteropHandleAPI::D3D12);
- auto d3d12Handle = (ID3D12Resource*)handle.handleValue;
+ auto d3d12Handle = (ID3D12Resource*)handle.value;
Slang::ComPtr<IUnknown> testHandle1;
GFX_CHECK_CALL_ABORT(d3d12Handle->QueryInterface<IUnknown>(testHandle1.writeRef()));
Slang::ComPtr<ID3D12Resource> testHandle2;
@@ -50,23 +50,24 @@ void getTextureResourceHandleTestImpl(IDevice* device, UnitTestContext* context)
void getTextureResourceHandleTestAPI(UnitTestContext* context, Slang::RenderApiFlag::Enum api)
{
- gfxEnableDebugLayer(context->enableDebugLayers);
+ if (context->enableDebugLayers)
+ getRHI()->enableDebugLayers();
if ((api & context->enabledApis) == 0)
{
SLANG_IGNORE_TEST;
}
Slang::ComPtr<IDevice> device;
- IDevice::Desc deviceDesc = {};
+ DeviceDesc deviceDesc = {};
switch (api)
{
case Slang::RenderApiFlag::D3D11:
- deviceDesc.deviceType = gfx::DeviceType::DirectX11;
+ deviceDesc.deviceType = rhi::DeviceType::D3D11;
break;
case Slang::RenderApiFlag::D3D12:
- deviceDesc.deviceType = gfx::DeviceType::DirectX12;
+ deviceDesc.deviceType = rhi::DeviceType::D3D12;
break;
case Slang::RenderApiFlag::Vulkan:
- deviceDesc.deviceType = gfx::DeviceType::Vulkan;
+ deviceDesc.deviceType = rhi::DeviceType::Vulkan;
break;
default:
SLANG_IGNORE_TEST;
@@ -75,14 +76,14 @@ void getTextureResourceHandleTestAPI(UnitTestContext* context, Slang::RenderApiF
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());
+ auto createDeviceResult = getRHI()->createDevice(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"))
+ if (Slang::String(device->getInfo().adapterName).toLower().contains("swiftshader"))
{
SLANG_IGNORE_TEST;
}
diff --git a/tools/gfx-unit-test/gfx-test-texture-util.cpp b/tools/gfx-unit-test/gfx-test-texture-util.cpp
index a0212b7b0..54e6416d7 100644
--- a/tools/gfx-unit-test/gfx-test-texture-util.cpp
+++ b/tools/gfx-unit-test/gfx-test-texture-util.cpp
@@ -1,9 +1,6 @@
#include "gfx-test-texture-util.h"
-#include "gfx-test-util.h"
-#include "slang-com-ptr.h"
-#include "unit-test/slang-unit-test.h"
-
+#include <slang-com-ptr.h>
#include <stdio.h>
#include <stdlib.h>
@@ -17,216 +14,169 @@
#pragma warning(pop)
#endif
-#define GFX_ENABLE_RENDERDOC_INTEGRATION 0
-
-#if GFX_ENABLE_RENDERDOC_INTEGRATION
-#include "external/renderdoc_app.h"
-
-#include <windows.h>
-#endif
-
-using namespace Slang;
-using namespace gfx;
-
namespace gfx_test
{
-TextureAspect getTextureAspect(Format format)
+
+TextureInfo::~TextureInfo()
{
- switch (format)
+ for (SubresourceData subresourceData : subresourceDatas)
{
- case Format::D16_UNORM:
- case Format::D32_FLOAT:
- return TextureAspect::Depth;
- default:
- return TextureAspect::Color;
+ ::free((void*)subresourceData.data);
}
}
-gfx::Size getTexelSize(Format format)
+Size getTexelSize(Format format)
{
- FormatInfo info;
- GFX_CHECK_CALL_ABORT(gfxGetFormatInfo(format, &info));
+ const FormatInfo& info = getFormatInfo(format);
return info.blockSizeInBytes / info.pixelsPerBlock;
}
-GfxIndex getSubresourceIndex(GfxIndex mipLevel, GfxCount mipLevelCount, GfxIndex baseArrayLayer)
-{
- return baseArrayLayer * mipLevelCount + mipLevel;
-}
-
RefPtr<ValidationTextureFormatBase> getValidationTextureFormat(Format 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:
+ case Format::RGBA32Float:
return new ValidationTextureFormat<float>(4);
- case Format::R32G32B32_FLOAT:
+ case Format::RGB32Float:
return new ValidationTextureFormat<float>(3);
- case Format::R32G32_FLOAT:
+ case Format::RG32Float:
return new ValidationTextureFormat<float>(2);
- case Format::R32_FLOAT:
+ case Format::R32Float:
return new ValidationTextureFormat<float>(1);
- case Format::R16G16B16A16_FLOAT:
+ case Format::RGBA16Float:
return new ValidationTextureFormat<uint16_t>(4);
- case Format::R16G16_FLOAT:
+ case Format::RG16Float:
return new ValidationTextureFormat<uint16_t>(2);
- case Format::R16_FLOAT:
+ case Format::R16Float:
return new ValidationTextureFormat<uint16_t>(1);
- case Format::R64_UINT:
+ case Format::R64Uint:
return new ValidationTextureFormat<uint64_t>(1);
- case Format::R32G32B32A32_UINT:
+ case Format::RGBA32Uint:
return new ValidationTextureFormat<uint32_t>(4);
- case Format::R32G32B32_UINT:
+ case Format::RGB32Uint:
return new ValidationTextureFormat<uint32_t>(3);
- case Format::R32G32_UINT:
+ case Format::RG32Uint:
return new ValidationTextureFormat<uint32_t>(2);
- case Format::R32_UINT:
+ case Format::R32Uint:
return new ValidationTextureFormat<uint32_t>(1);
- case Format::R16G16B16A16_UINT:
+ case Format::RGBA16Uint:
return new ValidationTextureFormat<uint16_t>(4);
- case Format::R16G16_UINT:
+ case Format::RG16Uint:
return new ValidationTextureFormat<uint16_t>(2);
- case Format::R16_UINT:
+ case Format::R16Uint:
return new ValidationTextureFormat<uint16_t>(1);
- case Format::R8G8B8A8_UINT:
+ case Format::RGBA8Uint:
return new ValidationTextureFormat<uint8_t>(4);
- case Format::R8G8_UINT:
+ case Format::RG8Uint:
return new ValidationTextureFormat<uint8_t>(2);
- case Format::R8_UINT:
+ case Format::R8Uint:
return new ValidationTextureFormat<uint8_t>(1);
- case Format::R64_SINT:
+ case Format::R64Sint:
return new ValidationTextureFormat<int64_t>(1);
- case Format::R32G32B32A32_SINT:
+ case Format::RGBA32Sint:
return new ValidationTextureFormat<int32_t>(4);
- case Format::R32G32B32_SINT:
+ case Format::RGB32Sint:
return new ValidationTextureFormat<int32_t>(3);
- case Format::R32G32_SINT:
+ case Format::RG32Sint:
return new ValidationTextureFormat<int32_t>(2);
- case Format::R32_SINT:
+ case Format::R32Sint:
return new ValidationTextureFormat<int32_t>(1);
- case Format::R16G16B16A16_SINT:
+ case Format::RGBA16Sint:
return new ValidationTextureFormat<int16_t>(4);
- case Format::R16G16_SINT:
+ case Format::RG16Sint:
return new ValidationTextureFormat<int16_t>(2);
- case Format::R16_SINT:
+ case Format::R16Sint:
return new ValidationTextureFormat<int16_t>(1);
- case Format::R8G8B8A8_SINT:
+ case Format::RGBA8Sint:
return new ValidationTextureFormat<int8_t>(4);
- case Format::R8G8_SINT:
+ case Format::RG8Sint:
return new ValidationTextureFormat<int8_t>(2);
- case Format::R8_SINT:
+ case Format::R8Sint:
return new ValidationTextureFormat<int8_t>(1);
- case Format::R16G16B16A16_UNORM:
+ case Format::RGBA16Unorm:
return new ValidationTextureFormat<uint16_t>(4);
- case Format::R16G16_UNORM:
+ case Format::RG16Unorm:
return new ValidationTextureFormat<uint16_t>(2);
- case Format::R16_UNORM:
+ case Format::R16Unorm:
return new ValidationTextureFormat<uint16_t>(1);
- case Format::R8G8B8A8_UNORM:
+ case Format::RGBA8Unorm:
return new ValidationTextureFormat<uint8_t>(4);
- case Format::R8G8B8A8_UNORM_SRGB:
+ case Format::RGBA8UnormSrgb:
return new ValidationTextureFormat<uint8_t>(4);
- case Format::R8G8_UNORM:
+ case Format::RG8Unorm:
return new ValidationTextureFormat<uint8_t>(2);
- case Format::R8_UNORM:
+ case Format::R8Unorm:
return new ValidationTextureFormat<uint8_t>(1);
- case Format::B8G8R8A8_UNORM:
+ case Format::BGRA8Unorm:
return new ValidationTextureFormat<uint8_t>(4);
- case Format::B8G8R8A8_UNORM_SRGB:
+ case Format::BGRA8UnormSrgb:
return new ValidationTextureFormat<uint8_t>(4);
- case Format::B8G8R8X8_UNORM:
+ case Format::BGRX8Unorm:
return new ValidationTextureFormat<uint8_t>(3);
- case Format::B8G8R8X8_UNORM_SRGB:
+ case Format::BGRX8UnormSrgb:
return new ValidationTextureFormat<uint8_t>(3);
- case Format::R16G16B16A16_SNORM:
+ case Format::RGBA16Snorm:
return new ValidationTextureFormat<int16_t>(4);
- case Format::R16G16_SNORM:
+ case Format::RG16Snorm:
return new ValidationTextureFormat<int16_t>(2);
- case Format::R16_SNORM:
+ case Format::R16Snorm:
return new ValidationTextureFormat<int16_t>(1);
- case Format::R8G8B8A8_SNORM:
+ case Format::RGBA8Snorm:
return new ValidationTextureFormat<int8_t>(4);
- case Format::R8G8_SNORM:
+ case Format::RG8Snorm:
return new ValidationTextureFormat<int8_t>(2);
- case Format::R8_SNORM:
+ case Format::R8Snorm:
return new ValidationTextureFormat<int8_t>(1);
- case Format::D32_FLOAT:
+ case Format::D32Float:
return new ValidationTextureFormat<float>(1);
- case Format::D16_UNORM:
+ case Format::D16Unorm:
return new ValidationTextureFormat<uint16_t>(1);
- case Format::B4G4R4A4_UNORM:
+ case Format::BGRA4Unorm:
return new PackedValidationTextureFormat<uint16_t>(4, 4, 4, 4);
- case Format::B5G6R5_UNORM:
+ case Format::B5G6R5Unorm:
return new PackedValidationTextureFormat<uint16_t>(5, 6, 5, 0);
- case Format::B5G5R5A1_UNORM:
+ case Format::BGR5A1Unorm:
return new PackedValidationTextureFormat<uint16_t>(5, 5, 5, 1);
- case Format::R9G9B9E5_SHAREDEXP:
+ case Format::RGB9E5Ufloat:
return new ValidationTextureFormat<uint32_t>(1);
- case Format::R10G10B10A2_TYPELESS:
+ case Format::RGB10A2Unorm:
return new PackedValidationTextureFormat<uint32_t>(10, 10, 10, 2);
- case Format::R10G10B10A2_UNORM:
+ case Format::RGB10A2Uint:
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:
+ case Format::R11G11B10Float:
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,
+ // BC1Unorm,
+ // BC1UnormSrgb,
+ // BC2Unorm,
+ // BC2UnormSrgb,
+ // BC3Unorm,
+ // BC3UnormSrgb,
+ // BC4Unorm,
+ // BC4Snorm,
+ // BC5Unorm,
+ // BC5Snorm,
+ // BC6HUfloat,
+ // BC6HSfloat,
+ // BC7Unorm,
+ // BC7UnormSrgb,
default:
return nullptr;
}
@@ -234,31 +184,33 @@ RefPtr<ValidationTextureFormatBase> getValidationTextureFormat(Format 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)
+ Extent3D extent = texture->extent;
+ uint32_t layerCount = texture->arrayLength;
+ if (texture->textureType == TextureType::TextureCube)
+ layerCount *= 6;
+ uint32_t mipLevels = texture->mipCount;
+ Size texelSize = getTexelSize(texture->format);
+
+ for (uint32_t layer = 0; layer < layerCount; ++layer)
{
- for (GfxIndex mip = 0; mip < mipLevels; ++mip)
+ for (uint32_t 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);
+ uint32_t mipWidth = std::max(extent.width >> mip, 1u);
+ uint32_t mipHeight = std::max(extent.height >> mip, 1u);
+ uint32_t mipDepth = std::max(extent.depth >> mip, 1u);
+ uint32_t mipSize = mipWidth * mipHeight * mipDepth * texelSize;
+ subresource->textureData = ::malloc(mipSize);
+ assert(subresource->textureData != nullptr);
+
+ subresource->extent.width = mipWidth;
+ subresource->extent.height = mipHeight;
+ subresource->extent.depth = mipDepth;
+ subresource->pitches.x = texelSize;
+ subresource->pitches.y = mipWidth * texelSize;
+ subresource->pitches.z = mipHeight * subresource->pitches.y;
+ texture->subresourceObjects.push_back(subresource);
for (int z = 0; z < mipDepth; ++z)
{
@@ -272,30 +224,30 @@ void generateTextureData(RefPtr<TextureInfo> texture, ValidationTextureFormatBas
}
}
- ITextureResource::SubresourceData subData = {};
+ SubresourceData subData = {};
subData.data = subresource->textureData;
- subData.strideY = subresource->strides.y;
- subData.strideZ = subresource->strides.z;
- texture->subresourceDatas.add(subData);
+ subData.rowPitch = subresource->pitches.y;
+ subData.slicePitch = subresource->pitches.z;
+ texture->subresourceDatas.push_back(subData);
}
}
}
-List<uint8_t> removePadding(
+std::vector<uint8_t> removePadding(
ISlangBlob* pixels,
- GfxCount width,
- GfxCount height,
- gfx::Size rowPitch,
- gfx::Size pixelSize)
+ uint32_t width,
+ uint32_t height,
+ Size rowPitch,
+ Size pixelSize)
{
- List<uint8_t> buffer;
- buffer.setCount(height * rowPitch);
- for (GfxIndex i = 0; i < height; ++i)
+ std::vector<uint8_t> buffer;
+ buffer.resize(height * rowPitch);
+ for (uint32_t i = 0; i < height; ++i)
{
Offset srcOffset = i * rowPitch;
Offset dstOffset = i * width * pixelSize;
memcpy(
- buffer.getBuffer() + dstOffset,
+ buffer.data() + dstOffset,
(char*)pixels->getBufferPointer() + srcOffset,
width * pixelSize);
}
@@ -303,14 +255,14 @@ List<uint8_t> removePadding(
return buffer;
}
-Slang::Result writeImage(const char* filename, ISlangBlob* pixels, uint32_t width, uint32_t height)
+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 stbResult ? SLANG_OK : SLANG_FAIL;
}
-Slang::Result writeImage(
+Result writeImage(
const char* filename,
ISlangBlob* pixels,
uint32_t width,
@@ -321,10 +273,11 @@ Slang::Result writeImage(
if (rowPitch == width * pixelSize)
return writeImage(filename, pixels, width, height);
- List<uint8_t> buffer = removePadding(pixels, width, height, rowPitch, pixelSize);
+ std::vector<uint8_t> buffer = removePadding(pixels, width, height, rowPitch, pixelSize);
- int stbResult = stbi_write_hdr(filename, width, height, 4, (float*)buffer.getBuffer());
+ int stbResult = stbi_write_hdr(filename, width, height, 4, (float*)buffer.data());
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 d084628e2..981eee44f 100644
--- a/tools/gfx-unit-test/gfx-test-texture-util.h
+++ b/tools/gfx-unit-test/gfx-test-texture-util.h
@@ -1,20 +1,20 @@
#pragma once
#include "core/slang-basic.h"
-#include "core/slang-render-api-util.h"
-#include "slang-gfx.h"
+#include "slang-rhi.h"
#include "unit-test/slang-unit-test.h"
-using namespace Slang;
-using namespace gfx;
+using namespace rhi;
+using Slang::RefObject;
+using Slang::RefPtr;
namespace gfx_test
{
struct Strides
{
- gfx::Size x;
- gfx::Size y;
- gfx::Size z;
+ Size x;
+ Size y;
+ Size z;
};
struct ValidationTextureFormatBase : RefObject
@@ -23,19 +23,19 @@ struct ValidationTextureFormatBase : RefObject
virtual void initializeTexel(
void* texel,
- GfxIndex x,
- GfxIndex y,
- GfxIndex z,
- GfxIndex mipLevel,
- GfxIndex arrayLayer) = 0;
+ uint32_t x,
+ uint32_t y,
+ uint32_t z,
+ uint32_t mip,
+ uint32_t layer) = 0;
};
template<typename T>
struct ValidationTextureFormat : ValidationTextureFormatBase
{
- int componentCount;
+ uint32_t componentCount;
- ValidationTextureFormat(int componentCount)
+ ValidationTextureFormat(uint32_t componentCount)
: componentCount(componentCount){};
virtual void validateBlocksEqual(const void* actual, const void* expected) override
@@ -43,7 +43,7 @@ struct ValidationTextureFormat : ValidationTextureFormatBase
auto a = (const T*)actual;
auto e = (const T*)expected;
- for (Int i = 0; i < componentCount; ++i)
+ for (uint32_t i = 0; i < componentCount; ++i)
{
SLANG_CHECK(a[i] == e[i]);
}
@@ -51,36 +51,36 @@ struct ValidationTextureFormat : ValidationTextureFormatBase
virtual void initializeTexel(
void* texel,
- GfxIndex x,
- GfxIndex y,
- GfxIndex z,
- GfxIndex mipLevel,
- GfxIndex arrayLayer) override
+ uint32_t x,
+ uint32_t y,
+ uint32_t z,
+ uint32_t mip,
+ uint32_t layer) override
{
auto temp = (T*)texel;
switch (componentCount)
{
case 1:
- temp[0] = T(x + y + z + mipLevel + arrayLayer);
+ temp[0] = T(x + y + z + mip + layer);
break;
case 2:
- temp[0] = T(x + z + arrayLayer);
- temp[1] = T(y + mipLevel);
+ temp[0] = T(x + z + layer);
+ temp[1] = T(y + mip);
break;
case 3:
- temp[0] = T(x + mipLevel);
- temp[1] = T(y + arrayLayer);
+ temp[0] = T(x + mip);
+ temp[1] = T(y + layer);
temp[2] = T(z);
break;
case 4:
- temp[0] = T(x + arrayLayer);
+ temp[0] = T(x + layer);
temp[1] = (T)y;
temp[2] = (T)z;
- temp[3] = (T)mipLevel;
+ temp[3] = (T)mip;
break;
default:
- assert(!"component count should be no greater than 4");
+ assert("component count should be no greater than 4");
SLANG_CHECK_ABORT(false);
}
}
@@ -104,7 +104,7 @@ struct PackedValidationTextureFormat : ValidationTextureFormatBase
unpackTexel(*(const T*)actual, a);
unpackTexel(*(const T*)expected, e);
- for (Int i = 0; i < 4; ++i)
+ for (uint32_t i = 0; i < 4; ++i)
{
SLANG_CHECK(a[i] == e[i]);
}
@@ -112,11 +112,11 @@ struct PackedValidationTextureFormat : ValidationTextureFormatBase
virtual void initializeTexel(
void* texel,
- GfxIndex x,
- GfxIndex y,
- GfxIndex z,
- GfxIndex mipLevel,
- GfxIndex arrayLayer) override
+ uint32_t x,
+ uint32_t y,
+ uint32_t z,
+ uint32_t mip,
+ uint32_t layer) override
{
T temp = 0;
@@ -125,19 +125,19 @@ struct PackedValidationTextureFormat : ValidationTextureFormatBase
{
temp |= z;
temp <<= gBits;
- temp |= (y + arrayLayer);
+ temp |= (y + layer);
temp <<= rBits;
- temp |= (x + mipLevel);
+ temp |= (x + mip);
}
else
{
- temp |= mipLevel;
+ temp |= mip;
temp <<= bBits;
temp |= z;
temp <<= gBits;
temp |= y;
temp <<= rBits;
- temp |= (x + arrayLayer);
+ temp |= (x + layer);
}
*(T*)texel = temp;
@@ -163,18 +163,18 @@ struct PackedValidationTextureFormat : ValidationTextureFormatBase
struct ValidationTextureData : RefObject
{
const void* textureData;
- ITextureResource::Extents extents;
- Strides strides;
+ Extent3D extent;
+ Strides pitches;
- void* getBlockAt(GfxIndex x, GfxIndex y, GfxIndex z)
+ void* getBlockAt(uint32_t x, uint32_t y, uint32_t z)
{
- assert(x >= 0 && x < extents.width);
- assert(y >= 0 && y < extents.height);
- assert(z >= 0 && z < extents.depth);
+ assert(x < extent.width);
+ assert(y < extent.height);
+ assert(z < extent.depth);
- char* layerData = (char*)textureData + z * strides.z;
- char* rowData = layerData + y * strides.y;
- return rowData + x * strides.x;
+ char* layerData = (char*)textureData + z * pitches.z;
+ char* rowData = layerData + y * pitches.y;
+ return rowData + x * pitches.x;
}
};
@@ -183,36 +183,54 @@ struct ValidationTextureData : RefObject
struct TextureInfo : RefObject
{
Format format;
- ITextureResource::Type textureType;
+ TextureType textureType;
- ITextureResource::Extents extents;
- GfxCount mipLevelCount;
- GfxCount arrayLayerCount;
+ Extent3D extent;
+ uint32_t mipCount;
+ uint32_t arrayLength;
- List<RefPtr<ValidationTextureData>> subresourceObjects;
- List<ITextureResource::SubresourceData> subresourceDatas;
+ std::vector<RefPtr<ValidationTextureData>> subresourceObjects;
+ std::vector<SubresourceData> subresourceDatas;
+
+ ~TextureInfo();
};
-TextureAspect getTextureAspect(Format format);
-gfx::Size getTexelSize(Format format);
-GfxIndex getSubresourceIndex(GfxIndex mipLevel, GfxCount mipLevelCount, GfxIndex baseArrayLayer);
+inline TextureType toArrayType(TextureType type)
+{
+ switch (type)
+ {
+ case TextureType::Texture1D:
+ return TextureType::Texture1DArray;
+ case TextureType::Texture2D:
+ return TextureType::Texture2DArray;
+ case TextureType::Texture2DMS:
+ return TextureType::Texture2DMSArray;
+ case TextureType::TextureCube:
+ return TextureType::TextureCubeArray;
+ default:
+ return type;
+ }
+}
+
+Size getTexelSize(Format format);
RefPtr<ValidationTextureFormatBase> getValidationTextureFormat(Format format);
void generateTextureData(
RefPtr<TextureInfo> texture,
ValidationTextureFormatBase* validationFormat);
-List<uint8_t> removePadding(
+std::vector<uint8_t> removePadding(
ISlangBlob* pixels,
- GfxCount width,
- GfxCount height,
- gfx::Size rowPitch,
- gfx::Size pixelSize);
-Slang::Result writeImage(const char* filename, ISlangBlob* pixels, uint32_t width, uint32_t height);
-Slang::Result writeImage(
+ uint32_t width,
+ uint32_t height,
+ Size rowPitch,
+ Size pixelSize);
+Result writeImage(const char* filename, ISlangBlob* pixels, uint32_t width, uint32_t height);
+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 688bf048e..4072b9814 100644
--- a/tools/gfx-unit-test/gfx-test-util.cpp
+++ b/tools/gfx-unit-test/gfx-test-util.cpp
@@ -15,6 +15,29 @@ using Slang::ComPtr;
namespace gfx_test
{
+class DebugPrinter : public rhi::IDebugCallback
+{
+public:
+ virtual SLANG_NO_THROW void SLANG_MCALL handleMessage(
+ rhi::DebugMessageType type,
+ rhi::DebugMessageSource source,
+ const char* message) override
+ {
+ static const char* kTypeStrings[] = {"INFO", "WARN", "ERROR"};
+ static const char* kSourceStrings[] = {"Layer", "Driver", "Slang"};
+ if (type == rhi::DebugMessageType::Error)
+ {
+ printf("[%s] (%s) %s\n", kTypeStrings[int(type)], kSourceStrings[int(source)], message);
+ fflush(stdout);
+ }
+ }
+ static DebugPrinter* getInstance()
+ {
+ static DebugPrinter instance;
+ return &instance;
+ }
+};
+
void diagnoseIfNeeded(slang::IBlob* diagnosticsBlob)
{
if (diagnosticsBlob != nullptr)
@@ -25,16 +48,16 @@ void diagnoseIfNeeded(slang::IBlob* diagnosticsBlob)
}
}
-Slang::Result loadComputeProgram(
- gfx::IDevice* device,
- Slang::ComPtr<gfx::IShaderProgram>& outShaderProgram,
+Result loadComputeProgram(
+ IDevice* device,
+ ComPtr<IShaderProgram>& outShaderProgram,
const char* shaderModuleName,
const char* entryPointName,
slang::ProgramLayout*& slangReflection)
{
- Slang::ComPtr<slang::ISession> slangSession;
+ ComPtr<slang::ISession> slangSession;
SLANG_RETURN_ON_FAIL(device->getSlangSession(slangSession.writeRef()));
- Slang::ComPtr<slang::IBlob> diagnosticsBlob;
+ ComPtr<slang::IBlob> diagnosticsBlob;
slang::IModule* module = slangSession->loadModule(shaderModuleName, diagnosticsBlob.writeRef());
diagnoseIfNeeded(diagnosticsBlob);
if (!module)
@@ -44,14 +67,14 @@ Slang::Result loadComputeProgram(
SLANG_RETURN_ON_FAIL(
module->findEntryPointByName(entryPointName, computeEntryPoint.writeRef()));
- Slang::List<slang::IComponentType*> componentTypes;
- componentTypes.add(module);
- componentTypes.add(computeEntryPoint);
+ std::vector<slang::IComponentType*> componentTypes;
+ componentTypes.push_back(module);
+ componentTypes.push_back(computeEntryPoint);
- Slang::ComPtr<slang::IComponentType> composedProgram;
- SlangResult result = slangSession->createCompositeComponentType(
- componentTypes.getBuffer(),
- componentTypes.getCount(),
+ ComPtr<slang::IComponentType> composedProgram;
+ Result result = slangSession->createCompositeComponentType(
+ componentTypes.data(),
+ componentTypes.size(),
composedProgram.writeRef(),
diagnosticsBlob.writeRef());
diagnoseIfNeeded(diagnosticsBlob);
@@ -62,30 +85,21 @@ Slang::Result loadComputeProgram(
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);
- if (!shaderProgram)
- return SLANG_FAIL;
-
- outShaderProgram = shaderProgram;
- return SLANG_OK;
+ slangReflection = linkedProgram->getLayout();
+ outShaderProgram = device->createShaderProgram(linkedProgram, diagnosticsBlob.writeRef());
+ diagnoseIfNeeded(diagnosticsBlob);
+ return outShaderProgram ? SLANG_OK : SLANG_FAIL;
}
-Slang::Result loadComputeProgram(
- gfx::IDevice* device,
+Result loadComputeProgram(
+ IDevice* device,
slang::ISession* slangSession,
- Slang::ComPtr<gfx::IShaderProgram>& outShaderProgram,
+ ComPtr<IShaderProgram>& outShaderProgram,
const char* shaderModuleName,
const char* entryPointName,
- slang::ProgramLayout*& slangReflection,
- PrecompilationMode precompilationMode)
+ slang::ProgramLayout*& slangReflection)
{
- Slang::ComPtr<slang::IBlob> diagnosticsBlob;
+ ComPtr<slang::IBlob> diagnosticsBlob;
slang::IModule* module = slangSession->loadModule(shaderModuleName, diagnosticsBlob.writeRef());
diagnoseIfNeeded(diagnosticsBlob);
if (!module)
@@ -95,14 +109,14 @@ Slang::Result loadComputeProgram(
SLANG_RETURN_ON_FAIL(
module->findEntryPointByName(entryPointName, computeEntryPoint.writeRef()));
- Slang::List<slang::IComponentType*> componentTypes;
- componentTypes.add(module);
- componentTypes.add(computeEntryPoint);
+ std::vector<slang::IComponentType*> componentTypes;
+ componentTypes.push_back(module);
+ componentTypes.push_back(computeEntryPoint);
- Slang::ComPtr<slang::IComponentType> composedProgram;
- SlangResult result = slangSession->createCompositeComponentType(
- componentTypes.getBuffer(),
- componentTypes.getCount(),
+ ComPtr<slang::IComponentType> composedProgram;
+ Result result = slangSession->createCompositeComponentType(
+ componentTypes.data(),
+ componentTypes.size(),
composedProgram.writeRef(),
diagnosticsBlob.writeRef());
diagnoseIfNeeded(diagnosticsBlob);
@@ -113,55 +127,71 @@ Slang::Result loadComputeProgram(
diagnoseIfNeeded(diagnosticsBlob);
SLANG_RETURN_ON_FAIL(result);
- composedProgram = linkedProgram;
- slangReflection = composedProgram->getLayout();
-
- gfx::IShaderProgram::Desc programDesc = {};
- programDesc.slangGlobalScope = composedProgram.get();
- if (precompilationMode == PrecompilationMode::ExternalLink)
- {
- programDesc.downstreamLinkMode = gfx::IShaderProgram::DownstreamLinkMode::Deferred;
- }
- else
- {
- programDesc.downstreamLinkMode = gfx::IShaderProgram::DownstreamLinkMode::None;
- }
-
- auto shaderProgram = device->createProgram(programDesc);
-
- outShaderProgram = shaderProgram;
- return SLANG_OK;
+ slangReflection = linkedProgram->getLayout();
+ outShaderProgram = device->createShaderProgram(linkedProgram, diagnosticsBlob.writeRef());
+ diagnoseIfNeeded(diagnosticsBlob);
+ return outShaderProgram ? SLANG_OK : SLANG_FAIL;
}
-Slang::Result loadComputeProgramFromSource(
- gfx::IDevice* device,
- Slang::ComPtr<gfx::IShaderProgram>& outShaderProgram,
- Slang::String source)
+Result loadComputeProgramFromSource(
+ IDevice* device,
+ ComPtr<IShaderProgram>& outShaderProgram,
+ std::string_view source)
{
- Slang::ComPtr<slang::IBlob> diagnosticsBlob;
+ auto slangSession = device->getSlangSession();
+ slang::IModule* module = nullptr;
+ ComPtr<slang::IBlob> diagnosticsBlob;
+ size_t hash = std::hash<std::string_view>()(source);
+ std::string moduleName = "source_module_" + std::to_string(hash);
+ auto srcBlob = Slang::UnownedRawBlob::create(source.data(), source.size());
+ module = slangSession->loadModuleFromSource(
+ moduleName.data(),
+ moduleName.data(),
+ srcBlob,
+ diagnosticsBlob.writeRef());
+ diagnoseIfNeeded(diagnosticsBlob);
+ if (!module)
+ return SLANG_FAIL;
+
+ std::vector<ComPtr<slang::IComponentType>> componentTypes;
+ componentTypes.push_back(ComPtr<slang::IComponentType>(module));
- gfx::IShaderProgram::CreateDesc2 programDesc = {};
- programDesc.sourceType = gfx::ShaderModuleSourceType::SlangSource;
- programDesc.sourceData = (void*)source.getBuffer();
- programDesc.sourceDataSize = source.getLength();
+ for (SlangInt32 i = 0; i < module->getDefinedEntryPointCount(); i++)
+ {
+ ComPtr<slang::IEntryPoint> entryPoint;
+ SLANG_RETURN_ON_FAIL(module->getDefinedEntryPoint(i, entryPoint.writeRef()));
+ componentTypes.push_back(ComPtr<slang::IComponentType>(entryPoint.get()));
+ }
- return device->createProgram2(
- programDesc,
- outShaderProgram.writeRef(),
+ std::vector<slang::IComponentType*> rawComponentTypes;
+ for (auto& compType : componentTypes)
+ rawComponentTypes.push_back(compType.get());
+
+ ComPtr<slang::IComponentType> linkedProgram;
+ Result result = slangSession->createCompositeComponentType(
+ rawComponentTypes.data(),
+ rawComponentTypes.size(),
+ linkedProgram.writeRef(),
diagnosticsBlob.writeRef());
+ diagnoseIfNeeded(diagnosticsBlob);
+ SLANG_RETURN_ON_FAIL(result);
+
+ outShaderProgram = device->createShaderProgram(linkedProgram, diagnosticsBlob.writeRef());
+ diagnoseIfNeeded(diagnosticsBlob);
+ return outShaderProgram ? SLANG_OK : SLANG_FAIL;
}
-Slang::Result loadGraphicsProgram(
- gfx::IDevice* device,
- Slang::ComPtr<gfx::IShaderProgram>& outShaderProgram,
+Result loadGraphicsProgram(
+ IDevice* device,
+ ComPtr<IShaderProgram>& outShaderProgram,
const char* shaderModuleName,
const char* vertexEntryPointName,
const char* fragmentEntryPointName,
slang::ProgramLayout*& slangReflection)
{
- Slang::ComPtr<slang::ISession> slangSession;
+ ComPtr<slang::ISession> slangSession;
SLANG_RETURN_ON_FAIL(device->getSlangSession(slangSession.writeRef()));
- Slang::ComPtr<slang::IBlob> diagnosticsBlob;
+ ComPtr<slang::IBlob> diagnosticsBlob;
slang::IModule* module = slangSession->loadModule(shaderModuleName, diagnosticsBlob.writeRef());
diagnoseIfNeeded(diagnosticsBlob);
if (!module)
@@ -175,158 +205,85 @@ Slang::Result loadGraphicsProgram(
SLANG_RETURN_ON_FAIL(
module->findEntryPointByName(fragmentEntryPointName, fragmentEntryPoint.writeRef()));
- Slang::List<slang::IComponentType*> componentTypes;
- componentTypes.add(module);
- componentTypes.add(vertexEntryPoint);
- componentTypes.add(fragmentEntryPoint);
+ std::vector<slang::IComponentType*> componentTypes;
+ componentTypes.push_back(module);
+ componentTypes.push_back(vertexEntryPoint);
+ componentTypes.push_back(fragmentEntryPoint);
- Slang::ComPtr<slang::IComponentType> composedProgram;
- SlangResult result = slangSession->createCompositeComponentType(
- componentTypes.getBuffer(),
- componentTypes.getCount(),
+ ComPtr<slang::IComponentType> composedProgram;
+ Result result = slangSession->createCompositeComponentType(
+ componentTypes.data(),
+ componentTypes.size(),
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)
-{
- // 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);
- }
-}
-
-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)
-{
- for (size_t i = 0; i < expectedBufferSize / sizeof(float); ++i)
- {
- SLANG_CHECK(abs(result[i] - expectedResult[i]) <= 0.01);
- }
-}
+ ComPtr<slang::IComponentType> linkedProgram;
+ result = composedProgram->link(linkedProgram.writeRef(), diagnosticsBlob.writeRef());
+ diagnoseIfNeeded(diagnosticsBlob);
+ SLANG_RETURN_ON_FAIL(result);
-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);
+ slangReflection = linkedProgram->getLayout();
+ outShaderProgram = device->createShaderProgram(linkedProgram, diagnosticsBlob.writeRef());
+ diagnoseIfNeeded(diagnosticsBlob);
+ return outShaderProgram ? SLANG_OK : SLANG_FAIL;
}
-Slang::ComPtr<gfx::IDevice> createTestingDevice(
+Slang::ComPtr<IDevice> createTestingDevice(
UnitTestContext* context,
- Slang::RenderApiFlag::Enum api,
- Slang::List<const char*> additionalSearchPaths,
- gfx::IDevice::ShaderCacheDesc shaderCache)
+ DeviceType deviceType,
+ Slang::List<const char*> additionalSearchPaths)
{
- 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
- }
+ Slang::ComPtr<IDevice> device;
+ DeviceDesc deviceDesc = {};
+ deviceDesc.deviceType = deviceType;
+
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;
+ deviceDesc.slang.searchPathCount = searchPaths.getCount();
- gfx::D3D12DeviceExtendedDesc extDesc = {};
- extDesc.rootParameterShaderAttributeName = "root";
+ std::vector<slang::PreprocessorMacroDesc> preprocessorMacros;
+ std::vector<slang::CompilerOptionEntry> compilerOptions;
- 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;
+ compilerOptions.push_back(emitSpirvDirectlyEntry);
+#if DEBUG_SPIRV
+ slang::CompilerOptionEntry debugLevelCompilerOptionEntry = {};
debugLevelCompilerOptionEntry.name = slang::CompilerOptionName::DebugInformation;
debugLevelCompilerOptionEntry.value.intValue0 = SLANG_DEBUG_INFO_LEVEL_STANDARD;
- entries.add(debugLevelCompilerOptionEntry);
+ compilerOptions.push_back(debugLevelCompilerOptionEntry);
+#endif
+#if DUMP_INTERMEDIATES
+ slang::CompilerOptionEntry dumpIntermediatesOptionEntry = {};
+ dumpIntermediatesOptionEntry.name = slang::CompilerOptionName::DumpIntermediates;
+ dumpIntermediatesOptionEntry.value.intValue0 = 1;
+ compilerOptions.push_back(dumpIntermediatesOptionEntry);
#endif
- slangExtDesc.compilerOptionEntries = entries.getBuffer();
- slangExtDesc.compilerOptionEntryCount = (uint32_t)entries.getCount();
- deviceDesc.extendedDescCount = 2;
- void* extDescPtrs[2] = {&extDesc, &slangExtDesc};
- deviceDesc.extendedDescs = extDescPtrs;
+ deviceDesc.slang.preprocessorMacros = preprocessorMacros.data();
+ deviceDesc.slang.preprocessorMacroCount = preprocessorMacros.size();
+ deviceDesc.slang.compilerOptionEntries = compilerOptions.data();
+ deviceDesc.slang.compilerOptionEntryCount = compilerOptions.size();
+
+ if (context->enableDebugLayers)
+ {
+ deviceDesc.enableValidation = context->enableDebugLayers;
+ deviceDesc.debugCallback = DebugPrinter::getInstance();
+ }
+
+ D3D12DeviceExtendedDesc extDesc = {};
+ if (deviceType == DeviceType::D3D12)
+ {
+ extDesc.rootParameterShaderAttributeName = "root";
+ deviceDesc.next = &extDesc;
+ }
- gfx::gfxEnableDebugLayer(context->enableDebugLayers);
- auto createDeviceResult = gfxCreateDevice(&deviceDesc, device.writeRef());
+ auto createDeviceResult = getRHI()->createDevice(deviceDesc, device.writeRef());
if (SLANG_FAILED(createDeviceResult))
{
SLANG_IGNORE_TEST
diff --git a/tools/gfx-unit-test/gfx-test-util.h b/tools/gfx-unit-test/gfx-test-util.h
index 3397584fc..38577cb08 100644
--- a/tools/gfx-unit-test/gfx-test-util.h
+++ b/tools/gfx-unit-test/gfx-test-util.h
@@ -1,10 +1,19 @@
#pragma once
#include "core/slang-basic.h"
+#include "core/slang-blob.h"
#include "core/slang-render-api-util.h"
-#include "slang-gfx.h"
+#include "core/slang-test-tool-util.h"
+#include "slang-rhi.h"
+#include "span.h"
#include "unit-test/slang-unit-test.h"
+// GFX_CHECK_CALL and GFX_CHECK_CALL_ABORT are used to check SlangResult
+#define GFX_CHECK_CALL(x) SLANG_CHECK(!SLANG_FAILED(x))
+#define GFX_CHECK_CALL_ABORT(x) SLANG_CHECK_ABORT(!SLANG_FAILED(x))
+
+using namespace rhi;
+
namespace gfx_test
{
enum class PrecompilationMode
@@ -17,90 +26,134 @@ enum class PrecompilationMode
/// 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`.
+/// Loads a compute shader module and produces a `rhi::IShaderProgram`.
Slang::Result loadComputeProgram(
- gfx::IDevice* device,
- Slang::ComPtr<gfx::IShaderProgram>& outShaderProgram,
+ rhi::IDevice* device,
+ Slang::ComPtr<rhi::IShaderProgram>& outShaderProgram,
const char* shaderModuleName,
const char* entryPointName,
slang::ProgramLayout*& slangReflection);
Slang::Result loadComputeProgram(
- gfx::IDevice* device,
+ rhi::IDevice* device,
slang::ISession* slangSession,
- Slang::ComPtr<gfx::IShaderProgram>& outShaderProgram,
+ Slang::ComPtr<rhi::IShaderProgram>& outShaderProgram,
const char* shaderModuleName,
const char* entryPointName,
- slang::ProgramLayout*& slangReflection,
- PrecompilationMode precompilationMode = PrecompilationMode::None);
+ slang::ProgramLayout*& slangReflection);
Slang::Result loadComputeProgramFromSource(
- gfx::IDevice* device,
- Slang::ComPtr<gfx::IShaderProgram>& outShaderProgram,
- Slang::String source);
+ rhi::IDevice* device,
+ Slang::ComPtr<rhi::IShaderProgram>& outShaderProgram,
+ std::string_view source);
Slang::Result loadGraphicsProgram(
- gfx::IDevice* device,
- Slang::ComPtr<gfx::IShaderProgram>& outShaderProgram,
+ rhi::IDevice* device,
+ Slang::ComPtr<rhi::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`.
+template<typename T>
+void compareResultFuzzy(const T* result, const T* expectedResult, size_t count)
+{
+ for (size_t i = 0; i < count; ++i)
+ {
+ SLANG_CHECK(abs(result[i] - expectedResult[i]) < 0.01f);
+ }
+}
+
+template<typename T>
+void compareResult(const T* result, const T* expectedResult, size_t count)
+{
+ for (size_t i = 0; i < count; i++)
+ {
+ SLANG_CHECK(result[i] == expectedResult[i]);
+ }
+}
+
+template<typename T>
+void compareComputeResult(rhi::IDevice* device, rhi::IBuffer* buffer, span<T> expectedResult)
+{
+ size_t bufferSize = expectedResult.size() * sizeof(T);
+ // Read back the results.`
+ ComPtr<ISlangBlob> bufferData;
+ SLANG_CHECK(SLANG_SUCCEEDED(device->readBuffer(buffer, 0, bufferSize, bufferData.writeRef())));
+ SLANG_CHECK(bufferData->getBufferSize() == bufferSize);
+ const T* result = reinterpret_cast<const T*>(bufferData->getBufferPointer());
+
+ if constexpr (std::is_same<T, float>::value || std::is_same<T, double>::value)
+ compareResultFuzzy(result, expectedResult.data(), expectedResult.size());
+ else
+ compareResult<T>(result, expectedResult.data(), expectedResult.size());
+}
+
+template<typename T, size_t Count>
void compareComputeResult(
- gfx::IDevice* device,
- gfx::IBufferResource* buffer,
- size_t offset,
- const void* expectedResult,
- size_t expectedBufferSize);
+ rhi::IDevice* device,
+ rhi::IBuffer* buffer,
+ std::array<T, Count> expectedResult)
+{
+ compareComputeResult(device, buffer, span<T>(expectedResult.data(), Count));
+}
-/// Reads back the content of `texture` and compares it against `expectedResult`.
+template<typename T>
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>
+ rhi::IDevice* device,
+ rhi::ITexture* texture,
+ uint32_t layer,
+ uint32_t mip,
+ span<T> expectedResult)
+{
+ size_t bufferSize = expectedResult.size() * sizeof(T);
+ // Read back the results.
+ ComPtr<ISlangBlob> textureData;
+ rhi::SubresourceLayout layout;
+ SLANG_CHECK(
+ SLANG_SUCCEEDED(device->readTexture(texture, layer, mip, textureData.writeRef(), &layout)));
+ SLANG_CHECK(textureData->getBufferSize() >= bufferSize);
+
+ uint8_t* buffer = (uint8_t*)textureData->getBufferPointer();
+ for (uint32_t z = 0; z < layout.size.depth; z++)
+ {
+ for (uint32_t y = 0; y < layout.size.height; y++)
+ {
+ for (uint32_t x = 0; x < layout.size.width; x++)
+ {
+ const uint8_t* src = reinterpret_cast<const uint8_t*>(
+ buffer + z * layout.slicePitch + y * layout.rowPitch + x * layout.colPitch);
+ uint8_t* dst = reinterpret_cast<uint8_t*>(
+ buffer +
+ (((z * layout.size.depth + y) * layout.size.width) + x) * layout.colPitch);
+ ::memcpy(dst, src, layout.colPitch);
+ }
+ }
+ }
+
+ const T* result = reinterpret_cast<const T*>(textureData->getBufferPointer());
+
+ if constexpr (std::is_same<T, float>::value)
+ compareResultFuzzy(result, expectedResult.data(), expectedResult.size());
+ else
+ compareResult<T>(result, expectedResult.data(), expectedResult.size());
+}
+
+template<typename T, size_t Count>
void compareComputeResult(
- gfx::IDevice* device,
- gfx::IBufferResource* buffer,
- Slang::Array<T, count> expectedResult)
+ rhi::IDevice* device,
+ rhi::ITexture* texture,
+ uint32_t layer,
+ uint32_t mip,
+ std::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);
+ compareComputeResult(device, texture, layer, mip, span<T>(expectedResult.data(), Count));
}
-Slang::ComPtr<gfx::IDevice> createTestingDevice(
+Slang::ComPtr<rhi::IDevice> createTestingDevice(
UnitTestContext* context,
- Slang::RenderApiFlag::Enum api,
- Slang::List<const char*> additionalSearchPaths = {},
- gfx::IDevice::ShaderCacheDesc shaderCache = {});
+ rhi::DeviceType deviceType,
+ Slang::List<const char*> additionalSearchPaths = {});
Slang::List<const char*> getSlangSearchPaths();
@@ -108,33 +161,64 @@ void initializeRenderDoc();
void renderDocBeginFrame();
void renderDocEndFrame();
+template<typename T, typename... Args>
+auto makeArray(Args... args)
+{
+ return std::array<T, sizeof...(Args)>{static_cast<T>(args)...};
+}
+
+inline bool deviceTypeInEnabledApis(rhi::DeviceType deviceType, Slang::RenderApiFlags enabledApis)
+{
+ switch (deviceType)
+ {
+ case rhi::DeviceType::Default:
+ return true;
+ case rhi::DeviceType::CPU:
+ return enabledApis & Slang::RenderApiFlag::CPU;
+ case rhi::DeviceType::CUDA:
+ return enabledApis & Slang::RenderApiFlag::CUDA;
+ case rhi::DeviceType::Metal:
+ return enabledApis & Slang::RenderApiFlag::Metal;
+ case rhi::DeviceType::WGPU:
+ return enabledApis & Slang::RenderApiFlag::WebGPU;
+ case rhi::DeviceType::Vulkan:
+ return enabledApis & Slang::RenderApiFlag::Vulkan;
+ case rhi::DeviceType::D3D11:
+ return enabledApis & Slang::RenderApiFlag::D3D11;
+ case rhi::DeviceType::D3D12:
+ return enabledApis & Slang::RenderApiFlag::D3D12;
+ }
+ return true;
+}
+
+
template<typename ImplFunc>
void runTestImpl(
const ImplFunc& f,
UnitTestContext* context,
- Slang::RenderApiFlag::Enum api,
- Slang::List<const char*> searchPaths = {},
- gfx::IDevice::ShaderCacheDesc shaderCache = {})
+ rhi::DeviceType deviceType,
+ Slang::List<const char*> searchPaths = {})
{
- if ((api & context->enabledApis) == 0)
+ if (!deviceTypeInEnabledApis(deviceType, context->enabledApis))
{
SLANG_IGNORE_TEST
}
- auto device = createTestingDevice(context, api, searchPaths, shaderCache);
+
+ auto device = createTestingDevice(context, deviceType, searchPaths);
if (!device)
{
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)
+ if (rhi::DeviceType == rhi::DeviceType::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)
+ if (deviceType == rhi::DeviceType::D3D11 && !SLANG_ENABLE_DXBC_SUPPORT)
{
SLANG_IGNORE_TEST
}
@@ -151,7 +235,4 @@ void runTestImpl(
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 636a4e2e4..b8f5d362f 100644
--- a/tools/gfx-unit-test/instanced-draw-tests.cpp
+++ b/tools/gfx-unit-test/instanced-draw-tests.cpp
@@ -1,7 +1,10 @@
+#if 0
+// Duplicated: This is tested in slang-rhi\tests\test-cmd-draw.cpp
+
#include "core/slang-basic.h"
#include "gfx-test-util.h"
-#include "gfx-util/shader-cursor.h"
#include "slang-gfx.h"
+#include "slang-rhi/shader-cursor.h"
#include "unit-test/slang-unit-test.h"
using namespace gfx;
@@ -602,3 +605,5 @@ SLANG_UNIT_TEST(drawIndexedIndirectVulkan)
Slang::RenderApiFlag::Vulkan);
}
} // namespace gfx_test
+
+#endif
diff --git a/tools/gfx-unit-test/link-time-constant-array-size.cpp b/tools/gfx-unit-test/link-time-constant-array-size.cpp
index e67e5636c..0c1c20c1d 100644
--- a/tools/gfx-unit-test/link-time-constant-array-size.cpp
+++ b/tools/gfx-unit-test/link-time-constant-array-size.cpp
@@ -1,17 +1,18 @@
#include "core/slang-basic.h"
#include "core/slang-blob.h"
#include "gfx-test-util.h"
-#include "gfx-util/shader-cursor.h"
-#include "slang-gfx.h"
#include "unit-test/slang-unit-test.h"
-using namespace gfx;
+#include <slang-rhi.h>
+#include <slang-rhi/shader-cursor.h>
+
+using namespace rhi;
namespace gfx_test
{
static Slang::Result loadProgram(
- gfx::IDevice* device,
- Slang::ComPtr<gfx::IShaderProgram>& outShaderProgram,
+ IDevice* device,
+ Slang::ComPtr<IShaderProgram>& outShaderProgram,
const char* mainModuleName,
const char* libModuleName,
const char* entryPointName,
@@ -64,10 +65,10 @@ static Slang::Result loadProgram(
slangReflection = composedProgram->getLayout();
// Create shader program
- gfx::IShaderProgram::Desc programDesc = {};
+ ShaderProgramDesc programDesc = {};
programDesc.slangGlobalScope = composedProgram.get();
- auto shaderProgram = device->createProgram(programDesc);
+ auto shaderProgram = device->createShaderProgram(programDesc);
outShaderProgram = shaderProgram;
return SLANG_OK;
@@ -80,20 +81,18 @@ static void validateArraySizeInStruct(
int expectedSize)
{
// Check reflection is available
- SLANG_CHECK(slangReflection != nullptr);
+ SLANG_CHECK_ABORT(slangReflection != nullptr);
// Get the global scope layout
auto globalScope = slangReflection->getGlobalParamsVarLayout();
- SLANG_CHECK_MSG(globalScope != nullptr, "Could not get global scope layout");
+ SLANG_CHECK_ABORT(globalScope != nullptr);
auto typeLayout = globalScope->getTypeLayout();
- SLANG_CHECK_MSG(typeLayout != nullptr, "Global scope has no type layout");
+ SLANG_CHECK_ABORT(typeLayout != nullptr);
// Check if the global scope is a struct type
auto kind = typeLayout->getKind();
- SLANG_CHECK_MSG(
- kind == slang::TypeReflection::Kind::Struct,
- "Global scope is not a struct type");
+ SLANG_CHECK_ABORT(kind == slang::TypeReflection::Kind::Struct);
// Find the buffer resource 'b'
bool foundBuffer = false;
@@ -117,7 +116,6 @@ static void validateArraySizeInStruct(
SLANG_CHECK_MSG(
elementTypeLayout != nullptr,
"Structured buffer has no element type layout");
-
// Check if it's a struct type
auto elementKind = elementTypeLayout->getKind();
SLANG_CHECK_MSG(
@@ -176,13 +174,6 @@ static void validateArraySizeInStruct(
void linkTimeConstantArraySizeTestImpl(IDevice* device, UnitTestContext* context)
{
- // Create transient heap
- Slang::ComPtr<ITransientResourceHeap> transientHeap;
- ITransientResourceHeap::Desc transientHeapDesc = {};
- transientHeapDesc.constantBufferSize = 4096;
- GFX_CHECK_CALL_ABORT(
- device->createTransientResourceHeap(transientHeapDesc, transientHeap.writeRef()));
-
// Load and link program
ComPtr<IShaderProgram> shaderProgram;
slang::ProgramLayout* slangReflection;
@@ -200,70 +191,56 @@ void linkTimeConstantArraySizeTestImpl(IDevice* device, UnitTestContext* context
validateArraySizeInStruct(context, slangReflection, N);
// Create compute pipeline
- ComputePipelineStateDesc pipelineDesc = {};
+ ComputePipelineDesc pipelineDesc = {};
pipelineDesc.program = shaderProgram.get();
- ComPtr<gfx::IPipelineState> pipelineState;
- GFX_CHECK_CALL_ABORT(
- device->createComputePipelineState(pipelineDesc, pipelineState.writeRef()));
+ ComPtr<IComputePipeline> pipelineState;
+ GFX_CHECK_CALL_ABORT(device->createComputePipeline(pipelineDesc, pipelineState.writeRef()));
// Create buffer for struct S with array of size N
int32_t initialData[] = {1, 2, 3, 4};
- IBufferResource::Desc bufferDesc = {};
- bufferDesc.sizeInBytes = N * sizeof(int32_t);
- bufferDesc.format = gfx::Format::Unknown;
+ BufferDesc bufferDesc = {};
+ bufferDesc.size = N * sizeof(int32_t);
+ bufferDesc.format = Format::Undefined;
bufferDesc.elementSize = sizeof(int32_t);
- bufferDesc.allowedStates = ResourceStateSet(
- ResourceState::ShaderResource,
- ResourceState::UnorderedAccess,
- ResourceState::CopyDestination,
- ResourceState::CopySource);
+ bufferDesc.usage = BufferUsage::ShaderResource | BufferUsage::UnorderedAccess |
+ BufferUsage::CopyDestination | BufferUsage::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;
+ ComPtr<IBuffer> numbersBuffer;
GFX_CHECK_CALL_ABORT(
- device->createBufferView(numbersBuffer, nullptr, viewDesc, bufferView.writeRef()));
+ device->createBuffer(bufferDesc, (void*)initialData, numbersBuffer.writeRef()));
// Record and execute command buffer
{
- ICommandQueue::Desc queueDesc = {ICommandQueue::QueueType::Graphics};
- auto queue = device->createCommandQueue(queueDesc);
-
- auto commandBuffer = transientHeap->createCommandBuffer();
- auto encoder = commandBuffer->encodeComputeCommands();
+ auto queue = device->getQueue(QueueType::Graphics);
+ auto commandEncoder = queue->createCommandEncoder();
+ auto encoder = commandEncoder->beginComputePass();
auto rootObject = encoder->bindPipeline(pipelineState);
ShaderCursor rootCursor(rootObject);
- rootCursor.getPath("b").setResource(bufferView);
+ rootCursor.getPath("b").setBinding(Binding(numbersBuffer));
encoder->dispatchCompute(1, 1, 1);
- encoder->endEncoding();
- commandBuffer->close();
- queue->executeCommandBuffer(commandBuffer);
+ encoder->end();
+ queue->submit(commandEncoder->finish());
queue->waitOnHost();
}
// Expected results: each element is input * N
// With N=4 and inputs [1,2,3,4], expected output is [4,8,12,16]
- compareComputeResult(device, numbersBuffer, Slang::makeArray<int>(4, 8, 12, 16));
+ compareComputeResult(device, numbersBuffer, std::array{4, 8, 12, 16});
}
SLANG_UNIT_TEST(linkTimeConstantArraySizeD3D12)
{
- runTestImpl(linkTimeConstantArraySizeTestImpl, unitTestContext, Slang::RenderApiFlag::D3D12);
+ runTestImpl(linkTimeConstantArraySizeTestImpl, unitTestContext, DeviceType::D3D12);
}
SLANG_UNIT_TEST(linkTimeConstantArraySizeVulkan)
{
- runTestImpl(linkTimeConstantArraySizeTestImpl, unitTestContext, Slang::RenderApiFlag::Vulkan);
+ runTestImpl(linkTimeConstantArraySizeTestImpl, unitTestContext, DeviceType::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 47dbbab2d..aa00f66f9 100644
--- a/tools/gfx-unit-test/link-time-constant.cpp
+++ b/tools/gfx-unit-test/link-time-constant.cpp
@@ -1,17 +1,17 @@
#include "core/slang-basic.h"
#include "core/slang-blob.h"
#include "gfx-test-util.h"
-#include "gfx-util/shader-cursor.h"
-#include "slang-gfx.h"
+#include "slang-rhi.h"
+#include "slang-rhi/shader-cursor.h"
#include "unit-test/slang-unit-test.h"
-using namespace gfx;
+using namespace rhi;
namespace gfx_test
{
static Slang::Result loadProgram(
- gfx::IDevice* device,
- Slang::ComPtr<gfx::IShaderProgram>& outShaderProgram,
+ rhi::IDevice* device,
+ Slang::ComPtr<rhi::IShaderProgram>& outShaderProgram,
const char* shaderModuleName,
const char* entryPointName,
slang::ProgramLayout*& slangReflection,
@@ -56,10 +56,10 @@ static Slang::Result loadProgram(
composedProgram = linkedProgram;
slangReflection = composedProgram->getLayout();
- gfx::IShaderProgram::Desc programDesc = {};
+ ShaderProgramDesc programDesc = {};
programDesc.slangGlobalScope = composedProgram.get();
- auto shaderProgram = device->createProgram(programDesc);
+ auto shaderProgram = device->createShaderProgram(programDesc);
outShaderProgram = shaderProgram;
return SLANG_OK;
@@ -67,12 +67,6 @@ static Slang::Result loadProgram(
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(
@@ -93,71 +87,57 @@ void linkTimeConstantTestImpl(IDevice* device, UnitTestContext* context)
->getComputeThreadGroupSize(3, threadGroupSizes);
SLANG_CHECK(threadGroupSizes[0] == 2 && threadGroupSizes[1] == 1 && threadGroupSizes[2] == 1);
- ComputePipelineStateDesc pipelineDesc = {};
+ ComputePipelineDesc pipelineDesc = {};
pipelineDesc.program = shaderProgram.get();
- ComPtr<gfx::IPipelineState> pipelineState;
- GFX_CHECK_CALL_ABORT(
- device->createComputePipelineState(pipelineDesc, pipelineState.writeRef()));
+ ComPtr<IComputePipeline> pipelineState;
+ GFX_CHECK_CALL_ABORT(device->createComputePipeline(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 bufferDesc = {};
+ bufferDesc.size = numberCount * sizeof(float);
+ bufferDesc.format = rhi::Format::Undefined;
bufferDesc.elementSize = sizeof(float);
- bufferDesc.allowedStates = ResourceStateSet(
- ResourceState::ShaderResource,
- ResourceState::UnorderedAccess,
- ResourceState::CopyDestination,
- ResourceState::CopySource);
+ bufferDesc.usage = BufferUsage::ShaderResource | BufferUsage::UnorderedAccess |
+ BufferUsage::CopyDestination | BufferUsage::CopySource;
bufferDesc.defaultState = ResourceState::UnorderedAccess;
bufferDesc.memoryType = MemoryType::DeviceLocal;
- ComPtr<IBufferResource> numbersBuffer;
+ ComPtr<IBuffer> 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()));
+ device->createBuffer(bufferDesc, (void*)initialData, numbersBuffer.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 queue = device->getQueue(QueueType::Graphics);
+ auto commandEncoder = queue->createCommandEncoder();
+ auto encoder = commandEncoder->beginComputePass();
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);
+ // Bind buffer to the entry point.
+ entryPointCursor.getPath("buffer").setBinding(numbersBuffer);
encoder->dispatchCompute(1, 1, 1);
- encoder->endEncoding();
- commandBuffer->close();
- queue->executeCommandBuffer(commandBuffer);
+ encoder->end();
+ queue->submit(commandEncoder->finish());
queue->waitOnHost();
}
- compareComputeResult(device, numbersBuffer, Slang::makeArray<float>(2.0));
+ compareComputeResult(device, numbersBuffer, std::array{2.0f});
}
SLANG_UNIT_TEST(linkTimeConstantD3D12)
{
- runTestImpl(linkTimeConstantTestImpl, unitTestContext, Slang::RenderApiFlag::D3D12);
+ runTestImpl(linkTimeConstantTestImpl, unitTestContext, DeviceType::D3D12);
}
SLANG_UNIT_TEST(linkTimeConstantVulkan)
{
- runTestImpl(linkTimeConstantTestImpl, unitTestContext, Slang::RenderApiFlag::Vulkan);
+ runTestImpl(linkTimeConstantTestImpl, unitTestContext, DeviceType::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 244991148..2ff669c5e 100644
--- a/tools/gfx-unit-test/link-time-default.cpp
+++ b/tools/gfx-unit-test/link-time-default.cpp
@@ -1,17 +1,17 @@
#include "core/slang-basic.h"
#include "core/slang-blob.h"
#include "gfx-test-util.h"
-#include "gfx-util/shader-cursor.h"
-#include "slang-gfx.h"
+#include "slang-rhi.h"
+#include "slang-rhi/shader-cursor.h"
#include "unit-test/slang-unit-test.h"
-using namespace gfx;
+using namespace rhi;
namespace gfx_test
{
static Slang::Result loadProgram(
- gfx::IDevice* device,
- Slang::ComPtr<gfx::IShaderProgram>& outShaderProgram,
+ rhi::IDevice* device,
+ Slang::ComPtr<rhi::IShaderProgram>& outShaderProgram,
slang::ProgramLayout*& slangReflection,
bool linkSpecialization = false)
{
@@ -102,10 +102,10 @@ static Slang::Result loadProgram(
composedProgram = linkedProgram;
slangReflection = composedProgram->getLayout();
- gfx::IShaderProgram::Desc programDesc = {};
+ ShaderProgramDesc programDesc = {};
programDesc.slangGlobalScope = composedProgram.get();
- auto shaderProgram = device->createProgram(programDesc);
+ auto shaderProgram = device->createShaderProgram(programDesc);
outShaderProgram = shaderProgram;
return SLANG_OK;
@@ -113,115 +113,96 @@ static Slang::Result loadProgram(
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 = {};
+ ComputePipelineDesc pipelineDesc = {};
pipelineDesc.program = shaderProgram.get();
- ComPtr<gfx::IPipelineState> pipelineState;
- GFX_CHECK_CALL_ABORT(
- device->createComputePipelineState(pipelineDesc, pipelineState.writeRef()));
+ ComPtr<IComputePipeline> pipelineState;
+ GFX_CHECK_CALL_ABORT(device->createComputePipeline(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 = {};
+ ComputePipelineDesc pipelineDesc1 = {};
pipelineDesc1.program = shaderProgram1.get();
- ComPtr<gfx::IPipelineState> pipelineState1;
- GFX_CHECK_CALL_ABORT(
- device->createComputePipelineState(pipelineDesc1, pipelineState1.writeRef()));
+ ComPtr<IComputePipeline> pipelineState1;
+ GFX_CHECK_CALL_ABORT(device->createComputePipeline(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 bufferDesc = {};
+ bufferDesc.size = numberCount * sizeof(float);
+ bufferDesc.format = rhi::Format::Undefined;
bufferDesc.elementSize = sizeof(float);
- bufferDesc.allowedStates = ResourceStateSet(
- ResourceState::ShaderResource,
- ResourceState::UnorderedAccess,
- ResourceState::CopyDestination,
- ResourceState::CopySource);
+ bufferDesc.usage = BufferUsage::ShaderResource | BufferUsage::UnorderedAccess |
+ BufferUsage::CopyDestination | BufferUsage::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;
+ ComPtr<IBuffer> numbersBuffer;
GFX_CHECK_CALL_ABORT(
- device->createBufferView(numbersBuffer, nullptr, viewDesc, bufferView.writeRef()));
+ device->createBuffer(bufferDesc, (void*)initialData, numbersBuffer.writeRef()));
- ICommandQueue::Desc queueDesc = {ICommandQueue::QueueType::Graphics};
- auto queue = device->createCommandQueue(queueDesc);
+ auto queue = device->getQueue(QueueType::Graphics);
// 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 commandEncoder = queue->createCommandEncoder();
+ auto computePassEncoder = commandEncoder->beginComputePass();
- auto rootObject = encoder->bindPipeline(pipelineState);
+ auto rootObject = computePassEncoder->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);
+ // Bind buffer to the entry point.
+ entryPointCursor.getPath("buffer").setBinding(Binding(numbersBuffer));
- encoder->dispatchCompute(1, 1, 1);
- encoder->endEncoding();
- commandBuffer->close();
- queue->executeCommandBuffer(commandBuffer);
+ computePassEncoder->dispatchCompute(1, 1, 1);
+ computePassEncoder->end();
+ auto commandBuffer = commandEncoder->finish();
+ queue->submit(commandBuffer);
queue->waitOnHost();
}
- compareComputeResult(device, numbersBuffer, Slang::makeArray<float>(8.0));
+ compareComputeResult(device, numbersBuffer, std::array{8.0f});
// Now run again with the overrided program.
{
- auto commandBuffer = transientHeap->createCommandBuffer();
- auto encoder = commandBuffer->encodeComputeCommands();
+ auto commandEncoder = queue->createCommandEncoder();
+ auto computePassEncoder = commandEncoder->beginComputePass();
- auto rootObject = encoder->bindPipeline(pipelineState1);
+ auto rootObject = computePassEncoder->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);
+ // Bind buffer to the entry point.
+ entryPointCursor.getPath("buffer").setBinding(Binding(numbersBuffer));
- encoder->dispatchCompute(1, 1, 1);
- encoder->endEncoding();
- commandBuffer->close();
- queue->executeCommandBuffer(commandBuffer);
+ computePassEncoder->dispatchCompute(1, 1, 1);
+ computePassEncoder->end();
+ auto commandBuffer = commandEncoder->finish();
+ queue->submit(commandBuffer);
queue->waitOnHost();
}
- compareComputeResult(device, numbersBuffer, Slang::makeArray<float>(10.0));
+ compareComputeResult(device, numbersBuffer, std::array{10.0f});
}
SLANG_UNIT_TEST(linkTimeDefaultD3D12)
{
- runTestImpl(linkTimeDefaultTestImpl, unitTestContext, Slang::RenderApiFlag::D3D12);
+ runTestImpl(linkTimeDefaultTestImpl, unitTestContext, DeviceType::D3D12);
}
SLANG_UNIT_TEST(linkTimeDefaultVulkan)
{
- runTestImpl(linkTimeDefaultTestImpl, unitTestContext, Slang::RenderApiFlag::Vulkan);
+ runTestImpl(linkTimeDefaultTestImpl, unitTestContext, DeviceType::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 64f189162..1c3525c08 100644
--- a/tools/gfx-unit-test/link-time-options.cpp
+++ b/tools/gfx-unit-test/link-time-options.cpp
@@ -1,11 +1,11 @@
#include "core/slang-basic.h"
#include "core/slang-blob.h"
#include "gfx-test-util.h"
-#include "gfx-util/shader-cursor.h"
-#include "slang-gfx.h"
+#include "slang-rhi.h"
+#include "slang-rhi/shader-cursor.h"
#include "unit-test/slang-unit-test.h"
-using namespace gfx;
+using namespace rhi;
namespace gfx_test
{
@@ -17,8 +17,8 @@ namespace gfx_test
// option to define the value of DOWNSTREAM_VALUE when running dxc.
//
static Slang::Result loadProgram(
- gfx::IDevice* device,
- Slang::ComPtr<gfx::IShaderProgram>& outShaderProgram,
+ rhi::IDevice* device,
+ Slang::ComPtr<rhi::IShaderProgram>& outShaderProgram,
const char* shaderModuleName,
const char* entryPointName,
slang::ProgramLayout*& slangReflection)
@@ -62,10 +62,10 @@ static Slang::Result loadProgram(
composedProgram = linkedProgram;
slangReflection = composedProgram->getLayout();
- gfx::IShaderProgram::Desc programDesc = {};
+ ShaderProgramDesc programDesc = {};
programDesc.slangGlobalScope = composedProgram.get();
- auto shaderProgram = device->createProgram(programDesc);
+ auto shaderProgram = device->createShaderProgram(programDesc);
outShaderProgram = shaderProgram;
return SLANG_OK;
@@ -73,76 +73,57 @@ static Slang::Result loadProgram(
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 = {};
+ ComputePipelineDesc pipelineDesc = {};
pipelineDesc.program = shaderProgram.get();
- ComPtr<gfx::IPipelineState> pipelineState;
- GFX_CHECK_CALL_ABORT(
- device->createComputePipelineState(pipelineDesc, pipelineState.writeRef()));
+ ComPtr<IComputePipeline> pipelineState;
+ GFX_CHECK_CALL_ABORT(device->createComputePipeline(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 bufferDesc = {};
+ bufferDesc.size = numberCount * sizeof(float);
+ bufferDesc.format = rhi::Format::Undefined;
bufferDesc.elementSize = sizeof(float);
- bufferDesc.allowedStates = ResourceStateSet(
- ResourceState::ShaderResource,
- ResourceState::UnorderedAccess,
- ResourceState::CopyDestination,
- ResourceState::CopySource);
+ bufferDesc.usage = BufferUsage::ShaderResource | BufferUsage::UnorderedAccess |
+ BufferUsage::CopyDestination | BufferUsage::CopySource;
bufferDesc.defaultState = ResourceState::UnorderedAccess;
bufferDesc.memoryType = MemoryType::DeviceLocal;
- ComPtr<IBufferResource> numbersBuffer;
+ ComPtr<IBuffer> 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()));
+ device->createBuffer(bufferDesc, (void*)initialData, numbersBuffer.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 queue = device->getQueue(QueueType::Graphics);
+ auto commandEncoder = queue->createCommandEncoder();
+ auto computePassEncoder = commandEncoder->beginComputePass();
- auto rootObject = encoder->bindPipeline(pipelineState);
+ auto rootObject = computePassEncoder->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);
+ // Bind buffer to the entry point.
+ entryPointCursor.getPath("buffer").setBinding(Binding(numbersBuffer));
- encoder->dispatchCompute(1, 1, 1);
- encoder->endEncoding();
- commandBuffer->close();
- queue->executeCommandBuffer(commandBuffer);
+ computePassEncoder->dispatchCompute(1, 1, 1);
+ computePassEncoder->end();
+ auto commandBuffer = commandEncoder->finish();
+ queue->submit(commandBuffer);
queue->waitOnHost();
}
- compareComputeResult(device, numbersBuffer, Slang::makeArray<float>(4.0));
+ compareComputeResult(device, numbersBuffer, std::array{4.0f});
}
SLANG_UNIT_TEST(linkTimeOptionD3D12)
{
- runTestImpl(linkTimeOptionTestImpl, unitTestContext, Slang::RenderApiFlag::D3D12);
+ runTestImpl(linkTimeOptionTestImpl, unitTestContext, DeviceType::D3D12);
}
} // namespace gfx_test
diff --git a/tools/gfx-unit-test/link-time-type-layout-cache.cpp b/tools/gfx-unit-test/link-time-type-layout-cache.cpp
index 1e5ff2ddd..b04733fb6 100644
--- a/tools/gfx-unit-test/link-time-type-layout-cache.cpp
+++ b/tools/gfx-unit-test/link-time-type-layout-cache.cpp
@@ -1,9 +1,9 @@
#include "core/slang-blob.h"
#include "gfx-test-util.h"
-#include "slang-gfx.h"
+#include "slang-rhi.h"
#include "unit-test/slang-unit-test.h"
-using namespace gfx;
+using namespace rhi;
namespace gfx_test
{
@@ -95,7 +95,7 @@ static void validateStructSLayout(
}
}
-void linkTimeTypeLayoutCacheImpl(gfx::IDevice* device, UnitTestContext* context)
+void linkTimeTypeLayoutCacheImpl(rhi::IDevice* device, UnitTestContext* context)
{
// main.slang: declares the interface and extern struct S
const char* mainSrc = R"(
@@ -198,7 +198,7 @@ void linkTimeTypeLayoutCacheImpl(gfx::IDevice* device, UnitTestContext* context)
SLANG_UNIT_TEST(linkTimeTypeLayoutCache)
{
- runTestImpl(linkTimeTypeLayoutCacheImpl, unitTestContext, Slang::RenderApiFlag::Vulkan);
+ runTestImpl(linkTimeTypeLayoutCacheImpl, unitTestContext, DeviceType::Vulkan);
}
} // namespace gfx_test
diff --git a/tools/gfx-unit-test/link-time-type-layout-nested.cpp b/tools/gfx-unit-test/link-time-type-layout-nested.cpp
index b6ea0e64d..2c2c83a94 100644
--- a/tools/gfx-unit-test/link-time-type-layout-nested.cpp
+++ b/tools/gfx-unit-test/link-time-type-layout-nested.cpp
@@ -1,9 +1,9 @@
#include "core/slang-blob.h"
#include "gfx-test-util.h"
-#include "slang-gfx.h"
+#include "slang-rhi.h"
#include "unit-test/slang-unit-test.h"
-using namespace gfx;
+using namespace rhi;
namespace gfx_test
{
@@ -17,8 +17,8 @@ static void diagnoseIfNeeded(Slang::ComPtr<slang::IBlob>& diagnosticsBlob)
}
static Slang::Result loadProgram(
- gfx::IDevice* device,
- Slang::ComPtr<gfx::IShaderProgram>& outShaderProgram,
+ rhi::IDevice* device,
+ Slang::ComPtr<rhi::IShaderProgram>& outShaderProgram,
slang::ProgramLayout*& slangReflection)
{
// main.slang: declares the interface, extern struct Inner, and Outer struct with Inner field
@@ -102,9 +102,9 @@ static Slang::Result loadProgram(
slangReflection = composedProgram->getLayout();
// Create a shader program
- gfx::IShaderProgram::Desc programDesc = {};
+ ShaderProgramDesc programDesc = {};
programDesc.slangGlobalScope = composedProgram.get();
- auto shaderProgram = device->createProgram(programDesc);
+ auto shaderProgram = device->createShaderProgram(programDesc);
outShaderProgram = shaderProgram;
return SLANG_OK;
@@ -200,9 +200,9 @@ static void validateNestedExternStructLayout(
SLANG_CHECK_MSG(foundDataField, "Could not find field 'data' in Inner struct");
}
-void linkTimeTypeLayoutNestedImpl(gfx::IDevice* device, UnitTestContext* context)
+void linkTimeTypeLayoutNestedImpl(rhi::IDevice* device, UnitTestContext* context)
{
- Slang::ComPtr<gfx::IShaderProgram> shaderProgram;
+ Slang::ComPtr<rhi::IShaderProgram> shaderProgram;
slang::ProgramLayout* slangReflection = nullptr;
auto result = loadProgram(device, shaderProgram, slangReflection);
@@ -212,13 +212,12 @@ void linkTimeTypeLayoutNestedImpl(gfx::IDevice* device, UnitTestContext* context
validateNestedExternStructLayout(context, slangReflection);
// Create a graphics pipeline to verify everything works
- GraphicsPipelineStateDesc pipelineDesc = {};
+ RenderPipelineDesc pipelineDesc = {};
pipelineDesc.program = shaderProgram.get();
- pipelineDesc.primitiveType = PrimitiveType::Triangle;
+ pipelineDesc.primitiveTopology = PrimitiveTopology::TriangleList;
- ComPtr<gfx::IPipelineState> pipelineState;
- auto pipelineResult =
- device->createGraphicsPipelineState(pipelineDesc, pipelineState.writeRef());
+ ComPtr<IRenderPipeline> pipelineState;
+ auto pipelineResult = device->createRenderPipeline(pipelineDesc, pipelineState.writeRef());
SLANG_CHECK(SLANG_SUCCEEDED(pipelineResult));
}
@@ -235,7 +234,7 @@ void linkTimeTypeLayoutNestedImpl(gfx::IDevice* device, UnitTestContext* context
SLANG_UNIT_TEST(linkTimeTypeLayoutNested)
{
- runTestImpl(linkTimeTypeLayoutNestedImpl, unitTestContext, Slang::RenderApiFlag::Vulkan);
+ runTestImpl(linkTimeTypeLayoutNestedImpl, unitTestContext, DeviceType::Vulkan);
}
} // namespace gfx_test
diff --git a/tools/gfx-unit-test/link-time-type-layout.cpp b/tools/gfx-unit-test/link-time-type-layout.cpp
index c1997b18a..c5c044acd 100644
--- a/tools/gfx-unit-test/link-time-type-layout.cpp
+++ b/tools/gfx-unit-test/link-time-type-layout.cpp
@@ -1,9 +1,9 @@
#include "core/slang-blob.h"
#include "gfx-test-util.h"
-#include "slang-gfx.h"
+#include "slang-rhi.h"
#include "unit-test/slang-unit-test.h"
-using namespace gfx;
+using namespace rhi;
namespace gfx_test
{
@@ -17,8 +17,8 @@ static void diagnoseIfNeeded(Slang::ComPtr<slang::IBlob>& diagnosticsBlob)
}
static Slang::Result loadSpirvProgram(
- gfx::IDevice* device,
- Slang::ComPtr<gfx::IShaderProgram>& outShaderProgram,
+ rhi::IDevice* device,
+ Slang::ComPtr<rhi::IShaderProgram>& outShaderProgram,
slang::ProgramLayout*& slangReflection)
{
// main.slang: declares the interface and extern struct S, and the vertex shader.
@@ -88,9 +88,9 @@ static Slang::Result loadSpirvProgram(
slangReflection = composedProgram->getLayout();
// Create a shader program that will generate SPIRV code.
- gfx::IShaderProgram::Desc programDesc = {};
+ ShaderProgramDesc programDesc = {};
programDesc.slangGlobalScope = composedProgram.get();
- auto shaderProgram = device->createProgram(programDesc);
+ auto shaderProgram = device->createShaderProgram(programDesc);
outShaderProgram = shaderProgram;
// Force SPIRV generation by explicitly requesting it
@@ -201,9 +201,9 @@ static void validateStructSLayout(UnitTestContext* context, slang::ProgramLayout
SLANG_CHECK_MSG(foundFooField, "Could not find field 'foo' in struct S");
}
-void linkTimeTypeLayoutImpl(gfx::IDevice* device, UnitTestContext* context)
+void linkTimeTypeLayoutImpl(rhi::IDevice* device, UnitTestContext* context)
{
- Slang::ComPtr<gfx::IShaderProgram> shaderProgram;
+ Slang::ComPtr<rhi::IShaderProgram> shaderProgram;
slang::ProgramLayout* slangReflection = nullptr;
auto result = loadSpirvProgram(device, shaderProgram, slangReflection);
@@ -213,15 +213,14 @@ void linkTimeTypeLayoutImpl(gfx::IDevice* device, UnitTestContext* context)
validateStructSLayout(context, slangReflection);
// Create a graphics pipeline to verify SPIRV code generation works
- GraphicsPipelineStateDesc pipelineDesc = {};
+ RenderPipelineDesc pipelineDesc = {};
pipelineDesc.program = shaderProgram.get();
// We need to set up a minimal pipeline state for a vertex shader
- pipelineDesc.primitiveType = PrimitiveType::Triangle;
+ pipelineDesc.primitiveTopology = PrimitiveTopology::TriangleList;
- ComPtr<gfx::IPipelineState> pipelineState;
- auto pipelineResult =
- device->createGraphicsPipelineState(pipelineDesc, pipelineState.writeRef());
+ ComPtr<IRenderPipeline> pipelineState;
+ auto pipelineResult = device->createRenderPipeline(pipelineDesc, pipelineState.writeRef());
SLANG_CHECK(SLANG_SUCCEEDED(pipelineResult));
}
@@ -239,7 +238,7 @@ void linkTimeTypeLayoutImpl(gfx::IDevice* device, UnitTestContext* context)
SLANG_UNIT_TEST(linkTimeTypeLayout)
{
- runTestImpl(linkTimeTypeLayoutImpl, unitTestContext, Slang::RenderApiFlag::Vulkan);
+ runTestImpl(linkTimeTypeLayoutImpl, unitTestContext, DeviceType::Vulkan);
}
} // namespace gfx_test
diff --git a/tools/gfx-unit-test/link-time-type.cpp b/tools/gfx-unit-test/link-time-type.cpp
index 8f4bcca01..d2dd54c46 100644
--- a/tools/gfx-unit-test/link-time-type.cpp
+++ b/tools/gfx-unit-test/link-time-type.cpp
@@ -1,17 +1,17 @@
#include "core/slang-basic.h"
#include "core/slang-blob.h"
#include "gfx-test-util.h"
-#include "gfx-util/shader-cursor.h"
-#include "slang-gfx.h"
+#include "slang-rhi.h"
+#include "slang-rhi/shader-cursor.h"
#include "unit-test/slang-unit-test.h"
-using namespace gfx;
+using namespace rhi;
namespace gfx_test
{
static Slang::Result loadProgram(
- gfx::IDevice* device,
- Slang::ComPtr<gfx::IShaderProgram>& outShaderProgram,
+ rhi::IDevice* device,
+ Slang::ComPtr<rhi::IShaderProgram>& outShaderProgram,
slang::ProgramLayout*& slangReflection)
{
const char* moduleInterfaceSrc = R"(
@@ -102,10 +102,10 @@ static Slang::Result loadProgram(
composedProgram = linkedProgram;
slangReflection = composedProgram->getLayout();
- gfx::IShaderProgram::Desc programDesc = {};
+ ShaderProgramDesc programDesc = {};
programDesc.slangGlobalScope = composedProgram.get();
- auto shaderProgram = device->createProgram(programDesc);
+ auto shaderProgram = device->createShaderProgram(programDesc);
outShaderProgram = shaderProgram;
return SLANG_OK;
@@ -113,81 +113,62 @@ static Slang::Result loadProgram(
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 = {};
+ ComputePipelineDesc pipelineDesc = {};
pipelineDesc.program = shaderProgram.get();
- ComPtr<gfx::IPipelineState> pipelineState;
- GFX_CHECK_CALL_ABORT(
- device->createComputePipelineState(pipelineDesc, pipelineState.writeRef()));
+ ComPtr<IComputePipeline> pipelineState;
+ GFX_CHECK_CALL_ABORT(device->createComputePipeline(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 bufferDesc = {};
+ bufferDesc.size = numberCount * sizeof(float);
+ bufferDesc.format = rhi::Format::Undefined;
bufferDesc.elementSize = sizeof(float);
- bufferDesc.allowedStates = ResourceStateSet(
- ResourceState::ShaderResource,
- ResourceState::UnorderedAccess,
- ResourceState::CopyDestination,
- ResourceState::CopySource);
+ bufferDesc.usage = BufferUsage::ShaderResource | BufferUsage::UnorderedAccess |
+ BufferUsage::CopyDestination | BufferUsage::CopySource;
bufferDesc.defaultState = ResourceState::UnorderedAccess;
bufferDesc.memoryType = MemoryType::DeviceLocal;
- ComPtr<IBufferResource> numbersBuffer;
+ ComPtr<IBuffer> 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()));
+ device->createBuffer(bufferDesc, (void*)initialData, numbersBuffer.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 queue = device->getQueue(QueueType::Graphics);
+ auto commandEncoder = queue->createCommandEncoder();
+ auto computePassEncoder = commandEncoder->beginComputePass();
- auto rootObject = encoder->bindPipeline(pipelineState);
+ auto rootObject = computePassEncoder->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);
+ // Bind buffer to the entry point.
+ entryPointCursor.getPath("buffer").setBinding(Binding(numbersBuffer));
- encoder->dispatchCompute(1, 1, 1);
- encoder->endEncoding();
- commandBuffer->close();
- queue->executeCommandBuffer(commandBuffer);
+ computePassEncoder->dispatchCompute(1, 1, 1);
+ computePassEncoder->end();
+ auto commandBuffer = commandEncoder->finish();
+ queue->submit(commandBuffer);
queue->waitOnHost();
}
- compareComputeResult(device, numbersBuffer, Slang::makeArray<float>(11.0));
+ compareComputeResult(device, numbersBuffer, std::array{11.0f});
}
SLANG_UNIT_TEST(linkTimeTypeD3D12)
{
- runTestImpl(linkTimeTypeTestImpl, unitTestContext, Slang::RenderApiFlag::D3D12);
+ runTestImpl(linkTimeTypeTestImpl, unitTestContext, DeviceType::D3D12);
}
SLANG_UNIT_TEST(linkTimeTypeVulkan)
{
- runTestImpl(linkTimeTypeTestImpl, unitTestContext, Slang::RenderApiFlag::Vulkan);
+ runTestImpl(linkTimeTypeTestImpl, unitTestContext, DeviceType::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 c7ce40d34..c84fdd42a 100644
--- a/tools/gfx-unit-test/mutable-shader-object.cpp
+++ b/tools/gfx-unit-test/mutable-shader-object.cpp
@@ -1,21 +1,16 @@
#include "core/slang-basic.h"
#include "gfx-test-util.h"
-#include "gfx-util/shader-cursor.h"
-#include "slang-gfx.h"
#include "unit-test/slang-unit-test.h"
-using namespace gfx;
+#include <slang-rhi.h>
+#include <slang-rhi/shader-cursor.h>
+
+using namespace rhi;
namespace gfx_test
{
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(
@@ -25,98 +20,85 @@ void mutableShaderObjectTestImpl(IDevice* device, UnitTestContext* context)
"computeMain",
slangReflection));
- ComputePipelineStateDesc pipelineDesc = {};
+ ComputePipelineDesc pipelineDesc = {};
pipelineDesc.program = shaderProgram.get();
- ComPtr<gfx::IPipelineState> pipelineState;
- GFX_CHECK_CALL_ABORT(
- device->createComputePipelineState(pipelineDesc, pipelineState.writeRef()));
+ ComPtr<IComputePipeline> pipelineState;
+ GFX_CHECK_CALL_ABORT(device->createComputePipeline(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 bufferDesc = {};
+ bufferDesc.size = sizeof(initialData);
+ bufferDesc.format = Format::Undefined;
bufferDesc.elementSize = sizeof(float);
- bufferDesc.allowedStates = ResourceStateSet(
- ResourceState::ShaderResource,
- ResourceState::UnorderedAccess,
- ResourceState::CopyDestination,
- ResourceState::CopySource);
+ bufferDesc.usage = BufferUsage::ShaderResource | BufferUsage::UnorderedAccess |
+ BufferUsage::CopyDestination | BufferUsage::CopySource;
bufferDesc.defaultState = ResourceState::UnorderedAccess;
bufferDesc.memoryType = MemoryType::DeviceLocal;
- ComPtr<IBufferResource> numbersBuffer;
+ ComPtr<IBuffer> 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()));
+ device->createBuffer(bufferDesc, (void*)initialData, numbersBuffer.writeRef()));
{
slang::TypeReflection* addTransformerType =
slangReflection->findTypeByName("AddTransformer");
ComPtr<IShaderObject> transformer;
- GFX_CHECK_CALL_ABORT(device->createMutableShaderObject(
+ 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));
- ICommandQueue::Desc queueDesc = {ICommandQueue::QueueType::Graphics};
- auto queue = device->createCommandQueue(queueDesc);
+ ComPtr<ICommandQueue> queue;
+ GFX_CHECK_CALL_ABORT(device->getQueue(QueueType::Graphics, queue.writeRef()));
- auto commandBuffer = transientHeap->createCommandBuffer();
- auto encoder = commandBuffer->encodeComputeCommands();
+ // Create root shader object
+ ComPtr<IShaderObject> rootObject;
+ GFX_CHECK_CALL_ABORT(device->createRootShaderObject(shaderProgram, rootObject.writeRef()));
- auto rootObject = encoder->bindPipeline(pipelineState);
+ auto commandEncoder = queue->createCommandEncoder();
+ auto computeEncoder = commandEncoder->beginComputePass();
+
+ // Bind pipeline with our root object
+ computeEncoder->bindPipeline(pipelineState, rootObject);
auto entryPointCursor = ShaderCursor(rootObject->getEntryPoint(0));
- entryPointCursor.getPath("buffer").setResource(bufferView);
+ entryPointCursor.getPath("buffer").setBinding(Binding(numbersBuffer));
- // Bind the previously created transformer object to root object.
- ComPtr<IShaderObject> transformerVersion;
- transformer->getCurrentVersion(transientHeap, transformerVersion.writeRef());
- entryPointCursor.getPath("transformer").setObject(transformerVersion);
+ // Bind the transformer object to root object.
+ entryPointCursor.getPath("transformer").setObject(transformer);
- encoder->dispatchCompute(1, 1, 1);
- encoder->endEncoding();
+ computeEncoder->dispatchCompute(1, 1, 1);
+ computeEncoder->end();
- auto barrierEncoder = commandBuffer->encodeResourceCommands();
- barrierEncoder->bufferBarrier(
- 1,
- numbersBuffer.readRef(),
- ResourceState::UnorderedAccess,
- ResourceState::UnorderedAccess);
- barrierEncoder->endEncoding();
+ // Set buffer state to ensure writes are visible
+ commandEncoder->setBufferState(numbersBuffer, ResourceState::UnorderedAccess);
- encoder = commandBuffer->encodeComputeCommands();
+ computeEncoder = commandEncoder->beginComputePass();
- rootObject = encoder->bindPipeline(pipelineState);
- entryPointCursor = ShaderCursor(rootObject->getEntryPoint(0));
+ // Bind pipeline with our root object again
+ computeEncoder->bindPipeline(pipelineState, rootObject);
// 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);
+ entryPointCursor.getPath("buffer").setBinding(Binding(numbersBuffer));
+ entryPointCursor.getPath("transformer").setObject(transformer);
+ computeEncoder->dispatchCompute(1, 1, 1);
+ computeEncoder->end();
+
+ auto commandBuffer = commandEncoder->finish();
+ queue->submit(commandBuffer);
queue->waitOnHost();
}
- compareComputeResult(device, numbersBuffer, Slang::makeArray<float>(3.0f, 4.0f, 5.0f, 6.0f));
+ compareComputeResult(device, numbersBuffer, std::array{3.0f, 4.0f, 5.0f, 6.0f});
}
// SLANG_UNIT_TEST(mutableShaderObjectCPU)
@@ -126,16 +108,16 @@ void mutableShaderObjectTestImpl(IDevice* device, UnitTestContext* context)
SLANG_UNIT_TEST(mutableShaderObjectD3D11)
{
- runTestImpl(mutableShaderObjectTestImpl, unitTestContext, Slang::RenderApiFlag::D3D11);
+ runTestImpl(mutableShaderObjectTestImpl, unitTestContext, DeviceType::D3D11);
}
SLANG_UNIT_TEST(mutableShaderObjectD3D12)
{
- runTestImpl(mutableShaderObjectTestImpl, unitTestContext, Slang::RenderApiFlag::D3D12);
+ runTestImpl(mutableShaderObjectTestImpl, unitTestContext, DeviceType::D3D12);
}
SLANG_UNIT_TEST(mutableShaderObjectVulkan)
{
- runTestImpl(mutableShaderObjectTestImpl, unitTestContext, Slang::RenderApiFlag::Vulkan);
+ runTestImpl(mutableShaderObjectTestImpl, unitTestContext, DeviceType::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 1201be261..d1e6f262f 100644
--- a/tools/gfx-unit-test/nested-parameter-block.cpp
+++ b/tools/gfx-unit-test/nested-parameter-block.cpp
@@ -1,34 +1,36 @@
#include "core/slang-basic.h"
#include "gfx-test-util.h"
-#include "gfx-util/shader-cursor.h"
-#include "slang-gfx.h"
+#include "slang-rhi.h"
+#include "slang-rhi/shader-cursor.h"
#include "unit-test/slang-unit-test.h"
-using namespace gfx;
+using namespace rhi;
namespace gfx_test
{
-Slang::ComPtr<IBufferResource> createBuffer(
- IDevice* device,
- uint32_t data,
- ResourceState defaultState)
+Slang::ComPtr<IBuffer> 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 bufferDesc = {};
+ bufferDesc.size = sizeof(initialData);
+ bufferDesc.format = rhi::Format::Undefined;
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;
+ // Set appropriate usage flags based on the default state
+ if (defaultState == ResourceState::ShaderResource)
+ {
+ bufferDesc.usage = BufferUsage::ShaderResource;
+ }
+ else if (defaultState == ResourceState::UnorderedAccess)
+ {
+ bufferDesc.usage = BufferUsage::UnorderedAccess | BufferUsage::CopySource;
+ }
+
+ ComPtr<IBuffer> numbersBuffer;
GFX_CHECK_CALL_ABORT(
- device->createBufferResource(bufferDesc, (void*)initialData, numbersBuffer.writeRef()));
+ device->createBuffer(bufferDesc, (void*)initialData, numbersBuffer.writeRef()));
return numbersBuffer;
}
@@ -39,12 +41,6 @@ struct uint4
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(
@@ -54,57 +50,38 @@ void nestedParameterBlockTestImpl(IDevice* device, UnitTestContext* context)
"computeMain",
slangReflection));
- ComputePipelineStateDesc pipelineDesc = {};
+ ComputePipelineDesc pipelineDesc = {};
pipelineDesc.program = shaderProgram.get();
- ComPtr<gfx::IPipelineState> pipelineState;
- GFX_CHECK_CALL_ABORT(
- device->createComputePipelineState(pipelineDesc, pipelineState.writeRef()));
+ ComPtr<rhi::IComputePipeline> pipeline;
+ pipeline = device->createComputePipeline(pipelineDesc);
ComPtr<IShaderObject> shaderObject;
- SLANG_CHECK(SLANG_SUCCEEDED(
- device->createMutableRootShaderObject(shaderProgram, shaderObject.writeRef())));
+ SLANG_CHECK(
+ SLANG_SUCCEEDED(device->createRootShaderObject(shaderProgram, shaderObject.writeRef())));
- Slang::List<Slang::ComPtr<IBufferResource>> srvBuffers;
- Slang::List<Slang::ComPtr<IResourceView>> srvs;
+ Slang::List<Slang::ComPtr<IBuffer>> srvBuffers;
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));
+ srvBuffers.add(createBuffer(device, i, rhi::ResourceState::ShaderResource));
}
- 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<IBuffer> resultBuffer =
+ createBuffer(device, 0, rhi::ResourceState::UnorderedAccess);
Slang::ComPtr<IShaderObject> materialObject;
- SLANG_CHECK(SLANG_SUCCEEDED(device->createMutableShaderObject(
+ SLANG_CHECK(SLANG_SUCCEEDED(device->createShaderObject(
slangReflection->findTypeByName("MaterialSystem"),
ShaderObjectContainerType::None,
materialObject.writeRef())));
Slang::ComPtr<IShaderObject> sceneObject;
- SLANG_CHECK(SLANG_SUCCEEDED(device->createMutableShaderObject(
+ SLANG_CHECK(SLANG_SUCCEEDED(device->createShaderObject(
slangReflection->findTypeByName("Scene"),
ShaderObjectContainerType::None,
sceneObject.writeRef())));
ShaderCursor cursor(shaderObject);
- cursor["resultBuffer"].setResource(resultBufferView);
+ cursor["resultBuffer"].setBinding(Binding(resultBuffer));
cursor["scene"].setObject(sceneObject);
Slang::ComPtr<IShaderObject> globalCB;
@@ -119,44 +96,39 @@ void nestedParameterBlockTestImpl(IDevice* device, UnitTestContext* context)
ShaderCursor sceneCursor(sceneObject);
sceneCursor["sceneCb"].setData(uint4{100, 100, 100, 100});
- sceneCursor["data"].setResource(srvs[1]);
+ sceneCursor["data"].setBinding(Binding(srvBuffers[1]));
sceneCursor["material"].setObject(materialObject);
ShaderCursor materialCursor(materialObject);
materialCursor["cb"].setData(uint4{1000, 1000, 1000, 1000});
- materialCursor["data"].setResource(srvs[2]);
+ materialCursor["data"].setBinding(Binding(srvBuffers[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 queue = device->getQueue(QueueType::Graphics);
- auto commandBuffer = transientHeap->createCommandBuffer();
- auto encoder = commandBuffer->encodeComputeCommands();
+ auto commandEncoder = queue->createCommandEncoder();
+ auto encoder = commandEncoder->beginComputePass();
- encoder->bindPipelineWithRootObject(pipelineState, shaderObject);
+ encoder->bindPipeline(pipeline, shaderObject);
encoder->dispatchCompute(1, 1, 1);
- encoder->endEncoding();
- commandBuffer->close();
- queue->executeCommandBuffer(commandBuffer);
+ encoder->end();
+ queue->submit(commandEncoder->finish());
queue->waitOnHost();
}
- compareComputeResult(
- device,
- resultBuffer,
- Slang::makeArray<uint32_t>(1123u, 1123u, 1123u, 1123u));
+ compareComputeResult(device, resultBuffer, std::array{1123u, 1123u, 1123u, 1123u});
}
SLANG_UNIT_TEST(nestedParameterBlockTestD3D12)
{
- runTestImpl(nestedParameterBlockTestImpl, unitTestContext, Slang::RenderApiFlag::D3D12);
+ runTestImpl(nestedParameterBlockTestImpl, unitTestContext, DeviceType::D3D12);
}
SLANG_UNIT_TEST(nestedParameterBlockTestVulkan)
{
- runTestImpl(nestedParameterBlockTestImpl, unitTestContext, Slang::RenderApiFlag::Vulkan);
+ runTestImpl(nestedParameterBlockTestImpl, unitTestContext, DeviceType::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 87420aa6e..9d0f3071c 100644
--- a/tools/gfx-unit-test/precompiled-module-2.cpp
+++ b/tools/gfx-unit-test/precompiled-module-2.cpp
@@ -1,20 +1,24 @@
+#if 0
+// Duplicated: This test is identical to slang-rhi\tests\test-precompiled-module-cache.cpp
+// TODO_TESTING port
+
#include "core/slang-basic.h"
#include "core/slang-blob.h"
#include "core/slang-io.h"
#include "core/slang-memory-file-system.h"
#include "gfx-test-util.h"
-#include "gfx-util/shader-cursor.h"
-#include "slang-gfx.h"
+#include "slang-rhi.h"
+#include "slang-rhi/shader-cursor.h"
#include "unit-test/slang-unit-test.h"
-using namespace gfx;
+using namespace rhi;
namespace gfx_test
{
// Test that mixing precompiled and non-precompiled modules is working.
static Slang::Result precompileProgram(
- gfx::IDevice* device,
+ rhi::IDevice* device,
ISlangMutableFileSystem* fileSys,
const char* shaderModuleName,
PrecompilationMode precompilationMode)
@@ -41,12 +45,12 @@ static Slang::Result precompileProgram(
precompilationMode == PrecompilationMode::ExternalLink)
{
SlangCompileTarget target;
- switch (device->getDeviceInfo().deviceType)
+ switch (device->getInfo().deviceType)
{
- case gfx::DeviceType::DirectX12:
+ case rhi::DeviceType::D3D12:
target = SLANG_DXIL;
break;
- case gfx::DeviceType::Vulkan:
+ case rhi::DeviceType::Vulkan:
target = SLANG_SPIRV;
break;
default:
@@ -71,7 +75,7 @@ static Slang::Result precompileProgram(
}
}
- // Write loaded modules to memory file system.
+ // Write loaded modules to file system.
for (SlangInt i = 0; i < slangSession->getLoadedModuleCount(); i++)
{
auto module = slangSession->getLoadedModule(i);
@@ -92,12 +96,6 @@ void precompiledModule2TestImplCommon(
UnitTestContext* context,
PrecompilationMode precompilationMode)
{
- 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());
@@ -116,13 +114,13 @@ void precompiledModule2TestImplCommon(
slang::SessionDesc sessionDesc = {};
sessionDesc.targetCount = 1;
slang::TargetDesc targetDesc = {};
- switch (device->getDeviceInfo().deviceType)
+ switch (device->getInfo().deviceType)
{
- case gfx::DeviceType::DirectX12:
+ case rhi::DeviceType::D3D12:
targetDesc.format = SLANG_DXIL;
targetDesc.profile = device->getSlangSession()->getGlobalSession()->findProfile("sm_6_6");
break;
- case gfx::DeviceType::Vulkan:
+ case rhi::DeviceType::Vulkan:
targetDesc.format = SLANG_SPIRV;
targetDesc.profile = device->getSlangSession()->getGlobalSession()->findProfile("GLSL_460");
break;
@@ -169,61 +167,44 @@ void precompiledModule2TestImplCommon(
slangReflection,
precompilationMode));
- ComputePipelineStateDesc pipelineDesc = {};
+ ComputePipelineDesc pipelineDesc = {};
pipelineDesc.program = shaderProgram.get();
- ComPtr<gfx::IPipelineState> pipelineState;
- GFX_CHECK_CALL_ABORT(
- device->createComputePipelineState(pipelineDesc, pipelineState.writeRef()));
-
+ ComPtr<rhi::IComputePipeline> pipeline = device->createComputePipeline(pipelineDesc);
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 bufferDesc = {};
+ bufferDesc.size = numberCount * sizeof(float);
+ bufferDesc.format = rhi::Format::Undefined;
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;
+ ComPtr<IBuffer> numbersBuffer;
GFX_CHECK_CALL_ABORT(
- device->createBufferView(numbersBuffer, nullptr, viewDesc, bufferView.writeRef()));
+ device->createBuffer(bufferDesc, (void*)initialData, numbersBuffer.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 queue = device->getQueue(QueueType::Graphics);
- auto commandBuffer = transientHeap->createCommandBuffer();
- auto encoder = commandBuffer->encodeComputeCommands();
+ auto commandBuffer = queue->createCommandEncoder();
+ auto encoder = commandBuffer->beginComputePass();
- auto rootObject = encoder->bindPipeline(pipelineState);
+ auto rootObject = encoder->bindPipeline(pipeline);
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);
+ entryPointCursor.getPath("buffer").setBinding(numbersBuffer);
encoder->dispatchCompute(1, 1, 1);
- encoder->endEncoding();
- commandBuffer->close();
- queue->executeCommandBuffer(commandBuffer);
+ encoder->end();
+ queue->submit(commandBuffer->finish());
queue->waitOnHost();
}
- compareComputeResult(device, numbersBuffer, Slang::makeArray<float>(3.0f, 3.0f, 3.0f, 3.0f));
+ compareComputeResult(device, numbersBuffer, std::array{3.0f, 3.0f, 3.0f, 3.0f});
}
void precompiledModule2TestImpl(IDevice* device, UnitTestContext* context)
@@ -243,7 +224,7 @@ void precompiledTargetModule2ExternalLinkTestImpl(IDevice* device, UnitTestConte
SLANG_UNIT_TEST(precompiledModule2D3D12)
{
- runTestImpl(precompiledModule2TestImpl, unitTestContext, Slang::RenderApiFlag::D3D12);
+ runTestImpl(precompiledModule2TestImpl, unitTestContext, DeviceType::D3D12);
}
SLANG_UNIT_TEST(precompiledTargetModuleInternalLink2D3D12)
@@ -251,7 +232,7 @@ SLANG_UNIT_TEST(precompiledTargetModuleInternalLink2D3D12)
runTestImpl(
precompiledTargetModule2InternalLinkTestImpl,
unitTestContext,
- Slang::RenderApiFlag::D3D12);
+ DeviceType::D3D12);
}
/*
@@ -259,13 +240,13 @@ SLANG_UNIT_TEST(precompiledTargetModuleInternalLink2D3D12)
SLANG_UNIT_TEST(precompiledTargetModuleExternalLink2D3D12)
{
runTestImpl(precompiledTargetModule2ExternalLinkTestImpl, unitTestContext,
-Slang::RenderApiFlag::D3D12);
+DeviceType::D3D12);
}
*/
SLANG_UNIT_TEST(precompiledModule2Vulkan)
{
- runTestImpl(precompiledModule2TestImpl, unitTestContext, Slang::RenderApiFlag::Vulkan);
+ runTestImpl(precompiledModule2TestImpl, unitTestContext, DeviceType::Vulkan);
}
SLANG_UNIT_TEST(precompiledTargetModule2InternalLinkVulkan)
@@ -273,7 +254,7 @@ SLANG_UNIT_TEST(precompiledTargetModule2InternalLinkVulkan)
runTestImpl(
precompiledTargetModule2InternalLinkTestImpl,
unitTestContext,
- Slang::RenderApiFlag::Vulkan);
+ DeviceType::Vulkan);
}
SLANG_UNIT_TEST(precompiledTargetModule2ExternalLinkVulkan)
@@ -281,7 +262,9 @@ SLANG_UNIT_TEST(precompiledTargetModule2ExternalLinkVulkan)
runTestImpl(
precompiledTargetModule2ExternalLinkTestImpl,
unitTestContext,
- Slang::RenderApiFlag::Vulkan);
+ DeviceType::Vulkan);
}
} // namespace gfx_test
+
+#endif
diff --git a/tools/gfx-unit-test/precompiled-module-cache.cpp b/tools/gfx-unit-test/precompiled-module-cache.cpp
index 778c68a89..f9ff31070 100644
--- a/tools/gfx-unit-test/precompiled-module-cache.cpp
+++ b/tools/gfx-unit-test/precompiled-module-cache.cpp
@@ -3,18 +3,18 @@
#include "core/slang-io.h"
#include "core/slang-memory-file-system.h"
#include "gfx-test-util.h"
-#include "gfx-util/shader-cursor.h"
-#include "slang-gfx.h"
+#include "slang-rhi.h"
+#include "slang-rhi/shader-cursor.h"
#include "unit-test/slang-unit-test.h"
#include <mutex>
-using namespace gfx;
+using namespace rhi;
namespace gfx_test
{
// Test that precompiled module cache is working.
-Slang::ComPtr<slang::ISession> createSession(gfx::IDevice* device, ISlangFileSystemExt* fileSys)
+Slang::ComPtr<slang::ISession> createSession(rhi::IDevice* device, ISlangFileSystemExt* fileSys)
{
static std::mutex m;
std::lock_guard<std ::mutex> lock(m);
@@ -33,13 +33,13 @@ Slang::ComPtr<slang::ISession> createSession(gfx::IDevice* device, ISlangFileSys
entry.value.intValue0 = 1;
sessionDesc.compilerOptionEntries = &entry;
slang::TargetDesc targetDesc = {};
- switch (device->getDeviceInfo().deviceType)
+ switch (device->getInfo().deviceType)
{
- case gfx::DeviceType::DirectX12:
+ case rhi::DeviceType::D3D12:
targetDesc.format = SLANG_DXIL;
targetDesc.profile = device->getSlangSession()->getGlobalSession()->findProfile("sm_6_1");
break;
- case gfx::DeviceType::Vulkan:
+ case rhi::DeviceType::Vulkan:
targetDesc.format = SLANG_SPIRV;
targetDesc.profile = device->getSlangSession()->getGlobalSession()->findProfile("GLSL_460");
break;
@@ -52,7 +52,7 @@ Slang::ComPtr<slang::ISession> createSession(gfx::IDevice* device, ISlangFileSys
}
static Slang::Result precompileProgram(
- gfx::IDevice* device,
+ rhi::IDevice* device,
ISlangMutableFileSystem* fileSys,
const char* shaderModuleName)
{
@@ -84,12 +84,6 @@ static Slang::Result precompileProgram(
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());
@@ -164,61 +158,47 @@ void precompiledModuleCacheTestImpl(IDevice* device, UnitTestContext* context)
"computeMain",
slangReflection));
- ComputePipelineStateDesc pipelineDesc = {};
+ ComputePipelineDesc pipelineDesc = {};
pipelineDesc.program = shaderProgram.get();
- ComPtr<gfx::IPipelineState> pipelineState;
- GFX_CHECK_CALL_ABORT(
- device->createComputePipelineState(pipelineDesc, pipelineState.writeRef()));
+ ComPtr<IComputePipeline> computePipeline;
+ GFX_CHECK_CALL_ABORT(device->createComputePipeline(pipelineDesc, computePipeline.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 bufferDesc = {};
+ bufferDesc.size = numberCount * sizeof(float);
+ bufferDesc.usage = BufferUsage::UnorderedAccess | BufferUsage::ShaderResource |
+ BufferUsage::CopySource | BufferUsage::CopyDestination;
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;
+ ComPtr<IBuffer> numbersBuffer;
GFX_CHECK_CALL_ABORT(
- device->createBufferView(numbersBuffer, nullptr, viewDesc, bufferView.writeRef()));
+ device->createBuffer(bufferDesc, (void*)initialData, numbersBuffer.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 queue = device->getQueue(QueueType::Graphics);
- auto commandBuffer = transientHeap->createCommandBuffer();
- auto encoder = commandBuffer->encodeComputeCommands();
+ auto commandEncoder = queue->createCommandEncoder();
+ auto encoder = commandEncoder->beginComputePass();
- auto rootObject = encoder->bindPipeline(pipelineState);
+ ComPtr<IShaderObject> rootObject;
+ device->createRootShaderObject(shaderProgram, rootObject.writeRef());
+ encoder->bindPipeline(computePipeline, rootObject);
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 buffer to the entry point.
+ entryPointCursor.getPath("buffer").setBinding(numbersBuffer);
encoder->dispatchCompute(1, 1, 1);
- encoder->endEncoding();
- commandBuffer->close();
- queue->executeCommandBuffer(commandBuffer);
+ encoder->end();
+ queue->submit(commandEncoder->finish());
queue->waitOnHost();
}
- compareComputeResult(device, numbersBuffer, Slang::makeArray<float>(3.0f, 3.0f, 3.0f, 3.0f));
+ compareComputeResult(device, numbersBuffer, std::array{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"(
@@ -239,12 +219,12 @@ void precompiledModuleCacheTestImpl(IDevice* device, UnitTestContext* context)
SLANG_UNIT_TEST(precompiledModuleCacheD3D12)
{
- runTestImpl(precompiledModuleCacheTestImpl, unitTestContext, Slang::RenderApiFlag::D3D12);
+ runTestImpl(precompiledModuleCacheTestImpl, unitTestContext, DeviceType::D3D12, {});
}
SLANG_UNIT_TEST(precompiledModuleCacheVulkan)
{
- runTestImpl(precompiledModuleCacheTestImpl, unitTestContext, Slang::RenderApiFlag::Vulkan);
+ runTestImpl(precompiledModuleCacheTestImpl, unitTestContext, DeviceType::Vulkan, {});
}
} // namespace gfx_test
diff --git a/tools/gfx-unit-test/precompiled-module.cpp b/tools/gfx-unit-test/precompiled-module.cpp
index 3d5e5e565..a1ad645a0 100644
--- a/tools/gfx-unit-test/precompiled-module.cpp
+++ b/tools/gfx-unit-test/precompiled-module.cpp
@@ -2,16 +2,16 @@
#include "core/slang-blob.h"
#include "core/slang-memory-file-system.h"
#include "gfx-test-util.h"
-#include "gfx-util/shader-cursor.h"
-#include "slang-gfx.h"
+#include "slang-rhi.h"
+#include "slang-rhi/shader-cursor.h"
#include "unit-test/slang-unit-test.h"
-using namespace gfx;
+using namespace rhi;
namespace gfx_test
{
static Slang::Result precompileProgram(
- gfx::IDevice* device,
+ IDevice* device,
ISlangMutableFileSystem* fileSys,
const char* shaderModuleName)
{
@@ -48,12 +48,6 @@ static Slang::Result precompileProgram(
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());
@@ -68,13 +62,13 @@ void precompiledModuleTestImpl(IDevice* device, UnitTestContext* context)
slang::SessionDesc sessionDesc = {};
sessionDesc.targetCount = 1;
slang::TargetDesc targetDesc = {};
- switch (device->getDeviceInfo().deviceType)
+ switch (device->getInfo().deviceType)
{
- case gfx::DeviceType::DirectX12:
+ case DeviceType::D3D12:
targetDesc.format = SLANG_DXIL;
targetDesc.profile = device->getSlangSession()->getGlobalSession()->findProfile("sm_6_1");
break;
- case gfx::DeviceType::Vulkan:
+ case DeviceType::Vulkan:
targetDesc.format = SLANG_SPIRV;
targetDesc.profile = device->getSlangSession()->getGlobalSession()->findProfile("GLSL_460");
break;
@@ -91,71 +85,60 @@ void precompiledModuleTestImpl(IDevice* device, UnitTestContext* context)
"computeMain",
slangReflection));
- ComputePipelineStateDesc pipelineDesc = {};
+ ComputePipelineDesc pipelineDesc = {};
pipelineDesc.program = shaderProgram.get();
- ComPtr<gfx::IPipelineState> pipelineState;
- GFX_CHECK_CALL_ABORT(
- device->createComputePipelineState(pipelineDesc, pipelineState.writeRef()));
+ ComPtr<IComputePipeline> pipelineState;
+ GFX_CHECK_CALL_ABORT(device->createComputePipeline(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 bufferDesc = {};
+ bufferDesc.size = numberCount * sizeof(float);
+ bufferDesc.format = Format::Undefined;
bufferDesc.elementSize = sizeof(float);
- bufferDesc.allowedStates = ResourceStateSet(
- ResourceState::ShaderResource,
- ResourceState::UnorderedAccess,
- ResourceState::CopyDestination,
- ResourceState::CopySource);
+ bufferDesc.usage = BufferUsage::ShaderResource | BufferUsage::UnorderedAccess |
+ BufferUsage::CopyDestination | BufferUsage::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;
+ ComPtr<IBuffer> numbersBuffer;
GFX_CHECK_CALL_ABORT(
- device->createBufferView(numbersBuffer, nullptr, viewDesc, bufferView.writeRef()));
+ device->createBuffer(bufferDesc, (void*)initialData, numbersBuffer.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 queue = device->getQueue(QueueType::Graphics);
+ auto commandEncoder = queue->createCommandEncoder();
+ {
+ auto encoder = commandEncoder->beginComputePass();
+ 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 directly to the entry point.
+ entryPointCursor.getPath("buffer").setBinding(Binding(numbersBuffer));
- 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->end();
+ }
- encoder->dispatchCompute(1, 1, 1);
- encoder->endEncoding();
- commandBuffer->close();
- queue->executeCommandBuffer(commandBuffer);
+ auto commandBuffer = commandEncoder->finish();
+ queue->submit(commandBuffer);
queue->waitOnHost();
}
- compareComputeResult(device, numbersBuffer, Slang::makeArray<float>(3.0f, 3.0f, 3.0f, 3.0f));
+ compareComputeResult(device, numbersBuffer, std::array{3.0f, 3.0f, 3.0f, 3.0f});
}
SLANG_UNIT_TEST(precompiledModuleD3D12)
{
- runTestImpl(precompiledModuleTestImpl, unitTestContext, Slang::RenderApiFlag::D3D12);
+ runTestImpl(precompiledModuleTestImpl, unitTestContext, DeviceType::D3D12);
}
SLANG_UNIT_TEST(precompiledModuleVulkan)
{
- runTestImpl(precompiledModuleTestImpl, unitTestContext, Slang::RenderApiFlag::Vulkan);
+ runTestImpl(precompiledModuleTestImpl, unitTestContext, DeviceType::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 1506128ad..a47e84095 100644
--- a/tools/gfx-unit-test/ray-tracing-tests.cpp
+++ b/tools/gfx-unit-test/ray-tracing-tests.cpp
@@ -1,14 +1,17 @@
+#if 0
+// Duplcated: This is ported to slang-rhi\tests\test-ray-tracing.cpp
+
#include "core/slang-basic.h"
#include "gfx-test-texture-util.h"
#include "gfx-test-util.h"
-#include "gfx-util/shader-cursor.h"
#include "platform/vector-math.h"
-#include "slang-gfx.h"
#include "unit-test/slang-unit-test.h"
#include <chrono>
+#include <slang-rhi.h>
+#include <slang-rhi/shader-cursor.h>
-using namespace gfx;
+using namespace rhi;
using namespace Slang;
namespace gfx_test
@@ -53,21 +56,19 @@ 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<IRayTracingPipeline> renderPipelineState;
+ ComPtr<IBuffer> vertexBuffer;
+ ComPtr<IBuffer> indexBuffer;
+ ComPtr<IBuffer> transformBuffer;
+ ComPtr<IBuffer> instanceBuffer;
+ ComPtr<IBuffer> BLASBuffer;
ComPtr<IAccelerationStructure> BLAS;
- ComPtr<IBufferResource> TLASBuffer;
+ ComPtr<IBuffer> TLASBuffer;
ComPtr<IAccelerationStructure> TLAS;
- ComPtr<ITextureResource> resultTexture;
- ComPtr<IResourceView> resultTextureUAV;
+ ComPtr<ITexture> resultTexture;
+ ComPtr<ITextureView> resultTextureUAV;
ComPtr<IShaderTable> shaderTable;
uint32_t width = 2;
@@ -85,7 +86,7 @@ struct BaseRayTracingTest
}
// Load and compile shader code from source.
- gfx::Result loadShaderProgram(gfx::IDevice* device, gfx::IShaderProgram** outProgram)
+ Result loadShaderProgram(IDevice* device, IShaderProgram** outProgram)
{
ComPtr<slang::ISession> slangSession;
slangSession = device->getSlangSession();
@@ -122,181 +123,151 @@ struct BaseRayTracingTest
diagnosticsBlob.writeRef());
SLANG_RETURN_ON_FAIL(result);
- gfx::IShaderProgram::Desc programDesc = {};
+ ShaderProgramDesc programDesc = {};
programDesc.slangGlobalScope = linkedProgram;
- SLANG_RETURN_ON_FAIL(device->createProgram(programDesc, outProgram));
+ SLANG_RETURN_ON_FAIL(device->createShaderProgram(programDesc, outProgram));
return SLANG_OK;
}
void createResultTexture()
{
- ITextureResource::Desc resultTextureDesc = {};
- resultTextureDesc.type = IResource::Type::Texture2D;
- resultTextureDesc.numMipLevels = 1;
+ TextureDesc resultTextureDesc = {};
+ resultTextureDesc.type = TextureType::Texture2D;
+ resultTextureDesc.mipCount = 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 = {};
+ resultTextureDesc.format = Format::RGBA32Float;
+ resultTextureDesc.usage = TextureUsage::UnorderedAccess | TextureUsage::CopySource;
+ resultTexture = device->createTexture(resultTextureDesc);
+
+ TextureViewDesc resultUAVDesc = {};
resultUAVDesc.format = resultTextureDesc.format;
- resultUAVDesc.type = IResourceView::Type::UnorderedAccess;
- resultTextureUAV = device->createTextureView(resultTexture, resultUAVDesc);
+ resultTextureUAV = resultTexture->createView(resultUAVDesc);
}
void createRequiredResources()
{
- ICommandQueue::Desc queueDesc = {};
- queueDesc.type = ICommandQueue::QueueType::Graphics;
- queue = device->createCommandQueue(queueDesc);
+ GFX_CHECK_CALL_ABORT(device->getQueue(QueueType::Graphics, queue.writeRef()));
- IBufferResource::Desc vertexBufferDesc;
- vertexBufferDesc.type = IResource::Type::Buffer;
- vertexBufferDesc.sizeInBytes = kVertexCount * sizeof(Vertex);
+ BufferDesc vertexBufferDesc;
+ vertexBufferDesc.size = kVertexCount * sizeof(Vertex);
vertexBufferDesc.defaultState = ResourceState::ShaderResource;
- vertexBuffer = device->createBufferResource(vertexBufferDesc, &kVertexData[0]);
+ vertexBufferDesc.usage = BufferUsage::ShaderResource | BufferUsage::AccelerationStructureBuildInput;
+ vertexBuffer = device->createBuffer(vertexBufferDesc, &kVertexData[0]);
SLANG_CHECK_ABORT(vertexBuffer != nullptr);
- IBufferResource::Desc indexBufferDesc;
- indexBufferDesc.type = IResource::Type::Buffer;
- indexBufferDesc.sizeInBytes = kIndexCount * sizeof(int32_t);
+ BufferDesc indexBufferDesc;
+ indexBufferDesc.size = kIndexCount * sizeof(int32_t);
indexBufferDesc.defaultState = ResourceState::ShaderResource;
- indexBuffer = device->createBufferResource(indexBufferDesc, &kIndexData[0]);
+ indexBufferDesc.usage = BufferUsage::ShaderResource | BufferUsage::AccelerationStructureBuildInput;
+ indexBuffer = device->createBuffer(indexBufferDesc, &kIndexData[0]);
SLANG_CHECK_ABORT(indexBuffer != nullptr);
- IBufferResource::Desc transformBufferDesc;
- transformBufferDesc.type = IResource::Type::Buffer;
- transformBufferDesc.sizeInBytes = sizeof(float) * 12;
+ BufferDesc transformBufferDesc;
+ transformBufferDesc.size = sizeof(float) * 12;
transformBufferDesc.defaultState = ResourceState::ShaderResource;
+ transformBufferDesc.usage = BufferUsage::ShaderResource | BufferUsage::AccelerationStructureBuildInput;
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);
+ transformBuffer = device->createBuffer(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;
+ AccelerationStructureBuildInput geomInput = {};
+ geomInput.type = AccelerationStructureBuildInputType::Triangles;
+ geomInput.triangles.flags = AccelerationStructureGeometryFlags::Opaque;
+ geomInput.triangles.indexCount = kIndexCount;
+ geomInput.triangles.indexBuffer = BufferOffsetPair(indexBuffer, 0);
+ geomInput.triangles.indexFormat = IndexFormat::Uint32;
+ geomInput.triangles.vertexCount = kVertexCount;
+ geomInput.triangles.vertexBuffers[0] = BufferOffsetPair(vertexBuffer, 0);
+ geomInput.triangles.vertexBufferCount = 1;
+ geomInput.triangles.vertexFormat = Format::RGB32Float;
+ geomInput.triangles.vertexStride = sizeof(Vertex);
+ geomInput.triangles.preTransformBuffer = BufferOffsetPair(transformBuffer, 0);
+
+ AccelerationStructureBuildDesc buildInputs = {};
+ buildInputs.inputs = &geomInput;
+ buildInputs.inputCount = 1;
+ buildInputs.flags = AccelerationStructureBuildFlags::AllowCompaction;
// Query buffer size for acceleration structure build.
- GFX_CHECK_CALL_ABORT(device->getAccelerationStructurePrebuildInfo(
- accelerationStructureBuildInputs,
- &accelerationStructurePrebuildInfo));
+ AccelerationStructureSizes sizes;
+ GFX_CHECK_CALL_ABORT(device->getAccelerationStructureSizes(buildInputs, &sizes));
+
// Allocate buffers for acceleration structure.
- IBufferResource::Desc asDraftBufferDesc;
- asDraftBufferDesc.type = IResource::Type::Buffer;
+ BufferDesc asDraftBufferDesc;
asDraftBufferDesc.defaultState = ResourceState::AccelerationStructure;
- asDraftBufferDesc.sizeInBytes =
- (size_t)accelerationStructurePrebuildInfo.resultDataMaxSize;
- ComPtr<IBufferResource> draftBuffer = device->createBufferResource(asDraftBufferDesc);
- IBufferResource::Desc scratchBufferDesc;
- scratchBufferDesc.type = IResource::Type::Buffer;
+ asDraftBufferDesc.size = sizes.accelerationStructureSize;
+ asDraftBufferDesc.usage = BufferUsage::AccelerationStructure;
+ ComPtr<IBuffer> draftBuffer = device->createBuffer(asDraftBufferDesc);
+
+ BufferDesc scratchBufferDesc;
scratchBufferDesc.defaultState = ResourceState::UnorderedAccess;
- scratchBufferDesc.sizeInBytes =
- (size_t)accelerationStructurePrebuildInfo.scratchDataSize;
- ComPtr<IBufferResource> scratchBuffer = device->createBufferResource(scratchBufferDesc);
+ scratchBufferDesc.size = sizes.scratchSize;
+ scratchBufferDesc.usage = BufferUsage::UnorderedAccess;
+ ComPtr<IBuffer> scratchBuffer = device->createBuffer(scratchBufferDesc);
// Build acceleration structure.
ComPtr<IQueryPool> compactedSizeQuery;
- IQueryPool::Desc queryPoolDesc;
+ QueryPoolDesc 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;
+ AccelerationStructureDesc draftCreateDesc;
+ draftCreateDesc.size = sizes.accelerationStructureSize;
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();
+ auto commandEncoder = queue->createCommandEncoder();
AccelerationStructureQueryDesc compactedSizeQueryDesc = {};
compactedSizeQueryDesc.queryPool = compactedSizeQuery;
compactedSizeQueryDesc.queryType = QueryType::AccelerationStructureCompactedSize;
- encoder->buildAccelerationStructure(buildDesc, 1, &compactedSizeQueryDesc);
- encoder->endEncoding();
- commandBuffer->close();
- queue->executeCommandBuffer(commandBuffer);
+ commandEncoder->buildAccelerationStructure(buildInputs, draftAS, nullptr, BufferOffsetPair(scratchBuffer, 0), 1, &compactedSizeQueryDesc);
+ auto commandBuffer = commandEncoder->finish();
+ queue->submit(commandBuffer);
queue->waitOnHost();
uint64_t compactedSize = 0;
compactedSizeQuery->getResult(0, 1, &compactedSize);
- IBufferResource::Desc asBufferDesc;
- asBufferDesc.type = IResource::Type::Buffer;
+
+ BufferDesc asBufferDesc;
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;
+ asBufferDesc.size = (size_t)compactedSize;
+ asBufferDesc.usage = BufferUsage::AccelerationStructure;
+ BLASBuffer = device->createBuffer(asBufferDesc);
+
+ AccelerationStructureDesc createDesc;
createDesc.size = (size_t)compactedSize;
device->createAccelerationStructure(createDesc, BLAS.writeRef());
- commandBuffer = transientHeap->createCommandBuffer();
- encoder = commandBuffer->encodeRayTracingCommands();
- encoder->copyAccelerationStructure(
+ commandEncoder = queue->createCommandEncoder();
+ commandEncoder->copyAccelerationStructure(
BLAS,
draftAS,
AccelerationStructureCopyMode::Compact);
- encoder->endEncoding();
- commandBuffer->close();
- queue->executeCommandBuffer(commandBuffer);
+ commandBuffer = commandEncoder->finish();
+ queue->submit(commandBuffer);
queue->waitOnHost();
}
// Build top level acceleration structure.
{
- List<IAccelerationStructure::InstanceDesc> instanceDescs;
+ List<AccelerationStructureInstanceDescGeneric> instanceDescs;
instanceDescs.setCount(1);
- instanceDescs[0].accelerationStructure = BLAS->getDeviceAddress();
- instanceDescs[0].flags =
- IAccelerationStructure::GeometryInstanceFlags::TriangleFacingCullDisable;
+ instanceDescs[0].accelerationStructure.value = BLAS->getDeviceAddress();
+ instanceDescs[0].flags = AccelerationStructureInstanceFlags::TriangleFacingCullDisable;
instanceDescs[0].instanceContributionToHitGroupIndex = 0;
instanceDescs[0].instanceID = 0;
instanceDescs[0].instanceMask = 0xFF;
@@ -304,64 +275,55 @@ struct BaseRayTracingTest
{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);
+ BufferDesc instanceBufferDesc;
+ instanceBufferDesc.size = instanceDescs.getCount() * sizeof(AccelerationStructureInstanceDescGeneric);
instanceBufferDesc.defaultState = ResourceState::ShaderResource;
- instanceBuffer =
- device->createBufferResource(instanceBufferDesc, instanceDescs.getBuffer());
+ instanceBufferDesc.usage = BufferUsage::ShaderResource | BufferUsage::AccelerationStructureBuildInput;
+ instanceBuffer = device->createBuffer(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();
+ AccelerationStructureBuildInput instanceInput = {};
+ instanceInput.type = AccelerationStructureBuildInputType::Instances;
+ instanceInput.instances.instanceBuffer = BufferOffsetPair(instanceBuffer, 0);
+ instanceInput.instances.instanceStride = sizeof(AccelerationStructureInstanceDescGeneric);
+ instanceInput.instances.instanceCount = instanceDescs.getCount();
+
+ AccelerationStructureBuildDesc buildInputs = {};
+ buildInputs.inputs = &instanceInput;
+ buildInputs.inputCount = 1;
// Query buffer size for acceleration structure build.
- GFX_CHECK_CALL_ABORT(device->getAccelerationStructurePrebuildInfo(
- accelerationStructureBuildInputs,
- &accelerationStructurePrebuildInfo));
+ AccelerationStructureSizes sizes;
+ GFX_CHECK_CALL_ABORT(device->getAccelerationStructureSizes(buildInputs, &sizes));
- IBufferResource::Desc asBufferDesc;
- asBufferDesc.type = IResource::Type::Buffer;
+ BufferDesc asBufferDesc;
asBufferDesc.defaultState = ResourceState::AccelerationStructure;
- asBufferDesc.sizeInBytes = (size_t)accelerationStructurePrebuildInfo.resultDataMaxSize;
- TLASBuffer = device->createBufferResource(asBufferDesc);
+ asBufferDesc.size = sizes.accelerationStructureSize;
+ asBufferDesc.usage = BufferUsage::AccelerationStructure;
+ TLASBuffer = device->createBuffer(asBufferDesc);
- IBufferResource::Desc scratchBufferDesc;
- scratchBufferDesc.type = IResource::Type::Buffer;
+ BufferDesc scratchBufferDesc;
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;
+ scratchBufferDesc.size = sizes.scratchSize;
+ scratchBufferDesc.usage = BufferUsage::UnorderedAccess;
+ ComPtr<IBuffer> scratchBuffer = device->createBuffer(scratchBufferDesc);
+
+ AccelerationStructureDesc createDesc;
+ createDesc.size = sizes.accelerationStructureSize;
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);
+ auto commandEncoder = queue->createCommandEncoder();
+ commandEncoder->buildAccelerationStructure(buildInputs, TLAS, nullptr, BufferOffsetPair(scratchBuffer, 0), 0, nullptr);
+ auto commandBuffer = commandEncoder->finish();
+ queue->submit(commandBuffer);
queue->waitOnHost();
}
const char* hitgroupNames[] = {"hitgroupA", "hitgroupB"};
ComPtr<IShaderProgram> rayTracingProgram;
- GFX_CHECK_CALL_ABORT(loadShaderProgram(device, rayTracingProgram.writeRef()));
- RayTracingPipelineStateDesc rtpDesc = {};
+ SLANG_CHECK_ABORT(loadShaderProgram(device, rayTracingProgram.writeRef()));
+ RayTracingPipelineDesc rtpDesc = {};
rtpDesc.program = rayTracingProgram;
rtpDesc.hitGroupCount = 2;
HitGroupDesc hitGroups[2];
@@ -373,13 +335,13 @@ struct BaseRayTracingTest
rtpDesc.maxRayPayloadSize = 64;
rtpDesc.maxRecursion = 2;
GFX_CHECK_CALL_ABORT(
- device->createRayTracingPipelineState(rtpDesc, renderPipelineState.writeRef()));
+ device->createRayTracingPipeline(rtpDesc, renderPipelineState.writeRef()));
SLANG_CHECK_ABORT(renderPipelineState != nullptr);
const char* raygenNames[] = {"rayGenShaderA", "rayGenShaderB"};
const char* missNames[] = {"missShaderA", "missShaderB"};
- IShaderTable::Desc shaderTableDesc = {};
+ ShaderTableDesc shaderTableDesc = {};
shaderTableDesc.program = rayTracingProgram;
shaderTableDesc.hitGroupCount = 2;
shaderTableDesc.hitGroupNames = hitgroupNames;
@@ -393,31 +355,26 @@ struct BaseRayTracingTest
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);
- encoder->endEncoding();
- cmdBuffer->close();
- queue->executeCommandBuffer(cmdBuffer.get());
+ auto commandEncoder = queue->createCommandEncoder();
+ commandEncoder->setTextureState(resultTexture, ResourceState::CopySource);
+ queue->submit(commandEncoder->finish());
queue->waitOnHost();
- GFX_CHECK_CALL_ABORT(device->readTextureResource(
+ SubresourceLayout layout;
+ GFX_CHECK_CALL_ABORT(device->readTexture(
resultTexture,
- ResourceState::CopySource,
+ 0, 0,
resultBlob.writeRef(),
- &rowPitch,
- &pixelSize));
+ &layout));
+ size_t rowPitch = layout.rowPitch;
+ size_t pixelSize = 4 ;
+
#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)
+ auto actualData = (float*)buffer.data();
+ SLANG_CHECK_ABORT(memcmp(actualData, expectedResult, count * sizeof(float)) == 0)
}
};
@@ -425,17 +382,16 @@ struct RayTracingTestA : BaseRayTracingTest
{
void renderFrame()
{
- ComPtr<ICommandBuffer> renderCommandBuffer = transientHeap->createCommandBuffer();
- auto renderEncoder = renderCommandBuffer->encodeRayTracingCommands();
- IShaderObject* rootObject = nullptr;
- renderEncoder->bindPipeline(renderPipelineState, &rootObject);
+ auto commandEncoder = queue->createCommandEncoder();
+ auto renderEncoder = commandEncoder->beginRayTracingPass();
+ auto rootObject = renderEncoder->bindPipeline(renderPipelineState, shaderTable);
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);
+ cursor["resultTexture"].setBinding(Binding(resultTextureUAV));
+ cursor["sceneBVH"].setBinding(Binding(TLAS));
+ renderEncoder->dispatchRays(0, width, height, 1);
+ renderEncoder->end();
+ auto commandBuffer = commandEncoder->finish();
+ queue->submit(commandBuffer);
queue->waitOnHost();
}
@@ -453,17 +409,16 @@ struct RayTracingTestB : BaseRayTracingTest
{
void renderFrame()
{
- ComPtr<ICommandBuffer> renderCommandBuffer = transientHeap->createCommandBuffer();
- auto renderEncoder = renderCommandBuffer->encodeRayTracingCommands();
- IShaderObject* rootObject = nullptr;
- renderEncoder->bindPipeline(renderPipelineState, &rootObject);
+ auto commandEncoder = queue->createCommandEncoder();
+ auto renderEncoder = commandEncoder->beginRayTracingPass();
+ auto rootObject = renderEncoder->bindPipeline(renderPipelineState, shaderTable);
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);
+ cursor["resultTexture"].setBinding(Binding(resultTextureUAV));
+ cursor["sceneBVH"].setBinding(Binding(TLAS));
+ renderEncoder->dispatchRays(1, width, height, 1);
+ renderEncoder->end();
+ auto commandBuffer = commandEncoder->finish();
+ queue->submit(commandBuffer);
queue->waitOnHost();
}
@@ -487,21 +442,22 @@ void rayTracingTestImpl(IDevice* device, UnitTestContext* context)
SLANG_UNIT_TEST(RayTracingTestAD3D12)
{
- runTestImpl(rayTracingTestImpl<RayTracingTestA>, unitTestContext, Slang::RenderApiFlag::D3D12);
+ runTestImpl(rayTracingTestImpl<RayTracingTestA>, unitTestContext, DeviceType::D3D12);
}
SLANG_UNIT_TEST(RayTracingTestAVulkan)
{
- runTestImpl(rayTracingTestImpl<RayTracingTestA>, unitTestContext, Slang::RenderApiFlag::Vulkan);
+ runTestImpl(rayTracingTestImpl<RayTracingTestA>, unitTestContext, DeviceType::Vulkan);
}
SLANG_UNIT_TEST(RayTracingTestBD3D12)
{
- runTestImpl(rayTracingTestImpl<RayTracingTestB>, unitTestContext, Slang::RenderApiFlag::D3D12);
+ runTestImpl(rayTracingTestImpl<RayTracingTestB>, unitTestContext, DeviceType::D3D12);
}
SLANG_UNIT_TEST(RayTracingTestBVulkan)
{
- runTestImpl(rayTracingTestImpl<RayTracingTestB>, unitTestContext, Slang::RenderApiFlag::Vulkan);
+ runTestImpl(rayTracingTestImpl<RayTracingTestB>, unitTestContext, DeviceType::Vulkan);
}
} // namespace gfx_test
+#endif \ No newline at end of file
diff --git a/tools/gfx-unit-test/resolve-resource-tests.cpp b/tools/gfx-unit-test/resolve-resource-tests.cpp
index dd318c7c4..eac03c228 100644
--- a/tools/gfx-unit-test/resolve-resource-tests.cpp
+++ b/tools/gfx-unit-test/resolve-resource-tests.cpp
@@ -1,15 +1,19 @@
+#if 0
+// Disabled: slang-rhi doesn't have resolveResource API.
+
#include "core/slang-basic.h"
#include "gfx-test-util.h"
-#include "gfx-util/shader-cursor.h"
-#include "slang-gfx.h"
#include "unit-test/slang-unit-test.h"
+#include <slang-rhi.h>
+#include <slang-rhi/shader-cursor.h>
+
#if SLANG_WINDOWS_FAMILY
#include <d3d12.h>
#endif
using namespace Slang;
-using namespace gfx;
+using namespace rhi;
namespace
{
@@ -46,17 +50,15 @@ static const Vertex kVertexData[kVertexCount] = {
const int kWidth = 256;
const int kHeight = 256;
-Format format = Format::R32G32B32A32_FLOAT;
+Format format = Format::RGBA32Float;
-ComPtr<IBufferResource> createVertexBuffer(IDevice* device)
+ComPtr<IBuffer> 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]);
+ BufferDesc vertexBufferDesc;
+ vertexBufferDesc.size = kVertexCount * sizeof(Vertex);
+ vertexBufferDesc.defaultState = ResourceState::VertexBuffer;
+ vertexBufferDesc.usage = BufferUsage::VertexBuffer;
+ ComPtr<IBuffer> vertexBuffer = device->createBuffer(vertexBufferDesc, &kVertexData[0]);
SLANG_CHECK_ABORT(vertexBuffer != nullptr);
return vertexBuffer;
}
@@ -66,22 +68,19 @@ struct BaseResolveResourceTest
IDevice* device;
UnitTestContext* context;
- ComPtr<ITextureResource> msaaTexture;
- ComPtr<ITextureResource> dstTexture;
+ ComPtr<ITexture> msaaTexture;
+ ComPtr<ITexture> dstTexture;
- ComPtr<ITransientResourceHeap> transientHeap;
- ComPtr<IPipelineState> pipelineState;
- ComPtr<IRenderPassLayout> renderPass;
- ComPtr<IFramebuffer> framebuffer;
+ ComPtr<IRenderPipeline> pipelineState;
- ComPtr<IBufferResource> vertexBuffer;
+ ComPtr<IBuffer> vertexBuffer;
struct TextureInfo
{
- ITextureResource::Extents extent;
+ Extent3D extent;
int numMipLevels;
int arraySize;
- ITextureResource::SubresourceData const* initData;
+ const SubresourceData* initData;
};
void init(IDevice* device, UnitTestContext* context)
@@ -101,42 +100,36 @@ struct BaseResolveResourceTest
InputElementDesc inputElements[] = {
// Vertex buffer data
- {"POSITION", 0, Format::R32G32B32_FLOAT, offsetof(Vertex, position), 0},
- {"COLOR", 0, Format::R32G32B32_FLOAT, offsetof(Vertex, color), 0},
+ {"POSITION", 0, Format::RGB32Float, offsetof(Vertex, position), 0},
+ {"COLOR", 0, Format::RGB32Float, offsetof(Vertex, color), 0},
};
- ITextureResource::Desc msaaTexDesc = {};
- msaaTexDesc.type = IResource::Type::Texture2D;
- msaaTexDesc.numMipLevels = dstTextureInfo.numMipLevels;
- msaaTexDesc.arraySize = dstTextureInfo.arraySize;
+ TextureDesc msaaTexDesc = {};
+ msaaTexDesc.type = TextureType::Texture2D;
+ msaaTexDesc.mipCount = dstTextureInfo.numMipLevels;
+ msaaTexDesc.arrayLength = dstTextureInfo.arraySize;
msaaTexDesc.size = dstTextureInfo.extent;
msaaTexDesc.defaultState = ResourceState::RenderTarget;
- msaaTexDesc.allowedStates =
- ResourceStateSet(ResourceState::RenderTarget, ResourceState::ResolveSource);
+ msaaTexDesc.usage = TextureUsage::RenderTarget;
msaaTexDesc.format = format;
- msaaTexDesc.sampleDesc.numSamples = 4;
+ msaaTexDesc.sampleCount = 4;
- GFX_CHECK_CALL_ABORT(device->createTextureResource(
- msaaTexDesc,
- msaaTextureInfo.initData,
- msaaTexture.writeRef()));
+ msaaTexture = device->createTexture(msaaTexDesc, msaaTextureInfo.initData);
+ SLANG_CHECK_ABORT(msaaTexture);
- ITextureResource::Desc dstTexDesc = {};
- dstTexDesc.type = IResource::Type::Texture2D;
- dstTexDesc.numMipLevels = dstTextureInfo.numMipLevels;
- dstTexDesc.arraySize = dstTextureInfo.arraySize;
+ TextureDesc dstTexDesc = {};
+ dstTexDesc.type = TextureType::Texture2D;
+ dstTexDesc.mipCount = dstTextureInfo.numMipLevels;
+ dstTexDesc.arrayLength = dstTextureInfo.arraySize;
dstTexDesc.size = dstTextureInfo.extent;
- dstTexDesc.defaultState = ResourceState::ResolveDestination;
- dstTexDesc.allowedStates =
- ResourceStateSet(ResourceState::ResolveDestination, ResourceState::CopySource);
+ dstTexDesc.defaultState = ResourceState::CopyDestination;
+ dstTexDesc.usage = TextureUsage::CopyDestination | TextureUsage::CopySource;
dstTexDesc.format = format;
- GFX_CHECK_CALL_ABORT(device->createTextureResource(
- dstTexDesc,
- dstTextureInfo.initData,
- dstTexture.writeRef()));
+ dstTexture = device->createTexture(dstTexDesc, dstTextureInfo.initData);
+ SLANG_CHECK_ABORT(dstTexture);
- IInputLayout::Desc inputLayoutDesc = {};
+ InputLayoutDesc inputLayoutDesc = {};
inputLayoutDesc.inputElementCount = SLANG_COUNT_OF(inputElements);
inputLayoutDesc.inputElements = inputElements;
inputLayoutDesc.vertexStreamCount = SLANG_COUNT_OF(vertexStreams);
@@ -146,11 +139,6 @@ struct BaseResolveResourceTest
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(
@@ -161,98 +149,84 @@ struct BaseResolveResourceTest
"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 = {};
+ ColorTargetDesc colorTarget = {};
+ colorTarget.format = format;
+
+ RenderPipelineDesc pipelineDesc = {};
pipelineDesc.program = shaderProgram.get();
pipelineDesc.inputLayout = inputLayout;
- pipelineDesc.framebufferLayout = framebufferLayout;
+ pipelineDesc.targets = &colorTarget;
+ pipelineDesc.targetCount = 1;
+ pipelineDesc.primitiveTopology = PrimitiveTopology::TriangleList;
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()));
+ pipelineState = device->createRenderPipeline(pipelineDesc);
+ SLANG_CHECK_ABORT(pipelineState);
}
void submitGPUWork(
SubresourceRange msaaSubresource,
SubresourceRange dstSubresource,
- ITextureResource::Extents extent)
+ Extent3D 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 queue = device->getQueue(QueueType::Graphics);
+
+ ComPtr<ICommandEncoder> encoder = queue->createCommandEncoder();
+
+ // Create render target view
+ TextureViewDesc rtvDesc = {};
+ rtvDesc.format = format;
+ auto rtv = device->createTextureView(msaaTexture, rtvDesc);
+
+ RenderPassColorAttachment colorAttachment = {};
+ colorAttachment.view = rtv;
+ colorAttachment.loadOp = LoadOp::Clear;
+ colorAttachment.storeOp = StoreOp::Store;
+ float clearColor[4] = {0.0f, 0.0f, 0.0f, 0.0f};
+ memcpy(colorAttachment.clearValue, clearColor, sizeof(clearColor));
+
+ RenderPassDesc passDesc = {};
+ passDesc.colorAttachments = &colorAttachment;
+ passDesc.colorAttachmentCount = 1;
+
+ auto renderEncoder = encoder->beginRenderPass(passDesc);
auto rootObject = renderEncoder->bindPipeline(pipelineState);
- gfx::Viewport viewport = {};
+ 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(
+
+ RenderState state = {};
+ state.viewports[0] = viewport;
+ state.viewportCount = 1;
+ state.vertexBuffers[0] = BufferOffsetPair(vertexBuffer, 0);
+ state.vertexBufferCount = 1;
+ renderEncoder->setRenderState(state);
+
+ DrawArguments drawArgs = {};
+ drawArgs.vertexCount = kVertexCount;
+ drawArgs.startVertexLocation = 0;
+ renderEncoder->draw(drawArgs);
+ renderEncoder->end();
+
+ // Note: slang-rhi doesn't have a direct resolveResource function
+ // For MSAA resolve, we would typically use a resolve render pass or blit operation
+ // For this test, we'll use a simple copy operation instead
+ encoder->copyTexture(
+ dstTexture,
+ dstSubresource,
+ Offset3D{0, 0, 0},
msaaTexture,
- ResourceState::ResolveSource,
msaaSubresource,
- dstTexture,
- ResourceState::ResolveDestination,
- dstSubresource);
- resourceEncoder->textureSubresourceBarrier(
+ Offset3D{0, 0, 0},
+ extent);
+ encoder->setTextureState(
dstTexture,
dstSubresource,
- ResourceState::ResolveDestination,
ResourceState::CopySource);
- resourceEncoder->endEncoding();
- commandBuffer->close();
- queue->executeCommandBuffer(commandBuffer);
+
+ queue->submit(encoder->finish());
queue->waitOnHost();
}
@@ -269,12 +243,12 @@ struct BaseResolveResourceTest
ComPtr<ISlangBlob> resultBlob;
size_t rowPitch = 0;
size_t pixelSize = 0;
- GFX_CHECK_CALL_ABORT(device->readTextureResource(
+ GFX_CHECK_CALL_ABORT(device->readTexture(
dstTexture,
- ResourceState::CopySource,
+ 0, // layer
+ 0, // mip
resultBlob.writeRef(),
- &rowPitch,
- &pixelSize));
+ nullptr)); // SubresourceLayout output is optional
auto result = (float*)resultBlob->getBufferPointer();
int cursor = 0;
@@ -297,13 +271,11 @@ struct BaseResolveResourceTest
}
};
-// TODO: Add more tests?
-
struct ResolveResourceSimple : BaseResolveResourceTest
{
void run()
{
- ITextureResource::Extents extent = {};
+ Extent3D extent = {};
extent.width = kWidth;
extent.height = kHeight;
extent.depth = 1;
@@ -314,18 +286,16 @@ struct ResolveResourceSimple : BaseResolveResourceTest
createRequiredResources(msaaTextureInfo, dstTextureInfo, format);
SubresourceRange msaaSubresource = {};
- msaaSubresource.aspectMask = TextureAspect::Color;
- msaaSubresource.mipLevel = 0;
- msaaSubresource.mipLevelCount = 1;
- msaaSubresource.baseArrayLayer = 0;
+ msaaSubresource.layer = 0;
msaaSubresource.layerCount = 1;
+ msaaSubresource.mip = 0;
+ msaaSubresource.mipCount = 1;
SubresourceRange dstSubresource = {};
- dstSubresource.aspectMask = TextureAspect::Color;
- dstSubresource.mipLevel = 0;
- dstSubresource.mipLevelCount = 1;
- dstSubresource.baseArrayLayer = 0;
+ dstSubresource.layer = 0;
dstSubresource.layerCount = 1;
+ dstSubresource.mip = 0;
+ dstSubresource.mipCount = 1;
submitGPUWork(msaaSubresource, dstSubresource, extent);
@@ -355,7 +325,7 @@ SLANG_UNIT_TEST(resolveResourceSimpleD3D12)
runTestImpl(
resolveResourceTestImpl<ResolveResourceSimple>,
unitTestContext,
- Slang::RenderApiFlag::D3D12);
+ DeviceType::D3D12);
}
SLANG_UNIT_TEST(resolveResourceSimpleVulkan)
@@ -363,6 +333,8 @@ SLANG_UNIT_TEST(resolveResourceSimpleVulkan)
runTestImpl(
resolveResourceTestImpl<ResolveResourceSimple>,
unitTestContext,
- Slang::RenderApiFlag::Vulkan);
+ DeviceType::Vulkan);
}
} // namespace gfx_test
+
+#endif
diff --git a/tools/gfx-unit-test/root-mutable-shader-object.cpp b/tools/gfx-unit-test/root-mutable-shader-object.cpp
index c3bd95382..4c538d730 100644
--- a/tools/gfx-unit-test/root-mutable-shader-object.cpp
+++ b/tools/gfx-unit-test/root-mutable-shader-object.cpp
@@ -1,21 +1,21 @@
+#if 0
+// Duplicated: This test is identical to slang-rhi\tests\test-mutable-shader-object.cpp
+// TODO: This test failed
+// The result buffer is still {0.0f, 1.0f, 2.0f, 3.0f}. Not incremented by the shader
+
#include "core/slang-basic.h"
#include "gfx-test-util.h"
-#include "gfx-util/shader-cursor.h"
-#include "slang-gfx.h"
#include "unit-test/slang-unit-test.h"
-using namespace gfx;
+#include <slang-rhi.h>
+#include <slang-rhi/shader-cursor.h>
+
+using namespace rhi;
namespace gfx_test
{
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(
@@ -25,45 +25,34 @@ void mutableRootShaderObjectTestImpl(IDevice* device, UnitTestContext* context)
"computeMain",
slangReflection));
- ComputePipelineStateDesc pipelineDesc = {};
+ ComputePipelineDesc pipelineDesc = {};
pipelineDesc.program = shaderProgram.get();
- ComPtr<gfx::IPipelineState> pipelineState;
+ ComPtr<IComputePipeline> computePipeline;
GFX_CHECK_CALL_ABORT(
- device->createComputePipelineState(pipelineDesc, pipelineState.writeRef()));
+ device->createComputePipeline(pipelineDesc, computePipeline.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 bufferDesc = {};
+ bufferDesc.size = sizeof(initialData);
+ bufferDesc.format = Format::Undefined;
bufferDesc.elementSize = sizeof(float);
- bufferDesc.allowedStates = ResourceStateSet(
- ResourceState::ShaderResource,
- ResourceState::UnorderedAccess,
- ResourceState::CopyDestination,
- ResourceState::CopySource);
+ bufferDesc.usage = BufferUsage::UnorderedAccess | BufferUsage::ShaderResource | BufferUsage::CopySource | BufferUsage::CopyDestination;
bufferDesc.defaultState = ResourceState::UnorderedAccess;
bufferDesc.memoryType = MemoryType::DeviceLocal;
- ComPtr<IBufferResource> numbersBuffer;
+ ComPtr<IBuffer> 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()));
+ device->createBuffer(bufferDesc, (void*)initialData, numbersBuffer.writeRef()));
ComPtr<IShaderObject> rootObject;
- device->createMutableRootShaderObject(shaderProgram, rootObject.writeRef());
+ device->createRootShaderObject(shaderProgram, rootObject.writeRef());
auto entryPointCursor = ShaderCursor(rootObject->getEntryPoint(0));
- entryPointCursor.getPath("buffer").setResource(bufferView);
+ entryPointCursor.getPath("buffer").setBinding(Binding(numbersBuffer));
slang::TypeReflection* addTransformerType = slangReflection->findTypeByName("AddTransformer");
ComPtr<IShaderObject> transformer;
- GFX_CHECK_CALL_ABORT(device->createMutableShaderObject(
+ GFX_CHECK_CALL_ABORT(device->createShaderObject(
addTransformerType,
ShaderObjectContainerType::None,
transformer.writeRef()));
@@ -74,50 +63,45 @@ void mutableRootShaderObjectTestImpl(IDevice* device, UnitTestContext* context)
ShaderCursor(transformer).getPath("c").setData(&c, sizeof(float));
{
- ICommandQueue::Desc queueDesc = {ICommandQueue::QueueType::Graphics};
- auto queue = device->createCommandQueue(queueDesc);
+ auto queue = device->getQueue(QueueType::Graphics);
- auto commandBuffer = transientHeap->createCommandBuffer();
+ auto commandEncoder = queue->createCommandEncoder();
{
- auto encoder = commandBuffer->encodeComputeCommands();
- encoder->bindPipelineWithRootObject(pipelineState, rootObject);
+ auto encoder = commandEncoder->beginComputePass();
+ encoder->bindPipeline(computePipeline, rootObject);
encoder->dispatchCompute(1, 1, 1);
- encoder->endEncoding();
+ encoder->end();
}
- auto barrierEncoder = commandBuffer->encodeResourceCommands();
- barrierEncoder->bufferBarrier(
- 1,
- numbersBuffer.readRef(),
- ResourceState::UnorderedAccess,
- ResourceState::UnorderedAccess);
- barrierEncoder->endEncoding();
+ // Set buffer state to ensure writes are visible
+ commandEncoder->setBufferState(numbersBuffer, ResourceState::UnorderedAccess);
// 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);
+ auto encoder = commandEncoder->beginComputePass();
+ encoder->bindPipeline(computePipeline, rootObject);
encoder->dispatchCompute(1, 1, 1);
- encoder->endEncoding();
+ encoder->end();
}
- commandBuffer->close();
- queue->executeCommandBuffer(commandBuffer);
+ queue->submit(commandEncoder->finish());
queue->waitOnHost();
}
- compareComputeResult(device, numbersBuffer, Slang::makeArray<float>(3.0f, 4.0f, 5.0f, 6.0f));
+ compareComputeResult(device, numbersBuffer, std::array{3.0f, 4.0f, 5.0f, 6.0f});
}
SLANG_UNIT_TEST(mutableRootShaderObjectD3D12)
{
- runTestImpl(mutableRootShaderObjectTestImpl, unitTestContext, Slang::RenderApiFlag::D3D12);
+ runTestImpl(mutableRootShaderObjectTestImpl, unitTestContext, DeviceType::D3D12, {});
}
/*SLANG_UNIT_TEST(mutableRootShaderObjectVulkan)
{
- runTestImpl(mutableRootShaderObjectTestImpl, unitTestContext, Slang::RenderApiFlag::Vulkan);
+ runTestImpl(mutableRootShaderObjectTestImpl, unitTestContext, DeviceType::Vulkan, {});
}*/
} // namespace gfx_test
+
+#endif \ No newline at end of file
diff --git a/tools/gfx-unit-test/root-shader-parameter.cpp b/tools/gfx-unit-test/root-shader-parameter.cpp
index a06a07ef5..8098a33d5 100644
--- a/tools/gfx-unit-test/root-shader-parameter.cpp
+++ b/tools/gfx-unit-test/root-shader-parameter.cpp
@@ -1,41 +1,38 @@
+// Duplicated: This test is identical slang-rhi\tests\test-root-shader-parameter.cpp
+
#include "core/slang-basic.h"
#include "gfx-test-util.h"
-#include "gfx-util/shader-cursor.h"
-#include "slang-gfx.h"
+#include "slang-rhi.h"
+#include "slang-rhi/shader-cursor.h"
#include "unit-test/slang-unit-test.h"
-using namespace gfx;
+using namespace rhi;
namespace gfx_test
{
-static ComPtr<IBufferResource> createBuffer(IDevice* device, uint32_t content)
+static ComPtr<IBuffer> createBuffer(IDevice* device, uint32_t content)
{
- ComPtr<IBufferResource> buffer;
- IBufferResource::Desc bufferDesc = {};
- bufferDesc.sizeInBytes = sizeof(uint32_t);
- bufferDesc.format = gfx::Format::Unknown;
+ ComPtr<IBuffer> buffer;
+ BufferDesc bufferDesc = {};
+ bufferDesc.size = sizeof(uint32_t);
+ bufferDesc.format = rhi::Format::Undefined;
bufferDesc.elementSize = sizeof(float);
- bufferDesc.allowedStates = ResourceStateSet(
- ResourceState::ShaderResource,
- ResourceState::UnorderedAccess,
- ResourceState::CopyDestination,
- ResourceState::CopySource);
+ bufferDesc.usage = BufferUsage::ShaderResource | BufferUsage::UnorderedAccess |
+ BufferUsage::CopyDestination | BufferUsage::CopySource;
bufferDesc.defaultState = ResourceState::UnorderedAccess;
bufferDesc.memoryType = MemoryType::DeviceLocal;
- ComPtr<IBufferResource> numbersBuffer;
- GFX_CHECK_CALL_ABORT(
- device->createBufferResource(bufferDesc, (void*)&content, buffer.writeRef()));
+ ComPtr<IBuffer> numbersBuffer;
+ GFX_CHECK_CALL_ABORT(device->createBuffer(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()));
+ if (!device->hasFeature(Feature::ParameterBlock))
+ {
+ SLANG_CHECK("no support for parameter blocks");
+ }
ComPtr<IShaderProgram> shaderProgram;
slang::ProgramLayout* slangReflection;
@@ -46,106 +43,84 @@ void rootShaderParameterTestImpl(IDevice* device, UnitTestContext* context)
"computeMain",
slangReflection));
- ComputePipelineStateDesc pipelineDesc = {};
+ ComputePipelineDesc pipelineDesc = {};
pipelineDesc.program = shaderProgram.get();
- ComPtr<gfx::IPipelineState> pipelineState;
- GFX_CHECK_CALL_ABORT(
- device->createComputePipelineState(pipelineDesc, pipelineState.writeRef()));
+ ComPtr<rhi::IComputePipeline> pipeline = device->createComputePipeline(pipelineDesc);
- Slang::List<ComPtr<IBufferResource>> buffers;
- Slang::List<ComPtr<IResourceView>> srvs, uavs;
+ Slang::List<ComPtr<IBuffer>> buffers;
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);
}
ComPtr<IShaderObject> rootObject;
- device->createMutableRootShaderObject(shaderProgram, rootObject.writeRef());
+ device->createRootShaderObject(shaderProgram, rootObject.writeRef());
ComPtr<IShaderObject> g, s1, s2;
- device->createMutableShaderObject(
+ device->createShaderObject(
slangReflection->findTypeByName("S0"),
ShaderObjectContainerType::None,
g.writeRef());
- device->createMutableShaderObject(
+ device->createShaderObject(
slangReflection->findTypeByName("S1"),
ShaderObjectContainerType::None,
s1.writeRef());
- device->createMutableShaderObject(
+ device->createShaderObject(
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]);
+ cursor["c0"].setBinding(buffers[2]);
+ cursor["c1"].setBinding(buffers[3]);
+ cursor["c2"].setBinding(buffers[4]);
}
{
auto cursor = ShaderCursor(s2);
- cursor["c0"].setResource(srvs[5]);
- cursor["c1"].setResource(uavs[6]);
- cursor["c2"].setResource(srvs[7]);
+ cursor["c0"].setBinding(buffers[5]);
+ cursor["c1"].setBinding(buffers[6]);
+ cursor["c2"].setBinding(buffers[7]);
}
{
auto cursor = ShaderCursor(g);
- cursor["b0"].setResource(srvs[0]);
- cursor["b1"].setResource(srvs[1]);
+ cursor["b0"].setBinding(buffers[0]);
+ cursor["b1"].setBinding(buffers[1]);
cursor["s1"].setObject(s1);
cursor["s2"].setObject(s2);
}
{
auto cursor = ShaderCursor(rootObject);
cursor["g"].setObject(g);
- cursor["buffer"].setResource(uavs[8]);
+ cursor["buffer"].setBinding(buffers[8]);
}
{
- ICommandQueue::Desc queueDesc = {ICommandQueue::QueueType::Graphics};
- auto queue = device->createCommandQueue(queueDesc);
+ auto queue = device->getQueue(QueueType::Graphics);
- auto commandBuffer = transientHeap->createCommandBuffer();
+ auto commandBuffer = queue->createCommandEncoder();
{
- auto encoder = commandBuffer->encodeComputeCommands();
- encoder->bindPipelineWithRootObject(pipelineState, rootObject);
+ auto encoder = commandBuffer->beginComputePass();
+ encoder->bindPipeline(pipeline, rootObject);
encoder->dispatchCompute(1, 1, 1);
- encoder->endEncoding();
+ encoder->end();
}
- commandBuffer->close();
- queue->executeCommandBuffer(commandBuffer);
+ queue->submit(commandBuffer->finish());
queue->waitOnHost();
}
- compareComputeResult(
- device,
- buffers[8],
- Slang::makeArray<uint32_t>(10 - 1 + 2 - 3 + 4 + 5 - 6 + 7));
+ compareComputeResult(device, buffers[8], std::array{10 - 1 + 2 - 3 + 4 + 5 - 6 + 7});
}
SLANG_UNIT_TEST(rootShaderParameterD3D12)
{
- runTestImpl(rootShaderParameterTestImpl, unitTestContext, Slang::RenderApiFlag::D3D12);
+ runTestImpl(rootShaderParameterTestImpl, unitTestContext, DeviceType::D3D12);
}
SLANG_UNIT_TEST(rootShaderParameterVulkan)
{
- runTestImpl(rootShaderParameterTestImpl, unitTestContext, Slang::RenderApiFlag::Vulkan);
+ runTestImpl(rootShaderParameterTestImpl, unitTestContext, DeviceType::Vulkan);
}
} // namespace gfx_test
diff --git a/tools/gfx-unit-test/sampler-array.cpp b/tools/gfx-unit-test/sampler-array.cpp
index 67efe0c32..6f43be08f 100644
--- a/tools/gfx-unit-test/sampler-array.cpp
+++ b/tools/gfx-unit-test/sampler-array.cpp
@@ -1,112 +1,83 @@
+// Duplicated: This test is identical to slang-rhi\tests\test-sampler-array.cpp
+
#include "core/slang-basic.h"
#include "gfx-test-util.h"
-#include "gfx-util/shader-cursor.h"
-#include "slang-gfx.h"
+#include "slang-rhi.h"
+#include "slang-rhi/shader-cursor.h"
#include "unit-test/slang-unit-test.h"
-using namespace gfx;
+using namespace rhi;
namespace gfx_test
{
-static ComPtr<IBufferResource> createBuffer(IDevice* device, uint32_t content)
+static ComPtr<IBuffer> createBuffer(IDevice* device, uint32_t content)
{
- ComPtr<IBufferResource> buffer;
- IBufferResource::Desc bufferDesc = {};
- bufferDesc.sizeInBytes = sizeof(uint32_t);
- bufferDesc.format = gfx::Format::Unknown;
+ ComPtr<IBuffer> buffer;
+ BufferDesc bufferDesc = {};
+ bufferDesc.size = sizeof(uint32_t);
+ bufferDesc.format = rhi::Format::Undefined;
bufferDesc.elementSize = sizeof(float);
- bufferDesc.allowedStates = ResourceStateSet(
- ResourceState::ShaderResource,
- ResourceState::UnorderedAccess,
- ResourceState::CopyDestination,
- ResourceState::CopySource);
+ bufferDesc.usage = BufferUsage::ShaderResource | BufferUsage::UnorderedAccess |
+ BufferUsage::CopyDestination | BufferUsage::CopySource;
bufferDesc.defaultState = ResourceState::UnorderedAccess;
bufferDesc.memoryType = MemoryType::DeviceLocal;
- ComPtr<IBufferResource> numbersBuffer;
- GFX_CHECK_CALL_ABORT(
- device->createBufferResource(bufferDesc, (void*)&content, buffer.writeRef()));
+ GFX_CHECK_CALL_ABORT(device->createBuffer(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 = {};
+ ComputePipelineDesc pipelineDesc = {};
pipelineDesc.program = shaderProgram.get();
- ComPtr<gfx::IPipelineState> pipelineState;
- GFX_CHECK_CALL_ABORT(
- device->createComputePipelineState(pipelineDesc, pipelineState.writeRef()));
+ ComPtr<IComputePipeline> pipeline;
+ GFX_CHECK_CALL_ABORT(device->createComputePipeline(pipelineDesc, pipeline.writeRef()));
- Slang::List<ComPtr<ISamplerState>> samplers;
- Slang::List<ComPtr<IResourceView>> srvs;
- ComPtr<IResourceView> uav;
- ComPtr<ITextureResource> texture;
- ComPtr<IBufferResource> buffer = createBuffer(device, 0);
+ Slang::List<ComPtr<ISampler>> samplers;
+ ComPtr<ITexture> texture;
+ ComPtr<IBuffer> buffer = createBuffer(device, 0);
{
- 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 textureDesc = {};
+ textureDesc.type = TextureType::Texture2D;
+ textureDesc.format = Format::RGBA8Unorm;
textureDesc.size.width = 2;
textureDesc.size.height = 2;
textureDesc.size.depth = 1;
- textureDesc.numMipLevels = 2;
+ textureDesc.mipCount = 2;
textureDesc.memoryType = MemoryType::DeviceLocal;
+ textureDesc.usage = TextureUsage::ShaderResource | TextureUsage::CopyDestination;
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}};
+ 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);
+ device->createTexture(textureDesc, subResourceData, texture.writeRef()));
}
for (uint32_t i = 0; i < 32; i++)
{
- ISamplerState::Desc desc = {};
- ComPtr<ISamplerState> sampler;
- GFX_CHECK_CALL_ABORT(device->createSamplerState(desc, sampler.writeRef()));
+ SamplerDesc desc = {};
+ ComPtr<ISampler> sampler;
+ GFX_CHECK_CALL_ABORT(device->createSampler(desc, sampler.writeRef()));
samplers.add(sampler);
}
ComPtr<IShaderObject> rootObject;
- device->createMutableRootShaderObject(shaderProgram, rootObject.writeRef());
+ device->createRootShaderObject(shaderProgram, rootObject.writeRef());
ComPtr<IShaderObject> g;
- device->createMutableShaderObject(
+ device->createShaderObject(
slangReflection->findTypeByName("S0"),
ShaderObjectContainerType::None,
g.writeRef());
ComPtr<IShaderObject> s1;
- device->createMutableShaderObject(
+ device->createShaderObject(
slangReflection->findTypeByName("S1"),
ShaderObjectContainerType::None,
s1.writeRef());
@@ -115,11 +86,12 @@ void samplerArrayTestImpl(IDevice* device, UnitTestContext* context)
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["samplers"][i].setBinding(Binding(samplers[i]));
+ cursor["tex"][i].setBinding(Binding(texture));
}
cursor["data"].setData(1.0f);
}
+ s1->finalize();
{
auto cursor = ShaderCursor(g);
@@ -130,31 +102,30 @@ void samplerArrayTestImpl(IDevice* device, UnitTestContext* context)
{
auto cursor = ShaderCursor(rootObject);
cursor["g"].setObject(g);
- cursor["buffer"].setResource(uav);
+ cursor["buffer"].setBinding(Binding(buffer));
}
+ g->finalize();
{
- 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 queue = device->getQueue(QueueType::Graphics);
+ auto commandEncoder = queue->createCommandEncoder();
+ auto passEncoder = commandEncoder->beginComputePass();
+ auto rootObject = passEncoder->bindPipeline(pipeline);
+ auto cursor = ShaderCursor(rootObject);
+ cursor["g"].setObject(g);
+ cursor["buffer"].setBinding(buffer);
+ passEncoder->dispatchCompute(1, 1, 1);
+ passEncoder->end();
- commandBuffer->close();
- queue->executeCommandBuffer(commandBuffer);
+ queue->submit(commandEncoder->finish());
queue->waitOnHost();
}
- compareComputeResult(device, buffer, Slang::makeArray<float>(4.0f));
+ compareComputeResult(device, buffer, std::array{4.0f});
}
SLANG_UNIT_TEST(samplerArrayVulkan)
{
- runTestImpl(samplerArrayTestImpl, unitTestContext, Slang::RenderApiFlag::Vulkan);
+ runTestImpl(samplerArrayTestImpl, unitTestContext, DeviceType::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 69767b3d2..ea914bd65 100644
--- a/tools/gfx-unit-test/shader-cache-tests.cpp
+++ b/tools/gfx-unit-test/shader-cache-tests.cpp
@@ -1,3 +1,8 @@
+#if 0
+// Duplicated: this is identical to slang-rhi\tests\test-shader-cache.cpp
+// This file uses gfx-specific shader cache functionality (IShaderCache)
+// that has been replaced with a different caching system (IPersistentCache) in slang-rhi.
+
#include "core/slang-basic.h"
#include "core/slang-file-system.h"
#include "core/slang-io.h"
@@ -5,8 +10,8 @@
#include "core/slang-string-util.h"
#include "gfx-test-texture-util.h"
#include "gfx-test-util.h"
-#include "gfx-util/shader-cursor.h"
#include "slang-gfx.h"
+#include "slang-rhi/shader-cursor.h"
#include "unit-test/slang-unit-test.h"
using namespace gfx;
@@ -1128,3 +1133,5 @@ SLANG_UNIT_TEST(shaderCacheGraphicsSplitVulkan)
runTest<ShaderCacheTestGraphicsSplit>(unitTestContext, Slang::RenderApiFlag::Vulkan);
}
} // namespace gfx_test
+
+#endif
diff --git a/tools/gfx-unit-test/shared-buffers-tests.cpp b/tools/gfx-unit-test/shared-buffers-tests.cpp
index dbb0be3be..357400e2a 100644
--- a/tools/gfx-unit-test/shared-buffers-tests.cpp
+++ b/tools/gfx-unit-test/shared-buffers-tests.cpp
@@ -1,10 +1,10 @@
#include "core/slang-basic.h"
#include "gfx-test-util.h"
-#include "gfx-util/shader-cursor.h"
-#include "slang-gfx.h"
+#include "slang-rhi.h"
+#include "slang-rhi/shader-cursor.h"
#include "unit-test/slang-unit-test.h"
-using namespace gfx;
+using namespace rhi;
namespace gfx_test
{
@@ -14,47 +14,37 @@ void sharedBufferTestImpl(IDevice* srcDevice, IDevice* dstDevice, UnitTestContex
// 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 bufferDesc = {};
+ bufferDesc.size = numberCount * sizeof(float);
+ bufferDesc.format = rhi::Format::Undefined;
bufferDesc.elementSize = sizeof(float);
- bufferDesc.allowedStates = ResourceStateSet(
- ResourceState::ShaderResource,
- ResourceState::UnorderedAccess,
- ResourceState::CopyDestination,
- ResourceState::CopySource);
+ bufferDesc.usage = BufferUsage::ShaderResource | BufferUsage::UnorderedAccess |
+ BufferUsage::CopySource | BufferUsage::CopyDestination | BufferUsage::Shared;
bufferDesc.defaultState = ResourceState::UnorderedAccess;
bufferDesc.memoryType = MemoryType::DeviceLocal;
- bufferDesc.isShared = true;
- ComPtr<IBufferResource> srcBuffer;
+ ComPtr<IBuffer> srcBuffer;
GFX_CHECK_CALL_ABORT(
- srcDevice->createBufferResource(bufferDesc, (void*)initialData, srcBuffer.writeRef()));
+ srcDevice->createBuffer(bufferDesc, (void*)initialData, srcBuffer.writeRef()));
- InteropHandle sharedHandle;
+ NativeHandle sharedHandle;
GFX_CHECK_CALL_ABORT(srcBuffer->getSharedHandle(&sharedHandle));
- ComPtr<IBufferResource> dstBuffer;
+ ComPtr<IBuffer> 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));
+ compareComputeResult(srcDevice, srcBuffer, std::array{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));
+ NativeHandle testHandle;
+ GFX_CHECK_CALL_ABORT(dstBuffer->getNativeHandle(&testHandle));
+ const BufferDesc& testDesc = dstBuffer->getDesc();
+ SLANG_CHECK(testDesc.elementSize == sizeof(float));
+ SLANG_CHECK(testDesc.size == numberCount * sizeof(float));
+ compareComputeResult(dstDevice, dstBuffer, std::array{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(
@@ -64,46 +54,31 @@ void sharedBufferTestImpl(IDevice* srcDevice, IDevice* dstDevice, UnitTestContex
"computeMain",
slangReflection));
- ComputePipelineStateDesc pipelineDesc = {};
+ ComputePipelineDesc 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);
+ ComPtr<IComputePipeline> pipelineState;
+ GFX_CHECK_CALL_ABORT(dstDevice->createComputePipeline(pipelineDesc, pipelineState.writeRef()));
- auto commandBuffer = transientHeap->createCommandBuffer();
- auto encoder = commandBuffer->encodeComputeCommands();
+ auto queue = dstDevice->getQueue(QueueType::Graphics);
+ auto commandEncoder = queue->createCommandEncoder();
+ auto computePassEncoder = commandEncoder->beginComputePass();
- auto rootObject = encoder->bindPipeline(pipelineState);
+ auto rootObject = computePassEncoder->bindPipeline(pipelineState);
- ShaderCursor rootCursor(rootObject);
- // Bind buffer view to the entry point.
- rootCursor.getPath("buffer").setResource(bufferView);
+ ShaderCursor rootCursor(rootObject);
+ // Bind buffer to the entry point.
+ rootCursor.getPath("buffer").setBinding(Binding(dstBuffer));
- encoder->dispatchCompute(1, 1, 1);
- encoder->endEncoding();
- commandBuffer->close();
- queue->executeCommandBuffer(commandBuffer);
- queue->waitOnHost();
- }
+ computePassEncoder->dispatchCompute(1, 1, 1);
+ computePassEncoder->end();
+ auto commandBuffer = commandEncoder->finish();
+ queue->submit(commandBuffer);
+ queue->waitOnHost();
- compareComputeResult(dstDevice, dstBuffer, Slang::makeArray<float>(1.0f, 2.0f, 3.0f, 4.0f));
+ compareComputeResult(dstDevice, dstBuffer, std::array{1.0f, 2.0f, 3.0f, 4.0f});
}
-void sharedBufferTestAPI(
- UnitTestContext* context,
- Slang::RenderApiFlag::Enum srcApi,
- Slang::RenderApiFlag::Enum dstApi)
+void sharedBufferTestAPI(UnitTestContext* context, DeviceType srcApi, DeviceType dstApi)
{
auto srcDevice = createTestingDevice(context, srcApi);
auto dstDevice = createTestingDevice(context, dstApi);
@@ -117,12 +92,12 @@ void sharedBufferTestAPI(
#if SLANG_WIN64
SLANG_UNIT_TEST(sharedBufferD3D12ToCUDA)
{
- sharedBufferTestAPI(unitTestContext, Slang::RenderApiFlag::D3D12, Slang::RenderApiFlag::CUDA);
+ sharedBufferTestAPI(unitTestContext, DeviceType::D3D12, DeviceType::CUDA);
}
SLANG_UNIT_TEST(sharedBufferVulkanToCUDA)
{
- sharedBufferTestAPI(unitTestContext, Slang::RenderApiFlag::Vulkan, Slang::RenderApiFlag::CUDA);
+ sharedBufferTestAPI(unitTestContext, DeviceType::Vulkan, DeviceType::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 f017c959e..7a1007489 100644
--- a/tools/gfx-unit-test/shared-textures-tests.cpp
+++ b/tools/gfx-unit-test/shared-textures-tests.cpp
@@ -1,7 +1,10 @@
+#if 0
+// Duplicated: This is identical to slang-rhi\tests\test-texture-shared.cpp
+
#include "core/slang-basic.h"
#include "gfx-test-util.h"
-#include "gfx-util/shader-cursor.h"
#include "slang-gfx.h"
+#include "slang-rhi/shader-cursor.h"
#include "unit-test/slang-unit-test.h"
using namespace gfx;
@@ -259,3 +262,5 @@ SLANG_UNIT_TEST(sharedTextureVulkanToCUDA)
}
#endif
} // namespace gfx_test
+
+#endif \ No newline at end of file
diff --git a/tools/gfx-unit-test/span.h b/tools/gfx-unit-test/span.h
new file mode 100644
index 000000000..1a010462d
--- /dev/null
+++ b/tools/gfx-unit-test/span.h
@@ -0,0 +1,643 @@
+/*
+This is an implementation of C++20's std::span
+http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/n4820.pdf
+*/
+
+// Copyright Tristan Brindle 2018.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file ../../LICENSE_1_0.txt or copy at
+// https://www.boost.org/LICENSE_1_0.txt)
+
+#pragma once
+
+#include <array>
+#include <cstddef>
+#include <cstdint>
+#include <type_traits>
+
+#ifndef TCB_SPAN_NO_EXCEPTIONS
+// Attempt to discover whether we're being compiled with exception support
+#if !(defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND))
+#define TCB_SPAN_NO_EXCEPTIONS
+#endif
+#endif
+
+#ifndef TCB_SPAN_NO_EXCEPTIONS
+#include <cstdio>
+#include <stdexcept>
+#endif
+
+// Various feature test macros
+
+#ifndef TCB_SPAN_NAMESPACE_NAME
+#define TCB_SPAN_NAMESPACE_NAME rhi
+#endif
+
+#if __cplusplus >= 201703L || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L)
+#define TCB_SPAN_HAVE_CPP17
+#endif
+
+#if __cplusplus >= 201402L || (defined(_MSVC_LANG) && _MSVC_LANG >= 201402L)
+#define TCB_SPAN_HAVE_CPP14
+#endif
+
+namespace TCB_SPAN_NAMESPACE_NAME
+{
+
+// Establish default contract checking behavior
+#if !defined(TCB_SPAN_THROW_ON_CONTRACT_VIOLATION) && \
+ !defined(TCB_SPAN_TERMINATE_ON_CONTRACT_VIOLATION) && !defined(TCB_SPAN_NO_CONTRACT_CHECKING)
+#if defined(NDEBUG) || !defined(TCB_SPAN_HAVE_CPP14)
+#define TCB_SPAN_NO_CONTRACT_CHECKING
+#else
+#define TCB_SPAN_TERMINATE_ON_CONTRACT_VIOLATION
+#endif
+#endif
+
+#if defined(TCB_SPAN_THROW_ON_CONTRACT_VIOLATION)
+struct contract_violation_error : std::logic_error
+{
+ explicit contract_violation_error(const char* msg)
+ : std::logic_error(msg)
+ {
+ }
+};
+
+inline void contract_violation(const char* msg)
+{
+ throw contract_violation_error(msg);
+}
+
+#elif defined(TCB_SPAN_TERMINATE_ON_CONTRACT_VIOLATION)
+[[noreturn]] inline void contract_violation(const char* /*unused*/)
+{
+ std::terminate();
+}
+#endif
+
+#if !defined(TCB_SPAN_NO_CONTRACT_CHECKING)
+#define TCB_SPAN_STRINGIFY(cond) #cond
+#define TCB_SPAN_EXPECT(cond) \
+ cond ? (void)0 : contract_violation("Expected " TCB_SPAN_STRINGIFY(cond))
+#else
+#define TCB_SPAN_EXPECT(cond)
+#endif
+
+#if defined(TCB_SPAN_HAVE_CPP17) || defined(__cpp_inline_variables)
+#define TCB_SPAN_INLINE_VAR inline
+#else
+#define TCB_SPAN_INLINE_VAR
+#endif
+
+#if defined(TCB_SPAN_HAVE_CPP14) || (defined(__cpp_constexpr) && __cpp_constexpr >= 201304)
+#define TCB_SPAN_HAVE_CPP14_CONSTEXPR
+#endif
+
+#if defined(TCB_SPAN_HAVE_CPP14_CONSTEXPR)
+#define TCB_SPAN_CONSTEXPR14 constexpr
+#else
+#define TCB_SPAN_CONSTEXPR14
+#endif
+
+#if defined(TCB_SPAN_HAVE_CPP14_CONSTEXPR) && (!defined(_MSC_VER) || _MSC_VER > 1900)
+#define TCB_SPAN_CONSTEXPR_ASSIGN constexpr
+#else
+#define TCB_SPAN_CONSTEXPR_ASSIGN
+#endif
+
+#if defined(TCB_SPAN_NO_CONTRACT_CHECKING)
+#define TCB_SPAN_CONSTEXPR11 constexpr
+#else
+#define TCB_SPAN_CONSTEXPR11 TCB_SPAN_CONSTEXPR14
+#endif
+
+#if defined(TCB_SPAN_HAVE_CPP17) || defined(__cpp_deduction_guides)
+#define TCB_SPAN_HAVE_DEDUCTION_GUIDES
+#endif
+
+#if defined(TCB_SPAN_HAVE_CPP17) || defined(__cpp_lib_byte)
+#define TCB_SPAN_HAVE_STD_BYTE
+#endif
+
+#if defined(TCB_SPAN_HAVE_CPP17) || defined(__cpp_lib_array_constexpr)
+#define TCB_SPAN_HAVE_CONSTEXPR_STD_ARRAY_ETC
+#endif
+
+#if defined(TCB_SPAN_HAVE_CONSTEXPR_STD_ARRAY_ETC)
+#define TCB_SPAN_ARRAY_CONSTEXPR constexpr
+#else
+#define TCB_SPAN_ARRAY_CONSTEXPR
+#endif
+
+#ifdef TCB_SPAN_HAVE_STD_BYTE
+using slang_byte = std::byte;
+#else
+using slang_byte = unsigned char;
+#endif
+
+#if defined(TCB_SPAN_HAVE_CPP17)
+#define TCB_SPAN_NODISCARD [[nodiscard]]
+#else
+#define TCB_SPAN_NODISCARD
+#endif
+
+TCB_SPAN_INLINE_VAR constexpr std::size_t dynamic_extent = SIZE_MAX;
+
+template<typename ElementType, std::size_t Extent = dynamic_extent>
+class span;
+
+namespace detail
+{
+
+template<typename E, std::size_t S>
+struct span_storage
+{
+ constexpr span_storage() noexcept = default;
+
+ constexpr span_storage(E* p_ptr, std::size_t /*unused*/) noexcept
+ : ptr(p_ptr)
+ {
+ }
+
+ E* ptr = nullptr;
+ static constexpr std::size_t size = S;
+};
+
+template<typename E>
+struct span_storage<E, dynamic_extent>
+{
+ constexpr span_storage() noexcept = default;
+
+ constexpr span_storage(E* p_ptr, std::size_t p_size) noexcept
+ : ptr(p_ptr), size(p_size)
+ {
+ }
+
+ E* ptr = nullptr;
+ std::size_t size = 0;
+};
+
+// Reimplementation of C++17 std::size() and std::data()
+#if defined(TCB_SPAN_HAVE_CPP17) || defined(__cpp_lib_nonmember_container_access)
+using std::data;
+using std::size;
+#else
+template<class C>
+constexpr auto size(const C& c) -> decltype(c.size())
+{
+ return c.size();
+}
+
+template<class T, std::size_t N>
+constexpr std::size_t size(const T (&)[N]) noexcept
+{
+ return N;
+}
+
+template<class C>
+constexpr auto data(C& c) -> decltype(c.data())
+{
+ return c.data();
+}
+
+template<class C>
+constexpr auto data(const C& c) -> decltype(c.data())
+{
+ return c.data();
+}
+
+template<class T, std::size_t N>
+constexpr T* data(T (&array)[N]) noexcept
+{
+ return array;
+}
+
+template<class E>
+constexpr const E* data(std::initializer_list<E> il) noexcept
+{
+ return il.begin();
+}
+#endif // TCB_SPAN_HAVE_CPP17
+
+#if defined(TCB_SPAN_HAVE_CPP17) || defined(__cpp_lib_void_t)
+using std::void_t;
+#else
+template<typename...>
+using void_t = void;
+#endif
+
+template<typename T>
+using uncvref_t = typename std::remove_cv<typename std::remove_reference<T>::type>::type;
+
+template<typename>
+struct is_span : std::false_type
+{
+};
+
+template<typename T, std::size_t S>
+struct is_span<span<T, S>> : std::true_type
+{
+};
+
+template<typename>
+struct is_std_array : std::false_type
+{
+};
+
+template<typename T, std::size_t N>
+struct is_std_array<std::array<T, N>> : std::true_type
+{
+};
+
+template<typename, typename = void>
+struct has_size_and_data : std::false_type
+{
+};
+
+template<typename T>
+struct has_size_and_data<
+ T,
+ void_t<decltype(detail::size(std::declval<T>())), decltype(detail::data(std::declval<T>()))>>
+ : std::true_type
+{
+};
+
+template<typename C, typename U = uncvref_t<C>>
+struct is_container
+{
+ static constexpr bool value = !is_span<U>::value && !is_std_array<U>::value &&
+ !std::is_array<U>::value && has_size_and_data<C>::value;
+};
+
+template<typename T>
+using remove_pointer_t = typename std::remove_pointer<T>::type;
+
+template<typename, typename, typename = void>
+struct is_container_element_type_compatible : std::false_type
+{
+};
+
+template<typename T, typename E>
+struct is_container_element_type_compatible<
+ T,
+ E,
+ typename std::enable_if<
+ !std::is_same<
+ typename std::remove_cv<decltype(detail::data(std::declval<T>()))>::type,
+ void>::value &&
+ std::is_convertible<
+ remove_pointer_t<decltype(detail::data(std::declval<T>()))> (*)[],
+ E (*)[]>::value>::type> : std::true_type
+{
+};
+
+template<typename, typename = size_t>
+struct is_complete : std::false_type
+{
+};
+
+template<typename T>
+struct is_complete<T, decltype(sizeof(T))> : std::true_type
+{
+};
+
+} // namespace detail
+
+template<typename ElementType, std::size_t Extent>
+class span
+{
+ static_assert(
+ std::is_object<ElementType>::value,
+ "A span's ElementType must be an object type (not a "
+ "reference type or void)");
+ static_assert(
+ detail::is_complete<ElementType>::value,
+ "A span's ElementType must be a complete type (not a forward "
+ "declaration)");
+ static_assert(
+ !std::is_abstract<ElementType>::value,
+ "A span's ElementType cannot be an abstract class type");
+
+ using storage_type = detail::span_storage<ElementType, Extent>;
+
+public:
+ // constants and types
+ using element_type = ElementType;
+ using value_type = typename std::remove_cv<ElementType>::type;
+ using size_type = std::size_t;
+ using difference_type = std::ptrdiff_t;
+ using pointer = element_type*;
+ using const_pointer = const element_type*;
+ using reference = element_type&;
+ using const_reference = const element_type&;
+ using iterator = pointer;
+ using reverse_iterator = std::reverse_iterator<iterator>;
+
+ static constexpr size_type extent = Extent;
+
+ // [span.cons], span constructors, copy, assignment, and destructor
+ template<
+ std::size_t E = Extent,
+ typename std::enable_if<(E == dynamic_extent || E <= 0), int>::type = 0>
+ constexpr span() noexcept
+ {
+ }
+
+ TCB_SPAN_CONSTEXPR11 span(pointer ptr, size_type count)
+ : storage_(ptr, count)
+ {
+ TCB_SPAN_EXPECT(extent == dynamic_extent || count == extent);
+ }
+
+ TCB_SPAN_CONSTEXPR11 span(pointer first_elem, pointer last_elem)
+ : storage_(first_elem, last_elem - first_elem)
+ {
+ TCB_SPAN_EXPECT(
+ extent == dynamic_extent ||
+ last_elem - first_elem == static_cast<std::ptrdiff_t>(extent));
+ }
+
+ template<
+ std::size_t N,
+ std::size_t E = Extent,
+ typename std::enable_if<
+ (E == dynamic_extent || N == E) &&
+ detail::is_container_element_type_compatible<element_type (&)[N], ElementType>::
+ value,
+ int>::type = 0>
+ constexpr span(element_type (&arr)[N]) noexcept
+ : storage_(arr, N)
+ {
+ }
+
+ template<
+ typename T,
+ std::size_t N,
+ std::size_t E = Extent,
+ typename std::enable_if<
+ (E == dynamic_extent || N == E) &&
+ detail::is_container_element_type_compatible<std::array<T, N>&, ElementType>::value,
+ int>::type = 0>
+ TCB_SPAN_ARRAY_CONSTEXPR span(std::array<T, N>& arr) noexcept
+ : storage_(arr.data(), N)
+ {
+ }
+
+ template<
+ typename T,
+ std::size_t N,
+ std::size_t E = Extent,
+ typename std::enable_if<
+ (E == dynamic_extent || N == E) &&
+ detail::is_container_element_type_compatible<const std::array<T, N>&, ElementType>::
+ value,
+ int>::type = 0>
+ TCB_SPAN_ARRAY_CONSTEXPR span(const std::array<T, N>& arr) noexcept
+ : storage_(arr.data(), N)
+ {
+ }
+
+ template<
+ typename Container,
+ std::size_t E = Extent,
+ typename std::enable_if<
+ E == dynamic_extent && detail::is_container<Container>::value &&
+ detail::is_container_element_type_compatible<Container&, ElementType>::value,
+ int>::type = 0>
+ constexpr span(Container& cont)
+ : storage_(detail::data(cont), detail::size(cont))
+ {
+ }
+
+ template<
+ typename Container,
+ std::size_t E = Extent,
+ typename std::enable_if<
+ E == dynamic_extent && detail::is_container<Container>::value &&
+ detail::is_container_element_type_compatible<const Container&, ElementType>::value,
+ int>::type = 0>
+ constexpr span(const Container& cont)
+ : storage_(detail::data(cont), detail::size(cont))
+ {
+ }
+
+ constexpr span(const span& other) noexcept = default;
+
+ template<
+ typename OtherElementType,
+ std::size_t OtherExtent,
+ typename std::enable_if<
+ (Extent == dynamic_extent || OtherExtent == dynamic_extent || Extent == OtherExtent) &&
+ std::is_convertible<OtherElementType (*)[], ElementType (*)[]>::value,
+ int>::type = 0>
+ constexpr span(const span<OtherElementType, OtherExtent>& other) noexcept
+ : storage_(other.data(), other.size())
+ {
+ }
+
+ ~span() noexcept = default;
+
+ TCB_SPAN_CONSTEXPR_ASSIGN span& operator=(const span& other) noexcept = default;
+
+ // [span.sub], span subviews
+ template<std::size_t Count>
+ TCB_SPAN_CONSTEXPR11 span<element_type, Count> first() const
+ {
+ TCB_SPAN_EXPECT(Count <= size());
+ return {data(), Count};
+ }
+
+ template<std::size_t Count>
+ TCB_SPAN_CONSTEXPR11 span<element_type, Count> last() const
+ {
+ TCB_SPAN_EXPECT(Count <= size());
+ return {data() + (size() - Count), Count};
+ }
+
+ template<std::size_t Offset, std::size_t Count = dynamic_extent>
+ using subspan_return_t = span<
+ ElementType,
+ Count != dynamic_extent ? Count
+ : (Extent != dynamic_extent ? Extent - Offset : dynamic_extent)>;
+
+ template<std::size_t Offset, std::size_t Count = dynamic_extent>
+ TCB_SPAN_CONSTEXPR11 subspan_return_t<Offset, Count> subspan() const
+ {
+ TCB_SPAN_EXPECT(Offset <= size() && (Count == dynamic_extent || Offset + Count <= size()));
+ return {data() + Offset, Count != dynamic_extent ? Count : size() - Offset};
+ }
+
+ TCB_SPAN_CONSTEXPR11 span<element_type, dynamic_extent> first(size_type count) const
+ {
+ TCB_SPAN_EXPECT(count <= size());
+ return {data(), count};
+ }
+
+ TCB_SPAN_CONSTEXPR11 span<element_type, dynamic_extent> last(size_type count) const
+ {
+ TCB_SPAN_EXPECT(count <= size());
+ return {data() + (size() - count), count};
+ }
+
+ TCB_SPAN_CONSTEXPR11 span<element_type, dynamic_extent> subspan(
+ size_type offset,
+ size_type count = dynamic_extent) const
+ {
+ TCB_SPAN_EXPECT(offset <= size() && (count == dynamic_extent || offset + count <= size()));
+ return {data() + offset, count == dynamic_extent ? size() - offset : count};
+ }
+
+ // [span.obs], span observers
+ constexpr size_type size() const noexcept { return storage_.size; }
+
+ constexpr size_type size_bytes() const noexcept { return size() * sizeof(element_type); }
+
+ TCB_SPAN_NODISCARD constexpr bool empty() const noexcept { return size() == 0; }
+
+ // [span.elem], span element access
+ TCB_SPAN_CONSTEXPR11 reference operator[](size_type idx) const
+ {
+ TCB_SPAN_EXPECT(idx < size());
+ return *(data() + idx);
+ }
+
+ TCB_SPAN_CONSTEXPR11 reference front() const
+ {
+ TCB_SPAN_EXPECT(!empty());
+ return *data();
+ }
+
+ TCB_SPAN_CONSTEXPR11 reference back() const
+ {
+ TCB_SPAN_EXPECT(!empty());
+ return *(data() + (size() - 1));
+ }
+
+ constexpr pointer data() const noexcept { return storage_.ptr; }
+
+ // [span.iterators], span iterator support
+ constexpr iterator begin() const noexcept { return data(); }
+
+ constexpr iterator end() const noexcept { return data() + size(); }
+
+ TCB_SPAN_ARRAY_CONSTEXPR reverse_iterator rbegin() const noexcept
+ {
+ return reverse_iterator(end());
+ }
+
+ TCB_SPAN_ARRAY_CONSTEXPR reverse_iterator rend() const noexcept
+ {
+ return reverse_iterator(begin());
+ }
+
+private:
+ storage_type storage_{};
+};
+
+#ifdef TCB_SPAN_HAVE_DEDUCTION_GUIDES
+
+/* Deduction Guides */
+template<class T, size_t N>
+span(T (&)[N]) -> span<T, N>;
+
+template<class T, size_t N>
+span(std::array<T, N>&) -> span<T, N>;
+
+template<class T, size_t N>
+span(const std::array<T, N>&) -> span<const T, N>;
+
+template<class Container>
+span(Container&) -> span<
+ typename std::remove_reference<decltype(*detail::data(std::declval<Container&>()))>::type>;
+
+template<class Container>
+span(const Container&) -> span<const typename Container::value_type>;
+
+#endif // TCB_HAVE_DEDUCTION_GUIDES
+
+template<typename ElementType, std::size_t Extent>
+constexpr span<ElementType, Extent> make_span(span<ElementType, Extent> s) noexcept
+{
+ return s;
+}
+
+template<typename T, std::size_t N>
+constexpr span<T, N> make_span(T (&arr)[N]) noexcept
+{
+ return {arr};
+}
+
+template<typename T, std::size_t N>
+TCB_SPAN_ARRAY_CONSTEXPR span<T, N> make_span(std::array<T, N>& arr) noexcept
+{
+ return {arr};
+}
+
+template<typename T, std::size_t N>
+TCB_SPAN_ARRAY_CONSTEXPR span<const T, N> make_span(const std::array<T, N>& arr) noexcept
+{
+ return {arr};
+}
+
+template<typename Container>
+constexpr span<
+ typename std::remove_reference<decltype(*detail::data(std::declval<Container&>()))>::type>
+make_span(Container& cont)
+{
+ return {cont};
+}
+
+template<typename Container>
+constexpr span<const typename Container::value_type> make_span(const Container& cont)
+{
+ return {cont};
+}
+
+template<typename ElementType, std::size_t Extent>
+span<const slang_byte, ((Extent == dynamic_extent) ? dynamic_extent : sizeof(ElementType) * Extent)>
+as_bytes(span<ElementType, Extent> s) noexcept
+{
+ return {reinterpret_cast<const slang_byte*>(s.data()), s.size_bytes()};
+}
+
+template<
+ class ElementType,
+ size_t Extent,
+ typename std::enable_if<!std::is_const<ElementType>::value, int>::type = 0>
+span<slang_byte, ((Extent == dynamic_extent) ? dynamic_extent : sizeof(ElementType) * Extent)>
+as_writable_bytes(span<ElementType, Extent> s) noexcept
+{
+ return {reinterpret_cast<slang_byte*>(s.data()), s.size_bytes()};
+}
+
+template<std::size_t N, typename E, std::size_t S>
+constexpr auto get(span<E, S> s) -> decltype(s[N])
+{
+ return s[N];
+}
+
+} // namespace TCB_SPAN_NAMESPACE_NAME
+
+namespace std
+{
+
+template<typename ElementType, size_t Extent>
+class tuple_size<TCB_SPAN_NAMESPACE_NAME::span<ElementType, Extent>>
+ : public integral_constant<size_t, Extent>
+{
+};
+
+template<typename ElementType>
+class tuple_size<
+ TCB_SPAN_NAMESPACE_NAME::span<ElementType, TCB_SPAN_NAMESPACE_NAME::dynamic_extent>>; // not
+ // defined
+
+template<size_t I, typename ElementType, size_t Extent>
+class tuple_element<I, TCB_SPAN_NAMESPACE_NAME::span<ElementType, Extent>>
+{
+public:
+ static_assert(Extent != TCB_SPAN_NAMESPACE_NAME::dynamic_extent && I < Extent, "");
+ using type = ElementType;
+};
+
+} // end namespace std
diff --git a/tools/gfx-unit-test/swap-chain-resize-test.cpp b/tools/gfx-unit-test/swap-chain-resize-test.cpp
index 23f39fd8a..c12c856b7 100644
--- a/tools/gfx-unit-test/swap-chain-resize-test.cpp
+++ b/tools/gfx-unit-test/swap-chain-resize-test.cpp
@@ -1,12 +1,15 @@
-#include "core/slang-basic.h"
+#if 0
+
+// Duplicated: This test is similar to slang-rhi\tests\test-surface.cpp
+
#include "gfx-test-util.h"
-#include "gfx-util/shader-cursor.h"
#include "platform/window.h"
-#include "slang-gfx.h"
#include "unit-test/slang-unit-test.h"
-using namespace gfx;
-using namespace Slang;
+#include <slang-rhi.h>
+#include <slang-rhi/shader-cursor.h>
+
+using namespace rhi;
namespace gfx_test
{
@@ -17,7 +20,6 @@ struct Vertex
static const int kVertexCount = 3;
static const Vertex kVertexData[kVertexCount] = {
- // Triangle 1
{0, 0, 1},
{4, 0, 1},
{0, 4, 1},
@@ -28,22 +30,22 @@ struct SwapchainResizeTest
IDevice* device;
UnitTestContext* context;
- RefPtr<platform::Window> window;
+ ComPtr<platform::Window> window;
ComPtr<ICommandQueue> queue;
- ComPtr<ISwapchain> swapchain;
+ ComPtr<ISurface> surface;
- ComPtr<ITransientResourceHeap> transientHeap;
- ComPtr<gfx::IFramebufferLayout> framebufferLayout;
- ComPtr<IPipelineState> pipelineState;
- ComPtr<IRenderPassLayout> renderPass;
- List<ComPtr<IFramebuffer>> framebuffers;
+ ComPtr<ITexture> swapchainImages[2];
+ uint32_t swapchainImageCount = 2;
+ Format desiredFormat = Format::RGBA8Unorm;
- ComPtr<IBufferResource> vertexBuffer;
+ ComPtr<IBuffer> vertexBuffer;
+ ComPtr<IInputLayout> inputLayout;
+ ComPtr<IRenderPipeline> pipeline;
+ ComPtr<IShaderProgram> shaderProgram;
+ ComPtr<IShaderObject> rootShaderObject;
- GfxCount width = 500;
- GfxCount height = 500;
- static const int kSwapchainImageCount = 2;
- const Format desiredFormat = Format::R8G8B8A8_UNORM;
+ uint32_t width = 500;
+ uint32_t height = 500;
void init(IDevice* device, UnitTestContext* context)
{
@@ -51,38 +53,10 @@ struct SwapchainResizeTest
this->context = context;
}
- 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 createRequiredResources()
+ void createSwapchainAndResources()
{
+ // Create window
platform::Application::init();
-
platform::WindowDesc windowDesc;
windowDesc.title = "";
windowDesc.width = width;
@@ -90,140 +64,141 @@ struct SwapchainResizeTest
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;
- }
+ // Create surface
+ WindowHandle windowHandle = WindowHandle::fromHwnd((void*)window->getNativeHandle().handleValues[0]);
+ surface = device->createSurface(windowHandle);
+
+ // Configure surface (swapchain)
+ SurfaceConfig config = {};
+ config.format = desiredFormat;
+ config.width = width;
+ config.height = height;
+ config.desiredImageCount = swapchainImageCount;
+ config.vsync = true;
+ surface->configure(config);
+
+ // Create vertex buffer
+ BufferDesc vertexBufferDesc = {};
+ vertexBufferDesc.size = sizeof(Vertex) * kVertexCount;
+ vertexBufferDesc.memoryType = MemoryType::DeviceLocal;
+ vertexBufferDesc.usage = BufferUsage::VertexBuffer;
+ vertexBufferDesc.defaultState = ResourceState::VertexBuffer;
+ vertexBuffer = device->createBuffer(vertexBufferDesc, kVertexData);
+ // Input layout
+ InputElementDesc inputElements[] = {
+ {"POSITIONA", 0, Format::RGB32Float, offsetof(Vertex, position), 0},
+ };
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 inputLayoutDesc = {};
+ inputLayoutDesc.inputElementCount = sizeof(inputElements) / sizeof(InputElementDesc);
inputLayoutDesc.inputElements = inputElements;
- inputLayoutDesc.vertexStreamCount = SLANG_COUNT_OF(vertexStreams);
+ inputLayoutDesc.vertexStreamCount = sizeof(vertexStreams) / sizeof(VertexStreamDesc);;
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()));
+ GFX_CHECK_CALL_ABORT(device->createInputLayout(inputLayoutDesc, inputLayout.writeRef()));
ComPtr<IShaderProgram> shaderProgram;
- slang::ProgramLayout* slangReflection;
+ slang::ProgramLayout* slangReflection = nullptr;
GFX_CHECK_CALL_ABORT(loadGraphicsProgram(
device,
shaderProgram,
"swapchain-shader",
"vertexMain",
"fragmentMain",
- slangReflection));
-
- IFramebufferLayout::TargetLayout targetLayout;
- targetLayout.format = swapchain->getDesc().format;
- targetLayout.sampleCount = 1;
+ slangReflection
+ ));
- IFramebufferLayout::Desc framebufferLayoutDesc;
- framebufferLayoutDesc.renderTargetCount = 1;
- framebufferLayoutDesc.renderTargets = &targetLayout;
- framebufferLayout = device->createFramebufferLayout(framebufferLayoutDesc);
- SLANG_CHECK_ABORT(framebufferLayout != nullptr);
- GraphicsPipelineStateDesc pipelineDesc = {};
+ // Pipeline
+ ColorTargetDesc colorTarget = {};
+ colorTarget.format = desiredFormat;
+ RenderPipelineDesc 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();
+ pipelineDesc.inputLayout = inputLayout.get();
+ pipelineDesc.primitiveTopology = PrimitiveTopology::TriangleList;
+ pipelineDesc.targets = &colorTarget;
+ pipelineDesc.targetCount = 1;
+ pipeline = device->createRenderPipeline(pipelineDesc);
}
- 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();
+ void renderFrame(uint32_t imageIndex)
+ {
+ // Acquire next image
+ ComPtr<ITexture> backBuffer;
+ if (SLANG_FAILED(surface->acquireNextImage(backBuffer.writeRef())))
+ {
+ return;
+ }
+
+ // Create command encoder
+ ComPtr<ICommandQueue> queue = device->getQueue(QueueType::Graphics);
+ ComPtr<ICommandEncoder> encoder = queue->createCommandEncoder();
+
+ // Render pass setup
+ RenderPassColorAttachment colorAttachment = {};
+ colorAttachment.view = backBuffer->getDefaultView();
+ colorAttachment.loadOp = LoadOp::Clear;
+ colorAttachment.storeOp = StoreOp::Store;
+ float clearColor[4] = {0.2f, 0.2f, 0.2f, 1.0f};
+ memcpy(colorAttachment.clearValue, clearColor, sizeof(clearColor));
+ RenderPassDesc passDesc = {};
+ passDesc.colorAttachments = &colorAttachment;
+ passDesc.colorAttachmentCount = 1;
+
+ // Begin render pass
+ auto pass = encoder->beginRenderPass(passDesc);
+
+ // Bind pipeline and root object
+ pass->bindPipeline(pipeline, rootShaderObject);
+
+ // Set render state
+ RenderState state = {};
+ state.vertexBuffers[0] = BufferOffsetPair(vertexBuffer, 0);
+ state.vertexBufferCount = 1;
+ // Set viewport
+ Viewport viewport = Viewport::fromSize((float)width, (float)height);
+ state.viewportCount = 1;
+ state.viewports[0] = viewport;
+
+ pass->setRenderState(state);
+
+ // Draw
+ DrawArguments args = {};
+ args.vertexCount = kVertexCount;
+ pass->draw(args);
+
+ pass->end();
+ ComPtr<ICommandBuffer> cmdBuffer;
+ encoder->finish(cmdBuffer.writeRef());
+ queue->submit(cmdBuffer);
+
+ // Present
+ surface->present();
}
void run()
{
- 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)
+ createSwapchainAndResources();
+ for (uint32_t i = 0; i < 5; ++i)
{
- renderFrame(i % kSwapchainImageCount);
+ renderFrame(i % swapchainImageCount);
}
queue->waitOnHost();
- framebuffers = decltype(framebuffers)();
- GFX_CHECK_CALL(swapchain->resize(700, 700));
- createSwapchainFramebuffers();
+ // Resize swapchain
width = 700;
height = 700;
+ SurfaceConfig config = surface->getConfig();
+ config.width = width;
+ config.height = height;
+ surface->configure(config);
- for (GfxIndex i = 0; i < 5; ++i)
+ for (uint32_t i = 0; i < 5; ++i)
{
- renderFrame(i % kSwapchainImageCount);
+ renderFrame(i % swapchainImageCount);
}
queue->waitOnHost();
}
@@ -238,12 +213,14 @@ void swapchainResizeTestImpl(IDevice* device, UnitTestContext* context)
SLANG_UNIT_TEST(swapchainResizeD3D12)
{
- runTestImpl(swapchainResizeTestImpl, unitTestContext, RenderApiFlag::D3D12);
+ runTestImpl(swapchainResizeTestImpl, unitTestContext, DeviceType::D3D12);
}
SLANG_UNIT_TEST(swapchainResizeVulkan)
{
- runTestImpl(swapchainResizeTestImpl, unitTestContext, RenderApiFlag::Vulkan);
+ runTestImpl(swapchainResizeTestImpl, unitTestContext, DeviceType::Vulkan);
}
} // namespace gfx_test
+
+#endif
diff --git a/tools/gfx-unit-test/texture-types-tests.cpp b/tools/gfx-unit-test/texture-types-tests.cpp
index b581fd3d7..327736b4e 100644
--- a/tools/gfx-unit-test/texture-types-tests.cpp
+++ b/tools/gfx-unit-test/texture-types-tests.cpp
@@ -1,16 +1,20 @@
+#if 0
+// Duplicated: This test is identical to slang-rhi\tests\test-texture-types.cpp
+
#include "core/slang-basic.h"
#include "gfx-test-texture-util.h"
#include "gfx-test-util.h"
-#include "gfx-util/shader-cursor.h"
-#include "slang-gfx.h"
#include "unit-test/slang-unit-test.h"
+#include <slang-rhi.h>
+#include <slang-rhi/shader-cursor.h>
+
#if SLANG_WINDOWS_FAMILY
#include <d3d12.h>
#endif
using namespace Slang;
-using namespace gfx;
+using namespace rhi;
namespace gfx_test
{
@@ -19,18 +23,18 @@ struct BaseTextureViewTest
IDevice* device;
UnitTestContext* context;
- IResourceView::Type viewType;
+ TextureViewType viewType;
size_t alignedRowStride;
RefPtr<TextureInfo> textureInfo;
RefPtr<ValidationTextureFormatBase> validationFormat;
- ComPtr<ITextureResource> texture;
- ComPtr<IResourceView> textureView;
- ComPtr<IBufferResource> resultsBuffer;
- ComPtr<IResourceView> bufferView;
+ ComPtr<ITexture> texture;
+ ComPtr<ITextureView> textureView;
+ ComPtr<IBuffer> resultsBuffer;
+ ComPtr<IBufferView> bufferView;
- ComPtr<ISamplerState> sampler;
+ ComPtr<ISampler> sampler;
const void* expectedTextureData;
@@ -39,8 +43,8 @@ struct BaseTextureViewTest
UnitTestContext* context,
Format format,
RefPtr<ValidationTextureFormatBase> validationFormat,
- IResourceView::Type viewType,
- IResource::Type type)
+ TextureViewType viewType,
+ TextureType type)
{
this->device = device;
this->context = context;
@@ -52,20 +56,18 @@ struct BaseTextureViewTest
this->textureInfo->textureType = type;
}
- ResourceState getDefaultResourceStateForViewType(IResourceView::Type type)
+ ResourceState getDefaultResourceStateForViewType(TextureViewType type)
{
switch (type)
{
- case IResourceView::Type::RenderTarget:
+ case TextureViewType::RenderTarget:
return ResourceState::RenderTarget;
- case IResourceView::Type::DepthStencil:
+ case TextureViewType::DepthStencil:
return ResourceState::DepthWrite;
- case IResourceView::Type::ShaderResource:
+ case TextureViewType::ShaderResource:
return ResourceState::ShaderResource;
- case IResourceView::Type::UnorderedAccess:
+ case TextureViewType::UnorderedAccess:
return ResourceState::UnorderedAccess;
- case IResourceView::Type::AccelerationStructure:
- return ResourceState::AccelerationStructure;
default:
return ResourceState::Undefined;
}
@@ -79,16 +81,16 @@ struct BaseTextureViewTest
switch (textureInfo->textureType)
{
- case IResource::Type::Texture1D:
+ case TextureType::Texture1D:
shape = "1D";
break;
- case IResource::Type::Texture2D:
+ case TextureType::Texture2D:
shape = "2D";
break;
- case IResource::Type::Texture3D:
+ case TextureType::Texture3D:
shape = "3D";
break;
- case IResource::Type::TextureCube:
+ case TextureType::TextureCube:
shape = "Cube";
break;
default:
@@ -98,21 +100,18 @@ struct BaseTextureViewTest
switch (viewType)
{
- case IResourceView::Type::RenderTarget:
+ case TextureViewType::RenderTarget:
view = "Render";
break;
- case IResourceView::Type::DepthStencil:
+ case TextureViewType::DepthStencil:
view = "Depth";
break;
- case IResourceView::Type::ShaderResource:
+ case TextureViewType::ShaderResource:
view = "Shader";
break;
- case IResourceView::Type::UnorderedAccess:
+ case TextureViewType::UnorderedAccess:
view = "Unordered";
break;
- case IResourceView::Type::AccelerationStructure:
- view = "Accel";
- break;
default:
assert(!"Invalid resource view");
SLANG_CHECK_ABORT(false);
@@ -127,10 +126,10 @@ struct ShaderAndUnorderedTests : BaseTextureViewTest
{
void createRequiredResources()
{
- ITextureResource::Desc textureDesc = {};
+ TextureDesc textureDesc = {};
textureDesc.type = textureInfo->textureType;
textureDesc.numMipLevels = textureInfo->mipLevelCount;
- textureDesc.arraySize = textureInfo->arrayLayerCount;
+ textureDesc.arrayLength = textureInfo->arrayLayerCount;
textureDesc.size = textureInfo->extents;
textureDesc.defaultState = getDefaultResourceStateForViewType(viewType);
textureDesc.allowedStates = ResourceStateSet(
@@ -139,28 +138,24 @@ struct ShaderAndUnorderedTests : BaseTextureViewTest
ResourceState::CopyDestination);
textureDesc.format = textureInfo->format;
- GFX_CHECK_CALL_ABORT(device->createTextureResource(
- textureDesc,
- textureInfo->subresourceDatas.getBuffer(),
- texture.writeRef()));
+ texture = device->createTexture(textureDesc, textureInfo->subresourceDatas.getBuffer());
+ SLANG_CHECK_ABORT(texture);
- IResourceView::Desc textureViewDesc = {};
+ TextureViewDesc 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()));
+ textureViewDesc.format = textureDesc.format;
+ textureView = device->createTextureView(texture, textureViewDesc);
+ SLANG_CHECK_ABORT(textureView);
auto texelSize = getTexelSize(textureInfo->format);
size_t alignment;
device->getTextureRowAlignment(&alignment);
alignedRowStride =
(textureInfo->extents.width * texelSize + alignment - 1) & ~(alignment - 1);
- IBufferResource::Desc bufferDesc = {};
+ BufferDesc 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.size = 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;
@@ -170,27 +165,18 @@ struct ShaderAndUnorderedTests : BaseTextureViewTest
ResourceState::CopySource);
bufferDesc.memoryType = MemoryType::DeviceLocal;
- GFX_CHECK_CALL_ABORT(
- device->createBufferResource(bufferDesc, nullptr, resultsBuffer.writeRef()));
+ resultsBuffer = device->createBuffer(bufferDesc, nullptr);
+ SLANG_CHECK_ABORT(resultsBuffer);
- IResourceView::Desc bufferViewDesc = {};
- bufferViewDesc.type = IResourceView::Type::UnorderedAccess;
+ BufferViewDesc bufferViewDesc = {};
+ bufferViewDesc.type = BufferViewType::UnorderedAccess;
bufferViewDesc.format = Format::Unknown;
- GFX_CHECK_CALL_ABORT(device->createBufferView(
- resultsBuffer,
- nullptr,
- bufferViewDesc,
- bufferView.writeRef()));
+ bufferView = device->createBufferView(resultsBuffer, nullptr, bufferViewDesc);
+ SLANG_CHECK_ABORT(bufferView);
}
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(
@@ -200,22 +186,21 @@ struct ShaderAndUnorderedTests : BaseTextureViewTest
entryPoint,
slangReflection));
- ComputePipelineStateDesc pipelineDesc = {};
+ ComputePipelineDesc pipelineDesc = {};
pipelineDesc.program = shaderProgram.get();
- ComPtr<gfx::IPipelineState> pipelineState;
- GFX_CHECK_CALL_ABORT(
- device->createComputePipelineState(pipelineDesc, pipelineState.writeRef()));
+ ComPtr<IComputePipeline> pipelineState;
+ pipelineState = device->createComputePipeline(pipelineDesc);
+ SLANG_CHECK_ABORT(pipelineState);
// 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 queue = device->getQueue(QueueType::Graphics);
- auto commandBuffer = transientHeap->createCommandBuffer();
- auto encoder = commandBuffer->encodeComputeCommands();
+ ComPtr<ICommandEncoder> encoder = queue->createCommandEncoder();
+ ComPtr<IComputeCommandEncoder> computeEncoder = encoder->beginComputePass();
- auto rootObject = encoder->bindPipeline(pipelineState);
+ ComPtr<IShaderObject> rootObject = computeEncoder->bindPipeline(pipelineState);
ShaderCursor entryPointCursor(
rootObject->getEntryPoint(0)); // get a cursor the the first entry-point.
@@ -229,20 +214,23 @@ struct ShaderAndUnorderedTests : BaseTextureViewTest
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["resourceView"].setResource(textureView);
entryPointCursor["testResults"].setResource(bufferView);
if (sampler)
- entryPointCursor["sampler"].setSampler(
- sampler); // TODO: Bind nullptr and make sure it doesn't splut
+ entryPointCursor["sampler"].setSampler(sampler);
auto bufferElementCount = width * height * depth;
- encoder->dispatchCompute(bufferElementCount, 1, 1);
- encoder->endEncoding();
- commandBuffer->close();
- queue->executeCommandBuffer(commandBuffer);
+ DispatchArguments args = {};
+ args.threadsPerAxis[0] = bufferElementCount;
+ args.threadsPerAxis[1] = 1;
+ args.threadsPerAxis[2] = 1;
+ computeEncoder->dispatchCompute(args);
+ computeEncoder->end();
+
+ ComPtr<ICommandBuffer> commandBuffer;
+ encoder->finish(commandBuffer.writeRef());
+ queue->submit(commandBuffer);
queue->waitOnHost();
}
}
@@ -270,12 +258,12 @@ struct ShaderAndUnorderedTests : BaseTextureViewTest
{
// Shader resources are read-only, so we don't need to check that writes to the resource
// were correct.
- if (viewType != IResourceView::Type::ShaderResource)
+ if (viewType != TextureViewType::ShaderResource)
{
ComPtr<ISlangBlob> textureBlob;
size_t rowPitch;
size_t pixelSize;
- GFX_CHECK_CALL_ABORT(device->readTextureResource(
+ GFX_CHECK_CALL_ABORT(device->readTexture(
texture,
ResourceState::CopySource,
textureBlob.writeRef(),
@@ -301,10 +289,10 @@ struct ShaderAndUnorderedTests : BaseTextureViewTest
}
ComPtr<ISlangBlob> bufferBlob;
- GFX_CHECK_CALL_ABORT(device->readBufferResource(
+ GFX_CHECK_CALL_ABORT(device->readBuffer(
resultsBuffer,
0,
- resultsBuffer->getDesc()->sizeInBytes,
+ resultsBuffer->getDesc().size,
bufferBlob.writeRef()));
auto results = (uint32_t*)bufferBlob->getBufferPointer();
@@ -320,15 +308,15 @@ struct ShaderAndUnorderedTests : BaseTextureViewTest
void run()
{
// TODO: Should test with samplers
- // ISamplerState::Desc samplerDesc;
- // sampler = device->createSamplerState(samplerDesc);
+ // SamplerDesc samplerDesc;
+ // sampler = device->createSampler(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->textureType == TextureType::Texture1D) ? 1 : 4;
textureInfo->extents.depth =
- (textureInfo->textureType != IResource::Type::Texture3D) ? 1 : 2;
+ (textureInfo->textureType != TextureType::Texture3D) ? 1 : 2;
textureInfo->mipLevelCount = 1;
textureInfo->arrayLayerCount = 1;
generateTextureData(textureInfo, validationFormat);
@@ -380,22 +368,19 @@ struct RenderTargetTests : BaseTextureViewTest
int sampleCount = 1;
- ComPtr<ITransientResourceHeap> transientHeap;
- ComPtr<IPipelineState> pipelineState;
- ComPtr<IRenderPassLayout> renderPass;
- ComPtr<IFramebuffer> framebuffer;
+ ComPtr<IRenderPipeline> pipelineState;
- ComPtr<ITextureResource> sampledTexture;
- ComPtr<IBufferResource> vertexBuffer;
+ ComPtr<ITexture> sampledTexture;
+ ComPtr<IBuffer> vertexBuffer;
void createRequiredResources()
{
- IBufferResource::Desc vertexBufferDesc;
- vertexBufferDesc.type = IResource::Type::Buffer;
- vertexBufferDesc.sizeInBytes = kVertexCount * sizeof(Vertex);
+ BufferDesc vertexBufferDesc;
+ vertexBufferDesc.size = kVertexCount * sizeof(Vertex);
vertexBufferDesc.defaultState = ResourceState::VertexBuffer;
vertexBufferDesc.allowedStates = ResourceState::VertexBuffer;
- vertexBuffer = device->createBufferResource(vertexBufferDesc, &kVertexData[0]);
+ vertexBufferDesc.usage = BufferUsage::VertexBuffer;
+ vertexBuffer = device->createBuffer(vertexBufferDesc, &kVertexData[0]);
SLANG_CHECK_ABORT(vertexBuffer != nullptr);
VertexStreamDesc vertexStreams[] = {
@@ -404,14 +389,14 @@ struct RenderTargetTests : BaseTextureViewTest
InputElementDesc inputElements[] = {
// Vertex buffer data
- {"POSITION", 0, Format::R32G32B32_FLOAT, offsetof(Vertex, position), 0},
- {"COLOR", 0, Format::R32G32B32_FLOAT, offsetof(Vertex, color), 0},
+ {"POSITION", 0, Format::RGB32Float, offsetof(Vertex, position), 0},
+ {"COLOR", 0, Format::RGB32Float, offsetof(Vertex, color), 0},
};
- ITextureResource::Desc sampledTexDesc = {};
+ TextureDesc sampledTexDesc = {};
sampledTexDesc.type = textureInfo->textureType;
sampledTexDesc.numMipLevels = textureInfo->mipLevelCount;
- sampledTexDesc.arraySize = textureInfo->arrayLayerCount;
+ sampledTexDesc.arrayLength = textureInfo->arrayLayerCount;
sampledTexDesc.size = textureInfo->extents;
sampledTexDesc.defaultState = getDefaultResourceStateForViewType(viewType);
sampledTexDesc.allowedStates = ResourceStateSet(
@@ -419,29 +404,29 @@ struct RenderTargetTests : BaseTextureViewTest
ResourceState::ResolveSource,
ResourceState::CopySource);
sampledTexDesc.format = textureInfo->format;
- sampledTexDesc.sampleDesc.numSamples = sampleCount;
+ sampledTexDesc.sampleCount = sampleCount;
- GFX_CHECK_CALL_ABORT(device->createTextureResource(
+ sampledTexture = device->createTexture(
sampledTexDesc,
- textureInfo->subresourceDatas.getBuffer(),
- sampledTexture.writeRef()));
+ textureInfo->subresourceDatas.getBuffer());
+ SLANG_CHECK_ABORT(sampledTexture);
- ITextureResource::Desc texDesc = {};
+ TextureDesc texDesc = {};
texDesc.type = textureInfo->textureType;
texDesc.numMipLevels = textureInfo->mipLevelCount;
- texDesc.arraySize = textureInfo->arrayLayerCount;
+ texDesc.arrayLength = 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(
+ texture = device->createTexture(
texDesc,
- textureInfo->subresourceDatas.getBuffer(),
- texture.writeRef()));
+ textureInfo->subresourceDatas.getBuffer());
+ SLANG_CHECK_ABORT(texture);
- IInputLayout::Desc inputLayoutDesc = {};
+ InputLayoutDesc inputLayoutDesc = {};
inputLayoutDesc.inputElementCount = SLANG_COUNT_OF(inputElements);
inputLayoutDesc.inputElements = inputElements;
inputLayoutDesc.vertexStreamCount = SLANG_COUNT_OF(vertexStreams);
@@ -449,11 +434,6 @@ struct RenderTargetTests : BaseTextureViewTest
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(
@@ -464,50 +444,19 @@ struct RenderTargetTests : BaseTextureViewTest
"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 = {};
+ ColorTargetDesc colorTarget = {};
+ colorTarget.format = textureInfo->format;
+
+ RenderPipelineDesc pipelineDesc = {};
pipelineDesc.program = shaderProgram.get();
pipelineDesc.inputLayout = inputLayout;
- pipelineDesc.framebufferLayout = framebufferLayout;
+ pipelineDesc.targets = &colorTarget;
+ pipelineDesc.targetCount = 1;
+ pipelineDesc.primitiveTopology = PrimitiveTopology::TriangleList;
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()));
+ pipelineState = device->createRenderPipeline(pipelineDesc);
+ SLANG_CHECK_ABORT(pipelineState);
auto texelSize = getTexelSize(textureInfo->format);
size_t alignment;
@@ -518,25 +467,47 @@ struct RenderTargetTests : BaseTextureViewTest
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 queue = device->getQueue(QueueType::Graphics);
+
+ ComPtr<ICommandEncoder> encoder = queue->createCommandEncoder();
+
+ // Create render target view
+ TextureViewDesc rtvDesc = {};
+ rtvDesc.type = TextureViewType::RenderTarget;
+ rtvDesc.format = textureInfo->format;
+ auto rtv = device->createTextureView(sampledTexture, rtvDesc);
+
+ RenderPassColorAttachment colorAttachment = {};
+ colorAttachment.view = rtv;
+ colorAttachment.loadOp = LoadOp::Clear;
+ colorAttachment.storeOp = StoreOp::Store;
+ float clearColor[4] = {0.0f, 0.0f, 0.0f, 0.0f};
+ memcpy(colorAttachment.clearValue, clearColor, sizeof(clearColor));
+
+ RenderPassDesc passDesc = {};
+ passDesc.colorAttachments = &colorAttachment;
+ passDesc.colorAttachmentCount = 1;
+
+ auto renderEncoder = encoder->beginRenderPass(passDesc);
auto rootObject = renderEncoder->bindPipeline(pipelineState);
- gfx::Viewport viewport = {};
+ 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();
+ viewport.width = (float)textureInfo->extents.width;
+ viewport.height = (float)textureInfo->extents.height;
+
+ RenderState state = {};
+ state.viewports[0] = viewport;
+ state.viewportCount = 1;
+ state.vertexBuffers[0] = BufferOffsetPair(vertexBuffer, 0);
+ state.vertexBufferCount = 1;
+ renderEncoder->setRenderState(state);
+
+ DrawArguments drawArgs = {};
+ drawArgs.vertexCount = kVertexCount;
+ drawArgs.startVertexLocation = 0;
+ renderEncoder->draw(drawArgs);
+ renderEncoder->end();
if (sampleCount > 1)
{
@@ -554,28 +525,29 @@ struct RenderTargetTests : BaseTextureViewTest
dstSubresource.baseArrayLayer = 0;
dstSubresource.layerCount = 1;
- resourceEncoder->resolveResource(
+ encoder->resolveResource(
sampledTexture,
ResourceState::ResolveSource,
msaaSubresource,
texture,
ResourceState::ResolveDestination,
dstSubresource);
- resourceEncoder->textureBarrier(
+ encoder->textureBarrier(
texture,
ResourceState::ResolveDestination,
ResourceState::CopySource);
}
else
{
- resourceEncoder->textureBarrier(
+ encoder->textureBarrier(
sampledTexture,
ResourceState::ResolveSource,
ResourceState::CopySource);
}
- resourceEncoder->endEncoding();
- commandBuffer->close();
- queue->executeCommandBuffer(commandBuffer);
+
+ ComPtr<ICommandBuffer> commandBuffer;
+ encoder->finish(commandBuffer.writeRef());
+ queue->submit(commandBuffer);
queue->waitOnHost();
}
@@ -614,7 +586,7 @@ struct RenderTargetTests : BaseTextureViewTest
size_t pixelSize;
if (sampleCount > 1)
{
- GFX_CHECK_CALL_ABORT(device->readTextureResource(
+ GFX_CHECK_CALL_ABORT(device->readTexture(
texture,
ResourceState::CopySource,
textureBlob.writeRef(),
@@ -623,7 +595,7 @@ struct RenderTargetTests : BaseTextureViewTest
}
else
{
- GFX_CHECK_CALL_ABORT(device->readTextureResource(
+ GFX_CHECK_CALL_ABORT(device->readTexture(
sampledTexture,
ResourceState::CopySource,
textureBlob.writeRef(),
@@ -653,9 +625,9 @@ struct RenderTargetTests : BaseTextureViewTest
textureInfo->extents.width = 4;
textureInfo->extents.height =
- (textureInfo->textureType == IResource::Type::Texture1D) ? 1 : 4;
+ (textureInfo->textureType == TextureType::Texture1D) ? 1 : 4;
textureInfo->extents.depth =
- (textureInfo->textureType != IResource::Type::Texture3D) ? 1 : 2;
+ (textureInfo->textureType != TextureType::Texture3D) ? 1 : 2;
textureInfo->mipLevelCount = 1;
textureInfo->arrayLayerCount = 1;
generateTextureData(textureInfo, validationFormat);
@@ -674,12 +646,12 @@ struct RenderTargetTests : BaseTextureViewTest
void shaderAndUnorderedTestImpl(IDevice* device, UnitTestContext* context)
{
// TODO: Buffer and TextureCube
- for (Int i = 2; i < (int32_t)IResource::Type::TextureCube; ++i)
+ for (Int i = 2; i < (int32_t)TextureType::TextureCube; ++i)
{
- for (Int j = 3; j < (int32_t)IResourceView::Type::AccelerationStructure; ++j)
+ for (Int j = 3; j < (int32_t)TextureViewType::AccelerationStructure; ++j)
{
- auto shape = (IResource::Type)i;
- auto view = (IResourceView::Type)j;
+ auto shape = (TextureType)i;
+ auto view = (TextureViewType)j;
auto format = Format::R8G8B8A8_UINT;
auto validationFormat = getValidationTextureFormat(format);
if (!validationFormat)
@@ -695,10 +667,10 @@ void shaderAndUnorderedTestImpl(IDevice* device, UnitTestContext* context)
void renderTargetTestImpl(IDevice* device, UnitTestContext* context)
{
// TODO: Buffer and TextureCube
- for (Int i = 2; i < (int32_t)IResource::Type::TextureCube; ++i)
+ for (Int i = 2; i < (int32_t)TextureType::TextureCube; ++i)
{
- auto shape = (IResource::Type)i;
- auto view = IResourceView::Type::RenderTarget;
+ auto shape = (TextureType)i;
+ auto view = TextureViewType::RenderTarget;
auto format = Format::R32G32B32A32_FLOAT;
auto validationFormat = getValidationTextureFormat(format);
if (!validationFormat)
@@ -712,17 +684,19 @@ void renderTargetTestImpl(IDevice* device, UnitTestContext* context)
SLANG_UNIT_TEST(shaderAndUnorderedAccessTests)
{
- runTestImpl(shaderAndUnorderedTestImpl, unitTestContext, Slang::RenderApiFlag::D3D12);
- runTestImpl(shaderAndUnorderedTestImpl, unitTestContext, Slang::RenderApiFlag::Vulkan);
+ runTestImpl(shaderAndUnorderedTestImpl, unitTestContext, DeviceType::D3D12);
+ runTestImpl(shaderAndUnorderedTestImpl, unitTestContext, DeviceType::Vulkan);
}
SLANG_UNIT_TEST(renderTargetTests)
{
- runTestImpl(renderTargetTestImpl, unitTestContext, Slang::RenderApiFlag::D3D12);
- runTestImpl(renderTargetTestImpl, unitTestContext, Slang::RenderApiFlag::Vulkan);
+ runTestImpl(renderTargetTestImpl, unitTestContext, DeviceType::D3D12);
+ runTestImpl(renderTargetTestImpl, unitTestContext, DeviceType::Vulkan);
}
} // namespace gfx_test
+#endif // Disabled test file
+
// 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)
diff --git a/tools/gfx-unit-test/uint16-structured-buffer.cpp b/tools/gfx-unit-test/uint16-structured-buffer.cpp
index d0d1789ed..280cc842b 100644
--- a/tools/gfx-unit-test/uint16-structured-buffer.cpp
+++ b/tools/gfx-unit-test/uint16-structured-buffer.cpp
@@ -1,91 +1,72 @@
+// Duplicated: This this test is identical to slang-rhi\tests\test-uint16-buffer.cpp
+
#include "core/slang-basic.h"
#include "gfx-test-util.h"
-#include "gfx-util/shader-cursor.h"
-#include "slang-gfx.h"
+#include "slang-rhi.h"
+#include "slang-rhi/shader-cursor.h"
#include "unit-test/slang-unit-test.h"
-using namespace gfx;
+using namespace rhi;
namespace gfx_test
{
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 = {};
+ ComputePipelineDesc pipelineDesc = {};
pipelineDesc.program = shaderProgram.get();
- ComPtr<gfx::IPipelineState> pipelineState;
- GFX_CHECK_CALL_ABORT(
- device->createComputePipelineState(pipelineDesc, pipelineState.writeRef()));
+ ComPtr<IComputePipeline> pipelineState;
+ GFX_CHECK_CALL_ABORT(device->createComputePipeline(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 bufferDesc = {};
+ bufferDesc.size = numberCount * sizeof(uint16_t);
+ bufferDesc.format = rhi::Format::Undefined;
+
+ bufferDesc.elementSize = 0; // Let RHI derive from reflection
+ bufferDesc.usage = BufferUsage::ShaderResource | BufferUsage::UnorderedAccess |
+ BufferUsage::CopyDestination | BufferUsage::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;
+ ComPtr<IBuffer> numbersBuffer;
GFX_CHECK_CALL_ABORT(
- device->createBufferView(numbersBuffer, nullptr, viewDesc, bufferView.writeRef()));
+ device->createBuffer(bufferDesc, (void*)initialData, numbersBuffer.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 queue = device->getQueue(QueueType::Graphics);
+ auto commandEncoder = queue->createCommandEncoder();
+ auto computePassEncoder = commandEncoder->beginComputePass();
- auto rootObject = encoder->bindPipeline(pipelineState);
+ auto rootObject = computePassEncoder->bindPipeline(pipelineState);
- // Bind buffer view to the entry point.
- ShaderCursor(rootObject).getPath("buffer").setResource(bufferView);
+ // Bind buffer to the entry point.
+ ShaderCursor(rootObject).getPath("buffer").setBinding(Binding(numbersBuffer));
- encoder->dispatchCompute(1, 1, 1);
- encoder->endEncoding();
- commandBuffer->close();
- queue->executeCommandBuffer(commandBuffer);
+ computePassEncoder->dispatchCompute(1, 1, 1);
+ computePassEncoder->end();
+ queue->submit(commandEncoder->finish());
queue->waitOnHost();
}
- compareComputeResult(device, numbersBuffer, Slang::makeArray<uint16_t>(1, 2, 3, 4));
+ compareComputeResult(device, numbersBuffer, std::array<uint16_t, 4>{1, 2, 3, 4});
}
SLANG_UNIT_TEST(uint16BufferTestD3D12)
{
- runTestImpl(uint16BufferTestImpl, unitTestContext, Slang::RenderApiFlag::D3D12);
+ runTestImpl(uint16BufferTestImpl, unitTestContext, DeviceType::D3D12);
}
SLANG_UNIT_TEST(uint16BufferTestVulkan)
{
- runTestImpl(uint16BufferTestImpl, unitTestContext, Slang::RenderApiFlag::Vulkan);
+ runTestImpl(uint16BufferTestImpl, unitTestContext, DeviceType::Vulkan);
}
} // namespace gfx_test
diff --git a/tools/gfx-util/shader-cursor.cpp b/tools/gfx-util/shader-cursor.cpp
deleted file mode 100644
index 80d674768..000000000
--- a/tools/gfx-util/shader-cursor.cpp
+++ /dev/null
@@ -1,379 +0,0 @@
-#include "shader-cursor.h"
-
-namespace gfx
-{
-
-Result gfx::ShaderCursor::getDereferenced(ShaderCursor& outCursor) const
-{
- switch (m_typeLayout->getKind())
- {
- default:
- return SLANG_E_INVALID_ARG;
-
- case slang::TypeReflection::Kind::ConstantBuffer:
- case slang::TypeReflection::Kind::ParameterBlock:
- {
- auto subObject = m_baseObject->getObject(m_offset);
- outCursor = ShaderCursor(subObject);
- return SLANG_OK;
- }
- }
-}
-
-ShaderCursor ShaderCursor::getExplicitCounter() const
-{
- // Similar to getField below
-
- // The alternative to handling this here would be to augment IResourceView
- // with a `getCounterResourceView()`, and set that also in `setResource`
- if (const auto counterVarLayout = m_typeLayout->getExplicitCounter())
- {
- ShaderCursor counterCursor;
-
- // The counter cursor will point into the same parent object.
- counterCursor.m_baseObject = m_baseObject;
-
- // The type being pointed to is the type of the field.
- counterCursor.m_typeLayout = counterVarLayout->getTypeLayout();
-
- // The byte offset is the current offset plus the relative offset of the counter.
- // The offset in binding ranges is computed similarly.
- counterCursor.m_offset.uniformOffset =
- m_offset.uniformOffset + SlangInt(counterVarLayout->getOffset());
- counterCursor.m_offset.bindingRangeIndex =
- m_offset.bindingRangeIndex +
- GfxIndex(m_typeLayout->getExplicitCounterBindingRangeOffset());
-
- // The index of the counter within any binding ranges will be the same
- // as the index computed for the parent structure.
- //
- // Note: this case would arise for an array of structured buffers
- //
- // AppendStructuredBuffer g[4];
- //
- // In this scenario, `g` holds two binding ranges:
- //
- // * Range #0 comprises 4 element buffers, representing `g[...].elements`
- // * Range #1 comprises 4 counter buffers, representing `g[...].counter`
- //
- // A cursor for `g[2]` would have a `bindingRangeIndex` of zero but
- // a `bindingArrayIndex` of 2, indicating that we could end up
- // referencing either range, but no matter what we know the index
- // is 2. Thus when we form a cursor for `g[2].counter` we want to
- // apply the binding range offset to get a `bindingRangeIndex` of
- // 1, while the `bindingArrayIndex` is unmodified.
- //
- // The result is that `g[2].counter` is stored in range #1 at array index 2.
- //
- counterCursor.m_offset.bindingArrayIndex = m_offset.bindingArrayIndex;
-
- return counterCursor;
- }
- // Otherwise, return an invalid cursor
- return ShaderCursor{};
-}
-
-Result ShaderCursor::getField(const char* name, const char* nameEnd, ShaderCursor& outCursor) const
-{
- // If this cursor is invalid, then can't possible fetch a field.
- //
- if (!isValid())
- return SLANG_E_INVALID_ARG;
-
- // If the cursor is valid, we want to consider the type of data
- // it is referencing.
- //
- switch (m_typeLayout->getKind())
- {
- // The easy/expected case is when the value has a structure type.
- //
- case slang::TypeReflection::Kind::Struct:
- {
- // We start by looking up the index of a field matching `name`.
- //
- // If there is no such field, we have an error.
- //
- SlangInt fieldIndex = m_typeLayout->findFieldIndexByName(name, nameEnd);
- if (fieldIndex == -1)
- break;
-
- // Once we know the index of the field being referenced,
- // we create a cursor to point at the field, based on
- // the offset information already in this cursor, plus
- // offsets derived from the field's layout.
- //
- slang::VariableLayoutReflection* fieldLayout =
- m_typeLayout->getFieldByIndex((unsigned int)fieldIndex);
- ShaderCursor fieldCursor;
-
- // The field cursorwill point into the same parent object.
- //
- fieldCursor.m_baseObject = m_baseObject;
-
- // The type being pointed to is the tyep of the field.
- //
- fieldCursor.m_typeLayout = fieldLayout->getTypeLayout();
-
- // The byte offset is the current offset plus the relative offset of the field.
- // The offset in binding ranges is computed similarly.
- //
- fieldCursor.m_offset.uniformOffset = m_offset.uniformOffset + fieldLayout->getOffset();
- fieldCursor.m_offset.bindingRangeIndex =
- m_offset.bindingRangeIndex +
- (GfxIndex)m_typeLayout->getFieldBindingRangeOffset(fieldIndex);
-
- // The index of the field within any binding ranges will be the same
- // as the index computed for the parent structure.
- //
- // Note: this case would arise for an array of structures with texture-type
- // fields. Suppose we have:
- //
- // struct S { Texture2D t; Texture2D u; }
- // S g[4];
- //
- // In this scenario, `g` holds two binding ranges:
- //
- // * Range #0 comprises 4 textures, representing `g[...].t`
- // * Range #1 comprises 4 textures, representing `g[...].u`
- //
- // A cursor for `g[2]` would have a `bindingRangeIndex` of zero but
- // a `bindingArrayIndex` of 2, iindicating that we could end up
- // referencing either range, but no matter what we know the index
- // is 2. Thus when we form a cursor for `g[2].u` we want to
- // apply the binding range offset to get a `bindingRangeIndex` of
- // 1, while the `bindingArrayIndex` is unmodified.
- //
- // The result is that `g[2].u` is stored in range #1 at array index 2.
- //
- fieldCursor.m_offset.bindingArrayIndex = m_offset.bindingArrayIndex;
-
- outCursor = fieldCursor;
- return SLANG_OK;
- }
- break;
-
- // In some cases the user might be trying to acess a field by name
- // from a cursor that references a constant buffer or parameter block,
- // and in these cases we want the access to Just Work.
- //
- case slang::TypeReflection::Kind::ConstantBuffer:
- case slang::TypeReflection::Kind::ParameterBlock:
- {
- // We basically need to "dereference" the current cursor
- // to go from a pointer to a constant buffer to a pointer
- // to the *contents* of the constant buffer.
- //
- ShaderCursor d = getDereferenced();
- return d.getField(name, nameEnd, outCursor);
- }
- break;
- }
-
- // If a cursor is pointing at a root shader object (created for a
- // program), then we will also iterate over the entry point shader
- // objects attached to it and look for a matching parameter name
- // on them.
- //
- // This is a bit of "do what I mean" logic and could potentially
- // lead to problems if there could be multiple entry points with
- // the same parameter name.
- //
- // TODO: figure out whether we should support this long-term.
- //
- auto entryPointCount = (GfxIndex)m_baseObject->getEntryPointCount();
- for (GfxIndex e = 0; e < entryPointCount; ++e)
- {
- ComPtr<IShaderObject> entryPoint;
- m_baseObject->getEntryPoint(e, entryPoint.writeRef());
-
- ShaderCursor entryPointCursor(entryPoint);
-
- auto result = entryPointCursor.getField(name, nameEnd, outCursor);
- if (SLANG_SUCCEEDED(result))
- return result;
- }
-
- return SLANG_E_INVALID_ARG;
-}
-
-ShaderCursor ShaderCursor::getElement(GfxIndex index) const
-{
- if (m_containerType != ShaderObjectContainerType::None)
- {
- ShaderCursor elementCursor;
- elementCursor.m_baseObject = m_baseObject;
- elementCursor.m_typeLayout = m_typeLayout->getElementTypeLayout();
- elementCursor.m_containerType = m_containerType;
- elementCursor.m_offset.uniformOffset = index * m_typeLayout->getStride();
- elementCursor.m_offset.bindingRangeIndex = 0;
- elementCursor.m_offset.bindingArrayIndex = index;
- return elementCursor;
- }
-
- switch (m_typeLayout->getKind())
- {
- case slang::TypeReflection::Kind::Array:
- {
- ShaderCursor elementCursor;
- elementCursor.m_baseObject = m_baseObject;
- elementCursor.m_typeLayout = m_typeLayout->getElementTypeLayout();
- elementCursor.m_offset.uniformOffset =
- m_offset.uniformOffset +
- index * m_typeLayout->getElementStride(SLANG_PARAMETER_CATEGORY_UNIFORM);
- elementCursor.m_offset.bindingRangeIndex = m_offset.bindingRangeIndex;
- elementCursor.m_offset.bindingArrayIndex =
- m_offset.bindingArrayIndex * (GfxCount)m_typeLayout->getElementCount() + index;
- return elementCursor;
- }
- break;
-
- case slang::TypeReflection::Kind::Struct:
- {
- // The logic here is similar to `getField()` except that we don't
- // need to look up the field index based on a name first.
- //
- auto fieldIndex = index;
- slang::VariableLayoutReflection* fieldLayout =
- m_typeLayout->getFieldByIndex((unsigned int)fieldIndex);
- if (!fieldLayout)
- return ShaderCursor();
-
- ShaderCursor fieldCursor;
- fieldCursor.m_baseObject = m_baseObject;
- fieldCursor.m_typeLayout = fieldLayout->getTypeLayout();
- fieldCursor.m_offset.uniformOffset = m_offset.uniformOffset + fieldLayout->getOffset();
- fieldCursor.m_offset.bindingRangeIndex =
- m_offset.bindingRangeIndex +
- (GfxIndex)m_typeLayout->getFieldBindingRangeOffset(fieldIndex);
- fieldCursor.m_offset.bindingArrayIndex = m_offset.bindingArrayIndex;
-
- return fieldCursor;
- }
- break;
-
- case slang::TypeReflection::Kind::Vector:
- case slang::TypeReflection::Kind::Matrix:
- {
- ShaderCursor fieldCursor;
- fieldCursor.m_baseObject = m_baseObject;
- fieldCursor.m_typeLayout = m_typeLayout->getElementTypeLayout();
- fieldCursor.m_offset.uniformOffset =
- m_offset.uniformOffset +
- m_typeLayout->getElementStride(SLANG_PARAMETER_CATEGORY_UNIFORM) * index;
- fieldCursor.m_offset.bindingRangeIndex = m_offset.bindingRangeIndex;
- fieldCursor.m_offset.bindingArrayIndex = m_offset.bindingArrayIndex;
- return fieldCursor;
- }
- break;
- }
-
- return ShaderCursor();
-}
-
-
-static int _peek(const char* slice)
-{
- const char* b = slice;
- if (!b || !*b)
- return -1;
- return *b;
-}
-
-static int _get(const char*& slice)
-{
- const char* b = slice;
- if (!b || !*b)
- return -1;
- auto result = *b++;
- slice = b;
- return result;
-}
-
-Result ShaderCursor::followPath(const char* path, ShaderCursor& ioCursor)
-{
- ShaderCursor cursor = ioCursor;
-
- enum
- {
- ALLOW_NAME = 0x1,
- ALLOW_SUBSCRIPT = 0x2,
- ALLOW_DOT = 0x4,
- };
- int state = ALLOW_NAME | ALLOW_SUBSCRIPT;
-
- const char* rest = path;
- for (;;)
- {
- int c = _peek(rest);
-
- if (c == -1)
- break;
- else if (c == '.')
- {
- if (!(state & ALLOW_DOT))
- return SLANG_E_INVALID_ARG;
-
- _get(rest);
- state = ALLOW_NAME;
- continue;
- }
- else if (c == '[')
- {
- if (!(state & ALLOW_SUBSCRIPT))
- return SLANG_E_INVALID_ARG;
-
- _get(rest);
- GfxCount index = 0;
- while (_peek(rest) != ']')
- {
- int d = _get(rest);
- if (d >= '0' && d <= '9')
- {
- index = index * 10 + (d - '0');
- }
- else
- {
- return SLANG_E_INVALID_ARG;
- }
- }
-
- if (_peek(rest) != ']')
- return SLANG_E_INVALID_ARG;
- _get(rest);
-
- cursor = cursor.getElement(index);
- state = ALLOW_DOT | ALLOW_SUBSCRIPT;
- continue;
- }
- else
- {
- const char* nameBegin = rest;
- for (;;)
- {
- switch (_peek(rest))
- {
- default:
- _get(rest);
- continue;
-
- case -1:
- case '.':
- case '[':
- break;
- }
- break;
- }
- char const* nameEnd = rest;
- ShaderCursor newCursor;
- cursor.getField(nameBegin, nameEnd, newCursor);
- cursor = newCursor;
- state = ALLOW_DOT | ALLOW_SUBSCRIPT;
- continue;
- }
- }
-
- ioCursor = cursor;
- return SLANG_OK;
-}
-
-} // namespace gfx
diff --git a/tools/gfx-util/shader-cursor.h b/tools/gfx-util/shader-cursor.h
deleted file mode 100644
index b24edb594..000000000
--- a/tools/gfx-util/shader-cursor.h
+++ /dev/null
@@ -1,146 +0,0 @@
-#pragma once
-
-#include "slang-gfx.h"
-
-namespace gfx
-{
-
-/// Represents a "pointer" to the storage for a shader parameter of a (dynamically) known type.
-///
-/// A `ShaderCursor` serves as a pointer-like type for things stored inside a `ShaderObject`.
-///
-/// A cursor that points to the entire content of a shader object can be formed as
-/// `ShaderCursor(someObject)`. A cursor pointing to a structure field or array element can be
-/// formed from another cursor using `getField` or `getElement` respectively.
-///
-/// Given a cursor pointing to a value of some "primitive" type, we can set or get the value
-/// using operations like `setResource`, `getResource`, etc.
-///
-/// Because type information for shader parameters is being reflected dynamically, all type
-/// checking for shader cursors occurs at runtime, and errors may occur when attempting to
-/// set a parameter using a value of an inappropriate type. As much as possible, `ShaderCursor`
-/// attempts to protect against these cases and return an error `Result` or an invalid
-/// cursor, rather than allowing operations to proceed with incorrect types.
-///
-struct ShaderCursor
-{
- IShaderObject* m_baseObject = nullptr;
- slang::TypeLayoutReflection* m_typeLayout = nullptr;
- ShaderObjectContainerType m_containerType = ShaderObjectContainerType::None;
- ShaderOffset m_offset;
-
- /// Get the type (layout) of the value being pointed at by the cursor
- slang::TypeLayoutReflection* getTypeLayout() const { return m_typeLayout; }
-
- /// Is this cursor valid (that is, does it seem to point to an actual location)?
- ///
- /// This check is equivalent to checking whether a pointer is null, so it is
- /// a very weak sense of "valid." In particular, it is possible to form a
- /// `ShaderCursor` for which `isValid()` is true, but attempting to get or
- /// set the value would be an error (like dereferencing a garbage pointer).
- ///
- bool isValid() const { return m_baseObject != nullptr; }
-
- Result getDereferenced(ShaderCursor& outCursor) const;
-
- ShaderCursor getDereferenced() const
- {
- ShaderCursor result;
- getDereferenced(result);
- return result;
- }
-
- /// Form a cursor pointing to the field with the given `name` within the value this cursor
- /// points at.
- ///
- /// If the operation succeeds, then the field cursor is written to `outCursor`.
- Result getField(const char* nameBegin, const char* nameEnd, ShaderCursor& outCursor) const;
-
- ShaderCursor getField(const char* name) const
- {
- ShaderCursor cursor;
- getField(name, nullptr, cursor);
- return cursor;
- }
-
- /// Some resources such as RWStructuredBuffer, AppendStructuredBuffer and
- /// ConsumeStructuredBuffer need to have their counter explicitly bound on
- /// APIs other than DirectX, this will return a valid ShaderCursor pointing
- /// to that resource if that is the case.
- /// Otherwise, this returns an invalid cursor.
- ShaderCursor getExplicitCounter() const;
-
- ShaderCursor getElement(GfxIndex index) const;
-
- static Result followPath(const char* path, ShaderCursor& ioCursor);
-
- ShaderCursor getPath(const char* path) const
- {
- ShaderCursor result(*this);
- followPath(path, result);
- return result;
- }
-
- ShaderCursor() {}
-
- ShaderCursor(IShaderObject* object)
- : m_baseObject(object)
- , m_typeLayout(object->getElementTypeLayout())
- , m_containerType(object->getContainerType())
- {
- }
-
- SlangResult setData(void const* data, Size size) const
- {
- return m_baseObject->setData(m_offset, data, size);
- }
-
- template<typename T>
- SlangResult setData(T const& data) const
- {
- return setData(&data, sizeof(data));
- }
-
- SlangResult setObject(IShaderObject* object) const
- {
- return m_baseObject->setObject(m_offset, object);
- }
-
- SlangResult setSpecializationArgs(const slang::SpecializationArg* args, GfxCount count) const
- {
- return m_baseObject->setSpecializationArgs(m_offset, args, count);
- }
-
- SlangResult setResource(IResourceView* resourceView) const
- {
- return m_baseObject->setResource(m_offset, resourceView);
- }
-
- SlangResult setSampler(ISamplerState* sampler) const
- {
- return m_baseObject->setSampler(m_offset, sampler);
- }
-
- SlangResult setCombinedTextureSampler(IResourceView* textureView, ISamplerState* sampler) const
- {
- return m_baseObject->setCombinedTextureSampler(m_offset, textureView, sampler);
- }
-
- /// Produce a cursor to the field with the given `name`.
- ///
- /// This is a convenience wrapper around `getField()`.
- ShaderCursor operator[](const char* name) const { return getField(name); }
-
- /// Produce a cursor to the element or field with the given `index`.
- ///
- /// This is a convenience wrapper around `getElement()`.
- ShaderCursor operator[](int64_t index) const { return getElement((GfxIndex)index); }
- ShaderCursor operator[](uint64_t index) const { return getElement((GfxIndex)index); }
- ShaderCursor operator[](int32_t index) const { return getElement((GfxIndex)index); }
- ShaderCursor operator[](uint32_t index) const { return getElement((GfxIndex)index); }
- ShaderCursor operator[](int16_t index) const { return getElement((GfxIndex)index); }
- ShaderCursor operator[](uint16_t index) const { return getElement((GfxIndex)index); }
- ShaderCursor operator[](int8_t index) const { return getElement((GfxIndex)index); }
- ShaderCursor operator[](uint8_t index) const { return getElement((GfxIndex)index); }
-};
-} // namespace gfx
diff --git a/tools/platform/gui.cpp b/tools/platform/gui.cpp
index 15d683ec8..b3d5d6b92 100644
--- a/tools/platform/gui.cpp
+++ b/tools/platform/gui.cpp
@@ -8,7 +8,7 @@ IMGUI_IMPL_API LRESULT
ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
#endif
-using namespace gfx;
+using namespace rhi;
namespace platform
{
@@ -41,11 +41,7 @@ LRESULT CALLBACK guiWindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam
#endif
-GUI::GUI(
- Window* window,
- IDevice* inDevice,
- ICommandQueue* inQueue,
- IFramebufferLayout* framebufferLayout)
+GUI::GUI(Window* window, IDevice* inDevice, ICommandQueue* inQueue)
: device(inDevice), queue(inQueue)
{
ImGui::CreateContext();
@@ -96,45 +92,46 @@ GUI::GUI(
auto slangSession = inDevice->getSlangSession();
// TODO: create slang program.
- IShaderProgram* program = nullptr;
+ // For now, we'll proceed without a proper shader program
+ // This is a limitation that would need to be addressed for full functionality
#if 0
- gfx::IShaderProgram::Desc programDesc = {};
- programDesc.pipelineType = gfx::PipelineType::Graphics;
+ ShaderProgramDesc programDesc = {};
programDesc.slangGlobalScope = slangGlobalScope;
- program = device->createProgram(programDesc);
+ shaderProgram = device->createShaderProgram(programDesc);
#endif
+
InputElementDesc inputElements[] = {
- {"U", 0, Format::R32G32_FLOAT, offsetof(ImDrawVert, pos)},
- {"U", 1, Format::R32G32_FLOAT, offsetof(ImDrawVert, uv)},
- {"U", 2, Format::R8G8B8A8_UNORM, offsetof(ImDrawVert, col)},
+ {"U", 0, Format::RG32Float, offsetof(ImDrawVert, pos)},
+ {"U", 1, Format::RG32Float, offsetof(ImDrawVert, uv)},
+ {"U", 2, Format::RGBA8Unorm, offsetof(ImDrawVert, col)},
};
- auto inputLayout = device->createInputLayout(
+ inputLayout = device->createInputLayout(
sizeof(ImDrawVert),
&inputElements[0],
SLANG_COUNT_OF(inputElements));
- //
-
- TargetBlendDesc targetBlendDesc;
- targetBlendDesc.color.srcFactor = BlendFactor::SrcAlpha;
- targetBlendDesc.color.dstFactor = BlendFactor::InvSrcAlpha;
- targetBlendDesc.alpha.srcFactor = BlendFactor::InvSrcAlpha;
- targetBlendDesc.alpha.dstFactor = BlendFactor::Zero;
-
- GraphicsPipelineStateDesc pipelineDesc;
- pipelineDesc.framebufferLayout = framebufferLayout;
- pipelineDesc.program = program;
+ // For now, skip pipeline creation since we don't have a shader program
+ // This would need to be completed for full functionality
+#if 0
+ ColorTargetDesc colorTarget;
+ colorTarget.format = Format::RGBA8Unorm;
+ colorTarget.enableBlend = true;
+ colorTarget.color.srcFactor = BlendFactor::SrcAlpha;
+ colorTarget.color.dstFactor = BlendFactor::InvSrcAlpha;
+ colorTarget.alpha.srcFactor = BlendFactor::InvSrcAlpha;
+ colorTarget.alpha.dstFactor = BlendFactor::Zero;
+
+ RenderPipelineDesc pipelineDesc;
+ pipelineDesc.program = shaderProgram;
pipelineDesc.inputLayout = inputLayout;
- pipelineDesc.blend.targets[0] = targetBlendDesc;
- pipelineDesc.blend.targetCount = 1;
+ pipelineDesc.targetCount = 1;
+ pipelineDesc.targets = &colorTarget;
pipelineDesc.rasterizer.cullMode = CullMode::None;
-
- // Set up the pieces of fixed-function state that we care about
pipelineDesc.depthStencil.depthTestEnable = false;
+ pipelineDesc.primitiveTopology = PrimitiveTopology::TriangleList;
- // TODO: need to set up blending state...
-
- pipelineState = device->createGraphicsPipelineState(pipelineDesc);
+ pipelineState = device->createRenderPipeline(pipelineDesc);
+#endif
// Initialize the texture atlas
unsigned char* pixels;
@@ -142,49 +139,35 @@ GUI::GUI(
io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height);
{
- gfx::ITextureResource::Desc desc = {};
- desc.type = IResource::Type::Texture2D;
- desc.format = Format::R8G8B8A8_UNORM;
- desc.arraySize = 0;
+ TextureDesc desc = {};
+ desc.type = TextureType::Texture2D;
+ desc.format = Format::RGBA8Unorm;
+ desc.arrayLength = 1;
desc.size.width = width;
desc.size.height = height;
desc.size.depth = 1;
- desc.numMipLevels = 1;
+ desc.mipCount = 1;
+ desc.usage = TextureUsage::ShaderResource;
desc.defaultState = ResourceState::ShaderResource;
- desc.allowedStates =
- ResourceStateSet(ResourceState::ShaderResource, ResourceState::CopyDestination);
- ITextureResource::SubresourceData initData = {};
+ SubresourceData initData = {};
initData.data = pixels;
- initData.strideY = width * 4 * sizeof(unsigned char);
+ initData.rowPitch = width * 4 * sizeof(unsigned char);
+ initData.slicePitch = initData.rowPitch * height;
- auto texture = device->createTextureResource(desc, &initData);
+ auto texture = device->createTexture(desc, &initData);
- gfx::IResourceView::Desc viewDesc;
+ TextureViewDesc viewDesc;
viewDesc.format = desc.format;
- viewDesc.type = IResourceView::Type::ShaderResource;
+ viewDesc.aspect = TextureAspect::All;
auto textureView = device->createTextureView(texture, viewDesc);
io.Fonts->TexID = (void*)textureView.detach();
}
{
- ISamplerState::Desc desc;
- samplerState = device->createSamplerState(desc);
- }
-
- {
- IRenderPassLayout::Desc desc;
- desc.framebufferLayout = framebufferLayout;
- IRenderPassLayout::TargetAccessDesc colorAccess;
- desc.depthStencilAccess = nullptr;
- colorAccess.initialState = ResourceState::Present;
- colorAccess.finalState = ResourceState::Present;
- colorAccess.loadOp = IRenderPassLayout::TargetLoadOp::Load;
- colorAccess.storeOp = IRenderPassLayout::TargetStoreOp::Store;
- desc.renderTargetAccess = &colorAccess;
- desc.renderTargetCount = 1;
- renderPass = device->createRenderPassLayout(desc);
+ SamplerDesc desc;
+ samplerState = device->createSampler(desc);
}
}
@@ -197,7 +180,7 @@ void GUI::beginFrame()
ImGui::NewFrame();
}
-void GUI::endFrame(ITransientResourceHeap* transientHeap, IFramebuffer* framebuffer)
+void GUI::endFrame(ITexture* renderTarget)
{
ImGui::Render();
@@ -213,53 +196,58 @@ void GUI::endFrame(ITransientResourceHeap* transientHeap, IFramebuffer* framebuf
if (!commandListCount)
return;
- // Allocate transient vertex/index buffers to hold the data for this frame.
-
- gfx::IBufferResource::Desc vertexBufferDesc;
- vertexBufferDesc.type = IResource::Type::Buffer;
+ // For now, skip rendering since we don't have a complete pipeline
+ // This would need shader program creation to work properly
+#if 0
+ // Create vertex and index buffers for this frame
+ BufferDesc vertexBufferDesc;
+ vertexBufferDesc.size = vertexCount * sizeof(ImDrawVert);
+ vertexBufferDesc.usage = BufferUsage::VertexBuffer | BufferUsage::CopyDestination;
vertexBufferDesc.defaultState = ResourceState::VertexBuffer;
- vertexBufferDesc.allowedStates =
- ResourceStateSet(ResourceState::VertexBuffer, ResourceState::CopyDestination);
- vertexBufferDesc.sizeInBytes = vertexCount * sizeof(ImDrawVert);
vertexBufferDesc.memoryType = MemoryType::Upload;
- auto vertexBuffer = device->createBufferResource(vertexBufferDesc);
+ auto vertexBuffer = device->createBuffer(vertexBufferDesc);
- gfx::IBufferResource::Desc indexBufferDesc;
- indexBufferDesc.type = IResource::Type::Buffer;
- indexBufferDesc.sizeInBytes = indexCount * sizeof(ImDrawIdx);
- indexBufferDesc.allowedStates =
- ResourceStateSet(ResourceState::IndexBuffer, ResourceState::CopyDestination);
+ BufferDesc indexBufferDesc;
+ indexBufferDesc.size = indexCount * sizeof(ImDrawIdx);
+ indexBufferDesc.usage = BufferUsage::IndexBuffer | BufferUsage::CopyDestination;
indexBufferDesc.defaultState = ResourceState::IndexBuffer;
indexBufferDesc.memoryType = MemoryType::Upload;
- auto indexBuffer = device->createBufferResource(indexBufferDesc);
- auto cmdBuf = transientHeap->createCommandBuffer();
- auto encoder = cmdBuf->encodeResourceCommands();
+ auto indexBuffer = device->createBuffer(indexBufferDesc);
+
+ // Upload vertex and index data
{
+ void* vertexData;
+ device->mapBuffer(vertexBuffer, CpuAccessMode::Write, &vertexData);
+ size_t vertexOffset = 0;
+ for (int ii = 0; ii < commandListCount; ++ii)
+ {
+ const ImDrawList* commandList = draw_data->CmdLists[ii];
+ size_t dataSize = commandList->VtxBuffer.Size * sizeof(ImDrawVert);
+ memcpy((char*)vertexData + vertexOffset, commandList->VtxBuffer.Data, dataSize);
+ vertexOffset += dataSize;
+ }
+ device->unmapBuffer(vertexBuffer);
+
+ void* indexData;
+ device->mapBuffer(indexBuffer, CpuAccessMode::Write, &indexData);
+ size_t indexOffset = 0;
for (int ii = 0; ii < commandListCount; ++ii)
{
const ImDrawList* commandList = draw_data->CmdLists[ii];
- encoder->uploadBufferData(
- vertexBuffer,
- commandList->VtxBuffer.Size * ii * sizeof(ImDrawVert),
- commandList->VtxBuffer.Size * sizeof(ImDrawVert),
- commandList->VtxBuffer.Data);
- encoder->uploadBufferData(
- indexBuffer,
- commandList->IdxBuffer.Size * ii * sizeof(ImDrawIdx),
- commandList->IdxBuffer.Size * sizeof(ImDrawIdx),
- commandList->IdxBuffer.Data);
+ size_t dataSize = commandList->IdxBuffer.Size * sizeof(ImDrawIdx);
+ memcpy((char*)indexData + indexOffset, commandList->IdxBuffer.Data, dataSize);
+ indexOffset += dataSize;
}
+ device->unmapBuffer(indexBuffer);
}
- // Allocate a transient constant buffer for projection matrix
- gfx::IBufferResource::Desc constantBufferDesc;
- constantBufferDesc.type = IResource::Type::Buffer;
- constantBufferDesc.allowedStates =
- ResourceStateSet(ResourceState::ConstantBuffer, ResourceState::CopyDestination);
+ // Create constant buffer for projection matrix
+ BufferDesc constantBufferDesc;
+ constantBufferDesc.size = sizeof(glm::mat4x4);
+ constantBufferDesc.usage = BufferUsage::ConstantBuffer | BufferUsage::CopyDestination;
constantBufferDesc.defaultState = ResourceState::ConstantBuffer;
- constantBufferDesc.sizeInBytes = sizeof(glm::mat4x4);
constantBufferDesc.memoryType = MemoryType::Upload;
- auto constantBuffer = device->createBufferResource(constantBufferDesc);
+ auto constantBuffer = device->createBuffer(constantBufferDesc);
{
float L = draw_data->DisplayPos.x;
@@ -272,30 +260,38 @@ void GUI::endFrame(ITransientResourceHeap* transientHeap, IFramebuffer* framebuf
{0.0f, 0.0f, 0.5f, 0.0f},
{(R + L) / (L - R), (T + B) / (B - T), 0.5f, 1.0f},
};
- encoder->uploadBufferData(constantBuffer, 0, sizeof(mvp), mvp);
+
+ void* constantData;
+ device->mapBuffer(constantBuffer, CpuAccessMode::Write, &constantData);
+ memcpy(constantData, mvp, sizeof(mvp));
+ device->unmapBuffer(constantBuffer);
}
- encoder->endEncoding();
+ // Record rendering commands
+ auto commandEncoder = queue->createCommandEncoder();
+
+ ComPtr<ITextureView> renderTargetView = device->createTextureView(renderTarget, {});
+ RenderPassColorAttachment colorAttachment = {};
+ colorAttachment.view = renderTargetView;
+ colorAttachment.loadOp = LoadOp::Load;
+ colorAttachment.storeOp = StoreOp::Store;
- gfx::Viewport viewport;
- viewport.originX = 0;
- viewport.originY = 0;
- viewport.extentY = draw_data->DisplaySize.y;
- viewport.extentX = draw_data->DisplaySize.x;
- viewport.extentY = draw_data->DisplaySize.y;
- viewport.minZ = 0;
- viewport.maxZ = 1;
+ RenderPassDesc renderPass = {};
+ renderPass.colorAttachments = &colorAttachment;
+ renderPass.colorAttachmentCount = 1;
- auto renderEncoder = cmdBuf->encodeRenderCommands(renderPass, framebuffer);
- renderEncoder->setViewportAndScissor(viewport);
+ auto renderEncoder = commandEncoder->beginRenderPass(renderPass);
- renderEncoder->bindPipeline(pipelineState);
+ RenderState renderState = {};
+ renderState.viewports[0] = Viewport::fromSize(draw_data->DisplaySize.x, draw_data->DisplaySize.y);
+ renderState.viewportCount = 1;
+ renderState.vertexBuffers[0] = vertexBuffer;
+ renderState.vertexBufferCount = 1;
+ renderState.indexBuffer = indexBuffer;
+ renderState.indexFormat = sizeof(ImDrawIdx) == 2 ? IndexFormat::Uint16 : IndexFormat::Uint32;
- renderEncoder->setVertexBuffer(0, vertexBuffer);
- renderEncoder->setIndexBuffer(
- indexBuffer,
- sizeof(ImDrawIdx) == 2 ? Format::R16_UINT : Format::R32_UINT);
- renderEncoder->setPrimitiveTopology(PrimitiveTopology::TriangleList);
+ auto rootObject = renderEncoder->bindPipeline(pipelineState);
+ renderEncoder->setRenderState(renderState);
uint32_t vertexOffset = 0;
uint32_t indexOffset = 0;
@@ -314,26 +310,30 @@ void GUI::endFrame(ITransientResourceHeap* transientHeap, IFramebuffer* framebuf
else
{
ScissorRect rect = {
- (int32_t)(command->ClipRect.x - pos.x),
- (int32_t)(command->ClipRect.y - pos.y),
- (int32_t)(command->ClipRect.z - pos.x),
- (int32_t)(command->ClipRect.w - pos.y)};
- renderEncoder->setScissorRects(1, &rect);
-
- // TODO: set parameter into root shader object.
-
- renderEncoder->drawIndexed(
- command->ElemCount,
- (uint32_t)indexOffset,
- (uint32_t)vertexOffset);
+ (uint32_t)(command->ClipRect.x - pos.x),
+ (uint32_t)(command->ClipRect.y - pos.y),
+ (uint32_t)(command->ClipRect.z - pos.x),
+ (uint32_t)(command->ClipRect.w - pos.y)};
+
+ RenderState scissorState = renderState;
+ scissorState.scissorRects[0] = rect;
+ scissorState.scissorRectCount = 1;
+ renderEncoder->setRenderState(scissorState);
+
+ DrawArguments drawArgs = {};
+ drawArgs.vertexCount = command->ElemCount;
+ drawArgs.startIndexLocation = indexOffset;
+ drawArgs.startVertexLocation = vertexOffset;
+ renderEncoder->drawIndexed(drawArgs);
}
indexOffset += command->ElemCount;
}
vertexOffset += commandList->VtxBuffer.Size;
}
- renderEncoder->endEncoding();
- cmdBuf->close();
- queue->executeCommandBuffer(cmdBuf);
+
+ renderEncoder->end();
+ queue->submit(commandEncoder->finish());
+#endif
}
GUI::~GUI()
@@ -341,8 +341,8 @@ GUI::~GUI()
auto& io = ImGui::GetIO();
{
- ComPtr<IResourceView> textureView;
- textureView.attach((IResourceView*)io.Fonts->TexID);
+ Slang::ComPtr<ITextureView> textureView;
+ textureView.attach((ITextureView*)io.Fonts->TexID);
textureView = nullptr;
}
diff --git a/tools/platform/gui.h b/tools/platform/gui.h
index 121fc0894..08386b862 100644
--- a/tools/platform/gui.h
+++ b/tools/platform/gui.h
@@ -4,30 +4,29 @@
#include "core/slang-basic.h"
#include "imgui/imgui.h"
#include "slang-com-ptr.h"
-#include "slang-gfx.h"
#include "vector-math.h"
#include "window.h"
+#include <slang-rhi.h>
+
namespace platform
{
struct GUI : Slang::RefObject
{
- GUI(Window* window,
- gfx::IDevice* device,
- gfx::ICommandQueue* queue,
- gfx::IFramebufferLayout* framebufferLayout);
+ GUI(Window* window, rhi::IDevice* device, rhi::ICommandQueue* queue);
~GUI();
void beginFrame();
- void endFrame(gfx::ITransientResourceHeap* transientHeap, gfx::IFramebuffer* framebuffer);
+ void endFrame(rhi::ITexture* renderTarget);
private:
- Slang::ComPtr<gfx::IDevice> device;
- Slang::ComPtr<gfx::ICommandQueue> queue;
- Slang::ComPtr<gfx::IRenderPassLayout> renderPass;
- Slang::ComPtr<gfx::IPipelineState> pipelineState;
- Slang::ComPtr<gfx::ISamplerState> samplerState;
+ Slang::ComPtr<rhi::IDevice> device;
+ Slang::ComPtr<rhi::ICommandQueue> queue;
+ Slang::ComPtr<rhi::IRenderPipeline> pipelineState;
+ Slang::ComPtr<rhi::ISampler> samplerState;
+ Slang::ComPtr<rhi::IShaderProgram> shaderProgram;
+ Slang::ComPtr<rhi::IInputLayout> inputLayout;
};
} // namespace platform
diff --git a/tools/platform/model.cpp b/tools/platform/model.cpp
index 8453363c3..ed19a5a83 100644
--- a/tools/platform/model.cpp
+++ b/tools/platform/model.cpp
@@ -22,7 +22,7 @@
namespace platform
{
-using namespace gfx;
+using namespace rhi;
using namespace Slang;
// TinyObj provides a tuple type that bundles up indices, but doesn't
@@ -101,7 +101,7 @@ struct hash<platform::SmoothingGroupVertexID>
namespace platform
{
-ComPtr<ITextureResource> loadTextureImage(IDevice* device, char const* path)
+ComPtr<ITexture> loadTextureImage(IDevice* device, char const* path)
{
int extentX = 0;
int extentY = 0;
@@ -121,20 +121,20 @@ ComPtr<ITextureResource> loadTextureImage(IDevice* device, char const* path)
return nullptr;
case 4:
- format = Format::R8G8B8A8_UNORM;
+ format = Format::RGBA8Unorm;
// TODO: handle other cases here if/when we stop forcing 4-component
// results when loading the image with stb_image.
}
- std::vector<ITextureResource::SubresourceData> subresourceInitData;
+ std::vector<SubresourceData> subresourceInitData;
ptrdiff_t stride = extentX * channelCount * sizeof(stbi_uc);
- ITextureResource::SubresourceData baseInitData;
+ SubresourceData baseInitData;
baseInitData.data = data;
- baseInitData.strideY = stride;
- baseInitData.strideZ = 0;
+ baseInitData.rowPitch = stride;
+ baseInitData.slicePitch = 0;
subresourceInitData.push_back(baseInitData);
@@ -178,10 +178,10 @@ ComPtr<ITextureResource> loadTextureImage(IDevice* device, char const* path)
STBIR_FLAG_ALPHA_PREMULTIPLIED);
- ITextureResource::SubresourceData mipInitData;
+ SubresourceData mipInitData;
mipInitData.data = newData;
- mipInitData.strideY = newStride;
- mipInitData.strideZ = 0;
+ mipInitData.rowPitch = newStride;
+ mipInitData.slicePitch = 0;
subresourceInitData.push_back(mipInitData);
@@ -194,16 +194,15 @@ ComPtr<ITextureResource> loadTextureImage(IDevice* device, char const* path)
int mipCount = (int)subresourceInitData.size();
- ITextureResource::Desc desc = {};
- desc.type = IResource::Type::Texture2D;
- desc.defaultState = ResourceState::ShaderResource;
- desc.allowedStates = ResourceStateSet(ResourceState::ShaderResource);
+ TextureDesc desc = {};
+ desc.type = TextureType::Texture2D;
+ desc.usage = TextureUsage::ShaderResource;
desc.format = format;
desc.size.width = extentX;
desc.size.height = extentY;
desc.size.depth = 1;
- desc.numMipLevels = mipCount;
- auto texture = device->createTextureResource(desc, subresourceInitData.data());
+ desc.mipCount = mipCount;
+ auto texture = device->createTexture(desc, subresourceInitData.data());
free(data);
return texture;
@@ -541,29 +540,26 @@ SlangResult ModelLoader::load(char const* inputPath, void** outModel)
modelData.vertexCount = (int)flatVertices.size();
modelData.indexCount = (int)flatIndices.size();
+ modelData.primitiveTopology = PrimitiveTopology::TriangleList;
modelData.meshCount = int(meshes.size());
modelData.meshes = meshes.data();
- IBufferResource::Desc vertexBufferDesc;
- vertexBufferDesc.type = IResource::Type::Buffer;
- vertexBufferDesc.sizeInBytes = modelData.vertexCount * sizeof(Vertex);
- vertexBufferDesc.allowedStates =
- ResourceStateSet(ResourceState::VertexBuffer, ResourceState::CopyDestination);
- vertexBufferDesc.defaultState = ResourceState::VertexBuffer;
+ BufferDesc vertexBufferDesc;
+ vertexBufferDesc.size = modelData.vertexCount * sizeof(Vertex);
+ vertexBufferDesc.usage = BufferUsage::VertexBuffer;
+ vertexBufferDesc.elementSize = sizeof(Vertex);
- modelData.vertexBuffer = device->createBufferResource(vertexBufferDesc, flatVertices.data());
+ modelData.vertexBuffer = device->createBuffer(vertexBufferDesc, flatVertices.data());
if (!modelData.vertexBuffer)
return SLANG_FAIL;
- IBufferResource::Desc indexBufferDesc;
- indexBufferDesc.type = IResource::Type::Buffer;
- indexBufferDesc.sizeInBytes = modelData.indexCount * sizeof(Index);
- indexBufferDesc.allowedStates =
- ResourceStateSet(ResourceState::IndexBuffer, ResourceState::CopyDestination);
- indexBufferDesc.defaultState = ResourceState::IndexBuffer;
+ BufferDesc indexBufferDesc;
+ indexBufferDesc.size = modelData.indexCount * sizeof(Index);
+ indexBufferDesc.usage = BufferUsage::IndexBuffer;
+ indexBufferDesc.elementSize = sizeof(Index);
- modelData.indexBuffer = device->createBufferResource(indexBufferDesc, flatIndices.data());
+ modelData.indexBuffer = device->createBuffer(indexBufferDesc, flatIndices.data());
if (!modelData.indexBuffer)
return SLANG_FAIL;
diff --git a/tools/platform/model.h b/tools/platform/model.h
index b0c625ec9..6289c3739 100644
--- a/tools/platform/model.h
+++ b/tools/platform/model.h
@@ -3,7 +3,7 @@
#include "platform-api.h"
#include "slang-com-ptr.h"
-#include "slang-gfx.h"
+#include "slang-rhi.h"
#include "vector-math.h"
#include <string>
@@ -20,7 +20,7 @@ struct ModelLoader
glm::vec3 specularColor;
float specularity;
- Slang::ComPtr<gfx::ITextureResource> diffuseMap;
+ Slang::ComPtr<rhi::ITexture> diffuseMap;
};
struct Vertex
@@ -42,9 +42,9 @@ struct ModelLoader
struct ModelData
{
- Slang::ComPtr<gfx::IBufferResource> vertexBuffer;
- Slang::ComPtr<gfx::IBufferResource> indexBuffer;
- gfx::PrimitiveTopology primitiveTopology;
+ Slang::ComPtr<rhi::IBuffer> vertexBuffer;
+ Slang::ComPtr<rhi::IBuffer> indexBuffer;
+ rhi::PrimitiveTopology primitiveTopology;
int vertexCount;
int indexCount;
int meshCount;
@@ -69,7 +69,7 @@ struct ModelLoader
};
ICallbacks* callbacks = nullptr;
- gfx::IDevice* device;
+ rhi::IDevice* device;
LoadFlags loadFlags = 0;
float scale = 1.0f;
diff --git a/tools/vk-pipeline-create/main.cpp b/tools/vk-pipeline-create/main.cpp
index 67301a2a0..91abb90bc 100644
--- a/tools/vk-pipeline-create/main.cpp
+++ b/tools/vk-pipeline-create/main.cpp
@@ -7,10 +7,10 @@
#include "../../source/core/slang-string-util.h"
#include "examples/hello-world/vulkan-api.h"
#include "slang-com-ptr.h"
-#include "slang-gfx.h"
#include "slang.h"
#include <chrono>
+#include <slang-rhi.h>
#if SLANG_WINDOWS_FAMILY
#include <windows.h>
@@ -19,6 +19,7 @@
#endif
using namespace Slang;
+using namespace rhi;
struct PipelineCreationReplay
{
@@ -233,7 +234,7 @@ struct PipelineCreationReplay
int run(int argc, const char** argv);
- void initVulkanAPI(gfx::IDevice* device);
+ void initVulkanAPI(IDevice* device);
};
int main(int argc, const char** argv)
@@ -244,10 +245,10 @@ int main(int argc, const char** argv)
int PipelineCreationReplay::run(int argc, const char** argv)
{
- gfx::IDevice::Desc deviceDesc = {};
- deviceDesc.deviceType = gfx::DeviceType::Vulkan;
- ComPtr<gfx::IDevice> device;
- gfx::gfxCreateDevice(&deviceDesc, device.writeRef());
+ DeviceDesc deviceDesc = {};
+ deviceDesc.deviceType = DeviceType::Vulkan;
+ ComPtr<IDevice> device;
+ SLANG_RETURN_ON_FAIL(createDevice(&deviceDesc, device.writeRef()));
initVulkanAPI(device);
if (argc < 2)
@@ -270,12 +271,12 @@ int PipelineCreationReplay::run(int argc, const char** argv)
return 0;
}
-void PipelineCreationReplay::initVulkanAPI(gfx::IDevice* device)
+void PipelineCreationReplay::initVulkanAPI(IDevice* device)
{
- gfx::IDevice::InteropHandles handle;
+ DeviceNativeHandles handle;
device->getNativeDeviceHandles(&handle);
- vkAPI.device = (VkDevice)(handle.handles[2].handleValue);
- vkAPI.instance = (VkInstance)(handle.handles[0].handleValue);
+ vkAPI.device = (VkDevice)(handle.handles[2].value);
+ vkAPI.instance = (VkInstance)(handle.handles[0].value);
#if SLANG_WINDOWS_FAMILY
auto dynamicLibraryName = "vulkan-1.dll";
HMODULE module = ::LoadLibraryA(dynamicLibraryName);