Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions include/Support/Pipeline.h
Original file line number Diff line number Diff line change
Expand Up @@ -383,11 +383,11 @@ struct VertexAttribute {

struct IOBindings {
std::string VertexBuffer;
CPUBuffer *VertexBufferPtr;
CPUBuffer *VertexBufferPtr = nullptr;
llvm::SmallVector<VertexAttribute> VertexAttributes;

std::string RenderTarget;
CPUBuffer *RTargetBufferPtr;
CPUBuffer *RTargetBufferPtr = nullptr;

uint32_t getVertexStride() const {
uint32_t Stride = 0;
Expand Down
52 changes: 21 additions & 31 deletions lib/API/DX/Device.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1638,6 +1638,16 @@ class DXDevice : public offloadtest::Device {
if (auto Err = CreateBuffer(Resource, IS.RootResources))
return Err;
}

if (P.isTraditionalRaster() && P.Bindings.VertexBufferPtr) {
auto VBOrErr = offloadtest::createVertexBufferFromCPUBuffer(
*this, *P.Bindings.VertexBufferPtr);
if (!VBOrErr)
return VBOrErr.takeError();
IS.VB = std::move(*VBOrErr);
llvm::outs() << "Vertex buffer created.\n";
}

return llvm::Error::success();
}

Expand Down Expand Up @@ -1911,39 +1921,11 @@ class DXDevice : public offloadtest::Device {
return llvm::Error::success();
}

llvm::Error createVertexBuffer(Pipeline &P, InvocationState &IS) {
if (!P.Bindings.VertexBufferPtr)
return llvm::createStringError(
std::errc::invalid_argument,
"No vertex buffer bound for graphics pipeline.");

auto VBOrErr = offloadtest::createVertexBufferFromCPUBuffer(
*this, *P.Bindings.VertexBufferPtr);
if (!VBOrErr)
return VBOrErr.takeError();
IS.VB = std::move(*VBOrErr);

auto &VBBuf = llvm::cast<DXBuffer>(*IS.VB);
D3D12_VERTEX_BUFFER_VIEW VBView = {};
VBView.BufferLocation = VBBuf.Buffer->GetGPUVirtualAddress();
VBView.SizeInBytes = static_cast<UINT>(IS.VB->getSizeInBytes());
VBView.StrideInBytes = P.Bindings.getVertexStride();

IS.CB->CmdList->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
IS.CB->CmdList->IASetVertexBuffers(0, 1, &VBView);

return llvm::Error::success();
}

llvm::Error createGraphicsCommands(Pipeline &P, InvocationState &IS) {
auto &RT = llvm::cast<DXTexture>(*IS.RT);
auto &DS = llvm::cast<DXTexture>(*IS.DS);
auto &RTReadback = llvm::cast<DXBuffer>(*IS.RTReadback);

if (!IS.VB)
return llvm::createStringError(std::errc::invalid_argument,
"Vertex buffer not initialized.");

const DXPipelineState &DXPipeline =
llvm::cast<DXPipelineState>(*IS.Pipeline.get());
IS.CB->CmdList->SetGraphicsRootSignature(DXPipeline.RootSig.Get());
Expand Down Expand Up @@ -1981,6 +1963,17 @@ class DXDevice : public offloadtest::Device {
static_cast<LONG>(VP.Height)};
IS.CB->CmdList->RSSetScissorRects(1, &Scissor);

if (IS.VB) {
auto &VBBuf = llvm::cast<DXBuffer>(*IS.VB);
D3D12_VERTEX_BUFFER_VIEW VBView = {};
VBView.BufferLocation = VBBuf.Buffer->GetGPUVirtualAddress();
VBView.SizeInBytes = static_cast<UINT>(IS.VB->getSizeInBytes());
VBView.StrideInBytes = P.Bindings.getVertexStride();
IS.CB->CmdList->IASetVertexBuffers(0, 1, &VBView);
}

IS.CB->CmdList->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);

IS.CB->CmdList->DrawInstanced(P.getVertexCount(), 1, 0, 0);

// Transition the render target to copy source and copy to the readback
Expand Down Expand Up @@ -2108,9 +2101,6 @@ class DXDevice : public offloadtest::Device {
if (auto Err = createDepthStencil(P, State))
return Err;
llvm::outs() << "Depth stencil created.\n";
if (auto Err = createVertexBuffer(P, State))
return Err;
llvm::outs() << "Vertex buffer created.\n";

ShaderContainer VS = {};
ShaderContainer PS = {};
Expand Down
19 changes: 8 additions & 11 deletions lib/API/MTL/MTLDevice.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -955,17 +955,13 @@ class MTLDevice : public offloadtest::Device {
}
}

if (P.isTraditionalRaster()) {
if (!P.Bindings.VertexBufferPtr)
return llvm::createStringError(
std::errc::invalid_argument,
"No vertex buffer specified for graphics pipeline.");

if (P.isTraditionalRaster() && P.Bindings.VertexBufferPtr) {
auto VBOrErr = offloadtest::createVertexBufferFromCPUBuffer(
*this, *P.Bindings.VertexBufferPtr);
if (!VBOrErr)
return VBOrErr.takeError();
IS.VB = std::move(*VBOrErr);
llvm::outs() << "Vertex buffer created.\n";
}
return llvm::Error::success();
}
Expand Down Expand Up @@ -1146,9 +1142,10 @@ class MTLDevice : public offloadtest::Device {
CmdEncoder->setCullMode(MTL::CullModeNone);
CmdEncoder->setFrontFacingWinding(MTL::WindingCounterClockwise);

// Bind vertex buffer at slot 0 to match the vertex descriptor which
// references buffer index 0.
CmdEncoder->setVertexBuffer(llvm::cast<MTLBuffer>(*IS.VB).Buf, 0, 0);
if (IS.VB)
// Bind vertex buffer at slot 0 to match the vertex descriptor which
// references buffer index 0.
CmdEncoder->setVertexBuffer(llvm::cast<MTLBuffer>(*IS.VB).Buf, 0, 0);

CmdEncoder->drawPrimitives(MTL::PrimitiveTypeTriangle, NS::UInteger(0),
P.getVertexCount());
Expand Down Expand Up @@ -1388,8 +1385,8 @@ class MTLDevice : public offloadtest::Device {
"Mismatch between vertex shader attribute count and pipeline "
"vertex input count.");

// Collect the attribute indices the shader expects so that we can map the
// specified attributes onto the correct indices.
// Collect the attribute indices the shader expects so that we can map
// the specified attributes onto the correct indices.
llvm::StringMap<uint32_t> ShaderAttrIndices;
for (uint32_t I = 0; I < FnAttrs->count(); ++I) {
auto *A = static_cast<MTL::VertexAttribute *>(FnAttrs->object(I));
Expand Down
15 changes: 7 additions & 8 deletions lib/API/VK/Device.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1931,17 +1931,15 @@ class VulkanDevice : public offloadtest::Device {
// conditional on the pipeline definition.
if (auto Err = createDepthStencil(P, IS))
return Err;
}

if (P.Bindings.VertexBufferPtr == nullptr)
return llvm::createStringError(
std::errc::invalid_argument,
"No Vertex buffer specified for graphics pipeline.");

if (P.isTraditionalRaster() && P.Bindings.VertexBufferPtr) {
auto VBOrErr = offloadtest::createVertexBufferFromCPUBuffer(
*this, *P.Bindings.VertexBufferPtr);
if (!VBOrErr)
return VBOrErr.takeError();
IS.VB = std::move(*VBOrErr);
llvm::outs() << "Vertex buffer created.\n";
}

return llvm::Error::success();
Expand Down Expand Up @@ -2737,9 +2735,10 @@ class VulkanDevice : public offloadtest::Device {
<< P.DispatchParameters.DispatchGroupCount[2] << " }\n";
} else {
VkDeviceSize Offsets[1]{0};
assert(IS.VB);
VkBuffer VBHandle = llvm::cast<VulkanBuffer>(*IS.VB).Buffer;
vkCmdBindVertexBuffers(IS.CB->CmdBuffer, 0, 1, &VBHandle, Offsets);
if (IS.VB) {
VkBuffer VBHandle = llvm::cast<VulkanBuffer>(*IS.VB).Buffer;
vkCmdBindVertexBuffers(IS.CB->CmdBuffer, 0, 1, &VBHandle, Offsets);
}
// instanceCount must be >=1 to draw; previously was 0 which draws nothing
vkCmdDraw(IS.CB->CmdBuffer, P.getVertexCount(), 1, 0, 0);
llvm::outs() << "Drew " << P.getVertexCount() << " vertices.\n";
Expand Down
74 changes: 74 additions & 0 deletions test/Graphics/VerticesFromVertexID.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
#--- vertex.hlsl
struct PSInput
{
float4 position : SV_POSITION;
float4 color : COLOR;
};

PSInput main(uint vertexID : SV_VertexID)
{
PSInput result;

if (vertexID == 0) {
result.position = float4(0.0, 0.25, 0.0, 1.0);
result.color = float4(1.0, 0.0, 0.0, 1.0);
} else if (vertexID == 1) {
result.position = float4(0.25, -0.25, 0.0, 1.0);
result.color = float4(0.0, 1.0, 0.0, 1.0);
} else {
result.position = float4(-0.25, -0.25, 0.0, 1.0);
result.color = float4(0.0, 0.0, 1.0, 1.0);
}

return result;
}


#--- pixel.hlsl
struct PSInput
{
float4 position : SV_POSITION;
float4 color : COLOR;
};

float4 main(PSInput input) : SV_TARGET
{
return input.color;
}
#--- pipeline.yaml
---
Shaders:
- Stage: Vertex
Entry: main
- Stage: Pixel
Entry: main
Buffers:
- Name: Output
Format: Float32
Channels: 4
FillSize: 1048576 # 256x256 @ 16 bytes per pixel
OutputProps:
Height: 256
Width: 256
Depth: 1
Bindings:
RenderTarget: Output
DescriptorSets: []
DispatchParameters:
VertexCount: 3
...
#--- rules.yaml
---
- Type: PixelPercent
Val: 0.2 # No more than 0.2% of pixels may be visibly different.
...
#--- end

# XFAIL: Clang && !Vulkan
# REQUIRES: goldenimage

# RUN: split-file %s %t
# RUN: %dxc_target -T vs_6_0 -Fo %t-vertex.o %t/vertex.hlsl
# RUN: %dxc_target -T ps_6_0 -Fo %t-pixel.o %t/pixel.hlsl
# RUN: %offloader %t/pipeline.yaml %t-vertex.o %t-pixel.o -r Output -o %t/Output.png
# RUN: imgdiff %t/Output.png %goldenimage_dir/hlsl/Graphics/VerticesFromVertexID.png -rules %t/rules.yaml
Loading