| 392 | } |
| 393 | |
| 394 | CodeGenerator GetVariableCodeGenerator(const char* const built_in, |
| 395 | const char* const execution_model, |
| 396 | const char* const storage_class, |
| 397 | const char* const capabilities, |
| 398 | const char* const extensions, |
| 399 | const char* const data_type) { |
| 400 | CodeGenerator generator = CodeGenerator::GetDefaultShaderCodeGenerator(); |
| 401 | |
| 402 | if (capabilities) { |
| 403 | generator.capabilities_ += capabilities; |
| 404 | } |
| 405 | if (extensions) { |
| 406 | generator.extensions_ += extensions; |
| 407 | } |
| 408 | |
| 409 | generator.before_types_ = "OpDecorate %built_in_var BuiltIn "; |
| 410 | generator.before_types_ += built_in; |
| 411 | generator.before_types_ += "\n"; |
| 412 | |
| 413 | if (strncmp(built_in, "TessLevel", 9) == 0) { |
| 414 | generator.before_types_ += "OpDecorate %built_in_var Patch\n"; |
| 415 | } |
| 416 | |
| 417 | if ((0 == std::strcmp(storage_class, "Input")) && |
| 418 | (0 == std::strcmp(execution_model, "Fragment"))) { |
| 419 | // ensure any needed input types that might require Flat |
| 420 | generator.before_types_ += "OpDecorate %built_in_var Flat\n"; |
| 421 | } |
| 422 | |
| 423 | std::ostringstream after_types; |
| 424 | if (InitializerRequired(storage_class)) { |
| 425 | after_types << "%built_in_null = OpConstantNull " << data_type << "\n"; |
| 426 | } |
| 427 | after_types << "%built_in_ptr = OpTypePointer " << storage_class << " " |
| 428 | << data_type << "\n"; |
| 429 | after_types << "%built_in_var = OpVariable %built_in_ptr " << storage_class; |
| 430 | if (InitializerRequired(storage_class)) { |
| 431 | after_types << " %built_in_null"; |
| 432 | } |
| 433 | after_types << "\n"; |
| 434 | generator.after_types_ = after_types.str(); |
| 435 | |
| 436 | EntryPoint entry_point; |
| 437 | entry_point.name = "main"; |
| 438 | entry_point.execution_model = execution_model; |
| 439 | if (strncmp(storage_class, "Input", 5) == 0 || |
| 440 | strncmp(storage_class, "Output", 6) == 0) { |
| 441 | entry_point.interfaces = "%built_in_var"; |
| 442 | } |
| 443 | // Any kind of reference would do. |
| 444 | entry_point.body = R"( |
| 445 | %val = OpCopyObject %built_in_ptr %built_in_var |
| 446 | )"; |
| 447 | |
| 448 | std::ostringstream execution_modes; |
| 449 | if (0 == std::strcmp(execution_model, "Fragment")) { |
| 450 | execution_modes << "OpExecutionMode %" << entry_point.name |
| 451 | << " OriginUpperLeft\n"; |
no test coverage detected