Skip to content

Commit c575aca

Browse files
committed
remove VertexBuffer abstraction. Rely on ParsedVertexBuffer for input layout and buffer metadata
1 parent 796648a commit c575aca

7 files changed

Lines changed: 77 additions & 150 deletions

File tree

include/API/Device.h

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
#include "API/Capabilities.h"
2020
#include "API/CommandBuffer.h"
2121
#include "API/Texture.h"
22-
#include "API/VertexBuffer.h"
2322
#include "Support/Pipeline.h"
2423
#include "llvm/ADT/StringRef.h"
2524
#include "llvm/ADT/iterator_range.h"
@@ -119,10 +118,6 @@ createRenderTargetFromCPUBuffer(Device &Dev, const CPUBuffer &Buf);
119118
llvm::Expected<std::shared_ptr<Texture>>
120119
createDefaultDepthStencilTarget(Device &Dev, uint32_t Width, uint32_t Height);
121120

122-
// Creates a VertexBuffer from a ParsedVertexBuffer.
123-
llvm::Expected<VertexBuffer> createVertexBuffer(Device &Dev,
124-
const ParsedVertexBuffer &PVB);
125-
126121
} // namespace offloadtest
127122

128123
#endif // OFFLOADTEST_API_DEVICE_H

include/API/VertexBuffer.h

Lines changed: 0 additions & 66 deletions
This file was deleted.

include/Support/Pipeline.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,11 @@
1616
#include "API/Resources.h"
1717

1818
#include "llvm/ADT/SmallVector.h"
19+
1920
#include "llvm/ADT/StringRef.h"
2021
#include "llvm/Support/MemoryBuffer.h"
2122
#include "llvm/Support/YAMLTraits.h"
23+
#include <cassert>
2224
#include <limits>
2325
#include <memory>
2426
#include <string>
@@ -372,6 +374,15 @@ struct ParsedVertexBuffer {
372374
return Stride;
373375
}
374376

377+
// Returns the byte offset of the stream at the given index.
378+
uint32_t getOffset(uint32_t Index) const {
379+
assert(Index < Streams.size() && "Stream index out of bounds");
380+
uint32_t Offset = 0;
381+
for (uint32_t I = 0; I < Index; ++I)
382+
Offset += getFormatSizeInBytes(Streams[I].Fmt);
383+
return Offset;
384+
}
385+
375386
uint32_t getVertexCount() const {
376387
uint32_t Stride = getStride();
377388
if (Stride == 0)

lib/API/DX/Device.cpp

Lines changed: 22 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@
3434
#include "API/Capabilities.h"
3535
#include "API/Device.h"
3636
#include "API/FormatConversion.h"
37-
#include "API/VertexBuffer.h"
3837
#include "DXFeatures.h"
3938
#include "Support/Pipeline.h"
4039
#include "Support/WinError.h"
@@ -486,7 +485,7 @@ class DXDevice : public offloadtest::Device {
486485
std::shared_ptr<DXTexture> RT;
487486
std::shared_ptr<DXBuffer> RTReadback;
488487
std::shared_ptr<DXTexture> DS;
489-
std::optional<offloadtest::VertexBuffer> VB;
488+
std::shared_ptr<DXBuffer> VB;
490489

491490
llvm::SmallVector<DescriptorTable> DescTables;
492491
llvm::SmallVector<ResourcePair> RootResources;
@@ -1615,26 +1614,29 @@ class DXDevice : public offloadtest::Device {
16151614
"No vertex buffer bound for graphics pipeline.");
16161615

16171616
const ParsedVertexBuffer &PVB = *P.Bindings.VertexBufferPtr;
1618-
auto VBOrErr = offloadtest::createVertexBuffer(*this, PVB);
1619-
if (!VBOrErr)
1620-
return VBOrErr.takeError();
1621-
IS.VB = std::move(*VBOrErr);
1617+
1618+
BufferCreateDesc BufDesc = {};
1619+
BufDesc.Location = MemoryLocation::CpuToGpu;
1620+
BufDesc.Usage = BufferUsage::VertexBuffer;
1621+
auto BufOrErr = createBuffer("VertexBuffer", BufDesc, PVB.InterleavedSize);
1622+
if (!BufOrErr)
1623+
return BufOrErr.takeError();
1624+
IS.VB = std::static_pointer_cast<DXBuffer>(*BufOrErr);
16221625

16231626
// TODO: Currently uses a single CpuToGpu mapped buffer. For optimal GPU
16241627
// performance on discrete GPUs, use a staging buffer + copy to a GpuOnly
16251628
// vertex buffer instead.
1626-
auto *DXBuf = static_cast<DXBuffer *>(IS.VB->Data.get());
16271629
void *Ptr = nullptr;
1628-
if (auto Err = HR::toError(DXBuf->Buffer->Map(0, nullptr, &Ptr),
1630+
if (auto Err = HR::toError(IS.VB->Buffer->Map(0, nullptr, &Ptr),
16291631
"Failed to map vertex buffer"))
16301632
return Err;
1631-
memcpy(Ptr, PVB.InterleavedData.get(), IS.VB->Data->getSizeInBytes());
1632-
DXBuf->Buffer->Unmap(0, nullptr);
1633+
memcpy(Ptr, PVB.InterleavedData.get(), IS.VB->getSizeInBytes());
1634+
IS.VB->Buffer->Unmap(0, nullptr);
16331635

16341636
D3D12_VERTEX_BUFFER_VIEW VBView = {};
1635-
VBView.BufferLocation = DXBuf->Buffer->GetGPUVirtualAddress();
1636-
VBView.SizeInBytes = static_cast<UINT>(IS.VB->Data->getSizeInBytes());
1637-
VBView.StrideInBytes = IS.VB->Desc.getStride();
1637+
VBView.BufferLocation = IS.VB->Buffer->GetGPUVirtualAddress();
1638+
VBView.SizeInBytes = static_cast<UINT>(IS.VB->getSizeInBytes());
1639+
VBView.StrideInBytes = PVB.getStride();
16381640

16391641
IS.CB->CmdList->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
16401642
IS.CB->CmdList->IASetVertexBuffers(0, 1, &VBView);
@@ -1646,13 +1648,13 @@ class DXDevice : public offloadtest::Device {
16461648
if (!IS.VB)
16471649
return llvm::createStringError(std::errc::invalid_argument,
16481650
"Vertex buffer not initialized.");
1649-
// Create the input layout from the vertex buffer description.
1651+
// Create the input layout from the parsed vertex buffer streams.
1652+
const ParsedVertexBuffer &PVB = *P.Bindings.VertexBufferPtr;
16501653
std::vector<D3D12_INPUT_ELEMENT_DESC> InputLayout;
1651-
const VertexBufferDesc &VBDesc = IS.VB->Desc;
1652-
for (uint32_t I = 0; I < VBDesc.Streams.size(); ++I) {
1653-
const VertexStream &S = VBDesc.Streams[I];
1654+
for (uint32_t I = 0; I < PVB.Streams.size(); ++I) {
1655+
const VertexStreamData &S = PVB.Streams[I];
16541656
InputLayout.push_back({S.Name.c_str(), 0, getDXGIFormat(S.Fmt), 0,
1655-
VBDesc.getOffset(I),
1657+
PVB.getOffset(I),
16561658
D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0});
16571659
}
16581660

@@ -1745,7 +1747,8 @@ class DXDevice : public offloadtest::Device {
17451747
static_cast<LONG>(VP.Height)};
17461748
IS.CB->CmdList->RSSetScissorRects(1, &Scissor);
17471749

1748-
IS.CB->CmdList->DrawInstanced(IS.VB->getVertexCount(), 1, 0, 0);
1750+
IS.CB->CmdList->DrawInstanced(P.Bindings.VertexBufferPtr->getVertexCount(),
1751+
1, 0, 0);
17491752

17501753
// Transition the render target to copy source and copy to the readback
17511754
// buffer.

lib/API/Device.cpp

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111

1212
#include "API/Device.h"
1313
#include "API/FormatConversion.h"
14-
#include "API/VertexBuffer.h"
1514

1615
#include "Config.h"
1716

@@ -88,26 +87,6 @@ offloadtest::createRenderTargetFromCPUBuffer(Device &Dev,
8887
return Dev.createTexture("RenderTarget", Desc);
8988
}
9089

91-
llvm::Expected<VertexBuffer>
92-
offloadtest::createVertexBuffer(Device &Dev, const ParsedVertexBuffer &PVB) {
93-
BufferCreateDesc BufDesc = {};
94-
BufDesc.Location = MemoryLocation::CpuToGpu;
95-
BufDesc.Usage = BufferUsage::VertexBuffer;
96-
auto BufOrErr =
97-
Dev.createBuffer("VertexBuffer", BufDesc, PVB.InterleavedSize);
98-
if (!BufOrErr)
99-
return BufOrErr.takeError();
100-
101-
VertexBufferDesc VBDesc;
102-
for (const auto &S : PVB.Streams)
103-
VBDesc.Streams.push_back({S.Name, S.Fmt});
104-
105-
// TODO: Generalize VB data copy so that we can deduplicate that from each
106-
// backend.
107-
108-
return VertexBuffer{VBDesc, *BufOrErr};
109-
}
110-
11190
llvm::Expected<std::shared_ptr<Texture>>
11291
offloadtest::createDefaultDepthStencilTarget(Device &Dev, uint32_t Width,
11392
uint32_t Height) {

lib/API/MTL/MTLDevice.cpp

Lines changed: 21 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111

1212
#include "API/Device.h"
1313
#include "API/FormatConversion.h"
14-
#include "API/VertexBuffer.h"
1514
#include "MTLResources.h"
1615
#include "Support/Pipeline.h"
1716

@@ -200,7 +199,7 @@ class MTLDevice : public offloadtest::Device {
200199
MTL::ComputePipelineState *ComputePipeline = nullptr;
201200
MTL::RenderPipelineState *RenderPipeline = nullptr;
202201
MTL::Buffer *ArgBuffer;
203-
std::optional<offloadtest::VertexBuffer> VB;
202+
std::shared_ptr<MTLBuffer> VB;
204203
MTL::VertexDescriptor *VertexDescriptor;
205204
llvm::SmallVector<MTL::Texture *> Textures;
206205
llvm::SmallVector<MTL::Buffer *> Buffers;
@@ -216,13 +215,13 @@ class MTLDevice : public offloadtest::Device {
216215
if (!IS.VB)
217216
return llvm::Error::success();
218217

219-
const VertexBufferDesc &VBDesc = IS.VB->Desc;
218+
const ParsedVertexBuffer &PVB = *P.Bindings.VertexBufferPtr;
220219

221220
NS::Array *FnAttrs = Fn->vertexAttributes();
222221
if (!FnAttrs)
223222
return llvm::createStringError(std::errc::invalid_argument,
224223
"Vertex shader has no vertex attributes.");
225-
if (FnAttrs->count() != VBDesc.Streams.size())
224+
if (FnAttrs->count() != PVB.Streams.size())
226225
return llvm::createStringError(
227226
std::errc::invalid_argument,
228227
"Mismatch between vertex shader attribute count and pipeline "
@@ -242,8 +241,8 @@ class MTLDevice : public offloadtest::Device {
242241
}
243242

244243
IS.VertexDescriptor = MTL::VertexDescriptor::alloc()->init();
245-
for (uint32_t I = 0; I < VBDesc.Streams.size(); ++I) {
246-
const VertexStream &S = VBDesc.Streams[I];
244+
for (uint32_t I = 0; I < PVB.Streams.size(); ++I) {
245+
const VertexStreamData &S = PVB.Streams[I];
247246
llvm::SmallString<32> AttrName(S.Name);
248247
llvm::transform(AttrName, AttrName.begin(), tolower);
249248
// Append a zero since we're only supporting one attribute per name.
@@ -252,15 +251,15 @@ class MTLDevice : public offloadtest::Device {
252251
MTL::VertexAttributeDescriptor *VADesc =
253252
MTL::VertexAttributeDescriptor::alloc()->init();
254253
VADesc->setBufferIndex(0);
255-
VADesc->setOffset(VBDesc.getOffset(I));
254+
VADesc->setOffset(PVB.getOffset(I));
256255
VADesc->setFormat(getMetalVertexFormat(S.Fmt));
257256
IS.VertexDescriptor->attributes()->setObject(VADesc,
258257
ShaderAttrIndices[AttrName]);
259258
}
260259

261260
MTL::VertexBufferLayoutDescriptor *LDesc =
262261
MTL::VertexBufferLayoutDescriptor::alloc()->init();
263-
LDesc->setStride(VBDesc.getStride());
262+
LDesc->setStride(PVB.getStride());
264263
LDesc->setStepRate(1);
265264
LDesc->setStepFunction(MTL::VertexStepFunctionPerVertex);
266265
IS.VertexDescriptor->layouts()->setObject(LDesc, 0);
@@ -450,19 +449,23 @@ class MTLDevice : public offloadtest::Device {
450449
"No vertex buffer specified for graphics pipeline.");
451450

452451
const ParsedVertexBuffer &PVB = *P.Bindings.VertexBufferPtr;
453-
auto VBOrErr = offloadtest::createVertexBuffer(*this, PVB);
454-
if (!VBOrErr)
455-
return VBOrErr.takeError();
456-
IS.VB = std::move(*VBOrErr);
452+
453+
BufferCreateDesc BufDesc = {};
454+
BufDesc.Location = MemoryLocation::CpuToGpu;
455+
BufDesc.Usage = BufferUsage::VertexBuffer;
456+
auto BufOrErr =
457+
createBuffer("VertexBuffer", BufDesc, PVB.InterleavedSize);
458+
if (!BufOrErr)
459+
return BufOrErr.takeError();
460+
IS.VB = std::static_pointer_cast<MTLBuffer>(*BufOrErr);
457461

458462
// TODO: Currently uses a single CpuToGpu mapped buffer. On discrete GPUs
459463
// (DX/VK), consider using a staging buffer + copy to a GpuOnly vertex
460464
// buffer for optimal GPU read performance. On Apple Silicon this is
461465
// unnecessary due to unified memory.
462-
auto *MTLBuf = static_cast<MTLBuffer *>(IS.VB->Data.get());
463-
const size_t BufSize = IS.VB->Data->getSizeInBytes();
464-
memcpy(MTLBuf->Buf->contents(), PVB.InterleavedData.get(), BufSize);
465-
MTLBuf->Buf->didModifyRange(NS::Range::Make(0, BufSize));
466+
const size_t BufSize = IS.VB->getSizeInBytes();
467+
memcpy(IS.VB->Buf->contents(), PVB.InterleavedData.get(), BufSize);
468+
IS.VB->Buf->didModifyRange(NS::Range::Make(0, BufSize));
466469
}
467470
return llvm::Error::success();
468471
}
@@ -645,11 +648,10 @@ class MTLDevice : public offloadtest::Device {
645648
if (!IS.VB)
646649
return llvm::createStringError(std::errc::invalid_argument,
647650
"Vertex buffer not initialized.");
648-
CmdEncoder->setVertexBuffer(
649-
static_cast<MTLBuffer *>(IS.VB->Data.get())->Buf, 0, 0);
651+
CmdEncoder->setVertexBuffer(IS.VB->Buf, 0, 0);
650652

651653
CmdEncoder->drawPrimitives(MTL::PrimitiveTypeTriangle, NS::UInteger(0),
652-
IS.VB->getVertexCount());
654+
P.Bindings.VertexBufferPtr->getVertexCount());
653655

654656
CmdEncoder->endEncoding();
655657

0 commit comments

Comments
 (0)