freedreno/ir3: disk-cache support
Adds a shader disk-cache for ir3 shader variants. Note that builds with `-Dshader-cache=false` have no-op stubs with `disk_cache_create()` that returns NULL. Binning pass variants are serialized together with their draw-pass counterparts, due to shared const-state. Signed-off-by: Rob Clark <robdclark@chromium.org> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/5372>
This commit is contained in:
parent
6aadb00e60
commit
f97acb4bb4
|
@ -35,6 +35,7 @@ ir3_SOURCES := \
|
||||||
ir3/ir3_cf.c \
|
ir3/ir3_cf.c \
|
||||||
ir3/ir3_dce.c \
|
ir3/ir3_dce.c \
|
||||||
ir3/ir3_delay.c \
|
ir3/ir3_delay.c \
|
||||||
|
ir3/ir3_disk_cache.c \
|
||||||
ir3/ir3_group.c \
|
ir3/ir3_group.c \
|
||||||
ir3/ir3_image.c \
|
ir3/ir3_image.c \
|
||||||
ir3/ir3_image.h \
|
ir3/ir3_image.h \
|
||||||
|
|
|
@ -40,6 +40,7 @@ static const struct debug_named_value shader_debug_options[] = {
|
||||||
{"forces2en", IR3_DBG_FORCES2EN, "Force s2en mode for tex sampler instructions"},
|
{"forces2en", IR3_DBG_FORCES2EN, "Force s2en mode for tex sampler instructions"},
|
||||||
{"nouboopt", IR3_DBG_NOUBOOPT, "Disable lowering UBO to uniform"},
|
{"nouboopt", IR3_DBG_NOUBOOPT, "Disable lowering UBO to uniform"},
|
||||||
{"nofp16", IR3_DBG_NOFP16, "Don't lower mediump to fp16"},
|
{"nofp16", IR3_DBG_NOFP16, "Don't lower mediump to fp16"},
|
||||||
|
{"nocache", IR3_DBG_NOCACHE, "Disable shader cache"},
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
/* DEBUG-only options: */
|
/* DEBUG-only options: */
|
||||||
{"schedmsgs", IR3_DBG_SCHEDMSGS, "Enable scheduler debug messages"},
|
{"schedmsgs", IR3_DBG_SCHEDMSGS, "Enable scheduler debug messages"},
|
||||||
|
@ -122,5 +123,7 @@ ir3_compiler_create(struct fd_device *dev, uint32_t gpu_id)
|
||||||
compiler->const_upload_unit = 8;
|
compiler->const_upload_unit = 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ir3_disk_cache_init(compiler);
|
||||||
|
|
||||||
return compiler;
|
return compiler;
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,6 +27,8 @@
|
||||||
#ifndef IR3_COMPILER_H_
|
#ifndef IR3_COMPILER_H_
|
||||||
#define IR3_COMPILER_H_
|
#define IR3_COMPILER_H_
|
||||||
|
|
||||||
|
#include "util/disk_cache.h"
|
||||||
|
|
||||||
#include "ir3.h"
|
#include "ir3.h"
|
||||||
|
|
||||||
struct ir3_ra_reg_set;
|
struct ir3_ra_reg_set;
|
||||||
|
@ -39,6 +41,8 @@ struct ir3_compiler {
|
||||||
struct ir3_ra_reg_set *mergedregs_set;
|
struct ir3_ra_reg_set *mergedregs_set;
|
||||||
uint32_t shader_count;
|
uint32_t shader_count;
|
||||||
|
|
||||||
|
struct disk_cache *disk_cache;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Configuration options for things that are handled differently on
|
* Configuration options for things that are handled differently on
|
||||||
* different generations:
|
* different generations:
|
||||||
|
@ -98,6 +102,14 @@ struct ir3_compiler {
|
||||||
void ir3_compiler_destroy(struct ir3_compiler *compiler);
|
void ir3_compiler_destroy(struct ir3_compiler *compiler);
|
||||||
struct ir3_compiler * ir3_compiler_create(struct fd_device *dev, uint32_t gpu_id);
|
struct ir3_compiler * ir3_compiler_create(struct fd_device *dev, uint32_t gpu_id);
|
||||||
|
|
||||||
|
void ir3_disk_cache_init(struct ir3_compiler *compiler);
|
||||||
|
void ir3_disk_cache_init_shader_key(struct ir3_compiler *compiler,
|
||||||
|
struct ir3_shader *shader);
|
||||||
|
bool ir3_disk_cache_retrieve(struct ir3_compiler *compiler,
|
||||||
|
struct ir3_shader_variant *v);
|
||||||
|
void ir3_disk_cache_store(struct ir3_compiler *compiler,
|
||||||
|
struct ir3_shader_variant *v);
|
||||||
|
|
||||||
int ir3_compile_shader_nir(struct ir3_compiler *compiler,
|
int ir3_compile_shader_nir(struct ir3_compiler *compiler,
|
||||||
struct ir3_shader_variant *so);
|
struct ir3_shader_variant *so);
|
||||||
|
|
||||||
|
@ -120,6 +132,7 @@ enum ir3_shader_debug {
|
||||||
IR3_DBG_FORCES2EN = BITFIELD_BIT(8),
|
IR3_DBG_FORCES2EN = BITFIELD_BIT(8),
|
||||||
IR3_DBG_NOUBOOPT = BITFIELD_BIT(9),
|
IR3_DBG_NOUBOOPT = BITFIELD_BIT(9),
|
||||||
IR3_DBG_NOFP16 = BITFIELD_BIT(10),
|
IR3_DBG_NOFP16 = BITFIELD_BIT(10),
|
||||||
|
IR3_DBG_NOCACHE = BITFIELD_BIT(11),
|
||||||
|
|
||||||
/* DEBUG-only options: */
|
/* DEBUG-only options: */
|
||||||
IR3_DBG_SCHEDMSGS = BITFIELD_BIT(20),
|
IR3_DBG_SCHEDMSGS = BITFIELD_BIT(20),
|
||||||
|
|
|
@ -0,0 +1,226 @@
|
||||||
|
/*
|
||||||
|
* Copyright © 2020 Google, Inc.
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
* copy of this software and associated documentation files (the "Software"),
|
||||||
|
* to deal in the Software without restriction, including without limitation
|
||||||
|
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
* and/or sell copies of the Software, and to permit persons to whom the
|
||||||
|
* Software is furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice (including the next
|
||||||
|
* paragraph) shall be included in all copies or substantial portions of the
|
||||||
|
* Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||||
|
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "nir_serialize.h"
|
||||||
|
|
||||||
|
#include "ir3_compiler.h"
|
||||||
|
#include "ir3_nir.h"
|
||||||
|
|
||||||
|
#define debug 0
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Shader disk-cache implementation.
|
||||||
|
*
|
||||||
|
* Note that at least in the EGL_ANDROID_blob_cache, we should never
|
||||||
|
* rely on inter-dependencies between different cache entries:
|
||||||
|
*
|
||||||
|
* No guarantees are made as to whether a given key/value pair is present in
|
||||||
|
* the cache after the set call. If a different value has been associated
|
||||||
|
* with the given key in the past then it is undefined which value, if any, is
|
||||||
|
* associated with the key after the set call. Note that while there are no
|
||||||
|
* guarantees, the cache implementation should attempt to cache the most
|
||||||
|
* recently set value for a given key.
|
||||||
|
*
|
||||||
|
* for this reason, because binning pass variants share const_state with
|
||||||
|
* their draw-pass counterpart, both variants are serialized together.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
ir3_disk_cache_init(struct ir3_compiler *compiler)
|
||||||
|
{
|
||||||
|
if (ir3_shader_debug & IR3_DBG_NOCACHE)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* array length = print length + nul char + 1 extra to verify it's unused */
|
||||||
|
char renderer[7];
|
||||||
|
ASSERTED int len =
|
||||||
|
snprintf(renderer, sizeof(renderer), "FD%03d", compiler->gpu_id);
|
||||||
|
assert(len == sizeof(renderer) - 2);
|
||||||
|
|
||||||
|
const struct build_id_note *note =
|
||||||
|
build_id_find_nhdr_for_addr(ir3_disk_cache_init);
|
||||||
|
assert(note && build_id_length(note) == 20); /* sha1 */
|
||||||
|
|
||||||
|
const uint8_t *id_sha1 = build_id_data(note);
|
||||||
|
assert(id_sha1);
|
||||||
|
|
||||||
|
char timestamp[41];
|
||||||
|
_mesa_sha1_format(timestamp, id_sha1);
|
||||||
|
|
||||||
|
const uint64_t driver_flags = ir3_shader_debug;
|
||||||
|
compiler->disk_cache = disk_cache_create(renderer, timestamp, driver_flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ir3_disk_cache_init_shader_key(struct ir3_compiler *compiler,
|
||||||
|
struct ir3_shader *shader)
|
||||||
|
{
|
||||||
|
if (!compiler->disk_cache)
|
||||||
|
return;
|
||||||
|
|
||||||
|
struct mesa_sha1 ctx;
|
||||||
|
|
||||||
|
_mesa_sha1_init(&ctx);
|
||||||
|
|
||||||
|
/* Serialize the NIR to a binary blob that we can hash for the disk
|
||||||
|
* cache. Drop unnecessary information (like variable names)
|
||||||
|
* so the serialized NIR is smaller, and also to let us detect more
|
||||||
|
* isomorphic shaders when hashing, increasing cache hits.
|
||||||
|
*/
|
||||||
|
struct blob blob;
|
||||||
|
blob_init(&blob);
|
||||||
|
nir_serialize(&blob, shader->nir, true);
|
||||||
|
_mesa_sha1_update(&ctx, blob.data, blob.size);
|
||||||
|
blob_finish(&blob);
|
||||||
|
|
||||||
|
/* Note that on some gens stream-out is lowered in ir3 to stg. For later
|
||||||
|
* gens we maybe don't need to include stream-out in the cache key.
|
||||||
|
*/
|
||||||
|
_mesa_sha1_update(&ctx, &shader->stream_output, sizeof(shader->stream_output));
|
||||||
|
|
||||||
|
_mesa_sha1_final(&ctx, shader->cache_key);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
compute_variant_key(struct ir3_compiler *compiler,
|
||||||
|
struct ir3_shader_variant *v, cache_key cache_key)
|
||||||
|
{
|
||||||
|
struct blob blob;
|
||||||
|
blob_init(&blob);
|
||||||
|
|
||||||
|
blob_write_bytes(&blob, &v->shader->cache_key, sizeof(v->shader->cache_key));
|
||||||
|
blob_write_bytes(&blob, &v->key, sizeof(v->key));
|
||||||
|
blob_write_uint8(&blob, v->binning_pass);
|
||||||
|
|
||||||
|
disk_cache_compute_key(compiler->disk_cache, blob.data, blob.size, cache_key);
|
||||||
|
|
||||||
|
blob_finish(&blob);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
retrieve_variant(struct blob_reader *blob, struct ir3_shader_variant *v)
|
||||||
|
{
|
||||||
|
blob_copy_bytes(blob, VARIANT_CACHE_PTR(v), VARIANT_CACHE_SIZE);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* pointers need special handling:
|
||||||
|
*/
|
||||||
|
|
||||||
|
v->bin = malloc(4 * v->info.sizedwords);
|
||||||
|
blob_copy_bytes(blob, v->bin, 4 * v->info.sizedwords);
|
||||||
|
|
||||||
|
if (!v->binning_pass) {
|
||||||
|
blob_copy_bytes(blob, v->const_state, sizeof(*v->const_state));
|
||||||
|
unsigned immeds_sz = v->const_state->immediates_size *
|
||||||
|
sizeof(v->const_state->immediates[0]);
|
||||||
|
v->const_state->immediates = ralloc_size(v->const_state, immeds_sz);
|
||||||
|
blob_copy_bytes(blob, v->const_state->immediates, immeds_sz);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
store_variant(struct blob *blob, struct ir3_shader_variant *v)
|
||||||
|
{
|
||||||
|
blob_write_bytes(blob, VARIANT_CACHE_PTR(v), VARIANT_CACHE_SIZE);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* pointers need special handling:
|
||||||
|
*/
|
||||||
|
|
||||||
|
blob_write_bytes(blob, v->bin, 4 * v->info.sizedwords);
|
||||||
|
|
||||||
|
if (!v->binning_pass) {
|
||||||
|
blob_write_bytes(blob, v->const_state, sizeof(*v->const_state));
|
||||||
|
unsigned immeds_sz = v->const_state->immediates_size *
|
||||||
|
sizeof(v->const_state->immediates[0]);
|
||||||
|
blob_write_bytes(blob, v->const_state->immediates, immeds_sz);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
ir3_disk_cache_retrieve(struct ir3_compiler *compiler,
|
||||||
|
struct ir3_shader_variant *v)
|
||||||
|
{
|
||||||
|
if (!compiler->disk_cache)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
cache_key cache_key;
|
||||||
|
|
||||||
|
compute_variant_key(compiler, v, cache_key);
|
||||||
|
|
||||||
|
if (debug) {
|
||||||
|
char sha1[41];
|
||||||
|
_mesa_sha1_format(sha1, cache_key);
|
||||||
|
fprintf(stderr, "[mesa disk cache] retrieving variant %s: ", sha1);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t size;
|
||||||
|
void *buffer = disk_cache_get(compiler->disk_cache, cache_key, &size);
|
||||||
|
|
||||||
|
if (debug)
|
||||||
|
fprintf(stderr, "%s\n", buffer ? "found" : "missing");
|
||||||
|
|
||||||
|
if (!buffer)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
struct blob_reader blob;
|
||||||
|
blob_reader_init(&blob, buffer, size);
|
||||||
|
|
||||||
|
retrieve_variant(&blob, v);
|
||||||
|
|
||||||
|
if (v->binning)
|
||||||
|
retrieve_variant(&blob, v->binning);
|
||||||
|
|
||||||
|
free(buffer);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ir3_disk_cache_store(struct ir3_compiler *compiler,
|
||||||
|
struct ir3_shader_variant *v)
|
||||||
|
{
|
||||||
|
if (!compiler->disk_cache)
|
||||||
|
return;
|
||||||
|
|
||||||
|
cache_key cache_key;
|
||||||
|
|
||||||
|
compute_variant_key(compiler, v, cache_key);
|
||||||
|
|
||||||
|
if (debug) {
|
||||||
|
char sha1[41];
|
||||||
|
_mesa_sha1_format(sha1, cache_key);
|
||||||
|
fprintf(stderr, "[mesa disk cache] storing variant %s\n", sha1);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct blob blob;
|
||||||
|
blob_init(&blob);
|
||||||
|
|
||||||
|
store_variant(&blob, v);
|
||||||
|
|
||||||
|
if (v->binning)
|
||||||
|
store_variant(&blob, v->binning);
|
||||||
|
|
||||||
|
disk_cache_put(compiler->disk_cache, cache_key, blob.data, blob.size, NULL);
|
||||||
|
blob_finish(&blob);
|
||||||
|
}
|
|
@ -245,12 +245,17 @@ create_variant(struct ir3_shader *shader, const struct ir3_shader_key *key)
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ir3_disk_cache_retrieve(shader->compiler, v))
|
||||||
|
return v;
|
||||||
|
|
||||||
if (!compile_variant(v))
|
if (!compile_variant(v))
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
if (needs_binning_variant(v) && !compile_variant(v->binning))
|
if (needs_binning_variant(v) && !compile_variant(v->binning))
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
|
ir3_disk_cache_store(shader->compiler, v);
|
||||||
|
|
||||||
return v;
|
return v;
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
|
@ -445,11 +450,12 @@ ir3_shader_from_nir(struct ir3_compiler *compiler, nir_shader *nir,
|
||||||
if (stream_output)
|
if (stream_output)
|
||||||
memcpy(&shader->stream_output, stream_output, sizeof(shader->stream_output));
|
memcpy(&shader->stream_output, stream_output, sizeof(shader->stream_output));
|
||||||
shader->num_reserved_user_consts = reserved_user_consts;
|
shader->num_reserved_user_consts = reserved_user_consts;
|
||||||
|
shader->nir = nir;
|
||||||
|
|
||||||
|
ir3_disk_cache_init_shader_key(compiler, shader);
|
||||||
|
|
||||||
ir3_nir_post_finalize(compiler, nir);
|
ir3_nir_post_finalize(compiler, nir);
|
||||||
|
|
||||||
shader->nir = nir;
|
|
||||||
|
|
||||||
if (ir3_shader_debug & IR3_DBG_DISASM) {
|
if (ir3_shader_debug & IR3_DBG_DISASM) {
|
||||||
printf("dump nir%d: type=%d", shader->id, shader->type);
|
printf("dump nir%d: type=%d", shader->id, shader->type);
|
||||||
nir_print_shader(shader->nir, stdout);
|
nir_print_shader(shader->nir, stdout);
|
||||||
|
|
|
@ -33,6 +33,7 @@
|
||||||
#include "compiler/shader_enums.h"
|
#include "compiler/shader_enums.h"
|
||||||
#include "compiler/nir/nir.h"
|
#include "compiler/nir/nir.h"
|
||||||
#include "util/bitscan.h"
|
#include "util/bitscan.h"
|
||||||
|
#include "util/disk_cache.h"
|
||||||
|
|
||||||
#include "ir3_compiler.h"
|
#include "ir3_compiler.h"
|
||||||
|
|
||||||
|
@ -481,11 +482,25 @@ struct ir3_shader_variant {
|
||||||
gl_shader_stage type;
|
gl_shader_stage type;
|
||||||
struct ir3_shader *shader;
|
struct ir3_shader *shader;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Below here is serialized when written to disk cache:
|
||||||
|
*/
|
||||||
|
|
||||||
/* The actual binary shader instructions, size given by info.sizedwords: */
|
/* The actual binary shader instructions, size given by info.sizedwords: */
|
||||||
uint32_t *bin;
|
uint32_t *bin;
|
||||||
|
|
||||||
struct ir3_const_state *const_state;
|
struct ir3_const_state *const_state;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The following macros are used by the shader disk cache save/
|
||||||
|
* restore paths to serialize/deserialize the variant. Any
|
||||||
|
* pointers that require special handling in store_variant()
|
||||||
|
* and retrieve_variant() should go above here.
|
||||||
|
*/
|
||||||
|
#define VARIANT_CACHE_START offsetof(struct ir3_shader_variant, info)
|
||||||
|
#define VARIANT_CACHE_PTR(v) (((char *)v) + VARIANT_CACHE_START)
|
||||||
|
#define VARIANT_CACHE_SIZE (sizeof(struct ir3_shader_variant) - VARIANT_CACHE_START)
|
||||||
|
|
||||||
struct ir3_info info;
|
struct ir3_info info;
|
||||||
|
|
||||||
/* Levels of nesting of flow control:
|
/* Levels of nesting of flow control:
|
||||||
|
@ -681,6 +696,8 @@ struct ir3_shader {
|
||||||
struct ir3_shader_variant *variants;
|
struct ir3_shader_variant *variants;
|
||||||
mtx_t variants_lock;
|
mtx_t variants_lock;
|
||||||
|
|
||||||
|
cache_key cache_key; /* shader disk-cache key */
|
||||||
|
|
||||||
/* Bitmask of bits of the shader key used by this shader. Used to avoid
|
/* Bitmask of bits of the shader key used by this shader. Used to avoid
|
||||||
* recompiles for GL NOS that doesn't actually apply to the shader.
|
* recompiles for GL NOS that doesn't actually apply to the shader.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -78,6 +78,7 @@ libfreedreno_ir3_files = files(
|
||||||
'ir3_cp_postsched.c',
|
'ir3_cp_postsched.c',
|
||||||
'ir3_dce.c',
|
'ir3_dce.c',
|
||||||
'ir3_delay.c',
|
'ir3_delay.c',
|
||||||
|
'ir3_disk_cache.c',
|
||||||
'ir3_group.c',
|
'ir3_group.c',
|
||||||
'ir3_image.c',
|
'ir3_image.c',
|
||||||
'ir3_image.h',
|
'ir3_image.h',
|
||||||
|
@ -110,7 +111,7 @@ libfreedreno_ir3 = static_library(
|
||||||
include_directories : [inc_freedreno, inc_include, inc_src, inc_mapi, inc_mesa, inc_gallium, inc_gallium_aux],
|
include_directories : [inc_freedreno, inc_include, inc_src, inc_mapi, inc_mesa, inc_gallium, inc_gallium_aux],
|
||||||
c_args : [no_override_init_args],
|
c_args : [no_override_init_args],
|
||||||
gnu_symbol_visibility : 'hidden',
|
gnu_symbol_visibility : 'hidden',
|
||||||
dependencies : idep_nir_headers,
|
dependencies : [idep_nir_headers, dep_dl],
|
||||||
build_by_default : false,
|
build_by_default : false,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -716,6 +716,19 @@ fd_get_compiler_options(struct pipe_screen *pscreen,
|
||||||
return ir2_get_compiler_options();
|
return ir2_get_compiler_options();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct disk_cache *
|
||||||
|
fd_get_disk_shader_cache(struct pipe_screen *pscreen)
|
||||||
|
{
|
||||||
|
struct fd_screen *screen = fd_screen(pscreen);
|
||||||
|
|
||||||
|
if (is_ir3(screen)) {
|
||||||
|
struct ir3_compiler *compiler = screen->compiler;
|
||||||
|
return compiler->disk_cache;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
fd_screen_bo_get_handle(struct pipe_screen *pscreen,
|
fd_screen_bo_get_handle(struct pipe_screen *pscreen,
|
||||||
struct fd_bo *bo,
|
struct fd_bo *bo,
|
||||||
|
@ -993,6 +1006,7 @@ fd_screen_create(struct fd_device *dev, struct renderonly *ro)
|
||||||
pscreen->get_shader_param = fd_screen_get_shader_param;
|
pscreen->get_shader_param = fd_screen_get_shader_param;
|
||||||
pscreen->get_compute_param = fd_get_compute_param;
|
pscreen->get_compute_param = fd_get_compute_param;
|
||||||
pscreen->get_compiler_options = fd_get_compiler_options;
|
pscreen->get_compiler_options = fd_get_compiler_options;
|
||||||
|
pscreen->get_disk_shader_cache = fd_get_disk_shader_cache;
|
||||||
|
|
||||||
fd_resource_screen_init(pscreen);
|
fd_resource_screen_init(pscreen);
|
||||||
fd_query_screen_init(pscreen);
|
fd_query_screen_init(pscreen);
|
||||||
|
|
Loading…
Reference in New Issue