summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--build/visual-studio/gfx-unit-test-tool/gfx-unit-test-tool.vcxproj2
-rw-r--r--build/visual-studio/gfx-unit-test-tool/gfx-unit-test-tool.vcxproj.filters6
-rw-r--r--slang-gfx.h10
-rw-r--r--tools/gfx-unit-test/draw-instanced-test.cpp156
-rw-r--r--tools/gfx-unit-test/gfx-test-util.cpp66
-rw-r--r--tools/gfx-unit-test/gfx-test-util.h11
-rw-r--r--tools/gfx-unit-test/graphics-smoke.slang54
-rw-r--r--tools/gfx-unit-test/shared-textures-tests.cpp3
-rw-r--r--tools/gfx/d3d12/render-d3d12.cpp90
-rw-r--r--tools/gfx/vulkan/render-vk.cpp87
-rw-r--r--tools/gfx/vulkan/vk-api.h2
11 files changed, 426 insertions, 61 deletions
diff --git a/build/visual-studio/gfx-unit-test-tool/gfx-unit-test-tool.vcxproj b/build/visual-studio/gfx-unit-test-tool/gfx-unit-test-tool.vcxproj
index 81790de85..285e77752 100644
--- a/build/visual-studio/gfx-unit-test-tool/gfx-unit-test-tool.vcxproj
+++ b/build/visual-studio/gfx-unit-test-tool/gfx-unit-test-tool.vcxproj
@@ -275,6 +275,7 @@
<ClCompile Include="..\..\..\tools\gfx-unit-test\buffer-barrier-test.cpp" />
<ClCompile Include="..\..\..\tools\gfx-unit-test\compute-smoke.cpp" />
<ClCompile Include="..\..\..\tools\gfx-unit-test\create-buffer-from-handle.cpp" />
+ <ClCompile Include="..\..\..\tools\gfx-unit-test\draw-instanced-test.cpp" />
<ClCompile Include="..\..\..\tools\gfx-unit-test\existing-device-handle-test.cpp" />
<ClCompile Include="..\..\..\tools\gfx-unit-test\format-unit-tests.cpp" />
<ClCompile Include="..\..\..\tools\gfx-unit-test\get-buffer-resource-handle-test.cpp" />
@@ -293,6 +294,7 @@
<None Include="..\..\..\tools\gfx-unit-test\compute-smoke.slang" />
<None Include="..\..\..\tools\gfx-unit-test\compute-trivial.slang" />
<None Include="..\..\..\tools\gfx-unit-test\format-test-shaders.slang" />
+ <None Include="..\..\..\tools\gfx-unit-test\graphics-smoke.slang" />
<None Include="..\..\..\tools\gfx-unit-test\mutable-shader-object.slang" />
<None Include="..\..\..\tools\gfx-unit-test\trivial-copy.slang" />
</ItemGroup>
diff --git a/build/visual-studio/gfx-unit-test-tool/gfx-unit-test-tool.vcxproj.filters b/build/visual-studio/gfx-unit-test-tool/gfx-unit-test-tool.vcxproj.filters
index 988f78ef4..60cdbeb60 100644
--- a/build/visual-studio/gfx-unit-test-tool/gfx-unit-test-tool.vcxproj.filters
+++ b/build/visual-studio/gfx-unit-test-tool/gfx-unit-test-tool.vcxproj.filters
@@ -62,6 +62,9 @@
<ClCompile Include="..\..\..\tools\unit-test\slang-unit-test.cpp">
<Filter>Source Files</Filter>
</ClCompile>
+ <ClCompile Include="..\..\..\tools\gfx-unit-test\draw-instanced-test.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="..\..\..\tools\gfx-unit-test\buffer-barrier-test.slang">
@@ -82,5 +85,8 @@
<None Include="..\..\..\tools\gfx-unit-test\trivial-copy.slang">
<Filter>Source Files</Filter>
</None>
+ <None Include="..\..\..\tools\gfx-unit-test\graphics-smoke.slang">
+ <Filter>Source Files</Filter>
+ </None>
</ItemGroup>
</Project> \ No newline at end of file
diff --git a/slang-gfx.h b/slang-gfx.h
index 10fabfa6c..cf5aa8d2b 100644
--- a/slang-gfx.h
+++ b/slang-gfx.h
@@ -1180,8 +1180,8 @@ public:
struct Desc
{
uint32_t renderTargetCount;
- AttachmentLayout* renderTargets;
- AttachmentLayout* depthStencil;
+ AttachmentLayout* renderTargets = nullptr;
+ AttachmentLayout* depthStencil = nullptr;
};
};
#define SLANG_UUID_IFramebufferLayout \
@@ -1335,10 +1335,10 @@ public:
};
struct Desc
{
- IFramebufferLayout* framebufferLayout;
+ IFramebufferLayout* framebufferLayout = nullptr;
uint32_t renderTargetCount;
- AttachmentAccessDesc* renderTargetAccess;
- AttachmentAccessDesc* depthStencilAccess;
+ AttachmentAccessDesc* renderTargetAccess = nullptr;
+ AttachmentAccessDesc* depthStencilAccess = nullptr;
};
};
#define SLANG_UUID_IRenderPassLayout \
diff --git a/tools/gfx-unit-test/draw-instanced-test.cpp b/tools/gfx-unit-test/draw-instanced-test.cpp
new file mode 100644
index 000000000..e15e6beda
--- /dev/null
+++ b/tools/gfx-unit-test/draw-instanced-test.cpp
@@ -0,0 +1,156 @@
+#include "tools/unit-test/slang-unit-test.h"
+
+#include "slang-gfx.h"
+#include "gfx-test-util.h"
+#include "tools/gfx-util/shader-cursor.h"
+#include "source/core/slang-basic.h"
+
+using namespace gfx;
+
+namespace gfx_test
+{
+ struct Vertex
+ {
+ float position[3];
+ float color[3];
+ };
+
+ static const int kVertexCount = 3;
+ static const Vertex kVertexData[kVertexCount] =
+ {
+ { { -1, -1, 0.5 }, { 1, 0, 0 } },
+ { { -1, 3, 0.5 }, { 1, 0, 0 } },
+ { { 3, -1, 0.5 }, { 1, 0, 0 } },
+ };
+
+ void drawInstancedTestImpl(IDevice* device, UnitTestContext* context)
+ {
+ Slang::ComPtr<ITransientResourceHeap> transientHeap;
+ ITransientResourceHeap::Desc transientHeapDesc = {};
+ transientHeapDesc.constantBufferSize = 4096;
+ GFX_CHECK_CALL_ABORT(
+ device->createTransientResourceHeap(transientHeapDesc, transientHeap.writeRef()));
+
+ ComPtr<IShaderProgram> shaderProgram;
+ slang::ProgramLayout* slangReflection;
+ GFX_CHECK_CALL_ABORT(loadGraphicsProgram(device, shaderProgram, "graphics-smoke", "vertexMain", "fragmentMain", slangReflection));
+
+ Format format = Format::R32G32B32A32_FLOAT;
+
+ InputElementDesc inputElements[] = {
+ { "POSITION", 0, Format::R32G32B32_FLOAT, offsetof(Vertex, position) },
+ { "COLOR", 0, Format::R32G32B32_FLOAT, offsetof(Vertex, color) },
+ };
+ ComPtr<gfx::IInputLayout> inputLayout = device->createInputLayout(inputElements, 2);
+ SLANG_CHECK_ABORT(inputLayout != nullptr);
+
+ IBufferResource::Desc vertexBufferDesc;
+ vertexBufferDesc.type = IResource::Type::Buffer;
+ vertexBufferDesc.sizeInBytes = kVertexCount * sizeof(Vertex);
+ vertexBufferDesc.defaultState = ResourceState::VertexBuffer;
+ vertexBufferDesc.allowedStates = ResourceState::VertexBuffer;
+ ComPtr<IBufferResource> vertexBuffer = device->createBufferResource(vertexBufferDesc, &kVertexData[0]);
+ SLANG_CHECK_ABORT(vertexBuffer != nullptr);
+
+ IFramebufferLayout::AttachmentLayout attachmentLayout;
+ attachmentLayout.format = format;
+ attachmentLayout.sampleCount = 1;
+
+ IFramebufferLayout::Desc framebufferLayoutDesc;
+ framebufferLayoutDesc.renderTargetCount = 1;
+ framebufferLayoutDesc.renderTargets = &attachmentLayout;
+ ComPtr<gfx::IFramebufferLayout> framebufferLayout = device->createFramebufferLayout(framebufferLayoutDesc);
+
+ GraphicsPipelineStateDesc pipelineDesc = {};
+ pipelineDesc.program = shaderProgram.get();
+ pipelineDesc.inputLayout = inputLayout;
+ pipelineDesc.framebufferLayout = framebufferLayout;
+ pipelineDesc.depthStencil.depthTestEnable = false;
+ pipelineDesc.depthStencil.depthWriteEnable = false;
+ ComPtr<gfx::IPipelineState> pipelineState;
+ GFX_CHECK_CALL_ABORT(
+ device->createGraphicsPipelineState(pipelineDesc, pipelineState.writeRef()));
+
+ ICommandQueue::Desc queueDesc = { ICommandQueue::QueueType::Graphics };
+ auto queue = device->createCommandQueue(queueDesc);
+ auto commandBuffer = transientHeap->createCommandBuffer();
+
+ IRenderPassLayout::Desc renderPassDesc = {};
+ renderPassDesc.framebufferLayout = framebufferLayout;
+ renderPassDesc.renderTargetCount = 1;
+ IRenderPassLayout::AttachmentAccessDesc renderTargetAccess = {};
+ renderTargetAccess.loadOp = IRenderPassLayout::AttachmentLoadOp::Clear;
+ renderTargetAccess.storeOp = IRenderPassLayout::AttachmentStoreOp::Store;
+ renderTargetAccess.initialState = ResourceState::Undefined;
+ renderTargetAccess.finalState = ResourceState::CopySource;
+ renderPassDesc.renderTargetAccess = &renderTargetAccess;
+ ComPtr<IRenderPassLayout> renderPass = device->createRenderPassLayout(renderPassDesc);
+
+ const int width = 2;
+ const int height = 2;
+
+ gfx::ITextureResource::Desc colorBufferDesc;
+ colorBufferDesc.type = IResource::Type::Texture2D;
+ colorBufferDesc.size.width = width;
+ colorBufferDesc.size.height = height;
+ colorBufferDesc.size.depth = 1;
+ colorBufferDesc.numMipLevels = 1;
+ colorBufferDesc.format = format;
+ colorBufferDesc.defaultState = ResourceState::RenderTarget;
+ colorBufferDesc.allowedStates = { ResourceState::RenderTarget, ResourceState::CopySource };
+ ComPtr<ITextureResource> colorBuffer = device->createTextureResource(colorBufferDesc, nullptr);
+
+ gfx::IResourceView::Desc colorBufferViewDesc;
+ memset(&colorBufferViewDesc, 0, sizeof(colorBufferViewDesc));
+ colorBufferViewDesc.format = format;
+ colorBufferViewDesc.renderTarget.shape = gfx::IResource::Type::Texture2D;
+ colorBufferViewDesc.type = gfx::IResourceView::Type::RenderTarget;
+ ComPtr<gfx::IResourceView> rtv =
+ device->createTextureView(colorBuffer.get(), colorBufferViewDesc);
+
+ gfx::IFramebuffer::Desc framebufferDesc;
+ framebufferDesc.renderTargetCount = 1;
+ framebufferDesc.depthStencilView = nullptr;
+ framebufferDesc.renderTargetViews = rtv.readRef();
+ framebufferDesc.layout = framebufferLayout;
+ ComPtr<gfx::IFramebuffer> framebuffer = device->createFramebuffer(framebufferDesc);
+
+ auto encoder = commandBuffer->encodeRenderCommands(renderPass, framebuffer);
+ auto rootObject = encoder->bindPipeline(pipelineState);
+
+ UInt vertexCount = 3;
+ UInt instanceCount = 1;
+ UInt startVertex = 0;
+ UInt startInstanceLocation = 0;
+
+ gfx::Viewport viewport = {};
+ viewport.maxZ = 1.0f;
+ viewport.extentX = width;
+ viewport.extentY = height;
+ encoder->setViewportAndScissor(viewport);
+
+ encoder->setVertexBuffer(0, vertexBuffer, sizeof(Vertex));
+ encoder->setPrimitiveTopology(PrimitiveTopology::TriangleList);
+ encoder->drawInstanced(vertexCount, instanceCount, startVertex, startInstanceLocation);
+ encoder->endEncoding();
+ commandBuffer->close();
+ queue->executeCommandBuffer(commandBuffer);
+ queue->waitOnHost();
+
+ float expectedResult[] = { 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f,
+ 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f };
+ compareComputeResult(device, colorBuffer, ResourceState::CopySource, expectedResult, 32, 2);
+ }
+
+ SLANG_UNIT_TEST(drawInstancedD3D12)
+ {
+ runTestImpl(drawInstancedTestImpl, unitTestContext, Slang::RenderApiFlag::D3D12);
+ }
+
+#if 0
+ SLANG_UNIT_TEST(drawInstancedVulkan)
+ {
+ runTestImpl(drawInstancedTestImpl, unitTestContext, Slang::RenderApiFlag::Vulkan);
+ }
+#endif
+ }
diff --git a/tools/gfx-unit-test/gfx-test-util.cpp b/tools/gfx-unit-test/gfx-test-util.cpp
index e1da919d8..619d2feb0 100644
--- a/tools/gfx-unit-test/gfx-test-util.cpp
+++ b/tools/gfx-unit-test/gfx-test-util.cpp
@@ -65,7 +65,61 @@ namespace gfx_test
return SLANG_OK;
}
- void compareComputeResult(gfx::IDevice* device, gfx::ITextureResource* texture, gfx::ResourceState state, float* expectedResult, size_t expectedBufferSize)
+ Slang::Result loadGraphicsProgram(
+ gfx::IDevice* device,
+ Slang::ComPtr<gfx::IShaderProgram>& outShaderProgram,
+ const char* shaderModuleName,
+ const char* vertexEntryPointName,
+ const char* fragmentEntryPointName,
+ slang::ProgramLayout*& slangReflection)
+ {
+ Slang::ComPtr<slang::ISession> slangSession;
+ SLANG_RETURN_ON_FAIL(device->getSlangSession(slangSession.writeRef()));
+ Slang::ComPtr<slang::IBlob> diagnosticsBlob;
+ slang::IModule* module = slangSession->loadModule(shaderModuleName, diagnosticsBlob.writeRef());
+ diagnoseIfNeeded(diagnosticsBlob);
+ if (!module)
+ return SLANG_FAIL;
+
+ ComPtr<slang::IEntryPoint> vertexEntryPoint;
+ SLANG_RETURN_ON_FAIL(
+ module->findEntryPointByName(vertexEntryPointName, vertexEntryPoint.writeRef()));
+
+ ComPtr<slang::IEntryPoint> fragmentEntryPoint;
+ SLANG_RETURN_ON_FAIL(
+ module->findEntryPointByName(fragmentEntryPointName, fragmentEntryPoint.writeRef()));
+
+ Slang::List<slang::IComponentType*> componentTypes;
+ componentTypes.add(module);
+ componentTypes.add(vertexEntryPoint);
+ componentTypes.add(fragmentEntryPoint);
+
+ Slang::ComPtr<slang::IComponentType> composedProgram;
+ SlangResult result = slangSession->createCompositeComponentType(
+ componentTypes.getBuffer(),
+ componentTypes.getCount(),
+ composedProgram.writeRef(),
+ diagnosticsBlob.writeRef());
+ diagnoseIfNeeded(diagnosticsBlob);
+ SLANG_RETURN_ON_FAIL(result);
+ slangReflection = composedProgram->getLayout();
+
+ gfx::IShaderProgram::Desc programDesc = {};
+ programDesc.slangProgram = composedProgram.get();
+
+ auto shaderProgram = device->createProgram(programDesc);
+
+ outShaderProgram = shaderProgram;
+ return SLANG_OK;
+ }
+
+ void compareComputeResult(
+ gfx::IDevice* device,
+ gfx::ITextureResource* texture,
+ gfx::ResourceState state,
+ float* expectedResult,
+ size_t expectedResultRowPitch,
+ size_t rowCount)
{
// Read back the results.
ComPtr<ISlangBlob> resultBlob;
@@ -73,10 +127,16 @@ namespace gfx_test
size_t pixelSize = 0;
GFX_CHECK_CALL_ABORT(device->readTextureResource(
texture, state, resultBlob.writeRef(), &rowPitch, &pixelSize));
- SLANG_CHECK(resultBlob->getBufferSize() == expectedBufferSize);
auto result = (float*)resultBlob->getBufferPointer();
// Compare results.
- SLANG_CHECK(memcmp(resultBlob->getBufferPointer(), expectedResult, expectedBufferSize) == 0);
+ for (size_t row = 0; row < rowCount; row++)
+ {
+ SLANG_CHECK(
+ memcmp(
+ (uint8_t*)resultBlob->getBufferPointer() + rowPitch * row,
+ (uint8_t*)expectedResult + expectedResultRowPitch * row,
+ expectedResultRowPitch) == 0);
+ }
}
void compareComputeResult(gfx::IDevice* device, gfx::IBufferResource* buffer, uint8_t* expectedResult, size_t expectedBufferSize)
diff --git a/tools/gfx-unit-test/gfx-test-util.h b/tools/gfx-unit-test/gfx-test-util.h
index 07513c39a..addcb151b 100644
--- a/tools/gfx-unit-test/gfx-test-util.h
+++ b/tools/gfx-unit-test/gfx-test-util.h
@@ -18,6 +18,14 @@ namespace gfx_test
const char* entryPointName,
slang::ProgramLayout*& slangReflection);
+ Slang::Result loadGraphicsProgram(
+ gfx::IDevice* device,
+ Slang::ComPtr<gfx::IShaderProgram>& outShaderProgram,
+ const char* shaderModuleName,
+ const char* vertexEntryPointName,
+ const char* fragmentEntryPointName,
+ slang::ProgramLayout*& slangReflection);
+
/// Reads back the content of `buffer` and compares it against `expectedResult`.
void compareComputeResult(
gfx::IDevice* device,
@@ -31,7 +39,8 @@ namespace gfx_test
gfx::ITextureResource* texture,
gfx::ResourceState state,
float* expectedResult,
- size_t expectedBufferSize);
+ size_t expectedResultRowPitch,
+ size_t rowCount);
/// Reads back the content of `buffer` and compares it against `expectedResult` with a set tolerance.
void compareComputeResultFuzzy(
diff --git a/tools/gfx-unit-test/graphics-smoke.slang b/tools/gfx-unit-test/graphics-smoke.slang
new file mode 100644
index 000000000..145b83a62
--- /dev/null
+++ b/tools/gfx-unit-test/graphics-smoke.slang
@@ -0,0 +1,54 @@
+// graphics-smoke.slang
+
+// Per-vertex attributes to be assembled from bound vertex buffers.
+struct AssembledVertex
+{
+ float3 position : POSITION;
+ float3 color : COLOR;
+};
+
+// Output of the vertex shader, and input to the fragment shader.
+struct CoarseVertex
+{
+ float3 color;
+};
+
+// Output of the fragment shader
+struct Fragment
+{
+ float4 color;
+};
+
+// Vertex Shader
+
+struct VertexStageOutput
+{
+ CoarseVertex coarseVertex : CoarseVertex;
+ float4 sv_position : SV_Position;
+};
+
+[shader("vertex")]
+VertexStageOutput vertexMain(
+ AssembledVertex assembledVertex)
+{
+ VertexStageOutput output;
+
+ float3 position = assembledVertex.position;
+ float3 color = assembledVertex.color;
+
+ output.coarseVertex.color = color;
+ output.sv_position = float4(position, 1.0);
+
+ return output;
+}
+
+// Fragment Shader
+
+[shader("fragment")]
+float4 fragmentMain(
+ CoarseVertex coarseVertex : CoarseVertex) : SV_Target
+{
+ float3 color = coarseVertex.color;
+
+ return float4(color, 1.0);
+}
diff --git a/tools/gfx-unit-test/shared-textures-tests.cpp b/tools/gfx-unit-test/shared-textures-tests.cpp
index 896d6d6e6..d32a8493e 100644
--- a/tools/gfx-unit-test/shared-textures-tests.cpp
+++ b/tools/gfx-unit-test/shared-textures-tests.cpp
@@ -184,7 +184,8 @@ namespace gfx_test
dstTexture,
ResourceState::ShaderResource,
texData,
- sizeof(texData));
+ 32,
+ 2);
auto texView = createTexView(dstDevice, dstTexture);
setUpAndRunShader(dstDevice, dstTexture, texView, floatBufferView, "copyTexFloat4");
diff --git a/tools/gfx/d3d12/render-d3d12.cpp b/tools/gfx/d3d12/render-d3d12.cpp
index 28128a04d..689c9c087 100644
--- a/tools/gfx/d3d12/render-d3d12.cpp
+++ b/tools/gfx/d3d12/render-d3d12.cpp
@@ -3424,12 +3424,29 @@ public:
IBufferResource* countBuffer,
uint64_t countOffset) override
{
- SLANG_UNUSED(maxDrawCount);
- SLANG_UNUSED(argBuffer);
- SLANG_UNUSED(argOffset);
- SLANG_UNUSED(countBuffer);
- SLANG_UNUSED(countOffset);
- SLANG_UNIMPLEMENTED_X("drawIndirect");
+ prepareDraw();
+
+ D3D12_INDIRECT_ARGUMENT_DESC args[1];
+ args[0].Type = D3D12_INDIRECT_ARGUMENT_TYPE_DRAW;
+
+ D3D12_COMMAND_SIGNATURE_DESC desc;
+ desc.ByteStride = 36;
+ desc.NumArgumentDescs = 1;
+ desc.pArgumentDescs = args;
+
+ ComPtr<ID3D12CommandSignature> cmdSignature = nullptr;
+ if (FAILED(m_device->CreateCommandSignature(&desc, nullptr, IID_PPV_ARGS(cmdSignature.writeRef()))))
+ {
+ return;
+ }
+
+ m_d3dCmdList->ExecuteIndirect(
+ cmdSignature,
+ maxDrawCount,
+ (ID3D12Resource*)argBuffer,
+ argOffset,
+ (ID3D12Resource*)countBuffer,
+ countOffset);
}
virtual SLANG_NO_THROW void SLANG_MCALL drawIndexedIndirect(
@@ -3439,12 +3456,29 @@ public:
IBufferResource* countBuffer,
uint64_t countOffset) override
{
- SLANG_UNUSED(maxDrawCount);
- SLANG_UNUSED(argBuffer);
- SLANG_UNUSED(argOffset);
- SLANG_UNUSED(countBuffer);
- SLANG_UNUSED(countOffset);
- SLANG_UNIMPLEMENTED_X("drawIndirect");
+ prepareDraw();
+
+ D3D12_INDIRECT_ARGUMENT_DESC args[1];
+ args[0].Type = D3D12_INDIRECT_ARGUMENT_TYPE_DRAW_INDEXED;
+
+ D3D12_COMMAND_SIGNATURE_DESC desc;
+ desc.ByteStride = 36;
+ desc.NumArgumentDescs = 1;
+ desc.pArgumentDescs = args;
+
+ ComPtr<ID3D12CommandSignature> cmdSignature = nullptr;
+ if (FAILED(m_device->CreateCommandSignature(&desc, nullptr, IID_PPV_ARGS(cmdSignature.writeRef()))))
+ {
+ return;
+ }
+
+ m_d3dCmdList->ExecuteIndirect(
+ cmdSignature,
+ maxDrawCount,
+ (ID3D12Resource*)argBuffer,
+ argOffset,
+ (ID3D12Resource*)countBuffer,
+ countOffset);
}
virtual SLANG_NO_THROW Result SLANG_MCALL setSamplePositions(
@@ -3464,11 +3498,8 @@ public:
UInt startVertex,
UInt startInstanceLocation) override
{
- SLANG_UNUSED(vertexCount);
- SLANG_UNUSED(instanceCount);
- SLANG_UNUSED(startVertex);
- SLANG_UNUSED(startInstanceLocation);
- SLANG_UNIMPLEMENTED_X("drawInstanced");
+ prepareDraw();
+ m_d3dCmdList->DrawInstanced(vertexCount, instanceCount, startVertex, startInstanceLocation);
}
virtual SLANG_NO_THROW void SLANG_MCALL drawIndexedInstanced(
@@ -3478,12 +3509,8 @@ public:
int32_t baseVertexLocation,
uint32_t startInstanceLocation) override
{
- SLANG_UNUSED(indexCount);
- SLANG_UNUSED(instanceCount);
- SLANG_UNUSED(startIndexLocation);
- SLANG_UNUSED(baseVertexLocation);
- SLANG_UNUSED(startInstanceLocation);
- SLANG_UNIMPLEMENTED_X("drawIndexedInstanced");
+ prepareDraw();
+ m_d3dCmdList->DrawIndexedInstanced(indexCount, instanceCount, startIndexLocation, baseVertexLocation, startInstanceLocation);
}
};
@@ -4145,7 +4172,7 @@ public:
bool isShared = false);
Result captureTextureToSurface(
- D3D12Resource& resource,
+ TextureResourceImpl* resource,
ResourceState state,
ISlangBlob** blob,
size_t* outRowPitch,
@@ -4485,14 +4512,17 @@ Result D3D12Device::createBuffer(const D3D12_RESOURCE_DESC& resourceDesc, const
}
Result D3D12Device::captureTextureToSurface(
- D3D12Resource& resource,
+ TextureResourceImpl* resourceImpl,
ResourceState state,
ISlangBlob** outBlob,
size_t* outRowPitch,
size_t* outPixelSize)
{
+ auto resource = resourceImpl->m_resource;
+
const D3D12_RESOURCE_STATES initialState = D3DUtil::translateResourceState(state);
+ const ITextureResource::Desc& gfxDesc = *resourceImpl->getDesc();
const D3D12_RESOURCE_DESC desc = resource.getResource()->GetDesc();
// Don't bother supporting MSAA for right now
@@ -4502,8 +4532,12 @@ Result D3D12Device::captureTextureToSurface(
return SLANG_FAIL;
}
- size_t bytesPerPixel = sizeof(uint32_t);
+ FormatInfo formatInfo;
+ gfxGetFormatInfo(gfxDesc.format, &formatInfo);
+ size_t bytesPerPixel = formatInfo.blockSizeInBytes / formatInfo.pixelsPerBlock;
size_t rowPitch = int(desc.Width) * bytesPerPixel;
+ static const size_t align = 256; // D3D requires minimum 256 byte alignment for texture data.
+ rowPitch = (rowPitch + align - 1) & ~(align - 1); // Bit trick for rounding up
size_t bufferSize = rowPitch * int(desc.Height);
if (outRowPitch)
*outRowPitch = rowPitch;
@@ -5023,7 +5057,7 @@ SlangResult D3D12Device::readTextureResource(
size_t* outPixelSize)
{
return captureTextureToSurface(
- static_cast<TextureResourceImpl*>(resource)->m_resource,
+ static_cast<TextureResourceImpl*>(resource),
state,
outBlob,
outRowPitch,
@@ -6097,7 +6131,7 @@ Result D3D12Device::createGraphicsPipelineState(const GraphicsPipelineStateDesc&
}
else
{
- psoDesc.DSVFormat = DXGI_FORMAT_D32_FLOAT;
+ psoDesc.DSVFormat = DXGI_FORMAT_UNKNOWN;
if (framebufferLayout->m_renderTargets.getCount())
{
psoDesc.SampleDesc.Count = framebufferLayout->m_renderTargets[0].sampleCount;
diff --git a/tools/gfx/vulkan/render-vk.cpp b/tools/gfx/vulkan/render-vk.cpp
index c48faeb7b..015f7e415 100644
--- a/tools/gfx/vulkan/render-vk.cpp
+++ b/tools/gfx/vulkan/render-vk.cpp
@@ -4093,12 +4093,19 @@ public:
IBufferResource* countBuffer,
uint64_t countOffset) override
{
- SLANG_UNUSED(maxDrawCount);
- SLANG_UNUSED(argBuffer);
- SLANG_UNUSED(argOffset);
- SLANG_UNUSED(countBuffer);
- SLANG_UNUSED(countOffset);
- SLANG_UNIMPLEMENTED_X("drawIndirect");
+ prepareDraw();
+ auto& api = *m_api;
+ // Bind the vertex buffer
+ if (m_boundVertexBuffers.getCount() > 0 && m_boundVertexBuffers[0].m_buffer)
+ {
+ const BoundVertexBuffer& boundVertexBuffer = m_boundVertexBuffers[0];
+
+ VkBuffer vertexBuffers[] = { boundVertexBuffer.m_buffer->m_buffer.m_buffer };
+ VkDeviceSize offsets[] = { VkDeviceSize(boundVertexBuffer.m_offset) };
+
+ api.vkCmdBindVertexBuffers(m_vkCommandBuffer, 0, 1, vertexBuffers, offsets);
+ }
+ api.vkCmdDrawIndirect(m_vkCommandBuffer, (VkBuffer)argBuffer, argOffset, maxDrawCount, sizeof(VkDrawIndirectCommand));
}
virtual SLANG_NO_THROW void SLANG_MCALL drawIndexedIndirect(
@@ -4108,12 +4115,24 @@ public:
IBufferResource* countBuffer,
uint64_t countOffset) override
{
- SLANG_UNUSED(maxDrawCount);
- SLANG_UNUSED(argBuffer);
- SLANG_UNUSED(argOffset);
- SLANG_UNUSED(countBuffer);
- SLANG_UNUSED(countOffset);
- SLANG_UNIMPLEMENTED_X("drawIndirect");
+ prepareDraw();
+ auto& api = *m_api;
+ api.vkCmdBindIndexBuffer(
+ m_vkCommandBuffer,
+ m_boundIndexBuffer.m_buffer->m_buffer.m_buffer,
+ m_boundIndexBuffer.m_offset,
+ m_boundIndexFormat);
+ // Bind the vertex buffer
+ if (m_boundVertexBuffers.getCount() > 0 && m_boundVertexBuffers[0].m_buffer)
+ {
+ const BoundVertexBuffer& boundVertexBuffer = m_boundVertexBuffers[0];
+
+ VkBuffer vertexBuffers[] = { boundVertexBuffer.m_buffer->m_buffer.m_buffer };
+ VkDeviceSize offsets[] = { VkDeviceSize(boundVertexBuffer.m_offset) };
+
+ api.vkCmdBindVertexBuffers(m_vkCommandBuffer, 0, 1, vertexBuffers, offsets);
+ }
+ api.vkCmdDrawIndirect(m_vkCommandBuffer, (VkBuffer)argBuffer, argOffset, maxDrawCount, sizeof(VkDrawIndexedIndirectCommand));
}
virtual SLANG_NO_THROW Result SLANG_MCALL setSamplePositions(
@@ -4133,11 +4152,20 @@ public:
UInt startVertex,
UInt startInstanceLocation) override
{
- SLANG_UNUSED(vertexCount);
- SLANG_UNUSED(instanceCount);
- SLANG_UNUSED(startVertex);
- SLANG_UNUSED(startInstanceLocation);
- SLANG_UNIMPLEMENTED_X("drawInstanced");
+ prepareDraw();
+ auto& api = *m_api;
+ // Bind the vertex buffer
+ if (m_boundVertexBuffers.getCount() > 0 && m_boundVertexBuffers[0].m_buffer)
+ {
+ const BoundVertexBuffer& boundVertexBuffer = m_boundVertexBuffers[0];
+
+ VkBuffer vertexBuffers[] = { boundVertexBuffer.m_buffer->m_buffer.m_buffer };
+ VkDeviceSize offsets[] = { VkDeviceSize(boundVertexBuffer.m_offset) };
+
+ api.vkCmdBindVertexBuffers(m_vkCommandBuffer, 0, 1, vertexBuffers, offsets);
+ }
+ api.vkCmdDraw(m_vkCommandBuffer, static_cast<uint32_t>(vertexCount), static_cast<uint32_t>(instanceCount),
+ static_cast<uint32_t>(startVertex), static_cast<uint32_t>(startInstanceLocation));
}
virtual SLANG_NO_THROW void SLANG_MCALL drawIndexedInstanced(
@@ -4147,12 +4175,25 @@ public:
int32_t baseVertexLocation,
uint32_t startInstanceLocation) override
{
- SLANG_UNUSED(indexCount);
- SLANG_UNUSED(instanceCount);
- SLANG_UNUSED(startIndexLocation);
- SLANG_UNUSED(baseVertexLocation);
- SLANG_UNUSED(startInstanceLocation);
- SLANG_UNIMPLEMENTED_X("drawIndexedInstanced");
+ prepareDraw();
+ auto& api = *m_api;
+ api.vkCmdBindIndexBuffer(
+ m_vkCommandBuffer,
+ m_boundIndexBuffer.m_buffer->m_buffer.m_buffer,
+ m_boundIndexBuffer.m_offset,
+ m_boundIndexFormat);
+ // Bind the vertex buffer
+ if (m_boundVertexBuffers.getCount() > 0 && m_boundVertexBuffers[0].m_buffer)
+ {
+ const BoundVertexBuffer& boundVertexBuffer = m_boundVertexBuffers[0];
+
+ VkBuffer vertexBuffers[] = { boundVertexBuffer.m_buffer->m_buffer.m_buffer };
+ VkDeviceSize offsets[] = { VkDeviceSize(boundVertexBuffer.m_offset) };
+
+ api.vkCmdBindVertexBuffers(m_vkCommandBuffer, 0, 1, vertexBuffers, offsets);
+ }
+ api.vkCmdDraw(m_vkCommandBuffer, static_cast<uint32_t>(indexCount), static_cast<uint32_t>(instanceCount),
+ static_cast<uint32_t>(baseVertexLocation), static_cast<uint32_t>(startInstanceLocation));
}
};
diff --git a/tools/gfx/vulkan/vk-api.h b/tools/gfx/vulkan/vk-api.h
index 81cfce973..9cbff8ee4 100644
--- a/tools/gfx/vulkan/vk-api.h
+++ b/tools/gfx/vulkan/vk-api.h
@@ -85,6 +85,8 @@ namespace gfx {
x(vkCmdBindDescriptorSets) \
x(vkCmdDispatch) \
x(vkCmdDraw) \
+ x(vkCmdDrawIndirect) \
+ x(vkCmdDrawIndexedIndirect) \
x(vkCmdSetScissor) \
x(vkCmdSetViewport) \
x(vkCmdBindVertexBuffers) \