From a572ba673b16e10576b45f9dd84638c0a22ce166 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Marek=20Ol=C5=A1=C3=A1k?= Date: Mon, 4 Nov 2019 21:31:40 -0500 Subject: [PATCH] nir/serialize: try to store a diff in var data locations instead of var data Reviewed-by: Connor Abbott --- src/compiler/nir/nir_serialize.c | 88 ++++++++++++++++++++++++++------ 1 file changed, 73 insertions(+), 15 deletions(-) diff --git a/src/compiler/nir/nir_serialize.c b/src/compiler/nir/nir_serialize.c index ee783284467..0fa5499657b 100644 --- a/src/compiler/nir/nir_serialize.c +++ b/src/compiler/nir/nir_serialize.c @@ -54,6 +54,7 @@ typedef struct { /* The last serialized type. */ const struct glsl_type *last_type; const struct glsl_type *last_interface_type; + struct nir_variable_data last_var_data; /* Don't write optional data such as variable names. */ bool strip; @@ -79,6 +80,7 @@ typedef struct { /* The last deserialized type. */ const struct glsl_type *last_type; const struct glsl_type *last_interface_type; + struct nir_variable_data last_var_data; } read_ctx; static void @@ -196,6 +198,7 @@ enum var_data_encoding { var_encode_full, var_encode_shader_temp, var_encode_function_temp, + var_encode_location_diff, }; union packed_var { @@ -213,6 +216,15 @@ union packed_var { } u; }; +union packed_var_data_diff { + uint32_t u32; + struct { + int location:13; + int location_frac:3; + int driver_location:16; + } u; +}; + static void write_variable(write_ctx *ctx, const nir_variable *var) { @@ -234,13 +246,40 @@ write_variable(write_ctx *ctx, const nir_variable *var) flags.u.num_state_slots = var->num_state_slots; flags.u.num_members = var->num_members; + struct nir_variable_data data = var->data; + + /* When stripping, we expect that the location is no longer needed, + * which is typically after shaders are linked. + */ + if (ctx->strip && + data.mode != nir_var_shader_in && + data.mode != nir_var_shader_out) + data.location = 0; + /* Temporary variables don't serialize var->data. */ - if (var->data.mode == nir_var_shader_temp) + if (data.mode == nir_var_shader_temp) flags.u.data_encoding = var_encode_shader_temp; - else if (var->data.mode == nir_var_function_temp) + else if (data.mode == nir_var_function_temp) flags.u.data_encoding = var_encode_function_temp; - else - flags.u.data_encoding = var_encode_full; + else { + struct nir_variable_data tmp = data; + + tmp.location = ctx->last_var_data.location; + tmp.location_frac = ctx->last_var_data.location_frac; + tmp.driver_location = ctx->last_var_data.driver_location; + + /* See if we can encode only the difference in locations from the last + * variable. + */ + if (memcmp(&ctx->last_var_data, &tmp, sizeof(tmp)) == 0 && + abs((int)data.location - + (int)ctx->last_var_data.location) < (1 << 12) && + abs((int)data.driver_location - + (int)ctx->last_var_data.driver_location) < (1 << 15)) + flags.u.data_encoding = var_encode_location_diff; + else + flags.u.data_encoding = var_encode_full; + } blob_write_uint32(ctx->blob, flags.u32); @@ -257,18 +296,25 @@ write_variable(write_ctx *ctx, const nir_variable *var) if (flags.u.has_name) blob_write_string(ctx->blob, var->name); - if (flags.u.data_encoding == var_encode_full) { - struct nir_variable_data data = var->data; + if (flags.u.data_encoding == var_encode_full || + flags.u.data_encoding == var_encode_location_diff) { + if (flags.u.data_encoding == var_encode_full) { + blob_write_bytes(ctx->blob, &data, sizeof(data)); + } else { + /* Serialize only the difference in locations from the last variable. + */ + union packed_var_data_diff diff; - /* When stripping, we expect that the location is no longer needed, - * which is typically after shaders are linked. - */ - if (ctx->strip && - data.mode != nir_var_shader_in && - data.mode != nir_var_shader_out) - data.location = 0; + diff.u.location = data.location - ctx->last_var_data.location; + diff.u.location_frac = data.location_frac - + ctx->last_var_data.location_frac; + diff.u.driver_location = data.driver_location - + ctx->last_var_data.driver_location; + + blob_write_uint32(ctx->blob, diff.u32); + } - blob_write_bytes(ctx->blob, &data, sizeof(data)); + ctx->last_var_data = data; } for (unsigned i = 0; i < var->num_state_slots; i++) { @@ -319,8 +365,20 @@ read_variable(read_ctx *ctx) var->data.mode = nir_var_shader_temp; else if (flags.u.data_encoding == var_encode_function_temp) var->data.mode = nir_var_function_temp; - else + else if (flags.u.data_encoding == var_encode_full) { blob_copy_bytes(ctx->blob, (uint8_t *) &var->data, sizeof(var->data)); + ctx->last_var_data = var->data; + } else { /* var_encode_location_diff */ + union packed_var_data_diff diff; + diff.u32 = blob_read_uint32(ctx->blob); + + var->data = ctx->last_var_data; + var->data.location += diff.u.location; + var->data.location_frac += diff.u.location_frac; + var->data.driver_location += diff.u.driver_location; + + ctx->last_var_data = var->data; + } var->num_state_slots = flags.u.num_state_slots; if (var->num_state_slots != 0) { -- 2.30.2