summaryrefslogtreecommitdiffstats
path: root/examples
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 /examples
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>
Diffstat (limited to 'examples')
-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
15 files changed, 1270 insertions, 1477 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();
}
}
};