hlsl & spriv writers: Remove const_cast hacks

Use the new type::Manager::Wrap() function to build a new temporary type manager that wraps the program's type manager.

This allows the writer to construct temporary new types (if they weren't already in the program) without actually mutating the program.

Bug: tint:390
Change-Id: Icadab42d66e0a88c494bd21b3a4f7bae2ed13832
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/38552
Reviewed-by: dan sinclair <dsinclair@chromium.org>
This commit is contained in:
Ben Clayton 2021-01-26 16:57:10 +00:00
parent a458c57662
commit 3bd1f81889
4 changed files with 17 additions and 21 deletions

View File

@ -125,7 +125,8 @@ const char* image_format_to_rwtexture_type(type::ImageFormat image_format) {
} // namespace
GeneratorImpl::GeneratorImpl(const Program* program) : program_(program) {}
GeneratorImpl::GeneratorImpl(const Program* program)
: program_(program), types_(type::Manager::Wrap(program->Types())) {}
GeneratorImpl::~GeneratorImpl() = default;
@ -882,8 +883,7 @@ bool GeneratorImpl::EmitTextureCall(std::ostream& pre,
auto* param_coords = params[pidx.coords];
auto emit_vector_appended_with_i32_zero = [&](tint::ast::Expression* vector) {
// TODO(https://crbug.com/tint/390): Remove this const_cast hack!
auto* i32 = const_cast<Program*>(program_)->create<type::I32>();
auto* i32 = types_.Get<type::I32>();
ast::SintLiteral zero_lit(Source{}, i32, 0);
ast::ScalarConstructorExpression zero(Source{}, &zero_lit);
zero.set_result_type(i32);

View File

@ -394,6 +394,7 @@ class GeneratorImpl {
Namer namer_;
const Program* program_ = nullptr;
type::Manager types_;
Symbol current_ep_sym_;
bool generating_entry_point_ = false;
uint32_t loop_emission_counter_ = 0;

View File

@ -286,7 +286,9 @@ Builder::AccessorInfo::AccessorInfo() : source_id(0), source_type(nullptr) {}
Builder::AccessorInfo::~AccessorInfo() {}
Builder::Builder(const Program* program)
: program_(program), scope_stack_({}) {}
: program_(program),
type_mgr_(type::Manager::Wrap(program->Types())),
scope_stack_({}) {}
Builder::~Builder() = default;
@ -2043,10 +2045,8 @@ bool Builder::GenerateTextureIntrinsic(ast::IdentifierExpression* ident,
// to calling append_result_type_and_id_to_spirv_params().
auto append_result_type_and_id_to_spirv_params_for_read = [&]() {
if (texture_type->Is<type::DepthTexture>()) {
// TODO(https://crbug.com/tint/390): Remove this const_cast hack!
auto* f32 = const_cast<Program*>(program_)->create<type::F32>();
auto* spirv_result_type =
const_cast<Program*>(program_)->create<type::Vector>(f32, 4);
auto* f32 = type_mgr_.Get<type::F32>();
auto* spirv_result_type = type_mgr_.Get<type::Vector>(f32, 4);
auto spirv_result = result_op();
post_emission = [=] {
return push_function_inst(
@ -2077,10 +2077,8 @@ bool Builder::GenerateTextureIntrinsic(ast::IdentifierExpression* ident,
// OpImageQuerySize[Lod].
auto* element_type = ElementTypeOf(call->result_type());
auto spirv_result = result_op();
// TODO(https://crbug.com/tint/390): Remove this const_cast hack!
auto* spirv_result_type =
const_cast<Program*>(program_)->create<type::Vector>(
element_type, spirv_result_width);
type_mgr_.Get<type::Vector>(element_type, spirv_result_width);
if (swizzle.size() > 1) {
post_emission = [=] {
OperandList operands{
@ -2198,9 +2196,7 @@ bool Builder::GenerateTextureIntrinsic(ast::IdentifierExpression* ident,
op = spv::Op::OpImageQuerySizeLod;
spirv_params.emplace_back(gen_param(pidx.level));
} else {
// TODO(https://crbug.com/tint/390): Remove this const_cast hack!
ast::SintLiteral i32_0(
Source{}, const_cast<Program*>(program_)->create<type::I32>(), 0);
ast::SintLiteral i32_0(Source{}, type_mgr_.Get<type::I32>(), 0);
op = spv::Op::OpImageQuerySizeLod;
spirv_params.emplace_back(
Operand::Int(GenerateLiteralIfNeeded(nullptr, &i32_0)));
@ -2235,9 +2231,7 @@ bool Builder::GenerateTextureIntrinsic(ast::IdentifierExpression* ident,
texture_type->Is<type::StorageTexture>()) {
op = spv::Op::OpImageQuerySize;
} else {
// TODO(https://crbug.com/tint/390): Remove this const_cast hack!
ast::SintLiteral i32_0(
Source{}, const_cast<Program*>(program_)->create<type::I32>(), 0);
ast::SintLiteral i32_0(Source{}, type_mgr_.Get<type::I32>(), 0);
op = spv::Op::OpImageQuerySizeLod;
spirv_params.emplace_back(
Operand::Int(GenerateLiteralIfNeeded(nullptr, &i32_0)));
@ -2316,8 +2310,7 @@ bool Builder::GenerateTextureIntrinsic(ast::IdentifierExpression* ident,
if (call->params()[pidx.level]->result_type()->Is<type::I32>()) {
// Depth textures have i32 parameters for the level, but SPIR-V expects
// F32. Cast.
// TODO(https://crbug.com/tint/390): Remove this const_cast hack!
auto* f32 = const_cast<Program*>(program_)->create<type::F32>();
auto* f32 = type_mgr_.Get<type::F32>();
ast::TypeConstructorExpression cast(Source{}, f32,
{call->params()[pidx.level]});
level = Operand::Int(GenerateExpression(&cast));

View File

@ -51,6 +51,7 @@
#include "src/type/pointer_type.h"
#include "src/type/storage_texture_type.h"
#include "src/type/struct_type.h"
#include "src/type/type_manager.h"
#include "src/type/vector_type.h"
#include "src/writer/spirv/function.h"
#include "src/writer/spirv/instruction.h"
@ -59,7 +60,7 @@ namespace tint {
namespace writer {
namespace spirv {
/// Builder class to create SPIR-V instructions from a program.
/// Builder class to create SPIR-V instructions from a module.
class Builder {
public:
/// Contains information for generating accessor chains
@ -82,7 +83,7 @@ class Builder {
};
/// Constructor
/// @param program the program to generate from
/// @param program the program
explicit Builder(const Program* program);
~Builder();
@ -488,6 +489,7 @@ class Builder {
Operand result_op();
const Program* program_;
type::Manager type_mgr_;
std::string error_;
uint32_t next_id_ = 1;
uint32_t current_label_id_ = 0;