a9741ee25a
Exactly enough implemented to run fm --skvm -b cpu -s runtime_shader -w foo This shader 0: 0077 load2 0 10: 00a2 pushimmediate 998277249(0.0039215688593685627) 22: 0070 dup 31: 0094 multiplyf2 40: 0080 loaduniform 2 50: 00a2 pushimmediate 1065353216(1.0) 62: 00c1 store4 2 71: 00b4 return 0 becomes this blitter, including matrix, blending, asserts, etc: 17 registers, 57 instructions: 0 r0 = uniform32 arg(0) 4 1 r0 = to_f32 r0 2 r1 = splat 3F000000 (0.5) 3 r0 = add_f32 r0 r1 4 r2 = uniform32 arg(0) 2C 5 r3 = uniform32 arg(0) 28 6 r2 = fma_f32 r0 r3 r2 7 r3 = uniform32 arg(0) 0 8 r4 = uniform32 arg(0) 24 9 r5 = splat 3F800000 (1) 10 r6 = uniform32 arg(0) 38 11 r6 = min_f32 r6 r5 12 r7 = splat 0 (0) 13 r6 = max_f32 r7 r6 14 r8 = splat 437F0000 (255) 15 r9 = mul_f32 r6 r8 16 r9 = round r9 17 r10 = splat FF (3.5733111e-43) 18 r10 = pack r9 r10 8 19 r9 = splat 3B808081 (0.0039215689) 20 r11 = uniform32 arg(0) 20 21 r12 = uniform32 arg(0) 1C 22 r11 = fma_f32 r0 r12 r11 23 r12 = uniform32 arg(0) 18 24 r0 = splat 3F800001 (1.0000001) 25 r13 = min_f32 r6 r0 26 r14 = splat B4000000 (-1.1920929e-07) 27 r13 = max_f32 r14 r13 28 r13 = eq_f32 r6 r13 29 assert_true r13 r6 loop: 30 r6 = index 31 r6 = sub_i32 r3 r6 32 r6 = to_f32 r6 33 r6 = add_f32 r6 r1 34 r13 = fma_f32 r6 r4 r2 35 r13 = mul_f32 r9 r13 36 r6 = fma_f32 r6 r12 r11 37 r13 = min_f32 r13 r5 38 r13 = max_f32 r7 r13 39 r15 = mul_f32 r13 r8 40 r15 = round r15 41 r6 = mul_f32 r9 r6 42 r6 = min_f32 r6 r5 43 r6 = max_f32 r7 r6 44 r16 = mul_f32 r6 r8 45 r16 = round r16 46 r15 = pack r16 r15 8 47 r15 = pack r15 r10 16 48 store32 arg(1) r15 49 r15 = min_f32 r13 r0 50 r15 = max_f32 r14 r15 51 r15 = eq_f32 r13 r15 52 assert_true r15 r13 53 r13 = min_f32 r6 r0 54 r13 = max_f32 r14 r13 55 r13 = eq_f32 r6 r13 56 assert_true r13 r6 And that JITs using 11 ymm registers. Change-Id: Ib45b5fa6aee427f290b77d8900f10d433ad81133 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/281746 Reviewed-by: Brian Osman <brianosman@google.com> Commit-Queue: Mike Klein <mtklein@google.com>
163 lines
4.7 KiB
C++
163 lines
4.7 KiB
C++
/*
|
|
* Copyright 2019 Google LLC
|
|
*
|
|
* Use of this source code is governed by a BSD-style license that can be
|
|
* found in the LICENSE file.
|
|
*/
|
|
|
|
#ifndef SkRuntimeEffect_DEFINED
|
|
#define SkRuntimeEffect_DEFINED
|
|
|
|
#include "include/core/SkString.h"
|
|
|
|
#include <vector>
|
|
|
|
#if SK_SUPPORT_GPU
|
|
#include "include/gpu/GrContextOptions.h"
|
|
#include "include/private/GrTypesPriv.h"
|
|
#endif
|
|
|
|
class GrShaderCaps;
|
|
class SkColorFilter;
|
|
class SkMatrix;
|
|
class SkShader;
|
|
|
|
namespace SkSL {
|
|
class ByteCode;
|
|
struct PipelineStageArgs;
|
|
struct Program;
|
|
class SharedCompiler;
|
|
}
|
|
|
|
/*
|
|
* SkRuntimeEffect supports creating custom SkShader and SkColorFilter objects using Skia's SkSL
|
|
* shading language.
|
|
* *
|
|
* This API is experimental and subject to change.
|
|
*/
|
|
class SK_API SkRuntimeEffect : public SkRefCnt {
|
|
public:
|
|
struct Variable {
|
|
enum class Qualifier {
|
|
kUniform,
|
|
kIn,
|
|
};
|
|
|
|
enum class Type {
|
|
kBool,
|
|
kInt,
|
|
kFloat,
|
|
kFloat2,
|
|
kFloat3,
|
|
kFloat4,
|
|
kFloat2x2,
|
|
kFloat3x3,
|
|
kFloat4x4,
|
|
};
|
|
|
|
enum Flags {
|
|
kArray_Flag = 0x1,
|
|
};
|
|
|
|
SkString fName;
|
|
size_t fOffset;
|
|
Qualifier fQualifier;
|
|
Type fType;
|
|
int fCount;
|
|
uint32_t fFlags;
|
|
|
|
#if SK_SUPPORT_GPU
|
|
GrSLType fGPUType;
|
|
#endif
|
|
|
|
bool isArray() const { return SkToBool(fFlags & kArray_Flag); }
|
|
size_t sizeInBytes() const;
|
|
};
|
|
|
|
struct Varying {
|
|
SkString fName;
|
|
int fWidth; // 1 - 4 (floats)
|
|
};
|
|
|
|
// [Effect, ErrorText]
|
|
// If successful, Effect != nullptr, otherwise, ErrorText contains the reason for failure.
|
|
using EffectResult = std::tuple<sk_sp<SkRuntimeEffect>, SkString>;
|
|
|
|
static EffectResult Make(SkString sksl);
|
|
|
|
sk_sp<SkShader> makeShader(sk_sp<SkData> inputs, sk_sp<SkShader> children[], size_t childCount,
|
|
const SkMatrix* localMatrix, bool isOpaque);
|
|
|
|
sk_sp<SkColorFilter> makeColorFilter(sk_sp<SkData> inputs, sk_sp<SkColorFilter> children[],
|
|
size_t childCount);
|
|
sk_sp<SkColorFilter> makeColorFilter(sk_sp<SkData> inputs);
|
|
|
|
const SkString& source() const { return fSkSL; }
|
|
uint32_t hash() const { return fHash; }
|
|
|
|
template <typename T>
|
|
class ConstIterable {
|
|
public:
|
|
ConstIterable(const std::vector<T>& vec) : fVec(vec) {}
|
|
|
|
using const_iterator = typename std::vector<T>::const_iterator;
|
|
|
|
const_iterator begin() const { return fVec.begin(); }
|
|
const_iterator end() const { return fVec.end(); }
|
|
size_t count() const { return fVec.size(); }
|
|
|
|
private:
|
|
const std::vector<T>& fVec;
|
|
};
|
|
|
|
// Combined size of all 'in' and 'uniform' variables. When calling makeColorFilter or
|
|
// makeShader, provide an SkData of this size, containing values for all of those variables.
|
|
size_t inputSize() const;
|
|
|
|
// Combined size of just the 'uniform' variables.
|
|
size_t uniformSize() const { return fUniformSize; }
|
|
|
|
ConstIterable<Variable> inputs() const { return ConstIterable<Variable>(fInAndUniformVars); }
|
|
ConstIterable<SkString> children() const { return ConstIterable<SkString>(fChildren); }
|
|
ConstIterable<Varying> varyings() const { return ConstIterable<Varying>(fVaryings); }
|
|
|
|
#if SK_SUPPORT_GPU
|
|
// This re-compiles the program from scratch, using the supplied shader caps.
|
|
// This is necessary to get the correct values of settings.
|
|
bool toPipelineStage(const void* inputs, const GrShaderCaps* shaderCaps,
|
|
GrContextOptions::ShaderErrorHandler* errorHandler,
|
|
SkSL::PipelineStageArgs* outArgs);
|
|
#endif
|
|
|
|
// [ByteCode, ErrorText]
|
|
// If successful, ByteCode != nullptr, otherwise, ErrorText contains the reason for failure.
|
|
using ByteCodeResult = std::tuple<std::unique_ptr<SkSL::ByteCode>, SkString>;
|
|
|
|
ByteCodeResult toByteCode(const void* inputs) const;
|
|
|
|
static void RegisterFlattenables();
|
|
|
|
~SkRuntimeEffect();
|
|
|
|
private:
|
|
SkRuntimeEffect(SkString sksl, std::unique_ptr<SkSL::Program> baseProgram,
|
|
std::vector<Variable>&& inAndUniformVars, std::vector<SkString>&& children,
|
|
std::vector<Varying>&& varyings, size_t uniformSize);
|
|
|
|
using SpecializeResult = std::tuple<std::unique_ptr<SkSL::Program>, SkString>;
|
|
SpecializeResult specialize(SkSL::Program& baseProgram, const void* inputs,
|
|
const SkSL::SharedCompiler&) const;
|
|
|
|
uint32_t fHash;
|
|
SkString fSkSL;
|
|
|
|
std::unique_ptr<SkSL::Program> fBaseProgram;
|
|
std::vector<Variable> fInAndUniformVars;
|
|
std::vector<SkString> fChildren;
|
|
std::vector<Varying> fVaryings;
|
|
|
|
size_t fUniformSize;
|
|
};
|
|
|
|
#endif
|