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
This commit is contained in:
parent
62e9b145a1
commit
720dc71cfe
@ -483,14 +483,16 @@ uint32_t get_blend_info_key(const GrPipeline& pipeline) {
|
|||||||
return key;
|
return key;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GrVkPipelineState::BuildStateKey(const GrPipeline& pipeline, GrPrimitiveType primitiveType,
|
bool GrVkPipelineState::Desc::Build(Desc* desc,
|
||||||
SkTArray<uint8_t, true>* key) {
|
const GrPrimitiveProcessor& primProc,
|
||||||
// Save room for the key length and key header
|
const GrPipeline& pipeline,
|
||||||
key->reset();
|
GrPrimitiveType primitiveType,
|
||||||
key->push_back_n(kData_StateKeyOffset);
|
const GrGLSLCaps& caps) {
|
||||||
|
if (!INHERITED::Build(desc, primProc, pipeline, caps)) {
|
||||||
GrProcessorKeyBuilder b(key);
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
GrProcessorKeyBuilder b(&desc->key());
|
||||||
GrVkRenderTarget* vkRT = (GrVkRenderTarget*)pipeline.getRenderTarget();
|
GrVkRenderTarget* vkRT = (GrVkRenderTarget*)pipeline.getRenderTarget();
|
||||||
vkRT->simpleRenderPass()->genKey(&b);
|
vkRT->simpleRenderPass()->genKey(&b);
|
||||||
|
|
||||||
@ -503,8 +505,5 @@ void GrVkPipelineState::BuildStateKey(const GrPipeline& pipeline, GrPrimitiveTyp
|
|||||||
|
|
||||||
b.add32(primitiveType);
|
b.add32(primitiveType);
|
||||||
|
|
||||||
// Set key length
|
return true;
|
||||||
int keyLength = key->count();
|
|
||||||
SkASSERT(0 == (keyLength % 4));
|
|
||||||
*reinterpret_cast<uint32_t*>(key->begin()) = SkToU32(keyLength);
|
|
||||||
}
|
}
|
||||||
|
@ -56,90 +56,28 @@ public:
|
|||||||
|
|
||||||
void abandonGPUResources();
|
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<unsigned char, true>* key);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* For Vulkan we want to cache the entire VkPipeline for reuse of draws. The Desc here holds all
|
* 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 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.
|
* pipeline.
|
||||||
*
|
*
|
||||||
* The fStateKey is used to store all the inputs for the rest of the state stored on the
|
* For Vulkan we need to add to the GrProgramDesc to include the rest of the state on the
|
||||||
* pipeline. This includes stencil settings, blending information, render pass format, draw face
|
* 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
|
* 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,
|
* each draw and thus is not included in this descriptor. This includes the viewport, scissor,
|
||||||
* and blend constant.
|
* 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 {
|
class Desc : public GrProgramDesc {
|
||||||
uint32_t fChecksum;
|
public:
|
||||||
GrProgramDesc fProgramDesc;
|
static bool Build(Desc*,
|
||||||
|
const GrPrimitiveProcessor&,
|
||||||
enum {
|
const GrPipeline&,
|
||||||
kRenderPassKeyAlloc = 12, // This is typical color attachment with no stencil or msaa
|
GrPrimitiveType primitiveType,
|
||||||
kStencilKeyAlloc = sizeof(GrStencilSettings),
|
const GrGLSLCaps&);
|
||||||
kDrawFaceKeyAlloc = 4,
|
private:
|
||||||
kBlendingKeyAlloc = 4,
|
typedef GrProgramDesc INHERITED;
|
||||||
kPrimitiveTypeKeyAlloc = 4,
|
|
||||||
kPreAllocSize = kData_StateKeyOffset + kRenderPassKeyAlloc + kStencilKeyAlloc +
|
|
||||||
kDrawFaceKeyAlloc + kBlendingKeyAlloc + kPrimitiveTypeKeyAlloc,
|
|
||||||
};
|
|
||||||
SkSTArray<kPreAllocSize, uint8_t, true> 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<const uint32_t*>(fStateKey.begin());
|
|
||||||
const uint32_t* bKey = reinterpret_cast<const uint32_t*>(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<const uint32_t*>(a.fStateKey.begin());
|
|
||||||
const uint32_t* bKey = reinterpret_cast<const uint32_t*>(b.fStateKey.begin());
|
|
||||||
for (int i = 0; i < l; ++i) {
|
|
||||||
if (aKey[i] != bKey[i]) {
|
|
||||||
return aKey[i] < bKey[i] ? true : false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const Desc& getDesc() { return fDesc; }
|
const Desc& getDesc() { return fDesc; }
|
||||||
|
@ -23,7 +23,7 @@ GrVkPipelineState* GrVkPipelineStateBuilder::CreatePipelineState(
|
|||||||
const GrVkRenderPass& renderPass) {
|
const GrVkRenderPass& renderPass) {
|
||||||
// create a builder. This will be handed off to effects so they can use it to add
|
// create a builder. This will be handed off to effects so they can use it to add
|
||||||
// uniforms, varyings, textures, etc
|
// uniforms, varyings, textures, etc
|
||||||
GrVkPipelineStateBuilder builder(gpu, pipeline, primProc, desc.fProgramDesc);
|
GrVkPipelineStateBuilder builder(gpu, pipeline, primProc, desc);
|
||||||
|
|
||||||
GrGLSLExpr4 inputColor;
|
GrGLSLExpr4 inputColor;
|
||||||
GrGLSLExpr4 inputCoverage;
|
GrGLSLExpr4 inputCoverage;
|
||||||
|
@ -29,7 +29,7 @@ struct GrVkResourceProvider::PipelineStateCache::Entry {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t Hash(const GrVkPipelineState::Desc& key) {
|
static uint32_t Hash(const GrVkPipelineState::Desc& key) {
|
||||||
return key.fChecksum;
|
return key.getChecksum();
|
||||||
}
|
}
|
||||||
|
|
||||||
sk_sp<GrVkPipelineState> fPipelineState;
|
sk_sp<GrVkPipelineState> fPipelineState;
|
||||||
@ -99,20 +99,12 @@ sk_sp<GrVkPipelineState> GrVkResourceProvider::PipelineStateCache::refPipelineSt
|
|||||||
#endif
|
#endif
|
||||||
// Get GrVkProgramDesc
|
// Get GrVkProgramDesc
|
||||||
GrVkPipelineState::Desc desc;
|
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");
|
GrCapsDebugf(fGpu->caps(), "Failed to build vk program descriptor!\n");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
desc.fProgramDesc.finalize();
|
desc.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());
|
|
||||||
|
|
||||||
Entry* entry = nullptr;
|
Entry* entry = nullptr;
|
||||||
if (Entry** entryptr = fHashTable.find(desc)) {
|
if (Entry** entryptr = fHashTable.find(desc)) {
|
||||||
|
Loading…
Reference in New Issue
Block a user