Add sampler targets to inspector data

Allows for reflection of the specific textures that a sampler has
sampled.

BUG=tint:699

Change-Id: Iba47baf5c99c4d03671caf2c01747bd6ad12b1e2
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/54901
Auto-Submit: Ryan Harrison <rharrison@chromium.org>
Reviewed-by: Ben Clayton <bclayton@google.com>
Commit-Queue: Ryan Harrison <rharrison@chromium.org>
Kokoro: Kokoro <noreply+kokoro@google.com>
This commit is contained in:
Ryan Harrison 2021-06-17 23:29:03 +00:00 committed by Tint LUCI CQ
parent 17287fcf1a
commit 44382a1857
8 changed files with 584 additions and 227 deletions

View File

@ -470,6 +470,9 @@ libtint_source_set("libtint_core_all_src") {
"inspector/entry_point.h", "inspector/entry_point.h",
"inspector/inspector.cc", "inspector/inspector.cc",
"inspector/inspector.h", "inspector/inspector.h",
"inspector/resource_binding.cc",
"inspector/resource_binding.h",
"inspector/sampler_texture_pair.h",
"inspector/scalar.cc", "inspector/scalar.cc",
"inspector/scalar.h", "inspector/scalar.h",
"intrinsic_table.cc", "intrinsic_table.cc",

View File

@ -217,6 +217,9 @@ set(TINT_LIB_SRCS
inspector/entry_point.h inspector/entry_point.h
inspector/inspector.cc inspector/inspector.cc
inspector/inspector.h inspector/inspector.h
inspector/resource_binding.cc
inspector/resource_binding.h
inspector/sampler_texture_pair.h
inspector/scalar.cc inspector/scalar.cc
inspector/scalar.h inspector/scalar.h
intrinsic_table.cc intrinsic_table.cc

View File

@ -17,6 +17,7 @@
#include <utility> #include <utility>
#include "src/ast/bool_literal.h" #include "src/ast/bool_literal.h"
#include "src/ast/call_expression.h"
#include "src/ast/float_literal.h" #include "src/ast/float_literal.h"
#include "src/ast/module.h" #include "src/ast/module.h"
#include "src/ast/override_decoration.h" #include "src/ast/override_decoration.h"
@ -24,12 +25,14 @@
#include "src/ast/sint_literal.h" #include "src/ast/sint_literal.h"
#include "src/ast/uint_literal.h" #include "src/ast/uint_literal.h"
#include "src/sem/array.h" #include "src/sem/array.h"
#include "src/sem/call.h"
#include "src/sem/f32_type.h" #include "src/sem/f32_type.h"
#include "src/sem/function.h" #include "src/sem/function.h"
#include "src/sem/i32_type.h" #include "src/sem/i32_type.h"
#include "src/sem/matrix_type.h" #include "src/sem/matrix_type.h"
#include "src/sem/multisampled_texture_type.h" #include "src/sem/multisampled_texture_type.h"
#include "src/sem/sampled_texture_type.h" #include "src/sem/sampled_texture_type.h"
#include "src/sem/statement.h"
#include "src/sem/storage_texture_type.h" #include "src/sem/storage_texture_type.h"
#include "src/sem/struct.h" #include "src/sem/struct.h"
#include "src/sem/u32_type.h" #include "src/sem/u32_type.h"
@ -53,131 +56,6 @@ void AppendResourceBindings(std::vector<ResourceBinding>* dest,
dest->insert(dest->end(), orig.begin(), orig.end()); dest->insert(dest->end(), orig.begin(), orig.end());
} }
ResourceBinding::TextureDimension
TypeTextureDimensionToResourceBindingTextureDimension(
const ast::TextureDimension& type_dim) {
switch (type_dim) {
case ast::TextureDimension::k1d:
return ResourceBinding::TextureDimension::k1d;
case ast::TextureDimension::k2d:
return ResourceBinding::TextureDimension::k2d;
case ast::TextureDimension::k2dArray:
return ResourceBinding::TextureDimension::k2dArray;
case ast::TextureDimension::k3d:
return ResourceBinding::TextureDimension::k3d;
case ast::TextureDimension::kCube:
return ResourceBinding::TextureDimension::kCube;
case ast::TextureDimension::kCubeArray:
return ResourceBinding::TextureDimension::kCubeArray;
case ast::TextureDimension::kNone:
return ResourceBinding::TextureDimension::kNone;
}
return ResourceBinding::TextureDimension::kNone;
}
ResourceBinding::SampledKind BaseTypeToSampledKind(const sem::Type* base_type) {
if (!base_type) {
return ResourceBinding::SampledKind::kUnknown;
}
if (auto* at = base_type->As<sem::Array>()) {
base_type = const_cast<sem::Type*>(at->ElemType());
} else if (auto* mt = base_type->As<sem::Matrix>()) {
base_type = mt->type();
} else if (auto* vt = base_type->As<sem::Vector>()) {
base_type = vt->type();
}
if (base_type->Is<sem::F32>()) {
return ResourceBinding::SampledKind::kFloat;
} else if (base_type->Is<sem::U32>()) {
return ResourceBinding::SampledKind::kUInt;
} else if (base_type->Is<sem::I32>()) {
return ResourceBinding::SampledKind::kSInt;
} else {
return ResourceBinding::SampledKind::kUnknown;
}
}
ResourceBinding::ImageFormat TypeImageFormatToResourceBindingImageFormat(
const ast::ImageFormat& image_format) {
switch (image_format) {
case ast::ImageFormat::kR8Unorm:
return ResourceBinding::ImageFormat::kR8Unorm;
case ast::ImageFormat::kR8Snorm:
return ResourceBinding::ImageFormat::kR8Snorm;
case ast::ImageFormat::kR8Uint:
return ResourceBinding::ImageFormat::kR8Uint;
case ast::ImageFormat::kR8Sint:
return ResourceBinding::ImageFormat::kR8Sint;
case ast::ImageFormat::kR16Uint:
return ResourceBinding::ImageFormat::kR16Uint;
case ast::ImageFormat::kR16Sint:
return ResourceBinding::ImageFormat::kR16Sint;
case ast::ImageFormat::kR16Float:
return ResourceBinding::ImageFormat::kR16Float;
case ast::ImageFormat::kRg8Unorm:
return ResourceBinding::ImageFormat::kRg8Unorm;
case ast::ImageFormat::kRg8Snorm:
return ResourceBinding::ImageFormat::kRg8Snorm;
case ast::ImageFormat::kRg8Uint:
return ResourceBinding::ImageFormat::kRg8Uint;
case ast::ImageFormat::kRg8Sint:
return ResourceBinding::ImageFormat::kRg8Sint;
case ast::ImageFormat::kR32Uint:
return ResourceBinding::ImageFormat::kR32Uint;
case ast::ImageFormat::kR32Sint:
return ResourceBinding::ImageFormat::kR32Sint;
case ast::ImageFormat::kR32Float:
return ResourceBinding::ImageFormat::kR32Float;
case ast::ImageFormat::kRg16Uint:
return ResourceBinding::ImageFormat::kRg16Uint;
case ast::ImageFormat::kRg16Sint:
return ResourceBinding::ImageFormat::kRg16Sint;
case ast::ImageFormat::kRg16Float:
return ResourceBinding::ImageFormat::kRg16Float;
case ast::ImageFormat::kRgba8Unorm:
return ResourceBinding::ImageFormat::kRgba8Unorm;
case ast::ImageFormat::kRgba8UnormSrgb:
return ResourceBinding::ImageFormat::kRgba8UnormSrgb;
case ast::ImageFormat::kRgba8Snorm:
return ResourceBinding::ImageFormat::kRgba8Snorm;
case ast::ImageFormat::kRgba8Uint:
return ResourceBinding::ImageFormat::kRgba8Uint;
case ast::ImageFormat::kRgba8Sint:
return ResourceBinding::ImageFormat::kRgba8Sint;
case ast::ImageFormat::kBgra8Unorm:
return ResourceBinding::ImageFormat::kBgra8Unorm;
case ast::ImageFormat::kBgra8UnormSrgb:
return ResourceBinding::ImageFormat::kBgra8UnormSrgb;
case ast::ImageFormat::kRgb10A2Unorm:
return ResourceBinding::ImageFormat::kRgb10A2Unorm;
case ast::ImageFormat::kRg11B10Float:
return ResourceBinding::ImageFormat::kRg11B10Float;
case ast::ImageFormat::kRg32Uint:
return ResourceBinding::ImageFormat::kRg32Uint;
case ast::ImageFormat::kRg32Sint:
return ResourceBinding::ImageFormat::kRg32Sint;
case ast::ImageFormat::kRg32Float:
return ResourceBinding::ImageFormat::kRg32Float;
case ast::ImageFormat::kRgba16Uint:
return ResourceBinding::ImageFormat::kRgba16Uint;
case ast::ImageFormat::kRgba16Sint:
return ResourceBinding::ImageFormat::kRgba16Sint;
case ast::ImageFormat::kRgba16Float:
return ResourceBinding::ImageFormat::kRgba16Float;
case ast::ImageFormat::kRgba32Uint:
return ResourceBinding::ImageFormat::kRgba32Uint;
case ast::ImageFormat::kRgba32Sint:
return ResourceBinding::ImageFormat::kRgba32Sint;
case ast::ImageFormat::kRgba32Float:
return ResourceBinding::ImageFormat::kRgba32Float;
case ast::ImageFormat::kNone:
return ResourceBinding::ImageFormat::kNone;
}
return ResourceBinding::ImageFormat::kNone;
}
} // namespace } // namespace
Inspector::Inspector(const Program* program) : program_(program) {} Inspector::Inspector(const Program* program) : program_(program) {}
@ -459,6 +337,8 @@ std::vector<ResourceBinding> Inspector::GetSamplerResourceBindings(
return {}; return {};
} }
GenerateSamplerTargets();
std::vector<ResourceBinding> result; std::vector<ResourceBinding> result;
auto* func_sem = program_->Sem().Get(func); auto* func_sem = program_->Sem().Get(func);
@ -483,6 +363,8 @@ std::vector<ResourceBinding> Inspector::GetComparisonSamplerResourceBindings(
return {}; return {};
} }
GenerateSamplerTargets();
std::vector<ResourceBinding> result; std::vector<ResourceBinding> result;
auto* func_sem = program_->Sem().Get(func); auto* func_sem = program_->Sem().Get(func);
@ -577,6 +459,22 @@ std::vector<ResourceBinding> Inspector::GetExternalTextureResourceBindings(
return result; return result;
} }
std::vector<SamplerTexturePair> Inspector::GetSamplerTextureUses(
const std::string& entry_point) {
auto* func = FindEntryPointByName(entry_point);
if (!func) {
return {};
}
GenerateSamplerTargets();
auto it = sampler_targets_->find(entry_point);
if (it == sampler_targets_->end()) {
return {};
}
return it->second;
}
ast::Function* Inspector::FindEntryPointByName(const std::string& name) { ast::Function* Inspector::FindEntryPointByName(const std::string& name) {
auto* func = program_->AST().Functions().Find(program_->Symbols().Get(name)); auto* func = program_->AST().Functions().Find(program_->Symbols().Get(name));
if (!func) { if (!func) {
@ -758,5 +656,76 @@ std::vector<ResourceBinding> Inspector::GetStorageTextureResourceBindingsImpl(
return result; return result;
} }
void Inspector::GenerateSamplerTargets() {
// Do not re-generate, since |program_| should not change during the lifetime
// of the inspector.
if (sampler_targets_ != nullptr) {
return;
}
sampler_targets_ = std::make_unique<
std::unordered_map<std::string, UniqueVector<SamplerTexturePair>>>();
auto& sem = program_->Sem();
for (auto* node : program_->ASTNodes().Objects()) {
auto* c = node->As<ast::CallExpression>();
if (!c) {
continue;
}
auto* call = sem.Get(c);
if (!call) {
continue;
}
auto* i = call->Target()->As<sem::Intrinsic>();
if (!i) {
continue;
}
const auto& params = i->Parameters();
int sampler_index = sem::IndexOf(params, sem::ParameterUsage::kSampler);
if (sampler_index == -1) {
continue;
}
int texture_index = sem::IndexOf(params, sem::ParameterUsage::kTexture);
if (texture_index == -1) {
continue;
}
auto* call_func = call->Stmt()->Function();
std::vector<Symbol> entry_points;
if (call_func->IsEntryPoint()) {
entry_points = {call_func->symbol()};
} else {
entry_points = sem.Get(call_func)->AncestorEntryPoints();
}
if (entry_points.empty()) {
continue;
}
auto* s = c->params()[sampler_index];
auto* sampler = sem.Get<sem::VariableUser>(s)->Variable();
sem::BindingPoint sampler_binding_point = {
sampler->Declaration()->binding_point().group->value(),
sampler->Declaration()->binding_point().binding->value()};
auto* t = c->params()[texture_index];
auto* texture = sem.Get<sem::VariableUser>(t)->Variable();
sem::BindingPoint texture_binding_point = {
texture->Declaration()->binding_point().group->value(),
texture->Declaration()->binding_point().binding->value()};
for (auto entry_point : entry_points) {
const auto& ep_name = program_->Symbols().NameFor(entry_point);
(*sampler_targets_)[ep_name].add(
{sampler_binding_point, texture_binding_point});
}
}
}
} // namespace inspector } // namespace inspector
} // namespace tint } // namespace tint

View File

@ -19,113 +19,19 @@
#include <memory> #include <memory>
#include <string> #include <string>
#include <tuple> #include <tuple>
#include <unordered_map>
#include <vector> #include <vector>
#include "src/inspector/entry_point.h" #include "src/inspector/entry_point.h"
#include "src/inspector/resource_binding.h"
#include "src/inspector/sampler_texture_pair.h"
#include "src/inspector/scalar.h" #include "src/inspector/scalar.h"
#include "src/program.h" #include "src/program.h"
#include "src/utils/unique_vector.h"
namespace tint { namespace tint {
namespace inspector { namespace inspector {
/// Container for information about how a resource is bound
struct ResourceBinding {
/// The dimensionality of a texture
enum class TextureDimension {
/// Invalid texture
kNone = -1,
/// 1 dimensional texture
k1d,
/// 2 dimensional texture
k2d,
/// 2 dimensional array texture
k2dArray,
/// 3 dimensional texture
k3d,
/// cube texture
kCube,
/// cube array texture
kCubeArray,
};
/// Component type of the texture's data. Same as the Sampled Type parameter
/// in SPIR-V OpTypeImage.
enum class SampledKind { kUnknown = -1, kFloat, kUInt, kSInt };
/// Enumerator of texture image formats
enum class ImageFormat {
kNone = -1,
kR8Unorm,
kR8Snorm,
kR8Uint,
kR8Sint,
kR16Uint,
kR16Sint,
kR16Float,
kRg8Unorm,
kRg8Snorm,
kRg8Uint,
kRg8Sint,
kR32Uint,
kR32Sint,
kR32Float,
kRg16Uint,
kRg16Sint,
kRg16Float,
kRgba8Unorm,
kRgba8UnormSrgb,
kRgba8Snorm,
kRgba8Uint,
kRgba8Sint,
kBgra8Unorm,
kBgra8UnormSrgb,
kRgb10A2Unorm,
kRg11B10Float,
kRg32Uint,
kRg32Sint,
kRg32Float,
kRgba16Uint,
kRgba16Sint,
kRgba16Float,
kRgba32Uint,
kRgba32Sint,
kRgba32Float,
};
/// kXXX maps to entries returned by GetXXXResourceBindings call.
enum class ResourceType {
kUniformBuffer,
kStorageBuffer,
kReadOnlyStorageBuffer,
kSampler,
kComparisonSampler,
kSampledTexture,
kMultisampledTexture,
kReadOnlyStorageTexture,
kWriteOnlyStorageTexture,
kDepthTexture,
kExternalTexture
};
/// Type of resource that is bound.
ResourceType resource_type;
/// Bind group the binding belongs
uint32_t bind_group;
/// Identifier to identify this binding within the bind group
uint32_t binding;
/// Size for this binding, in bytes, if defined.
uint64_t size;
/// Size for this binding without trailing structure padding, in bytes, if
/// defined.
uint64_t size_no_padding;
/// Dimensionality of this binding, if defined.
TextureDimension dim;
/// Kind of data being sampled, if defined.
SampledKind sampled_kind;
/// Format of data, if defined.
ImageFormat image_format;
};
/// Extracts information from a program /// Extracts information from a program
class Inspector { class Inspector {
public: public:
@ -215,9 +121,18 @@ class Inspector {
std::vector<ResourceBinding> GetExternalTextureResourceBindings( std::vector<ResourceBinding> GetExternalTextureResourceBindings(
const std::string& entry_point); const std::string& entry_point);
/// @param entry_point name of the entry point to get information about.
/// @returns vector of all of the sampler/texture sampling pairs that are used
/// by that entry point.
std::vector<SamplerTexturePair> GetSamplerTextureUses(
const std::string& entry_point);
private: private:
const Program* program_; const Program* program_;
std::string error_; std::string error_;
std::unique_ptr<
std::unordered_map<std::string, UniqueVector<SamplerTexturePair>>>
sampler_targets_;
/// @param name name of the entry point to find /// @param name name of the entry point to find
/// @returns a pointer to the entry point if it exists, otherwise returns /// @returns a pointer to the entry point if it exists, otherwise returns
@ -259,6 +174,9 @@ class Inspector {
std::vector<ResourceBinding> GetStorageTextureResourceBindingsImpl( std::vector<ResourceBinding> GetStorageTextureResourceBindingsImpl(
const std::string& entry_point, const std::string& entry_point,
bool read_only); bool read_only);
/// Constructes |sampler_targets_| if it hasn't already been instantiated.
void GenerateSamplerTargets();
}; };
} // namespace inspector } // namespace inspector

View File

@ -475,11 +475,10 @@ class InspectorHelper : public ProgramBuilder {
std::string result_name = "sampler_result"; std::string result_name = "sampler_result";
ast::StatementList stmts; ast::StatementList stmts;
stmts.emplace_back(Decl(Var("sampler_result", ty.vec(base_type, 4)))); stmts.emplace_back(Decl(Var(result_name, ty.vec(base_type, 4))));
stmts.emplace_back( stmts.emplace_back(Assign(result_name, Call("textureSample", texture_name,
Assign("sampler_result", sampler_name, coords_name)));
Call("textureSample", texture_name, sampler_name, coords_name)));
stmts.emplace_back(Return()); stmts.emplace_back(Return());
return Func(func_name, ast::VariableList(), ty.void_(), stmts, decorations); return Func(func_name, ast::VariableList(), ty.void_(), stmts, decorations);
@ -737,6 +736,9 @@ class InspectorGetStorageTextureResourceBindingsTestWithParam
class InspectorGetExternalTextureResourceBindingsTest : public InspectorHelper, class InspectorGetExternalTextureResourceBindingsTest : public InspectorHelper,
public testing::Test {}; public testing::Test {};
class InspectorGetSamplerTextureUsesTest : public InspectorHelper,
public testing::Test {};
TEST_F(InspectorGetEntryPointTest, NoFunctions) { TEST_F(InspectorGetEntryPointTest, NoFunctions) {
Inspector& inspector = Build(); Inspector& inspector = Build();
@ -3073,6 +3075,96 @@ TEST_F(InspectorGetExternalTextureResourceBindingsTest, Simple) {
EXPECT_EQ(0u, result[0].binding); EXPECT_EQ(0u, result[0].binding);
} }
TEST_F(InspectorGetSamplerTextureUsesTest, None) {
MakeEmptyBodyFunction("ep_func", ast::DecorationList{
Stage(ast::PipelineStage::kFragment),
});
Inspector& inspector = Build();
auto result = inspector.GetSamplerTextureUses("ep_func");
ASSERT_FALSE(inspector.has_error()) << inspector.error();
ASSERT_EQ(0u, result.size());
}
TEST_F(InspectorGetSamplerTextureUsesTest, Simple) {
auto* sampled_texture_type =
MakeSampledTextureType(ast::TextureDimension::k1d, ty.f32());
AddSampledTexture("foo_texture", sampled_texture_type, 0, 10);
AddSampler("foo_sampler", 0, 1);
AddGlobalVariable("foo_coords", ty.f32());
MakeSamplerReferenceBodyFunction("ep_func", "foo_texture", "foo_sampler",
"foo_coords", ty.f32(),
ast::DecorationList{
Stage(ast::PipelineStage::kFragment),
});
Inspector& inspector = Build();
auto result = inspector.GetSamplerTextureUses("ep_func");
ASSERT_FALSE(inspector.has_error()) << inspector.error();
ASSERT_EQ(1u, result.size());
EXPECT_EQ(0u, result[0].sampler_binding_point.group);
EXPECT_EQ(1u, result[0].sampler_binding_point.binding);
EXPECT_EQ(0u, result[0].texture_binding_point.group);
EXPECT_EQ(10u, result[0].texture_binding_point.binding);
}
TEST_F(InspectorGetSamplerTextureUsesTest, MultipleCalls) {
auto* sampled_texture_type =
MakeSampledTextureType(ast::TextureDimension::k1d, ty.f32());
AddSampledTexture("foo_texture", sampled_texture_type, 0, 10);
AddSampler("foo_sampler", 0, 1);
AddGlobalVariable("foo_coords", ty.f32());
MakeSamplerReferenceBodyFunction("ep_func", "foo_texture", "foo_sampler",
"foo_coords", ty.f32(),
ast::DecorationList{
Stage(ast::PipelineStage::kFragment),
});
Inspector& inspector = Build();
auto result_0 = inspector.GetSamplerTextureUses("ep_func");
ASSERT_FALSE(inspector.has_error()) << inspector.error();
auto result_1 = inspector.GetSamplerTextureUses("ep_func");
ASSERT_FALSE(inspector.has_error()) << inspector.error();
EXPECT_EQ(result_0, result_1);
}
TEST_F(InspectorGetSamplerTextureUsesTest, InFunction) {
auto* sampled_texture_type =
MakeSampledTextureType(ast::TextureDimension::k1d, ty.f32());
AddSampledTexture("foo_texture", sampled_texture_type, 0, 0);
AddSampler("foo_sampler", 0, 1);
AddGlobalVariable("foo_coords", ty.f32());
MakeSamplerReferenceBodyFunction("foo_func", "foo_texture", "foo_sampler",
"foo_coords", ty.f32(), {});
MakeCallerBodyFunction("ep_func", {"foo_func"},
ast::DecorationList{
Stage(ast::PipelineStage::kFragment),
});
Inspector& inspector = Build();
auto result = inspector.GetSamplerTextureUses("ep_func");
ASSERT_FALSE(inspector.has_error()) << inspector.error();
ASSERT_EQ(1u, result.size());
EXPECT_EQ(0u, result[0].sampler_binding_point.group);
EXPECT_EQ(1u, result[0].sampler_binding_point.binding);
EXPECT_EQ(0u, result[0].texture_binding_point.group);
EXPECT_EQ(0u, result[0].texture_binding_point.binding);
}
} // namespace } // namespace
} // namespace inspector } // namespace inspector
} // namespace tint } // namespace tint

View File

@ -0,0 +1,154 @@
// Copyright 2021 The Tint Authors.
//
// 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 "src/inspector/resource_binding.h"
#include "src/sem/array.h"
#include "src/sem/f32_type.h"
#include "src/sem/i32_type.h"
#include "src/sem/matrix_type.h"
#include "src/sem/type.h"
#include "src/sem/u32_type.h"
#include "src/sem/vector_type.h"
namespace tint {
namespace inspector {
ResourceBinding::TextureDimension
TypeTextureDimensionToResourceBindingTextureDimension(
const ast::TextureDimension& type_dim) {
switch (type_dim) {
case ast::TextureDimension::k1d:
return ResourceBinding::TextureDimension::k1d;
case ast::TextureDimension::k2d:
return ResourceBinding::TextureDimension::k2d;
case ast::TextureDimension::k2dArray:
return ResourceBinding::TextureDimension::k2dArray;
case ast::TextureDimension::k3d:
return ResourceBinding::TextureDimension::k3d;
case ast::TextureDimension::kCube:
return ResourceBinding::TextureDimension::kCube;
case ast::TextureDimension::kCubeArray:
return ResourceBinding::TextureDimension::kCubeArray;
case ast::TextureDimension::kNone:
return ResourceBinding::TextureDimension::kNone;
}
return ResourceBinding::TextureDimension::kNone;
}
ResourceBinding::SampledKind BaseTypeToSampledKind(const sem::Type* base_type) {
if (!base_type) {
return ResourceBinding::SampledKind::kUnknown;
}
if (auto* at = base_type->As<sem::Array>()) {
base_type = const_cast<sem::Type*>(at->ElemType());
} else if (auto* mt = base_type->As<sem::Matrix>()) {
base_type = mt->type();
} else if (auto* vt = base_type->As<sem::Vector>()) {
base_type = vt->type();
}
if (base_type->Is<sem::F32>()) {
return ResourceBinding::SampledKind::kFloat;
} else if (base_type->Is<sem::U32>()) {
return ResourceBinding::SampledKind::kUInt;
} else if (base_type->Is<sem::I32>()) {
return ResourceBinding::SampledKind::kSInt;
} else {
return ResourceBinding::SampledKind::kUnknown;
}
}
ResourceBinding::ImageFormat TypeImageFormatToResourceBindingImageFormat(
const ast::ImageFormat& image_format) {
switch (image_format) {
case ast::ImageFormat::kR8Unorm:
return ResourceBinding::ImageFormat::kR8Unorm;
case ast::ImageFormat::kR8Snorm:
return ResourceBinding::ImageFormat::kR8Snorm;
case ast::ImageFormat::kR8Uint:
return ResourceBinding::ImageFormat::kR8Uint;
case ast::ImageFormat::kR8Sint:
return ResourceBinding::ImageFormat::kR8Sint;
case ast::ImageFormat::kR16Uint:
return ResourceBinding::ImageFormat::kR16Uint;
case ast::ImageFormat::kR16Sint:
return ResourceBinding::ImageFormat::kR16Sint;
case ast::ImageFormat::kR16Float:
return ResourceBinding::ImageFormat::kR16Float;
case ast::ImageFormat::kRg8Unorm:
return ResourceBinding::ImageFormat::kRg8Unorm;
case ast::ImageFormat::kRg8Snorm:
return ResourceBinding::ImageFormat::kRg8Snorm;
case ast::ImageFormat::kRg8Uint:
return ResourceBinding::ImageFormat::kRg8Uint;
case ast::ImageFormat::kRg8Sint:
return ResourceBinding::ImageFormat::kRg8Sint;
case ast::ImageFormat::kR32Uint:
return ResourceBinding::ImageFormat::kR32Uint;
case ast::ImageFormat::kR32Sint:
return ResourceBinding::ImageFormat::kR32Sint;
case ast::ImageFormat::kR32Float:
return ResourceBinding::ImageFormat::kR32Float;
case ast::ImageFormat::kRg16Uint:
return ResourceBinding::ImageFormat::kRg16Uint;
case ast::ImageFormat::kRg16Sint:
return ResourceBinding::ImageFormat::kRg16Sint;
case ast::ImageFormat::kRg16Float:
return ResourceBinding::ImageFormat::kRg16Float;
case ast::ImageFormat::kRgba8Unorm:
return ResourceBinding::ImageFormat::kRgba8Unorm;
case ast::ImageFormat::kRgba8UnormSrgb:
return ResourceBinding::ImageFormat::kRgba8UnormSrgb;
case ast::ImageFormat::kRgba8Snorm:
return ResourceBinding::ImageFormat::kRgba8Snorm;
case ast::ImageFormat::kRgba8Uint:
return ResourceBinding::ImageFormat::kRgba8Uint;
case ast::ImageFormat::kRgba8Sint:
return ResourceBinding::ImageFormat::kRgba8Sint;
case ast::ImageFormat::kBgra8Unorm:
return ResourceBinding::ImageFormat::kBgra8Unorm;
case ast::ImageFormat::kBgra8UnormSrgb:
return ResourceBinding::ImageFormat::kBgra8UnormSrgb;
case ast::ImageFormat::kRgb10A2Unorm:
return ResourceBinding::ImageFormat::kRgb10A2Unorm;
case ast::ImageFormat::kRg11B10Float:
return ResourceBinding::ImageFormat::kRg11B10Float;
case ast::ImageFormat::kRg32Uint:
return ResourceBinding::ImageFormat::kRg32Uint;
case ast::ImageFormat::kRg32Sint:
return ResourceBinding::ImageFormat::kRg32Sint;
case ast::ImageFormat::kRg32Float:
return ResourceBinding::ImageFormat::kRg32Float;
case ast::ImageFormat::kRgba16Uint:
return ResourceBinding::ImageFormat::kRgba16Uint;
case ast::ImageFormat::kRgba16Sint:
return ResourceBinding::ImageFormat::kRgba16Sint;
case ast::ImageFormat::kRgba16Float:
return ResourceBinding::ImageFormat::kRgba16Float;
case ast::ImageFormat::kRgba32Uint:
return ResourceBinding::ImageFormat::kRgba32Uint;
case ast::ImageFormat::kRgba32Sint:
return ResourceBinding::ImageFormat::kRgba32Sint;
case ast::ImageFormat::kRgba32Float:
return ResourceBinding::ImageFormat::kRgba32Float;
case ast::ImageFormat::kNone:
return ResourceBinding::ImageFormat::kNone;
}
return ResourceBinding::ImageFormat::kNone;
}
} // namespace inspector
} // namespace tint

View File

@ -0,0 +1,147 @@
// Copyright 2021 The Tint Authors.
//
// 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 SRC_INSPECTOR_RESOURCE_BINDING_H_
#define SRC_INSPECTOR_RESOURCE_BINDING_H_
#include <cstdint>
#include "src/ast/storage_texture.h"
#include "src/ast/texture.h"
namespace tint {
namespace inspector {
/// Container for information about how a resource is bound
struct ResourceBinding {
/// The dimensionality of a texture
enum class TextureDimension {
/// Invalid texture
kNone = -1,
/// 1 dimensional texture
k1d,
/// 2 dimensional texture
k2d,
/// 2 dimensional array texture
k2dArray,
/// 3 dimensional texture
k3d,
/// cube texture
kCube,
/// cube array texture
kCubeArray,
};
/// Component type of the texture's data. Same as the Sampled Type parameter
/// in SPIR-V OpTypeImage.
enum class SampledKind { kUnknown = -1, kFloat, kUInt, kSInt };
/// Enumerator of texture image formats
enum class ImageFormat {
kNone = -1,
kR8Unorm,
kR8Snorm,
kR8Uint,
kR8Sint,
kR16Uint,
kR16Sint,
kR16Float,
kRg8Unorm,
kRg8Snorm,
kRg8Uint,
kRg8Sint,
kR32Uint,
kR32Sint,
kR32Float,
kRg16Uint,
kRg16Sint,
kRg16Float,
kRgba8Unorm,
kRgba8UnormSrgb,
kRgba8Snorm,
kRgba8Uint,
kRgba8Sint,
kBgra8Unorm,
kBgra8UnormSrgb,
kRgb10A2Unorm,
kRg11B10Float,
kRg32Uint,
kRg32Sint,
kRg32Float,
kRgba16Uint,
kRgba16Sint,
kRgba16Float,
kRgba32Uint,
kRgba32Sint,
kRgba32Float,
};
/// kXXX maps to entries returned by GetXXXResourceBindings call.
enum class ResourceType {
kUniformBuffer,
kStorageBuffer,
kReadOnlyStorageBuffer,
kSampler,
kComparisonSampler,
kSampledTexture,
kMultisampledTexture,
kReadOnlyStorageTexture,
kWriteOnlyStorageTexture,
kDepthTexture,
kExternalTexture
};
/// Type of resource that is bound.
ResourceType resource_type;
/// Bind group the binding belongs
uint32_t bind_group;
/// Identifier to identify this binding within the bind group
uint32_t binding;
/// Size for this binding, in bytes, if defined.
uint64_t size;
/// Size for this binding without trailing structure padding, in bytes, if
/// defined.
uint64_t size_no_padding;
/// Dimensionality of this binding, if defined.
TextureDimension dim;
/// Kind of data being sampled, if defined.
SampledKind sampled_kind;
/// Format of data, if defined.
ImageFormat image_format;
};
/// Convert from internal ast::TextureDimension to public
/// ResourceBinding::TextureDimension
/// @param type_dim internal value to convert from
/// @returns the publicly visible equivalent
ResourceBinding::TextureDimension
TypeTextureDimensionToResourceBindingTextureDimension(
const ast::TextureDimension& type_dim);
/// Infer ResourceBinding::SampledKind for a given sem::Type
/// @param base_type internal type to infer from
/// @returns the publicly visible equivalent
ResourceBinding::SampledKind BaseTypeToSampledKind(const sem::Type* base_type);
/// Convert from internal ast::ImageFormat to public
/// ResourceBinding::ImageFormat
/// @param image_format internal value to convert from
/// @returns the publicly visible equivalent
ResourceBinding::ImageFormat TypeImageFormatToResourceBindingImageFormat(
const ast::ImageFormat& image_format);
} // namespace inspector
} // namespace tint
#endif // SRC_INSPECTOR_RESOURCE_BINDING_H_

View File

@ -0,0 +1,71 @@
// Copyright 2021 The Tint Authors.
//
// 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 SRC_INSPECTOR_SAMPLER_TEXTURE_PAIR_H_
#define SRC_INSPECTOR_SAMPLER_TEXTURE_PAIR_H_
#include <cstdint>
#include <functional>
#include "src/sem/binding_point.h"
namespace tint {
namespace inspector {
/// Mapping of a sampler to a texture it samples.
struct SamplerTexturePair {
/// group & binding values for a sampler.
sem::BindingPoint sampler_binding_point;
/// group & binding values for a texture samepled by the sampler.
sem::BindingPoint texture_binding_point;
/// Equality operator
/// @param rhs the SamplerTexturePair to compare against
/// @returns true if this SamplerTexturePair is equal to `rhs`
inline bool operator==(const SamplerTexturePair& rhs) const {
return sampler_binding_point == rhs.sampler_binding_point &&
texture_binding_point == rhs.texture_binding_point;
}
/// Inequality operator
/// @param rhs the SamplerTexturePair to compare against
/// @returns true if this SamplerTexturePair is not equal to `rhs`
inline bool operator!=(const SamplerTexturePair& rhs) const {
return !(*this == rhs);
}
};
} // namespace inspector
} // namespace tint
namespace std {
/// Custom std::hash specialization for ttint::inspector::SamplerTexturePair so
/// SamplerTexturePairss be used as keys for std::unordered_map and
/// std::unordered_set.
template <>
class hash<tint::inspector::SamplerTexturePair> {
public:
/// @param stp the texture pair to create a hash for
/// @return the hash value
inline std::size_t operator()(
const tint::inspector::SamplerTexturePair& stp) const {
return tint::utils::Hash(stp.sampler_binding_point,
stp.texture_binding_point);
}
};
} // namespace std
#endif // SRC_INSPECTOR_SAMPLER_TEXTURE_PAIR_H_