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 brw_program_serialize_nir(struct gl_context
*ctx
, struct gl_program
*prog
)
74 if (prog
->driver_cache_blob
)
79 blob_write_uint32(&writer
, NIR_PART
);
80 intptr_t size_offset
= blob_reserve_uint32(&writer
);
81 size_t nir_start
= writer
.size
;
82 nir_serialize(&writer
, prog
->nir
);
83 blob_overwrite_uint32(&writer
, size_offset
, writer
.size
- nir_start
);
84 blob_write_uint32(&writer
, END_PART
);
85 prog
->driver_cache_blob
= ralloc_size(NULL
, writer
.size
);
86 memcpy(prog
->driver_cache_blob
, writer
.data
, writer
.size
);
87 prog
->driver_cache_blob_size
= writer
.size
;
92 deserialize_gen_program(struct blob_reader
*reader
, struct gl_context
*ctx
,
93 struct gl_program
*prog
, gl_shader_stage stage
)
95 struct brw_context
*brw
= brw_context(ctx
);
97 union brw_any_prog_key prog_key
;
98 blob_copy_bytes(reader
, &prog_key
, brw_prog_key_size(stage
));
99 brw_prog_key_set_id(&prog_key
, stage
, brw_program(prog
)->id
);
101 enum brw_cache_id cache_id
= brw_stage_cache_id(stage
);
103 const uint8_t *program
;
104 struct brw_stage_prog_data
*prog_data
=
105 ralloc_size(NULL
, sizeof(union brw_any_prog_data
));
107 if (!brw_read_blob_program_data(reader
, prog
, stage
, &program
, prog_data
)) {
108 ralloc_free(prog_data
);
114 brw_upload_cache(&brw
->cache
, cache_id
, &prog_key
, brw_prog_key_size(stage
),
115 program
, prog_data
->program_size
, prog_data
,
116 brw_prog_data_size(stage
), &offset
, &out_prog_data
);
118 ralloc_free(prog_data
);
124 brw_program_deserialize_driver_blob(struct gl_context
*ctx
,
125 struct gl_program
*prog
,
126 gl_shader_stage stage
)
128 if (!prog
->driver_cache_blob
)
131 struct blob_reader reader
;
132 blob_reader_init(&reader
, prog
->driver_cache_blob
,
133 prog
->driver_cache_blob_size
);
136 uint32_t part_type
= blob_read_uint32(&reader
);
137 if ((enum driver_cache_blob_part
)part_type
== END_PART
)
139 switch ((enum driver_cache_blob_part
)part_type
) {
141 uint32_t gen_size
= blob_read_uint32(&reader
);
142 assert(!reader
.overrun
&&
143 (uintptr_t)(reader
.end
- reader
.current
) > gen_size
);
144 deserialize_gen_program(&reader
, ctx
, prog
, stage
);
148 uint32_t nir_size
= blob_read_uint32(&reader
);
149 assert(!reader
.overrun
&&
150 (uintptr_t)(reader
.end
- reader
.current
) > nir_size
);
151 const struct nir_shader_compiler_options
*options
=
152 ctx
->Const
.ShaderCompilerOptions
[stage
].NirOptions
;
153 prog
->nir
= nir_deserialize(NULL
, options
, &reader
);
157 unreachable("Unsupported blob part type!");
162 ralloc_free(prog
->driver_cache_blob
);
163 prog
->driver_cache_blob
= NULL
;
164 prog
->driver_cache_blob_size
= 0;
167 /* This is just a wrapper around brw_program_deserialize_nir() as i965
168 * doesn't need gl_shader_program like other drivers do.
171 brw_deserialize_program_binary(struct gl_context
*ctx
,
172 struct gl_shader_program
*shProg
,
173 struct gl_program
*prog
)
175 brw_program_deserialize_driver_blob(ctx
, prog
, prog
->info
.stage
);
179 brw_write_blob_program_data(struct blob
*binary
, gl_shader_stage stage
,
181 struct brw_stage_prog_data
*prog_data
)
183 /* Write prog_data to blob. */
184 blob_write_bytes(binary
, prog_data
, brw_prog_data_size(stage
));
186 /* Write program to blob. */
187 blob_write_bytes(binary
, program
, prog_data
->program_size
);
189 /* Write push params */
190 blob_write_bytes(binary
, prog_data
->param
,
191 sizeof(uint32_t) * prog_data
->nr_params
);
193 /* Write pull params */
194 blob_write_bytes(binary
, prog_data
->pull_param
,
195 sizeof(uint32_t) * prog_data
->nr_pull_params
);
199 brw_read_blob_program_data(struct blob_reader
*binary
, struct gl_program
*prog
,
200 gl_shader_stage stage
, const uint8_t **program
,
201 struct brw_stage_prog_data
*prog_data
)
203 /* Read shader prog_data from blob. */
204 blob_copy_bytes(binary
, prog_data
, brw_prog_data_size(stage
));
208 /* Read shader program from blob. */
209 *program
= blob_read_bytes(binary
, prog_data
->program_size
);
211 /* Read push params */
212 prog_data
->param
= rzalloc_array(NULL
, uint32_t, prog_data
->nr_params
);
213 blob_copy_bytes(binary
, prog_data
->param
,
214 sizeof(uint32_t) * prog_data
->nr_params
);
216 /* Read pull params */
217 prog_data
->pull_param
= rzalloc_array(NULL
, uint32_t,
218 prog_data
->nr_pull_params
);
219 blob_copy_bytes(binary
, prog_data
->pull_param
,
220 sizeof(uint32_t) * prog_data
->nr_pull_params
);
222 return !binary
->overrun
;