Files
test/source/blender/compositor/cached_resources/intern/cached_shader.cc

101 lines
2.6 KiB
C++

/* SPDX-FileCopyrightText: 2023 Blender Authors
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#include <cstdint>
#include <memory>
#include <string>
#include "BLI_hash.hh"
#include "GPU_shader.hh"
#include "COM_cached_shader.hh"
#include "COM_result.hh"
#include "gpu_shader_create_info.hh"
namespace blender::compositor {
/* --------------------------------------------------------------------
* Cached Shader Key.
*/
CachedShaderKey::CachedShaderKey(const char *info_name, ResultPrecision precision)
: info_name(info_name), precision(precision)
{
}
uint64_t CachedShaderKey::hash() const
{
return get_default_hash(info_name, precision);
}
bool operator==(const CachedShaderKey &a, const CachedShaderKey &b)
{
return a.info_name == b.info_name && a.precision == b.precision;
}
/* --------------------------------------------------------------------
* Cached Shader.
*/
CachedShader::CachedShader(const char *info_name, ResultPrecision precision)
{
using namespace gpu::shader;
ShaderCreateInfo info = *reinterpret_cast<const ShaderCreateInfo *>(
GPU_shader_create_info_get(info_name));
/* Finalize first in case the create info had additional info. */
info.finalize();
/* Change the format of image resource to the target precision. */
for (ShaderCreateInfo::Resource &resource : info.pass_resources_) {
if (resource.bind_type != ShaderCreateInfo::Resource::BindType::IMAGE) {
continue;
}
resource.image.format = Result::gpu_texture_format(resource.image.format, precision);
}
shader_ = GPU_shader_create_from_info(reinterpret_cast<const GPUShaderCreateInfo *>(&info));
}
CachedShader::~CachedShader()
{
GPU_shader_free(shader_);
}
GPUShader *CachedShader::shader() const
{
return shader_;
}
/* --------------------------------------------------------------------
* Cached Shader Container.
*/
void CachedShaderContainer::reset()
{
/* First, delete all resources that are no longer needed. */
map_.remove_if([](auto item) { return !item.value->needed; });
/* Second, reset the needed status of the remaining resources to false to ready them to track
* their needed status for the next evaluation. */
for (auto &value : map_.values()) {
value->needed = false;
}
}
GPUShader *CachedShaderContainer::get(const char *info_name, ResultPrecision precision)
{
const CachedShaderKey key(info_name, precision);
auto &cached_shader = *map_.lookup_or_add_cb(
key, [&]() { return std::make_unique<CachedShader>(info_name, precision); });
cached_shader.needed = true;
return cached_shader.shader();
}
} // namespace blender::compositor