Realtime Compositor: Add utilities to handle texture formats

This patch adds a number of utilities to handle texture formats and
their relation to result types and precisions. This is needed for future
work, and also unifies the places one needs to update when adding a new
result type.
This commit is contained in:
Omar Emara
2023-11-30 15:21:56 +02:00
parent 14c2f6856a
commit b8f4c45638
3 changed files with 117 additions and 62 deletions

View File

@@ -15,8 +15,7 @@
namespace blender::realtime_compositor {
/* To add a new type, update the get_texture_format() and change_texture_format_precision()
* functions. */
/* To add a new type, update the format related static methods in the Result class. */
enum class ResultType : uint8_t {
/* The following types are user facing and can be used as inputs and outputs of operations. They
* either represent the base type of the result texture or a single value result. The color type
@@ -142,6 +141,15 @@ class Result {
/* Returns the appropriate texture format based on the given result type and precision. */
static eGPUTextureFormat texture_format(ResultType type, ResultPrecision precision);
/* Returns the texture format that corresponds to the give one, but with the given precision. */
static eGPUTextureFormat texture_format(eGPUTextureFormat format, ResultPrecision precision);
/* Returns the precision of the given format. */
static ResultPrecision precision(eGPUTextureFormat format);
/* Returns the type of the given format. */
static ResultType type(eGPUTextureFormat format);
/* Returns the appropriate texture format based on the result's type and precision. */
eGPUTextureFormat get_texture_format() const;

View File

@@ -41,65 +41,6 @@ bool operator==(const CachedShaderKey &a, const CachedShaderKey &b)
* Cached Shader.
*/
/* Given a texture format, return a corresponding texture format with the target precision. */
static eGPUTextureFormat change_texture_format_precision(eGPUTextureFormat format,
ResultPrecision target_precision)
{
switch (target_precision) {
case ResultPrecision::Half:
switch (format) {
/* Already half precision, return the input format. */
case GPU_R16F:
case GPU_RG16F:
case GPU_RGB16F:
case GPU_RGBA16F:
case GPU_RG16I:
return format;
case GPU_R32F:
return GPU_R16F;
case GPU_RG32F:
return GPU_RG16F;
case GPU_RGB32F:
return GPU_RGB16F;
case GPU_RGBA32F:
return GPU_RGBA16F;
case GPU_RG32I:
return GPU_RG16I;
default:
break;
}
break;
case ResultPrecision::Full:
switch (format) {
/* Already full precision, return the input format. */
case GPU_R32F:
case GPU_RG32F:
case GPU_RGB32F:
case GPU_RGBA32F:
case GPU_RG32I:
return format;
case GPU_R16F:
return GPU_R32F;
case GPU_RG16F:
return GPU_RG32F;
case GPU_RGB16F:
return GPU_RGB32F;
case GPU_RGBA16F:
return GPU_RGBA32F;
case GPU_RG16I:
return GPU_RG32I;
default:
break;
}
break;
}
BLI_assert_unreachable();
return format;
}
CachedShader::CachedShader(const char *info_name, ResultPrecision precision)
{
using namespace gpu::shader;
@@ -114,7 +55,7 @@ CachedShader::CachedShader(const char *info_name, ResultPrecision precision)
if (resource.bind_type != ShaderCreateInfo::Resource::BindType::IMAGE) {
continue;
}
resource.image.format = change_texture_format_precision(resource.image.format, precision);
resource.image.format = Result::texture_format(resource.image.format, precision);
}
shader_ = GPU_shader_create_from_info(reinterpret_cast<const GPUShaderCreateInfo *>(&info));

View File

@@ -68,6 +68,112 @@ eGPUTextureFormat Result::texture_format(ResultType type, ResultPrecision precis
return GPU_RGBA32F;
}
eGPUTextureFormat Result::texture_format(eGPUTextureFormat format, ResultPrecision precision)
{
switch (precision) {
case ResultPrecision::Half:
switch (format) {
/* Already half precision, return the input format. */
case GPU_R16F:
case GPU_RG16F:
case GPU_RGB16F:
case GPU_RGBA16F:
case GPU_RG16I:
return format;
case GPU_R32F:
return GPU_R16F;
case GPU_RG32F:
return GPU_RG16F;
case GPU_RGB32F:
return GPU_RGB16F;
case GPU_RGBA32F:
return GPU_RGBA16F;
case GPU_RG32I:
return GPU_RG16I;
default:
break;
}
break;
case ResultPrecision::Full:
switch (format) {
/* Already full precision, return the input format. */
case GPU_R32F:
case GPU_RG32F:
case GPU_RGB32F:
case GPU_RGBA32F:
case GPU_RG32I:
return format;
case GPU_R16F:
return GPU_R32F;
case GPU_RG16F:
return GPU_RG32F;
case GPU_RGB16F:
return GPU_RGB32F;
case GPU_RGBA16F:
return GPU_RGBA32F;
case GPU_RG16I:
return GPU_RG32I;
default:
break;
}
break;
}
BLI_assert_unreachable();
return format;
}
ResultPrecision Result::precision(eGPUTextureFormat format)
{
switch (format) {
case GPU_R16F:
case GPU_RG16F:
case GPU_RGB16F:
case GPU_RGBA16F:
case GPU_RG16I:
return ResultPrecision::Half;
case GPU_R32F:
case GPU_RG32F:
case GPU_RGB32F:
case GPU_RGBA32F:
case GPU_RG32I:
return ResultPrecision::Full;
default:
break;
}
BLI_assert_unreachable();
return ResultPrecision::Full;
}
ResultType Result::type(eGPUTextureFormat format)
{
switch (format) {
case GPU_R16F:
case GPU_R32F:
return ResultType::Float;
case GPU_RG16F:
case GPU_RG32F:
return ResultType::Float2;
case GPU_RGB16F:
case GPU_RGB32F:
return ResultType::Float3;
case GPU_RGBA16F:
case GPU_RGBA32F:
return ResultType::Color;
case GPU_RG16I:
case GPU_RG32I:
return ResultType::Int2;
default:
break;
}
BLI_assert_unreachable();
return ResultType::Color;
}
eGPUTextureFormat Result::get_texture_format() const
{
return Result::texture_format(type_, precision_);