mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-12 22:28:32 +09:00
[Fix] (MG_Util/ShaderTranspiler): keep decomposed workgroup types before globals
This commit is contained in:
@@ -822,6 +822,10 @@ layout(std430, binding = 0) writeonly buffer OutputBuffer {
|
|||||||
vec4 out_data[];
|
vec4 out_data[];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
vec3 evaluate_row(vec3 row_values[9], uint col) {
|
||||||
|
return row_values[col] + row_values[0];
|
||||||
|
}
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
uint row = gl_LocalInvocationIndex;
|
uint row = gl_LocalInvocationIndex;
|
||||||
uint col = u_col;
|
uint col = u_col;
|
||||||
@@ -837,7 +841,7 @@ void main() {
|
|||||||
memoryBarrierShared();
|
memoryBarrierShared();
|
||||||
barrier();
|
barrier();
|
||||||
|
|
||||||
out_data[gl_GlobalInvocationID.x] = vec4(loaded + rowCopy[col] + vec3(x), 1.0);
|
out_data[gl_GlobalInvocationID.x] = vec4(loaded + rowCopy[col] + evaluate_row(shared_memory[0], col) + vec3(x), 1.0);
|
||||||
}
|
}
|
||||||
)";
|
)";
|
||||||
|
|
||||||
@@ -874,13 +878,17 @@ TEST_F(ProgramUtilTest, DecomposeWorkgroupVec3InSpirvPass) {
|
|||||||
<< "SanitizeAndOptimizeBinary failed - the DecomposeWorkgroupVec3Pass may have "
|
<< "SanitizeAndOptimizeBinary failed - the DecomposeWorkgroupVec3Pass may have "
|
||||||
"encountered an unsupported pattern";
|
"encountered an unsupported pattern";
|
||||||
|
|
||||||
|
spvtools::Optimizer parseOnlyOptimizer(SPV_ENV_VULKAN_1_1);
|
||||||
|
Vector<uint32_t> parsedBinary;
|
||||||
|
ASSERT_TRUE(parseOnlyOptimizer.Run(optimized.data(), optimized.size(), &parsedBinary))
|
||||||
|
<< "DecomposeWorkgroupVec3Pass emitted SPIR-V with invalid physical layout";
|
||||||
|
|
||||||
SpvcSession session(optimized, SessionUsageBit::Transpile);
|
SpvcSession session(optimized, SessionUsageBit::Transpile);
|
||||||
auto sourceRes = ShaderCompiler::DecompileShader(session);
|
auto sourceRes = ShaderCompiler::DecompileShader(session);
|
||||||
ASSERT_TRUE(sourceRes.has_value()) << "errc: " << sourceRes.error().errc
|
ASSERT_TRUE(sourceRes.has_value()) << "errc: " << sourceRes.error().errc
|
||||||
<< "\nlog: " << sourceRes.error().log;
|
<< "\nlog: " << sourceRes.error().log;
|
||||||
|
|
||||||
const String& source = sourceRes.value();
|
const String& source = sourceRes.value();
|
||||||
|
|
||||||
// The decomposed output must not contain a `shared vec3` declaration.
|
// The decomposed output must not contain a `shared vec3` declaration.
|
||||||
EXPECT_EQ(source.find("shared vec3"), std::string::npos)
|
EXPECT_EQ(source.find("shared vec3"), std::string::npos)
|
||||||
<< "DecomposeWorkgroupVec3Pass did not eliminate `shared vec3`:\n"
|
<< "DecomposeWorkgroupVec3Pass did not eliminate `shared vec3`:\n"
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
#include "source/opt/instruction.h"
|
#include "source/opt/instruction.h"
|
||||||
#include "source/opt/ir_context.h"
|
#include "source/opt/ir_context.h"
|
||||||
#include "source/opt/module.h"
|
#include "source/opt/module.h"
|
||||||
|
#include "source/opt/reflect.h"
|
||||||
#include "source/opt/type_manager.h"
|
#include "source/opt/type_manager.h"
|
||||||
#include "spirv.hpp"
|
#include "spirv.hpp"
|
||||||
|
|
||||||
@@ -308,6 +309,39 @@ namespace MobileGL {
|
|||||||
|
|
||||||
assert(false && "DecomposeWorkgroupVec3Pass: unsupported composite store type");
|
assert(false && "DecomposeWorkgroupVec3Pass: unsupported composite store type");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MoveLateTypesConstantsBeforeGlobalVariables(IRContext* context) {
|
||||||
|
Instruction* firstVariable = nullptr;
|
||||||
|
for (Instruction& inst : context->module()->types_values()) {
|
||||||
|
if (inst.opcode() == spv::Op::OpVariable) {
|
||||||
|
firstVariable = &inst;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (firstVariable == nullptr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool sawFirstVariable = false;
|
||||||
|
for (auto it = context->module()->types_values_begin();
|
||||||
|
it != context->module()->types_values_end();) {
|
||||||
|
Instruction* inst = &*it;
|
||||||
|
++it;
|
||||||
|
|
||||||
|
if (inst == firstVariable) {
|
||||||
|
sawFirstVariable = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sawFirstVariable &&
|
||||||
|
(spvtools::opt::IsTypeInst(inst->opcode()) ||
|
||||||
|
spvtools::opt::IsConstantInst(inst->opcode()) ||
|
||||||
|
inst->opcode() == spv::Op::OpUndef)) {
|
||||||
|
inst->InsertBefore(firstVariable);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
spvtools::opt::Pass::Status DecomposeWorkgroupVec3Pass::Process() {
|
spvtools::opt::Pass::Status DecomposeWorkgroupVec3Pass::Process() {
|
||||||
@@ -605,6 +639,8 @@ namespace MobileGL {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MoveLateTypesConstantsBeforeGlobalVariables(ctx);
|
||||||
|
|
||||||
return Status::SuccessWithChange;
|
return Status::SuccessWithChange;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user