API CHANGE: honor user-defined precision, rename SamplerPrecision. (#4287)

* API CHANGE: honor user-defined precision, rename SamplerPrecision.

matc now honors 'precision' on non-samplers in mat files, and
the filamat API now allows clients to specify precision for
non-samplers.

This involved flattening a union that is internal to filamat.

* MaterialBuilder: Add Java bindings for precision.
This commit is contained in:
Philip Rideout
2021-07-09 17:32:08 -07:00
committed by GitHub
parent 0c244bc2ac
commit 0a2fa36d5a
9 changed files with 107 additions and 79 deletions

View File

@@ -3,7 +3,7 @@
This file contains one line summaries of commits that are worthy of mentioning in release notes.
A new header is inserted each time a *tag* is created.
## v1.10.8 (currently main branch)
## v1.11.0 (currently main branch)
- engine: Added support for transparent shadows. Add `transparentShadow : true` in the material file.
- java: Removed support for Java desktop targets (macOS, Linux, and Windows) [⚠️ **API Change**].

View File

@@ -123,19 +123,22 @@ Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderInterpo
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderUniformParameter(
JNIEnv* env, jclass, jlong nativeBuilder, jint uniformType, jstring name_) {
JNIEnv* env, jclass, jlong nativeBuilder, jint uniformType, jstring name_, jint precision) {
auto builder = (MaterialBuilder*) nativeBuilder;
const char* name = env->GetStringUTFChars(name_, nullptr);
builder->parameter((MaterialBuilder::UniformType) uniformType, name);
builder->parameter((MaterialBuilder::UniformType) uniformType, name,
(MaterialBuilder::ParameterPrecision) precision);
env->ReleaseStringUTFChars(name_, name);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderUniformParameterArray(
JNIEnv* env, jclass, jlong nativeBuilder, jint uniformType, jint size, jstring name_) {
JNIEnv* env, jclass, jlong nativeBuilder, jint uniformType, jint size, jstring name_,
jint precision) {
auto builder = (MaterialBuilder*) nativeBuilder;
const char* name = env->GetStringUTFChars(name_, nullptr);
builder->parameter((MaterialBuilder::UniformType) uniformType, (size_t) size, name);
builder->parameter((MaterialBuilder::UniformType) uniformType, (size_t) size, name,
(MaterialBuilder::ParameterPrecision) precision);
env->ReleaseStringUTFChars(name_, name);
}
@@ -146,7 +149,7 @@ Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderSampler
auto builder = (MaterialBuilder*) nativeBuilder;
const char* name = env->GetStringUTFChars(name_, nullptr);
builder->parameter((MaterialBuilder::SamplerType) samplerType,
(MaterialBuilder::SamplerFormat) format, (MaterialBuilder::SamplerPrecision) precision,
(MaterialBuilder::SamplerFormat) format, (MaterialBuilder::ParameterPrecision) precision,
name);
env->ReleaseStringUTFChars(name_, name);
}

View File

@@ -91,7 +91,7 @@ public class MaterialBuilder {
SHADOW
}
public enum SamplerPrecision {
public enum ParameterPrecision {
LOW,
MEDIUM,
HIGH,
@@ -247,19 +247,36 @@ public class MaterialBuilder {
@NonNull
public MaterialBuilder uniformParameter(@NonNull UniformType type, String name) {
nMaterialBuilderUniformParameter(mNativeObject, type.ordinal(), name);
nMaterialBuilderUniformParameter(mNativeObject, type.ordinal(), name,
ParameterPrecision.DEFAULT.ordinal());
return this;
}
@NonNull
public MaterialBuilder uniformParameter(@NonNull UniformType type, String name,
ParameterPrecision precision) {
nMaterialBuilderUniformParameter(mNativeObject, type.ordinal(), name, precision.ordinal());
return this;
}
@NonNull
public MaterialBuilder uniformParameterArray(@NonNull UniformType type, int size, String name) {
nMaterialBuilderUniformParameterArray(mNativeObject, type.ordinal(), size, name);
nMaterialBuilderUniformParameterArray(mNativeObject, type.ordinal(), size, name,
ParameterPrecision.DEFAULT.ordinal());
return this;
}
@NonNull
public MaterialBuilder uniformParameterArray(@NonNull UniformType type, int size, String name,
ParameterPrecision precision) {
nMaterialBuilderUniformParameterArray(mNativeObject, type.ordinal(), size, name,
precision.ordinal());
return this;
}
@NonNull
public MaterialBuilder samplerParameter(@NonNull SamplerType type, SamplerFormat format,
SamplerPrecision precision, String name) {
ParameterPrecision precision, String name) {
nMaterialBuilderSamplerParameter(
mNativeObject, type.ordinal(), format.ordinal(), precision.ordinal(), name);
return this;
@@ -535,9 +552,9 @@ public class MaterialBuilder {
private static native void nMaterialBuilderShading(long nativeBuilder, int shading);
private static native void nMaterialBuilderInterpolation(long nativeBuilder, int interpolation);
private static native void nMaterialBuilderUniformParameter(long nativeBuilder, int type,
String name);
String name, int precision);
private static native void nMaterialBuilderUniformParameterArray(long nativeBuilder, int type,
int size, String name);
int size, String name, int precision);
private static native void nMaterialBuilderSamplerParameter(long nativeBuilder, int type,
int format, int precision, String name);
private static native void nMaterialBuilderVariable(long nativeBuilder, int variable,

View File

@@ -959,7 +959,9 @@ Type
Value
: Each entry is an object with the properties `name` and `type`, both of `string` type. The
name must be a valid GLSL identifier. The type must be one of the types described in
name must be a valid GLSL identifier. Entries also have an optional `precision`, which can be
one of `default` (best precision for the platform, typically `high` on desktop, `medium` on
mobile), `low`, `medium`, `high`. The type must be one of the types described in
table [materialParamsTypes].
Type | Description
@@ -988,10 +990,8 @@ samplerCubemap | Cubemap texture
[Table [materialParamsTypes]: Material parameter types]
Samplers
: Sampler types can also specify a `format` (defaults to `float`) and a `precision` (defaults
to `default`). The format can be one of `int`, `float`. The precision can be one of `default`
(best precision for the platform, typically `high` on desktop, `medium` on mobile),
`low`, `medium`, `high`.
: Sampler types can also specify a `format` which can be either `int` or `float` (defaults to
`float`).
Arrays
: A parameter can define an array of values by appending `[size]` after the type name, where

View File

@@ -30,7 +30,7 @@ using UniformType = MaterialBuilder::UniformType;
using SamplerType = MaterialBuilder::SamplerType;
using SubpassType = MaterialBuilder::SubpassType;
using SamplerFormat = MaterialBuilder::SamplerFormat;
using SamplerPrecision = MaterialBuilder::SamplerPrecision;
using ParameterPrecision = MaterialBuilder::ParameterPrecision;
using OutputTarget = MaterialBuilder::OutputTarget;
using OutputQualifier = MaterialBuilder::VariableQualifier;
using OutputType = MaterialBuilder::OutputType;
@@ -73,7 +73,7 @@ private:
static std::unordered_map<std::string, SamplerType> mStringToSamplerType;
static std::unordered_map<std::string, SubpassType> mStringToSubpassType;
static std::unordered_map<std::string, SamplerFormat> mStringToSamplerFormat;
static std::unordered_map<std::string, SamplerPrecision> mStringToSamplerPrecision;
static std::unordered_map<std::string, ParameterPrecision> mStringToSamplerPrecision;
static std::unordered_map<std::string, OutputTarget> mStringToOutputTarget;
static std::unordered_map<std::string, OutputQualifier> mStringToOutputQualifier;
static std::unordered_map<std::string, OutputType> mStringToOutputType;

View File

@@ -203,7 +203,7 @@ public:
using SamplerType = filament::backend::SamplerType;
using SubpassType = filament::backend::SubpassType;
using SamplerFormat = filament::backend::SamplerFormat;
using SamplerPrecision = filament::backend::Precision;
using ParameterPrecision = filament::backend::Precision;
using CullingMode = filament::backend::CullingMode;
enum class VariableQualifier : uint8_t {
@@ -244,10 +244,12 @@ public:
MaterialBuilder& interpolation(Interpolation interpolation) noexcept;
//! Add a parameter (i.e., a uniform) to this material.
MaterialBuilder& parameter(UniformType type, const char* name) noexcept;
MaterialBuilder& parameter(UniformType type, const char* name,
ParameterPrecision precision = ParameterPrecision::DEFAULT) noexcept;
//! Add a parameter array to this material.
MaterialBuilder& parameter(UniformType type, size_t size, const char* name) noexcept;
MaterialBuilder& parameter(UniformType type, size_t size, const char* name,
ParameterPrecision precision = ParameterPrecision::DEFAULT) noexcept;
/**
* Add a sampler parameter to this material.
@@ -255,14 +257,14 @@ public:
* When SamplerType::SAMPLER_EXTERNAL is specifed, format and precision are ignored.
*/
MaterialBuilder& parameter(SamplerType samplerType, SamplerFormat format,
SamplerPrecision precision, const char* name) noexcept;
/// @copydoc parameter(SamplerType, SamplerFormat, SamplerPrecision, const char*)
ParameterPrecision precision, const char* name) noexcept;
/// @copydoc parameter(SamplerType, SamplerFormat, ParameterPrecision, const char*)
MaterialBuilder& parameter(SamplerType samplerType, SamplerFormat format,
const char* name) noexcept;
/// @copydoc parameter(SamplerType, SamplerFormat, SamplerPrecision, const char*)
MaterialBuilder& parameter(SamplerType samplerType, SamplerPrecision precision,
/// @copydoc parameter(SamplerType, SamplerFormat, ParameterPrecision, const char*)
MaterialBuilder& parameter(SamplerType samplerType, ParameterPrecision precision,
const char* name) noexcept;
/// @copydoc parameter(SamplerType, SamplerFormat, SamplerPrecision, const char*)
/// @copydoc parameter(SamplerType, SamplerFormat, ParameterPrecision, const char*)
MaterialBuilder& parameter(SamplerType samplerType, const char* name) noexcept;
//! Custom variables (all float4).
@@ -525,37 +527,36 @@ public:
/**
* Add a subpass parameter to this material.
*/
MaterialBuilder& parameter(SubpassType subpassType, SamplerFormat format, SamplerPrecision
MaterialBuilder& parameter(SubpassType subpassType, SamplerFormat format, ParameterPrecision
precision, const char* name) noexcept;
MaterialBuilder& parameter(SubpassType subpassType, SamplerFormat format, const char* name)
noexcept;
MaterialBuilder& parameter(SubpassType subpassType, SamplerPrecision precision,
MaterialBuilder& parameter(SubpassType subpassType, ParameterPrecision precision,
const char* name) noexcept;
MaterialBuilder& parameter(SubpassType subpassType, const char* name) noexcept;
struct Parameter {
Parameter() noexcept : parameterType(INVALID) {}
Parameter(const char* paramName, SamplerType t, SamplerFormat f, SamplerPrecision p)
: name(paramName), size(1), samplerType(t), format(f), precision(p),
parameterType(SAMPLER) { }
Parameter(const char* paramName, UniformType t, size_t typeSize)
: name(paramName), size(typeSize), uniformType(t), parameterType(UNIFORM) { }
Parameter(const char* paramName, SubpassType t, SamplerFormat f, SamplerPrecision p)
: name(paramName), size(1), subpassType(t), format(f), precision(p),
parameterType(SUBPASS) { }
// Sampler
Parameter(const char* paramName, SamplerType t, SamplerFormat f, ParameterPrecision p)
: name(paramName), size(1), precision(p), samplerType(t), format(f), parameterType(SAMPLER) { }
// Uniform
Parameter(const char* paramName, UniformType t, size_t typeSize, ParameterPrecision p)
: name(paramName), size(typeSize), uniformType(t), precision(p), parameterType(UNIFORM) { }
// Subpass
Parameter(const char* paramName, SubpassType t, SamplerFormat f, ParameterPrecision p)
: name(paramName), size(1), precision(p), subpassType(t), format(f), parameterType(SUBPASS) { }
utils::CString name;
size_t size;
union {
UniformType uniformType;
struct {
union {
SamplerType samplerType;
SubpassType subpassType;
};
SamplerFormat format;
SamplerPrecision precision;
};
};
UniformType uniformType;
ParameterPrecision precision;
SamplerType samplerType;
SubpassType subpassType;
SamplerFormat format;
enum {
INVALID,
UNIFORM,

View File

@@ -104,15 +104,15 @@ std::unordered_map<std::string, SubpassType>& Enums::getMap<SubpassType>() noexc
return mStringToSubpassType;
};
std::unordered_map<std::string, SamplerPrecision> Enums::mStringToSamplerPrecision = {
{ "default", SamplerPrecision::DEFAULT },
{ "low", SamplerPrecision::LOW },
{ "medium", SamplerPrecision::MEDIUM },
{ "high", SamplerPrecision::HIGH },
std::unordered_map<std::string, ParameterPrecision> Enums::mStringToSamplerPrecision = {
{ "default", ParameterPrecision::DEFAULT },
{ "low", ParameterPrecision::LOW },
{ "medium", ParameterPrecision::MEDIUM },
{ "high", ParameterPrecision::HIGH },
};
template <>
std::unordered_map<std::string, SamplerPrecision>& Enums::getMap<SamplerPrecision>() noexcept {
std::unordered_map<std::string, ParameterPrecision>& Enums::getMap<ParameterPrecision>() noexcept {
return mStringToSamplerPrecision;
};

View File

@@ -180,27 +180,29 @@ MaterialBuilder& MaterialBuilder::variable(Variable v, const char* name) noexcep
return *this;
}
MaterialBuilder& MaterialBuilder::parameter(UniformType type, const char* name) noexcept {
MaterialBuilder& MaterialBuilder::parameter(
UniformType type, const char* name, ParameterPrecision precision) noexcept {
ASSERT_POSTCONDITION(mParameterCount < MAX_PARAMETERS_COUNT, "Too many parameters");
mParameters[mParameterCount++] = { name, type, 1 };
return *this;
}
MaterialBuilder& MaterialBuilder::parameter(UniformType type, size_t size, const char* name) noexcept {
ASSERT_POSTCONDITION(mParameterCount < MAX_PARAMETERS_COUNT, "Too many parameters");
mParameters[mParameterCount++] = { name, type, size };
mParameters[mParameterCount++] = { name, type, 1, precision };
return *this;
}
MaterialBuilder& MaterialBuilder::parameter(
SamplerType samplerType, SamplerFormat format, SamplerPrecision precision, const char* name) noexcept {
UniformType type, size_t size, const char* name, ParameterPrecision precision) noexcept {
ASSERT_POSTCONDITION(mParameterCount < MAX_PARAMETERS_COUNT, "Too many parameters");
mParameters[mParameterCount++] = { name, type, size, precision };
return *this;
}
MaterialBuilder& MaterialBuilder::parameter(
SamplerType samplerType, SamplerFormat format, ParameterPrecision precision, const char* name) noexcept {
ASSERT_POSTCONDITION(mParameterCount < MAX_PARAMETERS_COUNT, "Too many parameters");
mParameters[mParameterCount++] = { name, samplerType, format, precision };
return *this;
}
MaterialBuilder& MaterialBuilder::parameter(SubpassType subpassType, SamplerFormat format,
SamplerPrecision precision, const char* name) noexcept {
ParameterPrecision precision, const char* name) noexcept {
ASSERT_PRECONDITION(format == SamplerFormat::FLOAT,
"Subpass parameters must have FLOAT format.");
@@ -215,31 +217,31 @@ MaterialBuilder& MaterialBuilder::parameter(SubpassType subpassType, SamplerForm
MaterialBuilder& MaterialBuilder::parameter(
SamplerType samplerType, SamplerFormat format, const char* name) noexcept {
return parameter(samplerType, format, SamplerPrecision::DEFAULT, name);
return parameter(samplerType, format, ParameterPrecision::DEFAULT, name);
}
MaterialBuilder& MaterialBuilder::parameter(
SamplerType samplerType, SamplerPrecision precision, const char* name) noexcept {
SamplerType samplerType, ParameterPrecision precision, const char* name) noexcept {
return parameter(samplerType, SamplerFormat::FLOAT, precision, name);
}
MaterialBuilder& MaterialBuilder::parameter(
SamplerType samplerType, const char* name) noexcept {
return parameter(samplerType, SamplerFormat::FLOAT, SamplerPrecision::DEFAULT, name);
return parameter(samplerType, SamplerFormat::FLOAT, ParameterPrecision::DEFAULT, name);
}
MaterialBuilder& MaterialBuilder::parameter(SubpassType subpassType, SamplerFormat format,
const char* name) noexcept {
return parameter(subpassType, format, SamplerPrecision::DEFAULT, name);
return parameter(subpassType, format, ParameterPrecision::DEFAULT, name);
}
MaterialBuilder& MaterialBuilder::parameter(SubpassType subpassType, SamplerPrecision precision,
MaterialBuilder& MaterialBuilder::parameter(SubpassType subpassType, ParameterPrecision precision,
const char* name) noexcept {
return parameter(subpassType, SamplerFormat::FLOAT, precision, name);
}
MaterialBuilder& MaterialBuilder::parameter(SubpassType subpassType, const char* name) noexcept {
return parameter(subpassType, SamplerFormat::FLOAT, SamplerPrecision::DEFAULT, name);
return parameter(subpassType, SamplerFormat::FLOAT, ParameterPrecision::DEFAULT, name);
}
MaterialBuilder& MaterialBuilder::require(filament::VertexAttribute attribute) noexcept {
@@ -427,7 +429,7 @@ void MaterialBuilder::prepareToBuild(MaterialInfo& info) noexcept {
if (param.isSampler()) {
sbb.add(param.name, param.samplerType, param.format, param.precision);
} else if (param.isUniform()) {
ibb.add(param.name, param.size, param.uniformType);
ibb.add(param.name, param.size, param.uniformType, param.precision);
} else if (param.isSubpass()) {
// For now, we only support a single subpass for attachment 0.
// Subpasses blong to the "MaterialParams" block.

View File

@@ -149,8 +149,8 @@ static bool processParameter(MaterialBuilder& builder, const JsonishObject& json
}
auto precisionString = precisionValue->toJsonString();
if (!Enums::isValid<SamplerPrecision>(precisionString->getString())){
return logEnumIssue("parameters", *precisionString, Enums::map<SamplerPrecision>());
if (!Enums::isValid<ParameterPrecision>(precisionString->getString())){
return logEnumIssue("parameters", *precisionString, Enums::map<ParameterPrecision>());
}
}
@@ -174,10 +174,15 @@ static bool processParameter(MaterialBuilder& builder, const JsonishObject& json
if (Enums::isValid<UniformType>(typeString)) {
MaterialBuilder::UniformType type = Enums::toEnum<UniformType>(typeString);
ParameterPrecision precision = ParameterPrecision::DEFAULT;
if (precisionValue) {
precision =
Enums::toEnum<ParameterPrecision>(precisionValue->toJsonString()->getString());
}
if (arraySize == 0) {
builder.parameter(type, nameString.c_str());
builder.parameter(type, nameString.c_str(), precision);
} else {
builder.parameter(type, arraySize, nameString.c_str());
builder.parameter(type, arraySize, nameString.c_str(), precision);
}
} else if (Enums::isValid<SamplerType>(typeString)) {
if (arraySize > 0) {
@@ -191,14 +196,14 @@ static bool processParameter(MaterialBuilder& builder, const JsonishObject& json
if (precisionValue && formatValue) {
auto format = Enums::toEnum<SamplerFormat>(formatValue->toJsonString()->getString());
auto precision =
Enums::toEnum<SamplerPrecision>(precisionValue->toJsonString()->getString());
Enums::toEnum<ParameterPrecision>(precisionValue->toJsonString()->getString());
builder.parameter(type, format, precision, nameString.c_str());
} else if (formatValue) {
auto format = Enums::toEnum<SamplerFormat>(formatValue->toJsonString()->getString());
builder.parameter(type, format, nameString.c_str());
} else if (precisionValue) {
auto precision =
Enums::toEnum<SamplerPrecision>(precisionValue->toJsonString()->getString());
Enums::toEnum<ParameterPrecision>(precisionValue->toJsonString()->getString());
builder.parameter(type, precision, nameString.c_str());
} else {
builder.parameter(type, nameString.c_str());
@@ -215,14 +220,14 @@ static bool processParameter(MaterialBuilder& builder, const JsonishObject& json
if (precisionValue && formatValue) {
auto format = Enums::toEnum<SamplerFormat>(formatValue->toJsonString()->getString());
auto precision =
Enums::toEnum<SamplerPrecision>(precisionValue->toJsonString()->getString());
Enums::toEnum<ParameterPrecision>(precisionValue->toJsonString()->getString());
builder.parameter(type, format, precision, nameString.c_str());
} else if (formatValue) {
auto format = Enums::toEnum<SamplerFormat>(formatValue->toJsonString()->getString());
builder.parameter(type, format, nameString.c_str());
} else if (precisionValue) {
auto precision =
Enums::toEnum<SamplerPrecision>(precisionValue->toJsonString()->getString());
Enums::toEnum<ParameterPrecision>(precisionValue->toJsonString()->getString());
builder.parameter(type, precision, nameString.c_str());
} else {
builder.parameter(type, nameString.c_str());