Fix overridable constants

dawn:
* Zero-initialize the SpecializationDataEntry. For booleans, the first
  byte may be initialized, while the 3 other bytes may contain garbage.
  This can cause boolean specializations to be 'true' when 'false' was
  specified.

dawn_node:
* Implement conversion of GPUProgrammableStage's constants.
* Fix Napi::Object -> unordered_map conversion.
* Fix member name in error messages generated by
  'DictionaryMembersFromJS'

Bug: dawn:1041
Change-Id: I016ec4916fc73226dfe1bd8e7dc52a1e88e46a6b
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/67383
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Commit-Queue: Ben Clayton <bclayton@google.com>
This commit is contained in:
Ben Clayton 2021-10-26 10:40:46 +00:00 committed by Dawn LUCI CQ
parent f4c8a6ac9b
commit 9b92a7cbc2
5 changed files with 55 additions and 7 deletions

View File

@ -227,7 +227,7 @@ namespace dawn_native { namespace vulkan {
sizeof(SpecializationDataEntry)),
sizeof(SpecializationDataEntry)});
SpecializationDataEntry entry;
SpecializationDataEntry entry{};
switch (moduleConstant.type) {
case EntryPointMetadata::OverridableConstant::Type::Boolean:
entry.b = static_cast<bool>(value);

View File

@ -422,6 +422,14 @@ namespace wgpu { namespace binding {
out = {};
out.entryPoint = in.entryPoint.c_str();
out.module = *in.module.As<GPUShaderModule>();
return Convert(out.constants, out.constantCount, in.constants);
}
bool Converter::Convert(wgpu::ConstantEntry& out,
const std::string& in_name,
wgpu::interop::GPUPipelineConstantValue in_value) {
out.key = in_name.c_str();
out.value = in_value;
return true;
}
@ -545,8 +553,10 @@ namespace wgpu { namespace binding {
bool Converter::Convert(wgpu::FragmentState& out, const interop::GPUFragmentState& in) {
out = {};
return Convert(out.targets, out.targetCount, in.targets) &&
Convert(out.module, in.module) && Convert(out.entryPoint, in.entryPoint);
return Convert(out.targets, out.targetCount, in.targets) && //
Convert(out.module, in.module) && //
Convert(out.entryPoint, in.entryPoint) && //
Convert(out.constants, out.constantCount, in.constants);
}
bool Converter::Convert(wgpu::PrimitiveTopology& out, const interop::GPUPrimitiveTopology& in) {
@ -698,7 +708,8 @@ namespace wgpu { namespace binding {
out = {};
return Convert(out.module, in.module) &&
Convert(out.buffers, out.bufferCount, in.buffers) &&
Convert(out.entryPoint, in.entryPoint);
Convert(out.entryPoint, in.entryPoint) &&
Convert(out.constants, out.constantCount, in.constants);
}
bool Converter::Convert(wgpu::VertexStepMode& out, const interop::GPUVertexStepMode& in) {
@ -1135,7 +1146,8 @@ namespace wgpu { namespace binding {
Convert(out.vertex, in.vertex) && //
Convert(out.primitive, in.primitive) && //
Convert(out.depthStencil, in.depthStencil) && //
Convert(out.multisample, in.multisample) && Convert(out.fragment, in.fragment);
Convert(out.multisample, in.multisample) && //
Convert(out.fragment, in.fragment);
}
}} // namespace wgpu::binding

View File

@ -145,6 +145,10 @@ namespace wgpu { namespace binding {
[[nodiscard]] bool Convert(wgpu::ProgrammableStageDescriptor& out,
const interop::GPUProgrammableStage& in);
[[nodiscard]] bool Convert(wgpu::ConstantEntry& out,
const std::string& in_name,
wgpu::interop::GPUPipelineConstantValue in_value);
[[nodiscard]] bool Convert(wgpu::BlendComponent& out, const interop::GPUBlendComponent& in);
[[nodiscard]] bool Convert(wgpu::BlendFactor& out, const interop::GPUBlendFactor& in);
@ -343,6 +347,38 @@ namespace wgpu { namespace binding {
return Convert(out_count, in.size());
}
// unordered_map -> raw pointer + count
template <typename OUT, typename IN_KEY, typename IN_VALUE>
inline bool Convert(OUT*& out_els,
uint32_t& out_count,
const std::unordered_map<IN_KEY, IN_VALUE>& in) {
if (in.size() == 0) {
out_els = nullptr;
out_count = 0;
return true;
}
auto* els = Allocate<std::remove_const_t<OUT>>(in.size());
size_t i = 0;
for (auto& it : in) {
if (!Convert(els[i++], it.first, it.second)) {
return false;
}
}
out_els = els;
return Convert(out_count, in.size());
}
// std::optional<T> -> raw pointer + count
template <typename OUT, typename IN>
inline bool Convert(OUT*& out_els, uint32_t& out_count, const std::optional<IN>& in) {
if (!in.has_value()) {
out_els = nullptr;
out_count = 0;
return true;
}
return Convert(out_els, out_count, in.value());
}
Napi::Env env;
// Allocate() allocates and constructs an array of 'n' elements, and returns a pointer to

View File

@ -521,7 +521,7 @@ namespace wgpu { namespace interop {
auto obj = value.ToObject();
auto keys = obj.GetPropertyNames();
std::unordered_map<K, V> map(keys.Length());
for (uint32_t i = 0; i < static_cast<uint32_t>(map.size()); i++) {
for (uint32_t i = 0; i < static_cast<uint32_t>(keys.Length()); i++) {
K key{};
V value{};
auto key_res = Converter<K>::FromJS(env, keys[i], key);

View File

@ -287,7 +287,7 @@ std::ostream& operator<<(std::ostream& o, const {{$.Name}}& dict) {
{{- else }}res = interop::FromJS(env, object.Get("{{$m.Name}}"), out.{{$m.Name}});
{{- end }}
if (!res) {
return res.Append("while converting member '{{$.Name}}'");
return res.Append("while converting member '{{$m.Name}}'");
}
{{- end}}
{{- end}}