1/*
2 * Copyright © 2022 Imagination Technologies Ltd.
3 *
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:
10 *
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
13 * Software.
14 *
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
21 * SOFTWARE.
22 */
23
24#ifndef ROGUE_BUILD_DATA_H
25#define ROGUE_BUILD_DATA_H
26
27#include <stdbool.h>
28#include <stddef.h>
29#include <stdint.h>
30
31#include "compiler/shader_enums.h"
32#include "nir/nir.h"
33#include "rogue.h"
34
35/* Max number of I/O varying variables.
36 * Fragment shader: MAX_VARYING + 1 (W coefficient).
37 * Vertex shader: MAX_VARYING + 1 (position slot).
38 */
39#define ROGUE_MAX_IO_VARYING_VARS (MAX_VARYING + 1)
40
41/* VERT_ATTRIB_GENERIC0-15 */
42#define ROGUE_MAX_IO_ATTRIB_VARS 16
43
44/* Max buffers entries that can be used. */
45/* TODO: Currently UBOs are the only supported buffers. */
46#define ROGUE_MAX_BUFFERS 24
47
48struct rogue_compiler;
49struct rogue_shader;
50struct rogue_shader_binary;
51
52/**
53 * \brief UBO data.
54 */
55struct rogue_ubo_data {
56   size_t num_ubo_entries;
57   size_t desc_set[ROGUE_MAX_BUFFERS];
58   size_t binding[ROGUE_MAX_BUFFERS];
59   size_t dest[ROGUE_MAX_BUFFERS];
60   size_t size[ROGUE_MAX_BUFFERS];
61};
62
63/**
64 * \brief Compile time constants that need uploading.
65 */
66struct rogue_compile_time_consts_data {
67   /* TODO: Output these from the compiler. */
68   /* TODO: Add the other types. */
69   struct {
70      size_t num;
71      size_t dest;
72      /* TODO: This should probably be bigger. Big enough to account for all
73       * available writable special constant regs.
74       */
75      uint32_t value[ROGUE_MAX_BUFFERS];
76   } static_consts;
77};
78
79/**
80 * \brief Per-stage common build data.
81 */
82struct rogue_common_build_data {
83   size_t temps;
84   size_t internals;
85   size_t coeffs;
86   size_t shareds;
87
88   struct rogue_ubo_data ubo_data;
89   struct rogue_compile_time_consts_data compile_time_consts_data;
90};
91
92/**
93 * \brief Arguments for the FPU iterator(s)
94 * (produces varyings for the fragment shader).
95 */
96struct rogue_iterator_args {
97   uint32_t num_fpu_iterators;
98   uint32_t fpu_iterators[ROGUE_MAX_IO_VARYING_VARS];
99   uint32_t destination[ROGUE_MAX_IO_VARYING_VARS];
100   size_t base[ROGUE_MAX_IO_VARYING_VARS];
101   size_t components[ROGUE_MAX_IO_VARYING_VARS];
102};
103
104/**
105 * \brief Vertex input register allocations.
106 */
107struct rogue_vertex_inputs {
108   size_t num_input_vars;
109   size_t base[ROGUE_MAX_IO_ATTRIB_VARS];
110   size_t components[ROGUE_MAX_IO_ATTRIB_VARS];
111};
112
113/**
114 * \brief Vertex output allocations.
115 */
116struct rogue_vertex_outputs {
117   size_t num_output_vars;
118   size_t base[ROGUE_MAX_IO_VARYING_VARS];
119   size_t components[ROGUE_MAX_IO_VARYING_VARS];
120};
121
122/**
123 * \brief Stage-specific build data.
124 */
125struct rogue_build_data {
126   struct rogue_fs_build_data {
127      struct rogue_iterator_args iterator_args;
128      enum rogue_msaa_mode msaa_mode;
129      bool phas; /* Indicates the presence of PHAS instruction. */
130   } fs;
131   struct rogue_vs_build_data {
132      struct rogue_vertex_inputs inputs;
133      size_t num_vertex_input_regs; /* Final number of inputs. */
134
135      struct rogue_vertex_outputs outputs;
136      size_t num_vertex_outputs; /* Final number of outputs. */
137
138      size_t num_varyings; /* Final number of varyings. */
139   } vs;
140};
141
142/**
143 * \brief Shared multi-stage build context.
144 */
145struct rogue_build_ctx {
146   struct rogue_compiler *compiler;
147
148   /* Shaders in various stages of compilations. */
149   nir_shader *nir[MESA_SHADER_FRAGMENT + 1];
150   struct rogue_shader *rogue[MESA_SHADER_FRAGMENT + 1];
151   struct rogue_shader_binary *binary[MESA_SHADER_FRAGMENT + 1];
152
153   struct rogue_common_build_data common_data[MESA_SHADER_FRAGMENT + 1];
154   struct rogue_build_data stage_data;
155};
156
157PUBLIC
158struct rogue_build_ctx *
159rogue_create_build_context(struct rogue_compiler *compiler);
160
161PUBLIC
162bool rogue_collect_io_data(struct rogue_build_ctx *ctx, nir_shader *nir);
163
164PUBLIC
165size_t rogue_coeff_index_fs(struct rogue_iterator_args *args,
166                            gl_varying_slot location,
167                            size_t component);
168
169PUBLIC
170size_t rogue_output_index_vs(struct rogue_vertex_outputs *outputs,
171                             gl_varying_slot location,
172                             size_t component);
173
174PUBLIC
175size_t rogue_ubo_reg(struct rogue_ubo_data *ubo_data,
176                     size_t desc_set,
177                     size_t binding,
178                     size_t offset_bytes);
179
180#endif /* ROGUE_BUILD_DATA_H */
181