blob: b4b316d6d1bac3f1bdd6a34688e0d54b900e9726 [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.
*/
#ifndef skgpu_GraphicsPipelineDesc_DEFINED
#define skgpu_GraphicsPipelineDesc_DEFINED
#include "include/core/SkTypes.h"
#include "include/core/SkSpan.h"
#include "include/private/SkOpts_spi.h"
#include "include/private/SkTArray.h"
#include "include/private/SkUniquePaintParamsID.h"
#include "src/gpu/graphite/Attribute.h"
#include "src/gpu/graphite/DrawTypes.h"
#include <array>
namespace skgpu::graphite {
class RenderStep;
/**
* GraphicsPipelineDesc represents the state needed to create a backend specific GraphicsPipeline,
* minus the target-specific properties that can be inferred from the DrawPass and RenderPassTask.
*/
class GraphicsPipelineDesc {
public:
GraphicsPipelineDesc();
SkSpan<const uint32_t> asKey() const { return SkSpan(fKey.data(), fKey.size()); }
bool operator==(const GraphicsPipelineDesc& that) const {
return this->fKey == that.fKey;
}
bool operator!=(const GraphicsPipelineDesc& other) const {
return !(*this == other);
}
// Describes the geometric portion of the pipeline's program and the pipeline's fixed state
// (except for renderpass-level state that will never change between draws).
const RenderStep* renderStep() const { return fRenderStep; }
// UniqueID of the required PaintParams
SkUniquePaintParamsID paintParamsID() const { return fUniqueID; }
void setProgram(const RenderStep* step, SkUniquePaintParamsID uniqueID) {
SkASSERT(step);
fRenderStep = step;
fUniqueID = uniqueID;
uintptr_t addr = reinterpret_cast<uintptr_t>(fRenderStep);
memcpy(fKey.data(), &addr, sizeof(uintptr_t));
fKey[kWords - 1] = fUniqueID.asUInt();
}
struct Hash {
uint32_t operator()(const GraphicsPipelineDesc& desc) const {
return SkOpts::hash_fn(desc.fKey.data(), desc.fKey.size() * sizeof(uint32_t), 0);
}
};
private:
// The key is the RenderStep address and the uint32_t key from Combination
static constexpr int kWords = sizeof(uintptr_t) / sizeof(uint32_t) + 1;
static_assert(sizeof(uintptr_t) % sizeof(uint32_t) == 0);
// TODO: I wonder if we could expose the "key" as just a char[] union over the renderstep and
// paint combination? That would avoid extra size, but definitely locks GraphicsPipelineDesc
// keys to the current process, which is probably okay since we can have something a with a more
// stable hash used for the pre-compilation combos.
std::array<uint32_t, kWords> fKey;
// Each RenderStep defines a fixed set of attributes and rasterization state, as well as the
// shader fragments that control the geometry and coverage calculations. The RenderStep's shader
// is combined with the rest of the shader generated from the PaintParams. Because each
// RenderStep is fixed, its pointer can be used as a proxy for everything that it specifies in
// the GraphicsPipeline.
const RenderStep* fRenderStep = nullptr;
SkUniquePaintParamsID fUniqueID;
};
} // namespace skgpu
#endif // skgpu_GraphicsPipelineDesc_DEFINED