aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu
diff options
context:
space:
mode:
authorGravatar egdaniel <egdaniel@google.com>2016-03-04 07:35:10 -0800
committerGravatar Commit bot <commit-bot@chromium.org>2016-03-04 07:35:10 -0800
commit8b6394c24f755db39936e4e5111a3f251cc56857 (patch)
treec9984ed5aae1a7a75fa2d3ec994e246ad2ecb944 /src/gpu
parentd3312595c86289113ea5994234844388523499e8 (diff)
Add a cache of GrVkSamplers in GrVkResourceProvider.
Diffstat (limited to 'src/gpu')
-rw-r--r--src/gpu/vk/GrVkProgram.cpp7
-rw-r--r--src/gpu/vk/GrVkProgram.h4
-rw-r--r--src/gpu/vk/GrVkResourceProvider.cpp27
-rw-r--r--src/gpu/vk/GrVkResourceProvider.h11
-rw-r--r--src/gpu/vk/GrVkSampler.cpp20
-rw-r--r--src/gpu/vk/GrVkSampler.h14
6 files changed, 71 insertions, 12 deletions
diff --git a/src/gpu/vk/GrVkProgram.cpp b/src/gpu/vk/GrVkProgram.cpp
index 0e1e201c2b..92adde86a9 100644
--- a/src/gpu/vk/GrVkProgram.cpp
+++ b/src/gpu/vk/GrVkProgram.cpp
@@ -163,7 +163,7 @@ static void append_texture_bindings(const GrProcessor& processor,
}
}
-void GrVkProgram::setData(const GrVkGpu* gpu,
+void GrVkProgram::setData(GrVkGpu* gpu,
const GrPrimitiveProcessor& primProc,
const GrPipeline& pipeline) {
// This is here to protect against someone calling setData multiple times in a row without
@@ -255,12 +255,13 @@ void GrVkProgram::writeUniformBuffers(const GrVkGpu* gpu) {
}
}
-void GrVkProgram::writeSamplers(const GrVkGpu* gpu,
+void GrVkProgram::writeSamplers(GrVkGpu* gpu,
const SkTArray<const GrTextureAccess*>& textureBindings) {
SkASSERT(fNumSamplers == textureBindings.count());
for (int i = 0; i < textureBindings.count(); ++i) {
- fSamplers.push(GrVkSampler::Create(gpu, *textureBindings[i]));
+ const GrTextureParams& params = textureBindings[i]->getParams();
+ fSamplers.push(gpu->resourceProvider().findOrCreateCompatibleSampler(params));
GrVkTexture* texture = static_cast<GrVkTexture*>(textureBindings[i]->getTexture());
diff --git a/src/gpu/vk/GrVkProgram.h b/src/gpu/vk/GrVkProgram.h
index e0477260e9..9b4eeb1e93 100644
--- a/src/gpu/vk/GrVkProgram.h
+++ b/src/gpu/vk/GrVkProgram.h
@@ -33,7 +33,7 @@ public:
GrVkPipeline* vkPipeline() const { return fPipeline; }
- void setData(const GrVkGpu*, const GrPrimitiveProcessor&, const GrPipeline&);
+ void setData(GrVkGpu*, const GrPrimitiveProcessor&, const GrPipeline&);
void bind(const GrVkGpu* gpu, GrVkCommandBuffer* commandBuffer);
@@ -68,7 +68,7 @@ private:
void writeUniformBuffers(const GrVkGpu* gpu);
- void writeSamplers(const GrVkGpu* gpu, const SkTArray<const GrTextureAccess*>& textureBindings);
+ void writeSamplers(GrVkGpu* gpu, const SkTArray<const GrTextureAccess*>& textureBindings);
/**
diff --git a/src/gpu/vk/GrVkResourceProvider.cpp b/src/gpu/vk/GrVkResourceProvider.cpp
index 19bda41525..b273e3b65d 100644
--- a/src/gpu/vk/GrVkResourceProvider.cpp
+++ b/src/gpu/vk/GrVkResourceProvider.cpp
@@ -7,9 +7,11 @@
#include "GrVkResourceProvider.h"
+#include "GrTextureParams.h"
#include "GrVkCommandBuffer.h"
#include "GrVkPipeline.h"
#include "GrVkRenderPass.h"
+#include "GrVkSampler.h"
#include "GrVkUtil.h"
#ifdef SK_TRACE_VK_RESOURCES
@@ -81,6 +83,17 @@ GrVkDescriptorPool* GrVkResourceProvider::findOrCreateCompatibleDescriptorPool(
return new GrVkDescriptorPool(fGpu, typeCounts);
}
+GrVkSampler* GrVkResourceProvider::findOrCreateCompatibleSampler(const GrTextureParams& params) {
+ GrVkSampler* sampler = fSamplers.find(GrVkSampler::GenerateKey(params));
+ if (!sampler) {
+ sampler = GrVkSampler::Create(fGpu, params);
+ fSamplers.add(sampler);
+ }
+ SkASSERT(sampler);
+ sampler->ref();
+ return sampler;
+}
+
GrVkCommandBuffer* GrVkResourceProvider::createCommandBuffer() {
GrVkCommandBuffer* cmdBuffer = GrVkCommandBuffer::Create(fGpu, fGpu->cmdPool());
fActiveCommandBuffers.push_back(cmdBuffer);
@@ -112,6 +125,13 @@ void GrVkResourceProvider::destroyResources() {
}
fSimpleRenderPasses.reset();
+ // Iterate through all store GrVkSamplers and unref them before resetting the hash.
+ SkTDynamicHash<GrVkSampler, uint8_t>::Iter iter(&fSamplers);
+ for (; !iter.done(); ++iter) {
+ (*iter).unref(fGpu);
+ }
+ fSamplers.reset();
+
#ifdef SK_TRACE_VK_RESOURCES
SkASSERT(0 == GrVkResource::fTrace.count());
#endif
@@ -133,6 +153,13 @@ void GrVkResourceProvider::abandonResources() {
}
fSimpleRenderPasses.reset();
+ // Iterate through all store GrVkSamplers and unrefAndAbandon them before resetting the hash.
+ SkTDynamicHash<GrVkSampler, uint8_t>::Iter iter(&fSamplers);
+ for (; !iter.done(); ++iter) {
+ (*iter).unrefAndAbandon();
+ }
+ fSamplers.reset();
+
#ifdef SK_TRACE_VK_RESOURCES
SkASSERT(0 == GrVkResource::fTrace.count());
#endif
diff --git a/src/gpu/vk/GrVkResourceProvider.h b/src/gpu/vk/GrVkResourceProvider.h
index 38d6c40187..a769a652d4 100644
--- a/src/gpu/vk/GrVkResourceProvider.h
+++ b/src/gpu/vk/GrVkResourceProvider.h
@@ -12,16 +12,19 @@
#include "GrVkResource.h"
#include "GrVkUtil.h"
#include "SkTArray.h"
+#include "SkTDynamicHash.h"
#include "vulkan/vulkan.h"
class GrPipeline;
class GrPrimitiveProcessor;
+class GrTextureParams;
class GrVkCommandBuffer;
class GrVkGpu;
class GrVkPipeline;
class GrVkRenderPass;
class GrVkRenderTarget;
+class GrVkSampler;
class GrVkResourceProvider {
public:
@@ -55,6 +58,10 @@ public:
GrVkDescriptorPool* findOrCreateCompatibleDescriptorPool(
const GrVkDescriptorPool::DescriptorTypeCounts& typeCounts);
+ // Finds or creates a compatible GrVkSampler based on the GrTextureParams.
+ // The refcount is incremented and a pointer returned.
+ GrVkSampler* findOrCreateCompatibleSampler(const GrTextureParams&);
+
// Destroy any cached resources. To be called before destroying the VkDevice.
// The assumption is that all queues are idle and all command buffers are finished.
// For resource tracing to work properly, this should be called after unrefing all other
@@ -78,6 +85,10 @@ private:
// Array of CommandBuffers that are currently in flight
SkSTArray<4, GrVkCommandBuffer*> fActiveCommandBuffers;
+
+ // Stores GrVkSampler objects that we've already created so we can reuse them across multiple
+ // programs
+ SkTDynamicHash<GrVkSampler, uint8_t> fSamplers;
};
#endif
diff --git a/src/gpu/vk/GrVkSampler.cpp b/src/gpu/vk/GrVkSampler.cpp
index 4bba66268b..9938340a84 100644
--- a/src/gpu/vk/GrVkSampler.cpp
+++ b/src/gpu/vk/GrVkSampler.cpp
@@ -23,7 +23,7 @@ static inline VkSamplerAddressMode tile_to_vk_sampler_address(SkShader::TileMode
return gWrapModes[tm];
}
-GrVkSampler* GrVkSampler::Create(const GrVkGpu* gpu, const GrTextureAccess& textureAccess) {
+GrVkSampler* GrVkSampler::Create(const GrVkGpu* gpu, const GrTextureParams& params) {
static VkFilter vkMinFilterModes[] = {
VK_FILTER_NEAREST,
@@ -36,8 +36,6 @@ GrVkSampler* GrVkSampler::Create(const GrVkGpu* gpu, const GrTextureAccess& text
VK_FILTER_LINEAR
};
- const GrTextureParams& params = textureAccess.getParams();
-
VkSamplerCreateInfo createInfo;
memset(&createInfo, 0, sizeof(VkSamplerCreateInfo));
createInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
@@ -65,10 +63,24 @@ GrVkSampler* GrVkSampler::Create(const GrVkGpu* gpu, const GrTextureAccess& text
nullptr,
&sampler));
- return new GrVkSampler(sampler);
+ return new GrVkSampler(sampler, GenerateKey(params));
}
void GrVkSampler::freeGPUData(const GrVkGpu* gpu) const {
SkASSERT(fSampler);
GR_VK_CALL(gpu->vkInterface(), DestroySampler(gpu->device(), fSampler, nullptr));
}
+
+uint8_t GrVkSampler::GenerateKey(const GrTextureParams& params) {
+
+ uint8_t key = params.filterMode();
+
+ SkASSERT(params.filterMode() <= 3);
+ key |= (params.getTileModeX() << 2);
+
+ GR_STATIC_ASSERT(SkShader::kTileModeCount <= 4);
+ key |= (params.getTileModeY() << 4);
+
+ return key;
+}
+
diff --git a/src/gpu/vk/GrVkSampler.h b/src/gpu/vk/GrVkSampler.h
index d3212cbc53..72181354eb 100644
--- a/src/gpu/vk/GrVkSampler.h
+++ b/src/gpu/vk/GrVkSampler.h
@@ -13,23 +13,31 @@
#include "vulkan/vulkan.h"
class GrTextureAccess;
+class GrTextureParams;
class GrVkGpu;
class GrVkSampler : public GrVkResource {
public:
- static GrVkSampler* Create(const GrVkGpu* gpu, const GrTextureAccess& textureAccess);
+ static GrVkSampler* Create(const GrVkGpu* gpu, const GrTextureParams&);
VkSampler sampler() const { return fSampler; }
+ // Helpers for hashing GrVkSampler
+ static uint8_t GenerateKey(const GrTextureParams&);
+
+ static const uint8_t& GetKey(const GrVkSampler& sampler) { return sampler.fKey; }
+ static uint32_t Hash(const uint8_t& key) { return key; }
private:
- GrVkSampler(VkSampler sampler) : INHERITED(), fSampler(sampler) {}
+ GrVkSampler(VkSampler sampler, uint8_t key) : INHERITED(), fSampler(sampler), fKey(key) {}
void freeGPUData(const GrVkGpu* gpu) const override;
VkSampler fSampler;
+ uint8_t fKey;
typedef GrVkResource INHERITED;
};
-#endif \ No newline at end of file
+#endif
+