[Graphite] Use more flexible system for storing commands in DrawPass.

Bug: skia:13357
Change-Id: I845872fd70771f273b339becc2064ec732884988
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/557390
Commit-Queue: Greg Daniel <egdaniel@google.com>
Reviewed-by: Michael Ludwig <michaelludwig@google.com>
This commit is contained in:
Greg Daniel 2022-07-14 14:07:38 -04:00 committed by SkCQ
parent 92c162532e
commit 23df8d2d73
9 changed files with 505 additions and 477 deletions

View File

@ -45,6 +45,7 @@ skia_graphite_sources = [
"$_src/DrawAtlas.h",
"$_src/DrawBufferManager.cpp",
"$_src/DrawBufferManager.h",
"$_src/DrawCommands.h",
"$_src/DrawContext.cpp",
"$_src/DrawContext.h",
"$_src/DrawList.cpp",

View File

@ -46,12 +46,16 @@ void CommandBuffer::callFinishedProcs(bool success) {
fFinishedProcs.reset();
}
bool CommandBuffer::beginRenderPass(const RenderPassDesc& renderPassDesc,
sk_sp<Texture> colorTexture,
sk_sp<Texture> resolveTexture,
sk_sp<Texture> depthStencilTexture) {
if (!this->onBeginRenderPass(renderPassDesc, colorTexture.get(), resolveTexture.get(),
depthStencilTexture.get())) {
bool CommandBuffer::addRenderPass(const RenderPassDesc& renderPassDesc,
sk_sp<Texture> colorTexture,
sk_sp<Texture> resolveTexture,
sk_sp<Texture> depthStencilTexture,
const std::vector<std::unique_ptr<DrawPass>>& drawPasses) {
if (!this->onAddRenderPass(renderPassDesc,
colorTexture.get(),
resolveTexture.get(),
depthStencilTexture.get(),
drawPasses)) {
return false;
}
@ -64,64 +68,14 @@ bool CommandBuffer::beginRenderPass(const RenderPassDesc& renderPassDesc,
if (depthStencilTexture) {
this->trackResource(std::move(depthStencilTexture));
}
#ifdef SK_DEBUG
if (renderPassDesc.fColorAttachment.fLoadOp == LoadOp::kClear &&
(renderPassDesc.fColorAttachment.fStoreOp == StoreOp::kStore ||
renderPassDesc.fColorResolveAttachment.fStoreOp == StoreOp::kStore)) {
fHasWork = true;
}
#endif
// We just assume if you are adding a render pass that the render pass will actually do work. In
// theory we could have a discard load that doesn't submit any draws, clears, etc. But hopefully
// something so trivial would be caught before getting here.
SkDEBUGCODE(fHasWork = true;)
return true;
}
void CommandBuffer::bindGraphicsPipeline(sk_sp<GraphicsPipeline> graphicsPipeline) {
this->onBindGraphicsPipeline(graphicsPipeline.get());
this->trackResource(std::move(graphicsPipeline));
}
void CommandBuffer::bindUniformBuffer(UniformSlot slot,
sk_sp<Buffer> uniformBuffer,
size_t offset) {
this->onBindUniformBuffer(slot, uniformBuffer.get(), offset);
this->trackResource(std::move(uniformBuffer));
}
void CommandBuffer::bindVertexBuffers(sk_sp<Buffer> vertexBuffer, size_t vertexOffset,
sk_sp<Buffer> instanceBuffer, size_t instanceOffset) {
this->onBindVertexBuffers(vertexBuffer.get(), vertexOffset,
instanceBuffer.get(), instanceOffset);
if (vertexBuffer) {
this->trackResource(std::move(vertexBuffer));
}
if (instanceBuffer) {
this->trackResource(std::move(instanceBuffer));
}
}
void CommandBuffer::bindIndexBuffer(sk_sp<Buffer> indexBuffer, size_t bufferOffset) {
this->onBindIndexBuffer(indexBuffer.get(), bufferOffset);
if (indexBuffer) {
this->trackResource(std::move(indexBuffer));
}
}
void CommandBuffer::bindDrawBuffers(BindBufferInfo vertices,
BindBufferInfo instances,
BindBufferInfo indices) {
this->bindVertexBuffers(sk_ref_sp(vertices.fBuffer), vertices.fOffset,
sk_ref_sp(instances.fBuffer), instances.fOffset);
this->bindIndexBuffer(sk_ref_sp(indices.fBuffer), indices.fOffset);
}
void CommandBuffer::bindTextureAndSampler(sk_sp<Texture> texture,
sk_sp<Sampler> sampler,
int bindIndex) {
this->onBindTextureAndSampler(texture, sampler, bindIndex);
this->trackResource(std::move(texture));
this->trackResource(std::move(sampler));
}
bool CommandBuffer::copyTextureToBuffer(sk_sp<Texture> texture,
SkIRect srcRect,
sk_sp<Buffer> buffer,

View File

@ -23,6 +23,7 @@ class RefCntedCallback;
namespace skgpu::graphite {
class Buffer;
class DrawPass;
class Gpu;
class GraphicsPipeline;
class Resource;
@ -46,59 +47,11 @@ public:
void addFinishedProc(sk_sp<RefCntedCallback> finishedProc);
void callFinishedProcs(bool success);
bool beginRenderPass(const RenderPassDesc&,
sk_sp<Texture> colorTexture,
sk_sp<Texture> resolveTexture,
sk_sp<Texture> depthStencilTexture);
virtual void endRenderPass() = 0;
//---------------------------------------------------------------
// Can only be used within renderpasses
//---------------------------------------------------------------
void bindGraphicsPipeline(sk_sp<GraphicsPipeline> graphicsPipeline);
void bindUniformBuffer(UniformSlot, sk_sp<Buffer>, size_t bufferOffset);
void bindDrawBuffers(BindBufferInfo vertices,
BindBufferInfo instances,
BindBufferInfo indices);
void bindTextureAndSampler(sk_sp<Texture>, sk_sp<Sampler>, int bindIndex);
// TODO: do we want to handle multiple scissor rects and viewports?
void setScissor(unsigned int left, unsigned int top, unsigned int width, unsigned int height) {
this->onSetScissor(left, top, width, height);
}
void setViewport(float x, float y, float width, float height,
float minDepth = 0, float maxDepth = 1) {
this->onSetViewport(x, y, width, height, minDepth, maxDepth);
}
void setBlendConstants(std::array<float, 4> blendConstants) {
this->onSetBlendConstants(blendConstants);
}
void draw(PrimitiveType type, unsigned int baseVertex, unsigned int vertexCount) {
this->onDraw(type, baseVertex, vertexCount);
SkDEBUGCODE(fHasWork = true;)
}
void drawIndexed(PrimitiveType type, unsigned int baseIndex, unsigned int indexCount,
unsigned int baseVertex) {
this->onDrawIndexed(type, baseIndex, indexCount, baseVertex);
SkDEBUGCODE(fHasWork = true;)
}
void drawInstanced(PrimitiveType type, unsigned int baseVertex, unsigned int vertexCount,
unsigned int baseInstance, unsigned int instanceCount) {
this->onDrawInstanced(type, baseVertex, vertexCount, baseInstance, instanceCount);
SkDEBUGCODE(fHasWork = true;)
}
void drawIndexedInstanced(PrimitiveType type, unsigned int baseIndex, unsigned int indexCount,
unsigned int baseVertex, unsigned int baseInstance,
unsigned int instanceCount) {
this->onDrawIndexedInstanced(type, baseIndex, indexCount, baseVertex, baseInstance,
instanceCount);
SkDEBUGCODE(fHasWork = true;)
}
bool addRenderPass(const RenderPassDesc&,
sk_sp<Texture> colorTexture,
sk_sp<Texture> resolveTexture,
sk_sp<Texture> depthStencilTexture,
const std::vector<std::unique_ptr<DrawPass>>& drawPasses);
//---------------------------------------------------------------
// Can only be used outside renderpasses
@ -117,43 +70,11 @@ protected:
CommandBuffer();
private:
// TODO: Once all buffer use goes through the DrawBufferManager, we likely do not need to track
// refs every time a buffer is bound, since the DBM will transfer ownership for any used buffer
// to the CommandBuffer.
void bindVertexBuffers(sk_sp<Buffer> vertexBuffer, size_t vertexOffset,
sk_sp<Buffer> instanceBuffer, size_t instanceOffset);
void bindIndexBuffer(sk_sp<Buffer> indexBuffer, size_t bufferOffset);
virtual bool onBeginRenderPass(const RenderPassDesc&,
const Texture* colorTexture,
const Texture* resolveTexture,
const Texture* depthStencilTexture) = 0;
virtual void onBindGraphicsPipeline(const GraphicsPipeline*) = 0;
virtual void onBindUniformBuffer(UniformSlot, const Buffer*, size_t bufferOffset) = 0;
virtual void onBindVertexBuffers(const Buffer* vertexBuffer, size_t vertexOffset,
const Buffer* instanceBuffer, size_t instanceOffset) = 0;
virtual void onBindIndexBuffer(const Buffer* indexBuffer, size_t bufferOffset) = 0;
virtual void onBindTextureAndSampler(sk_sp<Texture>,
sk_sp<Sampler>,
unsigned int bindIndex) = 0;
virtual void onSetScissor(unsigned int left, unsigned int top,
unsigned int width, unsigned int height) = 0;
virtual void onSetViewport(float x, float y, float width, float height,
float minDepth, float maxDepth) = 0;
virtual void onSetBlendConstants(std::array<float, 4> blendConstants) = 0;
virtual void onDraw(PrimitiveType type, unsigned int baseVertex, unsigned int vertexCount) = 0;
virtual void onDrawIndexed(PrimitiveType type, unsigned int baseIndex, unsigned int indexCount,
unsigned int baseVertex) = 0;
virtual void onDrawInstanced(PrimitiveType type,
unsigned int baseVertex, unsigned int vertexCount,
unsigned int baseInstance, unsigned int instanceCount) = 0;
virtual void onDrawIndexedInstanced(PrimitiveType type, unsigned int baseIndex,
unsigned int indexCount, unsigned int baseVertex,
unsigned int baseInstance, unsigned int instanceCount) = 0;
virtual bool onAddRenderPass(const RenderPassDesc&,
const Texture* colorTexture,
const Texture* resolveTexture,
const Texture* depthStencilTexture,
const std::vector<std::unique_ptr<DrawPass>>& drawPasses) = 0;
virtual bool onCopyTextureToBuffer(const Texture*,
SkIRect srcRect,

View File

@ -0,0 +1,229 @@
/*
* Copyright 2022 Google LLC
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef skgpu_graphite_DrawPassCommands_DEFINED
#define skgpu_graphite_DrawPassCommands_DEFINED
#include "include/core/SkRect.h"
#include "src/core/SkArenaAlloc.h"
#include "src/core/SkTBlockList.h"
#include "src/gpu/graphite/DrawTypes.h"
#include "src/gpu/graphite/DrawWriter.h"
namespace skgpu::graphite {
namespace DrawPassCommands {
// A list of all the commands types used by a DrawPass.
// Each of these is reified into a struct below.
//
// The design of this systems is based on SkRecords.
// (We're using the macro-of-macro trick here to do several different things with the same list.)
//
// We leave this SKGPU_DRAW_COMMAND_TYPES macro defined for use by code that wants to operate on
// DrawPassCommands types polymorphically.
#define SKGPU_DRAW_PASS_COMMAND_TYPES(M) \
M(BindGraphicsPipeline) \
M(SetBlendConstants) \
M(BindUniformBuffer) \
M(BindDrawBuffers) \
M(BindTexturesAndSamplers) \
M(SetViewport) \
M(SetScissor) \
M(Draw) \
M(DrawIndexed) \
M(DrawInstanced) \
M(DrawIndexedInstanced)
// Defines DrawPassCommands::Type, an enum of all draw command types.
#define ENUM(T) k##T,
enum class Type { SKGPU_DRAW_PASS_COMMAND_TYPES(ENUM) };
#undef ENUM
#define ACT_AS_PTR(ptr) \
operator T*() const { return ptr; } \
T* operator->() const { return ptr; }
// PODArray doesn't own the pointer's memory, and we assume the data is POD.
template <typename T>
class PODArray {
public:
PODArray() {}
PODArray(T* ptr) : fPtr(ptr) {}
// Default copy and assign.
ACT_AS_PTR(fPtr)
private:
T* fPtr;
};
#undef ACT_AS_PTR
// A macro to make it a little easier to define a struct that can be stored in DrawPass.
#define COMMAND(T, ...) \
struct T { \
static constexpr Type kType = Type::k##T; \
__VA_ARGS__; \
};
COMMAND(BindGraphicsPipeline,
uint32_t fPipelineIndex);
COMMAND(SetBlendConstants,
PODArray<float> fBlendConstants);
COMMAND(BindUniformBuffer,
BindBufferInfo fInfo;
UniformSlot fSlot);
COMMAND(BindDrawBuffers,
BindBufferInfo fVertices;
BindBufferInfo fInstances;
BindBufferInfo fIndices);
COMMAND(BindTexturesAndSamplers,
int fNumTexSamplers;
PODArray<int> fTextureIndices;
PODArray<int> fSamplerIndices);
COMMAND(SetViewport,
SkRect fViewport;
float fMinDepth;
float fMaxDepth);
COMMAND(SetScissor,
SkIRect fScissor);
COMMAND(Draw,
PrimitiveType fType;
uint32_t fBaseVertex;
uint32_t fVertexCount);
COMMAND(DrawIndexed,
PrimitiveType fType;
uint32_t fBaseIndex;
uint32_t fIndexCount;
uint32_t fBaseVertex);
COMMAND(DrawInstanced,
PrimitiveType fType;
uint32_t fBaseVertex;
uint32_t fVertexCount;
uint32_t fBaseInstance;
uint32_t fInstanceCount);
COMMAND(DrawIndexedInstanced,
PrimitiveType fType;
uint32_t fBaseIndex;
uint32_t fIndexCount;
uint32_t fBaseVertex;
uint32_t fBaseInstance;
uint32_t fInstanceCount);
#undef COMMAND
#define ASSERT_TRIV_DES(T) static_assert(std::is_trivially_destructible<T>::value);
SKGPU_DRAW_PASS_COMMAND_TYPES(ASSERT_TRIV_DES)
#undef ASSERT_TRIV_DES
#define ASSERT_TRIV_CPY(T) static_assert(std::is_trivially_copyable<T>::value);
SKGPU_DRAW_PASS_COMMAND_TYPES(ASSERT_TRIV_CPY)
#undef ASSERT_TRIV_CPY
class List final : public DrawDispatcher {
public:
List() = default;
~List() override = default;
void bindGraphicsPipeline(uint32_t pipelineIndex) {
this->add<BindGraphicsPipeline>(pipelineIndex);
}
void setBlendConstants(std::array<float, 4> blendConstants) {
this->add<SetBlendConstants>(this->copy(blendConstants.data(), 4));
}
void bindUniformBuffer(BindBufferInfo info, UniformSlot slot) {
this->add<BindUniformBuffer>(info, slot);
}
void bindTexturesAndSamplers(int numTexSamplers,
int* textureIndices,
int* samplerIndices) {
this->add<BindTexturesAndSamplers>(numTexSamplers,
this->copy(textureIndices, numTexSamplers),
this->copy(samplerIndices, numTexSamplers));
}
void setViewport(const SkRect& viewport,
float minDepth = 0,
float maxDepth = 1) {
this->add<SetViewport>(viewport, minDepth, maxDepth);
}
void setScissor(SkIRect scissor) {
this->add<SetScissor>(scissor);
}
// DrawDispatcher overrides
void bindDrawBuffers(BindBufferInfo vertexAttribs,
BindBufferInfo instanceAttribs,
BindBufferInfo indices) override {
this->add<BindDrawBuffers>(vertexAttribs, instanceAttribs, indices);
}
void draw(PrimitiveType type, unsigned int baseVertex, unsigned int vertexCount) override {
this->add<Draw>(type, baseVertex, vertexCount);
}
void drawIndexed(PrimitiveType type, unsigned int baseIndex,
unsigned int indexCount, unsigned int baseVertex) override {
this->add<DrawIndexed>(type, baseIndex, indexCount, baseVertex);
}
void drawInstanced(PrimitiveType type,
unsigned int baseVertex, unsigned int vertexCount,
unsigned int baseInstance, unsigned int instanceCount) override {
this->add<DrawInstanced>(type, baseVertex, vertexCount, baseInstance, instanceCount);
}
void drawIndexedInstanced(PrimitiveType type,
unsigned int baseIndex, unsigned int indexCount,
unsigned int baseVertex, unsigned int baseInstance,
unsigned int instanceCount) override {
this->add<DrawIndexedInstanced>(type,
baseIndex,
indexCount,
baseVertex,
baseInstance,
instanceCount);
}
using Command = std::pair<Type, void*>;
using Iter = SkTBlockList<Command>::CIter;
Iter commands() const { return fCommands.items(); }
private:
template <typename T, typename... Args>
void add(Args&&... args) {
T* cmd = fAlloc.make<T>(T{std::forward<Args>(args)...});
fCommands.push_back(std::make_pair(T::kType, cmd));
}
// This copy() is for arrays.
// It will work with POD only arrays.
template <typename T>
T* copy(const T src[], size_t count) {
static_assert(std::is_trivially_copyable<T>::value);
T* dst = fAlloc.makeArrayDefault<T>(count);
memcpy(dst, src, count*sizeof(T));
return dst;
}
SkTBlockList<Command> fCommands;
// fAlloc needs to be a data structure which can append variable length data in contiguous
// chunks, returning a stable handle to that data for later retrieval.
SkArenaAlloc fAlloc{256};
};
} // namespace DrawPassCommands
} // namespace skgpu::graphite
#endif // skgpu_graphite_DrawPassCommands_DEFINED

View File

@ -146,45 +146,6 @@ private:
SkNextLog2_portable(Renderer::kMaxRenderSteps * DrawList::kMaxDraws));
};
class DrawPass::Drawer final : public DrawDispatcher {
public:
Drawer(DrawPass* drawPass) : fPass(drawPass) {}
~Drawer() override = default;
void bindDrawBuffers(BindBufferInfo vertexAttribs,
BindBufferInfo instanceAttribs,
BindBufferInfo indices) override {
fPass->fCommands.emplace_back(BindDrawBuffers{vertexAttribs, instanceAttribs, indices});
}
void draw(PrimitiveType type, unsigned int baseVertex, unsigned int vertexCount) override {
fPass->fCommands.emplace_back(Draw{type, baseVertex, vertexCount});
}
void drawIndexed(PrimitiveType type, unsigned int baseIndex,
unsigned int indexCount, unsigned int baseVertex) override {
fPass->fCommands.emplace_back(DrawIndexed{type, baseIndex, indexCount, baseVertex});
}
void drawInstanced(PrimitiveType type,
unsigned int baseVertex, unsigned int vertexCount,
unsigned int baseInstance, unsigned int instanceCount) override {
fPass->fCommands.emplace_back(DrawInstanced{type, baseVertex, vertexCount,
baseInstance, instanceCount});
}
void drawIndexedInstanced(PrimitiveType type,
unsigned int baseIndex, unsigned int indexCount,
unsigned int baseVertex, unsigned int baseInstance,
unsigned int instanceCount) override {
fPass->fCommands.emplace_back(DrawIndexedInstanced{type, baseIndex, indexCount, baseVertex,
baseInstance, instanceCount});
}
private:
DrawPass* fPass;
};
///////////////////////////////////////////////////////////////////////////////////////////////////
namespace {
@ -249,8 +210,7 @@ DrawPass::DrawPass(sk_sp<TextureProxy> target,
std::pair<LoadOp, StoreOp> ops,
std::array<float, 4> clearColor,
int renderStepCount)
: fCommands(std::max(1, renderStepCount / 4), SkBlockAllocator::GrowthPolicy::kFibonacci)
, fTarget(std::move(target))
: fTarget(std::move(target))
, fBounds(SkIRect::MakeEmpty())
, fOps(ops)
, fClearColor(clearColor) {
@ -261,7 +221,6 @@ DrawPass::DrawPass(sk_sp<TextureProxy> target,
// many draws should be using a similar small set of samplers.
static constexpr int kReserveSamplerCnt = 8;
fSamplerDescs.reserve(kReserveSamplerCnt);
fCommands.reserve(renderStepCount);
}
DrawPass::~DrawPass() = default;
@ -433,8 +392,7 @@ std::unique_ptr<DrawPass> DrawPass::Make(Recorder* recorder,
std::sort(keys.begin(), keys.end());
// Used to record vertex/instance data, buffer binds, and draw calls
Drawer drawer(drawPass.get());
DrawWriter drawWriter(&drawer, bufferMgr);
DrawWriter drawWriter(&drawPass->fCommandList, bufferMgr);
// Used to track when a new pipeline or dynamic state needs recording between draw steps.
// Setting to # render steps ensures the very first time through the loop will bind a pipeline.
@ -444,6 +402,11 @@ std::unique_ptr<DrawPass> DrawPass::Make(Recorder* recorder,
UniformDataCache::Index lastGeometryUniforms;
SkIRect lastScissor = SkIRect::MakeSize(drawPass->fTarget->dimensions());
// Set viewport to the entire texture for now (eventually, we may have logically smaller bounds
// within an approx-sized texture). It is assumed that this also configures the sk_rtAdjust
// intrinsic for programs (however the backend chooses to do so).
drawPass->fCommandList.setViewport(SkRect::Make(drawPass->fTarget->dimensions()));
for (const SortKey& key : keys) {
const DrawList::Draw& draw = *key.draw();
const RenderStep& renderStep = key.renderStep();
@ -473,42 +436,41 @@ std::unique_ptr<DrawPass> DrawPass::Make(Recorder* recorder,
// Make state changes before accumulating new draw data
if (pipelineChange) {
drawPass->fCommands.emplace_back(BindGraphicsPipeline{key.pipeline()});
drawPass->fCommandList.bindGraphicsPipeline(key.pipeline());
lastPipeline = key.pipeline();
}
if (stateChange) {
if (geometryUniformChange) {
auto binding = geometryUniformBindings.getBinding(key.geometryUniforms());
drawPass->fCommands.emplace_back(
BindUniformBuffer{binding, UniformSlot::kRenderStep});
drawPass->fCommandList.bindUniformBuffer(binding, UniformSlot::kRenderStep);
lastGeometryUniforms = key.geometryUniforms();
}
if (shadingUniformChange) {
auto binding = shadingUniformBindings.getBinding(key.shadingUniforms());
drawPass->fCommands.emplace_back(
BindUniformBuffer{binding, UniformSlot::kPaint});
drawPass->fCommandList.bindUniformBuffer(binding, UniformSlot::kPaint);
lastShadingUniforms = key.shadingUniforms();
}
if (textureBindingsChange) {
auto textureDataBlock = textureDataCache->lookup(key.textureBindings());
BindTexturesAndSamplers bts;
bts.fNumTexSamplers = textureDataBlock->numTextures();
// TODO: Remove this assert once BindTexturesAndSamplers doesn't have a fixed size
// of textures and samplers arrays.
SkASSERT(bts.fNumTexSamplers <= 32);
for (int i = 0; i < bts.fNumTexSamplers; ++i) {
int numTextures = textureDataBlock->numTextures();
std::vector<int> textureIndices(numTextures);
std::vector<int> samplerIndices(numTextures);
for (int i = 0; i < numTextures; ++i) {
auto& info = textureDataBlock->texture(i);
std::tie(bts.fTextureIndices[i], bts.fSamplerIndices[i]) =
std::tie(textureIndices[i], samplerIndices[i]) =
get_unique_texture_sampler_indices(drawPass->fSampledTextures,
drawPass->fSamplerDescs,
info);
}
drawPass->fCommandList.bindTexturesAndSamplers(numTextures,
textureIndices.data(),
samplerIndices.data());
drawPass->fCommands.push_back(Command(bts));
lastTextureBindings = key.textureBindings();
}
if (draw.fDrawParams.clip().scissor() != lastScissor) {
drawPass->fCommands.emplace_back(SetScissor{draw.fDrawParams.clip().scissor()});
drawPass->fCommandList.setScissor(draw.fDrawParams.clip().scissor());
lastScissor = draw.fDrawParams.clip().scissor();
}
}
@ -571,72 +533,28 @@ bool DrawPass::prepareResources(ResourceProvider* resourceProvider,
return true;
}
bool DrawPass::addCommands(CommandBuffer* buffer) const {
// TODO: Validate RenderPass state against DrawPass's target and requirements?
// Generate actual GraphicsPipeline objects combining the target-level properties and each of
// the GraphicsPipelineDesc's referenced in this DrawPass.
// Set viewport to the entire texture for now (eventually, we may have logically smaller bounds
// within an approx-sized texture). It is assumed that this also configures the sk_rtAdjust
// intrinsic for programs (however the backend chooses to do so).
buffer->setViewport(0, 0, fTarget->dimensions().width(), fTarget->dimensions().height());
for (const Command& c : fCommands.items()) {
switch(c.fType) {
case CommandType::kBindGraphicsPipeline: {
auto& d = c.fBindGraphicsPipeline;
buffer->bindGraphicsPipeline(fFullPipelines[d.fPipelineIndex]);
} break;
case CommandType::kBindUniformBuffer: {
auto& d = c.fBindUniformBuffer;
buffer->bindUniformBuffer(d.fSlot, sk_ref_sp(d.fInfo.fBuffer), d.fInfo.fOffset);
} break;
case CommandType::kBindTexturesAndSamplers: {
auto& d = c.fBindTexturesAndSamplers;
for (int i = 0; i < d.fNumTexSamplers; ++i) {
SkASSERT(fSampledTextures[d.fTextureIndices[i]]);
SkASSERT(fSampledTextures[d.fTextureIndices[i]]->texture());
SkASSERT(fSamplers[d.fSamplerIndices[i]]);
buffer->bindTextureAndSampler(
fSampledTextures[d.fTextureIndices[i]]->refTexture(),
fSamplers[d.fSamplerIndices[i]],
i);
}
} break;
case CommandType::kBindDrawBuffers: {
auto& d = c.fBindDrawBuffers;
buffer->bindDrawBuffers(d.fVertices, d.fInstances, d.fIndices);
break; }
case CommandType::kDraw: {
auto& d = c.fDraw;
buffer->draw(d.fType, d.fBaseVertex, d.fVertexCount);
break; }
case CommandType::kDrawIndexed: {
auto& d = c.fDrawIndexed;
buffer->drawIndexed(d.fType, d.fBaseIndex, d.fIndexCount, d.fBaseVertex);
break; }
case CommandType::kDrawInstanced: {
auto& d = c.fDrawInstanced;
buffer->drawInstanced(d.fType, d.fBaseVertex, d.fVertexCount,
d.fBaseInstance, d.fInstanceCount);
break; }
case CommandType::kDrawIndexedInstanced: {
auto& d = c.fDrawIndexedInstanced;
buffer->drawIndexedInstanced(d.fType, d.fBaseIndex, d.fIndexCount, d.fBaseVertex,
d.fBaseInstance, d.fInstanceCount);
break; }
case CommandType::kSetScissor: {
auto& d = c.fSetScissor;
buffer->setScissor(d.fScissor.fLeft, d.fScissor.fTop,
d.fScissor.width(), d.fScissor.height());
break;
}
}
void DrawPass::addResourceRefs(CommandBuffer* commandBuffer) const {
for (size_t i = 0; i < fFullPipelines.size(); ++i) {
commandBuffer->trackResource(fFullPipelines[i]);
}
for (size_t i = 0; i < fSampledTextures.size(); ++i) {
commandBuffer->trackResource(fSampledTextures[i]->refTexture());
}
for (size_t i = 0; i < fSamplers.size(); ++i) {
commandBuffer->trackResource(fSamplers[i]);
}
}
return true;
const Texture* DrawPass::getTexture(size_t index) const {
SkASSERT(index < fSampledTextures.size());
SkASSERT(fSampledTextures[index]);
SkASSERT(fSampledTextures[index]->texture());
return fSampledTextures[index]->texture();
}
const Sampler* DrawPass::getSampler(size_t index) const {
SkASSERT(index < fSamplers.size());
SkASSERT(fSamplers[index]);
return fSamplers[index].get();
}
} // namespace skgpu::graphite

View File

@ -14,6 +14,7 @@
#include "src/core/SkEnumBitMask.h"
#include "src/core/SkTBlockList.h"
#include "src/gpu/graphite/AttachmentTypes.h"
#include "src/gpu/graphite/DrawCommands.h"
#include "src/gpu/graphite/DrawTypes.h"
#include "src/gpu/graphite/GraphicsPipelineDesc.h"
#include "src/gpu/graphite/ResourceTypes.h"
@ -35,6 +36,7 @@ class ResourceProvider;
class Sampler;
struct SamplerDesc;
class TextureProxy;
class Texture;
enum class UniformSlot;
/**
@ -75,140 +77,34 @@ public:
size_t vertexBufferSize() const { return 0; }
size_t uniformBufferSize() const { return 0; }
// TODO: Real return types, but it seems useful for DrawPass to report these as sets so that
// task execution can compile necessary programs and track resources within a render pass.
// Maybe these won't need to be exposed and RenderPassTask can do it per command as needed when
// it iterates over the DrawPass contents.
void samplers() const {}
void programs() const {}
// Instantiate and prepare any resources used by the DrawPass that require the Recorder's
// ResourceProvider. This includes things likes GraphicsPipelines, sampled Textures, Samplers,
// etc.
bool prepareResources(ResourceProvider*, const RenderPassDesc&);
// Transform this DrawPass into commands issued to the CommandBuffer. Assumes that the buffer
// has already begun a correctly configured render pass matching this pass's target.
// Returns true on success; false on failure
bool addCommands(CommandBuffer*) const;
DrawPassCommands::List::Iter commands() const {
return fCommandList.commands();
}
const GraphicsPipeline* getPipeline(size_t index) const {
return fFullPipelines[index].get();
}
const Texture* getTexture(size_t index) const;
const Sampler* getSampler(size_t index) const;
void addResourceRefs(CommandBuffer*) const;
private:
class SortKey;
class Drawer;
struct BindGraphicsPipeline {
// Points to a GraphicsPipelineDesc in DrawPass's fPipelineDescs array. It will also
// index into a parallel array of full GraphicsPipelines when commands are added to the CB.
uint32_t fPipelineIndex;
};
struct BindUniformBuffer {
BindBufferInfo fInfo;
UniformSlot fSlot;
};
struct BindTexturesAndSamplers {
int fNumTexSamplers;
// TODO: Right now we are hardcoding these arrays to be 32. However, when we rewrite the
// command system here to be more flexible and not require fixed sized structs, we will
// remove this hardcode size.
int fTextureIndices[32];
int fSamplerIndices[32];
};
struct BindDrawBuffers {
BindBufferInfo fVertices;
BindBufferInfo fInstances;
BindBufferInfo fIndices;
};
struct Draw {
PrimitiveType fType;
uint32_t fBaseVertex;
uint32_t fVertexCount;
};
struct DrawIndexed {
PrimitiveType fType;
uint32_t fBaseIndex;
uint32_t fIndexCount;
uint32_t fBaseVertex;
};
struct DrawInstanced {
PrimitiveType fType;
uint32_t fBaseVertex;
uint32_t fVertexCount;
uint32_t fBaseInstance;
uint32_t fInstanceCount;
};
struct DrawIndexedInstanced {
PrimitiveType fType;
uint32_t fBaseIndex;
uint32_t fIndexCount;
uint32_t fBaseVertex;
uint32_t fBaseInstance;
uint32_t fInstanceCount;
};
struct SetScissor {
SkIRect fScissor;
};
// TODO: BindSampler
enum class CommandType {
kBindGraphicsPipeline,
kBindUniformBuffer,
kBindTexturesAndSamplers,
kBindDrawBuffers,
kDraw,
kDrawIndexed,
kDrawInstanced,
kDrawIndexedInstanced,
kSetScissor,
// kBindSampler
};
// TODO: The goal is keep all command data in line, vs. type + void* to another data array, but
// the current union is memory inefficient. It would be better to have a byte buffer with per
// type advances, but then we need to work out alignment etc. so that will be easier to add
// once we have something up and running.
struct Command {
CommandType fType;
union {
BindGraphicsPipeline fBindGraphicsPipeline;
BindUniformBuffer fBindUniformBuffer;
BindTexturesAndSamplers fBindTexturesAndSamplers;
BindDrawBuffers fBindDrawBuffers;
Draw fDraw;
DrawIndexed fDrawIndexed;
DrawInstanced fDrawInstanced;
DrawIndexedInstanced fDrawIndexedInstanced;
SetScissor fSetScissor;
};
explicit Command(BindGraphicsPipeline d)
: fType(CommandType::kBindGraphicsPipeline), fBindGraphicsPipeline(d) {}
explicit Command(BindUniformBuffer d)
: fType(CommandType::kBindUniformBuffer), fBindUniformBuffer(d) {}
explicit Command(BindTexturesAndSamplers d)
: fType(CommandType::kBindTexturesAndSamplers), fBindTexturesAndSamplers(d) {}
explicit Command(BindDrawBuffers d)
: fType(CommandType::kBindDrawBuffers), fBindDrawBuffers(d) {}
explicit Command(Draw d)
: fType(CommandType::kDraw), fDraw(d) {}
explicit Command(DrawIndexed d)
: fType(CommandType::kDrawIndexed), fDrawIndexed(d) {}
explicit Command(DrawInstanced d)
: fType(CommandType::kDrawInstanced), fDrawInstanced(d) {}
explicit Command(DrawIndexedInstanced d)
: fType(CommandType::kDrawIndexedInstanced), fDrawIndexedInstanced(d) {}
explicit Command(SetScissor d)
: fType(CommandType::kSetScissor), fSetScissor(d) {}
};
// Not strictly necessary, but keeping Command trivially destructible means the command list
// can be cleaned up efficiently once it's converted to a command buffer.
static_assert(std::is_trivially_destructible<Command>::value);
DrawPass(sk_sp<TextureProxy> target,
std::pair<LoadOp, StoreOp> ops,
std::array<float, 4> clearColor,
int renderStepCount);
SkTBlockList<Command, 32> fCommands;
DrawPassCommands::List fCommandList;
// The pipelines are referenced by index in BindGraphicsPipeline, but that will index into a
// an array of actual GraphicsPipelines. fPipelineDescs only needs to accumulate encountered
// GraphicsPipelineDescs and provide stable pointers, hence SkTBlockList.

View File

@ -103,23 +103,11 @@ bool RenderPassTask::addCommands(ResourceProvider* resourceProvider, CommandBuff
// single sample resolve as an input attachment in that subpass, and then do a draw. The big
// thing with Vulkan is that this input attachment and subpass means we also need to update
// the fRenderPassDesc here.
if (commandBuffer->beginRenderPass(fRenderPassDesc,
std::move(colorAttachment),
std::move(resolveAttachment),
std::move(depthStencilAttachment))) {
// Assuming one draw pass per renderpasstask for now
SkASSERT(fDrawPasses.size() == 1);
for (const auto& drawPass: fDrawPasses) {
if (!drawPass->addCommands(commandBuffer)) {
commandBuffer->endRenderPass();
return false;
}
}
commandBuffer->endRenderPass();
}
return true;
return commandBuffer->addRenderPass(fRenderPassDesc,
std::move(colorAttachment),
std::move(resolveAttachment),
std::move(depthStencilAttachment),
fDrawPasses);
}
} // namespace skgpu::graphite

View File

@ -9,6 +9,7 @@
#define skgpu_graphite_MtlCommandBuffer_DEFINED
#include "src/gpu/graphite/CommandBuffer.h"
#include "src/gpu/graphite/DrawPass.h"
#include "src/gpu/graphite/GpuWorkSubmission.h"
#include "src/gpu/graphite/Log.h"
@ -51,38 +52,47 @@ public:
private:
MtlCommandBuffer(sk_cfp<id<MTLCommandBuffer>> cmdBuffer, const MtlGpu* gpu);
bool onBeginRenderPass(const RenderPassDesc&,
const Texture* colorTexture,
const Texture* resolveTexture,
const Texture* depthStencilTexture) override;
void endRenderPass() override;
bool onAddRenderPass(const RenderPassDesc&,
const Texture* colorTexture,
const Texture* resolveTexture,
const Texture* depthStencilTexture,
const std::vector<std::unique_ptr<DrawPass>>& drawPasses) override;
void onBindGraphicsPipeline(const GraphicsPipeline*) override;
void onBindUniformBuffer(UniformSlot, const Buffer*, size_t offset) override;
void onBindVertexBuffers(const Buffer* vertexBuffer, size_t vertexOffset,
const Buffer* instanceBuffer, size_t instanceOffset) override;
void onBindIndexBuffer(const Buffer* indexBuffer, size_t offset) override;
bool beginRenderPass(const RenderPassDesc&,
const Texture* colorTexture,
const Texture* resolveTexture,
const Texture* depthStencilTexture);
void endRenderPass();
void addDrawPass(const DrawPass*);
void onBindTextureAndSampler(sk_sp<Texture>,
sk_sp<Sampler>,
unsigned int bindIndex) override;
void bindGraphicsPipeline(const GraphicsPipeline*);
void setBlendConstants(float* blendConstants);
void onSetScissor(unsigned int left, unsigned int top,
unsigned int width, unsigned int height) override;
void onSetViewport(float x, float y, float width, float height,
float minDepth, float maxDepth) override;
void onSetBlendConstants(std::array<float, 4> blendConstants) override;
void bindUniformBuffer(const BindBufferInfo& info, UniformSlot);
void bindDrawBuffers(const BindBufferInfo& vertices,
const BindBufferInfo& instances,
const BindBufferInfo& indices);
void bindVertexBuffers(const Buffer* vertexBuffer, size_t vertexOffset,
const Buffer* instanceBuffer, size_t instanceOffset);
void bindIndexBuffer(const Buffer* indexBuffer, size_t offset);
void onDraw(PrimitiveType type, unsigned int baseVertex, unsigned int vertexCount) override;
void onDrawIndexed(PrimitiveType type, unsigned int baseIndex, unsigned int indexCount,
unsigned int baseVertex) override;
void onDrawInstanced(PrimitiveType type,
unsigned int baseVertex, unsigned int vertexCount,
unsigned int baseInstance, unsigned int instanceCount) override;
void onDrawIndexedInstanced(PrimitiveType type, unsigned int baseIndex,
unsigned int indexCount, unsigned int baseVertex,
unsigned int baseInstance, unsigned int instanceCount) override;
void bindTextureAndSampler(const Texture*, const Sampler*, unsigned int bindIndex);
void setScissor(unsigned int left, unsigned int top,
unsigned int width, unsigned int height);
void setViewport(float x, float y, float width, float height,
float minDepth, float maxDepth);
void draw(PrimitiveType type, unsigned int baseVertex, unsigned int vertexCount);
void drawIndexed(PrimitiveType type, unsigned int baseIndex, unsigned int indexCount,
unsigned int baseVertex);
void drawInstanced(PrimitiveType type,
unsigned int baseVertex, unsigned int vertexCount,
unsigned int baseInstance, unsigned int instanceCount);
void drawIndexedInstanced(PrimitiveType type, unsigned int baseIndex,
unsigned int indexCount, unsigned int baseVertex,
unsigned int baseInstance, unsigned int instanceCount);
bool onCopyTextureToBuffer(const Texture*,
SkIRect srcRect,

View File

@ -72,10 +72,27 @@ bool MtlCommandBuffer::commit() {
return ((*fCommandBuffer).status != MTLCommandBufferStatusError);
}
bool MtlCommandBuffer::onBeginRenderPass(const RenderPassDesc& renderPassDesc,
const Texture* colorTexture,
const Texture* resolveTexture,
const Texture* depthStencilTexture) {
bool MtlCommandBuffer::onAddRenderPass(const RenderPassDesc& renderPassDesc,
const Texture* colorTexture,
const Texture* resolveTexture,
const Texture* depthStencilTexture,
const std::vector<std::unique_ptr<DrawPass>>& drawPasses) {
if (!this->beginRenderPass(renderPassDesc, colorTexture, resolveTexture, depthStencilTexture)) {
return false;
}
for (size_t i = 0; i < drawPasses.size(); ++i) {
this->addDrawPass(drawPasses[i].get());
}
this->endRenderPass();
return true;
}
bool MtlCommandBuffer::beginRenderPass(const RenderPassDesc& renderPassDesc,
const Texture* colorTexture,
const Texture* resolveTexture,
const Texture* depthStencilTexture) {
SkASSERT(!fActiveRenderCommandEncoder);
this->endBlitCommandEncoder();
#ifdef SK_BUILD_FOR_IOS
@ -175,6 +192,92 @@ void MtlCommandBuffer::endRenderPass() {
fActiveRenderCommandEncoder.reset();
}
void MtlCommandBuffer::addDrawPass(const DrawPass* drawPass) {
drawPass->addResourceRefs(this);
for (auto[type, cmdPtr] : drawPass->commands()) {
switch (type) {
case DrawPassCommands::Type::kBindGraphicsPipeline: {
auto bgp = static_cast<DrawPassCommands::BindGraphicsPipeline*>(cmdPtr);
this->bindGraphicsPipeline(drawPass->getPipeline(bgp->fPipelineIndex));
break;
}
case DrawPassCommands::Type::kSetBlendConstants: {
auto sbc = static_cast<DrawPassCommands::SetBlendConstants*>(cmdPtr);
this->setBlendConstants(sbc->fBlendConstants);
break;
}
case DrawPassCommands::Type::kBindUniformBuffer: {
auto bub = static_cast<DrawPassCommands::BindUniformBuffer*>(cmdPtr);
this->bindUniformBuffer(bub->fInfo, bub->fSlot);
break;
}
case DrawPassCommands::Type::kBindDrawBuffers: {
auto bdb = static_cast<DrawPassCommands::BindDrawBuffers*>(cmdPtr);
this->bindDrawBuffers(bdb->fVertices, bdb->fInstances, bdb->fIndices);
break;
}
case DrawPassCommands::Type::kBindTexturesAndSamplers: {
auto bts = static_cast<DrawPassCommands::BindTexturesAndSamplers*>(cmdPtr);
for (int j = 0; j < bts->fNumTexSamplers; ++j) {
this->bindTextureAndSampler(drawPass->getTexture(bts->fTextureIndices[j]),
drawPass->getSampler(bts->fSamplerIndices[j]),
j);
}
break;
}
case DrawPassCommands::Type::kSetViewport: {
auto sv = static_cast<DrawPassCommands::SetViewport*>(cmdPtr);
this->setViewport(sv->fViewport.fLeft,
sv->fViewport.fTop,
sv->fViewport.width(),
sv->fViewport.height(),
sv->fMinDepth,
sv->fMaxDepth);
break;
}
case DrawPassCommands::Type::kSetScissor: {
auto ss = static_cast<DrawPassCommands::SetScissor*>(cmdPtr);
const SkIRect& rect = ss->fScissor;
this->setScissor(rect.fLeft, rect.fTop, rect.width(), rect.height());
break;
}
case DrawPassCommands::Type::kDraw: {
auto draw = static_cast<DrawPassCommands::Draw*>(cmdPtr);
this->draw(draw->fType, draw->fBaseVertex, draw->fVertexCount);
break;
}
case DrawPassCommands::Type::kDrawIndexed: {
auto draw = static_cast<DrawPassCommands::DrawIndexed*>(cmdPtr);
this->drawIndexed(draw->fType,
draw->fBaseIndex,
draw->fIndexCount,
draw->fBaseVertex);
break;
}
case DrawPassCommands::Type::kDrawInstanced: {
auto draw = static_cast<DrawPassCommands::DrawInstanced*>(cmdPtr);
this->drawInstanced(draw->fType,
draw->fBaseVertex,
draw->fVertexCount,
draw->fBaseInstance,
draw->fInstanceCount);
break;
}
case DrawPassCommands::Type::kDrawIndexedInstanced: {
auto draw = static_cast<DrawPassCommands::DrawIndexedInstanced*>(cmdPtr);
this->drawIndexedInstanced(draw->fType,
draw->fBaseIndex,
draw->fIndexCount,
draw->fBaseVertex,
draw->fBaseInstance,
draw->fInstanceCount);
break;
}
}
}
}
MtlBlitCommandEncoder* MtlCommandBuffer::getBlitCommandEncoder() {
if (fActiveBlitCommandEncoder) {
return fActiveBlitCommandEncoder.get();
@ -205,7 +308,7 @@ void MtlCommandBuffer::endBlitCommandEncoder() {
}
}
void MtlCommandBuffer::onBindGraphicsPipeline(const GraphicsPipeline* graphicsPipeline) {
void MtlCommandBuffer::bindGraphicsPipeline(const GraphicsPipeline* graphicsPipeline) {
SkASSERT(fActiveRenderCommandEncoder);
auto mtlPipeline = static_cast<const MtlGraphicsPipeline*>(graphicsPipeline);
@ -220,13 +323,11 @@ void MtlCommandBuffer::onBindGraphicsPipeline(const GraphicsPipeline* graphicsPi
fCurrentInstanceStride = mtlPipeline->instanceStride();
}
void MtlCommandBuffer::onBindUniformBuffer(UniformSlot slot,
const Buffer* uniformBuffer,
size_t uniformOffset) {
void MtlCommandBuffer::bindUniformBuffer(const BindBufferInfo& info, UniformSlot slot) {
SkASSERT(fActiveRenderCommandEncoder);
id<MTLBuffer> mtlBuffer = uniformBuffer ?
static_cast<const MtlBuffer*>(uniformBuffer)->mtlBuffer() : nullptr;
id<MTLBuffer> mtlBuffer = info.fBuffer ?
static_cast<const MtlBuffer*>(info.fBuffer)->mtlBuffer() : nullptr;
unsigned int bufferIndex;
switch(slot) {
@ -238,14 +339,24 @@ void MtlCommandBuffer::onBindUniformBuffer(UniformSlot slot,
break;
}
fActiveRenderCommandEncoder->setVertexBuffer(mtlBuffer, uniformOffset, bufferIndex);
fActiveRenderCommandEncoder->setFragmentBuffer(mtlBuffer, uniformOffset, bufferIndex);
fActiveRenderCommandEncoder->setVertexBuffer(mtlBuffer, info.fOffset, bufferIndex);
fActiveRenderCommandEncoder->setFragmentBuffer(mtlBuffer, info.fOffset, bufferIndex);
}
void MtlCommandBuffer::onBindVertexBuffers(const Buffer* vertexBuffer,
size_t vertexOffset,
const Buffer* instanceBuffer,
size_t instanceOffset) {
void MtlCommandBuffer::bindDrawBuffers(const BindBufferInfo& vertices,
const BindBufferInfo& instances,
const BindBufferInfo& indices) {
this->bindVertexBuffers(vertices.fBuffer,
vertices.fOffset,
instances.fBuffer,
instances.fOffset);
this->bindIndexBuffer(indices.fBuffer, indices.fOffset);
}
void MtlCommandBuffer::bindVertexBuffers(const Buffer* vertexBuffer,
size_t vertexOffset,
const Buffer* instanceBuffer,
size_t instanceOffset) {
SkASSERT(fActiveRenderCommandEncoder);
if (vertexBuffer) {
@ -264,7 +375,7 @@ void MtlCommandBuffer::onBindVertexBuffers(const Buffer* vertexBuffer,
}
}
void MtlCommandBuffer::onBindIndexBuffer(const Buffer* indexBuffer, size_t offset) {
void MtlCommandBuffer::bindIndexBuffer(const Buffer* indexBuffer, size_t offset) {
if (indexBuffer) {
fCurrentIndexBuffer = static_cast<const MtlBuffer*>(indexBuffer)->mtlBuffer();
fCurrentIndexBufferOffset = offset;
@ -274,26 +385,26 @@ void MtlCommandBuffer::onBindIndexBuffer(const Buffer* indexBuffer, size_t offse
}
}
void MtlCommandBuffer::onBindTextureAndSampler(sk_sp<Texture> texture,
sk_sp<Sampler> sampler,
unsigned int bindIndex) {
void MtlCommandBuffer::bindTextureAndSampler(const Texture* texture,
const Sampler* sampler,
unsigned int bindIndex) {
SkASSERT(texture && sampler);
id<MTLTexture> mtlTexture = ((MtlTexture*)texture.get())->mtlTexture();
id<MTLSamplerState> mtlSamplerState = ((MtlSampler*)sampler.get())->mtlSamplerState();
id<MTLTexture> mtlTexture = ((const MtlTexture*)texture)->mtlTexture();
id<MTLSamplerState> mtlSamplerState = ((const MtlSampler*)sampler)->mtlSamplerState();
fActiveRenderCommandEncoder->setFragmentTexture(mtlTexture, bindIndex);
fActiveRenderCommandEncoder->setFragmentSamplerState(mtlSamplerState, bindIndex);
}
void MtlCommandBuffer::onSetScissor(unsigned int left, unsigned int top,
unsigned int width, unsigned int height) {
void MtlCommandBuffer::setScissor(unsigned int left, unsigned int top,
unsigned int width, unsigned int height) {
SkASSERT(fActiveRenderCommandEncoder);
MTLScissorRect scissorRect = { left, top, width, height };
fActiveRenderCommandEncoder->setScissorRect(scissorRect);
}
void MtlCommandBuffer::onSetViewport(float x, float y, float width, float height,
float minDepth, float maxDepth) {
void MtlCommandBuffer::setViewport(float x, float y, float width, float height,
float minDepth, float maxDepth) {
SkASSERT(fActiveRenderCommandEncoder);
MTLViewport viewport = { x, y, width, height, minDepth, maxDepth };
fActiveRenderCommandEncoder->setViewport(viewport);
@ -308,10 +419,10 @@ void MtlCommandBuffer::onSetViewport(float x, float y, float width, float height
MtlGraphicsPipeline::kIntrinsicUniformBufferIndex);
}
void MtlCommandBuffer::onSetBlendConstants(std::array<float, 4> blendConstants) {
void MtlCommandBuffer::setBlendConstants(float* blendConstants) {
SkASSERT(fActiveRenderCommandEncoder);
fActiveRenderCommandEncoder->setBlendColor(blendConstants.data());
fActiveRenderCommandEncoder->setBlendColor(blendConstants);
}
static MTLPrimitiveType graphite_to_mtl_primitive(PrimitiveType primitiveType) {
@ -328,9 +439,9 @@ static MTLPrimitiveType graphite_to_mtl_primitive(PrimitiveType primitiveType) {
return mtlPrimitiveType[static_cast<int>(primitiveType)];
}
void MtlCommandBuffer::onDraw(PrimitiveType type,
unsigned int baseVertex,
unsigned int vertexCount) {
void MtlCommandBuffer::draw(PrimitiveType type,
unsigned int baseVertex,
unsigned int vertexCount) {
SkASSERT(fActiveRenderCommandEncoder);
auto mtlPrimitiveType = graphite_to_mtl_primitive(type);
@ -338,8 +449,8 @@ void MtlCommandBuffer::onDraw(PrimitiveType type,
fActiveRenderCommandEncoder->drawPrimitives(mtlPrimitiveType, baseVertex, vertexCount);
}
void MtlCommandBuffer::onDrawIndexed(PrimitiveType type, unsigned int baseIndex,
unsigned int indexCount, unsigned int baseVertex) {
void MtlCommandBuffer::drawIndexed(PrimitiveType type, unsigned int baseIndex,
unsigned int indexCount, unsigned int baseVertex) {
SkASSERT(fActiveRenderCommandEncoder);
if (@available(macOS 10.11, iOS 9.0, *)) {
@ -357,9 +468,9 @@ void MtlCommandBuffer::onDrawIndexed(PrimitiveType type, unsigned int baseIndex,
}
}
void MtlCommandBuffer::onDrawInstanced(PrimitiveType type, unsigned int baseVertex,
unsigned int vertexCount, unsigned int baseInstance,
unsigned int instanceCount) {
void MtlCommandBuffer::drawInstanced(PrimitiveType type, unsigned int baseVertex,
unsigned int vertexCount, unsigned int baseInstance,
unsigned int instanceCount) {
SkASSERT(fActiveRenderCommandEncoder);
auto mtlPrimitiveType = graphite_to_mtl_primitive(type);
@ -369,12 +480,12 @@ void MtlCommandBuffer::onDrawInstanced(PrimitiveType type, unsigned int baseVert
instanceCount, baseInstance);
}
void MtlCommandBuffer::onDrawIndexedInstanced(PrimitiveType type,
unsigned int baseIndex,
unsigned int indexCount,
unsigned int baseVertex,
unsigned int baseInstance,
unsigned int instanceCount) {
void MtlCommandBuffer::drawIndexedInstanced(PrimitiveType type,
unsigned int baseIndex,
unsigned int indexCount,
unsigned int baseVertex,
unsigned int baseInstance,
unsigned int instanceCount) {
SkASSERT(fActiveRenderCommandEncoder);
if (@available(macOS 10.11, iOS 9.0, *)) {