2
* Copyright © 2022 Imagination Technologies Ltd.
4
* Permission is hereby granted, free of charge, to any person obtaining a copy
5
* of this software and associated documentation files (the "Software"), to deal
6
* in the Software without restriction, including without limitation the rights
7
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
* copies of the Software, and to permit persons to whom the Software is
9
* furnished to do so, subject to the following conditions:
11
* The above copyright notice and this permission notice (including the next
12
* paragraph) shall be included in all copies or substantial portions of the
15
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28
#include "nir/nir_builder.h"
29
#include "nir/nir_search_helpers.h"
30
#include "rogue_nir.h"
31
#include "rogue_nir_helpers.h"
33
static void lower_vulkan_resource_index(nir_builder *b,
34
nir_intrinsic_instr *intr,
35
void *pipeline_layout)
37
unsigned desc_set = nir_intrinsic_desc_set(intr);
38
unsigned binding = nir_intrinsic_binding(intr);
40
nir_ssa_def *def = nir_vec3(b,
41
nir_imm_int(b, desc_set),
42
nir_imm_int(b, binding),
44
nir_ssa_def_rewrite_uses(&intr->dest.ssa, def);
45
nir_instr_remove(&intr->instr);
48
static void lower_load_vulkan_descriptor(nir_builder *b,
49
nir_intrinsic_instr *intr)
51
/* Loading the descriptor happens as part of the load/store instruction so
55
nir_ssa_def_rewrite_uses(&intr->dest.ssa, intr->src[0].ssa);
56
nir_instr_remove(&intr->instr);
59
static void lower_load_ubo_to_scalar(nir_builder *b, nir_intrinsic_instr *intr)
61
/* Scalarize the load_ubo. */
62
b->cursor = nir_before_instr(&intr->instr);
64
assert(intr->dest.is_ssa);
65
assert(intr->num_components > 1);
67
nir_ssa_def *loads[NIR_MAX_VEC_COMPONENTS];
69
for (uint8_t i = 0; i < intr->num_components; i++) {
70
size_t scaled_range = nir_intrinsic_range(intr) / intr->num_components;
71
nir_intrinsic_instr *chan_intr =
72
nir_intrinsic_instr_create(b->shader, intr->intrinsic);
73
nir_ssa_dest_init(&chan_intr->instr,
76
intr->dest.ssa.bit_size,
78
chan_intr->num_components = 1;
80
nir_intrinsic_set_access(chan_intr, nir_intrinsic_access(intr));
81
nir_intrinsic_set_align_mul(chan_intr, nir_intrinsic_align_mul(intr));
82
nir_intrinsic_set_align_offset(chan_intr,
83
nir_intrinsic_align_offset(intr));
84
nir_intrinsic_set_range_base(chan_intr,
85
nir_intrinsic_range_base(intr) +
86
(i * intr->num_components));
87
nir_intrinsic_set_range(chan_intr, scaled_range);
89
/* Base (desc_set, binding). */
90
nir_src_copy(&chan_intr->src[0], &intr->src[0]);
92
/* Offset (unused). */
93
chan_intr->src[1] = nir_src_for_ssa(nir_imm_int(b, 0));
95
nir_builder_instr_insert(b, &chan_intr->instr);
97
loads[i] = &chan_intr->dest.ssa;
100
nir_ssa_def_rewrite_uses(&intr->dest.ssa,
101
nir_vec(b, loads, intr->num_components));
102
nir_instr_remove(&intr->instr);
106
lower_intrinsic(nir_builder *b, nir_intrinsic_instr *instr, void *layout)
108
switch (instr->intrinsic) {
109
case nir_intrinsic_load_vulkan_descriptor:
110
lower_load_vulkan_descriptor(b, instr);
113
case nir_intrinsic_vulkan_resource_index:
114
lower_vulkan_resource_index(b, instr, layout);
117
case nir_intrinsic_load_ubo:
118
lower_load_ubo_to_scalar(b, instr);
128
static bool lower_impl(nir_function_impl *impl, void *layout)
130
bool progress = false;
133
nir_builder_init(&b, impl);
135
nir_foreach_block (block, impl) {
136
nir_foreach_instr_safe (instr, block) {
137
b.cursor = nir_before_instr(instr);
138
switch (instr->type) {
139
case nir_instr_type_intrinsic:
141
lower_intrinsic(&b, nir_instr_as_intrinsic(instr), layout);
151
nir_metadata_preserve(impl, nir_metadata_none);
153
nir_metadata_preserve(impl, nir_metadata_all);
158
bool rogue_nir_lower_io(nir_shader *shader, void *layout)
160
bool progress = false;
162
nir_foreach_function (function, shader) {
164
progress |= lower_impl(function->impl, layout);