blob: e96e6cf1db374cbab1d4480c9bfbb7046e9d1342 [file] [log] [blame]
/*
* Copyright 2021 Google LLC
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "experimental/graphite/src/CommandBuffer.h"
#include "experimental/graphite/src/GraphicsPipeline.h"
#include "src/core/SkTraceEvent.h"
#include "experimental/graphite/src/Buffer.h"
#include "experimental/graphite/src/Sampler.h"
#include "experimental/graphite/src/Texture.h"
#include "experimental/graphite/src/TextureProxy.h"
namespace skgpu {
CommandBuffer::CommandBuffer() {}
CommandBuffer::~CommandBuffer() {
this->releaseResources();
}
void CommandBuffer::releaseResources() {
TRACE_EVENT0("skia.gpu", TRACE_FUNC);
fTrackedResources.reset();
}
void CommandBuffer::trackResource(sk_sp<Resource> resource) {
fTrackedResources.push_back(std::move(resource));
}
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())) {
return false;
}
if (colorTexture) {
this->trackResource(std::move(colorTexture));
}
if (resolveTexture) {
this->trackResource(std::move(resolveTexture));
}
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
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::bindTextures(const TextureBindEntry* entries, int count) {
this->onBindTextures(entries, count);
for (int i = 0; i < count; ++i) {
SkASSERT(entries[i].fTexture);
this->trackResource(entries[i].fTexture);
}
}
void CommandBuffer::bindSamplers(const SamplerBindEntry* entries, int count) {
this->onBindSamplers(entries, count);
for (int i = 0; i < count; ++i) {
SkASSERT(entries[i].fSampler);
this->trackResource(entries[i].fSampler);
}
}
static bool check_max_blit_width(int widthInPixels) {
if (widthInPixels > 32767) {
SkASSERT(false); // surfaces should not be this wide anyway
return false;
}
return true;
}
bool CommandBuffer::copyTextureToBuffer(sk_sp<skgpu::Texture> texture,
SkIRect srcRect,
sk_sp<skgpu::Buffer> buffer,
size_t bufferOffset,
size_t bufferRowBytes) {
if (!check_max_blit_width(srcRect.width())) {
return false;
}
if (!this->onCopyTextureToBuffer(texture.get(), srcRect, buffer.get(), bufferOffset,
bufferRowBytes)) {
return false;
}
this->trackResource(std::move(texture));
this->trackResource(std::move(buffer));
SkDEBUGCODE(fHasWork = true;)
return true;
}
} // namespace skgpu