Add GrProgramInfo to centralize management of program information
This is the first step in moving the marshaling of program information earlier in renderTask processing (i.e., to onPrePrepare). Change-Id: I91e3baed9a128e845bd32f9dbbacd9b21d852a3d Reviewed-on: https://skia-review.googlesource.com/c/skia/+/244118 Reviewed-by: Greg Daniel <egdaniel@google.com> Commit-Queue: Robert Phillips <robertphillips@google.com>
This commit is contained in:
parent
e7bc084498
commit
901aff018b
@ -36,6 +36,7 @@
|
||||
#include "src/gpu/GrPrimitiveProcessor.h"
|
||||
#include "src/gpu/GrProcessor.h"
|
||||
#include "src/gpu/GrProcessorSet.h"
|
||||
#include "src/gpu/GrProgramInfo.h"
|
||||
#include "src/gpu/GrRecordingContextPriv.h"
|
||||
#include "src/gpu/GrRenderTargetContext.h"
|
||||
#include "src/gpu/GrRenderTargetContextPriv.h"
|
||||
@ -165,9 +166,16 @@ private:
|
||||
GrMesh mesh(GrPrimitiveType::kTriangleStrip);
|
||||
mesh.setNonIndexedNonInstanced(4);
|
||||
mesh.setVertexData(std::move(fVertexBuffer));
|
||||
flushState->opsRenderPass()->draw(ClockwiseTestProcessor(fReadSkFragCoord), pipeline,
|
||||
nullptr, nullptr, &mesh, 1,
|
||||
SkRect::MakeXYWH(0, fY, 100, 100));
|
||||
|
||||
ClockwiseTestProcessor primProc(fReadSkFragCoord);
|
||||
|
||||
GrProgramInfo programInfo(flushState->drawOpArgs().numSamples(),
|
||||
flushState->drawOpArgs().origin(),
|
||||
pipeline,
|
||||
primProc,
|
||||
nullptr, nullptr);
|
||||
|
||||
flushState->opsRenderPass()->draw(programInfo, &mesh, 1, SkRect::MakeXYWH(0, fY, 100, 100));
|
||||
}
|
||||
|
||||
sk_sp<GrBuffer> fVertexBuffer;
|
||||
|
@ -30,6 +30,7 @@
|
||||
#include "src/gpu/GrPrimitiveProcessor.h"
|
||||
#include "src/gpu/GrProcessor.h"
|
||||
#include "src/gpu/GrProcessorSet.h"
|
||||
#include "src/gpu/GrProgramInfo.h"
|
||||
#include "src/gpu/GrRecordingContextPriv.h"
|
||||
#include "src/gpu/GrRenderTargetContext.h"
|
||||
#include "src/gpu/GrRenderTargetContextPriv.h"
|
||||
@ -150,7 +151,7 @@ private:
|
||||
this->setBounds(SkRect::MakeIWH(kWidth, kHeight), HasAABloat::kNo, IsHairline::kNo);
|
||||
}
|
||||
|
||||
const char* name() const override { return "ClockwiseTestOp"; }
|
||||
const char* name() const override { return "FwidthSquircleTestOp"; }
|
||||
FixedFunctionFlags fixedFunctionFlags() const override { return FixedFunctionFlags::kNone; }
|
||||
GrProcessorSet::Analysis finalize(
|
||||
const GrCaps&, const GrAppliedClip*, bool hasMixedSampledCoverage, GrClampType) override {
|
||||
@ -172,12 +173,19 @@ private:
|
||||
}
|
||||
GrPipeline pipeline(GrScissorTest::kDisabled, SkBlendMode::kSrcOver,
|
||||
flushState->drawOpArgs().outputSwizzle());
|
||||
|
||||
FwidthSquircleTestProcessor primProc(fViewMatrix);
|
||||
|
||||
GrProgramInfo programInfo(flushState->drawOpArgs().numSamples(),
|
||||
flushState->drawOpArgs().origin(),
|
||||
pipeline,
|
||||
primProc,
|
||||
nullptr, nullptr);
|
||||
|
||||
GrMesh mesh(GrPrimitiveType::kTriangleStrip);
|
||||
mesh.setNonIndexedNonInstanced(4);
|
||||
mesh.setVertexData(std::move(fVertexBuffer));
|
||||
flushState->opsRenderPass()->draw(FwidthSquircleTestProcessor(fViewMatrix), pipeline,
|
||||
nullptr, nullptr, &mesh, 1, SkRect::MakeIWH(kWidth,
|
||||
kHeight));
|
||||
flushState->opsRenderPass()->draw(programInfo, &mesh, 1, SkRect::MakeIWH(kWidth, kHeight));
|
||||
}
|
||||
|
||||
sk_sp<GrBuffer> fVertexBuffer;
|
||||
|
@ -235,11 +235,17 @@ private:
|
||||
flushState->drawOpArgs().outputSwizzle(),
|
||||
GrPipeline::InputFlags::kHWAntialias, &kStencilWrite);
|
||||
|
||||
SampleLocationsTestProcessor primProc(fGradType);
|
||||
|
||||
GrProgramInfo programInfo(flushState->drawOpArgs().numSamples(),
|
||||
flushState->drawOpArgs().origin(),
|
||||
pipeline,
|
||||
primProc,
|
||||
nullptr, nullptr);
|
||||
|
||||
GrMesh mesh(GrPrimitiveType::kTriangleStrip);
|
||||
mesh.setInstanced(nullptr, 200*200, 0, 4);
|
||||
flushState->opsRenderPass()->draw(
|
||||
SampleLocationsTestProcessor(fGradType), pipeline, nullptr, nullptr, &mesh, 1,
|
||||
SkRect::MakeIWH(200, 200));
|
||||
flushState->opsRenderPass()->draw(programInfo, &mesh, 1, SkRect::MakeIWH(200, 200));
|
||||
}
|
||||
|
||||
const GradType fGradType;
|
||||
|
@ -120,6 +120,8 @@ skia_gpu_sources = [
|
||||
"$_src/gpu/GrMesh.h",
|
||||
"$_src/gpu/GrNativeRect.h",
|
||||
"$_src/gpu/GrNonAtomicRef.h",
|
||||
"$_src/gpu/GrOnFlushResourceProvider.cpp",
|
||||
"$_src/gpu/GrOnFlushResourceProvider.h",
|
||||
"$_src/gpu/GrOpFlushState.cpp",
|
||||
"$_src/gpu/GrOpFlushState.h",
|
||||
"$_src/gpu/GrOpsRenderPass.cpp",
|
||||
@ -132,8 +134,6 @@ skia_gpu_sources = [
|
||||
"$_src/gpu/GrPathRendererChain.h",
|
||||
"$_src/gpu/GrPathRenderer.cpp",
|
||||
"$_src/gpu/GrPathRenderer.h",
|
||||
"$_src/gpu/GrOnFlushResourceProvider.cpp",
|
||||
"$_src/gpu/GrOnFlushResourceProvider.h",
|
||||
"$_src/gpu/GrPipeline.cpp",
|
||||
"$_src/gpu/GrPipeline.h",
|
||||
"$_src/gpu/GrPrimitiveProcessor.cpp",
|
||||
@ -142,6 +142,7 @@ skia_gpu_sources = [
|
||||
"$_src/gpu/GrProcessorSet.h",
|
||||
"$_src/gpu/GrProgramDesc.cpp",
|
||||
"$_src/gpu/GrProgramDesc.h",
|
||||
"$_src/gpu/GrProgramInfo.h",
|
||||
"$_src/gpu/GrProcessor.cpp",
|
||||
"$_src/gpu/GrProcessor.h",
|
||||
"$_src/gpu/GrProcessorAnalysis.cpp",
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include "src/gpu/GrDrawOpAtlas.h"
|
||||
#include "src/gpu/GrGpu.h"
|
||||
#include "src/gpu/GrImageInfo.h"
|
||||
#include "src/gpu/GrProgramInfo.h"
|
||||
#include "src/gpu/GrResourceProvider.h"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
@ -52,10 +53,16 @@ void GrOpFlushState::executeDrawsAndUploadsForMeshDrawOp(
|
||||
this->opsRenderPass()->inlineUpload(this, fCurrUpload->fUpload);
|
||||
++fCurrUpload;
|
||||
}
|
||||
this->opsRenderPass()->draw(
|
||||
*fCurrDraw->fGeometryProcessor, *pipeline, fCurrDraw->fFixedDynamicState,
|
||||
fCurrDraw->fDynamicStateArrays, fCurrDraw->fMeshes, fCurrDraw->fMeshCnt,
|
||||
chainBounds);
|
||||
|
||||
GrProgramInfo programInfo(this->proxy()->numSamples(),
|
||||
this->proxy()->origin(),
|
||||
*pipeline,
|
||||
*fCurrDraw->fGeometryProcessor,
|
||||
fCurrDraw->fFixedDynamicState,
|
||||
fCurrDraw->fDynamicStateArrays);
|
||||
|
||||
this->opsRenderPass()->draw(programInfo, fCurrDraw->fMeshes,
|
||||
fCurrDraw->fMeshCnt, chainBounds);
|
||||
fTokenTracker->flushToken();
|
||||
++fCurrDraw;
|
||||
}
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include "src/gpu/GrGpu.h"
|
||||
#include "src/gpu/GrMesh.h"
|
||||
#include "src/gpu/GrPrimitiveProcessor.h"
|
||||
#include "src/gpu/GrProgramInfo.h"
|
||||
#include "src/gpu/GrRenderTarget.h"
|
||||
#include "src/gpu/GrRenderTargetPriv.h"
|
||||
#include "src/gpu/GrTexturePriv.h"
|
||||
@ -35,10 +36,7 @@ void GrOpsRenderPass::clearStencilClip(const GrFixedClip& clip, bool insideStenc
|
||||
}
|
||||
|
||||
#ifdef SK_DEBUG
|
||||
static void assert_msaa_and_mips_are_resolved(
|
||||
const GrPrimitiveProcessor& primProc, const GrPipeline& pipeline,
|
||||
const GrPipeline::FixedDynamicState* fixedDynamicState,
|
||||
const GrPipeline::DynamicStateArrays* dynamicStateArrays, int meshCount) {
|
||||
static void assert_msaa_and_mips_are_resolved(const GrProgramInfo& programInfo, int meshCount) {
|
||||
auto assertResolved = [](GrTexture* tex, const GrSamplerState& sampler) {
|
||||
SkASSERT(tex);
|
||||
|
||||
@ -52,68 +50,81 @@ static void assert_msaa_and_mips_are_resolved(
|
||||
}
|
||||
};
|
||||
|
||||
if (dynamicStateArrays && dynamicStateArrays->fPrimitiveProcessorTextures) {
|
||||
for (int m = 0, i = 0; m < meshCount; ++m) {
|
||||
for (int s = 0; s < primProc.numTextureSamplers(); ++s, ++i) {
|
||||
auto* tex = dynamicStateArrays->fPrimitiveProcessorTextures[i]->peekTexture();
|
||||
assertResolved(tex, primProc.textureSampler(s).samplerState());
|
||||
if (programInfo.hasDynamicPrimProcTextures()) {
|
||||
for (int m = 0; m < meshCount; ++m) {
|
||||
auto dynamicPrimProcTextures = programInfo.dynamicPrimProcTextures(m);
|
||||
|
||||
for (int s = 0; s < programInfo.primProc().numTextureSamplers(); ++s) {
|
||||
auto* tex = dynamicPrimProcTextures[s]->peekTexture();
|
||||
assertResolved(tex, programInfo.primProc().textureSampler(s).samplerState());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (int i = 0; i < primProc.numTextureSamplers(); ++i) {
|
||||
auto* tex = fixedDynamicState->fPrimitiveProcessorTextures[i]->peekTexture();
|
||||
assertResolved(tex, primProc.textureSampler(i).samplerState());
|
||||
} else if (programInfo.hasFixedPrimProcTextures()) {
|
||||
auto fixedPrimProcTextures = programInfo.fixedPrimProcTextures();
|
||||
|
||||
for (int s = 0; s < programInfo.primProc().numTextureSamplers(); ++s) {
|
||||
auto* tex = fixedPrimProcTextures[s]->peekTexture();
|
||||
assertResolved(tex, programInfo.primProc().textureSampler(s).samplerState());
|
||||
}
|
||||
}
|
||||
|
||||
GrFragmentProcessor::Iter iter(pipeline);
|
||||
GrFragmentProcessor::Iter iter(programInfo.pipeline());
|
||||
while (const GrFragmentProcessor* fp = iter.next()) {
|
||||
for (int i = 0; i < fp->numTextureSamplers(); ++i) {
|
||||
const auto& textureSampler = fp->textureSampler(i);
|
||||
for (int s = 0; s < fp->numTextureSamplers(); ++s) {
|
||||
const auto& textureSampler = fp->textureSampler(s);
|
||||
assertResolved(textureSampler.peekTexture(), textureSampler.samplerState());
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
bool GrOpsRenderPass::draw(const GrPrimitiveProcessor& primProc, const GrPipeline& pipeline,
|
||||
const GrPipeline::FixedDynamicState* fixedDynamicState,
|
||||
const GrPipeline::DynamicStateArrays* dynamicStateArrays,
|
||||
bool GrOpsRenderPass::draw(const GrProgramInfo& programInfo,
|
||||
const GrMesh meshes[], int meshCount, const SkRect& bounds) {
|
||||
if (!meshCount) {
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef SK_DEBUG
|
||||
SkASSERT(!primProc.hasInstanceAttributes() || this->gpu()->caps()->instanceAttribSupport());
|
||||
SkASSERT(!programInfo.primProc().hasInstanceAttributes() ||
|
||||
this->gpu()->caps()->instanceAttribSupport());
|
||||
for (int i = 0; i < meshCount; ++i) {
|
||||
SkASSERT(primProc.hasVertexAttributes() == meshes[i].hasVertexData());
|
||||
SkASSERT(primProc.hasInstanceAttributes() == meshes[i].hasInstanceData());
|
||||
SkASSERT(programInfo.primProc().hasVertexAttributes() == meshes[i].hasVertexData());
|
||||
SkASSERT(programInfo.primProc().hasInstanceAttributes() == meshes[i].hasInstanceData());
|
||||
}
|
||||
|
||||
SkASSERT(!pipeline.isScissorEnabled() || fixedDynamicState ||
|
||||
(dynamicStateArrays && dynamicStateArrays->fScissorRects));
|
||||
SkASSERT(!programInfo.pipeline().isScissorEnabled() || programInfo.fixedDynamicState() ||
|
||||
(programInfo.dynamicStateArrays() && programInfo.dynamicStateArrays()->fScissorRects));
|
||||
|
||||
SkASSERT(!pipeline.isBad());
|
||||
SkASSERT(!programInfo.pipeline().isBad());
|
||||
|
||||
if (fixedDynamicState && fixedDynamicState->fPrimitiveProcessorTextures) {
|
||||
GrTextureProxy** processorProxies = fixedDynamicState->fPrimitiveProcessorTextures;
|
||||
for (int i = 0; i < primProc.numTextureSamplers(); ++i) {
|
||||
SkASSERT(processorProxies[i]->isInstantiated());
|
||||
if (programInfo.hasFixedPrimProcTextures()) {
|
||||
auto fixedPrimProcTextures = programInfo.fixedPrimProcTextures();
|
||||
for (int s = 0; s < programInfo.primProc().numTextureSamplers(); ++s) {
|
||||
SkASSERT(fixedPrimProcTextures[s]->isInstantiated());
|
||||
}
|
||||
}
|
||||
if (dynamicStateArrays && dynamicStateArrays->fPrimitiveProcessorTextures) {
|
||||
int n = primProc.numTextureSamplers() * meshCount;
|
||||
const auto* textures = dynamicStateArrays->fPrimitiveProcessorTextures;
|
||||
for (int i = 0; i < n; ++i) {
|
||||
SkASSERT(textures[i]->isInstantiated());
|
||||
|
||||
if (programInfo.hasDynamicPrimProcTextures()) {
|
||||
for (int m = 0; m < meshCount; ++m) {
|
||||
auto dynamicPrimProcTextures = programInfo.dynamicPrimProcTextures(m);
|
||||
for (int s = 0; s < programInfo.primProc().numTextureSamplers(); ++s) {
|
||||
SkASSERT(dynamicPrimProcTextures[s]->isInstantiated());
|
||||
}
|
||||
}
|
||||
SkASSERT(meshCount >= 1);
|
||||
const GrTextureProxy* const* primProcProxies =
|
||||
dynamicStateArrays->fPrimitiveProcessorTextures;
|
||||
for (int i = 0; i < primProc.numTextureSamplers(); ++i) {
|
||||
const GrBackendFormat& format = primProcProxies[i]->backendFormat();
|
||||
GrTextureType type = primProcProxies[i]->textureType();
|
||||
GrPixelConfig config = primProcProxies[i]->config();
|
||||
for (int j = 1; j < meshCount; ++j) {
|
||||
const GrTextureProxy* testProxy =
|
||||
primProcProxies[j*primProc.numTextureSamplers() + i];
|
||||
|
||||
// Check that, for a given sampler, the properties of the dynamic textures remain
|
||||
// the same for all the meshes
|
||||
for (int s = 0; s < programInfo.primProc().numTextureSamplers(); ++s) {
|
||||
auto dynamicPrimProcTextures = programInfo.dynamicPrimProcTextures(0);
|
||||
|
||||
const GrBackendFormat& format = dynamicPrimProcTextures[s]->backendFormat();
|
||||
GrTextureType type = dynamicPrimProcTextures[s]->textureType();
|
||||
GrPixelConfig config = dynamicPrimProcTextures[s]->config();
|
||||
|
||||
for (int m = 1; m < meshCount; ++m) {
|
||||
dynamicPrimProcTextures = programInfo.dynamicPrimProcTextures(m);
|
||||
|
||||
auto testProxy = dynamicPrimProcTextures[s];
|
||||
SkASSERT(testProxy->backendFormat() == format);
|
||||
SkASSERT(testProxy->textureType() == type);
|
||||
SkASSERT(testProxy->config() == config);
|
||||
@ -121,22 +132,17 @@ bool GrOpsRenderPass::draw(const GrPrimitiveProcessor& primProc, const GrPipelin
|
||||
}
|
||||
}
|
||||
|
||||
assert_msaa_and_mips_are_resolved(
|
||||
primProc, pipeline, fixedDynamicState, dynamicStateArrays, meshCount);
|
||||
assert_msaa_and_mips_are_resolved(programInfo, meshCount);
|
||||
#endif
|
||||
|
||||
if (primProc.numVertexAttributes() > this->gpu()->caps()->maxVertexAttributes()) {
|
||||
if (programInfo.primProc().numVertexAttributes() > this->gpu()->caps()->maxVertexAttributes()) {
|
||||
this->gpu()->stats()->incNumFailedDraws();
|
||||
return false;
|
||||
}
|
||||
this->onDraw(primProc, pipeline, fixedDynamicState, dynamicStateArrays, meshes, meshCount,
|
||||
bounds);
|
||||
this->onDraw(programInfo, meshes, meshCount, bounds);
|
||||
|
||||
#ifdef SK_DEBUG
|
||||
GrProcessor::CustomFeatures processorFeatures = primProc.requestedFeatures();
|
||||
for (int i = 0; i < pipeline.numFragmentProcessors(); ++i) {
|
||||
processorFeatures |= pipeline.getFragmentProcessor(i).requestedFeatures();
|
||||
}
|
||||
processorFeatures |= pipeline.getXferProcessor().requestedFeatures();
|
||||
GrProcessor::CustomFeatures processorFeatures = programInfo.requestedFeatures();
|
||||
if (GrProcessor::CustomFeatures::kSampleLocations & processorFeatures) {
|
||||
// Verify we always have the same sample pattern key, regardless of graphics state.
|
||||
SkASSERT(this->gpu()->findOrAssignSamplePatternKey(fRenderTarget)
|
||||
|
@ -18,6 +18,7 @@ class GrGpu;
|
||||
class GrMesh;
|
||||
class GrPipeline;
|
||||
class GrPrimitiveProcessor;
|
||||
class GrProgramInfo;
|
||||
class GrRenderTarget;
|
||||
class GrSemaphore;
|
||||
struct SkIRect;
|
||||
@ -55,13 +56,7 @@ public:
|
||||
// GrMesh object and emit a draw for it. Each draw will use the same GrPipeline and
|
||||
// GrPrimitiveProcessor. This may fail if the draw would exceed any resource limits (e.g.
|
||||
// number of vertex attributes is too large).
|
||||
bool draw(const GrPrimitiveProcessor&,
|
||||
const GrPipeline&,
|
||||
const GrPipeline::FixedDynamicState*,
|
||||
const GrPipeline::DynamicStateArrays*,
|
||||
const GrMesh[],
|
||||
int meshCount,
|
||||
const SkRect& bounds);
|
||||
bool draw(const GrProgramInfo&, const GrMesh[], int meshCount, const SkRect& bounds);
|
||||
|
||||
// Performs an upload of vertex data in the middle of a set of a set of draws
|
||||
virtual void inlineUpload(GrOpFlushState*, GrDeferredTextureUploadFn&) = 0;
|
||||
@ -100,12 +95,7 @@ private:
|
||||
virtual GrGpu* gpu() = 0;
|
||||
|
||||
// overridden by backend-specific derived class to perform the draw call.
|
||||
virtual void onDraw(const GrPrimitiveProcessor&,
|
||||
const GrPipeline&,
|
||||
const GrPipeline::FixedDynamicState*,
|
||||
const GrPipeline::DynamicStateArrays*,
|
||||
const GrMesh[],
|
||||
int meshCount,
|
||||
virtual void onDraw(const GrProgramInfo&, const GrMesh[], int meshCount,
|
||||
const SkRect& bounds) = 0;
|
||||
|
||||
// overridden by backend-specific derived class to perform the clear.
|
||||
|
@ -412,11 +412,10 @@ void GrOpsTask::onPrepare(GrOpFlushState* flushState) {
|
||||
#ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK
|
||||
TRACE_EVENT0("skia.gpu", chain.head()->name());
|
||||
#endif
|
||||
GrOpFlushState::OpArgs opArgs(
|
||||
chain.head(),
|
||||
fTarget->asRenderTargetProxy(),
|
||||
chain.appliedClip(),
|
||||
chain.dstProxy());
|
||||
GrOpFlushState::OpArgs opArgs(chain.head(),
|
||||
fTarget->asRenderTargetProxy(),
|
||||
chain.appliedClip(),
|
||||
chain.dstProxy());
|
||||
|
||||
flushState->setOpArgs(&opArgs);
|
||||
chain.head()->prepare(flushState);
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include "src/core/SkScalerContext.h"
|
||||
#include "src/gpu/GrGpu.h"
|
||||
#include "src/gpu/GrPathRendering.h"
|
||||
#include "src/gpu/GrProgramInfo.h"
|
||||
#include "src/gpu/GrRenderTarget.h"
|
||||
|
||||
const GrUserStencilSettings& GrPathRendering::GetStencilPassSettings(FillType fill) {
|
||||
@ -50,18 +51,15 @@ void GrPathRendering::stencilPath(const StencilPathArgs& args, const GrPath* pat
|
||||
this->onStencilPath(args, path);
|
||||
}
|
||||
|
||||
void GrPathRendering::drawPath(GrRenderTarget* renderTarget, int numSamples, GrSurfaceOrigin origin,
|
||||
const GrPrimitiveProcessor& primProc,
|
||||
const GrPipeline& pipeline,
|
||||
const GrPipeline::FixedDynamicState& fixedDynamicState,
|
||||
void GrPathRendering::drawPath(GrRenderTarget* renderTarget,
|
||||
const GrProgramInfo& programInfo,
|
||||
// Cover pass settings in pipeline.
|
||||
const GrStencilSettings& stencilPassSettings,
|
||||
const GrPath* path) {
|
||||
fGpu->handleDirtyContext();
|
||||
if (GrXferBarrierType barrierType = pipeline.xferBarrierType(renderTarget->asTexture(),
|
||||
*fGpu->caps())) {
|
||||
if (auto barrierType = programInfo.pipeline().xferBarrierType(renderTarget->asTexture(),
|
||||
*fGpu->caps())) {
|
||||
fGpu->xferBarrier(renderTarget, barrierType);
|
||||
}
|
||||
this->onDrawPath(renderTarget, numSamples, origin, primProc, pipeline, fixedDynamicState,
|
||||
stencilPassSettings, path);
|
||||
this->onDrawPath(renderTarget, programInfo, stencilPassSettings, path);
|
||||
}
|
||||
|
@ -9,12 +9,16 @@
|
||||
#define GrPathRendering_DEFINED
|
||||
|
||||
#include "include/core/SkPath.h"
|
||||
#include "src/gpu/GrPipeline.h"
|
||||
|
||||
class GrGpu;
|
||||
class GrPath;
|
||||
class GrProgramInfo;
|
||||
class GrRenderTarget;
|
||||
class GrRenderTargetProxy;
|
||||
class GrScissorState;
|
||||
class GrStencilSettings;
|
||||
class GrStyle;
|
||||
struct GrUserStencilSettings;
|
||||
struct SkScalerContextEffects;
|
||||
class SkDescriptor;
|
||||
class SkTypeface;
|
||||
@ -108,10 +112,8 @@ public:
|
||||
|
||||
void stencilPath(const StencilPathArgs& args, const GrPath* path);
|
||||
|
||||
void drawPath(GrRenderTarget*, int numSamples, GrSurfaceOrigin,
|
||||
const GrPrimitiveProcessor& primProc,
|
||||
const GrPipeline& pipeline,
|
||||
const GrPipeline::FixedDynamicState&,
|
||||
void drawPath(GrRenderTarget*,
|
||||
const GrProgramInfo&,
|
||||
const GrStencilSettings& stencilPassSettings, // Cover pass settings in pipeline.
|
||||
const GrPath* path);
|
||||
|
||||
@ -119,10 +121,8 @@ protected:
|
||||
GrPathRendering(GrGpu* gpu) : fGpu(gpu) { }
|
||||
|
||||
virtual void onStencilPath(const StencilPathArgs&, const GrPath*) = 0;
|
||||
virtual void onDrawPath(GrRenderTarget*, int numSamples, GrSurfaceOrigin,
|
||||
const GrPrimitiveProcessor&,
|
||||
const GrPipeline&,
|
||||
const GrPipeline::FixedDynamicState&,
|
||||
virtual void onDrawPath(GrRenderTarget*,
|
||||
const GrProgramInfo&,
|
||||
const GrStencilSettings&,
|
||||
const GrPath*) = 0;
|
||||
|
||||
|
@ -42,10 +42,8 @@ void GrGLPathRendering::setProjectionMatrix(const SkMatrix&, const SkISize&, GrS
|
||||
|
||||
sk_sp<GrPath> GrGLPathRendering::createPath(const SkPath&, const GrStyle&) { return nullptr; }
|
||||
|
||||
void GrGLPathRendering::onDrawPath(GrRenderTarget*, int numSamples, GrSurfaceOrigin,
|
||||
const GrPrimitiveProcessor&,
|
||||
const GrPipeline&,
|
||||
const GrPipeline::FixedDynamicState&,
|
||||
void GrGLPathRendering::onDrawPath(GrRenderTarget*,
|
||||
const GrProgramInfo&,
|
||||
const GrStencilSettings&,
|
||||
const GrPath*) {}
|
||||
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include "src/gpu/GrPipeline.h"
|
||||
#include "src/gpu/GrPrimitiveProcessor.h"
|
||||
#include "src/gpu/GrProcessor.h"
|
||||
#include "src/gpu/GrProgramInfo.h"
|
||||
#include "src/gpu/GrRenderTargetPriv.h"
|
||||
#include "src/gpu/GrShaderCaps.h"
|
||||
#include "src/gpu/GrTexturePriv.h"
|
||||
@ -188,10 +189,8 @@ static bool gen_frag_proc_and_meta_keys(const GrPrimitiveProcessor& primProc,
|
||||
fp.numCoordTransforms()), b);
|
||||
}
|
||||
|
||||
bool GrProgramDesc::Build(
|
||||
GrProgramDesc* desc, const GrRenderTarget* renderTarget,
|
||||
const GrPrimitiveProcessor& primProc, bool hasPointSize, const GrPipeline& pipeline,
|
||||
GrGpu* gpu) {
|
||||
bool GrProgramDesc::Build(GrProgramDesc* desc, const GrRenderTarget* renderTarget,
|
||||
const GrProgramInfo& programInfo, bool hasPointSize, GrGpu* gpu) {
|
||||
// The descriptor is used as a cache key. Thus when a field of the
|
||||
// descriptor will not affect program generation (because of the attribute
|
||||
// bindings in use or other descriptor field settings) it should be set
|
||||
@ -206,28 +205,30 @@ bool GrProgramDesc::Build(
|
||||
|
||||
GrProcessorKeyBuilder b(&desc->key());
|
||||
|
||||
primProc.getGLSLProcessorKey(shaderCaps, &b);
|
||||
primProc.getAttributeKey(&b);
|
||||
if (!gen_meta_key(primProc, shaderCaps, 0, &b)) {
|
||||
programInfo.primProc().getGLSLProcessorKey(shaderCaps, &b);
|
||||
programInfo.primProc().getAttributeKey(&b);
|
||||
if (!gen_meta_key(programInfo.primProc(), shaderCaps, 0, &b)) {
|
||||
desc->key().reset();
|
||||
return false;
|
||||
}
|
||||
GrProcessor::CustomFeatures processorFeatures = primProc.requestedFeatures();
|
||||
|
||||
for (int i = 0; i < pipeline.numFragmentProcessors(); ++i) {
|
||||
const GrFragmentProcessor& fp = pipeline.getFragmentProcessor(i);
|
||||
if (!gen_frag_proc_and_meta_keys(primProc, fp, gpu, shaderCaps, &b)) {
|
||||
// TODO: use programInfo.requestedFeatures here
|
||||
GrProcessor::CustomFeatures processorFeatures = programInfo.primProc().requestedFeatures();
|
||||
|
||||
for (int i = 0; i < programInfo.pipeline().numFragmentProcessors(); ++i) {
|
||||
const GrFragmentProcessor& fp = programInfo.pipeline().getFragmentProcessor(i);
|
||||
if (!gen_frag_proc_and_meta_keys(programInfo.primProc(), fp, gpu, shaderCaps, &b)) {
|
||||
desc->key().reset();
|
||||
return false;
|
||||
}
|
||||
processorFeatures |= fp.requestedFeatures();
|
||||
}
|
||||
|
||||
const GrXferProcessor& xp = pipeline.getXferProcessor();
|
||||
const GrXferProcessor& xp = programInfo.pipeline().getXferProcessor();
|
||||
const GrSurfaceOrigin* originIfDstTexture = nullptr;
|
||||
GrSurfaceOrigin origin;
|
||||
if (pipeline.dstTextureProxy()) {
|
||||
origin = pipeline.dstTextureProxy()->origin();
|
||||
if (programInfo.pipeline().dstTextureProxy()) {
|
||||
origin = programInfo.pipeline().dstTextureProxy()->origin();
|
||||
originIfDstTexture = &origin;
|
||||
}
|
||||
xp.getGLSLProcessorKey(shaderCaps, &b, originIfDstTexture);
|
||||
@ -238,7 +239,7 @@ bool GrProgramDesc::Build(
|
||||
processorFeatures |= xp.requestedFeatures();
|
||||
|
||||
if (processorFeatures & GrProcessor::CustomFeatures::kSampleLocations) {
|
||||
SkASSERT(pipeline.isHWAntialiasState());
|
||||
SkASSERT(programInfo.pipeline().isHWAntialiasState());
|
||||
b.add32(renderTarget->renderTargetPriv().getSamplePatternKey());
|
||||
}
|
||||
|
||||
@ -249,17 +250,18 @@ bool GrProgramDesc::Build(
|
||||
|
||||
// make sure any padding in the header is zeroed.
|
||||
memset(header, 0, kHeaderSize);
|
||||
header->fOutputSwizzle = pipeline.outputSwizzle().asKey();
|
||||
header->fColorFragmentProcessorCnt = pipeline.numColorFragmentProcessors();
|
||||
header->fCoverageFragmentProcessorCnt = pipeline.numCoverageFragmentProcessors();
|
||||
header->fOutputSwizzle = programInfo.pipeline().outputSwizzle().asKey();
|
||||
header->fColorFragmentProcessorCnt = programInfo.pipeline().numColorFragmentProcessors();
|
||||
header->fCoverageFragmentProcessorCnt = programInfo.pipeline().numCoverageFragmentProcessors();
|
||||
// Fail if the client requested more processors than the key can fit.
|
||||
if (header->fColorFragmentProcessorCnt != pipeline.numColorFragmentProcessors() ||
|
||||
header->fCoverageFragmentProcessorCnt != pipeline.numCoverageFragmentProcessors()) {
|
||||
if (header->fColorFragmentProcessorCnt != programInfo.pipeline().numColorFragmentProcessors() ||
|
||||
header->fCoverageFragmentProcessorCnt !=
|
||||
programInfo.pipeline().numCoverageFragmentProcessors()) {
|
||||
return false;
|
||||
}
|
||||
header->fProcessorFeatures = (uint8_t)processorFeatures;
|
||||
SkASSERT(header->processorFeatures() == processorFeatures); // Ensure enough bits.
|
||||
header->fSnapVerticesToPixelCenters = pipeline.snapVerticesToPixelCenters();
|
||||
header->fSnapVerticesToPixelCenters = programInfo.pipeline().snapVerticesToPixelCenters();
|
||||
header->fHasPointSize = hasPointSize ? 1 : 0;
|
||||
return true;
|
||||
}
|
||||
|
@ -15,9 +15,8 @@
|
||||
#include "src/gpu/GrColor.h"
|
||||
#include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h"
|
||||
|
||||
class GrProgramInfo;
|
||||
class GrShaderCaps;
|
||||
class GrPipeline;
|
||||
class GrPrimitiveProcessor;
|
||||
|
||||
/** This class describes a program to generate. It also serves as a program cache key */
|
||||
class GrProgramDesc {
|
||||
@ -29,18 +28,14 @@ public:
|
||||
* Builds a program descriptor. Before the descriptor can be used, the client must call finalize
|
||||
* on the returned GrProgramDesc.
|
||||
*
|
||||
* @param GrPrimitiveProcessor The geometry
|
||||
* @param desc The built and finalized descriptor
|
||||
* @param renderTarget The target of the draw
|
||||
* @param programInfo Program information need to build the key
|
||||
* @param hasPointSize Controls whether the shader will output a point size.
|
||||
* @param GrPipeline The optimized drawstate. The descriptor will represent a program
|
||||
* which this optstate can use to draw with. The optstate contains
|
||||
* general draw information, as well as the specific color, geometry,
|
||||
* and coverage stages which will be used to generate the GL Program for
|
||||
* this optstate.
|
||||
* @param GrGpu Ptr to the GrGpu object the program will be used with.
|
||||
* @param GrProgramDesc The built and finalized descriptor
|
||||
* @param gpu Pointer to the GrGpu object the program will be used with.
|
||||
**/
|
||||
static bool Build(GrProgramDesc*, const GrRenderTarget*, const GrPrimitiveProcessor&,
|
||||
bool hasPointSize, const GrPipeline&, GrGpu*);
|
||||
static bool Build(GrProgramDesc*, const GrRenderTarget*, const GrProgramInfo&,
|
||||
bool hasPointSize, GrGpu*);
|
||||
|
||||
static bool BuildFromData(GrProgramDesc* desc, const void* keyData, size_t keyLength) {
|
||||
if (!SkTFitsIn<int>(keyLength)) {
|
||||
|
117
src/gpu/GrProgramInfo.h
Normal file
117
src/gpu/GrProgramInfo.h
Normal file
@ -0,0 +1,117 @@
|
||||
/*
|
||||
* 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 GrProgramInfo_DEFINED
|
||||
#define GrProgramInfo_DEFINED
|
||||
|
||||
#include "include/gpu/GrTypes.h"
|
||||
#include "src/gpu/GrPipeline.h"
|
||||
#include "src/gpu/GrPrimitiveProcessor.h"
|
||||
|
||||
class GrProgramInfo {
|
||||
public:
|
||||
GrProgramInfo(int numSamples,
|
||||
GrSurfaceOrigin origin,
|
||||
const GrPipeline& pipeline,
|
||||
const GrPrimitiveProcessor& primProc,
|
||||
const GrPipeline::FixedDynamicState* fixedDynamicState,
|
||||
const GrPipeline::DynamicStateArrays* dynamicStateArrays)
|
||||
: fNumSamples(numSamples)
|
||||
, fOrigin(origin)
|
||||
, fPipeline(pipeline)
|
||||
, fPrimProc(primProc)
|
||||
, fFixedDynamicState(fixedDynamicState)
|
||||
, fDynamicStateArrays(dynamicStateArrays) {
|
||||
}
|
||||
|
||||
int numSamples() const { return fNumSamples; }
|
||||
GrSurfaceOrigin origin() const { return fOrigin; }
|
||||
const GrPipeline& pipeline() const { return fPipeline; }
|
||||
const GrPrimitiveProcessor& primProc() const { return fPrimProc; }
|
||||
const GrPipeline::FixedDynamicState* fixedDynamicState() const { return fFixedDynamicState; }
|
||||
const GrPipeline::DynamicStateArrays* dynamicStateArrays() const { return fDynamicStateArrays; }
|
||||
|
||||
// TODO: can this be removed?
|
||||
const GrTextureProxy* const* primProcProxies() const {
|
||||
const GrTextureProxy* const* primProcProxies = nullptr;
|
||||
if (fDynamicStateArrays && fDynamicStateArrays->fPrimitiveProcessorTextures) {
|
||||
primProcProxies = fDynamicStateArrays->fPrimitiveProcessorTextures;
|
||||
} else if (fFixedDynamicState) {
|
||||
primProcProxies = fFixedDynamicState->fPrimitiveProcessorTextures;
|
||||
}
|
||||
|
||||
SkASSERT(SkToBool(primProcProxies) == SkToBool(fPrimProc.numTextureSamplers()));
|
||||
return primProcProxies;
|
||||
}
|
||||
|
||||
bool hasDynamicScissors() const {
|
||||
return fPipeline.isScissorEnabled() &&
|
||||
fDynamicStateArrays && fDynamicStateArrays->fScissorRects;
|
||||
}
|
||||
|
||||
const SkIRect& dynamicScissor(int i) const {
|
||||
SkASSERT(this->hasDynamicScissors());
|
||||
|
||||
return fDynamicStateArrays->fScissorRects[i];
|
||||
}
|
||||
|
||||
bool hasFixedScissor() const { return fPipeline.isScissorEnabled() && fFixedDynamicState; }
|
||||
|
||||
const SkIRect& fixedScissor() const {
|
||||
SkASSERT(this->hasFixedScissor());
|
||||
|
||||
return fFixedDynamicState->fScissorRect;
|
||||
}
|
||||
|
||||
bool hasDynamicPrimProcTextures() const {
|
||||
return fDynamicStateArrays && fDynamicStateArrays->fPrimitiveProcessorTextures;
|
||||
}
|
||||
|
||||
const GrTextureProxy* const* dynamicPrimProcTextures(int i) const {
|
||||
SkASSERT(this->hasDynamicPrimProcTextures());
|
||||
|
||||
return fDynamicStateArrays->fPrimitiveProcessorTextures +
|
||||
i * fPrimProc.numTextureSamplers();
|
||||
}
|
||||
|
||||
bool hasFixedPrimProcTextures() const {
|
||||
return fFixedDynamicState && fFixedDynamicState->fPrimitiveProcessorTextures;
|
||||
}
|
||||
|
||||
const GrTextureProxy* const* fixedPrimProcTextures() const {
|
||||
SkASSERT(this->hasFixedPrimProcTextures());
|
||||
|
||||
return fFixedDynamicState->fPrimitiveProcessorTextures;
|
||||
}
|
||||
|
||||
#ifdef SK_DEBUG
|
||||
bool isNVPR() const {
|
||||
return fPrimProc.isPathRendering() && !fPrimProc.willUseGeoShader() &&
|
||||
!fPrimProc.numVertexAttributes() && !fPrimProc.numInstanceAttributes();
|
||||
}
|
||||
|
||||
// TODO: calculate this once in the ctor and use more widely
|
||||
GrProcessor::CustomFeatures requestedFeatures() const {
|
||||
GrProcessor::CustomFeatures requestedFeatures = fPrimProc.requestedFeatures();
|
||||
for (int i = 0; i < fPipeline.numFragmentProcessors(); ++i) {
|
||||
requestedFeatures |= fPipeline.getFragmentProcessor(i).requestedFeatures();
|
||||
}
|
||||
requestedFeatures |= fPipeline.getXferProcessor().requestedFeatures();
|
||||
return requestedFeatures;
|
||||
}
|
||||
#endif
|
||||
|
||||
private:
|
||||
const int fNumSamples;
|
||||
const GrSurfaceOrigin fOrigin;
|
||||
const GrPipeline& fPipeline;
|
||||
const GrPrimitiveProcessor& fPrimProc;
|
||||
const GrPipeline::FixedDynamicState* fFixedDynamicState;
|
||||
const GrPipeline::DynamicStateArrays* fDynamicStateArrays;
|
||||
};
|
||||
|
||||
#endif
|
@ -10,6 +10,7 @@
|
||||
#include "src/core/SkMakeUnique.h"
|
||||
#include "src/gpu/GrOpFlushState.h"
|
||||
#include "src/gpu/GrOpsRenderPass.h"
|
||||
#include "src/gpu/GrProgramInfo.h"
|
||||
#include "src/gpu/ccpr/GrCCConicShader.h"
|
||||
#include "src/gpu/ccpr/GrCCCubicShader.h"
|
||||
#include "src/gpu/ccpr/GrCCQuadraticShader.h"
|
||||
@ -201,5 +202,14 @@ void GrCCCoverageProcessor::draw(
|
||||
GrPipeline::DynamicStateArrays dynamicStateArrays;
|
||||
dynamicStateArrays.fScissorRects = scissorRects;
|
||||
GrOpsRenderPass* renderPass = flushState->opsRenderPass();
|
||||
renderPass->draw(*this, pipeline, nullptr, &dynamicStateArrays, meshes, meshCount, drawBounds);
|
||||
|
||||
GrProgramInfo programInfo(flushState->drawOpArgs().numSamples(),
|
||||
flushState->drawOpArgs().origin(),
|
||||
pipeline,
|
||||
*this,
|
||||
nullptr,
|
||||
&dynamicStateArrays);
|
||||
|
||||
|
||||
renderPass->draw(programInfo, meshes, meshCount, drawBounds);
|
||||
}
|
||||
|
@ -141,8 +141,14 @@ void GrCCPathProcessor::drawPaths(GrOpFlushState* flushState, const GrPipeline&
|
||||
baseInstance, enablePrimitiveRestart);
|
||||
mesh.setVertexData(resources.refVertexBuffer());
|
||||
|
||||
flushState->opsRenderPass()->draw(*this, pipeline, fixedDynamicState, nullptr, &mesh, 1,
|
||||
bounds);
|
||||
GrProgramInfo programInfo(flushState->drawOpArgs().numSamples(),
|
||||
flushState->drawOpArgs().origin(),
|
||||
pipeline,
|
||||
*this,
|
||||
fixedDynamicState,
|
||||
nullptr);
|
||||
|
||||
flushState->opsRenderPass()->draw(programInfo, &mesh, 1, bounds);
|
||||
}
|
||||
|
||||
void GrCCPathProcessor::Impl::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) {
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include "src/core/SkPathPriv.h"
|
||||
#include "src/gpu/GrOnFlushResourceProvider.h"
|
||||
#include "src/gpu/GrOpsRenderPass.h"
|
||||
#include "src/gpu/GrProgramInfo.h"
|
||||
#include "src/gpu/ccpr/GrCCCoverageProcessor.h"
|
||||
#include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h"
|
||||
#include "src/gpu/glsl/GrGLSLVertexGeoBuilder.h"
|
||||
@ -775,7 +776,15 @@ void GrCCStroker::flushBufferedMeshesAsStrokes(const GrPrimitiveProcessor& proce
|
||||
SkASSERT(fMeshesBuffer.count() == fScissorsBuffer.count());
|
||||
GrPipeline::DynamicStateArrays dynamicStateArrays;
|
||||
dynamicStateArrays.fScissorRects = fScissorsBuffer.begin();
|
||||
flushState->opsRenderPass()->draw(processor, pipeline, nullptr, &dynamicStateArrays,
|
||||
|
||||
GrProgramInfo programInfo(flushState->drawOpArgs().numSamples(),
|
||||
flushState->drawOpArgs().origin(),
|
||||
pipeline,
|
||||
processor,
|
||||
nullptr,
|
||||
&dynamicStateArrays);
|
||||
|
||||
flushState->opsRenderPass()->draw(programInfo,
|
||||
fMeshesBuffer.begin(), fMeshesBuffer.count(),
|
||||
SkRect::Make(drawBounds));
|
||||
// Don't call reset(), as that also resets the reserve count.
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include "include/private/GrRecordingContext.h"
|
||||
#include "src/gpu/GrOpFlushState.h"
|
||||
#include "src/gpu/GrOpsRenderPass.h"
|
||||
#include "src/gpu/GrProgramInfo.h"
|
||||
#include "src/gpu/GrRecordingContextPriv.h"
|
||||
#include "src/gpu/ccpr/GrCCPerFlushResources.h"
|
||||
#include "src/gpu/ccpr/GrSampleMaskProcessor.h"
|
||||
@ -147,6 +148,15 @@ void GrStencilAtlasOp::onExecute(GrOpFlushState* flushState, const SkRect& chain
|
||||
mesh.setInstanced(fResources->refStencilResolveBuffer(),
|
||||
fEndStencilResolveInstance - fBaseStencilResolveInstance,
|
||||
fBaseStencilResolveInstance, 4);
|
||||
flushState->opsRenderPass()->draw(StencilResolveProcessor(), resolvePipeline, &scissorRectState,
|
||||
nullptr, &mesh, 1, SkRect::Make(drawBoundsRect));
|
||||
|
||||
StencilResolveProcessor primProc;
|
||||
|
||||
GrProgramInfo programInfo(flushState->drawOpArgs().numSamples(),
|
||||
flushState->drawOpArgs().origin(),
|
||||
resolvePipeline,
|
||||
primProc,
|
||||
&scissorRectState,
|
||||
nullptr);
|
||||
|
||||
flushState->opsRenderPass()->draw(programInfo, &mesh, 1, SkRect::Make(drawBoundsRect));
|
||||
}
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include "src/gpu/GrGpuResourcePriv.h"
|
||||
#include "src/gpu/GrMesh.h"
|
||||
#include "src/gpu/GrPipeline.h"
|
||||
#include "src/gpu/GrProgramInfo.h"
|
||||
#include "src/gpu/GrRenderTargetPriv.h"
|
||||
#include "src/gpu/GrShaderCaps.h"
|
||||
#include "src/gpu/GrSurfaceProxyPriv.h"
|
||||
@ -1658,28 +1659,11 @@ void GrGLGpu::disableWindowRectangles() {
|
||||
}
|
||||
|
||||
bool GrGLGpu::flushGLState(GrRenderTarget* renderTarget,
|
||||
int numSamples,
|
||||
GrSurfaceOrigin origin,
|
||||
const GrPrimitiveProcessor& primProc,
|
||||
const GrPipeline& pipeline,
|
||||
const GrPipeline::FixedDynamicState* fixedDynamicState,
|
||||
const GrPipeline::DynamicStateArrays* dynamicStateArrays,
|
||||
int dynamicStateArraysLength,
|
||||
const GrProgramInfo& programInfo,
|
||||
bool willDrawPoints) {
|
||||
const GrTextureProxy* const* primProcProxies = nullptr;
|
||||
const GrTextureProxy* const* primProcProxiesToBind = nullptr;
|
||||
if (dynamicStateArrays && dynamicStateArrays->fPrimitiveProcessorTextures) {
|
||||
primProcProxies = dynamicStateArrays->fPrimitiveProcessorTextures;
|
||||
} else if (fixedDynamicState && fixedDynamicState->fPrimitiveProcessorTextures) {
|
||||
primProcProxies = fixedDynamicState->fPrimitiveProcessorTextures;
|
||||
primProcProxiesToBind = fixedDynamicState->fPrimitiveProcessorTextures;
|
||||
}
|
||||
|
||||
SkASSERT(SkToBool(primProcProxies) == SkToBool(primProc.numTextureSamplers()));
|
||||
|
||||
sk_sp<GrGLProgram> program(fProgramCache->refProgram(
|
||||
this, renderTarget, numSamples, origin, primProc, primProcProxies, pipeline,
|
||||
willDrawPoints));
|
||||
sk_sp<GrGLProgram> program(fProgramCache->refProgram(this, renderTarget, programInfo,
|
||||
willDrawPoints));
|
||||
if (!program) {
|
||||
GrCapsDebugf(this->caps(), "Failed to create program!\n");
|
||||
return false;
|
||||
@ -1688,30 +1672,32 @@ bool GrGLGpu::flushGLState(GrRenderTarget* renderTarget,
|
||||
this->flushProgram(std::move(program));
|
||||
|
||||
// Swizzle the blend to match what the shader will output.
|
||||
this->flushBlendAndColorWrite(
|
||||
pipeline.getXferProcessor().getBlendInfo(), pipeline.outputSwizzle());
|
||||
this->flushBlendAndColorWrite(programInfo.pipeline().getXferProcessor().getBlendInfo(),
|
||||
programInfo.pipeline().outputSwizzle());
|
||||
|
||||
fHWProgram->updateUniformsAndTextureBindings(renderTarget, origin,
|
||||
primProc, pipeline, primProcProxiesToBind);
|
||||
fHWProgram->updateUniformsAndTextureBindings(renderTarget, programInfo);
|
||||
|
||||
GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(renderTarget);
|
||||
GrStencilSettings stencil;
|
||||
if (pipeline.isStencilEnabled()) {
|
||||
if (programInfo.pipeline().isStencilEnabled()) {
|
||||
// TODO: attach stencil and create settings during render target flush.
|
||||
SkASSERT(glRT->renderTargetPriv().getStencilAttachment());
|
||||
stencil.reset(*pipeline.getUserStencil(), pipeline.hasStencilClip(),
|
||||
stencil.reset(*programInfo.pipeline().getUserStencil(),
|
||||
programInfo.pipeline().hasStencilClip(),
|
||||
glRT->renderTargetPriv().numStencilBits());
|
||||
}
|
||||
this->flushStencil(stencil, origin);
|
||||
if (pipeline.isScissorEnabled()) {
|
||||
this->flushStencil(stencil, programInfo.origin());
|
||||
if (programInfo.pipeline().isScissorEnabled()) {
|
||||
static constexpr SkIRect kBogusScissor{0, 0, 1, 1};
|
||||
GrScissorState state(fixedDynamicState ? fixedDynamicState->fScissorRect : kBogusScissor);
|
||||
this->flushScissor(state, glRT->width(), glRT->height(), origin);
|
||||
GrScissorState state(programInfo.fixedDynamicState() ? programInfo.fixedScissor()
|
||||
: kBogusScissor);
|
||||
this->flushScissor(state, glRT->width(), glRT->height(), programInfo.origin());
|
||||
} else {
|
||||
this->disableScissor();
|
||||
}
|
||||
this->flushWindowRectangles(pipeline.getWindowRectsState(), glRT, origin);
|
||||
this->flushHWAAState(glRT, pipeline.isHWAntialiasState());
|
||||
this->flushWindowRectangles(programInfo.pipeline().getWindowRectsState(),
|
||||
glRT, programInfo.origin());
|
||||
this->flushHWAAState(glRT, programInfo.pipeline().isHWAntialiasState());
|
||||
|
||||
// This must come after textures are flushed because a texture may need
|
||||
// to be msaa-resolved (which will modify bound FBO state).
|
||||
@ -2180,15 +2166,16 @@ void GrGLGpu::flushViewport(int width, int height) {
|
||||
#endif
|
||||
#endif
|
||||
|
||||
void GrGLGpu::draw(GrRenderTarget* renderTarget, int numSamples, GrSurfaceOrigin origin,
|
||||
const GrPrimitiveProcessor& primProc,
|
||||
const GrPipeline& pipeline,
|
||||
const GrPipeline::FixedDynamicState* fixedDynamicState,
|
||||
const GrPipeline::DynamicStateArrays* dynamicStateArrays,
|
||||
void GrGLGpu::draw(GrRenderTarget* renderTarget,
|
||||
const GrProgramInfo& programInfo,
|
||||
const GrMesh meshes[],
|
||||
int meshCount) {
|
||||
this->handleDirtyContext();
|
||||
|
||||
if (meshCount == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
bool hasPoints = false;
|
||||
for (int i = 0; i < meshCount; ++i) {
|
||||
if (meshes[i].primitiveType() == GrPrimitiveType::kPoints) {
|
||||
@ -2196,32 +2183,28 @@ void GrGLGpu::draw(GrRenderTarget* renderTarget, int numSamples, GrSurfaceOrigin
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!this->flushGLState(renderTarget, numSamples, origin, primProc, pipeline, fixedDynamicState,
|
||||
dynamicStateArrays, meshCount, hasPoints)) {
|
||||
if (!this->flushGLState(renderTarget, programInfo, hasPoints)) {
|
||||
return;
|
||||
}
|
||||
|
||||
bool dynamicScissor = false;
|
||||
bool dynamicPrimProcTextures = false;
|
||||
if (dynamicStateArrays) {
|
||||
dynamicScissor = pipeline.isScissorEnabled() && dynamicStateArrays->fScissorRects;
|
||||
dynamicPrimProcTextures = dynamicStateArrays->fPrimitiveProcessorTextures;
|
||||
}
|
||||
bool hasDynamicScissors = programInfo.hasDynamicScissors();
|
||||
bool hasDynamicPrimProcTextures = programInfo.hasDynamicPrimProcTextures();
|
||||
|
||||
for (int m = 0; m < meshCount; ++m) {
|
||||
if (GrXferBarrierType barrierType = pipeline.xferBarrierType(renderTarget->asTexture(),
|
||||
*this->caps())) {
|
||||
if (auto barrierType = programInfo.pipeline().xferBarrierType(renderTarget->asTexture(),
|
||||
*this->caps())) {
|
||||
this->xferBarrier(renderTarget, barrierType);
|
||||
}
|
||||
|
||||
if (dynamicScissor) {
|
||||
if (hasDynamicScissors) {
|
||||
GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(renderTarget);
|
||||
this->flushScissor(GrScissorState(dynamicStateArrays->fScissorRects[m]),
|
||||
glRT->width(), glRT->height(), origin);
|
||||
this->flushScissor(GrScissorState(programInfo.dynamicScissor(m)),
|
||||
glRT->width(), glRT->height(), programInfo.origin());
|
||||
}
|
||||
if (dynamicPrimProcTextures) {
|
||||
auto texProxyArray = dynamicStateArrays->fPrimitiveProcessorTextures +
|
||||
m * primProc.numTextureSamplers();
|
||||
fHWProgram->updatePrimitiveProcessorTextureBindings(primProc, texProxyArray);
|
||||
if (hasDynamicPrimProcTextures) {
|
||||
auto texProxyArray = programInfo.dynamicPrimProcTextures(m);
|
||||
fHWProgram->updatePrimitiveProcessorTextureBindings(programInfo.primProc(),
|
||||
texProxyArray);
|
||||
}
|
||||
if (this->glCaps().requiresCullFaceEnableDisableWhenDrawingLinesAfterNonLines() &&
|
||||
GrIsPrimTypeLines(meshes[m].primitiveType()) &&
|
||||
|
@ -75,13 +75,7 @@ public:
|
||||
// The GrGLOpsRenderPass does not buffer up draws before submitting them to the gpu.
|
||||
// Thus this is the implementation of the draw call for the corresponding passthrough function
|
||||
// on GrGLOpsRenderPass.
|
||||
void draw(GrRenderTarget*, int numSamples, GrSurfaceOrigin,
|
||||
const GrPrimitiveProcessor&,
|
||||
const GrPipeline&,
|
||||
const GrPipeline::FixedDynamicState*,
|
||||
const GrPipeline::DynamicStateArrays*,
|
||||
const GrMesh[],
|
||||
int meshCount);
|
||||
void draw(GrRenderTarget*, const GrProgramInfo&, const GrMesh[], int meshCount);
|
||||
|
||||
// GrMesh::SendToGpuImpl methods. These issue the actual GL draw calls.
|
||||
// Marked final as a hint to the compiler to not use virtual dispatch.
|
||||
@ -280,10 +274,7 @@ private:
|
||||
// willDrawPoints must be true if point primitives will be rendered after setting the GL state.
|
||||
// If DynamicStateArrays is not null then dynamicStateArraysLength is the number of dynamic
|
||||
// state entries in each array.
|
||||
bool flushGLState(GrRenderTarget*, int numSamples, GrSurfaceOrigin, const GrPrimitiveProcessor&,
|
||||
const GrPipeline&, const GrPipeline::FixedDynamicState*,
|
||||
const GrPipeline::DynamicStateArrays*, int dynamicStateArraysLength,
|
||||
bool willDrawPoints);
|
||||
bool flushGLState(GrRenderTarget*, const GrProgramInfo&, bool willDrawPoints);
|
||||
|
||||
void flushProgram(sk_sp<GrGLProgram>);
|
||||
|
||||
@ -321,10 +312,7 @@ private:
|
||||
|
||||
void abandon();
|
||||
void reset();
|
||||
GrGLProgram* refProgram(GrGLGpu*, GrRenderTarget*, int numSamples, GrSurfaceOrigin,
|
||||
const GrPrimitiveProcessor&,
|
||||
const GrTextureProxy* const primProcProxies[],
|
||||
const GrPipeline&, bool hasPointSize);
|
||||
GrGLProgram* refProgram(GrGLGpu*, GrRenderTarget*, const GrProgramInfo&, bool hasPointSize);
|
||||
bool precompileShader(const SkData& key, const SkData& data);
|
||||
|
||||
private:
|
||||
|
@ -47,30 +47,29 @@ void GrGLGpu::ProgramCache::reset() {
|
||||
|
||||
GrGLProgram* GrGLGpu::ProgramCache::refProgram(GrGLGpu* gpu,
|
||||
GrRenderTarget* renderTarget,
|
||||
int numSamples,
|
||||
GrSurfaceOrigin origin,
|
||||
const GrPrimitiveProcessor& primProc,
|
||||
const GrTextureProxy* const primProcProxies[],
|
||||
const GrPipeline& pipeline,
|
||||
const GrProgramInfo& programInfo,
|
||||
bool isPoints) {
|
||||
|
||||
|
||||
// TODO: can this be unified between GL and Vk?
|
||||
// Get GrGLProgramDesc
|
||||
GrProgramDesc desc;
|
||||
if (!GrProgramDesc::Build(&desc, renderTarget, primProc, isPoints, pipeline, gpu)) {
|
||||
if (!GrProgramDesc::Build(&desc, renderTarget, programInfo, isPoints, gpu)) {
|
||||
GrCapsDebugf(gpu->caps(), "Failed to gl program descriptor!\n");
|
||||
return nullptr;
|
||||
}
|
||||
// If we knew the shader won't depend on origin, we could skip this (and use the same program
|
||||
// for both origins). Instrumenting all fragment processors would be difficult and error prone.
|
||||
desc.setSurfaceOriginKey(GrGLSLFragmentShaderBuilder::KeyForSurfaceOrigin(origin));
|
||||
desc.setSurfaceOriginKey(
|
||||
GrGLSLFragmentShaderBuilder::KeyForSurfaceOrigin(programInfo.origin()));
|
||||
|
||||
std::unique_ptr<Entry>* entry = fMap.find(desc);
|
||||
if (entry && !(*entry)->fProgram) {
|
||||
// We've pre-compiled the GL program, but don't have the GrGLProgram scaffolding
|
||||
const GrGLPrecompiledProgram* precompiledProgram = &((*entry)->fPrecompiledProgram);
|
||||
SkASSERT(precompiledProgram->fProgramID != 0);
|
||||
GrGLProgram* program = GrGLProgramBuilder::CreateProgram(renderTarget, numSamples, origin,
|
||||
primProc, primProcProxies,
|
||||
pipeline, &desc, fGpu,
|
||||
GrGLProgram* program = GrGLProgramBuilder::CreateProgram(renderTarget, programInfo,
|
||||
&desc, fGpu,
|
||||
precompiledProgram);
|
||||
if (nullptr == program) {
|
||||
// Should we purge the program ID from the cache at this point?
|
||||
@ -80,9 +79,8 @@ GrGLProgram* GrGLGpu::ProgramCache::refProgram(GrGLGpu* gpu,
|
||||
(*entry)->fProgram.reset(program);
|
||||
} else if (!entry) {
|
||||
// We have a cache miss
|
||||
GrGLProgram* program = GrGLProgramBuilder::CreateProgram(renderTarget, numSamples, origin,
|
||||
primProc, primProcProxies,
|
||||
pipeline, &desc, fGpu);
|
||||
GrGLProgram* program = GrGLProgramBuilder::CreateProgram(renderTarget, programInfo,
|
||||
&desc, fGpu);
|
||||
if (nullptr == program) {
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -52,15 +52,9 @@ public:
|
||||
private:
|
||||
GrGpu* gpu() override { return fGpu; }
|
||||
|
||||
void onDraw(const GrPrimitiveProcessor& primProc,
|
||||
const GrPipeline& pipeline,
|
||||
const GrPipeline::FixedDynamicState* fixedDynamicState,
|
||||
const GrPipeline::DynamicStateArrays* dynamicStateArrays,
|
||||
const GrMesh mesh[],
|
||||
int meshCount,
|
||||
void onDraw(const GrProgramInfo& programInfo, const GrMesh mesh[], int meshCount,
|
||||
const SkRect& bounds) override {
|
||||
fGpu->draw(fRenderTarget, fRenderTarget->numSamples(), fOrigin, primProc, pipeline,
|
||||
fixedDynamicState, dynamicStateArrays, mesh, meshCount);
|
||||
fGpu->draw(fRenderTarget, programInfo, mesh, meshCount);
|
||||
}
|
||||
|
||||
void onClear(const GrFixedClip& clip, const SkPMColor4f& color) override {
|
||||
|
@ -112,14 +112,10 @@ void GrGLPathRendering::onStencilPath(const StencilPathArgs& args, const GrPath*
|
||||
}
|
||||
|
||||
void GrGLPathRendering::onDrawPath(GrRenderTarget* renderTarget,
|
||||
int numSamples, GrSurfaceOrigin origin,
|
||||
const GrPrimitiveProcessor& primProc,
|
||||
const GrPipeline& pipeline,
|
||||
const GrPipeline::FixedDynamicState& fixedDynamicState,
|
||||
const GrProgramInfo& programInfo,
|
||||
const GrStencilSettings& stencilPassSettings,
|
||||
const GrPath* path) {
|
||||
if (!this->gpu()->flushGLState(renderTarget, numSamples, origin, primProc, pipeline,
|
||||
&fixedDynamicState, nullptr, 1, false)) {
|
||||
if (!this->gpu()->flushGLState(renderTarget, programInfo, false)) {
|
||||
return;
|
||||
}
|
||||
const GrGLPath* glPath = static_cast<const GrGLPath*>(path);
|
||||
|
@ -65,11 +65,7 @@ public:
|
||||
|
||||
protected:
|
||||
void onStencilPath(const StencilPathArgs&, const GrPath*) override;
|
||||
void onDrawPath(GrRenderTarget*, int numSamples, GrSurfaceOrigin,
|
||||
const GrPrimitiveProcessor&,
|
||||
const GrPipeline&,
|
||||
const GrPipeline::FixedDynamicState&,
|
||||
const GrStencilSettings&,
|
||||
void onDrawPath(GrRenderTarget*, const GrProgramInfo&, const GrStencilSettings&,
|
||||
const GrPath*) override;
|
||||
|
||||
private:
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include "src/gpu/GrPathProcessor.h"
|
||||
#include "src/gpu/GrPipeline.h"
|
||||
#include "src/gpu/GrProcessor.h"
|
||||
#include "src/gpu/GrProgramInfo.h"
|
||||
#include "src/gpu/GrTexturePriv.h"
|
||||
#include "src/gpu/GrXferProcessor.h"
|
||||
#include "src/gpu/gl/GrGLBuffer.h"
|
||||
@ -73,11 +74,9 @@ void GrGLProgram::abandon() {
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void GrGLProgram::updateUniformsAndTextureBindings(const GrRenderTarget* renderTarget,
|
||||
GrSurfaceOrigin origin,
|
||||
const GrPrimitiveProcessor& primProc,
|
||||
const GrPipeline& pipeline,
|
||||
const GrTextureProxy* const primProcTextures[]) {
|
||||
this->setRenderTargetState(renderTarget, origin, primProc);
|
||||
const GrProgramInfo& programInfo) {
|
||||
|
||||
this->setRenderTargetState(renderTarget, programInfo.origin(), programInfo.primProc());
|
||||
|
||||
// we set the textures, and uniforms for installed processors in a generic way, but subclasses
|
||||
// of GLProgram determine how to set coord transforms
|
||||
@ -85,23 +84,24 @@ void GrGLProgram::updateUniformsAndTextureBindings(const GrRenderTarget* renderT
|
||||
// We must bind to texture units in the same order in which we set the uniforms in
|
||||
// GrGLProgramDataManager. That is, we bind textures for processors in this order:
|
||||
// primProc, fragProcs, XP.
|
||||
fPrimitiveProcessor->setData(fProgramDataManager, primProc,
|
||||
GrFragmentProcessor::CoordTransformIter(pipeline));
|
||||
if (primProcTextures) {
|
||||
this->updatePrimitiveProcessorTextureBindings(primProc, primProcTextures);
|
||||
fPrimitiveProcessor->setData(fProgramDataManager, programInfo.primProc(),
|
||||
GrFragmentProcessor::CoordTransformIter(programInfo.pipeline()));
|
||||
if (programInfo.hasFixedPrimProcTextures()) {
|
||||
this->updatePrimitiveProcessorTextureBindings(programInfo.primProc(),
|
||||
programInfo.fixedPrimProcTextures());
|
||||
}
|
||||
int nextTexSamplerIdx = primProc.numTextureSamplers();
|
||||
int nextTexSamplerIdx = programInfo.primProc().numTextureSamplers();
|
||||
|
||||
this->setFragmentData(pipeline, &nextTexSamplerIdx);
|
||||
this->setFragmentData(programInfo.pipeline(), &nextTexSamplerIdx);
|
||||
|
||||
const GrXferProcessor& xp = pipeline.getXferProcessor();
|
||||
const GrXferProcessor& xp = programInfo.pipeline().getXferProcessor();
|
||||
SkIPoint offset;
|
||||
GrTexture* dstTexture = pipeline.peekDstTexture(&offset);
|
||||
GrTexture* dstTexture = programInfo.pipeline().peekDstTexture(&offset);
|
||||
|
||||
fXferProcessor->setData(fProgramDataManager, xp, dstTexture, offset);
|
||||
if (dstTexture) {
|
||||
fGpu->bindTexture(nextTexSamplerIdx++, GrSamplerState::ClampNearest(),
|
||||
pipeline.dstTextureProxy()->textureSwizzle(),
|
||||
programInfo.pipeline().dstTextureProxy()->textureSwizzle(),
|
||||
static_cast<GrGLTexture*>(dstTexture));
|
||||
}
|
||||
SkASSERT(nextTexSamplerIdx == fNumTextureSamplers);
|
||||
|
@ -18,6 +18,7 @@ class GrGLSLPrimitiveProcessor;
|
||||
class GrGLSLXferProcessor;
|
||||
class GrPipeline;
|
||||
class GrPrimitiveProcessor;
|
||||
class GrProgramInfo;
|
||||
class GrRenderTarget;
|
||||
class GrTextureProxy;
|
||||
|
||||
@ -118,9 +119,7 @@ public:
|
||||
*
|
||||
* It is the caller's responsibility to ensure the program is bound before calling.
|
||||
*/
|
||||
void updateUniformsAndTextureBindings(const GrRenderTarget*, GrSurfaceOrigin,
|
||||
const GrPrimitiveProcessor&, const GrPipeline&,
|
||||
const GrTextureProxy* const primitiveProcessorTextures[]);
|
||||
void updateUniformsAndTextureBindings(const GrRenderTarget*, const GrProgramInfo&);
|
||||
|
||||
void updatePrimitiveProcessorTextureBindings(const GrPrimitiveProcessor&,
|
||||
const GrTextureProxy* const[]);
|
||||
|
@ -18,10 +18,7 @@ GrGLSLVaryingHandler::VaryingHandle GrGLVaryingHandler::addPathProcessingVarying
|
||||
GrGLProgramBuilder* glPB = (GrGLProgramBuilder*) fProgramBuilder;
|
||||
// This call is not used for non-NVPR backends.
|
||||
SkASSERT(glPB->gpu()->glCaps().shaderCaps()->pathRenderingSupport() &&
|
||||
glPB->fPrimProc.isPathRendering() &&
|
||||
!glPB->fPrimProc.willUseGeoShader() &&
|
||||
!glPB->fPrimProc.numVertexAttributes() &&
|
||||
!glPB->fPrimProc.numInstanceAttributes());
|
||||
fProgramBuilder->fProgramInfo.isNVPR());
|
||||
#endif
|
||||
this->addVarying(name, v);
|
||||
auto varyingInfo = fPathProcVaryingInfos.push_back();
|
||||
|
@ -46,23 +46,18 @@ static void cleanup_program(GrGLGpu* gpu, GrGLuint programID,
|
||||
}
|
||||
|
||||
GrGLProgram* GrGLProgramBuilder::CreateProgram(GrRenderTarget* renderTarget,
|
||||
int numSamples,
|
||||
GrSurfaceOrigin origin,
|
||||
const GrPrimitiveProcessor& primProc,
|
||||
const GrTextureProxy* const primProcProxies[],
|
||||
const GrPipeline& pipeline,
|
||||
const GrProgramInfo& programInfo,
|
||||
GrProgramDesc* desc,
|
||||
GrGLGpu* gpu,
|
||||
const GrGLPrecompiledProgram* precompiledProgram) {
|
||||
SkASSERT(!pipeline.isBad());
|
||||
SkASSERT(!programInfo.pipeline().isBad());
|
||||
|
||||
ATRACE_ANDROID_FRAMEWORK("Shader Compile");
|
||||
GrAutoLocaleSetter als("C");
|
||||
|
||||
// create a builder. This will be handed off to effects so they can use it to add
|
||||
// uniforms, varyings, textures, etc
|
||||
GrGLProgramBuilder builder(gpu, renderTarget, numSamples, origin,
|
||||
pipeline, primProc, primProcProxies, desc);
|
||||
GrGLProgramBuilder builder(gpu, renderTarget, programInfo, desc);
|
||||
|
||||
auto persistentCache = gpu->getContext()->priv().getPersistentCache();
|
||||
if (persistentCache && !precompiledProgram) {
|
||||
@ -82,13 +77,9 @@ GrGLProgram* GrGLProgramBuilder::CreateProgram(GrRenderTarget* renderTarget,
|
||||
|
||||
GrGLProgramBuilder::GrGLProgramBuilder(GrGLGpu* gpu,
|
||||
GrRenderTarget* renderTarget,
|
||||
int numSamples,
|
||||
GrSurfaceOrigin origin,
|
||||
const GrPipeline& pipeline,
|
||||
const GrPrimitiveProcessor& primProc,
|
||||
const GrTextureProxy* const primProcProxies[],
|
||||
const GrProgramInfo& programInfo,
|
||||
GrProgramDesc* desc)
|
||||
: INHERITED(renderTarget, numSamples, origin, primProc, primProcProxies, pipeline, desc)
|
||||
: INHERITED(renderTarget, programInfo, desc)
|
||||
, fGpu(gpu)
|
||||
, fVaryingHandler(this)
|
||||
, fUniformHandler(this)
|
||||
@ -170,7 +161,7 @@ void GrGLProgramBuilder::storeShaderInCache(const SkSL::Program::Inputs& inputs,
|
||||
if (!this->gpu()->getContext()->priv().getPersistentCache()) {
|
||||
return;
|
||||
}
|
||||
sk_sp<SkData> key = SkData::MakeWithoutCopy(desc()->asKey(), desc()->keyLength());
|
||||
sk_sp<SkData> key = SkData::MakeWithoutCopy(this->desc()->asKey(), this->desc()->keyLength());
|
||||
if (fGpu->glCaps().programBinarySupport()) {
|
||||
// binary cache
|
||||
GrGLsizei length = 0;
|
||||
|
@ -48,11 +48,7 @@ public:
|
||||
* @return true if generation was successful.
|
||||
*/
|
||||
static GrGLProgram* CreateProgram(GrRenderTarget*,
|
||||
int numSamples,
|
||||
GrSurfaceOrigin,
|
||||
const GrPrimitiveProcessor&,
|
||||
const GrTextureProxy* const primProcProxies[],
|
||||
const GrPipeline&,
|
||||
const GrProgramInfo&,
|
||||
GrProgramDesc*,
|
||||
GrGLGpu*,
|
||||
const GrGLPrecompiledProgram* = nullptr);
|
||||
@ -64,9 +60,7 @@ public:
|
||||
GrGLGpu* gpu() const { return fGpu; }
|
||||
|
||||
private:
|
||||
GrGLProgramBuilder(GrGLGpu*, GrRenderTarget*, int numSamples, GrSurfaceOrigin,
|
||||
const GrPipeline&, const GrPrimitiveProcessor&,
|
||||
const GrTextureProxy* const primProcProxies[], GrProgramDesc*);
|
||||
GrGLProgramBuilder(GrGLGpu*, GrRenderTarget*, const GrProgramInfo&, GrProgramDesc*);
|
||||
|
||||
void addInputVars(const SkSL::Program::Inputs& inputs);
|
||||
bool compileAndAttachShaders(const SkSL::String& glsl,
|
||||
|
@ -21,22 +21,14 @@
|
||||
const int GrGLSLProgramBuilder::kVarsPerBlock = 8;
|
||||
|
||||
GrGLSLProgramBuilder::GrGLSLProgramBuilder(GrRenderTarget* renderTarget,
|
||||
int numSamples,
|
||||
GrSurfaceOrigin origin,
|
||||
const GrPrimitiveProcessor& primProc,
|
||||
const GrTextureProxy* const primProcProxies[],
|
||||
const GrPipeline& pipeline,
|
||||
GrProgramDesc* desc)
|
||||
const GrProgramInfo& programInfo,
|
||||
const GrProgramDesc* desc)
|
||||
: fVS(this)
|
||||
, fGS(this)
|
||||
, fFS(this)
|
||||
, fStageIndex(-1)
|
||||
, fRenderTarget(renderTarget)
|
||||
, fNumSamples(numSamples)
|
||||
, fOrigin(origin)
|
||||
, fPipeline(pipeline)
|
||||
, fPrimProc(primProc)
|
||||
, fPrimProcProxies(primProcProxies)
|
||||
, fProgramInfo(programInfo)
|
||||
, fDesc(desc)
|
||||
, fGeometryProcessor(nullptr)
|
||||
, fXferProcessor(nullptr)
|
||||
@ -115,7 +107,7 @@ void GrGLSLProgramBuilder::emitAndInstallPrimProc(SkString* outputColor,
|
||||
name.c_str());
|
||||
}
|
||||
|
||||
GrGLSLPrimitiveProcessor::FPCoordTransformHandler transformHandler(fPipeline,
|
||||
GrGLSLPrimitiveProcessor::FPCoordTransformHandler transformHandler(this->pipeline(),
|
||||
&fTransformedCoordVars);
|
||||
GrGLSLGeometryProcessor::EmitArgs args(&fVS,
|
||||
proc.willUseGeoShader() ? &fGS : nullptr,
|
||||
@ -229,7 +221,7 @@ void GrGLSLProgramBuilder::emitAndInstallXferProc(const SkString& colorIn,
|
||||
AutoStageAdvance adv(this);
|
||||
|
||||
SkASSERT(!fXferProcessor);
|
||||
const GrXferProcessor& xp = fPipeline.getXferProcessor();
|
||||
const GrXferProcessor& xp = this->pipeline().getXferProcessor();
|
||||
fXferProcessor.reset(xp.createGLSLInstance());
|
||||
|
||||
// Enable dual source secondary output if we have one
|
||||
@ -248,13 +240,13 @@ void GrGLSLProgramBuilder::emitAndInstallXferProc(const SkString& colorIn,
|
||||
SamplerHandle dstTextureSamplerHandle;
|
||||
GrSurfaceOrigin dstTextureOrigin = kTopLeft_GrSurfaceOrigin;
|
||||
|
||||
if (GrTexture* dstTexture = fPipeline.peekDstTexture()) {
|
||||
if (GrTexture* dstTexture = this->pipeline().peekDstTexture()) {
|
||||
// GrProcessor::TextureSampler sampler(dstTexture);
|
||||
SkASSERT(fPipeline.dstTextureProxy());
|
||||
const GrSwizzle& swizzle = fPipeline.dstTextureProxy()->textureSwizzle();
|
||||
SkASSERT(this->pipeline().dstTextureProxy());
|
||||
const GrSwizzle& swizzle = this->pipeline().dstTextureProxy()->textureSwizzle();
|
||||
dstTextureSamplerHandle =
|
||||
this->emitSampler(dstTexture, GrSamplerState(), swizzle, "DstTextureSampler");
|
||||
dstTextureOrigin = fPipeline.dstTextureProxy()->origin();
|
||||
dstTextureOrigin = this->pipeline().dstTextureProxy()->origin();
|
||||
SkASSERT(dstTexture->texturePriv().textureType() != GrTextureType::kExternal);
|
||||
}
|
||||
|
||||
@ -270,7 +262,7 @@ void GrGLSLProgramBuilder::emitAndInstallXferProc(const SkString& colorIn,
|
||||
fFS.getSecondaryColorOutputName(),
|
||||
dstTextureSamplerHandle,
|
||||
dstTextureOrigin,
|
||||
this->desc()->header().fOutputSwizzle);
|
||||
this->header().fOutputSwizzle);
|
||||
fXferProcessor->emitCode(args);
|
||||
|
||||
// We have to check that effects and the code they emit are consistent, ie if an effect
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include "src/gpu/GrCaps.h"
|
||||
#include "src/gpu/GrGeometryProcessor.h"
|
||||
#include "src/gpu/GrProgramDesc.h"
|
||||
#include "src/gpu/GrProgramInfo.h"
|
||||
#include "src/gpu/GrRenderTarget.h"
|
||||
#include "src/gpu/GrRenderTargetPriv.h"
|
||||
#include "src/gpu/glsl/GrGLSLFragmentProcessor.h"
|
||||
@ -36,8 +37,13 @@ public:
|
||||
virtual const GrCaps* caps() const = 0;
|
||||
const GrShaderCaps* shaderCaps() const { return this->caps()->shaderCaps(); }
|
||||
|
||||
const GrPrimitiveProcessor& primitiveProcessor() const { return fPrimProc; }
|
||||
const GrTextureProxy* const* primProcProxies() const { return fPrimProcProxies; }
|
||||
int numSamples() const { return fProgramInfo.numSamples(); }
|
||||
GrSurfaceOrigin origin() const { return fProgramInfo.origin(); }
|
||||
const GrPipeline& pipeline() const { return fProgramInfo.pipeline(); }
|
||||
const GrPrimitiveProcessor& primitiveProcessor() const { return fProgramInfo.primProc(); }
|
||||
const GrTextureProxy* const* primProcProxies() const { return fProgramInfo.primProcProxies(); }
|
||||
|
||||
// TODO: stop passing in the renderTarget for just the sampleLocations
|
||||
int effectiveSampleCnt() const {
|
||||
SkASSERT(GrProcessor::CustomFeatures::kSampleLocations & header().processorFeatures());
|
||||
return fRenderTarget->renderTargetPriv().getSampleLocations().count();
|
||||
@ -45,10 +51,8 @@ public:
|
||||
const SkTArray<SkPoint>& getSampleLocations() const {
|
||||
return fRenderTarget->renderTargetPriv().getSampleLocations();
|
||||
}
|
||||
int numSamples() const { return fNumSamples; }
|
||||
GrSurfaceOrigin origin() const { return fOrigin; }
|
||||
const GrPipeline& pipeline() const { return fPipeline; }
|
||||
GrProgramDesc* desc() { return fDesc; }
|
||||
|
||||
const GrProgramDesc* desc() const { return fDesc; }
|
||||
const GrProgramDesc::KeyHeader& header() const { return fDesc->header(); }
|
||||
|
||||
void appendUniformDecls(GrShaderFlags visibility, SkString*) const;
|
||||
@ -95,14 +99,10 @@ public:
|
||||
|
||||
int fStageIndex;
|
||||
|
||||
const GrRenderTarget* fRenderTarget;
|
||||
const int fNumSamples;
|
||||
const GrSurfaceOrigin fOrigin;
|
||||
const GrPipeline& fPipeline;
|
||||
const GrPrimitiveProcessor& fPrimProc;
|
||||
const GrTextureProxy* const* fPrimProcProxies;
|
||||
const GrRenderTarget* fRenderTarget; // TODO: remove this
|
||||
const GrProgramInfo& fProgramInfo;
|
||||
|
||||
GrProgramDesc* fDesc;
|
||||
const GrProgramDesc* fDesc;
|
||||
|
||||
GrGLSLBuiltinUniformHandles fUniformHandles;
|
||||
|
||||
@ -112,13 +112,7 @@ public:
|
||||
int fFragmentProcessorCnt;
|
||||
|
||||
protected:
|
||||
explicit GrGLSLProgramBuilder(GrRenderTarget* renderTarget,
|
||||
int numSamples,
|
||||
GrSurfaceOrigin origin,
|
||||
const GrPrimitiveProcessor&,
|
||||
const GrTextureProxy* const primProcProxies[],
|
||||
const GrPipeline&,
|
||||
GrProgramDesc*);
|
||||
explicit GrGLSLProgramBuilder(GrRenderTarget*, const GrProgramInfo&, const GrProgramDesc*);
|
||||
|
||||
void addFeature(GrShaderFlags shaders, uint32_t featureBit, const char* extensionName);
|
||||
|
||||
|
@ -14,7 +14,7 @@
|
||||
void GrGLSLVertexGeoBuilder::emitNormalizedSkPosition(SkString* out, const char* devPos,
|
||||
const char* rtAdjustName,
|
||||
GrSLType devPosType) {
|
||||
if (this->getProgramBuilder()->desc()->header().fSnapVerticesToPixelCenters) {
|
||||
if (this->getProgramBuilder()->header().fSnapVerticesToPixelCenters) {
|
||||
if (kFloat3_GrSLType == devPosType) {
|
||||
const char* p = devPos;
|
||||
out->appendf("{float2 _posTmp = float2(%s.x/%s.z, %s.y/%s.z);", p, p, p, p);
|
||||
@ -37,7 +37,7 @@ void GrGLSLVertexGeoBuilder::emitNormalizedSkPosition(SkString* out, const char*
|
||||
void GrGLSLVertexBuilder::onFinalize() {
|
||||
// We could have the GrGeometryProcessor do this, but its just easier to have it performed
|
||||
// here. If we ever need to set variable pointsize, then we can reinvestigate.
|
||||
if (this->getProgramBuilder()->desc()->header().fHasPointSize) {
|
||||
if (this->getProgramBuilder()->header().fHasPointSize) {
|
||||
this->codeAppend("sk_PointSize = 1.0;");
|
||||
}
|
||||
fProgramBuilder->varyingHandler()->getVertexDecls(&this->inputs(), &this->outputs());
|
||||
|
@ -35,9 +35,8 @@ public:
|
||||
int numDraws() const { return fNumDraws; }
|
||||
|
||||
private:
|
||||
void onDraw(const GrPrimitiveProcessor&, const GrPipeline&,
|
||||
const GrPipeline::FixedDynamicState*, const GrPipeline::DynamicStateArrays*,
|
||||
const GrMesh[], int meshCount, const SkRect& bounds) override {
|
||||
void onDraw(const GrProgramInfo&, const GrMesh[], int meshCount,
|
||||
const SkRect& bounds) override {
|
||||
this->markRenderTargetDirty();
|
||||
++fNumDraws;
|
||||
}
|
||||
|
@ -44,16 +44,9 @@ public:
|
||||
private:
|
||||
GrGpu* gpu() override { return fGpu; }
|
||||
|
||||
GrMtlPipelineState* prepareDrawState(
|
||||
const GrPrimitiveProcessor& primProc,
|
||||
const GrPipeline& pipeline,
|
||||
const GrPipeline::FixedDynamicState* fixedDynamicState,
|
||||
GrPrimitiveType primType);
|
||||
GrMtlPipelineState* prepareDrawState(const GrProgramInfo&, GrPrimitiveType);
|
||||
|
||||
void onDraw(const GrPrimitiveProcessor& primProc,
|
||||
const GrPipeline& pipeline,
|
||||
const GrPipeline::FixedDynamicState* fixedDynamicState,
|
||||
const GrPipeline::DynamicStateArrays* dynamicStateArrays,
|
||||
void onDraw(const GrProgramInfo& programInfo,
|
||||
const GrMesh mesh[],
|
||||
int meshCount,
|
||||
const SkRect& bounds) override;
|
||||
|
@ -53,50 +53,34 @@ void GrMtlOpsRenderPass::submit() {
|
||||
fGpu->submitIndirectCommandBuffer(fRenderTarget, fOrigin, &iBounds);
|
||||
}
|
||||
|
||||
GrMtlPipelineState* GrMtlOpsRenderPass::prepareDrawState(
|
||||
const GrPrimitiveProcessor& primProc,
|
||||
const GrPipeline& pipeline,
|
||||
const GrPipeline::FixedDynamicState* fixedDynamicState,
|
||||
GrPrimitiveType primType) {
|
||||
GrMtlPipelineState* GrMtlOpsRenderPass::prepareDrawState(const GrProgramInfo& programInfo,
|
||||
GrPrimitiveType primType) {
|
||||
// TODO: resolve textures and regenerate mipmaps as needed
|
||||
|
||||
const GrTextureProxy* const* primProcProxies = nullptr;
|
||||
if (fixedDynamicState) {
|
||||
primProcProxies = fixedDynamicState->fPrimitiveProcessorTextures;
|
||||
}
|
||||
SkASSERT(SkToBool(primProcProxies) == SkToBool(primProc.numTextureSamplers()));
|
||||
|
||||
GrMtlPipelineState* pipelineState =
|
||||
fGpu->resourceProvider().findOrCreateCompatiblePipelineState(fRenderTarget,
|
||||
fRenderTarget->numSamples(),
|
||||
fOrigin,
|
||||
pipeline,
|
||||
primProc,
|
||||
primProcProxies,
|
||||
programInfo,
|
||||
primType);
|
||||
if (!pipelineState) {
|
||||
return nullptr;
|
||||
}
|
||||
pipelineState->setData(fRenderTarget, fOrigin, primProc, pipeline, primProcProxies);
|
||||
fCurrentVertexStride = primProc.vertexStride();
|
||||
|
||||
pipelineState->setData(fRenderTarget, programInfo);
|
||||
fCurrentVertexStride = programInfo.primProc().vertexStride();
|
||||
|
||||
return pipelineState;
|
||||
}
|
||||
|
||||
void GrMtlOpsRenderPass::onDraw(const GrPrimitiveProcessor& primProc,
|
||||
const GrPipeline& pipeline,
|
||||
const GrPipeline::FixedDynamicState* fixedDynamicState,
|
||||
const GrPipeline::DynamicStateArrays* dynamicStateArrays,
|
||||
const GrMesh meshes[],
|
||||
int meshCount,
|
||||
const SkRect& bounds) {
|
||||
void GrMtlOpsRenderPass::onDraw(const GrProgramInfo& programInfo,
|
||||
const GrMesh meshes[],
|
||||
int meshCount,
|
||||
const SkRect& bounds) {
|
||||
if (!meshCount) {
|
||||
return;
|
||||
}
|
||||
|
||||
GrPrimitiveType primitiveType = meshes[0].primitiveType();
|
||||
GrMtlPipelineState* pipelineState = this->prepareDrawState(primProc, pipeline,
|
||||
fixedDynamicState, primitiveType);
|
||||
GrMtlPipelineState* pipelineState = this->prepareDrawState(programInfo, primitiveType);
|
||||
if (!pipelineState) {
|
||||
return;
|
||||
}
|
||||
@ -107,21 +91,23 @@ void GrMtlOpsRenderPass::onDraw(const GrPrimitiveProcessor& primProc,
|
||||
SkASSERT(fActiveRenderCmdEncoder);
|
||||
|
||||
[fActiveRenderCmdEncoder setRenderPipelineState:pipelineState->mtlPipelineState()];
|
||||
pipelineState->setDrawState(fActiveRenderCmdEncoder, pipeline.outputSwizzle(),
|
||||
pipeline.getXferProcessor());
|
||||
pipelineState->setDrawState(fActiveRenderCmdEncoder,
|
||||
programInfo.pipeline().outputSwizzle(),
|
||||
programInfo.pipeline().getXferProcessor());
|
||||
|
||||
bool dynamicScissor =
|
||||
pipeline.isScissorEnabled() && dynamicStateArrays && dynamicStateArrays->fScissorRects;
|
||||
if (!pipeline.isScissorEnabled()) {
|
||||
bool hasDynamicScissors = programInfo.hasDynamicScissors();
|
||||
|
||||
if (!programInfo.pipeline().isScissorEnabled()) {
|
||||
GrMtlPipelineState::SetDynamicScissorRectState(fActiveRenderCmdEncoder,
|
||||
fRenderTarget, fOrigin,
|
||||
SkIRect::MakeWH(fRenderTarget->width(),
|
||||
fRenderTarget->height()));
|
||||
} else if (!dynamicScissor) {
|
||||
SkASSERT(fixedDynamicState);
|
||||
} else if (!hasDynamicScissors) {
|
||||
SkASSERT(programInfo.hasFixedScissor());
|
||||
|
||||
GrMtlPipelineState::SetDynamicScissorRectState(fActiveRenderCmdEncoder,
|
||||
fRenderTarget, fOrigin,
|
||||
fixedDynamicState->fScissorRect);
|
||||
programInfo.fixedScissor());
|
||||
}
|
||||
|
||||
for (int i = 0; i < meshCount; ++i) {
|
||||
@ -130,21 +116,21 @@ void GrMtlOpsRenderPass::onDraw(const GrPrimitiveProcessor& primProc,
|
||||
if (mesh.primitiveType() != primitiveType) {
|
||||
SkDEBUGCODE(pipelineState = nullptr);
|
||||
primitiveType = mesh.primitiveType();
|
||||
pipelineState = this->prepareDrawState(primProc, pipeline, fixedDynamicState,
|
||||
primitiveType);
|
||||
pipelineState = this->prepareDrawState(programInfo, primitiveType);
|
||||
if (!pipelineState) {
|
||||
return;
|
||||
}
|
||||
|
||||
[fActiveRenderCmdEncoder setRenderPipelineState:pipelineState->mtlPipelineState()];
|
||||
pipelineState->setDrawState(fActiveRenderCmdEncoder, pipeline.outputSwizzle(),
|
||||
pipeline.getXferProcessor());
|
||||
pipelineState->setDrawState(fActiveRenderCmdEncoder,
|
||||
programInfo.pipeline().outputSwizzle(),
|
||||
programInfo.pipeline().getXferProcessor());
|
||||
}
|
||||
|
||||
if (dynamicScissor) {
|
||||
if (hasDynamicScissors) {
|
||||
GrMtlPipelineState::SetDynamicScissorRectState(fActiveRenderCmdEncoder, fRenderTarget,
|
||||
fOrigin,
|
||||
dynamicStateArrays->fScissorRects[i]);
|
||||
programInfo.dynamicScissor(i));
|
||||
}
|
||||
|
||||
mesh.sendToGpu(this);
|
||||
|
@ -46,9 +46,7 @@ public:
|
||||
|
||||
id<MTLRenderPipelineState> mtlPipelineState() { return fPipelineState; }
|
||||
|
||||
void setData(const GrRenderTarget*, GrSurfaceOrigin,
|
||||
const GrPrimitiveProcessor& primPRoc, const GrPipeline& pipeline,
|
||||
const GrTextureProxy* const primProcTextures[]);
|
||||
void setData(const GrRenderTarget*, const GrProgramInfo&);
|
||||
|
||||
void setDrawState(id<MTLRenderCommandEncoder>, const GrSwizzle& outputSwizzle,
|
||||
const GrXferProcessor&);
|
||||
|
@ -58,23 +58,23 @@ GrMtlPipelineState::GrMtlPipelineState(
|
||||
}
|
||||
|
||||
void GrMtlPipelineState::setData(const GrRenderTarget* renderTarget,
|
||||
GrSurfaceOrigin origin,
|
||||
const GrPrimitiveProcessor& primProc,
|
||||
const GrPipeline& pipeline,
|
||||
const GrTextureProxy* const primProcTextures[]) {
|
||||
SkASSERT(primProcTextures || !primProc.numTextureSamplers());
|
||||
const GrProgramInfo& programInfo) {
|
||||
SkASSERT(programInfo.primProcProxies() || !programInfo.primProc().numTextureSamplers());
|
||||
|
||||
this->setRenderTargetState(renderTarget, origin);
|
||||
fGeometryProcessor->setData(fDataManager, primProc,
|
||||
GrFragmentProcessor::CoordTransformIter(pipeline));
|
||||
// Note: the Metal backend currently only supports fixed primProc textures
|
||||
const GrTextureProxy* const* primProcProxies = programInfo.primProcProxies();
|
||||
|
||||
this->setRenderTargetState(renderTarget, programInfo.origin());
|
||||
fGeometryProcessor->setData(fDataManager, programInfo.primProc(),
|
||||
GrFragmentProcessor::CoordTransformIter(programInfo.pipeline()));
|
||||
fSamplerBindings.reset();
|
||||
for (int i = 0; i < primProc.numTextureSamplers(); ++i) {
|
||||
const auto& sampler = primProc.textureSampler(i);
|
||||
auto texture = static_cast<GrMtlTexture*>(primProcTextures[i]->peekTexture());
|
||||
for (int i = 0; i < programInfo.primProc().numTextureSamplers(); ++i) {
|
||||
const auto& sampler = programInfo.primProc().textureSampler(i);
|
||||
auto texture = static_cast<GrMtlTexture*>(primProcProxies[i]->peekTexture());
|
||||
fSamplerBindings.emplace_back(sampler.samplerState(), texture, fGpu);
|
||||
}
|
||||
|
||||
GrFragmentProcessor::Iter iter(pipeline);
|
||||
GrFragmentProcessor::Iter iter(programInfo.pipeline());
|
||||
GrGLSLFragmentProcessor::Iter glslIter(fFragmentProcessors.get(), fFragmentProcessorCnt);
|
||||
const GrFragmentProcessor* fp = iter.next();
|
||||
GrGLSLFragmentProcessor* glslFP = glslIter.next();
|
||||
@ -91,12 +91,13 @@ void GrMtlPipelineState::setData(const GrRenderTarget* renderTarget,
|
||||
|
||||
{
|
||||
SkIPoint offset;
|
||||
GrTexture* dstTexture = pipeline.peekDstTexture(&offset);
|
||||
GrTexture* dstTexture = programInfo.pipeline().peekDstTexture(&offset);
|
||||
|
||||
fXferProcessor->setData(fDataManager, pipeline.getXferProcessor(), dstTexture, offset);
|
||||
fXferProcessor->setData(fDataManager, programInfo.pipeline().getXferProcessor(),
|
||||
dstTexture, offset);
|
||||
}
|
||||
|
||||
if (GrTextureProxy* dstTextureProxy = pipeline.dstTextureProxy()) {
|
||||
if (GrTextureProxy* dstTextureProxy = programInfo.pipeline().dstTextureProxy()) {
|
||||
fSamplerBindings.emplace_back(GrSamplerState::ClampNearest(),
|
||||
dstTextureProxy->peekTexture(),
|
||||
fGpu);
|
||||
@ -105,9 +106,10 @@ void GrMtlPipelineState::setData(const GrRenderTarget* renderTarget,
|
||||
SkASSERT(fNumSamplers == fSamplerBindings.count());
|
||||
fDataManager.resetDirtyBits();
|
||||
|
||||
if (pipeline.isStencilEnabled()) {
|
||||
if (programInfo.pipeline().isStencilEnabled()) {
|
||||
SkASSERT(renderTarget->renderTargetPriv().getStencilAttachment());
|
||||
fStencil.reset(*pipeline.getUserStencil(), pipeline.hasStencilClip(),
|
||||
fStencil.reset(*programInfo.pipeline().getUserStencil(),
|
||||
programInfo.pipeline().hasStencilClip(),
|
||||
renderTarget->renderTargetPriv().numStencilBits());
|
||||
}
|
||||
}
|
||||
|
@ -17,6 +17,7 @@
|
||||
|
||||
#import <Metal/Metal.h>
|
||||
|
||||
class GrProgramInfo;
|
||||
class GrMtlGpu;
|
||||
class GrMtlPipelineState;
|
||||
|
||||
@ -35,12 +36,8 @@ public:
|
||||
*/
|
||||
class Desc : public GrProgramDesc {
|
||||
public:
|
||||
static bool Build(Desc*,
|
||||
GrRenderTarget*,
|
||||
const GrPrimitiveProcessor&,
|
||||
const GrPipeline&,
|
||||
GrPrimitiveType,
|
||||
GrMtlGpu* gpu);
|
||||
static bool Build(Desc*, GrRenderTarget*,
|
||||
const GrProgramInfo&, GrPrimitiveType, GrMtlGpu* gpu);
|
||||
|
||||
size_t shaderKeyLength() const { return fShaderKeyLength; }
|
||||
|
||||
@ -59,23 +56,14 @@ public:
|
||||
* @return true if generation was successful.
|
||||
*/
|
||||
static GrMtlPipelineState* CreatePipelineState(GrMtlGpu*,
|
||||
GrRenderTarget*, int numSamples, GrSurfaceOrigin,
|
||||
const GrPrimitiveProcessor&,
|
||||
const GrTextureProxy* const primProcProxies[],
|
||||
const GrPipeline&,
|
||||
GrRenderTarget*,
|
||||
const GrProgramInfo&,
|
||||
Desc*);
|
||||
|
||||
private:
|
||||
GrMtlPipelineStateBuilder(GrMtlGpu*, GrRenderTarget*, int numSamples, GrSurfaceOrigin,
|
||||
const GrPipeline&,
|
||||
const GrPrimitiveProcessor&,
|
||||
const GrTextureProxy* const primProcProxies[],
|
||||
GrProgramDesc*);
|
||||
GrMtlPipelineStateBuilder(GrMtlGpu*, GrRenderTarget*, const GrProgramInfo&, GrProgramDesc*);
|
||||
|
||||
GrMtlPipelineState* finalize(GrRenderTarget* renderTarget,
|
||||
const GrPrimitiveProcessor& primProc,
|
||||
const GrPipeline& pipeline,
|
||||
Desc*);
|
||||
GrMtlPipelineState* finalize(GrRenderTarget*, const GrProgramInfo&, Desc*);
|
||||
|
||||
const GrCaps* caps() const override;
|
||||
|
||||
|
@ -22,31 +22,23 @@
|
||||
#error This file must be compiled with Arc. Use -fobjc-arc flag
|
||||
#endif
|
||||
|
||||
GrMtlPipelineState* GrMtlPipelineStateBuilder::CreatePipelineState(
|
||||
GrMtlGpu* gpu,
|
||||
GrRenderTarget* renderTarget, int numSamples, GrSurfaceOrigin origin,
|
||||
const GrPrimitiveProcessor& primProc,
|
||||
const GrTextureProxy* const primProcProxies[],
|
||||
const GrPipeline& pipeline,
|
||||
Desc* desc) {
|
||||
GrMtlPipelineStateBuilder builder(gpu, renderTarget, numSamples, origin, pipeline, primProc,
|
||||
primProcProxies, desc);
|
||||
GrMtlPipelineState* GrMtlPipelineStateBuilder::CreatePipelineState(GrMtlGpu* gpu,
|
||||
GrRenderTarget* renderTarget,
|
||||
const GrProgramInfo& programInfo,
|
||||
Desc* desc) {
|
||||
GrMtlPipelineStateBuilder builder(gpu, renderTarget, programInfo, desc);
|
||||
|
||||
if (!builder.emitAndInstallProcs()) {
|
||||
return nullptr;
|
||||
}
|
||||
return builder.finalize(renderTarget, primProc, pipeline, desc);
|
||||
return builder.finalize(renderTarget, programInfo, desc);
|
||||
}
|
||||
|
||||
GrMtlPipelineStateBuilder::GrMtlPipelineStateBuilder(GrMtlGpu* gpu,
|
||||
GrRenderTarget* renderTarget,
|
||||
int numSamples,
|
||||
GrSurfaceOrigin origin,
|
||||
const GrPipeline& pipeline,
|
||||
const GrPrimitiveProcessor& primProc,
|
||||
const GrTextureProxy* const primProcProxies[],
|
||||
const GrProgramInfo& programInfo,
|
||||
GrProgramDesc* desc)
|
||||
: INHERITED(renderTarget, numSamples, origin, primProc, primProcProxies, pipeline, desc)
|
||||
: INHERITED(renderTarget, programInfo, desc)
|
||||
, fGpu(gpu)
|
||||
, fUniformHandler(this)
|
||||
, fVaryingHandler(this) {
|
||||
@ -348,8 +340,7 @@ uint32_t buffer_size(uint32_t offset, uint32_t maxAlignment) {
|
||||
}
|
||||
|
||||
GrMtlPipelineState* GrMtlPipelineStateBuilder::finalize(GrRenderTarget* renderTarget,
|
||||
const GrPrimitiveProcessor& primProc,
|
||||
const GrPipeline& pipeline,
|
||||
const GrProgramInfo& programInfo,
|
||||
Desc* desc) {
|
||||
auto pipelineDescriptor = [MTLRenderPipelineDescriptor new];
|
||||
|
||||
@ -397,9 +388,9 @@ GrMtlPipelineState* GrMtlPipelineStateBuilder::finalize(GrRenderTarget* renderTa
|
||||
|
||||
pipelineDescriptor.vertexFunction = vertexFunction;
|
||||
pipelineDescriptor.fragmentFunction = fragmentFunction;
|
||||
pipelineDescriptor.vertexDescriptor = create_vertex_descriptor(primProc);
|
||||
pipelineDescriptor.vertexDescriptor = create_vertex_descriptor(programInfo.primProc());
|
||||
pipelineDescriptor.colorAttachments[0] = create_color_attachment(renderTarget->config(),
|
||||
pipeline);
|
||||
programInfo.pipeline());
|
||||
pipelineDescriptor.sampleCount = renderTarget->numSamples();
|
||||
bool hasStencilAttachment = SkToBool(renderTarget->renderTargetPriv().getStencilAttachment());
|
||||
GrMtlCaps* mtlCaps = (GrMtlCaps*)this->caps();
|
||||
@ -455,12 +446,11 @@ GrMtlPipelineState* GrMtlPipelineStateBuilder::finalize(GrRenderTarget* renderTa
|
||||
|
||||
bool GrMtlPipelineStateBuilder::Desc::Build(Desc* desc,
|
||||
GrRenderTarget* renderTarget,
|
||||
const GrPrimitiveProcessor& primProc,
|
||||
const GrPipeline& pipeline,
|
||||
const GrProgramInfo& programInfo,
|
||||
GrPrimitiveType primitiveType,
|
||||
GrMtlGpu* gpu) {
|
||||
if (!INHERITED::Build(desc, renderTarget, primProc,
|
||||
GrPrimitiveType::kLines == primitiveType, pipeline, gpu)) {
|
||||
if (!GrProgramDesc::Build(desc, renderTarget, programInfo,
|
||||
GrPrimitiveType::kPoints == primitiveType, gpu)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -475,10 +465,10 @@ bool GrMtlPipelineStateBuilder::Desc::Build(Desc* desc,
|
||||
bool hasStencilAttachment = SkToBool(renderTarget->renderTargetPriv().getStencilAttachment());
|
||||
b.add32(hasStencilAttachment ? gpu->mtlCaps().preferredStencilFormat().fInternalFormat
|
||||
: MTLPixelFormatInvalid);
|
||||
b.add32((uint32_t)pipeline.isStencilEnabled());
|
||||
b.add32((uint32_t)programInfo.pipeline().isStencilEnabled());
|
||||
// Stencil samples don't seem to be tracked in the MTLRenderPipeline
|
||||
|
||||
b.add32(pipeline.getBlendInfoKey());
|
||||
b.add32(programInfo.pipeline().getBlendInfoKey());
|
||||
|
||||
b.add32((uint32_t)primitiveType);
|
||||
|
||||
|
@ -24,12 +24,9 @@ class GrMtlResourceProvider {
|
||||
public:
|
||||
GrMtlResourceProvider(GrMtlGpu* gpu);
|
||||
|
||||
GrMtlPipelineState* findOrCreateCompatiblePipelineState(
|
||||
GrRenderTarget*, int numSamples, GrSurfaceOrigin,
|
||||
const GrPipeline&,
|
||||
const GrPrimitiveProcessor&,
|
||||
const GrTextureProxy* const primProcProxies[],
|
||||
GrPrimitiveType);
|
||||
GrMtlPipelineState* findOrCreateCompatiblePipelineState(GrRenderTarget*,
|
||||
const GrProgramInfo&,
|
||||
GrPrimitiveType);
|
||||
|
||||
// Finds or creates a compatible MTLDepthStencilState based on the GrStencilSettings.
|
||||
GrMtlDepthStencil* findOrCreateCompatibleDepthStencilState(const GrStencilSettings&,
|
||||
@ -55,10 +52,7 @@ private:
|
||||
~PipelineStateCache();
|
||||
|
||||
void release();
|
||||
GrMtlPipelineState* refPipelineState(GrRenderTarget*, int numSamples, GrSurfaceOrigin,
|
||||
const GrPrimitiveProcessor&,
|
||||
const GrTextureProxy* const primProcProxies[],
|
||||
const GrPipeline&,
|
||||
GrMtlPipelineState* refPipelineState(GrRenderTarget*, const GrProgramInfo&,
|
||||
GrPrimitiveType);
|
||||
|
||||
private:
|
||||
|
@ -38,11 +38,10 @@ GrMtlResourceProvider::GrMtlResourceProvider(GrMtlGpu* gpu)
|
||||
}
|
||||
|
||||
GrMtlPipelineState* GrMtlResourceProvider::findOrCreateCompatiblePipelineState(
|
||||
GrRenderTarget* renderTarget, int numSamples, GrSurfaceOrigin origin,
|
||||
const GrPipeline& pipeline, const GrPrimitiveProcessor& proc,
|
||||
const GrTextureProxy* const primProcProxies[], GrPrimitiveType primType) {
|
||||
return fPipelineStateCache->refPipelineState(renderTarget, numSamples, origin, proc,
|
||||
primProcProxies, pipeline, primType);
|
||||
GrRenderTarget* renderTarget,
|
||||
const GrProgramInfo& programInfo,
|
||||
GrPrimitiveType primType) {
|
||||
return fPipelineStateCache->refPipelineState(renderTarget, programInfo, primType);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
@ -137,25 +136,23 @@ void GrMtlResourceProvider::PipelineStateCache::release() {
|
||||
|
||||
GrMtlPipelineState* GrMtlResourceProvider::PipelineStateCache::refPipelineState(
|
||||
GrRenderTarget* renderTarget,
|
||||
int numSamples,
|
||||
GrSurfaceOrigin origin,
|
||||
const GrPrimitiveProcessor& primProc,
|
||||
const GrTextureProxy* const primProcProxies[],
|
||||
const GrPipeline& pipeline,
|
||||
const GrProgramInfo& programInfo,
|
||||
GrPrimitiveType primType) {
|
||||
#ifdef GR_PIPELINE_STATE_CACHE_STATS
|
||||
++fTotalRequests;
|
||||
#endif
|
||||
|
||||
// TODO: unify GL, VK and Mtl
|
||||
// Get GrMtlProgramDesc
|
||||
GrMtlPipelineStateBuilder::Desc desc;
|
||||
if (!GrMtlPipelineStateBuilder::Desc::Build(&desc, renderTarget, primProc, pipeline, primType,
|
||||
fGpu)) {
|
||||
if (!GrMtlPipelineStateBuilder::Desc::Build(&desc, renderTarget, programInfo, primType, fGpu)) {
|
||||
GrCapsDebugf(fGpu->caps(), "Failed to build mtl program descriptor!\n");
|
||||
return nullptr;
|
||||
}
|
||||
// If we knew the shader won't depend on origin, we could skip this (and use the same program
|
||||
// for both origins). Instrumenting all fragment processors would be difficult and error prone.
|
||||
desc.setSurfaceOriginKey(GrGLSLFragmentShaderBuilder::KeyForSurfaceOrigin(origin));
|
||||
desc.setSurfaceOriginKey(
|
||||
GrGLSLFragmentShaderBuilder::KeyForSurfaceOrigin(programInfo.origin()));
|
||||
|
||||
std::unique_ptr<Entry>* entry = fMap.find(desc);
|
||||
if (!entry) {
|
||||
@ -163,8 +160,8 @@ GrMtlPipelineState* GrMtlResourceProvider::PipelineStateCache::refPipelineState(
|
||||
++fCacheMisses;
|
||||
#endif
|
||||
GrMtlPipelineState* pipelineState(GrMtlPipelineStateBuilder::CreatePipelineState(
|
||||
fGpu, renderTarget, numSamples, origin, primProc, primProcProxies, pipeline, &desc));
|
||||
if (nullptr == pipelineState) {
|
||||
fGpu, renderTarget, programInfo, &desc));
|
||||
if (!pipelineState) {
|
||||
return nullptr;
|
||||
}
|
||||
entry = fMap.insert(desc, std::unique_ptr<Entry>(new Entry(fGpu, pipelineState)));
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include "include/private/SkTemplates.h"
|
||||
#include "src/gpu/GrAppliedClip.h"
|
||||
#include "src/gpu/GrMemoryPool.h"
|
||||
#include "src/gpu/GrProgramInfo.h"
|
||||
#include "src/gpu/GrRecordingContextPriv.h"
|
||||
#include "src/gpu/GrRenderTargetContext.h"
|
||||
#include "src/gpu/GrRenderTargetPriv.h"
|
||||
@ -92,13 +93,17 @@ void GrDrawPathOp::onExecute(GrOpFlushState* state, const SkRect& chainBounds) {
|
||||
std::move(appliedClip));
|
||||
sk_sp<GrPathProcessor> pathProc(GrPathProcessor::Create(this->color(), this->viewMatrix()));
|
||||
|
||||
GrProgramInfo programInfo(state->drawOpArgs().numSamples(),
|
||||
state->drawOpArgs().origin(),
|
||||
pipeline,
|
||||
*pathProc,
|
||||
&fixedDynamicState,
|
||||
nullptr);
|
||||
|
||||
GrStencilSettings stencil;
|
||||
init_stencil_pass_settings(*state, this->fillType(), &stencil);
|
||||
state->gpu()->pathRendering()->drawPath(state->drawOpArgs().renderTarget(),
|
||||
state->drawOpArgs().renderTarget()->numSamples(),
|
||||
state->drawOpArgs().origin(),
|
||||
*pathProc, pipeline, fixedDynamicState, stencil,
|
||||
fPath.get());
|
||||
programInfo, stencil, fPath.get());
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include "src/gpu/GrMemoryPool.h"
|
||||
#include "src/gpu/GrOpFlushState.h"
|
||||
#include "src/gpu/GrOpsRenderPass.h"
|
||||
#include "src/gpu/GrProgramInfo.h"
|
||||
#include "src/gpu/GrRecordingContextPriv.h"
|
||||
#include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h"
|
||||
#include "src/gpu/glsl/GrGLSLGeometryProcessor.h"
|
||||
@ -750,13 +751,19 @@ void GrFillRRectOp::onExecute(GrOpFlushState* flushState, const SkRect& chainBou
|
||||
std::move(fProcessors),
|
||||
std::move(clip));
|
||||
|
||||
GrProgramInfo programInfo(flushState->drawOpArgs().numSamples(),
|
||||
flushState->drawOpArgs().origin(),
|
||||
*pipeline,
|
||||
*proc,
|
||||
fixedDynamicState,
|
||||
nullptr);
|
||||
|
||||
GrMesh* mesh = flushState->allocator()->make<GrMesh>(GrPrimitiveType::kTriangles);
|
||||
mesh->setIndexedInstanced(
|
||||
std::move(fIndexBuffer), fIndexCount, std::move(fInstanceBuffer), fInstanceCount,
|
||||
fBaseInstance, GrPrimitiveRestart::kNo);
|
||||
mesh->setVertexData(std::move(fVertexBuffer));
|
||||
flushState->opsRenderPass()->draw(
|
||||
*proc, *pipeline, fixedDynamicState, nullptr, mesh, 1, this->bounds());
|
||||
flushState->opsRenderPass()->draw(programInfo, mesh, 1, this->bounds());
|
||||
fIndexCount = 0;
|
||||
}
|
||||
|
||||
|
@ -10,6 +10,7 @@
|
||||
|
||||
#include "src/gpu/GrPath.h"
|
||||
#include "src/gpu/GrPathRendering.h"
|
||||
#include "src/gpu/GrScissorState.h"
|
||||
#include "src/gpu/GrStencilSettings.h"
|
||||
#include "src/gpu/ops/GrOp.h"
|
||||
|
||||
|
@ -374,8 +374,7 @@ void GrVkOpsRenderPass::addAdditionalRenderPass(bool mustUseSecondaryCommandBuff
|
||||
SkToBool(fCurrentSecondaryCommandBuffer));
|
||||
}
|
||||
|
||||
void GrVkOpsRenderPass::inlineUpload(GrOpFlushState* state,
|
||||
GrDeferredTextureUploadFn& upload) {
|
||||
void GrVkOpsRenderPass::inlineUpload(GrOpFlushState* state, GrDeferredTextureUploadFn& upload) {
|
||||
if (fCurrentSecondaryCommandBuffer) {
|
||||
fCurrentSecondaryCommandBuffer->end(fGpu);
|
||||
fGpu->submitSecondaryCommandBuffer(std::move(fCurrentSecondaryCommandBuffer));
|
||||
@ -428,10 +427,7 @@ void GrVkOpsRenderPass::bindGeometry(const GrGpuBuffer* indexBuffer,
|
||||
}
|
||||
|
||||
GrVkPipelineState* GrVkOpsRenderPass::prepareDrawState(
|
||||
const GrPrimitiveProcessor& primProc,
|
||||
const GrPipeline& pipeline,
|
||||
const GrPipeline::FixedDynamicState* fixedDynamicState,
|
||||
const GrPipeline::DynamicStateArrays* dynamicStateArrays,
|
||||
const GrProgramInfo& programInfo,
|
||||
GrPrimitiveType primitiveType,
|
||||
const SkIRect& renderPassScissorRect) {
|
||||
GrVkCommandBuffer* currentCB = this->currentCommandBuffer();
|
||||
@ -439,22 +435,9 @@ GrVkPipelineState* GrVkOpsRenderPass::prepareDrawState(
|
||||
|
||||
VkRenderPass compatibleRenderPass = fCurrentRenderPass->vkRenderPass();
|
||||
|
||||
const GrTextureProxy* const* primProcProxies = nullptr;
|
||||
if (dynamicStateArrays && dynamicStateArrays->fPrimitiveProcessorTextures) {
|
||||
primProcProxies = dynamicStateArrays->fPrimitiveProcessorTextures;
|
||||
} else if (fixedDynamicState) {
|
||||
primProcProxies = fixedDynamicState->fPrimitiveProcessorTextures;
|
||||
}
|
||||
|
||||
SkASSERT(SkToBool(primProcProxies) == SkToBool(primProc.numTextureSamplers()));
|
||||
|
||||
GrVkPipelineState* pipelineState =
|
||||
fGpu->resourceProvider().findOrCreateCompatiblePipelineState(fRenderTarget,
|
||||
fRenderTarget->numSamples(),
|
||||
fOrigin,
|
||||
pipeline,
|
||||
primProc,
|
||||
primProcProxies,
|
||||
programInfo,
|
||||
primitiveType,
|
||||
compatibleRenderPass);
|
||||
if (!pipelineState) {
|
||||
@ -463,30 +446,38 @@ GrVkPipelineState* GrVkOpsRenderPass::prepareDrawState(
|
||||
|
||||
pipelineState->bindPipeline(fGpu, currentCB);
|
||||
|
||||
pipelineState->setAndBindUniforms(fGpu, fRenderTarget, fOrigin, primProc, pipeline, currentCB);
|
||||
// Both the 'programInfo' and this renderPass have an origin. Since they come from the
|
||||
// same place (i.e., the target renderTargetProxy) that had best agree.
|
||||
SkASSERT(programInfo.origin() == fOrigin);
|
||||
|
||||
// TODO: just pass in GrProgramInfo
|
||||
pipelineState->setAndBindUniforms(fGpu, fRenderTarget, fOrigin,
|
||||
programInfo.primProc(), programInfo.pipeline(), currentCB);
|
||||
|
||||
// Check whether we need to bind textures between each GrMesh. If not we can bind them all now.
|
||||
bool setTextures = !(dynamicStateArrays && dynamicStateArrays->fPrimitiveProcessorTextures);
|
||||
if (setTextures) {
|
||||
pipelineState->setAndBindTextures(fGpu, primProc, pipeline, primProcProxies, currentCB);
|
||||
if (!programInfo.hasDynamicPrimProcTextures()) {
|
||||
// TODO: just pass in GrProgramInfo
|
||||
pipelineState->setAndBindTextures(fGpu, programInfo.primProc(), programInfo.pipeline(),
|
||||
programInfo.primProcProxies(), currentCB);
|
||||
}
|
||||
|
||||
if (!pipeline.isScissorEnabled()) {
|
||||
if (!programInfo.pipeline().isScissorEnabled()) {
|
||||
GrVkPipeline::SetDynamicScissorRectState(fGpu, currentCB, fRenderTarget, fOrigin,
|
||||
renderPassScissorRect);
|
||||
} else if (!dynamicStateArrays || !dynamicStateArrays->fScissorRects) {
|
||||
SkASSERT(fixedDynamicState);
|
||||
} else if (!programInfo.hasDynamicScissors()) {
|
||||
SkASSERT(programInfo.hasFixedScissor());
|
||||
|
||||
SkIRect combinedScissorRect;
|
||||
if (!combinedScissorRect.intersect(renderPassScissorRect,
|
||||
fixedDynamicState->fScissorRect)) {
|
||||
if (!combinedScissorRect.intersect(renderPassScissorRect, programInfo.fixedScissor())) {
|
||||
combinedScissorRect = SkIRect::MakeEmpty();
|
||||
}
|
||||
GrVkPipeline::SetDynamicScissorRectState(fGpu, currentCB, fRenderTarget, fOrigin,
|
||||
combinedScissorRect);
|
||||
}
|
||||
GrVkPipeline::SetDynamicViewportState(fGpu, currentCB, fRenderTarget);
|
||||
GrVkPipeline::SetDynamicBlendConstantState(fGpu, currentCB, pipeline.outputSwizzle(),
|
||||
pipeline.getXferProcessor());
|
||||
GrVkPipeline::SetDynamicBlendConstantState(fGpu, currentCB,
|
||||
programInfo.pipeline().outputSwizzle(),
|
||||
programInfo.pipeline().getXferProcessor());
|
||||
|
||||
return pipelineState;
|
||||
}
|
||||
@ -500,41 +491,46 @@ void check_sampled_texture(GrTexture* tex, GrRenderTarget* rt, GrVkGpu* gpu) {
|
||||
#endif
|
||||
|
||||
|
||||
void GrVkOpsRenderPass::onDraw(const GrPrimitiveProcessor& primProc,
|
||||
const GrPipeline& pipeline,
|
||||
const GrPipeline::FixedDynamicState* fixedDynamicState,
|
||||
const GrPipeline::DynamicStateArrays* dynamicStateArrays,
|
||||
const GrMesh meshes[],
|
||||
int meshCount,
|
||||
const SkRect& bounds) {
|
||||
void GrVkOpsRenderPass::onDraw(const GrProgramInfo& programInfo,
|
||||
const GrMesh meshes[], int meshCount,
|
||||
const SkRect& bounds) {
|
||||
if (!meshCount) {
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef SK_DEBUG
|
||||
if (dynamicStateArrays && dynamicStateArrays->fPrimitiveProcessorTextures) {
|
||||
for (int m = 0, i = 0; m < meshCount; ++m) {
|
||||
for (int s = 0; s < primProc.numTextureSamplers(); ++s, ++i) {
|
||||
auto texture = dynamicStateArrays->fPrimitiveProcessorTextures[i]->peekTexture();
|
||||
if (programInfo.hasDynamicPrimProcTextures()) {
|
||||
for (int m = 0; m < meshCount; ++m) {
|
||||
auto dynamicPrimProcTextures = programInfo.dynamicPrimProcTextures(m);
|
||||
|
||||
for (int s = 0; s < programInfo.primProc().numTextureSamplers(); ++s) {
|
||||
auto texture = dynamicPrimProcTextures[s]->peekTexture();
|
||||
check_sampled_texture(texture, fRenderTarget, fGpu);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (int i = 0; i < primProc.numTextureSamplers(); ++i) {
|
||||
auto texture = fixedDynamicState->fPrimitiveProcessorTextures[i]->peekTexture();
|
||||
} else if (programInfo.hasFixedPrimProcTextures()) {
|
||||
auto fixedPrimProcTextures = programInfo.fixedPrimProcTextures();
|
||||
|
||||
for (int s = 0; s < programInfo.primProc().numTextureSamplers(); ++s) {
|
||||
auto texture = fixedPrimProcTextures[s]->peekTexture();
|
||||
check_sampled_texture(texture, fRenderTarget, fGpu);
|
||||
}
|
||||
}
|
||||
GrFragmentProcessor::Iter iter(pipeline);
|
||||
|
||||
GrFragmentProcessor::Iter iter(programInfo.pipeline());
|
||||
while (const GrFragmentProcessor* fp = iter.next()) {
|
||||
for (int i = 0; i < fp->numTextureSamplers(); ++i) {
|
||||
const GrFragmentProcessor::TextureSampler& sampler = fp->textureSampler(i);
|
||||
check_sampled_texture(sampler.peekTexture(), fRenderTarget, fGpu);
|
||||
}
|
||||
}
|
||||
if (GrTexture* dstTexture = pipeline.peekDstTexture()) {
|
||||
if (GrTexture* dstTexture = programInfo.pipeline().peekDstTexture()) {
|
||||
check_sampled_texture(dstTexture, fRenderTarget, fGpu);
|
||||
}
|
||||
|
||||
// Both the 'programInfo' and this renderPass have an origin. Since they come from the
|
||||
// same place (i.e., the target renderTargetProxy) that had best agree.
|
||||
SkASSERT(programInfo.origin() == fOrigin);
|
||||
#endif
|
||||
|
||||
SkRect scissorRect = SkRect::Make(fBounds);
|
||||
@ -544,45 +540,41 @@ void GrVkOpsRenderPass::onDraw(const GrPrimitiveProcessor& primProc,
|
||||
}
|
||||
|
||||
GrPrimitiveType primitiveType = meshes[0].primitiveType();
|
||||
GrVkPipelineState* pipelineState = this->prepareDrawState(primProc, pipeline, fixedDynamicState,
|
||||
dynamicStateArrays, primitiveType,
|
||||
GrVkPipelineState* pipelineState = this->prepareDrawState(programInfo, primitiveType,
|
||||
renderPassScissorRect);
|
||||
if (!pipelineState) {
|
||||
return;
|
||||
}
|
||||
|
||||
bool dynamicScissor =
|
||||
pipeline.isScissorEnabled() && dynamicStateArrays && dynamicStateArrays->fScissorRects;
|
||||
|
||||
bool dynamicTextures = dynamicStateArrays && dynamicStateArrays->fPrimitiveProcessorTextures;
|
||||
bool hasDynamicScissors = programInfo.hasDynamicScissors();
|
||||
bool hasDynamicTextures = programInfo.hasDynamicPrimProcTextures();
|
||||
|
||||
for (int i = 0; i < meshCount; ++i) {
|
||||
const GrMesh& mesh = meshes[i];
|
||||
if (mesh.primitiveType() != primitiveType) {
|
||||
SkDEBUGCODE(pipelineState = nullptr);
|
||||
primitiveType = mesh.primitiveType();
|
||||
pipelineState = this->prepareDrawState(primProc, pipeline, fixedDynamicState,
|
||||
dynamicStateArrays, primitiveType,
|
||||
pipelineState = this->prepareDrawState(programInfo, primitiveType,
|
||||
renderPassScissorRect);
|
||||
if (!pipelineState) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (dynamicScissor) {
|
||||
if (hasDynamicScissors) {
|
||||
SkIRect combinedScissorRect;
|
||||
if (!combinedScissorRect.intersect(renderPassScissorRect,
|
||||
dynamicStateArrays->fScissorRects[i])) {
|
||||
programInfo.dynamicScissor(i))) {
|
||||
combinedScissorRect = SkIRect::MakeEmpty();
|
||||
}
|
||||
GrVkPipeline::SetDynamicScissorRectState(fGpu, this->currentCommandBuffer(),
|
||||
fRenderTarget, fOrigin,
|
||||
combinedScissorRect);
|
||||
}
|
||||
if (dynamicTextures) {
|
||||
GrTextureProxy* const* meshProxies = dynamicStateArrays->fPrimitiveProcessorTextures +
|
||||
primProc.numTextureSamplers() * i;
|
||||
pipelineState->setAndBindTextures(fGpu, primProc, pipeline, meshProxies,
|
||||
if (hasDynamicTextures) {
|
||||
auto meshProxies = programInfo.dynamicPrimProcTextures(i);
|
||||
pipelineState->setAndBindTextures(fGpu, programInfo.primProc(), programInfo.pipeline(),
|
||||
meshProxies,
|
||||
this->currentCommandBuffer());
|
||||
}
|
||||
SkASSERT(pipelineState);
|
||||
|
@ -70,19 +70,10 @@ private:
|
||||
const GrGpuBuffer* vertexBuffer,
|
||||
const GrGpuBuffer* instanceBuffer);
|
||||
|
||||
GrVkPipelineState* prepareDrawState(const GrPrimitiveProcessor&,
|
||||
const GrPipeline&,
|
||||
const GrPipeline::FixedDynamicState*,
|
||||
const GrPipeline::DynamicStateArrays*,
|
||||
GrPrimitiveType,
|
||||
GrVkPipelineState* prepareDrawState(const GrProgramInfo&, GrPrimitiveType,
|
||||
const SkIRect& renderPassScissorRect);
|
||||
|
||||
void onDraw(const GrPrimitiveProcessor&,
|
||||
const GrPipeline&,
|
||||
const GrPipeline::FixedDynamicState*,
|
||||
const GrPipeline::DynamicStateArrays*,
|
||||
const GrMesh[],
|
||||
int meshCount,
|
||||
void onDraw(const GrProgramInfo&, const GrMesh[], int meshCount,
|
||||
const SkRect& bounds) override;
|
||||
|
||||
// GrMesh::SendToGpuImpl methods. These issue the actual Vulkan draw commands.
|
||||
|
@ -278,17 +278,15 @@ static void setup_viewport_scissor_state(VkPipelineViewportStateCreateInfo* view
|
||||
SkASSERT(viewportInfo->viewportCount == viewportInfo->scissorCount);
|
||||
}
|
||||
|
||||
static void setup_multisample_state(int numColorSamples,
|
||||
const GrPrimitiveProcessor& primProc,
|
||||
const GrPipeline& pipeline,
|
||||
static void setup_multisample_state(const GrProgramInfo& programInfo,
|
||||
const GrCaps* caps,
|
||||
VkPipelineMultisampleStateCreateInfo* multisampleInfo) {
|
||||
memset(multisampleInfo, 0, sizeof(VkPipelineMultisampleStateCreateInfo));
|
||||
multisampleInfo->sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
|
||||
multisampleInfo->pNext = nullptr;
|
||||
multisampleInfo->flags = 0;
|
||||
SkAssertResult(GrSampleCountToVkSampleCount(numColorSamples,
|
||||
&multisampleInfo->rasterizationSamples));
|
||||
SkAssertResult(GrSampleCountToVkSampleCount(programInfo.numSamples(),
|
||||
&multisampleInfo->rasterizationSamples));
|
||||
multisampleInfo->sampleShadingEnable = VK_FALSE;
|
||||
multisampleInfo->minSampleShading = 0.0f;
|
||||
multisampleInfo->pSampleMask = nullptr;
|
||||
@ -498,38 +496,40 @@ static void setup_dynamic_state(VkPipelineDynamicStateCreateInfo* dynamicInfo,
|
||||
}
|
||||
|
||||
GrVkPipeline* GrVkPipeline::Create(
|
||||
GrVkGpu* gpu, int numColorSamples, const GrPrimitiveProcessor& primProc,
|
||||
const GrPipeline& pipeline, const GrStencilSettings& stencil, GrSurfaceOrigin origin,
|
||||
GrVkGpu* gpu,
|
||||
const GrProgramInfo& programInfo,
|
||||
const GrStencilSettings& stencil,
|
||||
VkPipelineShaderStageCreateInfo* shaderStageInfo, int shaderStageCount,
|
||||
GrPrimitiveType primitiveType, VkRenderPass compatibleRenderPass, VkPipelineLayout layout,
|
||||
VkPipelineCache cache) {
|
||||
VkPipelineVertexInputStateCreateInfo vertexInputInfo;
|
||||
SkSTArray<2, VkVertexInputBindingDescription, true> bindingDescs;
|
||||
SkSTArray<16, VkVertexInputAttributeDescription> attributeDesc;
|
||||
int totalAttributeCnt = primProc.numVertexAttributes() + primProc.numInstanceAttributes();
|
||||
int totalAttributeCnt = programInfo.primProc().numVertexAttributes() +
|
||||
programInfo.primProc().numInstanceAttributes();
|
||||
SkASSERT(totalAttributeCnt <= gpu->vkCaps().maxVertexAttributes());
|
||||
VkVertexInputAttributeDescription* pAttribs = attributeDesc.push_back_n(totalAttributeCnt);
|
||||
setup_vertex_input_state(primProc, &vertexInputInfo, &bindingDescs, pAttribs);
|
||||
setup_vertex_input_state(programInfo.primProc(), &vertexInputInfo, &bindingDescs, pAttribs);
|
||||
|
||||
VkPipelineInputAssemblyStateCreateInfo inputAssemblyInfo;
|
||||
setup_input_assembly_state(primitiveType, &inputAssemblyInfo);
|
||||
|
||||
VkPipelineDepthStencilStateCreateInfo depthStencilInfo;
|
||||
setup_depth_stencil_state(stencil, origin, &depthStencilInfo);
|
||||
setup_depth_stencil_state(stencil, programInfo.origin(), &depthStencilInfo);
|
||||
|
||||
VkPipelineViewportStateCreateInfo viewportInfo;
|
||||
setup_viewport_scissor_state(&viewportInfo);
|
||||
|
||||
VkPipelineMultisampleStateCreateInfo multisampleInfo;
|
||||
setup_multisample_state(numColorSamples, primProc, pipeline, gpu->caps(), &multisampleInfo);
|
||||
setup_multisample_state(programInfo, gpu->caps(), &multisampleInfo);
|
||||
|
||||
// We will only have one color attachment per pipeline.
|
||||
VkPipelineColorBlendAttachmentState attachmentStates[1];
|
||||
VkPipelineColorBlendStateCreateInfo colorBlendInfo;
|
||||
setup_color_blend_state(pipeline, &colorBlendInfo, attachmentStates);
|
||||
setup_color_blend_state(programInfo.pipeline(), &colorBlendInfo, attachmentStates);
|
||||
|
||||
VkPipelineRasterizationStateCreateInfo rasterInfo;
|
||||
setup_raster_state(pipeline, gpu->caps(), &rasterInfo);
|
||||
setup_raster_state(programInfo.pipeline(), gpu->caps(), &rasterInfo);
|
||||
|
||||
VkDynamicState dynamicStates[3];
|
||||
VkPipelineDynamicStateCreateInfo dynamicInfo;
|
||||
|
@ -25,11 +25,8 @@ struct SkIRect;
|
||||
class GrVkPipeline : public GrVkResource {
|
||||
public:
|
||||
static GrVkPipeline* Create(GrVkGpu*,
|
||||
int numColorSamples,
|
||||
const GrPrimitiveProcessor&,
|
||||
const GrPipeline& pipeline,
|
||||
const GrProgramInfo&,
|
||||
const GrStencilSettings&,
|
||||
GrSurfaceOrigin,
|
||||
VkPipelineShaderStageCreateInfo* shaderStageInfo,
|
||||
int shaderStageCount,
|
||||
GrPrimitiveType primitiveType,
|
||||
|
@ -22,19 +22,14 @@ typedef size_t shader_size;
|
||||
GrVkPipelineState* GrVkPipelineStateBuilder::CreatePipelineState(
|
||||
GrVkGpu* gpu,
|
||||
GrRenderTarget* renderTarget,
|
||||
int numSamples,
|
||||
GrSurfaceOrigin origin,
|
||||
const GrPrimitiveProcessor& primProc,
|
||||
const GrTextureProxy* const primProcProxies[],
|
||||
const GrPipeline& pipeline,
|
||||
const GrProgramInfo& programInfo,
|
||||
const GrStencilSettings& stencil,
|
||||
GrPrimitiveType primitiveType,
|
||||
Desc* desc,
|
||||
VkRenderPass compatibleRenderPass) {
|
||||
// create a builder. This will be handed off to effects so they can use it to add
|
||||
// uniforms, varyings, textures, etc
|
||||
GrVkPipelineStateBuilder builder(gpu, renderTarget, numSamples, origin, pipeline, primProc,
|
||||
primProcProxies, desc);
|
||||
GrVkPipelineStateBuilder builder(gpu, renderTarget, programInfo, desc);
|
||||
|
||||
if (!builder.emitAndInstallProcs()) {
|
||||
return nullptr;
|
||||
@ -45,13 +40,9 @@ GrVkPipelineState* GrVkPipelineStateBuilder::CreatePipelineState(
|
||||
|
||||
GrVkPipelineStateBuilder::GrVkPipelineStateBuilder(GrVkGpu* gpu,
|
||||
GrRenderTarget* renderTarget,
|
||||
int numSamples,
|
||||
GrSurfaceOrigin origin,
|
||||
const GrPipeline& pipeline,
|
||||
const GrPrimitiveProcessor& primProc,
|
||||
const GrTextureProxy* const primProcProxies[],
|
||||
const GrProgramInfo& programInfo,
|
||||
GrProgramDesc* desc)
|
||||
: INHERITED(renderTarget, numSamples, origin, primProc, primProcProxies, pipeline, desc)
|
||||
: INHERITED(renderTarget, programInfo, desc)
|
||||
, fGpu(gpu)
|
||||
, fVaryingHandler(this)
|
||||
, fUniformHandler(this) {}
|
||||
@ -142,7 +133,7 @@ int GrVkPipelineStateBuilder::loadShadersFromCache(SkReader32* cached,
|
||||
void GrVkPipelineStateBuilder::storeShadersInCache(const SkSL::String shaders[],
|
||||
const SkSL::Program::Inputs inputs[],
|
||||
bool isSkSL) {
|
||||
Desc* desc = static_cast<Desc*>(this->desc());
|
||||
const Desc* desc = static_cast<const Desc*>(this->desc());
|
||||
sk_sp<SkData> key = SkData::MakeWithoutCopy(desc->asKey(), desc->shaderKeyLength());
|
||||
sk_sp<SkData> data = GrPersistentCacheUtils::PackCachedShaders(isSkSL ? kSKSL_Tag : kSPIRV_Tag,
|
||||
shaders,
|
||||
@ -294,8 +285,7 @@ GrVkPipelineState* GrVkPipelineStateBuilder::finalize(const GrStencilSettings& s
|
||||
this->storeShadersInCache(shaders, inputs, isSkSL);
|
||||
}
|
||||
}
|
||||
GrVkPipeline* pipeline = resourceProvider.createPipeline(
|
||||
fNumSamples, fPrimProc, fPipeline, stencil, this->origin(),
|
||||
GrVkPipeline* pipeline = resourceProvider.createPipeline(fProgramInfo, stencil,
|
||||
shaderStageInfo, numShaderStages, primitiveType, compatibleRenderPass, pipelineLayout);
|
||||
for (int i = 0; i < kGrShaderTypeCount; ++i) {
|
||||
// This if check should not be needed since calling destroy on a VK_NULL_HANDLE is allowed.
|
||||
@ -329,13 +319,12 @@ GrVkPipelineState* GrVkPipelineStateBuilder::finalize(const GrStencilSettings& s
|
||||
|
||||
bool GrVkPipelineStateBuilder::Desc::Build(Desc* desc,
|
||||
GrRenderTarget* renderTarget,
|
||||
const GrPrimitiveProcessor& primProc,
|
||||
const GrPipeline& pipeline,
|
||||
const GrProgramInfo& programInfo,
|
||||
const GrStencilSettings& stencil,
|
||||
GrPrimitiveType primitiveType,
|
||||
GrVkGpu* gpu) {
|
||||
if (!INHERITED::Build(desc, renderTarget, primProc,
|
||||
primitiveType == GrPrimitiveType::kPoints, pipeline, gpu)) {
|
||||
if (!GrProgramDesc::Build(desc, renderTarget, programInfo,
|
||||
primitiveType == GrPrimitiveType::kPoints, gpu)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -351,7 +340,7 @@ bool GrVkPipelineStateBuilder::Desc::Build(Desc* desc,
|
||||
|
||||
stencil.genKey(&b);
|
||||
|
||||
b.add32(pipeline.getBlendInfoKey());
|
||||
b.add32(programInfo.pipeline().getBlendInfoKey());
|
||||
|
||||
b.add32((uint32_t)primitiveType);
|
||||
|
||||
|
@ -40,8 +40,7 @@ public:
|
||||
public:
|
||||
static bool Build(Desc*,
|
||||
GrRenderTarget*,
|
||||
const GrPrimitiveProcessor&,
|
||||
const GrPipeline&,
|
||||
const GrProgramInfo&,
|
||||
const GrStencilSettings&,
|
||||
GrPrimitiveType primitiveType,
|
||||
GrVkGpu* gpu);
|
||||
@ -64,11 +63,7 @@ public:
|
||||
*/
|
||||
static GrVkPipelineState* CreatePipelineState(GrVkGpu*,
|
||||
GrRenderTarget*,
|
||||
int numSamples,
|
||||
GrSurfaceOrigin,
|
||||
const GrPrimitiveProcessor&,
|
||||
const GrTextureProxy* const primProcProxies[],
|
||||
const GrPipeline&,
|
||||
const GrProgramInfo&,
|
||||
const GrStencilSettings&,
|
||||
GrPrimitiveType,
|
||||
Desc*,
|
||||
@ -82,13 +77,7 @@ public:
|
||||
void finalizeFragmentSecondaryColor(GrShaderVar& outputColor) override;
|
||||
|
||||
private:
|
||||
GrVkPipelineStateBuilder(GrVkGpu*, GrRenderTarget*,
|
||||
int numSamples,
|
||||
GrSurfaceOrigin,
|
||||
const GrPipeline&,
|
||||
const GrPrimitiveProcessor&,
|
||||
const GrTextureProxy* const primProcProxies[],
|
||||
GrProgramDesc*);
|
||||
GrVkPipelineStateBuilder(GrVkGpu*, GrRenderTarget*, const GrProgramInfo&, GrProgramDesc*);
|
||||
|
||||
GrVkPipelineState* finalize(const GrStencilSettings&,
|
||||
GrPrimitiveType primitiveType,
|
||||
|
@ -78,34 +78,33 @@ void GrVkResourceProvider::PipelineStateCache::release() {
|
||||
|
||||
GrVkPipelineState* GrVkResourceProvider::PipelineStateCache::refPipelineState(
|
||||
GrRenderTarget* renderTarget,
|
||||
int numSamples,
|
||||
GrSurfaceOrigin origin,
|
||||
const GrPrimitiveProcessor& primProc,
|
||||
const GrTextureProxy* const primProcProxies[],
|
||||
const GrPipeline& pipeline,
|
||||
const GrProgramInfo& programInfo,
|
||||
GrPrimitiveType primitiveType,
|
||||
VkRenderPass compatibleRenderPass) {
|
||||
#ifdef GR_PIPELINE_STATE_CACHE_STATS
|
||||
++fTotalRequests;
|
||||
#endif
|
||||
GrStencilSettings stencil;
|
||||
if (pipeline.isStencilEnabled()) {
|
||||
if (programInfo.pipeline().isStencilEnabled()) {
|
||||
// TODO: attach stencil and create settings during render target flush.
|
||||
SkASSERT(renderTarget->renderTargetPriv().getStencilAttachment());
|
||||
stencil.reset(*pipeline.getUserStencil(), pipeline.hasStencilClip(),
|
||||
stencil.reset(*programInfo.pipeline().getUserStencil(),
|
||||
programInfo.pipeline().hasStencilClip(),
|
||||
renderTarget->renderTargetPriv().numStencilBits());
|
||||
}
|
||||
|
||||
// TODO: can this be unified between Vulkan and GL?
|
||||
// Get GrVkProgramDesc
|
||||
GrVkPipelineStateBuilder::Desc desc;
|
||||
if (!GrVkPipelineStateBuilder::Desc::Build(&desc, renderTarget, primProc, pipeline, stencil,
|
||||
if (!GrVkPipelineStateBuilder::Desc::Build(&desc, renderTarget, programInfo, stencil,
|
||||
primitiveType, fGpu)) {
|
||||
GrCapsDebugf(fGpu->caps(), "Failed to build vk program descriptor!\n");
|
||||
return nullptr;
|
||||
}
|
||||
// If we knew the shader won't depend on origin, we could skip this (and use the same program
|
||||
// for both origins). Instrumenting all fragment processors would be difficult and error prone.
|
||||
desc.setSurfaceOriginKey(GrGLSLFragmentShaderBuilder::KeyForSurfaceOrigin(origin));
|
||||
desc.setSurfaceOriginKey(
|
||||
GrGLSLFragmentShaderBuilder::KeyForSurfaceOrigin(programInfo.origin()));
|
||||
|
||||
std::unique_ptr<Entry>* entry = fMap.find(desc);
|
||||
if (!entry) {
|
||||
@ -113,9 +112,9 @@ GrVkPipelineState* GrVkResourceProvider::PipelineStateCache::refPipelineState(
|
||||
++fCacheMisses;
|
||||
#endif
|
||||
GrVkPipelineState* pipelineState(GrVkPipelineStateBuilder::CreatePipelineState(
|
||||
fGpu, renderTarget, numSamples, origin, primProc, primProcProxies, pipeline,
|
||||
fGpu, renderTarget, programInfo,
|
||||
stencil, primitiveType, &desc, compatibleRenderPass));
|
||||
if (nullptr == pipelineState) {
|
||||
if (!pipelineState) {
|
||||
return nullptr;
|
||||
}
|
||||
entry = fMap.insert(desc, std::unique_ptr<Entry>(new Entry(fGpu, pipelineState)));
|
||||
|
@ -91,19 +91,16 @@ void GrVkResourceProvider::init() {
|
||||
fUniformDSHandle = GrVkDescriptorSetManager::Handle(0);
|
||||
}
|
||||
|
||||
GrVkPipeline* GrVkResourceProvider::createPipeline(int numColorSamples,
|
||||
const GrPrimitiveProcessor& primProc,
|
||||
const GrPipeline& pipeline,
|
||||
GrVkPipeline* GrVkResourceProvider::createPipeline(const GrProgramInfo& programInfo,
|
||||
const GrStencilSettings& stencil,
|
||||
GrSurfaceOrigin origin,
|
||||
VkPipelineShaderStageCreateInfo* shaderStageInfo,
|
||||
int shaderStageCount,
|
||||
GrPrimitiveType primitiveType,
|
||||
VkRenderPass compatibleRenderPass,
|
||||
VkPipelineLayout layout) {
|
||||
return GrVkPipeline::Create(
|
||||
fGpu, numColorSamples, primProc, pipeline, stencil, origin, shaderStageInfo,
|
||||
shaderStageCount, primitiveType, compatibleRenderPass, layout, this->pipelineCache());
|
||||
return GrVkPipeline::Create(fGpu, programInfo, stencil, shaderStageInfo,
|
||||
shaderStageCount, primitiveType, compatibleRenderPass,
|
||||
layout, this->pipelineCache());
|
||||
}
|
||||
|
||||
// To create framebuffers, we first need to create a simple RenderPass that is
|
||||
@ -228,13 +225,12 @@ GrVkSamplerYcbcrConversion* GrVkResourceProvider::findOrCreateCompatibleSamplerY
|
||||
}
|
||||
|
||||
GrVkPipelineState* GrVkResourceProvider::findOrCreateCompatiblePipelineState(
|
||||
GrRenderTarget* renderTarget, int numSamples, GrSurfaceOrigin origin,
|
||||
const GrPipeline& pipeline, const GrPrimitiveProcessor& proc,
|
||||
const GrTextureProxy* const primProcProxies[], GrPrimitiveType primitiveType,
|
||||
GrRenderTarget* renderTarget,
|
||||
const GrProgramInfo& programInfo,
|
||||
GrPrimitiveType primitiveType,
|
||||
VkRenderPass compatibleRenderPass) {
|
||||
return fPipelineStateCache->refPipelineState(renderTarget, numSamples, origin, proc,
|
||||
primProcProxies, pipeline, primitiveType,
|
||||
compatibleRenderPass);
|
||||
return fPipelineStateCache->refPipelineState(renderTarget, programInfo,
|
||||
primitiveType, compatibleRenderPass);
|
||||
}
|
||||
|
||||
void GrVkResourceProvider::getSamplerDescriptorSetHandle(VkDescriptorType type,
|
||||
|
@ -43,11 +43,8 @@ public:
|
||||
// Set up any initial vk objects
|
||||
void init();
|
||||
|
||||
GrVkPipeline* createPipeline(int numColorSamples,
|
||||
const GrPrimitiveProcessor& primProc,
|
||||
const GrPipeline& pipeline,
|
||||
GrVkPipeline* createPipeline(const GrProgramInfo&,
|
||||
const GrStencilSettings& stencil,
|
||||
GrSurfaceOrigin,
|
||||
VkPipelineShaderStageCreateInfo* shaderStageInfo,
|
||||
int shaderStageCount,
|
||||
GrPrimitiveType primitiveType,
|
||||
@ -114,10 +111,8 @@ public:
|
||||
const GrVkYcbcrConversionInfo& ycbcrInfo);
|
||||
|
||||
GrVkPipelineState* findOrCreateCompatiblePipelineState(
|
||||
GrRenderTarget*, int numSamples, GrSurfaceOrigin,
|
||||
const GrPipeline&,
|
||||
const GrPrimitiveProcessor&,
|
||||
const GrTextureProxy* const primProcProxies[],
|
||||
GrRenderTarget*,
|
||||
const GrProgramInfo&,
|
||||
GrPrimitiveType,
|
||||
VkRenderPass compatibleRenderPass);
|
||||
|
||||
@ -197,10 +192,8 @@ private:
|
||||
|
||||
void abandon();
|
||||
void release();
|
||||
GrVkPipelineState* refPipelineState(GrRenderTarget*, int numSamples, GrSurfaceOrigin,
|
||||
const GrPrimitiveProcessor&,
|
||||
const GrTextureProxy* const primProcProxies[],
|
||||
const GrPipeline&,
|
||||
GrVkPipelineState* refPipelineState(GrRenderTarget*,
|
||||
const GrProgramInfo&,
|
||||
GrPrimitiveType,
|
||||
VkRenderPass compatibleRenderPass);
|
||||
|
||||
|
@ -211,11 +211,10 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(GrAtlasTextOpPreparation, reporter, ctxInfo)
|
||||
TestingUploadTarget uploadTarget;
|
||||
|
||||
GrOpFlushState flushState(gpu, resourceProvider, uploadTarget.writeableTokenTracker());
|
||||
GrOpFlushState::OpArgs opArgs(
|
||||
op.get(),
|
||||
rtc->asRenderTargetProxy(),
|
||||
nullptr,
|
||||
GrXferProcessor::DstProxy(nullptr, SkIPoint::Make(0, 0)));
|
||||
GrOpFlushState::OpArgs opArgs(op.get(),
|
||||
rtc->asRenderTargetProxy(),
|
||||
nullptr,
|
||||
GrXferProcessor::DstProxy(nullptr, SkIPoint::Make(0, 0)));
|
||||
|
||||
// Cripple the atlas manager so it can't allocate any pages. This will force a failure
|
||||
// in the preparation of the text op
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include "src/gpu/GrMemoryPool.h"
|
||||
#include "src/gpu/GrOpFlushState.h"
|
||||
#include "src/gpu/GrOpsRenderPass.h"
|
||||
#include "src/gpu/GrProgramInfo.h"
|
||||
#include "src/gpu/GrRenderTargetContext.h"
|
||||
#include "src/gpu/GrRenderTargetContextPriv.h"
|
||||
#include "src/gpu/GrResourceProvider.h"
|
||||
@ -410,7 +411,14 @@ sk_sp<const GrBuffer> DrawMeshHelper::getIndexBuffer() {
|
||||
void DrawMeshHelper::drawMesh(const GrMesh& mesh) {
|
||||
GrPipeline pipeline(GrScissorTest::kDisabled, SkBlendMode::kSrc, GrSwizzle::RGBA());
|
||||
GrMeshTestProcessor mtp(mesh.isInstanced(), mesh.hasVertexData());
|
||||
fState->opsRenderPass()->draw(mtp, pipeline, nullptr, nullptr, &mesh, 1,
|
||||
|
||||
GrProgramInfo programInfo(fState->drawOpArgs().numSamples(),
|
||||
fState->drawOpArgs().origin(),
|
||||
pipeline,
|
||||
mtp,
|
||||
nullptr, nullptr);
|
||||
|
||||
fState->opsRenderPass()->draw(programInfo, &mesh, 1,
|
||||
SkRect::MakeIWH(kImageWidth, kImageHeight));
|
||||
}
|
||||
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include "src/gpu/GrMemoryPool.h"
|
||||
#include "src/gpu/GrOpFlushState.h"
|
||||
#include "src/gpu/GrOpsRenderPass.h"
|
||||
#include "src/gpu/GrProgramInfo.h"
|
||||
#include "src/gpu/GrRecordingContextPriv.h"
|
||||
#include "src/gpu/GrRenderTargetContext.h"
|
||||
#include "src/gpu/GrRenderTargetContextPriv.h"
|
||||
@ -140,8 +141,9 @@ private:
|
||||
return GrProcessorSet::EmptySetAnalysis();
|
||||
}
|
||||
void onPrepare(GrOpFlushState*) override {}
|
||||
void onExecute(GrOpFlushState* state, const SkRect& chainBounds) override {
|
||||
GrPipeline pipeline(fScissorTest, SkBlendMode::kSrc, state->drawOpArgs().outputSwizzle());
|
||||
void onExecute(GrOpFlushState* flushState, const SkRect& chainBounds) override {
|
||||
GrPipeline pipeline(fScissorTest, SkBlendMode::kSrc,
|
||||
flushState->drawOpArgs().outputSwizzle());
|
||||
SkSTArray<kNumMeshes, GrMesh> meshes;
|
||||
for (int i = 0; i < kNumMeshes; ++i) {
|
||||
GrMesh& mesh = meshes.emplace_back(GrPrimitiveType::kTriangleStrip);
|
||||
@ -150,9 +152,18 @@ private:
|
||||
}
|
||||
GrPipeline::DynamicStateArrays dynamicState;
|
||||
dynamicState.fScissorRects = kDynamicScissors;
|
||||
state->opsRenderPass()->draw(GrPipelineDynamicStateTestProcessor(), pipeline, nullptr,
|
||||
&dynamicState, meshes.begin(), 4,
|
||||
SkRect::MakeIWH(kScreenSize, kScreenSize));
|
||||
|
||||
GrPipelineDynamicStateTestProcessor primProc;
|
||||
|
||||
GrProgramInfo programInfo(flushState->drawOpArgs().numSamples(),
|
||||
flushState->drawOpArgs().origin(),
|
||||
pipeline,
|
||||
primProc,
|
||||
nullptr,
|
||||
&dynamicState);
|
||||
|
||||
flushState->opsRenderPass()->draw(programInfo, meshes.begin(), 4,
|
||||
SkRect::MakeIWH(kScreenSize, kScreenSize));
|
||||
}
|
||||
|
||||
GrScissorTest fScissorTest;
|
||||
|
Loading…
Reference in New Issue
Block a user