• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "vertex_input_declaration_loader.h"
17 
18 #include <algorithm>
19 
20 #include <core/io/intf_file_manager.h>
21 #include <core/namespace.h>
22 #include <render/device/pipeline_state_desc.h>
23 
24 #include "json_format_serialization.h"
25 #include "json_util.h"
26 #include "util/log.h"
27 
28 using namespace BASE_NS;
29 using namespace CORE_NS;
30 
31 RENDER_BEGIN_NAMESPACE()
32 // clang-format off
33 RENDER_JSON_SERIALIZE_ENUM(VertexInputRate,
34     {
35         { CORE_VERTEX_INPUT_RATE_VERTEX, "vertex" },
36         { CORE_VERTEX_INPUT_RATE_INSTANCE, "instance" },
37     })
38 // clang-format on
FromJson(const json::value & jsonData,JsonContext<VertexInputDeclaration::VertexInputBindingDescription> & context)39 void FromJson(const json::value& jsonData, JsonContext<VertexInputDeclaration::VertexInputBindingDescription>& context)
40 {
41     SafeGetJsonValue(jsonData, "binding", context.error, context.data.binding);
42     SafeGetJsonValue(jsonData, "stride", context.error, context.data.stride);
43     SafeGetJsonEnum(jsonData, "vertexInputRate", context.error, context.data.vertexInputRate);
44 }
45 
FromJson(const json::value & jsonData,JsonContext<VertexInputDeclaration::VertexInputAttributeDescription> & context)46 void FromJson(
47     const json::value& jsonData, JsonContext<VertexInputDeclaration::VertexInputAttributeDescription>& context)
48 {
49     SafeGetJsonValue(jsonData, "location", context.error, context.data.location);
50     SafeGetJsonValue(jsonData, "binding", context.error, context.data.binding);
51     SafeGetJsonEnum(jsonData, "format", context.error, context.data.format);
52     SafeGetJsonValue(jsonData, "offset", context.error, context.data.offset);
53 }
54 
55 namespace {
LoadState(const json::value & jsonData,const string_view uri,VertexInputDeclarationData & vertexInputDeclarationData_,string & renderSlotName,bool & defaultRenderSlot)56 VertexInputDeclarationLoader::LoadResult LoadState(const json::value& jsonData, const string_view uri,
57     VertexInputDeclarationData& vertexInputDeclarationData_, string& renderSlotName, bool& defaultRenderSlot)
58 {
59     VertexInputDeclarationLoader::LoadResult result;
60 
61     SafeGetJsonValue(jsonData, "renderSlot", result.error, renderSlotName);
62     SafeGetJsonValue(jsonData, "renderSlotDefaultVertexInputDeclaration", result.error, defaultRenderSlot);
63     if (!defaultRenderSlot) {
64         SafeGetJsonValue(jsonData, "renderSlotDefault", result.error, defaultRenderSlot);
65     }
66 
67     vector<VertexInputDeclaration::VertexInputBindingDescription> bindings;
68     vector<VertexInputDeclaration::VertexInputAttributeDescription> attributes;
69 
70     ParseArray<decltype(bindings)::value_type>(jsonData, "vertexInputBindingDescriptions", bindings, result);
71     ParseArray<decltype(attributes)::value_type>(jsonData, "vertexInputAttributeDescriptions", attributes, result);
72 
73     if (result.success) {
74         PLUGIN_ASSERT(bindings.size() <= PipelineStateConstants::MAX_VERTEX_BUFFER_COUNT);
75         PLUGIN_ASSERT(attributes.size() <= PipelineStateConstants::MAX_VERTEX_BUFFER_COUNT);
76 
77         vertexInputDeclarationData_.bindingDescriptionCount =
78             std::min((uint32_t)bindings.size(), PipelineStateConstants::MAX_VERTEX_BUFFER_COUNT);
79         vertexInputDeclarationData_.attributeDescriptionCount =
80             std::min((uint32_t)attributes.size(), PipelineStateConstants::MAX_VERTEX_BUFFER_COUNT);
81 
82         for (uint32_t idx = 0; idx < vertexInputDeclarationData_.bindingDescriptionCount; ++idx) {
83             vertexInputDeclarationData_.bindingDescriptions[idx] = bindings[idx];
84         }
85         for (uint32_t idx = 0; idx < vertexInputDeclarationData_.attributeDescriptionCount; ++idx) {
86             vertexInputDeclarationData_.attributeDescriptions[idx] = attributes[idx];
87             if (vertexInputDeclarationData_.attributeDescriptions[idx].format == Format::BASE_FORMAT_UNDEFINED) {
88                 result.success = false;
89                 result.error += "undefined format for vertex input attribute\n";
90                 PLUGIN_LOG_E("undefined format in vertex input attribute (%u), in %s", idx, uri.data());
91             }
92         }
93     }
94 
95     return result;
96 }
97 
Load(const json::value & jsonData,const string_view uri,VertexInputDeclarationData & vertexInputDeclarationData,string & renderSlotName,bool & renderSlotDefault)98 VertexInputDeclarationLoader::LoadResult Load(const json::value& jsonData, const string_view uri,
99     VertexInputDeclarationData& vertexInputDeclarationData, string& renderSlotName, bool& renderSlotDefault)
100 {
101     VertexInputDeclarationLoader::LoadResult result;
102 
103     if (const json::value* stateIter = jsonData.find("vertexInputState"); stateIter) {
104         result = LoadState(*stateIter, uri, vertexInputDeclarationData, renderSlotName, renderSlotDefault);
105     } else {
106         result.error += "vertex input state not found\n";
107         result.success = false;
108     }
109 
110     return result;
111 }
112 } // namespace
113 
GetUri() const114 string_view VertexInputDeclarationLoader::GetUri() const
115 {
116     return uri_;
117 }
118 
GetVertexInputDeclarationView() const119 VertexInputDeclarationView VertexInputDeclarationLoader::GetVertexInputDeclarationView() const
120 {
121     return {
122         array_view<const VertexInputDeclaration::VertexInputBindingDescription>(
123             vertexInputDeclarationData_.bindingDescriptions, vertexInputDeclarationData_.bindingDescriptionCount),
124         array_view<const VertexInputDeclaration::VertexInputAttributeDescription>(
125             vertexInputDeclarationData_.attributeDescriptions, vertexInputDeclarationData_.attributeDescriptionCount),
126     };
127 }
128 
GetRenderSlot() const129 BASE_NS::string_view VertexInputDeclarationLoader::GetRenderSlot() const
130 {
131     return renderSlotName_;
132 }
133 
GetDefaultRenderSlot() const134 bool VertexInputDeclarationLoader::GetDefaultRenderSlot() const
135 {
136     return renderSlotDefaultVid_;
137 }
138 
Load(const string_view jsonString)139 VertexInputDeclarationLoader::LoadResult VertexInputDeclarationLoader::Load(const string_view jsonString)
140 {
141     VertexInputDeclarationLoader::LoadResult result;
142     const auto json = json::parse(jsonString.data());
143     if (json) {
144         result = RENDER_NS::Load(json, uri_, vertexInputDeclarationData_, renderSlotName_, renderSlotDefaultVid_);
145     } else {
146         result.success = false;
147         result.error = "Invalid json file.";
148     }
149 
150     return result;
151 }
152 
Load(IFileManager & fileManager,const string_view uri)153 VertexInputDeclarationLoader::LoadResult VertexInputDeclarationLoader::Load(
154     IFileManager& fileManager, const string_view uri)
155 {
156     uri_ = uri;
157     LoadResult result;
158 
159     IFile::Ptr file = fileManager.OpenFile(uri);
160     if (!file) {
161         PLUGIN_LOG_E("Error loading '%s'", string(uri).c_str());
162         return LoadResult("Failed to open file.");
163     }
164 
165     const uint64_t byteLength = file->GetLength();
166 
167     string raw;
168     raw.resize(static_cast<size_t>(byteLength));
169 
170     if (file->Read(raw.data(), byteLength) != byteLength) {
171         PLUGIN_LOG_E("Error loading '%s'", string(uri).c_str());
172         return LoadResult("Failed to read file.");
173     }
174 
175     return Load(string_view(raw));
176 }
177 
178 RENDER_END_NAMESPACE()
179