From 720dc71cfe79d708b28829b99d1ecf4b1e192621 Mon Sep 17 00:00:00 2001 From: egdaniel Date: Wed, 7 Sep 2016 11:56:59 -0700 Subject: [PATCH] Merge building of program desc in Vulkan into one step BUG=skia: GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2318143002 Review-Url: https://codereview.chromium.org/2318143002 --- src/gpu/vk/GrVkPipelineState.cpp | 21 ++++---- src/gpu/vk/GrVkPipelineState.h | 86 +++++---------------------------- src/gpu/vk/GrVkPipelineStateBuilder.cpp | 2 +- src/gpu/vk/GrVkPipelineStateCache.cpp | 16 ++---- 4 files changed, 27 insertions(+), 98 deletions(-) diff --git a/src/gpu/vk/GrVkPipelineState.cpp b/src/gpu/vk/GrVkPipelineState.cpp index 2dd691c..2398385 100644 --- a/src/gpu/vk/GrVkPipelineState.cpp +++ b/src/gpu/vk/GrVkPipelineState.cpp @@ -483,14 +483,16 @@ uint32_t get_blend_info_key(const GrPipeline& pipeline) { return key; } -void GrVkPipelineState::BuildStateKey(const GrPipeline& pipeline, GrPrimitiveType primitiveType, - SkTArray* key) { - // Save room for the key length and key header - key->reset(); - key->push_back_n(kData_StateKeyOffset); - - GrProcessorKeyBuilder b(key); +bool GrVkPipelineState::Desc::Build(Desc* desc, + const GrPrimitiveProcessor& primProc, + const GrPipeline& pipeline, + GrPrimitiveType primitiveType, + const GrGLSLCaps& caps) { + if (!INHERITED::Build(desc, primProc, pipeline, caps)) { + return false; + } + GrProcessorKeyBuilder b(&desc->key()); GrVkRenderTarget* vkRT = (GrVkRenderTarget*)pipeline.getRenderTarget(); vkRT->simpleRenderPass()->genKey(&b); @@ -503,8 +505,5 @@ void GrVkPipelineState::BuildStateKey(const GrPipeline& pipeline, GrPrimitiveTyp b.add32(primitiveType); - // Set key length - int keyLength = key->count(); - SkASSERT(0 == (keyLength % 4)); - *reinterpret_cast(key->begin()) = SkToU32(keyLength); + return true; } diff --git a/src/gpu/vk/GrVkPipelineState.h b/src/gpu/vk/GrVkPipelineState.h index ad32ece..d15fef4 100644 --- a/src/gpu/vk/GrVkPipelineState.h +++ b/src/gpu/vk/GrVkPipelineState.h @@ -56,90 +56,28 @@ public: void abandonGPUResources(); - // The key is composed of two parts: - // 1. uint32_t for total key length - // 2. Pipeline state data - enum StateKeyOffsets { - // Part 1. - kLength_StateKeyOffset = 0, - // Part 2. - kData_StateKeyOffset = kLength_StateKeyOffset + sizeof(uint32_t), - }; - static void BuildStateKey(const GrPipeline&, GrPrimitiveType primitiveType, - SkTArray* key); - /** * For Vulkan we want to cache the entire VkPipeline for reuse of draws. The Desc here holds all * the information needed to differentiate one pipeline from another. * - * The GrGLSLProgramDesc contains all the information need to create the actual shaders for the + * The GrProgramDesc contains all the information need to create the actual shaders for the * pipeline. * - * The fStateKey is used to store all the inputs for the rest of the state stored on the - * pipeline. This includes stencil settings, blending information, render pass format, draw face + * For Vulkan we need to add to the GrProgramDesc to include the rest of the state on the + * pipline. This includes stencil settings, blending information, render pass format, draw face * information, and primitive type. Note that some state is set dynamically on the pipeline for * each draw and thus is not included in this descriptor. This includes the viewport, scissor, * and blend constant. - * - * A checksum which includes the fProgramDesc and fStateKey is included at the top of the Desc - * for caching purposes and faster equality checks. */ - struct Desc { - uint32_t fChecksum; - GrProgramDesc fProgramDesc; - - enum { - kRenderPassKeyAlloc = 12, // This is typical color attachment with no stencil or msaa - kStencilKeyAlloc = sizeof(GrStencilSettings), - kDrawFaceKeyAlloc = 4, - kBlendingKeyAlloc = 4, - kPrimitiveTypeKeyAlloc = 4, - kPreAllocSize = kData_StateKeyOffset + kRenderPassKeyAlloc + kStencilKeyAlloc + - kDrawFaceKeyAlloc + kBlendingKeyAlloc + kPrimitiveTypeKeyAlloc, - }; - SkSTArray fStateKey; - - bool operator== (const Desc& that) const { - if (fChecksum != that.fChecksum || fProgramDesc != that.fProgramDesc) { - return false; - } - // We store the keyLength at the start of fVkKey. Thus we don't have to worry about - // different length keys since we will fail on the comparison immediately. Therefore we - // just use this PipelineDesc to get the length to iterate over. - int keyLength = fStateKey.count(); - SkASSERT(SkIsAlign4(keyLength)); - int l = keyLength >> 2; - const uint32_t* aKey = reinterpret_cast(fStateKey.begin()); - const uint32_t* bKey = reinterpret_cast(that.fStateKey.begin()); - for (int i = 0; i < l; ++i) { - if (aKey[i] != bKey[i]) { - return false; - } - } - return true; - } - - static bool Less(const Desc& a, const Desc& b) { - if (a.fChecksum != b.fChecksum) { - return a.fChecksum < b.fChecksum ? true : false; - } - bool progDescLess = GrProgramDesc::Less(a.fProgramDesc, b.fProgramDesc); - if (progDescLess || a.fProgramDesc != b.fProgramDesc) { - return progDescLess; - } - - int keyLength = a.fStateKey.count(); - SkASSERT(SkIsAlign4(keyLength)); - int l = keyLength >> 2; - const uint32_t* aKey = reinterpret_cast(a.fStateKey.begin()); - const uint32_t* bKey = reinterpret_cast(b.fStateKey.begin()); - for (int i = 0; i < l; ++i) { - if (aKey[i] != bKey[i]) { - return aKey[i] < bKey[i] ? true : false; - } - } - return false; - } + class Desc : public GrProgramDesc { + public: + static bool Build(Desc*, + const GrPrimitiveProcessor&, + const GrPipeline&, + GrPrimitiveType primitiveType, + const GrGLSLCaps&); + private: + typedef GrProgramDesc INHERITED; }; const Desc& getDesc() { return fDesc; } diff --git a/src/gpu/vk/GrVkPipelineStateBuilder.cpp b/src/gpu/vk/GrVkPipelineStateBuilder.cpp index dead7d1..754ef42 100644 --- a/src/gpu/vk/GrVkPipelineStateBuilder.cpp +++ b/src/gpu/vk/GrVkPipelineStateBuilder.cpp @@ -23,7 +23,7 @@ GrVkPipelineState* GrVkPipelineStateBuilder::CreatePipelineState( const GrVkRenderPass& renderPass) { // create a builder. This will be handed off to effects so they can use it to add // uniforms, varyings, textures, etc - GrVkPipelineStateBuilder builder(gpu, pipeline, primProc, desc.fProgramDesc); + GrVkPipelineStateBuilder builder(gpu, pipeline, primProc, desc); GrGLSLExpr4 inputColor; GrGLSLExpr4 inputCoverage; diff --git a/src/gpu/vk/GrVkPipelineStateCache.cpp b/src/gpu/vk/GrVkPipelineStateCache.cpp index 1becad5..2e6a85b 100644 --- a/src/gpu/vk/GrVkPipelineStateCache.cpp +++ b/src/gpu/vk/GrVkPipelineStateCache.cpp @@ -29,7 +29,7 @@ struct GrVkResourceProvider::PipelineStateCache::Entry { } static uint32_t Hash(const GrVkPipelineState::Desc& key) { - return key.fChecksum; + return key.getChecksum(); } sk_sp fPipelineState; @@ -99,20 +99,12 @@ sk_sp GrVkResourceProvider::PipelineStateCache::refPipelineSt #endif // Get GrVkProgramDesc GrVkPipelineState::Desc desc; - if (!GrProgramDesc::Build(&desc.fProgramDesc, primProc, pipeline, *fGpu->vkCaps().glslCaps())) { + if (!GrVkPipelineState::Desc::Build(&desc, primProc, pipeline, primitiveType, + *fGpu->vkCaps().glslCaps())) { GrCapsDebugf(fGpu->caps(), "Failed to build vk program descriptor!\n"); return nullptr; } - desc.fProgramDesc.finalize(); - - // Get vulkan specific descriptor key - GrVkPipelineState::BuildStateKey(pipeline, primitiveType, &desc.fStateKey); - // Get checksum of entire PipelineDesc - int keyLength = desc.fStateKey.count(); - SkASSERT(0 == (keyLength % 4)); - // Seed the checksum with the checksum of the programDesc then add the vulkan key to it. - desc.fChecksum = SkOpts::hash(desc.fStateKey.begin(), keyLength, - desc.fProgramDesc.getChecksum()); + desc.finalize(); Entry* entry = nullptr; if (Entry** entryptr = fHashTable.find(desc)) { -- 2.7.4