2 * Copyright (c) 2017 Intel Corporation
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is 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
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
26 #include "compiler/nir/nir_serialize.h"
27 #include "util/build_id.h"
28 #include "util/mesa-sha1.h"
30 #include "brw_context.h"
31 #include "brw_program.h"
32 #include "brw_state.h"
34 static uint8_t driver_sha1
[20];
37 brw_program_binary_init(unsigned device_id
)
39 const struct build_id_note
*note
=
40 build_id_find_nhdr_for_addr(brw_program_binary_init
);
44 * With Mesa's megadrivers, taking the sha1 of i965_dri.so may not be
45 * unique. Therefore, we make a sha1 of the "i965" string and the sha1
46 * build id from i965_dri.so.
49 _mesa_sha1_init(&ctx
);
51 assert(device_id
< 0x10000);
52 int len
= snprintf(renderer
, sizeof(renderer
), "i965_%04x", device_id
);
53 assert(len
== sizeof(renderer
) - 1);
54 _mesa_sha1_update(&ctx
, renderer
, len
);
55 _mesa_sha1_update(&ctx
, build_id_data(note
), build_id_length(note
));
56 _mesa_sha1_final(&ctx
, driver_sha1
);
60 brw_get_program_binary_driver_sha1(struct gl_context
*ctx
, uint8_t *sha1
)
62 memcpy(sha1
, driver_sha1
, sizeof(uint8_t) * 20);
65 enum driver_cache_blob_part
{
72 blob_parts_valid(void *blob
, uint32_t size
)
74 struct blob_reader reader
;
75 blob_reader_init(&reader
, blob
, size
);
78 uint32_t part_type
= blob_read_uint32(&reader
);
81 if (part_type
== END_PART
)
82 return reader
.current
== reader
.end
;
83 switch ((enum driver_cache_blob_part
)part_type
) {
86 /* Read the uint32_t part-size and skip over it */
87 blob_skip_bytes(&reader
, blob_read_uint32(&reader
));
98 blob_has_part(void *blob
, uint32_t size
, enum driver_cache_blob_part part
)
100 struct blob_reader reader
;
101 blob_reader_init(&reader
, blob
, size
);
103 assert(blob_parts_valid(blob
, size
));
105 uint32_t part_type
= blob_read_uint32(&reader
);
106 if (part_type
== END_PART
)
108 if (part_type
== part
)
110 blob_skip_bytes(&reader
, blob_read_uint32(&reader
));
115 driver_blob_is_ready(void *blob
, uint32_t size
, bool with_gen_program
)
119 } else if (!blob_parts_valid(blob
, size
)) {
120 unreachable("Driver blob format is bad!");
122 } else if (blob_has_part(blob
, size
, GEN_PART
) == with_gen_program
) {
130 brw_program_serialize_nir(struct gl_context
*ctx
, struct gl_program
*prog
)
132 if (driver_blob_is_ready(prog
->driver_cache_blob
,
133 prog
->driver_cache_blob_size
, false))
136 if (prog
->driver_cache_blob
)
137 ralloc_free(prog
->driver_cache_blob
);
141 blob_write_uint32(&writer
, NIR_PART
);
142 intptr_t size_offset
= blob_reserve_uint32(&writer
);
143 size_t nir_start
= writer
.size
;
144 nir_serialize(&writer
, prog
->nir
);
145 blob_overwrite_uint32(&writer
, size_offset
, writer
.size
- nir_start
);
146 blob_write_uint32(&writer
, END_PART
);
147 prog
->driver_cache_blob
= ralloc_size(NULL
, writer
.size
);
148 memcpy(prog
->driver_cache_blob
, writer
.data
, writer
.size
);
149 prog
->driver_cache_blob_size
= writer
.size
;
150 blob_finish(&writer
);
154 deserialize_gen_program(struct blob_reader
*reader
, struct gl_context
*ctx
,
155 struct gl_program
*prog
, gl_shader_stage stage
)
157 struct brw_context
*brw
= brw_context(ctx
);
159 union brw_any_prog_key prog_key
;
160 blob_copy_bytes(reader
, &prog_key
, brw_prog_key_size(stage
));
161 brw_prog_key_set_id(&prog_key
, stage
, brw_program(prog
)->id
);
163 enum brw_cache_id cache_id
= brw_stage_cache_id(stage
);
165 const uint8_t *program
;
166 struct brw_stage_prog_data
*prog_data
=
167 ralloc_size(NULL
, sizeof(union brw_any_prog_data
));
169 if (!brw_read_blob_program_data(reader
, prog
, stage
, &program
, prog_data
)) {
170 ralloc_free(prog_data
);
176 brw_upload_cache(&brw
->cache
, cache_id
, &prog_key
, brw_prog_key_size(stage
),
177 program
, prog_data
->program_size
, prog_data
,
178 brw_prog_data_size(stage
), &offset
, &out_prog_data
);
180 ralloc_free(prog_data
);
186 brw_program_deserialize_driver_blob(struct gl_context
*ctx
,
187 struct gl_program
*prog
,
188 gl_shader_stage stage
)
190 if (!prog
->driver_cache_blob
)
193 struct blob_reader reader
;
194 blob_reader_init(&reader
, prog
->driver_cache_blob
,
195 prog
->driver_cache_blob_size
);
198 uint32_t part_type
= blob_read_uint32(&reader
);
199 if ((enum driver_cache_blob_part
)part_type
== END_PART
)
201 switch ((enum driver_cache_blob_part
)part_type
) {
203 uint32_t gen_size
= blob_read_uint32(&reader
);
204 assert(!reader
.overrun
&&
205 (uintptr_t)(reader
.end
- reader
.current
) > gen_size
);
206 deserialize_gen_program(&reader
, ctx
, prog
, stage
);
210 uint32_t nir_size
= blob_read_uint32(&reader
);
211 assert(!reader
.overrun
&&
212 (uintptr_t)(reader
.end
- reader
.current
) > nir_size
);
213 const struct nir_shader_compiler_options
*options
=
214 ctx
->Const
.ShaderCompilerOptions
[stage
].NirOptions
;
215 prog
->nir
= nir_deserialize(NULL
, options
, &reader
);
219 unreachable("Unsupported blob part type!");
224 ralloc_free(prog
->driver_cache_blob
);
225 prog
->driver_cache_blob
= NULL
;
226 prog
->driver_cache_blob_size
= 0;
229 /* This is just a wrapper around brw_program_deserialize_nir() as i965
230 * doesn't need gl_shader_program like other drivers do.
233 brw_deserialize_program_binary(struct gl_context
*ctx
,
234 struct gl_shader_program
*shProg
,
235 struct gl_program
*prog
)
237 brw_program_deserialize_driver_blob(ctx
, prog
, prog
->info
.stage
);
241 brw_serialize_program_binary(struct gl_context
*ctx
,
242 struct gl_shader_program
*sh_prog
,
243 struct gl_program
*prog
)
245 brw_program_serialize_nir(ctx
, prog
);
249 brw_write_blob_program_data(struct blob
*binary
, gl_shader_stage stage
,
251 struct brw_stage_prog_data
*prog_data
)
253 /* Write prog_data to blob. */
254 blob_write_bytes(binary
, prog_data
, brw_prog_data_size(stage
));
256 /* Write program to blob. */
257 blob_write_bytes(binary
, program
, prog_data
->program_size
);
259 /* Write push params */
260 blob_write_bytes(binary
, prog_data
->param
,
261 sizeof(uint32_t) * prog_data
->nr_params
);
263 /* Write pull params */
264 blob_write_bytes(binary
, prog_data
->pull_param
,
265 sizeof(uint32_t) * prog_data
->nr_pull_params
);
269 brw_read_blob_program_data(struct blob_reader
*binary
, struct gl_program
*prog
,
270 gl_shader_stage stage
, const uint8_t **program
,
271 struct brw_stage_prog_data
*prog_data
)
273 /* Read shader prog_data from blob. */
274 blob_copy_bytes(binary
, prog_data
, brw_prog_data_size(stage
));
278 /* Read shader program from blob. */
279 *program
= blob_read_bytes(binary
, prog_data
->program_size
);
281 /* Read push params */
282 prog_data
->param
= rzalloc_array(NULL
, uint32_t, prog_data
->nr_params
);
283 blob_copy_bytes(binary
, prog_data
->param
,
284 sizeof(uint32_t) * prog_data
->nr_params
);
286 /* Read pull params */
287 prog_data
->pull_param
= rzalloc_array(NULL
, uint32_t,
288 prog_data
->nr_pull_params
);
289 blob_copy_bytes(binary
, prog_data
->pull_param
,
290 sizeof(uint32_t) * prog_data
->nr_pull_params
);
292 return !binary
->overrun
;