|
1478 | 1478 | <a href="#1477" id="1477">1477</a> |
1479 | 1479 | <a href="#1478" id="1478">1478</a> |
1480 | 1480 | <a href="#1479" id="1479">1479</a> |
| 1481 | +<a href="#1480" id="1480">1480</a> |
| 1482 | +<a href="#1481" id="1481">1481</a> |
| 1483 | +<a href="#1482" id="1482">1482</a> |
| 1484 | +<a href="#1483" id="1483">1483</a> |
| 1485 | +<a href="#1484" id="1484">1484</a> |
| 1486 | +<a href="#1485" id="1485">1485</a> |
| 1487 | +<a href="#1486" id="1486">1486</a> |
| 1488 | +<a href="#1487" id="1487">1487</a> |
| 1489 | +<a href="#1488" id="1488">1488</a> |
| 1490 | +<a href="#1489" id="1489">1489</a> |
1481 | 1491 | </pre></div><pre class="rust"><code><span class="kw">use </span><span class="kw">crate</span>::arena::{Arena, UniqueArena}; |
1482 | 1492 | <span class="kw">use </span><span class="kw">crate</span>::arena::{Handle, HandleSet}; |
1483 | 1493 |
|
|
2492 | 2502 | } => { |
2493 | 2503 | <span class="comment">//Note: this code uses a lot of `FunctionError::InvalidImageStore`, |
2494 | 2504 | // and could probably be refactored. |
2495 | | - </span><span class="kw">let </span>var = <span class="kw">match </span><span class="kw-2">*</span>context.get_expression(image) { |
| 2505 | + </span><span class="kw">let </span>global_var; |
| 2506 | + <span class="kw">let </span>image_ty; |
| 2507 | + <span class="kw">match </span><span class="kw-2">*</span>context.get_expression(image) { |
2496 | 2508 | <span class="kw">crate</span>::Expression::GlobalVariable(var_handle) => { |
2497 | | - <span class="kw-2">&</span>context.global_vars[var_handle] |
| 2509 | + global_var = <span class="kw-2">&</span>context.global_vars[var_handle]; |
| 2510 | + image_ty = global_var.ty; |
2498 | 2511 | } |
2499 | | - <span class="comment">// We're looking at a binding index situation, so punch through the index and look at the global behind it. |
| 2512 | + <span class="comment">// The `image` operand is indexing into a binding array, |
| 2513 | + // so punch through the `Access`* expression and look at |
| 2514 | + // the global behind it. |
2500 | 2515 | </span><span class="kw">crate</span>::Expression::Access { base, .. } |
2501 | 2516 | | <span class="kw">crate</span>::Expression::AccessIndex { base, .. } => { |
2502 | | - <span class="kw">match </span><span class="kw-2">*</span>context.get_expression(base) { |
2503 | | - <span class="kw">crate</span>::Expression::GlobalVariable(var_handle) => { |
2504 | | - <span class="kw-2">&</span>context.global_vars[var_handle] |
2505 | | - } |
2506 | | - <span class="kw">_ </span>=> { |
2507 | | - <span class="kw">return </span><span class="prelude-val">Err</span>(FunctionError::InvalidImageStore( |
2508 | | - ExpressionError::ExpectedGlobalVariable, |
2509 | | - ) |
2510 | | - .with_span_handle(image, context.expressions)) |
2511 | | - } |
2512 | | - } |
| 2517 | + <span class="kw">let </span><span class="kw">crate</span>::Expression::GlobalVariable(var_handle) = |
| 2518 | + <span class="kw-2">*</span>context.get_expression(base) |
| 2519 | + <span class="kw">else </span>{ |
| 2520 | + <span class="kw">return </span><span class="prelude-val">Err</span>(FunctionError::InvalidImageStore( |
| 2521 | + ExpressionError::ExpectedGlobalVariable, |
| 2522 | + ) |
| 2523 | + .with_span_handle(image, context.expressions)); |
| 2524 | + }; |
| 2525 | + global_var = <span class="kw-2">&</span>context.global_vars[var_handle]; |
| 2526 | + |
| 2527 | + <span class="comment">// The global variable must be a binding array. |
| 2528 | + </span><span class="kw">let </span>Ti::BindingArray { base, .. } = context.types[global_var.ty].inner |
| 2529 | + <span class="kw">else </span>{ |
| 2530 | + <span class="kw">return </span><span class="prelude-val">Err</span>(FunctionError::InvalidImageStore( |
| 2531 | + ExpressionError::ExpectedBindingArrayType(global_var.ty), |
| 2532 | + ) |
| 2533 | + .with_span_handle(global_var.ty, context.types)); |
| 2534 | + }; |
| 2535 | + |
| 2536 | + image_ty = base; |
2513 | 2537 | } |
2514 | 2538 | <span class="kw">_ </span>=> { |
2515 | 2539 | <span class="kw">return </span><span class="prelude-val">Err</span>(FunctionError::InvalidImageStore( |
|
2519 | 2543 | } |
2520 | 2544 | }; |
2521 | 2545 |
|
2522 | | - <span class="comment">// Punch through a binding array to get the underlying type |
2523 | | - </span><span class="kw">let </span>global_ty = <span class="kw">match </span>context.types[var.ty].inner { |
2524 | | - Ti::BindingArray { base, .. } => <span class="kw-2">&</span>context.types[base].inner, |
2525 | | - <span class="kw-2">ref </span>inner => inner, |
| 2546 | + <span class="comment">// The `image` operand must be an `Image`. |
| 2547 | + </span><span class="kw">let </span>Ti::Image { |
| 2548 | + class, |
| 2549 | + arrayed, |
| 2550 | + dim, |
| 2551 | + } = context.types[image_ty].inner |
| 2552 | + <span class="kw">else </span>{ |
| 2553 | + <span class="kw">return </span><span class="prelude-val">Err</span>(FunctionError::InvalidImageStore( |
| 2554 | + ExpressionError::ExpectedImageType(global_var.ty), |
| 2555 | + ) |
| 2556 | + .with_span() |
| 2557 | + .with_handle(global_var.ty, context.types) |
| 2558 | + .with_handle(image, context.expressions)); |
2526 | 2559 | }; |
2527 | 2560 |
|
2528 | | - <span class="kw">let </span>value_ty = <span class="kw">match </span><span class="kw-2">*</span>global_ty { |
2529 | | - Ti::Image { |
2530 | | - class, |
2531 | | - arrayed, |
2532 | | - dim, |
2533 | | - } => { |
2534 | | - <span class="kw">match </span>context |
2535 | | - .resolve_type(coordinate, <span class="kw-2">&</span><span class="self">self</span>.valid_expression_set)<span class="question-mark">? |
2536 | | - </span>.image_storage_coordinates() |
2537 | | - { |
2538 | | - <span class="prelude-val">Some</span>(coord_dim) <span class="kw">if </span>coord_dim == dim => {} |
2539 | | - <span class="kw">_ </span>=> { |
2540 | | - <span class="kw">return </span><span class="prelude-val">Err</span>(FunctionError::InvalidImageStore( |
2541 | | - ExpressionError::InvalidImageCoordinateType( |
2542 | | - dim, coordinate, |
2543 | | - ), |
2544 | | - ) |
2545 | | - .with_span_handle(coordinate, context.expressions)); |
2546 | | - } |
2547 | | - }; |
2548 | | - <span class="kw">if </span>arrayed != array_index.is_some() { |
2549 | | - <span class="kw">return </span><span class="prelude-val">Err</span>(FunctionError::InvalidImageStore( |
2550 | | - ExpressionError::InvalidImageArrayIndex, |
2551 | | - ) |
2552 | | - .with_span_handle(coordinate, context.expressions)); |
2553 | | - } |
2554 | | - <span class="kw">if let </span><span class="prelude-val">Some</span>(expr) = array_index { |
2555 | | - <span class="kw">match </span><span class="kw-2">*</span>context.resolve_type(expr, <span class="kw-2">&</span><span class="self">self</span>.valid_expression_set)<span class="question-mark">? </span>{ |
2556 | | - Ti::Scalar(<span class="kw">crate</span>::Scalar { |
2557 | | - kind: <span class="kw">crate</span>::ScalarKind::Sint | <span class="kw">crate</span>::ScalarKind::Uint, |
2558 | | - width: <span class="kw">_</span>, |
2559 | | - }) => {} |
2560 | | - <span class="kw">_ </span>=> { |
2561 | | - <span class="kw">return </span><span class="prelude-val">Err</span>(FunctionError::InvalidImageStore( |
2562 | | - ExpressionError::InvalidImageArrayIndexType(expr), |
2563 | | - ) |
2564 | | - .with_span_handle(expr, context.expressions)); |
2565 | | - } |
2566 | | - } |
2567 | | - } |
2568 | | - <span class="kw">match </span>class { |
2569 | | - <span class="kw">crate</span>::ImageClass::Storage { format, .. } => { |
2570 | | - <span class="kw">crate</span>::TypeInner::Vector { |
2571 | | - size: <span class="kw">crate</span>::VectorSize::Quad, |
2572 | | - scalar: format.into(), |
2573 | | - } |
2574 | | - } |
2575 | | - <span class="kw">_ </span>=> { |
2576 | | - <span class="kw">return </span><span class="prelude-val">Err</span>(FunctionError::InvalidImageStore( |
2577 | | - ExpressionError::InvalidImageClass(class), |
2578 | | - ) |
2579 | | - .with_span_handle(image, context.expressions)); |
2580 | | - } |
2581 | | - } |
2582 | | - } |
2583 | | - <span class="kw">_ </span>=> { |
| 2561 | + <span class="comment">// It had better be a storage image, since we're writing to it. |
| 2562 | + </span><span class="kw">let </span><span class="kw">crate</span>::ImageClass::Storage { format, .. } = class <span class="kw">else </span>{ |
| 2563 | + <span class="kw">return </span><span class="prelude-val">Err</span>(FunctionError::InvalidImageStore( |
| 2564 | + ExpressionError::InvalidImageClass(class), |
| 2565 | + ) |
| 2566 | + .with_span_handle(image, context.expressions)); |
| 2567 | + }; |
| 2568 | + |
| 2569 | + <span class="comment">// The `coordinate` operand must be a vector of the appropriate size. |
| 2570 | + </span><span class="kw">if </span>!context |
| 2571 | + .resolve_type(coordinate, <span class="kw-2">&</span><span class="self">self</span>.valid_expression_set)<span class="question-mark">? |
| 2572 | + </span>.image_storage_coordinates() |
| 2573 | + .is_some_and(|coord_dim| coord_dim == dim) |
| 2574 | + { |
| 2575 | + <span class="kw">return </span><span class="prelude-val">Err</span>(FunctionError::InvalidImageStore( |
| 2576 | + ExpressionError::InvalidImageCoordinateType(dim, coordinate), |
| 2577 | + ) |
| 2578 | + .with_span_handle(coordinate, context.expressions)); |
| 2579 | + } |
| 2580 | + |
| 2581 | + <span class="comment">// The `array_index` operand should be present if and only if |
| 2582 | + // the image itself is arrayed. |
| 2583 | + </span><span class="kw">if </span>arrayed != array_index.is_some() { |
| 2584 | + <span class="kw">return </span><span class="prelude-val">Err</span>(FunctionError::InvalidImageStore( |
| 2585 | + ExpressionError::InvalidImageArrayIndex, |
| 2586 | + ) |
| 2587 | + .with_span_handle(coordinate, context.expressions)); |
| 2588 | + } |
| 2589 | + |
| 2590 | + <span class="comment">// If present, `array_index` must be a scalar integer type. |
| 2591 | + </span><span class="kw">if let </span><span class="prelude-val">Some</span>(expr) = array_index { |
| 2592 | + <span class="kw">if </span>!<span class="macro">matches!</span>( |
| 2593 | + <span class="kw-2">*</span>context.resolve_type(expr, <span class="kw-2">&</span><span class="self">self</span>.valid_expression_set)<span class="question-mark">?</span>, |
| 2594 | + Ti::Scalar(<span class="kw">crate</span>::Scalar { |
| 2595 | + kind: <span class="kw">crate</span>::ScalarKind::Sint | <span class="kw">crate</span>::ScalarKind::Uint, |
| 2596 | + width: <span class="kw">_</span>, |
| 2597 | + }) |
| 2598 | + ) { |
2584 | 2599 | <span class="kw">return </span><span class="prelude-val">Err</span>(FunctionError::InvalidImageStore( |
2585 | | - ExpressionError::ExpectedImageType(var.ty), |
| 2600 | + ExpressionError::InvalidImageArrayIndexType(expr), |
2586 | 2601 | ) |
2587 | | - .with_span() |
2588 | | - .with_handle(var.ty, context.types) |
2589 | | - .with_handle(image, context.expressions)) |
| 2602 | + .with_span_handle(expr, context.expressions)); |
2590 | 2603 | } |
| 2604 | + } |
| 2605 | + |
| 2606 | + <span class="kw">let </span>value_ty = <span class="kw">crate</span>::TypeInner::Vector { |
| 2607 | + size: <span class="kw">crate</span>::VectorSize::Quad, |
| 2608 | + scalar: format.into(), |
2591 | 2609 | }; |
2592 | 2610 |
|
2593 | | - <span class="kw">if </span><span class="kw-2">*</span>context.resolve_type(value, <span class="kw-2">&</span><span class="self">self</span>.valid_expression_set)<span class="question-mark">? </span>!= value_ty { |
| 2611 | + <span class="comment">// The value we're writing had better match the scalar type |
| 2612 | + // for `image`'s format. |
| 2613 | + </span><span class="kw">if </span><span class="kw-2">*</span>context.resolve_type(value, <span class="kw-2">&</span><span class="self">self</span>.valid_expression_set)<span class="question-mark">? </span>!= value_ty { |
2594 | 2614 | <span class="kw">return </span><span class="prelude-val">Err</span>(FunctionError::InvalidStoreValue(value) |
2595 | 2615 | .with_span_handle(value, context.expressions)); |
2596 | 2616 | } |
|
0 commit comments