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"
33 static uint8_t driver_sha1
[20];
36 brw_program_binary_init(unsigned device_id
)
38 const struct build_id_note
*note
=
39 build_id_find_nhdr_for_addr(brw_program_binary_init
);
43 * With Mesa's megadrivers, taking the sha1 of i965_dri.so may not be
44 * unique. Therefore, we make a sha1 of the "i965" string and the sha1
45 * build id from i965_dri.so.
48 _mesa_sha1_init(&ctx
);
50 assert(device_id
< 0x10000);
51 int len
= snprintf(renderer
, sizeof(renderer
), "i965_%04x", device_id
);
52 assert(len
== sizeof(renderer
) - 1);
53 _mesa_sha1_update(&ctx
, renderer
, len
);
54 _mesa_sha1_update(&ctx
, build_id_data(note
), build_id_length(note
));
55 _mesa_sha1_final(&ctx
, driver_sha1
);
59 brw_get_program_binary_driver_sha1(struct gl_context
*ctx
, uint8_t *sha1
)
61 memcpy(sha1
, driver_sha1
, sizeof(uint8_t) * 20);
64 enum driver_cache_blob_part
{
70 brw_program_serialize_nir(struct gl_context
*ctx
, struct gl_program
*prog
)
72 if (prog
->driver_cache_blob
)
77 blob_write_uint32(&writer
, NIR_PART
);
78 intptr_t size_offset
= blob_reserve_uint32(&writer
);
79 size_t nir_start
= writer
.size
;
80 nir_serialize(&writer
, prog
->nir
);
81 blob_overwrite_uint32(&writer
, size_offset
, writer
.size
- nir_start
);
82 blob_write_uint32(&writer
, END_PART
);
83 prog
->driver_cache_blob
= ralloc_size(NULL
, writer
.size
);
84 memcpy(prog
->driver_cache_blob
, writer
.data
, writer
.size
);
85 prog
->driver_cache_blob_size
= writer
.size
;
90 brw_program_deserialize_driver_blob(struct gl_context
*ctx
,
91 struct gl_program
*prog
,
92 gl_shader_stage stage
)
94 if (!prog
->driver_cache_blob
)
97 struct blob_reader reader
;
98 blob_reader_init(&reader
, prog
->driver_cache_blob
,
99 prog
->driver_cache_blob_size
);
102 uint32_t part_type
= blob_read_uint32(&reader
);
103 if ((enum driver_cache_blob_part
)part_type
== END_PART
)
105 switch ((enum driver_cache_blob_part
)part_type
) {
107 uint32_t nir_size
= blob_read_uint32(&reader
);
108 assert(!reader
.overrun
&&
109 (uintptr_t)(reader
.end
- reader
.current
) > nir_size
);
110 const struct nir_shader_compiler_options
*options
=
111 ctx
->Const
.ShaderCompilerOptions
[stage
].NirOptions
;
112 prog
->nir
= nir_deserialize(NULL
, options
, &reader
);
116 unreachable("Unsupported blob part type!");
121 ralloc_free(prog
->driver_cache_blob
);
122 prog
->driver_cache_blob
= NULL
;
123 prog
->driver_cache_blob_size
= 0;
126 /* This is just a wrapper around brw_program_deserialize_nir() as i965
127 * doesn't need gl_shader_program like other drivers do.
130 brw_deserialize_program_binary(struct gl_context
*ctx
,
131 struct gl_shader_program
*shProg
,
132 struct gl_program
*prog
)
134 brw_program_deserialize_driver_blob(ctx
, prog
, prog
->info
.stage
);
138 brw_write_blob_program_data(struct blob
*binary
, gl_shader_stage stage
,
140 struct brw_stage_prog_data
*prog_data
)
142 /* Write prog_data to blob. */
143 blob_write_bytes(binary
, prog_data
, brw_prog_data_size(stage
));
145 /* Write program to blob. */
146 blob_write_bytes(binary
, program
, prog_data
->program_size
);
148 /* Write push params */
149 blob_write_bytes(binary
, prog_data
->param
,
150 sizeof(uint32_t) * prog_data
->nr_params
);
152 /* Write pull params */
153 blob_write_bytes(binary
, prog_data
->pull_param
,
154 sizeof(uint32_t) * prog_data
->nr_pull_params
);
158 brw_read_blob_program_data(struct blob_reader
*binary
, struct gl_program
*prog
,
159 gl_shader_stage stage
, const uint8_t **program
,
160 struct brw_stage_prog_data
*prog_data
)
162 /* Read shader prog_data from blob. */
163 blob_copy_bytes(binary
, prog_data
, brw_prog_data_size(stage
));
167 /* Read shader program from blob. */
168 *program
= blob_read_bytes(binary
, prog_data
->program_size
);
170 /* Read push params */
171 prog_data
->param
= rzalloc_array(NULL
, uint32_t, prog_data
->nr_params
);
172 blob_copy_bytes(binary
, prog_data
->param
,
173 sizeof(uint32_t) * prog_data
->nr_params
);
175 /* Read pull params */
176 prog_data
->pull_param
= rzalloc_array(NULL
, uint32_t,
177 prog_data
->nr_pull_params
);
178 blob_copy_bytes(binary
, prog_data
->pull_param
,
179 sizeof(uint32_t) * prog_data
->nr_pull_params
);
181 return !binary
->overrun
;