Commit 63382c61 by Ben Clayton

Vulkan/Debug: Add Value and Variable

The Value interface exposes values to the debugger. Variables are named values. VariableContainer is a collection of Variables. Bug: b/145351270 Change-Id: Iae3749447554977f84bfc6e58f37b52aa6ed262f Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/38893Reviewed-by: 's avatarNicolas Capens <nicolascapens@google.com> Tested-by: 's avatarBen Clayton <bclayton@google.com> Kokoro-Presubmit: kokoro <noreply+kokoro@google.com>
parent b1f88766
// Copyright 2019 The SwiftShader Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "Type.hpp"
#include "Value.hpp"
#include "Variable.hpp"
namespace vk
{
namespace dbg
{
const FormatFlags FormatFlags::Default = {
"[", // listPrefix
"]", // listSuffix
", ", // listDelimiter
"", // listIndent
&FormatFlags::Default, // subListFmt
};
std::string Value::string(const FormatFlags& fmt /* = FormatFlags::Default */) const
{
switch(type()->kind)
{
case Kind::Bool:
return *reinterpret_cast<const bool*>(get()) ? "true" : "false";
case Kind::U8:
return std::to_string(*reinterpret_cast<const uint8_t*>(get()));
case Kind::S8:
return std::to_string(*reinterpret_cast<const int8_t*>(get()));
case Kind::U16:
return std::to_string(*reinterpret_cast<const uint16_t*>(get()));
case Kind::S16:
return std::to_string(*reinterpret_cast<const int16_t*>(get()));
case Kind::F32:
return std::to_string(*reinterpret_cast<const float*>(get()));
case Kind::U32:
return std::to_string(*reinterpret_cast<const uint32_t*>(get()));
case Kind::S32:
return std::to_string(*reinterpret_cast<const int32_t*>(get()));
case Kind::F64:
return std::to_string(*reinterpret_cast<const double*>(get()));
case Kind::U64:
return std::to_string(*reinterpret_cast<const uint64_t*>(get()));
case Kind::S64:
return std::to_string(*reinterpret_cast<const int64_t*>(get()));
case Kind::Ptr:
return std::to_string(reinterpret_cast<uintptr_t>(get()));
case Kind::VariableContainer:
auto const* vc = static_cast<const VariableContainer*>(this);
std::string out = "";
auto subfmt = *fmt.subListFmt;
subfmt.listIndent = fmt.listIndent + fmt.subListFmt->listIndent;
bool first = true;
vc->foreach(0, [&](const Variable& var) {
if(!first) { out += fmt.listDelimiter; }
first = false;
out += fmt.listIndent;
out += var.name;
out += ": ";
out += var.value->string(subfmt);
});
return fmt.listPrefix + out + fmt.listSuffix;
}
return "";
}
} // namespace dbg
} // namespace vk
\ No newline at end of file
// Copyright 2019 The SwiftShader Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef VK_DEBUG_VALUE_HPP_
#define VK_DEBUG_VALUE_HPP_
#include <memory>
#include <string>
namespace vk
{
namespace dbg
{
class Type;
// FormatFlags holds settings used to serialize a Value to a string.
struct FormatFlags
{
// The default FormatFlags used to serialize a Value to a string.
static const FormatFlags Default;
std::string listPrefix; // Prefix to lists.
std::string listSuffix; // Suffix to lists.
std::string listDelimiter; // List item delimiter.
std::string listIndent; // List item indententation prefix.
const FormatFlags* subListFmt; // Format used for list sub items.
};
// Value holds a value that can be read and possible written to.
class Value
{
public:
virtual ~Value() = default;
// type() returns the value's type.
virtual std::shared_ptr<Type> type() const = 0;
// string() returns a string representation of the value using the specified
// FormatFlags.
virtual std::string string(const FormatFlags& = FormatFlags::Default) const;
// get() returns a pointer to the value.
virtual const void* get() const = 0;
// set() changes the value to a copy of the value at ptr.
// set() returns true if the value was changed, or false if the value cannot
// be set.
virtual bool set(void* ptr) { return false; }
};
// Constant is an immutable value.
template <typename T>
class Constant : public Value
{
public:
inline Constant(const T& value);
inline std::shared_ptr<Type> type() const override;
inline const void* get() const override;
private:
const T value;
};
template <typename T>
Constant<T>::Constant(const T& value) :
value(value)
{
}
template <typename T>
std::shared_ptr<Type> Constant<T>::type() const
{
return TypeOf<T>::get();
}
template <typename T>
const void* Constant<T>::get() const
{
return &value;
}
// make_constant() returns a shared_ptr to a Constant with the given value.
template <typename T>
inline std::shared_ptr<Constant<T>> make_constant(const T& value)
{
return std::shared_ptr<Constant<T>>(new vk::dbg::Constant<T>(value));
}
} // namespace dbg
} // namespace vk
#endif // VK_DEBUG_VALUE_HPP_
\ No newline at end of file
// Copyright 2019 The SwiftShader Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef VK_DEBUG_VARIABLE_HPP_
#define VK_DEBUG_VARIABLE_HPP_
#include "ID.hpp"
#include "Type.hpp"
#include "Value.hpp"
#include <memory>
#include <mutex>
#include <string>
#include <unordered_map>
#include <vector>
namespace vk
{
namespace dbg
{
// Variable is a named value.
struct Variable
{
std::string name;
std::shared_ptr<Value> value;
};
// VariableContainer is a collection of named values.
class VariableContainer : public Value
{
public:
using ID = dbg::ID<VariableContainer>;
inline VariableContainer(ID id);
// foreach() calls cb with each of the variables in the container.
// F must be a function with the signature void(const Variable&).
template <typename F>
inline void foreach(size_t startIndex, const F& cb) const;
// find() looks up the variable with the given name.
// If the variable with the given name is found, cb is called with the
// variable and find() returns true.
template <typename F>
inline bool find(const std::string& name, const F& cb) const;
// put() places the variable var into the container.
inline void put(const Variable& var);
// put() places the variable with the given name and value into the container.
inline void put(const std::string& name, const std::shared_ptr<Value>& value);
// The unique identifier of the variable.
const ID id;
private:
inline std::shared_ptr<Type> type() const override;
inline const void* get() const override;
mutable std::mutex mutex;
std::vector<Variable> variables;
std::unordered_map<std::string, int> indices;
};
VariableContainer::VariableContainer(ID id) :
id(id) {}
template <typename F>
void VariableContainer::foreach(size_t startIndex, const F& cb) const
{
std::unique_lock<std::mutex> lock(mutex);
for(size_t i = startIndex; i < variables.size(); i++)
{
cb(variables[i]);
}
}
template <typename F>
bool VariableContainer::find(const std::string& name, const F& cb) const
{
std::unique_lock<std::mutex> lock(mutex);
for(auto const& var : variables)
{
if(var.name == name)
{
cb(var);
return true;
}
}
return false;
}
void VariableContainer::put(const Variable& var)
{
std::unique_lock<std::mutex> lock(mutex);
auto it = indices.find(var.name);
if(it == indices.end())
{
indices.emplace(var.name, variables.size());
variables.push_back(var);
}
else
{
variables[it->second].value = var.value;
}
}
void VariableContainer::put(const std::string& name,
const std::shared_ptr<Value>& value)
{
put({ name, value });
}
std::shared_ptr<Type> VariableContainer::type() const
{
return TypeOf<VariableContainer>::get();
}
const void* VariableContainer::get() const
{
return nullptr;
}
} // namespace dbg
} // namespace vk
#endif // VK_DEBUG_VARIABLE_HPP_
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment