compiler/brw_compiler.h \
compiler/brw_dead_control_flow.cpp \
compiler/brw_dead_control_flow.h \
+ compiler/brw_debug_recompile.c \
compiler/brw_disasm.c \
compiler/brw_disasm_info.c \
compiler/brw_disasm_info.h \
int shader_time_index,
char **error_str);
+void brw_debug_key_recompile(const struct brw_compiler *c, void *log,
+ gl_shader_stage stage,
+ const void *old_key, const void *key);
+
static inline uint32_t
encode_slm_size(unsigned gen, uint32_t bytes)
{
--- /dev/null
+/*
+ * Copyright © 2019 Intel Corporation
+ *
+ * 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 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.
+ */
+
+/**
+ * @file brw_debug_recompiles.c
+ */
+
+#include <stdio.h>
+
+#include "brw_compiler.h"
+
+static bool
+key_debug(const struct brw_compiler *c, void *log,
+ const char *name, int a, int b)
+{
+ if (a != b) {
+ c->shader_perf_log(log, " %s %d->%d\n", name, a, b);
+ return true;
+ }
+ return false;
+}
+
+static bool
+key_debug_float(const struct brw_compiler *c, void *log,
+ const char *name, float a, float b)
+{
+ if (a != b) {
+ c->shader_perf_log(log, " %s %f->%f\n", name, a, b);
+ return true;
+ }
+ return false;
+}
+
+#define check(name, field) \
+ key_debug(c, log, name, old_key->field, key->field)
+#define check_float(name, field) \
+ key_debug_float(c, log, name, old_key->field, key->field)
+
+static bool
+debug_sampler_recompile(const struct brw_compiler *c, void *log,
+ const struct brw_sampler_prog_key_data *old_key,
+ const struct brw_sampler_prog_key_data *key)
+{
+ bool found = false;
+
+ found |= check("gather channel quirk", gather_channel_quirk_mask);
+ found |= check("compressed multisample layout",
+ compressed_multisample_layout_mask);
+ found |= check("16x msaa", msaa_16);
+ found |= check("y_uv image bound", y_uv_image_mask);
+ found |= check("y_u_v image bound", y_u_v_image_mask);
+ found |= check("yx_xuxv image bound", yx_xuxv_image_mask);
+ found |= check("xy_uxvx image bound", xy_uxvx_image_mask);
+ found |= check("ayuv image bound", ayuv_image_mask);
+ found |= check("xyuv image bound", xyuv_image_mask);
+
+ for (unsigned i = 0; i < MAX_SAMPLERS; i++) {
+ found |= check("EXT_texture_swizzle or DEPTH_TEXTURE_MODE", swizzles[i]);
+ found |= check("textureGather workarounds", gen6_gather_wa[i]);
+ found |= check_float("scale factor", scale_factors[i]);
+ }
+
+ for (unsigned i = 0; i < 3; i++) {
+ found |= check("GL_CLAMP enabled on any texture unit", gl_clamp_mask[i]);
+ }
+
+ return found;
+}
+
+static void
+debug_vs_recompile(const struct brw_compiler *c, void *log,
+ const struct brw_vs_prog_key *old_key,
+ const struct brw_vs_prog_key *key)
+{
+ bool found = debug_sampler_recompile(c, log, &old_key->tex, &key->tex);
+
+ for (unsigned i = 0; i < VERT_ATTRIB_MAX; i++) {
+ found |= check("vertex attrib w/a flags", gl_attrib_wa_flags[i]);
+ }
+
+ found |= check("legacy user clipping", nr_userclip_plane_consts);
+ found |= check("copy edgeflag", copy_edgeflag);
+ found |= check("pointcoord replace", point_coord_replace);
+ found |= check("vertex color clamping", clamp_vertex_color);
+
+ if (!found) {
+ c->shader_perf_log(log, " something else\n");
+ }
+}
+
+static void
+debug_tcs_recompile(const struct brw_compiler *c, void *log,
+ const struct brw_tcs_prog_key *old_key,
+ const struct brw_tcs_prog_key *key)
+{
+ bool found = debug_sampler_recompile(c, log, &old_key->tex, &key->tex);
+
+ found |= check("input vertices", input_vertices);
+ found |= check("outputs written", outputs_written);
+ found |= check("patch outputs written", patch_outputs_written);
+ found |= check("tes primitive mode", tes_primitive_mode);
+ found |= check("quads and equal_spacing workaround", quads_workaround);
+
+ if (!found) {
+ c->shader_perf_log(log, " something else\n");
+ }
+}
+
+static void
+debug_tes_recompile(const struct brw_compiler *c, void *log,
+ const struct brw_tes_prog_key *old_key,
+ const struct brw_tes_prog_key *key)
+{
+ bool found = debug_sampler_recompile(c, log, &old_key->tex, &key->tex);
+
+ found |= check("inputs read", inputs_read);
+ found |= check("patch inputs read", patch_inputs_read);
+
+ if (!found) {
+ c->shader_perf_log(log, " something else\n");
+ }
+}
+
+static void
+debug_gs_recompile(const struct brw_compiler *c, void *log,
+ const struct brw_gs_prog_key *old_key,
+ const struct brw_gs_prog_key *key)
+{
+ bool found = debug_sampler_recompile(c, log, &old_key->tex, &key->tex);
+
+ if (!found) {
+ c->shader_perf_log(log, " something else\n");
+ }
+}
+
+static void
+debug_fs_recompile(const struct brw_compiler *c, void *log,
+ const struct brw_wm_prog_key *old_key,
+ const struct brw_wm_prog_key *key)
+{
+ bool found = false;
+
+ found |= check("alphatest, computed depth, depth test, or depth write",
+ iz_lookup);
+ found |= check("depth statistics", stats_wm);
+ found |= check("flat shading", flat_shade);
+ found |= check("number of color buffers", nr_color_regions);
+ found |= check("MRT alpha test", alpha_test_replicate_alpha);
+ found |= check("alpha to coverage", alpha_to_coverage);
+ found |= check("fragment color clamping", clamp_fragment_color);
+ found |= check("per-sample interpolation", persample_interp);
+ found |= check("multisampled FBO", multisample_fbo);
+ found |= check("frag coord adds sample pos", frag_coord_adds_sample_pos);
+ found |= check("line smoothing", line_aa);
+ found |= check("high quality derivatives", high_quality_derivatives);
+ found |= check("force dual color blending", force_dual_color_blend);
+ found |= check("coherent fb fetch", coherent_fb_fetch);
+
+ found |= check("input slots valid", input_slots_valid);
+ found |= check("mrt alpha test function", alpha_test_func);
+ found |= check("mrt alpha test reference value", alpha_test_ref);
+
+ found |= debug_sampler_recompile(c, log, &old_key->tex, &key->tex);
+
+ if (!found) {
+ c->shader_perf_log(log, " something else\n");
+ }
+}
+
+static void
+debug_cs_recompile(const struct brw_compiler *c, void *log,
+ const struct brw_cs_prog_key *old_key,
+ const struct brw_cs_prog_key *key)
+{
+ bool found = debug_sampler_recompile(c, log, &old_key->tex, &key->tex);
+
+ if (!found) {
+ c->shader_perf_log(log, " something else\n");
+ }
+}
+
+void
+brw_debug_key_recompile(const struct brw_compiler *c, void *log,
+ gl_shader_stage stage,
+ const void *old_key, const void *key)
+{
+ if (!old_key) {
+ c->shader_perf_log(log, " No previous compile found...\n");
+ return;
+ }
+
+ switch (stage) {
+ case MESA_SHADER_VERTEX:
+ debug_vs_recompile(c, log, old_key, key);
+ break;
+ case MESA_SHADER_TESS_CTRL:
+ debug_tcs_recompile(c, log, old_key, key);
+ break;
+ case MESA_SHADER_TESS_EVAL:
+ debug_tes_recompile(c, log, old_key, key);
+ break;
+ case MESA_SHADER_GEOMETRY:
+ debug_gs_recompile(c, log, old_key, key);
+ break;
+ case MESA_SHADER_FRAGMENT:
+ debug_fs_recompile(c, log, old_key, key);
+ break;
+ case MESA_SHADER_COMPUTE:
+ debug_cs_recompile(c, log, old_key, key);
+ break;
+ default:
+ break;
+ }
+}
'brw_compiler.h',
'brw_dead_control_flow.cpp',
'brw_dead_control_flow.h',
+ 'brw_debug_recompile.c',
'brw_disasm.c',
'brw_disasm_info.c',
'brw_disasm_info.h',
/*======================================================================
* brw_program.c
*/
-static inline bool
-key_debug(struct brw_context *brw, const char *name, int a, int b)
-{
- if (a != b) {
- perf_debug(" %s %d->%d\n", name, a, b);
- return true;
- }
- return false;
-}
-
-static inline bool
-key_debug_float(struct brw_context *brw, const char *name, float a, float b)
-{
- if (a != b) {
- perf_debug(" %s %f->%f\n", name, a, b);
- return true;
- }
- return false;
-}
-
void brwInitFragProgFuncs( struct dd_function_table *functions );
void brw_get_scratch_bo(struct brw_context *brw,
if (unlikely(brw->perf_debug)) {
if (cp->compiled_once) {
- _mesa_problem(&brw->ctx, "CS programs shouldn't need recompiles");
+ brw_debug_recompile(brw, MESA_SHADER_COMPUTE, cp->program.Id,
+ key->program_string_id, key);
}
cp->compiled_once = true;
#include "brw_program.h"
#include "compiler/glsl/ir_uniform.h"
-static void
-brw_gs_debug_recompile(struct brw_context *brw, struct gl_program *prog,
- const struct brw_gs_prog_key *key)
-{
- perf_debug("Recompiling geometry shader for program %d\n", prog->Id);
-
- bool found = false;
- const struct brw_gs_prog_key *old_key =
- brw_find_previous_compile(&brw->cache, BRW_CACHE_GS_PROG,
- key->program_string_id);
-
- if (!old_key) {
- perf_debug(" Didn't find previous compile in the shader cache for "
- "debug\n");
- return;
- }
-
- found |= brw_debug_recompile_sampler_key(brw, &old_key->tex, &key->tex);
-
- if (!found) {
- perf_debug(" Something else\n");
- }
-}
-
static void
assign_gs_binding_table_offsets(const struct gen_device_info *devinfo,
const struct gl_program *prog,
if (unlikely(brw->perf_debug)) {
if (gp->compiled_once) {
- brw_gs_debug_recompile(brw, &gp->program, key);
+ brw_debug_recompile(brw, MESA_SHADER_GEOMETRY, gp->program.Id,
+ key->program_string_id, key);
}
if (start_busy && !brw_bo_busy(brw->batch.last_bo)) {
perf_debug("GS compile took %.03f ms and stalled the GPU\n",
#include "brw_gs.h"
#include "brw_vs.h"
#include "brw_wm.h"
+#include "brw_state.h"
#include "main/shaderapi.h"
#include "main/shaderobj.h"
unreachable("Unsupported stage!");
}
}
+
+void
+brw_debug_recompile(struct brw_context *brw,
+ gl_shader_stage stage,
+ unsigned api_id,
+ unsigned key_program_string_id,
+ void *key)
+{
+ const struct brw_compiler *compiler = brw->screen->compiler;
+ enum brw_cache_id cache_id = brw_stage_cache_id(stage);
+
+ compiler->shader_perf_log(brw, "Recompiling %s shader for program %d\n",
+ _mesa_shader_stage_to_string(stage), api_id);
+
+ const void *old_key =
+ brw_find_previous_compile(&brw->cache, cache_id, key_program_string_id);
+
+ brw_debug_key_recompile(compiler, brw, stage, old_key, key);
+}
void brw_populate_sampler_prog_key_data(struct gl_context *ctx,
const struct gl_program *prog,
struct brw_sampler_prog_key_data *key);
-bool brw_debug_recompile_sampler_key(struct brw_context *brw,
- const struct brw_sampler_prog_key_data *old_key,
- const struct brw_sampler_prog_key_data *key);
-
+void brw_debug_recompile(struct brw_context *brw, gl_shader_stage stage,
+ unsigned api_id, unsigned prog_string_id, void *key);
uint32_t
brw_assign_common_binding_table_offsets(const struct gen_device_info *devinfo,
const struct gl_program *prog,
#include "program/prog_parameter.h"
#include "nir_builder.h"
-static void
-brw_tcs_debug_recompile(struct brw_context *brw, struct gl_program *prog,
- const struct brw_tcs_prog_key *key)
-{
- perf_debug("Recompiling tessellation control shader for program %d\n",
- prog->Id);
-
- bool found = false;
- const struct brw_tcs_prog_key *old_key =
- brw_find_previous_compile(&brw->cache, BRW_CACHE_TCS_PROG,
- key->program_string_id);
-
- if (!old_key) {
- perf_debug(" Didn't find previous compile in the shader cache for "
- "debug\n");
- return;
- }
-
- found |= key_debug(brw, "input vertices", old_key->input_vertices,
- key->input_vertices);
- found |= key_debug(brw, "outputs written", old_key->outputs_written,
- key->outputs_written);
- found |= key_debug(brw, "patch outputs written", old_key->patch_outputs_written,
- key->patch_outputs_written);
- found |= key_debug(brw, "TES primitive mode", old_key->tes_primitive_mode,
- key->tes_primitive_mode);
- found |= key_debug(brw, "quads and equal_spacing workaround",
- old_key->quads_workaround, key->quads_workaround);
- found |= brw_debug_recompile_sampler_key(brw, &old_key->tex, &key->tex);
-
- if (!found) {
- perf_debug(" Something else\n");
- }
-}
-
static bool
brw_codegen_tcs_prog(struct brw_context *brw, struct brw_program *tcp,
struct brw_program *tep, struct brw_tcs_prog_key *key)
if (unlikely(brw->perf_debug)) {
if (tcp) {
if (tcp->compiled_once) {
- brw_tcs_debug_recompile(brw, &tcp->program, key);
+ brw_debug_recompile(brw, MESA_SHADER_TESS_CTRL, tcp->program.Id,
+ key->program_string_id, key);
}
tcp->compiled_once = true;
}
#include "brw_state.h"
#include "program/prog_parameter.h"
-static void
-brw_tes_debug_recompile(struct brw_context *brw, struct gl_program *prog,
- const struct brw_tes_prog_key *key)
-{
- perf_debug("Recompiling tessellation evaluation shader for program %d\n",
- prog->Id);
-
- bool found = false;
- const struct brw_tes_prog_key *old_key =
- brw_find_previous_compile(&brw->cache, BRW_CACHE_TES_PROG,
- key->program_string_id);
-
- if (!old_key) {
- perf_debug(" Didn't find previous compile in the shader cache for "
- "debug\n");
- return;
- }
-
- found |= brw_debug_recompile_sampler_key(brw, &old_key->tex, &key->tex);
- found |= key_debug(brw, "inputs read", old_key->inputs_read,
- key->inputs_read);
- found |= key_debug(brw, "patch inputs read", old_key->patch_inputs_read,
- key->patch_inputs_read);
-
- if (!found) {
- perf_debug(" Something else\n");
- }
-}
-
static bool
brw_codegen_tes_prog(struct brw_context *brw,
struct brw_program *tep,
if (unlikely(brw->perf_debug)) {
if (tep->compiled_once) {
- brw_tes_debug_recompile(brw, &tep->program, key);
+ brw_debug_recompile(brw, MESA_SHADER_TESS_EVAL, tep->program.Id,
+ key->program_string_id, key);
}
if (start_busy && !brw_bo_busy(brw->batch.last_bo)) {
perf_debug("TES compile took %.03f ms and stalled the GPU\n",
return outputs_written;
}
-static void
-brw_vs_debug_recompile(struct brw_context *brw, struct gl_program *prog,
- const struct brw_vs_prog_key *key)
-{
- perf_debug("Recompiling vertex shader for program %d\n", prog->Id);
-
- bool found = false;
- const struct brw_vs_prog_key *old_key =
- brw_find_previous_compile(&brw->cache, BRW_CACHE_VS_PROG,
- key->program_string_id);
-
- if (!old_key) {
- perf_debug(" Didn't find previous compile in the shader cache for "
- "debug\n");
- return;
- }
-
- for (unsigned int i = 0; i < VERT_ATTRIB_MAX; i++) {
- found |= key_debug(brw, "Vertex attrib w/a flags",
- old_key->gl_attrib_wa_flags[i],
- key->gl_attrib_wa_flags[i]);
- }
-
- found |= key_debug(brw, "legacy user clipping",
- old_key->nr_userclip_plane_consts,
- key->nr_userclip_plane_consts);
-
- found |= key_debug(brw, "copy edgeflag",
- old_key->copy_edgeflag, key->copy_edgeflag);
- found |= key_debug(brw, "PointCoord replace",
- old_key->point_coord_replace, key->point_coord_replace);
- found |= key_debug(brw, "vertex color clamping",
- old_key->clamp_vertex_color, key->clamp_vertex_color);
-
- found |= brw_debug_recompile_sampler_key(brw, &old_key->tex, &key->tex);
-
- if (!found) {
- perf_debug(" Something else\n");
- }
-}
-
static bool
brw_codegen_vs_prog(struct brw_context *brw,
struct brw_program *vp,
if (unlikely(brw->perf_debug)) {
if (vp->compiled_once) {
- brw_vs_debug_recompile(brw, &vp->program, key);
+ brw_debug_recompile(brw, MESA_SHADER_VERTEX, vp->program.Id,
+ key->program_string_id, key);
}
if (start_busy && !brw_bo_busy(brw->batch.last_bo)) {
perf_debug("VS compile took %.03f ms and stalled the GPU\n",
prog_data->base.binding_table.size_bytes = next_binding_table_offset * 4;
}
-static void
-brw_wm_debug_recompile(struct brw_context *brw, struct gl_program *prog,
- const struct brw_wm_prog_key *key)
-{
- perf_debug("Recompiling fragment shader for program %d\n", prog->Id);
-
- bool found = false;
- const struct brw_wm_prog_key *old_key =
- brw_find_previous_compile(&brw->cache, BRW_CACHE_FS_PROG,
- key->program_string_id);
-
- if (!old_key) {
- perf_debug(" Didn't find previous compile in the shader cache for debug\n");
- return;
- }
-
- found |= key_debug(brw, "alphatest, computed depth, depth test, or "
- "depth write",
- old_key->iz_lookup, key->iz_lookup);
- found |= key_debug(brw, "depth statistics",
- old_key->stats_wm, key->stats_wm);
- found |= key_debug(brw, "flat shading",
- old_key->flat_shade, key->flat_shade);
- found |= key_debug(brw, "number of color buffers",
- old_key->nr_color_regions, key->nr_color_regions);
- found |= key_debug(brw, "MRT alpha test",
- old_key->alpha_test_replicate_alpha,
- key->alpha_test_replicate_alpha);
- found |= key_debug(brw, "alpha to coverage",
- old_key->alpha_to_coverage, key->alpha_to_coverage);
- found |= key_debug(brw, "fragment color clamping",
- old_key->clamp_fragment_color, key->clamp_fragment_color);
- found |= key_debug(brw, "per-sample interpolation",
- old_key->persample_interp, key->persample_interp);
- found |= key_debug(brw, "multisampled FBO",
- old_key->multisample_fbo, key->multisample_fbo);
- found |= key_debug(brw, "frag coord adds sample pos",
- old_key->frag_coord_adds_sample_pos,
- key->frag_coord_adds_sample_pos);
- found |= key_debug(brw, "line smoothing",
- old_key->line_aa, key->line_aa);
- found |= key_debug(brw, "high quality derivatives",
- old_key->high_quality_derivatives,
- key->high_quality_derivatives);
- found |= key_debug(brw, "force dual color blending",
- old_key->force_dual_color_blend,
- key->force_dual_color_blend);
- found |= key_debug(brw, "coherent fb fetch",
- old_key->coherent_fb_fetch, key->coherent_fb_fetch);
-
- found |= key_debug(brw, "input slots valid",
- old_key->input_slots_valid, key->input_slots_valid);
- found |= key_debug(brw, "mrt alpha test function",
- old_key->alpha_test_func, key->alpha_test_func);
- found |= key_debug(brw, "mrt alpha test reference value",
- old_key->alpha_test_ref, key->alpha_test_ref);
-
- found |= brw_debug_recompile_sampler_key(brw, &old_key->tex, &key->tex);
-
- if (!found) {
- perf_debug(" Something else\n");
- }
-}
-
static bool
brw_codegen_wm_prog(struct brw_context *brw,
struct brw_program *fp,
}
if (unlikely(brw->perf_debug)) {
- if (fp->compiled_once)
- brw_wm_debug_recompile(brw, &fp->program, key);
+ if (fp->compiled_once) {
+ brw_debug_recompile(brw, MESA_SHADER_FRAGMENT, fp->program.Id,
+ key->program_string_id, key);
+ }
fp->compiled_once = true;
if (start_busy && !brw_bo_busy(brw->batch.last_bo)) {
return true;
}
-bool
-brw_debug_recompile_sampler_key(struct brw_context *brw,
- const struct brw_sampler_prog_key_data *old_key,
- const struct brw_sampler_prog_key_data *key)
-{
- bool found = false;
-
- for (unsigned int i = 0; i < MAX_SAMPLERS; i++) {
- found |= key_debug(brw, "EXT_texture_swizzle or DEPTH_TEXTURE_MODE",
- old_key->swizzles[i], key->swizzles[i]);
- }
- found |= key_debug(brw, "GL_CLAMP enabled on any texture unit's 1st coordinate",
- old_key->gl_clamp_mask[0], key->gl_clamp_mask[0]);
- found |= key_debug(brw, "GL_CLAMP enabled on any texture unit's 2nd coordinate",
- old_key->gl_clamp_mask[1], key->gl_clamp_mask[1]);
- found |= key_debug(brw, "GL_CLAMP enabled on any texture unit's 3rd coordinate",
- old_key->gl_clamp_mask[2], key->gl_clamp_mask[2]);
- found |= key_debug(brw, "gather channel quirk on any texture unit",
- old_key->gather_channel_quirk_mask, key->gather_channel_quirk_mask);
- found |= key_debug(brw, "compressed multisample layout",
- old_key->compressed_multisample_layout_mask,
- key->compressed_multisample_layout_mask);
- found |= key_debug(brw, "16x msaa",
- old_key->msaa_16,
- key->msaa_16);
-
- found |= key_debug(brw, "y_uv image bound",
- old_key->y_uv_image_mask,
- key->y_uv_image_mask);
- found |= key_debug(brw, "y_u_v image bound",
- old_key->y_u_v_image_mask,
- key->y_u_v_image_mask);
- found |= key_debug(brw, "yx_xuxv image bound",
- old_key->yx_xuxv_image_mask,
- key->yx_xuxv_image_mask);
- found |= key_debug(brw, "xy_uxvx image bound",
- old_key->xy_uxvx_image_mask,
- key->xy_uxvx_image_mask);
- found |= key_debug(brw, "ayuv image bound",
- old_key->ayuv_image_mask,
- key->ayuv_image_mask);
- found |= key_debug(brw, "xyuv image bound",
- old_key->xyuv_image_mask,
- key->xyuv_image_mask);
-
- for (unsigned int i = 0; i < MAX_SAMPLERS; i++) {
- found |= key_debug(brw, "textureGather workarounds",
- old_key->gen6_gather_wa[i], key->gen6_gather_wa[i]);
- }
-
- for (unsigned int i = 0; i < MAX_SAMPLERS; i++) {
- found |= key_debug_float(brw, "scale factor",
- old_key->scale_factors[i],
- key->scale_factors[i]);
- }
-
- return found;
-}
-
static uint8_t
gen6_gather_workaround(GLenum internalformat)
{