mirror of
https://github.com/KhronosGroup/SPIRV-Tools
synced 2024-11-22 19:50:05 +00:00
These are bookend passes designed to help preserve line information across passes which delete, move and clone instructions. The propagation pass attaches a debug line instruction to every instruction based on SPIR-V line propagation rules. It should be performed before optimization. The redundant line elimination pass eliminates all line instructions which match the previous line instruction. This pass should be performed at the end of optimization to reduce physical SPIR-V file size. Fixes #2027.
This commit is contained in:
parent
ab76e332de
commit
c37388f1ad
@ -131,6 +131,7 @@ SPVTOOLS_OPT_SRC_FILES := \
|
||||
source/opt/pass.cpp \
|
||||
source/opt/pass_manager.cpp \
|
||||
source/opt/private_to_local_pass.cpp \
|
||||
source/opt/process_lines_pass.cpp \
|
||||
source/opt/propagator.cpp \
|
||||
source/opt/reduce_load_size.cpp \
|
||||
source/opt/redundancy_elimination.cpp \
|
||||
|
2
BUILD.gn
2
BUILD.gn
@ -573,6 +573,8 @@ static_library("spvtools_opt") {
|
||||
"source/opt/passes.h",
|
||||
"source/opt/private_to_local_pass.cpp",
|
||||
"source/opt/private_to_local_pass.h",
|
||||
"source/opt/process_lines_pass.cpp",
|
||||
"source/opt/process_lines_pass.h",
|
||||
"source/opt/propagator.cpp",
|
||||
"source/opt/propagator.h",
|
||||
"source/opt/reduce_load_size.cpp",
|
||||
|
@ -499,6 +499,30 @@ Optimizer::PassToken CreateCommonUniformElimPass();
|
||||
// eliminated with standard dead code elimination.
|
||||
Optimizer::PassToken CreateAggressiveDCEPass();
|
||||
|
||||
// Create line propagation pass
|
||||
// This pass propagates line information based on the rules for OpLine and
|
||||
// OpNoline and clones an appropriate line instruction into every instruction
|
||||
// which does not already have debug line instructions.
|
||||
//
|
||||
// This pass is intended to maximize preservation of source line information
|
||||
// through passes which delete, move and clone instructions. Ideally it should
|
||||
// be run before any such pass. It is a bookend pass with EliminateDeadLines
|
||||
// which can be used to remove redundant line instructions at the end of a
|
||||
// run of such passes and reduce final output file size.
|
||||
Optimizer::PassToken CreatePropagateLineInfoPass();
|
||||
|
||||
// Create dead line elimination pass
|
||||
// This pass eliminates redundant line instructions based on the rules for
|
||||
// OpLine and OpNoline. Its main purpose is to reduce the size of the file
|
||||
// need to store the SPIR-V without losing line information.
|
||||
//
|
||||
// This is a bookend pass with PropagateLines which attaches line instructions
|
||||
// to every instruction to preserve line information during passes which
|
||||
// delete, move and clone instructions. DeadLineElim should be run after
|
||||
// PropagateLines and all such subsequent passes. Normally it would be one
|
||||
// of the last passes to be run.
|
||||
Optimizer::PassToken CreateRedundantLineInfoElimPass();
|
||||
|
||||
// Creates a compact ids pass.
|
||||
// The pass remaps result ids to a compact and gapless range starting from %1.
|
||||
Optimizer::PassToken CreateCompactIdsPass();
|
||||
|
@ -77,6 +77,7 @@ set(SPIRV_TOOLS_OPT_SOURCES
|
||||
pass.h
|
||||
pass_manager.h
|
||||
private_to_local_pass.h
|
||||
process_lines_pass.h
|
||||
propagator.h
|
||||
reduce_load_size.h
|
||||
redundancy_elimination.h
|
||||
@ -165,6 +166,7 @@ set(SPIRV_TOOLS_OPT_SOURCES
|
||||
pass.cpp
|
||||
pass_manager.cpp
|
||||
private_to_local_pass.cpp
|
||||
process_lines_pass.cpp
|
||||
propagator.cpp
|
||||
reduce_load_size.cpp
|
||||
redundancy_elimination.cpp
|
||||
|
@ -68,6 +68,13 @@ void Function::ForEachInst(const std::function<void(const Instruction*)>& f,
|
||||
->ForEachInst(f, run_on_debug_line_insts);
|
||||
}
|
||||
|
||||
void Function::ForEachParam(const std::function<void(Instruction*)>& f,
|
||||
bool run_on_debug_line_insts) {
|
||||
for (auto& param : params_)
|
||||
static_cast<Instruction*>(param.get())
|
||||
->ForEachInst(f, run_on_debug_line_insts);
|
||||
}
|
||||
|
||||
void Function::ForEachParam(const std::function<void(const Instruction*)>& f,
|
||||
bool run_on_debug_line_insts) const {
|
||||
for (const auto& param : params_)
|
||||
|
@ -115,6 +115,8 @@ class Function {
|
||||
// and optionally on debug line instructions that might precede them.
|
||||
void ForEachParam(const std::function<void(const Instruction*)>& f,
|
||||
bool run_on_debug_line_insts = false) const;
|
||||
void ForEachParam(const std::function<void(Instruction*)>& f,
|
||||
bool run_on_debug_line_insts = false);
|
||||
|
||||
BasicBlock* InsertBasicBlockAfter(std::unique_ptr<BasicBlock>&& new_block,
|
||||
BasicBlock* position);
|
||||
|
@ -296,6 +296,10 @@ bool Optimizer::RegisterPassFromFlag(const std::string& flag) {
|
||||
RegisterPass(CreateLocalAccessChainConvertPass());
|
||||
} else if (pass_name == "eliminate-dead-code-aggressive") {
|
||||
RegisterPass(CreateAggressiveDCEPass());
|
||||
} else if (pass_name == "propagate-line-info") {
|
||||
RegisterPass(CreatePropagateLineInfoPass());
|
||||
} else if (pass_name == "eliminate-redundant-line-info") {
|
||||
RegisterPass(CreateRedundantLineInfoElimPass());
|
||||
} else if (pass_name == "eliminate-insert-extract") {
|
||||
RegisterPass(CreateInsertExtractElimPass());
|
||||
} else if (pass_name == "eliminate-local-single-block") {
|
||||
@ -624,6 +628,16 @@ Optimizer::PassToken CreateAggressiveDCEPass() {
|
||||
MakeUnique<opt::AggressiveDCEPass>());
|
||||
}
|
||||
|
||||
Optimizer::PassToken CreatePropagateLineInfoPass() {
|
||||
return MakeUnique<Optimizer::PassToken::Impl>(
|
||||
MakeUnique<opt::ProcessLinesPass>(opt::kLinesPropagateLines));
|
||||
}
|
||||
|
||||
Optimizer::PassToken CreateRedundantLineInfoElimPass() {
|
||||
return MakeUnique<Optimizer::PassToken::Impl>(
|
||||
MakeUnique<opt::ProcessLinesPass>(opt::kLinesEliminateDeadLines));
|
||||
}
|
||||
|
||||
Optimizer::PassToken CreateCommonUniformElimPass() {
|
||||
return MakeUnique<Optimizer::PassToken::Impl>(
|
||||
MakeUnique<opt::CommonUniformElimPass>());
|
||||
|
@ -51,6 +51,7 @@
|
||||
#include "source/opt/merge_return_pass.h"
|
||||
#include "source/opt/null_pass.h"
|
||||
#include "source/opt/private_to_local_pass.h"
|
||||
#include "source/opt/process_lines_pass.h"
|
||||
#include "source/opt/reduce_load_size.h"
|
||||
#include "source/opt/redundancy_elimination.h"
|
||||
#include "source/opt/remove_duplicates_pass.h"
|
||||
|
157
source/opt/process_lines_pass.cpp
Normal file
157
source/opt/process_lines_pass.cpp
Normal file
@ -0,0 +1,157 @@
|
||||
// Copyright (c) 2018 The Khronos Group Inc.
|
||||
// Copyright (c) 2018 Valve Corporation
|
||||
// Copyright (c) 2018 LunarG Inc.
|
||||
//
|
||||
// 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 "source/opt/process_lines_pass.h"
|
||||
|
||||
#include <set>
|
||||
#include <unordered_set>
|
||||
#include <vector>
|
||||
|
||||
namespace {
|
||||
|
||||
// Input Operand Indices
|
||||
static const int kSpvLineFileInIdx = 0;
|
||||
static const int kSpvLineLineInIdx = 1;
|
||||
static const int kSpvLineColInIdx = 2;
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
namespace spvtools {
|
||||
namespace opt {
|
||||
|
||||
Pass::Status ProcessLinesPass::Process() {
|
||||
bool modified = ProcessLines();
|
||||
return (modified ? Status::SuccessWithChange : Status::SuccessWithoutChange);
|
||||
}
|
||||
|
||||
bool ProcessLinesPass::ProcessLines() {
|
||||
bool modified = false;
|
||||
uint32_t file_id = 0;
|
||||
uint32_t line = 0;
|
||||
uint32_t col = 0;
|
||||
// Process types, globals, constants
|
||||
for (Instruction& inst : get_module()->types_values())
|
||||
modified |= line_process_func_(&inst, &file_id, &line, &col);
|
||||
// Process functions
|
||||
for (Function& function : *get_module()) {
|
||||
modified |= line_process_func_(&function.DefInst(), &file_id, &line, &col);
|
||||
function.ForEachParam(
|
||||
[this, &modified, &file_id, &line, &col](Instruction* param) {
|
||||
modified |= line_process_func_(param, &file_id, &line, &col);
|
||||
});
|
||||
for (BasicBlock& block : function) {
|
||||
modified |=
|
||||
line_process_func_(block.GetLabelInst(), &file_id, &line, &col);
|
||||
for (Instruction& inst : block) {
|
||||
modified |= line_process_func_(&inst, &file_id, &line, &col);
|
||||
// Don't process terminal instruction if preceeded by merge
|
||||
if (inst.opcode() == SpvOpSelectionMerge ||
|
||||
inst.opcode() == SpvOpLoopMerge)
|
||||
break;
|
||||
}
|
||||
// Nullify line info after each block.
|
||||
file_id = 0;
|
||||
}
|
||||
modified |= line_process_func_(function.EndInst(), &file_id, &line, &col);
|
||||
}
|
||||
return modified;
|
||||
}
|
||||
|
||||
bool ProcessLinesPass::PropagateLine(Instruction* inst, uint32_t* file_id,
|
||||
uint32_t* line, uint32_t* col) {
|
||||
bool modified = false;
|
||||
// only the last debug instruction needs to be considered
|
||||
auto line_itr = inst->dbg_line_insts().rbegin();
|
||||
// if no line instructions, propagate previous info
|
||||
if (line_itr == inst->dbg_line_insts().rend()) {
|
||||
// if no current line info, add OpNoLine, else OpLine
|
||||
if (*file_id == 0)
|
||||
inst->dbg_line_insts().push_back(Instruction(context(), SpvOpNoLine));
|
||||
else
|
||||
inst->dbg_line_insts().push_back(Instruction(
|
||||
context(), SpvOpLine, 0, 0,
|
||||
{{spv_operand_type_t::SPV_OPERAND_TYPE_ID, {*file_id}},
|
||||
{spv_operand_type_t::SPV_OPERAND_TYPE_LITERAL_INTEGER, {*line}},
|
||||
{spv_operand_type_t::SPV_OPERAND_TYPE_LITERAL_INTEGER, {*col}}}));
|
||||
modified = true;
|
||||
} else {
|
||||
// else pre-existing line instruction, so update source line info
|
||||
if (line_itr->opcode() == SpvOpNoLine) {
|
||||
*file_id = 0;
|
||||
} else {
|
||||
assert(line_itr->opcode() == SpvOpLine && "unexpected debug inst");
|
||||
*file_id = line_itr->GetSingleWordInOperand(kSpvLineFileInIdx);
|
||||
*line = line_itr->GetSingleWordInOperand(kSpvLineLineInIdx);
|
||||
*col = line_itr->GetSingleWordInOperand(kSpvLineColInIdx);
|
||||
}
|
||||
}
|
||||
return modified;
|
||||
}
|
||||
|
||||
bool ProcessLinesPass::EliminateDeadLines(Instruction* inst, uint32_t* file_id,
|
||||
uint32_t* line, uint32_t* col) {
|
||||
// If no debug line instructions, return without modifying lines
|
||||
if (inst->dbg_line_insts().empty()) return false;
|
||||
// Only the last debug instruction needs to be considered; delete all others
|
||||
bool modified = inst->dbg_line_insts().size() > 1;
|
||||
Instruction last_inst = inst->dbg_line_insts().back();
|
||||
inst->dbg_line_insts().clear();
|
||||
// If last line is OpNoLine
|
||||
if (last_inst.opcode() == SpvOpNoLine) {
|
||||
// If no propagated line info, throw away redundant OpNoLine
|
||||
if (*file_id == 0) {
|
||||
modified = true;
|
||||
// Else replace OpNoLine and propagate no line info
|
||||
} else {
|
||||
inst->dbg_line_insts().push_back(last_inst);
|
||||
*file_id = 0;
|
||||
}
|
||||
} else {
|
||||
// Else last line is OpLine
|
||||
assert(last_inst.opcode() == SpvOpLine && "unexpected debug inst");
|
||||
// If propagated info matches last line, throw away last line
|
||||
if (*file_id == last_inst.GetSingleWordInOperand(kSpvLineFileInIdx) &&
|
||||
*line == last_inst.GetSingleWordInOperand(kSpvLineLineInIdx) &&
|
||||
*col == last_inst.GetSingleWordInOperand(kSpvLineColInIdx)) {
|
||||
modified = true;
|
||||
} else {
|
||||
// Else replace last line and propagate line info
|
||||
*file_id = last_inst.GetSingleWordInOperand(kSpvLineFileInIdx);
|
||||
*line = last_inst.GetSingleWordInOperand(kSpvLineLineInIdx);
|
||||
*col = last_inst.GetSingleWordInOperand(kSpvLineColInIdx);
|
||||
inst->dbg_line_insts().push_back(last_inst);
|
||||
}
|
||||
}
|
||||
return modified;
|
||||
}
|
||||
|
||||
ProcessLinesPass::ProcessLinesPass(uint32_t func_id) {
|
||||
if (func_id == kLinesPropagateLines) {
|
||||
line_process_func_ = [this](Instruction* inst, uint32_t* file_id,
|
||||
uint32_t* line, uint32_t* col) {
|
||||
return PropagateLine(inst, file_id, line, col);
|
||||
};
|
||||
} else {
|
||||
assert(func_id == kLinesEliminateDeadLines && "unknown Lines param");
|
||||
line_process_func_ = [this](Instruction* inst, uint32_t* file_id,
|
||||
uint32_t* line, uint32_t* col) {
|
||||
return EliminateDeadLines(inst, file_id, line, col);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace opt
|
||||
} // namespace spvtools
|
86
source/opt/process_lines_pass.h
Normal file
86
source/opt/process_lines_pass.h
Normal file
@ -0,0 +1,86 @@
|
||||
// Copyright (c) 2018 The Khronos Group Inc.
|
||||
// Copyright (c) 2018 Valve Corporation
|
||||
// Copyright (c) 2018 LunarG Inc.
|
||||
//
|
||||
// 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 SOURCE_OPT_PROPAGATE_LINES_PASS_H_
|
||||
#define SOURCE_OPT_PROPAGATE_LINES_PASS_H_
|
||||
|
||||
#include "source/opt/function.h"
|
||||
#include "source/opt/ir_context.h"
|
||||
#include "source/opt/pass.h"
|
||||
|
||||
namespace spvtools {
|
||||
namespace opt {
|
||||
|
||||
namespace {
|
||||
|
||||
// Constructor Parameters
|
||||
static const int kLinesPropagateLines = 0;
|
||||
static const int kLinesEliminateDeadLines = 1;
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
// See optimizer.hpp for documentation.
|
||||
class ProcessLinesPass : public Pass {
|
||||
using LineProcessFunction =
|
||||
std::function<bool(Instruction*, uint32_t*, uint32_t*, uint32_t*)>;
|
||||
|
||||
public:
|
||||
ProcessLinesPass(uint32_t func_id);
|
||||
~ProcessLinesPass() = default;
|
||||
|
||||
const char* name() const override { return "propagate-lines"; }
|
||||
|
||||
// See optimizer.hpp for this pass' user documentation.
|
||||
Status Process() override;
|
||||
|
||||
IRContext::Analysis GetPreservedAnalyses() override {
|
||||
return IRContext::kAnalysisDefUse |
|
||||
IRContext::kAnalysisInstrToBlockMapping |
|
||||
IRContext::kAnalysisDecorations | IRContext::kAnalysisCombinators |
|
||||
IRContext::kAnalysisCFG | IRContext::kAnalysisDominatorAnalysis |
|
||||
IRContext::kAnalysisNameMap;
|
||||
}
|
||||
|
||||
private:
|
||||
// If |inst| has no debug line instruction, create one with
|
||||
// |file_id, line, col|. If |inst| has debug line instructions, set
|
||||
// |file_id, line, col| from the last. |file_id| equals 0 indicates no line
|
||||
// info is available. Return true if |inst| modified.
|
||||
bool PropagateLine(Instruction* inst, uint32_t* file_id, uint32_t* line,
|
||||
uint32_t* col);
|
||||
|
||||
// If last debug line instruction of |inst| matches |file_id, line, col|,
|
||||
// delete all debug line instructions of |inst|. If they do not match,
|
||||
// replace all debug line instructions of |inst| with new line instruction
|
||||
// set from |file_id, line, col|. If |inst| has no debug line instructions,
|
||||
// do not modify |inst|. |file_id| equals 0 indicates no line info is
|
||||
// available. Return true if |inst| modified.
|
||||
bool EliminateDeadLines(Instruction* inst, uint32_t* file_id, uint32_t* line,
|
||||
uint32_t* col);
|
||||
|
||||
// Apply lpfn() to all type, constant, global variable and function
|
||||
// instructions in their physical order.
|
||||
bool ProcessLines();
|
||||
|
||||
// A function that calls either PropagateLine or EliminateDeadLines.
|
||||
// Initialized by the class constructor.
|
||||
LineProcessFunction line_process_func_;
|
||||
};
|
||||
|
||||
} // namespace opt
|
||||
} // namespace spvtools
|
||||
|
||||
#endif // SOURCE_OPT_PROPAGATE_LINES_PASS_H_
|
@ -63,6 +63,7 @@ spv_result_t ValidateAdjacency(ValidationState_t& _) {
|
||||
}
|
||||
break;
|
||||
case SpvOpLine:
|
||||
case SpvOpNoLine:
|
||||
break;
|
||||
case SpvOpLoopMerge:
|
||||
adjacency_status = PHI_AND_VAR_INVALID;
|
||||
|
@ -64,6 +64,7 @@ add_spvtools_unittest(TARGET opt
|
||||
pass_test.cpp pass_utils.cpp
|
||||
pass_utils.cpp
|
||||
private_to_local_test.cpp
|
||||
process_lines_test.cpp
|
||||
propagator_test.cpp
|
||||
reduce_load_size_test.cpp
|
||||
redundancy_elimination_test.cpp
|
||||
|
695
test/opt/process_lines_test.cpp
Normal file
695
test/opt/process_lines_test.cpp
Normal file
@ -0,0 +1,695 @@
|
||||
// Copyright (c) 2017 Valve Corporation
|
||||
// Copyright (c) 2017 LunarG Inc.
|
||||
//
|
||||
// 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 <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "test/opt/pass_fixture.h"
|
||||
#include "test/opt/pass_utils.h"
|
||||
|
||||
namespace spvtools {
|
||||
namespace opt {
|
||||
namespace {
|
||||
|
||||
using ProcessLinesTest = PassTest<::testing::Test>;
|
||||
|
||||
TEST_F(ProcessLinesTest, SimplePropagation) {
|
||||
// Texture2D g_tColor[128];
|
||||
//
|
||||
// layout(push_constant) cbuffer PerViewConstantBuffer_t
|
||||
// {
|
||||
// uint g_nDataIdx;
|
||||
// uint g_nDataIdx2;
|
||||
// bool g_B;
|
||||
// };
|
||||
//
|
||||
// SamplerState g_sAniso;
|
||||
//
|
||||
// struct PS_INPUT
|
||||
// {
|
||||
// float2 vTextureCoords : TEXCOORD2;
|
||||
// };
|
||||
//
|
||||
// struct PS_OUTPUT
|
||||
// {
|
||||
// float4 vColor : SV_Target0;
|
||||
// };
|
||||
//
|
||||
// PS_OUTPUT MainPs(PS_INPUT i)
|
||||
// {
|
||||
// PS_OUTPUT ps_output;
|
||||
//
|
||||
// uint u;
|
||||
// if (g_B)
|
||||
// u = g_nDataIdx;
|
||||
// else
|
||||
// u = g_nDataIdx2;
|
||||
// ps_output.vColor = g_tColor[u].Sample(g_sAniso, i.vTextureCoords.xy);
|
||||
// return ps_output;
|
||||
// }
|
||||
|
||||
const std::string predefs =
|
||||
R"(OpCapability Shader
|
||||
%1 = OpExtInstImport "GLSL.std.450"
|
||||
OpMemoryModel Logical GLSL450
|
||||
OpEntryPoint Fragment %MainPs "MainPs" %i_vTextureCoords %_entryPointOutput_vColor
|
||||
OpExecutionMode %MainPs OriginUpperLeft
|
||||
%5 = OpString "foo.frag"
|
||||
OpSource HLSL 500
|
||||
OpName %MainPs "MainPs"
|
||||
OpName %PS_INPUT "PS_INPUT"
|
||||
OpMemberName %PS_INPUT 0 "vTextureCoords"
|
||||
OpName %PS_OUTPUT "PS_OUTPUT"
|
||||
OpMemberName %PS_OUTPUT 0 "vColor"
|
||||
OpName %_MainPs_struct_PS_INPUT_vf21_ "@MainPs(struct-PS_INPUT-vf21;"
|
||||
OpName %i "i"
|
||||
OpName %PerViewConstantBuffer_t "PerViewConstantBuffer_t"
|
||||
OpMemberName %PerViewConstantBuffer_t 0 "g_nDataIdx"
|
||||
OpMemberName %PerViewConstantBuffer_t 1 "g_nDataIdx2"
|
||||
OpMemberName %PerViewConstantBuffer_t 2 "g_B"
|
||||
OpName %_ ""
|
||||
OpName %u "u"
|
||||
OpName %ps_output "ps_output"
|
||||
OpName %g_tColor "g_tColor"
|
||||
OpName %g_sAniso "g_sAniso"
|
||||
OpName %i_0 "i"
|
||||
OpName %i_vTextureCoords "i.vTextureCoords"
|
||||
OpName %_entryPointOutput_vColor "@entryPointOutput.vColor"
|
||||
OpName %param "param"
|
||||
OpMemberDecorate %PerViewConstantBuffer_t 0 Offset 0
|
||||
OpMemberDecorate %PerViewConstantBuffer_t 1 Offset 4
|
||||
OpMemberDecorate %PerViewConstantBuffer_t 2 Offset 8
|
||||
OpDecorate %PerViewConstantBuffer_t Block
|
||||
OpDecorate %g_tColor DescriptorSet 0
|
||||
OpDecorate %g_sAniso DescriptorSet 0
|
||||
OpDecorate %i_vTextureCoords Location 0
|
||||
OpDecorate %_entryPointOutput_vColor Location 0
|
||||
)";
|
||||
|
||||
const std::string before =
|
||||
R"(%void = OpTypeVoid
|
||||
%19 = OpTypeFunction %void
|
||||
%float = OpTypeFloat 32
|
||||
%v2float = OpTypeVector %float 2
|
||||
%PS_INPUT = OpTypeStruct %v2float
|
||||
%_ptr_Function_PS_INPUT = OpTypePointer Function %PS_INPUT
|
||||
%v4float = OpTypeVector %float 4
|
||||
%PS_OUTPUT = OpTypeStruct %v4float
|
||||
%24 = OpTypeFunction %PS_OUTPUT %_ptr_Function_PS_INPUT
|
||||
%uint = OpTypeInt 32 0
|
||||
%PerViewConstantBuffer_t = OpTypeStruct %uint %uint %uint
|
||||
%_ptr_PushConstant_PerViewConstantBuffer_t = OpTypePointer PushConstant %PerViewConstantBuffer_t
|
||||
%_ = OpVariable %_ptr_PushConstant_PerViewConstantBuffer_t PushConstant
|
||||
%int = OpTypeInt 32 1
|
||||
%int_2 = OpConstant %int 2
|
||||
%_ptr_PushConstant_uint = OpTypePointer PushConstant %uint
|
||||
%bool = OpTypeBool
|
||||
%uint_0 = OpConstant %uint 0
|
||||
%_ptr_Function_uint = OpTypePointer Function %uint
|
||||
%int_0 = OpConstant %int 0
|
||||
%int_1 = OpConstant %int 1
|
||||
%_ptr_Function_PS_OUTPUT = OpTypePointer Function %PS_OUTPUT
|
||||
%36 = OpTypeImage %float 2D 0 0 0 1 Unknown
|
||||
%uint_128 = OpConstant %uint 128
|
||||
%_arr_36_uint_128 = OpTypeArray %36 %uint_128
|
||||
%_ptr_UniformConstant__arr_36_uint_128 = OpTypePointer UniformConstant %_arr_36_uint_128
|
||||
%g_tColor = OpVariable %_ptr_UniformConstant__arr_36_uint_128 UniformConstant
|
||||
%_ptr_UniformConstant_36 = OpTypePointer UniformConstant %36
|
||||
%41 = OpTypeSampler
|
||||
%_ptr_UniformConstant_41 = OpTypePointer UniformConstant %41
|
||||
%g_sAniso = OpVariable %_ptr_UniformConstant_41 UniformConstant
|
||||
%43 = OpTypeSampledImage %36
|
||||
%_ptr_Function_v2float = OpTypePointer Function %v2float
|
||||
%_ptr_Function_v4float = OpTypePointer Function %v4float
|
||||
%_ptr_Input_v2float = OpTypePointer Input %v2float
|
||||
%i_vTextureCoords = OpVariable %_ptr_Input_v2float Input
|
||||
%_ptr_Output_v4float = OpTypePointer Output %v4float
|
||||
%_entryPointOutput_vColor = OpVariable %_ptr_Output_v4float Output
|
||||
%MainPs = OpFunction %void None %19
|
||||
%48 = OpLabel
|
||||
%i_0 = OpVariable %_ptr_Function_PS_INPUT Function
|
||||
%param = OpVariable %_ptr_Function_PS_INPUT Function
|
||||
OpLine %5 23 0
|
||||
%49 = OpLoad %v2float %i_vTextureCoords
|
||||
%50 = OpAccessChain %_ptr_Function_v2float %i_0 %int_0
|
||||
OpStore %50 %49
|
||||
%51 = OpLoad %PS_INPUT %i_0
|
||||
OpStore %param %51
|
||||
%52 = OpFunctionCall %PS_OUTPUT %_MainPs_struct_PS_INPUT_vf21_ %param
|
||||
%53 = OpCompositeExtract %v4float %52 0
|
||||
OpStore %_entryPointOutput_vColor %53
|
||||
OpReturn
|
||||
OpFunctionEnd
|
||||
%_MainPs_struct_PS_INPUT_vf21_ = OpFunction %PS_OUTPUT None %24
|
||||
%i = OpFunctionParameter %_ptr_Function_PS_INPUT
|
||||
%54 = OpLabel
|
||||
%u = OpVariable %_ptr_Function_uint Function
|
||||
%ps_output = OpVariable %_ptr_Function_PS_OUTPUT Function
|
||||
OpLine %5 27 0
|
||||
%55 = OpAccessChain %_ptr_PushConstant_uint %_ %int_2
|
||||
%56 = OpLoad %uint %55
|
||||
%57 = OpINotEqual %bool %56 %uint_0
|
||||
OpSelectionMerge %58 None
|
||||
OpBranchConditional %57 %59 %60
|
||||
%59 = OpLabel
|
||||
OpLine %5 28 0
|
||||
%61 = OpAccessChain %_ptr_PushConstant_uint %_ %int_0
|
||||
%62 = OpLoad %uint %61
|
||||
OpStore %u %62
|
||||
OpBranch %58
|
||||
%60 = OpLabel
|
||||
OpLine %5 30 0
|
||||
%63 = OpAccessChain %_ptr_PushConstant_uint %_ %int_1
|
||||
%64 = OpLoad %uint %63
|
||||
OpStore %u %64
|
||||
OpBranch %58
|
||||
%58 = OpLabel
|
||||
OpLine %5 31 0
|
||||
%65 = OpLoad %uint %u
|
||||
%66 = OpAccessChain %_ptr_UniformConstant_36 %g_tColor %65
|
||||
%67 = OpLoad %36 %66
|
||||
%68 = OpLoad %41 %g_sAniso
|
||||
%69 = OpSampledImage %43 %67 %68
|
||||
%70 = OpAccessChain %_ptr_Function_v2float %i %int_0
|
||||
%71 = OpLoad %v2float %70
|
||||
%72 = OpImageSampleImplicitLod %v4float %69 %71
|
||||
%73 = OpAccessChain %_ptr_Function_v4float %ps_output %int_0
|
||||
OpStore %73 %72
|
||||
OpLine %5 32 0
|
||||
%74 = OpLoad %PS_OUTPUT %ps_output
|
||||
OpReturnValue %74
|
||||
OpFunctionEnd
|
||||
)";
|
||||
|
||||
const std::string after =
|
||||
R"(OpNoLine
|
||||
%void = OpTypeVoid
|
||||
OpNoLine
|
||||
%19 = OpTypeFunction %void
|
||||
OpNoLine
|
||||
%float = OpTypeFloat 32
|
||||
OpNoLine
|
||||
%v2float = OpTypeVector %float 2
|
||||
OpNoLine
|
||||
%PS_INPUT = OpTypeStruct %v2float
|
||||
OpNoLine
|
||||
%_ptr_Function_PS_INPUT = OpTypePointer Function %PS_INPUT
|
||||
OpNoLine
|
||||
%v4float = OpTypeVector %float 4
|
||||
OpNoLine
|
||||
%PS_OUTPUT = OpTypeStruct %v4float
|
||||
OpNoLine
|
||||
%24 = OpTypeFunction %PS_OUTPUT %_ptr_Function_PS_INPUT
|
||||
OpNoLine
|
||||
%uint = OpTypeInt 32 0
|
||||
OpNoLine
|
||||
%PerViewConstantBuffer_t = OpTypeStruct %uint %uint %uint
|
||||
OpNoLine
|
||||
%_ptr_PushConstant_PerViewConstantBuffer_t = OpTypePointer PushConstant %PerViewConstantBuffer_t
|
||||
OpNoLine
|
||||
%_ = OpVariable %_ptr_PushConstant_PerViewConstantBuffer_t PushConstant
|
||||
OpNoLine
|
||||
%int = OpTypeInt 32 1
|
||||
OpNoLine
|
||||
%int_2 = OpConstant %int 2
|
||||
OpNoLine
|
||||
%_ptr_PushConstant_uint = OpTypePointer PushConstant %uint
|
||||
OpNoLine
|
||||
%bool = OpTypeBool
|
||||
OpNoLine
|
||||
%uint_0 = OpConstant %uint 0
|
||||
OpNoLine
|
||||
%_ptr_Function_uint = OpTypePointer Function %uint
|
||||
OpNoLine
|
||||
%int_0 = OpConstant %int 0
|
||||
OpNoLine
|
||||
%int_1 = OpConstant %int 1
|
||||
OpNoLine
|
||||
%_ptr_Function_PS_OUTPUT = OpTypePointer Function %PS_OUTPUT
|
||||
OpNoLine
|
||||
%36 = OpTypeImage %float 2D 0 0 0 1 Unknown
|
||||
OpNoLine
|
||||
%uint_128 = OpConstant %uint 128
|
||||
OpNoLine
|
||||
%_arr_36_uint_128 = OpTypeArray %36 %uint_128
|
||||
OpNoLine
|
||||
%_ptr_UniformConstant__arr_36_uint_128 = OpTypePointer UniformConstant %_arr_36_uint_128
|
||||
OpNoLine
|
||||
%g_tColor = OpVariable %_ptr_UniformConstant__arr_36_uint_128 UniformConstant
|
||||
OpNoLine
|
||||
%_ptr_UniformConstant_36 = OpTypePointer UniformConstant %36
|
||||
OpNoLine
|
||||
%41 = OpTypeSampler
|
||||
OpNoLine
|
||||
%_ptr_UniformConstant_41 = OpTypePointer UniformConstant %41
|
||||
OpNoLine
|
||||
%g_sAniso = OpVariable %_ptr_UniformConstant_41 UniformConstant
|
||||
OpNoLine
|
||||
%43 = OpTypeSampledImage %36
|
||||
OpNoLine
|
||||
%_ptr_Function_v2float = OpTypePointer Function %v2float
|
||||
OpNoLine
|
||||
%_ptr_Function_v4float = OpTypePointer Function %v4float
|
||||
OpNoLine
|
||||
%_ptr_Input_v2float = OpTypePointer Input %v2float
|
||||
OpNoLine
|
||||
%i_vTextureCoords = OpVariable %_ptr_Input_v2float Input
|
||||
OpNoLine
|
||||
%_ptr_Output_v4float = OpTypePointer Output %v4float
|
||||
OpNoLine
|
||||
%_entryPointOutput_vColor = OpVariable %_ptr_Output_v4float Output
|
||||
OpNoLine
|
||||
%MainPs = OpFunction %void None %19
|
||||
OpNoLine
|
||||
%48 = OpLabel
|
||||
OpNoLine
|
||||
%i_0 = OpVariable %_ptr_Function_PS_INPUT Function
|
||||
OpNoLine
|
||||
%param = OpVariable %_ptr_Function_PS_INPUT Function
|
||||
OpLine %5 23 0
|
||||
%49 = OpLoad %v2float %i_vTextureCoords
|
||||
OpLine %5 23 0
|
||||
%50 = OpAccessChain %_ptr_Function_v2float %i_0 %int_0
|
||||
OpLine %5 23 0
|
||||
OpStore %50 %49
|
||||
OpLine %5 23 0
|
||||
%51 = OpLoad %PS_INPUT %i_0
|
||||
OpLine %5 23 0
|
||||
OpStore %param %51
|
||||
OpLine %5 23 0
|
||||
%52 = OpFunctionCall %PS_OUTPUT %_MainPs_struct_PS_INPUT_vf21_ %param
|
||||
OpLine %5 23 0
|
||||
%53 = OpCompositeExtract %v4float %52 0
|
||||
OpLine %5 23 0
|
||||
OpStore %_entryPointOutput_vColor %53
|
||||
OpLine %5 23 0
|
||||
OpReturn
|
||||
OpNoLine
|
||||
OpFunctionEnd
|
||||
OpNoLine
|
||||
%_MainPs_struct_PS_INPUT_vf21_ = OpFunction %PS_OUTPUT None %24
|
||||
OpNoLine
|
||||
%i = OpFunctionParameter %_ptr_Function_PS_INPUT
|
||||
OpNoLine
|
||||
%54 = OpLabel
|
||||
OpNoLine
|
||||
%u = OpVariable %_ptr_Function_uint Function
|
||||
OpNoLine
|
||||
%ps_output = OpVariable %_ptr_Function_PS_OUTPUT Function
|
||||
OpLine %5 27 0
|
||||
%55 = OpAccessChain %_ptr_PushConstant_uint %_ %int_2
|
||||
OpLine %5 27 0
|
||||
%56 = OpLoad %uint %55
|
||||
OpLine %5 27 0
|
||||
%57 = OpINotEqual %bool %56 %uint_0
|
||||
OpLine %5 27 0
|
||||
OpSelectionMerge %58 None
|
||||
OpBranchConditional %57 %59 %60
|
||||
OpNoLine
|
||||
%59 = OpLabel
|
||||
OpLine %5 28 0
|
||||
%61 = OpAccessChain %_ptr_PushConstant_uint %_ %int_0
|
||||
OpLine %5 28 0
|
||||
%62 = OpLoad %uint %61
|
||||
OpLine %5 28 0
|
||||
OpStore %u %62
|
||||
OpLine %5 28 0
|
||||
OpBranch %58
|
||||
OpNoLine
|
||||
%60 = OpLabel
|
||||
OpLine %5 30 0
|
||||
%63 = OpAccessChain %_ptr_PushConstant_uint %_ %int_1
|
||||
OpLine %5 30 0
|
||||
%64 = OpLoad %uint %63
|
||||
OpLine %5 30 0
|
||||
OpStore %u %64
|
||||
OpLine %5 30 0
|
||||
OpBranch %58
|
||||
OpNoLine
|
||||
%58 = OpLabel
|
||||
OpLine %5 31 0
|
||||
%65 = OpLoad %uint %u
|
||||
OpLine %5 31 0
|
||||
%66 = OpAccessChain %_ptr_UniformConstant_36 %g_tColor %65
|
||||
OpLine %5 31 0
|
||||
%67 = OpLoad %36 %66
|
||||
OpLine %5 31 0
|
||||
%68 = OpLoad %41 %g_sAniso
|
||||
OpLine %5 31 0
|
||||
%69 = OpSampledImage %43 %67 %68
|
||||
OpLine %5 31 0
|
||||
%70 = OpAccessChain %_ptr_Function_v2float %i %int_0
|
||||
OpLine %5 31 0
|
||||
%71 = OpLoad %v2float %70
|
||||
OpLine %5 31 0
|
||||
%72 = OpImageSampleImplicitLod %v4float %69 %71
|
||||
OpLine %5 31 0
|
||||
%73 = OpAccessChain %_ptr_Function_v4float %ps_output %int_0
|
||||
OpLine %5 31 0
|
||||
OpStore %73 %72
|
||||
OpLine %5 32 0
|
||||
%74 = OpLoad %PS_OUTPUT %ps_output
|
||||
OpLine %5 32 0
|
||||
OpReturnValue %74
|
||||
OpNoLine
|
||||
OpFunctionEnd
|
||||
)";
|
||||
|
||||
SinglePassRunAndCheck<ProcessLinesPass>(predefs + before, predefs + after,
|
||||
false, true, kLinesPropagateLines);
|
||||
}
|
||||
|
||||
TEST_F(ProcessLinesTest, SimpleElimination) {
|
||||
// Previous test with before and after reversed
|
||||
|
||||
const std::string predefs =
|
||||
R"(OpCapability Shader
|
||||
%1 = OpExtInstImport "GLSL.std.450"
|
||||
OpMemoryModel Logical GLSL450
|
||||
OpEntryPoint Fragment %MainPs "MainPs" %i_vTextureCoords %_entryPointOutput_vColor
|
||||
OpExecutionMode %MainPs OriginUpperLeft
|
||||
%5 = OpString "foo.frag"
|
||||
OpSource HLSL 500
|
||||
OpName %MainPs "MainPs"
|
||||
OpName %PS_INPUT "PS_INPUT"
|
||||
OpMemberName %PS_INPUT 0 "vTextureCoords"
|
||||
OpName %PS_OUTPUT "PS_OUTPUT"
|
||||
OpMemberName %PS_OUTPUT 0 "vColor"
|
||||
OpName %_MainPs_struct_PS_INPUT_vf21_ "@MainPs(struct-PS_INPUT-vf21;"
|
||||
OpName %i "i"
|
||||
OpName %PerViewConstantBuffer_t "PerViewConstantBuffer_t"
|
||||
OpMemberName %PerViewConstantBuffer_t 0 "g_nDataIdx"
|
||||
OpMemberName %PerViewConstantBuffer_t 1 "g_nDataIdx2"
|
||||
OpMemberName %PerViewConstantBuffer_t 2 "g_B"
|
||||
OpName %_ ""
|
||||
OpName %u "u"
|
||||
OpName %ps_output "ps_output"
|
||||
OpName %g_tColor "g_tColor"
|
||||
OpName %g_sAniso "g_sAniso"
|
||||
OpName %i_0 "i"
|
||||
OpName %i_vTextureCoords "i.vTextureCoords"
|
||||
OpName %_entryPointOutput_vColor "@entryPointOutput.vColor"
|
||||
OpName %param "param"
|
||||
OpMemberDecorate %PerViewConstantBuffer_t 0 Offset 0
|
||||
OpMemberDecorate %PerViewConstantBuffer_t 1 Offset 4
|
||||
OpMemberDecorate %PerViewConstantBuffer_t 2 Offset 8
|
||||
OpDecorate %PerViewConstantBuffer_t Block
|
||||
OpDecorate %g_tColor DescriptorSet 0
|
||||
OpDecorate %g_sAniso DescriptorSet 0
|
||||
OpDecorate %i_vTextureCoords Location 0
|
||||
OpDecorate %_entryPointOutput_vColor Location 0
|
||||
)";
|
||||
|
||||
const std::string before =
|
||||
R"(OpNoLine
|
||||
%void = OpTypeVoid
|
||||
OpNoLine
|
||||
%19 = OpTypeFunction %void
|
||||
OpNoLine
|
||||
%float = OpTypeFloat 32
|
||||
OpNoLine
|
||||
%v2float = OpTypeVector %float 2
|
||||
OpNoLine
|
||||
%PS_INPUT = OpTypeStruct %v2float
|
||||
OpNoLine
|
||||
%_ptr_Function_PS_INPUT = OpTypePointer Function %PS_INPUT
|
||||
OpNoLine
|
||||
%v4float = OpTypeVector %float 4
|
||||
OpNoLine
|
||||
%PS_OUTPUT = OpTypeStruct %v4float
|
||||
OpNoLine
|
||||
%24 = OpTypeFunction %PS_OUTPUT %_ptr_Function_PS_INPUT
|
||||
OpNoLine
|
||||
%uint = OpTypeInt 32 0
|
||||
OpNoLine
|
||||
%PerViewConstantBuffer_t = OpTypeStruct %uint %uint %uint
|
||||
OpNoLine
|
||||
%_ptr_PushConstant_PerViewConstantBuffer_t = OpTypePointer PushConstant %PerViewConstantBuffer_t
|
||||
OpNoLine
|
||||
%_ = OpVariable %_ptr_PushConstant_PerViewConstantBuffer_t PushConstant
|
||||
OpNoLine
|
||||
%int = OpTypeInt 32 1
|
||||
OpNoLine
|
||||
%int_2 = OpConstant %int 2
|
||||
OpNoLine
|
||||
%_ptr_PushConstant_uint = OpTypePointer PushConstant %uint
|
||||
OpNoLine
|
||||
%bool = OpTypeBool
|
||||
OpNoLine
|
||||
%uint_0 = OpConstant %uint 0
|
||||
OpNoLine
|
||||
%_ptr_Function_uint = OpTypePointer Function %uint
|
||||
OpNoLine
|
||||
%int_0 = OpConstant %int 0
|
||||
OpNoLine
|
||||
%int_1 = OpConstant %int 1
|
||||
OpNoLine
|
||||
%_ptr_Function_PS_OUTPUT = OpTypePointer Function %PS_OUTPUT
|
||||
OpNoLine
|
||||
%36 = OpTypeImage %float 2D 0 0 0 1 Unknown
|
||||
OpNoLine
|
||||
%uint_128 = OpConstant %uint 128
|
||||
OpNoLine
|
||||
%_arr_36_uint_128 = OpTypeArray %36 %uint_128
|
||||
OpNoLine
|
||||
%_ptr_UniformConstant__arr_36_uint_128 = OpTypePointer UniformConstant %_arr_36_uint_128
|
||||
OpNoLine
|
||||
%g_tColor = OpVariable %_ptr_UniformConstant__arr_36_uint_128 UniformConstant
|
||||
OpNoLine
|
||||
%_ptr_UniformConstant_36 = OpTypePointer UniformConstant %36
|
||||
OpNoLine
|
||||
%41 = OpTypeSampler
|
||||
OpNoLine
|
||||
%_ptr_UniformConstant_41 = OpTypePointer UniformConstant %41
|
||||
OpNoLine
|
||||
%g_sAniso = OpVariable %_ptr_UniformConstant_41 UniformConstant
|
||||
OpNoLine
|
||||
%43 = OpTypeSampledImage %36
|
||||
OpNoLine
|
||||
%_ptr_Function_v2float = OpTypePointer Function %v2float
|
||||
OpNoLine
|
||||
%_ptr_Function_v4float = OpTypePointer Function %v4float
|
||||
OpNoLine
|
||||
%_ptr_Input_v2float = OpTypePointer Input %v2float
|
||||
OpNoLine
|
||||
%i_vTextureCoords = OpVariable %_ptr_Input_v2float Input
|
||||
OpNoLine
|
||||
%_ptr_Output_v4float = OpTypePointer Output %v4float
|
||||
OpNoLine
|
||||
%_entryPointOutput_vColor = OpVariable %_ptr_Output_v4float Output
|
||||
OpNoLine
|
||||
%MainPs = OpFunction %void None %19
|
||||
OpNoLine
|
||||
%48 = OpLabel
|
||||
OpNoLine
|
||||
%i_0 = OpVariable %_ptr_Function_PS_INPUT Function
|
||||
OpNoLine
|
||||
%param = OpVariable %_ptr_Function_PS_INPUT Function
|
||||
OpLine %5 23 0
|
||||
%49 = OpLoad %v2float %i_vTextureCoords
|
||||
OpLine %5 23 0
|
||||
%50 = OpAccessChain %_ptr_Function_v2float %i_0 %int_0
|
||||
OpLine %5 23 0
|
||||
OpStore %50 %49
|
||||
OpLine %5 23 0
|
||||
%51 = OpLoad %PS_INPUT %i_0
|
||||
OpLine %5 23 0
|
||||
OpStore %param %51
|
||||
OpLine %5 23 0
|
||||
%52 = OpFunctionCall %PS_OUTPUT %_MainPs_struct_PS_INPUT_vf21_ %param
|
||||
OpLine %5 23 0
|
||||
%53 = OpCompositeExtract %v4float %52 0
|
||||
OpLine %5 23 0
|
||||
OpStore %_entryPointOutput_vColor %53
|
||||
OpLine %5 23 0
|
||||
OpReturn
|
||||
OpNoLine
|
||||
OpFunctionEnd
|
||||
OpNoLine
|
||||
%_MainPs_struct_PS_INPUT_vf21_ = OpFunction %PS_OUTPUT None %24
|
||||
OpNoLine
|
||||
%i = OpFunctionParameter %_ptr_Function_PS_INPUT
|
||||
OpNoLine
|
||||
%54 = OpLabel
|
||||
OpNoLine
|
||||
%u = OpVariable %_ptr_Function_uint Function
|
||||
OpNoLine
|
||||
%ps_output = OpVariable %_ptr_Function_PS_OUTPUT Function
|
||||
OpLine %5 27 0
|
||||
%55 = OpAccessChain %_ptr_PushConstant_uint %_ %int_2
|
||||
OpLine %5 27 0
|
||||
%56 = OpLoad %uint %55
|
||||
OpLine %5 27 0
|
||||
%57 = OpINotEqual %bool %56 %uint_0
|
||||
OpLine %5 27 0
|
||||
OpSelectionMerge %58 None
|
||||
OpBranchConditional %57 %59 %60
|
||||
OpNoLine
|
||||
%59 = OpLabel
|
||||
OpLine %5 28 0
|
||||
%61 = OpAccessChain %_ptr_PushConstant_uint %_ %int_0
|
||||
OpLine %5 28 0
|
||||
%62 = OpLoad %uint %61
|
||||
OpLine %5 28 0
|
||||
OpStore %u %62
|
||||
OpLine %5 28 0
|
||||
OpBranch %58
|
||||
OpNoLine
|
||||
%60 = OpLabel
|
||||
OpLine %5 30 0
|
||||
%63 = OpAccessChain %_ptr_PushConstant_uint %_ %int_1
|
||||
OpLine %5 30 0
|
||||
%64 = OpLoad %uint %63
|
||||
OpLine %5 30 0
|
||||
OpStore %u %64
|
||||
OpLine %5 30 0
|
||||
OpBranch %58
|
||||
OpNoLine
|
||||
%58 = OpLabel
|
||||
OpLine %5 31 0
|
||||
%65 = OpLoad %uint %u
|
||||
OpLine %5 31 0
|
||||
%66 = OpAccessChain %_ptr_UniformConstant_36 %g_tColor %65
|
||||
OpLine %5 31 0
|
||||
%67 = OpLoad %36 %66
|
||||
OpLine %5 31 0
|
||||
%68 = OpLoad %41 %g_sAniso
|
||||
OpLine %5 31 0
|
||||
%69 = OpSampledImage %43 %67 %68
|
||||
OpLine %5 31 0
|
||||
%70 = OpAccessChain %_ptr_Function_v2float %i %int_0
|
||||
OpLine %5 31 0
|
||||
%71 = OpLoad %v2float %70
|
||||
OpLine %5 31 0
|
||||
%72 = OpImageSampleImplicitLod %v4float %69 %71
|
||||
OpLine %5 31 0
|
||||
%73 = OpAccessChain %_ptr_Function_v4float %ps_output %int_0
|
||||
OpLine %5 31 0
|
||||
OpStore %73 %72
|
||||
OpLine %5 32 0
|
||||
%74 = OpLoad %PS_OUTPUT %ps_output
|
||||
OpLine %5 32 0
|
||||
OpReturnValue %74
|
||||
OpNoLine
|
||||
OpFunctionEnd
|
||||
)";
|
||||
|
||||
const std::string after =
|
||||
R"(%void = OpTypeVoid
|
||||
%19 = OpTypeFunction %void
|
||||
%float = OpTypeFloat 32
|
||||
%v2float = OpTypeVector %float 2
|
||||
%PS_INPUT = OpTypeStruct %v2float
|
||||
%_ptr_Function_PS_INPUT = OpTypePointer Function %PS_INPUT
|
||||
%v4float = OpTypeVector %float 4
|
||||
%PS_OUTPUT = OpTypeStruct %v4float
|
||||
%24 = OpTypeFunction %PS_OUTPUT %_ptr_Function_PS_INPUT
|
||||
%uint = OpTypeInt 32 0
|
||||
%PerViewConstantBuffer_t = OpTypeStruct %uint %uint %uint
|
||||
%_ptr_PushConstant_PerViewConstantBuffer_t = OpTypePointer PushConstant %PerViewConstantBuffer_t
|
||||
%_ = OpVariable %_ptr_PushConstant_PerViewConstantBuffer_t PushConstant
|
||||
%int = OpTypeInt 32 1
|
||||
%int_2 = OpConstant %int 2
|
||||
%_ptr_PushConstant_uint = OpTypePointer PushConstant %uint
|
||||
%bool = OpTypeBool
|
||||
%uint_0 = OpConstant %uint 0
|
||||
%_ptr_Function_uint = OpTypePointer Function %uint
|
||||
%int_0 = OpConstant %int 0
|
||||
%int_1 = OpConstant %int 1
|
||||
%_ptr_Function_PS_OUTPUT = OpTypePointer Function %PS_OUTPUT
|
||||
%36 = OpTypeImage %float 2D 0 0 0 1 Unknown
|
||||
%uint_128 = OpConstant %uint 128
|
||||
%_arr_36_uint_128 = OpTypeArray %36 %uint_128
|
||||
%_ptr_UniformConstant__arr_36_uint_128 = OpTypePointer UniformConstant %_arr_36_uint_128
|
||||
%g_tColor = OpVariable %_ptr_UniformConstant__arr_36_uint_128 UniformConstant
|
||||
%_ptr_UniformConstant_36 = OpTypePointer UniformConstant %36
|
||||
%41 = OpTypeSampler
|
||||
%_ptr_UniformConstant_41 = OpTypePointer UniformConstant %41
|
||||
%g_sAniso = OpVariable %_ptr_UniformConstant_41 UniformConstant
|
||||
%43 = OpTypeSampledImage %36
|
||||
%_ptr_Function_v2float = OpTypePointer Function %v2float
|
||||
%_ptr_Function_v4float = OpTypePointer Function %v4float
|
||||
%_ptr_Input_v2float = OpTypePointer Input %v2float
|
||||
%i_vTextureCoords = OpVariable %_ptr_Input_v2float Input
|
||||
%_ptr_Output_v4float = OpTypePointer Output %v4float
|
||||
%_entryPointOutput_vColor = OpVariable %_ptr_Output_v4float Output
|
||||
%MainPs = OpFunction %void None %19
|
||||
%48 = OpLabel
|
||||
%i_0 = OpVariable %_ptr_Function_PS_INPUT Function
|
||||
%param = OpVariable %_ptr_Function_PS_INPUT Function
|
||||
OpLine %5 23 0
|
||||
%49 = OpLoad %v2float %i_vTextureCoords
|
||||
%50 = OpAccessChain %_ptr_Function_v2float %i_0 %int_0
|
||||
OpStore %50 %49
|
||||
%51 = OpLoad %PS_INPUT %i_0
|
||||
OpStore %param %51
|
||||
%52 = OpFunctionCall %PS_OUTPUT %_MainPs_struct_PS_INPUT_vf21_ %param
|
||||
%53 = OpCompositeExtract %v4float %52 0
|
||||
OpStore %_entryPointOutput_vColor %53
|
||||
OpReturn
|
||||
OpFunctionEnd
|
||||
%_MainPs_struct_PS_INPUT_vf21_ = OpFunction %PS_OUTPUT None %24
|
||||
%i = OpFunctionParameter %_ptr_Function_PS_INPUT
|
||||
%54 = OpLabel
|
||||
%u = OpVariable %_ptr_Function_uint Function
|
||||
%ps_output = OpVariable %_ptr_Function_PS_OUTPUT Function
|
||||
OpLine %5 27 0
|
||||
%55 = OpAccessChain %_ptr_PushConstant_uint %_ %int_2
|
||||
%56 = OpLoad %uint %55
|
||||
%57 = OpINotEqual %bool %56 %uint_0
|
||||
OpSelectionMerge %58 None
|
||||
OpBranchConditional %57 %59 %60
|
||||
%59 = OpLabel
|
||||
OpLine %5 28 0
|
||||
%61 = OpAccessChain %_ptr_PushConstant_uint %_ %int_0
|
||||
%62 = OpLoad %uint %61
|
||||
OpStore %u %62
|
||||
OpBranch %58
|
||||
%60 = OpLabel
|
||||
OpLine %5 30 0
|
||||
%63 = OpAccessChain %_ptr_PushConstant_uint %_ %int_1
|
||||
%64 = OpLoad %uint %63
|
||||
OpStore %u %64
|
||||
OpBranch %58
|
||||
%58 = OpLabel
|
||||
OpLine %5 31 0
|
||||
%65 = OpLoad %uint %u
|
||||
%66 = OpAccessChain %_ptr_UniformConstant_36 %g_tColor %65
|
||||
%67 = OpLoad %36 %66
|
||||
%68 = OpLoad %41 %g_sAniso
|
||||
%69 = OpSampledImage %43 %67 %68
|
||||
%70 = OpAccessChain %_ptr_Function_v2float %i %int_0
|
||||
%71 = OpLoad %v2float %70
|
||||
%72 = OpImageSampleImplicitLod %v4float %69 %71
|
||||
%73 = OpAccessChain %_ptr_Function_v4float %ps_output %int_0
|
||||
OpStore %73 %72
|
||||
OpLine %5 32 0
|
||||
%74 = OpLoad %PS_OUTPUT %ps_output
|
||||
OpReturnValue %74
|
||||
OpFunctionEnd
|
||||
)";
|
||||
|
||||
SinglePassRunAndCheck<ProcessLinesPass>(
|
||||
predefs + before, predefs + after, false, true, kLinesEliminateDeadLines);
|
||||
}
|
||||
|
||||
// TODO(greg-lunarg): Add tests to verify handling of these cases:
|
||||
//
|
||||
// TODO(greg-lunarg): Think about other tests :)
|
||||
|
||||
} // namespace
|
||||
} // namespace opt
|
||||
} // namespace spvtools
|
Loading…
Reference in New Issue
Block a user