| 389 | } |
| 390 | } |
| 391 | void reshadefx::expression::add_swizzle_access(const signed char swizzle[4], unsigned int length) |
| 392 | { |
| 393 | assert(type.is_numeric() && !type.is_array()); |
| 394 | assert(length <= 4); |
| 395 | |
| 396 | const struct type prev_type = type; |
| 397 | |
| 398 | type.rows = length; |
| 399 | type.cols = 1; |
| 400 | |
| 401 | // To form a l-value, swizzling must contain no duplicate components |
| 402 | for (unsigned int i = 0; i < length; ++i) |
| 403 | for (unsigned int k = i + 1; k < length; ++k) |
| 404 | if (swizzle[k] == swizzle[i]) |
| 405 | type.qualifiers |= type::q_const; |
| 406 | |
| 407 | if (is_constant) |
| 408 | { |
| 409 | assert(constant.array_data.empty()); |
| 410 | |
| 411 | uint32_t data[16]; |
| 412 | std::memcpy(data, &constant.as_uint[0], sizeof(data)); |
| 413 | for (unsigned int i = 0; i < length; ++i) |
| 414 | constant.as_uint[i] = data[swizzle[i]]; |
| 415 | std::memset(&constant.as_uint[length], 0, sizeof(uint32_t) * (16 - length)); // Clear the rest of the constant |
| 416 | } |
| 417 | else if (length == 1 && prev_type.is_vector()) // Use indexing when possible since the code generation logic is simpler in SPIR-V |
| 418 | { |
| 419 | chain.push_back({ operation::op_constant_index, prev_type, type, static_cast<uint32_t>(swizzle[0]) }); |
| 420 | } |
| 421 | else if (prev_type.is_matrix()) |
| 422 | { |
| 423 | chain.push_back({ operation::op_matrix_swizzle, prev_type, type, 0, { swizzle[0], swizzle[1], swizzle[2], swizzle[3] } }); |
| 424 | } |
| 425 | else |
| 426 | { |
| 427 | chain.push_back({ operation::op_swizzle, prev_type, type, 0, { swizzle[0], swizzle[1], swizzle[2], swizzle[3] } }); |
| 428 | } |
| 429 | } |
| 430 | |
| 431 | bool reshadefx::expression::evaluate_constant_expression(reshadefx::tokenid op) |
| 432 | { |
no test coverage detected