Dawn: implement Sampler cache (optimization).
Change-Id: I0b1fabadb3fddd90350eff3b13037ce92c5dbfd8
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/238178
Commit-Queue: Stephen White <senorblanco@chromium.org>
Reviewed-by: Greg Daniel <egdaniel@google.com>
diff --git a/src/gpu/dawn/GrDawnGpu.cpp b/src/gpu/dawn/GrDawnGpu.cpp
index 9bfa34c..62ebcd9 100644
--- a/src/gpu/dawn/GrDawnGpu.cpp
+++ b/src/gpu/dawn/GrDawnGpu.cpp
@@ -37,10 +37,37 @@
const int kMaxRenderPipelineEntries = 1024;
-namespace {
+static dawn::FilterMode to_dawn_filter_mode(GrSamplerState::Filter filter) {
+ switch (filter) {
+ case GrSamplerState::Filter::kNearest:
+ return dawn::FilterMode::Nearest;
+ case GrSamplerState::Filter::kBilerp:
+ case GrSamplerState::Filter::kMipMap:
+ return dawn::FilterMode::Linear;
+ default:
+ SkASSERT(!"unsupported filter mode");
+ return dawn::FilterMode::Nearest;
+ }
+}
+
+static dawn::AddressMode to_dawn_address_mode(GrSamplerState::WrapMode wrapMode) {
+ switch (wrapMode) {
+ case GrSamplerState::WrapMode::kClamp:
+ return dawn::AddressMode::ClampToEdge;
+ case GrSamplerState::WrapMode::kRepeat:
+ return dawn::AddressMode::Repeat;
+ case GrSamplerState::WrapMode::kMirrorRepeat:
+ return dawn::AddressMode::MirrorRepeat;
+ case GrSamplerState::WrapMode::kClampToBorder:
+ SkASSERT(!"unsupported address mode");
+ }
+ SkASSERT(!"unsupported address mode");
+ return dawn::AddressMode::ClampToEdge;
+
+}
// FIXME: taken from GrVkPipelineState; refactor.
-uint32_t get_blend_info_key(const GrPipeline& pipeline) {
+static uint32_t get_blend_info_key(const GrPipeline& pipeline) {
GrXferProcessor::BlendInfo blendInfo = pipeline.getXferProcessor().getBlendInfo();
static const uint32_t kBlendWriteShift = 1;
@@ -82,8 +109,6 @@
}
};
-};
-
sk_sp<GrGpu> GrDawnGpu::Make(const dawn::Device& device,
const GrContextOptions& options, GrContext* context) {
if (!device) {
@@ -643,6 +668,25 @@
return program;
}
+dawn::Sampler GrDawnGpu::getOrCreateSampler(const GrSamplerState& samplerState) {
+ auto i = fSamplers.find(samplerState);
+ if (i != fSamplers.end()) {
+ return i->second;
+ }
+ dawn::SamplerDescriptor desc;
+ desc.addressModeU = to_dawn_address_mode(samplerState.wrapModeX());
+ desc.addressModeV = to_dawn_address_mode(samplerState.wrapModeY());
+ desc.addressModeW = dawn::AddressMode::ClampToEdge;
+ desc.magFilter = desc.minFilter = to_dawn_filter_mode(samplerState.filter());
+ desc.mipmapFilter = dawn::FilterMode::Linear;
+ desc.lodMinClamp = 0.0f;
+ desc.lodMaxClamp = 1000.0f;
+ desc.compare = dawn::CompareFunction::Never;
+ dawn::Sampler sampler = device().CreateSampler(&desc);
+ fSamplers.insert(std::pair<GrSamplerState, dawn::Sampler>(samplerState, sampler));
+ return sampler;
+}
+
GrDawnRingBuffer::Slice GrDawnGpu::allocateUniformRingBufferSlice(int size) {
return fUniformRingBuffer.allocate(size);
}
diff --git a/src/gpu/dawn/GrDawnGpu.h b/src/gpu/dawn/GrDawnGpu.h
index 059fd38..999fa7b 100644
--- a/src/gpu/dawn/GrDawnGpu.h
+++ b/src/gpu/dawn/GrDawnGpu.h
@@ -14,6 +14,8 @@
#include "src/gpu/dawn/GrDawnRingBuffer.h"
#include "src/gpu/dawn/GrDawnStagingManager.h"
+#include <unordered_map>
+
class GrDawnOpsRenderPass;
class GrPipeline;
struct GrDawnProgram;
@@ -94,6 +96,8 @@
bool hasPoints,
GrPrimitiveType primitiveType);
+ dawn::Sampler getOrCreateSampler(const GrSamplerState& samplerState);
+
GrDawnRingBuffer::Slice allocateUniformRingBufferSlice(int size);
GrDawnStagingBuffer* getStagingBuffer(size_t size);
GrDawnStagingManager* getStagingManager() { return &fStagingManager; }
@@ -175,7 +179,14 @@
}
};
+ struct SamplerHash {
+ size_t operator()(const GrSamplerState& samplerState) const {
+ return SkOpts::hash_fn(&samplerState, sizeof(samplerState), 0);
+ }
+ };
+
SkLRUCache<GrProgramDesc, sk_sp<GrDawnProgram>, ProgramDescHash> fRenderPipelineCache;
+ std::unordered_map<GrSamplerState, dawn::Sampler, SamplerHash> fSamplers;
GrDawnStagingManager fStagingManager;
typedef GrGpu INHERITED;
diff --git a/src/gpu/dawn/GrDawnProgramBuilder.cpp b/src/gpu/dawn/GrDawnProgramBuilder.cpp
index 30661b1..7e2f7cc 100644
--- a/src/gpu/dawn/GrDawnProgramBuilder.cpp
+++ b/src/gpu/dawn/GrDawnProgramBuilder.cpp
@@ -151,35 +151,6 @@
}
}
-static dawn::FilterMode to_dawn_filter_mode(GrSamplerState::Filter filter) {
- switch (filter) {
- case GrSamplerState::Filter::kNearest:
- return dawn::FilterMode::Nearest;
- case GrSamplerState::Filter::kBilerp:
- case GrSamplerState::Filter::kMipMap:
- return dawn::FilterMode::Linear;
- default:
- SkASSERT(!"unsupported filter mode");
- return dawn::FilterMode::Nearest;
- }
-}
-
-static dawn::AddressMode to_dawn_address_mode(GrSamplerState::WrapMode wrapMode) {
- switch (wrapMode) {
- case GrSamplerState::WrapMode::kClamp:
- return dawn::AddressMode::ClampToEdge;
- case GrSamplerState::WrapMode::kClampToBorder:
- // TODO: unsupported
- return dawn::AddressMode::ClampToEdge;
- case GrSamplerState::WrapMode::kRepeat:
- return dawn::AddressMode::Repeat;
- case GrSamplerState::WrapMode::kMirrorRepeat:
- return dawn::AddressMode::MirrorRepeat;
- }
- SkASSERT(!"unsupported address mode");
- return dawn::AddressMode::ClampToEdge;
-}
-
static dawn::PrimitiveTopology to_dawn_primitive_topology(GrPrimitiveType primitiveType) {
switch (primitiveType) {
case GrPrimitiveType::kTriangles:
@@ -281,19 +252,6 @@
return state;
}
-static dawn::Sampler create_sampler(const GrDawnGpu* gpu, const GrSamplerState& samplerState) {
- dawn::SamplerDescriptor desc;
- desc.addressModeU = to_dawn_address_mode(samplerState.wrapModeX());
- desc.addressModeV = to_dawn_address_mode(samplerState.wrapModeY());
- desc.addressModeW = dawn::AddressMode::ClampToEdge;
- desc.magFilter = desc.minFilter = to_dawn_filter_mode(samplerState.filter());
- desc.mipmapFilter = dawn::FilterMode::Linear;
- desc.lodMinClamp = 0.0f;
- desc.lodMaxClamp = 1000.0f;
- desc.compare = dawn::CompareFunction::Never;
- return gpu->device().CreateSampler(&desc);
-}
-
static dawn::BindGroupBinding make_bind_group_binding(uint32_t binding, const dawn::Buffer& buffer,
uint32_t offset, uint32_t size, const
dawn::Sampler& sampler,
@@ -530,7 +488,7 @@
static void setTexture(GrDawnGpu* gpu, const GrSamplerState& state, GrTexture* texture,
std::vector<dawn::BindGroupBinding> *bindings, int* binding) {
// FIXME: could probably cache samplers in GrDawnProgram
- dawn::Sampler sampler = create_sampler(gpu, state);
+ dawn::Sampler sampler = gpu->getOrCreateSampler(state);
bindings->push_back(make_bind_group_binding((*binding)++, sampler));
GrDawnTexture* tex = static_cast<GrDawnTexture*>(texture);
dawn::TextureView textureView = tex->textureView();
diff --git a/src/gpu/dawn/GrDawnProgramDataManager.cpp b/src/gpu/dawn/GrDawnProgramDataManager.cpp
index 573cb98..db22f25 100644
--- a/src/gpu/dawn/GrDawnProgramDataManager.cpp
+++ b/src/gpu/dawn/GrDawnProgramDataManager.cpp
@@ -18,6 +18,8 @@
, fFragmentUniformsDirty(false) {
fGeometryUniformData.reset(geometryUniformSize);
fFragmentUniformData.reset(fragmentUniformSize);
+ memset(fGeometryUniformData.get(), 0, fGeometryUniformSize);
+ memset(fFragmentUniformData.get(), 0, fFragmentUniformSize);
int count = uniforms.count();
fUniforms.push_back_n(count);
// We must add uniforms in same order is the UniformInfoArray so that UniformHandles already