Add a cache of GrVkSamplers in GrVkResourceProvider.
BUG=skia: GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1765523002 Review URL: https://codereview.chromium.org/1765523002
This commit is contained in:
parent
d3312595c8
commit
8b6394c24f
@ -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 GrPrimitiveProcessor& primProc,
|
||||||
const GrPipeline& pipeline) {
|
const GrPipeline& pipeline) {
|
||||||
// This is here to protect against someone calling setData multiple times in a row without
|
// 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) {
|
const SkTArray<const GrTextureAccess*>& textureBindings) {
|
||||||
SkASSERT(fNumSamplers == textureBindings.count());
|
SkASSERT(fNumSamplers == textureBindings.count());
|
||||||
|
|
||||||
for (int i = 0; i < textureBindings.count(); ++i) {
|
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());
|
GrVkTexture* texture = static_cast<GrVkTexture*>(textureBindings[i]->getTexture());
|
||||||
|
|
||||||
|
@ -33,7 +33,7 @@ public:
|
|||||||
|
|
||||||
GrVkPipeline* vkPipeline() const { return fPipeline; }
|
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);
|
void bind(const GrVkGpu* gpu, GrVkCommandBuffer* commandBuffer);
|
||||||
|
|
||||||
@ -68,7 +68,7 @@ private:
|
|||||||
|
|
||||||
void writeUniformBuffers(const GrVkGpu* gpu);
|
void writeUniformBuffers(const GrVkGpu* gpu);
|
||||||
|
|
||||||
void writeSamplers(const GrVkGpu* gpu, const SkTArray<const GrTextureAccess*>& textureBindings);
|
void writeSamplers(GrVkGpu* gpu, const SkTArray<const GrTextureAccess*>& textureBindings);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -7,9 +7,11 @@
|
|||||||
|
|
||||||
#include "GrVkResourceProvider.h"
|
#include "GrVkResourceProvider.h"
|
||||||
|
|
||||||
|
#include "GrTextureParams.h"
|
||||||
#include "GrVkCommandBuffer.h"
|
#include "GrVkCommandBuffer.h"
|
||||||
#include "GrVkPipeline.h"
|
#include "GrVkPipeline.h"
|
||||||
#include "GrVkRenderPass.h"
|
#include "GrVkRenderPass.h"
|
||||||
|
#include "GrVkSampler.h"
|
||||||
#include "GrVkUtil.h"
|
#include "GrVkUtil.h"
|
||||||
|
|
||||||
#ifdef SK_TRACE_VK_RESOURCES
|
#ifdef SK_TRACE_VK_RESOURCES
|
||||||
@ -81,6 +83,17 @@ GrVkDescriptorPool* GrVkResourceProvider::findOrCreateCompatibleDescriptorPool(
|
|||||||
return new GrVkDescriptorPool(fGpu, typeCounts);
|
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* GrVkResourceProvider::createCommandBuffer() {
|
||||||
GrVkCommandBuffer* cmdBuffer = GrVkCommandBuffer::Create(fGpu, fGpu->cmdPool());
|
GrVkCommandBuffer* cmdBuffer = GrVkCommandBuffer::Create(fGpu, fGpu->cmdPool());
|
||||||
fActiveCommandBuffers.push_back(cmdBuffer);
|
fActiveCommandBuffers.push_back(cmdBuffer);
|
||||||
@ -112,6 +125,13 @@ void GrVkResourceProvider::destroyResources() {
|
|||||||
}
|
}
|
||||||
fSimpleRenderPasses.reset();
|
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
|
#ifdef SK_TRACE_VK_RESOURCES
|
||||||
SkASSERT(0 == GrVkResource::fTrace.count());
|
SkASSERT(0 == GrVkResource::fTrace.count());
|
||||||
#endif
|
#endif
|
||||||
@ -133,6 +153,13 @@ void GrVkResourceProvider::abandonResources() {
|
|||||||
}
|
}
|
||||||
fSimpleRenderPasses.reset();
|
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
|
#ifdef SK_TRACE_VK_RESOURCES
|
||||||
SkASSERT(0 == GrVkResource::fTrace.count());
|
SkASSERT(0 == GrVkResource::fTrace.count());
|
||||||
#endif
|
#endif
|
||||||
|
@ -12,16 +12,19 @@
|
|||||||
#include "GrVkResource.h"
|
#include "GrVkResource.h"
|
||||||
#include "GrVkUtil.h"
|
#include "GrVkUtil.h"
|
||||||
#include "SkTArray.h"
|
#include "SkTArray.h"
|
||||||
|
#include "SkTDynamicHash.h"
|
||||||
|
|
||||||
#include "vulkan/vulkan.h"
|
#include "vulkan/vulkan.h"
|
||||||
|
|
||||||
class GrPipeline;
|
class GrPipeline;
|
||||||
class GrPrimitiveProcessor;
|
class GrPrimitiveProcessor;
|
||||||
|
class GrTextureParams;
|
||||||
class GrVkCommandBuffer;
|
class GrVkCommandBuffer;
|
||||||
class GrVkGpu;
|
class GrVkGpu;
|
||||||
class GrVkPipeline;
|
class GrVkPipeline;
|
||||||
class GrVkRenderPass;
|
class GrVkRenderPass;
|
||||||
class GrVkRenderTarget;
|
class GrVkRenderTarget;
|
||||||
|
class GrVkSampler;
|
||||||
|
|
||||||
class GrVkResourceProvider {
|
class GrVkResourceProvider {
|
||||||
public:
|
public:
|
||||||
@ -55,6 +58,10 @@ public:
|
|||||||
GrVkDescriptorPool* findOrCreateCompatibleDescriptorPool(
|
GrVkDescriptorPool* findOrCreateCompatibleDescriptorPool(
|
||||||
const GrVkDescriptorPool::DescriptorTypeCounts& typeCounts);
|
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.
|
// 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.
|
// 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
|
// 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
|
// Array of CommandBuffers that are currently in flight
|
||||||
SkSTArray<4, GrVkCommandBuffer*> fActiveCommandBuffers;
|
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
|
#endif
|
||||||
|
@ -23,7 +23,7 @@ static inline VkSamplerAddressMode tile_to_vk_sampler_address(SkShader::TileMode
|
|||||||
return gWrapModes[tm];
|
return gWrapModes[tm];
|
||||||
}
|
}
|
||||||
|
|
||||||
GrVkSampler* GrVkSampler::Create(const GrVkGpu* gpu, const GrTextureAccess& textureAccess) {
|
GrVkSampler* GrVkSampler::Create(const GrVkGpu* gpu, const GrTextureParams& params) {
|
||||||
|
|
||||||
static VkFilter vkMinFilterModes[] = {
|
static VkFilter vkMinFilterModes[] = {
|
||||||
VK_FILTER_NEAREST,
|
VK_FILTER_NEAREST,
|
||||||
@ -36,8 +36,6 @@ GrVkSampler* GrVkSampler::Create(const GrVkGpu* gpu, const GrTextureAccess& text
|
|||||||
VK_FILTER_LINEAR
|
VK_FILTER_LINEAR
|
||||||
};
|
};
|
||||||
|
|
||||||
const GrTextureParams& params = textureAccess.getParams();
|
|
||||||
|
|
||||||
VkSamplerCreateInfo createInfo;
|
VkSamplerCreateInfo createInfo;
|
||||||
memset(&createInfo, 0, sizeof(VkSamplerCreateInfo));
|
memset(&createInfo, 0, sizeof(VkSamplerCreateInfo));
|
||||||
createInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
|
createInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
|
||||||
@ -65,10 +63,24 @@ GrVkSampler* GrVkSampler::Create(const GrVkGpu* gpu, const GrTextureAccess& text
|
|||||||
nullptr,
|
nullptr,
|
||||||
&sampler));
|
&sampler));
|
||||||
|
|
||||||
return new GrVkSampler(sampler);
|
return new GrVkSampler(sampler, GenerateKey(params));
|
||||||
}
|
}
|
||||||
|
|
||||||
void GrVkSampler::freeGPUData(const GrVkGpu* gpu) const {
|
void GrVkSampler::freeGPUData(const GrVkGpu* gpu) const {
|
||||||
SkASSERT(fSampler);
|
SkASSERT(fSampler);
|
||||||
GR_VK_CALL(gpu->vkInterface(), DestroySampler(gpu->device(), fSampler, nullptr));
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -13,23 +13,31 @@
|
|||||||
#include "vulkan/vulkan.h"
|
#include "vulkan/vulkan.h"
|
||||||
|
|
||||||
class GrTextureAccess;
|
class GrTextureAccess;
|
||||||
|
class GrTextureParams;
|
||||||
class GrVkGpu;
|
class GrVkGpu;
|
||||||
|
|
||||||
|
|
||||||
class GrVkSampler : public GrVkResource {
|
class GrVkSampler : public GrVkResource {
|
||||||
public:
|
public:
|
||||||
static GrVkSampler* Create(const GrVkGpu* gpu, const GrTextureAccess& textureAccess);
|
static GrVkSampler* Create(const GrVkGpu* gpu, const GrTextureParams&);
|
||||||
|
|
||||||
VkSampler sampler() const { return fSampler; }
|
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:
|
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;
|
void freeGPUData(const GrVkGpu* gpu) const override;
|
||||||
|
|
||||||
VkSampler fSampler;
|
VkSampler fSampler;
|
||||||
|
uint8_t fKey;
|
||||||
|
|
||||||
typedef GrVkResource INHERITED;
|
typedef GrVkResource INHERITED;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user