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)),
sizeof(SpecializationDataEntry)}); sizeof(SpecializationDataEntry)});
SpecializationDataEntry entry; SpecializationDataEntry entry{};
switch (moduleConstant.type) { switch (moduleConstant.type) {
case EntryPointMetadata::OverridableConstant::Type::Boolean: case EntryPointMetadata::OverridableConstant::Type::Boolean:
entry.b = static_cast<bool>(value); entry.b = static_cast<bool>(value);

View File

@ -422,6 +422,14 @@ namespace wgpu { namespace binding {
out = {}; out = {};
out.entryPoint = in.entryPoint.c_str(); out.entryPoint = in.entryPoint.c_str();
out.module = *in.module.As<GPUShaderModule>(); 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; return true;
} }
@ -545,8 +553,10 @@ namespace wgpu { namespace binding {
bool Converter::Convert(wgpu::FragmentState& out, const interop::GPUFragmentState& in) { bool Converter::Convert(wgpu::FragmentState& out, const interop::GPUFragmentState& in) {
out = {}; out = {};
return Convert(out.targets, out.targetCount, in.targets) && return Convert(out.targets, out.targetCount, in.targets) && //
Convert(out.module, in.module) && Convert(out.entryPoint, in.entryPoint); 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) { bool Converter::Convert(wgpu::PrimitiveTopology& out, const interop::GPUPrimitiveTopology& in) {
@ -698,7 +708,8 @@ namespace wgpu { namespace binding {
out = {}; out = {};
return Convert(out.module, in.module) && return Convert(out.module, in.module) &&
Convert(out.buffers, out.bufferCount, in.buffers) && 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) { 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.vertex, in.vertex) && //
Convert(out.primitive, in.primitive) && // Convert(out.primitive, in.primitive) && //
Convert(out.depthStencil, in.depthStencil) && // 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 }} // namespace wgpu::binding

View File

@ -145,6 +145,10 @@ namespace wgpu { namespace binding {
[[nodiscard]] bool Convert(wgpu::ProgrammableStageDescriptor& out, [[nodiscard]] bool Convert(wgpu::ProgrammableStageDescriptor& out,
const interop::GPUProgrammableStage& in); 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::BlendComponent& out, const interop::GPUBlendComponent& in);
[[nodiscard]] bool Convert(wgpu::BlendFactor& out, const interop::GPUBlendFactor& 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()); 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; Napi::Env env;
// Allocate() allocates and constructs an array of 'n' elements, and returns a pointer to // 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 obj = value.ToObject();
auto keys = obj.GetPropertyNames(); auto keys = obj.GetPropertyNames();
std::unordered_map<K, V> map(keys.Length()); 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{}; K key{};
V value{}; V value{};
auto key_res = Converter<K>::FromJS(env, keys[i], key); 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}}); {{- else }}res = interop::FromJS(env, object.Get("{{$m.Name}}"), out.{{$m.Name}});
{{- end }} {{- end }}
if (!res) { if (!res) {
return res.Append("while converting member '{{$.Name}}'"); return res.Append("while converting member '{{$m.Name}}'");
} }
{{- end}} {{- end}}
{{- end}} {{- end}}