summaryrefslogtreecommitdiff
path: root/lib/mesa
diff options
context:
space:
mode:
Diffstat (limited to 'lib/mesa')
-rw-r--r--lib/mesa/src/amd/common/ac_shader_abi.h101
-rw-r--r--lib/mesa/src/amd/vulkan/dev_icd.json.in2
-rw-r--r--lib/mesa/src/amd/vulkan/radv_debug.c736
-rw-r--r--lib/mesa/src/amd/vulkan/radv_extensions.c407
-rw-r--r--lib/mesa/src/amd/vulkan/radv_extensions.py278
-rw-r--r--lib/mesa/src/amd/vulkan/radv_pass.c25
-rw-r--r--lib/mesa/src/amd/vulkan/radv_shader.c671
-rw-r--r--lib/mesa/src/amd/vulkan/radv_shader.h123
-rw-r--r--lib/mesa/src/broadcom/Makefile.cle.am6
-rw-r--r--lib/mesa/src/broadcom/Makefile.vc5.am20
-rw-r--r--lib/mesa/src/broadcom/cle/v3d_decoder.c876
-rw-r--r--lib/mesa/src/broadcom/cle/v3d_decoder.h146
-rw-r--r--lib/mesa/src/broadcom/cle/v3d_packet_v33.xml910
-rw-r--r--lib/mesa/src/broadcom/cle/v3d_packet_v33_pack.h3733
-rw-r--r--lib/mesa/src/broadcom/cle/v3d_xml.h719
-rw-r--r--lib/mesa/src/broadcom/clif/clif_dump.c281
-rw-r--r--lib/mesa/src/broadcom/clif/clif_dump.h42
-rw-r--r--lib/mesa/src/broadcom/common/v3d_debug.c89
-rw-r--r--lib/mesa/src/broadcom/common/v3d_debug.h82
-rw-r--r--lib/mesa/src/broadcom/compiler/nir_to_vir.c2054
-rw-r--r--lib/mesa/src/broadcom/compiler/qpu_schedule.c1365
-rw-r--r--lib/mesa/src/broadcom/compiler/qpu_validate.c208
-rw-r--r--lib/mesa/src/broadcom/compiler/v3d_compiler.h934
-rw-r--r--lib/mesa/src/broadcom/compiler/v3d_nir_lower_io.c176
-rw-r--r--lib/mesa/src/broadcom/compiler/vir.c898
-rw-r--r--lib/mesa/src/broadcom/compiler/vir_dump.c339
-rw-r--r--lib/mesa/src/broadcom/compiler/vir_live_variables.c340
-rw-r--r--lib/mesa/src/broadcom/compiler/vir_lower_uniforms.c209
-rw-r--r--lib/mesa/src/broadcom/compiler/vir_opt_copy_propagate.c233
-rw-r--r--lib/mesa/src/broadcom/compiler/vir_opt_dead_code.c162
-rw-r--r--lib/mesa/src/broadcom/compiler/vir_register_allocate.c254
-rw-r--r--lib/mesa/src/broadcom/compiler/vir_to_qpu.c359
-rw-r--r--lib/mesa/src/broadcom/qpu/qpu_disasm.c298
-rw-r--r--lib/mesa/src/broadcom/qpu/qpu_disasm.h39
-rw-r--r--lib/mesa/src/broadcom/qpu/qpu_instr.c645
-rw-r--r--lib/mesa/src/broadcom/qpu/qpu_instr.h411
-rw-r--r--lib/mesa/src/broadcom/qpu/qpu_pack.c1206
-rw-r--r--lib/mesa/src/broadcom/qpu/tests/qpu_disasm.c146
-rw-r--r--lib/mesa/src/egl/SConscript2
-rw-r--r--lib/mesa/src/egl/drivers/dri2/platform_x11_dri3.h2
-rw-r--r--lib/mesa/src/egl/main/eglcurrent.h7
-rw-r--r--lib/mesa/src/egl/main/egldriver.c282
-rw-r--r--lib/mesa/src/egl/main/egldriver.h18
-rw-r--r--lib/mesa/src/egl/wayland/wayland-drm/Makefile.am2
-rw-r--r--lib/mesa/src/egl/wayland/wayland-drm/wayland-drm.h74
-rw-r--r--lib/mesa/src/egl/wayland/wayland-egl/wayland-egl-backend.h63
-rw-r--r--lib/mesa/src/glx/apple/apple_glapi.c12
-rw-r--r--lib/mesa/src/glx/apple/apple_glx_context.c4
-rw-r--r--lib/mesa/src/glx/apple/apple_glx_log.c3
-rw-r--r--lib/mesa/src/glx/apple/apple_glx_pbuffer.c6
-rw-r--r--lib/mesa/src/glx/apple/apple_visual.c9
-rw-r--r--lib/mesa/src/glx/driwindows_glx.c3
-rw-r--r--lib/mesa/src/glx/glxext.c24
-rw-r--r--lib/mesa/src/glx/glxextensions.c23
-rw-r--r--lib/mesa/src/glx/indirect_glx.c6
-rw-r--r--lib/mesa/src/glx/tests/enum_sizes.cpp2
-rw-r--r--lib/mesa/src/intel/compiler/brw_nir_lower_cs_intrinsics.c184
-rw-r--r--lib/mesa/src/intel/compiler/brw_reg_type.c299
-rw-r--r--lib/mesa/src/intel/compiler/brw_reg_type.h117
-rw-r--r--lib/mesa/src/mesa/drivers/SConscript1
-rw-r--r--lib/mesa/src/mesa/drivers/dri/common/Makefile.sources7
-rw-r--r--lib/mesa/src/mesa/drivers/dri/common/SConscript8
-rw-r--r--lib/mesa/src/mesa/drivers/dri/common/utils.c8
-rw-r--r--lib/mesa/src/mesa/main/barrier.h3
-rw-r--r--lib/mesa/src/mesa/main/condrender.h6
-rw-r--r--lib/mesa/src/mesa/main/execmem.h37
-rw-r--r--lib/mesa/src/mesa/main/extensions.c7
-rw-r--r--lib/mesa/src/mesa/main/externalobjects.c640
-rw-r--r--lib/mesa/src/mesa/main/externalobjects.h231
-rw-r--r--lib/mesa/src/mesa/main/format_pack.c72
-rw-r--r--lib/mesa/src/mesa/main/format_unpack.c59
-rw-r--r--lib/mesa/src/mesa/main/format_utils.c14
-rw-r--r--lib/mesa/src/mesa/main/formats.csv1
-rw-r--r--lib/mesa/src/mesa/main/get.h6
-rw-r--r--lib/mesa/src/mesa/main/lines.h5
-rw-r--r--lib/mesa/src/mesa/main/multisample.h6
-rw-r--r--lib/mesa/src/mesa/main/points.c30
-rw-r--r--lib/mesa/src/mesa/main/points.h3
-rw-r--r--lib/mesa/src/mesa/main/readpix.h9
-rw-r--r--lib/mesa/src/mesa/main/texcompress_s3tc.c269
-rw-r--r--lib/mesa/src/mesa/main/texcompress_s3tc.h3
-rw-r--r--lib/mesa/src/mesa/main/texcompress_s3tc_tmp.h989
-rw-r--r--lib/mesa/src/mesa/main/texformat.c18
-rw-r--r--lib/mesa/src/mesa/main/textureview.h6
-rw-r--r--lib/mesa/src/mesa/main/version.h11
-rw-r--r--lib/mesa/src/mesa/state_tracker/st_cb_bufferobjects.h6
-rw-r--r--lib/mesa/src/mesa/state_tracker/st_cb_drawpixels_shader.c2
-rw-r--r--lib/mesa/src/mesa/state_tracker/st_cb_flush.c51
-rw-r--r--lib/mesa/src/mesa/state_tracker/st_cb_memoryobjects.c66
-rw-r--r--lib/mesa/src/mesa/state_tracker/st_cb_memoryobjects.h25
-rw-r--r--lib/mesa/src/mesa/state_tracker/st_cb_syncobj.c13
-rw-r--r--lib/mesa/src/mesa/state_tracker/st_extensions.h3
-rw-r--r--lib/mesa/src/mesa/state_tracker/st_glsl_to_tgsi_private.cpp252
-rw-r--r--lib/mesa/src/mesa/state_tracker/st_glsl_to_tgsi_private.h180
-rw-r--r--lib/mesa/src/mesa/state_tracker/st_glsl_to_tgsi_temprename.cpp1010
-rw-r--r--lib/mesa/src/mesa/state_tracker/st_glsl_to_tgsi_temprename.h71
-rw-r--r--lib/mesa/src/mesa/state_tracker/st_glsl_types.h4
-rw-r--r--lib/mesa/src/mesa/state_tracker/st_vdpau.c4
-rw-r--r--lib/mesa/src/mesa/state_tracker/tests/Makefile.am34
-rw-r--r--lib/mesa/src/mesa/state_tracker/tests/Makefile.in1266
-rw-r--r--lib/mesa/src/mesa/state_tracker/tests/test_glsl_to_tgsi_lifetime.cpp1600
-rw-r--r--lib/mesa/src/mesa/tnl/t_vertex.c1
-rw-r--r--lib/mesa/src/mesa/x86/rtasm/x86sse.c1
-rw-r--r--lib/mesa/src/util/debug.h6
-rw-r--r--lib/mesa/src/util/drirc286
-rw-r--r--lib/mesa/src/util/half_float.h8
-rw-r--r--lib/mesa/src/util/merge_driinfo.py222
-rw-r--r--lib/mesa/src/util/register_allocate.c142
-rw-r--r--lib/mesa/src/util/string_buffer.c148
-rw-r--r--lib/mesa/src/util/string_buffer.h104
-rw-r--r--lib/mesa/src/util/tests/string_buffer/Makefile.am40
-rw-r--r--lib/mesa/src/util/tests/string_buffer/Makefile.in1188
-rw-r--r--lib/mesa/src/util/tests/string_buffer/string_buffer_test.cpp122
-rw-r--r--lib/mesa/src/util/xmlconfig.c1113
-rw-r--r--lib/mesa/src/util/xmlconfig.h179
-rw-r--r--lib/mesa/src/util/xmlpool.h105
-rw-r--r--lib/mesa/src/util/xmlpool/Makefile.am101
-rw-r--r--lib/mesa/src/util/xmlpool/Makefile.in732
-rw-r--r--lib/mesa/src/util/xmlpool/SConscript14
-rw-r--r--lib/mesa/src/util/xmlpool/ca.po348
-rw-r--r--lib/mesa/src/util/xmlpool/ca/LC_MESSAGES/options.mobin0 -> 8395 bytes
-rw-r--r--lib/mesa/src/util/xmlpool/de.po320
-rw-r--r--lib/mesa/src/util/xmlpool/de/LC_MESSAGES/options.mobin0 -> 6385 bytes
-rw-r--r--lib/mesa/src/util/xmlpool/es.po332
-rw-r--r--lib/mesa/src/util/xmlpool/es/LC_MESSAGES/options.mobin0 -> 8385 bytes
-rw-r--r--lib/mesa/src/util/xmlpool/fr.po310
-rw-r--r--lib/mesa/src/util/xmlpool/fr/LC_MESSAGES/options.mobin0 -> 5186 bytes
-rw-r--r--lib/mesa/src/util/xmlpool/gen_xmlpool.py203
-rw-r--r--lib/mesa/src/util/xmlpool/nl.po311
-rw-r--r--lib/mesa/src/util/xmlpool/nl/LC_MESSAGES/options.mobin0 -> 5238 bytes
-rw-r--r--lib/mesa/src/util/xmlpool/options.h1028
-rw-r--r--lib/mesa/src/util/xmlpool/sv.po309
-rw-r--r--lib/mesa/src/util/xmlpool/sv/LC_MESSAGES/options.mobin0 -> 5024 bytes
-rw-r--r--lib/mesa/src/util/xmlpool/t_options.h454
-rw-r--r--lib/mesa/src/vulkan/registry/vk_android_native_buffer.xml52
135 files changed, 35130 insertions, 750 deletions
diff --git a/lib/mesa/src/amd/common/ac_shader_abi.h b/lib/mesa/src/amd/common/ac_shader_abi.h
new file mode 100644
index 000000000..b04dc076d
--- /dev/null
+++ b/lib/mesa/src/amd/common/ac_shader_abi.h
@@ -0,0 +1,101 @@
+/*
+ * Copyright 2017 Advanced Micro Devices, 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
+ * on the rights to use, copy, modify, merge, publish, distribute, sub
+ * license, 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 NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHOR(S) AND/OR THEIR SUPPLIERS 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.
+ */
+
+#ifndef AC_SHADER_ABI_H
+#define AC_SHADER_ABI_H
+
+#include <llvm-c/Core.h>
+
+enum ac_descriptor_type {
+ AC_DESC_IMAGE,
+ AC_DESC_FMASK,
+ AC_DESC_SAMPLER,
+ AC_DESC_BUFFER,
+};
+
+/* Document the shader ABI during compilation. This is what allows radeonsi and
+ * radv to share a compiler backend.
+ */
+struct ac_shader_abi {
+ LLVMValueRef base_vertex;
+ LLVMValueRef start_instance;
+ LLVMValueRef draw_id;
+ LLVMValueRef vertex_id;
+ LLVMValueRef instance_id;
+ LLVMValueRef frag_pos[4];
+ LLVMValueRef front_face;
+ LLVMValueRef ancillary;
+ LLVMValueRef sample_coverage;
+
+ /* For VS and PS: pre-loaded shader inputs.
+ *
+ * Currently only used for NIR shaders; indexed by variables'
+ * driver_location.
+ */
+ LLVMValueRef *inputs;
+
+ void (*emit_outputs)(struct ac_shader_abi *abi,
+ unsigned max_outputs,
+ LLVMValueRef *addrs);
+
+ LLVMValueRef (*load_ubo)(struct ac_shader_abi *abi, LLVMValueRef index);
+
+ /**
+ * Load the descriptor for the given buffer.
+ *
+ * \param buffer the buffer as presented in NIR: this is the descriptor
+ * in Vulkan, and the buffer index in OpenGL/Gallium
+ * \param write whether buffer contents will be written
+ */
+ LLVMValueRef (*load_ssbo)(struct ac_shader_abi *abi,
+ LLVMValueRef buffer, bool write);
+
+ /**
+ * Load a descriptor associated to a sampler.
+ *
+ * \param descriptor_set the descriptor set index (only for Vulkan)
+ * \param base_index the base index of the sampler variable
+ * \param constant_index constant part of an array index (or 0, if the
+ * sampler variable is not an array)
+ * \param index non-constant part of an array index (may be NULL)
+ * \param desc_type the type of descriptor to load
+ * \param image whether the descriptor is loaded for an image operation
+ */
+ LLVMValueRef (*load_sampler_desc)(struct ac_shader_abi *abi,
+ unsigned descriptor_set,
+ unsigned base_index,
+ unsigned constant_index,
+ LLVMValueRef index,
+ enum ac_descriptor_type desc_type,
+ bool image, bool write);
+
+ /* Whether to clamp the shadow reference value to [0,1]on VI. Radeonsi currently
+ * uses it due to promoting D16 to D32, but radv needs it off. */
+ bool clamp_shadow_reference;
+
+ /* Whether to workaround GFX9 ignoring the stride for the buffer size if IDXEN=0
+ * and LLVM optimizes an indexed load with constant index to IDXEN=0. */
+ bool gfx9_stride_size_workaround;
+};
+
+#endif /* AC_SHADER_ABI_H */
diff --git a/lib/mesa/src/amd/vulkan/dev_icd.json.in b/lib/mesa/src/amd/vulkan/dev_icd.json.in
index f726df02a..cc80641f5 100644
--- a/lib/mesa/src/amd/vulkan/dev_icd.json.in
+++ b/lib/mesa/src/amd/vulkan/dev_icd.json.in
@@ -1,7 +1,7 @@
{
"file_format_version": "1.0.0",
"ICD": {
- "library_path": "@build_libdir@/libvulkan_radeon.so",
+ "library_path": "@libvulkan_radeon_path@",
"api_version": "1.0.3"
}
}
diff --git a/lib/mesa/src/amd/vulkan/radv_debug.c b/lib/mesa/src/amd/vulkan/radv_debug.c
new file mode 100644
index 000000000..b69c05b64
--- /dev/null
+++ b/lib/mesa/src/amd/vulkan/radv_debug.c
@@ -0,0 +1,736 @@
+/*
+ * Copyright © 2016 Red Hat.
+ * Copyright © 2016 Bas Nieuwenhuizen
+ *
+ * based in part on anv driver which is:
+ * Copyright © 2015 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 (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 <stdlib.h>
+#include <stdio.h>
+#include <sys/utsname.h>
+
+#include "sid.h"
+#include "gfx9d.h"
+#include "ac_debug.h"
+#include "radv_debug.h"
+#include "radv_shader.h"
+
+#define TRACE_BO_SIZE 4096
+
+#define COLOR_RESET "\033[0m"
+#define COLOR_RED "\033[31m"
+#define COLOR_GREEN "\033[1;32m"
+#define COLOR_YELLOW "\033[1;33m"
+#define COLOR_CYAN "\033[1;36m"
+
+/* Trace BO layout (offsets are 4 bytes):
+ *
+ * [0]: primary trace ID
+ * [1]: secondary trace ID
+ * [2-3]: 64-bit GFX pipeline pointer
+ * [4-5]: 64-bit COMPUTE pipeline pointer
+ * [6-7]: 64-bit descriptor set #0 pointer
+ * ...
+ * [68-69]: 64-bit descriptor set #31 pointer
+ */
+
+bool
+radv_init_trace(struct radv_device *device)
+{
+ struct radeon_winsys *ws = device->ws;
+
+ device->trace_bo = ws->buffer_create(ws, TRACE_BO_SIZE, 8,
+ RADEON_DOMAIN_VRAM,
+ RADEON_FLAG_CPU_ACCESS);
+ if (!device->trace_bo)
+ return false;
+
+ device->trace_id_ptr = ws->buffer_map(device->trace_bo);
+ if (!device->trace_id_ptr)
+ return false;
+
+ memset(device->trace_id_ptr, 0, TRACE_BO_SIZE);
+
+ ac_vm_fault_occured(device->physical_device->rad_info.chip_class,
+ &device->dmesg_timestamp, NULL);
+
+ return true;
+}
+
+static void
+radv_dump_trace(struct radv_device *device, struct radeon_winsys_cs *cs)
+{
+ const char *filename = getenv("RADV_TRACE_FILE");
+ FILE *f = fopen(filename, "w");
+
+ if (!f) {
+ fprintf(stderr, "Failed to write trace dump to %s\n", filename);
+ return;
+ }
+
+ fprintf(f, "Trace ID: %x\n", *device->trace_id_ptr);
+ device->ws->cs_dump(cs, f, (const int*)device->trace_id_ptr, 2);
+ fclose(f);
+}
+
+static void
+radv_dump_mmapped_reg(struct radv_device *device, FILE *f, unsigned offset)
+{
+ struct radeon_winsys *ws = device->ws;
+ uint32_t value;
+
+ if (ws->read_registers(ws, offset, 1, &value))
+ ac_dump_reg(f, device->physical_device->rad_info.chip_class,
+ offset, value, ~0);
+}
+
+static void
+radv_dump_debug_registers(struct radv_device *device, FILE *f)
+{
+ struct radeon_info *info = &device->physical_device->rad_info;
+
+ if (info->drm_major == 2 && info->drm_minor < 42)
+ return; /* no radeon support */
+
+ fprintf(f, "Memory-mapped registers:\n");
+ radv_dump_mmapped_reg(device, f, R_008010_GRBM_STATUS);
+
+ /* No other registers can be read on DRM < 3.1.0. */
+ if (info->drm_major < 3 || info->drm_minor < 1) {
+ fprintf(f, "\n");
+ return;
+ }
+
+ radv_dump_mmapped_reg(device, f, R_008008_GRBM_STATUS2);
+ radv_dump_mmapped_reg(device, f, R_008014_GRBM_STATUS_SE0);
+ radv_dump_mmapped_reg(device, f, R_008018_GRBM_STATUS_SE1);
+ radv_dump_mmapped_reg(device, f, R_008038_GRBM_STATUS_SE2);
+ radv_dump_mmapped_reg(device, f, R_00803C_GRBM_STATUS_SE3);
+ radv_dump_mmapped_reg(device, f, R_00D034_SDMA0_STATUS_REG);
+ radv_dump_mmapped_reg(device, f, R_00D834_SDMA1_STATUS_REG);
+ if (info->chip_class <= VI) {
+ radv_dump_mmapped_reg(device, f, R_000E50_SRBM_STATUS);
+ radv_dump_mmapped_reg(device, f, R_000E4C_SRBM_STATUS2);
+ radv_dump_mmapped_reg(device, f, R_000E54_SRBM_STATUS3);
+ }
+ radv_dump_mmapped_reg(device, f, R_008680_CP_STAT);
+ radv_dump_mmapped_reg(device, f, R_008674_CP_STALLED_STAT1);
+ radv_dump_mmapped_reg(device, f, R_008678_CP_STALLED_STAT2);
+ radv_dump_mmapped_reg(device, f, R_008670_CP_STALLED_STAT3);
+ radv_dump_mmapped_reg(device, f, R_008210_CP_CPC_STATUS);
+ radv_dump_mmapped_reg(device, f, R_008214_CP_CPC_BUSY_STAT);
+ radv_dump_mmapped_reg(device, f, R_008218_CP_CPC_STALLED_STAT1);
+ radv_dump_mmapped_reg(device, f, R_00821C_CP_CPF_STATUS);
+ radv_dump_mmapped_reg(device, f, R_008220_CP_CPF_BUSY_STAT);
+ radv_dump_mmapped_reg(device, f, R_008224_CP_CPF_STALLED_STAT1);
+ fprintf(f, "\n");
+}
+
+static const char *
+radv_get_descriptor_name(enum VkDescriptorType type)
+{
+ switch (type) {
+ case VK_DESCRIPTOR_TYPE_SAMPLER:
+ return "SAMPLER";
+ case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
+ return "COMBINED_IMAGE_SAMPLER";
+ case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
+ return "SAMPLED_IMAGE";
+ case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
+ return "STORAGE_IMAGE";
+ case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
+ return "UNIFORM_TEXEL_BUFFER";
+ case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
+ return "STORAGE_TEXEL_BUFFER";
+ case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
+ return "UNIFORM_BUFFER";
+ case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
+ return "STORAGE_BUFFER";
+ case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
+ return "UNIFORM_BUFFER_DYNAMIC";
+ case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
+ return "STORAGE_BUFFER_DYNAMIC";
+ case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
+ return "INPUT_ATTACHMENT";
+ default:
+ return "UNKNOWN";
+ }
+}
+
+static void
+radv_dump_buffer_descriptor(enum chip_class chip_class, const uint32_t *desc,
+ FILE *f)
+{
+ fprintf(f, COLOR_CYAN " Buffer:" COLOR_RESET "\n");
+ for (unsigned j = 0; j < 4; j++)
+ ac_dump_reg(f, chip_class, R_008F00_SQ_BUF_RSRC_WORD0 + j * 4,
+ desc[j], 0xffffffff);
+}
+
+static void
+radv_dump_image_descriptor(enum chip_class chip_class, const uint32_t *desc,
+ FILE *f)
+{
+ fprintf(f, COLOR_CYAN " Image:" COLOR_RESET "\n");
+ for (unsigned j = 0; j < 8; j++)
+ ac_dump_reg(f, chip_class, R_008F10_SQ_IMG_RSRC_WORD0 + j * 4,
+ desc[j], 0xffffffff);
+
+ fprintf(f, COLOR_CYAN " FMASK:" COLOR_RESET "\n");
+ for (unsigned j = 0; j < 8; j++)
+ ac_dump_reg(f, chip_class, R_008F10_SQ_IMG_RSRC_WORD0 + j * 4,
+ desc[8 + j], 0xffffffff);
+}
+
+static void
+radv_dump_sampler_descriptor(enum chip_class chip_class, const uint32_t *desc,
+ FILE *f)
+{
+ fprintf(f, COLOR_CYAN " Sampler state:" COLOR_RESET "\n");
+ for (unsigned j = 0; j < 4; j++) {
+ ac_dump_reg(f, chip_class, R_008F30_SQ_IMG_SAMP_WORD0 + j * 4,
+ desc[j], 0xffffffff);
+ }
+}
+
+static void
+radv_dump_combined_image_sampler_descriptor(enum chip_class chip_class,
+ const uint32_t *desc, FILE *f)
+{
+ radv_dump_image_descriptor(chip_class, desc, f);
+ radv_dump_sampler_descriptor(chip_class, desc + 16, f);
+}
+
+static void
+radv_dump_descriptor_set(enum chip_class chip_class,
+ struct radv_descriptor_set *set, unsigned id, FILE *f)
+{
+ const struct radv_descriptor_set_layout *layout;
+ int i;
+
+ if (!set)
+ return;
+ layout = set->layout;
+
+ fprintf(f, "** descriptor set (%d) **\n", id);
+ fprintf(f, "va: 0x%"PRIx64"\n", set->va);
+ fprintf(f, "size: %d\n", set->size);
+ fprintf(f, "mapped_ptr:\n");
+
+ for (i = 0; i < set->size / 4; i++) {
+ fprintf(f, "\t[0x%x] = 0x%08x\n", i, set->mapped_ptr[i]);
+ }
+ fprintf(f, "\n");
+
+ fprintf(f, "\t*** layout ***\n");
+ fprintf(f, "\tbinding_count: %d\n", layout->binding_count);
+ fprintf(f, "\tsize: %d\n", layout->size);
+ fprintf(f, "\tshader_stages: %x\n", layout->shader_stages);
+ fprintf(f, "\tdynamic_shader_stages: %x\n",
+ layout->dynamic_shader_stages);
+ fprintf(f, "\tbuffer_count: %d\n", layout->buffer_count);
+ fprintf(f, "\tdynamic_offset_count: %d\n",
+ layout->dynamic_offset_count);
+ fprintf(f, "\n");
+
+ for (i = 0; i < set->layout->binding_count; i++) {
+ uint32_t *desc =
+ set->mapped_ptr + layout->binding[i].offset / 4;
+
+ fprintf(f, "\t\t**** binding layout (%d) ****\n", i);
+ fprintf(f, "\t\ttype: %s\n",
+ radv_get_descriptor_name(layout->binding[i].type));
+ fprintf(f, "\t\tarray_size: %d\n",
+ layout->binding[i].array_size);
+ fprintf(f, "\t\toffset: %d\n",
+ layout->binding[i].offset);
+ fprintf(f, "\t\tbuffer_offset: %d\n",
+ layout->binding[i].buffer_offset);
+ fprintf(f, "\t\tdynamic_offset_offset: %d\n",
+ layout->binding[i].dynamic_offset_offset);
+ fprintf(f, "\t\tdynamic_offset_count: %d\n",
+ layout->binding[i].dynamic_offset_count);
+ fprintf(f, "\t\tsize: %d\n",
+ layout->binding[i].size);
+ fprintf(f, "\t\timmutable_samplers_offset: %d\n",
+ layout->binding[i].immutable_samplers_offset);
+ fprintf(f, "\t\timmutable_samplers_equal: %d\n",
+ layout->binding[i].immutable_samplers_equal);
+ fprintf(f, "\n");
+
+ switch (layout->binding[i].type) {
+ case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
+ case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
+ case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
+ case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
+ radv_dump_buffer_descriptor(chip_class, desc, f);
+ break;
+ case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
+ case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
+ case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
+ radv_dump_image_descriptor(chip_class, desc, f);
+ break;
+ case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
+ radv_dump_combined_image_sampler_descriptor(chip_class, desc, f);
+ break;
+ case VK_DESCRIPTOR_TYPE_SAMPLER:
+ radv_dump_sampler_descriptor(chip_class, desc, f);
+ break;
+ case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
+ case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
+ /* todo */
+ break;
+ default:
+ assert(!"unknown descriptor type");
+ break;
+ }
+ fprintf(f, "\n");
+ }
+ fprintf(f, "\n\n");
+}
+
+static void
+radv_dump_descriptors(struct radv_pipeline *pipeline, FILE *f)
+{
+ struct radv_device *device = pipeline->device;
+ enum chip_class chip_class = device->physical_device->rad_info.chip_class;
+ uint64_t *ptr = (uint64_t *)device->trace_id_ptr;
+ int i;
+
+ fprintf(f, "List of descriptors:\n");
+ for (i = 0; i < MAX_SETS; i++) {
+ struct radv_descriptor_set *set =
+ (struct radv_descriptor_set *)ptr[i + 3];
+
+ radv_dump_descriptor_set(chip_class, set, i, f);
+ }
+}
+
+struct radv_shader_inst {
+ char text[160]; /* one disasm line */
+ unsigned offset; /* instruction offset */
+ unsigned size; /* instruction size = 4 or 8 */
+};
+
+/* Split a disassembly string into lines and add them to the array pointed
+ * to by "instructions". */
+static void si_add_split_disasm(const char *disasm,
+ uint64_t start_addr,
+ unsigned *num,
+ struct radv_shader_inst *instructions)
+{
+ struct radv_shader_inst *last_inst = *num ? &instructions[*num - 1] : NULL;
+ char *next;
+
+ while ((next = strchr(disasm, '\n'))) {
+ struct radv_shader_inst *inst = &instructions[*num];
+ unsigned len = next - disasm;
+
+ assert(len < ARRAY_SIZE(inst->text));
+ memcpy(inst->text, disasm, len);
+ inst->text[len] = 0;
+ inst->offset = last_inst ? last_inst->offset + last_inst->size : 0;
+
+ const char *semicolon = strchr(disasm, ';');
+ assert(semicolon);
+ /* More than 16 chars after ";" means the instruction is 8 bytes long. */
+ inst->size = next - semicolon > 16 ? 8 : 4;
+
+ snprintf(inst->text + len, ARRAY_SIZE(inst->text) - len,
+ " [PC=0x%"PRIx64", off=%u, size=%u]",
+ start_addr + inst->offset, inst->offset, inst->size);
+
+ last_inst = inst;
+ (*num)++;
+ disasm = next + 1;
+ }
+}
+
+static void
+radv_dump_annotated_shader(struct radv_pipeline *pipeline,
+ struct radv_shader_variant *shader,
+ gl_shader_stage stage,
+ struct ac_wave_info *waves, unsigned num_waves,
+ FILE *f)
+{
+ uint64_t start_addr, end_addr;
+ unsigned i;
+
+ if (!shader)
+ return;
+
+ start_addr = radv_buffer_get_va(shader->bo) + shader->bo_offset;
+ end_addr = start_addr + shader->code_size;
+
+ /* See if any wave executes the shader. */
+ for (i = 0; i < num_waves; i++) {
+ if (start_addr <= waves[i].pc && waves[i].pc <= end_addr)
+ break;
+ }
+
+ if (i == num_waves)
+ return; /* the shader is not being executed */
+
+ /* Remember the first found wave. The waves are sorted according to PC. */
+ waves = &waves[i];
+ num_waves -= i;
+
+ /* Get the list of instructions.
+ * Buffer size / 4 is the upper bound of the instruction count.
+ */
+ unsigned num_inst = 0;
+ struct radv_shader_inst *instructions =
+ calloc(shader->code_size / 4, sizeof(struct radv_shader_inst));
+
+ si_add_split_disasm(shader->disasm_string,
+ start_addr, &num_inst, instructions);
+
+ fprintf(f, COLOR_YELLOW "%s - annotated disassembly:" COLOR_RESET "\n",
+ radv_get_shader_name(shader, stage));
+
+ /* Print instructions with annotations. */
+ for (i = 0; i < num_inst; i++) {
+ struct radv_shader_inst *inst = &instructions[i];
+
+ fprintf(f, "%s\n", inst->text);
+
+ /* Print which waves execute the instruction right now. */
+ while (num_waves && start_addr + inst->offset == waves->pc) {
+ fprintf(f,
+ " " COLOR_GREEN "^ SE%u SH%u CU%u "
+ "SIMD%u WAVE%u EXEC=%016"PRIx64 " ",
+ waves->se, waves->sh, waves->cu, waves->simd,
+ waves->wave, waves->exec);
+
+ if (inst->size == 4) {
+ fprintf(f, "INST32=%08X" COLOR_RESET "\n",
+ waves->inst_dw0);
+ } else {
+ fprintf(f, "INST64=%08X %08X" COLOR_RESET "\n",
+ waves->inst_dw0, waves->inst_dw1);
+ }
+
+ waves->matched = true;
+ waves = &waves[1];
+ num_waves--;
+ }
+ }
+
+ fprintf(f, "\n\n");
+ free(instructions);
+}
+
+static void
+radv_dump_annotated_shaders(struct radv_pipeline *pipeline,
+ struct radv_shader_variant *compute_shader,
+ FILE *f)
+{
+ struct ac_wave_info waves[AC_MAX_WAVES_PER_CHIP];
+ unsigned num_waves = ac_get_wave_info(waves);
+ unsigned mask;
+
+ fprintf(f, COLOR_CYAN "The number of active waves = %u" COLOR_RESET
+ "\n\n", num_waves);
+
+ /* Dump annotated active graphics shaders. */
+ mask = pipeline->active_stages;
+ while (mask) {
+ int stage = u_bit_scan(&mask);
+
+ radv_dump_annotated_shader(pipeline, pipeline->shaders[stage],
+ stage, waves, num_waves, f);
+ }
+
+ radv_dump_annotated_shader(pipeline, compute_shader,
+ MESA_SHADER_COMPUTE, waves, num_waves, f);
+
+ /* Print waves executing shaders that are not currently bound. */
+ unsigned i;
+ bool found = false;
+ for (i = 0; i < num_waves; i++) {
+ if (waves[i].matched)
+ continue;
+
+ if (!found) {
+ fprintf(f, COLOR_CYAN
+ "Waves not executing currently-bound shaders:"
+ COLOR_RESET "\n");
+ found = true;
+ }
+ fprintf(f, " SE%u SH%u CU%u SIMD%u WAVE%u EXEC=%016"PRIx64
+ " INST=%08X %08X PC=%"PRIx64"\n",
+ waves[i].se, waves[i].sh, waves[i].cu, waves[i].simd,
+ waves[i].wave, waves[i].exec, waves[i].inst_dw0,
+ waves[i].inst_dw1, waves[i].pc);
+ }
+ if (found)
+ fprintf(f, "\n\n");
+}
+
+static void
+radv_dump_shader(struct radv_pipeline *pipeline,
+ struct radv_shader_variant *shader, gl_shader_stage stage,
+ FILE *f)
+{
+ if (!shader)
+ return;
+
+ fprintf(f, "%s:\n\n", radv_get_shader_name(shader, stage));
+
+ if (shader->spirv) {
+ fprintf(f, "SPIRV:\n");
+ radv_print_spirv(shader->spirv, shader->spirv_size, f);
+ }
+
+ if (shader->nir) {
+ fprintf(f, "NIR:\n");
+ nir_print_shader(shader->nir, f);
+ }
+
+ fprintf(stderr, "DISASM:\n%s\n", shader->disasm_string);
+
+ radv_shader_dump_stats(pipeline->device, shader, stage, f);
+}
+
+static void
+radv_dump_shaders(struct radv_pipeline *pipeline,
+ struct radv_shader_variant *compute_shader, FILE *f)
+{
+ unsigned mask;
+
+ /* Dump active graphics shaders. */
+ mask = pipeline->active_stages;
+ while (mask) {
+ int stage = u_bit_scan(&mask);
+
+ radv_dump_shader(pipeline, pipeline->shaders[stage], stage, f);
+ }
+
+ radv_dump_shader(pipeline, compute_shader, MESA_SHADER_COMPUTE, f);
+}
+
+static void
+radv_dump_graphics_state(struct radv_pipeline *graphics_pipeline,
+ struct radv_pipeline *compute_pipeline, FILE *f)
+{
+ struct radv_shader_variant *compute_shader =
+ compute_pipeline ? compute_pipeline->shaders[MESA_SHADER_COMPUTE] : NULL;
+
+ if (!graphics_pipeline)
+ return;
+
+ radv_dump_shaders(graphics_pipeline, compute_shader, f);
+ radv_dump_annotated_shaders(graphics_pipeline, compute_shader, f);
+ radv_dump_descriptors(graphics_pipeline, f);
+}
+
+static void
+radv_dump_compute_state(struct radv_pipeline *compute_pipeline, FILE *f)
+{
+ if (!compute_pipeline)
+ return;
+
+ radv_dump_shaders(compute_pipeline,
+ compute_pipeline->shaders[MESA_SHADER_COMPUTE], f);
+ radv_dump_annotated_shaders(compute_pipeline,
+ compute_pipeline->shaders[MESA_SHADER_COMPUTE],
+ f);
+ radv_dump_descriptors(compute_pipeline, f);
+}
+
+static struct radv_pipeline *
+radv_get_saved_graphics_pipeline(struct radv_device *device)
+{
+ uint64_t *ptr = (uint64_t *)device->trace_id_ptr;
+
+ return (struct radv_pipeline *)ptr[1];
+}
+
+static struct radv_pipeline *
+radv_get_saved_compute_pipeline(struct radv_device *device)
+{
+ uint64_t *ptr = (uint64_t *)device->trace_id_ptr;
+
+ return (struct radv_pipeline *)ptr[2];
+}
+
+static void
+radv_dump_dmesg(FILE *f)
+{
+ char line[2000];
+ FILE *p;
+
+ p = popen("dmesg | tail -n60", "r");
+ if (!p)
+ return;
+
+ fprintf(f, "\nLast 60 lines of dmesg:\n\n");
+ while (fgets(line, sizeof(line), p))
+ fputs(line, f);
+ fprintf(f, "\n");
+
+ pclose(p);
+}
+
+static void
+radv_dump_enabled_options(struct radv_device *device, FILE *f)
+{
+ uint64_t mask;
+
+ fprintf(f, "Enabled debug options: ");
+
+ mask = device->instance->debug_flags;
+ while (mask) {
+ int i = u_bit_scan64(&mask);
+ fprintf(f, "%s, ", radv_get_debug_option_name(i));
+ }
+ fprintf(f, "\n");
+
+ fprintf(f, "Enabled perftest options: ");
+
+ mask = device->instance->perftest_flags;
+ while (mask) {
+ int i = u_bit_scan64(&mask);
+ fprintf(f, "%s, ", radv_get_perftest_option_name(i));
+ }
+ fprintf(f, "\n");
+}
+
+static void
+radv_dump_device_name(struct radv_device *device, FILE *f)
+{
+ struct radeon_info *info = &device->physical_device->rad_info;
+ char llvm_string[32] = {}, kernel_version[128] = {};
+ struct utsname uname_data;
+ const char *chip_name;
+
+ chip_name = device->ws->get_chip_name(device->ws);
+
+ if (uname(&uname_data) == 0)
+ snprintf(kernel_version, sizeof(kernel_version),
+ " / %s", uname_data.release);
+
+ if (HAVE_LLVM > 0) {
+ snprintf(llvm_string, sizeof(llvm_string),
+ ", LLVM %i.%i.%i", (HAVE_LLVM >> 8) & 0xff,
+ HAVE_LLVM & 0xff, MESA_LLVM_VERSION_PATCH);
+ }
+
+ fprintf(f, "Device name: %s (%s DRM %i.%i.%i%s%s)\n\n",
+ chip_name, device->physical_device->name,
+ info->drm_major, info->drm_minor, info->drm_patchlevel,
+ kernel_version, llvm_string);
+}
+
+static bool
+radv_gpu_hang_occured(struct radv_queue *queue, enum ring_type ring)
+{
+ struct radeon_winsys *ws = queue->device->ws;
+
+ if (!ws->ctx_wait_idle(queue->hw_ctx, ring, queue->queue_idx))
+ return true;
+
+ return false;
+}
+
+void
+radv_check_gpu_hangs(struct radv_queue *queue, struct radeon_winsys_cs *cs)
+{
+ struct radv_pipeline *graphics_pipeline, *compute_pipeline;
+ struct radv_device *device = queue->device;
+ enum ring_type ring;
+ uint64_t addr;
+
+ ring = radv_queue_family_to_ring(queue->queue_family_index);
+
+ bool hang_occurred = radv_gpu_hang_occured(queue, ring);
+ bool vm_fault_occurred = false;
+ if (queue->device->instance->debug_flags & RADV_DEBUG_VM_FAULTS)
+ vm_fault_occurred = ac_vm_fault_occured(device->physical_device->rad_info.chip_class,
+ &device->dmesg_timestamp, &addr);
+ if (!hang_occurred && !vm_fault_occurred)
+ return;
+
+ graphics_pipeline = radv_get_saved_graphics_pipeline(device);
+ compute_pipeline = radv_get_saved_compute_pipeline(device);
+
+ fprintf(stderr, "GPU hang report:\n\n");
+ radv_dump_device_name(device, stderr);
+
+ radv_dump_enabled_options(device, stderr);
+ radv_dump_dmesg(stderr);
+
+ if (vm_fault_occurred) {
+ fprintf(stderr, "VM fault report.\n\n");
+ fprintf(stderr, "Failing VM page: 0x%08"PRIx64"\n\n", addr);
+ }
+
+ radv_dump_debug_registers(device, stderr);
+
+ switch (ring) {
+ case RING_GFX:
+ radv_dump_graphics_state(graphics_pipeline, compute_pipeline,
+ stderr);
+ break;
+ case RING_COMPUTE:
+ radv_dump_compute_state(compute_pipeline, stderr);
+ break;
+ default:
+ assert(0);
+ break;
+ }
+
+ radv_dump_trace(queue->device, cs);
+ abort();
+}
+
+void
+radv_print_spirv(uint32_t *data, uint32_t size, FILE *fp)
+{
+ char path[] = "/tmp/fileXXXXXX";
+ char line[2048], command[128];
+ FILE *p;
+ int fd;
+
+ /* Dump the binary into a temporary file. */
+ fd = mkstemp(path);
+ if (fd < 0)
+ return;
+
+ if (write(fd, data, size) == -1)
+ goto fail;
+
+ sprintf(command, "spirv-dis %s", path);
+
+ /* Disassemble using spirv-dis if installed. */
+ p = popen(command, "r");
+ if (p) {
+ while (fgets(line, sizeof(line), p))
+ fprintf(fp, "%s", line);
+ pclose(p);
+ }
+
+fail:
+ close(fd);
+ unlink(path);
+}
diff --git a/lib/mesa/src/amd/vulkan/radv_extensions.c b/lib/mesa/src/amd/vulkan/radv_extensions.c
new file mode 100644
index 000000000..f9268dfbe
--- /dev/null
+++ b/lib/mesa/src/amd/vulkan/radv_extensions.c
@@ -0,0 +1,407 @@
+/*
+ * Copyright 2017 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, sub license, 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 NON-INFRINGEMENT.
+ * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS 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 "radv_private.h"
+
+#include "vk_util.h"
+
+/* Convert the VK_USE_PLATFORM_* defines to booleans */
+#ifdef VK_USE_PLATFORM_ANDROID_KHR
+# undef VK_USE_PLATFORM_ANDROID_KHR
+# define VK_USE_PLATFORM_ANDROID_KHR true
+#else
+# define VK_USE_PLATFORM_ANDROID_KHR false
+#endif
+#ifdef VK_USE_PLATFORM_WAYLAND_KHR
+# undef VK_USE_PLATFORM_WAYLAND_KHR
+# define VK_USE_PLATFORM_WAYLAND_KHR true
+#else
+# define VK_USE_PLATFORM_WAYLAND_KHR false
+#endif
+#ifdef VK_USE_PLATFORM_XCB_KHR
+# undef VK_USE_PLATFORM_XCB_KHR
+# define VK_USE_PLATFORM_XCB_KHR true
+#else
+# define VK_USE_PLATFORM_XCB_KHR false
+#endif
+#ifdef VK_USE_PLATFORM_XLIB_KHR
+# undef VK_USE_PLATFORM_XLIB_KHR
+# define VK_USE_PLATFORM_XLIB_KHR true
+#else
+# define VK_USE_PLATFORM_XLIB_KHR false
+#endif
+
+/* And ANDROID too */
+#ifdef ANDROID
+# undef ANDROID
+# define ANDROID true
+#else
+# define ANDROID false
+#endif
+
+#define RADV_HAS_SURFACE (VK_USE_PLATFORM_WAYLAND_KHR || VK_USE_PLATFORM_XCB_KHR || VK_USE_PLATFORM_XLIB_KHR)
+
+bool
+radv_instance_extension_supported(const char *name)
+{
+ if (strcmp(name, "VK_KHR_external_memory_capabilities") == 0)
+ return true;
+ if (strcmp(name, "VK_KHR_external_semaphore_capabilities") == 0)
+ return true;
+ if (strcmp(name, "VK_KHR_get_physical_device_properties2") == 0)
+ return true;
+ if (strcmp(name, "VK_KHR_surface") == 0)
+ return RADV_HAS_SURFACE;
+ if (strcmp(name, "VK_KHR_wayland_surface") == 0)
+ return VK_USE_PLATFORM_WAYLAND_KHR;
+ if (strcmp(name, "VK_KHR_xcb_surface") == 0)
+ return VK_USE_PLATFORM_XCB_KHR;
+ if (strcmp(name, "VK_KHR_xlib_surface") == 0)
+ return VK_USE_PLATFORM_XLIB_KHR;
+ return false;
+}
+
+VkResult radv_EnumerateInstanceExtensionProperties(
+ const char* pLayerName,
+ uint32_t* pPropertyCount,
+ VkExtensionProperties* pProperties)
+{
+ VK_OUTARRAY_MAKE(out, pProperties, pPropertyCount);
+
+ if (true) {
+ vk_outarray_append(&out, prop) {
+ *prop = (VkExtensionProperties) {
+ .extensionName = "VK_KHR_external_memory_capabilities",
+ .specVersion = 1,
+ };
+ }
+ }
+ if (true) {
+ vk_outarray_append(&out, prop) {
+ *prop = (VkExtensionProperties) {
+ .extensionName = "VK_KHR_external_semaphore_capabilities",
+ .specVersion = 1,
+ };
+ }
+ }
+ if (true) {
+ vk_outarray_append(&out, prop) {
+ *prop = (VkExtensionProperties) {
+ .extensionName = "VK_KHR_get_physical_device_properties2",
+ .specVersion = 1,
+ };
+ }
+ }
+ if (RADV_HAS_SURFACE) {
+ vk_outarray_append(&out, prop) {
+ *prop = (VkExtensionProperties) {
+ .extensionName = "VK_KHR_surface",
+ .specVersion = 25,
+ };
+ }
+ }
+ if (VK_USE_PLATFORM_WAYLAND_KHR) {
+ vk_outarray_append(&out, prop) {
+ *prop = (VkExtensionProperties) {
+ .extensionName = "VK_KHR_wayland_surface",
+ .specVersion = 6,
+ };
+ }
+ }
+ if (VK_USE_PLATFORM_XCB_KHR) {
+ vk_outarray_append(&out, prop) {
+ *prop = (VkExtensionProperties) {
+ .extensionName = "VK_KHR_xcb_surface",
+ .specVersion = 6,
+ };
+ }
+ }
+ if (VK_USE_PLATFORM_XLIB_KHR) {
+ vk_outarray_append(&out, prop) {
+ *prop = (VkExtensionProperties) {
+ .extensionName = "VK_KHR_xlib_surface",
+ .specVersion = 6,
+ };
+ }
+ }
+
+ return vk_outarray_status(&out);
+}
+
+uint32_t
+radv_physical_device_api_version(struct radv_physical_device *dev)
+{
+ return VK_MAKE_VERSION(1, 0, 57);
+}
+
+bool
+radv_physical_device_extension_supported(struct radv_physical_device *device,
+ const char *name)
+{
+ if (strcmp(name, "VK_KHR_bind_memory2") == 0)
+ return true;
+ if (strcmp(name, "VK_KHR_dedicated_allocation") == 0)
+ return true;
+ if (strcmp(name, "VK_KHR_descriptor_update_template") == 0)
+ return true;
+ if (strcmp(name, "VK_KHR_external_memory") == 0)
+ return true;
+ if (strcmp(name, "VK_KHR_external_memory_fd") == 0)
+ return true;
+ if (strcmp(name, "VK_KHR_external_semaphore") == 0)
+ return device->rad_info.has_syncobj;
+ if (strcmp(name, "VK_KHR_external_semaphore_fd") == 0)
+ return device->rad_info.has_syncobj;
+ if (strcmp(name, "VK_KHR_get_memory_requirements2") == 0)
+ return true;
+ if (strcmp(name, "VK_KHR_image_format_list") == 0)
+ return true;
+ if (strcmp(name, "VK_KHR_incremental_present") == 0)
+ return true;
+ if (strcmp(name, "VK_KHR_maintenance1") == 0)
+ return true;
+ if (strcmp(name, "VK_KHR_maintenance2") == 0)
+ return true;
+ if (strcmp(name, "VK_KHR_push_descriptor") == 0)
+ return true;
+ if (strcmp(name, "VK_KHR_relaxed_block_layout") == 0)
+ return true;
+ if (strcmp(name, "VK_KHR_sampler_mirror_clamp_to_edge") == 0)
+ return true;
+ if (strcmp(name, "VK_KHR_shader_draw_parameters") == 0)
+ return true;
+ if (strcmp(name, "VK_KHR_storage_buffer_storage_class") == 0)
+ return true;
+ if (strcmp(name, "VK_KHR_swapchain") == 0)
+ return RADV_HAS_SURFACE;
+ if (strcmp(name, "VK_KHR_variable_pointers") == 0)
+ return true;
+ if (strcmp(name, "VK_KHX_multiview") == 0)
+ return false;
+ if (strcmp(name, "VK_EXT_global_priority") == 0)
+ return device->rad_info.has_ctx_priority;
+ if (strcmp(name, "VK_AMD_draw_indirect_count") == 0)
+ return true;
+ if (strcmp(name, "VK_AMD_rasterization_order") == 0)
+ return device->rad_info.chip_class >= VI && device->rad_info.max_se >= 2;
+ return false;
+}
+
+VkResult radv_EnumerateDeviceExtensionProperties(
+ VkPhysicalDevice physicalDevice,
+ const char* pLayerName,
+ uint32_t* pPropertyCount,
+ VkExtensionProperties* pProperties)
+{
+ RADV_FROM_HANDLE(radv_physical_device, device, physicalDevice);
+ VK_OUTARRAY_MAKE(out, pProperties, pPropertyCount);
+ (void)device;
+
+ if (true) {
+ vk_outarray_append(&out, prop) {
+ *prop = (VkExtensionProperties) {
+ .extensionName = "VK_KHR_bind_memory2",
+ .specVersion = 1,
+ };
+ }
+ }
+ if (true) {
+ vk_outarray_append(&out, prop) {
+ *prop = (VkExtensionProperties) {
+ .extensionName = "VK_KHR_dedicated_allocation",
+ .specVersion = 1,
+ };
+ }
+ }
+ if (true) {
+ vk_outarray_append(&out, prop) {
+ *prop = (VkExtensionProperties) {
+ .extensionName = "VK_KHR_descriptor_update_template",
+ .specVersion = 1,
+ };
+ }
+ }
+ if (true) {
+ vk_outarray_append(&out, prop) {
+ *prop = (VkExtensionProperties) {
+ .extensionName = "VK_KHR_external_memory",
+ .specVersion = 1,
+ };
+ }
+ }
+ if (true) {
+ vk_outarray_append(&out, prop) {
+ *prop = (VkExtensionProperties) {
+ .extensionName = "VK_KHR_external_memory_fd",
+ .specVersion = 1,
+ };
+ }
+ }
+ if (device->rad_info.has_syncobj) {
+ vk_outarray_append(&out, prop) {
+ *prop = (VkExtensionProperties) {
+ .extensionName = "VK_KHR_external_semaphore",
+ .specVersion = 1,
+ };
+ }
+ }
+ if (device->rad_info.has_syncobj) {
+ vk_outarray_append(&out, prop) {
+ *prop = (VkExtensionProperties) {
+ .extensionName = "VK_KHR_external_semaphore_fd",
+ .specVersion = 1,
+ };
+ }
+ }
+ if (true) {
+ vk_outarray_append(&out, prop) {
+ *prop = (VkExtensionProperties) {
+ .extensionName = "VK_KHR_get_memory_requirements2",
+ .specVersion = 1,
+ };
+ }
+ }
+ if (true) {
+ vk_outarray_append(&out, prop) {
+ *prop = (VkExtensionProperties) {
+ .extensionName = "VK_KHR_image_format_list",
+ .specVersion = 1,
+ };
+ }
+ }
+ if (true) {
+ vk_outarray_append(&out, prop) {
+ *prop = (VkExtensionProperties) {
+ .extensionName = "VK_KHR_incremental_present",
+ .specVersion = 1,
+ };
+ }
+ }
+ if (true) {
+ vk_outarray_append(&out, prop) {
+ *prop = (VkExtensionProperties) {
+ .extensionName = "VK_KHR_maintenance1",
+ .specVersion = 1,
+ };
+ }
+ }
+ if (true) {
+ vk_outarray_append(&out, prop) {
+ *prop = (VkExtensionProperties) {
+ .extensionName = "VK_KHR_maintenance2",
+ .specVersion = 1,
+ };
+ }
+ }
+ if (true) {
+ vk_outarray_append(&out, prop) {
+ *prop = (VkExtensionProperties) {
+ .extensionName = "VK_KHR_push_descriptor",
+ .specVersion = 1,
+ };
+ }
+ }
+ if (true) {
+ vk_outarray_append(&out, prop) {
+ *prop = (VkExtensionProperties) {
+ .extensionName = "VK_KHR_relaxed_block_layout",
+ .specVersion = 1,
+ };
+ }
+ }
+ if (true) {
+ vk_outarray_append(&out, prop) {
+ *prop = (VkExtensionProperties) {
+ .extensionName = "VK_KHR_sampler_mirror_clamp_to_edge",
+ .specVersion = 1,
+ };
+ }
+ }
+ if (true) {
+ vk_outarray_append(&out, prop) {
+ *prop = (VkExtensionProperties) {
+ .extensionName = "VK_KHR_shader_draw_parameters",
+ .specVersion = 1,
+ };
+ }
+ }
+ if (true) {
+ vk_outarray_append(&out, prop) {
+ *prop = (VkExtensionProperties) {
+ .extensionName = "VK_KHR_storage_buffer_storage_class",
+ .specVersion = 1,
+ };
+ }
+ }
+ if (RADV_HAS_SURFACE) {
+ vk_outarray_append(&out, prop) {
+ *prop = (VkExtensionProperties) {
+ .extensionName = "VK_KHR_swapchain",
+ .specVersion = 68,
+ };
+ }
+ }
+ if (true) {
+ vk_outarray_append(&out, prop) {
+ *prop = (VkExtensionProperties) {
+ .extensionName = "VK_KHR_variable_pointers",
+ .specVersion = 1,
+ };
+ }
+ }
+ if (false) {
+ vk_outarray_append(&out, prop) {
+ *prop = (VkExtensionProperties) {
+ .extensionName = "VK_KHX_multiview",
+ .specVersion = 1,
+ };
+ }
+ }
+ if (device->rad_info.has_ctx_priority) {
+ vk_outarray_append(&out, prop) {
+ *prop = (VkExtensionProperties) {
+ .extensionName = "VK_EXT_global_priority",
+ .specVersion = 1,
+ };
+ }
+ }
+ if (true) {
+ vk_outarray_append(&out, prop) {
+ *prop = (VkExtensionProperties) {
+ .extensionName = "VK_AMD_draw_indirect_count",
+ .specVersion = 1,
+ };
+ }
+ }
+ if (device->rad_info.chip_class >= VI && device->rad_info.max_se >= 2) {
+ vk_outarray_append(&out, prop) {
+ *prop = (VkExtensionProperties) {
+ .extensionName = "VK_AMD_rasterization_order",
+ .specVersion = 1,
+ };
+ }
+ }
+
+ return vk_outarray_status(&out);
+}
diff --git a/lib/mesa/src/amd/vulkan/radv_extensions.py b/lib/mesa/src/amd/vulkan/radv_extensions.py
new file mode 100644
index 000000000..43c0fa740
--- /dev/null
+++ b/lib/mesa/src/amd/vulkan/radv_extensions.py
@@ -0,0 +1,278 @@
+COPYRIGHT = """\
+/*
+ * Copyright 2017 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, sub license, 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 NON-INFRINGEMENT.
+ * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS 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.
+ */
+"""
+
+import argparse
+import copy
+import re
+import xml.etree.cElementTree as et
+
+from mako.template import Template
+
+MAX_API_VERSION = '1.0.57'
+
+class Extension:
+ def __init__(self, name, ext_version, enable):
+ self.name = name
+ self.ext_version = int(ext_version)
+ if enable is True:
+ self.enable = 'true';
+ elif enable is False:
+ self.enable = 'false';
+ else:
+ self.enable = enable;
+
+# On Android, we disable all surface and swapchain extensions. Android's Vulkan
+# loader implements VK_KHR_surface and VK_KHR_swapchain, and applications
+# cannot access the driver's implementation. Moreoever, if the driver exposes
+# the those extension strings, then tests dEQP-VK.api.info.instance.extensions
+# and dEQP-VK.api.info.device fail due to the duplicated strings.
+EXTENSIONS = [
+ Extension('VK_KHR_bind_memory2', 1, True),
+ Extension('VK_KHR_dedicated_allocation', 1, True),
+ Extension('VK_KHR_descriptor_update_template', 1, True),
+ Extension('VK_KHR_external_memory', 1, True),
+ Extension('VK_KHR_external_memory_capabilities', 1, True),
+ Extension('VK_KHR_external_memory_fd', 1, True),
+ Extension('VK_KHR_external_semaphore', 1, 'device->rad_info.has_syncobj'),
+ Extension('VK_KHR_external_semaphore_capabilities', 1, True),
+ Extension('VK_KHR_external_semaphore_fd', 1, 'device->rad_info.has_syncobj'),
+ Extension('VK_KHR_get_memory_requirements2', 1, True),
+ Extension('VK_KHR_get_physical_device_properties2', 1, True),
+ Extension('VK_KHR_image_format_list', 1, True),
+ Extension('VK_KHR_incremental_present', 1, True),
+ Extension('VK_KHR_maintenance1', 1, True),
+ Extension('VK_KHR_maintenance2', 1, True),
+ Extension('VK_KHR_push_descriptor', 1, True),
+ Extension('VK_KHR_relaxed_block_layout', 1, True),
+ Extension('VK_KHR_sampler_mirror_clamp_to_edge', 1, True),
+ Extension('VK_KHR_shader_draw_parameters', 1, True),
+ Extension('VK_KHR_storage_buffer_storage_class', 1, True),
+ Extension('VK_KHR_surface', 25, 'RADV_HAS_SURFACE'),
+ Extension('VK_KHR_swapchain', 68, 'RADV_HAS_SURFACE'),
+ Extension('VK_KHR_variable_pointers', 1, True),
+ Extension('VK_KHR_wayland_surface', 6, 'VK_USE_PLATFORM_WAYLAND_KHR'),
+ Extension('VK_KHR_xcb_surface', 6, 'VK_USE_PLATFORM_XCB_KHR'),
+ Extension('VK_KHR_xlib_surface', 6, 'VK_USE_PLATFORM_XLIB_KHR'),
+ Extension('VK_KHX_multiview', 1, False),
+ Extension('VK_EXT_global_priority', 1, 'device->rad_info.has_ctx_priority'),
+ Extension('VK_AMD_draw_indirect_count', 1, True),
+ Extension('VK_AMD_rasterization_order', 1, 'device->rad_info.chip_class >= VI && device->rad_info.max_se >= 2'),
+]
+
+class VkVersion:
+ def __init__(self, string):
+ split = string.split('.')
+ self.major = int(split[0])
+ self.minor = int(split[1])
+ if len(split) > 2:
+ assert len(split) == 3
+ self.patch = int(split[2])
+ else:
+ self.patch = None
+
+ # Sanity check. The range bits are required by the definition of the
+ # VK_MAKE_VERSION macro
+ assert self.major < 1024 and self.minor < 1024
+ assert self.patch is None or self.patch < 4096
+ assert(str(self) == string)
+
+ def __str__(self):
+ ver_list = [str(self.major), str(self.minor)]
+ if self.patch is not None:
+ ver_list.append(str(self.patch))
+ return '.'.join(ver_list)
+
+ def c_vk_version(self):
+ ver_list = [str(self.major), str(self.minor), str(self.patch)]
+ return 'VK_MAKE_VERSION(' + ', '.join(ver_list) + ')'
+
+ def __int_ver(self):
+ # This is just an expansion of VK_VERSION
+ patch = self.patch if self.patch is not None else 0
+ return (self.major << 22) | (self.minor << 12) | patch
+
+ def __cmp__(self, other):
+ # If only one of them has a patch version, "ignore" it by making
+ # other's patch version match self.
+ if (self.patch is None) != (other.patch is None):
+ other = copy.copy(other)
+ other.patch = self.patch
+
+ return self.__int_ver().__cmp__(other.__int_ver())
+
+MAX_API_VERSION = VkVersion(MAX_API_VERSION)
+
+def _init_exts_from_xml(xml):
+ """ Walk the Vulkan XML and fill out extra extension information. """
+
+ xml = et.parse(xml)
+
+ ext_name_map = {}
+ for ext in EXTENSIONS:
+ ext_name_map[ext.name] = ext
+
+ for ext_elem in xml.findall('.extensions/extension'):
+ ext_name = ext_elem.attrib['name']
+ if ext_name not in ext_name_map:
+ continue
+
+ # Workaround for VK_ANDROID_native_buffer. Its <extension> element in
+ # vk.xml lists it as supported="disabled" and provides only a stub
+ # definition. Its <extension> element in Mesa's custom
+ # vk_android_native_buffer.xml, though, lists it as
+ # supported='android-vendor' and fully defines the extension. We want
+ # to skip the <extension> element in vk.xml.
+ if ext_elem.attrib['supported'] == 'disabled':
+ assert ext_name == 'VK_ANDROID_native_buffer'
+ continue
+
+ ext = ext_name_map[ext_name]
+ ext.type = ext_elem.attrib['type']
+
+_TEMPLATE = Template(COPYRIGHT + """
+#include "radv_private.h"
+
+#include "vk_util.h"
+
+/* Convert the VK_USE_PLATFORM_* defines to booleans */
+%for platform in ['ANDROID', 'WAYLAND', 'XCB', 'XLIB']:
+#ifdef VK_USE_PLATFORM_${platform}_KHR
+# undef VK_USE_PLATFORM_${platform}_KHR
+# define VK_USE_PLATFORM_${platform}_KHR true
+#else
+# define VK_USE_PLATFORM_${platform}_KHR false
+#endif
+%endfor
+
+/* And ANDROID too */
+#ifdef ANDROID
+# undef ANDROID
+# define ANDROID true
+#else
+# define ANDROID false
+#endif
+
+#define RADV_HAS_SURFACE (VK_USE_PLATFORM_WAYLAND_KHR || \\
+ VK_USE_PLATFORM_XCB_KHR || \\
+ VK_USE_PLATFORM_XLIB_KHR)
+
+bool
+radv_instance_extension_supported(const char *name)
+{
+%for ext in instance_extensions:
+ if (strcmp(name, "${ext.name}") == 0)
+ return ${ext.enable};
+%endfor
+ return false;
+}
+
+VkResult radv_EnumerateInstanceExtensionProperties(
+ const char* pLayerName,
+ uint32_t* pPropertyCount,
+ VkExtensionProperties* pProperties)
+{
+ VK_OUTARRAY_MAKE(out, pProperties, pPropertyCount);
+
+%for ext in instance_extensions:
+ if (${ext.enable}) {
+ vk_outarray_append(&out, prop) {
+ *prop = (VkExtensionProperties) {
+ .extensionName = "${ext.name}",
+ .specVersion = ${ext.ext_version},
+ };
+ }
+ }
+%endfor
+
+ return vk_outarray_status(&out);
+}
+
+uint32_t
+radv_physical_device_api_version(struct radv_physical_device *dev)
+{
+ return ${MAX_API_VERSION.c_vk_version()};
+}
+
+bool
+radv_physical_device_extension_supported(struct radv_physical_device *device,
+ const char *name)
+{
+%for ext in device_extensions:
+ if (strcmp(name, "${ext.name}") == 0)
+ return ${ext.enable};
+%endfor
+ return false;
+}
+
+VkResult radv_EnumerateDeviceExtensionProperties(
+ VkPhysicalDevice physicalDevice,
+ const char* pLayerName,
+ uint32_t* pPropertyCount,
+ VkExtensionProperties* pProperties)
+{
+ RADV_FROM_HANDLE(radv_physical_device, device, physicalDevice);
+ VK_OUTARRAY_MAKE(out, pProperties, pPropertyCount);
+ (void)device;
+
+%for ext in device_extensions:
+ if (${ext.enable}) {
+ vk_outarray_append(&out, prop) {
+ *prop = (VkExtensionProperties) {
+ .extensionName = "${ext.name}",
+ .specVersion = ${ext.ext_version},
+ };
+ }
+ }
+%endfor
+
+ return vk_outarray_status(&out);
+}
+""")
+
+if __name__ == '__main__':
+ parser = argparse.ArgumentParser()
+ parser.add_argument('--out', help='Output C file.', required=True)
+ parser.add_argument('--xml',
+ help='Vulkan API XML file.',
+ required=True,
+ action='append',
+ dest='xml_files')
+ args = parser.parse_args()
+
+ for filename in args.xml_files:
+ _init_exts_from_xml(filename)
+
+ for ext in EXTENSIONS:
+ assert ext.type == 'instance' or ext.type == 'device'
+
+ template_env = {
+ 'MAX_API_VERSION': MAX_API_VERSION,
+ 'instance_extensions': [e for e in EXTENSIONS if e.type == 'instance'],
+ 'device_extensions': [e for e in EXTENSIONS if e.type == 'device'],
+ }
+
+ with open(args.out, 'w') as f:
+ f.write(_TEMPLATE.render(**template_env))
diff --git a/lib/mesa/src/amd/vulkan/radv_pass.c b/lib/mesa/src/amd/vulkan/radv_pass.c
index 17eff3937..a52dae39d 100644
--- a/lib/mesa/src/amd/vulkan/radv_pass.c
+++ b/lib/mesa/src/amd/vulkan/radv_pass.c
@@ -26,6 +26,8 @@
*/
#include "radv_private.h"
+#include "vk_util.h"
+
VkResult radv_CreateRenderPass(
VkDevice _device,
const VkRenderPassCreateInfo* pCreateInfo,
@@ -36,6 +38,7 @@ VkResult radv_CreateRenderPass(
struct radv_render_pass *pass;
size_t size;
size_t attachments_offset;
+ VkRenderPassMultiviewCreateInfoKHX *multiview_info = NULL;
assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO);
@@ -54,6 +57,16 @@ VkResult radv_CreateRenderPass(
pass->subpass_count = pCreateInfo->subpassCount;
pass->attachments = (void *) pass + attachments_offset;
+ vk_foreach_struct(ext, pCreateInfo->pNext) {
+ switch(ext->sType) {
+ case VK_STRUCTURE_TYPE_RENDER_PASS_MULTIVIEW_CREATE_INFO_KHX:
+ multiview_info = ( VkRenderPassMultiviewCreateInfoKHX*)ext;
+ break;
+ default:
+ break;
+ }
+ }
+
for (uint32_t i = 0; i < pCreateInfo->attachmentCount; i++) {
struct radv_render_pass_attachment *att = &pass->attachments[i];
@@ -97,6 +110,8 @@ VkResult radv_CreateRenderPass(
subpass->input_count = desc->inputAttachmentCount;
subpass->color_count = desc->colorAttachmentCount;
+ if (multiview_info)
+ subpass->view_mask = multiview_info->pViewMasks[i];
if (desc->inputAttachmentCount > 0) {
subpass->input_attachments = p;
@@ -105,6 +120,8 @@ VkResult radv_CreateRenderPass(
for (uint32_t j = 0; j < desc->inputAttachmentCount; j++) {
subpass->input_attachments[j]
= desc->pInputAttachments[j];
+ if (desc->pInputAttachments[j].attachment != VK_ATTACHMENT_UNUSED)
+ pass->attachments[desc->pInputAttachments[j].attachment].view_mask |= subpass->view_mask;
}
}
@@ -115,6 +132,8 @@ VkResult radv_CreateRenderPass(
for (uint32_t j = 0; j < desc->colorAttachmentCount; j++) {
subpass->color_attachments[j]
= desc->pColorAttachments[j];
+ if (desc->pColorAttachments[j].attachment != VK_ATTACHMENT_UNUSED)
+ pass->attachments[desc->pColorAttachments[j].attachment].view_mask |= subpass->view_mask;
}
}
@@ -127,14 +146,18 @@ VkResult radv_CreateRenderPass(
uint32_t a = desc->pResolveAttachments[j].attachment;
subpass->resolve_attachments[j]
= desc->pResolveAttachments[j];
- if (a != VK_ATTACHMENT_UNUSED)
+ if (a != VK_ATTACHMENT_UNUSED) {
subpass->has_resolve = true;
+ pass->attachments[desc->pResolveAttachments[j].attachment].view_mask |= subpass->view_mask;
+ }
}
}
if (desc->pDepthStencilAttachment) {
subpass->depth_stencil_attachment =
*desc->pDepthStencilAttachment;
+ if (desc->pDepthStencilAttachment->attachment != VK_ATTACHMENT_UNUSED)
+ pass->attachments[desc->pDepthStencilAttachment->attachment].view_mask |= subpass->view_mask;
} else {
subpass->depth_stencil_attachment.attachment = VK_ATTACHMENT_UNUSED;
}
diff --git a/lib/mesa/src/amd/vulkan/radv_shader.c b/lib/mesa/src/amd/vulkan/radv_shader.c
new file mode 100644
index 000000000..83e2e675e
--- /dev/null
+++ b/lib/mesa/src/amd/vulkan/radv_shader.c
@@ -0,0 +1,671 @@
+/*
+ * Copyright © 2016 Red Hat.
+ * Copyright © 2016 Bas Nieuwenhuizen
+ *
+ * based in part on anv driver which is:
+ * Copyright © 2015 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 (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 "util/mesa-sha1.h"
+#include "util/u_atomic.h"
+#include "radv_debug.h"
+#include "radv_private.h"
+#include "radv_shader.h"
+#include "nir/nir.h"
+#include "nir/nir_builder.h"
+#include "spirv/nir_spirv.h"
+
+#include <llvm-c/Core.h>
+#include <llvm-c/TargetMachine.h>
+
+#include "sid.h"
+#include "gfx9d.h"
+#include "ac_binary.h"
+#include "ac_llvm_util.h"
+#include "ac_nir_to_llvm.h"
+#include "vk_format.h"
+#include "util/debug.h"
+#include "ac_exp_param.h"
+
+static const struct nir_shader_compiler_options nir_options = {
+ .vertex_id_zero_based = true,
+ .lower_scmp = true,
+ .lower_flrp32 = true,
+ .lower_fsat = true,
+ .lower_fdiv = true,
+ .lower_sub = true,
+ .lower_pack_snorm_2x16 = true,
+ .lower_pack_snorm_4x8 = true,
+ .lower_pack_unorm_2x16 = true,
+ .lower_pack_unorm_4x8 = true,
+ .lower_unpack_snorm_2x16 = true,
+ .lower_unpack_snorm_4x8 = true,
+ .lower_unpack_unorm_2x16 = true,
+ .lower_unpack_unorm_4x8 = true,
+ .lower_extract_byte = true,
+ .lower_extract_word = true,
+ .lower_ffma = true,
+ .max_unroll_iterations = 32
+};
+
+VkResult radv_CreateShaderModule(
+ VkDevice _device,
+ const VkShaderModuleCreateInfo* pCreateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkShaderModule* pShaderModule)
+{
+ RADV_FROM_HANDLE(radv_device, device, _device);
+ struct radv_shader_module *module;
+
+ assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO);
+ assert(pCreateInfo->flags == 0);
+
+ module = vk_alloc2(&device->alloc, pAllocator,
+ sizeof(*module) + pCreateInfo->codeSize, 8,
+ VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
+ if (module == NULL)
+ return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
+
+ module->nir = NULL;
+ module->size = pCreateInfo->codeSize;
+ memcpy(module->data, pCreateInfo->pCode, module->size);
+
+ _mesa_sha1_compute(module->data, module->size, module->sha1);
+
+ *pShaderModule = radv_shader_module_to_handle(module);
+
+ return VK_SUCCESS;
+}
+
+void radv_DestroyShaderModule(
+ VkDevice _device,
+ VkShaderModule _module,
+ const VkAllocationCallbacks* pAllocator)
+{
+ RADV_FROM_HANDLE(radv_device, device, _device);
+ RADV_FROM_HANDLE(radv_shader_module, module, _module);
+
+ if (!module)
+ return;
+
+ vk_free2(&device->alloc, pAllocator, module);
+}
+
+bool
+radv_lower_indirect_derefs(struct nir_shader *nir,
+ struct radv_physical_device *device)
+{
+ /* While it would be nice not to have this flag, we are constrained
+ * by the reality that LLVM 5.0 doesn't have working VGPR indexing
+ * on GFX9.
+ */
+ bool llvm_has_working_vgpr_indexing =
+ device->rad_info.chip_class <= VI;
+
+ /* TODO: Indirect indexing of GS inputs is unimplemented.
+ *
+ * TCS and TES load inputs directly from LDS or offchip memory, so
+ * indirect indexing is trivial.
+ */
+ nir_variable_mode indirect_mask = 0;
+ if (nir->info.stage == MESA_SHADER_GEOMETRY ||
+ (nir->info.stage != MESA_SHADER_TESS_CTRL &&
+ nir->info.stage != MESA_SHADER_TESS_EVAL &&
+ !llvm_has_working_vgpr_indexing)) {
+ indirect_mask |= nir_var_shader_in;
+ }
+ if (!llvm_has_working_vgpr_indexing &&
+ nir->info.stage != MESA_SHADER_TESS_CTRL)
+ indirect_mask |= nir_var_shader_out;
+
+ /* TODO: We shouldn't need to do this, however LLVM isn't currently
+ * smart enough to handle indirects without causing excess spilling
+ * causing the gpu to hang.
+ *
+ * See the following thread for more details of the problem:
+ * https://lists.freedesktop.org/archives/mesa-dev/2017-July/162106.html
+ */
+ indirect_mask |= nir_var_local;
+
+ return nir_lower_indirect_derefs(nir, indirect_mask);
+}
+
+void
+radv_optimize_nir(struct nir_shader *shader)
+{
+ bool progress;
+
+ do {
+ progress = false;
+
+ NIR_PASS_V(shader, nir_lower_vars_to_ssa);
+ NIR_PASS_V(shader, nir_lower_64bit_pack);
+ NIR_PASS_V(shader, nir_lower_alu_to_scalar);
+ NIR_PASS_V(shader, nir_lower_phis_to_scalar);
+
+ NIR_PASS(progress, shader, nir_copy_prop);
+ NIR_PASS(progress, shader, nir_opt_remove_phis);
+ NIR_PASS(progress, shader, nir_opt_dce);
+ if (nir_opt_trivial_continues(shader)) {
+ progress = true;
+ NIR_PASS(progress, shader, nir_copy_prop);
+ NIR_PASS(progress, shader, nir_opt_remove_phis);
+ NIR_PASS(progress, shader, nir_opt_dce);
+ }
+ NIR_PASS(progress, shader, nir_opt_if);
+ NIR_PASS(progress, shader, nir_opt_dead_cf);
+ NIR_PASS(progress, shader, nir_opt_cse);
+ NIR_PASS(progress, shader, nir_opt_peephole_select, 8);
+ NIR_PASS(progress, shader, nir_opt_algebraic);
+ NIR_PASS(progress, shader, nir_opt_constant_folding);
+ NIR_PASS(progress, shader, nir_opt_undef);
+ NIR_PASS(progress, shader, nir_opt_conditional_discard);
+ if (shader->options->max_unroll_iterations) {
+ NIR_PASS(progress, shader, nir_opt_loop_unroll, 0);
+ }
+ } while (progress);
+}
+
+nir_shader *
+radv_shader_compile_to_nir(struct radv_device *device,
+ struct radv_shader_module *module,
+ const char *entrypoint_name,
+ gl_shader_stage stage,
+ const VkSpecializationInfo *spec_info)
+{
+ if (strcmp(entrypoint_name, "main") != 0) {
+ radv_finishme("Multiple shaders per module not really supported");
+ }
+
+ nir_shader *nir;
+ nir_function *entry_point;
+ if (module->nir) {
+ /* Some things such as our meta clear/blit code will give us a NIR
+ * shader directly. In that case, we just ignore the SPIR-V entirely
+ * and just use the NIR shader */
+ nir = module->nir;
+ nir->options = &nir_options;
+ nir_validate_shader(nir);
+
+ assert(exec_list_length(&nir->functions) == 1);
+ struct exec_node *node = exec_list_get_head(&nir->functions);
+ entry_point = exec_node_data(nir_function, node, node);
+ } else {
+ uint32_t *spirv = (uint32_t *) module->data;
+ assert(module->size % 4 == 0);
+
+ if (device->instance->debug_flags & RADV_DEBUG_DUMP_SPIRV)
+ radv_print_spirv(spirv, module->size, stderr);
+
+ uint32_t num_spec_entries = 0;
+ struct nir_spirv_specialization *spec_entries = NULL;
+ if (spec_info && spec_info->mapEntryCount > 0) {
+ num_spec_entries = spec_info->mapEntryCount;
+ spec_entries = malloc(num_spec_entries * sizeof(*spec_entries));
+ for (uint32_t i = 0; i < num_spec_entries; i++) {
+ VkSpecializationMapEntry entry = spec_info->pMapEntries[i];
+ const void *data = spec_info->pData + entry.offset;
+ assert(data + entry.size <= spec_info->pData + spec_info->dataSize);
+
+ spec_entries[i].id = spec_info->pMapEntries[i].constantID;
+ if (spec_info->dataSize == 8)
+ spec_entries[i].data64 = *(const uint64_t *)data;
+ else
+ spec_entries[i].data32 = *(const uint32_t *)data;
+ }
+ }
+ const struct nir_spirv_supported_extensions supported_ext = {
+ .draw_parameters = true,
+ .float64 = true,
+ .image_read_without_format = true,
+ .image_write_without_format = true,
+ .tessellation = true,
+ .int64 = true,
+ .multiview = true,
+ .variable_pointers = true,
+ };
+ entry_point = spirv_to_nir(spirv, module->size / 4,
+ spec_entries, num_spec_entries,
+ stage, entrypoint_name, &supported_ext, &nir_options);
+ nir = entry_point->shader;
+ assert(nir->info.stage == stage);
+ nir_validate_shader(nir);
+
+ free(spec_entries);
+
+ /* We have to lower away local constant initializers right before we
+ * inline functions. That way they get properly initialized at the top
+ * of the function and not at the top of its caller.
+ */
+ NIR_PASS_V(nir, nir_lower_constant_initializers, nir_var_local);
+ NIR_PASS_V(nir, nir_lower_returns);
+ NIR_PASS_V(nir, nir_inline_functions);
+
+ /* Pick off the single entrypoint that we want */
+ foreach_list_typed_safe(nir_function, func, node, &nir->functions) {
+ if (func != entry_point)
+ exec_node_remove(&func->node);
+ }
+ assert(exec_list_length(&nir->functions) == 1);
+ entry_point->name = ralloc_strdup(entry_point, "main");
+
+ NIR_PASS_V(nir, nir_remove_dead_variables,
+ nir_var_shader_in | nir_var_shader_out | nir_var_system_value);
+
+ /* Now that we've deleted all but the main function, we can go ahead and
+ * lower the rest of the constant initializers.
+ */
+ NIR_PASS_V(nir, nir_lower_constant_initializers, ~0);
+ NIR_PASS_V(nir, nir_lower_system_values);
+ NIR_PASS_V(nir, nir_lower_clip_cull_distance_arrays);
+ }
+
+ /* Vulkan uses the separate-shader linking model */
+ nir->info.separate_shader = true;
+
+ nir_shader_gather_info(nir, entry_point->impl);
+
+ static const nir_lower_tex_options tex_options = {
+ .lower_txp = ~0,
+ };
+
+ nir_lower_tex(nir, &tex_options);
+
+ nir_lower_vars_to_ssa(nir);
+ nir_lower_var_copies(nir);
+ nir_lower_global_vars_to_local(nir);
+ nir_remove_dead_variables(nir, nir_var_local);
+ radv_lower_indirect_derefs(nir, device->physical_device);
+ radv_optimize_nir(nir);
+
+ return nir;
+}
+
+void *
+radv_alloc_shader_memory(struct radv_device *device,
+ struct radv_shader_variant *shader)
+{
+ mtx_lock(&device->shader_slab_mutex);
+ list_for_each_entry(struct radv_shader_slab, slab, &device->shader_slabs, slabs) {
+ uint64_t offset = 0;
+ list_for_each_entry(struct radv_shader_variant, s, &slab->shaders, slab_list) {
+ if (s->bo_offset - offset >= shader->code_size) {
+ shader->bo = slab->bo;
+ shader->bo_offset = offset;
+ list_addtail(&shader->slab_list, &s->slab_list);
+ mtx_unlock(&device->shader_slab_mutex);
+ return slab->ptr + offset;
+ }
+ offset = align_u64(s->bo_offset + s->code_size, 256);
+ }
+ if (slab->size - offset >= shader->code_size) {
+ shader->bo = slab->bo;
+ shader->bo_offset = offset;
+ list_addtail(&shader->slab_list, &slab->shaders);
+ mtx_unlock(&device->shader_slab_mutex);
+ return slab->ptr + offset;
+ }
+ }
+
+ mtx_unlock(&device->shader_slab_mutex);
+ struct radv_shader_slab *slab = calloc(1, sizeof(struct radv_shader_slab));
+
+ slab->size = 256 * 1024;
+ slab->bo = device->ws->buffer_create(device->ws, slab->size, 256,
+ RADEON_DOMAIN_VRAM, 0);
+ slab->ptr = (char*)device->ws->buffer_map(slab->bo);
+ list_inithead(&slab->shaders);
+
+ mtx_lock(&device->shader_slab_mutex);
+ list_add(&slab->slabs, &device->shader_slabs);
+
+ shader->bo = slab->bo;
+ shader->bo_offset = 0;
+ list_add(&shader->slab_list, &slab->shaders);
+ mtx_unlock(&device->shader_slab_mutex);
+ return slab->ptr;
+}
+
+void
+radv_destroy_shader_slabs(struct radv_device *device)
+{
+ list_for_each_entry_safe(struct radv_shader_slab, slab, &device->shader_slabs, slabs) {
+ device->ws->buffer_destroy(slab->bo);
+ free(slab);
+ }
+ mtx_destroy(&device->shader_slab_mutex);
+}
+
+static void
+radv_fill_shader_variant(struct radv_device *device,
+ struct radv_shader_variant *variant,
+ struct ac_shader_binary *binary,
+ gl_shader_stage stage)
+{
+ bool scratch_enabled = variant->config.scratch_bytes_per_wave > 0;
+ unsigned vgpr_comp_cnt = 0;
+
+ if (scratch_enabled && !device->llvm_supports_spill)
+ radv_finishme("shader scratch support only available with LLVM 4.0");
+
+ variant->code_size = binary->code_size;
+ variant->rsrc2 = S_00B12C_USER_SGPR(variant->info.num_user_sgprs) |
+ S_00B12C_SCRATCH_EN(scratch_enabled);
+
+ variant->rsrc1 = S_00B848_VGPRS((variant->config.num_vgprs - 1) / 4) |
+ S_00B848_SGPRS((variant->config.num_sgprs - 1) / 8) |
+ S_00B848_DX10_CLAMP(1) |
+ S_00B848_FLOAT_MODE(variant->config.float_mode);
+
+ switch (stage) {
+ case MESA_SHADER_TESS_EVAL:
+ vgpr_comp_cnt = 3;
+ variant->rsrc2 |= S_00B12C_OC_LDS_EN(1);
+ break;
+ case MESA_SHADER_TESS_CTRL:
+ if (device->physical_device->rad_info.chip_class >= GFX9)
+ vgpr_comp_cnt = variant->info.vs.vgpr_comp_cnt;
+ else
+ variant->rsrc2 |= S_00B12C_OC_LDS_EN(1);
+ break;
+ case MESA_SHADER_VERTEX:
+ case MESA_SHADER_GEOMETRY:
+ vgpr_comp_cnt = variant->info.vs.vgpr_comp_cnt;
+ break;
+ case MESA_SHADER_FRAGMENT:
+ break;
+ case MESA_SHADER_COMPUTE:
+ variant->rsrc2 |=
+ S_00B84C_TGID_X_EN(1) | S_00B84C_TGID_Y_EN(1) |
+ S_00B84C_TGID_Z_EN(1) | S_00B84C_TIDIG_COMP_CNT(2) |
+ S_00B84C_TG_SIZE_EN(1) |
+ S_00B84C_LDS_SIZE(variant->config.lds_size);
+ break;
+ default:
+ unreachable("unsupported shader type");
+ break;
+ }
+
+ if (device->physical_device->rad_info.chip_class >= GFX9 &&
+ stage == MESA_SHADER_GEOMETRY) {
+ /* TODO: Figure out how many we actually need. */
+ variant->rsrc1 |= S_00B228_GS_VGPR_COMP_CNT(3);
+ variant->rsrc2 |= S_00B22C_ES_VGPR_COMP_CNT(3) |
+ S_00B22C_OC_LDS_EN(1);
+ } else if (device->physical_device->rad_info.chip_class >= GFX9 &&
+ stage == MESA_SHADER_TESS_CTRL)
+ variant->rsrc1 |= S_00B428_LS_VGPR_COMP_CNT(vgpr_comp_cnt);
+ else
+ variant->rsrc1 |= S_00B128_VGPR_COMP_CNT(vgpr_comp_cnt);
+
+ void *ptr = radv_alloc_shader_memory(device, variant);
+ memcpy(ptr, binary->code, binary->code_size);
+}
+
+static struct radv_shader_variant *
+shader_variant_create(struct radv_device *device,
+ struct radv_shader_module *module,
+ struct nir_shader * const *shaders,
+ int shader_count,
+ gl_shader_stage stage,
+ struct ac_nir_compiler_options *options,
+ bool gs_copy_shader,
+ void **code_out,
+ unsigned *code_size_out)
+{
+ enum radeon_family chip_family = device->physical_device->rad_info.family;
+ bool dump_shaders = device->instance->debug_flags & RADV_DEBUG_DUMP_SHADERS;
+ enum ac_target_machine_options tm_options = 0;
+ struct radv_shader_variant *variant;
+ struct ac_shader_binary binary;
+ LLVMTargetMachineRef tm;
+
+ variant = calloc(1, sizeof(struct radv_shader_variant));
+ if (!variant)
+ return NULL;
+
+ options->family = chip_family;
+ options->chip_class = device->physical_device->rad_info.chip_class;
+
+ if (options->supports_spill)
+ tm_options |= AC_TM_SUPPORTS_SPILL;
+ if (device->instance->perftest_flags & RADV_PERFTEST_SISCHED)
+ tm_options |= AC_TM_SISCHED;
+ tm = ac_create_target_machine(chip_family, tm_options);
+
+ if (gs_copy_shader) {
+ assert(shader_count == 1);
+ ac_create_gs_copy_shader(tm, *shaders, &binary, &variant->config,
+ &variant->info, options, dump_shaders);
+ } else {
+ ac_compile_nir_shader(tm, &binary, &variant->config,
+ &variant->info, shaders, shader_count, options,
+ dump_shaders);
+ }
+
+ LLVMDisposeTargetMachine(tm);
+
+ radv_fill_shader_variant(device, variant, &binary, stage);
+
+ if (code_out) {
+ *code_out = binary.code;
+ *code_size_out = binary.code_size;
+ } else
+ free(binary.code);
+ free(binary.config);
+ free(binary.rodata);
+ free(binary.global_symbol_offsets);
+ free(binary.relocs);
+ variant->ref_count = 1;
+
+ if (device->trace_bo) {
+ variant->disasm_string = binary.disasm_string;
+ if (!gs_copy_shader && !module->nir) {
+ variant->nir = *shaders;
+ variant->spirv = (uint32_t *)module->data;
+ variant->spirv_size = module->size;
+ }
+ } else {
+ free(binary.disasm_string);
+ }
+
+ return variant;
+}
+
+struct radv_shader_variant *
+radv_shader_variant_create(struct radv_device *device,
+ struct radv_shader_module *module,
+ struct nir_shader *const *shaders,
+ int shader_count,
+ struct radv_pipeline_layout *layout,
+ const struct ac_shader_variant_key *key,
+ void **code_out,
+ unsigned *code_size_out)
+{
+ struct ac_nir_compiler_options options = {0};
+
+ options.layout = layout;
+ if (key)
+ options.key = *key;
+
+ options.unsafe_math = !!(device->instance->debug_flags & RADV_DEBUG_UNSAFE_MATH);
+ options.supports_spill = device->llvm_supports_spill;
+
+ return shader_variant_create(device, module, shaders, shader_count, shaders[shader_count - 1]->info.stage,
+ &options, false, code_out, code_size_out);
+}
+
+struct radv_shader_variant *
+radv_create_gs_copy_shader(struct radv_device *device,
+ struct nir_shader *shader,
+ void **code_out,
+ unsigned *code_size_out,
+ bool multiview)
+{
+ struct ac_nir_compiler_options options = {0};
+
+ options.key.has_multiview_view_index = multiview;
+
+ return shader_variant_create(device, NULL, &shader, 1, MESA_SHADER_VERTEX,
+ &options, true, code_out, code_size_out);
+}
+
+void
+radv_shader_variant_destroy(struct radv_device *device,
+ struct radv_shader_variant *variant)
+{
+ if (!p_atomic_dec_zero(&variant->ref_count))
+ return;
+
+ mtx_lock(&device->shader_slab_mutex);
+ list_del(&variant->slab_list);
+ mtx_unlock(&device->shader_slab_mutex);
+
+ ralloc_free(variant->nir);
+ free(variant->disasm_string);
+ free(variant);
+}
+
+uint32_t
+radv_shader_stage_to_user_data_0(gl_shader_stage stage, enum chip_class chip_class,
+ bool has_gs, bool has_tess)
+{
+ switch (stage) {
+ case MESA_SHADER_FRAGMENT:
+ return R_00B030_SPI_SHADER_USER_DATA_PS_0;
+ case MESA_SHADER_VERTEX:
+ if (chip_class >= GFX9) {
+ return has_tess ? R_00B430_SPI_SHADER_USER_DATA_LS_0 :
+ has_gs ? R_00B330_SPI_SHADER_USER_DATA_ES_0 :
+ R_00B130_SPI_SHADER_USER_DATA_VS_0;
+ }
+ if (has_tess)
+ return R_00B530_SPI_SHADER_USER_DATA_LS_0;
+ else
+ return has_gs ? R_00B330_SPI_SHADER_USER_DATA_ES_0 : R_00B130_SPI_SHADER_USER_DATA_VS_0;
+ case MESA_SHADER_GEOMETRY:
+ return chip_class >= GFX9 ? R_00B330_SPI_SHADER_USER_DATA_ES_0 :
+ R_00B230_SPI_SHADER_USER_DATA_GS_0;
+ case MESA_SHADER_COMPUTE:
+ return R_00B900_COMPUTE_USER_DATA_0;
+ case MESA_SHADER_TESS_CTRL:
+ return chip_class >= GFX9 ? R_00B430_SPI_SHADER_USER_DATA_LS_0 :
+ R_00B430_SPI_SHADER_USER_DATA_HS_0;
+ case MESA_SHADER_TESS_EVAL:
+ if (chip_class >= GFX9) {
+ return has_gs ? R_00B330_SPI_SHADER_USER_DATA_ES_0 :
+ R_00B130_SPI_SHADER_USER_DATA_VS_0;
+ }
+ if (has_gs)
+ return R_00B330_SPI_SHADER_USER_DATA_ES_0;
+ else
+ return R_00B130_SPI_SHADER_USER_DATA_VS_0;
+ default:
+ unreachable("unknown shader");
+ }
+}
+
+const char *
+radv_get_shader_name(struct radv_shader_variant *var, gl_shader_stage stage)
+{
+ switch (stage) {
+ case MESA_SHADER_VERTEX: return var->info.vs.as_ls ? "Vertex Shader as LS" : var->info.vs.as_es ? "Vertex Shader as ES" : "Vertex Shader as VS";
+ case MESA_SHADER_GEOMETRY: return "Geometry Shader";
+ case MESA_SHADER_FRAGMENT: return "Pixel Shader";
+ case MESA_SHADER_COMPUTE: return "Compute Shader";
+ case MESA_SHADER_TESS_CTRL: return "Tessellation Control Shader";
+ case MESA_SHADER_TESS_EVAL: return var->info.tes.as_es ? "Tessellation Evaluation Shader as ES" : "Tessellation Evaluation Shader as VS";
+ default:
+ return "Unknown shader";
+ };
+}
+
+void
+radv_shader_dump_stats(struct radv_device *device,
+ struct radv_shader_variant *variant,
+ gl_shader_stage stage,
+ FILE *file)
+{
+ unsigned lds_increment = device->physical_device->rad_info.chip_class >= CIK ? 512 : 256;
+ struct ac_shader_config *conf;
+ unsigned max_simd_waves;
+ unsigned lds_per_wave = 0;
+
+ switch (device->physical_device->rad_info.family) {
+ /* These always have 8 waves: */
+ case CHIP_POLARIS10:
+ case CHIP_POLARIS11:
+ case CHIP_POLARIS12:
+ max_simd_waves = 8;
+ break;
+ default:
+ max_simd_waves = 10;
+ }
+
+ conf = &variant->config;
+
+ if (stage == MESA_SHADER_FRAGMENT) {
+ lds_per_wave = conf->lds_size * lds_increment +
+ align(variant->info.fs.num_interp * 48,
+ lds_increment);
+ }
+
+ if (conf->num_sgprs) {
+ if (device->physical_device->rad_info.chip_class >= VI)
+ max_simd_waves = MIN2(max_simd_waves, 800 / conf->num_sgprs);
+ else
+ max_simd_waves = MIN2(max_simd_waves, 512 / conf->num_sgprs);
+ }
+
+ if (conf->num_vgprs)
+ max_simd_waves = MIN2(max_simd_waves, 256 / conf->num_vgprs);
+
+ /* LDS is 64KB per CU (4 SIMDs), divided into 16KB blocks per SIMD
+ * that PS can use.
+ */
+ if (lds_per_wave)
+ max_simd_waves = MIN2(max_simd_waves, 16384 / lds_per_wave);
+
+ fprintf(file, "\n%s:\n", radv_get_shader_name(variant, stage));
+
+ if (stage == MESA_SHADER_FRAGMENT) {
+ fprintf(file, "*** SHADER CONFIG ***\n"
+ "SPI_PS_INPUT_ADDR = 0x%04x\n"
+ "SPI_PS_INPUT_ENA = 0x%04x\n",
+ conf->spi_ps_input_addr, conf->spi_ps_input_ena);
+ }
+
+ fprintf(file, "*** SHADER STATS ***\n"
+ "SGPRS: %d\n"
+ "VGPRS: %d\n"
+ "Spilled SGPRs: %d\n"
+ "Spilled VGPRs: %d\n"
+ "Code Size: %d bytes\n"
+ "LDS: %d blocks\n"
+ "Scratch: %d bytes per wave\n"
+ "Max Waves: %d\n"
+ "********************\n\n\n",
+ conf->num_sgprs, conf->num_vgprs,
+ conf->spilled_sgprs, conf->spilled_vgprs, variant->code_size,
+ conf->lds_size, conf->scratch_bytes_per_wave,
+ max_simd_waves);
+}
diff --git a/lib/mesa/src/amd/vulkan/radv_shader.h b/lib/mesa/src/amd/vulkan/radv_shader.h
new file mode 100644
index 000000000..6e4e9966c
--- /dev/null
+++ b/lib/mesa/src/amd/vulkan/radv_shader.h
@@ -0,0 +1,123 @@
+/*
+ * Copyright © 2016 Red Hat.
+ * Copyright © 2016 Bas Nieuwenhuizen
+ *
+ * based in part on anv driver which is:
+ * Copyright © 2015 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 (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.
+ */
+
+#ifndef RADV_SHADER_H
+#define RADV_SHADER_H
+
+#include "radv_private.h"
+
+#include "nir/nir.h"
+
+struct radv_shader_module {
+ struct nir_shader *nir;
+ unsigned char sha1[20];
+ uint32_t size;
+ char data[0];
+};
+
+struct radv_shader_variant {
+ uint32_t ref_count;
+
+ struct radeon_winsys_bo *bo;
+ uint64_t bo_offset;
+ struct ac_shader_config config;
+ uint32_t code_size;
+ struct ac_shader_variant_info info;
+ unsigned rsrc1;
+ unsigned rsrc2;
+
+ /* debug only */
+ uint32_t *spirv;
+ uint32_t spirv_size;
+ struct nir_shader *nir;
+ char *disasm_string;
+
+ struct list_head slab_list;
+};
+
+struct radv_shader_slab {
+ struct list_head slabs;
+ struct list_head shaders;
+ struct radeon_winsys_bo *bo;
+ uint64_t size;
+ char *ptr;
+};
+
+void
+radv_optimize_nir(struct nir_shader *shader);
+
+nir_shader *
+radv_shader_compile_to_nir(struct radv_device *device,
+ struct radv_shader_module *module,
+ const char *entrypoint_name,
+ gl_shader_stage stage,
+ const VkSpecializationInfo *spec_info);
+
+void *
+radv_alloc_shader_memory(struct radv_device *device,
+ struct radv_shader_variant *shader);
+
+void
+radv_destroy_shader_slabs(struct radv_device *device);
+
+struct radv_shader_variant *
+radv_shader_variant_create(struct radv_device *device,
+ struct radv_shader_module *module,
+ struct nir_shader *const *shaders,
+ int shader_count,
+ struct radv_pipeline_layout *layout,
+ const struct ac_shader_variant_key *key,
+ void **code_out,
+ unsigned *code_size_out);
+
+struct radv_shader_variant *
+radv_create_gs_copy_shader(struct radv_device *device, struct nir_shader *nir,
+ void **code_out, unsigned *code_size_out,
+ bool multiview);
+
+void
+radv_shader_variant_destroy(struct radv_device *device,
+ struct radv_shader_variant *variant);
+
+bool
+radv_lower_indirect_derefs(struct nir_shader *nir,
+ struct radv_physical_device *device);
+
+uint32_t
+radv_shader_stage_to_user_data_0(gl_shader_stage stage, enum chip_class chip_class,
+ bool has_gs, bool has_tess);
+
+const char *
+radv_get_shader_name(struct radv_shader_variant *var, gl_shader_stage stage);
+
+void
+radv_shader_dump_stats(struct radv_device *device,
+ struct radv_shader_variant *variant,
+ gl_shader_stage stage,
+ FILE *file);
+
+#endif
diff --git a/lib/mesa/src/broadcom/Makefile.cle.am b/lib/mesa/src/broadcom/Makefile.cle.am
new file mode 100644
index 000000000..1c262d039
--- /dev/null
+++ b/lib/mesa/src/broadcom/Makefile.cle.am
@@ -0,0 +1,6 @@
+noinst_LTLIBRARIES += cle/libbroadcom_cle.la
+
+cle_libbroadcom_cle_la_CFLAGS = \
+ -I$(top_builddir)/src/broadcom/cle \
+ $(AM_CFLAGS)
+cle_libbroadcom_cle_la_SOURCES = $(BROADCOM_DECODER_FILES)
diff --git a/lib/mesa/src/broadcom/Makefile.vc5.am b/lib/mesa/src/broadcom/Makefile.vc5.am
new file mode 100644
index 000000000..3e8e28bc9
--- /dev/null
+++ b/lib/mesa/src/broadcom/Makefile.vc5.am
@@ -0,0 +1,20 @@
+noinst_LTLIBRARIES += libbroadcom.la
+
+if USE_VC5_SIMULATOR
+AM_CFLAGS += $(VC5_SIMULATOR_CFLAGS)
+libbroadcom_la_LDFLAGS = $(VC5_SIMULATOR_LIBS)
+endif
+
+libbroadcom_la_SOURCES = $(BROADCOM_FILES)
+
+check_PROGRAMS += \
+ qpu/tests/qpu_disasm \
+ $(NULL)
+
+LDADD = \
+ libbroadcom.la \
+ $(top_builddir)/src/compiler/nir/libnir.la \
+ $(top_builddir)/src/util/libmesautil.la \
+ $(NULL)
+
+TESTS += $(check_PROGRAMS)
diff --git a/lib/mesa/src/broadcom/cle/v3d_decoder.c b/lib/mesa/src/broadcom/cle/v3d_decoder.c
new file mode 100644
index 000000000..4ac40af05
--- /dev/null
+++ b/lib/mesa/src/broadcom/cle/v3d_decoder.c
@@ -0,0 +1,876 @@
+/*
+ * Copyright © 2016 Intel Corporation
+ * Copyright © 2017 Broadcom
+ *
+ * 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 <stdio.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdarg.h>
+#include <string.h>
+#include <expat.h>
+#include <inttypes.h>
+#include <zlib.h>
+
+#include <util/macros.h>
+#include <util/ralloc.h>
+
+#include "v3d_decoder.h"
+#include "v3d_packet_helpers.h"
+#include "v3d_xml.h"
+
+struct v3d_spec {
+ uint32_t ver;
+
+ int ncommands;
+ struct v3d_group *commands[256];
+ int nstructs;
+ struct v3d_group *structs[256];
+ int nregisters;
+ struct v3d_group *registers[256];
+ int nenums;
+ struct v3d_enum *enums[256];
+};
+
+struct location {
+ const char *filename;
+ int line_number;
+};
+
+struct parser_context {
+ XML_Parser parser;
+ int foo;
+ struct location loc;
+
+ struct v3d_group *group;
+ struct v3d_enum *enoom;
+
+ int nvalues;
+ struct v3d_value *values[256];
+
+ struct v3d_spec *spec;
+};
+
+const char *
+v3d_group_get_name(struct v3d_group *group)
+{
+ return group->name;
+}
+
+uint8_t
+v3d_group_get_opcode(struct v3d_group *group)
+{
+ return group->opcode;
+}
+
+struct v3d_group *
+v3d_spec_find_struct(struct v3d_spec *spec, const char *name)
+{
+ for (int i = 0; i < spec->nstructs; i++)
+ if (strcmp(spec->structs[i]->name, name) == 0)
+ return spec->structs[i];
+
+ return NULL;
+}
+
+struct v3d_group *
+v3d_spec_find_register(struct v3d_spec *spec, uint32_t offset)
+{
+ for (int i = 0; i < spec->nregisters; i++)
+ if (spec->registers[i]->register_offset == offset)
+ return spec->registers[i];
+
+ return NULL;
+}
+
+struct v3d_group *
+v3d_spec_find_register_by_name(struct v3d_spec *spec, const char *name)
+{
+ for (int i = 0; i < spec->nregisters; i++) {
+ if (strcmp(spec->registers[i]->name, name) == 0)
+ return spec->registers[i];
+ }
+
+ return NULL;
+}
+
+struct v3d_enum *
+v3d_spec_find_enum(struct v3d_spec *spec, const char *name)
+{
+ for (int i = 0; i < spec->nenums; i++)
+ if (strcmp(spec->enums[i]->name, name) == 0)
+ return spec->enums[i];
+
+ return NULL;
+}
+
+static void __attribute__((noreturn))
+fail(struct location *loc, const char *msg, ...)
+{
+ va_list ap;
+
+ va_start(ap, msg);
+ fprintf(stderr, "%s:%d: error: ",
+ loc->filename, loc->line_number);
+ vfprintf(stderr, msg, ap);
+ fprintf(stderr, "\n");
+ va_end(ap);
+ exit(EXIT_FAILURE);
+}
+
+static void *
+fail_on_null(void *p)
+{
+ if (p == NULL) {
+ fprintf(stderr, "aubinator: out of memory\n");
+ exit(EXIT_FAILURE);
+ }
+
+ return p;
+}
+
+static char *
+xstrdup(const char *s)
+{
+ return fail_on_null(strdup(s));
+}
+
+static void *
+zalloc(size_t s)
+{
+ return calloc(s, 1);
+}
+
+static void *
+xzalloc(size_t s)
+{
+ return fail_on_null(zalloc(s));
+}
+
+/* We allow fields to have either a bit index, or append "b" for a byte index.
+ */
+static bool
+is_byte_offset(const char *value)
+{
+ return value[strlen(value) - 1] == 'b';
+}
+
+static void
+get_group_offset_count(const char **atts, uint32_t *offset, uint32_t *count,
+ uint32_t *size, bool *variable)
+{
+ char *p;
+ int i;
+
+ for (i = 0; atts[i]; i += 2) {
+ if (strcmp(atts[i], "count") == 0) {
+ *count = strtoul(atts[i + 1], &p, 0);
+ if (*count == 0)
+ *variable = true;
+ } else if (strcmp(atts[i], "start") == 0) {
+ *offset = strtoul(atts[i + 1], &p, 0);
+ } else if (strcmp(atts[i], "size") == 0) {
+ *size = strtoul(atts[i + 1], &p, 0);
+ }
+ }
+ return;
+}
+
+static struct v3d_group *
+create_group(struct parser_context *ctx,
+ const char *name,
+ const char **atts,
+ struct v3d_group *parent)
+{
+ struct v3d_group *group;
+
+ group = xzalloc(sizeof(*group));
+ if (name)
+ group->name = xstrdup(name);
+
+ group->spec = ctx->spec;
+ group->group_offset = 0;
+ group->group_count = 0;
+ group->variable = false;
+
+ if (parent) {
+ group->parent = parent;
+ get_group_offset_count(atts,
+ &group->group_offset,
+ &group->group_count,
+ &group->group_size,
+ &group->variable);
+ }
+
+ return group;
+}
+
+static struct v3d_enum *
+create_enum(struct parser_context *ctx, const char *name, const char **atts)
+{
+ struct v3d_enum *e;
+
+ e = xzalloc(sizeof(*e));
+ if (name)
+ e->name = xstrdup(name);
+
+ e->nvalues = 0;
+
+ return e;
+}
+
+static void
+get_register_offset(const char **atts, uint32_t *offset)
+{
+ char *p;
+ int i;
+
+ for (i = 0; atts[i]; i += 2) {
+ if (strcmp(atts[i], "num") == 0)
+ *offset = strtoul(atts[i + 1], &p, 0);
+ }
+ return;
+}
+
+static void
+get_start_end_pos(int *start, int *end)
+{
+ /* start value has to be mod with 32 as we need the relative
+ * start position in the first DWord. For the end position, add
+ * the length of the field to the start position to get the
+ * relative postion in the 64 bit address.
+ */
+ if (*end - *start > 32) {
+ int len = *end - *start;
+ *start = *start % 32;
+ *end = *start + len;
+ } else {
+ *start = *start % 32;
+ *end = *end % 32;
+ }
+
+ return;
+}
+
+static inline uint64_t
+mask(int start, int end)
+{
+ uint64_t v;
+
+ v = ~0ULL >> (63 - end + start);
+
+ return v << start;
+}
+
+static inline uint64_t
+field(uint64_t value, int start, int end)
+{
+ get_start_end_pos(&start, &end);
+ return (value & mask(start, end)) >> (start);
+}
+
+static inline uint64_t
+field_address(uint64_t value, int start, int end)
+{
+ /* no need to right shift for address/offset */
+ get_start_end_pos(&start, &end);
+ return (value & mask(start, end));
+}
+
+static struct v3d_type
+string_to_type(struct parser_context *ctx, const char *s)
+{
+ int i, f;
+ struct v3d_group *g;
+ struct v3d_enum *e;
+
+ if (strcmp(s, "int") == 0)
+ return (struct v3d_type) { .kind = V3D_TYPE_INT };
+ else if (strcmp(s, "uint") == 0)
+ return (struct v3d_type) { .kind = V3D_TYPE_UINT };
+ else if (strcmp(s, "bool") == 0)
+ return (struct v3d_type) { .kind = V3D_TYPE_BOOL };
+ else if (strcmp(s, "float") == 0)
+ return (struct v3d_type) { .kind = V3D_TYPE_FLOAT };
+ else if (strcmp(s, "address") == 0)
+ return (struct v3d_type) { .kind = V3D_TYPE_ADDRESS };
+ else if (strcmp(s, "offset") == 0)
+ return (struct v3d_type) { .kind = V3D_TYPE_OFFSET };
+ else if (sscanf(s, "u%d.%d", &i, &f) == 2)
+ return (struct v3d_type) { .kind = V3D_TYPE_UFIXED, .i = i, .f = f };
+ else if (sscanf(s, "s%d.%d", &i, &f) == 2)
+ return (struct v3d_type) { .kind = V3D_TYPE_SFIXED, .i = i, .f = f };
+ else if (g = v3d_spec_find_struct(ctx->spec, s), g != NULL)
+ return (struct v3d_type) { .kind = V3D_TYPE_STRUCT, .v3d_struct = g };
+ else if (e = v3d_spec_find_enum(ctx->spec, s), e != NULL)
+ return (struct v3d_type) { .kind = V3D_TYPE_ENUM, .v3d_enum = e };
+ else if (strcmp(s, "mbo") == 0)
+ return (struct v3d_type) { .kind = V3D_TYPE_MBO };
+ else
+ fail(&ctx->loc, "invalid type: %s", s);
+}
+
+static struct v3d_field *
+create_field(struct parser_context *ctx, const char **atts)
+{
+ struct v3d_field *field;
+ char *p;
+ int i;
+ uint32_t size = 0;
+
+ field = xzalloc(sizeof(*field));
+
+ for (i = 0; atts[i]; i += 2) {
+ if (strcmp(atts[i], "name") == 0)
+ field->name = xstrdup(atts[i + 1]);
+ else if (strcmp(atts[i], "start") == 0) {
+ field->start = strtoul(atts[i + 1], &p, 0);
+ if (is_byte_offset(atts[i + 1]))
+ field->start *= 8;
+ } else if (strcmp(atts[i], "end") == 0) {
+ field->end = strtoul(atts[i + 1], &p, 0) - 1;
+ if (is_byte_offset(atts[i + 1]))
+ field->end *= 8;
+ } else if (strcmp(atts[i], "size") == 0) {
+ size = strtoul(atts[i + 1], &p, 0);
+ if (is_byte_offset(atts[i + 1]))
+ size *= 8;
+ } else if (strcmp(atts[i], "type") == 0)
+ field->type = string_to_type(ctx, atts[i + 1]);
+ else if (strcmp(atts[i], "default") == 0) {
+ field->has_default = true;
+ field->default_value = strtoul(atts[i + 1], &p, 0);
+ }
+ }
+
+ if (size)
+ field->end = field->start + size - 1;
+
+ return field;
+}
+
+static struct v3d_value *
+create_value(struct parser_context *ctx, const char **atts)
+{
+ struct v3d_value *value = xzalloc(sizeof(*value));
+
+ for (int i = 0; atts[i]; i += 2) {
+ if (strcmp(atts[i], "name") == 0)
+ value->name = xstrdup(atts[i + 1]);
+ else if (strcmp(atts[i], "value") == 0)
+ value->value = strtoul(atts[i + 1], NULL, 0);
+ }
+
+ return value;
+}
+
+static void
+create_and_append_field(struct parser_context *ctx,
+ const char **atts)
+{
+ if (ctx->group->nfields == ctx->group->fields_size) {
+ ctx->group->fields_size = MAX2(ctx->group->fields_size * 2, 2);
+ ctx->group->fields =
+ (struct v3d_field **) realloc(ctx->group->fields,
+ sizeof(ctx->group->fields[0]) *
+ ctx->group->fields_size);
+ }
+
+ ctx->group->fields[ctx->group->nfields++] = create_field(ctx, atts);
+}
+
+static void
+set_group_opcode(struct v3d_group *group, const char **atts)
+{
+ char *p;
+ int i;
+
+ for (i = 0; atts[i]; i += 2) {
+ if (strcmp(atts[i], "code") == 0)
+ group->opcode = strtoul(atts[i + 1], &p, 0);
+ }
+ return;
+}
+
+static void
+start_element(void *data, const char *element_name, const char **atts)
+{
+ struct parser_context *ctx = data;
+ int i;
+ const char *name = NULL;
+ const char *ver = NULL;
+
+ ctx->loc.line_number = XML_GetCurrentLineNumber(ctx->parser);
+
+ for (i = 0; atts[i]; i += 2) {
+ if (strcmp(atts[i], "name") == 0)
+ name = atts[i + 1];
+ else if (strcmp(atts[i], "gen") == 0)
+ ver = atts[i + 1];
+ }
+
+ if (strcmp(element_name, "vcxml") == 0) {
+ if (ver == NULL)
+ fail(&ctx->loc, "no ver given");
+
+ int major, minor;
+ int n = sscanf(ver, "%d.%d", &major, &minor);
+ if (n == 0)
+ fail(&ctx->loc, "invalid ver given: %s", ver);
+ if (n == 1)
+ minor = 0;
+
+ ctx->spec->ver = major * 10 + minor;
+ } else if (strcmp(element_name, "packet") == 0 ||
+ strcmp(element_name, "struct") == 0) {
+ ctx->group = create_group(ctx, name, atts, NULL);
+
+ if (strcmp(element_name, "packet") == 0)
+ set_group_opcode(ctx->group, atts);
+ } else if (strcmp(element_name, "register") == 0) {
+ ctx->group = create_group(ctx, name, atts, NULL);
+ get_register_offset(atts, &ctx->group->register_offset);
+ } else if (strcmp(element_name, "group") == 0) {
+ struct v3d_group *previous_group = ctx->group;
+ while (previous_group->next)
+ previous_group = previous_group->next;
+
+ struct v3d_group *group = create_group(ctx, "", atts,
+ ctx->group);
+ previous_group->next = group;
+ ctx->group = group;
+ } else if (strcmp(element_name, "field") == 0) {
+ create_and_append_field(ctx, atts);
+ } else if (strcmp(element_name, "enum") == 0) {
+ ctx->enoom = create_enum(ctx, name, atts);
+ } else if (strcmp(element_name, "value") == 0) {
+ ctx->values[ctx->nvalues++] = create_value(ctx, atts);
+ assert(ctx->nvalues < ARRAY_SIZE(ctx->values));
+ }
+
+}
+
+static void
+end_element(void *data, const char *name)
+{
+ struct parser_context *ctx = data;
+ struct v3d_spec *spec = ctx->spec;
+
+ if (strcmp(name, "packet") == 0 ||
+ strcmp(name, "struct") == 0 ||
+ strcmp(name, "register") == 0) {
+ struct v3d_group *group = ctx->group;
+
+ ctx->group = ctx->group->parent;
+
+ if (strcmp(name, "packet") == 0) {
+ spec->commands[spec->ncommands++] = group;
+
+ /* V3D packet XML has the packet contents with offsets
+ * starting from the first bit after the opcode, to
+ * match the spec. Shift the fields up now.
+ */
+ for (int i = 0; i < group->nfields; i++) {
+ group->fields[i]->start += 8;
+ group->fields[i]->end += 8;
+ }
+ }
+ else if (strcmp(name, "struct") == 0)
+ spec->structs[spec->nstructs++] = group;
+ else if (strcmp(name, "register") == 0)
+ spec->registers[spec->nregisters++] = group;
+
+ assert(spec->ncommands < ARRAY_SIZE(spec->commands));
+ assert(spec->nstructs < ARRAY_SIZE(spec->structs));
+ assert(spec->nregisters < ARRAY_SIZE(spec->registers));
+ } else if (strcmp(name, "group") == 0) {
+ ctx->group = ctx->group->parent;
+ } else if (strcmp(name, "field") == 0) {
+ assert(ctx->group->nfields > 0);
+ struct v3d_field *field = ctx->group->fields[ctx->group->nfields - 1];
+ size_t size = ctx->nvalues * sizeof(ctx->values[0]);
+ field->inline_enum.values = xzalloc(size);
+ field->inline_enum.nvalues = ctx->nvalues;
+ memcpy(field->inline_enum.values, ctx->values, size);
+ ctx->nvalues = 0;
+ } else if (strcmp(name, "enum") == 0) {
+ struct v3d_enum *e = ctx->enoom;
+ size_t size = ctx->nvalues * sizeof(ctx->values[0]);
+ e->values = xzalloc(size);
+ e->nvalues = ctx->nvalues;
+ memcpy(e->values, ctx->values, size);
+ ctx->nvalues = 0;
+ ctx->enoom = NULL;
+ spec->enums[spec->nenums++] = e;
+ }
+}
+
+static void
+character_data(void *data, const XML_Char *s, int len)
+{
+}
+
+static uint32_t zlib_inflate(const void *compressed_data,
+ uint32_t compressed_len,
+ void **out_ptr)
+{
+ struct z_stream_s zstream;
+ void *out;
+
+ memset(&zstream, 0, sizeof(zstream));
+
+ zstream.next_in = (unsigned char *)compressed_data;
+ zstream.avail_in = compressed_len;
+
+ if (inflateInit(&zstream) != Z_OK)
+ return 0;
+
+ out = malloc(4096);
+ zstream.next_out = out;
+ zstream.avail_out = 4096;
+
+ do {
+ switch (inflate(&zstream, Z_SYNC_FLUSH)) {
+ case Z_STREAM_END:
+ goto end;
+ case Z_OK:
+ break;
+ default:
+ inflateEnd(&zstream);
+ return 0;
+ }
+
+ if (zstream.avail_out)
+ break;
+
+ out = realloc(out, 2*zstream.total_out);
+ if (out == NULL) {
+ inflateEnd(&zstream);
+ return 0;
+ }
+
+ zstream.next_out = (unsigned char *)out + zstream.total_out;
+ zstream.avail_out = zstream.total_out;
+ } while (1);
+ end:
+ inflateEnd(&zstream);
+ *out_ptr = out;
+ return zstream.total_out;
+}
+
+struct v3d_spec *
+v3d_spec_load(const struct v3d_device_info *devinfo)
+{
+ struct parser_context ctx;
+ void *buf;
+ uint8_t *text_data = NULL;
+ uint32_t text_offset = 0, text_length = 0, total_length;
+
+ for (int i = 0; i < ARRAY_SIZE(genxml_files_table); i++) {
+ if (genxml_files_table[i].gen_10 == devinfo->ver) {
+ text_offset = genxml_files_table[i].offset;
+ text_length = genxml_files_table[i].length;
+ break;
+ }
+ }
+
+ if (text_length == 0) {
+ fprintf(stderr, "unable to find gen (%u) data\n", devinfo->ver);
+ return NULL;
+ }
+
+ memset(&ctx, 0, sizeof ctx);
+ ctx.parser = XML_ParserCreate(NULL);
+ XML_SetUserData(ctx.parser, &ctx);
+ if (ctx.parser == NULL) {
+ fprintf(stderr, "failed to create parser\n");
+ return NULL;
+ }
+
+ XML_SetElementHandler(ctx.parser, start_element, end_element);
+ XML_SetCharacterDataHandler(ctx.parser, character_data);
+
+ ctx.spec = xzalloc(sizeof(*ctx.spec));
+
+ total_length = zlib_inflate(compress_genxmls,
+ sizeof(compress_genxmls),
+ (void **) &text_data);
+ assert(text_offset + text_length <= total_length);
+
+ buf = XML_GetBuffer(ctx.parser, text_length);
+ memcpy(buf, &text_data[text_offset], text_length);
+
+ if (XML_ParseBuffer(ctx.parser, text_length, true) == 0) {
+ fprintf(stderr,
+ "Error parsing XML at line %ld col %ld byte %ld/%u: %s\n",
+ XML_GetCurrentLineNumber(ctx.parser),
+ XML_GetCurrentColumnNumber(ctx.parser),
+ XML_GetCurrentByteIndex(ctx.parser), text_length,
+ XML_ErrorString(XML_GetErrorCode(ctx.parser)));
+ XML_ParserFree(ctx.parser);
+ free(text_data);
+ return NULL;
+ }
+
+ XML_ParserFree(ctx.parser);
+ free(text_data);
+
+ return ctx.spec;
+}
+
+struct v3d_group *
+v3d_spec_find_instruction(struct v3d_spec *spec, const uint8_t *p)
+{
+ uint8_t opcode = *p;
+
+ for (int i = 0; i < spec->ncommands; i++) {
+ struct v3d_group *group = spec->commands[i];
+
+ if (opcode != group->opcode)
+ continue;
+
+ /* If there's a "sub-id" field, make sure that it matches the
+ * instruction being decoded.
+ */
+ struct v3d_field *subid = NULL;
+ for (int j = 0; j < group->nfields; j++) {
+ struct v3d_field *field = group->fields[j];
+ if (strcmp(field->name, "sub-id") == 0) {
+ subid = field;
+ break;
+ }
+ }
+
+ if (subid && (__gen_unpack_uint(p, subid->start, subid->end) !=
+ subid->default_value)) {
+ continue;
+ }
+
+ return group;
+ }
+
+ return NULL;
+}
+
+/** Returns the size of a V3D packet. */
+int
+v3d_group_get_length(struct v3d_group *group)
+{
+ int last_bit = 0;
+ for (int i = 0; i < group->nfields; i++) {
+ struct v3d_field *field = group->fields[i];
+
+ last_bit = MAX2(last_bit, field->end);
+ }
+ return last_bit / 8 + 1;
+}
+
+void
+v3d_field_iterator_init(struct v3d_field_iterator *iter,
+ struct v3d_group *group,
+ const uint8_t *p,
+ bool print_colors)
+{
+ memset(iter, 0, sizeof(*iter));
+
+ iter->group = group;
+ iter->p = p;
+ iter->print_colors = print_colors;
+}
+
+static const char *
+v3d_get_enum_name(struct v3d_enum *e, uint64_t value)
+{
+ for (int i = 0; i < e->nvalues; i++) {
+ if (e->values[i]->value == value) {
+ return e->values[i]->name;
+ }
+ }
+ return NULL;
+}
+
+static bool
+iter_more_fields(const struct v3d_field_iterator *iter)
+{
+ return iter->field_iter < iter->group->nfields;
+}
+
+static uint32_t
+iter_group_offset_bits(const struct v3d_field_iterator *iter,
+ uint32_t group_iter)
+{
+ return iter->group->group_offset + (group_iter *
+ iter->group->group_size);
+}
+
+static bool
+iter_more_groups(const struct v3d_field_iterator *iter)
+{
+ if (iter->group->variable) {
+ return iter_group_offset_bits(iter, iter->group_iter + 1) <
+ (v3d_group_get_length(iter->group) * 8);
+ } else {
+ return (iter->group_iter + 1) < iter->group->group_count ||
+ iter->group->next != NULL;
+ }
+}
+
+static void
+iter_advance_group(struct v3d_field_iterator *iter)
+{
+ if (iter->group->variable)
+ iter->group_iter++;
+ else {
+ if ((iter->group_iter + 1) < iter->group->group_count) {
+ iter->group_iter++;
+ } else {
+ iter->group = iter->group->next;
+ iter->group_iter = 0;
+ }
+ }
+
+ iter->field_iter = 0;
+}
+
+static bool
+iter_advance_field(struct v3d_field_iterator *iter)
+{
+ while (!iter_more_fields(iter)) {
+ if (!iter_more_groups(iter))
+ return false;
+
+ iter_advance_group(iter);
+ }
+
+ iter->field = iter->group->fields[iter->field_iter++];
+ if (iter->field->name)
+ strncpy(iter->name, iter->field->name, sizeof(iter->name));
+ else
+ memset(iter->name, 0, sizeof(iter->name));
+ iter->offset = iter_group_offset_bits(iter, iter->group_iter) / 8 +
+ iter->field->start / 8;
+ iter->struct_desc = NULL;
+
+ return true;
+}
+
+bool
+v3d_field_iterator_next(struct v3d_field_iterator *iter)
+{
+ if (!iter_advance_field(iter))
+ return false;
+
+ const char *enum_name = NULL;
+
+ int s = iter->field->start;
+ int e = iter->field->end;
+
+ switch (iter->field->type.kind) {
+ case V3D_TYPE_UNKNOWN:
+ case V3D_TYPE_INT: {
+ uint32_t value = __gen_unpack_sint(iter->p, s, e);
+ snprintf(iter->value, sizeof(iter->value), "%d", value);
+ enum_name = v3d_get_enum_name(&iter->field->inline_enum, value);
+ break;
+ }
+ case V3D_TYPE_UINT: {
+ uint32_t value = __gen_unpack_uint(iter->p, s, e);
+ snprintf(iter->value, sizeof(iter->value), "%u", value);
+ enum_name = v3d_get_enum_name(&iter->field->inline_enum, value);
+ break;
+ }
+ case V3D_TYPE_BOOL: {
+ const char *true_string =
+ iter->print_colors ? "\e[0;35mtrue\e[0m" : "true";
+ snprintf(iter->value, sizeof(iter->value), "%s",
+ __gen_unpack_uint(iter->p, s, e) ?
+ true_string : "false");
+ break;
+ }
+ case V3D_TYPE_FLOAT:
+ snprintf(iter->value, sizeof(iter->value), "%f",
+ __gen_unpack_float(iter->p, s, e));
+ break;
+ case V3D_TYPE_ADDRESS:
+ case V3D_TYPE_OFFSET:
+ snprintf(iter->value, sizeof(iter->value), "0x%08"PRIx64,
+ __gen_unpack_uint(iter->p, s, e) << (31 - (e - s)));
+ break;
+ case V3D_TYPE_STRUCT:
+ snprintf(iter->value, sizeof(iter->value), "<struct %s>",
+ iter->field->type.v3d_struct->name);
+ iter->struct_desc =
+ v3d_spec_find_struct(iter->group->spec,
+ iter->field->type.v3d_struct->name);
+ break;
+ case V3D_TYPE_SFIXED:
+ snprintf(iter->value, sizeof(iter->value), "%f",
+ __gen_unpack_sfixed(iter->p, s, e,
+ iter->field->type.f));
+ break;
+ case V3D_TYPE_UFIXED:
+ snprintf(iter->value, sizeof(iter->value), "%f",
+ __gen_unpack_ufixed(iter->p, s, e,
+ iter->field->type.f));
+ break;
+ case V3D_TYPE_MBO:
+ break;
+ case V3D_TYPE_ENUM: {
+ uint32_t value = __gen_unpack_uint(iter->p, s, e);
+ snprintf(iter->value, sizeof(iter->value), "%d", value);
+ enum_name = v3d_get_enum_name(iter->field->type.v3d_enum, value);
+ break;
+ }
+ }
+
+ if (strlen(iter->group->name) == 0) {
+ int length = strlen(iter->name);
+ snprintf(iter->name + length, sizeof(iter->name) - length,
+ "[%i]", iter->group_iter);
+ }
+
+ if (enum_name) {
+ int length = strlen(iter->value);
+ snprintf(iter->value + length, sizeof(iter->value) - length,
+ " (%s)", enum_name);
+ }
+
+ return true;
+}
+
+void
+v3d_print_group(FILE *outfile, struct v3d_group *group,
+ uint64_t offset, const uint8_t *p, bool color)
+{
+ struct v3d_field_iterator iter;
+
+ v3d_field_iterator_init(&iter, group, p, color);
+ while (v3d_field_iterator_next(&iter)) {
+ fprintf(outfile, " %s: %s\n", iter.name, iter.value);
+ if (iter.struct_desc) {
+ uint64_t struct_offset = offset + iter.offset;
+ v3d_print_group(outfile, iter.struct_desc,
+ struct_offset,
+ &p[iter.offset], color);
+ }
+ }
+}
diff --git a/lib/mesa/src/broadcom/cle/v3d_decoder.h b/lib/mesa/src/broadcom/cle/v3d_decoder.h
new file mode 100644
index 000000000..541d877a9
--- /dev/null
+++ b/lib/mesa/src/broadcom/cle/v3d_decoder.h
@@ -0,0 +1,146 @@
+/*
+ * Copyright © 2016 Intel Corporation
+ * Copyright © 2017 Broadcom
+ *
+ * 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.
+ */
+
+#ifndef V3D_DECODER_H
+#define V3D_DECODER_H
+
+#include <stdint.h>
+#include <stdio.h>
+#include <stdbool.h>
+
+#include "broadcom/common/v3d_device_info.h"
+
+struct v3d_spec;
+struct v3d_group;
+struct v3d_field;
+
+struct v3d_group *v3d_spec_find_struct(struct v3d_spec *spec, const char *name);
+struct v3d_spec *v3d_spec_load(const struct v3d_device_info *devinfo);
+struct v3d_group *v3d_spec_find_instruction(struct v3d_spec *spec, const uint8_t *p);
+struct v3d_group *v3d_spec_find_register(struct v3d_spec *spec, uint32_t offset);
+struct v3d_group *v3d_spec_find_register_by_name(struct v3d_spec *spec, const char *name);
+int v3d_group_get_length(struct v3d_group *group);
+const char *v3d_group_get_name(struct v3d_group *group);
+uint8_t v3d_group_get_opcode(struct v3d_group *group);
+struct v3d_enum *v3d_spec_find_enum(struct v3d_spec *spec, const char *name);
+
+struct v3d_field_iterator {
+ struct v3d_group *group;
+ char name[128];
+ char value[128];
+ struct v3d_group *struct_desc;
+ const uint8_t *p;
+ int offset; /**< current field starts at &p[offset] */
+
+ int field_iter;
+ int group_iter;
+
+ struct v3d_field *field;
+ bool print_colors;
+};
+
+struct v3d_group {
+ struct v3d_spec *spec;
+ char *name;
+
+ struct v3d_field **fields;
+ uint32_t nfields;
+ uint32_t fields_size;
+
+ uint32_t group_offset, group_count;
+ uint32_t group_size;
+ bool variable;
+
+ struct v3d_group *parent;
+ struct v3d_group *next;
+
+ uint8_t opcode;
+
+ /* Register specific */
+ uint32_t register_offset;
+};
+
+struct v3d_value {
+ char *name;
+ uint64_t value;
+};
+
+struct v3d_enum {
+ char *name;
+ int nvalues;
+ struct v3d_value **values;
+};
+
+struct v3d_type {
+ enum {
+ V3D_TYPE_UNKNOWN,
+ V3D_TYPE_INT,
+ V3D_TYPE_UINT,
+ V3D_TYPE_BOOL,
+ V3D_TYPE_FLOAT,
+ V3D_TYPE_ADDRESS,
+ V3D_TYPE_OFFSET,
+ V3D_TYPE_STRUCT,
+ V3D_TYPE_UFIXED,
+ V3D_TYPE_SFIXED,
+ V3D_TYPE_MBO,
+ V3D_TYPE_ENUM
+ } kind;
+
+ /* Struct definition for V3D_TYPE_STRUCT */
+ union {
+ struct v3d_group *v3d_struct;
+ struct v3d_enum *v3d_enum;
+ struct {
+ /* Integer and fractional sizes for V3D_TYPE_UFIXED and
+ * V3D_TYPE_SFIXED
+ */
+ int i, f;
+ };
+ };
+};
+
+struct v3d_field {
+ char *name;
+ int start, end;
+ struct v3d_type type;
+ bool has_default;
+ uint32_t default_value;
+
+ struct v3d_enum inline_enum;
+};
+
+void v3d_field_iterator_init(struct v3d_field_iterator *iter,
+ struct v3d_group *group,
+ const uint8_t *p,
+ bool print_colors);
+
+bool v3d_field_iterator_next(struct v3d_field_iterator *iter);
+
+void v3d_print_group(FILE *out,
+ struct v3d_group *group,
+ uint64_t offset, const uint8_t *p,
+ bool color);
+
+#endif /* V3D_DECODER_H */
diff --git a/lib/mesa/src/broadcom/cle/v3d_packet_v33.xml b/lib/mesa/src/broadcom/cle/v3d_packet_v33.xml
new file mode 100644
index 000000000..e6562a262
--- /dev/null
+++ b/lib/mesa/src/broadcom/cle/v3d_packet_v33.xml
@@ -0,0 +1,910 @@
+<vcxml gen="3.3">
+
+ <enum name="Compare Function" prefix="V3D_COMPARE_FUNC">
+ <value name="NEVER" value="0"/>
+ <value name="LESS" value="1"/>
+ <value name="EQUAL" value="2"/>
+ <value name="LEQUAL" value="3"/>
+ <value name="GREATER" value="4"/>
+ <value name="NOTEQUAL" value="5"/>
+ <value name="GEQUAL" value="6"/>
+ <value name="ALWAYS" value="7"/>
+ </enum>
+
+ <enum name="Blend Factor" prefix="V3D_BLEND_FACTOR">
+ <value name="ZERO" value="0"/>
+ <value name="ONE" value="1"/>
+ <value name="SRC_COLOR" value="2"/>
+ <value name="INV_SRC_COLOR" value="3"/>
+ <value name="DST_COLOR" value="4"/>
+ <value name="INV_DST_COLOR" value="5"/>
+ <value name="SRC_ALPHA" value="6"/>
+ <value name="INV_SRC_ALPHA" value="7"/>
+ <value name="DST_ALPHA" value="8"/>
+ <value name="INV_DST_ALPHA" value="9"/>
+ <value name="CONST_COLOR" value="10"/>
+ <value name="INV_CONST_COLOR" value="11"/>
+ <value name="CONST_ALPHA" value="12"/>
+ <value name="INV_CONST_ALPHA" value="13"/>
+ <value name="SRC_ALPHA_SATURATE" value="14"/>
+ </enum>
+
+ <enum name="Blend Mode" prefix="V3D_BLEND_MODE">
+ <value name="ADD" value="0"/>
+ <value name="SUB" value="1"/>
+ <value name="RSUB" value="2"/>
+ <value name="MIN" value="3"/>
+ <value name="MAX" value="4"/>
+ <value name="MUL" value="5"/>
+ <value name="SCREEN" value="6"/>
+ <value name="DARKEN" value="7"/>
+ <value name="LIGHTEN" value="8"/>
+ </enum>
+
+ <enum name="Stencil Op" prefix="V3D_STENCIL_OP">
+ <value name="ZERO" value="0"/>
+ <value name="KEEP" value="1"/>
+ <value name="REPLACE" value="2"/>
+ <value name="INCR" value="3"/>
+ <value name="DECR" value="4"/>
+ <value name="INVERT" value="5"/>
+ <value name="INCWRAP" value="6"/>
+ <value name="DECWRAP" value="7"/>
+ </enum>
+
+ <enum name="Primitive" prefix="V3D_PRIM">
+ <value name="POINTS" value="0"/>
+ <value name="LINES" value="1"/>
+ <value name="LINE_LOOP" value="2"/>
+ <value name="LINE_STRIP" value="3"/>
+ <value name="TRIANGLES" value="4"/>
+ <value name="TRIANGLE_STRIP" value="5"/>
+ <value name="TRIANGLE_FAN" value="6"/>
+ <value name="POINTS_TF" value="16"/>
+ <value name="LINES_TF" value="17"/>
+ <value name="LINE_LOOP_TF" value="18"/>
+ <value name="LINE_STRIP_TF" value="19"/>
+ <value name="TRIANGLES_TF" value="20"/>
+ <value name="TRIANGLE_STRIP_TF" value="21"/>
+ <value name="TRIANGLE_FAN_TF" value="22"/>
+ </enum>
+
+ <packet code="0" name="Halt"/>
+ <packet code="1" name="NOP"/>
+ <packet code="4" name="Flush"/>
+ <packet code="5" name="Flush All State"/>
+ <packet code="6" name="Start Tile Binning"/>
+ <packet code="7" name="Increment Semaphore"/>
+ <packet code="8" name="Wait on Semaphore"/>
+ <packet code="9" name="Wait for previous frame"/>
+ <packet code="10" name="Enable Z-only rendering" cl="R"/>
+ <packet code="11" name="Disable Z-only rendering" cl="R"/>
+ <packet code="12" name="End of Z-only rendering in frame"/>
+ <packet code="13" name="End of rendering"/>
+
+ <packet code="14" name="Wait for transform feedback" cl="B">
+ <field name="Block count" size="8" start="0" type="uint"/>
+ </packet>
+
+ <packet code="15" name="Branch to auto-chained sub-list">
+ <field name="address" size="32" start="0" type="address"/>
+ </packet>
+
+ <packet code="16" name="Branch">
+ <field name="address" size="32" start="0" type="address"/>
+ </packet>
+
+ <packet code="17" name="Branch to Sub-list">
+ <field name="address" size="32" start="0" type="address"/>
+ </packet>
+
+ <packet code="18" name="Return from sub-list"/>
+ <packet code="19" name="Flush VCD cache"/>
+
+ <packet code="20" name="Start Address of Generic Tile List">
+ <field name="start" size="32" start="0" type="address"/>
+ <field name="end" size="32" start="32" type="address"/>
+ </packet>
+
+ <packet code="21" name="Branch to Implicit Tile List">
+ <field name="tile list set number" size="8" start="0" type="uint"/>
+ </packet>
+
+ <packet code="22" name="Branch to Explicit Supertile">
+ <field name="Absolute address of explicit supertile render list" size="32" start="24" type="address"/>
+ <field name="explicit supertile number" size="8" start="16" type="uint"/>
+ <field name="row number" size="8" start="8" type="uint"/>
+ <field name="column number" size="8" start="0" type="uint"/>
+ </packet>
+
+ <packet code="23" name="Supertile Coordinates">
+ <field name="row number in supertiles" size="8" start="8" type="uint"/>
+ <field name="column number in supertiles" size="8" start="0" type="uint"/>
+ </packet>
+
+ <packet code="24" name="Store Multi-Sample Resolved Tile Color Buffer" cl="R"/>
+
+ <packet code="25" name="Store Multi-Sample Resolved Tile Color Buffer (extended)" cl="R">
+ <field name="Disable Color Buffer write" size="8" start="8" type="uint"/>
+ <field name="Enable Z write" size="1" start="7" type="bool"/>
+ <field name="Enable Stencil write" size="1" start="6" type="bool"/>
+ <!-- bit 5 unused -->
+ <field name="Disable Colour buffer(s) clear on write" size="1" start="4" type="bool"/>
+ <field name="Disable Stencil buffer clear on write" size="1" start="3" type="bool"/>
+ <field name="Disable Z buffer clear on write" size="1" start="2" type="bool"/>
+ <field name="Disable fast opportunistic write out in multisample mode" size="1" start="1" type="bool"/>
+ <field name="Last Tile of Frame" size="1" start="0" type="bool"/>
+ </packet>
+
+ <packet code="26" name="Reload Tile Colour Buffer" cl="R">
+ <field name="Disable Colour Buffer load" size="8" start="8" type="uint"/>
+ <field name="Enable Z load" size="1" start="7" type="bool"/>
+ <field name="Enable Stencil load" size="1" start="6" type="bool"/>
+ </packet>
+
+ <packet code="27" name="End of Tile Marker" cl="R"/>
+
+ <packet code="29" name="Store Tile Buffer General" cl="R">
+ <field name="Address" size="32" start="16" type="address"/>
+ <field name="Padded height of output image in UIF blocks" size="13" start="11" type="uint"/>
+ <field name="XOR UIF" size="1" start="10" type="bool"/>
+ <field name="Last Tile of Frame" size="1" start="8" type="bool"/>
+ <field name="Disable Colour buffer(s) clear on write" size="1" start="7" type="bool"/>
+ <field name="Disable Stencil buffer clear on write" size="1" start="6" type="bool"/>
+ <field name="Disable Z buffer clear on write" size="1" start="5" type="bool"/>
+ <field name="Raw Mode" size="1" start="4" type="bool"/>
+ <field name="Buffer to Store" size="4" start="0" type="uint">
+ <value name="Render target 0" value="0"/>
+ <value name="Render target 1" value="1"/>
+ <value name="Render target 2" value="2"/>
+ <value name="Render target 3" value="3"/>
+ <value name="None" value="8"/>
+ <value name="Z" value="9"/>
+ <value name="Stencil" value="10"/>
+ <value name="Z+Stencil" value="11"/>
+ </field>
+ </packet>
+
+ <packet code="30" name="Load Tile Buffer General" cl="R">
+ <field name="Address" size="24" start="24" type="address"/>
+ <field name="Padded height of output image in UIF blocks" size="13" start="11" type="uint"/>
+ <field name="XOR UIF" size="1" start="10" type="bool"/>
+ <field name="Raw Mode" size="1" start="4" type="bool"/>
+ <field name="Buffer to Load" size="4" start="0" type="uint">
+ <value name="Render target 0" value="0"/>
+ <value name="Render target 1" value="1"/>
+ <value name="Render target 2" value="2"/>
+ <value name="Render target 3" value="3"/>
+ <value name="None" value="8"/>
+ <value name="Z" value="9"/>
+ <value name="Stencil" value="10"/>
+ <value name="Z+Stencil" value="11"/>
+ </field>
+ </packet>
+
+ <packet code="32" name="Indexed Primitive List" cl="B">
+ <field name="Minimum index" size="32" start="104" type="uint"/>
+ <field name="Enable Primitive Restarts" size="1" start="103" type="bool"/>
+ <field name="Maximum index" size="31" start="72" type="uint"/>
+ <field name="Address of Indices List" size="32" start="40" type="address"/>
+ <field name="Length" size="32" start="8" type="uint"/>
+
+ <field name="Index type" size="2" start="6" type="uint">
+ <value name="Index type 8-bit" value="0"/>
+ <value name="Index type 16-bit" value="1"/>
+ <value name="Index type 32-bit" value="2"/>
+ </field>
+
+ <field name="mode" size="5" start="0" type="uint">
+ </field>
+ </packet>
+
+ <packet code="34" name="Indexed Instanced Primitive List" cl="B">
+ <field name="Enable Primitive Restarts" size="1" start="135" type="bool"/>
+ <field name="Maximum index" size="31" start="104" type="uint"/>
+ <field name="Address of Indices List" size="32" start="72" type="address"/>
+ <field name="Number of Instances" size="32" start="40" type="uint"/>
+ <field name="Instance Length" size="32" start="8" type="uint"/>
+
+ <field name="Index type" size="2" start="6" type="uint">
+ <value name="Index type 8-bit" value="0"/>
+ <value name="Index type 16-bit" value="1"/>
+ <value name="Index type 32-bit" value="2"/>
+ </field>
+
+ <field name="mode" size="5" start="0" type="Primitive"/>
+ </packet>
+
+ <packet code="36" name="Vertex Array Primitives" cl="B">
+ <field name="Index of First Vertex" size="32" start="40" type="uint"/>
+ <field name="Length" size="32" start="8" type="uint"/>
+
+ <field name="mode" size="8" start="0" type="Primitive"/>
+ </packet>
+
+ <packet code="38" name="Vertex Array Instanced Primitives" cl="B">
+ <field name="Index of First Vertex" size="32" start="72" type="uint"/>
+ <field name="Number of Instances" size="32" start="40" type="uint"/>
+ <field name="Instance Length" size="32" start="8" type="uint"/>
+
+ <field name="mode" size="8" start="0" type="Primitive"/>
+ </packet>
+
+ <packet code="43" name="Base Vertex Base Instance" cl="B">
+ <field name="Base Instance" size="32" start="32" type="uint"/>
+
+ <field name="Base Vertex" size="32" start="0" type="uint"/>
+ </packet>
+
+ <packet code="56" name="Primitive List Format">
+ <field name="data type" size="1" start="6" type="uint">
+ <value name="List Indexed" value="0"/>
+ <value name="List 32-bit X/Y" value="1"/>
+ </field>
+ <field name="primitive type" size="6" start="0" type="uint">
+ <value name="List Points" value="0"/>
+ <value name="List Lines" value="1"/>
+ <value name="List Triangles" value="2"/>
+ </field>
+ </packet>
+
+ <packet code="64" name="GL Shader State">
+ <field name="address" size="27" start="5" type="address"/>
+ <field name="number of attribute arrays" size="5" start="0" type="uint"/>
+ </packet>
+
+ <packet code="74" name="Transform Feedback Enable">
+ <field name="number of 32-bit Output Buffer Address following" size="3" start="8" type="uint"/>
+ <field name="number of 16-bit Output Data Specs following" size="5" start="11" type="uint"/>
+ </packet>
+
+ <packet code="75" name="Flush Transform Feedback Data"/>
+
+ <struct name="Transform Feedback Output Data Spec">
+ <field name="First Shaded Vertex Value to output" size="8" start="0" type="uint"/>
+ <field name="Number of consecutive Vertex Values to output as 32-bit values minus 1" size="4" start="8" type="uint"/>
+ <field name="Output Buffer to write to" size="2" start="12" type="uint"/>
+ </struct>
+
+ <struct name="Transform Feedback Output Address">
+ <field name="address" size="32" start="0" type="address"/>
+ </struct>
+
+ <packet code="80" name="Stencil Config">
+ <field name="Stencil Write Mask" size="8" start="32" type="uint"/>
+ <field name="Back Config" size="1" start="29" type="bool"/>
+ <field name="Front Config" size="1" start="28" type="bool"/>
+ <field name="Stencil Pass Op" size="3" start="25" type="Stencil Op"/>
+ <field name="Depth Test Fail Op" size="3" start="22" type="Stencil Op"/>
+ <field name="Stencil Test Fail Op" size="3" start="19" type="Stencil Op"/>
+ <field name="Stencil Test Function" size="3" start="16" type="Compare Function"/>
+ <field name="Stencil Test Mask" size="8" start="8" type="uint"/>
+ <field name="Stencil Ref Value" size="8" start="0" type="uint"/>
+ </packet>
+
+ <packet code="84" name="Blend Config">
+ <field name="VG Coverage Modes" size="2" start="28" type="uint"/>
+ <field name="Colour blend dst factor" size="4" start="20" type="Blend Factor"/>
+ <field name="Colour blend src factor" size="4" start="16" type="Blend Factor"/>
+ <field name="Colour blend mode" size="4" start="12" type="Blend Mode"/>
+ <field name="Alpha blend dst factor" size="4" start="8" type="Blend Factor"/>
+ <field name="Alpha blend src factor" size="4" start="4" type="Blend Factor"/>
+ <field name="Alpha blend mode" size="4" start="0" type="Blend Mode"/>
+ </packet>
+
+ <packet code="86" name="Blend Constant Colour">
+ <field name="Alpha (F16)" size="16" start="48" type="uint"/>
+ <field name="Blue (F16)" size="16" start="32" type="uint"/>
+ <field name="Green (F16)" size="16" start="16" type="uint"/>
+ <field name="Red (F16)" size="16" start="0" type="uint"/>
+ </packet>
+
+ <packet code="87" name="Colour Write Masks">
+ <field name="Reserved" size="16" start="16" type="uint"/>
+ <field name="Render Target 3 per colour component write masks" size="4" start="12" type="uint"/>
+ <field name="Render Target 2 per colour component write masks" size="4" start="8" type="uint"/>
+ <field name="Render Target 1 per colour component write masks" size="4" start="4" type="uint"/>
+ <field name="Render Target 0 per colour component write masks" size="4" start="0" type="uint"/>
+ </packet>
+
+ <packet code="96" name="Configuration Bits">
+ <field name="Direct3D Provoking Vertex" size="1" start="21" type="bool"/>
+ <field name="Direct3D 'Point-fill' mode" size="1" start="20" type="bool"/>
+ <field name="Blend enable" size="1" start="19" type="bool"/>
+ <field name="Stencil enable" size="1" start="18" type="bool"/>
+ <field name="Early Z updates enable" size="1" start="17" type="bool"/>
+ <field name="Early Z enable" size="1" start="16" type="bool"/>
+ <field name="Z updates enable" size="1" start="15" type="bool"/>
+ <field name="Depth-Test Function" size="3" start="12" type="Compare Function"/>
+ <field name="Direct3D Wireframe triangles mode" size="1" start="11" type="bool"/>
+ <field name="Coverage Update Mode" size="2" start="9" type="uint"/>
+ <field name="Coverage Pipe Select" size="1" start="8" type="bool"/>
+ <field name="Rasterizer Oversample Mode" size="2" start="6" type="uint"/>
+ <field name="Line Rasterization" size="2" start="4" type="uint"/>
+ <field name="Enable Depth Offset" size="1" start="3" type="bool"/>
+ <field name="Clockwise Primitives" size="1" start="2" type="bool"/>
+ <field name="Enable Reverse Facing Primitive" size="1" start="1" type="bool"/>
+ <field name="Enable Forward Facing Primitive" size="1" start="0" type="bool"/>
+ </packet>
+
+ <packet code="97" name="Zero All Flat Shade Flags"/>
+
+ <packet code="98" name="Flat Shade Flags">
+ <field name="Flat Shade Flags for varyings V0*24" size="24" start="8" type="uint"/>
+ <field name="Action for Flat Shade Flags of higher numbered varyings" size="2" start="6" type="uint"/>
+ <field name="Action for Flat Shade Flags of lower numbered varyings" size="2" start="4" type="uint"/>
+ <field name="Varying offset V0" size="4" start="0" type="uint"/>
+ </packet>
+
+ <packet code="104" name="Point size">
+ <field name="Point Size" size="32" start="0" type="float"/>
+ </packet>
+
+ <packet code="105" name="Line width">
+ <field name="Line width" size="32" start="0" type="float"/>
+ </packet>
+
+ <packet name="Depth Offset" code="106">
+ <!-- these fields are both float-1-8-7 encoded (top 16 bits of a float32) -->
+ <field name="Depth Offset Units" size="16" start="16" type="uint"/>
+ <field name="Depth Offset Factor" size="16" start="0" type="uint"/>
+ </packet>
+
+ <packet name="Clip Window" code="107">
+ <field name="Clip Window Height in pixels" size="16" start="48" type="uint"/>
+ <field name="Clip Window Width in pixels" size="16" start="32" type="uint"/>
+ <field name="Clip Window Bottom Pixel Coordinate" size="16" start="16" type="uint"/>
+ <field name="Clip Window Left Pixel Coordinate" size="16" start="0" type="uint"/>
+ </packet>
+
+ <packet name="Viewport Offset" code="108">
+ <field name="Viewport Centre Y-coordinate" size="32" start="32" type="s24.8"/>
+ <field name="Viewport Centre X-coordinate" size="32" start="0" type="s24.8"/>
+ </packet>
+
+ <packet name="Clipper Z min/max clipping planes" code="109">
+ <field name="Maximum Zw" size="32" start="32" type="float"/>
+ <field name="Minimum Zw" size="32" start="0" type="float"/>
+ </packet>
+
+ <packet name="Clipper XY Scaling" code="110" cl="B">
+ <field name="Viewport Half-Height in 1/256th of pixel" size="32" start="32" type="float"/>
+ <field name="Viewport Half-Width in 1/256th of pixel" size="32" start="0" type="float"/>
+ </packet>
+
+ <packet name="Clipper Z Scale and Offset" code="111" cl="B">
+ <field name="Viewport Z Offset (Zc to Zs)" size="32" start="32" type="float"/>
+ <field name="Viewport Z Scale (Zc to Zs)" size="32" start="0" type="float"/>
+ </packet>
+
+ <packet code="120" name="Tile Binning Mode Configuration (Part1)">
+ <field name="Double-buffer in non-ms mode" size="1" start="63" type="bool"/>
+ <field name="Multisample Mode (4x)" size="1" start="62" type="bool"/>
+
+ <field name="Maximum BPP of all render targets" size="2" start="60" type="uint">
+ <value name="Render target maximum 32bpp" value="0"/>
+ <value name="Render target maximum 64bpp" value="1"/>
+ <value name="Render target maximum 128bpp" value="2"/>
+ </field>
+
+ <field name="Number of Render Targets" size="4" start="56" type="uint"/>
+ <field name="Height (in tiles)" size="12" start="44" type="uint"/>
+ <field name="Width (in tiles)" size="12" start="32" type="uint"/>
+
+ <field name="Tile State Data Array Base Address" size="32" start="0" type="address"/>
+
+ <field name="tile allocation block size" size="2" start="4" type="uint">
+ <value name="tile allocation block size 64b" value="0"/>
+ <value name="tile allocation block size 128b" value="1"/>
+ <value name="tile allocation block size 256b" value="2"/>
+ </field>
+ <field name="tile allocation initial block size" size="2" start="2" type="uint">
+ <value name="tile allocation initial block size 64b" value="0"/>
+ <value name="tile allocation initial block size 128b" value="1"/>
+ <value name="tile allocation initial block size 256b" value="2"/>
+ </field>
+ <field name="auto-initialize tile state data array" size="1" start="1" type="bool" default="1"/>
+ <field name="sub-id" size="1" start="0" type="uint" default="0"/>
+ </packet>
+
+ <packet code="120" name="Tile Binning Mode Configuration (Part2)" cl="B">
+ <field name="Tile Allocation Memory Address" size="32" start="32" type="address"/>
+ <field name="Tile Allocation Memory Size" size="32" start="0" type="uint"/>
+
+ <field name="sub-id" size="1" start="0" type="uint" default="1"/>
+ </packet>
+
+ <packet code="121" name="Tile Rendering Mode Configuration (Common Configuration)" cl="R">
+ <field name="Disable Render Target Stores" size="8" start="56" type="uint"/>
+ <field name="Enable Z Store" size="1" start="55" type="bool"/>
+ <field name="Enable Stencil Store" size="1" start="54" type="bool"/>
+
+ <field name="Early-Z disable" size="1" start="46" type="bool"/>
+
+ <field name="Early-Z Test and Update Direction" size="1" start="45" type="uint">
+ <value name="Early-Z direction LT/LE" value="0"/>
+ <value name="Early-Z direction GT/GE" value="1"/>
+ </field>
+
+ <field name="Select Coverage Mode" size="1" start="44" type="bool"/>
+ <field name="Double-buffer in non-ms mode" size="1" start="43" type="bool"/>
+ <field name="Multisample Mode (4x)" size="1" start="42" type="bool"/>
+
+ <field name="Maximum BPP of all render targets" size="2" start="40" type="uint">
+ <value name="Render target maximum 32bpp" value="0"/>
+ <value name="Render target maximum 64bpp" value="1"/>
+ <value name="Render target maximum 128bpp" value="2"/>
+ </field>
+
+ <field name="Image Height (pixels)" size="16" start="24" type="uint"/>
+ <field name="Image Width (pixels)" size="16" start="8" type="uint"/>
+ <field name="Number of Render Targets Minus 1" size="4" start="4" type="uint"/>
+
+ <field name="sub-id" size="4" start="0" type="uint" default="0"/>
+ </packet>
+
+ <packet code="121" name="Tile Rendering Mode Configuration (Render Target config)" cl="R">
+ <field name="Address" size="32" start="32" type="address"/>
+
+ <field name="Pad" size="4" start="28" type="uint"/>
+
+ <field name="Flip Y" size="1" start="27" type="bool"/>
+
+ <field name="Memory Format" size="3" start="24" type="uint" prefix="Memory Format">
+ <value name="Raster" value="0"/>
+ <value name="Lineartile" value="1"/>
+ <value name="UB-linear (1 UIF block wide)" value="2"/>
+ <value name="UB-linear (2 UIF blocks wide)" value="3"/>
+ <value name="UIF (No XOR)" value="4"/>
+ <value name="UIF (XOR)" value="5"/>
+ </field>
+
+ <field name="A dithered" size="1" start="23" type="bool"/>
+ <field name="BGR dithered" size="1" start="22" type="bool"/>
+
+ <field name="Output image format" size="6" start="16" type="uint" prefix="Output Image Format">
+ <value name="srgb8_alpha8" value="0"/>
+ <value name="srgb" value="1"/>
+ <value name="rgb10_a2ui" value="2"/>
+ <value name="rgb10_a2" value="3"/>
+ <value name="abgr1555" value="4"/>
+ <value name="alpha-masked abgr1555" value="5"/>
+ <value name="abgr4444" value="6"/>
+ <value name="bgr565" value="7"/>
+ <value name="r11f_g11f_b10f" value="8"/>
+ <value name="rgba32f" value="9"/>
+ <value name="rg32f" value="10"/>
+ <value name="r32f" value="11"/>
+ <value name="rgba32i" value="12"/>
+ <value name="rg32i" value="13"/>
+ <value name="r32i" value="14"/>
+ <value name="rgba32ui" value="15"/>
+ <value name="rg32ui" value="16"/>
+ <value name="r32ui" value="17"/>
+ <value name="rgba16f" value="18"/>
+ <value name="rg16f" value="19"/>
+ <value name="r16f" value="20"/>
+ <value name="rgba16i" value="21"/>
+ <value name="rg16i" value="22"/>
+ <value name="r16i" value="23"/>
+ <value name="rgba16ui" value="24"/>
+ <value name="rg16ui" value="25"/>
+ <value name="r16ui" value="26"/>
+ <value name="rgba8" value="27"/>
+ <value name="rgb8" value="28"/>
+ <value name="rg8" value="29"/>
+ <value name="r8" value="30"/>
+ <value name="rgba8i" value="31"/>
+ <value name="rg8i" value="32"/>
+ <value name="r8i" value="33"/>
+ <value name="rgba8ui" value="34"/>
+ <value name="rg8ui" value="35"/>
+ <value name="r8ui" value="36"/>
+ <value name="srgbx8" value="37"/>
+ <value name="rgbx8" value="38"/>
+ </field>
+
+ <field name="Decimate mode" size="2" start="14" type="uint"/>
+
+ <field name="Internal Type" size="4" start="10" type="uint" prefix="Internal Type">
+ <value name="8i" value="0"/>
+ <value name="8ui" value="1"/>
+ <value name="8" value="2"/>
+ <value name="16i" value="4"/>
+ <value name="16ui" value="5"/>
+ <value name="16f" value="6"/>
+ <value name="32i" value="8"/>
+ <value name="32ui" value="9"/>
+ <value name="32f" value="10"/>
+ </field>
+
+ <field name="Internal BPP" size="2" start="8" type="uint" prefix="Internal Bpp">
+ <value name="32" value="0"/>
+ <value name="64" value="1"/>
+ <value name="128" value="2"/>
+ </field>
+ <field name="Render Target Number" size="4" start="4" type="uint"/>
+ <field name="sub-id" size="4" start="0" type="uint" default="2"/>
+ </packet>
+
+ <packet code="121" name="Tile Rendering Mode Configuration (Z/Stencil config)" cl="R">
+ <field name="Address" size="32" start="32" type="address"/>
+
+ <field name="Padded height of output image in UIF blocks" size="13" start="25" type="uint"/>
+
+ <field name="Memory Format" size="3" start="22" type="uint" prefix="Memory Format">
+ <value name="Raster" value="0"/>
+ <value name="Lineartile" value="1"/>
+ <value name="UB-linear (1 UIF block wide)" value="2"/>
+ <value name="UB-linear (2 UIF blocks wide)" value="3"/>
+ <value name="UIF (No XOR)" value="4"/>
+ <value name="UIF (XOR)" value="5"/>
+ </field>
+
+ <field name="Output image format" size="6" start="16" type="uint" prefix="Output Image Format">
+ <value name="depth_component32f" value="0"/>
+ <value name="depth_component24" value="1"/>
+ <value name="depth_component16" value="2"/>
+ <value name="depth24_stencil8" value="3"/>
+ </field>
+
+ <field name="Decimate mode" size="2" start="14" type="uint"/>
+
+ <field name="Internal Type" size="4" start="10" type="uint" prefix="Internal Type">
+ <value name="depth_32f" value="0"/>
+ <value name="depth_24" value="1"/>
+ <value name="depth_16" value="2"/>
+ </field>
+
+ <field name="Internal BPP (ignored)" size="2" start="8" type="uint"/>
+ <!-- selects between Z/Stencil config packet and Separate Stencil packet. -->
+ <field name="Z/Stencil ID" size="4" start="4" type="uint" default="0"/>
+ <field name="sub-id" size="4" start="0" type="uint" default="1"/>
+ </packet>
+
+ <packet code="121" name="Tile Rendering Mode Configuration (Z Stencil Clear Values)" cl="R">
+ <field name="unused" size="16" start="48" type="uint"/>
+
+ <field name="Z Clear Value" size="32" start="16" type="float"/>
+
+ <field name="Stencil/VG Mask Clear Value" size="8" start="8" type="uint"/>
+ <field name="sub-id" size="4" start="0" type="uint" default="3"/>
+ </packet>
+
+ <packet code="121" name="Tile Rendering Mode Configuration (Clear Colors Part1)" cl="R">
+ <!-- Express this as a 56-bit field? -->
+ <field name="Clear Color next 24 bits" size="24" start="40" type="uint"/>
+ <field name="Clear Color low 32 bits" size="32" start="8" type="uint"/>
+
+ <field name="Render Target number" size="4" start="4" type="uint"/>
+ <field name="sub-id" size="4" start="0" type="uint" default="4"/>
+ </packet>
+
+ <packet code="121" name="Tile Rendering Mode Configuration (Clear Colors Part2)" cl="R">
+ <!-- Express this as a 56-bit field? -->
+ <field name="Clear Color mid-high 24 bits" size="24" start="40" type="uint"/>
+ <field name="Clear Color mid-low 32 bits" size="32" start="8" type="uint"/>
+
+ <field name="Render Target number" size="4" start="4" type="uint"/>
+ <field name="sub-id" size="4" start="0" type="uint" default="5"/>
+ </packet>
+
+ <packet code="121" name="Tile Rendering Mode Configuration (Clear Colors Part3)" cl="R">
+ <field name="pad" size="11" start="53" type="uint"/>
+ <field name="UIF padded height in UIF blocks" size="13" start="40" type="uint"/>
+ <!-- image height is for Y flipping -->
+ <field name="Raster Row Stride or Image Height in Pixels" size="16" start="24" type="uint"/>
+ <field name="Clear Color high 16 bits" size="16" start="8" type="uint"/>
+
+ <field name="Render Target number" size="4" start="4" type="uint"/>
+ <field name="sub-id" size="4" start="0" type="uint" default="6"/>
+ </packet>
+
+ <packet code="124" name="Tile Coordinates">
+ <field name="tile row number" size="12" start="12" type="uint"/>
+ <field name="tile column number" size="12" start="0" type="uint"/>
+ </packet>
+
+ <packet code="122" name="Multicore Rendering Supertile Configuration" cl="R">
+ <field name="Supertile Raster Order" size="1" start="60" type="bool"/>
+ <field name="Multicore Enable" size="1" start="56" type="bool"/>
+
+ <field name="Total Frame Height in Tiles" size="12" start="44" type="uint"/>
+ <field name="Total Frame Width in Tiles" size="12" start="32" type="uint"/>
+
+ <field name="Total Frame Height in Supertiles" size="8" start="24" type="uint"/>
+ <field name="Total Frame Width in Supertiles" size="8" start="16" type="uint"/>
+
+ <field name="Supertile Height in Tiles minus 1" size="8" start="8" type="uint"/>
+ <field name="Supertile Width in Tiles minus 1" size="8" start="0" type="uint"/>
+ </packet>
+
+ <packet code="123" name="Multicore Rendering Tile List Set Base" cl="R">
+ <field name="address" size="26" start="6" type="address"/>
+ <field name="Tile List Set Number" size="4" start="0" type="uint"/>
+ </packet>
+
+ <!-- add fields -->
+ <packet code="125" name="Tile Coordinates Implicit"/>
+
+ <packet code="126" name="Tile List Initial Block Size">
+ <field name="Use auto-chained tile lists" size="1" start="2" type="bool"/>
+
+ <field name="Size of first block in chained tile lists" size="2" start="0" type="uint">
+ <value name="tile allocation block size 64b" value="0"/>
+ <value name="tile allocation block size 128b" value="1"/>
+ <value name="tile allocation block size 256b" value="2"/>
+ </field>
+ </packet>
+
+ <struct name="GL Shader State Record">
+ <field name="Point size in shaded vertex data" size="1" start="0" type="bool"/>
+ <field name="Enable clipping" size="1" start="1" type="bool"/>
+ <field name="Vertex ID read by coordinate shader" size="1" start="2" type="bool"/>
+ <field name="Instance ID read by coordinate shader" size="1" start="3" type="bool"/>
+ <field name="Vertex ID read by vertex shader" size="1" start="4" type="bool"/>
+ <field name="Instance ID read by vertex shader" size="1" start="5" type="bool"/>
+ <field name="Fragment shader does Z writes" size="1" start="6" type="bool"/>
+ <field name="Turn off early-z test" size="1" start="7" type="bool"/>
+ <field name="Coordinate shader has separate input and output VPM blocks" size="1" start="8" type="bool"/>
+ <field name="Vertex shader has separate input and output VPM blocks" size="1" start="9" type="bool"/>
+ <field name="Fragment shader uses real pixel centre W in addition to centroid W2" size="1" start="10" type="bool"/>
+
+ <field name="Number of varyings in Fragment Shader" size="8" start="2b" type="uint"/>
+ <field name="Coordinate Shader output VPM segment size" size="8" start="4b" type="uint"/>
+ <field name="Coordinate Shader input VPM segment size" size="8" start="5b" type="uint"/>
+ <field name="Vertex Shader output VPM segment size" size="8" start="6b" type="uint"/>
+ <field name="Vertex Shader input VPM segment size" size="8" start="7b" type="uint"/>
+ <field name="Address of default attribute values" size="32" start="8b" type="address"/>
+ <field name="Fragment Shader Code Address" size="29" start="99" type="address"/>
+ <field name="2-way threadable" size="1" start="96" type="bool"/>
+ <field name="4-way threadable" size="1" start="97" type="bool"/>
+ <field name="Propagate NaNs" size="1" start="98" type="bool"/>
+ <field name="Fragment Shader Uniforms Address" size="32" start="16b" type="address"/>
+ <field name="Vertex Shader Code Address" size="32" start="20b" type="address"/>
+ <field name="Vertex Shader Uniforms Address" size="32" start="24b" type="address"/>
+ <field name="Coordinate Shader Code Address" size="32" start="28b" type="address"/>
+ <field name="Coordinate Shader Uniforms Address" size="32" start="32b" type="address"/>
+ </struct>
+
+ <struct name="GL Shader State Attribute Record">
+ <field name="Address" size="32" start="0" type="address"/>
+
+ <field name="Vec size" size="2" start="32" type="uint"/>
+ <field name="Type" size="3" start="34" type="uint">
+ <value name="Attribute half-float" value="1"/>
+ <value name="Attribute float" value="2"/>
+ <value name="Attribute fixed" value="3"/>
+ <value name="Attribute byte" value="4"/>
+ <value name="Attribute short" value="5"/>
+ <value name="Attribute int" value="6"/>
+ <value name="Attribute int2_10_10_10" value="7"/>
+ </field>
+ <field name="Signed int type" size="1" start="37" type="bool"/>
+ <field name="Normalized int type" size="1" start="38" type="bool"/>
+ <field name="Read as int/uint" size="1" start="39" type="bool"/>
+
+ <field name="Number of values read by Coordinate shader" size="4" start="40" type="uint"/>
+ <field name="Number of values read by Vertex shader" size="4" start="44" type="uint"/>
+
+ <field name="Instance Divisor" size="16" start="6b" type="uint"/>
+ <field name="Stride" size="32" start="8b" type="uint"/>
+ </struct>
+
+ <struct name="VPM generic block write setup">
+ <field name="id" size="2" start="30" type="uint" default="0"/>
+ <field name="id0" size="3" start="27" type="uint" default="0"/>
+
+ <field name="horiz" size="1" start="24" type="bool"/>
+ <field name="laned" size="1" start="23" type="bool"/>
+ <field name="segs" size="1" start="22" type="bool"/>
+ <field name="stride" size="7" start="15" type="int"/>
+
+ <field name="size" size="2" start="13" type="uint">
+ <value name="VPM setup size 8-bit" value="0"/>
+ <value name="VPM setup size 16-bit" value="1"/>
+ <value name="VPM setup size 32-bit" value="2"/>
+ </field>
+
+ <field name="addr" size="13" start="0" type="uint"/>
+ </struct>
+
+ <struct name="VPM generic block read setup">
+ <field name="id" size="2" start="30" type="uint" default="1"/>
+
+ <field name="horiz" size="1" start="29" type="bool"/>
+ <field name="laned" size="1" start="28" type="bool"/>
+ <field name="segs" size="1" start="27" type="bool"/>
+ <field name="num" size="5" start="22" type="uint"/>
+ <field name="stride" size="7" start="15" type="int"/>
+
+ <field name="size" size="2" start="13" type="uint">
+ <value name="VPM setup size 8-bit" value="0"/>
+ <value name="VPM setup size 16-bit" value="1"/>
+ <value name="VPM setup size 32-bit" value="2"/>
+ </field>
+
+ <field name="addr" size="13" start="0" type="uint"/>
+ </struct>
+
+ <struct name="Texture Uniform Parameter 0 CFG_MODE=1">
+ <field name="Per-pixel mask enable" size="1" start="31" type="bool"/>
+
+ <field name="Texel offset for r coordinate" size="4" start="27" type="int"/>
+ <field name="Texel offset for t coordinate" size="4" start="23" type="int"/>
+ <field name="Texel offset for s coordinate" size="4" start="19" type="int"/>
+
+ <field name="R Wrap Mode" size="3" start="16" type="uint">
+ <value name="Wrap mode REPEAT" value="0"/>
+ <value name="Wrap mode CLAMP" value="1"/>
+ <value name="Wrap mode MIRROR" value="2"/>
+ <value name="Wrap mode BORDER" value="3"/>
+ <value name="Wrap mode MIRROR_ONCE" value="4"/>
+ </field>
+
+ <field name="T Wrap Mode" size="3" start="13" type="uint">
+ <value name="Wrap mode REPEAT" value="0"/>
+ <value name="Wrap mode CLAMP" value="1"/>
+ <value name="Wrap mode MIRROR" value="2"/>
+ <value name="Wrap mode BORDER" value="3"/>
+ <value name="Wrap mode MIRROR_ONCE" value="4"/>
+ </field>
+
+ <field name="S Wrap Mode" size="3" start="10" type="uint">
+ <value name="Wrap mode REPEAT" value="0"/>
+ <value name="Wrap mode CLAMP" value="1"/>
+ <value name="Wrap mode MIRROR" value="2"/>
+ <value name="Wrap mode BORDER" value="3"/>
+ <value name="Wrap mode MIRROR_ONCE" value="4"/>
+ </field>
+
+ <field name="New configuration mode" size="1" start="9" type="bool" default="1"/>
+
+ <field name="Shadow" size="1" start="8" type="bool"/>
+ <field name="Coefficient lookup mode" size="1" start="7" type="bool"/>
+ <field name="Disable AutoLOD, use bias only" size="1" start="6" type="bool"/>
+ <field name="Bias supplied" size="1" start="5" type="bool"/>
+ <field name="Gather sample mode" size="1" start="4" type="bool"/>
+ <field name="Fetch sample mode" size="1" start="3" type="bool"/>
+
+ <field name="Lookup Type" size="3" start="0" type="bool">
+ <value name="Texture 2D" value="0"/>
+ <value name="Texture 2D array" value="1"/>
+ <value name="Texture 3D" value="2"/>
+ <value name="Texture Cube Map" value="3"/>
+ <value name="Texture 1D" value="4"/>
+ <value name="Texture 1D Array" value="5"/>
+ <value name="Texture Child Image" value="6"/>
+ </field>
+ </struct>
+
+ <struct name="Texture Uniform Parameter 1 CFG_MODE=1">
+ <field name="Texture state record base address" size="32" start="0" type="address"/>
+ <field name="Return word 3 of texture data" size="1" start="3" type="bool"/>
+ <field name="Return word 2 of texture data" size="1" start="2" type="bool"/>
+ <field name="Return word 1 of texture data" size="1" start="1" type="bool"/>
+ <field name="Return word 0 of texture data" size="1" start="0" type="bool"/>
+ </struct>
+
+ <struct name="Texture Shader State">
+ <field name="Level 0 is strictly UIF" size="1" start="254" type="bool"/>
+ <field name="Level 0 XOR enable" size="1" start="252" type="bool"/>
+ <field name="Level 0 UB_PAD" size="4" start="248" type="uint"/>
+
+ <field name="Base Level" size="4" start="240" type="uint"/>
+ <field name="Fixed Bias" size="16" start="224" type="s8.8"/>
+ <field name="Max Level-of-Detail" size="16" start="208" type="s8.8"/>
+ <field name="Min Level-of-Detail" size="16" start="192" type="s8.8"/>
+
+ <field name="Border Color alpha" size="16" start="176" type="uint"/>
+ <field name="Border Color blue" size="16" start="160" type="uint"/>
+ <field name="Border Color green" size="16" start="144" type="uint"/>
+ <field name="Border Color red" size="16" start="128" type="uint"/>
+
+ <field name="Flip S and T on incoming request" size="1" start="127" type="bool"/>
+ <field name="Flip ETC Y" size="1" start="126" type="bool" default="1"/>
+ <field name="Flip texture Y Axis" size="1" start="125" type="bool"/>
+ <field name="Flip texture X Axis" size="1" start="124" type="bool"/>
+
+ <field name="Swizzle A" size="3" start="121" type="uint">
+ <value name="Swizzle Zero" value="0"/>
+ <value name="Swizzle One" value="1"/>
+ <value name="Swizzle Red" value="2"/>
+ <value name="Swizzle Green" value="3"/>
+ <value name="Swizzle Blue" value="4"/>
+ <value name="Swizzle Alpha" value="5"/>
+ </field>
+
+ <field name="Swizzle B" size="3" start="118" type="uint"/>
+ <field name="Swizzle G" size="3" start="115" type="uint"/>
+ <field name="Swizzle R" size="3" start="112" type="uint"/>
+
+ <field name="Depth Compare Function" size="3" start="109" type="Compare Function"/>
+
+ <field name="sRGB" size="1" start="107" type="bool"/>
+
+ <field name="Texture type" size="7" start="100" type="uint"/>
+
+ <field name="Image Depth" size="14" start="86" type="uint"/>
+ <field name="Image Height" size="14" start="72" type="uint"/>
+ <field name="Image Width" size="14" start="58" type="uint"/>
+
+ <field name="Array Stride (64-byte aligned)" size="26" start="32" type="uint"/>
+
+ <field name="Texture base pointer" size="32" start="0" type="address"/>
+
+ <field name="Minification Filter" size="3" start="1" type="uint"/>
+ <field name="Magnification Filter" size="1" start="0" type="uint"/>
+ </struct>
+
+ <enum name="Texture Data Formats">
+ <value name="Texture Data Format R8" value="0"/>
+ <value name="Texture Data Format R8 SNORM" value="1"/>
+ <value name="Texture Data Format RG8" value="2"/>
+ <value name="Texture Data Format RG8 SNORM" value="3"/>
+ <value name="Texture Data Format RGBA8" value="4"/>
+ <value name="Texture Data Format RGBA8 SNORM" value="5"/>
+ <value name="Texture Data Format RGB565" value="6"/>
+ <value name="Texture Data Format RGBA4" value="7"/>
+ <value name="Texture Data Format RGB5_A1" value="8"/>
+ <value name="Texture Data Format RGB10_A2" value="9"/>
+ <value name="Texture Data Format R16" value="10"/>
+ <value name="Texture Data Format R16 SNORM" value="11"/>
+ <value name="Texture Data Format RG16" value="12"/>
+ <value name="Texture Data Format RG16 SNORM" value="13"/>
+ <value name="Texture Data Format RGBA16" value="14"/>
+ <value name="Texture Data Format RGBA16 SNORM" value="15"/>
+ <value name="Texture Data Format R16F" value="16"/>
+ <value name="Texture Data Format RG16F" value="17"/>
+ <value name="Texture Data Format RGBA16F" value="18"/>
+ <value name="Texture Data Format R11F_G11F_B10F" value="19"/>
+ <value name="Texture Data Format RGB9_E5" value="20"/>
+ <value name="Texture Data Format DEPTH COMP16" value="21"/>
+ <value name="Texture Data Format DEPTH COMP24" value="22"/>
+ <value name="Texture Data Format DEPTH COMP32F" value="23"/>
+ <value name="Texture Data Format DEPTH24_X8" value="24"/>
+ <value name="Texture Data Format R4" value="25"/>
+ <value name="Texture Data Format R1" value="26"/>
+ <!-- generic unfiltered 8-bit sample -->
+ <value name="Texture Data Format S8" value="27"/>
+ <!-- generic unfiltered 16-bit sample -->
+ <value name="Texture Data Format S16" value="28"/>
+ <!-- generic unfiltered 32-bit sample -->
+ <value name="Texture Data Format R32F" value="29"/>
+ <!-- generic unfiltered 64-bit sample -->
+ <value name="Texture Data Format RG32F" value="30"/>
+ <!-- generic unfiltered 128-bit sample -->
+ <value name="Texture Data Format RGBA32F" value="31"/>
+
+ <value name="Texture Data Format RGB8_ETC2" value="32"/>
+ <value name="Texture Data Format RGB8_PUNCHTHROUGH_ALPHA1" value="33"/>
+
+ <value name="Texture Data Format R11_EAC" value="34"/>
+ <value name="Texture Data Format SIGNED_R11_EAC" value="35"/>
+ <value name="Texture Data Format RG11_EAC" value="36"/>
+ <value name="Texture Data Format SIGNED_RG11_EAC" value="37"/>
+
+ <value name="Texture Data Format RGBA8_ETC2_EAC" value="38"/>
+ <value name="Texture Data Format YCBCR_LUMA" value="39"/>
+ <value name="Texture Data Format YCBCR_420_CHROMA" value="40"/>
+
+ <value name="Texture Data Format BC1" value="48"/>
+ <value name="Texture Data Format BC2" value="49"/>
+ <value name="Texture Data Format BC3" value="50"/>
+
+ <value name="Texture Data Format ASTC_4x4" value="64"/>
+ <value name="Texture Data Format ASTC_5x4" value="65"/>
+ <value name="Texture Data Format ASTC_5x5" value="66"/>
+ <value name="Texture Data Format ASTC_6x5" value="67"/>
+ <value name="Texture Data Format ASTC_6x6" value="68"/>
+ <value name="Texture Data Format ASTC_8x5" value="69"/>
+ <value name="Texture Data Format ASTC_8x6" value="70"/>
+ <value name="Texture Data Format ASTC_8x8" value="71"/>
+ <value name="Texture Data Format ASTC_10x5" value="72"/>
+ <value name="Texture Data Format ASTC_10x6" value="73"/>
+ <value name="Texture Data Format ASTC_10x8" value="74"/>
+ <value name="Texture Data Format ASTC_10x10" value="75"/>
+ <value name="Texture Data Format ASTC_12x10" value="76"/>
+ <value name="Texture Data Format ASTC_12x12" value="77"/>
+ </enum>
+</vcxml>
diff --git a/lib/mesa/src/broadcom/cle/v3d_packet_v33_pack.h b/lib/mesa/src/broadcom/cle/v3d_packet_v33_pack.h
new file mode 100644
index 000000000..934b0de4f
--- /dev/null
+++ b/lib/mesa/src/broadcom/cle/v3d_packet_v33_pack.h
@@ -0,0 +1,3733 @@
+/* Generated code, see packets.xml and gen_packet_header.py */
+
+
+/* Packets, enums and structures for V3D 3.3.
+ *
+ * This file has been generated, do not hand edit.
+ */
+
+#ifndef V3D33_PACK_H
+#define V3D33_PACK_H
+
+#include "v3d_packet_helpers.h"
+
+
+enum V3D33_Compare_Function {
+ V3D_COMPARE_FUNC_NEVER = 0,
+ V3D_COMPARE_FUNC_LESS = 1,
+ V3D_COMPARE_FUNC_EQUAL = 2,
+ V3D_COMPARE_FUNC_LEQUAL = 3,
+ V3D_COMPARE_FUNC_GREATER = 4,
+ V3D_COMPARE_FUNC_NOTEQUAL = 5,
+ V3D_COMPARE_FUNC_GEQUAL = 6,
+ V3D_COMPARE_FUNC_ALWAYS = 7,
+};
+
+enum V3D33_Blend_Factor {
+ V3D_BLEND_FACTOR_ZERO = 0,
+ V3D_BLEND_FACTOR_ONE = 1,
+ V3D_BLEND_FACTOR_SRC_COLOR = 2,
+ V3D_BLEND_FACTOR_INV_SRC_COLOR = 3,
+ V3D_BLEND_FACTOR_DST_COLOR = 4,
+ V3D_BLEND_FACTOR_INV_DST_COLOR = 5,
+ V3D_BLEND_FACTOR_SRC_ALPHA = 6,
+ V3D_BLEND_FACTOR_INV_SRC_ALPHA = 7,
+ V3D_BLEND_FACTOR_DST_ALPHA = 8,
+ V3D_BLEND_FACTOR_INV_DST_ALPHA = 9,
+ V3D_BLEND_FACTOR_CONST_COLOR = 10,
+ V3D_BLEND_FACTOR_INV_CONST_COLOR = 11,
+ V3D_BLEND_FACTOR_CONST_ALPHA = 12,
+ V3D_BLEND_FACTOR_INV_CONST_ALPHA = 13,
+ V3D_BLEND_FACTOR_SRC_ALPHA_SATURATE = 14,
+};
+
+enum V3D33_Blend_Mode {
+ V3D_BLEND_MODE_ADD = 0,
+ V3D_BLEND_MODE_SUB = 1,
+ V3D_BLEND_MODE_RSUB = 2,
+ V3D_BLEND_MODE_MIN = 3,
+ V3D_BLEND_MODE_MAX = 4,
+ V3D_BLEND_MODE_MUL = 5,
+ V3D_BLEND_MODE_SCREEN = 6,
+ V3D_BLEND_MODE_DARKEN = 7,
+ V3D_BLEND_MODE_LIGHTEN = 8,
+};
+
+enum V3D33_Stencil_Op {
+ V3D_STENCIL_OP_ZERO = 0,
+ V3D_STENCIL_OP_KEEP = 1,
+ V3D_STENCIL_OP_REPLACE = 2,
+ V3D_STENCIL_OP_INCR = 3,
+ V3D_STENCIL_OP_DECR = 4,
+ V3D_STENCIL_OP_INVERT = 5,
+ V3D_STENCIL_OP_INCWRAP = 6,
+ V3D_STENCIL_OP_DECWRAP = 7,
+};
+
+enum V3D33_Primitive {
+ V3D_PRIM_POINTS = 0,
+ V3D_PRIM_LINES = 1,
+ V3D_PRIM_LINE_LOOP = 2,
+ V3D_PRIM_LINE_STRIP = 3,
+ V3D_PRIM_TRIANGLES = 4,
+ V3D_PRIM_TRIANGLE_STRIP = 5,
+ V3D_PRIM_TRIANGLE_FAN = 6,
+ V3D_PRIM_POINTS_TF = 16,
+ V3D_PRIM_LINES_TF = 17,
+ V3D_PRIM_LINE_LOOP_TF = 18,
+ V3D_PRIM_LINE_STRIP_TF = 19,
+ V3D_PRIM_TRIANGLES_TF = 20,
+ V3D_PRIM_TRIANGLE_STRIP_TF = 21,
+ V3D_PRIM_TRIANGLE_FAN_TF = 22,
+};
+
+#define V3D33_HALT_opcode 0
+#define V3D33_HALT_header \
+ .opcode = 0
+
+struct V3D33_HALT {
+ uint32_t opcode;
+};
+
+static inline void
+V3D33_HALT_pack(__gen_user_data *data, uint8_t * restrict cl,
+ const struct V3D33_HALT * restrict values)
+{
+ cl[ 0] = __gen_uint(values->opcode, 0, 7);
+
+}
+
+#define V3D33_HALT_length 1
+#ifdef __gen_unpack_address
+static inline void
+V3D33_HALT_unpack(const uint8_t * restrict cl,
+ struct V3D33_HALT * restrict values)
+{
+ values->opcode = __gen_unpack_uint(cl, 0, 7);
+}
+#endif
+
+
+#define V3D33_NOP_opcode 1
+#define V3D33_NOP_header \
+ .opcode = 1
+
+struct V3D33_NOP {
+ uint32_t opcode;
+};
+
+static inline void
+V3D33_NOP_pack(__gen_user_data *data, uint8_t * restrict cl,
+ const struct V3D33_NOP * restrict values)
+{
+ cl[ 0] = __gen_uint(values->opcode, 0, 7);
+
+}
+
+#define V3D33_NOP_length 1
+#ifdef __gen_unpack_address
+static inline void
+V3D33_NOP_unpack(const uint8_t * restrict cl,
+ struct V3D33_NOP * restrict values)
+{
+ values->opcode = __gen_unpack_uint(cl, 0, 7);
+}
+#endif
+
+
+#define V3D33_FLUSH_opcode 4
+#define V3D33_FLUSH_header \
+ .opcode = 4
+
+struct V3D33_FLUSH {
+ uint32_t opcode;
+};
+
+static inline void
+V3D33_FLUSH_pack(__gen_user_data *data, uint8_t * restrict cl,
+ const struct V3D33_FLUSH * restrict values)
+{
+ cl[ 0] = __gen_uint(values->opcode, 0, 7);
+
+}
+
+#define V3D33_FLUSH_length 1
+#ifdef __gen_unpack_address
+static inline void
+V3D33_FLUSH_unpack(const uint8_t * restrict cl,
+ struct V3D33_FLUSH * restrict values)
+{
+ values->opcode = __gen_unpack_uint(cl, 0, 7);
+}
+#endif
+
+
+#define V3D33_FLUSH_ALL_STATE_opcode 5
+#define V3D33_FLUSH_ALL_STATE_header \
+ .opcode = 5
+
+struct V3D33_FLUSH_ALL_STATE {
+ uint32_t opcode;
+};
+
+static inline void
+V3D33_FLUSH_ALL_STATE_pack(__gen_user_data *data, uint8_t * restrict cl,
+ const struct V3D33_FLUSH_ALL_STATE * restrict values)
+{
+ cl[ 0] = __gen_uint(values->opcode, 0, 7);
+
+}
+
+#define V3D33_FLUSH_ALL_STATE_length 1
+#ifdef __gen_unpack_address
+static inline void
+V3D33_FLUSH_ALL_STATE_unpack(const uint8_t * restrict cl,
+ struct V3D33_FLUSH_ALL_STATE * restrict values)
+{
+ values->opcode = __gen_unpack_uint(cl, 0, 7);
+}
+#endif
+
+
+#define V3D33_START_TILE_BINNING_opcode 6
+#define V3D33_START_TILE_BINNING_header \
+ .opcode = 6
+
+struct V3D33_START_TILE_BINNING {
+ uint32_t opcode;
+};
+
+static inline void
+V3D33_START_TILE_BINNING_pack(__gen_user_data *data, uint8_t * restrict cl,
+ const struct V3D33_START_TILE_BINNING * restrict values)
+{
+ cl[ 0] = __gen_uint(values->opcode, 0, 7);
+
+}
+
+#define V3D33_START_TILE_BINNING_length 1
+#ifdef __gen_unpack_address
+static inline void
+V3D33_START_TILE_BINNING_unpack(const uint8_t * restrict cl,
+ struct V3D33_START_TILE_BINNING * restrict values)
+{
+ values->opcode = __gen_unpack_uint(cl, 0, 7);
+}
+#endif
+
+
+#define V3D33_INCREMENT_SEMAPHORE_opcode 7
+#define V3D33_INCREMENT_SEMAPHORE_header \
+ .opcode = 7
+
+struct V3D33_INCREMENT_SEMAPHORE {
+ uint32_t opcode;
+};
+
+static inline void
+V3D33_INCREMENT_SEMAPHORE_pack(__gen_user_data *data, uint8_t * restrict cl,
+ const struct V3D33_INCREMENT_SEMAPHORE * restrict values)
+{
+ cl[ 0] = __gen_uint(values->opcode, 0, 7);
+
+}
+
+#define V3D33_INCREMENT_SEMAPHORE_length 1
+#ifdef __gen_unpack_address
+static inline void
+V3D33_INCREMENT_SEMAPHORE_unpack(const uint8_t * restrict cl,
+ struct V3D33_INCREMENT_SEMAPHORE * restrict values)
+{
+ values->opcode = __gen_unpack_uint(cl, 0, 7);
+}
+#endif
+
+
+#define V3D33_WAIT_ON_SEMAPHORE_opcode 8
+#define V3D33_WAIT_ON_SEMAPHORE_header \
+ .opcode = 8
+
+struct V3D33_WAIT_ON_SEMAPHORE {
+ uint32_t opcode;
+};
+
+static inline void
+V3D33_WAIT_ON_SEMAPHORE_pack(__gen_user_data *data, uint8_t * restrict cl,
+ const struct V3D33_WAIT_ON_SEMAPHORE * restrict values)
+{
+ cl[ 0] = __gen_uint(values->opcode, 0, 7);
+
+}
+
+#define V3D33_WAIT_ON_SEMAPHORE_length 1
+#ifdef __gen_unpack_address
+static inline void
+V3D33_WAIT_ON_SEMAPHORE_unpack(const uint8_t * restrict cl,
+ struct V3D33_WAIT_ON_SEMAPHORE * restrict values)
+{
+ values->opcode = __gen_unpack_uint(cl, 0, 7);
+}
+#endif
+
+
+#define V3D33_WAIT_FOR_PREVIOUS_FRAME_opcode 9
+#define V3D33_WAIT_FOR_PREVIOUS_FRAME_header \
+ .opcode = 9
+
+struct V3D33_WAIT_FOR_PREVIOUS_FRAME {
+ uint32_t opcode;
+};
+
+static inline void
+V3D33_WAIT_FOR_PREVIOUS_FRAME_pack(__gen_user_data *data, uint8_t * restrict cl,
+ const struct V3D33_WAIT_FOR_PREVIOUS_FRAME * restrict values)
+{
+ cl[ 0] = __gen_uint(values->opcode, 0, 7);
+
+}
+
+#define V3D33_WAIT_FOR_PREVIOUS_FRAME_length 1
+#ifdef __gen_unpack_address
+static inline void
+V3D33_WAIT_FOR_PREVIOUS_FRAME_unpack(const uint8_t * restrict cl,
+ struct V3D33_WAIT_FOR_PREVIOUS_FRAME * restrict values)
+{
+ values->opcode = __gen_unpack_uint(cl, 0, 7);
+}
+#endif
+
+
+#define V3D33_ENABLE_Z_ONLY_RENDERING_opcode 10
+#define V3D33_ENABLE_Z_ONLY_RENDERING_header \
+ .opcode = 10
+
+struct V3D33_ENABLE_Z_ONLY_RENDERING {
+ uint32_t opcode;
+};
+
+static inline void
+V3D33_ENABLE_Z_ONLY_RENDERING_pack(__gen_user_data *data, uint8_t * restrict cl,
+ const struct V3D33_ENABLE_Z_ONLY_RENDERING * restrict values)
+{
+ cl[ 0] = __gen_uint(values->opcode, 0, 7);
+
+}
+
+#define V3D33_ENABLE_Z_ONLY_RENDERING_length 1
+#ifdef __gen_unpack_address
+static inline void
+V3D33_ENABLE_Z_ONLY_RENDERING_unpack(const uint8_t * restrict cl,
+ struct V3D33_ENABLE_Z_ONLY_RENDERING * restrict values)
+{
+ values->opcode = __gen_unpack_uint(cl, 0, 7);
+}
+#endif
+
+
+#define V3D33_DISABLE_Z_ONLY_RENDERING_opcode 11
+#define V3D33_DISABLE_Z_ONLY_RENDERING_header \
+ .opcode = 11
+
+struct V3D33_DISABLE_Z_ONLY_RENDERING {
+ uint32_t opcode;
+};
+
+static inline void
+V3D33_DISABLE_Z_ONLY_RENDERING_pack(__gen_user_data *data, uint8_t * restrict cl,
+ const struct V3D33_DISABLE_Z_ONLY_RENDERING * restrict values)
+{
+ cl[ 0] = __gen_uint(values->opcode, 0, 7);
+
+}
+
+#define V3D33_DISABLE_Z_ONLY_RENDERING_length 1
+#ifdef __gen_unpack_address
+static inline void
+V3D33_DISABLE_Z_ONLY_RENDERING_unpack(const uint8_t * restrict cl,
+ struct V3D33_DISABLE_Z_ONLY_RENDERING * restrict values)
+{
+ values->opcode = __gen_unpack_uint(cl, 0, 7);
+}
+#endif
+
+
+#define V3D33_END_OF_Z_ONLY_RENDERING_IN_FRAME_opcode 12
+#define V3D33_END_OF_Z_ONLY_RENDERING_IN_FRAME_header\
+ .opcode = 12
+
+struct V3D33_END_OF_Z_ONLY_RENDERING_IN_FRAME {
+ uint32_t opcode;
+};
+
+static inline void
+V3D33_END_OF_Z_ONLY_RENDERING_IN_FRAME_pack(__gen_user_data *data, uint8_t * restrict cl,
+ const struct V3D33_END_OF_Z_ONLY_RENDERING_IN_FRAME * restrict values)
+{
+ cl[ 0] = __gen_uint(values->opcode, 0, 7);
+
+}
+
+#define V3D33_END_OF_Z_ONLY_RENDERING_IN_FRAME_length 1
+#ifdef __gen_unpack_address
+static inline void
+V3D33_END_OF_Z_ONLY_RENDERING_IN_FRAME_unpack(const uint8_t * restrict cl,
+ struct V3D33_END_OF_Z_ONLY_RENDERING_IN_FRAME * restrict values)
+{
+ values->opcode = __gen_unpack_uint(cl, 0, 7);
+}
+#endif
+
+
+#define V3D33_END_OF_RENDERING_opcode 13
+#define V3D33_END_OF_RENDERING_header \
+ .opcode = 13
+
+struct V3D33_END_OF_RENDERING {
+ uint32_t opcode;
+};
+
+static inline void
+V3D33_END_OF_RENDERING_pack(__gen_user_data *data, uint8_t * restrict cl,
+ const struct V3D33_END_OF_RENDERING * restrict values)
+{
+ cl[ 0] = __gen_uint(values->opcode, 0, 7);
+
+}
+
+#define V3D33_END_OF_RENDERING_length 1
+#ifdef __gen_unpack_address
+static inline void
+V3D33_END_OF_RENDERING_unpack(const uint8_t * restrict cl,
+ struct V3D33_END_OF_RENDERING * restrict values)
+{
+ values->opcode = __gen_unpack_uint(cl, 0, 7);
+}
+#endif
+
+
+#define V3D33_WAIT_FOR_TRANSFORM_FEEDBACK_opcode 14
+#define V3D33_WAIT_FOR_TRANSFORM_FEEDBACK_header\
+ .opcode = 14
+
+struct V3D33_WAIT_FOR_TRANSFORM_FEEDBACK {
+ uint32_t opcode;
+ uint32_t block_count;
+};
+
+static inline void
+V3D33_WAIT_FOR_TRANSFORM_FEEDBACK_pack(__gen_user_data *data, uint8_t * restrict cl,
+ const struct V3D33_WAIT_FOR_TRANSFORM_FEEDBACK * restrict values)
+{
+ cl[ 0] = __gen_uint(values->opcode, 0, 7);
+
+ cl[ 1] = __gen_uint(values->block_count, 0, 7);
+
+}
+
+#define V3D33_WAIT_FOR_TRANSFORM_FEEDBACK_length 2
+#ifdef __gen_unpack_address
+static inline void
+V3D33_WAIT_FOR_TRANSFORM_FEEDBACK_unpack(const uint8_t * restrict cl,
+ struct V3D33_WAIT_FOR_TRANSFORM_FEEDBACK * restrict values)
+{
+ values->opcode = __gen_unpack_uint(cl, 0, 7);
+ values->block_count = __gen_unpack_uint(cl, 8, 15);
+}
+#endif
+
+
+#define V3D33_BRANCH_TO_AUTO_CHAINED_SUB_LIST_opcode 15
+#define V3D33_BRANCH_TO_AUTO_CHAINED_SUB_LIST_header\
+ .opcode = 15
+
+struct V3D33_BRANCH_TO_AUTO_CHAINED_SUB_LIST {
+ uint32_t opcode;
+ __gen_address_type address;
+};
+
+static inline void
+V3D33_BRANCH_TO_AUTO_CHAINED_SUB_LIST_pack(__gen_user_data *data, uint8_t * restrict cl,
+ const struct V3D33_BRANCH_TO_AUTO_CHAINED_SUB_LIST * restrict values)
+{
+ cl[ 0] = __gen_uint(values->opcode, 0, 7);
+
+ __gen_emit_reloc(data, &values->address);
+ cl[ 1] = __gen_address_offset(&values->address);
+
+ cl[ 2] = __gen_address_offset(&values->address) >> 8;
+
+ cl[ 3] = __gen_address_offset(&values->address) >> 16;
+
+ cl[ 4] = __gen_address_offset(&values->address) >> 24;
+
+}
+
+#define V3D33_BRANCH_TO_AUTO_CHAINED_SUB_LIST_length 5
+#ifdef __gen_unpack_address
+static inline void
+V3D33_BRANCH_TO_AUTO_CHAINED_SUB_LIST_unpack(const uint8_t * restrict cl,
+ struct V3D33_BRANCH_TO_AUTO_CHAINED_SUB_LIST * restrict values)
+{
+ values->opcode = __gen_unpack_uint(cl, 0, 7);
+ values->address = __gen_unpack_address(cl, 8, 39);
+}
+#endif
+
+
+#define V3D33_BRANCH_opcode 16
+#define V3D33_BRANCH_header \
+ .opcode = 16
+
+struct V3D33_BRANCH {
+ uint32_t opcode;
+ __gen_address_type address;
+};
+
+static inline void
+V3D33_BRANCH_pack(__gen_user_data *data, uint8_t * restrict cl,
+ const struct V3D33_BRANCH * restrict values)
+{
+ cl[ 0] = __gen_uint(values->opcode, 0, 7);
+
+ __gen_emit_reloc(data, &values->address);
+ cl[ 1] = __gen_address_offset(&values->address);
+
+ cl[ 2] = __gen_address_offset(&values->address) >> 8;
+
+ cl[ 3] = __gen_address_offset(&values->address) >> 16;
+
+ cl[ 4] = __gen_address_offset(&values->address) >> 24;
+
+}
+
+#define V3D33_BRANCH_length 5
+#ifdef __gen_unpack_address
+static inline void
+V3D33_BRANCH_unpack(const uint8_t * restrict cl,
+ struct V3D33_BRANCH * restrict values)
+{
+ values->opcode = __gen_unpack_uint(cl, 0, 7);
+ values->address = __gen_unpack_address(cl, 8, 39);
+}
+#endif
+
+
+#define V3D33_BRANCH_TO_SUB_LIST_opcode 17
+#define V3D33_BRANCH_TO_SUB_LIST_header \
+ .opcode = 17
+
+struct V3D33_BRANCH_TO_SUB_LIST {
+ uint32_t opcode;
+ __gen_address_type address;
+};
+
+static inline void
+V3D33_BRANCH_TO_SUB_LIST_pack(__gen_user_data *data, uint8_t * restrict cl,
+ const struct V3D33_BRANCH_TO_SUB_LIST * restrict values)
+{
+ cl[ 0] = __gen_uint(values->opcode, 0, 7);
+
+ __gen_emit_reloc(data, &values->address);
+ cl[ 1] = __gen_address_offset(&values->address);
+
+ cl[ 2] = __gen_address_offset(&values->address) >> 8;
+
+ cl[ 3] = __gen_address_offset(&values->address) >> 16;
+
+ cl[ 4] = __gen_address_offset(&values->address) >> 24;
+
+}
+
+#define V3D33_BRANCH_TO_SUB_LIST_length 5
+#ifdef __gen_unpack_address
+static inline void
+V3D33_BRANCH_TO_SUB_LIST_unpack(const uint8_t * restrict cl,
+ struct V3D33_BRANCH_TO_SUB_LIST * restrict values)
+{
+ values->opcode = __gen_unpack_uint(cl, 0, 7);
+ values->address = __gen_unpack_address(cl, 8, 39);
+}
+#endif
+
+
+#define V3D33_RETURN_FROM_SUB_LIST_opcode 18
+#define V3D33_RETURN_FROM_SUB_LIST_header \
+ .opcode = 18
+
+struct V3D33_RETURN_FROM_SUB_LIST {
+ uint32_t opcode;
+};
+
+static inline void
+V3D33_RETURN_FROM_SUB_LIST_pack(__gen_user_data *data, uint8_t * restrict cl,
+ const struct V3D33_RETURN_FROM_SUB_LIST * restrict values)
+{
+ cl[ 0] = __gen_uint(values->opcode, 0, 7);
+
+}
+
+#define V3D33_RETURN_FROM_SUB_LIST_length 1
+#ifdef __gen_unpack_address
+static inline void
+V3D33_RETURN_FROM_SUB_LIST_unpack(const uint8_t * restrict cl,
+ struct V3D33_RETURN_FROM_SUB_LIST * restrict values)
+{
+ values->opcode = __gen_unpack_uint(cl, 0, 7);
+}
+#endif
+
+
+#define V3D33_FLUSH_VCD_CACHE_opcode 19
+#define V3D33_FLUSH_VCD_CACHE_header \
+ .opcode = 19
+
+struct V3D33_FLUSH_VCD_CACHE {
+ uint32_t opcode;
+};
+
+static inline void
+V3D33_FLUSH_VCD_CACHE_pack(__gen_user_data *data, uint8_t * restrict cl,
+ const struct V3D33_FLUSH_VCD_CACHE * restrict values)
+{
+ cl[ 0] = __gen_uint(values->opcode, 0, 7);
+
+}
+
+#define V3D33_FLUSH_VCD_CACHE_length 1
+#ifdef __gen_unpack_address
+static inline void
+V3D33_FLUSH_VCD_CACHE_unpack(const uint8_t * restrict cl,
+ struct V3D33_FLUSH_VCD_CACHE * restrict values)
+{
+ values->opcode = __gen_unpack_uint(cl, 0, 7);
+}
+#endif
+
+
+#define V3D33_START_ADDRESS_OF_GENERIC_TILE_LIST_opcode 20
+#define V3D33_START_ADDRESS_OF_GENERIC_TILE_LIST_header\
+ .opcode = 20
+
+struct V3D33_START_ADDRESS_OF_GENERIC_TILE_LIST {
+ uint32_t opcode;
+ __gen_address_type start;
+ __gen_address_type end;
+};
+
+static inline void
+V3D33_START_ADDRESS_OF_GENERIC_TILE_LIST_pack(__gen_user_data *data, uint8_t * restrict cl,
+ const struct V3D33_START_ADDRESS_OF_GENERIC_TILE_LIST * restrict values)
+{
+ cl[ 0] = __gen_uint(values->opcode, 0, 7);
+
+ __gen_emit_reloc(data, &values->start);
+ cl[ 1] = __gen_address_offset(&values->start);
+
+ cl[ 2] = __gen_address_offset(&values->start) >> 8;
+
+ cl[ 3] = __gen_address_offset(&values->start) >> 16;
+
+ cl[ 4] = __gen_address_offset(&values->start) >> 24;
+
+ __gen_emit_reloc(data, &values->end);
+ cl[ 5] = __gen_address_offset(&values->end);
+
+ cl[ 6] = __gen_address_offset(&values->end) >> 8;
+
+ cl[ 7] = __gen_address_offset(&values->end) >> 16;
+
+ cl[ 8] = __gen_address_offset(&values->end) >> 24;
+
+}
+
+#define V3D33_START_ADDRESS_OF_GENERIC_TILE_LIST_length 9
+#ifdef __gen_unpack_address
+static inline void
+V3D33_START_ADDRESS_OF_GENERIC_TILE_LIST_unpack(const uint8_t * restrict cl,
+ struct V3D33_START_ADDRESS_OF_GENERIC_TILE_LIST * restrict values)
+{
+ values->opcode = __gen_unpack_uint(cl, 0, 7);
+ values->start = __gen_unpack_address(cl, 8, 39);
+ values->end = __gen_unpack_address(cl, 40, 71);
+}
+#endif
+
+
+#define V3D33_BRANCH_TO_IMPLICIT_TILE_LIST_opcode 21
+#define V3D33_BRANCH_TO_IMPLICIT_TILE_LIST_header\
+ .opcode = 21
+
+struct V3D33_BRANCH_TO_IMPLICIT_TILE_LIST {
+ uint32_t opcode;
+ uint32_t tile_list_set_number;
+};
+
+static inline void
+V3D33_BRANCH_TO_IMPLICIT_TILE_LIST_pack(__gen_user_data *data, uint8_t * restrict cl,
+ const struct V3D33_BRANCH_TO_IMPLICIT_TILE_LIST * restrict values)
+{
+ cl[ 0] = __gen_uint(values->opcode, 0, 7);
+
+ cl[ 1] = __gen_uint(values->tile_list_set_number, 0, 7);
+
+}
+
+#define V3D33_BRANCH_TO_IMPLICIT_TILE_LIST_length 2
+#ifdef __gen_unpack_address
+static inline void
+V3D33_BRANCH_TO_IMPLICIT_TILE_LIST_unpack(const uint8_t * restrict cl,
+ struct V3D33_BRANCH_TO_IMPLICIT_TILE_LIST * restrict values)
+{
+ values->opcode = __gen_unpack_uint(cl, 0, 7);
+ values->tile_list_set_number = __gen_unpack_uint(cl, 8, 15);
+}
+#endif
+
+
+#define V3D33_BRANCH_TO_EXPLICIT_SUPERTILE_opcode 22
+#define V3D33_BRANCH_TO_EXPLICIT_SUPERTILE_header\
+ .opcode = 22
+
+struct V3D33_BRANCH_TO_EXPLICIT_SUPERTILE {
+ uint32_t opcode;
+ __gen_address_type absolute_address_of_explicit_supertile_render_list;
+ uint32_t explicit_supertile_number;
+ uint32_t row_number;
+ uint32_t column_number;
+};
+
+static inline void
+V3D33_BRANCH_TO_EXPLICIT_SUPERTILE_pack(__gen_user_data *data, uint8_t * restrict cl,
+ const struct V3D33_BRANCH_TO_EXPLICIT_SUPERTILE * restrict values)
+{
+ cl[ 0] = __gen_uint(values->opcode, 0, 7);
+
+ cl[ 1] = __gen_uint(values->column_number, 0, 7);
+
+ cl[ 2] = __gen_uint(values->row_number, 0, 7);
+
+ cl[ 3] = __gen_uint(values->explicit_supertile_number, 0, 7);
+
+ __gen_emit_reloc(data, &values->absolute_address_of_explicit_supertile_render_list);
+ cl[ 4] = __gen_address_offset(&values->absolute_address_of_explicit_supertile_render_list);
+
+ cl[ 5] = __gen_address_offset(&values->absolute_address_of_explicit_supertile_render_list) >> 8;
+
+ cl[ 6] = __gen_address_offset(&values->absolute_address_of_explicit_supertile_render_list) >> 16;
+
+ cl[ 7] = __gen_address_offset(&values->absolute_address_of_explicit_supertile_render_list) >> 24;
+
+}
+
+#define V3D33_BRANCH_TO_EXPLICIT_SUPERTILE_length 8
+#ifdef __gen_unpack_address
+static inline void
+V3D33_BRANCH_TO_EXPLICIT_SUPERTILE_unpack(const uint8_t * restrict cl,
+ struct V3D33_BRANCH_TO_EXPLICIT_SUPERTILE * restrict values)
+{
+ values->opcode = __gen_unpack_uint(cl, 0, 7);
+ values->absolute_address_of_explicit_supertile_render_list = __gen_unpack_address(cl, 32, 63);
+ values->explicit_supertile_number = __gen_unpack_uint(cl, 24, 31);
+ values->row_number = __gen_unpack_uint(cl, 16, 23);
+ values->column_number = __gen_unpack_uint(cl, 8, 15);
+}
+#endif
+
+
+#define V3D33_SUPERTILE_COORDINATES_opcode 23
+#define V3D33_SUPERTILE_COORDINATES_header \
+ .opcode = 23
+
+struct V3D33_SUPERTILE_COORDINATES {
+ uint32_t opcode;
+ uint32_t row_number_in_supertiles;
+ uint32_t column_number_in_supertiles;
+};
+
+static inline void
+V3D33_SUPERTILE_COORDINATES_pack(__gen_user_data *data, uint8_t * restrict cl,
+ const struct V3D33_SUPERTILE_COORDINATES * restrict values)
+{
+ cl[ 0] = __gen_uint(values->opcode, 0, 7);
+
+ cl[ 1] = __gen_uint(values->column_number_in_supertiles, 0, 7);
+
+ cl[ 2] = __gen_uint(values->row_number_in_supertiles, 0, 7);
+
+}
+
+#define V3D33_SUPERTILE_COORDINATES_length 3
+#ifdef __gen_unpack_address
+static inline void
+V3D33_SUPERTILE_COORDINATES_unpack(const uint8_t * restrict cl,
+ struct V3D33_SUPERTILE_COORDINATES * restrict values)
+{
+ values->opcode = __gen_unpack_uint(cl, 0, 7);
+ values->row_number_in_supertiles = __gen_unpack_uint(cl, 16, 23);
+ values->column_number_in_supertiles = __gen_unpack_uint(cl, 8, 15);
+}
+#endif
+
+
+#define V3D33_STORE_MULTI_SAMPLE_RESOLVED_TILE_COLOR_BUFFER_opcode 24
+#define V3D33_STORE_MULTI_SAMPLE_RESOLVED_TILE_COLOR_BUFFER_header\
+ .opcode = 24
+
+struct V3D33_STORE_MULTI_SAMPLE_RESOLVED_TILE_COLOR_BUFFER {
+ uint32_t opcode;
+};
+
+static inline void
+V3D33_STORE_MULTI_SAMPLE_RESOLVED_TILE_COLOR_BUFFER_pack(__gen_user_data *data, uint8_t * restrict cl,
+ const struct V3D33_STORE_MULTI_SAMPLE_RESOLVED_TILE_COLOR_BUFFER * restrict values)
+{
+ cl[ 0] = __gen_uint(values->opcode, 0, 7);
+
+}
+
+#define V3D33_STORE_MULTI_SAMPLE_RESOLVED_TILE_COLOR_BUFFER_length 1
+#ifdef __gen_unpack_address
+static inline void
+V3D33_STORE_MULTI_SAMPLE_RESOLVED_TILE_COLOR_BUFFER_unpack(const uint8_t * restrict cl,
+ struct V3D33_STORE_MULTI_SAMPLE_RESOLVED_TILE_COLOR_BUFFER * restrict values)
+{
+ values->opcode = __gen_unpack_uint(cl, 0, 7);
+}
+#endif
+
+
+#define V3D33_STORE_MULTI_SAMPLE_RESOLVED_TILE_COLOR_BUFFER_EXTENDED_opcode 25
+#define V3D33_STORE_MULTI_SAMPLE_RESOLVED_TILE_COLOR_BUFFER_EXTENDED_header\
+ .opcode = 25
+
+struct V3D33_STORE_MULTI_SAMPLE_RESOLVED_TILE_COLOR_BUFFER_EXTENDED {
+ uint32_t opcode;
+ uint32_t disable_color_buffer_write;
+ bool enable_z_write;
+ bool enable_stencil_write;
+ bool disable_colour_buffers_clear_on_write;
+ bool disable_stencil_buffer_clear_on_write;
+ bool disable_z_buffer_clear_on_write;
+ bool disable_fast_opportunistic_write_out_in_multisample_mode;
+ bool last_tile_of_frame;
+};
+
+static inline void
+V3D33_STORE_MULTI_SAMPLE_RESOLVED_TILE_COLOR_BUFFER_EXTENDED_pack(__gen_user_data *data, uint8_t * restrict cl,
+ const struct V3D33_STORE_MULTI_SAMPLE_RESOLVED_TILE_COLOR_BUFFER_EXTENDED * restrict values)
+{
+ cl[ 0] = __gen_uint(values->opcode, 0, 7);
+
+ cl[ 1] = __gen_uint(values->enable_z_write, 7, 7) |
+ __gen_uint(values->enable_stencil_write, 6, 6) |
+ __gen_uint(values->disable_colour_buffers_clear_on_write, 4, 4) |
+ __gen_uint(values->disable_stencil_buffer_clear_on_write, 3, 3) |
+ __gen_uint(values->disable_z_buffer_clear_on_write, 2, 2) |
+ __gen_uint(values->disable_fast_opportunistic_write_out_in_multisample_mode, 1, 1) |
+ __gen_uint(values->last_tile_of_frame, 0, 0);
+
+ cl[ 2] = __gen_uint(values->disable_color_buffer_write, 0, 7);
+
+}
+
+#define V3D33_STORE_MULTI_SAMPLE_RESOLVED_TILE_COLOR_BUFFER_EXTENDED_length 3
+#ifdef __gen_unpack_address
+static inline void
+V3D33_STORE_MULTI_SAMPLE_RESOLVED_TILE_COLOR_BUFFER_EXTENDED_unpack(const uint8_t * restrict cl,
+ struct V3D33_STORE_MULTI_SAMPLE_RESOLVED_TILE_COLOR_BUFFER_EXTENDED * restrict values)
+{
+ values->opcode = __gen_unpack_uint(cl, 0, 7);
+ values->disable_color_buffer_write = __gen_unpack_uint(cl, 16, 23);
+ values->enable_z_write = __gen_unpack_uint(cl, 15, 15);
+ values->enable_stencil_write = __gen_unpack_uint(cl, 14, 14);
+ values->disable_colour_buffers_clear_on_write = __gen_unpack_uint(cl, 12, 12);
+ values->disable_stencil_buffer_clear_on_write = __gen_unpack_uint(cl, 11, 11);
+ values->disable_z_buffer_clear_on_write = __gen_unpack_uint(cl, 10, 10);
+ values->disable_fast_opportunistic_write_out_in_multisample_mode = __gen_unpack_uint(cl, 9, 9);
+ values->last_tile_of_frame = __gen_unpack_uint(cl, 8, 8);
+}
+#endif
+
+
+#define V3D33_RELOAD_TILE_COLOUR_BUFFER_opcode 26
+#define V3D33_RELOAD_TILE_COLOUR_BUFFER_header \
+ .opcode = 26
+
+struct V3D33_RELOAD_TILE_COLOUR_BUFFER {
+ uint32_t opcode;
+ uint32_t disable_colour_buffer_load;
+ bool enable_z_load;
+ bool enable_stencil_load;
+};
+
+static inline void
+V3D33_RELOAD_TILE_COLOUR_BUFFER_pack(__gen_user_data *data, uint8_t * restrict cl,
+ const struct V3D33_RELOAD_TILE_COLOUR_BUFFER * restrict values)
+{
+ cl[ 0] = __gen_uint(values->opcode, 0, 7);
+
+ cl[ 1] = __gen_uint(values->enable_z_load, 7, 7) |
+ __gen_uint(values->enable_stencil_load, 6, 6);
+
+ cl[ 2] = __gen_uint(values->disable_colour_buffer_load, 0, 7);
+
+}
+
+#define V3D33_RELOAD_TILE_COLOUR_BUFFER_length 3
+#ifdef __gen_unpack_address
+static inline void
+V3D33_RELOAD_TILE_COLOUR_BUFFER_unpack(const uint8_t * restrict cl,
+ struct V3D33_RELOAD_TILE_COLOUR_BUFFER * restrict values)
+{
+ values->opcode = __gen_unpack_uint(cl, 0, 7);
+ values->disable_colour_buffer_load = __gen_unpack_uint(cl, 16, 23);
+ values->enable_z_load = __gen_unpack_uint(cl, 15, 15);
+ values->enable_stencil_load = __gen_unpack_uint(cl, 14, 14);
+}
+#endif
+
+
+#define V3D33_END_OF_TILE_MARKER_opcode 27
+#define V3D33_END_OF_TILE_MARKER_header \
+ .opcode = 27
+
+struct V3D33_END_OF_TILE_MARKER {
+ uint32_t opcode;
+};
+
+static inline void
+V3D33_END_OF_TILE_MARKER_pack(__gen_user_data *data, uint8_t * restrict cl,
+ const struct V3D33_END_OF_TILE_MARKER * restrict values)
+{
+ cl[ 0] = __gen_uint(values->opcode, 0, 7);
+
+}
+
+#define V3D33_END_OF_TILE_MARKER_length 1
+#ifdef __gen_unpack_address
+static inline void
+V3D33_END_OF_TILE_MARKER_unpack(const uint8_t * restrict cl,
+ struct V3D33_END_OF_TILE_MARKER * restrict values)
+{
+ values->opcode = __gen_unpack_uint(cl, 0, 7);
+}
+#endif
+
+
+#define V3D33_STORE_TILE_BUFFER_GENERAL_opcode 29
+#define V3D33_STORE_TILE_BUFFER_GENERAL_header \
+ .opcode = 29
+
+struct V3D33_STORE_TILE_BUFFER_GENERAL {
+ uint32_t opcode;
+ __gen_address_type address;
+ uint32_t padded_height_of_output_image_in_uif_blocks;
+ bool xor_uif;
+ bool last_tile_of_frame;
+ bool disable_colour_buffers_clear_on_write;
+ bool disable_stencil_buffer_clear_on_write;
+ bool disable_z_buffer_clear_on_write;
+ bool raw_mode;
+ uint32_t buffer_to_store;
+#define RENDER_TARGET_0 0
+#define RENDER_TARGET_1 1
+#define RENDER_TARGET_2 2
+#define RENDER_TARGET_3 3
+#define NONE 8
+#define Z 9
+#define STENCIL 10
+#define ZSTENCIL 11
+};
+
+static inline void
+V3D33_STORE_TILE_BUFFER_GENERAL_pack(__gen_user_data *data, uint8_t * restrict cl,
+ const struct V3D33_STORE_TILE_BUFFER_GENERAL * restrict values)
+{
+ cl[ 0] = __gen_uint(values->opcode, 0, 7);
+
+ cl[ 1] = __gen_uint(values->disable_colour_buffers_clear_on_write, 7, 7) |
+ __gen_uint(values->disable_stencil_buffer_clear_on_write, 6, 6) |
+ __gen_uint(values->disable_z_buffer_clear_on_write, 5, 5) |
+ __gen_uint(values->raw_mode, 4, 4) |
+ __gen_uint(values->buffer_to_store, 0, 3);
+
+ cl[ 2] = __gen_uint(values->padded_height_of_output_image_in_uif_blocks, 3, 15) |
+ __gen_uint(values->xor_uif, 2, 2) |
+ __gen_uint(values->last_tile_of_frame, 0, 0);
+
+ __gen_emit_reloc(data, &values->address);
+ cl[ 3] = __gen_address_offset(&values->address) |
+ __gen_uint(values->padded_height_of_output_image_in_uif_blocks, 3, 15) >> 8;
+
+ cl[ 4] = __gen_address_offset(&values->address) >> 8;
+
+ cl[ 5] = __gen_address_offset(&values->address) >> 16;
+
+ cl[ 6] = __gen_address_offset(&values->address) >> 24;
+
+}
+
+#define V3D33_STORE_TILE_BUFFER_GENERAL_length 7
+#ifdef __gen_unpack_address
+static inline void
+V3D33_STORE_TILE_BUFFER_GENERAL_unpack(const uint8_t * restrict cl,
+ struct V3D33_STORE_TILE_BUFFER_GENERAL * restrict values)
+{
+ values->opcode = __gen_unpack_uint(cl, 0, 7);
+ values->address = __gen_unpack_address(cl, 24, 55);
+ values->padded_height_of_output_image_in_uif_blocks = __gen_unpack_uint(cl, 19, 31);
+ values->xor_uif = __gen_unpack_uint(cl, 18, 18);
+ values->last_tile_of_frame = __gen_unpack_uint(cl, 16, 16);
+ values->disable_colour_buffers_clear_on_write = __gen_unpack_uint(cl, 15, 15);
+ values->disable_stencil_buffer_clear_on_write = __gen_unpack_uint(cl, 14, 14);
+ values->disable_z_buffer_clear_on_write = __gen_unpack_uint(cl, 13, 13);
+ values->raw_mode = __gen_unpack_uint(cl, 12, 12);
+ values->buffer_to_store = __gen_unpack_uint(cl, 8, 11);
+}
+#endif
+
+
+#define V3D33_LOAD_TILE_BUFFER_GENERAL_opcode 30
+#define V3D33_LOAD_TILE_BUFFER_GENERAL_header \
+ .opcode = 30
+
+struct V3D33_LOAD_TILE_BUFFER_GENERAL {
+ uint32_t opcode;
+ __gen_address_type address;
+ uint32_t padded_height_of_output_image_in_uif_blocks;
+ bool xor_uif;
+ bool raw_mode;
+ uint32_t buffer_to_load;
+#define RENDER_TARGET_0 0
+#define RENDER_TARGET_1 1
+#define RENDER_TARGET_2 2
+#define RENDER_TARGET_3 3
+#define NONE 8
+#define Z 9
+#define STENCIL 10
+#define ZSTENCIL 11
+};
+
+static inline void
+V3D33_LOAD_TILE_BUFFER_GENERAL_pack(__gen_user_data *data, uint8_t * restrict cl,
+ const struct V3D33_LOAD_TILE_BUFFER_GENERAL * restrict values)
+{
+ cl[ 0] = __gen_uint(values->opcode, 0, 7);
+
+ cl[ 1] = __gen_uint(values->raw_mode, 4, 4) |
+ __gen_uint(values->buffer_to_load, 0, 3);
+
+ cl[ 2] = __gen_uint(values->padded_height_of_output_image_in_uif_blocks, 3, 15) |
+ __gen_uint(values->xor_uif, 2, 2);
+
+ cl[ 3] = __gen_uint(values->padded_height_of_output_image_in_uif_blocks, 3, 15) >> 8;
+
+ __gen_emit_reloc(data, &values->address);
+ cl[ 4] = __gen_address_offset(&values->address);
+
+ cl[ 5] = __gen_address_offset(&values->address) >> 8;
+
+ cl[ 6] = __gen_address_offset(&values->address) >> 16;
+
+}
+
+#define V3D33_LOAD_TILE_BUFFER_GENERAL_length 7
+#ifdef __gen_unpack_address
+static inline void
+V3D33_LOAD_TILE_BUFFER_GENERAL_unpack(const uint8_t * restrict cl,
+ struct V3D33_LOAD_TILE_BUFFER_GENERAL * restrict values)
+{
+ values->opcode = __gen_unpack_uint(cl, 0, 7);
+ values->address = __gen_unpack_address(cl, 32, 55);
+ values->padded_height_of_output_image_in_uif_blocks = __gen_unpack_uint(cl, 19, 31);
+ values->xor_uif = __gen_unpack_uint(cl, 18, 18);
+ values->raw_mode = __gen_unpack_uint(cl, 12, 12);
+ values->buffer_to_load = __gen_unpack_uint(cl, 8, 11);
+}
+#endif
+
+
+#define V3D33_INDEXED_PRIMITIVE_LIST_opcode 32
+#define V3D33_INDEXED_PRIMITIVE_LIST_header \
+ .opcode = 32
+
+struct V3D33_INDEXED_PRIMITIVE_LIST {
+ uint32_t opcode;
+ uint32_t minimum_index;
+ bool enable_primitive_restarts;
+ uint32_t maximum_index;
+ __gen_address_type address_of_indices_list;
+ uint32_t length;
+ uint32_t index_type;
+#define INDEX_TYPE_8_BIT 0
+#define INDEX_TYPE_16_BIT 1
+#define INDEX_TYPE_32_BIT 2
+ uint32_t mode;
+};
+
+static inline void
+V3D33_INDEXED_PRIMITIVE_LIST_pack(__gen_user_data *data, uint8_t * restrict cl,
+ const struct V3D33_INDEXED_PRIMITIVE_LIST * restrict values)
+{
+ cl[ 0] = __gen_uint(values->opcode, 0, 7);
+
+ cl[ 1] = __gen_uint(values->index_type, 6, 7) |
+ __gen_uint(values->mode, 0, 4);
+
+
+ memcpy(&cl[2], &values->length, sizeof(values->length));
+ __gen_emit_reloc(data, &values->address_of_indices_list);
+ cl[ 6] = __gen_address_offset(&values->address_of_indices_list);
+
+ cl[ 7] = __gen_address_offset(&values->address_of_indices_list) >> 8;
+
+ cl[ 8] = __gen_address_offset(&values->address_of_indices_list) >> 16;
+
+ cl[ 9] = __gen_address_offset(&values->address_of_indices_list) >> 24;
+
+ cl[10] = __gen_uint(values->maximum_index, 0, 30);
+
+ cl[11] = __gen_uint(values->maximum_index, 0, 30) >> 8;
+
+ cl[12] = __gen_uint(values->maximum_index, 0, 30) >> 16;
+
+ cl[13] = __gen_uint(values->enable_primitive_restarts, 7, 7) |
+ __gen_uint(values->maximum_index, 0, 30) >> 24;
+
+
+ memcpy(&cl[14], &values->minimum_index, sizeof(values->minimum_index));
+}
+
+#define V3D33_INDEXED_PRIMITIVE_LIST_length 18
+#ifdef __gen_unpack_address
+static inline void
+V3D33_INDEXED_PRIMITIVE_LIST_unpack(const uint8_t * restrict cl,
+ struct V3D33_INDEXED_PRIMITIVE_LIST * restrict values)
+{
+ values->opcode = __gen_unpack_uint(cl, 0, 7);
+ values->minimum_index = __gen_unpack_uint(cl, 112, 143);
+ values->enable_primitive_restarts = __gen_unpack_uint(cl, 111, 111);
+ values->maximum_index = __gen_unpack_uint(cl, 80, 110);
+ values->address_of_indices_list = __gen_unpack_address(cl, 48, 79);
+ values->length = __gen_unpack_uint(cl, 16, 47);
+ values->index_type = __gen_unpack_uint(cl, 14, 15);
+ values->mode = __gen_unpack_uint(cl, 8, 12);
+}
+#endif
+
+
+#define V3D33_INDEXED_INSTANCED_PRIMITIVE_LIST_opcode 34
+#define V3D33_INDEXED_INSTANCED_PRIMITIVE_LIST_header\
+ .opcode = 34
+
+struct V3D33_INDEXED_INSTANCED_PRIMITIVE_LIST {
+ uint32_t opcode;
+ bool enable_primitive_restarts;
+ uint32_t maximum_index;
+ __gen_address_type address_of_indices_list;
+ uint32_t number_of_instances;
+ uint32_t instance_length;
+ uint32_t index_type;
+#define INDEX_TYPE_8_BIT 0
+#define INDEX_TYPE_16_BIT 1
+#define INDEX_TYPE_32_BIT 2
+ enum V3D33_Primitive mode;
+};
+
+static inline void
+V3D33_INDEXED_INSTANCED_PRIMITIVE_LIST_pack(__gen_user_data *data, uint8_t * restrict cl,
+ const struct V3D33_INDEXED_INSTANCED_PRIMITIVE_LIST * restrict values)
+{
+ cl[ 0] = __gen_uint(values->opcode, 0, 7);
+
+ cl[ 1] = __gen_uint(values->index_type, 6, 7) |
+ __gen_uint(values->mode, 0, 4);
+
+
+ memcpy(&cl[2], &values->instance_length, sizeof(values->instance_length));
+
+ memcpy(&cl[6], &values->number_of_instances, sizeof(values->number_of_instances));
+ __gen_emit_reloc(data, &values->address_of_indices_list);
+ cl[10] = __gen_address_offset(&values->address_of_indices_list);
+
+ cl[11] = __gen_address_offset(&values->address_of_indices_list) >> 8;
+
+ cl[12] = __gen_address_offset(&values->address_of_indices_list) >> 16;
+
+ cl[13] = __gen_address_offset(&values->address_of_indices_list) >> 24;
+
+ cl[14] = __gen_uint(values->maximum_index, 0, 30);
+
+ cl[15] = __gen_uint(values->maximum_index, 0, 30) >> 8;
+
+ cl[16] = __gen_uint(values->maximum_index, 0, 30) >> 16;
+
+ cl[17] = __gen_uint(values->enable_primitive_restarts, 7, 7) |
+ __gen_uint(values->maximum_index, 0, 30) >> 24;
+
+}
+
+#define V3D33_INDEXED_INSTANCED_PRIMITIVE_LIST_length 18
+#ifdef __gen_unpack_address
+static inline void
+V3D33_INDEXED_INSTANCED_PRIMITIVE_LIST_unpack(const uint8_t * restrict cl,
+ struct V3D33_INDEXED_INSTANCED_PRIMITIVE_LIST * restrict values)
+{
+ values->opcode = __gen_unpack_uint(cl, 0, 7);
+ values->enable_primitive_restarts = __gen_unpack_uint(cl, 143, 143);
+ values->maximum_index = __gen_unpack_uint(cl, 112, 142);
+ values->address_of_indices_list = __gen_unpack_address(cl, 80, 111);
+ values->number_of_instances = __gen_unpack_uint(cl, 48, 79);
+ values->instance_length = __gen_unpack_uint(cl, 16, 47);
+ values->index_type = __gen_unpack_uint(cl, 14, 15);
+ values->mode = __gen_unpack_uint(cl, 8, 12);
+}
+#endif
+
+
+#define V3D33_VERTEX_ARRAY_PRIMITIVES_opcode 36
+#define V3D33_VERTEX_ARRAY_PRIMITIVES_header \
+ .opcode = 36
+
+struct V3D33_VERTEX_ARRAY_PRIMITIVES {
+ uint32_t opcode;
+ uint32_t index_of_first_vertex;
+ uint32_t length;
+ enum V3D33_Primitive mode;
+};
+
+static inline void
+V3D33_VERTEX_ARRAY_PRIMITIVES_pack(__gen_user_data *data, uint8_t * restrict cl,
+ const struct V3D33_VERTEX_ARRAY_PRIMITIVES * restrict values)
+{
+ cl[ 0] = __gen_uint(values->opcode, 0, 7);
+
+ cl[ 1] = __gen_uint(values->mode, 0, 7);
+
+
+ memcpy(&cl[2], &values->length, sizeof(values->length));
+
+ memcpy(&cl[6], &values->index_of_first_vertex, sizeof(values->index_of_first_vertex));
+}
+
+#define V3D33_VERTEX_ARRAY_PRIMITIVES_length 10
+#ifdef __gen_unpack_address
+static inline void
+V3D33_VERTEX_ARRAY_PRIMITIVES_unpack(const uint8_t * restrict cl,
+ struct V3D33_VERTEX_ARRAY_PRIMITIVES * restrict values)
+{
+ values->opcode = __gen_unpack_uint(cl, 0, 7);
+ values->index_of_first_vertex = __gen_unpack_uint(cl, 48, 79);
+ values->length = __gen_unpack_uint(cl, 16, 47);
+ values->mode = __gen_unpack_uint(cl, 8, 15);
+}
+#endif
+
+
+#define V3D33_VERTEX_ARRAY_INSTANCED_PRIMITIVES_opcode 38
+#define V3D33_VERTEX_ARRAY_INSTANCED_PRIMITIVES_header\
+ .opcode = 38
+
+struct V3D33_VERTEX_ARRAY_INSTANCED_PRIMITIVES {
+ uint32_t opcode;
+ uint32_t index_of_first_vertex;
+ uint32_t number_of_instances;
+ uint32_t instance_length;
+ enum V3D33_Primitive mode;
+};
+
+static inline void
+V3D33_VERTEX_ARRAY_INSTANCED_PRIMITIVES_pack(__gen_user_data *data, uint8_t * restrict cl,
+ const struct V3D33_VERTEX_ARRAY_INSTANCED_PRIMITIVES * restrict values)
+{
+ cl[ 0] = __gen_uint(values->opcode, 0, 7);
+
+ cl[ 1] = __gen_uint(values->mode, 0, 7);
+
+
+ memcpy(&cl[2], &values->instance_length, sizeof(values->instance_length));
+
+ memcpy(&cl[6], &values->number_of_instances, sizeof(values->number_of_instances));
+
+ memcpy(&cl[10], &values->index_of_first_vertex, sizeof(values->index_of_first_vertex));
+}
+
+#define V3D33_VERTEX_ARRAY_INSTANCED_PRIMITIVES_length 14
+#ifdef __gen_unpack_address
+static inline void
+V3D33_VERTEX_ARRAY_INSTANCED_PRIMITIVES_unpack(const uint8_t * restrict cl,
+ struct V3D33_VERTEX_ARRAY_INSTANCED_PRIMITIVES * restrict values)
+{
+ values->opcode = __gen_unpack_uint(cl, 0, 7);
+ values->index_of_first_vertex = __gen_unpack_uint(cl, 80, 111);
+ values->number_of_instances = __gen_unpack_uint(cl, 48, 79);
+ values->instance_length = __gen_unpack_uint(cl, 16, 47);
+ values->mode = __gen_unpack_uint(cl, 8, 15);
+}
+#endif
+
+
+#define V3D33_BASE_VERTEX_BASE_INSTANCE_opcode 43
+#define V3D33_BASE_VERTEX_BASE_INSTANCE_header \
+ .opcode = 43
+
+struct V3D33_BASE_VERTEX_BASE_INSTANCE {
+ uint32_t opcode;
+ uint32_t base_instance;
+ uint32_t base_vertex;
+};
+
+static inline void
+V3D33_BASE_VERTEX_BASE_INSTANCE_pack(__gen_user_data *data, uint8_t * restrict cl,
+ const struct V3D33_BASE_VERTEX_BASE_INSTANCE * restrict values)
+{
+ cl[ 0] = __gen_uint(values->opcode, 0, 7);
+
+
+ memcpy(&cl[1], &values->base_vertex, sizeof(values->base_vertex));
+
+ memcpy(&cl[5], &values->base_instance, sizeof(values->base_instance));
+}
+
+#define V3D33_BASE_VERTEX_BASE_INSTANCE_length 9
+#ifdef __gen_unpack_address
+static inline void
+V3D33_BASE_VERTEX_BASE_INSTANCE_unpack(const uint8_t * restrict cl,
+ struct V3D33_BASE_VERTEX_BASE_INSTANCE * restrict values)
+{
+ values->opcode = __gen_unpack_uint(cl, 0, 7);
+ values->base_instance = __gen_unpack_uint(cl, 40, 71);
+ values->base_vertex = __gen_unpack_uint(cl, 8, 39);
+}
+#endif
+
+
+#define V3D33_PRIMITIVE_LIST_FORMAT_opcode 56
+#define V3D33_PRIMITIVE_LIST_FORMAT_header \
+ .opcode = 56
+
+struct V3D33_PRIMITIVE_LIST_FORMAT {
+ uint32_t opcode;
+ uint32_t data_type;
+#define LIST_INDEXED 0
+#define LIST_32_BIT_X_Y 1
+ uint32_t primitive_type;
+#define LIST_POINTS 0
+#define LIST_LINES 1
+#define LIST_TRIANGLES 2
+};
+
+static inline void
+V3D33_PRIMITIVE_LIST_FORMAT_pack(__gen_user_data *data, uint8_t * restrict cl,
+ const struct V3D33_PRIMITIVE_LIST_FORMAT * restrict values)
+{
+ cl[ 0] = __gen_uint(values->opcode, 0, 7);
+
+ cl[ 1] = __gen_uint(values->data_type, 6, 6) |
+ __gen_uint(values->primitive_type, 0, 5);
+
+}
+
+#define V3D33_PRIMITIVE_LIST_FORMAT_length 2
+#ifdef __gen_unpack_address
+static inline void
+V3D33_PRIMITIVE_LIST_FORMAT_unpack(const uint8_t * restrict cl,
+ struct V3D33_PRIMITIVE_LIST_FORMAT * restrict values)
+{
+ values->opcode = __gen_unpack_uint(cl, 0, 7);
+ values->data_type = __gen_unpack_uint(cl, 14, 14);
+ values->primitive_type = __gen_unpack_uint(cl, 8, 13);
+}
+#endif
+
+
+#define V3D33_GL_SHADER_STATE_opcode 64
+#define V3D33_GL_SHADER_STATE_header \
+ .opcode = 64
+
+struct V3D33_GL_SHADER_STATE {
+ uint32_t opcode;
+ __gen_address_type address;
+ uint32_t number_of_attribute_arrays;
+};
+
+static inline void
+V3D33_GL_SHADER_STATE_pack(__gen_user_data *data, uint8_t * restrict cl,
+ const struct V3D33_GL_SHADER_STATE * restrict values)
+{
+ cl[ 0] = __gen_uint(values->opcode, 0, 7);
+
+ __gen_emit_reloc(data, &values->address);
+ cl[ 1] = __gen_address_offset(&values->address) |
+ __gen_uint(values->number_of_attribute_arrays, 0, 4);
+
+ cl[ 2] = __gen_address_offset(&values->address) >> 8;
+
+ cl[ 3] = __gen_address_offset(&values->address) >> 16;
+
+ cl[ 4] = __gen_address_offset(&values->address) >> 24;
+
+}
+
+#define V3D33_GL_SHADER_STATE_length 5
+#ifdef __gen_unpack_address
+static inline void
+V3D33_GL_SHADER_STATE_unpack(const uint8_t * restrict cl,
+ struct V3D33_GL_SHADER_STATE * restrict values)
+{
+ values->opcode = __gen_unpack_uint(cl, 0, 7);
+ values->address = __gen_unpack_address(cl, 13, 39);
+ values->number_of_attribute_arrays = __gen_unpack_uint(cl, 8, 12);
+}
+#endif
+
+
+#define V3D33_TRANSFORM_FEEDBACK_ENABLE_opcode 74
+#define V3D33_TRANSFORM_FEEDBACK_ENABLE_header \
+ .opcode = 74
+
+struct V3D33_TRANSFORM_FEEDBACK_ENABLE {
+ uint32_t opcode;
+ uint32_t number_of_32_bit_output_buffer_address_following;
+ uint32_t number_of_16_bit_output_data_specs_following;
+};
+
+static inline void
+V3D33_TRANSFORM_FEEDBACK_ENABLE_pack(__gen_user_data *data, uint8_t * restrict cl,
+ const struct V3D33_TRANSFORM_FEEDBACK_ENABLE * restrict values)
+{
+ cl[ 0] = __gen_uint(values->opcode, 0, 7);
+
+ cl[ 1] = 0;
+ cl[ 2] = __gen_uint(values->number_of_32_bit_output_buffer_address_following, 0, 2) |
+ __gen_uint(values->number_of_16_bit_output_data_specs_following, 3, 7);
+
+}
+
+#define V3D33_TRANSFORM_FEEDBACK_ENABLE_length 3
+#ifdef __gen_unpack_address
+static inline void
+V3D33_TRANSFORM_FEEDBACK_ENABLE_unpack(const uint8_t * restrict cl,
+ struct V3D33_TRANSFORM_FEEDBACK_ENABLE * restrict values)
+{
+ values->opcode = __gen_unpack_uint(cl, 0, 7);
+ values->number_of_32_bit_output_buffer_address_following = __gen_unpack_uint(cl, 16, 18);
+ values->number_of_16_bit_output_data_specs_following = __gen_unpack_uint(cl, 19, 23);
+}
+#endif
+
+
+#define V3D33_FLUSH_TRANSFORM_FEEDBACK_DATA_opcode 75
+#define V3D33_FLUSH_TRANSFORM_FEEDBACK_DATA_header\
+ .opcode = 75
+
+struct V3D33_FLUSH_TRANSFORM_FEEDBACK_DATA {
+ uint32_t opcode;
+};
+
+static inline void
+V3D33_FLUSH_TRANSFORM_FEEDBACK_DATA_pack(__gen_user_data *data, uint8_t * restrict cl,
+ const struct V3D33_FLUSH_TRANSFORM_FEEDBACK_DATA * restrict values)
+{
+ cl[ 0] = __gen_uint(values->opcode, 0, 7);
+
+}
+
+#define V3D33_FLUSH_TRANSFORM_FEEDBACK_DATA_length 1
+#ifdef __gen_unpack_address
+static inline void
+V3D33_FLUSH_TRANSFORM_FEEDBACK_DATA_unpack(const uint8_t * restrict cl,
+ struct V3D33_FLUSH_TRANSFORM_FEEDBACK_DATA * restrict values)
+{
+ values->opcode = __gen_unpack_uint(cl, 0, 7);
+}
+#endif
+
+
+#define V3D33_TRANSFORM_FEEDBACK_OUTPUT_DATA_SPEC_header\
+
+
+struct V3D33_TRANSFORM_FEEDBACK_OUTPUT_DATA_SPEC {
+ uint32_t first_shaded_vertex_value_to_output;
+ uint32_t number_of_consecutive_vertex_values_to_output_as_32_bit_values_minus_1;
+ uint32_t output_buffer_to_write_to;
+};
+
+static inline void
+V3D33_TRANSFORM_FEEDBACK_OUTPUT_DATA_SPEC_pack(__gen_user_data *data, uint8_t * restrict cl,
+ const struct V3D33_TRANSFORM_FEEDBACK_OUTPUT_DATA_SPEC * restrict values)
+{
+ cl[ 0] = __gen_uint(values->first_shaded_vertex_value_to_output, 0, 7);
+
+ cl[ 1] = __gen_uint(values->number_of_consecutive_vertex_values_to_output_as_32_bit_values_minus_1, 0, 3) |
+ __gen_uint(values->output_buffer_to_write_to, 4, 5);
+
+}
+
+#define V3D33_TRANSFORM_FEEDBACK_OUTPUT_DATA_SPEC_length 2
+#ifdef __gen_unpack_address
+static inline void
+V3D33_TRANSFORM_FEEDBACK_OUTPUT_DATA_SPEC_unpack(const uint8_t * restrict cl,
+ struct V3D33_TRANSFORM_FEEDBACK_OUTPUT_DATA_SPEC * restrict values)
+{
+ values->first_shaded_vertex_value_to_output = __gen_unpack_uint(cl, 0, 7);
+ values->number_of_consecutive_vertex_values_to_output_as_32_bit_values_minus_1 = __gen_unpack_uint(cl, 8, 11);
+ values->output_buffer_to_write_to = __gen_unpack_uint(cl, 12, 13);
+}
+#endif
+
+
+#define V3D33_TRANSFORM_FEEDBACK_OUTPUT_ADDRESS_header\
+
+
+struct V3D33_TRANSFORM_FEEDBACK_OUTPUT_ADDRESS {
+ __gen_address_type address;
+};
+
+static inline void
+V3D33_TRANSFORM_FEEDBACK_OUTPUT_ADDRESS_pack(__gen_user_data *data, uint8_t * restrict cl,
+ const struct V3D33_TRANSFORM_FEEDBACK_OUTPUT_ADDRESS * restrict values)
+{
+ __gen_emit_reloc(data, &values->address);
+ cl[ 0] = __gen_address_offset(&values->address);
+
+ cl[ 1] = __gen_address_offset(&values->address) >> 8;
+
+ cl[ 2] = __gen_address_offset(&values->address) >> 16;
+
+ cl[ 3] = __gen_address_offset(&values->address) >> 24;
+
+}
+
+#define V3D33_TRANSFORM_FEEDBACK_OUTPUT_ADDRESS_length 4
+#ifdef __gen_unpack_address
+static inline void
+V3D33_TRANSFORM_FEEDBACK_OUTPUT_ADDRESS_unpack(const uint8_t * restrict cl,
+ struct V3D33_TRANSFORM_FEEDBACK_OUTPUT_ADDRESS * restrict values)
+{
+ values->address = __gen_unpack_address(cl, 0, 31);
+}
+#endif
+
+
+#define V3D33_STENCIL_CONFIG_opcode 80
+#define V3D33_STENCIL_CONFIG_header \
+ .opcode = 80
+
+struct V3D33_STENCIL_CONFIG {
+ uint32_t opcode;
+ uint32_t stencil_write_mask;
+ bool back_config;
+ bool front_config;
+ enum V3D33_Stencil_Op stencil_pass_op;
+ enum V3D33_Stencil_Op depth_test_fail_op;
+ enum V3D33_Stencil_Op stencil_test_fail_op;
+ enum V3D33_Compare_Function stencil_test_function;
+ uint32_t stencil_test_mask;
+ uint32_t stencil_ref_value;
+};
+
+static inline void
+V3D33_STENCIL_CONFIG_pack(__gen_user_data *data, uint8_t * restrict cl,
+ const struct V3D33_STENCIL_CONFIG * restrict values)
+{
+ cl[ 0] = __gen_uint(values->opcode, 0, 7);
+
+ cl[ 1] = __gen_uint(values->stencil_ref_value, 0, 7);
+
+ cl[ 2] = __gen_uint(values->stencil_test_mask, 0, 7);
+
+ cl[ 3] = __gen_uint(values->depth_test_fail_op, 6, 8) |
+ __gen_uint(values->stencil_test_fail_op, 3, 5) |
+ __gen_uint(values->stencil_test_function, 0, 2);
+
+ cl[ 4] = __gen_uint(values->back_config, 5, 5) |
+ __gen_uint(values->front_config, 4, 4) |
+ __gen_uint(values->stencil_pass_op, 1, 3) |
+ __gen_uint(values->depth_test_fail_op, 6, 8) >> 8;
+
+ cl[ 5] = __gen_uint(values->stencil_write_mask, 0, 7);
+
+}
+
+#define V3D33_STENCIL_CONFIG_length 6
+#ifdef __gen_unpack_address
+static inline void
+V3D33_STENCIL_CONFIG_unpack(const uint8_t * restrict cl,
+ struct V3D33_STENCIL_CONFIG * restrict values)
+{
+ values->opcode = __gen_unpack_uint(cl, 0, 7);
+ values->stencil_write_mask = __gen_unpack_uint(cl, 40, 47);
+ values->back_config = __gen_unpack_uint(cl, 37, 37);
+ values->front_config = __gen_unpack_uint(cl, 36, 36);
+ values->stencil_pass_op = __gen_unpack_uint(cl, 33, 35);
+ values->depth_test_fail_op = __gen_unpack_uint(cl, 30, 32);
+ values->stencil_test_fail_op = __gen_unpack_uint(cl, 27, 29);
+ values->stencil_test_function = __gen_unpack_uint(cl, 24, 26);
+ values->stencil_test_mask = __gen_unpack_uint(cl, 16, 23);
+ values->stencil_ref_value = __gen_unpack_uint(cl, 8, 15);
+}
+#endif
+
+
+#define V3D33_BLEND_CONFIG_opcode 84
+#define V3D33_BLEND_CONFIG_header \
+ .opcode = 84
+
+struct V3D33_BLEND_CONFIG {
+ uint32_t opcode;
+ uint32_t vg_coverage_modes;
+ enum V3D33_Blend_Factor colour_blend_dst_factor;
+ enum V3D33_Blend_Factor colour_blend_src_factor;
+ enum V3D33_Blend_Mode colour_blend_mode;
+ enum V3D33_Blend_Factor alpha_blend_dst_factor;
+ enum V3D33_Blend_Factor alpha_blend_src_factor;
+ enum V3D33_Blend_Mode alpha_blend_mode;
+};
+
+static inline void
+V3D33_BLEND_CONFIG_pack(__gen_user_data *data, uint8_t * restrict cl,
+ const struct V3D33_BLEND_CONFIG * restrict values)
+{
+ cl[ 0] = __gen_uint(values->opcode, 0, 7);
+
+ cl[ 1] = __gen_uint(values->alpha_blend_src_factor, 4, 7) |
+ __gen_uint(values->alpha_blend_mode, 0, 3);
+
+ cl[ 2] = __gen_uint(values->colour_blend_mode, 4, 7) |
+ __gen_uint(values->alpha_blend_dst_factor, 0, 3);
+
+ cl[ 3] = __gen_uint(values->colour_blend_dst_factor, 4, 7) |
+ __gen_uint(values->colour_blend_src_factor, 0, 3);
+
+ cl[ 4] = __gen_uint(values->vg_coverage_modes, 4, 5);
+
+}
+
+#define V3D33_BLEND_CONFIG_length 5
+#ifdef __gen_unpack_address
+static inline void
+V3D33_BLEND_CONFIG_unpack(const uint8_t * restrict cl,
+ struct V3D33_BLEND_CONFIG * restrict values)
+{
+ values->opcode = __gen_unpack_uint(cl, 0, 7);
+ values->vg_coverage_modes = __gen_unpack_uint(cl, 36, 37);
+ values->colour_blend_dst_factor = __gen_unpack_uint(cl, 28, 31);
+ values->colour_blend_src_factor = __gen_unpack_uint(cl, 24, 27);
+ values->colour_blend_mode = __gen_unpack_uint(cl, 20, 23);
+ values->alpha_blend_dst_factor = __gen_unpack_uint(cl, 16, 19);
+ values->alpha_blend_src_factor = __gen_unpack_uint(cl, 12, 15);
+ values->alpha_blend_mode = __gen_unpack_uint(cl, 8, 11);
+}
+#endif
+
+
+#define V3D33_BLEND_CONSTANT_COLOUR_opcode 86
+#define V3D33_BLEND_CONSTANT_COLOUR_header \
+ .opcode = 86
+
+struct V3D33_BLEND_CONSTANT_COLOUR {
+ uint32_t opcode;
+ uint32_t alpha_f16;
+ uint32_t blue_f16;
+ uint32_t green_f16;
+ uint32_t red_f16;
+};
+
+static inline void
+V3D33_BLEND_CONSTANT_COLOUR_pack(__gen_user_data *data, uint8_t * restrict cl,
+ const struct V3D33_BLEND_CONSTANT_COLOUR * restrict values)
+{
+ cl[ 0] = __gen_uint(values->opcode, 0, 7);
+
+ cl[ 1] = __gen_uint(values->red_f16, 0, 15);
+
+ cl[ 2] = __gen_uint(values->red_f16, 0, 15) >> 8;
+
+ cl[ 3] = __gen_uint(values->green_f16, 0, 15);
+
+ cl[ 4] = __gen_uint(values->green_f16, 0, 15) >> 8;
+
+ cl[ 5] = __gen_uint(values->blue_f16, 0, 15);
+
+ cl[ 6] = __gen_uint(values->blue_f16, 0, 15) >> 8;
+
+ cl[ 7] = __gen_uint(values->alpha_f16, 0, 15);
+
+ cl[ 8] = __gen_uint(values->alpha_f16, 0, 15) >> 8;
+
+}
+
+#define V3D33_BLEND_CONSTANT_COLOUR_length 9
+#ifdef __gen_unpack_address
+static inline void
+V3D33_BLEND_CONSTANT_COLOUR_unpack(const uint8_t * restrict cl,
+ struct V3D33_BLEND_CONSTANT_COLOUR * restrict values)
+{
+ values->opcode = __gen_unpack_uint(cl, 0, 7);
+ values->alpha_f16 = __gen_unpack_uint(cl, 56, 71);
+ values->blue_f16 = __gen_unpack_uint(cl, 40, 55);
+ values->green_f16 = __gen_unpack_uint(cl, 24, 39);
+ values->red_f16 = __gen_unpack_uint(cl, 8, 23);
+}
+#endif
+
+
+#define V3D33_COLOUR_WRITE_MASKS_opcode 87
+#define V3D33_COLOUR_WRITE_MASKS_header \
+ .opcode = 87
+
+struct V3D33_COLOUR_WRITE_MASKS {
+ uint32_t opcode;
+ uint32_t reserved;
+ uint32_t render_target_3_per_colour_component_write_masks;
+ uint32_t render_target_2_per_colour_component_write_masks;
+ uint32_t render_target_1_per_colour_component_write_masks;
+ uint32_t render_target_0_per_colour_component_write_masks;
+};
+
+static inline void
+V3D33_COLOUR_WRITE_MASKS_pack(__gen_user_data *data, uint8_t * restrict cl,
+ const struct V3D33_COLOUR_WRITE_MASKS * restrict values)
+{
+ cl[ 0] = __gen_uint(values->opcode, 0, 7);
+
+ cl[ 1] = __gen_uint(values->render_target_1_per_colour_component_write_masks, 4, 7) |
+ __gen_uint(values->render_target_0_per_colour_component_write_masks, 0, 3);
+
+ cl[ 2] = __gen_uint(values->render_target_3_per_colour_component_write_masks, 4, 7) |
+ __gen_uint(values->render_target_2_per_colour_component_write_masks, 0, 3);
+
+ cl[ 3] = __gen_uint(values->reserved, 0, 15);
+
+ cl[ 4] = __gen_uint(values->reserved, 0, 15) >> 8;
+
+}
+
+#define V3D33_COLOUR_WRITE_MASKS_length 5
+#ifdef __gen_unpack_address
+static inline void
+V3D33_COLOUR_WRITE_MASKS_unpack(const uint8_t * restrict cl,
+ struct V3D33_COLOUR_WRITE_MASKS * restrict values)
+{
+ values->opcode = __gen_unpack_uint(cl, 0, 7);
+ values->reserved = __gen_unpack_uint(cl, 24, 39);
+ values->render_target_3_per_colour_component_write_masks = __gen_unpack_uint(cl, 20, 23);
+ values->render_target_2_per_colour_component_write_masks = __gen_unpack_uint(cl, 16, 19);
+ values->render_target_1_per_colour_component_write_masks = __gen_unpack_uint(cl, 12, 15);
+ values->render_target_0_per_colour_component_write_masks = __gen_unpack_uint(cl, 8, 11);
+}
+#endif
+
+
+#define V3D33_CONFIGURATION_BITS_opcode 96
+#define V3D33_CONFIGURATION_BITS_header \
+ .opcode = 96
+
+struct V3D33_CONFIGURATION_BITS {
+ uint32_t opcode;
+ bool direct3d_provoking_vertex;
+ bool direct3d_point_fill_mode;
+ bool blend_enable;
+ bool stencil_enable;
+ bool early_z_updates_enable;
+ bool early_z_enable;
+ bool z_updates_enable;
+ enum V3D33_Compare_Function depth_test_function;
+ bool direct3d_wireframe_triangles_mode;
+ uint32_t coverage_update_mode;
+ bool coverage_pipe_select;
+ uint32_t rasterizer_oversample_mode;
+ uint32_t line_rasterization;
+ bool enable_depth_offset;
+ bool clockwise_primitives;
+ bool enable_reverse_facing_primitive;
+ bool enable_forward_facing_primitive;
+};
+
+static inline void
+V3D33_CONFIGURATION_BITS_pack(__gen_user_data *data, uint8_t * restrict cl,
+ const struct V3D33_CONFIGURATION_BITS * restrict values)
+{
+ cl[ 0] = __gen_uint(values->opcode, 0, 7);
+
+ cl[ 1] = __gen_uint(values->rasterizer_oversample_mode, 6, 7) |
+ __gen_uint(values->line_rasterization, 4, 5) |
+ __gen_uint(values->enable_depth_offset, 3, 3) |
+ __gen_uint(values->clockwise_primitives, 2, 2) |
+ __gen_uint(values->enable_reverse_facing_primitive, 1, 1) |
+ __gen_uint(values->enable_forward_facing_primitive, 0, 0);
+
+ cl[ 2] = __gen_uint(values->z_updates_enable, 7, 7) |
+ __gen_uint(values->depth_test_function, 4, 6) |
+ __gen_uint(values->direct3d_wireframe_triangles_mode, 3, 3) |
+ __gen_uint(values->coverage_update_mode, 1, 2) |
+ __gen_uint(values->coverage_pipe_select, 0, 0);
+
+ cl[ 3] = __gen_uint(values->direct3d_provoking_vertex, 5, 5) |
+ __gen_uint(values->direct3d_point_fill_mode, 4, 4) |
+ __gen_uint(values->blend_enable, 3, 3) |
+ __gen_uint(values->stencil_enable, 2, 2) |
+ __gen_uint(values->early_z_updates_enable, 1, 1) |
+ __gen_uint(values->early_z_enable, 0, 0);
+
+}
+
+#define V3D33_CONFIGURATION_BITS_length 4
+#ifdef __gen_unpack_address
+static inline void
+V3D33_CONFIGURATION_BITS_unpack(const uint8_t * restrict cl,
+ struct V3D33_CONFIGURATION_BITS * restrict values)
+{
+ values->opcode = __gen_unpack_uint(cl, 0, 7);
+ values->direct3d_provoking_vertex = __gen_unpack_uint(cl, 29, 29);
+ values->direct3d_point_fill_mode = __gen_unpack_uint(cl, 28, 28);
+ values->blend_enable = __gen_unpack_uint(cl, 27, 27);
+ values->stencil_enable = __gen_unpack_uint(cl, 26, 26);
+ values->early_z_updates_enable = __gen_unpack_uint(cl, 25, 25);
+ values->early_z_enable = __gen_unpack_uint(cl, 24, 24);
+ values->z_updates_enable = __gen_unpack_uint(cl, 23, 23);
+ values->depth_test_function = __gen_unpack_uint(cl, 20, 22);
+ values->direct3d_wireframe_triangles_mode = __gen_unpack_uint(cl, 19, 19);
+ values->coverage_update_mode = __gen_unpack_uint(cl, 17, 18);
+ values->coverage_pipe_select = __gen_unpack_uint(cl, 16, 16);
+ values->rasterizer_oversample_mode = __gen_unpack_uint(cl, 14, 15);
+ values->line_rasterization = __gen_unpack_uint(cl, 12, 13);
+ values->enable_depth_offset = __gen_unpack_uint(cl, 11, 11);
+ values->clockwise_primitives = __gen_unpack_uint(cl, 10, 10);
+ values->enable_reverse_facing_primitive = __gen_unpack_uint(cl, 9, 9);
+ values->enable_forward_facing_primitive = __gen_unpack_uint(cl, 8, 8);
+}
+#endif
+
+
+#define V3D33_ZERO_ALL_FLAT_SHADE_FLAGS_opcode 97
+#define V3D33_ZERO_ALL_FLAT_SHADE_FLAGS_header \
+ .opcode = 97
+
+struct V3D33_ZERO_ALL_FLAT_SHADE_FLAGS {
+ uint32_t opcode;
+};
+
+static inline void
+V3D33_ZERO_ALL_FLAT_SHADE_FLAGS_pack(__gen_user_data *data, uint8_t * restrict cl,
+ const struct V3D33_ZERO_ALL_FLAT_SHADE_FLAGS * restrict values)
+{
+ cl[ 0] = __gen_uint(values->opcode, 0, 7);
+
+}
+
+#define V3D33_ZERO_ALL_FLAT_SHADE_FLAGS_length 1
+#ifdef __gen_unpack_address
+static inline void
+V3D33_ZERO_ALL_FLAT_SHADE_FLAGS_unpack(const uint8_t * restrict cl,
+ struct V3D33_ZERO_ALL_FLAT_SHADE_FLAGS * restrict values)
+{
+ values->opcode = __gen_unpack_uint(cl, 0, 7);
+}
+#endif
+
+
+#define V3D33_FLAT_SHADE_FLAGS_opcode 98
+#define V3D33_FLAT_SHADE_FLAGS_header \
+ .opcode = 98
+
+struct V3D33_FLAT_SHADE_FLAGS {
+ uint32_t opcode;
+ uint32_t flat_shade_flags_for_varyings_v024;
+ uint32_t action_for_flat_shade_flags_of_higher_numbered_varyings;
+ uint32_t action_for_flat_shade_flags_of_lower_numbered_varyings;
+ uint32_t varying_offset_v0;
+};
+
+static inline void
+V3D33_FLAT_SHADE_FLAGS_pack(__gen_user_data *data, uint8_t * restrict cl,
+ const struct V3D33_FLAT_SHADE_FLAGS * restrict values)
+{
+ cl[ 0] = __gen_uint(values->opcode, 0, 7);
+
+ cl[ 1] = __gen_uint(values->action_for_flat_shade_flags_of_higher_numbered_varyings, 6, 7) |
+ __gen_uint(values->action_for_flat_shade_flags_of_lower_numbered_varyings, 4, 5) |
+ __gen_uint(values->varying_offset_v0, 0, 3);
+
+ cl[ 2] = __gen_uint(values->flat_shade_flags_for_varyings_v024, 0, 23);
+
+ cl[ 3] = __gen_uint(values->flat_shade_flags_for_varyings_v024, 0, 23) >> 8;
+
+ cl[ 4] = __gen_uint(values->flat_shade_flags_for_varyings_v024, 0, 23) >> 16;
+
+}
+
+#define V3D33_FLAT_SHADE_FLAGS_length 5
+#ifdef __gen_unpack_address
+static inline void
+V3D33_FLAT_SHADE_FLAGS_unpack(const uint8_t * restrict cl,
+ struct V3D33_FLAT_SHADE_FLAGS * restrict values)
+{
+ values->opcode = __gen_unpack_uint(cl, 0, 7);
+ values->flat_shade_flags_for_varyings_v024 = __gen_unpack_uint(cl, 16, 39);
+ values->action_for_flat_shade_flags_of_higher_numbered_varyings = __gen_unpack_uint(cl, 14, 15);
+ values->action_for_flat_shade_flags_of_lower_numbered_varyings = __gen_unpack_uint(cl, 12, 13);
+ values->varying_offset_v0 = __gen_unpack_uint(cl, 8, 11);
+}
+#endif
+
+
+#define V3D33_POINT_SIZE_opcode 104
+#define V3D33_POINT_SIZE_header \
+ .opcode = 104
+
+struct V3D33_POINT_SIZE {
+ uint32_t opcode;
+ float point_size;
+};
+
+static inline void
+V3D33_POINT_SIZE_pack(__gen_user_data *data, uint8_t * restrict cl,
+ const struct V3D33_POINT_SIZE * restrict values)
+{
+ cl[ 0] = __gen_uint(values->opcode, 0, 7);
+
+
+ memcpy(&cl[1], &values->point_size, sizeof(values->point_size));
+}
+
+#define V3D33_POINT_SIZE_length 5
+#ifdef __gen_unpack_address
+static inline void
+V3D33_POINT_SIZE_unpack(const uint8_t * restrict cl,
+ struct V3D33_POINT_SIZE * restrict values)
+{
+ values->opcode = __gen_unpack_uint(cl, 0, 7);
+ values->point_size = __gen_unpack_float(cl, 8, 39);
+}
+#endif
+
+
+#define V3D33_LINE_WIDTH_opcode 105
+#define V3D33_LINE_WIDTH_header \
+ .opcode = 105
+
+struct V3D33_LINE_WIDTH {
+ uint32_t opcode;
+ float line_width;
+};
+
+static inline void
+V3D33_LINE_WIDTH_pack(__gen_user_data *data, uint8_t * restrict cl,
+ const struct V3D33_LINE_WIDTH * restrict values)
+{
+ cl[ 0] = __gen_uint(values->opcode, 0, 7);
+
+
+ memcpy(&cl[1], &values->line_width, sizeof(values->line_width));
+}
+
+#define V3D33_LINE_WIDTH_length 5
+#ifdef __gen_unpack_address
+static inline void
+V3D33_LINE_WIDTH_unpack(const uint8_t * restrict cl,
+ struct V3D33_LINE_WIDTH * restrict values)
+{
+ values->opcode = __gen_unpack_uint(cl, 0, 7);
+ values->line_width = __gen_unpack_float(cl, 8, 39);
+}
+#endif
+
+
+#define V3D33_DEPTH_OFFSET_opcode 106
+#define V3D33_DEPTH_OFFSET_header \
+ .opcode = 106
+
+struct V3D33_DEPTH_OFFSET {
+ uint32_t opcode;
+ uint32_t depth_offset_units;
+ uint32_t depth_offset_factor;
+};
+
+static inline void
+V3D33_DEPTH_OFFSET_pack(__gen_user_data *data, uint8_t * restrict cl,
+ const struct V3D33_DEPTH_OFFSET * restrict values)
+{
+ cl[ 0] = __gen_uint(values->opcode, 0, 7);
+
+ cl[ 1] = __gen_uint(values->depth_offset_factor, 0, 15);
+
+ cl[ 2] = __gen_uint(values->depth_offset_factor, 0, 15) >> 8;
+
+ cl[ 3] = __gen_uint(values->depth_offset_units, 0, 15);
+
+ cl[ 4] = __gen_uint(values->depth_offset_units, 0, 15) >> 8;
+
+}
+
+#define V3D33_DEPTH_OFFSET_length 5
+#ifdef __gen_unpack_address
+static inline void
+V3D33_DEPTH_OFFSET_unpack(const uint8_t * restrict cl,
+ struct V3D33_DEPTH_OFFSET * restrict values)
+{
+ values->opcode = __gen_unpack_uint(cl, 0, 7);
+ values->depth_offset_units = __gen_unpack_uint(cl, 24, 39);
+ values->depth_offset_factor = __gen_unpack_uint(cl, 8, 23);
+}
+#endif
+
+
+#define V3D33_CLIP_WINDOW_opcode 107
+#define V3D33_CLIP_WINDOW_header \
+ .opcode = 107
+
+struct V3D33_CLIP_WINDOW {
+ uint32_t opcode;
+ uint32_t clip_window_height_in_pixels;
+ uint32_t clip_window_width_in_pixels;
+ uint32_t clip_window_bottom_pixel_coordinate;
+ uint32_t clip_window_left_pixel_coordinate;
+};
+
+static inline void
+V3D33_CLIP_WINDOW_pack(__gen_user_data *data, uint8_t * restrict cl,
+ const struct V3D33_CLIP_WINDOW * restrict values)
+{
+ cl[ 0] = __gen_uint(values->opcode, 0, 7);
+
+ cl[ 1] = __gen_uint(values->clip_window_left_pixel_coordinate, 0, 15);
+
+ cl[ 2] = __gen_uint(values->clip_window_left_pixel_coordinate, 0, 15) >> 8;
+
+ cl[ 3] = __gen_uint(values->clip_window_bottom_pixel_coordinate, 0, 15);
+
+ cl[ 4] = __gen_uint(values->clip_window_bottom_pixel_coordinate, 0, 15) >> 8;
+
+ cl[ 5] = __gen_uint(values->clip_window_width_in_pixels, 0, 15);
+
+ cl[ 6] = __gen_uint(values->clip_window_width_in_pixels, 0, 15) >> 8;
+
+ cl[ 7] = __gen_uint(values->clip_window_height_in_pixels, 0, 15);
+
+ cl[ 8] = __gen_uint(values->clip_window_height_in_pixels, 0, 15) >> 8;
+
+}
+
+#define V3D33_CLIP_WINDOW_length 9
+#ifdef __gen_unpack_address
+static inline void
+V3D33_CLIP_WINDOW_unpack(const uint8_t * restrict cl,
+ struct V3D33_CLIP_WINDOW * restrict values)
+{
+ values->opcode = __gen_unpack_uint(cl, 0, 7);
+ values->clip_window_height_in_pixels = __gen_unpack_uint(cl, 56, 71);
+ values->clip_window_width_in_pixels = __gen_unpack_uint(cl, 40, 55);
+ values->clip_window_bottom_pixel_coordinate = __gen_unpack_uint(cl, 24, 39);
+ values->clip_window_left_pixel_coordinate = __gen_unpack_uint(cl, 8, 23);
+}
+#endif
+
+
+#define V3D33_VIEWPORT_OFFSET_opcode 108
+#define V3D33_VIEWPORT_OFFSET_header \
+ .opcode = 108
+
+struct V3D33_VIEWPORT_OFFSET {
+ uint32_t opcode;
+ float viewport_centre_y_coordinate;
+ float viewport_centre_x_coordinate;
+};
+
+static inline void
+V3D33_VIEWPORT_OFFSET_pack(__gen_user_data *data, uint8_t * restrict cl,
+ const struct V3D33_VIEWPORT_OFFSET * restrict values)
+{
+ cl[ 0] = __gen_uint(values->opcode, 0, 7);
+
+ cl[ 1] = __gen_sfixed(values->viewport_centre_x_coordinate, 0, 31, 8);
+
+ cl[ 2] = __gen_sfixed(values->viewport_centre_x_coordinate, 0, 31, 8) >> 8;
+
+ cl[ 3] = __gen_sfixed(values->viewport_centre_x_coordinate, 0, 31, 8) >> 16;
+
+ cl[ 4] = __gen_sfixed(values->viewport_centre_x_coordinate, 0, 31, 8) >> 24;
+
+ cl[ 5] = __gen_sfixed(values->viewport_centre_y_coordinate, 0, 31, 8);
+
+ cl[ 6] = __gen_sfixed(values->viewport_centre_y_coordinate, 0, 31, 8) >> 8;
+
+ cl[ 7] = __gen_sfixed(values->viewport_centre_y_coordinate, 0, 31, 8) >> 16;
+
+ cl[ 8] = __gen_sfixed(values->viewport_centre_y_coordinate, 0, 31, 8) >> 24;
+
+}
+
+#define V3D33_VIEWPORT_OFFSET_length 9
+#ifdef __gen_unpack_address
+static inline void
+V3D33_VIEWPORT_OFFSET_unpack(const uint8_t * restrict cl,
+ struct V3D33_VIEWPORT_OFFSET * restrict values)
+{
+ values->opcode = __gen_unpack_uint(cl, 0, 7);
+ values->viewport_centre_y_coordinate = __gen_unpack_sfixed(cl, 40, 71, 8);
+ values->viewport_centre_x_coordinate = __gen_unpack_sfixed(cl, 8, 39, 8);
+}
+#endif
+
+
+#define V3D33_CLIPPER_Z_MIN_MAX_CLIPPING_PLANES_opcode 109
+#define V3D33_CLIPPER_Z_MIN_MAX_CLIPPING_PLANES_header\
+ .opcode = 109
+
+struct V3D33_CLIPPER_Z_MIN_MAX_CLIPPING_PLANES {
+ uint32_t opcode;
+ float maximum_zw;
+ float minimum_zw;
+};
+
+static inline void
+V3D33_CLIPPER_Z_MIN_MAX_CLIPPING_PLANES_pack(__gen_user_data *data, uint8_t * restrict cl,
+ const struct V3D33_CLIPPER_Z_MIN_MAX_CLIPPING_PLANES * restrict values)
+{
+ cl[ 0] = __gen_uint(values->opcode, 0, 7);
+
+
+ memcpy(&cl[1], &values->minimum_zw, sizeof(values->minimum_zw));
+
+ memcpy(&cl[5], &values->maximum_zw, sizeof(values->maximum_zw));
+}
+
+#define V3D33_CLIPPER_Z_MIN_MAX_CLIPPING_PLANES_length 9
+#ifdef __gen_unpack_address
+static inline void
+V3D33_CLIPPER_Z_MIN_MAX_CLIPPING_PLANES_unpack(const uint8_t * restrict cl,
+ struct V3D33_CLIPPER_Z_MIN_MAX_CLIPPING_PLANES * restrict values)
+{
+ values->opcode = __gen_unpack_uint(cl, 0, 7);
+ values->maximum_zw = __gen_unpack_float(cl, 40, 71);
+ values->minimum_zw = __gen_unpack_float(cl, 8, 39);
+}
+#endif
+
+
+#define V3D33_CLIPPER_XY_SCALING_opcode 110
+#define V3D33_CLIPPER_XY_SCALING_header \
+ .opcode = 110
+
+struct V3D33_CLIPPER_XY_SCALING {
+ uint32_t opcode;
+ float viewport_half_height_in_1_256th_of_pixel;
+ float viewport_half_width_in_1_256th_of_pixel;
+};
+
+static inline void
+V3D33_CLIPPER_XY_SCALING_pack(__gen_user_data *data, uint8_t * restrict cl,
+ const struct V3D33_CLIPPER_XY_SCALING * restrict values)
+{
+ cl[ 0] = __gen_uint(values->opcode, 0, 7);
+
+
+ memcpy(&cl[1], &values->viewport_half_width_in_1_256th_of_pixel, sizeof(values->viewport_half_width_in_1_256th_of_pixel));
+
+ memcpy(&cl[5], &values->viewport_half_height_in_1_256th_of_pixel, sizeof(values->viewport_half_height_in_1_256th_of_pixel));
+}
+
+#define V3D33_CLIPPER_XY_SCALING_length 9
+#ifdef __gen_unpack_address
+static inline void
+V3D33_CLIPPER_XY_SCALING_unpack(const uint8_t * restrict cl,
+ struct V3D33_CLIPPER_XY_SCALING * restrict values)
+{
+ values->opcode = __gen_unpack_uint(cl, 0, 7);
+ values->viewport_half_height_in_1_256th_of_pixel = __gen_unpack_float(cl, 40, 71);
+ values->viewport_half_width_in_1_256th_of_pixel = __gen_unpack_float(cl, 8, 39);
+}
+#endif
+
+
+#define V3D33_CLIPPER_Z_SCALE_AND_OFFSET_opcode 111
+#define V3D33_CLIPPER_Z_SCALE_AND_OFFSET_header \
+ .opcode = 111
+
+struct V3D33_CLIPPER_Z_SCALE_AND_OFFSET {
+ uint32_t opcode;
+ float viewport_z_offset_zc_to_zs;
+ float viewport_z_scale_zc_to_zs;
+};
+
+static inline void
+V3D33_CLIPPER_Z_SCALE_AND_OFFSET_pack(__gen_user_data *data, uint8_t * restrict cl,
+ const struct V3D33_CLIPPER_Z_SCALE_AND_OFFSET * restrict values)
+{
+ cl[ 0] = __gen_uint(values->opcode, 0, 7);
+
+
+ memcpy(&cl[1], &values->viewport_z_scale_zc_to_zs, sizeof(values->viewport_z_scale_zc_to_zs));
+
+ memcpy(&cl[5], &values->viewport_z_offset_zc_to_zs, sizeof(values->viewport_z_offset_zc_to_zs));
+}
+
+#define V3D33_CLIPPER_Z_SCALE_AND_OFFSET_length 9
+#ifdef __gen_unpack_address
+static inline void
+V3D33_CLIPPER_Z_SCALE_AND_OFFSET_unpack(const uint8_t * restrict cl,
+ struct V3D33_CLIPPER_Z_SCALE_AND_OFFSET * restrict values)
+{
+ values->opcode = __gen_unpack_uint(cl, 0, 7);
+ values->viewport_z_offset_zc_to_zs = __gen_unpack_float(cl, 40, 71);
+ values->viewport_z_scale_zc_to_zs = __gen_unpack_float(cl, 8, 39);
+}
+#endif
+
+
+#define V3D33_TILE_BINNING_MODE_CONFIGURATION_PART1_opcode 120
+#define V3D33_TILE_BINNING_MODE_CONFIGURATION_PART1_header\
+ .opcode = 120, \
+ .auto_initialize_tile_state_data_array = 1, \
+ .sub_id = 0
+
+struct V3D33_TILE_BINNING_MODE_CONFIGURATION_PART1 {
+ uint32_t opcode;
+ bool double_buffer_in_non_ms_mode;
+ bool multisample_mode_4x;
+ uint32_t maximum_bpp_of_all_render_targets;
+#define RENDER_TARGET_MAXIMUM_32BPP 0
+#define RENDER_TARGET_MAXIMUM_64BPP 1
+#define RENDER_TARGET_MAXIMUM_128BPP 2
+ uint32_t number_of_render_targets;
+ uint32_t height_in_tiles;
+ uint32_t width_in_tiles;
+ __gen_address_type tile_state_data_array_base_address;
+ uint32_t tile_allocation_block_size;
+#define TILE_ALLOCATION_BLOCK_SIZE_64B 0
+#define TILE_ALLOCATION_BLOCK_SIZE_128B 1
+#define TILE_ALLOCATION_BLOCK_SIZE_256B 2
+ uint32_t tile_allocation_initial_block_size;
+#define TILE_ALLOCATION_INITIAL_BLOCK_SIZE_64B 0
+#define TILE_ALLOCATION_INITIAL_BLOCK_SIZE_128B 1
+#define TILE_ALLOCATION_INITIAL_BLOCK_SIZE_256B 2
+ bool auto_initialize_tile_state_data_array;
+ uint32_t sub_id;
+};
+
+static inline void
+V3D33_TILE_BINNING_MODE_CONFIGURATION_PART1_pack(__gen_user_data *data, uint8_t * restrict cl,
+ const struct V3D33_TILE_BINNING_MODE_CONFIGURATION_PART1 * restrict values)
+{
+ cl[ 0] = __gen_uint(values->opcode, 0, 7);
+
+ __gen_emit_reloc(data, &values->tile_state_data_array_base_address);
+ cl[ 1] = __gen_address_offset(&values->tile_state_data_array_base_address) |
+ __gen_uint(values->tile_allocation_block_size, 4, 5) |
+ __gen_uint(values->tile_allocation_initial_block_size, 2, 3) |
+ __gen_uint(values->auto_initialize_tile_state_data_array, 1, 1) |
+ __gen_uint(values->sub_id, 0, 0);
+
+ cl[ 2] = __gen_address_offset(&values->tile_state_data_array_base_address) >> 8;
+
+ cl[ 3] = __gen_address_offset(&values->tile_state_data_array_base_address) >> 16;
+
+ cl[ 4] = __gen_address_offset(&values->tile_state_data_array_base_address) >> 24;
+
+ cl[ 5] = __gen_uint(values->width_in_tiles, 0, 11);
+
+ cl[ 6] = __gen_uint(values->height_in_tiles, 4, 15) |
+ __gen_uint(values->width_in_tiles, 0, 11) >> 8;
+
+ cl[ 7] = __gen_uint(values->height_in_tiles, 4, 15) >> 8;
+
+ cl[ 8] = __gen_uint(values->double_buffer_in_non_ms_mode, 7, 7) |
+ __gen_uint(values->multisample_mode_4x, 6, 6) |
+ __gen_uint(values->maximum_bpp_of_all_render_targets, 4, 5) |
+ __gen_uint(values->number_of_render_targets, 0, 3);
+
+}
+
+#define V3D33_TILE_BINNING_MODE_CONFIGURATION_PART1_length 9
+#ifdef __gen_unpack_address
+static inline void
+V3D33_TILE_BINNING_MODE_CONFIGURATION_PART1_unpack(const uint8_t * restrict cl,
+ struct V3D33_TILE_BINNING_MODE_CONFIGURATION_PART1 * restrict values)
+{
+ values->opcode = __gen_unpack_uint(cl, 0, 7);
+ values->double_buffer_in_non_ms_mode = __gen_unpack_uint(cl, 71, 71);
+ values->multisample_mode_4x = __gen_unpack_uint(cl, 70, 70);
+ values->maximum_bpp_of_all_render_targets = __gen_unpack_uint(cl, 68, 69);
+ values->number_of_render_targets = __gen_unpack_uint(cl, 64, 67);
+ values->height_in_tiles = __gen_unpack_uint(cl, 52, 63);
+ values->width_in_tiles = __gen_unpack_uint(cl, 40, 51);
+ values->tile_state_data_array_base_address = __gen_unpack_address(cl, 8, 39);
+ values->tile_allocation_block_size = __gen_unpack_uint(cl, 12, 13);
+ values->tile_allocation_initial_block_size = __gen_unpack_uint(cl, 10, 11);
+ values->auto_initialize_tile_state_data_array = __gen_unpack_uint(cl, 9, 9);
+ values->sub_id = __gen_unpack_uint(cl, 8, 8);
+}
+#endif
+
+
+#define V3D33_TILE_BINNING_MODE_CONFIGURATION_PART2_opcode 120
+#define V3D33_TILE_BINNING_MODE_CONFIGURATION_PART2_header\
+ .opcode = 120, \
+ .sub_id = 1
+
+struct V3D33_TILE_BINNING_MODE_CONFIGURATION_PART2 {
+ uint32_t opcode;
+ __gen_address_type tile_allocation_memory_address;
+ uint32_t tile_allocation_memory_size;
+ uint32_t sub_id;
+};
+
+static inline void
+V3D33_TILE_BINNING_MODE_CONFIGURATION_PART2_pack(__gen_user_data *data, uint8_t * restrict cl,
+ const struct V3D33_TILE_BINNING_MODE_CONFIGURATION_PART2 * restrict values)
+{
+ cl[ 0] = __gen_uint(values->opcode, 0, 7);
+
+ cl[ 1] = __gen_uint(values->tile_allocation_memory_size, 0, 31) |
+ __gen_uint(values->sub_id, 0, 0);
+
+ cl[ 2] = __gen_uint(values->tile_allocation_memory_size, 0, 31) >> 8;
+
+ cl[ 3] = __gen_uint(values->tile_allocation_memory_size, 0, 31) >> 16;
+
+ cl[ 4] = __gen_uint(values->tile_allocation_memory_size, 0, 31) >> 24;
+
+ __gen_emit_reloc(data, &values->tile_allocation_memory_address);
+ cl[ 5] = __gen_address_offset(&values->tile_allocation_memory_address);
+
+ cl[ 6] = __gen_address_offset(&values->tile_allocation_memory_address) >> 8;
+
+ cl[ 7] = __gen_address_offset(&values->tile_allocation_memory_address) >> 16;
+
+ cl[ 8] = __gen_address_offset(&values->tile_allocation_memory_address) >> 24;
+
+}
+
+#define V3D33_TILE_BINNING_MODE_CONFIGURATION_PART2_length 9
+#ifdef __gen_unpack_address
+static inline void
+V3D33_TILE_BINNING_MODE_CONFIGURATION_PART2_unpack(const uint8_t * restrict cl,
+ struct V3D33_TILE_BINNING_MODE_CONFIGURATION_PART2 * restrict values)
+{
+ values->opcode = __gen_unpack_uint(cl, 0, 7);
+ values->tile_allocation_memory_address = __gen_unpack_address(cl, 40, 71);
+ values->tile_allocation_memory_size = __gen_unpack_uint(cl, 8, 39);
+ values->sub_id = __gen_unpack_uint(cl, 8, 8);
+}
+#endif
+
+
+#define V3D33_TILE_RENDERING_MODE_CONFIGURATION_COMMON_CONFIGURATION_opcode 121
+#define V3D33_TILE_RENDERING_MODE_CONFIGURATION_COMMON_CONFIGURATION_header\
+ .opcode = 121, \
+ .sub_id = 0
+
+struct V3D33_TILE_RENDERING_MODE_CONFIGURATION_COMMON_CONFIGURATION {
+ uint32_t opcode;
+ uint32_t disable_render_target_stores;
+ bool enable_z_store;
+ bool enable_stencil_store;
+ bool early_z_disable;
+ uint32_t early_z_test_and_update_direction;
+#define EARLY_Z_DIRECTION_LT_LE 0
+#define EARLY_Z_DIRECTION_GT_GE 1
+ bool select_coverage_mode;
+ bool double_buffer_in_non_ms_mode;
+ bool multisample_mode_4x;
+ uint32_t maximum_bpp_of_all_render_targets;
+#define RENDER_TARGET_MAXIMUM_32BPP 0
+#define RENDER_TARGET_MAXIMUM_64BPP 1
+#define RENDER_TARGET_MAXIMUM_128BPP 2
+ uint32_t image_height_pixels;
+ uint32_t image_width_pixels;
+ uint32_t number_of_render_targets_minus_1;
+ uint32_t sub_id;
+};
+
+static inline void
+V3D33_TILE_RENDERING_MODE_CONFIGURATION_COMMON_CONFIGURATION_pack(__gen_user_data *data, uint8_t * restrict cl,
+ const struct V3D33_TILE_RENDERING_MODE_CONFIGURATION_COMMON_CONFIGURATION * restrict values)
+{
+ cl[ 0] = __gen_uint(values->opcode, 0, 7);
+
+ cl[ 1] = __gen_uint(values->number_of_render_targets_minus_1, 4, 7) |
+ __gen_uint(values->sub_id, 0, 3);
+
+ cl[ 2] = __gen_uint(values->image_width_pixels, 0, 15);
+
+ cl[ 3] = __gen_uint(values->image_width_pixels, 0, 15) >> 8;
+
+ cl[ 4] = __gen_uint(values->image_height_pixels, 0, 15);
+
+ cl[ 5] = __gen_uint(values->image_height_pixels, 0, 15) >> 8;
+
+ cl[ 6] = __gen_uint(values->early_z_disable, 6, 6) |
+ __gen_uint(values->early_z_test_and_update_direction, 5, 5) |
+ __gen_uint(values->select_coverage_mode, 4, 4) |
+ __gen_uint(values->double_buffer_in_non_ms_mode, 3, 3) |
+ __gen_uint(values->multisample_mode_4x, 2, 2) |
+ __gen_uint(values->maximum_bpp_of_all_render_targets, 0, 1);
+
+ cl[ 7] = __gen_uint(values->enable_z_store, 7, 7) |
+ __gen_uint(values->enable_stencil_store, 6, 6);
+
+ cl[ 8] = __gen_uint(values->disable_render_target_stores, 0, 7);
+
+}
+
+#define V3D33_TILE_RENDERING_MODE_CONFIGURATION_COMMON_CONFIGURATION_length 9
+#ifdef __gen_unpack_address
+static inline void
+V3D33_TILE_RENDERING_MODE_CONFIGURATION_COMMON_CONFIGURATION_unpack(const uint8_t * restrict cl,
+ struct V3D33_TILE_RENDERING_MODE_CONFIGURATION_COMMON_CONFIGURATION * restrict values)
+{
+ values->opcode = __gen_unpack_uint(cl, 0, 7);
+ values->disable_render_target_stores = __gen_unpack_uint(cl, 64, 71);
+ values->enable_z_store = __gen_unpack_uint(cl, 63, 63);
+ values->enable_stencil_store = __gen_unpack_uint(cl, 62, 62);
+ values->early_z_disable = __gen_unpack_uint(cl, 54, 54);
+ values->early_z_test_and_update_direction = __gen_unpack_uint(cl, 53, 53);
+ values->select_coverage_mode = __gen_unpack_uint(cl, 52, 52);
+ values->double_buffer_in_non_ms_mode = __gen_unpack_uint(cl, 51, 51);
+ values->multisample_mode_4x = __gen_unpack_uint(cl, 50, 50);
+ values->maximum_bpp_of_all_render_targets = __gen_unpack_uint(cl, 48, 49);
+ values->image_height_pixels = __gen_unpack_uint(cl, 32, 47);
+ values->image_width_pixels = __gen_unpack_uint(cl, 16, 31);
+ values->number_of_render_targets_minus_1 = __gen_unpack_uint(cl, 12, 15);
+ values->sub_id = __gen_unpack_uint(cl, 8, 11);
+}
+#endif
+
+
+#define V3D33_TILE_RENDERING_MODE_CONFIGURATION_RENDER_TARGET_CONFIG_opcode 121
+#define V3D33_TILE_RENDERING_MODE_CONFIGURATION_RENDER_TARGET_CONFIG_header\
+ .opcode = 121, \
+ .sub_id = 2
+
+struct V3D33_TILE_RENDERING_MODE_CONFIGURATION_RENDER_TARGET_CONFIG {
+ uint32_t opcode;
+ __gen_address_type address;
+ uint32_t pad;
+ bool flip_y;
+ uint32_t memory_format;
+#define MEMORY_FORMAT_RASTER 0
+#define MEMORY_FORMAT_LINEARTILE 1
+#define MEMORY_FORMAT_UB_LINEAR_1_UIF_BLOCK_WIDE 2
+#define MEMORY_FORMAT_UB_LINEAR_2_UIF_BLOCKS_WIDE 3
+#define MEMORY_FORMAT_UIF_NO_XOR 4
+#define MEMORY_FORMAT_UIF_XOR 5
+ bool a_dithered;
+ bool bgr_dithered;
+ uint32_t output_image_format;
+#define OUTPUT_IMAGE_FORMAT_SRGB8_ALPHA8 0
+#define OUTPUT_IMAGE_FORMAT_SRGB 1
+#define OUTPUT_IMAGE_FORMAT_RGB10_A2UI 2
+#define OUTPUT_IMAGE_FORMAT_RGB10_A2 3
+#define OUTPUT_IMAGE_FORMAT_ABGR1555 4
+#define OUTPUT_IMAGE_FORMAT_ALPHA_MASKED_ABGR1555 5
+#define OUTPUT_IMAGE_FORMAT_ABGR4444 6
+#define OUTPUT_IMAGE_FORMAT_BGR565 7
+#define OUTPUT_IMAGE_FORMAT_R11F_G11F_B10F 8
+#define OUTPUT_IMAGE_FORMAT_RGBA32F 9
+#define OUTPUT_IMAGE_FORMAT_RG32F 10
+#define OUTPUT_IMAGE_FORMAT_R32F 11
+#define OUTPUT_IMAGE_FORMAT_RGBA32I 12
+#define OUTPUT_IMAGE_FORMAT_RG32I 13
+#define OUTPUT_IMAGE_FORMAT_R32I 14
+#define OUTPUT_IMAGE_FORMAT_RGBA32UI 15
+#define OUTPUT_IMAGE_FORMAT_RG32UI 16
+#define OUTPUT_IMAGE_FORMAT_R32UI 17
+#define OUTPUT_IMAGE_FORMAT_RGBA16F 18
+#define OUTPUT_IMAGE_FORMAT_RG16F 19
+#define OUTPUT_IMAGE_FORMAT_R16F 20
+#define OUTPUT_IMAGE_FORMAT_RGBA16I 21
+#define OUTPUT_IMAGE_FORMAT_RG16I 22
+#define OUTPUT_IMAGE_FORMAT_R16I 23
+#define OUTPUT_IMAGE_FORMAT_RGBA16UI 24
+#define OUTPUT_IMAGE_FORMAT_RG16UI 25
+#define OUTPUT_IMAGE_FORMAT_R16UI 26
+#define OUTPUT_IMAGE_FORMAT_RGBA8 27
+#define OUTPUT_IMAGE_FORMAT_RGB8 28
+#define OUTPUT_IMAGE_FORMAT_RG8 29
+#define OUTPUT_IMAGE_FORMAT_R8 30
+#define OUTPUT_IMAGE_FORMAT_RGBA8I 31
+#define OUTPUT_IMAGE_FORMAT_RG8I 32
+#define OUTPUT_IMAGE_FORMAT_R8I 33
+#define OUTPUT_IMAGE_FORMAT_RGBA8UI 34
+#define OUTPUT_IMAGE_FORMAT_RG8UI 35
+#define OUTPUT_IMAGE_FORMAT_R8UI 36
+#define OUTPUT_IMAGE_FORMAT_SRGBX8 37
+#define OUTPUT_IMAGE_FORMAT_RGBX8 38
+ uint32_t decimate_mode;
+ uint32_t internal_type;
+#define INTERNAL_TYPE_8I 0
+#define INTERNAL_TYPE_8UI 1
+#define INTERNAL_TYPE_8 2
+#define INTERNAL_TYPE_16I 4
+#define INTERNAL_TYPE_16UI 5
+#define INTERNAL_TYPE_16F 6
+#define INTERNAL_TYPE_32I 8
+#define INTERNAL_TYPE_32UI 9
+#define INTERNAL_TYPE_32F 10
+ uint32_t internal_bpp;
+#define INTERNAL_BPP_32 0
+#define INTERNAL_BPP_64 1
+#define INTERNAL_BPP_128 2
+ uint32_t render_target_number;
+ uint32_t sub_id;
+};
+
+static inline void
+V3D33_TILE_RENDERING_MODE_CONFIGURATION_RENDER_TARGET_CONFIG_pack(__gen_user_data *data, uint8_t * restrict cl,
+ const struct V3D33_TILE_RENDERING_MODE_CONFIGURATION_RENDER_TARGET_CONFIG * restrict values)
+{
+ cl[ 0] = __gen_uint(values->opcode, 0, 7);
+
+ cl[ 1] = __gen_uint(values->render_target_number, 4, 7) |
+ __gen_uint(values->sub_id, 0, 3);
+
+ cl[ 2] = __gen_uint(values->decimate_mode, 6, 7) |
+ __gen_uint(values->internal_type, 2, 5) |
+ __gen_uint(values->internal_bpp, 0, 1);
+
+ cl[ 3] = __gen_uint(values->a_dithered, 7, 7) |
+ __gen_uint(values->bgr_dithered, 6, 6) |
+ __gen_uint(values->output_image_format, 0, 5);
+
+ cl[ 4] = __gen_uint(values->pad, 4, 7) |
+ __gen_uint(values->flip_y, 3, 3) |
+ __gen_uint(values->memory_format, 0, 2);
+
+ __gen_emit_reloc(data, &values->address);
+ cl[ 5] = __gen_address_offset(&values->address);
+
+ cl[ 6] = __gen_address_offset(&values->address) >> 8;
+
+ cl[ 7] = __gen_address_offset(&values->address) >> 16;
+
+ cl[ 8] = __gen_address_offset(&values->address) >> 24;
+
+}
+
+#define V3D33_TILE_RENDERING_MODE_CONFIGURATION_RENDER_TARGET_CONFIG_length 9
+#ifdef __gen_unpack_address
+static inline void
+V3D33_TILE_RENDERING_MODE_CONFIGURATION_RENDER_TARGET_CONFIG_unpack(const uint8_t * restrict cl,
+ struct V3D33_TILE_RENDERING_MODE_CONFIGURATION_RENDER_TARGET_CONFIG * restrict values)
+{
+ values->opcode = __gen_unpack_uint(cl, 0, 7);
+ values->address = __gen_unpack_address(cl, 40, 71);
+ values->pad = __gen_unpack_uint(cl, 36, 39);
+ values->flip_y = __gen_unpack_uint(cl, 35, 35);
+ values->memory_format = __gen_unpack_uint(cl, 32, 34);
+ values->a_dithered = __gen_unpack_uint(cl, 31, 31);
+ values->bgr_dithered = __gen_unpack_uint(cl, 30, 30);
+ values->output_image_format = __gen_unpack_uint(cl, 24, 29);
+ values->decimate_mode = __gen_unpack_uint(cl, 22, 23);
+ values->internal_type = __gen_unpack_uint(cl, 18, 21);
+ values->internal_bpp = __gen_unpack_uint(cl, 16, 17);
+ values->render_target_number = __gen_unpack_uint(cl, 12, 15);
+ values->sub_id = __gen_unpack_uint(cl, 8, 11);
+}
+#endif
+
+
+#define V3D33_TILE_RENDERING_MODE_CONFIGURATION_Z_STENCIL_CONFIG_opcode 121
+#define V3D33_TILE_RENDERING_MODE_CONFIGURATION_Z_STENCIL_CONFIG_header\
+ .opcode = 121, \
+ .z_stencil_id = 0, \
+ .sub_id = 1
+
+struct V3D33_TILE_RENDERING_MODE_CONFIGURATION_Z_STENCIL_CONFIG {
+ uint32_t opcode;
+ __gen_address_type address;
+ uint32_t padded_height_of_output_image_in_uif_blocks;
+ uint32_t memory_format;
+#define MEMORY_FORMAT_RASTER 0
+#define MEMORY_FORMAT_LINEARTILE 1
+#define MEMORY_FORMAT_UB_LINEAR_1_UIF_BLOCK_WIDE 2
+#define MEMORY_FORMAT_UB_LINEAR_2_UIF_BLOCKS_WIDE 3
+#define MEMORY_FORMAT_UIF_NO_XOR 4
+#define MEMORY_FORMAT_UIF_XOR 5
+ uint32_t output_image_format;
+#define OUTPUT_IMAGE_FORMAT_DEPTH_COMPONENT32F 0
+#define OUTPUT_IMAGE_FORMAT_DEPTH_COMPONENT24 1
+#define OUTPUT_IMAGE_FORMAT_DEPTH_COMPONENT16 2
+#define OUTPUT_IMAGE_FORMAT_DEPTH24_STENCIL8 3
+ uint32_t decimate_mode;
+ uint32_t internal_type;
+#define INTERNAL_TYPE_DEPTH_32F 0
+#define INTERNAL_TYPE_DEPTH_24 1
+#define INTERNAL_TYPE_DEPTH_16 2
+ uint32_t internal_bpp_ignored;
+ uint32_t z_stencil_id;
+ uint32_t sub_id;
+};
+
+static inline void
+V3D33_TILE_RENDERING_MODE_CONFIGURATION_Z_STENCIL_CONFIG_pack(__gen_user_data *data, uint8_t * restrict cl,
+ const struct V3D33_TILE_RENDERING_MODE_CONFIGURATION_Z_STENCIL_CONFIG * restrict values)
+{
+ cl[ 0] = __gen_uint(values->opcode, 0, 7);
+
+ cl[ 1] = __gen_uint(values->z_stencil_id, 4, 7) |
+ __gen_uint(values->sub_id, 0, 3);
+
+ cl[ 2] = __gen_uint(values->decimate_mode, 6, 7) |
+ __gen_uint(values->internal_type, 2, 5) |
+ __gen_uint(values->internal_bpp_ignored, 0, 1);
+
+ cl[ 3] = __gen_uint(values->memory_format, 6, 8) |
+ __gen_uint(values->output_image_format, 0, 5);
+
+ cl[ 4] = __gen_uint(values->padded_height_of_output_image_in_uif_blocks, 1, 13) |
+ __gen_uint(values->memory_format, 6, 8) >> 8;
+
+ __gen_emit_reloc(data, &values->address);
+ cl[ 5] = __gen_address_offset(&values->address) |
+ __gen_uint(values->padded_height_of_output_image_in_uif_blocks, 1, 13) >> 8;
+
+ cl[ 6] = __gen_address_offset(&values->address) >> 8;
+
+ cl[ 7] = __gen_address_offset(&values->address) >> 16;
+
+ cl[ 8] = __gen_address_offset(&values->address) >> 24;
+
+}
+
+#define V3D33_TILE_RENDERING_MODE_CONFIGURATION_Z_STENCIL_CONFIG_length 9
+#ifdef __gen_unpack_address
+static inline void
+V3D33_TILE_RENDERING_MODE_CONFIGURATION_Z_STENCIL_CONFIG_unpack(const uint8_t * restrict cl,
+ struct V3D33_TILE_RENDERING_MODE_CONFIGURATION_Z_STENCIL_CONFIG * restrict values)
+{
+ values->opcode = __gen_unpack_uint(cl, 0, 7);
+ values->address = __gen_unpack_address(cl, 40, 71);
+ values->padded_height_of_output_image_in_uif_blocks = __gen_unpack_uint(cl, 33, 45);
+ values->memory_format = __gen_unpack_uint(cl, 30, 32);
+ values->output_image_format = __gen_unpack_uint(cl, 24, 29);
+ values->decimate_mode = __gen_unpack_uint(cl, 22, 23);
+ values->internal_type = __gen_unpack_uint(cl, 18, 21);
+ values->internal_bpp_ignored = __gen_unpack_uint(cl, 16, 17);
+ values->z_stencil_id = __gen_unpack_uint(cl, 12, 15);
+ values->sub_id = __gen_unpack_uint(cl, 8, 11);
+}
+#endif
+
+
+#define V3D33_TILE_RENDERING_MODE_CONFIGURATION_Z_STENCIL_CLEAR_VALUES_opcode 121
+#define V3D33_TILE_RENDERING_MODE_CONFIGURATION_Z_STENCIL_CLEAR_VALUES_header\
+ .opcode = 121, \
+ .sub_id = 3
+
+struct V3D33_TILE_RENDERING_MODE_CONFIGURATION_Z_STENCIL_CLEAR_VALUES {
+ uint32_t opcode;
+ uint32_t unused;
+ float z_clear_value;
+ uint32_t stencil_vg_mask_clear_value;
+ uint32_t sub_id;
+};
+
+static inline void
+V3D33_TILE_RENDERING_MODE_CONFIGURATION_Z_STENCIL_CLEAR_VALUES_pack(__gen_user_data *data, uint8_t * restrict cl,
+ const struct V3D33_TILE_RENDERING_MODE_CONFIGURATION_Z_STENCIL_CLEAR_VALUES * restrict values)
+{
+ cl[ 0] = __gen_uint(values->opcode, 0, 7);
+
+ cl[ 1] = __gen_uint(values->sub_id, 0, 3);
+
+ cl[ 2] = __gen_uint(values->stencil_vg_mask_clear_value, 0, 7);
+
+
+ memcpy(&cl[3], &values->z_clear_value, sizeof(values->z_clear_value));
+ cl[ 7] = __gen_uint(values->unused, 0, 15);
+
+ cl[ 8] = __gen_uint(values->unused, 0, 15) >> 8;
+
+}
+
+#define V3D33_TILE_RENDERING_MODE_CONFIGURATION_Z_STENCIL_CLEAR_VALUES_length 9
+#ifdef __gen_unpack_address
+static inline void
+V3D33_TILE_RENDERING_MODE_CONFIGURATION_Z_STENCIL_CLEAR_VALUES_unpack(const uint8_t * restrict cl,
+ struct V3D33_TILE_RENDERING_MODE_CONFIGURATION_Z_STENCIL_CLEAR_VALUES * restrict values)
+{
+ values->opcode = __gen_unpack_uint(cl, 0, 7);
+ values->unused = __gen_unpack_uint(cl, 56, 71);
+ values->z_clear_value = __gen_unpack_float(cl, 24, 55);
+ values->stencil_vg_mask_clear_value = __gen_unpack_uint(cl, 16, 23);
+ values->sub_id = __gen_unpack_uint(cl, 8, 11);
+}
+#endif
+
+
+#define V3D33_TILE_RENDERING_MODE_CONFIGURATION_CLEAR_COLORS_PART1_opcode 121
+#define V3D33_TILE_RENDERING_MODE_CONFIGURATION_CLEAR_COLORS_PART1_header\
+ .opcode = 121, \
+ .sub_id = 4
+
+struct V3D33_TILE_RENDERING_MODE_CONFIGURATION_CLEAR_COLORS_PART1 {
+ uint32_t opcode;
+ uint32_t clear_color_next_24_bits;
+ uint32_t clear_color_low_32_bits;
+ uint32_t render_target_number;
+ uint32_t sub_id;
+};
+
+static inline void
+V3D33_TILE_RENDERING_MODE_CONFIGURATION_CLEAR_COLORS_PART1_pack(__gen_user_data *data, uint8_t * restrict cl,
+ const struct V3D33_TILE_RENDERING_MODE_CONFIGURATION_CLEAR_COLORS_PART1 * restrict values)
+{
+ cl[ 0] = __gen_uint(values->opcode, 0, 7);
+
+ cl[ 1] = __gen_uint(values->render_target_number, 4, 7) |
+ __gen_uint(values->sub_id, 0, 3);
+
+
+ memcpy(&cl[2], &values->clear_color_low_32_bits, sizeof(values->clear_color_low_32_bits));
+ cl[ 6] = __gen_uint(values->clear_color_next_24_bits, 0, 23);
+
+ cl[ 7] = __gen_uint(values->clear_color_next_24_bits, 0, 23) >> 8;
+
+ cl[ 8] = __gen_uint(values->clear_color_next_24_bits, 0, 23) >> 16;
+
+}
+
+#define V3D33_TILE_RENDERING_MODE_CONFIGURATION_CLEAR_COLORS_PART1_length 9
+#ifdef __gen_unpack_address
+static inline void
+V3D33_TILE_RENDERING_MODE_CONFIGURATION_CLEAR_COLORS_PART1_unpack(const uint8_t * restrict cl,
+ struct V3D33_TILE_RENDERING_MODE_CONFIGURATION_CLEAR_COLORS_PART1 * restrict values)
+{
+ values->opcode = __gen_unpack_uint(cl, 0, 7);
+ values->clear_color_next_24_bits = __gen_unpack_uint(cl, 48, 71);
+ values->clear_color_low_32_bits = __gen_unpack_uint(cl, 16, 47);
+ values->render_target_number = __gen_unpack_uint(cl, 12, 15);
+ values->sub_id = __gen_unpack_uint(cl, 8, 11);
+}
+#endif
+
+
+#define V3D33_TILE_RENDERING_MODE_CONFIGURATION_CLEAR_COLORS_PART2_opcode 121
+#define V3D33_TILE_RENDERING_MODE_CONFIGURATION_CLEAR_COLORS_PART2_header\
+ .opcode = 121, \
+ .sub_id = 5
+
+struct V3D33_TILE_RENDERING_MODE_CONFIGURATION_CLEAR_COLORS_PART2 {
+ uint32_t opcode;
+ uint32_t clear_color_mid_high_24_bits;
+ uint32_t clear_color_mid_low_32_bits;
+ uint32_t render_target_number;
+ uint32_t sub_id;
+};
+
+static inline void
+V3D33_TILE_RENDERING_MODE_CONFIGURATION_CLEAR_COLORS_PART2_pack(__gen_user_data *data, uint8_t * restrict cl,
+ const struct V3D33_TILE_RENDERING_MODE_CONFIGURATION_CLEAR_COLORS_PART2 * restrict values)
+{
+ cl[ 0] = __gen_uint(values->opcode, 0, 7);
+
+ cl[ 1] = __gen_uint(values->render_target_number, 4, 7) |
+ __gen_uint(values->sub_id, 0, 3);
+
+
+ memcpy(&cl[2], &values->clear_color_mid_low_32_bits, sizeof(values->clear_color_mid_low_32_bits));
+ cl[ 6] = __gen_uint(values->clear_color_mid_high_24_bits, 0, 23);
+
+ cl[ 7] = __gen_uint(values->clear_color_mid_high_24_bits, 0, 23) >> 8;
+
+ cl[ 8] = __gen_uint(values->clear_color_mid_high_24_bits, 0, 23) >> 16;
+
+}
+
+#define V3D33_TILE_RENDERING_MODE_CONFIGURATION_CLEAR_COLORS_PART2_length 9
+#ifdef __gen_unpack_address
+static inline void
+V3D33_TILE_RENDERING_MODE_CONFIGURATION_CLEAR_COLORS_PART2_unpack(const uint8_t * restrict cl,
+ struct V3D33_TILE_RENDERING_MODE_CONFIGURATION_CLEAR_COLORS_PART2 * restrict values)
+{
+ values->opcode = __gen_unpack_uint(cl, 0, 7);
+ values->clear_color_mid_high_24_bits = __gen_unpack_uint(cl, 48, 71);
+ values->clear_color_mid_low_32_bits = __gen_unpack_uint(cl, 16, 47);
+ values->render_target_number = __gen_unpack_uint(cl, 12, 15);
+ values->sub_id = __gen_unpack_uint(cl, 8, 11);
+}
+#endif
+
+
+#define V3D33_TILE_RENDERING_MODE_CONFIGURATION_CLEAR_COLORS_PART3_opcode 121
+#define V3D33_TILE_RENDERING_MODE_CONFIGURATION_CLEAR_COLORS_PART3_header\
+ .opcode = 121, \
+ .sub_id = 6
+
+struct V3D33_TILE_RENDERING_MODE_CONFIGURATION_CLEAR_COLORS_PART3 {
+ uint32_t opcode;
+ uint32_t pad;
+ uint32_t uif_padded_height_in_uif_blocks;
+ uint32_t raster_row_stride_or_image_height_in_pixels;
+ uint32_t clear_color_high_16_bits;
+ uint32_t render_target_number;
+ uint32_t sub_id;
+};
+
+static inline void
+V3D33_TILE_RENDERING_MODE_CONFIGURATION_CLEAR_COLORS_PART3_pack(__gen_user_data *data, uint8_t * restrict cl,
+ const struct V3D33_TILE_RENDERING_MODE_CONFIGURATION_CLEAR_COLORS_PART3 * restrict values)
+{
+ cl[ 0] = __gen_uint(values->opcode, 0, 7);
+
+ cl[ 1] = __gen_uint(values->render_target_number, 4, 7) |
+ __gen_uint(values->sub_id, 0, 3);
+
+ cl[ 2] = __gen_uint(values->clear_color_high_16_bits, 0, 15);
+
+ cl[ 3] = __gen_uint(values->clear_color_high_16_bits, 0, 15) >> 8;
+
+ cl[ 4] = __gen_uint(values->raster_row_stride_or_image_height_in_pixels, 0, 15);
+
+ cl[ 5] = __gen_uint(values->raster_row_stride_or_image_height_in_pixels, 0, 15) >> 8;
+
+ cl[ 6] = __gen_uint(values->uif_padded_height_in_uif_blocks, 0, 12);
+
+ cl[ 7] = __gen_uint(values->pad, 5, 15) |
+ __gen_uint(values->uif_padded_height_in_uif_blocks, 0, 12) >> 8;
+
+ cl[ 8] = __gen_uint(values->pad, 5, 15) >> 8;
+
+}
+
+#define V3D33_TILE_RENDERING_MODE_CONFIGURATION_CLEAR_COLORS_PART3_length 9
+#ifdef __gen_unpack_address
+static inline void
+V3D33_TILE_RENDERING_MODE_CONFIGURATION_CLEAR_COLORS_PART3_unpack(const uint8_t * restrict cl,
+ struct V3D33_TILE_RENDERING_MODE_CONFIGURATION_CLEAR_COLORS_PART3 * restrict values)
+{
+ values->opcode = __gen_unpack_uint(cl, 0, 7);
+ values->pad = __gen_unpack_uint(cl, 61, 71);
+ values->uif_padded_height_in_uif_blocks = __gen_unpack_uint(cl, 48, 60);
+ values->raster_row_stride_or_image_height_in_pixels = __gen_unpack_uint(cl, 32, 47);
+ values->clear_color_high_16_bits = __gen_unpack_uint(cl, 16, 31);
+ values->render_target_number = __gen_unpack_uint(cl, 12, 15);
+ values->sub_id = __gen_unpack_uint(cl, 8, 11);
+}
+#endif
+
+
+#define V3D33_TILE_COORDINATES_opcode 124
+#define V3D33_TILE_COORDINATES_header \
+ .opcode = 124
+
+struct V3D33_TILE_COORDINATES {
+ uint32_t opcode;
+ uint32_t tile_row_number;
+ uint32_t tile_column_number;
+};
+
+static inline void
+V3D33_TILE_COORDINATES_pack(__gen_user_data *data, uint8_t * restrict cl,
+ const struct V3D33_TILE_COORDINATES * restrict values)
+{
+ cl[ 0] = __gen_uint(values->opcode, 0, 7);
+
+ cl[ 1] = __gen_uint(values->tile_column_number, 0, 11);
+
+ cl[ 2] = __gen_uint(values->tile_row_number, 4, 15) |
+ __gen_uint(values->tile_column_number, 0, 11) >> 8;
+
+ cl[ 3] = __gen_uint(values->tile_row_number, 4, 15) >> 8;
+
+}
+
+#define V3D33_TILE_COORDINATES_length 4
+#ifdef __gen_unpack_address
+static inline void
+V3D33_TILE_COORDINATES_unpack(const uint8_t * restrict cl,
+ struct V3D33_TILE_COORDINATES * restrict values)
+{
+ values->opcode = __gen_unpack_uint(cl, 0, 7);
+ values->tile_row_number = __gen_unpack_uint(cl, 20, 31);
+ values->tile_column_number = __gen_unpack_uint(cl, 8, 19);
+}
+#endif
+
+
+#define V3D33_MULTICORE_RENDERING_SUPERTILE_CONFIGURATION_opcode 122
+#define V3D33_MULTICORE_RENDERING_SUPERTILE_CONFIGURATION_header\
+ .opcode = 122
+
+struct V3D33_MULTICORE_RENDERING_SUPERTILE_CONFIGURATION {
+ uint32_t opcode;
+ bool supertile_raster_order;
+ bool multicore_enable;
+ uint32_t total_frame_height_in_tiles;
+ uint32_t total_frame_width_in_tiles;
+ uint32_t total_frame_height_in_supertiles;
+ uint32_t total_frame_width_in_supertiles;
+ uint32_t supertile_height_in_tiles_minus_1;
+ uint32_t supertile_width_in_tiles_minus_1;
+};
+
+static inline void
+V3D33_MULTICORE_RENDERING_SUPERTILE_CONFIGURATION_pack(__gen_user_data *data, uint8_t * restrict cl,
+ const struct V3D33_MULTICORE_RENDERING_SUPERTILE_CONFIGURATION * restrict values)
+{
+ cl[ 0] = __gen_uint(values->opcode, 0, 7);
+
+ cl[ 1] = __gen_uint(values->supertile_width_in_tiles_minus_1, 0, 7);
+
+ cl[ 2] = __gen_uint(values->supertile_height_in_tiles_minus_1, 0, 7);
+
+ cl[ 3] = __gen_uint(values->total_frame_width_in_supertiles, 0, 7);
+
+ cl[ 4] = __gen_uint(values->total_frame_height_in_supertiles, 0, 7);
+
+ cl[ 5] = __gen_uint(values->total_frame_width_in_tiles, 0, 11);
+
+ cl[ 6] = __gen_uint(values->total_frame_height_in_tiles, 4, 15) |
+ __gen_uint(values->total_frame_width_in_tiles, 0, 11) >> 8;
+
+ cl[ 7] = __gen_uint(values->total_frame_height_in_tiles, 4, 15) >> 8;
+
+ cl[ 8] = __gen_uint(values->supertile_raster_order, 4, 4) |
+ __gen_uint(values->multicore_enable, 0, 0);
+
+}
+
+#define V3D33_MULTICORE_RENDERING_SUPERTILE_CONFIGURATION_length 9
+#ifdef __gen_unpack_address
+static inline void
+V3D33_MULTICORE_RENDERING_SUPERTILE_CONFIGURATION_unpack(const uint8_t * restrict cl,
+ struct V3D33_MULTICORE_RENDERING_SUPERTILE_CONFIGURATION * restrict values)
+{
+ values->opcode = __gen_unpack_uint(cl, 0, 7);
+ values->supertile_raster_order = __gen_unpack_uint(cl, 68, 68);
+ values->multicore_enable = __gen_unpack_uint(cl, 64, 64);
+ values->total_frame_height_in_tiles = __gen_unpack_uint(cl, 52, 63);
+ values->total_frame_width_in_tiles = __gen_unpack_uint(cl, 40, 51);
+ values->total_frame_height_in_supertiles = __gen_unpack_uint(cl, 32, 39);
+ values->total_frame_width_in_supertiles = __gen_unpack_uint(cl, 24, 31);
+ values->supertile_height_in_tiles_minus_1 = __gen_unpack_uint(cl, 16, 23);
+ values->supertile_width_in_tiles_minus_1 = __gen_unpack_uint(cl, 8, 15);
+}
+#endif
+
+
+#define V3D33_MULTICORE_RENDERING_TILE_LIST_SET_BASE_opcode 123
+#define V3D33_MULTICORE_RENDERING_TILE_LIST_SET_BASE_header\
+ .opcode = 123
+
+struct V3D33_MULTICORE_RENDERING_TILE_LIST_SET_BASE {
+ uint32_t opcode;
+ __gen_address_type address;
+ uint32_t tile_list_set_number;
+};
+
+static inline void
+V3D33_MULTICORE_RENDERING_TILE_LIST_SET_BASE_pack(__gen_user_data *data, uint8_t * restrict cl,
+ const struct V3D33_MULTICORE_RENDERING_TILE_LIST_SET_BASE * restrict values)
+{
+ cl[ 0] = __gen_uint(values->opcode, 0, 7);
+
+ __gen_emit_reloc(data, &values->address);
+ cl[ 1] = __gen_address_offset(&values->address) |
+ __gen_uint(values->tile_list_set_number, 0, 3);
+
+ cl[ 2] = __gen_address_offset(&values->address) >> 8;
+
+ cl[ 3] = __gen_address_offset(&values->address) >> 16;
+
+ cl[ 4] = __gen_address_offset(&values->address) >> 24;
+
+}
+
+#define V3D33_MULTICORE_RENDERING_TILE_LIST_SET_BASE_length 5
+#ifdef __gen_unpack_address
+static inline void
+V3D33_MULTICORE_RENDERING_TILE_LIST_SET_BASE_unpack(const uint8_t * restrict cl,
+ struct V3D33_MULTICORE_RENDERING_TILE_LIST_SET_BASE * restrict values)
+{
+ values->opcode = __gen_unpack_uint(cl, 0, 7);
+ values->address = __gen_unpack_address(cl, 14, 39);
+ values->tile_list_set_number = __gen_unpack_uint(cl, 8, 11);
+}
+#endif
+
+
+#define V3D33_TILE_COORDINATES_IMPLICIT_opcode 125
+#define V3D33_TILE_COORDINATES_IMPLICIT_header \
+ .opcode = 125
+
+struct V3D33_TILE_COORDINATES_IMPLICIT {
+ uint32_t opcode;
+};
+
+static inline void
+V3D33_TILE_COORDINATES_IMPLICIT_pack(__gen_user_data *data, uint8_t * restrict cl,
+ const struct V3D33_TILE_COORDINATES_IMPLICIT * restrict values)
+{
+ cl[ 0] = __gen_uint(values->opcode, 0, 7);
+
+}
+
+#define V3D33_TILE_COORDINATES_IMPLICIT_length 1
+#ifdef __gen_unpack_address
+static inline void
+V3D33_TILE_COORDINATES_IMPLICIT_unpack(const uint8_t * restrict cl,
+ struct V3D33_TILE_COORDINATES_IMPLICIT * restrict values)
+{
+ values->opcode = __gen_unpack_uint(cl, 0, 7);
+}
+#endif
+
+
+#define V3D33_TILE_LIST_INITIAL_BLOCK_SIZE_opcode 126
+#define V3D33_TILE_LIST_INITIAL_BLOCK_SIZE_header\
+ .opcode = 126
+
+struct V3D33_TILE_LIST_INITIAL_BLOCK_SIZE {
+ uint32_t opcode;
+ bool use_auto_chained_tile_lists;
+ uint32_t size_of_first_block_in_chained_tile_lists;
+#define TILE_ALLOCATION_BLOCK_SIZE_64B 0
+#define TILE_ALLOCATION_BLOCK_SIZE_128B 1
+#define TILE_ALLOCATION_BLOCK_SIZE_256B 2
+};
+
+static inline void
+V3D33_TILE_LIST_INITIAL_BLOCK_SIZE_pack(__gen_user_data *data, uint8_t * restrict cl,
+ const struct V3D33_TILE_LIST_INITIAL_BLOCK_SIZE * restrict values)
+{
+ cl[ 0] = __gen_uint(values->opcode, 0, 7);
+
+ cl[ 1] = __gen_uint(values->use_auto_chained_tile_lists, 2, 2) |
+ __gen_uint(values->size_of_first_block_in_chained_tile_lists, 0, 1);
+
+}
+
+#define V3D33_TILE_LIST_INITIAL_BLOCK_SIZE_length 2
+#ifdef __gen_unpack_address
+static inline void
+V3D33_TILE_LIST_INITIAL_BLOCK_SIZE_unpack(const uint8_t * restrict cl,
+ struct V3D33_TILE_LIST_INITIAL_BLOCK_SIZE * restrict values)
+{
+ values->opcode = __gen_unpack_uint(cl, 0, 7);
+ values->use_auto_chained_tile_lists = __gen_unpack_uint(cl, 10, 10);
+ values->size_of_first_block_in_chained_tile_lists = __gen_unpack_uint(cl, 8, 9);
+}
+#endif
+
+
+#define V3D33_GL_SHADER_STATE_RECORD_header \
+
+
+struct V3D33_GL_SHADER_STATE_RECORD {
+ bool point_size_in_shaded_vertex_data;
+ bool enable_clipping;
+ bool vertex_id_read_by_coordinate_shader;
+ bool instance_id_read_by_coordinate_shader;
+ bool vertex_id_read_by_vertex_shader;
+ bool instance_id_read_by_vertex_shader;
+ bool fragment_shader_does_z_writes;
+ bool turn_off_early_z_test;
+ bool coordinate_shader_has_separate_input_and_output_vpm_blocks;
+ bool vertex_shader_has_separate_input_and_output_vpm_blocks;
+ bool fragment_shader_uses_real_pixel_centre_w_in_addition_to_centroid_w2;
+ uint32_t number_of_varyings_in_fragment_shader;
+ uint32_t coordinate_shader_output_vpm_segment_size;
+ uint32_t coordinate_shader_input_vpm_segment_size;
+ uint32_t vertex_shader_output_vpm_segment_size;
+ uint32_t vertex_shader_input_vpm_segment_size;
+ __gen_address_type address_of_default_attribute_values;
+ __gen_address_type fragment_shader_code_address;
+ bool _2_way_threadable;
+ bool _4_way_threadable;
+ bool propagate_nans;
+ __gen_address_type fragment_shader_uniforms_address;
+ __gen_address_type vertex_shader_code_address;
+ __gen_address_type vertex_shader_uniforms_address;
+ __gen_address_type coordinate_shader_code_address;
+ __gen_address_type coordinate_shader_uniforms_address;
+};
+
+static inline void
+V3D33_GL_SHADER_STATE_RECORD_pack(__gen_user_data *data, uint8_t * restrict cl,
+ const struct V3D33_GL_SHADER_STATE_RECORD * restrict values)
+{
+ cl[ 0] = __gen_uint(values->point_size_in_shaded_vertex_data, 0, 0) |
+ __gen_uint(values->enable_clipping, 1, 1) |
+ __gen_uint(values->vertex_id_read_by_coordinate_shader, 2, 2) |
+ __gen_uint(values->instance_id_read_by_coordinate_shader, 3, 3) |
+ __gen_uint(values->vertex_id_read_by_vertex_shader, 4, 4) |
+ __gen_uint(values->instance_id_read_by_vertex_shader, 5, 5) |
+ __gen_uint(values->fragment_shader_does_z_writes, 6, 6) |
+ __gen_uint(values->turn_off_early_z_test, 7, 7);
+
+ cl[ 1] = __gen_uint(values->coordinate_shader_has_separate_input_and_output_vpm_blocks, 0, 0) |
+ __gen_uint(values->vertex_shader_has_separate_input_and_output_vpm_blocks, 1, 1) |
+ __gen_uint(values->fragment_shader_uses_real_pixel_centre_w_in_addition_to_centroid_w2, 2, 2);
+
+ cl[ 2] = __gen_uint(values->number_of_varyings_in_fragment_shader, 0, 7);
+
+ cl[ 3] = 0;
+ cl[ 4] = __gen_uint(values->coordinate_shader_output_vpm_segment_size, 0, 7);
+
+ cl[ 5] = __gen_uint(values->coordinate_shader_input_vpm_segment_size, 0, 7);
+
+ cl[ 6] = __gen_uint(values->vertex_shader_output_vpm_segment_size, 0, 7);
+
+ cl[ 7] = __gen_uint(values->vertex_shader_input_vpm_segment_size, 0, 7);
+
+ __gen_emit_reloc(data, &values->address_of_default_attribute_values);
+ cl[ 8] = __gen_address_offset(&values->address_of_default_attribute_values);
+
+ cl[ 9] = __gen_address_offset(&values->address_of_default_attribute_values) >> 8;
+
+ cl[10] = __gen_address_offset(&values->address_of_default_attribute_values) >> 16;
+
+ cl[11] = __gen_address_offset(&values->address_of_default_attribute_values) >> 24;
+
+ __gen_emit_reloc(data, &values->fragment_shader_code_address);
+ cl[12] = __gen_address_offset(&values->fragment_shader_code_address) |
+ __gen_uint(values->_2_way_threadable, 0, 0) |
+ __gen_uint(values->_4_way_threadable, 1, 1) |
+ __gen_uint(values->propagate_nans, 2, 2);
+
+ cl[13] = __gen_address_offset(&values->fragment_shader_code_address) >> 8;
+
+ cl[14] = __gen_address_offset(&values->fragment_shader_code_address) >> 16;
+
+ cl[15] = __gen_address_offset(&values->fragment_shader_code_address) >> 24;
+
+ __gen_emit_reloc(data, &values->fragment_shader_uniforms_address);
+ cl[16] = __gen_address_offset(&values->fragment_shader_uniforms_address);
+
+ cl[17] = __gen_address_offset(&values->fragment_shader_uniforms_address) >> 8;
+
+ cl[18] = __gen_address_offset(&values->fragment_shader_uniforms_address) >> 16;
+
+ cl[19] = __gen_address_offset(&values->fragment_shader_uniforms_address) >> 24;
+
+ __gen_emit_reloc(data, &values->vertex_shader_code_address);
+ cl[20] = __gen_address_offset(&values->vertex_shader_code_address);
+
+ cl[21] = __gen_address_offset(&values->vertex_shader_code_address) >> 8;
+
+ cl[22] = __gen_address_offset(&values->vertex_shader_code_address) >> 16;
+
+ cl[23] = __gen_address_offset(&values->vertex_shader_code_address) >> 24;
+
+ __gen_emit_reloc(data, &values->vertex_shader_uniforms_address);
+ cl[24] = __gen_address_offset(&values->vertex_shader_uniforms_address);
+
+ cl[25] = __gen_address_offset(&values->vertex_shader_uniforms_address) >> 8;
+
+ cl[26] = __gen_address_offset(&values->vertex_shader_uniforms_address) >> 16;
+
+ cl[27] = __gen_address_offset(&values->vertex_shader_uniforms_address) >> 24;
+
+ __gen_emit_reloc(data, &values->coordinate_shader_code_address);
+ cl[28] = __gen_address_offset(&values->coordinate_shader_code_address);
+
+ cl[29] = __gen_address_offset(&values->coordinate_shader_code_address) >> 8;
+
+ cl[30] = __gen_address_offset(&values->coordinate_shader_code_address) >> 16;
+
+ cl[31] = __gen_address_offset(&values->coordinate_shader_code_address) >> 24;
+
+ __gen_emit_reloc(data, &values->coordinate_shader_uniforms_address);
+ cl[32] = __gen_address_offset(&values->coordinate_shader_uniforms_address);
+
+ cl[33] = __gen_address_offset(&values->coordinate_shader_uniforms_address) >> 8;
+
+ cl[34] = __gen_address_offset(&values->coordinate_shader_uniforms_address) >> 16;
+
+ cl[35] = __gen_address_offset(&values->coordinate_shader_uniforms_address) >> 24;
+
+}
+
+#define V3D33_GL_SHADER_STATE_RECORD_length 36
+#ifdef __gen_unpack_address
+static inline void
+V3D33_GL_SHADER_STATE_RECORD_unpack(const uint8_t * restrict cl,
+ struct V3D33_GL_SHADER_STATE_RECORD * restrict values)
+{
+ values->point_size_in_shaded_vertex_data = __gen_unpack_uint(cl, 0, 0);
+ values->enable_clipping = __gen_unpack_uint(cl, 1, 1);
+ values->vertex_id_read_by_coordinate_shader = __gen_unpack_uint(cl, 2, 2);
+ values->instance_id_read_by_coordinate_shader = __gen_unpack_uint(cl, 3, 3);
+ values->vertex_id_read_by_vertex_shader = __gen_unpack_uint(cl, 4, 4);
+ values->instance_id_read_by_vertex_shader = __gen_unpack_uint(cl, 5, 5);
+ values->fragment_shader_does_z_writes = __gen_unpack_uint(cl, 6, 6);
+ values->turn_off_early_z_test = __gen_unpack_uint(cl, 7, 7);
+ values->coordinate_shader_has_separate_input_and_output_vpm_blocks = __gen_unpack_uint(cl, 8, 8);
+ values->vertex_shader_has_separate_input_and_output_vpm_blocks = __gen_unpack_uint(cl, 9, 9);
+ values->fragment_shader_uses_real_pixel_centre_w_in_addition_to_centroid_w2 = __gen_unpack_uint(cl, 10, 10);
+ values->number_of_varyings_in_fragment_shader = __gen_unpack_uint(cl, 16, 23);
+ values->coordinate_shader_output_vpm_segment_size = __gen_unpack_uint(cl, 32, 39);
+ values->coordinate_shader_input_vpm_segment_size = __gen_unpack_uint(cl, 40, 47);
+ values->vertex_shader_output_vpm_segment_size = __gen_unpack_uint(cl, 48, 55);
+ values->vertex_shader_input_vpm_segment_size = __gen_unpack_uint(cl, 56, 63);
+ values->address_of_default_attribute_values = __gen_unpack_address(cl, 64, 95);
+ values->fragment_shader_code_address = __gen_unpack_address(cl, 99, 127);
+ values->_2_way_threadable = __gen_unpack_uint(cl, 96, 96);
+ values->_4_way_threadable = __gen_unpack_uint(cl, 97, 97);
+ values->propagate_nans = __gen_unpack_uint(cl, 98, 98);
+ values->fragment_shader_uniforms_address = __gen_unpack_address(cl, 128, 159);
+ values->vertex_shader_code_address = __gen_unpack_address(cl, 160, 191);
+ values->vertex_shader_uniforms_address = __gen_unpack_address(cl, 192, 223);
+ values->coordinate_shader_code_address = __gen_unpack_address(cl, 224, 255);
+ values->coordinate_shader_uniforms_address = __gen_unpack_address(cl, 256, 287);
+}
+#endif
+
+
+#define V3D33_GL_SHADER_STATE_ATTRIBUTE_RECORD_header\
+
+
+struct V3D33_GL_SHADER_STATE_ATTRIBUTE_RECORD {
+ __gen_address_type address;
+ uint32_t vec_size;
+ uint32_t type;
+#define ATTRIBUTE_HALF_FLOAT 1
+#define ATTRIBUTE_FLOAT 2
+#define ATTRIBUTE_FIXED 3
+#define ATTRIBUTE_BYTE 4
+#define ATTRIBUTE_SHORT 5
+#define ATTRIBUTE_INT 6
+#define ATTRIBUTE_INT2_10_10_10 7
+ bool signed_int_type;
+ bool normalized_int_type;
+ bool read_as_int_uint;
+ uint32_t number_of_values_read_by_coordinate_shader;
+ uint32_t number_of_values_read_by_vertex_shader;
+ uint32_t instance_divisor;
+ uint32_t stride;
+};
+
+static inline void
+V3D33_GL_SHADER_STATE_ATTRIBUTE_RECORD_pack(__gen_user_data *data, uint8_t * restrict cl,
+ const struct V3D33_GL_SHADER_STATE_ATTRIBUTE_RECORD * restrict values)
+{
+ __gen_emit_reloc(data, &values->address);
+ cl[ 0] = __gen_address_offset(&values->address);
+
+ cl[ 1] = __gen_address_offset(&values->address) >> 8;
+
+ cl[ 2] = __gen_address_offset(&values->address) >> 16;
+
+ cl[ 3] = __gen_address_offset(&values->address) >> 24;
+
+ cl[ 4] = __gen_uint(values->vec_size, 0, 1) |
+ __gen_uint(values->type, 2, 4) |
+ __gen_uint(values->signed_int_type, 5, 5) |
+ __gen_uint(values->normalized_int_type, 6, 6) |
+ __gen_uint(values->read_as_int_uint, 7, 7);
+
+ cl[ 5] = __gen_uint(values->number_of_values_read_by_coordinate_shader, 0, 3) |
+ __gen_uint(values->number_of_values_read_by_vertex_shader, 4, 7);
+
+ cl[ 6] = __gen_uint(values->instance_divisor, 0, 15);
+
+ cl[ 7] = __gen_uint(values->instance_divisor, 0, 15) >> 8;
+
+
+ memcpy(&cl[8], &values->stride, sizeof(values->stride));
+}
+
+#define V3D33_GL_SHADER_STATE_ATTRIBUTE_RECORD_length 12
+#ifdef __gen_unpack_address
+static inline void
+V3D33_GL_SHADER_STATE_ATTRIBUTE_RECORD_unpack(const uint8_t * restrict cl,
+ struct V3D33_GL_SHADER_STATE_ATTRIBUTE_RECORD * restrict values)
+{
+ values->address = __gen_unpack_address(cl, 0, 31);
+ values->vec_size = __gen_unpack_uint(cl, 32, 33);
+ values->type = __gen_unpack_uint(cl, 34, 36);
+ values->signed_int_type = __gen_unpack_uint(cl, 37, 37);
+ values->normalized_int_type = __gen_unpack_uint(cl, 38, 38);
+ values->read_as_int_uint = __gen_unpack_uint(cl, 39, 39);
+ values->number_of_values_read_by_coordinate_shader = __gen_unpack_uint(cl, 40, 43);
+ values->number_of_values_read_by_vertex_shader = __gen_unpack_uint(cl, 44, 47);
+ values->instance_divisor = __gen_unpack_uint(cl, 48, 63);
+ values->stride = __gen_unpack_uint(cl, 64, 95);
+}
+#endif
+
+
+#define V3D33_VPM_GENERIC_BLOCK_WRITE_SETUP_header\
+ .id = 0, \
+ .id0 = 0
+
+struct V3D33_VPM_GENERIC_BLOCK_WRITE_SETUP {
+ uint32_t id;
+ uint32_t id0;
+ bool horiz;
+ bool laned;
+ bool segs;
+ int32_t stride;
+ uint32_t size;
+#define VPM_SETUP_SIZE_8_BIT 0
+#define VPM_SETUP_SIZE_16_BIT 1
+#define VPM_SETUP_SIZE_32_BIT 2
+ uint32_t addr;
+};
+
+static inline void
+V3D33_VPM_GENERIC_BLOCK_WRITE_SETUP_pack(__gen_user_data *data, uint8_t * restrict cl,
+ const struct V3D33_VPM_GENERIC_BLOCK_WRITE_SETUP * restrict values)
+{
+ cl[ 0] = __gen_uint(values->addr, 0, 12);
+
+ cl[ 1] = __gen_sint(values->stride, 7, 13) |
+ __gen_uint(values->size, 5, 6) |
+ __gen_uint(values->addr, 0, 12) >> 8;
+
+ cl[ 2] = __gen_uint(values->laned, 7, 7) |
+ __gen_uint(values->segs, 6, 6) |
+ __gen_sint(values->stride, 7, 13) >> 8;
+
+ cl[ 3] = __gen_uint(values->id, 6, 7) |
+ __gen_uint(values->id0, 3, 5) |
+ __gen_uint(values->horiz, 0, 0);
+
+}
+
+#define V3D33_VPM_GENERIC_BLOCK_WRITE_SETUP_length 4
+#ifdef __gen_unpack_address
+static inline void
+V3D33_VPM_GENERIC_BLOCK_WRITE_SETUP_unpack(const uint8_t * restrict cl,
+ struct V3D33_VPM_GENERIC_BLOCK_WRITE_SETUP * restrict values)
+{
+ values->id = __gen_unpack_uint(cl, 30, 31);
+ values->id0 = __gen_unpack_uint(cl, 27, 29);
+ values->horiz = __gen_unpack_uint(cl, 24, 24);
+ values->laned = __gen_unpack_uint(cl, 23, 23);
+ values->segs = __gen_unpack_uint(cl, 22, 22);
+ values->stride = __gen_unpack_sint(cl, 15, 21);
+ values->size = __gen_unpack_uint(cl, 13, 14);
+ values->addr = __gen_unpack_uint(cl, 0, 12);
+}
+#endif
+
+
+#define V3D33_VPM_GENERIC_BLOCK_READ_SETUP_header\
+ .id = 1
+
+struct V3D33_VPM_GENERIC_BLOCK_READ_SETUP {
+ uint32_t id;
+ bool horiz;
+ bool laned;
+ bool segs;
+ uint32_t num;
+ int32_t stride;
+ uint32_t size;
+#define VPM_SETUP_SIZE_8_BIT 0
+#define VPM_SETUP_SIZE_16_BIT 1
+#define VPM_SETUP_SIZE_32_BIT 2
+ uint32_t addr;
+};
+
+static inline void
+V3D33_VPM_GENERIC_BLOCK_READ_SETUP_pack(__gen_user_data *data, uint8_t * restrict cl,
+ const struct V3D33_VPM_GENERIC_BLOCK_READ_SETUP * restrict values)
+{
+ cl[ 0] = __gen_uint(values->addr, 0, 12);
+
+ cl[ 1] = __gen_sint(values->stride, 7, 13) |
+ __gen_uint(values->size, 5, 6) |
+ __gen_uint(values->addr, 0, 12) >> 8;
+
+ cl[ 2] = __gen_uint(values->num, 6, 10) |
+ __gen_sint(values->stride, 7, 13) >> 8;
+
+ cl[ 3] = __gen_uint(values->id, 6, 7) |
+ __gen_uint(values->horiz, 5, 5) |
+ __gen_uint(values->laned, 4, 4) |
+ __gen_uint(values->segs, 3, 3) |
+ __gen_uint(values->num, 6, 10) >> 8;
+
+}
+
+#define V3D33_VPM_GENERIC_BLOCK_READ_SETUP_length 4
+#ifdef __gen_unpack_address
+static inline void
+V3D33_VPM_GENERIC_BLOCK_READ_SETUP_unpack(const uint8_t * restrict cl,
+ struct V3D33_VPM_GENERIC_BLOCK_READ_SETUP * restrict values)
+{
+ values->id = __gen_unpack_uint(cl, 30, 31);
+ values->horiz = __gen_unpack_uint(cl, 29, 29);
+ values->laned = __gen_unpack_uint(cl, 28, 28);
+ values->segs = __gen_unpack_uint(cl, 27, 27);
+ values->num = __gen_unpack_uint(cl, 22, 26);
+ values->stride = __gen_unpack_sint(cl, 15, 21);
+ values->size = __gen_unpack_uint(cl, 13, 14);
+ values->addr = __gen_unpack_uint(cl, 0, 12);
+}
+#endif
+
+
+#define V3D33_TEXTURE_UNIFORM_PARAMETER_0_CFG_MODE1_header\
+ .new_configuration_mode = 1
+
+struct V3D33_TEXTURE_UNIFORM_PARAMETER_0_CFG_MODE1 {
+ bool per_pixel_mask_enable;
+ int32_t texel_offset_for_r_coordinate;
+ int32_t texel_offset_for_t_coordinate;
+ int32_t texel_offset_for_s_coordinate;
+ uint32_t r_wrap_mode;
+#define WRAP_MODE_REPEAT 0
+#define WRAP_MODE_CLAMP 1
+#define WRAP_MODE_MIRROR 2
+#define WRAP_MODE_BORDER 3
+#define WRAP_MODE_MIRROR_ONCE 4
+ uint32_t t_wrap_mode;
+#define WRAP_MODE_REPEAT 0
+#define WRAP_MODE_CLAMP 1
+#define WRAP_MODE_MIRROR 2
+#define WRAP_MODE_BORDER 3
+#define WRAP_MODE_MIRROR_ONCE 4
+ uint32_t s_wrap_mode;
+#define WRAP_MODE_REPEAT 0
+#define WRAP_MODE_CLAMP 1
+#define WRAP_MODE_MIRROR 2
+#define WRAP_MODE_BORDER 3
+#define WRAP_MODE_MIRROR_ONCE 4
+ bool new_configuration_mode;
+ bool shadow;
+ bool coefficient_lookup_mode;
+ bool disable_autolod_use_bias_only;
+ bool bias_supplied;
+ bool gather_sample_mode;
+ bool fetch_sample_mode;
+ bool lookup_type;
+#define TEXTURE_2D 0
+#define TEXTURE_2D_ARRAY 1
+#define TEXTURE_3D 2
+#define TEXTURE_CUBE_MAP 3
+#define TEXTURE_1D 4
+#define TEXTURE_1D_ARRAY 5
+#define TEXTURE_CHILD_IMAGE 6
+};
+
+static inline void
+V3D33_TEXTURE_UNIFORM_PARAMETER_0_CFG_MODE1_pack(__gen_user_data *data, uint8_t * restrict cl,
+ const struct V3D33_TEXTURE_UNIFORM_PARAMETER_0_CFG_MODE1 * restrict values)
+{
+ cl[ 0] = __gen_uint(values->coefficient_lookup_mode, 7, 7) |
+ __gen_uint(values->disable_autolod_use_bias_only, 6, 6) |
+ __gen_uint(values->bias_supplied, 5, 5) |
+ __gen_uint(values->gather_sample_mode, 4, 4) |
+ __gen_uint(values->fetch_sample_mode, 3, 3) |
+ __gen_uint(values->lookup_type, 0, 2);
+
+ cl[ 1] = __gen_uint(values->t_wrap_mode, 5, 7) |
+ __gen_uint(values->s_wrap_mode, 2, 4) |
+ __gen_uint(values->new_configuration_mode, 1, 1) |
+ __gen_uint(values->shadow, 0, 0);
+
+ cl[ 2] = __gen_sint(values->texel_offset_for_t_coordinate, 7, 10) |
+ __gen_sint(values->texel_offset_for_s_coordinate, 3, 6) |
+ __gen_uint(values->r_wrap_mode, 0, 2);
+
+ cl[ 3] = __gen_uint(values->per_pixel_mask_enable, 7, 7) |
+ __gen_sint(values->texel_offset_for_r_coordinate, 3, 6) |
+ __gen_sint(values->texel_offset_for_t_coordinate, 7, 10) >> 8;
+
+}
+
+#define V3D33_TEXTURE_UNIFORM_PARAMETER_0_CFG_MODE1_length 4
+#ifdef __gen_unpack_address
+static inline void
+V3D33_TEXTURE_UNIFORM_PARAMETER_0_CFG_MODE1_unpack(const uint8_t * restrict cl,
+ struct V3D33_TEXTURE_UNIFORM_PARAMETER_0_CFG_MODE1 * restrict values)
+{
+ values->per_pixel_mask_enable = __gen_unpack_uint(cl, 31, 31);
+ values->texel_offset_for_r_coordinate = __gen_unpack_sint(cl, 27, 30);
+ values->texel_offset_for_t_coordinate = __gen_unpack_sint(cl, 23, 26);
+ values->texel_offset_for_s_coordinate = __gen_unpack_sint(cl, 19, 22);
+ values->r_wrap_mode = __gen_unpack_uint(cl, 16, 18);
+ values->t_wrap_mode = __gen_unpack_uint(cl, 13, 15);
+ values->s_wrap_mode = __gen_unpack_uint(cl, 10, 12);
+ values->new_configuration_mode = __gen_unpack_uint(cl, 9, 9);
+ values->shadow = __gen_unpack_uint(cl, 8, 8);
+ values->coefficient_lookup_mode = __gen_unpack_uint(cl, 7, 7);
+ values->disable_autolod_use_bias_only = __gen_unpack_uint(cl, 6, 6);
+ values->bias_supplied = __gen_unpack_uint(cl, 5, 5);
+ values->gather_sample_mode = __gen_unpack_uint(cl, 4, 4);
+ values->fetch_sample_mode = __gen_unpack_uint(cl, 3, 3);
+ values->lookup_type = __gen_unpack_uint(cl, 0, 2);
+}
+#endif
+
+
+#define V3D33_TEXTURE_UNIFORM_PARAMETER_1_CFG_MODE1_header\
+
+
+struct V3D33_TEXTURE_UNIFORM_PARAMETER_1_CFG_MODE1 {
+ __gen_address_type texture_state_record_base_address;
+ bool return_word_3_of_texture_data;
+ bool return_word_2_of_texture_data;
+ bool return_word_1_of_texture_data;
+ bool return_word_0_of_texture_data;
+};
+
+static inline void
+V3D33_TEXTURE_UNIFORM_PARAMETER_1_CFG_MODE1_pack(__gen_user_data *data, uint8_t * restrict cl,
+ const struct V3D33_TEXTURE_UNIFORM_PARAMETER_1_CFG_MODE1 * restrict values)
+{
+ __gen_emit_reloc(data, &values->texture_state_record_base_address);
+ cl[ 0] = __gen_address_offset(&values->texture_state_record_base_address) |
+ __gen_uint(values->return_word_3_of_texture_data, 3, 3) |
+ __gen_uint(values->return_word_2_of_texture_data, 2, 2) |
+ __gen_uint(values->return_word_1_of_texture_data, 1, 1) |
+ __gen_uint(values->return_word_0_of_texture_data, 0, 0);
+
+ cl[ 1] = __gen_address_offset(&values->texture_state_record_base_address) >> 8;
+
+ cl[ 2] = __gen_address_offset(&values->texture_state_record_base_address) >> 16;
+
+ cl[ 3] = __gen_address_offset(&values->texture_state_record_base_address) >> 24;
+
+}
+
+#define V3D33_TEXTURE_UNIFORM_PARAMETER_1_CFG_MODE1_length 4
+#ifdef __gen_unpack_address
+static inline void
+V3D33_TEXTURE_UNIFORM_PARAMETER_1_CFG_MODE1_unpack(const uint8_t * restrict cl,
+ struct V3D33_TEXTURE_UNIFORM_PARAMETER_1_CFG_MODE1 * restrict values)
+{
+ values->texture_state_record_base_address = __gen_unpack_address(cl, 0, 31);
+ values->return_word_3_of_texture_data = __gen_unpack_uint(cl, 3, 3);
+ values->return_word_2_of_texture_data = __gen_unpack_uint(cl, 2, 2);
+ values->return_word_1_of_texture_data = __gen_unpack_uint(cl, 1, 1);
+ values->return_word_0_of_texture_data = __gen_unpack_uint(cl, 0, 0);
+}
+#endif
+
+
+#define V3D33_TEXTURE_SHADER_STATE_header \
+ .flip_etc_y = 1
+
+struct V3D33_TEXTURE_SHADER_STATE {
+ bool level_0_is_strictly_uif;
+ bool level_0_xor_enable;
+ uint32_t level_0_ub_pad;
+ uint32_t base_level;
+ float fixed_bias;
+ float max_level_of_detail;
+ float min_level_of_detail;
+ uint32_t border_color_alpha;
+ uint32_t border_color_blue;
+ uint32_t border_color_green;
+ uint32_t border_color_red;
+ bool flip_s_and_t_on_incoming_request;
+ bool flip_etc_y;
+ bool flip_texture_y_axis;
+ bool flip_texture_x_axis;
+ uint32_t swizzle_a;
+#define SWIZZLE_ZERO 0
+#define SWIZZLE_ONE 1
+#define SWIZZLE_RED 2
+#define SWIZZLE_GREEN 3
+#define SWIZZLE_BLUE 4
+#define SWIZZLE_ALPHA 5
+ uint32_t swizzle_b;
+ uint32_t swizzle_g;
+ uint32_t swizzle_r;
+ enum V3D33_Compare_Function depth_compare_function;
+ bool srgb;
+ uint32_t texture_type;
+ uint32_t image_depth;
+ uint32_t image_height;
+ uint32_t image_width;
+ uint32_t array_stride_64_byte_aligned;
+ __gen_address_type texture_base_pointer;
+ uint32_t minification_filter;
+ uint32_t magnification_filter;
+};
+
+static inline void
+V3D33_TEXTURE_SHADER_STATE_pack(__gen_user_data *data, uint8_t * restrict cl,
+ const struct V3D33_TEXTURE_SHADER_STATE * restrict values)
+{
+ __gen_emit_reloc(data, &values->texture_base_pointer);
+ cl[ 0] = __gen_address_offset(&values->texture_base_pointer) |
+ __gen_uint(values->minification_filter, 1, 3) |
+ __gen_uint(values->magnification_filter, 0, 0);
+
+ cl[ 1] = __gen_address_offset(&values->texture_base_pointer) >> 8;
+
+ cl[ 2] = __gen_address_offset(&values->texture_base_pointer) >> 16;
+
+ cl[ 3] = __gen_address_offset(&values->texture_base_pointer) >> 24;
+
+ cl[ 4] = __gen_uint(values->array_stride_64_byte_aligned, 0, 25);
+
+ cl[ 5] = __gen_uint(values->array_stride_64_byte_aligned, 0, 25) >> 8;
+
+ cl[ 6] = __gen_uint(values->array_stride_64_byte_aligned, 0, 25) >> 16;
+
+ cl[ 7] = __gen_uint(values->image_width, 2, 15) |
+ __gen_uint(values->array_stride_64_byte_aligned, 0, 25) >> 24;
+
+ cl[ 8] = __gen_uint(values->image_width, 2, 15) >> 8;
+
+ cl[ 9] = __gen_uint(values->image_height, 0, 13);
+
+ cl[10] = __gen_uint(values->image_depth, 6, 19) |
+ __gen_uint(values->image_height, 0, 13) >> 8;
+
+ cl[11] = __gen_uint(values->image_depth, 6, 19) >> 8;
+
+ cl[12] = __gen_uint(values->texture_type, 4, 10) |
+ __gen_uint(values->image_depth, 6, 19) >> 16;
+
+ cl[13] = __gen_uint(values->depth_compare_function, 5, 7) |
+ __gen_uint(values->srgb, 3, 3) |
+ __gen_uint(values->texture_type, 4, 10) >> 8;
+
+ cl[14] = __gen_uint(values->swizzle_b, 6, 8) |
+ __gen_uint(values->swizzle_g, 3, 5) |
+ __gen_uint(values->swizzle_r, 0, 2);
+
+ cl[15] = __gen_uint(values->flip_s_and_t_on_incoming_request, 7, 7) |
+ __gen_uint(values->flip_etc_y, 6, 6) |
+ __gen_uint(values->flip_texture_y_axis, 5, 5) |
+ __gen_uint(values->flip_texture_x_axis, 4, 4) |
+ __gen_uint(values->swizzle_a, 1, 3) |
+ __gen_uint(values->swizzle_b, 6, 8) >> 8;
+
+ cl[16] = __gen_uint(values->border_color_red, 0, 15);
+
+ cl[17] = __gen_uint(values->border_color_red, 0, 15) >> 8;
+
+ cl[18] = __gen_uint(values->border_color_green, 0, 15);
+
+ cl[19] = __gen_uint(values->border_color_green, 0, 15) >> 8;
+
+ cl[20] = __gen_uint(values->border_color_blue, 0, 15);
+
+ cl[21] = __gen_uint(values->border_color_blue, 0, 15) >> 8;
+
+ cl[22] = __gen_uint(values->border_color_alpha, 0, 15);
+
+ cl[23] = __gen_uint(values->border_color_alpha, 0, 15) >> 8;
+
+ cl[24] = __gen_sfixed(values->min_level_of_detail, 0, 15, 8);
+
+ cl[25] = __gen_sfixed(values->min_level_of_detail, 0, 15, 8) >> 8;
+
+ cl[26] = __gen_sfixed(values->max_level_of_detail, 0, 15, 8);
+
+ cl[27] = __gen_sfixed(values->max_level_of_detail, 0, 15, 8) >> 8;
+
+ cl[28] = __gen_sfixed(values->fixed_bias, 0, 15, 8);
+
+ cl[29] = __gen_sfixed(values->fixed_bias, 0, 15, 8) >> 8;
+
+ cl[30] = __gen_uint(values->base_level, 0, 3);
+
+ cl[31] = __gen_uint(values->level_0_is_strictly_uif, 6, 6) |
+ __gen_uint(values->level_0_xor_enable, 4, 4) |
+ __gen_uint(values->level_0_ub_pad, 0, 3);
+
+}
+
+#define V3D33_TEXTURE_SHADER_STATE_length 32
+#ifdef __gen_unpack_address
+static inline void
+V3D33_TEXTURE_SHADER_STATE_unpack(const uint8_t * restrict cl,
+ struct V3D33_TEXTURE_SHADER_STATE * restrict values)
+{
+ values->level_0_is_strictly_uif = __gen_unpack_uint(cl, 254, 254);
+ values->level_0_xor_enable = __gen_unpack_uint(cl, 252, 252);
+ values->level_0_ub_pad = __gen_unpack_uint(cl, 248, 251);
+ values->base_level = __gen_unpack_uint(cl, 240, 243);
+ values->fixed_bias = __gen_unpack_sfixed(cl, 224, 239, 8);
+ values->max_level_of_detail = __gen_unpack_sfixed(cl, 208, 223, 8);
+ values->min_level_of_detail = __gen_unpack_sfixed(cl, 192, 207, 8);
+ values->border_color_alpha = __gen_unpack_uint(cl, 176, 191);
+ values->border_color_blue = __gen_unpack_uint(cl, 160, 175);
+ values->border_color_green = __gen_unpack_uint(cl, 144, 159);
+ values->border_color_red = __gen_unpack_uint(cl, 128, 143);
+ values->flip_s_and_t_on_incoming_request = __gen_unpack_uint(cl, 127, 127);
+ values->flip_etc_y = __gen_unpack_uint(cl, 126, 126);
+ values->flip_texture_y_axis = __gen_unpack_uint(cl, 125, 125);
+ values->flip_texture_x_axis = __gen_unpack_uint(cl, 124, 124);
+ values->swizzle_a = __gen_unpack_uint(cl, 121, 123);
+ values->swizzle_b = __gen_unpack_uint(cl, 118, 120);
+ values->swizzle_g = __gen_unpack_uint(cl, 115, 117);
+ values->swizzle_r = __gen_unpack_uint(cl, 112, 114);
+ values->depth_compare_function = __gen_unpack_uint(cl, 109, 111);
+ values->srgb = __gen_unpack_uint(cl, 107, 107);
+ values->texture_type = __gen_unpack_uint(cl, 100, 106);
+ values->image_depth = __gen_unpack_uint(cl, 86, 99);
+ values->image_height = __gen_unpack_uint(cl, 72, 85);
+ values->image_width = __gen_unpack_uint(cl, 58, 71);
+ values->array_stride_64_byte_aligned = __gen_unpack_uint(cl, 32, 57);
+ values->texture_base_pointer = __gen_unpack_address(cl, 0, 31);
+ values->minification_filter = __gen_unpack_uint(cl, 1, 3);
+ values->magnification_filter = __gen_unpack_uint(cl, 0, 0);
+}
+#endif
+
+
+enum V3D33_Texture_Data_Formats {
+ TEXTURE_DATA_FORMAT_R8 = 0,
+ TEXTURE_DATA_FORMAT_R8_SNORM = 1,
+ TEXTURE_DATA_FORMAT_RG8 = 2,
+ TEXTURE_DATA_FORMAT_RG8_SNORM = 3,
+ TEXTURE_DATA_FORMAT_RGBA8 = 4,
+ TEXTURE_DATA_FORMAT_RGBA8_SNORM = 5,
+ TEXTURE_DATA_FORMAT_RGB565 = 6,
+ TEXTURE_DATA_FORMAT_RGBA4 = 7,
+ TEXTURE_DATA_FORMAT_RGB5_A1 = 8,
+ TEXTURE_DATA_FORMAT_RGB10_A2 = 9,
+ TEXTURE_DATA_FORMAT_R16 = 10,
+ TEXTURE_DATA_FORMAT_R16_SNORM = 11,
+ TEXTURE_DATA_FORMAT_RG16 = 12,
+ TEXTURE_DATA_FORMAT_RG16_SNORM = 13,
+ TEXTURE_DATA_FORMAT_RGBA16 = 14,
+ TEXTURE_DATA_FORMAT_RGBA16_SNORM = 15,
+ TEXTURE_DATA_FORMAT_R16F = 16,
+ TEXTURE_DATA_FORMAT_RG16F = 17,
+ TEXTURE_DATA_FORMAT_RGBA16F = 18,
+ TEXTURE_DATA_FORMAT_R11F_G11F_B10F = 19,
+ TEXTURE_DATA_FORMAT_RGB9_E5 = 20,
+ TEXTURE_DATA_FORMAT_DEPTH_COMP16 = 21,
+ TEXTURE_DATA_FORMAT_DEPTH_COMP24 = 22,
+ TEXTURE_DATA_FORMAT_DEPTH_COMP32F = 23,
+ TEXTURE_DATA_FORMAT_DEPTH24_X8 = 24,
+ TEXTURE_DATA_FORMAT_R4 = 25,
+ TEXTURE_DATA_FORMAT_R1 = 26,
+ TEXTURE_DATA_FORMAT_S8 = 27,
+ TEXTURE_DATA_FORMAT_S16 = 28,
+ TEXTURE_DATA_FORMAT_R32F = 29,
+ TEXTURE_DATA_FORMAT_RG32F = 30,
+ TEXTURE_DATA_FORMAT_RGBA32F = 31,
+ TEXTURE_DATA_FORMAT_RGB8_ETC2 = 32,
+ TEXTURE_DATA_FORMAT_RGB8_PUNCHTHROUGH_ALPHA1 = 33,
+ TEXTURE_DATA_FORMAT_R11_EAC = 34,
+ TEXTURE_DATA_FORMAT_SIGNED_R11_EAC = 35,
+ TEXTURE_DATA_FORMAT_RG11_EAC = 36,
+ TEXTURE_DATA_FORMAT_SIGNED_RG11_EAC = 37,
+ TEXTURE_DATA_FORMAT_RGBA8_ETC2_EAC = 38,
+ TEXTURE_DATA_FORMAT_YCBCR_LUMA = 39,
+ TEXTURE_DATA_FORMAT_YCBCR_420_CHROMA = 40,
+ TEXTURE_DATA_FORMAT_BC1 = 48,
+ TEXTURE_DATA_FORMAT_BC2 = 49,
+ TEXTURE_DATA_FORMAT_BC3 = 50,
+ TEXTURE_DATA_FORMAT_ASTC_4X4 = 64,
+ TEXTURE_DATA_FORMAT_ASTC_5X4 = 65,
+ TEXTURE_DATA_FORMAT_ASTC_5X5 = 66,
+ TEXTURE_DATA_FORMAT_ASTC_6X5 = 67,
+ TEXTURE_DATA_FORMAT_ASTC_6X6 = 68,
+ TEXTURE_DATA_FORMAT_ASTC_8X5 = 69,
+ TEXTURE_DATA_FORMAT_ASTC_8X6 = 70,
+ TEXTURE_DATA_FORMAT_ASTC_8X8 = 71,
+ TEXTURE_DATA_FORMAT_ASTC_10X5 = 72,
+ TEXTURE_DATA_FORMAT_ASTC_10X6 = 73,
+ TEXTURE_DATA_FORMAT_ASTC_10X8 = 74,
+ TEXTURE_DATA_FORMAT_ASTC_10X10 = 75,
+ TEXTURE_DATA_FORMAT_ASTC_12X10 = 76,
+ TEXTURE_DATA_FORMAT_ASTC_12X12 = 77,
+};
+
+#endif /* V3D33_PACK_H */
diff --git a/lib/mesa/src/broadcom/cle/v3d_xml.h b/lib/mesa/src/broadcom/cle/v3d_xml.h
new file mode 100644
index 000000000..a940429c1
--- /dev/null
+++ b/lib/mesa/src/broadcom/cle/v3d_xml.h
@@ -0,0 +1,719 @@
+static const struct {
+ uint32_t gen_10;
+ uint32_t offset;
+ uint32_t length;
+} genxml_files_table[] = {
+ { 21, 0, 15431 },
+ { 33, 15431, 42910 },
+};
+
+static const uint8_t compress_genxmls[] = {
+ 0x78, 0x9c, 0xed, 0x5d, 0x5b, 0x73, 0xe3, 0xb6, 0x92, 0x7e, 0xcf, 0xaf,
+ 0xc0, 0xce, 0xcb, 0xf1, 0xec, 0xae, 0x62, 0x91, 0xba, 0x58, 0xae, 0x4a,
+ 0xb2, 0xa5, 0x9b, 0x3d, 0xae, 0x23, 0x5b, 0x5a, 0x49, 0xf6, 0xcc, 0xf8,
+ 0x45, 0x45, 0x49, 0x94, 0xcd, 0x8a, 0x44, 0xea, 0x90, 0x94, 0x2f, 0xf9,
+ 0xf5, 0x8b, 0x0b, 0x49, 0x00, 0x64, 0x83, 0x00, 0x35, 0x9e, 0x49, 0xb2,
+ 0xc7, 0xa7, 0x4e, 0x25, 0x8e, 0xdd, 0x68, 0x00, 0xdd, 0x8d, 0x46, 0xa3,
+ 0xd1, 0xf8, 0xf8, 0xcb, 0xd3, 0xea, 0x65, 0xb7, 0x45, 0x0f, 0xae, 0xff,
+ 0xeb, 0x07, 0xfb, 0x67, 0xeb, 0xc3, 0x6f, 0x3f, 0x21, 0xf4, 0xcb, 0xde,
+ 0x59, 0xfd, 0xee, 0xc6, 0xc8, 0x77, 0x76, 0xee, 0xaf, 0x1f, 0x3e, 0x39,
+ 0xdb, 0xf8, 0x03, 0x5a, 0x05, 0x6b, 0xfc, 0x73, 0xfd, 0xc3, 0x69, 0x91,
+ 0xe0, 0x66, 0x3c, 0x49, 0xff, 0x6e, 0x41, 0x7f, 0xbf, 0xd8, 0x1e, 0xa2,
+ 0xc7, 0x94, 0xa2, 0x89, 0x7f, 0xd8, 0xfe, 0xfa, 0xa1, 0xa7, 0x24, 0x44,
+ 0xdd, 0xed, 0x16, 0xcd, 0x62, 0x27, 0x76, 0xd3, 0x26, 0xad, 0x92, 0x26,
+ 0x98, 0x30, 0x8c, 0xd1, 0xdc, 0xdb, 0xba, 0xa8, 0xe7, 0xf9, 0xbe, 0xe7,
+ 0x3f, 0xa4, 0xad, 0xda, 0x25, 0xad, 0xae, 0xfc, 0x55, 0xe8, 0xee, 0x5c,
+ 0x3f, 0x46, 0x33, 0x77, 0xe7, 0xec, 0x1f, 0x83, 0x30, 0xeb, 0xec, 0x0c,
+ 0xa2, 0xff, 0xec, 0x78, 0x31, 0x0a, 0xfc, 0x22, 0x75, 0x07, 0xa2, 0xee,
+ 0x85, 0x8e, 0xbf, 0xca, 0x26, 0x6c, 0xb5, 0xa9, 0x4c, 0x31, 0xd1, 0xc6,
+ 0x73, 0xb7, 0xeb, 0x84, 0xa6, 0xbb, 0x5e, 0x87, 0x6e, 0x14, 0x7d, 0x40,
+ 0x91, 0xf7, 0x07, 0xfe, 0xcf, 0x86, 0x8d, 0x7f, 0x22, 0x53, 0x21, 0x22,
+ 0x46, 0xf1, 0xeb, 0x1e, 0xff, 0xce, 0x49, 0x48, 0x58, 0x0f, 0xa7, 0xac,
+ 0x0b, 0x55, 0x6f, 0x28, 0x0e, 0x50, 0x74, 0x58, 0xd6, 0xb6, 0x5e, 0x94,
+ 0x29, 0xcb, 0x3a, 0xfb, 0xbe, 0x3d, 0x4f, 0xdd, 0xf8, 0x10, 0xfa, 0x68,
+ 0x13, 0x06, 0xbb, 0x62, 0xdf, 0x54, 0x32, 0x80, 0xba, 0xb0, 0xf0, 0xd0,
+ 0xf5, 0x61, 0x1b, 0x7b, 0xb5, 0xc8, 0xd9, 0xed, 0xb1, 0xda, 0xa6, 0x6e,
+ 0x14, 0x6c, 0x9f, 0xdc, 0x35, 0x53, 0x62, 0x3f, 0xd8, 0x06, 0x21, 0xea,
+ 0x1d, 0x36, 0x1b, 0x37, 0x4c, 0x79, 0xd9, 0x89, 0xcd, 0x4c, 0x61, 0x03,
+ 0xa8, 0xc0, 0x11, 0x39, 0xfe, 0x1a, 0x0d, 0xc7, 0x17, 0x19, 0xe7, 0x96,
+ 0xc0, 0x59, 0xc1, 0xfa, 0xe2, 0x80, 0xed, 0x91, 0xb2, 0x3c, 0xc4, 0x1e,
+ 0xb6, 0x01, 0x66, 0x6b, 0xe9, 0x00, 0x69, 0xe3, 0x94, 0x9b, 0x89, 0xa6,
+ 0xed, 0x4e, 0x26, 0xef, 0x26, 0x28, 0xef, 0x5c, 0xf3, 0x91, 0x13, 0x31,
+ 0xfb, 0x4e, 0x19, 0x58, 0x59, 0xfb, 0x46, 0xda, 0x7e, 0x19, 0x04, 0x5b,
+ 0xb0, 0xf1, 0xc0, 0x8b, 0x9c, 0x25, 0x91, 0xc1, 0xd6, 0x75, 0x42, 0x62,
+ 0xc0, 0x9f, 0x43, 0x2f, 0x06, 0x38, 0xd9, 0xc6, 0x9c, 0xee, 0x4f, 0x67,
+ 0xb1, 0xeb, 0xaf, 0xbc, 0x6d, 0x2a, 0xd1, 0x67, 0x98, 0xa3, 0x65, 0x3e,
+ 0x36, 0x51, 0x3f, 0x0a, 0x6e, 0xf5, 0x22, 0x37, 0x6e, 0x96, 0x80, 0x5d,
+ 0xd6, 0xb6, 0x81, 0xb3, 0xae, 0xa2, 0x39, 0x93, 0x95, 0x52, 0x55, 0x73,
+ 0x4a, 0x91, 0x85, 0xae, 0xb3, 0x7e, 0x33, 0x89, 0xc1, 0xcc, 0xaa, 0x09,
+ 0x8c, 0x19, 0xba, 0x20, 0x1e, 0x74, 0xe9, 0xfa, 0x6e, 0xe8, 0x6c, 0x33,
+ 0xf9, 0x74, 0x52, 0x81, 0x01, 0xc3, 0xba, 0x76, 0x77, 0x41, 0xf8, 0x8a,
+ 0x96, 0x4e, 0xe4, 0xa2, 0x44, 0x1e, 0x28, 0xd8, 0x60, 0xb7, 0x80, 0xff,
+ 0x7a, 0x1a, 0x13, 0xa6, 0xeb, 0xc3, 0x6e, 0x8f, 0x96, 0x89, 0xe0, 0x0b,
+ 0xc2, 0xb4, 0x61, 0xbf, 0xa3, 0x5a, 0x07, 0x84, 0xf7, 0x05, 0xe1, 0x0d,
+ 0x88, 0xf0, 0xdc, 0x58, 0x86, 0x77, 0x97, 0xb5, 0x6b, 0x27, 0xfa, 0x3d,
+ 0x19, 0x15, 0x1d, 0x21, 0xc0, 0xaf, 0x73, 0xc4, 0xba, 0x28, 0xe7, 0x78,
+ 0x56, 0x51, 0xcb, 0xe5, 0xdc, 0xda, 0xc7, 0xce, 0x77, 0x95, 0x3a, 0x84,
+ 0x88, 0xa8, 0xfe, 0x54, 0xc1, 0xbe, 0x75, 0xfc, 0xf4, 0xcd, 0x3a, 0x68,
+ 0x1e, 0x27, 0x0d, 0x33, 0xe6, 0x05, 0xf7, 0x58, 0xe4, 0x3e, 0xf1, 0x5e,
+ 0xdc, 0x6d, 0xc2, 0xfb, 0x22, 0x08, 0x77, 0x4e, 0x9c, 0xd9, 0x67, 0xc6,
+ 0x27, 0xb3, 0x81, 0x83, 0xe7, 0xc7, 0x89, 0xfd, 0x63, 0x36, 0x4f, 0xce,
+ 0xf6, 0xe0, 0x26, 0x6c, 0xc2, 0x87, 0xa5, 0xd3, 0xc1, 0xff, 0xfb, 0x80,
+ 0xe8, 0x6f, 0xb3, 0x30, 0xa9, 0x40, 0xb8, 0x7c, 0x08, 0x5b, 0xed, 0x16,
+ 0x5a, 0x7b, 0xf1, 0xa3, 0x1b, 0xba, 0xeb, 0x8c, 0xde, 0x2a, 0xa7, 0xf7,
+ 0x83, 0xa4, 0x49, 0xd6, 0xc0, 0xce, 0x84, 0x75, 0x4a, 0xe7, 0x03, 0x4d,
+ 0xee, 0x1a, 0x2f, 0xdd, 0xe2, 0x74, 0xda, 0xfa, 0xe9, 0xcc, 0xd8, 0x36,
+ 0x5a, 0xd7, 0x4e, 0x67, 0xe0, 0xae, 0x3c, 0x2c, 0x33, 0x17, 0xbd, 0x34,
+ 0xb5, 0x53, 0xe1, 0xb4, 0xc4, 0x6a, 0x2b, 0x4c, 0x43, 0xa5, 0x97, 0xa6,
+ 0x7e, 0x22, 0x53, 0xec, 0x33, 0x04, 0xa1, 0xa9, 0xa6, 0x31, 0xd7, 0x0e,
+ 0x7e, 0x34, 0xaf, 0x34, 0xe4, 0xc4, 0x89, 0xe2, 0x90, 0x8c, 0x7a, 0xd6,
+ 0x2c, 0xd4, 0x2a, 0xba, 0x67, 0xf5, 0xd8, 0x6f, 0x02, 0xdf, 0xd5, 0x8e,
+ 0x9c, 0x5a, 0xae, 0x76, 0xf4, 0xf7, 0xa7, 0x11, 0x5b, 0x9c, 0xc5, 0x49,
+ 0xe4, 0x29, 0x33, 0x8a, 0x86, 0x82, 0x22, 0xf1, 0x23, 0x19, 0x5d, 0xb3,
+ 0x20, 0x8e, 0xd2, 0x9d, 0x66, 0x44, 0xf6, 0xe5, 0xb2, 0x8d, 0xe6, 0xfc,
+ 0x4f, 0xdf, 0x68, 0x14, 0x1e, 0x93, 0x44, 0x14, 0x6f, 0xbb, 0x43, 0x28,
+ 0x38, 0x1e, 0xb9, 0x43, 0x28, 0xb8, 0x15, 0x76, 0x88, 0x77, 0x27, 0xf8,
+ 0xee, 0x04, 0xdf, 0x9d, 0xe0, 0x9f, 0xea, 0x04, 0xaf, 0xfc, 0xb5, 0xfb,
+ 0x82, 0x8f, 0xa7, 0x93, 0xd0, 0xdb, 0x79, 0xb1, 0xf7, 0xe4, 0xa2, 0x91,
+ 0x70, 0x72, 0xc6, 0x07, 0x72, 0xc8, 0xf7, 0x39, 0x2f, 0xde, 0xee, 0xb0,
+ 0x43, 0xb4, 0x2d, 0x70, 0x76, 0x3f, 0xb3, 0x25, 0x69, 0x42, 0x6e, 0xa3,
+ 0xcb, 0x5d, 0x26, 0xe6, 0xe2, 0xad, 0xdc, 0x28, 0xe9, 0xb7, 0xc0, 0xac,
+ 0x59, 0xd7, 0x32, 0x1b, 0xb9, 0xfe, 0x43, 0xfc, 0x08, 0xb4, 0xed, 0x68,
+ 0x9b, 0xd2, 0x29, 0x50, 0xa2, 0xb4, 0x79, 0xb3, 0x8a, 0x3d, 0x77, 0x6a,
+ 0x4b, 0x2f, 0xd6, 0x1a, 0x85, 0xd5, 0x96, 0xc8, 0x2c, 0x40, 0x43, 0x79,
+ 0x37, 0x98, 0x69, 0x63, 0x27, 0xf8, 0x8c, 0x66, 0x15, 0x73, 0xdd, 0x07,
+ 0xf8, 0x4f, 0x91, 0x76, 0x6c, 0x5b, 0xcf, 0x77, 0x23, 0xad, 0xc1, 0x12,
+ 0x2a, 0xec, 0xd5, 0x83, 0xbd, 0xd6, 0x60, 0x29, 0x65, 0x14, 0x87, 0xde,
+ 0x5e, 0x6b, 0xb9, 0x98, 0xc8, 0xf1, 0x1f, 0xb6, 0x42, 0xf7, 0x4d, 0x1d,
+ 0x65, 0x8e, 0x73, 0x4b, 0x4b, 0xbf, 0x71, 0xfc, 0x8c, 0xba, 0x5d, 0x6d,
+ 0x65, 0xdc, 0xb9, 0x61, 0x8c, 0x6d, 0xa3, 0x1b, 0x86, 0xce, 0x2b, 0x5f,
+ 0x1e, 0x51, 0xb6, 0x34, 0x1a, 0xd0, 0xd2, 0x60, 0xf6, 0x44, 0x4e, 0x85,
+ 0x5e, 0x88, 0xcf, 0x88, 0x8c, 0xc7, 0x0f, 0xb7, 0xea, 0x77, 0xf3, 0xf9,
+ 0xf3, 0xcd, 0x47, 0x76, 0xa8, 0x59, 0x30, 0x23, 0xa5, 0x7a, 0x5a, 0x60,
+ 0x92, 0x6e, 0xe0, 0xc4, 0x0e, 0x9a, 0x1f, 0xeb, 0x92, 0x98, 0xb3, 0x41,
+ 0x1e, 0xf3, 0xcd, 0x1a, 0xc5, 0x34, 0x6c, 0x4a, 0xfc, 0x72, 0xfa, 0x5a,
+ 0x14, 0x77, 0xc9, 0x76, 0xca, 0xe7, 0x06, 0x0f, 0xd3, 0xc0, 0xbe, 0x26,
+ 0xd4, 0xbe, 0x12, 0xa7, 0xaf, 0x31, 0xb2, 0x11, 0x31, 0x32, 0x99, 0x54,
+ 0x35, 0xa1, 0x79, 0xa6, 0x3a, 0x89, 0x5c, 0x65, 0x6e, 0xd3, 0x4f, 0x5f,
+ 0x65, 0xc2, 0xe2, 0xec, 0x4b, 0x95, 0x7c, 0x39, 0x42, 0xb3, 0x47, 0x67,
+ 0x8d, 0x43, 0x0b, 0xe9, 0x92, 0xa0, 0xdd, 0x4c, 0xf5, 0xfa, 0x1f, 0xb5,
+ 0x1a, 0x9a, 0x3f, 0xf2, 0x23, 0x02, 0x93, 0xe2, 0xb3, 0xb7, 0xc5, 0x91,
+ 0xb7, 0x8b, 0xff, 0x6b, 0xbb, 0xc5, 0x7b, 0xaf, 0xe7, 0xa3, 0xe5, 0x2b,
+ 0xfa, 0xdd, 0x0d, 0x7d, 0x1c, 0xfb, 0xe2, 0x81, 0x78, 0x6b, 0x87, 0xe6,
+ 0x08, 0x09, 0xb3, 0x9f, 0x51, 0xad, 0x56, 0x29, 0x1d, 0xa8, 0x77, 0x2c,
+ 0xc3, 0x17, 0x1c, 0x7c, 0xac, 0x71, 0xbf, 0x11, 0x1b, 0x7a, 0xe8, 0xae,
+ 0x82, 0x10, 0x88, 0xd7, 0xf5, 0x29, 0xdd, 0x9b, 0xc3, 0x6e, 0x89, 0x19,
+ 0x60, 0x77, 0xe7, 0xc4, 0x78, 0xd1, 0x2c, 0x0f, 0x38, 0x9a, 0x74, 0x88,
+ 0xbf, 0x8c, 0x74, 0x11, 0x96, 0x2e, 0x0b, 0xc8, 0x92, 0xc4, 0x34, 0x9a,
+ 0x8a, 0x72, 0x8b, 0xc6, 0xb2, 0x9a, 0xd0, 0xaa, 0x61, 0x2d, 0x66, 0x69,
+ 0x5c, 0xc5, 0xba, 0xe7, 0x62, 0x39, 0x6f, 0x6b, 0xe5, 0xc2, 0x38, 0xdc,
+ 0x5d, 0x22, 0x16, 0x4f, 0xe5, 0x39, 0x74, 0xf4, 0x7e, 0x97, 0x71, 0xb8,
+ 0x9f, 0x65, 0x6a, 0xe1, 0x4b, 0xa2, 0xdd, 0x34, 0x6c, 0x9d, 0x44, 0x90,
+ 0x8c, 0x41, 0x5b, 0xb5, 0xa6, 0xb4, 0xf2, 0x0b, 0xfc, 0x8d, 0xf7, 0x70,
+ 0x08, 0x99, 0x21, 0xf5, 0xbc, 0x38, 0xdb, 0xb7, 0xce, 0x41, 0x9f, 0x33,
+ 0x74, 0xc2, 0xed, 0x2b, 0xba, 0x47, 0x87, 0x3d, 0xb6, 0x3d, 0xbc, 0x7a,
+ 0x5c, 0x9f, 0x9c, 0xea, 0x8e, 0x3a, 0x11, 0xa6, 0xac, 0x94, 0x2c, 0xf4,
+ 0x89, 0x42, 0x83, 0x71, 0x18, 0xa4, 0x03, 0xdd, 0x7d, 0xfc, 0x58, 0x9b,
+ 0xbb, 0xc4, 0xf9, 0x1e, 0xfc, 0x15, 0x11, 0x44, 0xd1, 0x2a, 0x2d, 0x38,
+ 0x54, 0x25, 0xcb, 0x16, 0x2f, 0x59, 0xe6, 0x15, 0x22, 0x78, 0x09, 0xf6,
+ 0x83, 0x27, 0x37, 0x74, 0x1e, 0xc8, 0x15, 0x8f, 0xb3, 0x46, 0xe2, 0xd9,
+ 0x4e, 0x18, 0xa6, 0xf5, 0xed, 0xec, 0x27, 0xde, 0xde, 0x45, 0x33, 0x77,
+ 0xeb, 0xae, 0xe2, 0x62, 0x07, 0xfa, 0x23, 0x3f, 0x3b, 0x72, 0x79, 0x11,
+ 0x5e, 0xa7, 0x63, 0xcc, 0x31, 0xb9, 0x96, 0xd2, 0x1c, 0x45, 0x25, 0x6e,
+ 0xd5, 0x85, 0x21, 0xee, 0x0a, 0x7c, 0xac, 0xad, 0xa3, 0x65, 0xd1, 0xf5,
+ 0x63, 0x0f, 0xbb, 0x45, 0x27, 0x22, 0x07, 0x15, 0xb6, 0x71, 0x90, 0xcb,
+ 0xb3, 0x11, 0x0b, 0x3e, 0xf2, 0xfd, 0xe8, 0x13, 0xb9, 0x43, 0x6a, 0x55,
+ 0x88, 0x5a, 0x08, 0x1a, 0x6f, 0x36, 0x91, 0x0b, 0x88, 0x56, 0xef, 0xfe,
+ 0xfa, 0xdb, 0x60, 0xf5, 0xfb, 0x33, 0x16, 0xad, 0x14, 0x1e, 0x56, 0xbf,
+ 0xcf, 0x4a, 0x86, 0x33, 0x75, 0x89, 0x7e, 0x5c, 0x74, 0xe1, 0xac, 0x3c,
+ 0xff, 0x81, 0xf3, 0x3c, 0xe6, 0x7a, 0x26, 0x61, 0x89, 0xa3, 0x8e, 0x67,
+ 0x27, 0x5c, 0x1b, 0xb0, 0xac, 0x76, 0x49, 0x73, 0xb1, 0x75, 0x62, 0xb6,
+ 0xf3, 0x21, 0xfc, 0xe3, 0x03, 0x77, 0x2e, 0xe0, 0xdd, 0x15, 0xa1, 0xae,
+ 0x91, 0xcd, 0x86, 0x8c, 0x21, 0xa1, 0x57, 0x5f, 0xf8, 0x1a, 0xf9, 0x37,
+ 0x6a, 0x05, 0x94, 0x49, 0xd6, 0x75, 0x07, 0xea, 0x9a, 0xd1, 0xcd, 0x28,
+ 0x9d, 0xba, 0xcb, 0xcd, 0x36, 0x70, 0xf4, 0x7d, 0x12, 0x73, 0xc3, 0x5b,
+ 0xf7, 0x3a, 0xce, 0xae, 0xd3, 0xcf, 0xcf, 0xa1, 0x3e, 0x45, 0xba, 0x6f,
+ 0xed, 0x73, 0xfa, 0x69, 0x8e, 0xbe, 0xa0, 0x65, 0x70, 0xf0, 0xd7, 0x4e,
+ 0xf8, 0x9a, 0x6d, 0x81, 0xf5, 0x3a, 0xd4, 0x31, 0x21, 0xde, 0x67, 0xa1,
+ 0x99, 0xd8, 0x2c, 0xd1, 0x76, 0xbb, 0x38, 0x0c, 0x13, 0x61, 0xcb, 0xeb,
+ 0x24, 0x1d, 0x82, 0x25, 0xc6, 0x38, 0xf1, 0xa3, 0x1b, 0xb9, 0x2c, 0xba,
+ 0xc1, 0x6b, 0x33, 0x74, 0x71, 0xdf, 0xb8, 0x09, 0x9d, 0x63, 0xcd, 0xaa,
+ 0x75, 0x6a, 0x67, 0xd8, 0x93, 0x93, 0x86, 0x6b, 0x74, 0x12, 0x07, 0x7b,
+ 0x64, 0xb5, 0x11, 0x8e, 0x3b, 0xe9, 0xf1, 0xdf, 0x61, 0x54, 0x0d, 0xfb,
+ 0x23, 0xbc, 0xf6, 0xc5, 0xce, 0xd1, 0xad, 0x4f, 0x77, 0xb2, 0xc2, 0x74,
+ 0x2c, 0xfd, 0xee, 0x2e, 0xf1, 0xc1, 0xeb, 0x21, 0xe6, 0xbb, 0x2c, 0x24,
+ 0x17, 0xc3, 0x28, 0xc5, 0xdb, 0xa3, 0xcf, 0x38, 0xd4, 0x0e, 0x9e, 0xb9,
+ 0x5c, 0xc0, 0x94, 0x89, 0x40, 0x89, 0x3e, 0xb9, 0xde, 0xc3, 0x23, 0x89,
+ 0xd0, 0xd1, 0x9e, 0x64, 0x3b, 0xa1, 0xf9, 0x34, 0x4d, 0x62, 0x0d, 0xce,
+ 0xf1, 0x33, 0x31, 0xb6, 0x52, 0x86, 0x0d, 0x7d, 0x4a, 0x46, 0x64, 0xd8,
+ 0x0b, 0xe2, 0x38, 0xd8, 0xa1, 0x34, 0x1b, 0x8b, 0xc3, 0x43, 0xcf, 0x77,
+ 0x84, 0xcb, 0xf0, 0x4a, 0x92, 0x17, 0x19, 0x8f, 0xdc, 0x4d, 0x6c, 0xc2,
+ 0xb6, 0x9a, 0x1e, 0xee, 0x3c, 0xf7, 0x79, 0x1f, 0x84, 0x71, 0xc1, 0x46,
+ 0xc1, 0x33, 0x7a, 0x46, 0xdd, 0x77, 0xfd, 0x18, 0x9b, 0xea, 0xd7, 0xda,
+ 0xca, 0x6c, 0x86, 0x91, 0x65, 0xff, 0xdc, 0x04, 0xa7, 0x98, 0x67, 0xf9,
+ 0xa5, 0x9c, 0x65, 0x1d, 0xe0, 0x58, 0x32, 0xbd, 0x7b, 0xb4, 0xc3, 0xba,
+ 0x25, 0x3b, 0xde, 0xce, 0x79, 0xc1, 0xc1, 0xb0, 0xb7, 0xdf, 0x13, 0x4f,
+ 0xba, 0xdf, 0x3a, 0x3e, 0xcf, 0x47, 0x58, 0x75, 0x30, 0x2c, 0x4e, 0x73,
+ 0x75, 0xf7, 0xcf, 0x80, 0x33, 0xe2, 0x56, 0x21, 0x78, 0xa3, 0x3c, 0x03,
+ 0xcf, 0x57, 0x33, 0xa8, 0xe8, 0xcd, 0x88, 0x25, 0xec, 0x71, 0x20, 0xf2,
+ 0xe5, 0x2b, 0x9a, 0xad, 0xf0, 0x86, 0xce, 0x0b, 0xa4, 0xac, 0x7a, 0x56,
+ 0x58, 0x55, 0x26, 0xde, 0x4f, 0xce, 0x76, 0x53, 0xe3, 0xeb, 0xc7, 0x3a,
+ 0xb5, 0xda, 0xd8, 0xf0, 0xb1, 0x17, 0xa1, 0x86, 0x7f, 0xe4, 0x0c, 0x65,
+ 0xee, 0xd9, 0x5a, 0xd2, 0x33, 0x3f, 0x72, 0xf6, 0xf7, 0x74, 0xf2, 0x2e,
+ 0x55, 0x68, 0xde, 0x60, 0xdb, 0x26, 0x52, 0xb8, 0x4f, 0xdd, 0xd8, 0xc9,
+ 0xfd, 0x8a, 0xe4, 0xb4, 0xef, 0xa3, 0x8f, 0xdf, 0x3a, 0xf5, 0x74, 0x4c,
+ 0xa5, 0x1c, 0x2b, 0xce, 0x57, 0x2c, 0x84, 0xa3, 0x01, 0x27, 0x92, 0x4e,
+ 0x25, 0xfc, 0x3c, 0x67, 0x97, 0x4c, 0x7a, 0x10, 0x1c, 0x70, 0x20, 0x53,
+ 0x4b, 0x2e, 0x96, 0xb0, 0x5a, 0xfc, 0xc0, 0xaf, 0xed, 0x22, 0x29, 0xb1,
+ 0x25, 0xc6, 0xdb, 0x85, 0xaa, 0x8b, 0x22, 0x4b, 0x3a, 0xae, 0xee, 0x16,
+ 0x07, 0x6f, 0xc9, 0xe9, 0x88, 0x84, 0x71, 0x52, 0x8c, 0x60, 0x0b, 0x0c,
+ 0xcf, 0x24, 0x4f, 0x04, 0x5f, 0x0a, 0x51, 0x06, 0xa4, 0x29, 0x22, 0xd2,
+ 0xd2, 0x5d, 0x39, 0x71, 0xea, 0xb6, 0xfe, 0x96, 0x46, 0xa0, 0xb6, 0xec,
+ 0x8e, 0x36, 0xa1, 0x21, 0x90, 0xdb, 0xad, 0x76, 0xa5, 0xa4, 0x4e, 0x5e,
+ 0x2c, 0x57, 0x78, 0xaf, 0xc5, 0x51, 0xb7, 0x46, 0x3c, 0xad, 0x7f, 0x17,
+ 0xf1, 0x74, 0x0f, 0x71, 0x50, 0xf3, 0x98, 0x4c, 0x48, 0xc8, 0x4f, 0xc5,
+ 0x45, 0xb3, 0x3e, 0x88, 0x26, 0xec, 0x68, 0x9e, 0x18, 0xb2, 0x48, 0xfd,
+ 0x71, 0x44, 0xbc, 0x83, 0x6e, 0x37, 0x69, 0x46, 0x8e, 0xdd, 0x80, 0xd2,
+ 0x98, 0x05, 0xe2, 0xa9, 0x3f, 0x9b, 0xd0, 0x22, 0x44, 0xe1, 0xb0, 0x87,
+ 0x4e, 0x9a, 0x2f, 0x1f, 0x21, 0x56, 0x85, 0xe3, 0x49, 0x91, 0x57, 0xe2,
+ 0x70, 0x4f, 0xf0, 0xea, 0x23, 0x37, 0xdb, 0xdc, 0x37, 0xf0, 0xe4, 0x08,
+ 0xd9, 0x7d, 0x74, 0x71, 0x00, 0xf3, 0xac, 0x65, 0x5c, 0x8a, 0x49, 0x1a,
+ 0x85, 0xb0, 0xf2, 0x72, 0x47, 0xea, 0x42, 0x52, 0x83, 0xc4, 0x4b, 0xde,
+ 0xf2, 0x77, 0xec, 0x6e, 0x3f, 0x82, 0x4f, 0x0d, 0x06, 0xa1, 0x94, 0x82,
+ 0xa1, 0xa3, 0xaf, 0x76, 0x15, 0xe6, 0xad, 0xf3, 0xac, 0x53, 0x92, 0xc4,
+ 0x0b, 0x75, 0xbe, 0xb5, 0x51, 0x52, 0xc3, 0x50, 0xcd, 0xb7, 0x9e, 0xe9,
+ 0xf3, 0x36, 0x34, 0xf5, 0x53, 0xbb, 0x3f, 0x65, 0xff, 0xee, 0x07, 0x4f,
+ 0x68, 0xcd, 0xca, 0x03, 0x00, 0x6e, 0xfa, 0x04, 0x4e, 0xc2, 0x0d, 0xdd,
+ 0xd2, 0x5c, 0x10, 0x1a, 0x78, 0xa1, 0x4b, 0xb3, 0x38, 0xe8, 0x72, 0x7e,
+ 0x7a, 0x39, 0x04, 0x58, 0xea, 0x57, 0x1a, 0x4b, 0xa3, 0xa0, 0x2c, 0x5b,
+ 0x01, 0x67, 0x6d, 0xce, 0xf4, 0xcb, 0x2b, 0x39, 0x5f, 0x27, 0xc9, 0xc2,
+ 0xac, 0x90, 0xb3, 0xc0, 0x49, 0x7f, 0xf8, 0x4f, 0x0a, 0x49, 0x54, 0x97,
+ 0xea, 0x67, 0x06, 0xb9, 0xf4, 0x1f, 0x73, 0xab, 0x0e, 0x9c, 0xa8, 0x92,
+ 0x02, 0x02, 0x45, 0x32, 0xa9, 0x70, 0x86, 0x01, 0x12, 0xc8, 0xd8, 0xe0,
+ 0x3e, 0x0d, 0xa6, 0xac, 0x86, 0x32, 0x75, 0x81, 0xe5, 0xd5, 0x1f, 0x6d,
+ 0x83, 0x7a, 0x89, 0x30, 0x5b, 0x1a, 0x2b, 0xba, 0x2a, 0x90, 0xaa, 0xcc,
+ 0x43, 0x25, 0xaa, 0x02, 0x83, 0x42, 0x41, 0x89, 0x4a, 0x84, 0xaa, 0xae,
+ 0x8f, 0xab, 0x18, 0xa9, 0xba, 0x33, 0xb4, 0xf5, 0xab, 0xca, 0x70, 0x63,
+ 0x68, 0xeb, 0x17, 0x53, 0xba, 0x2d, 0xb0, 0x43, 0x27, 0xe7, 0x51, 0xe9,
+ 0x18, 0x9b, 0x6c, 0x0a, 0x6a, 0x1e, 0x06, 0xee, 0x36, 0x59, 0x42, 0xc7,
+ 0x3f, 0x26, 0x80, 0x1d, 0x2c, 0x3f, 0xa0, 0xf2, 0x43, 0x96, 0xd5, 0x2a,
+ 0xf1, 0xa7, 0xcc, 0x2d, 0xe3, 0x53, 0x2e, 0xbb, 0x17, 0x01, 0xae, 0x10,
+ 0xcc, 0x76, 0x0e, 0xac, 0xe2, 0xc3, 0xce, 0x57, 0x72, 0xa9, 0x76, 0x36,
+ 0xbe, 0x74, 0x77, 0x78, 0xab, 0x48, 0xb7, 0xa2, 0x6c, 0x26, 0x76, 0xab,
+ 0x59, 0x12, 0x75, 0x27, 0x5b, 0x82, 0x75, 0xdc, 0xf6, 0x97, 0xb4, 0xae,
+ 0x1f, 0x93, 0xe5, 0x8b, 0xe2, 0xf0, 0xb0, 0xca, 0x6a, 0xc1, 0xd9, 0x05,
+ 0xd5, 0x94, 0x5d, 0x50, 0x41, 0x99, 0x45, 0xec, 0xc5, 0xd9, 0xd3, 0x19,
+ 0x46, 0xe9, 0x45, 0xb8, 0x4b, 0x72, 0xff, 0x87, 0xe2, 0x47, 0x52, 0x8c,
+ 0xee, 0x9a, 0x95, 0xa3, 0x2b, 0x93, 0x86, 0x78, 0x53, 0x5c, 0x6d, 0x0f,
+ 0x6b, 0x76, 0x47, 0x47, 0xaf, 0xcb, 0xd6, 0xe8, 0x89, 0xd5, 0x05, 0xe0,
+ 0x3d, 0xc9, 0xf9, 0x86, 0xcc, 0x6c, 0x3f, 0x39, 0xc5, 0x1b, 0xe4, 0x8b,
+ 0xf5, 0xd3, 0xe6, 0xf7, 0x70, 0xb7, 0xbe, 0xb7, 0xc1, 0x8e, 0x33, 0x42,
+ 0x27, 0x7e, 0x10, 0xa3, 0x03, 0x49, 0x98, 0xaf, 0x0e, 0x21, 0x76, 0x4a,
+ 0xf1, 0xf6, 0x15, 0x5a, 0x5d, 0xf6, 0x52, 0xab, 0x4d, 0x75, 0x67, 0x77,
+ 0x4e, 0xf8, 0x8a, 0xa7, 0x10, 0x15, 0x4d, 0xb4, 0x51, 0x9d, 0x6d, 0x9f,
+ 0xf8, 0x22, 0xf5, 0x12, 0x6e, 0x2e, 0xc1, 0x35, 0x9c, 0xa4, 0x1f, 0xc9,
+ 0x61, 0xf8, 0xb0, 0x27, 0xb7, 0xa8, 0xd8, 0xc5, 0xa6, 0x37, 0xa9, 0x60,
+ 0x3a, 0x31, 0xdf, 0x6d, 0x26, 0x30, 0x75, 0xd7, 0x9d, 0xc2, 0x64, 0x80,
+ 0x83, 0x34, 0x33, 0x8a, 0x6f, 0xd6, 0x87, 0x65, 0xa0, 0x10, 0xb9, 0xaf,
+ 0x6e, 0x76, 0xf3, 0xca, 0x22, 0xe1, 0x88, 0x85, 0x38, 0x4b, 0x21, 0x51,
+ 0x2a, 0x84, 0xe9, 0xcd, 0xaa, 0xec, 0xe7, 0x41, 0x8c, 0xcf, 0x80, 0x59,
+ 0x27, 0x91, 0x74, 0x10, 0x14, 0x18, 0xb7, 0xaa, 0x32, 0xd6, 0xe8, 0xdb,
+ 0x6a, 0xbf, 0x91, 0xc2, 0xe5, 0x5e, 0x0d, 0xd4, 0x2d, 0xf4, 0xac, 0xd6,
+ 0x37, 0xdf, 0x1b, 0xde, 0x60, 0x0d, 0x1a, 0x28, 0xa5, 0xd8, 0x5f, 0x25,
+ 0xbd, 0xdb, 0xc5, 0x39, 0x19, 0x74, 0x61, 0xa8, 0x7b, 0xfb, 0xec, 0x18,
+ 0xe6, 0x1a, 0xfd, 0xdb, 0x9d, 0x37, 0xd2, 0x7f, 0xb1, 0x67, 0x03, 0x1b,
+ 0x68, 0x40, 0xcb, 0xf0, 0x97, 0x53, 0xb6, 0x39, 0x01, 0x1b, 0x15, 0x57,
+ 0x86, 0x7a, 0xaf, 0x2a, 0x09, 0x4f, 0x94, 0x53, 0x85, 0x8b, 0x2d, 0x7a,
+ 0xaf, 0x44, 0x19, 0x3b, 0xcf, 0x3f, 0x44, 0x7c, 0x8b, 0xee, 0x00, 0xae,
+ 0x52, 0xa9, 0x8e, 0x19, 0x1e, 0xee, 0x1a, 0x50, 0x65, 0xe5, 0x55, 0x7c,
+ 0x37, 0xb9, 0xc6, 0x23, 0x12, 0x2f, 0x50, 0x39, 0xb3, 0xa3, 0x6c, 0xae,
+ 0x8c, 0x21, 0x64, 0x67, 0x82, 0x52, 0x7e, 0x39, 0xa5, 0xcf, 0x87, 0x7f,
+ 0xfb, 0xe9, 0x17, 0xe1, 0x19, 0x71, 0xe3, 0x67, 0x72, 0x07, 0x40, 0x08,
+ 0x5d, 0xff, 0xb0, 0xcb, 0xba, 0xdd, 0xed, 0x1d, 0xfa, 0x9c, 0x32, 0xad,
+ 0x0b, 0xd8, 0x87, 0xee, 0xc6, 0x7b, 0xc1, 0xb3, 0x6b, 0x0c, 0x16, 0xfd,
+ 0xf1, 0xf5, 0xa4, 0x3b, 0x1d, 0x2e, 0x2e, 0x6e, 0x6f, 0xfa, 0xa9, 0x22,
+ 0xa5, 0x42, 0xe0, 0xe1, 0xdd, 0x70, 0x5a, 0x3c, 0x42, 0xc8, 0x27, 0xa9,
+ 0xe1, 0x6c, 0x06, 0x14, 0x7c, 0x8a, 0x24, 0xc3, 0xff, 0xbd, 0xed, 0x8e,
+ 0x80, 0xd3, 0x80, 0xcc, 0x46, 0x22, 0x6a, 0x80, 0x44, 0x97, 0xd3, 0x61,
+ 0x77, 0x2e, 0x8c, 0xa8, 0x09, 0x52, 0xdd, 0x8c, 0xe7, 0x32, 0xb3, 0x16,
+ 0xcc, 0x4c, 0x26, 0x6a, 0x83, 0x44, 0xdd, 0xd1, 0xe7, 0xee, 0x57, 0x3e,
+ 0xbf, 0xf4, 0x99, 0xf2, 0x29, 0x11, 0x71, 0x41, 0xd8, 0xbd, 0x2d, 0x3e,
+ 0x12, 0x65, 0x37, 0x6e, 0xa2, 0xa0, 0x7b, 0xa3, 0xe1, 0xcd, 0x60, 0x71,
+ 0xd1, 0xed, 0xcf, 0xc7, 0x53, 0x48, 0xd0, 0xf7, 0xc3, 0xe9, 0x58, 0x23,
+ 0xe7, 0xf1, 0xcd, 0x50, 0x23, 0xe6, 0xd9, 0xb4, 0x8f, 0x35, 0x3a, 0x1a,
+ 0x4f, 0x35, 0xa2, 0xbe, 0xba, 0xb9, 0x5b, 0x14, 0x69, 0x61, 0x89, 0x0f,
+ 0x66, 0xf3, 0x1c, 0x1d, 0x2c, 0x73, 0xc2, 0xb3, 0x48, 0x0b, 0x0b, 0x9e,
+ 0xf4, 0xdd, 0x1d, 0x4d, 0x3e, 0x75, 0x35, 0xb2, 0x4f, 0xc7, 0x29, 0xd3,
+ 0x9e, 0x29, 0xc7, 0x29, 0xd3, 0x75, 0x4a, 0xc7, 0x29, 0xd3, 0x9e, 0x83,
+ 0xb4, 0xfd, 0xf1, 0x4d, 0x61, 0x46, 0x16, 0xac, 0x1c, 0xc2, 0x16, 0x24,
+ 0x87, 0x35, 0xc5, 0x48, 0xe5, 0x31, 0x58, 0x6a, 0x65, 0x81, 0xe4, 0xb0,
+ 0xbe, 0x32, 0x79, 0x2d, 0x66, 0xdd, 0xf9, 0xed, 0x14, 0xaf, 0x16, 0xde,
+ 0xa2, 0x69, 0x60, 0xbc, 0x2c, 0xc1, 0x51, 0x34, 0xdd, 0xeb, 0xf1, 0x60,
+ 0x08, 0x19, 0x6e, 0x77, 0x30, 0xd0, 0xd8, 0xed, 0xec, 0xb6, 0xa7, 0xb1,
+ 0xdb, 0xa9, 0x48, 0x02, 0x4b, 0xe1, 0xfa, 0xea, 0x46, 0x63, 0xa8, 0xd7,
+ 0xdd, 0x2f, 0x1a, 0x13, 0xbd, 0xbe, 0xd5, 0x79, 0x84, 0x59, 0x7f, 0x3a,
+ 0x1c, 0xde, 0x68, 0xac, 0x72, 0xd0, 0x9d, 0xfe, 0x53, 0x20, 0x82, 0xcd,
+ 0x71, 0x74, 0x75, 0xf9, 0x69, 0x2e, 0x50, 0x75, 0x4a, 0x45, 0x9f, 0xbe,
+ 0x50, 0x1a, 0xef, 0x65, 0xd1, 0xcf, 0x30, 0x8b, 0xfe, 0xd5, 0x68, 0x31,
+ 0x9e, 0x1c, 0xe9, 0x33, 0xfe, 0x39, 0x1c, 0x4e, 0x74, 0xc2, 0x1f, 0x4e,
+ 0x46, 0xdd, 0xfe, 0x50, 0xeb, 0x32, 0xfa, 0x5a, 0x4f, 0x31, 0xec, 0x1b,
+ 0x38, 0x89, 0xe1, 0x74, 0xae, 0x51, 0x02, 0xee, 0xea, 0xf3, 0xb4, 0x3b,
+ 0xd1, 0x69, 0x61, 0x28, 0x53, 0x95, 0x3b, 0x66, 0xa1, 0x1a, 0x48, 0x94,
+ 0xef, 0x64, 0x7a, 0x75, 0x0d, 0x49, 0x76, 0x32, 0xbe, 0xba, 0x99, 0xcf,
+ 0x34, 0xb2, 0x1d, 0x5d, 0xdd, 0x0c, 0x75, 0x1b, 0x1f, 0xa1, 0x59, 0x8c,
+ 0xc6, 0xe3, 0x89, 0x46, 0xbc, 0x94, 0x6e, 0x36, 0x9f, 0x5e, 0x4d, 0x34,
+ 0x42, 0xc6, 0x24, 0xdd, 0x9b, 0xcb, 0x91, 0xd0, 0x31, 0x2c, 0xe9, 0x94,
+ 0x2e, 0xc7, 0x14, 0x96, 0x78, 0x46, 0x7c, 0xd1, 0xd5, 0x19, 0x3f, 0x93,
+ 0xcc, 0x62, 0x7e, 0xc1, 0x27, 0x0e, 0x13, 0x52, 0xe9, 0x48, 0x74, 0xaa,
+ 0x85, 0x92, 0x48, 0x48, 0xa2, 0x85, 0x7d, 0x37, 0x97, 0x92, 0x44, 0x0c,
+ 0x3b, 0xef, 0x4c, 0x52, 0x22, 0xad, 0x0d, 0xab, 0x52, 0x96, 0x96, 0xd4,
+ 0x00, 0xd6, 0xab, 0x28, 0x31, 0x89, 0xdc, 0x2e, 0x9a, 0x61, 0x92, 0xa2,
+ 0x4a, 0x81, 0x5c, 0xd2, 0x8c, 0x22, 0x41, 0x77, 0x61, 0xb4, 0x12, 0x81,
+ 0x95, 0x12, 0x10, 0x74, 0x17, 0xe0, 0xef, 0xcd, 0xf4, 0xef, 0x0c, 0xdd,
+ 0x05, 0xa0, 0x68, 0x49, 0x14, 0x02, 0xac, 0x0b, 0x40, 0xdb, 0xfe, 0x90,
+ 0x79, 0x20, 0x27, 0x8f, 0xe7, 0x02, 0x90, 0x9f, 0xa5, 0xe4, 0x10, 0x90,
+ 0x0b, 0x40, 0xdf, 0x49, 0xe9, 0x8b, 0x40, 0x2e, 0x00, 0xf5, 0xb9, 0x44,
+ 0x8d, 0xcf, 0x2d, 0x64, 0xad, 0x3e, 0x79, 0x01, 0x0e, 0xfd, 0xe9, 0x5b,
+ 0x53, 0x50, 0x5c, 0x99, 0x40, 0x93, 0x64, 0xd3, 0x7d, 0x2d, 0xf0, 0xb7,
+ 0xaf, 0x28, 0xcb, 0x4d, 0x83, 0x10, 0x26, 0x69, 0x86, 0x33, 0x6d, 0x9b,
+ 0xbd, 0x15, 0xad, 0xd0, 0xd8, 0xe6, 0x1d, 0xaf, 0xc9, 0x49, 0x25, 0xdf,
+ 0x96, 0xa4, 0xd1, 0xd4, 0xc3, 0x6e, 0xe4, 0x5a, 0xf3, 0x2e, 0x4f, 0x01,
+ 0xab, 0xb1, 0x9a, 0x05, 0xd1, 0xc4, 0xa1, 0xe3, 0x47, 0xe4, 0x6c, 0x87,
+ 0x36, 0xae, 0xbb, 0x5e, 0x62, 0xea, 0x92, 0x1c, 0x27, 0xbb, 0xd7, 0x5e,
+ 0x05, 0x07, 0x1f, 0x38, 0x6a, 0x98, 0xe6, 0x58, 0x93, 0xa1, 0x64, 0xe6,
+ 0xc5, 0x01, 0x70, 0x1c, 0x72, 0x5f, 0xbc, 0x7a, 0x74, 0x3c, 0x9f, 0x54,
+ 0xda, 0xa7, 0x88, 0x34, 0xc0, 0x38, 0x0c, 0x6e, 0x05, 0xf5, 0x69, 0xeb,
+ 0x0c, 0xde, 0x47, 0x1a, 0xc7, 0xf7, 0xee, 0xee, 0xac, 0x38, 0xed, 0xd9,
+ 0x0f, 0x9a, 0x69, 0xb6, 0x8a, 0x40, 0xe0, 0x1f, 0xc8, 0xba, 0xce, 0x65,
+ 0x17, 0x70, 0xd7, 0x1f, 0xa0, 0x95, 0xb3, 0x7a, 0x74, 0x41, 0xe3, 0xb2,
+ 0xeb, 0xb2, 0x13, 0x10, 0xde, 0x2b, 0xd2, 0x57, 0xe2, 0xde, 0x8a, 0xf9,
+ 0x85, 0x91, 0x62, 0xaa, 0x74, 0x5e, 0xc6, 0x13, 0xcd, 0x35, 0xc6, 0x66,
+ 0x5f, 0x9a, 0x78, 0x37, 0x15, 0x92, 0x6d, 0x15, 0xf5, 0x73, 0xb5, 0xdb,
+ 0x6f, 0xbd, 0x95, 0x17, 0x97, 0x0f, 0x9f, 0x3e, 0x60, 0x27, 0x92, 0xa4,
+ 0x89, 0x16, 0xff, 0x1b, 0x2f, 0x22, 0x92, 0xd1, 0xd8, 0xc5, 0xd1, 0x0c,
+ 0x5f, 0x92, 0xd1, 0xcc, 0x0e, 0x7b, 0x37, 0x24, 0xbd, 0x82, 0x99, 0x93,
+ 0x25, 0x85, 0xcd, 0x91, 0x1e, 0xda, 0xbb, 0x69, 0xcb, 0x28, 0x6d, 0x99,
+ 0xb8, 0x0b, 0xb4, 0x85, 0xdf, 0x91, 0xda, 0x46, 0x38, 0x39, 0x00, 0x5b,
+ 0xd5, 0xec, 0x0d, 0x2a, 0x1f, 0xc3, 0xe0, 0x59, 0xd9, 0x5c, 0x7f, 0x17,
+ 0xb4, 0x62, 0xd7, 0x40, 0x6f, 0x24, 0xfd, 0xcc, 0xb9, 0x66, 0xa2, 0x96,
+ 0x2e, 0xb8, 0x4a, 0x47, 0x4f, 0x6f, 0x3f, 0xd2, 0x66, 0x40, 0x7a, 0xb1,
+ 0xe2, 0x5c, 0x74, 0xec, 0x2a, 0xce, 0xac, 0xc9, 0x97, 0x2a, 0x87, 0xdf,
+ 0x9a, 0x19, 0x00, 0x7a, 0x01, 0x60, 0x5b, 0x1c, 0x8a, 0xeb, 0x08, 0x96,
+ 0xe8, 0xc4, 0x4d, 0x9e, 0x56, 0x7d, 0x2c, 0xab, 0xba, 0xd0, 0x62, 0x4d,
+ 0x55, 0x11, 0x6c, 0xba, 0xc3, 0xab, 0xd0, 0xaa, 0x0c, 0xde, 0xeb, 0x30,
+ 0x0e, 0xe9, 0x71, 0x4b, 0xc1, 0x47, 0xfd, 0x34, 0x84, 0x5c, 0x4a, 0xb7,
+ 0xd0, 0xc1, 0xa7, 0x89, 0x6e, 0xb8, 0x84, 0x5b, 0x98, 0xf1, 0x21, 0x05,
+ 0x89, 0x38, 0x89, 0x3e, 0x72, 0xec, 0x1c, 0x45, 0xa7, 0xe6, 0x90, 0x3c,
+ 0x2a, 0xc4, 0x1f, 0x05, 0x63, 0x73, 0xb4, 0xb2, 0x7b, 0x53, 0x96, 0xe6,
+ 0xb0, 0x65, 0x1b, 0x82, 0x1e, 0x15, 0xec, 0x49, 0xdd, 0xe5, 0xc1, 0xc7,
+ 0xce, 0x0a, 0xef, 0x25, 0x94, 0x27, 0x0a, 0x0e, 0xb4, 0xaa, 0x75, 0x27,
+ 0xdc, 0xd0, 0x2b, 0xca, 0x1c, 0xb5, 0x7d, 0x99, 0x20, 0x54, 0x99, 0x3e,
+ 0xf9, 0xc8, 0x00, 0xe5, 0xb2, 0x1d, 0x77, 0x9b, 0x21, 0xa7, 0x24, 0x2a,
+ 0x95, 0x97, 0x94, 0xde, 0x04, 0x7a, 0x45, 0x9c, 0x90, 0xa3, 0x8c, 0x1e,
+ 0x06, 0x1a, 0xa9, 0x6c, 0xf3, 0x30, 0x1b, 0xc0, 0xe4, 0xcb, 0xe4, 0x73,
+ 0x96, 0x8b, 0x5e, 0xa9, 0x7c, 0xae, 0x9d, 0xf0, 0x77, 0x8d, 0xaf, 0x39,
+ 0x97, 0x7d, 0x0d, 0x0c, 0x48, 0xa3, 0x92, 0x6b, 0xd9, 0x35, 0x96, 0xc9,
+ 0x7e, 0x37, 0xc1, 0x7f, 0xc4, 0xcb, 0xf6, 0x91, 0x95, 0x72, 0xe0, 0x51,
+ 0x63, 0x1b, 0xdc, 0x13, 0x33, 0xdc, 0x91, 0xf2, 0x28, 0x6c, 0x8c, 0xb7,
+ 0x57, 0x17, 0x88, 0x56, 0x4d, 0xf2, 0x57, 0x05, 0xc2, 0xeb, 0x39, 0xf8,
+ 0x79, 0x9b, 0xd8, 0xc1, 0x97, 0xf1, 0x94, 0xf0, 0x00, 0x6c, 0x58, 0x7f,
+ 0x0f, 0x6f, 0x62, 0xc4, 0xe6, 0x98, 0x37, 0x95, 0xbd, 0x8f, 0x39, 0xf8,
+ 0x4d, 0x45, 0xef, 0x63, 0x8e, 0x94, 0x66, 0xec, 0x7d, 0xf4, 0x75, 0x3f,
+ 0x53, 0xe7, 0x59, 0x51, 0xee, 0xa6, 0xf7, 0xb2, 0x0a, 0xf8, 0x94, 0x4a,
+ 0x0f, 0xbe, 0x59, 0xb9, 0x22, 0xc2, 0xf4, 0x0f, 0xd8, 0xf6, 0xf5, 0x50,
+ 0x36, 0x32, 0xbd, 0xa5, 0x2d, 0xbc, 0x92, 0xe9, 0xed, 0x62, 0x6e, 0xa9,
+ 0x94, 0xbe, 0xa1, 0x85, 0x1b, 0x90, 0xe0, 0x5f, 0x3a, 0x0a, 0x22, 0x0e,
+ 0xd7, 0x72, 0xae, 0xa0, 0x98, 0xe5, 0x80, 0x5f, 0x2c, 0xd5, 0xfc, 0xef,
+ 0xff, 0xab, 0x40, 0x0a, 0x01, 0x87, 0x94, 0x78, 0xa4, 0x46, 0x76, 0x86,
+ 0x29, 0x41, 0xba, 0x32, 0x74, 0x2c, 0xc2, 0x4b, 0x66, 0xb3, 0x40, 0xfa,
+ 0x2f, 0xed, 0x58, 0xde, 0x66, 0x2d, 0x8c, 0x84, 0x5d, 0xe3, 0x7d, 0x29,
+ 0xfc, 0xb5, 0x97, 0x82, 0xcd, 0x93, 0x74, 0x0a, 0xbc, 0x23, 0x55, 0x9a,
+ 0x28, 0x7d, 0xff, 0xe4, 0x29, 0xc0, 0x8e, 0x4c, 0x2a, 0xdf, 0x93, 0x70,
+ 0x83, 0xf7, 0x89, 0xcf, 0x10, 0xa4, 0x35, 0xf0, 0x5a, 0x98, 0xbc, 0x59,
+ 0xd3, 0x96, 0x70, 0x26, 0x6f, 0xba, 0xe4, 0x21, 0x41, 0x55, 0xc7, 0x6f,
+ 0x8a, 0xbf, 0x54, 0x8a, 0x88, 0x6a, 0x0c, 0x56, 0x53, 0x6c, 0x5b, 0xc4,
+ 0x60, 0xaa, 0x04, 0x8e, 0xc6, 0x9b, 0x23, 0x33, 0x38, 0x26, 0xa1, 0x81,
+ 0x0a, 0x99, 0x49, 0xdd, 0x82, 0x21, 0xa6, 0x54, 0x2a, 0xe2, 0x15, 0x63,
+ 0xf8, 0x56, 0xa9, 0x9f, 0x30, 0x34, 0xe6, 0x66, 0xde, 0x98, 0xaf, 0x7c,
+ 0xcc, 0xd4, 0x5f, 0x55, 0x31, 0xeb, 0x2a, 0x26, 0xd9, 0x30, 0xa8, 0x2a,
+ 0xd6, 0x98, 0xa4, 0xc9, 0x2a, 0x31, 0xb7, 0xc9, 0x33, 0x38, 0x15, 0x96,
+ 0xe3, 0xc7, 0x0b, 0x66, 0x52, 0xf9, 0x80, 0x85, 0x85, 0x7a, 0xc0, 0x94,
+ 0xb4, 0x39, 0x7a, 0xb7, 0xf2, 0xa3, 0xad, 0x9c, 0x5f, 0x36, 0xea, 0x0e,
+ 0x52, 0x8d, 0xec, 0xa0, 0xa9, 0x46, 0xe0, 0x52, 0x59, 0xf5, 0x9f, 0x02,
+ 0xbf, 0x55, 0x2e, 0x0b, 0x20, 0xad, 0x55, 0x41, 0x16, 0x1d, 0x50, 0x16,
+ 0xc0, 0x7a, 0x7f, 0x0b, 0xa9, 0x18, 0xec, 0x1b, 0x7f, 0xad, 0x35, 0xf5,
+ 0x66, 0x72, 0x6e, 0x66, 0xd9, 0xd1, 0x1e, 0x01, 0x74, 0x4d, 0x84, 0x4d,
+ 0x7f, 0x4e, 0x07, 0x5a, 0x76, 0x93, 0x24, 0xd3, 0x19, 0x94, 0xcc, 0x2b,
+ 0x78, 0x28, 0x35, 0x53, 0x2d, 0x23, 0xda, 0xca, 0x56, 0x10, 0x0c, 0x42,
+ 0x06, 0x4c, 0x81, 0x54, 0xb3, 0x4b, 0xce, 0x09, 0x38, 0xad, 0xaa, 0x9d,
+ 0x13, 0x65, 0x9e, 0x6c, 0x46, 0x06, 0x68, 0x5e, 0x98, 0x38, 0x01, 0x1e,
+ 0xfb, 0x72, 0xfa, 0xb5, 0x0a, 0x2c, 0x22, 0x07, 0xb7, 0x10, 0x87, 0xaa,
+ 0x42, 0x0d, 0x50, 0xf7, 0x3e, 0x31, 0x03, 0xb7, 0xa3, 0xb4, 0x23, 0x23,
+ 0x84, 0x3b, 0x4a, 0x3a, 0x2f, 0x20, 0xd2, 0x41, 0xaf, 0xa8, 0x4a, 0x14,
+ 0xd7, 0xce, 0x76, 0xf6, 0x3c, 0xb0, 0x98, 0xfe, 0x36, 0x8d, 0xe4, 0x9f,
+ 0xf2, 0xc9, 0x80, 0xb2, 0xdd, 0xd1, 0xd7, 0x62, 0x77, 0xa9, 0x62, 0x15,
+ 0x9d, 0xf9, 0x9d, 0x65, 0xb3, 0x98, 0x67, 0xf7, 0xb1, 0x17, 0xc9, 0x7d,
+ 0x2c, 0x62, 0x71, 0x07, 0x34, 0x1f, 0x3e, 0xa0, 0xc4, 0x38, 0xc6, 0xec,
+ 0xc4, 0x98, 0x1c, 0xb8, 0xd2, 0xe8, 0x60, 0x13, 0x6c, 0xb7, 0xc1, 0xb3,
+ 0xf0, 0x72, 0xa2, 0xa1, 0xf6, 0x18, 0x25, 0x7d, 0x24, 0x30, 0x79, 0x49,
+ 0x1f, 0xf4, 0x25, 0xe9, 0x6c, 0xef, 0xae, 0x00, 0xfe, 0x5c, 0x0c, 0xd0,
+ 0xa9, 0xb4, 0x4c, 0x0e, 0xb9, 0xa2, 0x03, 0x40, 0x1a, 0xa4, 0xdf, 0x34,
+ 0x2b, 0x28, 0x15, 0x14, 0x03, 0xb4, 0xf9, 0xa1, 0x82, 0xef, 0x61, 0xa8,
+ 0x83, 0x9f, 0xb1, 0x87, 0x2a, 0x89, 0x17, 0xbb, 0xa3, 0x66, 0x8a, 0xcf,
+ 0xab, 0xec, 0x04, 0x6e, 0x74, 0xdd, 0xa2, 0xf4, 0xfa, 0xab, 0xc0, 0x8f,
+ 0xdc, 0xd5, 0x81, 0xae, 0x41, 0x91, 0x7f, 0xc4, 0x3b, 0x40, 0x4e, 0x94,
+ 0x6a, 0xf0, 0x89, 0xfd, 0x29, 0x57, 0xa9, 0xdc, 0xac, 0xa0, 0x30, 0xd9,
+ 0x06, 0x70, 0x1f, 0x2c, 0x53, 0x1e, 0x07, 0xc5, 0x20, 0x0a, 0x82, 0xf2,
+ 0x2a, 0x29, 0xd9, 0x56, 0x4b, 0x38, 0x4d, 0x7d, 0xbc, 0xc9, 0x0d, 0xb6,
+ 0xd8, 0xbf, 0x5c, 0x06, 0x22, 0xdc, 0x30, 0xb3, 0xec, 0x21, 0x7b, 0xc1,
+ 0x0b, 0x75, 0x9b, 0x52, 0xd0, 0x2f, 0xa6, 0x28, 0xe0, 0xe9, 0x0c, 0xde,
+ 0x65, 0xf5, 0xc8, 0x24, 0x93, 0x5e, 0x8a, 0xf7, 0x17, 0xfa, 0xef, 0x55,
+ 0x5c, 0x84, 0x81, 0x1f, 0xab, 0x19, 0xe8, 0x53, 0xb1, 0xe9, 0x3c, 0x26,
+ 0x0e, 0x5e, 0xc8, 0xe3, 0x7d, 0x71, 0x05, 0xdb, 0x99, 0xeb, 0x12, 0xaa,
+ 0xff, 0xc0, 0x04, 0x29, 0x45, 0xf3, 0x61, 0xe0, 0x6e, 0x4e, 0x52, 0x24,
+ 0x58, 0x60, 0x66, 0x1b, 0x32, 0x4b, 0xff, 0x5c, 0xce, 0x8e, 0x43, 0x4b,
+ 0x54, 0x62, 0xa7, 0x86, 0x9e, 0xcb, 0x36, 0xd6, 0x42, 0x39, 0xba, 0x96,
+ 0xab, 0x02, 0xa1, 0xd0, 0xa0, 0xee, 0x9f, 0x31, 0x99, 0xba, 0x1b, 0xb6,
+ 0x6e, 0x8d, 0xbc, 0x41, 0x89, 0x8f, 0xeb, 0x64, 0xbe, 0x9e, 0x55, 0xca,
+ 0xaa, 0x6d, 0xf8, 0xee, 0x52, 0x7e, 0x76, 0x1d, 0x15, 0x57, 0xb0, 0xad,
+ 0x9f, 0x40, 0x9a, 0xc4, 0xa7, 0x9d, 0xad, 0xb1, 0x24, 0x36, 0x12, 0x92,
+ 0x93, 0x90, 0xa5, 0xcc, 0xe6, 0x21, 0xd5, 0x9f, 0x6b, 0x79, 0x46, 0xe1,
+ 0x4a, 0xc9, 0x93, 0x6b, 0xac, 0x1a, 0x4f, 0x18, 0x84, 0x97, 0xfb, 0x2b,
+ 0xa1, 0xc8, 0x18, 0x3c, 0x17, 0x6f, 0xf7, 0x8f, 0x8e, 0xc1, 0x94, 0x3b,
+ 0xc6, 0xa3, 0x13, 0x39, 0x96, 0x4d, 0xb8, 0x79, 0x14, 0x47, 0x0d, 0xe6,
+ 0x70, 0x7e, 0xb6, 0x65, 0xd6, 0xd5, 0x2e, 0x58, 0x17, 0x09, 0xb2, 0xe3,
+ 0xe4, 0x2e, 0x07, 0xcc, 0x5b, 0xd3, 0x81, 0x9c, 0x5c, 0x58, 0xed, 0x23,
+ 0x1f, 0x24, 0xf7, 0xc8, 0x6e, 0xa9, 0x6a, 0x6f, 0xe0, 0x64, 0x2f, 0x43,
+ 0xd7, 0xf5, 0x95, 0x0c, 0x0c, 0x8a, 0x46, 0xa6, 0x04, 0x24, 0x4d, 0xd1,
+ 0xbc, 0xe2, 0xe2, 0xcc, 0xae, 0x24, 0x13, 0x73, 0xe4, 0xfb, 0x07, 0xb8,
+ 0xbb, 0x4d, 0xdd, 0xc8, 0x0d, 0x9f, 0x84, 0x37, 0xb3, 0x15, 0xc7, 0x4d,
+ 0xb3, 0xc8, 0xf3, 0x24, 0x8b, 0x8c, 0x08, 0xd4, 0xd1, 0x8a, 0xf5, 0xbb,
+ 0xc2, 0x0e, 0x2e, 0xf0, 0x49, 0x65, 0x24, 0xdb, 0xbe, 0x77, 0x74, 0x04,
+ 0x25, 0x2b, 0xc2, 0xb0, 0x13, 0xfb, 0x88, 0x4e, 0xf4, 0x16, 0x20, 0xf7,
+ 0x61, 0x1d, 0xd1, 0x87, 0x3e, 0xd7, 0x25, 0xf7, 0x51, 0x3f, 0xa2, 0x8f,
+ 0x6a, 0xa6, 0x70, 0xde, 0xe6, 0xa6, 0x50, 0x40, 0x86, 0x05, 0x2f, 0x20,
+ 0x09, 0xd8, 0x46, 0x63, 0x80, 0x26, 0x61, 0xf0, 0x14, 0xfc, 0x4e, 0x4a,
+ 0x37, 0xe5, 0xc3, 0xa9, 0xb0, 0xef, 0x9b, 0x7c, 0x2c, 0x2c, 0xe1, 0xf6,
+ 0x0f, 0x7a, 0xf2, 0xaa, 0x11, 0xdc, 0xe3, 0x7f, 0x28, 0x6a, 0x1b, 0x6c,
+ 0xfd, 0xf5, 0x0d, 0x73, 0x06, 0x4a, 0x68, 0x58, 0x7d, 0x20, 0x93, 0x6e,
+ 0x83, 0x4a, 0x16, 0xfa, 0x50, 0xe6, 0x1d, 0x30, 0xd7, 0x28, 0x6a, 0xc9,
+ 0x34, 0xff, 0x19, 0xff, 0x40, 0x2b, 0x7f, 0x11, 0x47, 0x57, 0x57, 0x61,
+ 0x78, 0x69, 0x47, 0x9a, 0x05, 0x12, 0x09, 0x34, 0x0c, 0x0c, 0x40, 0x72,
+ 0x6e, 0x10, 0x4d, 0xbc, 0x29, 0xc6, 0xee, 0x1f, 0x95, 0x30, 0x76, 0xd5,
+ 0x99, 0x47, 0x82, 0x1f, 0x9a, 0xb2, 0x74, 0x44, 0x35, 0xa8, 0xbe, 0xb5,
+ 0x52, 0x72, 0xe7, 0xf4, 0x8e, 0x71, 0x7b, 0x6c, 0xc1, 0xd3, 0x79, 0xb6,
+ 0x7b, 0xde, 0xbb, 0x61, 0x40, 0x9f, 0x0c, 0x14, 0x60, 0x6f, 0xa1, 0x82,
+ 0x9e, 0xf3, 0x0e, 0x3f, 0xf6, 0xe7, 0xc8, 0xa1, 0x33, 0x55, 0x8e, 0x86,
+ 0xd6, 0xb1, 0x3f, 0x25, 0xc0, 0x0a, 0xe8, 0xae, 0xfe, 0x9f, 0xf4, 0xe6,
+ 0x3d, 0x7f, 0x07, 0xaf, 0xdf, 0xc4, 0xba, 0x0c, 0x2a, 0x89, 0x70, 0x2b,
+ 0x74, 0x81, 0xcf, 0xf1, 0x8f, 0xde, 0xc3, 0x23, 0xb6, 0x56, 0x96, 0x0f,
+ 0x21, 0xa0, 0x16, 0x39, 0x28, 0x87, 0x2a, 0xf6, 0xaa, 0xe9, 0x6a, 0x1b,
+ 0x3c, 0x9b, 0xf5, 0xa4, 0xb7, 0xe9, 0x04, 0x70, 0x22, 0x79, 0x20, 0x8c,
+ 0xa5, 0xf3, 0xad, 0xdb, 0x22, 0xbd, 0x96, 0x4a, 0x52, 0xa5, 0x1c, 0x51,
+ 0x18, 0x2a, 0x67, 0x78, 0x13, 0x1c, 0x61, 0x01, 0xeb, 0x52, 0x58, 0xea,
+ 0x0c, 0x2a, 0x58, 0xe5, 0x08, 0xde, 0x08, 0x48, 0x18, 0xc6, 0xf0, 0xcd,
+ 0xb0, 0xe0, 0xdf, 0x31, 0x7c, 0x25, 0x0c, 0x5f, 0x10, 0xc6, 0xfa, 0x1d,
+ 0xc3, 0xf7, 0x4f, 0xc1, 0xf0, 0x05, 0x71, 0xbd, 0x4d, 0x30, 0x7c, 0xc1,
+ 0x1b, 0x98, 0xc8, 0x6e, 0xfe, 0xdc, 0x81, 0x9d, 0x8b, 0x01, 0x86, 0x2f,
+ 0xb4, 0xfe, 0x04, 0x8e, 0x46, 0xe0, 0xaf, 0x3b, 0xcf, 0x3f, 0x2d, 0xc5,
+ 0xf1, 0x05, 0x41, 0xc5, 0xff, 0x2e, 0x38, 0xbe, 0xa4, 0xfa, 0xea, 0x08,
+ 0x1c, 0x5f, 0xbb, 0xf5, 0x3d, 0x81, 0x7c, 0xb5, 0xdc, 0xdf, 0x1e, 0xc9,
+ 0x97, 0x44, 0xb1, 0xff, 0x0f, 0x90, 0x7c, 0xd3, 0x77, 0x7d, 0x59, 0xb2,
+ 0x5a, 0x03, 0xea, 0x8b, 0x4e, 0x26, 0xb8, 0x03, 0xeb, 0xe3, 0xb7, 0xc3,
+ 0x4d, 0xb6, 0xdf, 0x0c, 0xe3, 0xb4, 0x6d, 0x80, 0xa8, 0x95, 0x2e, 0xaf,
+ 0xde, 0x64, 0x42, 0x37, 0x34, 0x1c, 0xec, 0x85, 0x62, 0x55, 0x1c, 0x14,
+ 0x18, 0x55, 0xae, 0xf4, 0xdb, 0x25, 0x9d, 0x34, 0xec, 0xe5, 0x7e, 0x5f,
+ 0xb1, 0xea, 0x2f, 0x6d, 0xdb, 0x6e, 0x8a, 0x6d, 0xcd, 0x2a, 0x00, 0xd3,
+ 0xb6, 0x96, 0xdd, 0x11, 0x1b, 0x9b, 0x54, 0x75, 0xf0, 0x9b, 0x1f, 0x29,
+ 0x63, 0x01, 0xe4, 0x23, 0x5a, 0xfa, 0x4d, 0x44, 0x89, 0x23, 0x6b, 0x09,
+ 0x41, 0xe0, 0xf1, 0x38, 0xb2, 0x16, 0xb4, 0x62, 0xaa, 0x02, 0xc9, 0xd2,
+ 0x7b, 0xf8, 0x6a, 0x48, 0x82, 0x45, 0xd6, 0xf4, 0x75, 0x95, 0xc3, 0xf1,
+ 0x5f, 0x39, 0xec, 0xb0, 0x2e, 0xea, 0x05, 0xb5, 0xa9, 0x66, 0x47, 0xcc,
+ 0x41, 0x6b, 0x48, 0x25, 0xcd, 0x2d, 0x0a, 0xb3, 0xa4, 0x31, 0xa6, 0x92,
+ 0xf6, 0xd8, 0xb1, 0x2e, 0x4b, 0x2f, 0xbb, 0x35, 0x82, 0x49, 0xf0, 0x94,
+ 0x4b, 0x05, 0x64, 0x57, 0x17, 0x50, 0x91, 0xed, 0x51, 0x82, 0x02, 0xd8,
+ 0x1c, 0x25, 0x30, 0x80, 0x4f, 0x55, 0xc1, 0x39, 0x22, 0xfa, 0x34, 0x6e,
+ 0x4f, 0xbb, 0x88, 0xa8, 0xf1, 0xd2, 0xd2, 0x0d, 0x47, 0x81, 0x3e, 0x2d,
+ 0x79, 0x3e, 0xb4, 0x76, 0x37, 0x0e, 0xf6, 0x99, 0x62, 0xad, 0x85, 0xd8,
+ 0x09, 0x79, 0x3e, 0xeb, 0x95, 0x21, 0x26, 0x52, 0x0d, 0x70, 0x2e, 0xf5,
+ 0x37, 0xdf, 0x38, 0xec, 0x8f, 0x25, 0xbb, 0x66, 0x1e, 0x55, 0x59, 0x0b,
+ 0xfb, 0xa9, 0x78, 0x31, 0x6b, 0xc6, 0x56, 0x77, 0xd6, 0x53, 0x3b, 0x96,
+ 0xaa, 0x62, 0xb4, 0x0c, 0xc4, 0x68, 0x49, 0x62, 0x2c, 0x83, 0x7e, 0x46,
+ 0x27, 0xfd, 0x60, 0xb7, 0xc3, 0xff, 0x96, 0x7e, 0x6b, 0xf2, 0x20, 0x51,
+ 0xce, 0x49, 0xd3, 0x97, 0x1e, 0xc0, 0xe3, 0x4c, 0x03, 0x3f, 0x9f, 0x3d,
+ 0xcf, 0x92, 0x5e, 0x8b, 0x08, 0x8f, 0x55, 0x0c, 0xb0, 0x9f, 0xe5, 0x07,
+ 0x5a, 0x2a, 0x46, 0x85, 0x72, 0x7d, 0x45, 0x76, 0xb5, 0x76, 0xaf, 0x46,
+ 0xa2, 0x6e, 0x1a, 0x7c, 0x96, 0x3a, 0x65, 0x42, 0x93, 0xa3, 0x24, 0xda,
+ 0xcb, 0x63, 0x52, 0x03, 0x6c, 0x0d, 0x90, 0xf1, 0xf9, 0xd8, 0x52, 0x68,
+ 0xeb, 0xd1, 0xfc, 0x74, 0x34, 0xd4, 0x3a, 0xaa, 0x62, 0xbb, 0x04, 0x12,
+ 0x5b, 0x59, 0x4a, 0x05, 0xe4, 0xc0, 0x8d, 0xa0, 0xb0, 0x9b, 0x05, 0x09,
+ 0x7f, 0x63, 0x58, 0xd7, 0x7c, 0xb3, 0xb0, 0xae, 0xf9, 0x7d, 0xc2, 0xba,
+ 0xe6, 0xbf, 0x43, 0x58, 0x77, 0x45, 0x5f, 0xe1, 0xe8, 0x01, 0x9c, 0x6d,
+ 0x7d, 0x34, 0xc6, 0x58, 0x69, 0x61, 0x9c, 0xf5, 0xc9, 0x10, 0x55, 0xa8,
+ 0x89, 0xae, 0x55, 0xe5, 0x43, 0x85, 0xc1, 0xe9, 0x7c, 0xb1, 0x2a, 0x4d,
+ 0x58, 0x6d, 0x4b, 0xab, 0xe2, 0x8b, 0x65, 0x9f, 0xca, 0x20, 0xc1, 0xcb,
+ 0x7c, 0x71, 0xc5, 0xcd, 0x0c, 0x48, 0x54, 0x42, 0x6f, 0x92, 0x8a, 0x85,
+ 0x15, 0x50, 0x22, 0xda, 0xdb, 0xa3, 0xaf, 0x40, 0x6a, 0xbf, 0x70, 0x81,
+ 0x05, 0x2c, 0x33, 0x08, 0xc3, 0xbe, 0xa1, 0xb2, 0xa2, 0x0c, 0x6d, 0x4a,
+ 0x6e, 0x06, 0x5b, 0xbc, 0x19, 0xb4, 0x3d, 0xc9, 0x94, 0x3a, 0x0c, 0x3f,
+ 0x42, 0xb7, 0x86, 0x6e, 0x7b, 0xb5, 0x2d, 0xa5, 0x46, 0x27, 0x16, 0x7f,
+ 0x84, 0x46, 0xd2, 0xac, 0xee, 0x47, 0xed, 0x4b, 0x29, 0xa1, 0xb1, 0x2d,
+ 0xbc, 0x60, 0xcb, 0xb5, 0x56, 0xbd, 0x9b, 0x22, 0x0d, 0x4e, 0x6e, 0x02,
+ 0xf4, 0x65, 0x3c, 0xe5, 0xc4, 0xcd, 0x32, 0x62, 0x89, 0xb2, 0x65, 0xb0,
+ 0xb0, 0xbb, 0x02, 0xc6, 0x7d, 0x41, 0x93, 0x7a, 0xd7, 0xdb, 0xbb, 0x9c,
+ 0x96, 0x31, 0x30, 0xf0, 0xb8, 0x63, 0xf1, 0x99, 0xdf, 0x46, 0x32, 0x08,
+ 0x65, 0xc2, 0x31, 0x33, 0x88, 0xa4, 0x31, 0x73, 0x29, 0x65, 0x66, 0x11,
+ 0x85, 0x0f, 0xcb, 0xce, 0xc2, 0x21, 0xb5, 0x1e, 0x1d, 0xad, 0x71, 0x10,
+ 0x62, 0x3d, 0x6e, 0xff, 0xc3, 0xd2, 0xaa, 0x2f, 0x1c, 0xfb, 0xe0, 0x69,
+ 0x8d, 0x20, 0x25, 0xd5, 0xea, 0xdb, 0x59, 0x3e, 0x84, 0x56, 0x8b, 0x44,
+ 0x3b, 0x1a, 0x5d, 0xd3, 0x89, 0xd4, 0xc8, 0x45, 0xbf, 0xbb, 0x46, 0x85,
+ 0x56, 0xaa, 0xcf, 0x54, 0x13, 0xc2, 0x66, 0xb3, 0xc9, 0x3f, 0x92, 0xd3,
+ 0x56, 0x10, 0xb2, 0x4f, 0x10, 0x14, 0xc1, 0xf9, 0xf2, 0xf3, 0xb2, 0xac,
+ 0xcd, 0xe2, 0x81, 0xfc, 0x03, 0xcf, 0x6f, 0xa3, 0x7d, 0xe0, 0x47, 0x3e,
+ 0x89, 0xd0, 0xb0, 0x31, 0x9d, 0xee, 0x9d, 0x5f, 0xf8, 0xc0, 0xc8, 0x32,
+ 0x42, 0xe5, 0x43, 0xbf, 0x30, 0x25, 0x2c, 0xbe, 0xf3, 0x03, 0x3b, 0xf7,
+ 0x78, 0xe7, 0x96, 0x5a, 0x5b, 0x8c, 0x8e, 0x53, 0xaa, 0xd4, 0x15, 0xa6,
+ 0x84, 0x79, 0x6c, 0x48, 0x45, 0xef, 0x82, 0xa9, 0x58, 0x2a, 0x1d, 0x91,
+ 0xde, 0x0f, 0x94, 0x6b, 0x4a, 0xa9, 0x52, 0x52, 0x98, 0x12, 0x16, 0xb1,
+ 0xe1, 0x80, 0xde, 0xad, 0xb6, 0x20, 0x78, 0x4b, 0xad, 0x22, 0x46, 0xc7,
+ 0x29, 0x95, 0x3a, 0x4a, 0x09, 0x8b, 0xa0, 0x70, 0x60, 0xef, 0x82, 0xe4,
+ 0x6d, 0xb5, 0x8e, 0x18, 0x1d, 0xa7, 0x54, 0xea, 0x28, 0x25, 0xcc, 0x28,
+ 0x95, 0x3a, 0xa2, 0xbd, 0x8b, 0x8b, 0x54, 0xad, 0x23, 0x46, 0xc7, 0x79,
+ 0x2a, 0x75, 0x94, 0x12, 0x66, 0x94, 0x4a, 0x1d, 0x91, 0xaf, 0x80, 0x48,
+ 0x94, 0x25, 0x3a, 0xea, 0xc8, 0x33, 0x52, 0xeb, 0x28, 0x21, 0xcc, 0x28,
+ 0x95, 0x3a, 0x4a, 0x09, 0x33, 0xbf, 0x53, 0xa6, 0xa3, 0x8e, 0x38, 0xf7,
+ 0x86, 0x5a, 0x47, 0x1d, 0x59, 0xf2, 0x0d, 0xa5, 0x8e, 0x52, 0xc2, 0x8c,
+ 0xb2, 0x4c, 0x47, 0x9d, 0x83, 0x60, 0x21, 0x0d, 0xb5, 0x8e, 0x3a, 0xb2,
+ 0xe4, 0x1b, 0x4a, 0x1d, 0xa5, 0x84, 0x19, 0xa5, 0x4a, 0x47, 0xc4, 0xdb,
+ 0xbf, 0x74, 0xc4, 0xb9, 0x97, 0xe8, 0xe8, 0x45, 0xd2, 0x66, 0x83, 0x5f,
+ 0x0c, 0xa9, 0x77, 0xd8, 0xec, 0xab, 0x37, 0x3b, 0xb0, 0xbc, 0xc3, 0x32,
+ 0x08, 0x4a, 0xaf, 0x7c, 0x1c, 0xd3, 0xf8, 0xce, 0x56, 0xfa, 0x4e, 0xb2,
+ 0x50, 0x06, 0x57, 0x87, 0x77, 0x47, 0xb9, 0x19, 0x38, 0xa5, 0x8e, 0xa7,
+ 0xdd, 0x0d, 0x3b, 0xa2, 0xdb, 0x52, 0xd1, 0x68, 0xf7, 0x40, 0xba, 0x60,
+ 0x35, 0xbb, 0x9a, 0xb4, 0x4e, 0x55, 0x8a, 0xa5, 0x7e, 0x47, 0xb3, 0x7f,
+ 0x51, 0xbf, 0xac, 0xd9, 0x8d, 0x24, 0x77, 0xac, 0x5a, 0x41, 0x74, 0x7b,
+ 0x29, 0x6c, 0x42, 0x65, 0xe7, 0xa4, 0x54, 0xe4, 0xf8, 0x00, 0x59, 0xd4,
+ 0x75, 0x47, 0xa3, 0xa7, 0x1e, 0x3e, 0x95, 0x29, 0xc6, 0xa1, 0x55, 0x93,
+ 0xc1, 0xb7, 0xef, 0xc0, 0x0f, 0xde, 0xa9, 0x53, 0x88, 0xf2, 0x51, 0x44,
+ 0xfe, 0xb8, 0x4c, 0x95, 0xd2, 0xc5, 0xaa, 0x47, 0xaa, 0x0c, 0xfd, 0xf3,
+ 0x8d, 0x8e, 0x54, 0xf7, 0xa7, 0x69, 0x56, 0xe8, 0xc7, 0x1c, 0xa7, 0xbe,
+ 0x01, 0xc6, 0xc2, 0x2e, 0x7c, 0xf2, 0xbc, 0xfa, 0xd9, 0xc9, 0x7e, 0x3f,
+ 0x3b, 0xfd, 0xa0, 0xb3, 0xd3, 0x8f, 0x39, 0xba, 0xac, 0x49, 0x0d, 0xcb,
+ 0x22, 0x2b, 0xf2, 0x15, 0x5d, 0x92, 0x4a, 0x43, 0xb9, 0x26, 0xb6, 0xde,
+ 0x35, 0xe4, 0x5a, 0x58, 0x6d, 0xad, 0x76, 0x68, 0x0b, 0xbb, 0xb9, 0x88,
+ 0xd8, 0xda, 0xea, 0x14, 0x15, 0xf2, 0x77, 0xdd, 0x13, 0x99, 0x2c, 0xcc,
+ 0xe5, 0x6c, 0x2c, 0x5e, 0x48, 0xaa, 0x86, 0x7b, 0x09, 0x3a, 0xf1, 0x1e,
+ 0xfc, 0x20, 0xa4, 0x40, 0x81, 0xe5, 0xbb, 0x4a, 0xca, 0x97, 0x7d, 0xf4,
+ 0x84, 0xa4, 0x6c, 0x23, 0xb4, 0x74, 0xe3, 0x67, 0xf2, 0xc8, 0x20, 0xef,
+ 0x09, 0x51, 0xe2, 0x55, 0x49, 0x82, 0x7a, 0xe6, 0xee, 0x9d, 0x90, 0x7e,
+ 0x57, 0x23, 0x21, 0x61, 0x7f, 0xfb, 0x19, 0x2e, 0xd0, 0xe2, 0x9c, 0xae,
+ 0x06, 0xba, 0x3d, 0xa1, 0x90, 0x2c, 0xfb, 0xc6, 0xfd, 0xe1, 0xad, 0xaf,
+ 0x3f, 0xee, 0xb3, 0x29, 0xf7, 0x29, 0x68, 0xd6, 0x1d, 0x51, 0x51, 0x54,
+ 0xb6, 0x4b, 0x30, 0xec, 0x42, 0xa3, 0x12, 0x2e, 0x40, 0x74, 0x62, 0x37,
+ 0xc0, 0x46, 0xc3, 0x1d, 0x46, 0x56, 0x6b, 0x01, 0x24, 0xe3, 0xd9, 0x88,
+ 0x4f, 0xd3, 0xef, 0x49, 0x02, 0x2c, 0xab, 0x3c, 0xf3, 0xaa, 0xaa, 0x82,
+ 0xc6, 0x5b, 0xdf, 0x40, 0xd1, 0xe1, 0x53, 0x80, 0xcb, 0x08, 0x25, 0x05,
+ 0x21, 0xb2, 0xf8, 0x89, 0x39, 0x0f, 0x5f, 0xf6, 0xf4, 0x45, 0x6f, 0xfc,
+ 0xe8, 0x45, 0xe4, 0xd1, 0xa8, 0x83, 0x5a, 0xec, 0x51, 0x2e, 0x9d, 0xca,
+ 0xff, 0x28, 0x3e, 0xe7, 0xc3, 0x59, 0x23, 0xdf, 0x7d, 0x89, 0x91, 0xdd,
+ 0x94, 0xbe, 0x79, 0x24, 0x14, 0xc9, 0x1a, 0xa0, 0x10, 0x88, 0xdc, 0xb6,
+ 0xc1, 0x33, 0x6a, 0xd8, 0x12, 0xb3, 0x6a, 0x68, 0x04, 0x72, 0x80, 0xe5,
+ 0xff, 0xb0, 0x00, 0xab, 0xf9, 0xbd, 0xb5, 0x67, 0x7f, 0x17, 0xed, 0xed,
+ 0xbc, 0x75, 0x8d, 0x94, 0x21, 0xbf, 0x9d, 0x06, 0x09, 0xc7, 0xbf, 0xad,
+ 0x16, 0x5b, 0xdf, 0x5b, 0x8b, 0x8d, 0x32, 0x17, 0xb8, 0x17, 0x00, 0x30,
+ 0x85, 0xfb, 0xd5, 0x86, 0x76, 0x9a, 0x24, 0xd4, 0xda, 0x4b, 0x41, 0xb2,
+ 0x2e, 0x28, 0x56, 0x28, 0x95, 0xd8, 0x14, 0x0b, 0xbd, 0x52, 0x3e, 0xac,
+ 0x16, 0xfe, 0x2b, 0xda, 0xa4, 0x85, 0x92, 0xa0, 0x49, 0xb1, 0x28, 0x97,
+ 0x7e, 0x76, 0x93, 0x7d, 0xd5, 0x0a, 0xe1, 0x46, 0xd2, 0xfd, 0x16, 0x1e,
+ 0xd0, 0x44, 0x55, 0x53, 0x6b, 0x70, 0xc1, 0x25, 0x5a, 0x18, 0xb5, 0xd7,
+ 0xa4, 0xf0, 0xd9, 0xe4, 0x92, 0xeb, 0xaf, 0x63, 0x5e, 0x6d, 0x03, 0xf3,
+ 0x6a, 0x4a, 0xe6, 0xa5, 0x41, 0x87, 0x66, 0x90, 0xdb, 0x05, 0x80, 0x6b,
+ 0xa1, 0x08, 0xcb, 0xe0, 0x39, 0x1f, 0x65, 0x02, 0xe2, 0x5c, 0x5b, 0x25,
+ 0x25, 0x17, 0x9a, 0x69, 0x64, 0x58, 0x6f, 0xf4, 0x22, 0x79, 0x45, 0x40,
+ 0x55, 0xf9, 0x52, 0x11, 0xd1, 0xaf, 0xe5, 0x0f, 0x66, 0xab, 0x96, 0x06,
+ 0x6f, 0x91, 0x98, 0xda, 0x38, 0x5c, 0x43, 0xdf, 0x7a, 0xe6, 0xf5, 0x80,
+ 0xe5, 0x37, 0xdb, 0x74, 0x40, 0x43, 0xc5, 0x33, 0xad, 0x96, 0x41, 0x31,
+ 0x02, 0xfb, 0x2c, 0x1f, 0xfb, 0x64, 0x32, 0x37, 0xf1, 0xb9, 0x88, 0xa5,
+ 0x5d, 0xad, 0xa0, 0x4e, 0x64, 0x98, 0x55, 0xcd, 0xaa, 0xf8, 0x19, 0x95,
+ 0xd6, 0x81, 0x23, 0x9c, 0x95, 0x40, 0x7e, 0x1b, 0xac, 0x43, 0x70, 0x94,
+ 0x65, 0x3c, 0x8b, 0x65, 0xed, 0x65, 0xca, 0xcd, 0x49, 0x52, 0xfd, 0x79,
+ 0x3d, 0x83, 0x57, 0xf6, 0x19, 0x53, 0x59, 0x9a, 0x6a, 0x9e, 0x55, 0x4d,
+ 0xbc, 0x51, 0x66, 0xe2, 0x19, 0xb2, 0x3f, 0x3e, 0x04, 0xc4, 0xb4, 0xa0,
+ 0xb1, 0xc4, 0xba, 0xf3, 0x28, 0x32, 0xdc, 0x99, 0x19, 0xe1, 0x07, 0xcb,
+ 0x7d, 0xa9, 0x92, 0x4a, 0xda, 0xe9, 0x11, 0xe7, 0x8f, 0xbb, 0x49, 0x1f,
+ 0x9f, 0x30, 0x47, 0x9f, 0x9f, 0x74, 0x4b, 0xe5, 0x9e, 0xb2, 0x8f, 0x1a,
+ 0x24, 0x3a, 0xce, 0x37, 0x6c, 0x7f, 0x28, 0x8c, 0xf6, 0x2a, 0x29, 0xc9,
+ 0x63, 0x1f, 0x01, 0x99, 0x29, 0x5e, 0xfd, 0xdc, 0x46, 0xae, 0xfc, 0x1d,
+ 0x8f, 0xec, 0xbb, 0x08, 0x26, 0x6f, 0xe0, 0x00, 0xc3, 0x20, 0xa5, 0x7b,
+ 0xc1, 0x06, 0x4f, 0x93, 0xc0, 0xb4, 0xb0, 0xe4, 0x09, 0x36, 0x0e, 0x35,
+ 0x77, 0x95, 0x13, 0x04, 0x4f, 0xa5, 0x7f, 0xe3, 0x32, 0xd1, 0x92, 0x6f,
+ 0x40, 0xe7, 0x90, 0x90, 0x4a, 0x3e, 0xb0, 0xc9, 0x5f, 0x70, 0x99, 0x7e,
+ 0xad, 0x59, 0xef, 0xb1, 0x93, 0x3a, 0xb4, 0x95, 0xf2, 0x6b, 0xcd, 0xfa,
+ 0x67, 0x8a, 0x09, 0x4c, 0xce, 0xd5, 0x00, 0x91, 0x2f, 0x52, 0x93, 0x4f,
+ 0x96, 0xf2, 0x77, 0x25, 0x6c, 0x94, 0xc0, 0x66, 0xa2, 0x7f, 0x50, 0x99,
+ 0x01, 0xa8, 0x55, 0x63, 0xac, 0xaf, 0x01, 0x28, 0x8e, 0x37, 0x91, 0xa1,
+ 0x8a, 0xa5, 0xbe, 0x44, 0x0c, 0x1a, 0xab, 0x86, 0xa9, 0xbe, 0x44, 0x30,
+ 0xfb, 0x92, 0x33, 0x63, 0x81, 0xd6, 0x01, 0xf6, 0x04, 0xc9, 0x77, 0x10,
+ 0x80, 0xe5, 0xa9, 0x7f, 0x44, 0x3d, 0x27, 0xdf, 0x91, 0x09, 0x36, 0x1b,
+ 0xe4, 0xd2, 0xf2, 0xba, 0x3f, 0x10, 0xe6, 0x03, 0xbc, 0x99, 0xd5, 0x3f,
+ 0xe8, 0xee, 0xe7, 0xd5, 0x80, 0x1e, 0xf1, 0x01, 0x29, 0x4a, 0x33, 0x32,
+ 0x9e, 0x4f, 0x51, 0x92, 0x08, 0x4a, 0x3c, 0x4b, 0x1a, 0x92, 0x6f, 0x9e,
+ 0xe6, 0xc2, 0xe5, 0xe2, 0x6e, 0xa3, 0xd3, 0xd7, 0x37, 0xf7, 0x64, 0x82,
+ 0xff, 0x23, 0x4b, 0xfc, 0x10, 0x61, 0x89, 0x63, 0x7d, 0x6e, 0xd9, 0xbb,
+ 0x1a, 0xb4, 0x62, 0x0f, 0xa7, 0x3e, 0x93, 0xe5, 0x87, 0xbd, 0xb9, 0x47,
+ 0xdd, 0x40, 0x1c, 0xb0, 0xdf, 0x07, 0xde, 0x1a, 0x7d, 0xb6, 0x81, 0x05,
+ 0x54, 0x58, 0x84, 0xc5, 0x8e, 0x79, 0x69, 0x58, 0xf6, 0x32, 0x16, 0x77,
+ 0x91, 0xfb, 0x94, 0x37, 0x10, 0x54, 0x1c, 0xf3, 0x01, 0x5a, 0x41, 0x52,
+ 0x91, 0x9b, 0x4c, 0xd7, 0x83, 0x3e, 0x7b, 0x7c, 0xd4, 0x57, 0x9b, 0x99,
+ 0x46, 0xf4, 0xcc, 0x2b, 0x7f, 0x88, 0xd7, 0x78, 0xd8, 0x06, 0x5f, 0xe5,
+ 0x95, 0x39, 0x9b, 0x0e, 0xd9, 0xe0, 0x2b, 0xd0, 0x02, 0xc2, 0x6b, 0x72,
+ 0x30, 0x11, 0xc0, 0xe7, 0xe8, 0xf6, 0x50, 0xfe, 0xfd, 0xf5, 0xb2, 0x48,
+ 0xc4, 0xe4, 0x7b, 0xf2, 0x04, 0xe3, 0x2a, 0xb5, 0xf6, 0x73, 0x13, 0xa6,
+ 0x76, 0xed, 0xd9, 0x21, 0x9f, 0x98, 0x26, 0x4e, 0x0b, 0x0e, 0xd8, 0xcf,
+ 0xf5, 0x7e, 0xa5, 0xa9, 0x67, 0xa2, 0xf7, 0x29, 0x93, 0x30, 0xd8, 0x3b,
+ 0x0f, 0xc4, 0x92, 0x6e, 0x9c, 0x1b, 0x68, 0xf5, 0xea, 0x1d, 0x45, 0x5e,
+ 0x42, 0xd5, 0xbe, 0x85, 0x5e, 0x26, 0xa6, 0x4a, 0x5f, 0x76, 0xb7, 0xcd,
+ 0x3e, 0x77, 0x5d, 0xf9, 0xbb, 0xed, 0xc2, 0x67, 0xd4, 0xcb, 0xf8, 0xbe,
+ 0xe5, 0x97, 0xc8, 0xcb, 0xf9, 0x56, 0xfb, 0xce, 0x78, 0x09, 0x6e, 0x5c,
+ 0x69, 0x3c, 0xf4, 0x8d, 0x9f, 0x1e, 0x37, 0xba, 0x05, 0xbd, 0x73, 0x57,
+ 0x8a, 0xc7, 0x39, 0x06, 0x6f, 0x92, 0xc5, 0x0b, 0x1d, 0x9e, 0x05, 0x6a,
+ 0x18, 0xbc, 0x7b, 0xe2, 0x53, 0x7b, 0x24, 0x0f, 0x3a, 0x59, 0xfe, 0x5c,
+ 0x17, 0x86, 0xf2, 0x46, 0x32, 0xbd, 0xea, 0xe2, 0x4b, 0xa0, 0xf7, 0x44,
+ 0xf8, 0x52, 0xd5, 0x45, 0x24, 0xa7, 0x5f, 0xbe, 0xc6, 0xae, 0xf6, 0x2a,
+ 0x92, 0x93, 0x47, 0x8f, 0x41, 0x18, 0x6b, 0xeb, 0x21, 0x38, 0x3d, 0xcd,
+ 0xdf, 0x68, 0x2a, 0x23, 0x24, 0x6a, 0x7b, 0x61, 0xd5, 0xd9, 0xff, 0x81,
+ 0xef, 0xf0, 0x2a, 0xcb, 0x02, 0x66, 0xde, 0x03, 0x39, 0x7b, 0x90, 0xd0,
+ 0x39, 0x7e, 0x85, 0xf0, 0x5f, 0x1b, 0x7a, 0xe7, 0x74, 0x43, 0xee, 0x3b,
+ 0xc9, 0xbb, 0xa4, 0x52, 0x3e, 0x06, 0x38, 0x2a, 0x24, 0x36, 0x74, 0xc8,
+ 0xe6, 0x1e, 0x9f, 0xb2, 0xfc, 0x55, 0x81, 0x49, 0x21, 0x4a, 0x29, 0x8f,
+ 0x16, 0xc8, 0x96, 0x92, 0x85, 0x9c, 0x85, 0xb8, 0x0c, 0x48, 0xbc, 0x55,
+ 0x01, 0xc3, 0xcc, 0xb1, 0xbf, 0x83, 0x22, 0x5a, 0x81, 0xb5, 0xd1, 0x2d,
+ 0x68, 0x12, 0x28, 0x0f, 0xbc, 0x27, 0x2f, 0x02, 0xd1, 0x0d, 0x0c, 0xf6,
+ 0x6f, 0x96, 0x07, 0x2d, 0xdd, 0x49, 0x8d, 0x20, 0x32, 0xc9, 0x9e, 0xff,
+ 0x90, 0x7c, 0xed, 0x30, 0xb9, 0xe9, 0xa7, 0x88, 0x54, 0x91, 0x1b, 0x1f,
+ 0xf6, 0x90, 0x9f, 0xe1, 0x09, 0x49, 0xc1, 0x43, 0x68, 0x4a, 0xed, 0x0b,
+ 0x2c, 0xea, 0x45, 0x67, 0xc1, 0x6b, 0xd0, 0x21, 0x1e, 0x45, 0x26, 0x78,
+ 0xa5, 0x79, 0x7f, 0x00, 0x87, 0x2a, 0xfd, 0x49, 0x85, 0x3c, 0xc5, 0x3f,
+ 0xae, 0x74, 0x1a, 0x07, 0x47, 0x50, 0x52, 0x40, 0x7f, 0x90, 0x8b, 0x24,
+ 0x6d, 0x71, 0x14, 0x5f, 0x8e, 0xd8, 0xa4, 0x7e, 0xdd, 0x00, 0xfa, 0x64,
+ 0xab, 0xa1, 0x77, 0xad, 0x2c, 0x9c, 0xc3, 0x6a, 0x64, 0xe7, 0x65, 0x33,
+ 0x48, 0xf9, 0x5c, 0x23, 0x43, 0x58, 0xf9, 0x5c, 0xab, 0x23, 0xa0, 0xe5,
+ 0xc9, 0xde, 0x04, 0x5c, 0x24, 0x80, 0x59, 0xa5, 0x0a, 0xc6, 0x4c, 0xd7,
+ 0xed, 0xdb, 0xd8, 0xb2, 0x55, 0xcd, 0x0e, 0xf5, 0x47, 0x2d, 0x95, 0x1d,
+ 0xea, 0x7d, 0xa8, 0xc2, 0x0e, 0xf5, 0x4e, 0xdc, 0x3f, 0xec, 0xd2, 0x76,
+ 0x2d, 0xc0, 0x7e, 0xd5, 0x37, 0x11, 0xef, 0xf6, 0xfb, 0x23, 0xec, 0x77,
+ 0xee, 0xbe, 0xc4, 0x07, 0x7c, 0xba, 0x4e, 0xa2, 0x4a, 0x72, 0xa5, 0x87,
+ 0x7f, 0x4f, 0xee, 0x23, 0xea, 0xa8, 0x7f, 0x71, 0xb9, 0xb8, 0x1e, 0x0f,
+ 0x86, 0xbf, 0x5a, 0x60, 0x5e, 0xcc, 0x0d, 0x6b, 0xec, 0x80, 0x4e, 0x5e,
+ 0x18, 0x28, 0x11, 0xe2, 0x1a, 0x85, 0x54, 0x16, 0x10, 0xcb, 0xb9, 0x84,
+ 0x4d, 0x02, 0xbf, 0x44, 0x6e, 0xe7, 0x42, 0x54, 0x04, 0x49, 0x69, 0x02,
+ 0x56, 0xa7, 0x0c, 0x0e, 0xf3, 0x0c, 0xe3, 0x72, 0x86, 0x8d, 0xca, 0x0c,
+ 0xa3, 0x52, 0x86, 0x1c, 0x2c, 0x50, 0x7d, 0x63, 0x87, 0x3e, 0x87, 0xce,
+ 0x5e, 0x7a, 0x1f, 0x09, 0x81, 0xf8, 0xaa, 0x6d, 0x95, 0x36, 0x27, 0x95,
+ 0x51, 0x68, 0x3a, 0x9c, 0x0c, 0xbb, 0x73, 0xad, 0x9d, 0xf2, 0x06, 0xfd,
+ 0x51, 0xf7, 0x7a, 0xa2, 0xb5, 0x50, 0x4e, 0x7f, 0x7d, 0x35, 0x9d, 0x8e,
+ 0xa7, 0xda, 0x98, 0x97, 0x37, 0xe8, 0x8d, 0xa7, 0x83, 0xe1, 0x54, 0x1b,
+ 0xf4, 0xe6, 0x7b, 0x58, 0x8c, 0x6f, 0xfa, 0xc3, 0x62, 0xec, 0x5b, 0xb2,
+ 0x06, 0xe6, 0xa5, 0x52, 0x34, 0x58, 0xf1, 0xef, 0x52, 0x24, 0x91, 0x5d,
+ 0xa9, 0x14, 0x0d, 0xee, 0x08, 0xde, 0xa5, 0x48, 0x22, 0x78, 0xf7, 0x39,
+ 0xa9, 0x98, 0x4b, 0xab, 0x25, 0xe0, 0xb7, 0xca, 0xf2, 0x36, 0xad, 0xdd,
+ 0xed, 0xc9, 0xb1, 0x3c, 0x78, 0x2e, 0xb2, 0xd1, 0xef, 0xd9, 0xfd, 0xc0,
+ 0xdd, 0x6c, 0xbc, 0x95, 0x47, 0x92, 0x33, 0xdb, 0x20, 0xf8, 0xfd, 0xb0,
+ 0x57, 0x8c, 0xc8, 0xfc, 0x93, 0x94, 0xdd, 0x43, 0x1c, 0x8c, 0xc6, 0x83,
+ 0xff, 0x26, 0x49, 0x5a, 0xb4, 0xf4, 0xf0, 0xa1, 0x2a, 0xf0, 0xb7, 0x00,
+ 0x42, 0x84, 0x3e, 0x7d, 0xd5, 0x23, 0x8d, 0xa3, 0xc3, 0x7e, 0xbf, 0xf5,
+ 0xa0, 0x90, 0x44, 0x9f, 0xa8, 0xbf, 0x74, 0xc8, 0x83, 0x42, 0x54, 0xfa,
+ 0x45, 0x5b, 0x7d, 0x64, 0x7e, 0xe1, 0xc6, 0xab, 0xc7, 0x72, 0x26, 0x85,
+ 0x20, 0xbd, 0xc8, 0x65, 0xc4, 0xa4, 0x0b, 0xe7, 0x24, 0xe4, 0x4c, 0x34,
+ 0x68, 0x7c, 0xe9, 0x2e, 0x6c, 0x0f, 0xb4, 0x2b, 0x87, 0x93, 0xa6, 0xe8,
+ 0x1c, 0x9a, 0xa5, 0x93, 0x36, 0x68, 0x0c, 0xb4, 0x8b, 0x26, 0x25, 0xed,
+ 0x1f, 0x96, 0x04, 0xcf, 0x79, 0xaf, 0x5d, 0x34, 0x69, 0x03, 0x6b, 0xa0,
+ 0xcd, 0x58, 0x70, 0x52, 0x06, 0x89, 0xa3, 0x4d, 0x59, 0x64, 0x83, 0x79,
+ 0xf4, 0xb0, 0x9c, 0x69, 0xe9, 0x4d, 0x31, 0x71, 0x21, 0x5d, 0xf6, 0x1d,
+ 0x11, 0xe4, 0x58, 0x9a, 0x20, 0x27, 0x6d, 0x19, 0xd1, 0xa4, 0x58, 0x48,
+ 0x53, 0x61, 0x68, 0x49, 0xc0, 0x7c, 0xaa, 0x7e, 0xb3, 0xa1, 0x90, 0x93,
+ 0x88, 0xc9, 0xbd, 0xd0, 0x33, 0xe1, 0xd7, 0x20, 0xa7, 0xfe, 0x38, 0xe9,
+ 0x09, 0xbe, 0x52, 0xd4, 0x1f, 0x14, 0x45, 0x86, 0xb6, 0x9e, 0xa1, 0xfe,
+ 0x00, 0x29, 0x32, 0xb4, 0xf4, 0x0c, 0xf5, 0x37, 0x96, 0x22, 0xc3, 0xba,
+ 0x9e, 0x21, 0x08, 0xab, 0xaa, 0x55, 0xb1, 0xee, 0xf3, 0x36, 0x23, 0xf7,
+ 0x09, 0x07, 0x72, 0x75, 0x52, 0x06, 0x46, 0x4e, 0x18, 0xab, 0x78, 0xfb,
+ 0x0a, 0x7f, 0xef, 0xd3, 0x2e, 0xa2, 0x80, 0x28, 0x99, 0x91, 0x8f, 0x86,
+ 0xaa, 0xe2, 0x5f, 0xbb, 0xa5, 0x17, 0x75, 0xca, 0xe7, 0xb6, 0xb7, 0x98,
+ 0x74, 0x81, 0x4a, 0x69, 0xdb, 0xa4, 0x62, 0x98, 0x42, 0x4c, 0x51, 0x4e,
+ 0x10, 0x03, 0x7d, 0x02, 0xea, 0x82, 0xe4, 0x29, 0x11, 0x71, 0xcb, 0x40,
+ 0x7a, 0xc8, 0xe6, 0x49, 0x8e, 0xa8, 0xa3, 0x40, 0x3a, 0xbc, 0x76, 0x5e,
+ 0x58, 0xff, 0xb5, 0x60, 0x53, 0x1b, 0xb8, 0xb1, 0xe3, 0x6d, 0x21, 0x4e,
+ 0xf5, 0x8e, 0x9e, 0x93, 0xe7, 0x1b, 0x70, 0xb2, 0xce, 0xed, 0x3c, 0x27,
+ 0x40, 0x2a, 0x41, 0xc8, 0x92, 0xf1, 0xa4, 0xce, 0x8e, 0x3e, 0x88, 0x86,
+ 0x38, 0x9d, 0xe9, 0xd1, 0x67, 0x24, 0x46, 0x4b, 0xa1, 0x82, 0x5a, 0x42,
+ 0xbc, 0xd4, 0x8b, 0x59, 0xe2, 0xf3, 0x40, 0x50, 0xfd, 0x21, 0x46, 0x06,
+ 0xe5, 0x55, 0x12, 0xa3, 0x10, 0x86, 0xd7, 0x37, 0x46, 0x68, 0x98, 0xd1,
+ 0xeb, 0xdc, 0x39, 0xa2, 0xb0, 0x52, 0xab, 0x60, 0x47, 0x0a, 0x7e, 0x42,
+ 0xf7, 0x5f, 0x07, 0xf0, 0xaa, 0xda, 0x32, 0x38, 0xf6, 0x53, 0xae, 0xc3,
+ 0x79, 0x1f, 0xc2, 0x7e, 0xa0, 0xa5, 0x33, 0xea, 0x10, 0x08, 0xe6, 0x95,
+ 0x3a, 0x8b, 0xaf, 0xa8, 0xfb, 0xe2, 0x41, 0x9f, 0x93, 0xb4, 0x0d, 0xee,
+ 0xf6, 0x45, 0x46, 0x5f, 0x94, 0x8c, 0x0c, 0xe0, 0x7f, 0x66, 0xcf, 0xde,
+ 0x1f, 0x7f, 0x90, 0x78, 0x08, 0x88, 0x97, 0x39, 0x72, 0xbd, 0x3a, 0x60,
+ 0x4e, 0xdb, 0x13, 0x0c, 0x68, 0xed, 0x96, 0x9f, 0x12, 0x8f, 0x85, 0xef,
+ 0xe3, 0xaa, 0x76, 0xfb, 0x94, 0x76, 0x2a, 0xdc, 0x39, 0xa8, 0xb6, 0xfb,
+ 0x94, 0xf6, 0x92, 0x59, 0xa1, 0x66, 0xaf, 0x4f, 0xa9, 0x7b, 0xd4, 0xf6,
+ 0x35, 0xbb, 0x7d, 0x26, 0x1f, 0xb6, 0xe2, 0x2a, 0x3c, 0x97, 0xca, 0xba,
+ 0x01, 0x24, 0x6b, 0x19, 0x14, 0xc9, 0xa5, 0x73, 0x82, 0x9a, 0x17, 0xde,
+ 0xcd, 0x29, 0x9b, 0x4f, 0xa1, 0xe6, 0x06, 0x25, 0x8a, 0x0c, 0x4a, 0xb8,
+ 0x80, 0x61, 0x0f, 0x1c, 0xaa, 0xb2, 0x53, 0x00, 0x04, 0x78, 0x0f, 0xe4,
+ 0xb4, 0xa6, 0x97, 0x3d, 0xc0, 0x56, 0xeb, 0x06, 0x30, 0x2a, 0xe9, 0xd6,
+ 0x28, 0xde, 0x9f, 0x08, 0xf9, 0xb4, 0xba, 0x01, 0xf6, 0x18, 0x2b, 0x7c,
+ 0xa6, 0x93, 0xcb, 0x06, 0x21, 0xc0, 0x86, 0xeb, 0xbd, 0xa7, 0x58, 0x39,
+ 0x0d, 0x70, 0x30, 0xf8, 0x44, 0xa4, 0x00, 0x08, 0x04, 0x30, 0x68, 0x19,
+ 0x38, 0x3a, 0x86, 0xc4, 0x98, 0x54, 0x73, 0x9f, 0xb4, 0x9b, 0x35, 0x72,
+ 0xd3, 0x86, 0xf7, 0x04, 0x7a, 0x53, 0xc5, 0x5f, 0x4c, 0x95, 0x21, 0x23,
+ 0xab, 0x85, 0x4b, 0x63, 0xc2, 0x3d, 0x29, 0x15, 0xe3, 0x97, 0x34, 0x95,
+ 0x2f, 0x44, 0x09, 0x98, 0x2e, 0x3e, 0xb0, 0xb1, 0xc3, 0xe3, 0x85, 0xb7,
+ 0x15, 0x79, 0x15, 0x03, 0x2d, 0xa5, 0xa8, 0xae, 0x9d, 0x07, 0x25, 0x1f,
+ 0x15, 0x6e, 0x1c, 0x10, 0x5f, 0xb9, 0xfe, 0x61, 0x97, 0x9b, 0x25, 0x45,
+ 0xb4, 0x64, 0xcf, 0x10, 0xb3, 0xea, 0x6d, 0x28, 0x66, 0x17, 0xe8, 0xd0,
+ 0x14, 0x80, 0x52, 0x31, 0x68, 0x84, 0x66, 0x37, 0xe3, 0xe9, 0x35, 0x80,
+ 0x3d, 0xa6, 0x6d, 0x7a, 0x09, 0xbd, 0x5f, 0x36, 0x68, 0x95, 0xeb, 0xb1,
+ 0x51, 0xa1, 0x6d, 0xaf, 0xdb, 0x01, 0x52, 0x05, 0x46, 0xed, 0x72, 0xbd,
+ 0xb6, 0xaa, 0xb4, 0x16, 0xe1, 0x57, 0xda, 0x95, 0xba, 0xe5, 0x8f, 0x11,
+ 0xcf, 0x2a, 0x75, 0xb8, 0xe8, 0xf2, 0xef, 0xc4, 0x77, 0xaa, 0xb4, 0xb4,
+ 0xea, 0x8b, 0x2e, 0x7f, 0x9e, 0x7e, 0x6e, 0xde, 0x54, 0x78, 0x0e, 0x69,
+ 0x55, 0xb0, 0x1f, 0xab, 0x9d, 0x37, 0xa0, 0x2a, 0x16, 0x24, 0x76, 0x5a,
+ 0xc5, 0x86, 0x8a, 0xbd, 0x56, 0xb3, 0x22, 0xb1, 0xdf, 0x6a, 0x76, 0x54,
+ 0xec, 0xb9, 0x82, 0x25, 0x59, 0xed, 0x0b, 0xde, 0xae, 0x8a, 0x21, 0x49,
+ 0x0d, 0x2b, 0x59, 0x52, 0x57, 0x6a, 0x5a, 0xc1, 0x94, 0x2c, 0xeb, 0x62,
+ 0x71, 0x49, 0xfe, 0x81, 0x4d, 0x4a, 0xe0, 0x50, 0xc1, 0xa2, 0x2e, 0x7b,
+ 0xe7, 0x8b, 0x21, 0x5f, 0x38, 0xb6, 0xb9, 0x55, 0x0d, 0x86, 0x93, 0xf9,
+ 0x27, 0xd4, 0x1f, 0x5f, 0x4f, 0xc4, 0x47, 0xba, 0xe6, 0x86, 0xc5, 0xdb,
+ 0x0b, 0xaf, 0x81, 0x6d, 0x73, 0x03, 0xe3, 0xed, 0x1b, 0x36, 0x9f, 0xbb,
+ 0x6d, 0x6e, 0x63, 0x94, 0x81, 0xdd, 0x5c, 0x7c, 0x11, 0x5c, 0x64, 0x05,
+ 0x3b, 0x13, 0x06, 0x5d, 0xc5, 0xba, 0x78, 0x2b, 0x6e, 0x5b, 0xa4, 0x34,
+ 0x3f, 0xbd, 0x37, 0x3d, 0xf8, 0x1b, 0xba, 0x47, 0xe1, 0xe3, 0x27, 0xbd,
+ 0x71, 0x4b, 0xd3, 0x71, 0xd9, 0xc3, 0x2c, 0x5d, 0x17, 0x33, 0x61, 0x3a,
+ 0x67, 0xba, 0x2e, 0x92, 0x4f, 0xb4, 0x56, 0xee, 0x43, 0x54, 0x79, 0x47,
+ 0xd7, 0x49, 0xf2, 0xa5, 0xd2, 0xaa, 0x9d, 0x4c, 0x25, 0xbd, 0x9e, 0xeb,
+ 0x7a, 0x21, 0x31, 0xcc, 0x31, 0xbd, 0x5c, 0x8a, 0xdd, 0x70, 0xb8, 0x1f,
+ 0xa5, 0xc4, 0xec, 0xe3, 0xd4, 0x42, 0x96, 0xb9, 0xd4, 0x93, 0x90, 0xe1,
+ 0x36, 0x68, 0xdb, 0x59, 0xe0, 0xf3, 0xa3, 0x00, 0x87, 0x56, 0xc5, 0x11,
+ 0xe3, 0xc6, 0x93, 0xdb, 0x9b, 0xfe, 0xa7, 0xf9, 0xa7, 0xe9, 0xf8, 0xf6,
+ 0xf2, 0xd3, 0xa2, 0x3b, 0x9a, 0x7c, 0x12, 0xb6, 0x2e, 0x06, 0x32, 0x64,
+ 0xec, 0x71, 0x16, 0xc3, 0x6e, 0x9f, 0xb7, 0x35, 0x5f, 0x30, 0xb3, 0xab,
+ 0xcb, 0x9b, 0xe1, 0x60, 0x51, 0xe0, 0x50, 0x65, 0x93, 0xcf, 0xb7, 0x35,
+ 0x77, 0xcf, 0x69, 0xef, 0x05, 0x16, 0x67, 0x95, 0xd4, 0xd0, 0x65, 0x7a,
+ 0x90, 0x59, 0x98, 0x3b, 0xec, 0xaf, 0xfd, 0x5e, 0x7f, 0xba, 0x18, 0xdd,
+ 0x5e, 0x77, 0x79, 0x6b, 0x73, 0x67, 0xcd, 0x5a, 0x37, 0xed, 0xfa, 0xa2,
+ 0x8f, 0x35, 0x29, 0xf0, 0x68, 0xd6, 0xcd, 0x27, 0xd1, 0xeb, 0x73, 0xcd,
+ 0x37, 0xcd, 0x47, 0xde, 0x13, 0x8c, 0xaf, 0x69, 0x3e, 0xe4, 0x5e, 0xbf,
+ 0xc1, 0xa3, 0xb9, 0x0a, 0xa3, 0xec, 0xce, 0xe6, 0xfd, 0x45, 0xf3, 0x45,
+ 0xc0, 0xdd, 0x33, 0x37, 0x34, 0xda, 0xb6, 0x25, 0xb6, 0x35, 0x37, 0xb1,
+ 0xa4, 0xad, 0x10, 0x49, 0x9a, 0x9b, 0x18, 0x6d, 0xdb, 0x16, 0xdb, 0x9a,
+ 0x07, 0x01, 0x49, 0x5b, 0xee, 0x55, 0xdb, 0xe6, 0xaa, 0xa1, 0x6d, 0x3b,
+ 0x62, 0xbf, 0xe6, 0xfa, 0x49, 0xda, 0xf2, 0x7e, 0xcf, 0xcc, 0x03, 0x80,
+ 0xa4, 0x2d, 0xdf, 0x6e, 0xce, 0xcc, 0x37, 0x7f, 0xda, 0xd6, 0xaa, 0x0b,
+ 0x83, 0x3e, 0x33, 0xf7, 0x68, 0x69, 0x63, 0x61, 0xd4, 0xe6, 0xbb, 0x7e,
+ 0xda, 0x58, 0x18, 0x76, 0x45, 0xd3, 0xc2, 0x8d, 0xc5, 0xf2, 0xcf, 0x8a,
+ 0xc6, 0x65, 0xd9, 0x52, 0xeb, 0x8a, 0xe6, 0x45, 0x5a, 0xf3, 0x85, 0x78,
+ 0x76, 0x96, 0x1e, 0x55, 0xc9, 0xf1, 0xf4, 0xb7, 0x9f, 0x7e, 0x39, 0x7d,
+ 0x5a, 0xbd, 0xec, 0xb6, 0xbf, 0xfd, 0xf4, 0x7f, 0xf9, 0x0b, 0x6a, 0x39,
+
+};
diff --git a/lib/mesa/src/broadcom/clif/clif_dump.c b/lib/mesa/src/broadcom/clif/clif_dump.c
new file mode 100644
index 000000000..339fc3835
--- /dev/null
+++ b/lib/mesa/src/broadcom/clif/clif_dump.c
@@ -0,0 +1,281 @@
+/*
+ * Copyright © 2016 Broadcom
+ *
+ * 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "clif_dump.h"
+#include "util/list.h"
+#include "util/ralloc.h"
+
+#include "broadcom/cle/v3d_decoder.h"
+
+#define __gen_user_data void
+#define __gen_address_type uint32_t
+#define __gen_address_offset(reloc) (*reloc)
+#define __gen_emit_reloc(cl, reloc)
+#define __gen_unpack_address(cl, s, e) (__gen_unpack_uint(cl, s, e) << (31 - (e - s)))
+
+enum reloc_worklist_type {
+ reloc_gl_shader_state,
+};
+
+struct reloc_worklist_entry {
+ struct list_head link;
+
+ enum reloc_worklist_type type;
+ uint32_t addr;
+
+ union {
+ struct {
+ uint32_t num_attrs;
+ } shader_state;
+ };
+};
+
+struct clif_dump {
+ const struct v3d_device_info *devinfo;
+ bool (*lookup_vaddr)(void *data, uint32_t addr, void **vaddr);
+ FILE *out;
+ /* Opaque data from the caller that is passed to the callbacks. */
+ void *data;
+
+ struct v3d_spec *spec;
+
+ /* List of struct reloc_worklist_entry */
+ struct list_head worklist;
+};
+
+static void
+out(struct clif_dump *clif, const char *fmt, ...)
+{
+ va_list args;
+
+ va_start(args, fmt);
+ vfprintf(clif->out, fmt, args);
+ va_end(args);
+}
+
+#include "broadcom/cle/v3d_packet_v33_pack.h"
+
+static struct reloc_worklist_entry *
+clif_dump_add_address_to_worklist(struct clif_dump *clif,
+ enum reloc_worklist_type type,
+ uint32_t addr)
+{
+ struct reloc_worklist_entry *entry =
+ rzalloc(clif, struct reloc_worklist_entry);
+ if (!entry)
+ return NULL;
+
+ entry->type = type;
+ entry->addr = addr;
+
+ list_addtail(&entry->link, &clif->worklist);
+
+ return entry;
+}
+
+struct clif_dump *
+clif_dump_init(const struct v3d_device_info *devinfo,
+ FILE *out,
+ bool (*lookup_vaddr)(void *data, uint32_t addr, void **vaddr),
+ void *data)
+{
+ struct clif_dump *clif = rzalloc(NULL, struct clif_dump);
+
+ clif->devinfo = devinfo;
+ clif->lookup_vaddr = lookup_vaddr;
+ clif->out = out;
+ clif->data = data;
+ clif->spec = v3d_spec_load(devinfo);
+
+ list_inithead(&clif->worklist);
+
+ return clif;
+}
+
+void
+clif_dump_destroy(struct clif_dump *clif)
+{
+ ralloc_free(clif);
+}
+
+#define out_uint(_clif, field) out(_clif, " /* %s = */ %u\n", \
+ #field, values-> field);
+
+static bool
+clif_dump_packet(struct clif_dump *clif, uint32_t offset, const uint8_t *cl,
+ uint32_t *size)
+{
+ struct v3d_group *inst = v3d_spec_find_instruction(clif->spec, cl);
+ if (!inst) {
+ out(clif, "0x%08x: Unknown packet %d!\n", offset, *cl);
+ return false;
+ }
+
+ *size = v3d_group_get_length(inst);
+
+ out(clif, "%s\n", v3d_group_get_name(inst));
+ v3d_print_group(clif->out, inst, 0, cl, "");
+
+ switch (*cl) {
+ case V3D33_GL_SHADER_STATE_opcode: {
+ struct V3D33_GL_SHADER_STATE values;
+ V3D33_GL_SHADER_STATE_unpack(cl, &values);
+
+ struct reloc_worklist_entry *reloc =
+ clif_dump_add_address_to_worklist(clif,
+ reloc_gl_shader_state,
+ values.address);
+ if (reloc) {
+ reloc->shader_state.num_attrs =
+ values.number_of_attribute_arrays;
+ }
+ return true;
+ }
+
+ case V3D33_STORE_MULTI_SAMPLE_RESOLVED_TILE_COLOR_BUFFER_EXTENDED_opcode: {
+ struct V3D33_STORE_MULTI_SAMPLE_RESOLVED_TILE_COLOR_BUFFER_EXTENDED values;
+ V3D33_STORE_MULTI_SAMPLE_RESOLVED_TILE_COLOR_BUFFER_EXTENDED_unpack(cl, &values);
+
+ if (values.last_tile_of_frame)
+ return false;
+ break;
+ }
+
+ case V3D33_TRANSFORM_FEEDBACK_ENABLE_opcode: {
+ struct V3D33_TRANSFORM_FEEDBACK_ENABLE values;
+ V3D33_TRANSFORM_FEEDBACK_ENABLE_unpack(cl, &values);
+ struct v3d_group *spec = v3d_spec_find_struct(clif->spec,
+ "Transform Feedback Output Data Spec");
+ struct v3d_group *addr = v3d_spec_find_struct(clif->spec,
+ "Transform Feedback Output Address");
+ assert(spec);
+ assert(addr);
+
+ cl += *size;
+
+ for (int i = 0; i < values.number_of_16_bit_output_data_specs_following; i++) {
+ v3d_print_group(clif->out, spec, 0, cl, "");
+ cl += v3d_group_get_length(spec);
+ *size += v3d_group_get_length(spec);
+ }
+
+ for (int i = 0; i < values.number_of_32_bit_output_buffer_address_following; i++) {
+ v3d_print_group(clif->out, addr, 0, cl, "");
+ cl += v3d_group_get_length(addr);
+ *size += v3d_group_get_length(addr);
+ }
+ break;
+ }
+
+ case V3D33_HALT_opcode:
+ return false;
+ }
+
+ return true;
+}
+
+static void
+clif_dump_gl_shader_state_record(struct clif_dump *clif,
+ struct reloc_worklist_entry *reloc, void *vaddr)
+{
+ struct v3d_group *state = v3d_spec_find_struct(clif->spec,
+ "GL Shader State Record");
+ struct v3d_group *attr = v3d_spec_find_struct(clif->spec,
+ "GL Shader State Attribute Record");
+ assert(state);
+ assert(attr);
+
+ out(clif, "GL Shader State Record at 0x%08x\n", reloc->addr);
+ v3d_print_group(clif->out, state, 0, vaddr, "");
+ vaddr += v3d_group_get_length(state);
+
+ for (int i = 0; i < reloc->shader_state.num_attrs; i++) {
+ out(clif, " Attribute %d\n", i);
+ v3d_print_group(clif->out, attr, 0, vaddr, "");
+ vaddr += v3d_group_get_length(attr);
+ }
+}
+
+static void
+clif_process_worklist(struct clif_dump *clif)
+{
+ while (!list_empty(&clif->worklist)) {
+ struct reloc_worklist_entry *reloc =
+ list_first_entry(&clif->worklist,
+ struct reloc_worklist_entry, link);
+ list_del(&reloc->link);
+
+ void *vaddr;
+ if (!clif->lookup_vaddr(clif->data, reloc->addr, &vaddr)) {
+ out(clif, "Failed to look up address 0x%08x\n",
+ reloc->addr);
+ continue;
+ }
+
+ switch (reloc->type) {
+ case reloc_gl_shader_state:
+ clif_dump_gl_shader_state_record(clif, reloc, vaddr);
+ break;
+ }
+ out(clif, "\n");
+ }
+}
+
+void
+clif_dump_add_cl(struct clif_dump *clif, uint32_t start, uint32_t end)
+{
+ uint32_t size;
+
+ void *start_vaddr;
+ if (!clif->lookup_vaddr(clif->data, start, &start_vaddr)) {
+ out(clif, "Failed to look up address 0x%08x\n",
+ start);
+ return;
+ }
+
+ /* The end address is optional (for example, a BRANCH instruction
+ * won't set an end), but is used for BCL/RCL termination.
+ */
+ void *end_vaddr = NULL;
+ if (end && !clif->lookup_vaddr(clif->data, end, &end_vaddr)) {
+ out(clif, "Failed to look up address 0x%08x\n",
+ end);
+ return;
+ }
+
+ uint8_t *cl = start_vaddr;
+ while (clif_dump_packet(clif, start, cl, &size)) {
+ cl += size;
+ start += size;
+
+ if (cl == end_vaddr)
+ break;
+ }
+
+ out(clif, "\n");
+
+ clif_process_worklist(clif);
+}
diff --git a/lib/mesa/src/broadcom/clif/clif_dump.h b/lib/mesa/src/broadcom/clif/clif_dump.h
new file mode 100644
index 000000000..d46cc8471
--- /dev/null
+++ b/lib/mesa/src/broadcom/clif/clif_dump.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright © 2016 Broadcom
+ *
+ * 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.
+ */
+
+#ifndef CLIF_DUMP_H
+#define CLIF_DUMP_H
+
+#include <stdbool.h>
+#include <stdint.h>
+
+struct v3d_device_info;
+struct clif_dump;
+
+struct clif_dump *clif_dump_init(const struct v3d_device_info *devinfo,
+ FILE *output,
+ bool (*lookup_vaddr)(void *data, uint32_t addr,
+ void **vaddr),
+ void *data);
+void clif_dump_destroy(struct clif_dump *clif);
+
+void clif_dump_add_cl(struct clif_dump *clif, uint32_t start, uint32_t end);
+
+#endif
diff --git a/lib/mesa/src/broadcom/common/v3d_debug.c b/lib/mesa/src/broadcom/common/v3d_debug.c
new file mode 100644
index 000000000..630bfe0fc
--- /dev/null
+++ b/lib/mesa/src/broadcom/common/v3d_debug.c
@@ -0,0 +1,89 @@
+/*
+ * Copyright 2003 VMware, Inc.
+ * Copyright © 2006 Intel Corporation
+ * Copyright © 2017 Broadcom
+ *
+ * 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.
+ */
+
+/**
+ * \file v3d_debug.c
+ *
+ * Support for the V3D_DEBUG environment variable, along with other
+ * miscellaneous debugging code.
+ */
+
+#include <stdlib.h>
+
+#include "common/v3d_debug.h"
+#include "util/macros.h"
+#include "util/debug.h"
+#include "c11/threads.h"
+
+uint32_t V3D_DEBUG = 0;
+
+static const struct debug_control debug_control[] = {
+ { "cl", V3D_DEBUG_CL},
+ { "qpu", V3D_DEBUG_QPU},
+ { "vir", V3D_DEBUG_VIR},
+ { "nir", V3D_DEBUG_NIR},
+ { "tgsi", V3D_DEBUG_TGSI},
+ { "shaderdb", V3D_DEBUG_SHADERDB},
+ { "surface", V3D_DEBUG_SURFACE},
+ { "perf", V3D_DEBUG_PERF},
+ { "norast", V3D_DEBUG_NORAST},
+ { "fs", V3D_DEBUG_FS},
+ { "vs", V3D_DEBUG_VS},
+ { "cs", V3D_DEBUG_CS},
+ { NULL, 0 }
+};
+
+uint32_t
+v3d_debug_flag_for_shader_stage(gl_shader_stage stage)
+{
+ uint32_t flags[] = {
+ [MESA_SHADER_VERTEX] = V3D_DEBUG_VS,
+ [MESA_SHADER_TESS_CTRL] = 0,
+ [MESA_SHADER_TESS_EVAL] = 0,
+ [MESA_SHADER_GEOMETRY] = 0,
+ [MESA_SHADER_FRAGMENT] = V3D_DEBUG_FS,
+ [MESA_SHADER_COMPUTE] = V3D_DEBUG_CS,
+ };
+ STATIC_ASSERT(MESA_SHADER_STAGES == 6);
+ return flags[stage];
+}
+
+static void
+v3d_process_debug_variable_once(void)
+{
+ V3D_DEBUG = parse_debug_string(getenv("V3D_DEBUG"), debug_control);
+
+ if (V3D_DEBUG & V3D_DEBUG_SHADERDB)
+ V3D_DEBUG |= V3D_DEBUG_NORAST;
+}
+
+void
+v3d_process_debug_variable(void)
+{
+ static once_flag v3d_process_debug_variable_flag = ONCE_FLAG_INIT;
+
+ call_once(&v3d_process_debug_variable_flag,
+ v3d_process_debug_variable_once);
+}
diff --git a/lib/mesa/src/broadcom/common/v3d_debug.h b/lib/mesa/src/broadcom/common/v3d_debug.h
new file mode 100644
index 000000000..bdb951854
--- /dev/null
+++ b/lib/mesa/src/broadcom/common/v3d_debug.h
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2003 VMware, Inc.
+ * Copyright © 2007 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 (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 COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS 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.
+ */
+
+#ifndef MESA_V3D_DEBUG_H
+#define MESA_V3D_DEBUG_H
+
+#include <stdint.h>
+#include "compiler/shader_enums.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/**
+ * \file v3d_debug.h
+ *
+ * Basic V3D_DEBUG environment variable handling. This file defines the
+ * list of debugging flags, as well as some macros for handling them.
+ */
+
+extern uint32_t V3D_DEBUG;
+
+#define V3D_DEBUG_SHADERDB (1 << 0)
+#define V3D_DEBUG_TGSI (1 << 1)
+#define V3D_DEBUG_NIR (1 << 2)
+#define V3D_DEBUG_VIR (1 << 3)
+#define V3D_DEBUG_QPU (1 << 4)
+#define V3D_DEBUG_FS (1 << 5)
+#define V3D_DEBUG_VS (1 << 6)
+#define V3D_DEBUG_CS (1 << 7)
+#define V3D_DEBUG_CL (1 << 8)
+#define V3D_DEBUG_SURFACE (1 << 9)
+#define V3D_DEBUG_PERF (1 << 10)
+#define V3D_DEBUG_NORAST (1 << 11)
+#define V3D_DEBUG_ALWAYS_FLUSH (1 << 12)
+
+#ifdef HAVE_ANDROID_PLATFORM
+#define LOG_TAG "BROADCOM-MESA"
+#include <cutils/log.h>
+#ifndef ALOGW
+#define ALOGW LOGW
+#endif
+#define dbg_printf(...) ALOGW(__VA_ARGS__)
+#else
+#define dbg_printf(...) fprintf(stderr, __VA_ARGS__)
+#endif /* HAVE_ANDROID_PLATFORM */
+
+#define DBG(flag, ...) do { \
+ if (unlikely(V3D_DEBUG & (flag))) \
+ dbg_printf(__VA_ARGS__); \
+} while(0)
+
+extern uint32_t v3d_debug_flag_for_shader_stage(gl_shader_stage stage);
+
+extern void v3d_process_debug_variable(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* V3D_DEBUG_H */
diff --git a/lib/mesa/src/broadcom/compiler/nir_to_vir.c b/lib/mesa/src/broadcom/compiler/nir_to_vir.c
new file mode 100644
index 000000000..3b032b704
--- /dev/null
+++ b/lib/mesa/src/broadcom/compiler/nir_to_vir.c
@@ -0,0 +1,2054 @@
+/*
+ * Copyright © 2016 Broadcom
+ *
+ * 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 <inttypes.h>
+#include "util/u_format.h"
+#include "util/u_math.h"
+#include "util/u_memory.h"
+#include "util/ralloc.h"
+#include "util/hash_table.h"
+#include "compiler/nir/nir.h"
+#include "compiler/nir/nir_builder.h"
+#include "v3d_compiler.h"
+
+/* We don't do any address packing. */
+#define __gen_user_data void
+#define __gen_address_type uint32_t
+#define __gen_address_offset(reloc) (*reloc)
+#define __gen_emit_reloc(cl, reloc)
+#include "cle/v3d_packet_v33_pack.h"
+
+static struct qreg
+ntq_get_src(struct v3d_compile *c, nir_src src, int i);
+static void
+ntq_emit_cf_list(struct v3d_compile *c, struct exec_list *list);
+
+static void
+resize_qreg_array(struct v3d_compile *c,
+ struct qreg **regs,
+ uint32_t *size,
+ uint32_t decl_size)
+{
+ if (*size >= decl_size)
+ return;
+
+ uint32_t old_size = *size;
+ *size = MAX2(*size * 2, decl_size);
+ *regs = reralloc(c, *regs, struct qreg, *size);
+ if (!*regs) {
+ fprintf(stderr, "Malloc failure\n");
+ abort();
+ }
+
+ for (uint32_t i = old_size; i < *size; i++)
+ (*regs)[i] = c->undef;
+}
+
+static struct qreg
+vir_SFU(struct v3d_compile *c, int waddr, struct qreg src)
+{
+ vir_FMOV_dest(c, vir_reg(QFILE_MAGIC, waddr), src);
+ return vir_FMOV(c, vir_reg(QFILE_MAGIC, V3D_QPU_WADDR_R4));
+}
+
+static struct qreg
+vir_LDTMU(struct v3d_compile *c)
+{
+ vir_NOP(c)->qpu.sig.ldtmu = true;
+ return vir_MOV(c, vir_reg(QFILE_MAGIC, V3D_QPU_WADDR_R4));
+}
+
+static struct qreg
+indirect_uniform_load(struct v3d_compile *c, nir_intrinsic_instr *intr)
+{
+ struct qreg indirect_offset = ntq_get_src(c, intr->src[0], 0);
+ uint32_t offset = nir_intrinsic_base(intr);
+ struct v3d_ubo_range *range = NULL;
+ unsigned i;
+
+ for (i = 0; i < c->num_ubo_ranges; i++) {
+ range = &c->ubo_ranges[i];
+ if (offset >= range->src_offset &&
+ offset < range->src_offset + range->size) {
+ break;
+ }
+ }
+ /* The driver-location-based offset always has to be within a declared
+ * uniform range.
+ */
+ assert(i != c->num_ubo_ranges);
+ if (!c->ubo_range_used[i]) {
+ c->ubo_range_used[i] = true;
+ range->dst_offset = c->next_ubo_dst_offset;
+ c->next_ubo_dst_offset += range->size;
+ }
+
+ offset -= range->src_offset;
+
+ if (range->dst_offset + offset != 0) {
+ indirect_offset = vir_ADD(c, indirect_offset,
+ vir_uniform_ui(c, range->dst_offset +
+ offset));
+ }
+
+ /* Adjust for where we stored the TGSI register base. */
+ vir_ADD_dest(c,
+ vir_reg(QFILE_MAGIC, V3D_QPU_WADDR_TMUA),
+ vir_uniform(c, QUNIFORM_UBO_ADDR, 0),
+ indirect_offset);
+
+ return vir_LDTMU(c);
+}
+
+static struct qreg *
+ntq_init_ssa_def(struct v3d_compile *c, nir_ssa_def *def)
+{
+ struct qreg *qregs = ralloc_array(c->def_ht, struct qreg,
+ def->num_components);
+ _mesa_hash_table_insert(c->def_ht, def, qregs);
+ return qregs;
+}
+
+/**
+ * This function is responsible for getting VIR results into the associated
+ * storage for a NIR instruction.
+ *
+ * If it's a NIR SSA def, then we just set the associated hash table entry to
+ * the new result.
+ *
+ * If it's a NIR reg, then we need to update the existing qreg assigned to the
+ * NIR destination with the incoming value. To do that without introducing
+ * new MOVs, we require that the incoming qreg either be a uniform, or be
+ * SSA-defined by the previous VIR instruction in the block and rewritable by
+ * this function. That lets us sneak ahead and insert the SF flag beforehand
+ * (knowing that the previous instruction doesn't depend on flags) and rewrite
+ * its destination to be the NIR reg's destination
+ */
+static void
+ntq_store_dest(struct v3d_compile *c, nir_dest *dest, int chan,
+ struct qreg result)
+{
+ struct qinst *last_inst = NULL;
+ if (!list_empty(&c->cur_block->instructions))
+ last_inst = (struct qinst *)c->cur_block->instructions.prev;
+
+ assert(result.file == QFILE_UNIF ||
+ (result.file == QFILE_TEMP &&
+ last_inst && last_inst == c->defs[result.index]));
+
+ if (dest->is_ssa) {
+ assert(chan < dest->ssa.num_components);
+
+ struct qreg *qregs;
+ struct hash_entry *entry =
+ _mesa_hash_table_search(c->def_ht, &dest->ssa);
+
+ if (entry)
+ qregs = entry->data;
+ else
+ qregs = ntq_init_ssa_def(c, &dest->ssa);
+
+ qregs[chan] = result;
+ } else {
+ nir_register *reg = dest->reg.reg;
+ assert(dest->reg.base_offset == 0);
+ assert(reg->num_array_elems == 0);
+ struct hash_entry *entry =
+ _mesa_hash_table_search(c->def_ht, reg);
+ struct qreg *qregs = entry->data;
+
+ /* Insert a MOV if the source wasn't an SSA def in the
+ * previous instruction.
+ */
+ if (result.file == QFILE_UNIF) {
+ result = vir_MOV(c, result);
+ last_inst = c->defs[result.index];
+ }
+
+ /* We know they're both temps, so just rewrite index. */
+ c->defs[last_inst->dst.index] = NULL;
+ last_inst->dst.index = qregs[chan].index;
+
+ /* If we're in control flow, then make this update of the reg
+ * conditional on the execution mask.
+ */
+ if (c->execute.file != QFILE_NULL) {
+ last_inst->dst.index = qregs[chan].index;
+
+ /* Set the flags to the current exec mask. To insert
+ * the flags push, we temporarily remove our SSA
+ * instruction.
+ */
+ list_del(&last_inst->link);
+ vir_PF(c, c->execute, V3D_QPU_PF_PUSHZ);
+ list_addtail(&last_inst->link,
+ &c->cur_block->instructions);
+
+ vir_set_cond(last_inst, V3D_QPU_COND_IFA);
+ last_inst->cond_is_exec_mask = true;
+ }
+ }
+}
+
+static struct qreg
+ntq_get_src(struct v3d_compile *c, nir_src src, int i)
+{
+ struct hash_entry *entry;
+ if (src.is_ssa) {
+ entry = _mesa_hash_table_search(c->def_ht, src.ssa);
+ assert(i < src.ssa->num_components);
+ } else {
+ nir_register *reg = src.reg.reg;
+ entry = _mesa_hash_table_search(c->def_ht, reg);
+ assert(reg->num_array_elems == 0);
+ assert(src.reg.base_offset == 0);
+ assert(i < reg->num_components);
+ }
+
+ struct qreg *qregs = entry->data;
+ return qregs[i];
+}
+
+static struct qreg
+ntq_get_alu_src(struct v3d_compile *c, nir_alu_instr *instr,
+ unsigned src)
+{
+ assert(util_is_power_of_two(instr->dest.write_mask));
+ unsigned chan = ffs(instr->dest.write_mask) - 1;
+ struct qreg r = ntq_get_src(c, instr->src[src].src,
+ instr->src[src].swizzle[chan]);
+
+ assert(!instr->src[src].abs);
+ assert(!instr->src[src].negate);
+
+ return r;
+};
+
+static inline struct qreg
+vir_SAT(struct v3d_compile *c, struct qreg val)
+{
+ return vir_FMAX(c,
+ vir_FMIN(c, val, vir_uniform_f(c, 1.0)),
+ vir_uniform_f(c, 0.0));
+}
+
+static struct qreg
+ntq_umul(struct v3d_compile *c, struct qreg src0, struct qreg src1)
+{
+ vir_MULTOP(c, src0, src1);
+ return vir_UMUL24(c, src0, src1);
+}
+
+static struct qreg
+ntq_minify(struct v3d_compile *c, struct qreg size, struct qreg level)
+{
+ return vir_MAX(c, vir_SHR(c, size, level), vir_uniform_ui(c, 1));
+}
+
+static void
+ntq_emit_txs(struct v3d_compile *c, nir_tex_instr *instr)
+{
+ unsigned unit = instr->texture_index;
+ int lod_index = nir_tex_instr_src_index(instr, nir_tex_src_lod);
+ int dest_size = nir_tex_instr_dest_size(instr);
+
+ struct qreg lod = c->undef;
+ if (lod_index != -1)
+ lod = ntq_get_src(c, instr->src[lod_index].src, 0);
+
+ for (int i = 0; i < dest_size; i++) {
+ assert(i < 3);
+ enum quniform_contents contents;
+
+ if (instr->is_array && i == dest_size - 1)
+ contents = QUNIFORM_TEXTURE_ARRAY_SIZE;
+ else
+ contents = QUNIFORM_TEXTURE_WIDTH + i;
+
+ struct qreg size = vir_uniform(c, contents, unit);
+
+ switch (instr->sampler_dim) {
+ case GLSL_SAMPLER_DIM_1D:
+ case GLSL_SAMPLER_DIM_2D:
+ case GLSL_SAMPLER_DIM_3D:
+ case GLSL_SAMPLER_DIM_CUBE:
+ /* Don't minify the array size. */
+ if (!(instr->is_array && i == dest_size - 1)) {
+ size = ntq_minify(c, size, lod);
+ }
+ break;
+
+ case GLSL_SAMPLER_DIM_RECT:
+ /* There's no LOD field for rects */
+ break;
+
+ default:
+ unreachable("Bad sampler type");
+ }
+
+ ntq_store_dest(c, &instr->dest, i, size);
+ }
+}
+
+static void
+ntq_emit_tex(struct v3d_compile *c, nir_tex_instr *instr)
+{
+ unsigned unit = instr->texture_index;
+
+ /* Since each texture sampling op requires uploading uniforms to
+ * reference the texture, there's no HW support for texture size and
+ * you just upload uniforms containing the size.
+ */
+ switch (instr->op) {
+ case nir_texop_query_levels:
+ ntq_store_dest(c, &instr->dest, 0,
+ vir_uniform(c, QUNIFORM_TEXTURE_LEVELS, unit));
+ return;
+ case nir_texop_txs:
+ ntq_emit_txs(c, instr);
+ return;
+ default:
+ break;
+ }
+
+ struct V3D33_TEXTURE_UNIFORM_PARAMETER_0_CFG_MODE1 p0_unpacked = {
+ V3D33_TEXTURE_UNIFORM_PARAMETER_0_CFG_MODE1_header,
+
+ .fetch_sample_mode = instr->op == nir_texop_txf,
+ };
+
+ switch (instr->sampler_dim) {
+ case GLSL_SAMPLER_DIM_1D:
+ if (instr->is_array)
+ p0_unpacked.lookup_type = TEXTURE_1D_ARRAY;
+ else
+ p0_unpacked.lookup_type = TEXTURE_1D;
+ break;
+ case GLSL_SAMPLER_DIM_2D:
+ case GLSL_SAMPLER_DIM_RECT:
+ if (instr->is_array)
+ p0_unpacked.lookup_type = TEXTURE_2D_ARRAY;
+ else
+ p0_unpacked.lookup_type = TEXTURE_2D;
+ break;
+ case GLSL_SAMPLER_DIM_3D:
+ p0_unpacked.lookup_type = TEXTURE_3D;
+ break;
+ case GLSL_SAMPLER_DIM_CUBE:
+ p0_unpacked.lookup_type = TEXTURE_CUBE_MAP;
+ break;
+ default:
+ unreachable("Bad sampler type");
+ }
+
+ struct qreg coords[5];
+ int next_coord = 0;
+ for (unsigned i = 0; i < instr->num_srcs; i++) {
+ switch (instr->src[i].src_type) {
+ case nir_tex_src_coord:
+ for (int j = 0; j < instr->coord_components; j++) {
+ coords[next_coord++] =
+ ntq_get_src(c, instr->src[i].src, j);
+ }
+ if (instr->coord_components < 2)
+ coords[next_coord++] = vir_uniform_f(c, 0.5);
+ break;
+ case nir_tex_src_bias:
+ coords[next_coord++] =
+ ntq_get_src(c, instr->src[i].src, 0);
+
+ p0_unpacked.bias_supplied = true;
+ break;
+ case nir_tex_src_lod:
+ /* XXX: Needs base level addition */
+ coords[next_coord++] =
+ ntq_get_src(c, instr->src[i].src, 0);
+
+ if (instr->op != nir_texop_txf &&
+ instr->op != nir_texop_tg4) {
+ p0_unpacked.disable_autolod_use_bias_only = true;
+ }
+ break;
+ case nir_tex_src_comparator:
+ coords[next_coord++] =
+ ntq_get_src(c, instr->src[i].src, 0);
+
+ p0_unpacked.shadow = true;
+ break;
+
+ case nir_tex_src_offset: {
+ nir_const_value *offset =
+ nir_src_as_const_value(instr->src[i].src);
+ p0_unpacked.texel_offset_for_s_coordinate =
+ offset->i32[0];
+
+ if (instr->coord_components >= 2)
+ p0_unpacked.texel_offset_for_t_coordinate =
+ offset->i32[1];
+
+ if (instr->coord_components >= 3)
+ p0_unpacked.texel_offset_for_r_coordinate =
+ offset->i32[2];
+ break;
+ }
+
+ default:
+ unreachable("unknown texture source");
+ }
+ }
+
+ uint32_t p0_packed;
+ V3D33_TEXTURE_UNIFORM_PARAMETER_0_CFG_MODE1_pack(NULL,
+ (uint8_t *)&p0_packed,
+ &p0_unpacked);
+
+ /* There is no native support for GL texture rectangle coordinates, so
+ * we have to rescale from ([0, width], [0, height]) to ([0, 1], [0,
+ * 1]).
+ */
+ if (instr->sampler_dim == GLSL_SAMPLER_DIM_RECT) {
+ coords[0] = vir_FMUL(c, coords[0],
+ vir_uniform(c, QUNIFORM_TEXRECT_SCALE_X,
+ unit));
+ coords[1] = vir_FMUL(c, coords[1],
+ vir_uniform(c, QUNIFORM_TEXRECT_SCALE_Y,
+ unit));
+ }
+
+ struct qreg texture_u[] = {
+ vir_uniform(c, QUNIFORM_TEXTURE_CONFIG_P0_0 + unit, p0_packed),
+ vir_uniform(c, QUNIFORM_TEXTURE_CONFIG_P1, unit),
+ };
+ uint32_t next_texture_u = 0;
+
+ for (int i = 0; i < next_coord; i++) {
+ struct qreg dst;
+
+ if (i == next_coord - 1)
+ dst = vir_reg(QFILE_MAGIC, V3D_QPU_WADDR_TMUL);
+ else
+ dst = vir_reg(QFILE_MAGIC, V3D_QPU_WADDR_TMU);
+
+ struct qinst *tmu = vir_MOV_dest(c, dst, coords[i]);
+
+ if (i < 2) {
+ tmu->has_implicit_uniform = true;
+ tmu->src[vir_get_implicit_uniform_src(tmu)] =
+ texture_u[next_texture_u++];
+ }
+ }
+
+ bool return_16 = (c->key->tex[unit].return_size == 16 ||
+ p0_unpacked.shadow);
+
+ struct qreg return_values[4];
+ for (int i = 0; i < c->key->tex[unit].return_channels; i++)
+ return_values[i] = vir_LDTMU(c);
+ /* Swizzling .zw of an RG texture should give undefined results, not
+ * crash the compiler.
+ */
+ for (int i = c->key->tex[unit].return_channels; i < 4; i++)
+ return_values[i] = c->undef;
+
+ for (int i = 0; i < nir_tex_instr_dest_size(instr); i++) {
+ struct qreg chan;
+
+ if (return_16) {
+ STATIC_ASSERT(PIPE_SWIZZLE_X == 0);
+ chan = return_values[i / 2];
+
+ enum v3d_qpu_input_unpack unpack;
+ if (i & 1)
+ unpack = V3D_QPU_UNPACK_H;
+ else
+ unpack = V3D_QPU_UNPACK_L;
+
+ chan = vir_FMOV(c, chan);
+ vir_set_unpack(c->defs[chan.index], 0, unpack);
+ } else {
+ chan = vir_MOV(c, return_values[i]);
+ }
+ ntq_store_dest(c, &instr->dest, i, chan);
+ }
+}
+
+static struct qreg
+ntq_fsincos(struct v3d_compile *c, struct qreg src, bool is_cos)
+{
+ struct qreg input = vir_FMUL(c, src, vir_uniform_f(c, 1.0f / M_PI));
+ if (is_cos)
+ input = vir_FADD(c, input, vir_uniform_f(c, 0.5));
+
+ struct qreg periods = vir_FROUND(c, input);
+ struct qreg sin_output = vir_SFU(c, V3D_QPU_WADDR_SIN,
+ vir_FSUB(c, input, periods));
+ return vir_XOR(c, sin_output, vir_SHL(c,
+ vir_FTOIN(c, periods),
+ vir_uniform_ui(c, -1)));
+}
+
+static struct qreg
+ntq_fsign(struct v3d_compile *c, struct qreg src)
+{
+ struct qreg t = vir_get_temp(c);
+
+ vir_MOV_dest(c, t, vir_uniform_f(c, 0.0));
+ vir_PF(c, vir_FMOV(c, src), V3D_QPU_PF_PUSHZ);
+ vir_MOV_cond(c, V3D_QPU_COND_IFNA, t, vir_uniform_f(c, 1.0));
+ vir_PF(c, vir_FMOV(c, src), V3D_QPU_PF_PUSHN);
+ vir_MOV_cond(c, V3D_QPU_COND_IFA, t, vir_uniform_f(c, -1.0));
+ return vir_MOV(c, t);
+}
+
+static struct qreg
+ntq_isign(struct v3d_compile *c, struct qreg src)
+{
+ struct qreg t = vir_get_temp(c);
+
+ vir_MOV_dest(c, t, vir_uniform_ui(c, 0));
+ vir_PF(c, vir_MOV(c, src), V3D_QPU_PF_PUSHZ);
+ vir_MOV_cond(c, V3D_QPU_COND_IFNA, t, vir_uniform_ui(c, 1));
+ vir_PF(c, vir_MOV(c, src), V3D_QPU_PF_PUSHN);
+ vir_MOV_cond(c, V3D_QPU_COND_IFA, t, vir_uniform_ui(c, -1));
+ return vir_MOV(c, t);
+}
+
+static void
+emit_fragcoord_input(struct v3d_compile *c, int attr)
+{
+ c->inputs[attr * 4 + 0] = vir_FXCD(c);
+ c->inputs[attr * 4 + 1] = vir_FYCD(c);
+ c->inputs[attr * 4 + 2] = c->payload_z;
+ c->inputs[attr * 4 + 3] = vir_SFU(c, V3D_QPU_WADDR_RECIP,
+ c->payload_w);
+}
+
+static struct qreg
+emit_fragment_varying(struct v3d_compile *c, nir_variable *var,
+ uint8_t swizzle)
+{
+ struct qreg vary = vir_reg(QFILE_VARY, ~0);
+ struct qreg r5 = vir_reg(QFILE_MAGIC, V3D_QPU_WADDR_R5);
+
+ /* For gl_PointCoord input or distance along a line, we'll be called
+ * with no nir_variable, and we don't count toward VPM size so we
+ * don't track an input slot.
+ */
+ if (!var) {
+ return vir_FADD(c, vir_FMUL(c, vary, c->payload_w), r5);
+ }
+
+ int i = c->num_inputs++;
+ c->input_slots[i] = v3d_slot_from_slot_and_component(var->data.location,
+ swizzle);
+
+ switch (var->data.interpolation) {
+ case INTERP_MODE_NONE:
+ /* If a gl_FrontColor or gl_BackColor input has no interp
+ * qualifier, then flag it for glShadeModel() handling by the
+ * driver.
+ */
+ switch (var->data.location) {
+ case VARYING_SLOT_COL0:
+ case VARYING_SLOT_COL1:
+ case VARYING_SLOT_BFC0:
+ case VARYING_SLOT_BFC1:
+ BITSET_SET(c->shade_model_flags, i);
+ break;
+ default:
+ break;
+ }
+ /* FALLTHROUGH */
+ case INTERP_MODE_SMOOTH:
+ if (var->data.centroid) {
+ return vir_FADD(c, vir_FMUL(c, vary,
+ c->payload_w_centroid), r5);
+ } else {
+ return vir_FADD(c, vir_FMUL(c, vary, c->payload_w), r5);
+ }
+ case INTERP_MODE_NOPERSPECTIVE:
+ /* C appears after the mov from the varying.
+ XXX: improve ldvary setup.
+ */
+ return vir_FADD(c, vir_MOV(c, vary), r5);
+ case INTERP_MODE_FLAT:
+ BITSET_SET(c->flat_shade_flags, i);
+ vir_MOV_dest(c, c->undef, vary);
+ return vir_MOV(c, r5);
+ default:
+ unreachable("Bad interp mode");
+ }
+}
+
+static void
+emit_fragment_input(struct v3d_compile *c, int attr, nir_variable *var)
+{
+ for (int i = 0; i < glsl_get_vector_elements(var->type); i++) {
+ c->inputs[attr * 4 + i] =
+ emit_fragment_varying(c, var, i);
+ }
+}
+
+static void
+add_output(struct v3d_compile *c,
+ uint32_t decl_offset,
+ uint8_t slot,
+ uint8_t swizzle)
+{
+ uint32_t old_array_size = c->outputs_array_size;
+ resize_qreg_array(c, &c->outputs, &c->outputs_array_size,
+ decl_offset + 1);
+
+ if (old_array_size != c->outputs_array_size) {
+ c->output_slots = reralloc(c,
+ c->output_slots,
+ struct v3d_varying_slot,
+ c->outputs_array_size);
+ }
+
+ c->output_slots[decl_offset] =
+ v3d_slot_from_slot_and_component(slot, swizzle);
+}
+
+static void
+declare_uniform_range(struct v3d_compile *c, uint32_t start, uint32_t size)
+{
+ unsigned array_id = c->num_ubo_ranges++;
+ if (array_id >= c->ubo_ranges_array_size) {
+ c->ubo_ranges_array_size = MAX2(c->ubo_ranges_array_size * 2,
+ array_id + 1);
+ c->ubo_ranges = reralloc(c, c->ubo_ranges,
+ struct v3d_ubo_range,
+ c->ubo_ranges_array_size);
+ c->ubo_range_used = reralloc(c, c->ubo_range_used,
+ bool,
+ c->ubo_ranges_array_size);
+ }
+
+ c->ubo_ranges[array_id].dst_offset = 0;
+ c->ubo_ranges[array_id].src_offset = start;
+ c->ubo_ranges[array_id].size = size;
+ c->ubo_range_used[array_id] = false;
+}
+
+/**
+ * If compare_instr is a valid comparison instruction, emits the
+ * compare_instr's comparison and returns the sel_instr's return value based
+ * on the compare_instr's result.
+ */
+static bool
+ntq_emit_comparison(struct v3d_compile *c, struct qreg *dest,
+ nir_alu_instr *compare_instr,
+ nir_alu_instr *sel_instr)
+{
+ struct qreg src0 = ntq_get_alu_src(c, compare_instr, 0);
+ struct qreg src1 = ntq_get_alu_src(c, compare_instr, 1);
+ bool cond_invert = false;
+
+ switch (compare_instr->op) {
+ case nir_op_feq:
+ case nir_op_seq:
+ vir_PF(c, vir_FCMP(c, src0, src1), V3D_QPU_PF_PUSHZ);
+ break;
+ case nir_op_ieq:
+ vir_PF(c, vir_XOR(c, src0, src1), V3D_QPU_PF_PUSHZ);
+ break;
+
+ case nir_op_fne:
+ case nir_op_sne:
+ vir_PF(c, vir_FCMP(c, src0, src1), V3D_QPU_PF_PUSHZ);
+ cond_invert = true;
+ break;
+ case nir_op_ine:
+ vir_PF(c, vir_XOR(c, src0, src1), V3D_QPU_PF_PUSHZ);
+ cond_invert = true;
+ break;
+
+ case nir_op_fge:
+ case nir_op_sge:
+ vir_PF(c, vir_FCMP(c, src1, src0), V3D_QPU_PF_PUSHC);
+ break;
+ case nir_op_ige:
+ vir_PF(c, vir_MIN(c, src1, src0), V3D_QPU_PF_PUSHC);
+ cond_invert = true;
+ break;
+ case nir_op_uge:
+ vir_PF(c, vir_SUB(c, src0, src1), V3D_QPU_PF_PUSHC);
+ cond_invert = true;
+ break;
+
+ case nir_op_slt:
+ case nir_op_flt:
+ vir_PF(c, vir_FCMP(c, src0, src1), V3D_QPU_PF_PUSHN);
+ break;
+ case nir_op_ilt:
+ vir_PF(c, vir_MIN(c, src1, src0), V3D_QPU_PF_PUSHC);
+ break;
+ case nir_op_ult:
+ vir_PF(c, vir_SUB(c, src0, src1), V3D_QPU_PF_PUSHC);
+ break;
+
+ default:
+ return false;
+ }
+
+ enum v3d_qpu_cond cond = (cond_invert ?
+ V3D_QPU_COND_IFNA :
+ V3D_QPU_COND_IFA);
+
+ switch (sel_instr->op) {
+ case nir_op_seq:
+ case nir_op_sne:
+ case nir_op_sge:
+ case nir_op_slt:
+ *dest = vir_SEL(c, cond,
+ vir_uniform_f(c, 1.0), vir_uniform_f(c, 0.0));
+ break;
+
+ case nir_op_bcsel:
+ *dest = vir_SEL(c, cond,
+ ntq_get_alu_src(c, sel_instr, 1),
+ ntq_get_alu_src(c, sel_instr, 2));
+ break;
+
+ default:
+ *dest = vir_SEL(c, cond,
+ vir_uniform_ui(c, ~0), vir_uniform_ui(c, 0));
+ break;
+ }
+
+ /* Make the temporary for nir_store_dest(). */
+ *dest = vir_MOV(c, *dest);
+
+ return true;
+}
+
+/**
+ * Attempts to fold a comparison generating a boolean result into the
+ * condition code for selecting between two values, instead of comparing the
+ * boolean result against 0 to generate the condition code.
+ */
+static struct qreg ntq_emit_bcsel(struct v3d_compile *c, nir_alu_instr *instr,
+ struct qreg *src)
+{
+ if (!instr->src[0].src.is_ssa)
+ goto out;
+ if (instr->src[0].src.ssa->parent_instr->type != nir_instr_type_alu)
+ goto out;
+ nir_alu_instr *compare =
+ nir_instr_as_alu(instr->src[0].src.ssa->parent_instr);
+ if (!compare)
+ goto out;
+
+ struct qreg dest;
+ if (ntq_emit_comparison(c, &dest, compare, instr))
+ return dest;
+
+out:
+ vir_PF(c, src[0], V3D_QPU_PF_PUSHZ);
+ return vir_MOV(c, vir_SEL(c, V3D_QPU_COND_IFNA, src[1], src[2]));
+}
+
+
+static void
+ntq_emit_alu(struct v3d_compile *c, nir_alu_instr *instr)
+{
+ /* This should always be lowered to ALU operations for V3D. */
+ assert(!instr->dest.saturate);
+
+ /* Vectors are special in that they have non-scalarized writemasks,
+ * and just take the first swizzle channel for each argument in order
+ * into each writemask channel.
+ */
+ if (instr->op == nir_op_vec2 ||
+ instr->op == nir_op_vec3 ||
+ instr->op == nir_op_vec4) {
+ struct qreg srcs[4];
+ for (int i = 0; i < nir_op_infos[instr->op].num_inputs; i++)
+ srcs[i] = ntq_get_src(c, instr->src[i].src,
+ instr->src[i].swizzle[0]);
+ for (int i = 0; i < nir_op_infos[instr->op].num_inputs; i++)
+ ntq_store_dest(c, &instr->dest.dest, i,
+ vir_MOV(c, srcs[i]));
+ return;
+ }
+
+ /* General case: We can just grab the one used channel per src. */
+ struct qreg src[nir_op_infos[instr->op].num_inputs];
+ for (int i = 0; i < nir_op_infos[instr->op].num_inputs; i++) {
+ src[i] = ntq_get_alu_src(c, instr, i);
+ }
+
+ struct qreg result;
+
+ switch (instr->op) {
+ case nir_op_fmov:
+ case nir_op_imov:
+ result = vir_MOV(c, src[0]);
+ break;
+ case nir_op_fmul:
+ result = vir_FMUL(c, src[0], src[1]);
+ break;
+ case nir_op_fadd:
+ result = vir_FADD(c, src[0], src[1]);
+ break;
+ case nir_op_fsub:
+ result = vir_FSUB(c, src[0], src[1]);
+ break;
+ case nir_op_fmin:
+ result = vir_FMIN(c, src[0], src[1]);
+ break;
+ case nir_op_fmax:
+ result = vir_FMAX(c, src[0], src[1]);
+ break;
+
+ case nir_op_f2i32:
+ result = vir_FTOIZ(c, src[0]);
+ break;
+ case nir_op_f2u32:
+ result = vir_FTOUZ(c, src[0]);
+ break;
+ case nir_op_i2f32:
+ result = vir_ITOF(c, src[0]);
+ break;
+ case nir_op_u2f32:
+ result = vir_UTOF(c, src[0]);
+ break;
+ case nir_op_b2f:
+ result = vir_AND(c, src[0], vir_uniform_f(c, 1.0));
+ break;
+ case nir_op_b2i:
+ result = vir_AND(c, src[0], vir_uniform_ui(c, 1));
+ break;
+ case nir_op_i2b:
+ case nir_op_f2b:
+ vir_PF(c, src[0], V3D_QPU_PF_PUSHZ);
+ result = vir_MOV(c, vir_SEL(c, V3D_QPU_COND_IFNA,
+ vir_uniform_ui(c, ~0),
+ vir_uniform_ui(c, 0)));
+ break;
+
+ case nir_op_iadd:
+ result = vir_ADD(c, src[0], src[1]);
+ break;
+ case nir_op_ushr:
+ result = vir_SHR(c, src[0], src[1]);
+ break;
+ case nir_op_isub:
+ result = vir_SUB(c, src[0], src[1]);
+ break;
+ case nir_op_ishr:
+ result = vir_ASR(c, src[0], src[1]);
+ break;
+ case nir_op_ishl:
+ result = vir_SHL(c, src[0], src[1]);
+ break;
+ case nir_op_imin:
+ result = vir_MIN(c, src[0], src[1]);
+ break;
+ case nir_op_umin:
+ result = vir_UMIN(c, src[0], src[1]);
+ break;
+ case nir_op_imax:
+ result = vir_MAX(c, src[0], src[1]);
+ break;
+ case nir_op_umax:
+ result = vir_UMAX(c, src[0], src[1]);
+ break;
+ case nir_op_iand:
+ result = vir_AND(c, src[0], src[1]);
+ break;
+ case nir_op_ior:
+ result = vir_OR(c, src[0], src[1]);
+ break;
+ case nir_op_ixor:
+ result = vir_XOR(c, src[0], src[1]);
+ break;
+ case nir_op_inot:
+ result = vir_NOT(c, src[0]);
+ break;
+
+ case nir_op_imul:
+ result = ntq_umul(c, src[0], src[1]);
+ break;
+
+ case nir_op_seq:
+ case nir_op_sne:
+ case nir_op_sge:
+ case nir_op_slt:
+ case nir_op_feq:
+ case nir_op_fne:
+ case nir_op_fge:
+ case nir_op_flt:
+ case nir_op_ieq:
+ case nir_op_ine:
+ case nir_op_ige:
+ case nir_op_uge:
+ case nir_op_ilt:
+ case nir_op_ult:
+ if (!ntq_emit_comparison(c, &result, instr, instr)) {
+ fprintf(stderr, "Bad comparison instruction\n");
+ }
+ break;
+
+ case nir_op_bcsel:
+ result = ntq_emit_bcsel(c, instr, src);
+ break;
+ case nir_op_fcsel:
+ vir_PF(c, src[0], V3D_QPU_PF_PUSHZ);
+ result = vir_MOV(c, vir_SEL(c, V3D_QPU_COND_IFNA,
+ src[1], src[2]));
+ break;
+
+ case nir_op_frcp:
+ result = vir_SFU(c, V3D_QPU_WADDR_RECIP, src[0]);
+ break;
+ case nir_op_frsq:
+ result = vir_SFU(c, V3D_QPU_WADDR_RSQRT, src[0]);
+ break;
+ case nir_op_fexp2:
+ result = vir_SFU(c, V3D_QPU_WADDR_EXP, src[0]);
+ break;
+ case nir_op_flog2:
+ result = vir_SFU(c, V3D_QPU_WADDR_LOG, src[0]);
+ break;
+
+ case nir_op_fceil:
+ result = vir_FCEIL(c, src[0]);
+ break;
+ case nir_op_ffloor:
+ result = vir_FFLOOR(c, src[0]);
+ break;
+ case nir_op_fround_even:
+ result = vir_FROUND(c, src[0]);
+ break;
+ case nir_op_ftrunc:
+ result = vir_FTRUNC(c, src[0]);
+ break;
+ case nir_op_ffract:
+ result = vir_FSUB(c, src[0], vir_FFLOOR(c, src[0]));
+ break;
+
+ case nir_op_fsin:
+ result = ntq_fsincos(c, src[0], false);
+ break;
+ case nir_op_fcos:
+ result = ntq_fsincos(c, src[0], true);
+ break;
+
+ case nir_op_fsign:
+ result = ntq_fsign(c, src[0]);
+ break;
+ case nir_op_isign:
+ result = ntq_isign(c, src[0]);
+ break;
+
+ case nir_op_fabs: {
+ result = vir_FMOV(c, src[0]);
+ vir_set_unpack(c->defs[result.index], 0, V3D_QPU_UNPACK_ABS);
+ break;
+ }
+
+ case nir_op_iabs:
+ result = vir_MAX(c, src[0],
+ vir_SUB(c, vir_uniform_ui(c, 0), src[0]));
+ break;
+
+ case nir_op_fddx:
+ case nir_op_fddx_coarse:
+ case nir_op_fddx_fine:
+ result = vir_FDX(c, src[0]);
+ break;
+
+ case nir_op_fddy:
+ case nir_op_fddy_coarse:
+ case nir_op_fddy_fine:
+ result = vir_FDY(c, src[0]);
+ break;
+
+ default:
+ fprintf(stderr, "unknown NIR ALU inst: ");
+ nir_print_instr(&instr->instr, stderr);
+ fprintf(stderr, "\n");
+ abort();
+ }
+
+ /* We have a scalar result, so the instruction should only have a
+ * single channel written to.
+ */
+ assert(util_is_power_of_two(instr->dest.write_mask));
+ ntq_store_dest(c, &instr->dest.dest,
+ ffs(instr->dest.write_mask) - 1, result);
+}
+
+/* Each TLB read/write setup (a render target or depth buffer) takes an 8-bit
+ * specifier. They come from a register that's preloaded with 0xffffffff
+ * (0xff gets you normal vec4 f16 RT0 writes), and when one is neaded the low
+ * 8 bits are shifted off the bottom and 0xff shifted in from the top.
+ */
+#define TLB_TYPE_F16_COLOR (3 << 6)
+#define TLB_TYPE_I32_COLOR (1 << 6)
+#define TLB_TYPE_F32_COLOR (0 << 6)
+#define TLB_RENDER_TARGET_SHIFT 3 /* Reversed! 7 = RT 0, 0 = RT 7. */
+#define TLB_SAMPLE_MODE_PER_SAMPLE (0 << 2)
+#define TLB_SAMPLE_MODE_PER_PIXEL (1 << 2)
+#define TLB_F16_SWAP_HI_LO (1 << 1)
+#define TLB_VEC_SIZE_4_F16 (1 << 0)
+#define TLB_VEC_SIZE_2_F16 (0 << 0)
+#define TLB_VEC_SIZE_MINUS_1_SHIFT 0
+
+/* Triggers Z/Stencil testing, used when the shader state's "FS modifies Z"
+ * flag is set.
+ */
+#define TLB_TYPE_DEPTH ((2 << 6) | (0 << 4))
+#define TLB_DEPTH_TYPE_INVARIANT (0 << 2) /* Unmodified sideband input used */
+#define TLB_DEPTH_TYPE_PER_PIXEL (1 << 2) /* QPU result used */
+
+/* Stencil is a single 32-bit write. */
+#define TLB_TYPE_STENCIL_ALPHA ((2 << 6) | (1 << 4))
+
+static void
+emit_frag_end(struct v3d_compile *c)
+{
+ /* XXX
+ if (c->output_sample_mask_index != -1) {
+ vir_MS_MASK(c, c->outputs[c->output_sample_mask_index]);
+ }
+ */
+
+ if (c->output_position_index != -1) {
+ struct qinst *inst = vir_MOV_dest(c,
+ vir_reg(QFILE_TLBU, 0),
+ c->outputs[c->output_position_index]);
+
+ inst->src[vir_get_implicit_uniform_src(inst)] =
+ vir_uniform_ui(c,
+ TLB_TYPE_DEPTH |
+ TLB_DEPTH_TYPE_PER_PIXEL |
+ 0xffffff00);
+ } else if (c->s->info.fs.uses_discard) {
+ struct qinst *inst = vir_MOV_dest(c,
+ vir_reg(QFILE_TLBU, 0),
+ vir_reg(QFILE_NULL, 0));
+
+ inst->src[vir_get_implicit_uniform_src(inst)] =
+ vir_uniform_ui(c,
+ TLB_TYPE_DEPTH |
+ TLB_DEPTH_TYPE_INVARIANT |
+ 0xffffff00);
+ }
+
+ /* XXX: Performance improvement: Merge Z write and color writes TLB
+ * uniform setup
+ */
+
+ for (int rt = 0; rt < c->fs_key->nr_cbufs; rt++) {
+ if (!c->output_color_var[rt])
+ continue;
+
+ nir_variable *var = c->output_color_var[rt];
+ struct qreg *color = &c->outputs[var->data.driver_location * 4];
+ int num_components = glsl_get_vector_elements(var->type);
+ uint32_t conf = 0xffffff00;
+ struct qinst *inst;
+
+ conf |= TLB_SAMPLE_MODE_PER_PIXEL;
+ conf |= (7 - rt) << TLB_RENDER_TARGET_SHIFT;
+
+ assert(num_components != 0);
+ switch (glsl_get_base_type(var->type)) {
+ case GLSL_TYPE_UINT:
+ case GLSL_TYPE_INT:
+ conf |= TLB_TYPE_I32_COLOR;
+ conf |= ((num_components - 1) <<
+ TLB_VEC_SIZE_MINUS_1_SHIFT);
+
+ inst = vir_MOV_dest(c, vir_reg(QFILE_TLBU, 0), color[0]);
+ inst->src[vir_get_implicit_uniform_src(inst)] =
+ vir_uniform_ui(c, conf);
+
+ for (int i = 1; i < num_components; i++) {
+ inst = vir_MOV_dest(c, vir_reg(QFILE_TLB, 0),
+ color[i]);
+ }
+ break;
+
+ default: {
+ struct qreg r = color[0];
+ struct qreg g = color[1];
+ struct qreg b = color[2];
+ struct qreg a = color[3];
+
+ if (c->fs_key->f32_color_rb) {
+ conf |= TLB_TYPE_F32_COLOR;
+ conf |= ((num_components - 1) <<
+ TLB_VEC_SIZE_MINUS_1_SHIFT);
+ } else {
+ conf |= TLB_TYPE_F16_COLOR;
+ conf |= TLB_F16_SWAP_HI_LO;
+ if (num_components >= 3)
+ conf |= TLB_VEC_SIZE_4_F16;
+ else
+ conf |= TLB_VEC_SIZE_2_F16;
+ }
+
+ if (c->fs_key->swap_color_rb & (1 << rt)) {
+ r = color[2];
+ b = color[0];
+ }
+
+ if (c->fs_key->f32_color_rb & (1 << rt)) {
+ inst = vir_MOV_dest(c, vir_reg(QFILE_TLBU, 0), color[0]);
+ inst->src[vir_get_implicit_uniform_src(inst)] =
+ vir_uniform_ui(c, conf);
+
+ for (int i = 1; i < num_components; i++) {
+ inst = vir_MOV_dest(c, vir_reg(QFILE_TLB, 0),
+ color[i]);
+ }
+ } else {
+ inst = vir_VFPACK_dest(c, vir_reg(QFILE_TLB, 0), r, g);
+ if (conf != ~0) {
+ inst->dst.file = QFILE_TLBU;
+ inst->src[vir_get_implicit_uniform_src(inst)] =
+ vir_uniform_ui(c, conf);
+ }
+
+ inst = vir_VFPACK_dest(c, vir_reg(QFILE_TLB, 0), b, a);
+ }
+ break;
+ }
+ }
+ }
+}
+
+static void
+emit_scaled_viewport_write(struct v3d_compile *c, struct qreg rcp_w)
+{
+ for (int i = 0; i < 2; i++) {
+ struct qreg coord = c->outputs[c->output_position_index + i];
+ coord = vir_FMUL(c, coord,
+ vir_uniform(c, QUNIFORM_VIEWPORT_X_SCALE + i,
+ 0));
+ coord = vir_FMUL(c, coord, rcp_w);
+ vir_FTOIN_dest(c, vir_reg(QFILE_MAGIC, V3D_QPU_WADDR_VPM),
+ coord);
+ }
+
+}
+
+static void
+emit_zs_write(struct v3d_compile *c, struct qreg rcp_w)
+{
+ struct qreg zscale = vir_uniform(c, QUNIFORM_VIEWPORT_Z_SCALE, 0);
+ struct qreg zoffset = vir_uniform(c, QUNIFORM_VIEWPORT_Z_OFFSET, 0);
+
+ vir_FADD_dest(c, vir_reg(QFILE_MAGIC, V3D_QPU_WADDR_VPM),
+ vir_FMUL(c, vir_FMUL(c,
+ c->outputs[c->output_position_index + 2],
+ zscale),
+ rcp_w),
+ zoffset);
+}
+
+static void
+emit_rcp_wc_write(struct v3d_compile *c, struct qreg rcp_w)
+{
+ vir_VPM_WRITE(c, rcp_w);
+}
+
+static void
+emit_point_size_write(struct v3d_compile *c)
+{
+ struct qreg point_size;
+
+ if (c->output_point_size_index != -1)
+ point_size = c->outputs[c->output_point_size_index];
+ else
+ point_size = vir_uniform_f(c, 1.0);
+
+ /* Workaround: HW-2726 PTB does not handle zero-size points (BCM2835,
+ * BCM21553).
+ */
+ point_size = vir_FMAX(c, point_size, vir_uniform_f(c, .125));
+
+ vir_VPM_WRITE(c, point_size);
+}
+
+static void
+emit_vpm_write_setup(struct v3d_compile *c)
+{
+ uint32_t packed;
+ struct V3D33_VPM_GENERIC_BLOCK_WRITE_SETUP unpacked = {
+ V3D33_VPM_GENERIC_BLOCK_WRITE_SETUP_header,
+
+ .horiz = true,
+ .laned = false,
+ .segs = true,
+ .stride = 1,
+ .size = VPM_SETUP_SIZE_32_BIT,
+ .addr = 0,
+ };
+
+ V3D33_VPM_GENERIC_BLOCK_WRITE_SETUP_pack(NULL,
+ (uint8_t *)&packed,
+ &unpacked);
+ vir_VPMSETUP(c, vir_uniform_ui(c, packed));
+}
+
+static void
+emit_vert_end(struct v3d_compile *c)
+{
+ struct qreg rcp_w = vir_SFU(c, V3D_QPU_WADDR_RECIP,
+ c->outputs[c->output_position_index + 3]);
+
+ emit_vpm_write_setup(c);
+
+ if (c->vs_key->is_coord) {
+ for (int i = 0; i < 4; i++)
+ vir_VPM_WRITE(c, c->outputs[c->output_position_index + i]);
+ emit_scaled_viewport_write(c, rcp_w);
+ if (c->vs_key->per_vertex_point_size) {
+ emit_point_size_write(c);
+ /* emit_rcp_wc_write(c, rcp_w); */
+ }
+ /* XXX: Z-only rendering */
+ if (0)
+ emit_zs_write(c, rcp_w);
+ } else {
+ emit_scaled_viewport_write(c, rcp_w);
+ emit_zs_write(c, rcp_w);
+ emit_rcp_wc_write(c, rcp_w);
+ if (c->vs_key->per_vertex_point_size)
+ emit_point_size_write(c);
+ }
+
+ for (int i = 0; i < c->vs_key->num_fs_inputs; i++) {
+ struct v3d_varying_slot input = c->vs_key->fs_inputs[i];
+ int j;
+
+ for (j = 0; j < c->num_outputs; j++) {
+ struct v3d_varying_slot output = c->output_slots[j];
+
+ if (!memcmp(&input, &output, sizeof(input))) {
+ vir_VPM_WRITE(c, c->outputs[j]);
+ break;
+ }
+ }
+ /* Emit padding if we didn't find a declared VS output for
+ * this FS input.
+ */
+ if (j == c->num_outputs)
+ vir_VPM_WRITE(c, vir_uniform_f(c, 0.0));
+ }
+}
+
+void
+v3d_optimize_nir(struct nir_shader *s)
+{
+ bool progress;
+
+ do {
+ progress = false;
+
+ NIR_PASS_V(s, nir_lower_vars_to_ssa);
+ NIR_PASS(progress, s, nir_lower_alu_to_scalar);
+ NIR_PASS(progress, s, nir_lower_phis_to_scalar);
+ NIR_PASS(progress, s, nir_copy_prop);
+ NIR_PASS(progress, s, nir_opt_remove_phis);
+ NIR_PASS(progress, s, nir_opt_dce);
+ NIR_PASS(progress, s, nir_opt_dead_cf);
+ NIR_PASS(progress, s, nir_opt_cse);
+ NIR_PASS(progress, s, nir_opt_peephole_select, 8);
+ NIR_PASS(progress, s, nir_opt_algebraic);
+ NIR_PASS(progress, s, nir_opt_constant_folding);
+ NIR_PASS(progress, s, nir_opt_undef);
+ } while (progress);
+}
+
+static int
+driver_location_compare(const void *in_a, const void *in_b)
+{
+ const nir_variable *const *a = in_a;
+ const nir_variable *const *b = in_b;
+
+ return (*a)->data.driver_location - (*b)->data.driver_location;
+}
+
+static struct qreg
+ntq_emit_vpm_read(struct v3d_compile *c,
+ uint32_t *num_components_queued,
+ uint32_t *remaining,
+ uint32_t vpm_index)
+{
+ struct qreg vpm = vir_reg(QFILE_VPM, vpm_index);
+
+ if (*num_components_queued != 0) {
+ (*num_components_queued)--;
+ c->num_inputs++;
+ return vir_MOV(c, vpm);
+ }
+
+ uint32_t num_components = MIN2(*remaining, 32);
+
+ struct V3D33_VPM_GENERIC_BLOCK_READ_SETUP unpacked = {
+ V3D33_VPM_GENERIC_BLOCK_READ_SETUP_header,
+
+ .horiz = true,
+ .laned = false,
+ /* If the field is 0, that means a read count of 32. */
+ .num = num_components & 31,
+ .segs = true,
+ .stride = 1,
+ .size = VPM_SETUP_SIZE_32_BIT,
+ .addr = c->num_inputs,
+ };
+
+ uint32_t packed;
+ V3D33_VPM_GENERIC_BLOCK_READ_SETUP_pack(NULL,
+ (uint8_t *)&packed,
+ &unpacked);
+ vir_VPMSETUP(c, vir_uniform_ui(c, packed));
+
+ *num_components_queued = num_components - 1;
+ *remaining -= num_components;
+ c->num_inputs++;
+
+ return vir_MOV(c, vpm);
+}
+
+static void
+ntq_setup_inputs(struct v3d_compile *c)
+{
+ unsigned num_entries = 0;
+ unsigned num_components = 0;
+ nir_foreach_variable(var, &c->s->inputs) {
+ num_entries++;
+ num_components += glsl_get_components(var->type);
+ }
+
+ nir_variable *vars[num_entries];
+
+ unsigned i = 0;
+ nir_foreach_variable(var, &c->s->inputs)
+ vars[i++] = var;
+
+ /* Sort the variables so that we emit the input setup in
+ * driver_location order. This is required for VPM reads, whose data
+ * is fetched into the VPM in driver_location (TGSI register index)
+ * order.
+ */
+ qsort(&vars, num_entries, sizeof(*vars), driver_location_compare);
+
+ uint32_t vpm_components_queued = 0;
+ if (c->s->info.stage == MESA_SHADER_VERTEX) {
+ bool uses_iid = c->s->info.system_values_read &
+ (1ull << SYSTEM_VALUE_INSTANCE_ID);
+ bool uses_vid = c->s->info.system_values_read &
+ (1ull << SYSTEM_VALUE_VERTEX_ID);
+
+ num_components += uses_iid;
+ num_components += uses_vid;
+
+ if (uses_iid) {
+ c->iid = ntq_emit_vpm_read(c, &vpm_components_queued,
+ &num_components, ~0);
+ }
+
+ if (uses_vid) {
+ c->vid = ntq_emit_vpm_read(c, &vpm_components_queued,
+ &num_components, ~0);
+ }
+ }
+
+ for (unsigned i = 0; i < num_entries; i++) {
+ nir_variable *var = vars[i];
+ unsigned array_len = MAX2(glsl_get_length(var->type), 1);
+ unsigned loc = var->data.driver_location;
+
+ assert(array_len == 1);
+ (void)array_len;
+ resize_qreg_array(c, &c->inputs, &c->inputs_array_size,
+ (loc + 1) * 4);
+
+ if (c->s->info.stage == MESA_SHADER_FRAGMENT) {
+ if (var->data.location == VARYING_SLOT_POS) {
+ emit_fragcoord_input(c, loc);
+ } else if (var->data.location == VARYING_SLOT_PNTC ||
+ (var->data.location >= VARYING_SLOT_VAR0 &&
+ (c->fs_key->point_sprite_mask &
+ (1 << (var->data.location -
+ VARYING_SLOT_VAR0))))) {
+ c->inputs[loc * 4 + 0] = c->point_x;
+ c->inputs[loc * 4 + 1] = c->point_y;
+ } else {
+ emit_fragment_input(c, loc, var);
+ }
+ } else {
+ int var_components = glsl_get_components(var->type);
+
+ for (int i = 0; i < var_components; i++) {
+ c->inputs[loc * 4 + i] =
+ ntq_emit_vpm_read(c,
+ &vpm_components_queued,
+ &num_components,
+ loc * 4 + i);
+
+ }
+ c->vattr_sizes[loc] = var_components;
+ }
+ }
+
+ if (c->s->info.stage == MESA_SHADER_VERTEX) {
+ assert(vpm_components_queued == 0);
+ assert(num_components == 0);
+ }
+}
+
+static void
+ntq_setup_outputs(struct v3d_compile *c)
+{
+ nir_foreach_variable(var, &c->s->outputs) {
+ unsigned array_len = MAX2(glsl_get_length(var->type), 1);
+ unsigned loc = var->data.driver_location * 4;
+
+ assert(array_len == 1);
+ (void)array_len;
+
+ for (int i = 0; i < 4; i++)
+ add_output(c, loc + i, var->data.location, i);
+
+ if (c->s->info.stage == MESA_SHADER_FRAGMENT) {
+ switch (var->data.location) {
+ case FRAG_RESULT_COLOR:
+ c->output_color_var[0] = var;
+ c->output_color_var[1] = var;
+ c->output_color_var[2] = var;
+ c->output_color_var[3] = var;
+ break;
+ case FRAG_RESULT_DATA0:
+ case FRAG_RESULT_DATA1:
+ case FRAG_RESULT_DATA2:
+ case FRAG_RESULT_DATA3:
+ c->output_color_var[var->data.location -
+ FRAG_RESULT_DATA0] = var;
+ break;
+ case FRAG_RESULT_DEPTH:
+ c->output_position_index = loc;
+ break;
+ case FRAG_RESULT_SAMPLE_MASK:
+ c->output_sample_mask_index = loc;
+ break;
+ }
+ } else {
+ switch (var->data.location) {
+ case VARYING_SLOT_POS:
+ c->output_position_index = loc;
+ break;
+ case VARYING_SLOT_PSIZ:
+ c->output_point_size_index = loc;
+ break;
+ }
+ }
+ }
+}
+
+static void
+ntq_setup_uniforms(struct v3d_compile *c)
+{
+ nir_foreach_variable(var, &c->s->uniforms) {
+ uint32_t vec4_count = glsl_count_attribute_slots(var->type,
+ false);
+ unsigned vec4_size = 4 * sizeof(float);
+
+ declare_uniform_range(c, var->data.driver_location * vec4_size,
+ vec4_count * vec4_size);
+
+ }
+}
+
+/**
+ * Sets up the mapping from nir_register to struct qreg *.
+ *
+ * Each nir_register gets a struct qreg per 32-bit component being stored.
+ */
+static void
+ntq_setup_registers(struct v3d_compile *c, struct exec_list *list)
+{
+ foreach_list_typed(nir_register, nir_reg, node, list) {
+ unsigned array_len = MAX2(nir_reg->num_array_elems, 1);
+ struct qreg *qregs = ralloc_array(c->def_ht, struct qreg,
+ array_len *
+ nir_reg->num_components);
+
+ _mesa_hash_table_insert(c->def_ht, nir_reg, qregs);
+
+ for (int i = 0; i < array_len * nir_reg->num_components; i++)
+ qregs[i] = vir_get_temp(c);
+ }
+}
+
+static void
+ntq_emit_load_const(struct v3d_compile *c, nir_load_const_instr *instr)
+{
+ struct qreg *qregs = ntq_init_ssa_def(c, &instr->def);
+ for (int i = 0; i < instr->def.num_components; i++)
+ qregs[i] = vir_uniform_ui(c, instr->value.u32[i]);
+
+ _mesa_hash_table_insert(c->def_ht, &instr->def, qregs);
+}
+
+static void
+ntq_emit_ssa_undef(struct v3d_compile *c, nir_ssa_undef_instr *instr)
+{
+ struct qreg *qregs = ntq_init_ssa_def(c, &instr->def);
+
+ /* VIR needs there to be *some* value, so pick 0 (same as for
+ * ntq_setup_registers().
+ */
+ for (int i = 0; i < instr->def.num_components; i++)
+ qregs[i] = vir_uniform_ui(c, 0);
+}
+
+static void
+ntq_emit_intrinsic(struct v3d_compile *c, nir_intrinsic_instr *instr)
+{
+ nir_const_value *const_offset;
+ unsigned offset;
+
+ switch (instr->intrinsic) {
+ case nir_intrinsic_load_uniform:
+ assert(instr->num_components == 1);
+ const_offset = nir_src_as_const_value(instr->src[0]);
+ if (const_offset) {
+ offset = nir_intrinsic_base(instr) + const_offset->u32[0];
+ assert(offset % 4 == 0);
+ /* We need dwords */
+ offset = offset / 4;
+ ntq_store_dest(c, &instr->dest, 0,
+ vir_uniform(c, QUNIFORM_UNIFORM,
+ offset));
+ } else {
+ ntq_store_dest(c, &instr->dest, 0,
+ indirect_uniform_load(c, instr));
+ }
+ break;
+
+ case nir_intrinsic_load_ubo:
+ for (int i = 0; i < instr->num_components; i++) {
+ int ubo = nir_src_as_const_value(instr->src[0])->u32[0];
+
+ /* Adjust for where we stored the TGSI register base. */
+ vir_ADD_dest(c,
+ vir_reg(QFILE_MAGIC, V3D_QPU_WADDR_TMUA),
+ vir_uniform(c, QUNIFORM_UBO_ADDR, 1 + ubo),
+ vir_ADD(c,
+ ntq_get_src(c, instr->src[1], 0),
+ vir_uniform_ui(c, i * 4)));
+
+ ntq_store_dest(c, &instr->dest, i, vir_LDTMU(c));
+ }
+ break;
+
+ const_offset = nir_src_as_const_value(instr->src[0]);
+ if (const_offset) {
+ offset = nir_intrinsic_base(instr) + const_offset->u32[0];
+ assert(offset % 4 == 0);
+ /* We need dwords */
+ offset = offset / 4;
+ ntq_store_dest(c, &instr->dest, 0,
+ vir_uniform(c, QUNIFORM_UNIFORM,
+ offset));
+ } else {
+ ntq_store_dest(c, &instr->dest, 0,
+ indirect_uniform_load(c, instr));
+ }
+ break;
+
+ case nir_intrinsic_load_user_clip_plane:
+ for (int i = 0; i < instr->num_components; i++) {
+ ntq_store_dest(c, &instr->dest, i,
+ vir_uniform(c, QUNIFORM_USER_CLIP_PLANE,
+ nir_intrinsic_ucp_id(instr) *
+ 4 + i));
+ }
+ break;
+
+ case nir_intrinsic_load_alpha_ref_float:
+ ntq_store_dest(c, &instr->dest, 0,
+ vir_uniform(c, QUNIFORM_ALPHA_REF, 0));
+ break;
+
+ case nir_intrinsic_load_sample_mask_in:
+ ntq_store_dest(c, &instr->dest, 0,
+ vir_uniform(c, QUNIFORM_SAMPLE_MASK, 0));
+ break;
+
+ case nir_intrinsic_load_front_face:
+ /* The register contains 0 (front) or 1 (back), and we need to
+ * turn it into a NIR bool where true means front.
+ */
+ ntq_store_dest(c, &instr->dest, 0,
+ vir_ADD(c,
+ vir_uniform_ui(c, -1),
+ vir_REVF(c)));
+ break;
+
+ case nir_intrinsic_load_instance_id:
+ ntq_store_dest(c, &instr->dest, 0, vir_MOV(c, c->iid));
+ break;
+
+ case nir_intrinsic_load_vertex_id:
+ ntq_store_dest(c, &instr->dest, 0, vir_MOV(c, c->vid));
+ break;
+
+ case nir_intrinsic_load_input:
+ const_offset = nir_src_as_const_value(instr->src[0]);
+ assert(const_offset && "v3d doesn't support indirect inputs");
+ for (int i = 0; i < instr->num_components; i++) {
+ offset = nir_intrinsic_base(instr) + const_offset->u32[0];
+ int comp = nir_intrinsic_component(instr) + i;
+ ntq_store_dest(c, &instr->dest, i,
+ vir_MOV(c, c->inputs[offset * 4 + comp]));
+ }
+ break;
+
+ case nir_intrinsic_store_output:
+ const_offset = nir_src_as_const_value(instr->src[1]);
+ assert(const_offset && "v3d doesn't support indirect outputs");
+ offset = ((nir_intrinsic_base(instr) +
+ const_offset->u32[0]) * 4 +
+ nir_intrinsic_component(instr));
+
+ for (int i = 0; i < instr->num_components; i++) {
+ c->outputs[offset + i] =
+ vir_MOV(c, ntq_get_src(c, instr->src[0], i));
+ }
+ c->num_outputs = MAX2(c->num_outputs,
+ offset + instr->num_components);
+ break;
+
+ case nir_intrinsic_discard:
+ if (c->execute.file != QFILE_NULL) {
+ vir_PF(c, c->execute, V3D_QPU_PF_PUSHZ);
+ vir_set_cond(vir_SETMSF_dest(c, vir_reg(QFILE_NULL, 0),
+ vir_uniform_ui(c, 0)),
+ V3D_QPU_COND_IFA);
+ } else {
+ vir_SETMSF_dest(c, vir_reg(QFILE_NULL, 0),
+ vir_uniform_ui(c, 0));
+ }
+ break;
+
+ case nir_intrinsic_discard_if: {
+ /* true (~0) if we're discarding */
+ struct qreg cond = ntq_get_src(c, instr->src[0], 0);
+
+ if (c->execute.file != QFILE_NULL) {
+ /* execute == 0 means the channel is active. Invert
+ * the condition so that we can use zero as "executing
+ * and discarding."
+ */
+ vir_PF(c, vir_AND(c, c->execute, vir_NOT(c, cond)),
+ V3D_QPU_PF_PUSHZ);
+ vir_set_cond(vir_SETMSF_dest(c, vir_reg(QFILE_NULL, 0),
+ vir_uniform_ui(c, 0)),
+ V3D_QPU_COND_IFA);
+ } else {
+ vir_PF(c, cond, V3D_QPU_PF_PUSHZ);
+ vir_set_cond(vir_SETMSF_dest(c, vir_reg(QFILE_NULL, 0),
+ vir_uniform_ui(c, 0)),
+ V3D_QPU_COND_IFNA);
+ }
+
+ break;
+ }
+
+ default:
+ fprintf(stderr, "Unknown intrinsic: ");
+ nir_print_instr(&instr->instr, stderr);
+ fprintf(stderr, "\n");
+ break;
+ }
+}
+
+/* Clears (activates) the execute flags for any channels whose jump target
+ * matches this block.
+ */
+static void
+ntq_activate_execute_for_block(struct v3d_compile *c)
+{
+ vir_PF(c, vir_SUB(c, c->execute, vir_uniform_ui(c, c->cur_block->index)),
+ V3D_QPU_PF_PUSHZ);
+
+ vir_MOV_cond(c, V3D_QPU_COND_IFA, c->execute, vir_uniform_ui(c, 0));
+}
+
+static void
+ntq_emit_if(struct v3d_compile *c, nir_if *if_stmt)
+{
+ nir_block *nir_else_block = nir_if_first_else_block(if_stmt);
+ bool empty_else_block =
+ (nir_else_block == nir_if_last_else_block(if_stmt) &&
+ exec_list_is_empty(&nir_else_block->instr_list));
+
+ struct qblock *then_block = vir_new_block(c);
+ struct qblock *after_block = vir_new_block(c);
+ struct qblock *else_block;
+ if (empty_else_block)
+ else_block = after_block;
+ else
+ else_block = vir_new_block(c);
+
+ bool was_top_level = false;
+ if (c->execute.file == QFILE_NULL) {
+ c->execute = vir_MOV(c, vir_uniform_ui(c, 0));
+ was_top_level = true;
+ }
+
+ /* Set A for executing (execute == 0) and jumping (if->condition ==
+ * 0) channels, and then update execute flags for those to point to
+ * the ELSE block.
+ */
+ vir_PF(c, vir_OR(c,
+ c->execute,
+ ntq_get_src(c, if_stmt->condition, 0)),
+ V3D_QPU_PF_PUSHZ);
+ vir_MOV_cond(c, V3D_QPU_COND_IFA,
+ c->execute,
+ vir_uniform_ui(c, else_block->index));
+
+ /* Jump to ELSE if nothing is active for THEN, otherwise fall
+ * through.
+ */
+ vir_PF(c, c->execute, V3D_QPU_PF_PUSHZ);
+ vir_BRANCH(c, V3D_QPU_BRANCH_COND_ALLNA);
+ vir_link_blocks(c->cur_block, else_block);
+ vir_link_blocks(c->cur_block, then_block);
+
+ /* Process the THEN block. */
+ vir_set_emit_block(c, then_block);
+ ntq_emit_cf_list(c, &if_stmt->then_list);
+
+ if (!empty_else_block) {
+ /* Handle the end of the THEN block. First, all currently
+ * active channels update their execute flags to point to
+ * ENDIF
+ */
+ vir_PF(c, c->execute, V3D_QPU_PF_PUSHZ);
+ vir_MOV_cond(c, V3D_QPU_COND_IFA, c->execute,
+ vir_uniform_ui(c, after_block->index));
+
+ /* If everything points at ENDIF, then jump there immediately. */
+ vir_PF(c, vir_SUB(c, c->execute,
+ vir_uniform_ui(c, after_block->index)),
+ V3D_QPU_PF_PUSHZ);
+ vir_BRANCH(c, V3D_QPU_BRANCH_COND_ALLA);
+ vir_link_blocks(c->cur_block, after_block);
+ vir_link_blocks(c->cur_block, else_block);
+
+ vir_set_emit_block(c, else_block);
+ ntq_activate_execute_for_block(c);
+ ntq_emit_cf_list(c, &if_stmt->else_list);
+ }
+
+ vir_link_blocks(c->cur_block, after_block);
+
+ vir_set_emit_block(c, after_block);
+ if (was_top_level)
+ c->execute = c->undef;
+ else
+ ntq_activate_execute_for_block(c);
+}
+
+static void
+ntq_emit_jump(struct v3d_compile *c, nir_jump_instr *jump)
+{
+ switch (jump->type) {
+ case nir_jump_break:
+ vir_PF(c, c->execute, V3D_QPU_PF_PUSHZ);
+ vir_MOV_cond(c, V3D_QPU_COND_IFA, c->execute,
+ vir_uniform_ui(c, c->loop_break_block->index));
+ break;
+
+ case nir_jump_continue:
+ vir_PF(c, c->execute, V3D_QPU_PF_PUSHZ);
+ vir_MOV_cond(c, V3D_QPU_COND_IFA, c->execute,
+ vir_uniform_ui(c, c->loop_cont_block->index));
+ break;
+
+ case nir_jump_return:
+ unreachable("All returns shouold be lowered\n");
+ }
+}
+
+static void
+ntq_emit_instr(struct v3d_compile *c, nir_instr *instr)
+{
+ switch (instr->type) {
+ case nir_instr_type_alu:
+ ntq_emit_alu(c, nir_instr_as_alu(instr));
+ break;
+
+ case nir_instr_type_intrinsic:
+ ntq_emit_intrinsic(c, nir_instr_as_intrinsic(instr));
+ break;
+
+ case nir_instr_type_load_const:
+ ntq_emit_load_const(c, nir_instr_as_load_const(instr));
+ break;
+
+ case nir_instr_type_ssa_undef:
+ ntq_emit_ssa_undef(c, nir_instr_as_ssa_undef(instr));
+ break;
+
+ case nir_instr_type_tex:
+ ntq_emit_tex(c, nir_instr_as_tex(instr));
+ break;
+
+ case nir_instr_type_jump:
+ ntq_emit_jump(c, nir_instr_as_jump(instr));
+ break;
+
+ default:
+ fprintf(stderr, "Unknown NIR instr type: ");
+ nir_print_instr(instr, stderr);
+ fprintf(stderr, "\n");
+ abort();
+ }
+}
+
+static void
+ntq_emit_block(struct v3d_compile *c, nir_block *block)
+{
+ nir_foreach_instr(instr, block) {
+ ntq_emit_instr(c, instr);
+ }
+}
+
+static void ntq_emit_cf_list(struct v3d_compile *c, struct exec_list *list);
+
+static void
+ntq_emit_loop(struct v3d_compile *c, nir_loop *loop)
+{
+ bool was_top_level = false;
+ if (c->execute.file == QFILE_NULL) {
+ c->execute = vir_MOV(c, vir_uniform_ui(c, 0));
+ was_top_level = true;
+ }
+
+ struct qblock *save_loop_cont_block = c->loop_cont_block;
+ struct qblock *save_loop_break_block = c->loop_break_block;
+
+ c->loop_cont_block = vir_new_block(c);
+ c->loop_break_block = vir_new_block(c);
+
+ vir_link_blocks(c->cur_block, c->loop_cont_block);
+ vir_set_emit_block(c, c->loop_cont_block);
+ ntq_activate_execute_for_block(c);
+
+ ntq_emit_cf_list(c, &loop->body);
+
+ /* Re-enable any previous continues now, so our ANYA check below
+ * works.
+ *
+ * XXX: Use the .ORZ flags update, instead.
+ */
+ vir_PF(c, vir_SUB(c,
+ c->execute,
+ vir_uniform_ui(c, c->loop_cont_block->index)),
+ V3D_QPU_PF_PUSHZ);
+ vir_MOV_cond(c, V3D_QPU_COND_IFA, c->execute, vir_uniform_ui(c, 0));
+
+ vir_PF(c, c->execute, V3D_QPU_PF_PUSHZ);
+
+ vir_BRANCH(c, V3D_QPU_BRANCH_COND_ANYA);
+ vir_link_blocks(c->cur_block, c->loop_cont_block);
+ vir_link_blocks(c->cur_block, c->loop_break_block);
+
+ vir_set_emit_block(c, c->loop_break_block);
+ if (was_top_level)
+ c->execute = c->undef;
+ else
+ ntq_activate_execute_for_block(c);
+
+ c->loop_break_block = save_loop_break_block;
+ c->loop_cont_block = save_loop_cont_block;
+}
+
+static void
+ntq_emit_function(struct v3d_compile *c, nir_function_impl *func)
+{
+ fprintf(stderr, "FUNCTIONS not handled.\n");
+ abort();
+}
+
+static void
+ntq_emit_cf_list(struct v3d_compile *c, struct exec_list *list)
+{
+ foreach_list_typed(nir_cf_node, node, node, list) {
+ switch (node->type) {
+ case nir_cf_node_block:
+ ntq_emit_block(c, nir_cf_node_as_block(node));
+ break;
+
+ case nir_cf_node_if:
+ ntq_emit_if(c, nir_cf_node_as_if(node));
+ break;
+
+ case nir_cf_node_loop:
+ ntq_emit_loop(c, nir_cf_node_as_loop(node));
+ break;
+
+ case nir_cf_node_function:
+ ntq_emit_function(c, nir_cf_node_as_function(node));
+ break;
+
+ default:
+ fprintf(stderr, "Unknown NIR node type\n");
+ abort();
+ }
+ }
+}
+
+static void
+ntq_emit_impl(struct v3d_compile *c, nir_function_impl *impl)
+{
+ ntq_setup_registers(c, &impl->registers);
+ ntq_emit_cf_list(c, &impl->body);
+}
+
+static void
+nir_to_vir(struct v3d_compile *c)
+{
+ if (c->s->info.stage == MESA_SHADER_FRAGMENT) {
+ c->payload_w = vir_MOV(c, vir_reg(QFILE_REG, 0));
+ c->payload_w_centroid = vir_MOV(c, vir_reg(QFILE_REG, 1));
+ c->payload_z = vir_MOV(c, vir_reg(QFILE_REG, 2));
+
+ if (c->fs_key->is_points) {
+ c->point_x = emit_fragment_varying(c, NULL, 0);
+ c->point_y = emit_fragment_varying(c, NULL, 0);
+ } else if (c->fs_key->is_lines) {
+ c->line_x = emit_fragment_varying(c, NULL, 0);
+ }
+ }
+
+ ntq_setup_inputs(c);
+ ntq_setup_outputs(c);
+ ntq_setup_uniforms(c);
+ ntq_setup_registers(c, &c->s->registers);
+
+ /* Find the main function and emit the body. */
+ nir_foreach_function(function, c->s) {
+ assert(strcmp(function->name, "main") == 0);
+ assert(function->impl);
+ ntq_emit_impl(c, function->impl);
+ }
+}
+
+const nir_shader_compiler_options v3d_nir_options = {
+ .lower_extract_byte = true,
+ .lower_extract_word = true,
+ .lower_bitfield_insert = true,
+ .lower_bitfield_extract = true,
+ .lower_pack_unorm_2x16 = true,
+ .lower_pack_snorm_2x16 = true,
+ .lower_pack_unorm_4x8 = true,
+ .lower_pack_snorm_4x8 = true,
+ .lower_ffma = true,
+ .lower_flrp32 = true,
+ .lower_fpow = true,
+ .lower_fsat = true,
+ .lower_fsqrt = true,
+ .lower_negate = true,
+ .native_integers = true,
+};
+
+
+#if 0
+static int
+count_nir_instrs(nir_shader *nir)
+{
+ int count = 0;
+ nir_foreach_function(function, nir) {
+ if (!function->impl)
+ continue;
+ nir_foreach_block(block, function->impl) {
+ nir_foreach_instr(instr, block)
+ count++;
+ }
+ }
+ return count;
+}
+#endif
+
+void
+v3d_nir_to_vir(struct v3d_compile *c)
+{
+ if (V3D_DEBUG & (V3D_DEBUG_NIR |
+ v3d_debug_flag_for_shader_stage(c->s->info.stage))) {
+ fprintf(stderr, "%s prog %d/%d NIR:\n",
+ vir_get_stage_name(c),
+ c->program_id, c->variant_id);
+ nir_print_shader(c->s, stderr);
+ }
+
+ nir_to_vir(c);
+
+ switch (c->s->info.stage) {
+ case MESA_SHADER_FRAGMENT:
+ emit_frag_end(c);
+ break;
+ case MESA_SHADER_VERTEX:
+ emit_vert_end(c);
+ break;
+ default:
+ unreachable("bad stage");
+ }
+
+ if (V3D_DEBUG & (V3D_DEBUG_VIR |
+ v3d_debug_flag_for_shader_stage(c->s->info.stage))) {
+ fprintf(stderr, "%s prog %d/%d pre-opt VIR:\n",
+ vir_get_stage_name(c),
+ c->program_id, c->variant_id);
+ vir_dump(c);
+ fprintf(stderr, "\n");
+ }
+
+ vir_optimize(c);
+ vir_lower_uniforms(c);
+
+ /* XXX: vir_schedule_instructions(c); */
+
+ if (V3D_DEBUG & (V3D_DEBUG_VIR |
+ v3d_debug_flag_for_shader_stage(c->s->info.stage))) {
+ fprintf(stderr, "%s prog %d/%d VIR:\n",
+ vir_get_stage_name(c),
+ c->program_id, c->variant_id);
+ vir_dump(c);
+ fprintf(stderr, "\n");
+ }
+
+ v3d_vir_to_qpu(c);
+}
diff --git a/lib/mesa/src/broadcom/compiler/qpu_schedule.c b/lib/mesa/src/broadcom/compiler/qpu_schedule.c
new file mode 100644
index 000000000..dd221e027
--- /dev/null
+++ b/lib/mesa/src/broadcom/compiler/qpu_schedule.c
@@ -0,0 +1,1365 @@
+/*
+ * Copyright © 2010 Intel Corporation
+ * Copyright © 2014-2017 Broadcom
+ *
+ * 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.
+ */
+
+/**
+ * @file
+ *
+ * The basic model of the list scheduler is to take a basic block, compute a
+ * DAG of the dependencies, and make a list of the DAG heads. Heuristically
+ * pick a DAG head, then put all the children that are now DAG heads into the
+ * list of things to schedule.
+ *
+ * The goal of scheduling here is to pack pairs of operations together in a
+ * single QPU instruction.
+ */
+
+#include "qpu/qpu_disasm.h"
+#include "v3d_compiler.h"
+#include "util/ralloc.h"
+
+static bool debug;
+
+struct schedule_node_child;
+
+struct schedule_node {
+ struct list_head link;
+ struct qinst *inst;
+ struct schedule_node_child *children;
+ uint32_t child_count;
+ uint32_t child_array_size;
+ uint32_t parent_count;
+
+ /* Longest cycles + instruction_latency() of any parent of this node. */
+ uint32_t unblocked_time;
+
+ /**
+ * Minimum number of cycles from scheduling this instruction until the
+ * end of the program, based on the slowest dependency chain through
+ * the children.
+ */
+ uint32_t delay;
+
+ /**
+ * cycles between this instruction being scheduled and when its result
+ * can be consumed.
+ */
+ uint32_t latency;
+};
+
+struct schedule_node_child {
+ struct schedule_node *node;
+ bool write_after_read;
+};
+
+/* When walking the instructions in reverse, we need to swap before/after in
+ * add_dep().
+ */
+enum direction { F, R };
+
+struct schedule_state {
+ struct schedule_node *last_r[6];
+ struct schedule_node *last_rf[64];
+ struct schedule_node *last_sf;
+ struct schedule_node *last_vpm_read;
+ struct schedule_node *last_tmu_write;
+ struct schedule_node *last_tlb;
+ struct schedule_node *last_vpm;
+ struct schedule_node *last_unif;
+ struct schedule_node *last_rtop;
+ enum direction dir;
+ /* Estimated cycle when the current instruction would start. */
+ uint32_t time;
+};
+
+static void
+add_dep(struct schedule_state *state,
+ struct schedule_node *before,
+ struct schedule_node *after,
+ bool write)
+{
+ bool write_after_read = !write && state->dir == R;
+
+ if (!before || !after)
+ return;
+
+ assert(before != after);
+
+ if (state->dir == R) {
+ struct schedule_node *t = before;
+ before = after;
+ after = t;
+ }
+
+ for (int i = 0; i < before->child_count; i++) {
+ if (before->children[i].node == after &&
+ (before->children[i].write_after_read == write_after_read)) {
+ return;
+ }
+ }
+
+ if (before->child_array_size <= before->child_count) {
+ before->child_array_size = MAX2(before->child_array_size * 2, 16);
+ before->children = reralloc(before, before->children,
+ struct schedule_node_child,
+ before->child_array_size);
+ }
+
+ before->children[before->child_count].node = after;
+ before->children[before->child_count].write_after_read =
+ write_after_read;
+ before->child_count++;
+ after->parent_count++;
+}
+
+static void
+add_read_dep(struct schedule_state *state,
+ struct schedule_node *before,
+ struct schedule_node *after)
+{
+ add_dep(state, before, after, false);
+}
+
+static void
+add_write_dep(struct schedule_state *state,
+ struct schedule_node **before,
+ struct schedule_node *after)
+{
+ add_dep(state, *before, after, true);
+ *before = after;
+}
+
+static bool
+qpu_inst_is_tlb(const struct v3d_qpu_instr *inst)
+{
+ if (inst->type != V3D_QPU_INSTR_TYPE_ALU)
+ return false;
+
+ if (inst->alu.add.magic_write &&
+ (inst->alu.add.waddr == V3D_QPU_WADDR_TLB ||
+ inst->alu.add.waddr == V3D_QPU_WADDR_TLBU))
+ return true;
+
+ if (inst->alu.mul.magic_write &&
+ (inst->alu.mul.waddr == V3D_QPU_WADDR_TLB ||
+ inst->alu.mul.waddr == V3D_QPU_WADDR_TLBU))
+ return true;
+
+ return false;
+}
+
+static void
+process_mux_deps(struct schedule_state *state, struct schedule_node *n,
+ enum v3d_qpu_mux mux)
+{
+ switch (mux) {
+ case V3D_QPU_MUX_A:
+ add_read_dep(state, state->last_rf[n->inst->qpu.raddr_a], n);
+ break;
+ case V3D_QPU_MUX_B:
+ add_read_dep(state, state->last_rf[n->inst->qpu.raddr_b], n);
+ break;
+ default:
+ add_read_dep(state, state->last_r[mux - V3D_QPU_MUX_R0], n);
+ break;
+ }
+}
+
+
+static void
+process_waddr_deps(struct schedule_state *state, struct schedule_node *n,
+ uint32_t waddr, bool magic)
+{
+ if (!magic) {
+ add_write_dep(state, &state->last_rf[waddr], n);
+ } else if (v3d_qpu_magic_waddr_is_tmu(waddr)) {
+ add_write_dep(state, &state->last_tmu_write, n);
+ } else if (v3d_qpu_magic_waddr_is_sfu(waddr)) {
+ /* Handled by v3d_qpu_writes_r4() check. */
+ } else {
+ switch (waddr) {
+ case V3D_QPU_WADDR_R0:
+ case V3D_QPU_WADDR_R1:
+ case V3D_QPU_WADDR_R2:
+ case V3D_QPU_WADDR_R3:
+ case V3D_QPU_WADDR_R4:
+ case V3D_QPU_WADDR_R5:
+ add_write_dep(state,
+ &state->last_r[waddr - V3D_QPU_WADDR_R0],
+ n);
+ break;
+
+ case V3D_QPU_WADDR_VPM:
+ case V3D_QPU_WADDR_VPMU:
+ add_write_dep(state, &state->last_vpm, n);
+ break;
+
+ case V3D_QPU_WADDR_TLB:
+ case V3D_QPU_WADDR_TLBU:
+ add_write_dep(state, &state->last_tlb, n);
+ break;
+
+ case V3D_QPU_WADDR_NOP:
+ break;
+
+ default:
+ fprintf(stderr, "Unknown waddr %d\n", waddr);
+ abort();
+ }
+ }
+}
+
+static void
+process_cond_deps(struct schedule_state *state, struct schedule_node *n,
+ enum v3d_qpu_cond cond)
+{
+ if (cond != V3D_QPU_COND_NONE)
+ add_read_dep(state, state->last_sf, n);
+}
+
+static void
+process_pf_deps(struct schedule_state *state, struct schedule_node *n,
+ enum v3d_qpu_pf pf)
+{
+ if (pf != V3D_QPU_PF_NONE)
+ add_write_dep(state, &state->last_sf, n);
+}
+
+static void
+process_uf_deps(struct schedule_state *state, struct schedule_node *n,
+ enum v3d_qpu_uf uf)
+{
+ if (uf != V3D_QPU_UF_NONE)
+ add_write_dep(state, &state->last_sf, n);
+}
+
+/**
+ * Common code for dependencies that need to be tracked both forward and
+ * backward.
+ *
+ * This is for things like "all reads of r4 have to happen between the r4
+ * writes that surround them".
+ */
+static void
+calculate_deps(struct schedule_state *state, struct schedule_node *n)
+{
+ struct qinst *qinst = n->inst;
+ struct v3d_qpu_instr *inst = &qinst->qpu;
+
+ if (inst->type == V3D_QPU_INSTR_TYPE_BRANCH) {
+ if (inst->branch.cond != V3D_QPU_BRANCH_COND_ALWAYS)
+ add_read_dep(state, state->last_sf, n);
+
+ /* XXX: BDI */
+ /* XXX: BDU */
+ /* XXX: ub */
+ /* XXX: raddr_a */
+
+ add_write_dep(state, &state->last_unif, n);
+ return;
+ }
+
+ assert(inst->type == V3D_QPU_INSTR_TYPE_ALU);
+
+ /* XXX: LOAD_IMM */
+
+ if (v3d_qpu_add_op_num_src(inst->alu.add.op) > 0)
+ process_mux_deps(state, n, inst->alu.add.a);
+ if (v3d_qpu_add_op_num_src(inst->alu.add.op) > 1)
+ process_mux_deps(state, n, inst->alu.add.b);
+
+ if (v3d_qpu_mul_op_num_src(inst->alu.mul.op) > 0)
+ process_mux_deps(state, n, inst->alu.mul.a);
+ if (v3d_qpu_mul_op_num_src(inst->alu.mul.op) > 1)
+ process_mux_deps(state, n, inst->alu.mul.b);
+
+ switch (inst->alu.add.op) {
+ case V3D_QPU_A_VPMSETUP:
+ /* Could distinguish read/write by unpacking the uniform. */
+ add_write_dep(state, &state->last_vpm, n);
+ add_write_dep(state, &state->last_vpm_read, n);
+ break;
+
+ case V3D_QPU_A_STVPMV:
+ case V3D_QPU_A_STVPMD:
+ case V3D_QPU_A_STVPMP:
+ add_write_dep(state, &state->last_vpm, n);
+ break;
+
+ case V3D_QPU_A_MSF:
+ add_read_dep(state, state->last_tlb, n);
+ break;
+
+ case V3D_QPU_A_SETMSF:
+ case V3D_QPU_A_SETREVF:
+ add_write_dep(state, &state->last_tlb, n);
+ break;
+
+ case V3D_QPU_A_FLAPUSH:
+ case V3D_QPU_A_FLBPUSH:
+ case V3D_QPU_A_VFLA:
+ case V3D_QPU_A_VFLNA:
+ case V3D_QPU_A_VFLB:
+ case V3D_QPU_A_VFLNB:
+ add_read_dep(state, state->last_sf, n);
+ break;
+
+ case V3D_QPU_A_FLBPOP:
+ add_write_dep(state, &state->last_sf, n);
+ break;
+
+ default:
+ break;
+ }
+
+ switch (inst->alu.mul.op) {
+ case V3D_QPU_M_MULTOP:
+ case V3D_QPU_M_UMUL24:
+ /* MULTOP sets rtop, and UMUL24 implicitly reads rtop and
+ * resets it to 0. We could possibly reorder umul24s relative
+ * to each other, but for now just keep all the MUL parts in
+ * order.
+ */
+ add_write_dep(state, &state->last_rtop, n);
+ break;
+ default:
+ break;
+ }
+
+ if (inst->alu.add.op != V3D_QPU_A_NOP) {
+ process_waddr_deps(state, n, inst->alu.add.waddr,
+ inst->alu.add.magic_write);
+ }
+ if (inst->alu.mul.op != V3D_QPU_M_NOP) {
+ process_waddr_deps(state, n, inst->alu.mul.waddr,
+ inst->alu.mul.magic_write);
+ }
+
+ if (v3d_qpu_writes_r3(inst))
+ add_write_dep(state, &state->last_r[3], n);
+ if (v3d_qpu_writes_r4(inst))
+ add_write_dep(state, &state->last_r[4], n);
+ if (v3d_qpu_writes_r5(inst))
+ add_write_dep(state, &state->last_r[5], n);
+
+ if (inst->sig.thrsw) {
+ /* All accumulator contents and flags are undefined after the
+ * switch.
+ */
+ for (int i = 0; i < ARRAY_SIZE(state->last_r); i++)
+ add_write_dep(state, &state->last_r[i], n);
+ add_write_dep(state, &state->last_sf, n);
+
+ /* Scoreboard-locking operations have to stay after the last
+ * thread switch.
+ */
+ add_write_dep(state, &state->last_tlb, n);
+
+ add_write_dep(state, &state->last_tmu_write, n);
+ }
+
+ if (inst->sig.ldtmu) {
+ /* TMU loads are coming from a FIFO, so ordering is important.
+ */
+ add_write_dep(state, &state->last_tmu_write, n);
+ }
+
+ if (inst->sig.ldtlb | inst->sig.ldtlbu)
+ add_read_dep(state, state->last_tlb, n);
+
+ if (inst->sig.ldvpm)
+ add_write_dep(state, &state->last_vpm_read, n);
+
+ /* inst->sig.ldunif or sideband uniform read */
+ if (qinst->uniform != ~0)
+ add_write_dep(state, &state->last_unif, n);
+
+ process_cond_deps(state, n, inst->flags.ac);
+ process_cond_deps(state, n, inst->flags.mc);
+ process_pf_deps(state, n, inst->flags.apf);
+ process_pf_deps(state, n, inst->flags.mpf);
+ process_uf_deps(state, n, inst->flags.auf);
+ process_uf_deps(state, n, inst->flags.muf);
+}
+
+static void
+calculate_forward_deps(struct v3d_compile *c, struct list_head *schedule_list)
+{
+ struct schedule_state state;
+
+ memset(&state, 0, sizeof(state));
+ state.dir = F;
+
+ list_for_each_entry(struct schedule_node, node, schedule_list, link)
+ calculate_deps(&state, node);
+}
+
+static void
+calculate_reverse_deps(struct v3d_compile *c, struct list_head *schedule_list)
+{
+ struct list_head *node;
+ struct schedule_state state;
+
+ memset(&state, 0, sizeof(state));
+ state.dir = R;
+
+ for (node = schedule_list->prev; schedule_list != node; node = node->prev) {
+ calculate_deps(&state, (struct schedule_node *)node);
+ }
+}
+
+struct choose_scoreboard {
+ int tick;
+ int last_sfu_write_tick;
+ int last_ldvary_tick;
+ int last_uniforms_reset_tick;
+ uint32_t last_waddr_add, last_waddr_mul;
+ bool tlb_locked;
+};
+
+static bool
+mux_reads_too_soon(struct choose_scoreboard *scoreboard,
+ const struct v3d_qpu_instr *inst, enum v3d_qpu_mux mux)
+{
+ switch (mux) {
+ case V3D_QPU_MUX_A:
+ if (scoreboard->last_waddr_add == inst->raddr_a ||
+ scoreboard->last_waddr_mul == inst->raddr_a) {
+ return true;
+ }
+ break;
+
+ case V3D_QPU_MUX_B:
+ if (scoreboard->last_waddr_add == inst->raddr_b ||
+ scoreboard->last_waddr_mul == inst->raddr_b) {
+ return true;
+ }
+ break;
+
+ case V3D_QPU_MUX_R4:
+ if (scoreboard->tick - scoreboard->last_sfu_write_tick <= 2)
+ return true;
+ break;
+
+ case V3D_QPU_MUX_R5:
+ if (scoreboard->tick - scoreboard->last_ldvary_tick <= 1)
+ return true;
+ break;
+ default:
+ break;
+ }
+
+ return false;
+}
+
+static bool
+reads_too_soon_after_write(struct choose_scoreboard *scoreboard,
+ struct qinst *qinst)
+{
+ const struct v3d_qpu_instr *inst = &qinst->qpu;
+
+ /* XXX: Branching off of raddr. */
+ if (inst->type == V3D_QPU_INSTR_TYPE_BRANCH)
+ return false;
+
+ assert(inst->type == V3D_QPU_INSTR_TYPE_ALU);
+
+ if (inst->alu.add.op != V3D_QPU_A_NOP) {
+ if (v3d_qpu_add_op_num_src(inst->alu.add.op) > 0 &&
+ mux_reads_too_soon(scoreboard, inst, inst->alu.add.a)) {
+ return true;
+ }
+ if (v3d_qpu_add_op_num_src(inst->alu.add.op) > 1 &&
+ mux_reads_too_soon(scoreboard, inst, inst->alu.add.b)) {
+ return true;
+ }
+ }
+
+ if (inst->alu.mul.op != V3D_QPU_M_NOP) {
+ if (v3d_qpu_mul_op_num_src(inst->alu.mul.op) > 0 &&
+ mux_reads_too_soon(scoreboard, inst, inst->alu.mul.a)) {
+ return true;
+ }
+ if (v3d_qpu_mul_op_num_src(inst->alu.mul.op) > 1 &&
+ mux_reads_too_soon(scoreboard, inst, inst->alu.mul.b)) {
+ return true;
+ }
+ }
+
+ /* XXX: imm */
+
+ return false;
+}
+
+static bool
+writes_too_soon_after_write(struct choose_scoreboard *scoreboard,
+ struct qinst *qinst)
+{
+ const struct v3d_qpu_instr *inst = &qinst->qpu;
+
+ /* Don't schedule any other r4 write too soon after an SFU write.
+ * This would normally be prevented by dependency tracking, but might
+ * occur if a dead SFU computation makes it to scheduling.
+ */
+ if (scoreboard->tick - scoreboard->last_sfu_write_tick < 2 &&
+ v3d_qpu_writes_r4(inst))
+ return true;
+
+ return false;
+}
+
+static bool
+pixel_scoreboard_too_soon(struct choose_scoreboard *scoreboard,
+ const struct v3d_qpu_instr *inst)
+{
+ return (scoreboard->tick == 0 && qpu_inst_is_tlb(inst));
+}
+
+static int
+get_instruction_priority(const struct v3d_qpu_instr *inst)
+{
+ uint32_t baseline_score;
+ uint32_t next_score = 0;
+
+ /* Schedule TLB operations as late as possible, to get more
+ * parallelism between shaders.
+ */
+ if (qpu_inst_is_tlb(inst))
+ return next_score;
+ next_score++;
+
+ /* Schedule texture read results collection late to hide latency. */
+ if (inst->sig.ldtmu)
+ return next_score;
+ next_score++;
+
+ /* Default score for things that aren't otherwise special. */
+ baseline_score = next_score;
+ next_score++;
+
+ /* Schedule texture read setup early to hide their latency better. */
+ if (inst->type == V3D_QPU_INSTR_TYPE_ALU &&
+ ((inst->alu.add.magic_write &&
+ v3d_qpu_magic_waddr_is_tmu(inst->alu.add.waddr)) ||
+ (inst->alu.mul.magic_write &&
+ v3d_qpu_magic_waddr_is_tmu(inst->alu.mul.waddr)))) {
+ return next_score;
+ }
+ next_score++;
+
+ return baseline_score;
+}
+
+static bool
+qpu_magic_waddr_is_periph(enum v3d_qpu_waddr waddr)
+{
+ return (v3d_qpu_magic_waddr_is_tmu(waddr) ||
+ v3d_qpu_magic_waddr_is_sfu(waddr) ||
+ v3d_qpu_magic_waddr_is_tlb(waddr) ||
+ v3d_qpu_magic_waddr_is_vpm(waddr) ||
+ v3d_qpu_magic_waddr_is_tsy(waddr));
+}
+
+static bool
+qpu_accesses_peripheral(const struct v3d_qpu_instr *inst)
+{
+ if (inst->type == V3D_QPU_INSTR_TYPE_ALU) {
+ if (inst->alu.add.op != V3D_QPU_A_NOP &&
+ inst->alu.add.magic_write &&
+ qpu_magic_waddr_is_periph(inst->alu.add.waddr)) {
+ return true;
+ }
+
+ if (inst->alu.add.op == V3D_QPU_A_VPMSETUP)
+ return true;
+
+ if (inst->alu.mul.op != V3D_QPU_M_NOP &&
+ inst->alu.mul.magic_write &&
+ qpu_magic_waddr_is_periph(inst->alu.mul.waddr)) {
+ return true;
+ }
+ }
+
+ return (inst->sig.ldvpm ||
+ inst->sig.ldtmu ||
+ inst->sig.ldtlb ||
+ inst->sig.ldtlbu);
+}
+
+static bool
+qpu_merge_inst(const struct v3d_device_info *devinfo,
+ struct v3d_qpu_instr *result,
+ const struct v3d_qpu_instr *a,
+ const struct v3d_qpu_instr *b)
+{
+ if (a->type != V3D_QPU_INSTR_TYPE_ALU ||
+ b->type != V3D_QPU_INSTR_TYPE_ALU) {
+ return false;
+ }
+
+ /* Can't do more than one peripheral access in an instruction. */
+ if (qpu_accesses_peripheral(a) && qpu_accesses_peripheral(b))
+ return false;
+
+ struct v3d_qpu_instr merge = *a;
+
+ if (b->alu.add.op != V3D_QPU_A_NOP) {
+ if (a->alu.add.op != V3D_QPU_A_NOP)
+ return false;
+ merge.alu.add = b->alu.add;
+
+ merge.flags.ac = b->flags.ac;
+ merge.flags.apf = b->flags.apf;
+ merge.flags.auf = b->flags.auf;
+ }
+
+ if (b->alu.mul.op != V3D_QPU_M_NOP) {
+ if (a->alu.mul.op != V3D_QPU_M_NOP)
+ return false;
+ merge.alu.mul = b->alu.mul;
+
+ merge.flags.mc = b->flags.mc;
+ merge.flags.mpf = b->flags.mpf;
+ merge.flags.muf = b->flags.muf;
+ }
+
+ if (v3d_qpu_uses_mux(b, V3D_QPU_MUX_A)) {
+ if (v3d_qpu_uses_mux(a, V3D_QPU_MUX_A) &&
+ a->raddr_a != b->raddr_a) {
+ return false;
+ }
+ merge.raddr_a = b->raddr_a;
+ }
+
+ if (v3d_qpu_uses_mux(b, V3D_QPU_MUX_B)) {
+ if (v3d_qpu_uses_mux(a, V3D_QPU_MUX_B) &&
+ a->raddr_b != b->raddr_b) {
+ return false;
+ }
+ merge.raddr_b = b->raddr_b;
+ }
+
+ merge.sig.thrsw |= b->sig.thrsw;
+ merge.sig.ldunif |= b->sig.ldunif;
+ merge.sig.ldtmu |= b->sig.ldtmu;
+ merge.sig.ldvary |= b->sig.ldvary;
+ merge.sig.ldvpm |= b->sig.ldvpm;
+ merge.sig.small_imm |= b->sig.small_imm;
+ merge.sig.ldtlb |= b->sig.ldtlb;
+ merge.sig.ldtlbu |= b->sig.ldtlbu;
+ merge.sig.ucb |= b->sig.ucb;
+ merge.sig.rotate |= b->sig.rotate;
+ merge.sig.wrtmuc |= b->sig.wrtmuc;
+
+ uint64_t packed;
+ bool ok = v3d_qpu_instr_pack(devinfo, &merge, &packed);
+
+ *result = merge;
+ /* No modifying the real instructions on failure. */
+ assert(ok || (a != result && b != result));
+
+ return ok;
+}
+
+static struct schedule_node *
+choose_instruction_to_schedule(const struct v3d_device_info *devinfo,
+ struct choose_scoreboard *scoreboard,
+ struct list_head *schedule_list,
+ struct schedule_node *prev_inst)
+{
+ struct schedule_node *chosen = NULL;
+ int chosen_prio = 0;
+
+ /* Don't pair up anything with a thread switch signal -- emit_thrsw()
+ * will handle pairing it along with filling the delay slots.
+ */
+ if (prev_inst) {
+ if (prev_inst->inst->qpu.sig.thrsw)
+ return NULL;
+ }
+
+ list_for_each_entry(struct schedule_node, n, schedule_list, link) {
+ const struct v3d_qpu_instr *inst = &n->inst->qpu;
+
+ /* Don't choose the branch instruction until it's the last one
+ * left. We'll move it up to fit its delay slots after we
+ * choose it.
+ */
+ if (inst->type == V3D_QPU_INSTR_TYPE_BRANCH &&
+ !list_is_singular(schedule_list)) {
+ continue;
+ }
+
+ /* "An instruction must not read from a location in physical
+ * regfile A or B that was written to by the previous
+ * instruction."
+ */
+ if (reads_too_soon_after_write(scoreboard, n->inst))
+ continue;
+
+ if (writes_too_soon_after_write(scoreboard, n->inst))
+ continue;
+
+ /* "A scoreboard wait must not occur in the first two
+ * instructions of a fragment shader. This is either the
+ * explicit Wait for Scoreboard signal or an implicit wait
+ * with the first tile-buffer read or write instruction."
+ */
+ if (pixel_scoreboard_too_soon(scoreboard, inst))
+ continue;
+
+ /* ldunif and ldvary both write r5, but ldunif does so a tick
+ * sooner. If the ldvary's r5 wasn't used, then ldunif might
+ * otherwise get scheduled so ldunif and ldvary try to update
+ * r5 in the same tick.
+ */
+ if (inst->sig.ldunif &&
+ scoreboard->tick == scoreboard->last_ldvary_tick + 1) {
+ continue;
+ }
+
+ /* If we're trying to pair with another instruction, check
+ * that they're compatible.
+ */
+ if (prev_inst) {
+ /* Don't pair up a thread switch signal -- we'll
+ * handle pairing it when we pick it on its own.
+ */
+ if (inst->sig.thrsw)
+ continue;
+
+ if (prev_inst->inst->uniform != -1 &&
+ n->inst->uniform != -1)
+ continue;
+
+ /* Don't merge in something that will lock the TLB.
+ * Hopwefully what we have in inst will release some
+ * other instructions, allowing us to delay the
+ * TLB-locking instruction until later.
+ */
+ if (!scoreboard->tlb_locked && qpu_inst_is_tlb(inst))
+ continue;
+
+ struct v3d_qpu_instr merged_inst;
+ if (!qpu_merge_inst(devinfo, &merged_inst,
+ &prev_inst->inst->qpu, inst)) {
+ continue;
+ }
+ }
+
+ int prio = get_instruction_priority(inst);
+
+ /* Found a valid instruction. If nothing better comes along,
+ * this one works.
+ */
+ if (!chosen) {
+ chosen = n;
+ chosen_prio = prio;
+ continue;
+ }
+
+ if (prio > chosen_prio) {
+ chosen = n;
+ chosen_prio = prio;
+ } else if (prio < chosen_prio) {
+ continue;
+ }
+
+ if (n->delay > chosen->delay) {
+ chosen = n;
+ chosen_prio = prio;
+ } else if (n->delay < chosen->delay) {
+ continue;
+ }
+ }
+
+ return chosen;
+}
+
+static void
+update_scoreboard_for_magic_waddr(struct choose_scoreboard *scoreboard,
+ enum v3d_qpu_waddr waddr)
+{
+ if (v3d_qpu_magic_waddr_is_sfu(waddr))
+ scoreboard->last_sfu_write_tick = scoreboard->tick;
+}
+
+static void
+update_scoreboard_for_chosen(struct choose_scoreboard *scoreboard,
+ const struct v3d_qpu_instr *inst)
+{
+ scoreboard->last_waddr_add = ~0;
+ scoreboard->last_waddr_mul = ~0;
+
+ if (inst->type == V3D_QPU_INSTR_TYPE_BRANCH)
+ return;
+
+ assert(inst->type == V3D_QPU_INSTR_TYPE_ALU);
+
+ if (inst->alu.add.op != V3D_QPU_A_NOP) {
+ if (inst->alu.add.magic_write) {
+ update_scoreboard_for_magic_waddr(scoreboard,
+ inst->alu.add.waddr);
+ } else {
+ scoreboard->last_waddr_add = inst->alu.add.waddr;
+ }
+ }
+
+ if (inst->alu.mul.op != V3D_QPU_M_NOP) {
+ if (inst->alu.mul.magic_write) {
+ update_scoreboard_for_magic_waddr(scoreboard,
+ inst->alu.mul.waddr);
+ } else {
+ scoreboard->last_waddr_mul = inst->alu.mul.waddr;
+ }
+ }
+
+ if (inst->sig.ldvary)
+ scoreboard->last_ldvary_tick = scoreboard->tick;
+
+ if (qpu_inst_is_tlb(inst))
+ scoreboard->tlb_locked = true;
+}
+
+static void
+dump_state(const struct v3d_device_info *devinfo,
+ struct list_head *schedule_list)
+{
+ list_for_each_entry(struct schedule_node, n, schedule_list, link) {
+ fprintf(stderr, " t=%4d: ", n->unblocked_time);
+ v3d_qpu_dump(devinfo, &n->inst->qpu);
+ fprintf(stderr, "\n");
+
+ for (int i = 0; i < n->child_count; i++) {
+ struct schedule_node *child = n->children[i].node;
+ if (!child)
+ continue;
+
+ fprintf(stderr, " - ");
+ v3d_qpu_dump(devinfo, &child->inst->qpu);
+ fprintf(stderr, " (%d parents, %c)\n",
+ child->parent_count,
+ n->children[i].write_after_read ? 'w' : 'r');
+ }
+ }
+}
+
+static uint32_t magic_waddr_latency(enum v3d_qpu_waddr waddr,
+ const struct v3d_qpu_instr *after)
+{
+ /* Apply some huge latency between texture fetch requests and getting
+ * their results back.
+ *
+ * FIXME: This is actually pretty bogus. If we do:
+ *
+ * mov tmu0_s, a
+ * <a bit of math>
+ * mov tmu0_s, b
+ * load_tmu0
+ * <more math>
+ * load_tmu0
+ *
+ * we count that as worse than
+ *
+ * mov tmu0_s, a
+ * mov tmu0_s, b
+ * <lots of math>
+ * load_tmu0
+ * <more math>
+ * load_tmu0
+ *
+ * because we associate the first load_tmu0 with the *second* tmu0_s.
+ */
+ if (v3d_qpu_magic_waddr_is_tmu(waddr) && after->sig.ldtmu)
+ return 100;
+
+ /* Assume that anything depending on us is consuming the SFU result. */
+ if (v3d_qpu_magic_waddr_is_sfu(waddr))
+ return 3;
+
+ return 1;
+}
+
+static uint32_t
+instruction_latency(struct schedule_node *before, struct schedule_node *after)
+{
+ const struct v3d_qpu_instr *before_inst = &before->inst->qpu;
+ const struct v3d_qpu_instr *after_inst = &after->inst->qpu;
+ uint32_t latency = 1;
+
+ if (before_inst->type != V3D_QPU_INSTR_TYPE_ALU ||
+ after_inst->type != V3D_QPU_INSTR_TYPE_ALU)
+ return latency;
+
+ if (before_inst->alu.add.magic_write) {
+ latency = MAX2(latency,
+ magic_waddr_latency(before_inst->alu.add.waddr,
+ after_inst));
+ }
+
+ if (before_inst->alu.mul.magic_write) {
+ latency = MAX2(latency,
+ magic_waddr_latency(before_inst->alu.mul.waddr,
+ after_inst));
+ }
+
+ return latency;
+}
+
+/** Recursive computation of the delay member of a node. */
+static void
+compute_delay(struct schedule_node *n)
+{
+ if (!n->child_count) {
+ n->delay = 1;
+ } else {
+ for (int i = 0; i < n->child_count; i++) {
+ if (!n->children[i].node->delay)
+ compute_delay(n->children[i].node);
+ n->delay = MAX2(n->delay,
+ n->children[i].node->delay +
+ instruction_latency(n, n->children[i].node));
+ }
+ }
+}
+
+static void
+mark_instruction_scheduled(struct list_head *schedule_list,
+ uint32_t time,
+ struct schedule_node *node,
+ bool war_only)
+{
+ if (!node)
+ return;
+
+ for (int i = node->child_count - 1; i >= 0; i--) {
+ struct schedule_node *child =
+ node->children[i].node;
+
+ if (!child)
+ continue;
+
+ if (war_only && !node->children[i].write_after_read)
+ continue;
+
+ /* If the requirement is only that the node not appear before
+ * the last read of its destination, then it can be scheduled
+ * immediately after (or paired with!) the thing reading the
+ * destination.
+ */
+ uint32_t latency = 0;
+ if (!war_only) {
+ latency = instruction_latency(node,
+ node->children[i].node);
+ }
+
+ child->unblocked_time = MAX2(child->unblocked_time,
+ time + latency);
+ child->parent_count--;
+ if (child->parent_count == 0)
+ list_add(&child->link, schedule_list);
+
+ node->children[i].node = NULL;
+ }
+}
+
+static struct qinst *
+vir_nop()
+{
+ struct qreg undef = { QFILE_NULL, 0 };
+ struct qinst *qinst = vir_add_inst(V3D_QPU_A_NOP, undef, undef, undef);
+
+ return qinst;
+}
+
+#if 0
+static struct qinst *
+nop_after(struct qinst *inst)
+{
+ struct qinst *q = vir_nop();
+
+ list_add(&q->link, &inst->link);
+
+ return q;
+}
+
+/**
+ * Emits a THRSW/LTHRSW signal in the stream, trying to move it up to pair
+ * with another instruction.
+ */
+static void
+emit_thrsw(struct v3d_compile *c,
+ struct choose_scoreboard *scoreboard,
+ const struct v3d_qpu_instr *inst)
+{
+ /* There should be nothing in a thrsw inst being scheduled other than
+ * the signal bits.
+ */
+ assert(inst->type == V3D_QPU_INSTR_TYPE_ALU);
+ assert(inst->alu.add.op == V3D_QPU_A_NOP);
+ assert(inst->alu.mul.op == V3D_QPU_M_NOP);
+
+ /* Try to find an earlier scheduled instruction that we can merge the
+ * thrsw into.
+ */
+ int thrsw_ip = c->qpu_inst_count;
+ for (int i = 1; i <= MIN2(c->qpu_inst_count, 3); i++) {
+ uint64_t prev_instr = c->qpu_insts[c->qpu_inst_count - i];
+ uint32_t prev_sig = QPU_GET_FIELD(prev_instr, QPU_SIG);
+
+ if (prev_sig == QPU_SIG_NONE)
+ thrsw_ip = c->qpu_inst_count - i;
+ }
+
+ if (thrsw_ip != c->qpu_inst_count) {
+ /* Merge the thrsw into the existing instruction. */
+ c->qpu_insts[thrsw_ip] =
+ QPU_UPDATE_FIELD(c->qpu_insts[thrsw_ip], sig, QPU_SIG);
+ } else {
+ qpu_serialize_one_inst(c, inst);
+ update_scoreboard_for_chosen(scoreboard, inst);
+ }
+
+ /* Fill the delay slots. */
+ while (c->qpu_inst_count < thrsw_ip + 3) {
+ update_scoreboard_for_chosen(scoreboard, v3d_qpu_nop());
+ qpu_serialize_one_inst(c, v3d_qpu_nop());
+ }
+}
+#endif
+
+static uint32_t
+schedule_instructions(struct v3d_compile *c,
+ struct choose_scoreboard *scoreboard,
+ struct qblock *block,
+ struct list_head *schedule_list,
+ enum quniform_contents *orig_uniform_contents,
+ uint32_t *orig_uniform_data,
+ uint32_t *next_uniform)
+{
+ const struct v3d_device_info *devinfo = c->devinfo;
+ uint32_t time = 0;
+
+ if (debug) {
+ fprintf(stderr, "initial deps:\n");
+ dump_state(devinfo, schedule_list);
+ fprintf(stderr, "\n");
+ }
+
+ /* Remove non-DAG heads from the list. */
+ list_for_each_entry_safe(struct schedule_node, n, schedule_list, link) {
+ if (n->parent_count != 0)
+ list_del(&n->link);
+ }
+
+ while (!list_empty(schedule_list)) {
+ struct schedule_node *chosen =
+ choose_instruction_to_schedule(devinfo,
+ scoreboard,
+ schedule_list,
+ NULL);
+ struct schedule_node *merge = NULL;
+
+ /* If there are no valid instructions to schedule, drop a NOP
+ * in.
+ */
+ struct qinst *qinst = chosen ? chosen->inst : vir_nop();
+ struct v3d_qpu_instr *inst = &qinst->qpu;
+
+ if (debug) {
+ fprintf(stderr, "t=%4d: current list:\n",
+ time);
+ dump_state(devinfo, schedule_list);
+ fprintf(stderr, "t=%4d: chose: ", time);
+ v3d_qpu_dump(devinfo, inst);
+ fprintf(stderr, "\n");
+ }
+
+ /* Schedule this instruction onto the QPU list. Also try to
+ * find an instruction to pair with it.
+ */
+ if (chosen) {
+ time = MAX2(chosen->unblocked_time, time);
+ list_del(&chosen->link);
+ mark_instruction_scheduled(schedule_list, time,
+ chosen, true);
+
+ merge = choose_instruction_to_schedule(devinfo,
+ scoreboard,
+ schedule_list,
+ chosen);
+ if (merge) {
+ time = MAX2(merge->unblocked_time, time);
+ list_del(&merge->link);
+ (void)qpu_merge_inst(devinfo, inst,
+ inst, &merge->inst->qpu);
+ if (merge->inst->uniform != -1) {
+ chosen->inst->uniform =
+ merge->inst->uniform;
+ }
+
+ if (debug) {
+ fprintf(stderr, "t=%4d: merging: ",
+ time);
+ v3d_qpu_dump(devinfo, &merge->inst->qpu);
+ fprintf(stderr, "\n");
+ fprintf(stderr, " result: ");
+ v3d_qpu_dump(devinfo, inst);
+ fprintf(stderr, "\n");
+ }
+ }
+ }
+
+ /* Update the uniform index for the rewritten location --
+ * branch target updating will still need to change
+ * c->uniform_data[] using this index.
+ */
+ if (qinst->uniform != -1) {
+ if (inst->type == V3D_QPU_INSTR_TYPE_BRANCH)
+ block->branch_uniform = *next_uniform;
+
+ c->uniform_data[*next_uniform] =
+ orig_uniform_data[qinst->uniform];
+ c->uniform_contents[*next_uniform] =
+ orig_uniform_contents[qinst->uniform];
+ qinst->uniform = *next_uniform;
+ (*next_uniform)++;
+ }
+
+ if (debug) {
+ fprintf(stderr, "\n");
+ }
+
+ /* Now that we've scheduled a new instruction, some of its
+ * children can be promoted to the list of instructions ready to
+ * be scheduled. Update the children's unblocked time for this
+ * DAG edge as we do so.
+ */
+ mark_instruction_scheduled(schedule_list, time, chosen, false);
+
+ if (merge) {
+ mark_instruction_scheduled(schedule_list, time, merge,
+ false);
+
+ /* The merged VIR instruction doesn't get re-added to the
+ * block, so free it now.
+ */
+ free(merge->inst);
+ }
+
+ if (0 && inst->sig.thrsw) {
+ /* XXX emit_thrsw(c, scoreboard, qinst); */
+ } else {
+ c->qpu_inst_count++;
+ list_addtail(&qinst->link, &block->instructions);
+ update_scoreboard_for_chosen(scoreboard, inst);
+ }
+
+ scoreboard->tick++;
+ time++;
+
+ if (inst->type == V3D_QPU_INSTR_TYPE_BRANCH ||
+ inst->sig.thrsw /* XXX */) {
+ block->branch_qpu_ip = c->qpu_inst_count - 1;
+ /* Fill the delay slots.
+ *
+ * We should fill these with actual instructions,
+ * instead, but that will probably need to be done
+ * after this, once we know what the leading
+ * instructions of the successors are (so we can
+ * handle A/B register file write latency)
+ */
+ /* XXX: scoreboard */
+ int slots = (inst->type == V3D_QPU_INSTR_TYPE_BRANCH ?
+ 3 : 2);
+ for (int i = 0; i < slots; i++) {
+ struct qinst *nop = vir_nop();
+ list_addtail(&nop->link, &block->instructions);
+
+ update_scoreboard_for_chosen(scoreboard,
+ &nop->qpu);
+ c->qpu_inst_count++;
+ scoreboard->tick++;
+ time++;
+ }
+ }
+ }
+
+ return time;
+}
+
+static uint32_t
+qpu_schedule_instructions_block(struct v3d_compile *c,
+ struct choose_scoreboard *scoreboard,
+ struct qblock *block,
+ enum quniform_contents *orig_uniform_contents,
+ uint32_t *orig_uniform_data,
+ uint32_t *next_uniform)
+{
+ void *mem_ctx = ralloc_context(NULL);
+ struct list_head schedule_list;
+
+ list_inithead(&schedule_list);
+
+ /* Wrap each instruction in a scheduler structure. */
+ while (!list_empty(&block->instructions)) {
+ struct qinst *qinst = (struct qinst *)block->instructions.next;
+ struct schedule_node *n =
+ rzalloc(mem_ctx, struct schedule_node);
+
+ n->inst = qinst;
+
+ list_del(&qinst->link);
+ list_addtail(&n->link, &schedule_list);
+ }
+
+ calculate_forward_deps(c, &schedule_list);
+ calculate_reverse_deps(c, &schedule_list);
+
+ list_for_each_entry(struct schedule_node, n, &schedule_list, link) {
+ compute_delay(n);
+ }
+
+ uint32_t cycles = schedule_instructions(c, scoreboard, block,
+ &schedule_list,
+ orig_uniform_contents,
+ orig_uniform_data,
+ next_uniform);
+
+ ralloc_free(mem_ctx);
+
+ return cycles;
+}
+
+static void
+qpu_set_branch_targets(struct v3d_compile *c)
+{
+ vir_for_each_block(block, c) {
+ /* The end block of the program has no branch. */
+ if (!block->successors[0])
+ continue;
+
+ /* If there was no branch instruction, then the successor
+ * block must follow immediately after this one.
+ */
+ if (block->branch_qpu_ip == ~0) {
+ assert(block->end_qpu_ip + 1 ==
+ block->successors[0]->start_qpu_ip);
+ continue;
+ }
+
+ /* Walk back through the delay slots to find the branch
+ * instr.
+ */
+ struct list_head *entry = block->instructions.prev;
+ for (int i = 0; i < 3; i++)
+ entry = entry->prev;
+ struct qinst *branch = container_of(entry, branch, link);
+ assert(branch->qpu.type == V3D_QPU_INSTR_TYPE_BRANCH);
+
+ /* Make sure that the if-we-don't-jump
+ * successor was scheduled just after the
+ * delay slots.
+ */
+ assert(!block->successors[1] ||
+ block->successors[1]->start_qpu_ip ==
+ block->branch_qpu_ip + 4);
+
+ branch->qpu.branch.offset =
+ ((block->successors[0]->start_qpu_ip -
+ (block->branch_qpu_ip + 4)) *
+ sizeof(uint64_t));
+
+ /* Set up the relative offset to jump in the
+ * uniform stream.
+ *
+ * Use a temporary here, because
+ * uniform_data[inst->uniform] may be shared
+ * between multiple instructions.
+ */
+ assert(c->uniform_contents[branch->uniform] == QUNIFORM_CONSTANT);
+ c->uniform_data[branch->uniform] =
+ (block->successors[0]->start_uniform -
+ (block->branch_uniform + 1)) * 4;
+ }
+}
+
+uint32_t
+v3d_qpu_schedule_instructions(struct v3d_compile *c)
+{
+ const struct v3d_device_info *devinfo = c->devinfo;
+
+ /* We reorder the uniforms as we schedule instructions, so save the
+ * old data off and replace it.
+ */
+ uint32_t *uniform_data = c->uniform_data;
+ enum quniform_contents *uniform_contents = c->uniform_contents;
+ c->uniform_contents = ralloc_array(c, enum quniform_contents,
+ c->num_uniforms);
+ c->uniform_data = ralloc_array(c, uint32_t, c->num_uniforms);
+ c->uniform_array_size = c->num_uniforms;
+ uint32_t next_uniform = 0;
+
+ struct choose_scoreboard scoreboard;
+ memset(&scoreboard, 0, sizeof(scoreboard));
+ scoreboard.last_waddr_add = ~0;
+ scoreboard.last_waddr_mul = ~0;
+ scoreboard.last_ldvary_tick = -10;
+ scoreboard.last_sfu_write_tick = -10;
+ scoreboard.last_uniforms_reset_tick = -10;
+
+ if (debug) {
+ fprintf(stderr, "Pre-schedule instructions\n");
+ vir_for_each_block(block, c) {
+ fprintf(stderr, "BLOCK %d\n", block->index);
+ list_for_each_entry(struct qinst, qinst,
+ &block->instructions, link) {
+ v3d_qpu_dump(devinfo, &qinst->qpu);
+ fprintf(stderr, "\n");
+ }
+ }
+ fprintf(stderr, "\n");
+ }
+
+ uint32_t cycles = 0;
+ vir_for_each_block(block, c) {
+ block->start_qpu_ip = c->qpu_inst_count;
+ block->branch_qpu_ip = ~0;
+ block->start_uniform = next_uniform;
+
+ cycles += qpu_schedule_instructions_block(c,
+ &scoreboard,
+ block,
+ uniform_contents,
+ uniform_data,
+ &next_uniform);
+
+ block->end_qpu_ip = c->qpu_inst_count - 1;
+ }
+
+ qpu_set_branch_targets(c);
+
+ assert(next_uniform == c->num_uniforms);
+
+ return cycles;
+}
diff --git a/lib/mesa/src/broadcom/compiler/qpu_validate.c b/lib/mesa/src/broadcom/compiler/qpu_validate.c
new file mode 100644
index 000000000..d99d76a8b
--- /dev/null
+++ b/lib/mesa/src/broadcom/compiler/qpu_validate.c
@@ -0,0 +1,208 @@
+/*
+ * Copyright © 2014 Broadcom
+ *
+ * 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.
+ */
+
+/**
+ * @file
+ *
+ * Validates the QPU instruction sequence after register allocation and
+ * scheduling.
+ */
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "v3d_compiler.h"
+#include "qpu/qpu_disasm.h"
+
+struct v3d_qpu_validate_state {
+ struct v3d_compile *c;
+ const struct v3d_qpu_instr *last;
+ int ip;
+ int last_sfu_write;
+};
+
+static void
+fail_instr(struct v3d_qpu_validate_state *state, const char *msg)
+{
+ struct v3d_compile *c = state->c;
+
+ fprintf(stderr, "v3d_qpu_validate at ip %d: %s:\n", state->ip, msg);
+
+ int dump_ip = 0;
+ vir_for_each_inst_inorder(inst, c) {
+ v3d_qpu_dump(c->devinfo, &inst->qpu);
+
+ if (dump_ip++ == state->ip)
+ fprintf(stderr, " *** ERROR ***");
+
+ fprintf(stderr, "\n");
+ }
+
+ fprintf(stderr, "\n");
+ abort();
+}
+
+static bool
+qpu_magic_waddr_matches(const struct v3d_qpu_instr *inst,
+ bool (*predicate)(enum v3d_qpu_waddr waddr))
+{
+ if (inst->type == V3D_QPU_INSTR_TYPE_ALU)
+ return false;
+
+ if (inst->alu.add.op != V3D_QPU_A_NOP &&
+ inst->alu.add.magic_write &&
+ predicate(inst->alu.add.waddr))
+ return true;
+
+ if (inst->alu.mul.op != V3D_QPU_M_NOP &&
+ inst->alu.mul.magic_write &&
+ predicate(inst->alu.mul.waddr))
+ return true;
+
+ return false;
+}
+
+static void
+qpu_validate_inst(struct v3d_qpu_validate_state *state, struct qinst *qinst)
+{
+ const struct v3d_qpu_instr *inst = &qinst->qpu;
+
+ if (inst->type != V3D_QPU_INSTR_TYPE_ALU)
+ return;
+
+ /* LDVARY writes r5 two instructions later and LDUNIF writes
+ * r5 one instruction later, which is illegal to have
+ * together.
+ */
+ if (state->last && state->last->sig.ldvary && inst->sig.ldunif) {
+ fail_instr(state, "LDUNIF after a LDVARY");
+ }
+
+ int tmu_writes = 0;
+ int sfu_writes = 0;
+ int vpm_writes = 0;
+ int tlb_writes = 0;
+ int tsy_writes = 0;
+
+ if (inst->alu.add.op != V3D_QPU_A_NOP) {
+ if (inst->alu.add.magic_write) {
+ if (v3d_qpu_magic_waddr_is_tmu(inst->alu.add.waddr))
+ tmu_writes++;
+ if (v3d_qpu_magic_waddr_is_sfu(inst->alu.add.waddr))
+ sfu_writes++;
+ if (v3d_qpu_magic_waddr_is_vpm(inst->alu.add.waddr))
+ vpm_writes++;
+ if (v3d_qpu_magic_waddr_is_tlb(inst->alu.add.waddr))
+ tlb_writes++;
+ if (v3d_qpu_magic_waddr_is_tsy(inst->alu.add.waddr))
+ tsy_writes++;
+ }
+ }
+
+ if (inst->alu.mul.op != V3D_QPU_M_NOP) {
+ if (inst->alu.mul.magic_write) {
+ if (v3d_qpu_magic_waddr_is_tmu(inst->alu.mul.waddr))
+ tmu_writes++;
+ if (v3d_qpu_magic_waddr_is_sfu(inst->alu.mul.waddr))
+ sfu_writes++;
+ if (v3d_qpu_magic_waddr_is_vpm(inst->alu.mul.waddr))
+ vpm_writes++;
+ if (v3d_qpu_magic_waddr_is_tlb(inst->alu.mul.waddr))
+ tlb_writes++;
+ if (v3d_qpu_magic_waddr_is_tsy(inst->alu.mul.waddr))
+ tsy_writes++;
+ }
+ }
+
+ (void)qpu_magic_waddr_matches; /* XXX */
+
+ /* SFU r4 results come back two instructions later. No doing
+ * r4 read/writes or other SFU lookups until it's done.
+ */
+ if (state->ip - state->last_sfu_write < 2) {
+ if (v3d_qpu_uses_mux(inst, V3D_QPU_MUX_R4))
+ fail_instr(state, "R4 read too soon after SFU");
+
+ if (v3d_qpu_writes_r4(inst))
+ fail_instr(state, "R4 write too soon after SFU");
+
+ if (sfu_writes)
+ fail_instr(state, "SFU write too soon after SFU");
+ }
+
+ /* XXX: The docs say VPM can happen with the others, but the simulator
+ * disagrees.
+ */
+ if (tmu_writes +
+ sfu_writes +
+ vpm_writes +
+ tlb_writes +
+ tsy_writes +
+ inst->sig.ldtmu +
+ inst->sig.ldtlb +
+ inst->sig.ldvpm +
+ inst->sig.ldtlbu > 1) {
+ fail_instr(state,
+ "Only one of [TMU, SFU, TSY, TLB read, VPM] allowed");
+ }
+
+ if (sfu_writes)
+ state->last_sfu_write = state->ip;
+}
+
+static void
+qpu_validate_block(struct v3d_qpu_validate_state *state, struct qblock *block)
+{
+ vir_for_each_inst(qinst, block) {
+ qpu_validate_inst(state, qinst);
+
+ state->last = &qinst->qpu;
+ state->ip++;
+ }
+}
+
+/**
+ * Checks for the instruction restrictions from page 37 ("Summary of
+ * Instruction Restrictions").
+ */
+void
+qpu_validate(struct v3d_compile *c)
+{
+ /* We don't want to do validation in release builds, but we want to
+ * keep compiling the validation code to make sure it doesn't get
+ * broken.
+ */
+#ifndef DEBUG
+ return;
+#endif
+
+ struct v3d_qpu_validate_state state = {
+ .c = c,
+ .last_sfu_write = -10,
+ .ip = 0,
+ };
+
+ vir_for_each_block(block, c) {
+ qpu_validate_block(&state, block);
+ }
+}
diff --git a/lib/mesa/src/broadcom/compiler/v3d_compiler.h b/lib/mesa/src/broadcom/compiler/v3d_compiler.h
new file mode 100644
index 000000000..021c88f7b
--- /dev/null
+++ b/lib/mesa/src/broadcom/compiler/v3d_compiler.h
@@ -0,0 +1,934 @@
+/*
+ * Copyright © 2016 Broadcom
+ *
+ * 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.
+ */
+
+#ifndef V3D_COMPILER_H
+#define V3D_COMPILER_H
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <string.h>
+
+#include "util/macros.h"
+#include "common/v3d_debug.h"
+#include "compiler/nir/nir.h"
+#include "util/list.h"
+#include "util/u_math.h"
+
+#include "qpu/qpu_instr.h"
+#include "pipe/p_state.h"
+
+#define V3D_MAX_TEXTURE_SAMPLERS 32
+#define V3D_MAX_SAMPLES 4
+#define V3D_MAX_FS_INPUTS 64
+#define V3D_MAX_VS_INPUTS 64
+
+struct nir_builder;
+
+struct v3d_fs_inputs {
+ /**
+ * Array of the meanings of the VPM inputs this shader needs.
+ *
+ * It doesn't include those that aren't part of the VPM, like
+ * point/line coordinates.
+ */
+ struct v3d_varying_slot *input_slots;
+ uint32_t num_inputs;
+};
+
+enum qfile {
+ /** An unused source or destination register. */
+ QFILE_NULL,
+
+ /** A physical register, such as the W coordinate payload. */
+ QFILE_REG,
+ /** One of the regsiters for fixed function interactions. */
+ QFILE_MAGIC,
+
+ /**
+ * A virtual register, that will be allocated to actual accumulator
+ * or physical registers later.
+ */
+ QFILE_TEMP,
+ QFILE_VARY,
+ QFILE_UNIF,
+ QFILE_TLB,
+ QFILE_TLBU,
+
+ /**
+ * VPM reads use this with an index value to say what part of the VPM
+ * is being read.
+ */
+ QFILE_VPM,
+
+ /**
+ * Stores an immediate value in the index field that will be used
+ * directly by qpu_load_imm().
+ */
+ QFILE_LOAD_IMM,
+
+ /**
+ * Stores an immediate value in the index field that can be turned
+ * into a small immediate field by qpu_encode_small_immediate().
+ */
+ QFILE_SMALL_IMM,
+};
+
+/**
+ * A reference to a QPU register or a virtual temp register.
+ */
+struct qreg {
+ enum qfile file;
+ uint32_t index;
+};
+
+static inline struct qreg vir_reg(enum qfile file, uint32_t index)
+{
+ return (struct qreg){file, index};
+}
+
+/**
+ * A reference to an actual register at the QPU level, for register
+ * allocation.
+ */
+struct qpu_reg {
+ bool magic;
+ int index;
+};
+
+struct qinst {
+ /** Entry in qblock->instructions */
+ struct list_head link;
+
+ /**
+ * The instruction being wrapped. Its condition codes, pack flags,
+ * signals, etc. will all be used, with just the register references
+ * being replaced by the contents of qinst->dst and qinst->src[].
+ */
+ struct v3d_qpu_instr qpu;
+
+ /* Pre-register-allocation references to src/dst registers */
+ struct qreg dst;
+ struct qreg src[3];
+ bool cond_is_exec_mask;
+ bool has_implicit_uniform;
+
+ /* After vir_to_qpu.c: If instr reads a uniform, which uniform from
+ * the uncompiled stream it is.
+ */
+ int uniform;
+};
+
+enum quniform_contents {
+ /**
+ * Indicates that a constant 32-bit value is copied from the program's
+ * uniform contents.
+ */
+ QUNIFORM_CONSTANT,
+ /**
+ * Indicates that the program's uniform contents are used as an index
+ * into the GL uniform storage.
+ */
+ QUNIFORM_UNIFORM,
+
+ /** @{
+ * Scaling factors from clip coordinates to relative to the viewport
+ * center.
+ *
+ * This is used by the coordinate and vertex shaders to produce the
+ * 32-bit entry consisting of 2 16-bit fields with 12.4 signed fixed
+ * point offsets from the viewport ccenter.
+ */
+ QUNIFORM_VIEWPORT_X_SCALE,
+ QUNIFORM_VIEWPORT_Y_SCALE,
+ /** @} */
+
+ QUNIFORM_VIEWPORT_Z_OFFSET,
+ QUNIFORM_VIEWPORT_Z_SCALE,
+
+ QUNIFORM_USER_CLIP_PLANE,
+
+ /**
+ * A reference to a texture config parameter 0 uniform.
+ *
+ * This is a uniform implicitly loaded with a QPU_W_TMU* write, which
+ * defines texture type, miplevels, and such. It will be found as a
+ * parameter to the first QOP_TEX_[STRB] instruction in a sequence.
+ */
+ QUNIFORM_TEXTURE_CONFIG_P0_0,
+ QUNIFORM_TEXTURE_CONFIG_P0_1,
+ QUNIFORM_TEXTURE_CONFIG_P0_2,
+ QUNIFORM_TEXTURE_CONFIG_P0_3,
+ QUNIFORM_TEXTURE_CONFIG_P0_4,
+ QUNIFORM_TEXTURE_CONFIG_P0_5,
+ QUNIFORM_TEXTURE_CONFIG_P0_6,
+ QUNIFORM_TEXTURE_CONFIG_P0_7,
+ QUNIFORM_TEXTURE_CONFIG_P0_8,
+ QUNIFORM_TEXTURE_CONFIG_P0_9,
+ QUNIFORM_TEXTURE_CONFIG_P0_10,
+ QUNIFORM_TEXTURE_CONFIG_P0_11,
+ QUNIFORM_TEXTURE_CONFIG_P0_12,
+ QUNIFORM_TEXTURE_CONFIG_P0_13,
+ QUNIFORM_TEXTURE_CONFIG_P0_14,
+ QUNIFORM_TEXTURE_CONFIG_P0_15,
+ QUNIFORM_TEXTURE_CONFIG_P0_16,
+ QUNIFORM_TEXTURE_CONFIG_P0_17,
+ QUNIFORM_TEXTURE_CONFIG_P0_18,
+ QUNIFORM_TEXTURE_CONFIG_P0_19,
+ QUNIFORM_TEXTURE_CONFIG_P0_20,
+ QUNIFORM_TEXTURE_CONFIG_P0_21,
+ QUNIFORM_TEXTURE_CONFIG_P0_22,
+ QUNIFORM_TEXTURE_CONFIG_P0_23,
+ QUNIFORM_TEXTURE_CONFIG_P0_24,
+ QUNIFORM_TEXTURE_CONFIG_P0_25,
+ QUNIFORM_TEXTURE_CONFIG_P0_26,
+ QUNIFORM_TEXTURE_CONFIG_P0_27,
+ QUNIFORM_TEXTURE_CONFIG_P0_28,
+ QUNIFORM_TEXTURE_CONFIG_P0_29,
+ QUNIFORM_TEXTURE_CONFIG_P0_30,
+ QUNIFORM_TEXTURE_CONFIG_P0_31,
+ QUNIFORM_TEXTURE_CONFIG_P0_32,
+
+ /**
+ * A reference to a texture config parameter 1 uniform.
+ *
+ * This is a uniform implicitly loaded with a QPU_W_TMU* write, which
+ * defines texture width, height, filters, and wrap modes. It will be
+ * found as a parameter to the second QOP_TEX_[STRB] instruction in a
+ * sequence.
+ */
+ QUNIFORM_TEXTURE_CONFIG_P1,
+
+ QUNIFORM_TEXTURE_FIRST_LEVEL,
+
+ QUNIFORM_TEXTURE_WIDTH,
+ QUNIFORM_TEXTURE_HEIGHT,
+ QUNIFORM_TEXTURE_DEPTH,
+ QUNIFORM_TEXTURE_ARRAY_SIZE,
+ QUNIFORM_TEXTURE_LEVELS,
+
+ QUNIFORM_TEXTURE_MSAA_ADDR,
+
+ QUNIFORM_UBO_ADDR,
+
+ QUNIFORM_TEXRECT_SCALE_X,
+ QUNIFORM_TEXRECT_SCALE_Y,
+
+ QUNIFORM_TEXTURE_BORDER_COLOR,
+
+ QUNIFORM_STENCIL,
+
+ QUNIFORM_ALPHA_REF,
+ QUNIFORM_SAMPLE_MASK,
+};
+
+struct v3d_varying_slot {
+ uint8_t slot_and_component;
+};
+
+static inline struct v3d_varying_slot
+v3d_slot_from_slot_and_component(uint8_t slot, uint8_t component)
+{
+ assert(slot < 255 / 4);
+ return (struct v3d_varying_slot){ (slot << 2) + component };
+}
+
+static inline uint8_t v3d_slot_get_slot(struct v3d_varying_slot slot)
+{
+ return slot.slot_and_component >> 2;
+}
+
+static inline uint8_t v3d_slot_get_component(struct v3d_varying_slot slot)
+{
+ return slot.slot_and_component & 3;
+}
+
+struct v3d_ubo_range {
+ /**
+ * offset in bytes from the start of the ubo where this range is
+ * uploaded.
+ *
+ * Only set once used is set.
+ */
+ uint32_t dst_offset;
+
+ /**
+ * offset in bytes from the start of the gallium uniforms where the
+ * data comes from.
+ */
+ uint32_t src_offset;
+
+ /** size in bytes of this ubo range */
+ uint32_t size;
+};
+
+struct v3d_key {
+ void *shader_state;
+ struct {
+ uint8_t swizzle[4];
+ uint8_t return_size;
+ uint8_t return_channels;
+ union {
+ struct {
+ unsigned compare_mode:1;
+ unsigned compare_func:3;
+ unsigned wrap_s:3;
+ unsigned wrap_t:3;
+ };
+ struct {
+ uint16_t msaa_width, msaa_height;
+ };
+ };
+ } tex[V3D_MAX_TEXTURE_SAMPLERS];
+ uint8_t ucp_enables;
+};
+
+struct v3d_fs_key {
+ struct v3d_key base;
+ bool depth_enabled;
+ bool is_points;
+ bool is_lines;
+ bool alpha_test;
+ bool point_coord_upper_left;
+ bool light_twoside;
+ bool msaa;
+ bool sample_coverage;
+ bool sample_alpha_to_coverage;
+ bool sample_alpha_to_one;
+ bool clamp_color;
+ uint8_t nr_cbufs;
+ uint8_t swap_color_rb;
+ /* Mask of which render targets need to be written as 32-bit floats */
+ uint8_t f32_color_rb;
+ uint8_t alpha_test_func;
+ uint8_t logicop_func;
+ uint32_t point_sprite_mask;
+
+ struct pipe_rt_blend_state blend;
+};
+
+struct v3d_vs_key {
+ struct v3d_key base;
+
+ struct v3d_varying_slot fs_inputs[V3D_MAX_FS_INPUTS];
+ uint8_t num_fs_inputs;
+
+ bool is_coord;
+ bool per_vertex_point_size;
+ bool clamp_color;
+};
+
+/** A basic block of VIR intructions. */
+struct qblock {
+ struct list_head link;
+
+ struct list_head instructions;
+
+ struct set *predecessors;
+ struct qblock *successors[2];
+
+ int index;
+
+ /* Instruction IPs for the first and last instruction of the block.
+ * Set by qpu_schedule.c.
+ */
+ uint32_t start_qpu_ip;
+ uint32_t end_qpu_ip;
+
+ /* Instruction IP for the branch instruction of the block. Set by
+ * qpu_schedule.c.
+ */
+ uint32_t branch_qpu_ip;
+
+ /** Offset within the uniform stream at the start of the block. */
+ uint32_t start_uniform;
+ /** Offset within the uniform stream of the branch instruction */
+ uint32_t branch_uniform;
+
+ /** @{ used by v3d_vir_live_variables.c */
+ BITSET_WORD *def;
+ BITSET_WORD *use;
+ BITSET_WORD *live_in;
+ BITSET_WORD *live_out;
+ int start_ip, end_ip;
+ /** @} */
+};
+
+/**
+ * Compiler state saved across compiler invocations, for any expensive global
+ * setup.
+ */
+struct v3d_compiler {
+ const struct v3d_device_info *devinfo;
+ struct ra_regs *regs;
+ unsigned int reg_class[3];
+};
+
+struct v3d_compile {
+ const struct v3d_device_info *devinfo;
+ nir_shader *s;
+ nir_function_impl *impl;
+ struct exec_list *cf_node_list;
+ const struct v3d_compiler *compiler;
+
+ /**
+ * Mapping from nir_register * or nir_ssa_def * to array of struct
+ * qreg for the values.
+ */
+ struct hash_table *def_ht;
+
+ /* For each temp, the instruction generating its value. */
+ struct qinst **defs;
+ uint32_t defs_array_size;
+
+ /**
+ * Inputs to the shader, arranged by TGSI declaration order.
+ *
+ * Not all fragment shader QFILE_VARY reads are present in this array.
+ */
+ struct qreg *inputs;
+ struct qreg *outputs;
+ bool msaa_per_sample_output;
+ struct qreg color_reads[V3D_MAX_SAMPLES];
+ struct qreg sample_colors[V3D_MAX_SAMPLES];
+ uint32_t inputs_array_size;
+ uint32_t outputs_array_size;
+ uint32_t uniforms_array_size;
+
+ /* Booleans for whether the corresponding QFILE_VARY[i] is
+ * flat-shaded. This doesn't count gl_FragColor flat-shading, which is
+ * controlled by shader->color_inputs and rasterizer->flatshade in the
+ * gallium driver.
+ */
+ BITSET_WORD flat_shade_flags[BITSET_WORDS(V3D_MAX_FS_INPUTS)];
+
+ /* Booleans for whether the corresponding QFILE_VARY[i] uses the
+ * default glShadeModel() behavior.
+ */
+ BITSET_WORD shade_model_flags[BITSET_WORDS(V3D_MAX_FS_INPUTS)];
+
+ struct v3d_ubo_range *ubo_ranges;
+ bool *ubo_range_used;
+ uint32_t ubo_ranges_array_size;
+ /** Number of uniform areas tracked in ubo_ranges. */
+ uint32_t num_ubo_ranges;
+ uint32_t next_ubo_dst_offset;
+
+ /* State for whether we're executing on each channel currently. 0 if
+ * yes, otherwise a block number + 1 that the channel jumped to.
+ */
+ struct qreg execute;
+
+ struct qreg line_x, point_x, point_y;
+
+ /**
+ * Instance ID, which comes in before the vertex attribute payload if
+ * the shader record requests it.
+ */
+ struct qreg iid;
+
+ /**
+ * Vertex ID, which comes in before the vertex attribute payload
+ * (after Instance ID) if the shader record requests it.
+ */
+ struct qreg vid;
+
+ /* Fragment shader payload regs. */
+ struct qreg payload_w, payload_w_centroid, payload_z;
+
+ uint8_t vattr_sizes[V3D_MAX_VS_INPUTS];
+ uint32_t num_vpm_writes;
+
+ /**
+ * Array of the VARYING_SLOT_* of all FS QFILE_VARY reads.
+ *
+ * This includes those that aren't part of the VPM varyings, like
+ * point/line coordinates.
+ */
+ struct v3d_varying_slot input_slots[V3D_MAX_FS_INPUTS];
+
+ /**
+ * An entry per outputs[] in the VS indicating what the VARYING_SLOT_*
+ * of the output is. Used to emit from the VS in the order that the
+ * FS needs.
+ */
+ struct v3d_varying_slot *output_slots;
+
+ struct pipe_shader_state *shader_state;
+ struct v3d_key *key;
+ struct v3d_fs_key *fs_key;
+ struct v3d_vs_key *vs_key;
+
+ /* Live ranges of temps. */
+ int *temp_start, *temp_end;
+
+ uint32_t *uniform_data;
+ enum quniform_contents *uniform_contents;
+ uint32_t uniform_array_size;
+ uint32_t num_uniforms;
+ uint32_t num_outputs;
+ uint32_t output_position_index;
+ nir_variable *output_color_var[4];
+ uint32_t output_point_size_index;
+ uint32_t output_sample_mask_index;
+
+ struct qreg undef;
+ uint32_t num_temps;
+
+ struct list_head blocks;
+ int next_block_index;
+ struct qblock *cur_block;
+ struct qblock *loop_cont_block;
+ struct qblock *loop_break_block;
+
+ uint64_t *qpu_insts;
+ uint32_t qpu_inst_count;
+ uint32_t qpu_inst_size;
+
+ /* For the FS, the number of varying inputs not counting the
+ * point/line varyings payload
+ */
+ uint32_t num_inputs;
+
+ /**
+ * Number of inputs from num_inputs remaining to be queued to the read
+ * FIFO in the VS/CS.
+ */
+ uint32_t num_inputs_remaining;
+
+ /* Number of inputs currently in the read FIFO for the VS/CS */
+ uint32_t num_inputs_in_fifo;
+
+ /** Next offset in the VPM to read from in the VS/CS */
+ uint32_t vpm_read_offset;
+
+ uint32_t program_id;
+ uint32_t variant_id;
+
+ /* Set to compile program in threaded FS mode, where SIG_THREAD_SWITCH
+ * is used to hide texturing latency at the cost of limiting ourselves
+ * to the bottom half of physical reg space.
+ */
+ bool fs_threaded;
+
+ bool last_thrsw_at_top_level;
+
+ bool failed;
+};
+
+struct v3d_uniform_list {
+ enum quniform_contents *contents;
+ uint32_t *data;
+ uint32_t count;
+};
+
+struct v3d_prog_data {
+ struct v3d_uniform_list uniforms;
+
+ struct v3d_ubo_range *ubo_ranges;
+ uint32_t num_ubo_ranges;
+ uint32_t ubo_size;
+
+ uint8_t num_inputs;
+
+};
+
+struct v3d_vs_prog_data {
+ struct v3d_prog_data base;
+
+ bool uses_iid, uses_vid;
+
+ /* Number of components read from each vertex attribute. */
+ uint8_t vattr_sizes[32];
+
+ /* Total number of components read, for the shader state record. */
+ uint32_t vpm_input_size;
+
+ /* Total number of components written, for the shader state record. */
+ uint32_t vpm_output_size;
+};
+
+struct v3d_fs_prog_data {
+ struct v3d_prog_data base;
+
+ struct v3d_varying_slot input_slots[V3D_MAX_FS_INPUTS];
+
+ /* Bitmask for whether the corresponding input is flat-shaded,
+ * independent of rasterizer (gl_FragColor) flat-shading.
+ */
+ BITSET_WORD flat_shade_flags[BITSET_WORDS(V3D_MAX_FS_INPUTS)];
+ /* Bitmask for whether the corresponding input uses the default
+ * glShadeModel() behavior.
+ */
+ BITSET_WORD shade_model_flags[BITSET_WORDS(V3D_MAX_FS_INPUTS)];
+
+ bool writes_z;
+ bool discard;
+};
+
+/* Special nir_load_input intrinsic index for loading the current TLB
+ * destination color.
+ */
+#define V3D_NIR_TLB_COLOR_READ_INPUT 2000000000
+
+#define V3D_NIR_MS_MASK_OUTPUT 2000000000
+
+extern const nir_shader_compiler_options v3d_nir_options;
+
+const struct v3d_compiler *v3d_compiler_init(const struct v3d_device_info *devinfo);
+void v3d_compiler_free(const struct v3d_compiler *compiler);
+void v3d_optimize_nir(struct nir_shader *s);
+
+uint64_t *v3d_compile_vs(const struct v3d_compiler *compiler,
+ struct v3d_vs_key *key,
+ struct v3d_vs_prog_data *prog_data,
+ nir_shader *s,
+ int program_id, int variant_id,
+ uint32_t *final_assembly_size);
+
+uint64_t *v3d_compile_fs(const struct v3d_compiler *compiler,
+ struct v3d_fs_key *key,
+ struct v3d_fs_prog_data *prog_data,
+ nir_shader *s,
+ int program_id, int variant_id,
+ uint32_t *final_assembly_size);
+
+void v3d_nir_to_vir(struct v3d_compile *c);
+
+void vir_compile_destroy(struct v3d_compile *c);
+const char *vir_get_stage_name(struct v3d_compile *c);
+struct qblock *vir_new_block(struct v3d_compile *c);
+void vir_set_emit_block(struct v3d_compile *c, struct qblock *block);
+void vir_link_blocks(struct qblock *predecessor, struct qblock *successor);
+struct qblock *vir_entry_block(struct v3d_compile *c);
+struct qblock *vir_exit_block(struct v3d_compile *c);
+struct qinst *vir_add_inst(enum v3d_qpu_add_op op, struct qreg dst,
+ struct qreg src0, struct qreg src1);
+struct qinst *vir_mul_inst(enum v3d_qpu_mul_op op, struct qreg dst,
+ struct qreg src0, struct qreg src1);
+struct qinst *vir_branch_inst(enum v3d_qpu_branch_cond cond, struct qreg src0);
+void vir_remove_instruction(struct v3d_compile *c, struct qinst *qinst);
+struct qreg vir_uniform(struct v3d_compile *c,
+ enum quniform_contents contents,
+ uint32_t data);
+void vir_schedule_instructions(struct v3d_compile *c);
+struct v3d_qpu_instr v3d_qpu_nop(void);
+
+struct qreg vir_emit_def(struct v3d_compile *c, struct qinst *inst);
+struct qinst *vir_emit_nondef(struct v3d_compile *c, struct qinst *inst);
+void vir_set_cond(struct qinst *inst, enum v3d_qpu_cond cond);
+void vir_set_pf(struct qinst *inst, enum v3d_qpu_pf pf);
+void vir_set_unpack(struct qinst *inst, int src,
+ enum v3d_qpu_input_unpack unpack);
+
+struct qreg vir_get_temp(struct v3d_compile *c);
+void vir_calculate_live_intervals(struct v3d_compile *c);
+bool vir_has_implicit_uniform(struct qinst *inst);
+int vir_get_implicit_uniform_src(struct qinst *inst);
+int vir_get_non_sideband_nsrc(struct qinst *inst);
+int vir_get_nsrc(struct qinst *inst);
+bool vir_has_side_effects(struct v3d_compile *c, struct qinst *inst);
+bool vir_get_add_op(struct qinst *inst, enum v3d_qpu_add_op *op);
+bool vir_get_mul_op(struct qinst *inst, enum v3d_qpu_mul_op *op);
+bool vir_is_raw_mov(struct qinst *inst);
+bool vir_is_tex(struct qinst *inst);
+bool vir_is_add(struct qinst *inst);
+bool vir_is_mul(struct qinst *inst);
+bool vir_is_float_input(struct qinst *inst);
+bool vir_depends_on_flags(struct qinst *inst);
+bool vir_writes_r3(struct qinst *inst);
+bool vir_writes_r4(struct qinst *inst);
+struct qreg vir_follow_movs(struct v3d_compile *c, struct qreg reg);
+uint8_t vir_channels_written(struct qinst *inst);
+
+void vir_dump(struct v3d_compile *c);
+void vir_dump_inst(struct v3d_compile *c, struct qinst *inst);
+
+void vir_validate(struct v3d_compile *c);
+
+void vir_optimize(struct v3d_compile *c);
+bool vir_opt_algebraic(struct v3d_compile *c);
+bool vir_opt_constant_folding(struct v3d_compile *c);
+bool vir_opt_copy_propagate(struct v3d_compile *c);
+bool vir_opt_dead_code(struct v3d_compile *c);
+bool vir_opt_peephole_sf(struct v3d_compile *c);
+bool vir_opt_small_immediates(struct v3d_compile *c);
+bool vir_opt_vpm(struct v3d_compile *c);
+void v3d_nir_lower_blend(nir_shader *s, struct v3d_compile *c);
+void v3d_nir_lower_io(nir_shader *s, struct v3d_compile *c);
+void v3d_nir_lower_txf_ms(nir_shader *s, struct v3d_compile *c);
+void vir_lower_uniforms(struct v3d_compile *c);
+
+void v3d_vir_to_qpu(struct v3d_compile *c);
+uint32_t v3d_qpu_schedule_instructions(struct v3d_compile *c);
+void qpu_validate(struct v3d_compile *c);
+struct qpu_reg *v3d_register_allocate(struct v3d_compile *c);
+bool vir_init_reg_sets(struct v3d_compiler *compiler);
+
+void vir_PF(struct v3d_compile *c, struct qreg src, enum v3d_qpu_pf pf);
+
+static inline bool
+quniform_contents_is_texture_p0(enum quniform_contents contents)
+{
+ return (contents >= QUNIFORM_TEXTURE_CONFIG_P0_0 &&
+ contents < (QUNIFORM_TEXTURE_CONFIG_P0_0 +
+ V3D_MAX_TEXTURE_SAMPLERS));
+}
+
+static inline struct qreg
+vir_uniform_ui(struct v3d_compile *c, uint32_t ui)
+{
+ return vir_uniform(c, QUNIFORM_CONSTANT, ui);
+}
+
+static inline struct qreg
+vir_uniform_f(struct v3d_compile *c, float f)
+{
+ return vir_uniform(c, QUNIFORM_CONSTANT, fui(f));
+}
+
+#define VIR_ALU0(name, vir_inst, op) \
+static inline struct qreg \
+vir_##name(struct v3d_compile *c) \
+{ \
+ return vir_emit_def(c, vir_inst(op, c->undef, \
+ c->undef, c->undef)); \
+} \
+static inline struct qinst * \
+vir_##name##_dest(struct v3d_compile *c, struct qreg dest) \
+{ \
+ return vir_emit_nondef(c, vir_inst(op, dest, \
+ c->undef, c->undef)); \
+}
+
+#define VIR_ALU1(name, vir_inst, op) \
+static inline struct qreg \
+vir_##name(struct v3d_compile *c, struct qreg a) \
+{ \
+ return vir_emit_def(c, vir_inst(op, c->undef, \
+ a, c->undef)); \
+} \
+static inline struct qinst * \
+vir_##name##_dest(struct v3d_compile *c, struct qreg dest, \
+ struct qreg a) \
+{ \
+ return vir_emit_nondef(c, vir_inst(op, dest, a, \
+ c->undef)); \
+}
+
+#define VIR_ALU2(name, vir_inst, op) \
+static inline struct qreg \
+vir_##name(struct v3d_compile *c, struct qreg a, struct qreg b) \
+{ \
+ return vir_emit_def(c, vir_inst(op, c->undef, a, b)); \
+} \
+static inline struct qinst * \
+vir_##name##_dest(struct v3d_compile *c, struct qreg dest, \
+ struct qreg a, struct qreg b) \
+{ \
+ return vir_emit_nondef(c, vir_inst(op, dest, a, b)); \
+}
+
+#define VIR_NODST_1(name, vir_inst, op) \
+static inline struct qinst * \
+vir_##name(struct v3d_compile *c, struct qreg a) \
+{ \
+ return vir_emit_nondef(c, vir_inst(op, c->undef, \
+ a, c->undef)); \
+}
+
+#define VIR_NODST_2(name, vir_inst, op) \
+static inline struct qinst * \
+vir_##name(struct v3d_compile *c, struct qreg a, struct qreg b) \
+{ \
+ return vir_emit_nondef(c, vir_inst(op, c->undef, \
+ a, b)); \
+}
+
+#define VIR_A_ALU2(name) VIR_ALU2(name, vir_add_inst, V3D_QPU_A_##name)
+#define VIR_M_ALU2(name) VIR_ALU2(name, vir_mul_inst, V3D_QPU_M_##name)
+#define VIR_A_ALU1(name) VIR_ALU1(name, vir_add_inst, V3D_QPU_A_##name)
+#define VIR_M_ALU1(name) VIR_ALU1(name, vir_mul_inst, V3D_QPU_M_##name)
+#define VIR_A_ALU0(name) VIR_ALU0(name, vir_add_inst, V3D_QPU_A_##name)
+#define VIR_M_ALU0(name) VIR_ALU0(name, vir_mul_inst, V3D_QPU_M_##name)
+#define VIR_A_NODST_2(name) VIR_NODST_2(name, vir_add_inst, V3D_QPU_A_##name)
+#define VIR_M_NODST_2(name) VIR_NODST_2(name, vir_mul_inst, V3D_QPU_M_##name)
+#define VIR_A_NODST_1(name) VIR_NODST_1(name, vir_add_inst, V3D_QPU_A_##name)
+#define VIR_M_NODST_1(name) VIR_NODST_1(name, vir_mul_inst, V3D_QPU_M_##name)
+
+VIR_A_ALU2(FADD)
+VIR_A_ALU2(VFPACK)
+VIR_A_ALU2(FSUB)
+VIR_A_ALU2(FMIN)
+VIR_A_ALU2(FMAX)
+
+VIR_A_ALU2(ADD)
+VIR_A_ALU2(SUB)
+VIR_A_ALU2(SHL)
+VIR_A_ALU2(SHR)
+VIR_A_ALU2(ASR)
+VIR_A_ALU2(ROR)
+VIR_A_ALU2(MIN)
+VIR_A_ALU2(MAX)
+VIR_A_ALU2(UMIN)
+VIR_A_ALU2(UMAX)
+VIR_A_ALU2(AND)
+VIR_A_ALU2(OR)
+VIR_A_ALU2(XOR)
+VIR_A_ALU2(VADD)
+VIR_A_ALU2(VSUB)
+VIR_A_ALU1(NOT)
+VIR_A_ALU1(NEG)
+VIR_A_ALU1(FLAPUSH)
+VIR_A_ALU1(FLBPUSH)
+VIR_A_ALU1(FLBPOP)
+VIR_A_ALU1(SETMSF)
+VIR_A_ALU1(SETREVF)
+VIR_A_ALU1(TIDX)
+VIR_A_ALU1(EIDX)
+
+VIR_A_ALU0(FXCD)
+VIR_A_ALU0(XCD)
+VIR_A_ALU0(FYCD)
+VIR_A_ALU0(YCD)
+VIR_A_ALU0(MSF)
+VIR_A_ALU0(REVF)
+VIR_A_NODST_1(VPMSETUP)
+VIR_A_ALU2(FCMP)
+VIR_A_ALU2(VFMAX)
+
+VIR_A_ALU1(FROUND)
+VIR_A_ALU1(FTOIN)
+VIR_A_ALU1(FTRUNC)
+VIR_A_ALU1(FTOIZ)
+VIR_A_ALU1(FFLOOR)
+VIR_A_ALU1(FTOUZ)
+VIR_A_ALU1(FCEIL)
+VIR_A_ALU1(FTOC)
+
+VIR_A_ALU1(FDX)
+VIR_A_ALU1(FDY)
+
+VIR_A_ALU1(ITOF)
+VIR_A_ALU1(CLZ)
+VIR_A_ALU1(UTOF)
+
+VIR_M_ALU2(UMUL24)
+VIR_M_ALU2(FMUL)
+VIR_M_ALU2(SMUL24)
+VIR_M_NODST_2(MULTOP)
+
+VIR_M_ALU1(MOV)
+VIR_M_ALU1(FMOV)
+
+static inline struct qinst *
+vir_MOV_cond(struct v3d_compile *c, enum v3d_qpu_cond cond,
+ struct qreg dest, struct qreg src)
+{
+ struct qinst *mov = vir_MOV_dest(c, dest, src);
+ vir_set_cond(mov, cond);
+ return mov;
+}
+
+static inline struct qreg
+vir_SEL(struct v3d_compile *c, enum v3d_qpu_cond cond,
+ struct qreg src0, struct qreg src1)
+{
+ struct qreg t = vir_get_temp(c);
+ vir_MOV_dest(c, t, src1);
+ vir_MOV_cond(c, cond, t, src0);
+ return t;
+}
+
+static inline void
+vir_VPM_WRITE(struct v3d_compile *c, struct qreg val)
+{
+ vir_MOV_dest(c, vir_reg(QFILE_MAGIC, V3D_QPU_WADDR_VPM), val);
+}
+
+static inline struct qinst *
+vir_NOP(struct v3d_compile *c)
+{
+ return vir_emit_nondef(c, vir_add_inst(V3D_QPU_A_NOP,
+ c->undef, c->undef, c->undef));
+}
+/*
+static inline struct qreg
+vir_LOAD_IMM(struct v3d_compile *c, uint32_t val)
+{
+ return vir_emit_def(c, vir_inst(QOP_LOAD_IMM, c->undef,
+ vir_reg(QFILE_LOAD_IMM, val), c->undef));
+}
+
+static inline struct qreg
+vir_LOAD_IMM_U2(struct v3d_compile *c, uint32_t val)
+{
+ return vir_emit_def(c, vir_inst(QOP_LOAD_IMM_U2, c->undef,
+ vir_reg(QFILE_LOAD_IMM, val),
+ c->undef));
+}
+static inline struct qreg
+vir_LOAD_IMM_I2(struct v3d_compile *c, uint32_t val)
+{
+ return vir_emit_def(c, vir_inst(QOP_LOAD_IMM_I2, c->undef,
+ vir_reg(QFILE_LOAD_IMM, val),
+ c->undef));
+}
+*/
+
+static inline struct qinst *
+vir_BRANCH(struct v3d_compile *c, enum v3d_qpu_cond cond)
+{
+ /* The actual uniform_data value will be set at scheduling time */
+ return vir_emit_nondef(c, vir_branch_inst(cond, vir_uniform_ui(c, 0)));
+}
+
+#define vir_for_each_block(block, c) \
+ list_for_each_entry(struct qblock, block, &c->blocks, link)
+
+#define vir_for_each_block_rev(block, c) \
+ list_for_each_entry_rev(struct qblock, block, &c->blocks, link)
+
+/* Loop over the non-NULL members of the successors array. */
+#define vir_for_each_successor(succ, block) \
+ for (struct qblock *succ = block->successors[0]; \
+ succ != NULL; \
+ succ = (succ == block->successors[1] ? NULL : \
+ block->successors[1]))
+
+#define vir_for_each_inst(inst, block) \
+ list_for_each_entry(struct qinst, inst, &block->instructions, link)
+
+#define vir_for_each_inst_rev(inst, block) \
+ list_for_each_entry_rev(struct qinst, inst, &block->instructions, link)
+
+#define vir_for_each_inst_safe(inst, block) \
+ list_for_each_entry_safe(struct qinst, inst, &block->instructions, link)
+
+#define vir_for_each_inst_inorder(inst, c) \
+ vir_for_each_block(_block, c) \
+ vir_for_each_inst(inst, _block)
+
+#endif /* V3D_COMPILER_H */
diff --git a/lib/mesa/src/broadcom/compiler/v3d_nir_lower_io.c b/lib/mesa/src/broadcom/compiler/v3d_nir_lower_io.c
new file mode 100644
index 000000000..9cdcc0219
--- /dev/null
+++ b/lib/mesa/src/broadcom/compiler/v3d_nir_lower_io.c
@@ -0,0 +1,176 @@
+/*
+ * Copyright © 2015 Broadcom
+ *
+ * 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 "compiler/v3d_compiler.h"
+#include "compiler/nir/nir_builder.h"
+
+/**
+ * Walks the NIR generated by TGSI-to-NIR or GLSL-to-NIR to lower its io
+ * intrinsics into something amenable to the V3D architecture.
+ *
+ * Currently, it splits VS inputs and uniforms into scalars, drops any
+ * non-position outputs in coordinate shaders, and fixes up the addressing on
+ * indirect uniform loads. FS input and VS output scalarization is handled by
+ * nir_lower_io_to_scalar().
+ */
+
+static void
+replace_intrinsic_with_vec(nir_builder *b, nir_intrinsic_instr *intr,
+ nir_ssa_def **comps)
+{
+
+ /* Batch things back together into a vector. This will get split by
+ * the later ALU scalarization pass.
+ */
+ nir_ssa_def *vec = nir_vec(b, comps, intr->num_components);
+
+ /* Replace the old intrinsic with a reference to our reconstructed
+ * vector.
+ */
+ nir_ssa_def_rewrite_uses(&intr->dest.ssa, nir_src_for_ssa(vec));
+ nir_instr_remove(&intr->instr);
+}
+
+static void
+v3d_nir_lower_output(struct v3d_compile *c, nir_builder *b,
+ nir_intrinsic_instr *intr)
+{
+ nir_variable *output_var = NULL;
+ nir_foreach_variable(var, &c->s->outputs) {
+ if (var->data.driver_location == nir_intrinsic_base(intr)) {
+ output_var = var;
+ break;
+ }
+ }
+ assert(output_var);
+
+ if (c->vs_key) {
+ int slot = output_var->data.location;
+ bool used = false;
+
+ switch (slot) {
+ case VARYING_SLOT_PSIZ:
+ case VARYING_SLOT_POS:
+ used = true;
+ break;
+
+ default:
+ for (int i = 0; i < c->vs_key->num_fs_inputs; i++) {
+ if (v3d_slot_get_slot(c->vs_key->fs_inputs[i]) == slot) {
+ used = true;
+ break;
+ }
+ }
+ break;
+ }
+
+ if (!used)
+ nir_instr_remove(&intr->instr);
+ }
+}
+
+static void
+v3d_nir_lower_uniform(struct v3d_compile *c, nir_builder *b,
+ nir_intrinsic_instr *intr)
+{
+ b->cursor = nir_before_instr(&intr->instr);
+
+ /* Generate scalar loads equivalent to the original vector. */
+ nir_ssa_def *dests[4];
+ for (unsigned i = 0; i < intr->num_components; i++) {
+ nir_intrinsic_instr *intr_comp =
+ nir_intrinsic_instr_create(c->s, intr->intrinsic);
+ intr_comp->num_components = 1;
+ nir_ssa_dest_init(&intr_comp->instr, &intr_comp->dest, 1, 32, NULL);
+
+ /* Convert the uniform offset to bytes. If it happens
+ * to be a constant, constant-folding will clean up
+ * the shift for us.
+ */
+ nir_intrinsic_set_base(intr_comp,
+ nir_intrinsic_base(intr) * 16 +
+ i * 4);
+
+ intr_comp->src[0] =
+ nir_src_for_ssa(nir_ishl(b, intr->src[0].ssa,
+ nir_imm_int(b, 4)));
+
+ dests[i] = &intr_comp->dest.ssa;
+
+ nir_builder_instr_insert(b, &intr_comp->instr);
+ }
+
+ replace_intrinsic_with_vec(b, intr, dests);
+}
+
+static void
+v3d_nir_lower_io_instr(struct v3d_compile *c, nir_builder *b,
+ struct nir_instr *instr)
+{
+ if (instr->type != nir_instr_type_intrinsic)
+ return;
+ nir_intrinsic_instr *intr = nir_instr_as_intrinsic(instr);
+
+ switch (intr->intrinsic) {
+ case nir_intrinsic_load_input:
+ break;
+
+ case nir_intrinsic_store_output:
+ v3d_nir_lower_output(c, b, intr);
+ break;
+
+ case nir_intrinsic_load_uniform:
+ v3d_nir_lower_uniform(c, b, intr);
+ break;
+
+ case nir_intrinsic_load_user_clip_plane:
+ default:
+ break;
+ }
+}
+
+static bool
+v3d_nir_lower_io_impl(struct v3d_compile *c, nir_function_impl *impl)
+{
+ nir_builder b;
+ nir_builder_init(&b, impl);
+
+ nir_foreach_block(block, impl) {
+ nir_foreach_instr_safe(instr, block)
+ v3d_nir_lower_io_instr(c, &b, instr);
+ }
+
+ nir_metadata_preserve(impl, nir_metadata_block_index |
+ nir_metadata_dominance);
+
+ return true;
+}
+
+void
+v3d_nir_lower_io(nir_shader *s, struct v3d_compile *c)
+{
+ nir_foreach_function(function, s) {
+ if (function->impl)
+ v3d_nir_lower_io_impl(c, function->impl);
+ }
+}
diff --git a/lib/mesa/src/broadcom/compiler/vir.c b/lib/mesa/src/broadcom/compiler/vir.c
new file mode 100644
index 000000000..99b31841b
--- /dev/null
+++ b/lib/mesa/src/broadcom/compiler/vir.c
@@ -0,0 +1,898 @@
+/*
+ * Copyright © 2016-2017 Broadcom
+ *
+ * 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 "v3d_compiler.h"
+
+int
+vir_get_non_sideband_nsrc(struct qinst *inst)
+{
+ switch (inst->qpu.type) {
+ case V3D_QPU_INSTR_TYPE_BRANCH:
+ return 0;
+ case V3D_QPU_INSTR_TYPE_ALU:
+ if (inst->qpu.alu.add.op != V3D_QPU_A_NOP)
+ return v3d_qpu_add_op_num_src(inst->qpu.alu.add.op);
+ else
+ return v3d_qpu_mul_op_num_src(inst->qpu.alu.mul.op);
+ }
+
+ return 0;
+}
+
+int
+vir_get_nsrc(struct qinst *inst)
+{
+ int nsrc = vir_get_non_sideband_nsrc(inst);
+
+ if (vir_has_implicit_uniform(inst))
+ nsrc++;
+
+ return nsrc;
+}
+
+bool
+vir_has_implicit_uniform(struct qinst *inst)
+{
+ switch (inst->qpu.type) {
+ case V3D_QPU_INSTR_TYPE_BRANCH:
+ return true;
+ case V3D_QPU_INSTR_TYPE_ALU:
+ switch (inst->dst.file) {
+ case QFILE_TLBU:
+ return true;
+ default:
+ return inst->has_implicit_uniform;
+ }
+ }
+ return false;
+}
+
+/* The sideband uniform for textures gets stored after the normal ALU
+ * arguments.
+ */
+int
+vir_get_implicit_uniform_src(struct qinst *inst)
+{
+ return vir_get_nsrc(inst) - 1;
+}
+
+/**
+ * Returns whether the instruction has any side effects that must be
+ * preserved.
+ */
+bool
+vir_has_side_effects(struct v3d_compile *c, struct qinst *inst)
+{
+ switch (inst->qpu.type) {
+ case V3D_QPU_INSTR_TYPE_BRANCH:
+ return true;
+ case V3D_QPU_INSTR_TYPE_ALU:
+ switch (inst->qpu.alu.add.op) {
+ case V3D_QPU_A_SETREVF:
+ case V3D_QPU_A_SETMSF:
+ case V3D_QPU_A_VPMSETUP:
+ return true;
+ default:
+ break;
+ }
+
+ switch (inst->qpu.alu.mul.op) {
+ case V3D_QPU_M_MULTOP:
+ return true;
+ default:
+ break;
+ }
+ }
+
+ if (inst->qpu.sig.ldtmu)
+ return true;
+
+ return false;
+}
+
+bool
+vir_is_float_input(struct qinst *inst)
+{
+ /* XXX: More instrs */
+ switch (inst->qpu.type) {
+ case V3D_QPU_INSTR_TYPE_BRANCH:
+ return false;
+ case V3D_QPU_INSTR_TYPE_ALU:
+ switch (inst->qpu.alu.add.op) {
+ case V3D_QPU_A_FADD:
+ case V3D_QPU_A_FSUB:
+ case V3D_QPU_A_FMIN:
+ case V3D_QPU_A_FMAX:
+ case V3D_QPU_A_FTOIN:
+ return true;
+ default:
+ break;
+ }
+
+ switch (inst->qpu.alu.mul.op) {
+ case V3D_QPU_M_FMOV:
+ case V3D_QPU_M_VFMUL:
+ case V3D_QPU_M_FMUL:
+ return true;
+ default:
+ break;
+ }
+ }
+
+ return false;
+}
+
+bool
+vir_is_raw_mov(struct qinst *inst)
+{
+ if (inst->qpu.type != V3D_QPU_INSTR_TYPE_ALU ||
+ (inst->qpu.alu.mul.op != V3D_QPU_M_FMOV &&
+ inst->qpu.alu.mul.op != V3D_QPU_M_MOV)) {
+ return false;
+ }
+
+ if (inst->qpu.alu.add.output_pack != V3D_QPU_PACK_NONE ||
+ inst->qpu.alu.mul.output_pack != V3D_QPU_PACK_NONE) {
+ return false;
+ }
+
+ if (inst->qpu.flags.ac != V3D_QPU_COND_NONE ||
+ inst->qpu.flags.mc != V3D_QPU_COND_NONE)
+ return false;
+
+ return true;
+}
+
+bool
+vir_is_add(struct qinst *inst)
+{
+ return (inst->qpu.type == V3D_QPU_INSTR_TYPE_ALU &&
+ inst->qpu.alu.add.op != V3D_QPU_A_NOP);
+}
+
+bool
+vir_is_mul(struct qinst *inst)
+{
+ return (inst->qpu.type == V3D_QPU_INSTR_TYPE_ALU &&
+ inst->qpu.alu.mul.op != V3D_QPU_M_NOP);
+}
+
+bool
+vir_is_tex(struct qinst *inst)
+{
+ if (inst->dst.file == QFILE_MAGIC)
+ return v3d_qpu_magic_waddr_is_tmu(inst->dst.index);
+
+ return false;
+}
+
+bool
+vir_depends_on_flags(struct qinst *inst)
+{
+ if (inst->qpu.type == V3D_QPU_INSTR_TYPE_BRANCH) {
+ return (inst->qpu.branch.cond != V3D_QPU_BRANCH_COND_ALWAYS);
+ } else {
+ return (inst->qpu.flags.ac != V3D_QPU_COND_NONE &&
+ inst->qpu.flags.mc != V3D_QPU_COND_NONE);
+ }
+}
+
+bool
+vir_writes_r3(struct qinst *inst)
+{
+ for (int i = 0; i < vir_get_nsrc(inst); i++) {
+ switch (inst->src[i].file) {
+ case QFILE_VARY:
+ case QFILE_VPM:
+ return true;
+ default:
+ break;
+ }
+ }
+
+ return false;
+}
+
+bool
+vir_writes_r4(struct qinst *inst)
+{
+ switch (inst->dst.file) {
+ case QFILE_MAGIC:
+ switch (inst->dst.index) {
+ case V3D_QPU_WADDR_RECIP:
+ case V3D_QPU_WADDR_RSQRT:
+ case V3D_QPU_WADDR_EXP:
+ case V3D_QPU_WADDR_LOG:
+ case V3D_QPU_WADDR_SIN:
+ return true;
+ }
+ break;
+ default:
+ break;
+ }
+
+ if (inst->qpu.sig.ldtmu)
+ return true;
+
+ return false;
+}
+
+void
+vir_set_unpack(struct qinst *inst, int src,
+ enum v3d_qpu_input_unpack unpack)
+{
+ assert(src == 0 || src == 1);
+
+ if (vir_is_add(inst)) {
+ if (src == 0)
+ inst->qpu.alu.add.a_unpack = unpack;
+ else
+ inst->qpu.alu.add.b_unpack = unpack;
+ } else {
+ assert(vir_is_mul(inst));
+ if (src == 0)
+ inst->qpu.alu.mul.a_unpack = unpack;
+ else
+ inst->qpu.alu.mul.b_unpack = unpack;
+ }
+}
+
+void
+vir_set_cond(struct qinst *inst, enum v3d_qpu_cond cond)
+{
+ if (vir_is_add(inst)) {
+ inst->qpu.flags.ac = cond;
+ } else {
+ assert(vir_is_mul(inst));
+ inst->qpu.flags.mc = cond;
+ }
+}
+
+void
+vir_set_pf(struct qinst *inst, enum v3d_qpu_pf pf)
+{
+ if (vir_is_add(inst)) {
+ inst->qpu.flags.apf = pf;
+ } else {
+ assert(vir_is_mul(inst));
+ inst->qpu.flags.mpf = pf;
+ }
+}
+
+#if 0
+uint8_t
+vir_channels_written(struct qinst *inst)
+{
+ if (vir_is_mul(inst)) {
+ switch (inst->dst.pack) {
+ case QPU_PACK_MUL_NOP:
+ case QPU_PACK_MUL_8888:
+ return 0xf;
+ case QPU_PACK_MUL_8A:
+ return 0x1;
+ case QPU_PACK_MUL_8B:
+ return 0x2;
+ case QPU_PACK_MUL_8C:
+ return 0x4;
+ case QPU_PACK_MUL_8D:
+ return 0x8;
+ }
+ } else {
+ switch (inst->dst.pack) {
+ case QPU_PACK_A_NOP:
+ case QPU_PACK_A_8888:
+ case QPU_PACK_A_8888_SAT:
+ case QPU_PACK_A_32_SAT:
+ return 0xf;
+ case QPU_PACK_A_8A:
+ case QPU_PACK_A_8A_SAT:
+ return 0x1;
+ case QPU_PACK_A_8B:
+ case QPU_PACK_A_8B_SAT:
+ return 0x2;
+ case QPU_PACK_A_8C:
+ case QPU_PACK_A_8C_SAT:
+ return 0x4;
+ case QPU_PACK_A_8D:
+ case QPU_PACK_A_8D_SAT:
+ return 0x8;
+ case QPU_PACK_A_16A:
+ case QPU_PACK_A_16A_SAT:
+ return 0x3;
+ case QPU_PACK_A_16B:
+ case QPU_PACK_A_16B_SAT:
+ return 0xc;
+ }
+ }
+ unreachable("Bad pack field");
+}
+#endif
+
+struct qreg
+vir_get_temp(struct v3d_compile *c)
+{
+ struct qreg reg;
+
+ reg.file = QFILE_TEMP;
+ reg.index = c->num_temps++;
+
+ if (c->num_temps > c->defs_array_size) {
+ uint32_t old_size = c->defs_array_size;
+ c->defs_array_size = MAX2(old_size * 2, 16);
+ c->defs = reralloc(c, c->defs, struct qinst *,
+ c->defs_array_size);
+ memset(&c->defs[old_size], 0,
+ sizeof(c->defs[0]) * (c->defs_array_size - old_size));
+ }
+
+ return reg;
+}
+
+struct qinst *
+vir_add_inst(enum v3d_qpu_add_op op, struct qreg dst, struct qreg src0, struct qreg src1)
+{
+ struct qinst *inst = calloc(1, sizeof(*inst));
+
+ inst->qpu = v3d_qpu_nop();
+ inst->qpu.alu.add.op = op;
+
+ inst->dst = dst;
+ inst->src[0] = src0;
+ inst->src[1] = src1;
+ inst->uniform = ~0;
+
+ return inst;
+}
+
+struct qinst *
+vir_mul_inst(enum v3d_qpu_mul_op op, struct qreg dst, struct qreg src0, struct qreg src1)
+{
+ struct qinst *inst = calloc(1, sizeof(*inst));
+
+ inst->qpu = v3d_qpu_nop();
+ inst->qpu.alu.mul.op = op;
+
+ inst->dst = dst;
+ inst->src[0] = src0;
+ inst->src[1] = src1;
+ inst->uniform = ~0;
+
+ return inst;
+}
+
+struct qinst *
+vir_branch_inst(enum v3d_qpu_branch_cond cond, struct qreg src)
+{
+ struct qinst *inst = calloc(1, sizeof(*inst));
+
+ inst->qpu = v3d_qpu_nop();
+ inst->qpu.type = V3D_QPU_INSTR_TYPE_BRANCH;
+ inst->qpu.branch.cond = cond;
+ inst->qpu.branch.msfign = V3D_QPU_MSFIGN_NONE;
+ inst->qpu.branch.bdi = V3D_QPU_BRANCH_DEST_REL;
+ inst->qpu.branch.ub = true;
+ inst->qpu.branch.bdu = V3D_QPU_BRANCH_DEST_REL;
+
+ inst->dst = vir_reg(QFILE_NULL, 0);
+ inst->src[0] = src;
+ inst->uniform = ~0;
+
+ return inst;
+}
+
+static void
+vir_emit(struct v3d_compile *c, struct qinst *inst)
+{
+ list_addtail(&inst->link, &c->cur_block->instructions);
+
+ if (inst->dst.file == QFILE_MAGIC &&
+ inst->dst.index == V3D_QPU_WADDR_VPM)
+ c->num_vpm_writes++;
+}
+
+/* Updates inst to write to a new temporary, emits it, and notes the def. */
+struct qreg
+vir_emit_def(struct v3d_compile *c, struct qinst *inst)
+{
+ assert(inst->dst.file == QFILE_NULL);
+
+ inst->dst = vir_get_temp(c);
+
+ if (inst->dst.file == QFILE_TEMP)
+ c->defs[inst->dst.index] = inst;
+
+ vir_emit(c, inst);
+
+ return inst->dst;
+}
+
+struct qinst *
+vir_emit_nondef(struct v3d_compile *c, struct qinst *inst)
+{
+ if (inst->dst.file == QFILE_TEMP)
+ c->defs[inst->dst.index] = NULL;
+
+ vir_emit(c, inst);
+
+ return inst;
+}
+
+struct qblock *
+vir_new_block(struct v3d_compile *c)
+{
+ struct qblock *block = rzalloc(c, struct qblock);
+
+ list_inithead(&block->instructions);
+
+ block->predecessors = _mesa_set_create(block,
+ _mesa_hash_pointer,
+ _mesa_key_pointer_equal);
+
+ block->index = c->next_block_index++;
+
+ return block;
+}
+
+void
+vir_set_emit_block(struct v3d_compile *c, struct qblock *block)
+{
+ c->cur_block = block;
+ list_addtail(&block->link, &c->blocks);
+}
+
+struct qblock *
+vir_entry_block(struct v3d_compile *c)
+{
+ return list_first_entry(&c->blocks, struct qblock, link);
+}
+
+struct qblock *
+vir_exit_block(struct v3d_compile *c)
+{
+ return list_last_entry(&c->blocks, struct qblock, link);
+}
+
+void
+vir_link_blocks(struct qblock *predecessor, struct qblock *successor)
+{
+ _mesa_set_add(successor->predecessors, predecessor);
+ if (predecessor->successors[0]) {
+ assert(!predecessor->successors[1]);
+ predecessor->successors[1] = successor;
+ } else {
+ predecessor->successors[0] = successor;
+ }
+}
+
+const struct v3d_compiler *
+v3d_compiler_init(const struct v3d_device_info *devinfo)
+{
+ struct v3d_compiler *compiler = rzalloc(NULL, struct v3d_compiler);
+ if (!compiler)
+ return NULL;
+
+ compiler->devinfo = devinfo;
+
+ if (!vir_init_reg_sets(compiler)) {
+ ralloc_free(compiler);
+ return NULL;
+ }
+
+ return compiler;
+}
+
+void
+v3d_compiler_free(const struct v3d_compiler *compiler)
+{
+ ralloc_free((void *)compiler);
+}
+
+static struct v3d_compile *
+vir_compile_init(const struct v3d_compiler *compiler,
+ struct v3d_key *key,
+ nir_shader *s,
+ int program_id, int variant_id)
+{
+ struct v3d_compile *c = rzalloc(NULL, struct v3d_compile);
+
+ c->compiler = compiler;
+ c->devinfo = compiler->devinfo;
+ c->key = key;
+ c->program_id = program_id;
+ c->variant_id = variant_id;
+
+ s = nir_shader_clone(c, s);
+ c->s = s;
+
+ list_inithead(&c->blocks);
+ vir_set_emit_block(c, vir_new_block(c));
+
+ c->output_position_index = -1;
+ c->output_point_size_index = -1;
+ c->output_sample_mask_index = -1;
+
+ c->def_ht = _mesa_hash_table_create(c, _mesa_hash_pointer,
+ _mesa_key_pointer_equal);
+
+ return c;
+}
+
+static void
+v3d_lower_nir(struct v3d_compile *c)
+{
+ struct nir_lower_tex_options tex_options = {
+ .lower_rect = false, /* XXX */
+ .lower_txp = ~0,
+ /* Apply swizzles to all samplers. */
+ .swizzle_result = ~0,
+ };
+
+ /* Lower the format swizzle and (for 32-bit returns)
+ * ARB_texture_swizzle-style swizzle.
+ */
+ for (int i = 0; i < ARRAY_SIZE(c->key->tex); i++) {
+ for (int j = 0; j < 4; j++)
+ tex_options.swizzles[i][j] = c->key->tex[i].swizzle[j];
+ }
+
+ NIR_PASS_V(c->s, nir_lower_tex, &tex_options);
+}
+
+static void
+v3d_lower_nir_late(struct v3d_compile *c)
+{
+ NIR_PASS_V(c->s, v3d_nir_lower_io, c);
+ NIR_PASS_V(c->s, nir_lower_idiv);
+}
+
+static void
+v3d_set_prog_data_uniforms(struct v3d_compile *c,
+ struct v3d_prog_data *prog_data)
+{
+ int count = c->num_uniforms;
+ struct v3d_uniform_list *ulist = &prog_data->uniforms;
+
+ ulist->count = count;
+ ulist->data = ralloc_array(prog_data, uint32_t, count);
+ memcpy(ulist->data, c->uniform_data,
+ count * sizeof(*ulist->data));
+ ulist->contents = ralloc_array(prog_data, enum quniform_contents, count);
+ memcpy(ulist->contents, c->uniform_contents,
+ count * sizeof(*ulist->contents));
+}
+
+/* Copy the compiler UBO range state to the compiled shader, dropping out
+ * arrays that were never referenced by an indirect load.
+ *
+ * (Note that QIR dead code elimination of an array access still leaves that
+ * array alive, though)
+ */
+static void
+v3d_set_prog_data_ubo(struct v3d_compile *c,
+ struct v3d_prog_data *prog_data)
+{
+ if (!c->num_ubo_ranges)
+ return;
+
+ prog_data->num_ubo_ranges = 0;
+ prog_data->ubo_ranges = ralloc_array(prog_data, struct v3d_ubo_range,
+ c->num_ubo_ranges);
+ for (int i = 0; i < c->num_ubo_ranges; i++) {
+ if (!c->ubo_range_used[i])
+ continue;
+
+ struct v3d_ubo_range *range = &c->ubo_ranges[i];
+ prog_data->ubo_ranges[prog_data->num_ubo_ranges++] = *range;
+ prog_data->ubo_size += range->size;
+ }
+
+ if (prog_data->ubo_size) {
+ if (V3D_DEBUG & V3D_DEBUG_SHADERDB) {
+ fprintf(stderr, "SHADER-DB: %s prog %d/%d: %d UBO uniforms\n",
+ vir_get_stage_name(c),
+ c->program_id, c->variant_id,
+ prog_data->ubo_size / 4);
+ }
+ }
+}
+
+static void
+v3d_set_prog_data(struct v3d_compile *c,
+ struct v3d_prog_data *prog_data)
+{
+ v3d_set_prog_data_uniforms(c, prog_data);
+ v3d_set_prog_data_ubo(c, prog_data);
+}
+
+static uint64_t *
+v3d_return_qpu_insts(struct v3d_compile *c, uint32_t *final_assembly_size)
+{
+ *final_assembly_size = c->qpu_inst_count * sizeof(uint64_t);
+
+ uint64_t *qpu_insts = malloc(*final_assembly_size);
+ if (!qpu_insts)
+ return NULL;
+
+ memcpy(qpu_insts, c->qpu_insts, *final_assembly_size);
+
+ vir_compile_destroy(c);
+
+ return qpu_insts;
+}
+
+uint64_t *v3d_compile_vs(const struct v3d_compiler *compiler,
+ struct v3d_vs_key *key,
+ struct v3d_vs_prog_data *prog_data,
+ nir_shader *s,
+ int program_id, int variant_id,
+ uint32_t *final_assembly_size)
+{
+ struct v3d_compile *c = vir_compile_init(compiler, &key->base, s,
+ program_id, variant_id);
+
+ c->vs_key = key;
+
+ v3d_lower_nir(c);
+
+ if (key->clamp_color)
+ NIR_PASS_V(c->s, nir_lower_clamp_color_outputs);
+
+ if (key->base.ucp_enables) {
+ NIR_PASS_V(c->s, nir_lower_clip_vs, key->base.ucp_enables);
+ NIR_PASS_V(c->s, nir_lower_io_to_scalar,
+ nir_var_shader_out);
+ }
+
+ /* Note: VS output scalarizing must happen after nir_lower_clip_vs. */
+ NIR_PASS_V(c->s, nir_lower_io_to_scalar, nir_var_shader_out);
+
+ v3d_lower_nir_late(c);
+ v3d_optimize_nir(c->s);
+ NIR_PASS_V(c->s, nir_convert_from_ssa, true);
+
+ v3d_nir_to_vir(c);
+
+ v3d_set_prog_data(c, &prog_data->base);
+
+ prog_data->base.num_inputs = c->num_inputs;
+
+ /* The vertex data gets format converted by the VPM so that
+ * each attribute channel takes up a VPM column. Precompute
+ * the sizes for the shader record.
+ */
+ for (int i = 0; i < ARRAY_SIZE(prog_data->vattr_sizes); i++) {
+ prog_data->vattr_sizes[i] = c->vattr_sizes[i];
+ prog_data->vpm_input_size += c->vattr_sizes[i];
+ }
+
+ /* Input/output segment size are in 8x32-bit multiples. */
+ prog_data->vpm_input_size = align(prog_data->vpm_input_size, 8) / 8;
+ prog_data->vpm_output_size = align(c->num_vpm_writes, 8) / 8;
+
+ prog_data->uses_vid = (s->info.system_values_read &
+ (1ull << SYSTEM_VALUE_VERTEX_ID));
+ prog_data->uses_iid = (s->info.system_values_read &
+ (1ull << SYSTEM_VALUE_INSTANCE_ID));
+
+ return v3d_return_qpu_insts(c, final_assembly_size);
+}
+
+static void
+v3d_set_fs_prog_data_inputs(struct v3d_compile *c,
+ struct v3d_fs_prog_data *prog_data)
+{
+ prog_data->base.num_inputs = c->num_inputs;
+ memcpy(prog_data->input_slots, c->input_slots,
+ c->num_inputs * sizeof(*c->input_slots));
+
+ memcpy(prog_data->flat_shade_flags, c->flat_shade_flags,
+ sizeof(c->flat_shade_flags));
+ memcpy(prog_data->shade_model_flags, c->shade_model_flags,
+ sizeof(c->shade_model_flags));
+}
+
+uint64_t *v3d_compile_fs(const struct v3d_compiler *compiler,
+ struct v3d_fs_key *key,
+ struct v3d_fs_prog_data *prog_data,
+ nir_shader *s,
+ int program_id, int variant_id,
+ uint32_t *final_assembly_size)
+{
+ struct v3d_compile *c = vir_compile_init(compiler, &key->base, s,
+ program_id, variant_id);
+
+ c->fs_key = key;
+
+ v3d_lower_nir(c);
+
+ if (key->light_twoside)
+ NIR_PASS_V(c->s, nir_lower_two_sided_color);
+
+ if (key->clamp_color)
+ NIR_PASS_V(c->s, nir_lower_clamp_color_outputs);
+
+ if (key->alpha_test) {
+ NIR_PASS_V(c->s, nir_lower_alpha_test, key->alpha_test_func,
+ false);
+ }
+
+ if (key->base.ucp_enables)
+ NIR_PASS_V(c->s, nir_lower_clip_fs, key->base.ucp_enables);
+
+ /* Note: FS input scalarizing must happen after
+ * nir_lower_two_sided_color, which only handles a vec4 at a time.
+ */
+ NIR_PASS_V(c->s, nir_lower_io_to_scalar, nir_var_shader_in);
+
+ v3d_lower_nir_late(c);
+ v3d_optimize_nir(c->s);
+ NIR_PASS_V(c->s, nir_convert_from_ssa, true);
+
+ v3d_nir_to_vir(c);
+
+ v3d_set_prog_data(c, &prog_data->base);
+ v3d_set_fs_prog_data_inputs(c, prog_data);
+ prog_data->writes_z = (c->s->info.outputs_written &
+ (1 << FRAG_RESULT_DEPTH));
+ prog_data->discard = c->s->info.fs.uses_discard;
+
+ return v3d_return_qpu_insts(c, final_assembly_size);
+}
+
+void
+vir_remove_instruction(struct v3d_compile *c, struct qinst *qinst)
+{
+ if (qinst->dst.file == QFILE_TEMP)
+ c->defs[qinst->dst.index] = NULL;
+
+ list_del(&qinst->link);
+ free(qinst);
+}
+
+struct qreg
+vir_follow_movs(struct v3d_compile *c, struct qreg reg)
+{
+ /* XXX
+ int pack = reg.pack;
+
+ while (reg.file == QFILE_TEMP &&
+ c->defs[reg.index] &&
+ (c->defs[reg.index]->op == QOP_MOV ||
+ c->defs[reg.index]->op == QOP_FMOV) &&
+ !c->defs[reg.index]->dst.pack &&
+ !c->defs[reg.index]->src[0].pack) {
+ reg = c->defs[reg.index]->src[0];
+ }
+
+ reg.pack = pack;
+ */
+ return reg;
+}
+
+void
+vir_compile_destroy(struct v3d_compile *c)
+{
+ vir_for_each_block(block, c) {
+ while (!list_empty(&block->instructions)) {
+ struct qinst *qinst =
+ list_first_entry(&block->instructions,
+ struct qinst, link);
+ vir_remove_instruction(c, qinst);
+ }
+ }
+
+ ralloc_free(c);
+}
+
+struct qreg
+vir_uniform(struct v3d_compile *c,
+ enum quniform_contents contents,
+ uint32_t data)
+{
+ for (int i = 0; i < c->num_uniforms; i++) {
+ if (c->uniform_contents[i] == contents &&
+ c->uniform_data[i] == data) {
+ return vir_reg(QFILE_UNIF, i);
+ }
+ }
+
+ uint32_t uniform = c->num_uniforms++;
+
+ if (uniform >= c->uniform_array_size) {
+ c->uniform_array_size = MAX2(MAX2(16, uniform + 1),
+ c->uniform_array_size * 2);
+
+ c->uniform_data = reralloc(c, c->uniform_data,
+ uint32_t,
+ c->uniform_array_size);
+ c->uniform_contents = reralloc(c, c->uniform_contents,
+ enum quniform_contents,
+ c->uniform_array_size);
+ }
+
+ c->uniform_contents[uniform] = contents;
+ c->uniform_data[uniform] = data;
+
+ return vir_reg(QFILE_UNIF, uniform);
+}
+
+void
+vir_PF(struct v3d_compile *c, struct qreg src, enum v3d_qpu_pf pf)
+{
+ struct qinst *last_inst = NULL;
+
+ if (!list_empty(&c->cur_block->instructions))
+ last_inst = (struct qinst *)c->cur_block->instructions.prev;
+
+ if (src.file != QFILE_TEMP ||
+ !c->defs[src.index] ||
+ last_inst != c->defs[src.index]) {
+ /* XXX: Make the MOV be the appropriate type */
+ last_inst = vir_MOV_dest(c, vir_reg(QFILE_NULL, 0), src);
+ last_inst = (struct qinst *)c->cur_block->instructions.prev;
+ }
+
+ vir_set_pf(last_inst, pf);
+}
+
+#define OPTPASS(func) \
+ do { \
+ bool stage_progress = func(c); \
+ if (stage_progress) { \
+ progress = true; \
+ if (print_opt_debug) { \
+ fprintf(stderr, \
+ "VIR opt pass %2d: %s progress\n", \
+ pass, #func); \
+ } \
+ /*XXX vir_validate(c);*/ \
+ } \
+ } while (0)
+
+void
+vir_optimize(struct v3d_compile *c)
+{
+ bool print_opt_debug = false;
+ int pass = 1;
+
+ while (true) {
+ bool progress = false;
+
+ OPTPASS(vir_opt_copy_propagate);
+ OPTPASS(vir_opt_dead_code);
+
+ if (!progress)
+ break;
+
+ pass++;
+ }
+}
+
+const char *
+vir_get_stage_name(struct v3d_compile *c)
+{
+ if (c->vs_key && c->vs_key->is_coord)
+ return "MESA_SHADER_COORD";
+ else
+ return gl_shader_stage_name(c->s->info.stage);
+}
diff --git a/lib/mesa/src/broadcom/compiler/vir_dump.c b/lib/mesa/src/broadcom/compiler/vir_dump.c
new file mode 100644
index 000000000..ad5c061a1
--- /dev/null
+++ b/lib/mesa/src/broadcom/compiler/vir_dump.c
@@ -0,0 +1,339 @@
+/*
+ * Copyright © 2016-2017 Broadcom
+ *
+ * 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 "v3d_compiler.h"
+
+static void
+vir_print_reg(struct v3d_compile *c, struct qreg reg)
+{
+ static const char *files[] = {
+ [QFILE_TEMP] = "t",
+ [QFILE_VARY] = "v",
+ [QFILE_UNIF] = "u",
+ [QFILE_TLB] = "tlb",
+ [QFILE_TLBU] = "tlbu",
+ };
+ static const char *quniform_names[] = {
+ [QUNIFORM_VIEWPORT_X_SCALE] = "vp_x_scale",
+ [QUNIFORM_VIEWPORT_Y_SCALE] = "vp_y_scale",
+ [QUNIFORM_VIEWPORT_Z_OFFSET] = "vp_z_offset",
+ [QUNIFORM_VIEWPORT_Z_SCALE] = "vp_z_scale",
+ };
+
+ switch (reg.file) {
+
+ case QFILE_NULL:
+ fprintf(stderr, "null");
+ break;
+
+ case QFILE_LOAD_IMM:
+ fprintf(stderr, "0x%08x (%f)", reg.index, uif(reg.index));
+ break;
+
+ case QFILE_REG:
+ fprintf(stderr, "rf%d", reg.index);
+ break;
+
+ case QFILE_MAGIC:
+ fprintf(stderr, "%s", v3d_qpu_magic_waddr_name(reg.index));
+ break;
+
+ case QFILE_SMALL_IMM:
+ if ((int)reg.index >= -16 && (int)reg.index <= 15)
+ fprintf(stderr, "%d", reg.index);
+ else
+ fprintf(stderr, "%f", uif(reg.index));
+ break;
+
+ case QFILE_VPM:
+ fprintf(stderr, "vpm%d.%d",
+ reg.index / 4, reg.index % 4);
+ break;
+
+ case QFILE_TLB:
+ fprintf(stderr, "%s", files[reg.file]);
+ break;
+
+ case QFILE_UNIF: {
+ enum quniform_contents contents = c->uniform_contents[reg.index];
+
+ fprintf(stderr, "%s%d", files[reg.file], reg.index);
+
+ switch (contents) {
+ case QUNIFORM_CONSTANT:
+ fprintf(stderr, " (0x%08x / %f)",
+ c->uniform_data[reg.index],
+ uif(c->uniform_data[reg.index]));
+ break;
+
+ case QUNIFORM_UNIFORM:
+ fprintf(stderr, " (push[%d])",
+ c->uniform_data[reg.index]);
+ break;
+
+ case QUNIFORM_TEXTURE_CONFIG_P1:
+ fprintf(stderr, " (tex[%d].p1)",
+ c->uniform_data[reg.index]);
+ break;
+
+ case QUNIFORM_TEXTURE_WIDTH:
+ fprintf(stderr, " (tex[%d].width)",
+ c->uniform_data[reg.index]);
+ break;
+ case QUNIFORM_TEXTURE_HEIGHT:
+ fprintf(stderr, " (tex[%d].height)",
+ c->uniform_data[reg.index]);
+ break;
+ case QUNIFORM_TEXTURE_DEPTH:
+ fprintf(stderr, " (tex[%d].depth)",
+ c->uniform_data[reg.index]);
+ break;
+ case QUNIFORM_TEXTURE_ARRAY_SIZE:
+ fprintf(stderr, " (tex[%d].array_size)",
+ c->uniform_data[reg.index]);
+ break;
+ case QUNIFORM_TEXTURE_LEVELS:
+ fprintf(stderr, " (tex[%d].levels)",
+ c->uniform_data[reg.index]);
+ break;
+
+ case QUNIFORM_UBO_ADDR:
+ fprintf(stderr, " (ubo[%d])",
+ c->uniform_data[reg.index]);
+ break;
+
+ default:
+ if (quniform_contents_is_texture_p0(contents)) {
+ fprintf(stderr, " (tex[%d].p0: 0x%08x)",
+ contents - QUNIFORM_TEXTURE_CONFIG_P0_0,
+ c->uniform_data[reg.index]);
+ } else if (contents < ARRAY_SIZE(quniform_names)) {
+ fprintf(stderr, " (%s)",
+ quniform_names[contents]);
+ } else {
+ fprintf(stderr, " (%d / 0x%08x)", contents,
+ c->uniform_data[reg.index]);
+ }
+ }
+
+ break;
+ }
+
+ default:
+ fprintf(stderr, "%s%d", files[reg.file], reg.index);
+ break;
+ }
+}
+
+static void
+vir_dump_sig(struct v3d_compile *c, struct qinst *inst)
+{
+ struct v3d_qpu_sig *sig = &inst->qpu.sig;
+
+ if (sig->thrsw)
+ fprintf(stderr, "; thrsw");
+ if (sig->ldvary)
+ fprintf(stderr, "; ldvary");
+ if (sig->ldvpm)
+ fprintf(stderr, "; ldvpm");
+ if (sig->ldtmu)
+ fprintf(stderr, "; ldtmu");
+ if (sig->ldunif)
+ fprintf(stderr, "; ldunif");
+ if (sig->wrtmuc)
+ fprintf(stderr, "; wrtmuc");
+}
+
+static void
+vir_dump_alu(struct v3d_compile *c, struct qinst *inst)
+{
+ struct v3d_qpu_instr *instr = &inst->qpu;
+ int nsrc = vir_get_non_sideband_nsrc(inst);
+ int sideband_nsrc = vir_get_nsrc(inst);
+ enum v3d_qpu_input_unpack unpack[2];
+
+ if (inst->qpu.alu.add.op != V3D_QPU_A_NOP) {
+ fprintf(stderr, "%s", v3d_qpu_add_op_name(instr->alu.add.op));
+ fprintf(stderr, "%s", v3d_qpu_cond_name(instr->flags.ac));
+ fprintf(stderr, "%s", v3d_qpu_pf_name(instr->flags.apf));
+ fprintf(stderr, "%s", v3d_qpu_uf_name(instr->flags.auf));
+ fprintf(stderr, " ");
+
+ vir_print_reg(c, inst->dst);
+ fprintf(stderr, "%s", v3d_qpu_pack_name(instr->alu.add.output_pack));
+
+ unpack[0] = instr->alu.add.a_unpack;
+ unpack[1] = instr->alu.add.b_unpack;
+ } else {
+ fprintf(stderr, "%s", v3d_qpu_mul_op_name(instr->alu.mul.op));
+ fprintf(stderr, "%s", v3d_qpu_cond_name(instr->flags.mc));
+ fprintf(stderr, "%s", v3d_qpu_pf_name(instr->flags.mpf));
+ fprintf(stderr, "%s", v3d_qpu_uf_name(instr->flags.muf));
+ fprintf(stderr, " ");
+
+ vir_print_reg(c, inst->dst);
+ fprintf(stderr, "%s", v3d_qpu_pack_name(instr->alu.mul.output_pack));
+
+ unpack[0] = instr->alu.mul.a_unpack;
+ unpack[1] = instr->alu.mul.b_unpack;
+ }
+
+ for (int i = 0; i < sideband_nsrc; i++) {
+ fprintf(stderr, ", ");
+ vir_print_reg(c, inst->src[i]);
+ if (i < nsrc)
+ fprintf(stderr, "%s", v3d_qpu_unpack_name(unpack[i]));
+ }
+
+ vir_dump_sig(c, inst);
+}
+
+void
+vir_dump_inst(struct v3d_compile *c, struct qinst *inst)
+{
+ struct v3d_qpu_instr *instr = &inst->qpu;
+
+ switch (inst->qpu.type) {
+ case V3D_QPU_INSTR_TYPE_ALU:
+ vir_dump_alu(c, inst);
+ break;
+ case V3D_QPU_INSTR_TYPE_BRANCH:
+ fprintf(stderr, "b");
+ if (instr->branch.ub)
+ fprintf(stderr, "u");
+
+ fprintf(stderr, "%s",
+ v3d_qpu_branch_cond_name(instr->branch.cond));
+ fprintf(stderr, "%s", v3d_qpu_msfign_name(instr->branch.msfign));
+
+ switch (instr->branch.bdi) {
+ case V3D_QPU_BRANCH_DEST_ABS:
+ fprintf(stderr, " zero_addr+0x%08x", instr->branch.offset);
+ break;
+
+ case V3D_QPU_BRANCH_DEST_REL:
+ fprintf(stderr, " %d", instr->branch.offset);
+ break;
+
+ case V3D_QPU_BRANCH_DEST_LINK_REG:
+ fprintf(stderr, " lri");
+ break;
+
+ case V3D_QPU_BRANCH_DEST_REGFILE:
+ fprintf(stderr, " rf%d", instr->branch.raddr_a);
+ break;
+ }
+
+ if (instr->branch.ub) {
+ switch (instr->branch.bdu) {
+ case V3D_QPU_BRANCH_DEST_ABS:
+ fprintf(stderr, ", a:unif");
+ break;
+
+ case V3D_QPU_BRANCH_DEST_REL:
+ fprintf(stderr, ", r:unif");
+ break;
+
+ case V3D_QPU_BRANCH_DEST_LINK_REG:
+ fprintf(stderr, ", lri");
+ break;
+
+ case V3D_QPU_BRANCH_DEST_REGFILE:
+ fprintf(stderr, ", rf%d", instr->branch.raddr_a);
+ break;
+ }
+ }
+
+ if (vir_has_implicit_uniform(inst)) {
+ fprintf(stderr, " ");
+ vir_print_reg(c, inst->src[vir_get_implicit_uniform_src(inst)]);
+ }
+
+ break;
+ }
+}
+
+void
+vir_dump(struct v3d_compile *c)
+{
+ int ip = 0;
+
+ vir_for_each_block(block, c) {
+ fprintf(stderr, "BLOCK %d:\n", block->index);
+ vir_for_each_inst(inst, block) {
+ if (c->temp_start) {
+ bool first = true;
+
+ for (int i = 0; i < c->num_temps; i++) {
+ if (c->temp_start[i] != ip)
+ continue;
+
+ if (first) {
+ first = false;
+ } else {
+ fprintf(stderr, ", ");
+ }
+ fprintf(stderr, "S%4d", i);
+ }
+
+ if (first)
+ fprintf(stderr, " ");
+ else
+ fprintf(stderr, " ");
+ }
+
+ if (c->temp_end) {
+ bool first = true;
+
+ for (int i = 0; i < c->num_temps; i++) {
+ if (c->temp_end[i] != ip)
+ continue;
+
+ if (first) {
+ first = false;
+ } else {
+ fprintf(stderr, ", ");
+ }
+ fprintf(stderr, "E%4d", i);
+ }
+
+ if (first)
+ fprintf(stderr, " ");
+ else
+ fprintf(stderr, " ");
+ }
+
+ vir_dump_inst(c, inst);
+ fprintf(stderr, "\n");
+ ip++;
+ }
+ if (block->successors[1]) {
+ fprintf(stderr, "-> BLOCK %d, %d\n",
+ block->successors[0]->index,
+ block->successors[1]->index);
+ } else if (block->successors[0]) {
+ fprintf(stderr, "-> BLOCK %d\n",
+ block->successors[0]->index);
+ }
+ }
+}
diff --git a/lib/mesa/src/broadcom/compiler/vir_live_variables.c b/lib/mesa/src/broadcom/compiler/vir_live_variables.c
new file mode 100644
index 000000000..217b716fd
--- /dev/null
+++ b/lib/mesa/src/broadcom/compiler/vir_live_variables.c
@@ -0,0 +1,340 @@
+/*
+ * Copyright © 2012 Intel Corporation
+ * Copyright © 2016 Broadcom
+ *
+ * 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.
+ */
+
+#define MAX_INSTRUCTION (1 << 30)
+
+#include "util/ralloc.h"
+#include "util/register_allocate.h"
+#include "v3d_compiler.h"
+
+struct partial_update_state {
+ struct qinst *insts[4];
+ uint8_t channels;
+};
+
+static uint32_t
+int_hash(const void *key)
+{
+ return _mesa_hash_data(key, sizeof(int));
+}
+
+static bool
+int_compare(const void *key1, const void *key2)
+{
+ return *(const int *)key1 == *(const int *)key2;
+}
+
+static int
+vir_reg_to_var(struct qreg reg)
+{
+ if (reg.file == QFILE_TEMP)
+ return reg.index;
+
+ return -1;
+}
+
+static void
+vir_setup_use(struct v3d_compile *c, struct qblock *block, int ip,
+ struct qreg src)
+{
+ int var = vir_reg_to_var(src);
+ if (var == -1)
+ return;
+
+ c->temp_start[var] = MIN2(c->temp_start[var], ip);
+ c->temp_end[var] = MAX2(c->temp_end[var], ip);
+
+ /* The use[] bitset marks when the block makes
+ * use of a variable without having completely
+ * defined that variable within the block.
+ */
+ if (!BITSET_TEST(block->def, var))
+ BITSET_SET(block->use, var);
+}
+
+static struct partial_update_state *
+get_partial_update_state(struct hash_table *partial_update_ht,
+ struct qinst *inst)
+{
+ struct hash_entry *entry =
+ _mesa_hash_table_search(partial_update_ht,
+ &inst->dst.index);
+ if (entry)
+ return entry->data;
+
+ struct partial_update_state *state =
+ rzalloc(partial_update_ht, struct partial_update_state);
+
+ _mesa_hash_table_insert(partial_update_ht, &inst->dst.index, state);
+
+ return state;
+}
+
+static void
+vir_setup_def(struct v3d_compile *c, struct qblock *block, int ip,
+ struct hash_table *partial_update_ht, struct qinst *inst)
+{
+ if (inst->qpu.type != V3D_QPU_INSTR_TYPE_ALU)
+ return;
+
+ /* The def[] bitset marks when an initialization in a
+ * block completely screens off previous updates of
+ * that variable.
+ */
+ int var = vir_reg_to_var(inst->dst);
+ if (var == -1)
+ return;
+
+ c->temp_start[var] = MIN2(c->temp_start[var], ip);
+ c->temp_end[var] = MAX2(c->temp_end[var], ip);
+
+ /* If we've already tracked this as a def, or already used it within
+ * the block, there's nothing to do.
+ */
+ if (BITSET_TEST(block->use, var) || BITSET_TEST(block->def, var))
+ return;
+
+ /* Easy, common case: unconditional full register update.
+ *
+ * We treat conditioning on the exec mask as the same as not being
+ * conditional. This makes sure that if the register gets set on
+ * either side of an if, it is treated as being screened off before
+ * the if. Otherwise, if there was no intervening def, its live
+ * interval doesn't extend back to the start of he program, and if too
+ * many registers did that we'd fail to register allocate.
+ */
+ if (((inst->qpu.flags.ac == V3D_QPU_COND_NONE &&
+ inst->qpu.flags.mc == V3D_QPU_COND_NONE) ||
+ inst->cond_is_exec_mask) &&
+ inst->qpu.alu.add.output_pack == V3D_QPU_PACK_NONE &&
+ inst->qpu.alu.mul.output_pack == V3D_QPU_PACK_NONE) {
+ BITSET_SET(block->def, var);
+ return;
+ }
+
+ /* Finally, look at the condition code and packing and mark it as a
+ * def. We need to make sure that we understand sequences
+ * instructions like:
+ *
+ * mov.zs t0, t1
+ * mov.zc t0, t2
+ *
+ * or:
+ *
+ * mmov t0.8a, t1
+ * mmov t0.8b, t2
+ * mmov t0.8c, t3
+ * mmov t0.8d, t4
+ *
+ * as defining the temp within the block, because otherwise dst's live
+ * range will get extended up the control flow to the top of the
+ * program.
+ */
+ struct partial_update_state *state =
+ get_partial_update_state(partial_update_ht, inst);
+ uint8_t mask = 0xf; /* XXX vir_channels_written(inst); */
+
+ if (inst->qpu.flags.ac == V3D_QPU_COND_NONE &&
+ inst->qpu.flags.mc == V3D_QPU_COND_NONE) {
+ state->channels |= mask;
+ } else {
+ for (int i = 0; i < 4; i++) {
+ if (!(mask & (1 << i)))
+ continue;
+
+ /* XXXif (state->insts[i] &&
+ state->insts[i]->cond ==
+ qpu_cond_complement(inst->cond))
+ state->channels |= 1 << i;
+ else
+ */
+ state->insts[i] = inst;
+ }
+ }
+
+ if (state->channels == 0xf)
+ BITSET_SET(block->def, var);
+}
+
+static void
+sf_state_clear(struct hash_table *partial_update_ht)
+{
+ struct hash_entry *entry;
+
+ hash_table_foreach(partial_update_ht, entry) {
+ struct partial_update_state *state = entry->data;
+
+ for (int i = 0; i < 4; i++) {
+ if (state->insts[i] &&
+ (state->insts[i]->qpu.flags.ac != V3D_QPU_COND_NONE ||
+ state->insts[i]->qpu.flags.mc != V3D_QPU_COND_NONE))
+ state->insts[i] = NULL;
+ }
+ }
+}
+
+/* Sets up the def/use arrays for when variables are used-before-defined or
+ * defined-before-used in the block.
+ *
+ * Also initializes the temp_start/temp_end to cover just the instruction IPs
+ * where the variable is used, which will be extended later in
+ * vir_compute_start_end().
+ */
+static void
+vir_setup_def_use(struct v3d_compile *c)
+{
+ struct hash_table *partial_update_ht =
+ _mesa_hash_table_create(c, int_hash, int_compare);
+ int ip = 0;
+
+ vir_for_each_block(block, c) {
+ block->start_ip = ip;
+
+ _mesa_hash_table_clear(partial_update_ht, NULL);
+
+ vir_for_each_inst(inst, block) {
+ for (int i = 0; i < vir_get_nsrc(inst); i++)
+ vir_setup_use(c, block, ip, inst->src[i]);
+
+ vir_setup_def(c, block, ip, partial_update_ht, inst);
+
+ if (false /* XXX inst->uf */)
+ sf_state_clear(partial_update_ht);
+
+ /* Payload registers: r0/1/2 contain W, centroid W,
+ * and Z at program start. Register allocation will
+ * force their nodes to R0/1/2.
+ */
+ if (inst->src[0].file == QFILE_REG) {
+ switch (inst->src[0].index) {
+ case 0:
+ case 1:
+ case 2:
+ c->temp_start[inst->dst.index] = 0;
+ break;
+ }
+ }
+
+ ip++;
+ }
+ block->end_ip = ip;
+ }
+
+ _mesa_hash_table_destroy(partial_update_ht, NULL);
+}
+
+static bool
+vir_live_variables_dataflow(struct v3d_compile *c, int bitset_words)
+{
+ bool cont = false;
+
+ vir_for_each_block_rev(block, c) {
+ /* Update live_out: Any successor using the variable
+ * on entrance needs us to have the variable live on
+ * exit.
+ */
+ vir_for_each_successor(succ, block) {
+ for (int i = 0; i < bitset_words; i++) {
+ BITSET_WORD new_live_out = (succ->live_in[i] &
+ ~block->live_out[i]);
+ if (new_live_out) {
+ block->live_out[i] |= new_live_out;
+ cont = true;
+ }
+ }
+ }
+
+ /* Update live_in */
+ for (int i = 0; i < bitset_words; i++) {
+ BITSET_WORD new_live_in = (block->use[i] |
+ (block->live_out[i] &
+ ~block->def[i]));
+ if (new_live_in & ~block->live_in[i]) {
+ block->live_in[i] |= new_live_in;
+ cont = true;
+ }
+ }
+ }
+
+ return cont;
+}
+
+/**
+ * Extend the start/end ranges for each variable to account for the
+ * new information calculated from control flow.
+ */
+static void
+vir_compute_start_end(struct v3d_compile *c, int num_vars)
+{
+ vir_for_each_block(block, c) {
+ for (int i = 0; i < num_vars; i++) {
+ if (BITSET_TEST(block->live_in, i)) {
+ c->temp_start[i] = MIN2(c->temp_start[i],
+ block->start_ip);
+ c->temp_end[i] = MAX2(c->temp_end[i],
+ block->start_ip);
+ }
+
+ if (BITSET_TEST(block->live_out, i)) {
+ c->temp_start[i] = MIN2(c->temp_start[i],
+ block->end_ip);
+ c->temp_end[i] = MAX2(c->temp_end[i],
+ block->end_ip);
+ }
+ }
+ }
+}
+
+void
+vir_calculate_live_intervals(struct v3d_compile *c)
+{
+ int bitset_words = BITSET_WORDS(c->num_temps);
+
+ /* If we called this function more than once, then we should be
+ * freeing the previous arrays.
+ */
+ assert(!c->temp_start);
+
+ c->temp_start = rzalloc_array(c, int, c->num_temps);
+ c->temp_end = rzalloc_array(c, int, c->num_temps);
+
+ for (int i = 0; i < c->num_temps; i++) {
+ c->temp_start[i] = MAX_INSTRUCTION;
+ c->temp_end[i] = -1;
+ }
+
+ vir_for_each_block(block, c) {
+ block->def = rzalloc_array(c, BITSET_WORD, bitset_words);
+ block->use = rzalloc_array(c, BITSET_WORD, bitset_words);
+ block->live_in = rzalloc_array(c, BITSET_WORD, bitset_words);
+ block->live_out = rzalloc_array(c, BITSET_WORD, bitset_words);
+ }
+
+ vir_setup_def_use(c);
+
+ while (vir_live_variables_dataflow(c, bitset_words))
+ ;
+
+ vir_compute_start_end(c, c->num_temps);
+}
diff --git a/lib/mesa/src/broadcom/compiler/vir_lower_uniforms.c b/lib/mesa/src/broadcom/compiler/vir_lower_uniforms.c
new file mode 100644
index 000000000..7f3bb8460
--- /dev/null
+++ b/lib/mesa/src/broadcom/compiler/vir_lower_uniforms.c
@@ -0,0 +1,209 @@
+/*
+ * Copyright © 2014 Broadcom
+ *
+ * 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.
+ */
+
+/**
+ * @file v3d_vir_lower_uniforms.c
+ *
+ * This is the pre-code-generation pass for fixing up instructions that try to
+ * read from multiple uniform values.
+ */
+
+#include "v3d_compiler.h"
+#include "util/hash_table.h"
+#include "util/u_math.h"
+
+static inline uint32_t
+index_hash(const void *key)
+{
+ return (uintptr_t)key;
+}
+
+static inline bool
+index_compare(const void *a, const void *b)
+{
+ return a == b;
+}
+
+static void
+add_uniform(struct hash_table *ht, struct qreg reg)
+{
+ struct hash_entry *entry;
+ void *key = (void *)(uintptr_t)(reg.index + 1);
+
+ entry = _mesa_hash_table_search(ht, key);
+ if (entry) {
+ entry->data++;
+ } else {
+ _mesa_hash_table_insert(ht, key, (void *)(uintptr_t)1);
+ }
+}
+
+static void
+remove_uniform(struct hash_table *ht, struct qreg reg)
+{
+ struct hash_entry *entry;
+ void *key = (void *)(uintptr_t)(reg.index + 1);
+
+ entry = _mesa_hash_table_search(ht, key);
+ assert(entry);
+ entry->data = (void *)(((uintptr_t) entry->data) - 1);
+ if (entry->data == NULL)
+ _mesa_hash_table_remove(ht, entry);
+}
+
+static bool
+is_lowerable_uniform(struct qinst *inst, int i)
+{
+ if (inst->src[i].file != QFILE_UNIF)
+ return false;
+ if (vir_has_implicit_uniform(inst))
+ return i != vir_get_implicit_uniform_src(inst);
+ return true;
+}
+
+/* Returns the number of different uniform values referenced by the
+ * instruction.
+ */
+static uint32_t
+vir_get_instruction_uniform_count(struct qinst *inst)
+{
+ uint32_t count = 0;
+
+ for (int i = 0; i < vir_get_nsrc(inst); i++) {
+ if (inst->src[i].file != QFILE_UNIF)
+ continue;
+
+ bool is_duplicate = false;
+ for (int j = 0; j < i; j++) {
+ if (inst->src[j].file == QFILE_UNIF &&
+ inst->src[j].index == inst->src[i].index) {
+ is_duplicate = true;
+ break;
+ }
+ }
+ if (!is_duplicate)
+ count++;
+ }
+
+ return count;
+}
+
+void
+vir_lower_uniforms(struct v3d_compile *c)
+{
+ struct hash_table *ht =
+ _mesa_hash_table_create(c, index_hash, index_compare);
+
+ /* Walk the instruction list, finding which instructions have more
+ * than one uniform referenced, and add those uniform values to the
+ * ht.
+ */
+ vir_for_each_inst_inorder(inst, c) {
+ uint32_t nsrc = vir_get_nsrc(inst);
+
+ if (vir_get_instruction_uniform_count(inst) <= 1)
+ continue;
+
+ for (int i = 0; i < nsrc; i++) {
+ if (is_lowerable_uniform(inst, i))
+ add_uniform(ht, inst->src[i]);
+ }
+ }
+
+ while (ht->entries) {
+ /* Find the most commonly used uniform in instructions that
+ * need a uniform lowered.
+ */
+ uint32_t max_count = 0;
+ uint32_t max_index = 0;
+ struct hash_entry *entry;
+ hash_table_foreach(ht, entry) {
+ uint32_t count = (uintptr_t)entry->data;
+ uint32_t index = (uintptr_t)entry->key - 1;
+ if (count > max_count) {
+ max_count = count;
+ max_index = index;
+ }
+ }
+
+ struct qreg unif = vir_reg(QFILE_UNIF, max_index);
+
+ /* Now, find the instructions using this uniform and make them
+ * reference a temp instead.
+ */
+ vir_for_each_block(block, c) {
+ struct qinst *mov = NULL;
+
+ vir_for_each_inst(inst, block) {
+ uint32_t nsrc = vir_get_nsrc(inst);
+
+ uint32_t count = vir_get_instruction_uniform_count(inst);
+
+ if (count <= 1)
+ continue;
+
+ /* If the block doesn't have a load of the
+ * uniform yet, add it. We could potentially
+ * do better and CSE MOVs from multiple blocks
+ * into dominating blocks, except that may
+ * cause troubles for register allocation.
+ */
+ if (!mov) {
+ mov = vir_mul_inst(V3D_QPU_M_MOV,
+ vir_get_temp(c),
+ unif, c->undef);
+ list_add(&mov->link,
+ &block->instructions);
+ c->defs[mov->dst.index] = mov;
+ }
+
+ bool removed = false;
+ for (int i = 0; i < nsrc; i++) {
+ if (is_lowerable_uniform(inst, i) &&
+ inst->src[i].index == max_index) {
+ inst->src[i].file =
+ mov->dst.file;
+ inst->src[i].index =
+ mov->dst.index;
+ remove_uniform(ht, unif);
+ removed = true;
+ }
+ }
+ if (removed)
+ count--;
+
+ /* If the instruction doesn't need lowering any more,
+ * then drop it from the list.
+ */
+ if (count <= 1) {
+ for (int i = 0; i < nsrc; i++) {
+ if (is_lowerable_uniform(inst, i))
+ remove_uniform(ht, inst->src[i]);
+ }
+ }
+ }
+ }
+ }
+
+ _mesa_hash_table_destroy(ht, NULL);
+}
diff --git a/lib/mesa/src/broadcom/compiler/vir_opt_copy_propagate.c b/lib/mesa/src/broadcom/compiler/vir_opt_copy_propagate.c
new file mode 100644
index 000000000..2a22a1b55
--- /dev/null
+++ b/lib/mesa/src/broadcom/compiler/vir_opt_copy_propagate.c
@@ -0,0 +1,233 @@
+/*
+ * Copyright © 2014 Broadcom
+ *
+ * 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.
+ */
+
+/**
+ * @file v3d_opt_copy_propagation.c
+ *
+ * This implements simple copy propagation for VIR without control flow.
+ *
+ * For each temp, it keeps a qreg of which source it was MOVed from, if it
+ * was. If we see that used later, we can just reuse the source value, since
+ * we know we don't have control flow, and we have SSA for our values so
+ * there's no killing to worry about.
+ */
+
+#include "v3d_compiler.h"
+
+static bool
+is_copy_mov(struct qinst *inst)
+{
+ if (!inst)
+ return false;
+
+ if (inst->qpu.type != V3D_QPU_INSTR_TYPE_ALU ||
+ (inst->qpu.alu.mul.op != V3D_QPU_M_FMOV &&
+ inst->qpu.alu.mul.op != V3D_QPU_M_MOV)) {
+ return false;
+ }
+
+ if (inst->dst.file != QFILE_TEMP)
+ return false;
+
+ if (inst->src[0].file != QFILE_TEMP &&
+ inst->src[0].file != QFILE_UNIF) {
+ return false;
+ }
+
+ if (inst->qpu.alu.add.output_pack != V3D_QPU_PACK_NONE ||
+ inst->qpu.alu.mul.output_pack != V3D_QPU_PACK_NONE) {
+ return false;
+ }
+
+ if (inst->qpu.flags.ac != V3D_QPU_COND_NONE ||
+ inst->qpu.flags.mc != V3D_QPU_COND_NONE) {
+ return false;
+ }
+
+ switch (inst->src[0].file) {
+ case QFILE_MAGIC:
+ /* No copy propagating from R3/R4/R5 -- the MOVs from those
+ * are there to register allocate values produced into R3/4/5
+ * to other regs (though hopefully r3/4/5).
+ */
+ switch (inst->src[0].index) {
+ case V3D_QPU_WADDR_R3:
+ case V3D_QPU_WADDR_R4:
+ case V3D_QPU_WADDR_R5:
+ return false;
+ default:
+ break;
+ }
+ break;
+
+ case QFILE_REG:
+ switch (inst->src[0].index) {
+ case 0:
+ case 1:
+ case 2:
+ /* MOVs from rf0/1/2 are only to track the live
+ * intervals for W/centroid W/Z.
+ */
+ return false;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ return true;
+}
+
+static bool
+vir_has_unpack(struct qinst *inst, int chan)
+{
+ assert(chan == 0 || chan == 1);
+
+ if (vir_is_add(inst)) {
+ if (chan == 0)
+ return inst->qpu.alu.add.a_unpack != V3D_QPU_UNPACK_NONE;
+ else
+ return inst->qpu.alu.add.b_unpack != V3D_QPU_UNPACK_NONE;
+ } else {
+ if (chan == 0)
+ return inst->qpu.alu.mul.a_unpack != V3D_QPU_UNPACK_NONE;
+ else
+ return inst->qpu.alu.mul.b_unpack != V3D_QPU_UNPACK_NONE;
+ }
+}
+
+static bool
+try_copy_prop(struct v3d_compile *c, struct qinst *inst, struct qinst **movs)
+{
+ bool debug = false;
+ bool progress = false;
+
+ for (int i = 0; i < vir_get_nsrc(inst); i++) {
+ if (inst->src[i].file != QFILE_TEMP)
+ continue;
+
+ /* We have two ways of finding MOVs we can copy propagate
+ * from. One is if it's an SSA def: then we can reuse it from
+ * any block in the program, as long as its source is also an
+ * SSA def. Alternatively, if it's in the "movs" array
+ * tracked within the block, then we know the sources for it
+ * haven't been changed since we saw the instruction within
+ * our block.
+ */
+ struct qinst *mov = movs[inst->src[i].index];
+ if (!mov) {
+ if (!is_copy_mov(c->defs[inst->src[i].index]))
+ continue;
+ mov = c->defs[inst->src[i].index];
+
+ if (mov->src[0].file == QFILE_TEMP &&
+ !c->defs[mov->src[0].index])
+ continue;
+ }
+
+ if (vir_has_unpack(mov, 0)) {
+ /* Make sure that the meaning of the unpack
+ * would be the same between the two
+ * instructions.
+ */
+ if (vir_is_float_input(inst) !=
+ vir_is_float_input(mov)) {
+ continue;
+ }
+ /* No composing the unpacks. */
+ if (vir_has_unpack(inst, i))
+ continue;
+ }
+
+ if (debug) {
+ fprintf(stderr, "Copy propagate: ");
+ vir_dump_inst(c, inst);
+ fprintf(stderr, "\n");
+ }
+
+ inst->src[i] = mov->src[0];
+ if (vir_has_unpack(mov, 0)) {
+ enum v3d_qpu_input_unpack unpack = mov->qpu.alu.mul.a_unpack;
+
+ vir_set_unpack(inst, i, unpack);
+ }
+
+ if (debug) {
+ fprintf(stderr, "to: ");
+ vir_dump_inst(c, inst);
+ fprintf(stderr, "\n");
+ }
+
+ progress = true;
+ }
+
+ return progress;
+}
+
+static void
+apply_kills(struct v3d_compile *c, struct qinst **movs, struct qinst *inst)
+{
+ if (inst->dst.file != QFILE_TEMP)
+ return;
+
+ for (int i = 0; i < c->num_temps; i++) {
+ if (movs[i] &&
+ (movs[i]->dst.index == inst->dst.index ||
+ (movs[i]->src[0].file == QFILE_TEMP &&
+ movs[i]->src[0].index == inst->dst.index))) {
+ movs[i] = NULL;
+ }
+ }
+}
+
+bool
+vir_opt_copy_propagate(struct v3d_compile *c)
+{
+ bool progress = false;
+ struct qinst **movs;
+
+ movs = ralloc_array(c, struct qinst *, c->num_temps);
+ if (!movs)
+ return false;
+
+ vir_for_each_block(block, c) {
+ /* The MOVs array tracks only available movs within the
+ * block.
+ */
+ memset(movs, 0, sizeof(struct qinst *) * c->num_temps);
+
+ vir_for_each_inst(inst, block) {
+ progress = try_copy_prop(c, inst, movs) || progress;
+
+ apply_kills(c, movs, inst);
+
+ if (is_copy_mov(inst))
+ movs[inst->dst.index] = inst;
+ }
+ }
+
+ ralloc_free(movs);
+
+ return progress;
+}
diff --git a/lib/mesa/src/broadcom/compiler/vir_opt_dead_code.c b/lib/mesa/src/broadcom/compiler/vir_opt_dead_code.c
new file mode 100644
index 000000000..9e0ef20b6
--- /dev/null
+++ b/lib/mesa/src/broadcom/compiler/vir_opt_dead_code.c
@@ -0,0 +1,162 @@
+/*
+ * Copyright © 2014 Broadcom
+ *
+ * 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.
+ */
+
+/**
+ * @file v3d_opt_dead_code.c
+ *
+ * This is a simple dead code eliminator for SSA values in VIR.
+ *
+ * It walks all the instructions finding what temps are used, then walks again
+ * to remove instructions writing unused temps.
+ *
+ * This is an inefficient implementation if you have long chains of
+ * instructions where the entire chain is dead, but we expect those to have
+ * been eliminated at the NIR level, and here we're just cleaning up small
+ * problems produced by NIR->VIR.
+ */
+
+#include "v3d_compiler.h"
+
+static bool debug;
+
+static void
+dce(struct v3d_compile *c, struct qinst *inst)
+{
+ if (debug) {
+ fprintf(stderr, "Removing: ");
+ vir_dump_inst(c, inst);
+ fprintf(stderr, "\n");
+ }
+ assert(inst->qpu.flags.apf == V3D_QPU_PF_NONE);
+ assert(inst->qpu.flags.mpf == V3D_QPU_PF_NONE);
+ vir_remove_instruction(c, inst);
+}
+
+static bool
+has_nonremovable_reads(struct v3d_compile *c, struct qinst *inst)
+{
+ for (int i = 0; i < vir_get_nsrc(inst); i++) {
+ if (inst->src[i].file == QFILE_VPM) {
+ /* Instance ID, Vertex ID: Should have been removed at
+ * the NIR level
+ */
+ if (inst->src[i].index == ~0)
+ return true;
+
+ uint32_t attr = inst->src[i].index / 4;
+ uint32_t offset = inst->src[i].index % 4;
+
+ if (c->vattr_sizes[attr] != offset)
+ return true;
+
+ /* Can't get rid of the last VPM read, or the
+ * simulator (at least) throws an error.
+ */
+ uint32_t total_size = 0;
+ for (uint32_t i = 0; i < ARRAY_SIZE(c->vattr_sizes); i++)
+ total_size += c->vattr_sizes[i];
+ if (total_size == 1)
+ return true;
+ }
+
+ /* Dead code removal of varyings is tricky, so just assert
+ * that it all happened at the NIR level.
+ */
+ if (inst->src[i].file == QFILE_VARY)
+ return true;
+ }
+
+ return false;
+}
+
+bool
+vir_opt_dead_code(struct v3d_compile *c)
+{
+ bool progress = false;
+ bool *used = calloc(c->num_temps, sizeof(bool));
+
+ vir_for_each_inst_inorder(inst, c) {
+ for (int i = 0; i < vir_get_nsrc(inst); i++) {
+ if (inst->src[i].file == QFILE_TEMP)
+ used[inst->src[i].index] = true;
+ }
+ }
+
+ vir_for_each_block(block, c) {
+ vir_for_each_inst_safe(inst, block) {
+ if (inst->dst.file != QFILE_NULL &&
+ !(inst->dst.file == QFILE_TEMP &&
+ !used[inst->dst.index])) {
+ continue;
+ }
+
+ if (vir_has_side_effects(c, inst))
+ continue;
+
+ if (inst->qpu.flags.apf != V3D_QPU_PF_NONE ||
+ inst->qpu.flags.mpf != V3D_QPU_PF_NONE||
+ has_nonremovable_reads(c, inst)) {
+ /* If we can't remove the instruction, but we
+ * don't need its destination value, just
+ * remove the destination. The register
+ * allocator would trivially color it and it
+ * wouldn't cause any register pressure, but
+ * it's nicer to read the VIR code without
+ * unused destination regs.
+ */
+ if (inst->dst.file == QFILE_TEMP) {
+ if (debug) {
+ fprintf(stderr,
+ "Removing dst from: ");
+ vir_dump_inst(c, inst);
+ fprintf(stderr, "\n");
+ }
+ c->defs[inst->dst.index] = NULL;
+ inst->dst.file = QFILE_NULL;
+ progress = true;
+ }
+ continue;
+ }
+
+ for (int i = 0; i < vir_get_nsrc(inst); i++) {
+ if (inst->src[i].file != QFILE_VPM)
+ continue;
+ uint32_t attr = inst->src[i].index / 4;
+ uint32_t offset = (inst->src[i].index % 4);
+
+ if (c->vattr_sizes[attr] == offset) {
+ c->num_inputs--;
+ c->vattr_sizes[attr]--;
+ }
+ }
+
+ dce(c, inst);
+ progress = true;
+ continue;
+ }
+ }
+
+ free(used);
+
+ return progress;
+}
diff --git a/lib/mesa/src/broadcom/compiler/vir_register_allocate.c b/lib/mesa/src/broadcom/compiler/vir_register_allocate.c
new file mode 100644
index 000000000..9ebf2cd69
--- /dev/null
+++ b/lib/mesa/src/broadcom/compiler/vir_register_allocate.c
@@ -0,0 +1,254 @@
+/*
+ * Copyright © 2014 Broadcom
+ *
+ * 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 "util/ralloc.h"
+#include "util/register_allocate.h"
+#include "v3d_compiler.h"
+
+#define QPU_R(i) { .magic = false, .index = i }
+
+#define ACC_INDEX 0
+#define ACC_COUNT 5
+#define PHYS_INDEX (ACC_INDEX + ACC_COUNT)
+#define PHYS_COUNT 64
+
+bool
+vir_init_reg_sets(struct v3d_compiler *compiler)
+{
+ compiler->regs = ra_alloc_reg_set(compiler, PHYS_INDEX + PHYS_COUNT,
+ true);
+ if (!compiler->regs)
+ return false;
+
+ /* Allocate 3 regfile classes, for the ways the physical register file
+ * can be divided up for fragment shader threading.
+ */
+ for (int threads = 0; threads < 3; threads++) {
+ compiler->reg_class[threads] =
+ ra_alloc_reg_class(compiler->regs);
+
+ for (int i = PHYS_INDEX;
+ i < PHYS_INDEX + (PHYS_COUNT >> threads); i++) {
+ ra_class_add_reg(compiler->regs,
+ compiler->reg_class[threads], i);
+ }
+
+ for (int i = ACC_INDEX + 0; i < ACC_INDEX + ACC_COUNT; i++) {
+ ra_class_add_reg(compiler->regs,
+ compiler->reg_class[threads], i);
+ }
+ }
+
+ ra_set_finalize(compiler->regs, NULL);
+
+ return true;
+}
+
+struct node_to_temp_map {
+ uint32_t temp;
+ uint32_t priority;
+};
+
+static int
+node_to_temp_priority(const void *in_a, const void *in_b)
+{
+ const struct node_to_temp_map *a = in_a;
+ const struct node_to_temp_map *b = in_b;
+
+ return a->priority - b->priority;
+}
+
+#define CLASS_BIT_PHYS (1 << 0)
+#define CLASS_BIT_R0_R2 (1 << 1)
+#define CLASS_BIT_R3 (1 << 2)
+#define CLASS_BIT_R4 (1 << 3)
+
+/**
+ * Returns a mapping from QFILE_TEMP indices to struct qpu_regs.
+ *
+ * The return value should be freed by the caller.
+ */
+struct qpu_reg *
+v3d_register_allocate(struct v3d_compile *c)
+{
+ struct node_to_temp_map map[c->num_temps];
+ uint32_t temp_to_node[c->num_temps];
+ uint8_t class_bits[c->num_temps];
+ struct qpu_reg *temp_registers = calloc(c->num_temps,
+ sizeof(*temp_registers));
+ int acc_nodes[ACC_COUNT];
+
+ struct ra_graph *g = ra_alloc_interference_graph(c->compiler->regs,
+ c->num_temps +
+ ARRAY_SIZE(acc_nodes));
+
+ /* Make some fixed nodes for the accumulators, which we will need to
+ * interfere with when ops have implied r3/r4 writes or for the thread
+ * switches. We could represent these as classes for the nodes to
+ * live in, but the classes take up a lot of memory to set up, so we
+ * don't want to make too many.
+ */
+ for (int i = 0; i < ARRAY_SIZE(acc_nodes); i++) {
+ acc_nodes[i] = c->num_temps + i;
+ ra_set_node_reg(g, acc_nodes[i], ACC_INDEX + i);
+ }
+
+ /* Compute the live ranges so we can figure out interference. */
+ vir_calculate_live_intervals(c);
+
+ for (uint32_t i = 0; i < c->num_temps; i++) {
+ map[i].temp = i;
+ map[i].priority = c->temp_end[i] - c->temp_start[i];
+ }
+ qsort(map, c->num_temps, sizeof(map[0]), node_to_temp_priority);
+ for (uint32_t i = 0; i < c->num_temps; i++) {
+ temp_to_node[map[i].temp] = i;
+ }
+
+ /* Figure out our register classes and preallocated registers. We
+ * start with any temp being able to be in any file, then instructions
+ * incrementally remove bits that the temp definitely can't be in.
+ */
+ memset(class_bits,
+ CLASS_BIT_PHYS | CLASS_BIT_R0_R2 | CLASS_BIT_R3 | CLASS_BIT_R4,
+ sizeof(class_bits));
+
+ int ip = 0;
+ vir_for_each_inst_inorder(inst, c) {
+ /* If the instruction writes r3/r4 (and optionally moves its
+ * result to a temp), nothing else can be stored in r3/r4 across
+ * it.
+ */
+ if (vir_writes_r3(inst)) {
+ for (int i = 0; i < c->num_temps; i++) {
+ if (c->temp_start[i] < ip &&
+ c->temp_end[i] > ip) {
+ ra_add_node_interference(g,
+ temp_to_node[i],
+ acc_nodes[3]);
+ }
+ }
+ }
+ if (vir_writes_r4(inst)) {
+ for (int i = 0; i < c->num_temps; i++) {
+ if (c->temp_start[i] < ip &&
+ c->temp_end[i] > ip) {
+ ra_add_node_interference(g,
+ temp_to_node[i],
+ acc_nodes[4]);
+ }
+ }
+ }
+
+ if (inst->src[0].file == QFILE_REG) {
+ switch (inst->src[0].index) {
+ case 0:
+ case 1:
+ case 2:
+ /* Payload setup instructions: Force allocate
+ * the dst to the given register (so the MOV
+ * will disappear).
+ */
+ assert(inst->qpu.alu.mul.op == V3D_QPU_M_MOV);
+ assert(inst->dst.file == QFILE_TEMP);
+ ra_set_node_reg(g,
+ temp_to_node[inst->dst.index],
+ PHYS_INDEX +
+ inst->src[0].index);
+ break;
+ }
+ }
+
+#if 0
+ switch (inst->op) {
+ case QOP_THRSW:
+ /* All accumulators are invalidated across a thread
+ * switch.
+ */
+ for (int i = 0; i < c->num_temps; i++) {
+ if (c->temp_start[i] < ip && c->temp_end[i] > ip)
+ class_bits[i] &= ~(CLASS_BIT_R0_R3 |
+ CLASS_BIT_R4);
+ }
+ break;
+
+ default:
+ break;
+ }
+#endif
+
+ ip++;
+ }
+
+ for (uint32_t i = 0; i < c->num_temps; i++) {
+ ra_set_node_class(g, temp_to_node[i],
+ c->compiler->reg_class[c->fs_threaded]);
+ }
+
+ for (uint32_t i = 0; i < c->num_temps; i++) {
+ for (uint32_t j = i + 1; j < c->num_temps; j++) {
+ if (!(c->temp_start[i] >= c->temp_end[j] ||
+ c->temp_start[j] >= c->temp_end[i])) {
+ ra_add_node_interference(g,
+ temp_to_node[i],
+ temp_to_node[j]);
+ }
+ }
+ }
+
+ bool ok = ra_allocate(g);
+ if (!ok) {
+ if (!c->fs_threaded) {
+ fprintf(stderr, "Failed to register allocate:\n");
+ vir_dump(c);
+ }
+
+ c->failed = true;
+ free(temp_registers);
+ return NULL;
+ }
+
+ for (uint32_t i = 0; i < c->num_temps; i++) {
+ int ra_reg = ra_get_node_reg(g, temp_to_node[i]);
+ if (ra_reg < PHYS_INDEX) {
+ temp_registers[i].magic = true;
+ temp_registers[i].index = (V3D_QPU_WADDR_R0 +
+ ra_reg - ACC_INDEX);
+ } else {
+ temp_registers[i].magic = false;
+ temp_registers[i].index = ra_reg - PHYS_INDEX;
+ }
+
+ /* If the value's never used, just write to the NOP register
+ * for clarity in debug output.
+ */
+ if (c->temp_start[i] == c->temp_end[i]) {
+ temp_registers[i].magic = true;
+ temp_registers[i].index = V3D_QPU_WADDR_NOP;
+ }
+ }
+
+ ralloc_free(g);
+
+ return temp_registers;
+}
diff --git a/lib/mesa/src/broadcom/compiler/vir_to_qpu.c b/lib/mesa/src/broadcom/compiler/vir_to_qpu.c
new file mode 100644
index 000000000..eeb7b0bc2
--- /dev/null
+++ b/lib/mesa/src/broadcom/compiler/vir_to_qpu.c
@@ -0,0 +1,359 @@
+/*
+ * Copyright © 2016 Broadcom
+ *
+ * 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 "compiler/v3d_compiler.h"
+#include "qpu/qpu_instr.h"
+#include "qpu/qpu_disasm.h"
+
+static inline struct qpu_reg
+qpu_reg(int index)
+{
+ struct qpu_reg reg = {
+ .magic = false,
+ .index = index,
+ };
+ return reg;
+}
+
+static inline struct qpu_reg
+qpu_magic(enum v3d_qpu_waddr waddr)
+{
+ struct qpu_reg reg = {
+ .magic = true,
+ .index = waddr,
+ };
+ return reg;
+}
+
+static inline struct qpu_reg
+qpu_acc(int acc)
+{
+ return qpu_magic(V3D_QPU_WADDR_R0 + acc);
+}
+
+struct v3d_qpu_instr
+v3d_qpu_nop(void)
+{
+ struct v3d_qpu_instr instr = {
+ .type = V3D_QPU_INSTR_TYPE_ALU,
+ .alu = {
+ .add = {
+ .op = V3D_QPU_A_NOP,
+ .waddr = V3D_QPU_WADDR_NOP,
+ .magic_write = true,
+ },
+ .mul = {
+ .op = V3D_QPU_M_NOP,
+ .waddr = V3D_QPU_WADDR_NOP,
+ .magic_write = true,
+ },
+ }
+ };
+
+ return instr;
+}
+
+static struct qinst *
+vir_nop(void)
+{
+ struct qreg undef = { QFILE_NULL, 0 };
+ struct qinst *qinst = vir_add_inst(V3D_QPU_A_NOP, undef, undef, undef);
+
+ return qinst;
+}
+
+static struct qinst *
+new_qpu_nop_before(struct qinst *inst)
+{
+ struct qinst *q = vir_nop();
+
+ list_addtail(&q->link, &inst->link);
+
+ return q;
+}
+
+static void
+new_ldunif_instr(struct qinst *inst, int i)
+{
+ struct qinst *ldunif = new_qpu_nop_before(inst);
+
+ ldunif->qpu.sig.ldunif = true;
+ assert(inst->src[i].file == QFILE_UNIF);
+ ldunif->uniform = inst->src[i].index;
+}
+
+/**
+ * Allocates the src register (accumulator or register file) into the RADDR
+ * fields of the instruction.
+ */
+static void
+set_src(struct v3d_qpu_instr *instr, enum v3d_qpu_mux *mux, struct qpu_reg src)
+{
+ if (src.magic) {
+ assert(src.index >= V3D_QPU_WADDR_R0 &&
+ src.index <= V3D_QPU_WADDR_R5);
+ *mux = src.index - V3D_QPU_WADDR_R0 + V3D_QPU_MUX_R0;
+ return;
+ }
+
+ if (instr->alu.add.a != V3D_QPU_MUX_A &&
+ instr->alu.add.b != V3D_QPU_MUX_A &&
+ instr->alu.mul.a != V3D_QPU_MUX_A &&
+ instr->alu.mul.b != V3D_QPU_MUX_A) {
+ instr->raddr_a = src.index;
+ *mux = V3D_QPU_MUX_A;
+ } else {
+ if (instr->raddr_a == src.index) {
+ *mux = V3D_QPU_MUX_A;
+ } else {
+ assert(!(instr->alu.add.a == V3D_QPU_MUX_B &&
+ instr->alu.add.b == V3D_QPU_MUX_B &&
+ instr->alu.mul.a == V3D_QPU_MUX_B &&
+ instr->alu.mul.b == V3D_QPU_MUX_B) ||
+ src.index == instr->raddr_b);
+
+ instr->raddr_b = src.index;
+ *mux = V3D_QPU_MUX_B;
+ }
+ }
+}
+
+static void
+v3d_generate_code_block(struct v3d_compile *c,
+ struct qblock *block,
+ struct qpu_reg *temp_registers)
+{
+ int last_vpm_read_index = -1;
+
+ vir_for_each_inst(qinst, block) {
+#if 0
+ fprintf(stderr, "translating qinst to qpu: ");
+ vir_dump_inst(c, qinst);
+ fprintf(stderr, "\n");
+#endif
+
+ struct qinst *temp;
+
+ if (vir_has_implicit_uniform(qinst)) {
+ int src = vir_get_implicit_uniform_src(qinst);
+ assert(qinst->src[src].file == QFILE_UNIF);
+ qinst->uniform = qinst->src[src].index;
+ c->num_uniforms++;
+ }
+
+ int nsrc = vir_get_non_sideband_nsrc(qinst);
+ struct qpu_reg src[ARRAY_SIZE(qinst->src)];
+ bool emitted_ldunif = false;
+ for (int i = 0; i < nsrc; i++) {
+ int index = qinst->src[i].index;
+ switch (qinst->src[i].file) {
+ case QFILE_REG:
+ src[i] = qpu_reg(qinst->src[i].index);
+ break;
+ case QFILE_MAGIC:
+ src[i] = qpu_magic(qinst->src[i].index);
+ break;
+ case QFILE_NULL:
+ case QFILE_LOAD_IMM:
+ src[i] = qpu_acc(0);
+ break;
+ case QFILE_TEMP:
+ src[i] = temp_registers[index];
+ break;
+ case QFILE_UNIF:
+ if (!emitted_ldunif) {
+ new_ldunif_instr(qinst, i);
+ c->num_uniforms++;
+ emitted_ldunif = true;
+ }
+
+ src[i] = qpu_acc(5);
+ break;
+ case QFILE_VARY:
+ temp = new_qpu_nop_before(qinst);
+ temp->qpu.sig.ldvary = true;
+
+ src[i] = qpu_acc(3);
+ break;
+ case QFILE_SMALL_IMM:
+ abort(); /* XXX */
+#if 0
+ src[i].mux = QPU_MUX_SMALL_IMM;
+ src[i].addr = qpu_encode_small_immediate(qinst->src[i].index);
+ /* This should only have returned a valid
+ * small immediate field, not ~0 for failure.
+ */
+ assert(src[i].addr <= 47);
+#endif
+ break;
+
+ case QFILE_VPM:
+ assert((int)qinst->src[i].index >=
+ last_vpm_read_index);
+ (void)last_vpm_read_index;
+ last_vpm_read_index = qinst->src[i].index;
+
+ temp = new_qpu_nop_before(qinst);
+ temp->qpu.sig.ldvpm = true;
+
+ src[i] = qpu_acc(3);
+ break;
+
+ case QFILE_TLB:
+ case QFILE_TLBU:
+ unreachable("bad vir src file");
+ }
+ }
+
+ struct qpu_reg dst;
+ switch (qinst->dst.file) {
+ case QFILE_NULL:
+ dst = qpu_magic(V3D_QPU_WADDR_NOP);
+ break;
+
+ case QFILE_REG:
+ dst = qpu_reg(qinst->dst.index);
+ break;
+
+ case QFILE_MAGIC:
+ dst = qpu_magic(qinst->dst.index);
+ break;
+
+ case QFILE_TEMP:
+ dst = temp_registers[qinst->dst.index];
+ break;
+
+ case QFILE_VPM:
+ dst = qpu_magic(V3D_QPU_WADDR_VPM);
+ break;
+
+ case QFILE_TLB:
+ dst = qpu_magic(V3D_QPU_WADDR_TLB);
+ break;
+
+ case QFILE_TLBU:
+ dst = qpu_magic(V3D_QPU_WADDR_TLBU);
+ break;
+
+ case QFILE_VARY:
+ case QFILE_UNIF:
+ case QFILE_SMALL_IMM:
+ case QFILE_LOAD_IMM:
+ assert(!"not reached");
+ break;
+ }
+
+ if (qinst->qpu.type == V3D_QPU_INSTR_TYPE_ALU) {
+ if (qinst->qpu.alu.add.op != V3D_QPU_A_NOP) {
+ assert(qinst->qpu.alu.mul.op == V3D_QPU_M_NOP);
+ if (nsrc >= 1) {
+ set_src(&qinst->qpu,
+ &qinst->qpu.alu.add.a, src[0]);
+ }
+ if (nsrc >= 2) {
+ set_src(&qinst->qpu,
+ &qinst->qpu.alu.add.b, src[1]);
+ }
+
+ qinst->qpu.alu.add.waddr = dst.index;
+ qinst->qpu.alu.add.magic_write = dst.magic;
+ } else {
+ if (nsrc >= 1) {
+ set_src(&qinst->qpu,
+ &qinst->qpu.alu.mul.a, src[0]);
+ }
+ if (nsrc >= 2) {
+ set_src(&qinst->qpu,
+ &qinst->qpu.alu.mul.b, src[1]);
+ }
+
+ qinst->qpu.alu.mul.waddr = dst.index;
+ qinst->qpu.alu.mul.magic_write = dst.magic;
+ }
+ } else {
+ assert(qinst->qpu.type == V3D_QPU_INSTR_TYPE_BRANCH);
+ }
+ }
+}
+
+
+static void
+v3d_dump_qpu(struct v3d_compile *c)
+{
+ fprintf(stderr, "%s prog %d/%d QPU:\n",
+ vir_get_stage_name(c),
+ c->program_id, c->variant_id);
+
+ for (int i = 0; i < c->qpu_inst_count; i++) {
+ const char *str = v3d_qpu_disasm(c->devinfo, c->qpu_insts[i]);
+ fprintf(stderr, "0x%016"PRIx64" %s\n", c->qpu_insts[i], str);
+ }
+ fprintf(stderr, "\n");
+}
+
+void
+v3d_vir_to_qpu(struct v3d_compile *c)
+{
+ struct qpu_reg *temp_registers = v3d_register_allocate(c);
+ struct qblock *end_block = list_last_entry(&c->blocks,
+ struct qblock, link);
+
+ /* Reset the uniform count to how many will be actually loaded by the
+ * generated QPU code.
+ */
+ c->num_uniforms = 0;
+
+ vir_for_each_block(block, c)
+ v3d_generate_code_block(c, block, temp_registers);
+
+ struct qinst *thrsw = vir_nop();
+ list_addtail(&thrsw->link, &end_block->instructions);
+ thrsw->qpu.sig.thrsw = true;
+
+ uint32_t cycles = v3d_qpu_schedule_instructions(c);
+
+ c->qpu_insts = rzalloc_array(c, uint64_t, c->qpu_inst_count);
+ int i = 0;
+ vir_for_each_inst_inorder(inst, c) {
+ bool ok = v3d_qpu_instr_pack(c->devinfo, &inst->qpu,
+ &c->qpu_insts[i++]);
+ assert(ok); (void) ok;
+ }
+ assert(i == c->qpu_inst_count);
+
+ if (V3D_DEBUG & V3D_DEBUG_SHADERDB) {
+ fprintf(stderr, "SHADER-DB: %s prog %d/%d: %d estimated cycles\n",
+ vir_get_stage_name(c),
+ c->program_id, c->variant_id,
+ cycles);
+ }
+
+ if (V3D_DEBUG & (V3D_DEBUG_QPU |
+ v3d_debug_flag_for_shader_stage(c->s->info.stage))) {
+ v3d_dump_qpu(c);
+ }
+
+ qpu_validate(c);
+
+ free(temp_registers);
+}
diff --git a/lib/mesa/src/broadcom/qpu/qpu_disasm.c b/lib/mesa/src/broadcom/qpu/qpu_disasm.c
new file mode 100644
index 000000000..5ee834852
--- /dev/null
+++ b/lib/mesa/src/broadcom/qpu/qpu_disasm.c
@@ -0,0 +1,298 @@
+/*
+ * Copyright © 2016 Broadcom
+ *
+ * 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 <string.h>
+#include <stdio.h>
+#include "util/ralloc.h"
+
+#include "broadcom/common/v3d_device_info.h"
+#include "qpu_instr.h"
+#include "qpu_disasm.h"
+
+struct disasm_state {
+ const struct v3d_device_info *devinfo;
+ char *string;
+ size_t offset;
+};
+
+static void
+append(struct disasm_state *disasm, const char *fmt, ...)
+{
+ va_list args;
+ va_start(args, fmt);
+ ralloc_vasprintf_rewrite_tail(&disasm->string,
+ &disasm->offset,
+ fmt, args);
+ va_end(args);
+}
+
+static void
+pad_to(struct disasm_state *disasm, int n)
+{
+ /* FIXME: Do a single append somehow. */
+ while (disasm->offset < n)
+ append(disasm, " ");
+}
+
+
+static void
+v3d_qpu_disasm_raddr(struct disasm_state *disasm,
+ const struct v3d_qpu_instr *instr, uint8_t mux)
+{
+ if (mux == V3D_QPU_MUX_A) {
+ append(disasm, "rf%d", instr->raddr_a);
+ } else if (mux == V3D_QPU_MUX_B) {
+ append(disasm, "rf%d", instr->raddr_b);
+ } else {
+ append(disasm, "r%d", mux);
+ }
+}
+
+static void
+v3d_qpu_disasm_waddr(struct disasm_state *disasm, uint32_t waddr, bool magic)
+{
+ if (!magic) {
+ append(disasm, "rf%d", waddr);
+ return;
+ }
+
+ const char *name = v3d_qpu_magic_waddr_name(waddr);
+ if (name)
+ append(disasm, "%s", name);
+ else
+ append(disasm, "waddr UNKNOWN %d", waddr);
+}
+
+static void
+v3d_qpu_disasm_add(struct disasm_state *disasm,
+ const struct v3d_qpu_instr *instr)
+{
+ bool has_dst = v3d_qpu_add_op_has_dst(instr->alu.add.op);
+ int num_src = v3d_qpu_add_op_num_src(instr->alu.add.op);
+
+ append(disasm, "%s", v3d_qpu_add_op_name(instr->alu.add.op));
+ append(disasm, "%s", v3d_qpu_cond_name(instr->flags.ac));
+ append(disasm, "%s", v3d_qpu_pf_name(instr->flags.apf));
+ append(disasm, "%s", v3d_qpu_uf_name(instr->flags.auf));
+
+ append(disasm, " ");
+
+ if (has_dst) {
+ v3d_qpu_disasm_waddr(disasm, instr->alu.add.waddr,
+ instr->alu.add.magic_write);
+ append(disasm, v3d_qpu_pack_name(instr->alu.add.output_pack));
+ }
+
+ if (num_src >= 1) {
+ if (has_dst)
+ append(disasm, ", ");
+ v3d_qpu_disasm_raddr(disasm, instr, instr->alu.add.a);
+ append(disasm, "%s",
+ v3d_qpu_unpack_name(instr->alu.add.a_unpack));
+ }
+
+ if (num_src >= 2) {
+ append(disasm, ", ");
+ v3d_qpu_disasm_raddr(disasm, instr, instr->alu.add.b);
+ append(disasm, "%s",
+ v3d_qpu_unpack_name(instr->alu.add.b_unpack));
+ }
+}
+
+static void
+v3d_qpu_disasm_mul(struct disasm_state *disasm,
+ const struct v3d_qpu_instr *instr)
+{
+ bool has_dst = v3d_qpu_mul_op_has_dst(instr->alu.mul.op);
+ int num_src = v3d_qpu_mul_op_num_src(instr->alu.mul.op);
+
+ pad_to(disasm, 21);
+ append(disasm, "; ");
+
+ append(disasm, "%s", v3d_qpu_mul_op_name(instr->alu.mul.op));
+ append(disasm, "%s", v3d_qpu_cond_name(instr->flags.mc));
+ append(disasm, "%s", v3d_qpu_pf_name(instr->flags.mpf));
+ append(disasm, "%s", v3d_qpu_uf_name(instr->flags.muf));
+
+ if (instr->alu.mul.op == V3D_QPU_M_NOP)
+ return;
+
+ append(disasm, " ");
+
+ if (has_dst) {
+ v3d_qpu_disasm_waddr(disasm, instr->alu.mul.waddr,
+ instr->alu.mul.magic_write);
+ append(disasm, v3d_qpu_pack_name(instr->alu.mul.output_pack));
+ }
+
+ if (num_src >= 1) {
+ if (has_dst)
+ append(disasm, ", ");
+ v3d_qpu_disasm_raddr(disasm, instr, instr->alu.mul.a);
+ append(disasm, "%s",
+ v3d_qpu_unpack_name(instr->alu.mul.a_unpack));
+ }
+
+ if (num_src >= 2) {
+ append(disasm, ", ");
+ v3d_qpu_disasm_raddr(disasm, instr, instr->alu.mul.b);
+ append(disasm, "%s",
+ v3d_qpu_unpack_name(instr->alu.mul.b_unpack));
+ }
+}
+
+static void
+v3d_qpu_disasm_sig(struct disasm_state *disasm,
+ const struct v3d_qpu_instr *instr)
+{
+ const struct v3d_qpu_sig *sig = &instr->sig;
+
+ if (!sig->thrsw &&
+ !sig->ldvary &&
+ !sig->ldvpm &&
+ !sig->ldtmu &&
+ !sig->ldunif &&
+ !sig->wrtmuc) {
+ return;
+ }
+
+ pad_to(disasm, 41);
+
+ if (sig->thrsw)
+ append(disasm, "; thrsw");
+ if (sig->ldvary)
+ append(disasm, "; ldvary");
+ if (sig->ldvpm)
+ append(disasm, "; ldvpm");
+ if (sig->ldtmu)
+ append(disasm, "; ldtmu");
+ if (sig->ldunif)
+ append(disasm, "; ldunif");
+ if (sig->wrtmuc)
+ append(disasm, "; wrtmuc");
+}
+
+static void
+v3d_qpu_disasm_alu(struct disasm_state *disasm,
+ const struct v3d_qpu_instr *instr)
+{
+ v3d_qpu_disasm_add(disasm, instr);
+ v3d_qpu_disasm_mul(disasm, instr);
+ v3d_qpu_disasm_sig(disasm, instr);
+}
+
+static void
+v3d_qpu_disasm_branch(struct disasm_state *disasm,
+ const struct v3d_qpu_instr *instr)
+{
+ append(disasm, "b");
+ if (instr->branch.ub)
+ append(disasm, "u");
+ append(disasm, "%s", v3d_qpu_branch_cond_name(instr->branch.cond));
+ append(disasm, "%s", v3d_qpu_msfign_name(instr->branch.msfign));
+
+ switch (instr->branch.bdi) {
+ case V3D_QPU_BRANCH_DEST_ABS:
+ append(disasm, " zero_addr+0x%08x", instr->branch.offset);
+ break;
+
+ case V3D_QPU_BRANCH_DEST_REL:
+ append(disasm, " %d", instr->branch.offset);
+ break;
+
+ case V3D_QPU_BRANCH_DEST_LINK_REG:
+ append(disasm, " lri");
+ break;
+
+ case V3D_QPU_BRANCH_DEST_REGFILE:
+ append(disasm, " rf%d", instr->branch.raddr_a);
+ break;
+ }
+
+ if (instr->branch.ub) {
+ switch (instr->branch.bdu) {
+ case V3D_QPU_BRANCH_DEST_ABS:
+ append(disasm, ", a:unif");
+ break;
+
+ case V3D_QPU_BRANCH_DEST_REL:
+ append(disasm, ", r:unif");
+ break;
+
+ case V3D_QPU_BRANCH_DEST_LINK_REG:
+ append(disasm, ", lri");
+ break;
+
+ case V3D_QPU_BRANCH_DEST_REGFILE:
+ append(disasm, ", rf%d", instr->branch.raddr_a);
+ break;
+ }
+ }
+}
+
+const char *
+v3d_qpu_decode(const struct v3d_device_info *devinfo,
+ const struct v3d_qpu_instr *instr)
+{
+ struct disasm_state disasm = {
+ .string = rzalloc_size(NULL, 1),
+ .offset = 0,
+ .devinfo = devinfo,
+ };
+
+ switch (instr->type) {
+ case V3D_QPU_INSTR_TYPE_ALU:
+ v3d_qpu_disasm_alu(&disasm, instr);
+ break;
+
+ case V3D_QPU_INSTR_TYPE_BRANCH:
+ v3d_qpu_disasm_branch(&disasm, instr);
+ break;
+ }
+
+ return disasm.string;
+}
+
+/**
+ * Returns a string containing the disassembled representation of the QPU
+ * instruction. It is the caller's responsibility to free the return value
+ * with ralloc_free().
+ */
+const char *
+v3d_qpu_disasm(const struct v3d_device_info *devinfo, uint64_t inst)
+{
+ struct v3d_qpu_instr instr;
+ bool ok = v3d_qpu_instr_unpack(devinfo, inst, &instr);
+ assert(ok); (void)ok;
+
+ return v3d_qpu_decode(devinfo, &instr);
+}
+
+void
+v3d_qpu_dump(const struct v3d_device_info *devinfo,
+ const struct v3d_qpu_instr *instr)
+{
+ const char *decoded = v3d_qpu_decode(devinfo, instr);
+ fprintf(stderr, "%s", decoded);
+ ralloc_free((char *)decoded);
+}
diff --git a/lib/mesa/src/broadcom/qpu/qpu_disasm.h b/lib/mesa/src/broadcom/qpu/qpu_disasm.h
new file mode 100644
index 000000000..efdf8ddb5
--- /dev/null
+++ b/lib/mesa/src/broadcom/qpu/qpu_disasm.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright © 2016 Broadcom
+ *
+ * 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.
+ */
+
+#ifndef VC5_QPU_DISASM_H
+#define VC5_QPU_DISASM_H
+
+#include "broadcom/common/v3d_device_info.h"
+
+struct v3d_qpu_instr;
+
+const char *v3d_qpu_decode(const struct v3d_device_info *devinfo, const
+ struct v3d_qpu_instr *instr);
+
+const char *v3d_qpu_disasm(const struct v3d_device_info *devinfo, uint64_t inst);
+
+void v3d_qpu_dump(const struct v3d_device_info *devinfo, const
+ struct v3d_qpu_instr *instr);
+
+#endif /* VC5_QPU_DISASM_H */
diff --git a/lib/mesa/src/broadcom/qpu/qpu_instr.c b/lib/mesa/src/broadcom/qpu/qpu_instr.c
new file mode 100644
index 000000000..7499170de
--- /dev/null
+++ b/lib/mesa/src/broadcom/qpu/qpu_instr.c
@@ -0,0 +1,645 @@
+/*
+ * Copyright © 2016 Broadcom
+ *
+ * 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 <stdlib.h>
+#include "util/macros.h"
+#include "qpu_instr.h"
+
+#ifndef QPU_MASK
+#define QPU_MASK(high, low) ((((uint64_t)1<<((high)-(low)+1))-1)<<(low))
+/* Using the GNU statement expression extension */
+#define QPU_SET_FIELD(value, field) \
+ ({ \
+ uint64_t fieldval = (uint64_t)(value) << field ## _SHIFT; \
+ assert((fieldval & ~ field ## _MASK) == 0); \
+ fieldval & field ## _MASK; \
+ })
+
+#define QPU_GET_FIELD(word, field) ((uint32_t)(((word) & field ## _MASK) >> field ## _SHIFT))
+
+#define QPU_UPDATE_FIELD(inst, value, field) \
+ (((inst) & ~(field ## _MASK)) | QPU_SET_FIELD(value, field))
+#endif /* QPU_MASK */
+
+#define VC5_QPU_OP_MUL_SHIFT 58
+#define VC5_QPU_OP_MUL_MASK QPU_MASK(63, 58)
+
+#define VC5_QPU_SIG_SHIFT 53
+#define VC5_QPU_SIG_MASK QPU_MASK(57, 53)
+# define VC5_QPU_SIG_THRSW_BIT 0x1
+# define VC5_QPU_SIG_LDUNIF_BIT 0x2
+# define VC5_QPU_SIG_LDTMU_BIT 0x4
+# define VC5_QPU_SIG_LDVARY_BIT 0x8
+
+#define VC5_QPU_COND_SHIFT 46
+#define VC5_QPU_COND_MASK QPU_MASK(52, 46)
+
+#define VC5_QPU_COND_IFA 0
+#define VC5_QPU_COND_IFB 1
+#define VC5_QPU_COND_IFNA 2
+#define VC5_QPU_COND_IFNB 3
+
+#define VC5_QPU_MM QPU_MASK(45, 45)
+#define VC5_QPU_MA QPU_MASK(44, 44)
+
+#define V3D_QPU_WADDR_M_SHIFT 38
+#define V3D_QPU_WADDR_M_MASK QPU_MASK(43, 38)
+
+#define VC5_QPU_BRANCH_ADDR_LOW_SHIFT 35
+#define VC5_QPU_BRANCH_ADDR_LOW_MASK QPU_MASK(55, 35)
+
+#define V3D_QPU_WADDR_A_SHIFT 32
+#define V3D_QPU_WADDR_A_MASK QPU_MASK(37, 32)
+
+#define VC5_QPU_BRANCH_COND_SHIFT 32
+#define VC5_QPU_BRANCH_COND_MASK QPU_MASK(34, 32)
+
+#define VC5_QPU_BRANCH_ADDR_HIGH_SHIFT 24
+#define VC5_QPU_BRANCH_ADDR_HIGH_MASK QPU_MASK(31, 24)
+
+#define VC5_QPU_OP_ADD_SHIFT 24
+#define VC5_QPU_OP_ADD_MASK QPU_MASK(31, 24)
+
+#define VC5_QPU_MUL_B_SHIFT 21
+#define VC5_QPU_MUL_B_MASK QPU_MASK(23, 21)
+
+#define VC5_QPU_BRANCH_MSFIGN_SHIFT 21
+#define VC5_QPU_BRANCH_MSFIGN_MASK QPU_MASK(22, 21)
+
+#define VC5_QPU_MUL_A_SHIFT 18
+#define VC5_QPU_MUL_A_MASK QPU_MASK(20, 18)
+
+#define VC5_QPU_ADD_B_SHIFT 15
+#define VC5_QPU_ADD_B_MASK QPU_MASK(17, 15)
+
+#define VC5_QPU_BRANCH_BDU_SHIFT 15
+#define VC5_QPU_BRANCH_BDU_MASK QPU_MASK(17, 15)
+
+#define VC5_QPU_BRANCH_UB QPU_MASK(14, 14)
+
+#define VC5_QPU_ADD_A_SHIFT 12
+#define VC5_QPU_ADD_A_MASK QPU_MASK(14, 12)
+
+#define VC5_QPU_BRANCH_BDI_SHIFT 12
+#define VC5_QPU_BRANCH_BDI_MASK QPU_MASK(13, 12)
+
+#define VC5_QPU_RADDR_A_SHIFT 6
+#define VC5_QPU_RADDR_A_MASK QPU_MASK(11, 6)
+
+#define VC5_QPU_RADDR_B_SHIFT 0
+#define VC5_QPU_RADDR_B_MASK QPU_MASK(5, 0)
+
+const char *
+v3d_qpu_magic_waddr_name(enum v3d_qpu_waddr waddr)
+{
+ static const char *waddr_magic[] = {
+ [V3D_QPU_WADDR_R0] = "r0",
+ [V3D_QPU_WADDR_R1] = "r1",
+ [V3D_QPU_WADDR_R2] = "r2",
+ [V3D_QPU_WADDR_R3] = "r3",
+ [V3D_QPU_WADDR_R4] = "r4",
+ [V3D_QPU_WADDR_R5] = "r5",
+ [V3D_QPU_WADDR_NOP] = "-",
+ [V3D_QPU_WADDR_TLB] = "tlb",
+ [V3D_QPU_WADDR_TLBU] = "tlbu",
+ [V3D_QPU_WADDR_TMU] = "tmu",
+ [V3D_QPU_WADDR_TMUL] = "tmul",
+ [V3D_QPU_WADDR_TMUD] = "tmud",
+ [V3D_QPU_WADDR_TMUA] = "tmua",
+ [V3D_QPU_WADDR_TMUAU] = "tmuau",
+ [V3D_QPU_WADDR_VPM] = "vpm",
+ [V3D_QPU_WADDR_VPMU] = "vpmu",
+ [V3D_QPU_WADDR_SYNC] = "sync",
+ [V3D_QPU_WADDR_SYNCU] = "syncu",
+ [V3D_QPU_WADDR_RECIP] = "recip",
+ [V3D_QPU_WADDR_RSQRT] = "rsqrt",
+ [V3D_QPU_WADDR_EXP] = "exp",
+ [V3D_QPU_WADDR_LOG] = "log",
+ [V3D_QPU_WADDR_SIN] = "sin",
+ [V3D_QPU_WADDR_RSQRT2] = "rsqrt2",
+ };
+
+ return waddr_magic[waddr];
+}
+
+const char *
+v3d_qpu_add_op_name(enum v3d_qpu_add_op op)
+{
+ static const char *op_names[] = {
+ [V3D_QPU_A_FADD] = "fadd",
+ [V3D_QPU_A_FADDNF] = "faddnf",
+ [V3D_QPU_A_VFPACK] = "vfpack",
+ [V3D_QPU_A_ADD] = "add",
+ [V3D_QPU_A_SUB] = "sub",
+ [V3D_QPU_A_FSUB] = "fsub",
+ [V3D_QPU_A_MIN] = "min",
+ [V3D_QPU_A_MAX] = "max",
+ [V3D_QPU_A_UMIN] = "umin",
+ [V3D_QPU_A_UMAX] = "umax",
+ [V3D_QPU_A_SHL] = "shl",
+ [V3D_QPU_A_SHR] = "shr",
+ [V3D_QPU_A_ASR] = "asr",
+ [V3D_QPU_A_ROR] = "ror",
+ [V3D_QPU_A_FMIN] = "fmin",
+ [V3D_QPU_A_FMAX] = "fmax",
+ [V3D_QPU_A_VFMIN] = "vfmin",
+ [V3D_QPU_A_AND] = "and",
+ [V3D_QPU_A_OR] = "or",
+ [V3D_QPU_A_XOR] = "xor",
+ [V3D_QPU_A_VADD] = "vadd",
+ [V3D_QPU_A_VSUB] = "vsub",
+ [V3D_QPU_A_NOT] = "not",
+ [V3D_QPU_A_NEG] = "neg",
+ [V3D_QPU_A_FLAPUSH] = "flapush",
+ [V3D_QPU_A_FLBPUSH] = "flbpush",
+ [V3D_QPU_A_FLBPOP] = "flbpop",
+ [V3D_QPU_A_SETMSF] = "setmsf",
+ [V3D_QPU_A_SETREVF] = "setrevf",
+ [V3D_QPU_A_NOP] = "nop",
+ [V3D_QPU_A_TIDX] = "tidx",
+ [V3D_QPU_A_EIDX] = "eidx",
+ [V3D_QPU_A_LR] = "lr",
+ [V3D_QPU_A_VFLA] = "vfla",
+ [V3D_QPU_A_VFLNA] = "vflna",
+ [V3D_QPU_A_VFLB] = "vflb",
+ [V3D_QPU_A_VFLNB] = "vflnb",
+ [V3D_QPU_A_FXCD] = "fxcd",
+ [V3D_QPU_A_XCD] = "xcd",
+ [V3D_QPU_A_FYCD] = "fycd",
+ [V3D_QPU_A_YCD] = "ycd",
+ [V3D_QPU_A_MSF] = "msf",
+ [V3D_QPU_A_REVF] = "revf",
+ [V3D_QPU_A_VDWWT] = "vdwwt",
+ [V3D_QPU_A_IID] = "iid",
+ [V3D_QPU_A_SAMPID] = "sampid",
+ [V3D_QPU_A_PATCHID] = "patchid",
+ [V3D_QPU_A_TMUWT] = "tmuwt",
+ [V3D_QPU_A_VPMSETUP] = "vpmsetup",
+ [V3D_QPU_A_VPMWT] = "vpmwt",
+ [V3D_QPU_A_LDVPMV] = "ldvpmv",
+ [V3D_QPU_A_LDVPMD] = "ldvpmd",
+ [V3D_QPU_A_LDVPMP] = "ldvpmp",
+ [V3D_QPU_A_LDVPMG] = "ldvpmg",
+ [V3D_QPU_A_FCMP] = "fcmp",
+ [V3D_QPU_A_VFMAX] = "vfmax",
+ [V3D_QPU_A_FROUND] = "fround",
+ [V3D_QPU_A_FTOIN] = "ftoin",
+ [V3D_QPU_A_FTRUNC] = "ftrunc",
+ [V3D_QPU_A_FTOIZ] = "ftoiz",
+ [V3D_QPU_A_FFLOOR] = "ffloor",
+ [V3D_QPU_A_FTOUZ] = "ftouz",
+ [V3D_QPU_A_FCEIL] = "fceil",
+ [V3D_QPU_A_FTOC] = "ftoc",
+ [V3D_QPU_A_FDX] = "fdx",
+ [V3D_QPU_A_FDY] = "fdy",
+ [V3D_QPU_A_STVPMV] = "stvpmv",
+ [V3D_QPU_A_STVPMD] = "stvpmd",
+ [V3D_QPU_A_STVPMP] = "stvpmp",
+ [V3D_QPU_A_ITOF] = "itof",
+ [V3D_QPU_A_CLZ] = "clz",
+ [V3D_QPU_A_UTOF] = "utof",
+ };
+
+ if (op >= ARRAY_SIZE(op_names))
+ return NULL;
+
+ return op_names[op];
+}
+
+const char *
+v3d_qpu_mul_op_name(enum v3d_qpu_mul_op op)
+{
+ static const char *op_names[] = {
+ [V3D_QPU_M_ADD] = "add",
+ [V3D_QPU_M_SUB] = "sub",
+ [V3D_QPU_M_UMUL24] = "umul24",
+ [V3D_QPU_M_VFMUL] = "vfmul",
+ [V3D_QPU_M_SMUL24] = "smul24",
+ [V3D_QPU_M_MULTOP] = "multop",
+ [V3D_QPU_M_FMOV] = "fmov",
+ [V3D_QPU_M_MOV] = "mov",
+ [V3D_QPU_M_NOP] = "nop",
+ [V3D_QPU_M_FMUL] = "fmul",
+ };
+
+ if (op >= ARRAY_SIZE(op_names))
+ return NULL;
+
+ return op_names[op];
+}
+
+const char *
+v3d_qpu_cond_name(enum v3d_qpu_cond cond)
+{
+ switch (cond) {
+ case V3D_QPU_COND_NONE:
+ return "";
+ case V3D_QPU_COND_IFA:
+ return ".ifa";
+ case V3D_QPU_COND_IFB:
+ return ".ifb";
+ case V3D_QPU_COND_IFNA:
+ return ".ifna";
+ case V3D_QPU_COND_IFNB:
+ return ".ifnb";
+ default:
+ unreachable("bad cond value");
+ }
+}
+
+const char *
+v3d_qpu_branch_cond_name(enum v3d_qpu_branch_cond cond)
+{
+ switch (cond) {
+ case V3D_QPU_BRANCH_COND_ALWAYS:
+ return "";
+ case V3D_QPU_BRANCH_COND_A0:
+ return ".a0";
+ case V3D_QPU_BRANCH_COND_NA0:
+ return ".na0";
+ case V3D_QPU_BRANCH_COND_ALLA:
+ return ".alla";
+ case V3D_QPU_BRANCH_COND_ANYNA:
+ return ".anyna";
+ case V3D_QPU_BRANCH_COND_ANYA:
+ return ".anya";
+ case V3D_QPU_BRANCH_COND_ALLNA:
+ return ".allna";
+ default:
+ unreachable("bad branch cond value");
+ }
+}
+
+const char *
+v3d_qpu_msfign_name(enum v3d_qpu_msfign msfign)
+{
+ switch (msfign) {
+ case V3D_QPU_MSFIGN_NONE:
+ return "";
+ case V3D_QPU_MSFIGN_P:
+ return "p";
+ case V3D_QPU_MSFIGN_Q:
+ return "q";
+ default:
+ unreachable("bad branch cond value");
+ }
+}
+
+const char *
+v3d_qpu_pf_name(enum v3d_qpu_pf pf)
+{
+ switch (pf) {
+ case V3D_QPU_PF_NONE:
+ return "";
+ case V3D_QPU_PF_PUSHZ:
+ return ".pushz";
+ case V3D_QPU_PF_PUSHN:
+ return ".pushn";
+ case V3D_QPU_PF_PUSHC:
+ return ".pushc";
+ default:
+ unreachable("bad pf value");
+ }
+}
+
+const char *
+v3d_qpu_uf_name(enum v3d_qpu_uf uf)
+{
+ switch (uf) {
+ case V3D_QPU_UF_NONE:
+ return "";
+ case V3D_QPU_UF_ANDZ:
+ return ".andz";
+ case V3D_QPU_UF_ANDNZ:
+ return ".andnz";
+ case V3D_QPU_UF_NORZ:
+ return ".norz";
+ case V3D_QPU_UF_NORNZ:
+ return ".nornz";
+ case V3D_QPU_UF_ANDN:
+ return ".andn";
+ case V3D_QPU_UF_ANDNN:
+ return ".andnn";
+ case V3D_QPU_UF_NORN:
+ return ".norn";
+ case V3D_QPU_UF_NORNN:
+ return ".nornn";
+ case V3D_QPU_UF_ANDC:
+ return ".andc";
+ case V3D_QPU_UF_ANDNC:
+ return ".andnc";
+ case V3D_QPU_UF_NORC:
+ return ".norc";
+ case V3D_QPU_UF_NORNC:
+ return ".nornc";
+ default:
+ unreachable("bad pf value");
+ }
+}
+
+const char *
+v3d_qpu_pack_name(enum v3d_qpu_output_pack pack)
+{
+ switch (pack) {
+ case V3D_QPU_PACK_NONE:
+ return "";
+ case V3D_QPU_PACK_L:
+ return ".l";
+ case V3D_QPU_PACK_H:
+ return ".h";
+ default:
+ unreachable("bad pack value");
+ }
+}
+
+const char *
+v3d_qpu_unpack_name(enum v3d_qpu_input_unpack unpack)
+{
+ switch (unpack) {
+ case V3D_QPU_UNPACK_NONE:
+ return "";
+ case V3D_QPU_UNPACK_L:
+ return ".l";
+ case V3D_QPU_UNPACK_H:
+ return ".h";
+ case V3D_QPU_UNPACK_ABS:
+ return ".abs";
+ case V3D_QPU_UNPACK_REPLICATE_32F_16:
+ return ".ff";
+ case V3D_QPU_UNPACK_REPLICATE_L_16:
+ return ".ll";
+ case V3D_QPU_UNPACK_REPLICATE_H_16:
+ return ".hh";
+ case V3D_QPU_UNPACK_SWAP_16:
+ return ".swp";
+ default:
+ unreachable("bad unpack value");
+ }
+}
+
+#define D 1
+#define A 2
+#define B 4
+static const uint8_t add_op_args[] = {
+ [V3D_QPU_A_FADD] = D | A | B,
+ [V3D_QPU_A_FADDNF] = D | A | B,
+ [V3D_QPU_A_VFPACK] = D | A | B,
+ [V3D_QPU_A_ADD] = D | A | B,
+ [V3D_QPU_A_VFPACK] = D | A | B,
+ [V3D_QPU_A_SUB] = D | A | B,
+ [V3D_QPU_A_VFPACK] = D | A | B,
+ [V3D_QPU_A_FSUB] = D | A | B,
+ [V3D_QPU_A_MIN] = D | A | B,
+ [V3D_QPU_A_MAX] = D | A | B,
+ [V3D_QPU_A_UMIN] = D | A | B,
+ [V3D_QPU_A_UMAX] = D | A | B,
+ [V3D_QPU_A_SHL] = D | A | B,
+ [V3D_QPU_A_SHR] = D | A | B,
+ [V3D_QPU_A_ASR] = D | A | B,
+ [V3D_QPU_A_ROR] = D | A | B,
+ [V3D_QPU_A_FMIN] = D | A | B,
+ [V3D_QPU_A_FMAX] = D | A | B,
+ [V3D_QPU_A_VFMIN] = D | A | B,
+
+ [V3D_QPU_A_AND] = D | A | B,
+ [V3D_QPU_A_OR] = D | A | B,
+ [V3D_QPU_A_XOR] = D | A | B,
+
+ [V3D_QPU_A_VADD] = D | A | B,
+ [V3D_QPU_A_VSUB] = D | A | B,
+ [V3D_QPU_A_NOT] = D | A,
+ [V3D_QPU_A_NEG] = D | A,
+ [V3D_QPU_A_FLAPUSH] = D | A,
+ [V3D_QPU_A_FLBPUSH] = D | A,
+ [V3D_QPU_A_FLBPOP] = D | A,
+ [V3D_QPU_A_SETMSF] = D | A,
+ [V3D_QPU_A_SETREVF] = D | A,
+ [V3D_QPU_A_NOP] = 0,
+ [V3D_QPU_A_TIDX] = D,
+ [V3D_QPU_A_EIDX] = D,
+ [V3D_QPU_A_LR] = D,
+ [V3D_QPU_A_VFLA] = D,
+ [V3D_QPU_A_VFLNA] = D,
+ [V3D_QPU_A_VFLB] = D,
+ [V3D_QPU_A_VFLNB] = D,
+
+ [V3D_QPU_A_FXCD] = D,
+ [V3D_QPU_A_XCD] = D,
+ [V3D_QPU_A_FYCD] = D,
+ [V3D_QPU_A_YCD] = D,
+
+ [V3D_QPU_A_MSF] = D,
+ [V3D_QPU_A_REVF] = D,
+ [V3D_QPU_A_VDWWT] = D,
+ [V3D_QPU_A_IID] = D,
+ [V3D_QPU_A_SAMPID] = D,
+ [V3D_QPU_A_PATCHID] = D,
+ [V3D_QPU_A_TMUWT] = D,
+ [V3D_QPU_A_VPMWT] = D,
+
+ [V3D_QPU_A_VPMSETUP] = D | A,
+
+ [V3D_QPU_A_LDVPMV] = D | A,
+ [V3D_QPU_A_LDVPMD] = D | A,
+ [V3D_QPU_A_LDVPMP] = D | A,
+ [V3D_QPU_A_LDVPMG] = D | A | B,
+
+ /* FIXME: MOVABSNEG */
+
+ [V3D_QPU_A_FCMP] = D | A | B,
+ [V3D_QPU_A_VFMAX] = D | A | B,
+
+ [V3D_QPU_A_FROUND] = D | A,
+ [V3D_QPU_A_FTOIN] = D | A,
+ [V3D_QPU_A_FTRUNC] = D | A,
+ [V3D_QPU_A_FTOIZ] = D | A,
+ [V3D_QPU_A_FFLOOR] = D | A,
+ [V3D_QPU_A_FTOUZ] = D | A,
+ [V3D_QPU_A_FCEIL] = D | A,
+ [V3D_QPU_A_FTOC] = D | A,
+
+ [V3D_QPU_A_FDX] = D | A,
+ [V3D_QPU_A_FDY] = D | A,
+
+ [V3D_QPU_A_STVPMV] = A | B,
+ [V3D_QPU_A_STVPMD] = A | B,
+ [V3D_QPU_A_STVPMP] = A | B,
+
+ [V3D_QPU_A_ITOF] = D | A,
+ [V3D_QPU_A_CLZ] = D | A,
+ [V3D_QPU_A_UTOF] = D | A,
+};
+
+static const uint8_t mul_op_args[] = {
+ [V3D_QPU_M_ADD] = D | A | B,
+ [V3D_QPU_M_SUB] = D | A | B,
+ [V3D_QPU_M_UMUL24] = D | A | B,
+ [V3D_QPU_M_VFMUL] = D | A | B,
+ [V3D_QPU_M_SMUL24] = D | A | B,
+ [V3D_QPU_M_MULTOP] = D | A | B,
+ [V3D_QPU_M_FMOV] = D | A,
+ [V3D_QPU_M_NOP] = 0,
+ [V3D_QPU_M_MOV] = D | A,
+ [V3D_QPU_M_FMUL] = D | A | B,
+};
+
+bool
+v3d_qpu_add_op_has_dst(enum v3d_qpu_add_op op)
+{
+ assert(op < ARRAY_SIZE(add_op_args));
+
+ return add_op_args[op] & D;
+}
+
+bool
+v3d_qpu_mul_op_has_dst(enum v3d_qpu_mul_op op)
+{
+ assert(op < ARRAY_SIZE(mul_op_args));
+
+ return mul_op_args[op] & D;
+}
+
+int
+v3d_qpu_add_op_num_src(enum v3d_qpu_add_op op)
+{
+ assert(op < ARRAY_SIZE(add_op_args));
+
+ uint8_t args = add_op_args[op];
+ if (args & B)
+ return 2;
+ else if (args & A)
+ return 1;
+ else
+ return 0;
+}
+
+int
+v3d_qpu_mul_op_num_src(enum v3d_qpu_mul_op op)
+{
+ assert(op < ARRAY_SIZE(mul_op_args));
+
+ uint8_t args = mul_op_args[op];
+ if (args & B)
+ return 2;
+ else if (args & A)
+ return 1;
+ else
+ return 0;
+}
+
+bool
+v3d_qpu_magic_waddr_is_sfu(enum v3d_qpu_waddr waddr)
+{
+ switch (waddr) {
+ case V3D_QPU_WADDR_RECIP:
+ case V3D_QPU_WADDR_RSQRT:
+ case V3D_QPU_WADDR_EXP:
+ case V3D_QPU_WADDR_LOG:
+ case V3D_QPU_WADDR_SIN:
+ case V3D_QPU_WADDR_RSQRT2:
+ return true;
+ default:
+ return false;
+ }
+}
+
+bool
+v3d_qpu_magic_waddr_is_tmu(enum v3d_qpu_waddr waddr)
+{
+ switch (waddr) {
+ case V3D_QPU_WADDR_TMU:
+ case V3D_QPU_WADDR_TMUL:
+ case V3D_QPU_WADDR_TMUD:
+ case V3D_QPU_WADDR_TMUA:
+ case V3D_QPU_WADDR_TMUAU:
+ return true;
+ default:
+ return false;
+ }
+}
+
+bool
+v3d_qpu_magic_waddr_is_tlb(enum v3d_qpu_waddr waddr)
+{
+ return (waddr == V3D_QPU_WADDR_TLB ||
+ waddr == V3D_QPU_WADDR_TLBU);
+}
+
+bool
+v3d_qpu_magic_waddr_is_vpm(enum v3d_qpu_waddr waddr)
+{
+ return (waddr == V3D_QPU_WADDR_VPM ||
+ waddr == V3D_QPU_WADDR_VPMU);
+}
+
+bool
+v3d_qpu_magic_waddr_is_tsy(enum v3d_qpu_waddr waddr)
+{
+ return (waddr == V3D_QPU_WADDR_SYNC ||
+ waddr == V3D_QPU_WADDR_SYNCU);
+}
+
+bool
+v3d_qpu_writes_r3(const struct v3d_qpu_instr *inst)
+{
+ return inst->sig.ldvary || inst->sig.ldvpm;
+}
+
+bool
+v3d_qpu_writes_r4(const struct v3d_qpu_instr *inst)
+{
+ if (inst->sig.ldtmu)
+ return true;
+
+ if (inst->type == V3D_QPU_INSTR_TYPE_ALU) {
+ if (inst->alu.add.magic_write &&
+ v3d_qpu_magic_waddr_is_sfu(inst->alu.add.waddr)) {
+ return true;
+ }
+
+ if (inst->alu.mul.magic_write &&
+ v3d_qpu_magic_waddr_is_sfu(inst->alu.mul.waddr)) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+bool
+v3d_qpu_writes_r5(const struct v3d_qpu_instr *inst)
+{
+ return inst->sig.ldvary || inst->sig.ldunif;
+}
+
+bool
+v3d_qpu_uses_mux(const struct v3d_qpu_instr *inst, enum v3d_qpu_mux mux)
+{
+ int add_nsrc = v3d_qpu_add_op_num_src(inst->alu.add.op);
+ int mul_nsrc = v3d_qpu_mul_op_num_src(inst->alu.mul.op);
+
+ return ((add_nsrc > 0 && inst->alu.add.a == mux) ||
+ (add_nsrc > 1 && inst->alu.add.b == mux) ||
+ (mul_nsrc > 0 && inst->alu.mul.a == mux) ||
+ (mul_nsrc > 1 && inst->alu.mul.b == mux));
+}
diff --git a/lib/mesa/src/broadcom/qpu/qpu_instr.h b/lib/mesa/src/broadcom/qpu/qpu_instr.h
new file mode 100644
index 000000000..a425fae8b
--- /dev/null
+++ b/lib/mesa/src/broadcom/qpu/qpu_instr.h
@@ -0,0 +1,411 @@
+/*
+ * Copyright © 2016 Broadcom
+ *
+ * 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.
+ */
+
+/**
+ * @file qpu_instr.h
+ *
+ * Definitions of the unpacked form of QPU instructions. Assembly and
+ * disassembly will use this for talking about instructions, with qpu_encode.c
+ * and qpu_decode.c handling the pack and unpack of the actual 64-bit QPU
+ * instruction.
+ */
+
+#ifndef QPU_INSTR_H
+#define QPU_INSTR_H
+
+#include <stdbool.h>
+#include <stdint.h>
+#include "util/macros.h"
+
+struct v3d_device_info;
+
+struct v3d_qpu_sig {
+ bool thrsw:1;
+ bool ldunif:1;
+ bool ldtmu:1;
+ bool ldvary:1;
+ bool ldvpm:1;
+ bool ldtlb:1;
+ bool ldtlbu:1;
+ bool small_imm:1;
+ bool ucb:1;
+ bool rotate:1;
+ bool wrtmuc:1;
+};
+
+enum v3d_qpu_cond {
+ V3D_QPU_COND_NONE,
+ V3D_QPU_COND_IFA,
+ V3D_QPU_COND_IFB,
+ V3D_QPU_COND_IFNA,
+ V3D_QPU_COND_IFNB,
+};
+
+enum v3d_qpu_pf {
+ V3D_QPU_PF_NONE,
+ V3D_QPU_PF_PUSHZ,
+ V3D_QPU_PF_PUSHN,
+ V3D_QPU_PF_PUSHC,
+};
+
+enum v3d_qpu_uf {
+ V3D_QPU_UF_NONE,
+ V3D_QPU_UF_ANDZ,
+ V3D_QPU_UF_ANDNZ,
+ V3D_QPU_UF_NORNZ,
+ V3D_QPU_UF_NORZ,
+ V3D_QPU_UF_ANDN,
+ V3D_QPU_UF_ANDNN,
+ V3D_QPU_UF_NORNN,
+ V3D_QPU_UF_NORN,
+ V3D_QPU_UF_ANDC,
+ V3D_QPU_UF_ANDNC,
+ V3D_QPU_UF_NORNC,
+ V3D_QPU_UF_NORC,
+};
+
+enum v3d_qpu_waddr {
+ V3D_QPU_WADDR_R0 = 0,
+ V3D_QPU_WADDR_R1 = 1,
+ V3D_QPU_WADDR_R2 = 2,
+ V3D_QPU_WADDR_R3 = 3,
+ V3D_QPU_WADDR_R4 = 4,
+ V3D_QPU_WADDR_R5 = 5,
+ /* 6 is reserved, but note 3.2.2.8: "Result Writes" */
+ V3D_QPU_WADDR_NOP = 6,
+ V3D_QPU_WADDR_TLB = 7,
+ V3D_QPU_WADDR_TLBU = 8,
+ V3D_QPU_WADDR_TMU = 9,
+ V3D_QPU_WADDR_TMUL = 10,
+ V3D_QPU_WADDR_TMUD = 11,
+ V3D_QPU_WADDR_TMUA = 12,
+ V3D_QPU_WADDR_TMUAU = 13,
+ V3D_QPU_WADDR_VPM = 14,
+ V3D_QPU_WADDR_VPMU = 15,
+ V3D_QPU_WADDR_SYNC = 16,
+ V3D_QPU_WADDR_SYNCU = 17,
+ /* reserved */
+ V3D_QPU_WADDR_RECIP = 19,
+ V3D_QPU_WADDR_RSQRT = 20,
+ V3D_QPU_WADDR_EXP = 21,
+ V3D_QPU_WADDR_LOG = 22,
+ V3D_QPU_WADDR_SIN = 23,
+ V3D_QPU_WADDR_RSQRT2 = 24,
+};
+
+struct v3d_qpu_flags {
+ enum v3d_qpu_cond ac, mc;
+ enum v3d_qpu_pf apf, mpf;
+ enum v3d_qpu_uf auf, muf;
+};
+
+enum v3d_qpu_add_op {
+ V3D_QPU_A_FADD,
+ V3D_QPU_A_FADDNF,
+ V3D_QPU_A_VFPACK,
+ V3D_QPU_A_ADD,
+ V3D_QPU_A_SUB,
+ V3D_QPU_A_FSUB,
+ V3D_QPU_A_MIN,
+ V3D_QPU_A_MAX,
+ V3D_QPU_A_UMIN,
+ V3D_QPU_A_UMAX,
+ V3D_QPU_A_SHL,
+ V3D_QPU_A_SHR,
+ V3D_QPU_A_ASR,
+ V3D_QPU_A_ROR,
+ V3D_QPU_A_FMIN,
+ V3D_QPU_A_FMAX,
+ V3D_QPU_A_VFMIN,
+ V3D_QPU_A_AND,
+ V3D_QPU_A_OR,
+ V3D_QPU_A_XOR,
+ V3D_QPU_A_VADD,
+ V3D_QPU_A_VSUB,
+ V3D_QPU_A_NOT,
+ V3D_QPU_A_NEG,
+ V3D_QPU_A_FLAPUSH,
+ V3D_QPU_A_FLBPUSH,
+ V3D_QPU_A_FLBPOP,
+ V3D_QPU_A_SETMSF,
+ V3D_QPU_A_SETREVF,
+ V3D_QPU_A_NOP,
+ V3D_QPU_A_TIDX,
+ V3D_QPU_A_EIDX,
+ V3D_QPU_A_LR,
+ V3D_QPU_A_VFLA,
+ V3D_QPU_A_VFLNA,
+ V3D_QPU_A_VFLB,
+ V3D_QPU_A_VFLNB,
+ V3D_QPU_A_FXCD,
+ V3D_QPU_A_XCD,
+ V3D_QPU_A_FYCD,
+ V3D_QPU_A_YCD,
+ V3D_QPU_A_MSF,
+ V3D_QPU_A_REVF,
+ V3D_QPU_A_VDWWT,
+ V3D_QPU_A_IID,
+ V3D_QPU_A_SAMPID,
+ V3D_QPU_A_PATCHID,
+ V3D_QPU_A_TMUWT,
+ V3D_QPU_A_VPMSETUP,
+ V3D_QPU_A_VPMWT,
+ V3D_QPU_A_LDVPMV,
+ V3D_QPU_A_LDVPMD,
+ V3D_QPU_A_LDVPMP,
+ V3D_QPU_A_LDVPMG,
+ V3D_QPU_A_FCMP,
+ V3D_QPU_A_VFMAX,
+ V3D_QPU_A_FROUND,
+ V3D_QPU_A_FTOIN,
+ V3D_QPU_A_FTRUNC,
+ V3D_QPU_A_FTOIZ,
+ V3D_QPU_A_FFLOOR,
+ V3D_QPU_A_FTOUZ,
+ V3D_QPU_A_FCEIL,
+ V3D_QPU_A_FTOC,
+ V3D_QPU_A_FDX,
+ V3D_QPU_A_FDY,
+ V3D_QPU_A_STVPMV,
+ V3D_QPU_A_STVPMD,
+ V3D_QPU_A_STVPMP,
+ V3D_QPU_A_ITOF,
+ V3D_QPU_A_CLZ,
+ V3D_QPU_A_UTOF,
+};
+
+enum v3d_qpu_mul_op {
+ V3D_QPU_M_ADD,
+ V3D_QPU_M_SUB,
+ V3D_QPU_M_UMUL24,
+ V3D_QPU_M_VFMUL,
+ V3D_QPU_M_SMUL24,
+ V3D_QPU_M_MULTOP,
+ V3D_QPU_M_FMOV,
+ V3D_QPU_M_MOV,
+ V3D_QPU_M_NOP,
+ V3D_QPU_M_FMUL,
+};
+
+enum v3d_qpu_output_pack {
+ V3D_QPU_PACK_NONE,
+ /**
+ * Convert to 16-bit float, put in low 16 bits of destination leaving
+ * high unmodified.
+ */
+ V3D_QPU_PACK_L,
+ /**
+ * Convert to 16-bit float, put in high 16 bits of destination leaving
+ * low unmodified.
+ */
+ V3D_QPU_PACK_H,
+};
+
+enum v3d_qpu_input_unpack {
+ /**
+ * No-op input unpacking. Note that this enum's value doesn't match
+ * the packed QPU instruction value of the field (we use 0 so that the
+ * default on new instruction creation is no-op).
+ */
+ V3D_QPU_UNPACK_NONE,
+ /** Absolute value. Only available for some operations. */
+ V3D_QPU_UNPACK_ABS,
+ /** Convert low 16 bits from 16-bit float to 32-bit float. */
+ V3D_QPU_UNPACK_L,
+ /** Convert high 16 bits from 16-bit float to 32-bit float. */
+ V3D_QPU_UNPACK_H,
+
+ /** Convert to 16f and replicate it to the high bits. */
+ V3D_QPU_UNPACK_REPLICATE_32F_16,
+
+ /** Replicate low 16 bits to high */
+ V3D_QPU_UNPACK_REPLICATE_L_16,
+
+ /** Replicate high 16 bits to low */
+ V3D_QPU_UNPACK_REPLICATE_H_16,
+
+ /** Swap high and low 16 bits */
+ V3D_QPU_UNPACK_SWAP_16,
+};
+
+enum v3d_qpu_mux {
+ V3D_QPU_MUX_R0,
+ V3D_QPU_MUX_R1,
+ V3D_QPU_MUX_R2,
+ V3D_QPU_MUX_R3,
+ V3D_QPU_MUX_R4,
+ V3D_QPU_MUX_R5,
+ V3D_QPU_MUX_A,
+ V3D_QPU_MUX_B,
+};
+
+struct v3d_qpu_alu_instr {
+ struct {
+ enum v3d_qpu_add_op op;
+ enum v3d_qpu_mux a, b;
+ uint8_t waddr;
+ bool magic_write;
+ enum v3d_qpu_output_pack output_pack;
+ enum v3d_qpu_input_unpack a_unpack;
+ enum v3d_qpu_input_unpack b_unpack;
+ } add;
+
+ struct {
+ enum v3d_qpu_mul_op op;
+ enum v3d_qpu_mux a, b;
+ uint8_t waddr;
+ bool magic_write;
+ enum v3d_qpu_output_pack output_pack;
+ enum v3d_qpu_input_unpack a_unpack;
+ enum v3d_qpu_input_unpack b_unpack;
+ } mul;
+};
+
+enum v3d_qpu_branch_cond {
+ V3D_QPU_BRANCH_COND_ALWAYS,
+ V3D_QPU_BRANCH_COND_A0,
+ V3D_QPU_BRANCH_COND_NA0,
+ V3D_QPU_BRANCH_COND_ALLA,
+ V3D_QPU_BRANCH_COND_ANYNA,
+ V3D_QPU_BRANCH_COND_ANYA,
+ V3D_QPU_BRANCH_COND_ALLNA,
+};
+
+enum v3d_qpu_msfign {
+ /** Ignore multisample flags when determining branch condition. */
+ V3D_QPU_MSFIGN_NONE,
+ /**
+ * If no multisample flags are set in the lane (a pixel in the FS, a
+ * vertex in the VS), ignore the lane's condition when computing the
+ * branch condition.
+ */
+ V3D_QPU_MSFIGN_P,
+ /**
+ * If no multisample flags are set in a 2x2 quad in the FS, ignore the
+ * quad's a/b conditions.
+ */
+ V3D_QPU_MSFIGN_Q,
+};
+
+enum v3d_qpu_branch_dest {
+ V3D_QPU_BRANCH_DEST_ABS,
+ V3D_QPU_BRANCH_DEST_REL,
+ V3D_QPU_BRANCH_DEST_LINK_REG,
+ V3D_QPU_BRANCH_DEST_REGFILE,
+};
+
+struct v3d_qpu_branch_instr {
+ enum v3d_qpu_branch_cond cond;
+ enum v3d_qpu_msfign msfign;
+
+ /** Selects how to compute the new IP if the branch is taken. */
+ enum v3d_qpu_branch_dest bdi;
+
+ /**
+ * Selects how to compute the new uniforms pointer if the branch is
+ * taken. (ABS/REL implicitly load a uniform and use that)
+ */
+ enum v3d_qpu_branch_dest bdu;
+
+ /**
+ * If set, then udest determines how the uniform stream will branch,
+ * otherwise the uniform stream is left as is.
+ */
+ bool ub;
+
+ uint8_t raddr_a;
+
+ uint32_t offset;
+};
+
+enum v3d_qpu_instr_type {
+ V3D_QPU_INSTR_TYPE_ALU,
+ V3D_QPU_INSTR_TYPE_BRANCH,
+};
+
+struct v3d_qpu_instr {
+ enum v3d_qpu_instr_type type;
+
+ struct v3d_qpu_sig sig;
+ uint8_t raddr_a;
+ uint8_t raddr_b;
+ struct v3d_qpu_flags flags;
+
+ union {
+ struct v3d_qpu_alu_instr alu;
+ struct v3d_qpu_branch_instr branch;
+ };
+};
+
+const char *v3d_qpu_magic_waddr_name(enum v3d_qpu_waddr waddr);
+const char *v3d_qpu_add_op_name(enum v3d_qpu_add_op op);
+const char *v3d_qpu_mul_op_name(enum v3d_qpu_mul_op op);
+const char *v3d_qpu_cond_name(enum v3d_qpu_cond cond);
+const char *v3d_qpu_pf_name(enum v3d_qpu_pf pf);
+const char *v3d_qpu_uf_name(enum v3d_qpu_uf uf);
+const char *v3d_qpu_pack_name(enum v3d_qpu_output_pack pack);
+const char *v3d_qpu_unpack_name(enum v3d_qpu_input_unpack unpack);
+const char *v3d_qpu_branch_cond_name(enum v3d_qpu_branch_cond cond);
+const char *v3d_qpu_msfign_name(enum v3d_qpu_msfign msfign);
+
+bool v3d_qpu_add_op_has_dst(enum v3d_qpu_add_op op);
+bool v3d_qpu_mul_op_has_dst(enum v3d_qpu_mul_op op);
+int v3d_qpu_add_op_num_src(enum v3d_qpu_add_op op);
+int v3d_qpu_mul_op_num_src(enum v3d_qpu_mul_op op);
+
+bool v3d_qpu_sig_pack(const struct v3d_device_info *devinfo,
+ const struct v3d_qpu_sig *sig,
+ uint32_t *packed_sig);
+bool v3d_qpu_sig_unpack(const struct v3d_device_info *devinfo,
+ uint32_t packed_sig,
+ struct v3d_qpu_sig *sig);
+
+bool
+v3d_qpu_flags_pack(const struct v3d_device_info *devinfo,
+ const struct v3d_qpu_flags *cond,
+ uint32_t *packed_cond);
+bool
+v3d_qpu_flags_unpack(const struct v3d_device_info *devinfo,
+ uint32_t packed_cond,
+ struct v3d_qpu_flags *cond);
+
+bool
+v3d_qpu_instr_pack(const struct v3d_device_info *devinfo,
+ const struct v3d_qpu_instr *instr,
+ uint64_t *packed_instr);
+bool
+v3d_qpu_instr_unpack(const struct v3d_device_info *devinfo,
+ uint64_t packed_instr,
+ struct v3d_qpu_instr *instr);
+
+bool v3d_qpu_magic_waddr_is_sfu(enum v3d_qpu_waddr waddr) ATTRIBUTE_CONST;
+bool v3d_qpu_magic_waddr_is_tmu(enum v3d_qpu_waddr waddr) ATTRIBUTE_CONST;
+bool v3d_qpu_magic_waddr_is_tlb(enum v3d_qpu_waddr waddr) ATTRIBUTE_CONST;
+bool v3d_qpu_magic_waddr_is_vpm(enum v3d_qpu_waddr waddr) ATTRIBUTE_CONST;
+bool v3d_qpu_magic_waddr_is_tsy(enum v3d_qpu_waddr waddr) ATTRIBUTE_CONST;
+bool v3d_qpu_writes_r3(const struct v3d_qpu_instr *instr) ATTRIBUTE_CONST;
+bool v3d_qpu_writes_r4(const struct v3d_qpu_instr *instr) ATTRIBUTE_CONST;
+bool v3d_qpu_writes_r5(const struct v3d_qpu_instr *instr) ATTRIBUTE_CONST;
+bool v3d_qpu_uses_mux(const struct v3d_qpu_instr *inst, enum v3d_qpu_mux mux);
+
+#endif
diff --git a/lib/mesa/src/broadcom/qpu/qpu_pack.c b/lib/mesa/src/broadcom/qpu/qpu_pack.c
new file mode 100644
index 000000000..0ecce8666
--- /dev/null
+++ b/lib/mesa/src/broadcom/qpu/qpu_pack.c
@@ -0,0 +1,1206 @@
+/*
+ * Copyright © 2016 Broadcom
+ *
+ * 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 <string.h>
+#include "util/macros.h"
+
+#include "broadcom/common/v3d_device_info.h"
+#include "qpu_instr.h"
+
+#ifndef QPU_MASK
+#define QPU_MASK(high, low) ((((uint64_t)1<<((high)-(low)+1))-1)<<(low))
+/* Using the GNU statement expression extension */
+#define QPU_SET_FIELD(value, field) \
+ ({ \
+ uint64_t fieldval = (uint64_t)(value) << field ## _SHIFT; \
+ assert((fieldval & ~ field ## _MASK) == 0); \
+ fieldval & field ## _MASK; \
+ })
+
+#define QPU_GET_FIELD(word, field) ((uint32_t)(((word) & field ## _MASK) >> field ## _SHIFT))
+
+#define QPU_UPDATE_FIELD(inst, value, field) \
+ (((inst) & ~(field ## _MASK)) | QPU_SET_FIELD(value, field))
+#endif /* QPU_MASK */
+
+#define VC5_QPU_OP_MUL_SHIFT 58
+#define VC5_QPU_OP_MUL_MASK QPU_MASK(63, 58)
+
+#define VC5_QPU_SIG_SHIFT 53
+#define VC5_QPU_SIG_MASK QPU_MASK(57, 53)
+# define VC5_QPU_SIG_THRSW_BIT 0x1
+# define VC5_QPU_SIG_LDUNIF_BIT 0x2
+# define VC5_QPU_SIG_LDTMU_BIT 0x4
+# define VC5_QPU_SIG_LDVARY_BIT 0x8
+
+#define VC5_QPU_COND_SHIFT 46
+#define VC5_QPU_COND_MASK QPU_MASK(52, 46)
+
+#define VC5_QPU_COND_IFA 0
+#define VC5_QPU_COND_IFB 1
+#define VC5_QPU_COND_IFNA 2
+#define VC5_QPU_COND_IFNB 3
+
+#define VC5_QPU_MM QPU_MASK(45, 45)
+#define VC5_QPU_MA QPU_MASK(44, 44)
+
+#define V3D_QPU_WADDR_M_SHIFT 38
+#define V3D_QPU_WADDR_M_MASK QPU_MASK(43, 38)
+
+#define VC5_QPU_BRANCH_ADDR_LOW_SHIFT 35
+#define VC5_QPU_BRANCH_ADDR_LOW_MASK QPU_MASK(55, 35)
+
+#define V3D_QPU_WADDR_A_SHIFT 32
+#define V3D_QPU_WADDR_A_MASK QPU_MASK(37, 32)
+
+#define VC5_QPU_BRANCH_COND_SHIFT 32
+#define VC5_QPU_BRANCH_COND_MASK QPU_MASK(34, 32)
+
+#define VC5_QPU_BRANCH_ADDR_HIGH_SHIFT 24
+#define VC5_QPU_BRANCH_ADDR_HIGH_MASK QPU_MASK(31, 24)
+
+#define VC5_QPU_OP_ADD_SHIFT 24
+#define VC5_QPU_OP_ADD_MASK QPU_MASK(31, 24)
+
+#define VC5_QPU_MUL_B_SHIFT 21
+#define VC5_QPU_MUL_B_MASK QPU_MASK(23, 21)
+
+#define VC5_QPU_BRANCH_MSFIGN_SHIFT 21
+#define VC5_QPU_BRANCH_MSFIGN_MASK QPU_MASK(22, 21)
+
+#define VC5_QPU_MUL_A_SHIFT 18
+#define VC5_QPU_MUL_A_MASK QPU_MASK(20, 18)
+
+#define VC5_QPU_ADD_B_SHIFT 15
+#define VC5_QPU_ADD_B_MASK QPU_MASK(17, 15)
+
+#define VC5_QPU_BRANCH_BDU_SHIFT 15
+#define VC5_QPU_BRANCH_BDU_MASK QPU_MASK(17, 15)
+
+#define VC5_QPU_BRANCH_UB QPU_MASK(14, 14)
+
+#define VC5_QPU_ADD_A_SHIFT 12
+#define VC5_QPU_ADD_A_MASK QPU_MASK(14, 12)
+
+#define VC5_QPU_BRANCH_BDI_SHIFT 12
+#define VC5_QPU_BRANCH_BDI_MASK QPU_MASK(13, 12)
+
+#define VC5_QPU_RADDR_A_SHIFT 6
+#define VC5_QPU_RADDR_A_MASK QPU_MASK(11, 6)
+
+#define VC5_QPU_RADDR_B_SHIFT 0
+#define VC5_QPU_RADDR_B_MASK QPU_MASK(5, 0)
+
+#define THRSW .thrsw = true
+#define LDUNIF .ldunif = true
+#define LDTMU .ldtmu = true
+#define LDVARY .ldvary = true
+#define LDVPM .ldvpm = true
+#define SMIMM .small_imm = true
+#define LDTLB .ldtlb = true
+#define LDTLBU .ldtlbu = true
+#define UCB .ucb = true
+#define ROT .rotate = true
+#define WRTMUC .wrtmuc = true
+
+static const struct v3d_qpu_sig v33_sig_map[] = {
+ /* MISC R3 R4 R5 */
+ [0] = { },
+ [1] = { THRSW, },
+ [2] = { LDUNIF },
+ [3] = { THRSW, LDUNIF },
+ [4] = { LDTMU, },
+ [5] = { THRSW, LDTMU, },
+ [6] = { LDTMU, LDUNIF },
+ [7] = { THRSW, LDTMU, LDUNIF },
+ [8] = { LDVARY, },
+ [9] = { THRSW, LDVARY, },
+ [10] = { LDVARY, LDUNIF },
+ [11] = { THRSW, LDVARY, LDUNIF },
+ [12] = { LDVARY, LDTMU, },
+ [13] = { THRSW, LDVARY, LDTMU, },
+ [14] = { SMIMM, LDVARY, },
+ [15] = { SMIMM, },
+ [16] = { LDTLB, },
+ [17] = { LDTLBU, },
+ /* 18-21 reserved */
+ [22] = { UCB, },
+ [23] = { ROT, },
+ [24] = { LDVPM, },
+ [25] = { THRSW, LDVPM, },
+ [26] = { LDVPM, LDUNIF },
+ [27] = { THRSW, LDVPM, LDUNIF },
+ [28] = { LDVPM, LDTMU, },
+ [29] = { THRSW, LDVPM, LDTMU, },
+ [30] = { SMIMM, LDVPM, },
+ [31] = { SMIMM, },
+};
+
+bool
+v3d_qpu_sig_unpack(const struct v3d_device_info *devinfo,
+ uint32_t packed_sig,
+ struct v3d_qpu_sig *sig)
+{
+ if (packed_sig >= ARRAY_SIZE(v33_sig_map))
+ return false;
+
+ *sig = v33_sig_map[packed_sig];
+
+ /* Signals with zeroed unpacked contents after element 0 are reserved. */
+ return (packed_sig == 0 ||
+ memcmp(sig, &v33_sig_map[0], sizeof(*sig) != 0));
+}
+
+bool
+v3d_qpu_sig_pack(const struct v3d_device_info *devinfo,
+ const struct v3d_qpu_sig *sig,
+ uint32_t *packed_sig)
+{
+ static const struct v3d_qpu_sig *map;
+
+ map = v33_sig_map;
+
+ for (int i = 0; i < ARRAY_SIZE(v33_sig_map); i++) {
+ if (memcmp(&map[i], sig, sizeof(*sig)) == 0) {
+ *packed_sig = i;
+ return true;
+ }
+ }
+
+ return false;
+}
+
+bool
+v3d_qpu_flags_unpack(const struct v3d_device_info *devinfo,
+ uint32_t packed_cond,
+ struct v3d_qpu_flags *cond)
+{
+ static const enum v3d_qpu_cond cond_map[4] = {
+ [0] = V3D_QPU_COND_IFA,
+ [1] = V3D_QPU_COND_IFB,
+ [2] = V3D_QPU_COND_IFNA,
+ [3] = V3D_QPU_COND_IFNB,
+ };
+
+ cond->ac = V3D_QPU_COND_NONE;
+ cond->mc = V3D_QPU_COND_NONE;
+ cond->apf = V3D_QPU_PF_NONE;
+ cond->mpf = V3D_QPU_PF_NONE;
+ cond->auf = V3D_QPU_UF_NONE;
+ cond->muf = V3D_QPU_UF_NONE;
+
+ if (packed_cond == 0) {
+ return true;
+ } else if (packed_cond >> 2 == 0) {
+ cond->apf = packed_cond & 0x3;
+ } else if (packed_cond >> 4 == 0) {
+ cond->auf = (packed_cond & 0xf) - 4 + V3D_QPU_UF_ANDZ;
+ } else if (packed_cond == 0x10) {
+ return false;
+ } else if (packed_cond >> 2 == 0x4) {
+ cond->mpf = packed_cond & 0x3;
+ } else if (packed_cond >> 4 == 0x1) {
+ cond->muf = (packed_cond & 0xf) - 4 + V3D_QPU_UF_ANDZ;
+ } else if (packed_cond >> 4 == 0x2) {
+ cond->ac = ((packed_cond >> 2) & 0x3) + V3D_QPU_COND_IFA;
+ cond->mpf = packed_cond & 0x3;
+ } else if (packed_cond >> 4 == 0x3) {
+ cond->mc = ((packed_cond >> 2) & 0x3) + V3D_QPU_COND_IFA;
+ cond->apf = packed_cond & 0x3;
+ } else if (packed_cond >> 6) {
+ cond->mc = cond_map[(packed_cond >> 4) & 0x3];
+ if (((packed_cond >> 2) & 0x3) == 0) {
+ cond->ac = cond_map[packed_cond & 0x3];
+ } else {
+ cond->auf = (packed_cond & 0xf) - 4 + V3D_QPU_UF_ANDZ;
+ }
+ }
+
+ return true;
+}
+
+bool
+v3d_qpu_flags_pack(const struct v3d_device_info *devinfo,
+ const struct v3d_qpu_flags *cond,
+ uint32_t *packed_cond)
+{
+#define AC (1 << 0)
+#define MC (1 << 1)
+#define APF (1 << 2)
+#define MPF (1 << 3)
+#define AUF (1 << 4)
+#define MUF (1 << 5)
+ static const struct {
+ uint8_t flags_present;
+ uint8_t bits;
+ } flags_table[] = {
+ { 0, 0 },
+ { APF, 0 },
+ { AUF, 0 },
+ { MPF, (1 << 4) },
+ { MUF, (1 << 4) },
+ { AC, (1 << 5) },
+ { AC | MPF, (1 << 5) },
+ { MC, (1 << 5) | (1 << 4) },
+ { MC | APF, (1 << 5) | (1 << 4) },
+ { MC | AC, (1 << 6) },
+ { MC | AUF, (1 << 6) },
+ };
+
+ uint8_t flags_present = 0;
+ if (cond->ac != V3D_QPU_COND_NONE)
+ flags_present |= AC;
+ if (cond->mc != V3D_QPU_COND_NONE)
+ flags_present |= MC;
+ if (cond->apf != V3D_QPU_PF_NONE)
+ flags_present |= APF;
+ if (cond->mpf != V3D_QPU_PF_NONE)
+ flags_present |= MPF;
+ if (cond->auf != V3D_QPU_UF_NONE)
+ flags_present |= AUF;
+ if (cond->muf != V3D_QPU_UF_NONE)
+ flags_present |= MUF;
+
+ for (int i = 0; i < ARRAY_SIZE(flags_table); i++) {
+ if (flags_table[i].flags_present != flags_present)
+ continue;
+
+ *packed_cond = flags_table[i].bits;
+
+ *packed_cond |= cond->apf;
+ *packed_cond |= cond->mpf;
+
+ if (flags_present & AUF)
+ *packed_cond |= cond->auf - V3D_QPU_UF_ANDZ + 4;
+ if (flags_present & MUF)
+ *packed_cond |= cond->muf - V3D_QPU_UF_ANDZ + 4;
+
+ if (flags_present & AC)
+ *packed_cond |= (cond->ac - V3D_QPU_COND_IFA) << 2;
+
+ if (flags_present & MC) {
+ if (*packed_cond & (1 << 6))
+ *packed_cond |= (cond->mc -
+ V3D_QPU_COND_IFA) << 4;
+ else
+ *packed_cond |= (cond->mc -
+ V3D_QPU_COND_IFA) << 2;
+ }
+
+ return true;
+ }
+
+ return false;
+}
+
+/* Make a mapping of the table of opcodes in the spec. The opcode is
+ * determined by a combination of the opcode field, and in the case of 0 or
+ * 1-arg opcodes, the mux_b field as well.
+ */
+#define MUX_MASK(bot, top) (((1 << (top + 1)) - 1) - ((1 << (bot)) - 1))
+#define ANYMUX MUX_MASK(0, 7)
+
+struct opcode_desc {
+ uint8_t opcode_first;
+ uint8_t opcode_last;
+ uint8_t mux_b_mask;
+ uint8_t mux_a_mask;
+ uint8_t op;
+ /* 0 if it's the same across V3D versions, or a specific V3D version. */
+ uint8_t ver;
+};
+
+static const struct opcode_desc add_ops[] = {
+ /* FADD is FADDNF depending on the order of the mux_a/mux_b. */
+ { 0, 47, ANYMUX, ANYMUX, V3D_QPU_A_FADD },
+ { 0, 47, ANYMUX, ANYMUX, V3D_QPU_A_FADDNF },
+ { 53, 55, ANYMUX, ANYMUX, V3D_QPU_A_VFPACK },
+ { 56, 56, ANYMUX, ANYMUX, V3D_QPU_A_ADD },
+ { 57, 59, ANYMUX, ANYMUX, V3D_QPU_A_VFPACK },
+ { 60, 60, ANYMUX, ANYMUX, V3D_QPU_A_SUB },
+ { 61, 63, ANYMUX, ANYMUX, V3D_QPU_A_VFPACK },
+ { 64, 111, ANYMUX, ANYMUX, V3D_QPU_A_FSUB },
+ { 120, 120, ANYMUX, ANYMUX, V3D_QPU_A_MIN },
+ { 121, 121, ANYMUX, ANYMUX, V3D_QPU_A_MAX },
+ { 122, 122, ANYMUX, ANYMUX, V3D_QPU_A_UMIN },
+ { 123, 123, ANYMUX, ANYMUX, V3D_QPU_A_UMAX },
+ { 124, 124, ANYMUX, ANYMUX, V3D_QPU_A_SHL },
+ { 125, 125, ANYMUX, ANYMUX, V3D_QPU_A_SHR },
+ { 126, 126, ANYMUX, ANYMUX, V3D_QPU_A_ASR },
+ { 127, 127, ANYMUX, ANYMUX, V3D_QPU_A_ROR },
+ /* FMIN is instead FMAX depending on the order of the mux_a/mux_b. */
+ { 128, 175, ANYMUX, ANYMUX, V3D_QPU_A_FMIN },
+ { 128, 175, ANYMUX, ANYMUX, V3D_QPU_A_FMAX },
+ { 176, 180, ANYMUX, ANYMUX, V3D_QPU_A_VFMIN },
+
+ { 181, 181, ANYMUX, ANYMUX, V3D_QPU_A_AND },
+ { 182, 182, ANYMUX, ANYMUX, V3D_QPU_A_OR },
+ { 183, 183, ANYMUX, ANYMUX, V3D_QPU_A_XOR },
+
+ { 184, 184, ANYMUX, ANYMUX, V3D_QPU_A_VADD },
+ { 185, 185, ANYMUX, ANYMUX, V3D_QPU_A_VSUB },
+ { 186, 186, 1 << 0, ANYMUX, V3D_QPU_A_NOT },
+ { 186, 186, 1 << 1, ANYMUX, V3D_QPU_A_NEG },
+ { 186, 186, 1 << 2, ANYMUX, V3D_QPU_A_FLAPUSH },
+ { 186, 186, 1 << 3, ANYMUX, V3D_QPU_A_FLBPUSH },
+ { 186, 186, 1 << 4, ANYMUX, V3D_QPU_A_FLBPOP },
+ { 186, 186, 1 << 6, ANYMUX, V3D_QPU_A_SETMSF },
+ { 186, 186, 1 << 7, ANYMUX, V3D_QPU_A_SETREVF },
+ { 187, 187, 1 << 0, 1 << 0, V3D_QPU_A_NOP, 0 },
+ { 187, 187, 1 << 0, 1 << 1, V3D_QPU_A_TIDX },
+ { 187, 187, 1 << 0, 1 << 2, V3D_QPU_A_EIDX },
+ { 187, 187, 1 << 0, 1 << 3, V3D_QPU_A_LR },
+ { 187, 187, 1 << 0, 1 << 4, V3D_QPU_A_VFLA },
+ { 187, 187, 1 << 0, 1 << 5, V3D_QPU_A_VFLNA },
+ { 187, 187, 1 << 0, 1 << 6, V3D_QPU_A_VFLB },
+ { 187, 187, 1 << 0, 1 << 7, V3D_QPU_A_VFLNB },
+
+ { 187, 187, 1 << 1, MUX_MASK(0, 2), V3D_QPU_A_FXCD },
+ { 187, 187, 1 << 1, 1 << 3, V3D_QPU_A_XCD },
+ { 187, 187, 1 << 1, MUX_MASK(4, 6), V3D_QPU_A_FYCD },
+ { 187, 187, 1 << 1, 1 << 7, V3D_QPU_A_YCD },
+
+ { 187, 187, 1 << 2, 1 << 0, V3D_QPU_A_MSF },
+ { 187, 187, 1 << 2, 1 << 1, V3D_QPU_A_REVF },
+ { 187, 187, 1 << 2, 1 << 2, V3D_QPU_A_VDWWT },
+ { 187, 187, 1 << 2, 1 << 5, V3D_QPU_A_TMUWT },
+ { 187, 187, 1 << 2, 1 << 6, V3D_QPU_A_VPMWT },
+
+ { 187, 187, 1 << 3, ANYMUX, V3D_QPU_A_VPMSETUP },
+
+ /* FIXME: MORE COMPLICATED */
+ /* { 190, 191, ANYMUX, ANYMUX, V3D_QPU_A_VFMOVABSNEGNAB }, */
+
+ { 192, 239, ANYMUX, ANYMUX, V3D_QPU_A_FCMP },
+ { 240, 244, ANYMUX, ANYMUX, V3D_QPU_A_VFMAX },
+
+ { 245, 245, MUX_MASK(0, 2), ANYMUX, V3D_QPU_A_FROUND },
+ { 245, 245, 1 << 3, ANYMUX, V3D_QPU_A_FTOIN },
+ { 245, 245, MUX_MASK(4, 6), ANYMUX, V3D_QPU_A_FTRUNC },
+ { 245, 245, 1 << 7, ANYMUX, V3D_QPU_A_FTOIZ },
+ { 246, 246, MUX_MASK(0, 2), ANYMUX, V3D_QPU_A_FFLOOR },
+ { 246, 246, 1 << 3, ANYMUX, V3D_QPU_A_FTOUZ },
+ { 246, 246, MUX_MASK(4, 6), ANYMUX, V3D_QPU_A_FCEIL },
+ { 246, 246, 1 << 7, ANYMUX, V3D_QPU_A_FTOC },
+
+ { 247, 247, MUX_MASK(0, 2), ANYMUX, V3D_QPU_A_FDX },
+ { 247, 247, MUX_MASK(4, 6), ANYMUX, V3D_QPU_A_FDY },
+
+ /* The stvpms are distinguished by the waddr field. */
+ { 248, 248, ANYMUX, ANYMUX, V3D_QPU_A_STVPMV },
+ { 248, 248, ANYMUX, ANYMUX, V3D_QPU_A_STVPMD },
+ { 248, 248, ANYMUX, ANYMUX, V3D_QPU_A_STVPMP },
+
+ { 252, 252, MUX_MASK(0, 2), ANYMUX, V3D_QPU_A_ITOF },
+ { 252, 252, 1 << 3, ANYMUX, V3D_QPU_A_CLZ },
+ { 252, 252, MUX_MASK(4, 6), ANYMUX, V3D_QPU_A_UTOF },
+};
+
+static const struct opcode_desc mul_ops[] = {
+ { 1, 1, ANYMUX, ANYMUX, V3D_QPU_M_ADD },
+ { 2, 2, ANYMUX, ANYMUX, V3D_QPU_M_SUB },
+ { 3, 3, ANYMUX, ANYMUX, V3D_QPU_M_UMUL24 },
+ { 4, 8, ANYMUX, ANYMUX, V3D_QPU_M_VFMUL },
+ { 9, 9, ANYMUX, ANYMUX, V3D_QPU_M_SMUL24 },
+ { 10, 10, ANYMUX, ANYMUX, V3D_QPU_M_MULTOP },
+ { 14, 14, ANYMUX, ANYMUX, V3D_QPU_M_FMOV },
+ { 15, 15, MUX_MASK(0, 3), ANYMUX, V3D_QPU_M_FMOV },
+ { 15, 15, 1 << 4, 1 << 0, V3D_QPU_M_NOP, 0 },
+ { 15, 15, 1 << 7, ANYMUX, V3D_QPU_M_MOV },
+ { 16, 63, ANYMUX, ANYMUX, V3D_QPU_M_FMUL },
+};
+
+static const struct opcode_desc *
+lookup_opcode(const struct opcode_desc *opcodes, size_t num_opcodes,
+ uint32_t opcode, uint32_t mux_a, uint32_t mux_b)
+{
+ for (int i = 0; i < num_opcodes; i++) {
+ const struct opcode_desc *op_desc = &opcodes[i];
+
+ if (opcode < op_desc->opcode_first ||
+ opcode > op_desc->opcode_last)
+ continue;
+
+ if (!(op_desc->mux_b_mask & (1 << mux_b)))
+ continue;
+
+ if (!(op_desc->mux_a_mask & (1 << mux_a)))
+ continue;
+
+ return op_desc;
+ }
+
+ return NULL;
+}
+
+static bool
+v3d_qpu_float32_unpack_unpack(uint32_t packed,
+ enum v3d_qpu_input_unpack *unpacked)
+{
+ switch (packed) {
+ case 0:
+ *unpacked = V3D_QPU_UNPACK_ABS;
+ return true;
+ case 1:
+ *unpacked = V3D_QPU_UNPACK_NONE;
+ return true;
+ case 2:
+ *unpacked = V3D_QPU_UNPACK_L;
+ return true;
+ case 3:
+ *unpacked = V3D_QPU_UNPACK_H;
+ return true;
+ default:
+ return false;
+ }
+}
+
+static bool
+v3d_qpu_float32_unpack_pack(enum v3d_qpu_input_unpack unpacked,
+ uint32_t *packed)
+{
+ switch (unpacked) {
+ case V3D_QPU_UNPACK_ABS:
+ *packed = 0;
+ return true;
+ case V3D_QPU_UNPACK_NONE:
+ *packed = 1;
+ return true;
+ case V3D_QPU_UNPACK_L:
+ *packed = 2;
+ return true;
+ case V3D_QPU_UNPACK_H:
+ *packed = 3;
+ return true;
+ default:
+ return false;
+ }
+}
+
+static bool
+v3d_qpu_float16_unpack_unpack(uint32_t packed,
+ enum v3d_qpu_input_unpack *unpacked)
+{
+ switch (packed) {
+ case 0:
+ *unpacked = V3D_QPU_UNPACK_NONE;
+ return true;
+ case 1:
+ *unpacked = V3D_QPU_UNPACK_REPLICATE_32F_16;
+ return true;
+ case 2:
+ *unpacked = V3D_QPU_UNPACK_REPLICATE_L_16;
+ return true;
+ case 3:
+ *unpacked = V3D_QPU_UNPACK_REPLICATE_H_16;
+ return true;
+ case 4:
+ *unpacked = V3D_QPU_UNPACK_SWAP_16;
+ return true;
+ default:
+ return false;
+ }
+}
+
+static bool
+v3d_qpu_float16_unpack_pack(enum v3d_qpu_input_unpack unpacked,
+ uint32_t *packed)
+{
+ switch (unpacked) {
+ case V3D_QPU_UNPACK_NONE:
+ *packed = 0;
+ return true;
+ case V3D_QPU_UNPACK_REPLICATE_32F_16:
+ *packed = 1;
+ return true;
+ case V3D_QPU_UNPACK_REPLICATE_L_16:
+ *packed = 2;
+ return true;
+ case V3D_QPU_UNPACK_REPLICATE_H_16:
+ *packed = 3;
+ return true;
+ case V3D_QPU_UNPACK_SWAP_16:
+ *packed = 4;
+ return true;
+ default:
+ return false;
+ }
+}
+
+static bool
+v3d_qpu_float32_pack_pack(enum v3d_qpu_input_unpack unpacked,
+ uint32_t *packed)
+{
+ switch (unpacked) {
+ case V3D_QPU_PACK_NONE:
+ *packed = 0;
+ return true;
+ case V3D_QPU_PACK_L:
+ *packed = 1;
+ return true;
+ case V3D_QPU_PACK_H:
+ *packed = 2;
+ return true;
+ default:
+ return false;
+ }
+}
+
+static bool
+v3d_qpu_add_unpack(const struct v3d_device_info *devinfo, uint64_t packed_inst,
+ struct v3d_qpu_instr *instr)
+{
+ uint32_t op = QPU_GET_FIELD(packed_inst, VC5_QPU_OP_ADD);
+ uint32_t mux_a = QPU_GET_FIELD(packed_inst, VC5_QPU_ADD_A);
+ uint32_t mux_b = QPU_GET_FIELD(packed_inst, VC5_QPU_ADD_B);
+ uint32_t waddr = QPU_GET_FIELD(packed_inst, V3D_QPU_WADDR_A);
+
+ uint32_t map_op = op;
+ /* Some big clusters of opcodes are replicated with unpack
+ * flags
+ */
+ if (map_op >= 249 && map_op <= 251)
+ map_op = (map_op - 249 + 245);
+ if (map_op >= 253 && map_op <= 255)
+ map_op = (map_op - 253 + 245);
+
+ const struct opcode_desc *desc =
+ lookup_opcode(add_ops, ARRAY_SIZE(add_ops),
+ map_op, mux_a, mux_b);
+ if (!desc)
+ return false;
+
+ instr->alu.add.op = desc->op;
+
+ /* FADD/FADDNF and FMIN/FMAX are determined by the orders of the
+ * operands.
+ */
+ if (((op >> 2) & 3) * 8 + mux_a > (op & 3) * 8 + mux_b) {
+ if (instr->alu.add.op == V3D_QPU_A_FMIN)
+ instr->alu.add.op = V3D_QPU_A_FMAX;
+ if (instr->alu.add.op == V3D_QPU_A_FADD)
+ instr->alu.add.op = V3D_QPU_A_FADDNF;
+ }
+
+ /* Some QPU ops require a bit more than just basic opcode and mux a/b
+ * comparisons to distinguish them.
+ */
+ switch (instr->alu.add.op) {
+ case V3D_QPU_A_STVPMV:
+ case V3D_QPU_A_STVPMD:
+ case V3D_QPU_A_STVPMP:
+ switch (waddr) {
+ case 0:
+ instr->alu.add.op = V3D_QPU_A_STVPMV;
+ break;
+ case 1:
+ instr->alu.add.op = V3D_QPU_A_STVPMD;
+ break;
+ case 2:
+ instr->alu.add.op = V3D_QPU_A_STVPMP;
+ break;
+ default:
+ return false;
+ }
+ break;
+ default:
+ break;
+ }
+
+ switch (instr->alu.add.op) {
+ case V3D_QPU_A_FADD:
+ case V3D_QPU_A_FADDNF:
+ case V3D_QPU_A_FSUB:
+ case V3D_QPU_A_FMIN:
+ case V3D_QPU_A_FMAX:
+ case V3D_QPU_A_FCMP:
+ instr->alu.add.output_pack = (op >> 4) & 0x3;
+
+ if (!v3d_qpu_float32_unpack_unpack((op >> 2) & 0x3,
+ &instr->alu.add.a_unpack)) {
+ return false;
+ }
+
+ if (!v3d_qpu_float32_unpack_unpack((op >> 0) & 0x3,
+ &instr->alu.add.b_unpack)) {
+ return false;
+ }
+ break;
+
+ case V3D_QPU_A_FFLOOR:
+ case V3D_QPU_A_FROUND:
+ case V3D_QPU_A_FTRUNC:
+ case V3D_QPU_A_FCEIL:
+ case V3D_QPU_A_FDX:
+ case V3D_QPU_A_FDY:
+ instr->alu.add.output_pack = mux_b & 0x3;
+
+ if (!v3d_qpu_float32_unpack_unpack((op >> 2) & 0x3,
+ &instr->alu.add.a_unpack)) {
+ return false;
+ }
+ break;
+
+ case V3D_QPU_A_FTOIN:
+ case V3D_QPU_A_FTOIZ:
+ case V3D_QPU_A_FTOUZ:
+ case V3D_QPU_A_FTOC:
+ instr->alu.add.output_pack = V3D_QPU_PACK_NONE;
+
+ if (!v3d_qpu_float32_unpack_unpack((op >> 2) & 0x3,
+ &instr->alu.add.a_unpack)) {
+ return false;
+ }
+ break;
+
+ case V3D_QPU_A_VFMIN:
+ case V3D_QPU_A_VFMAX:
+ if (!v3d_qpu_float16_unpack_unpack(op & 0x7,
+ &instr->alu.add.a_unpack)) {
+ return false;
+ }
+
+ instr->alu.add.output_pack = V3D_QPU_PACK_NONE;
+ instr->alu.add.b_unpack = V3D_QPU_UNPACK_NONE;
+ break;
+
+ default:
+ instr->alu.add.output_pack = V3D_QPU_PACK_NONE;
+ instr->alu.add.a_unpack = V3D_QPU_UNPACK_NONE;
+ instr->alu.add.b_unpack = V3D_QPU_UNPACK_NONE;
+ break;
+ }
+
+ instr->alu.add.a = mux_a;
+ instr->alu.add.b = mux_b;
+ instr->alu.add.waddr = QPU_GET_FIELD(packed_inst, V3D_QPU_WADDR_A);
+ instr->alu.add.magic_write = packed_inst & VC5_QPU_MA;
+
+ return true;
+}
+
+static bool
+v3d_qpu_mul_unpack(const struct v3d_device_info *devinfo, uint64_t packed_inst,
+ struct v3d_qpu_instr *instr)
+{
+ uint32_t op = QPU_GET_FIELD(packed_inst, VC5_QPU_OP_MUL);
+ uint32_t mux_a = QPU_GET_FIELD(packed_inst, VC5_QPU_MUL_A);
+ uint32_t mux_b = QPU_GET_FIELD(packed_inst, VC5_QPU_MUL_B);
+
+ {
+ const struct opcode_desc *desc =
+ lookup_opcode(mul_ops, ARRAY_SIZE(mul_ops),
+ op, mux_a, mux_b);
+ if (!desc)
+ return false;
+
+ instr->alu.mul.op = desc->op;
+ }
+
+ switch (instr->alu.mul.op) {
+ case V3D_QPU_M_FMUL:
+ instr->alu.mul.output_pack = ((op >> 4) & 0x3) - 1;
+
+ if (!v3d_qpu_float32_unpack_unpack((op >> 2) & 0x3,
+ &instr->alu.mul.a_unpack)) {
+ return false;
+ }
+
+ if (!v3d_qpu_float32_unpack_unpack((op >> 0) & 0x3,
+ &instr->alu.mul.b_unpack)) {
+ return false;
+ }
+
+ break;
+
+ case V3D_QPU_M_FMOV:
+ instr->alu.mul.output_pack = (((op & 1) << 1) +
+ ((mux_b >> 2) & 1));
+
+ if (!v3d_qpu_float32_unpack_unpack(mux_b & 0x3,
+ &instr->alu.mul.a_unpack)) {
+ return false;
+ }
+
+ break;
+ default:
+ instr->alu.mul.output_pack = V3D_QPU_PACK_NONE;
+ instr->alu.mul.a_unpack = V3D_QPU_UNPACK_NONE;
+ instr->alu.mul.b_unpack = V3D_QPU_UNPACK_NONE;
+ break;
+ }
+
+ instr->alu.mul.a = mux_a;
+ instr->alu.mul.b = mux_b;
+ instr->alu.mul.waddr = QPU_GET_FIELD(packed_inst, V3D_QPU_WADDR_M);
+ instr->alu.mul.magic_write = packed_inst & VC5_QPU_MM;
+
+ return true;
+}
+
+static bool
+v3d_qpu_add_pack(const struct v3d_device_info *devinfo,
+ const struct v3d_qpu_instr *instr, uint64_t *packed_instr)
+{
+ uint32_t waddr = instr->alu.add.waddr;
+ uint32_t mux_a = instr->alu.add.a;
+ uint32_t mux_b = instr->alu.add.b;
+ int nsrc = v3d_qpu_add_op_num_src(instr->alu.add.op);
+ const struct opcode_desc *desc;
+
+ int opcode;
+ for (desc = add_ops; desc != &add_ops[ARRAY_SIZE(add_ops)];
+ desc++) {
+ if (desc->op == instr->alu.add.op)
+ break;
+ }
+ if (desc == &add_ops[ARRAY_SIZE(add_ops)])
+ return false;
+
+ opcode = desc->opcode_first;
+
+ /* If an operation doesn't use an arg, its mux values may be used to
+ * identify the operation type.
+ */
+ if (nsrc < 2)
+ mux_b = ffs(desc->mux_b_mask) - 1;
+
+ if (nsrc < 1)
+ mux_a = ffs(desc->mux_a_mask) - 1;
+
+ switch (instr->alu.add.op) {
+ case V3D_QPU_A_STVPMV:
+ waddr = 0;
+ break;
+ case V3D_QPU_A_STVPMD:
+ waddr = 1;
+ break;
+ case V3D_QPU_A_STVPMP:
+ waddr = 2;
+ break;
+ default:
+ break;
+ }
+
+ switch (instr->alu.add.op) {
+ case V3D_QPU_A_FADD:
+ case V3D_QPU_A_FADDNF:
+ case V3D_QPU_A_FSUB:
+ case V3D_QPU_A_FMIN:
+ case V3D_QPU_A_FMAX:
+ case V3D_QPU_A_FCMP: {
+ uint32_t output_pack;
+ uint32_t a_unpack;
+ uint32_t b_unpack;
+
+ if (!v3d_qpu_float32_pack_pack(instr->alu.add.output_pack,
+ &output_pack)) {
+ return false;
+ }
+ opcode |= output_pack << 4;
+
+ if (!v3d_qpu_float32_unpack_pack(instr->alu.add.a_unpack,
+ &a_unpack)) {
+ return false;
+ }
+
+ if (!v3d_qpu_float32_unpack_pack(instr->alu.add.b_unpack,
+ &b_unpack)) {
+ return false;
+ }
+
+ /* These operations with commutative operands are
+ * distinguished by which order their operands come in.
+ */
+ bool ordering = a_unpack * 8 + mux_a > b_unpack * 8 + mux_b;
+ if (((instr->alu.add.op == V3D_QPU_A_FMIN ||
+ instr->alu.add.op == V3D_QPU_A_FADD) && ordering) ||
+ ((instr->alu.add.op == V3D_QPU_A_FMAX ||
+ instr->alu.add.op == V3D_QPU_A_FADDNF) && !ordering)) {
+ uint32_t temp;
+
+ temp = a_unpack;
+ a_unpack = b_unpack;
+ b_unpack = temp;
+
+ temp = mux_a;
+ mux_a = mux_b;
+ mux_b = temp;
+ }
+
+ opcode |= a_unpack << 2;
+ opcode |= b_unpack << 0;
+ break;
+ }
+
+ case V3D_QPU_A_FFLOOR:
+ case V3D_QPU_A_FROUND:
+ case V3D_QPU_A_FTRUNC:
+ case V3D_QPU_A_FCEIL:
+ case V3D_QPU_A_FDX:
+ case V3D_QPU_A_FDY: {
+ uint32_t packed;
+
+ if (!v3d_qpu_float32_pack_pack(instr->alu.add.output_pack,
+ &packed)) {
+ return false;
+ }
+ mux_b |= packed;
+
+ if (!v3d_qpu_float32_unpack_pack(instr->alu.add.a_unpack,
+ &packed)) {
+ return false;
+ }
+ if (packed == 0)
+ return false;
+ opcode |= packed << 2;
+ break;
+ }
+
+ case V3D_QPU_A_FTOIN:
+ case V3D_QPU_A_FTOIZ:
+ case V3D_QPU_A_FTOUZ:
+ case V3D_QPU_A_FTOC:
+ if (instr->alu.add.output_pack != V3D_QPU_PACK_NONE)
+ return false;
+
+ uint32_t packed;
+ if (!v3d_qpu_float32_unpack_pack(instr->alu.add.a_unpack,
+ &packed)) {
+ return false;
+ }
+ if (packed == 0)
+ return false;
+ opcode |= packed << 2;
+
+ break;
+
+ case V3D_QPU_A_VFMIN:
+ case V3D_QPU_A_VFMAX:
+ if (instr->alu.add.output_pack != V3D_QPU_PACK_NONE ||
+ instr->alu.add.b_unpack != V3D_QPU_UNPACK_NONE) {
+ return false;
+ }
+
+ if (!v3d_qpu_float16_unpack_pack(instr->alu.add.a_unpack,
+ &packed)) {
+ return false;
+ }
+ opcode |= packed;
+ break;
+
+ default:
+ if (instr->alu.add.op != V3D_QPU_A_NOP &&
+ (instr->alu.add.output_pack != V3D_QPU_PACK_NONE ||
+ instr->alu.add.a_unpack != V3D_QPU_UNPACK_NONE ||
+ instr->alu.add.b_unpack != V3D_QPU_UNPACK_NONE)) {
+ return false;
+ }
+ break;
+ }
+
+ *packed_instr |= QPU_SET_FIELD(mux_a, VC5_QPU_ADD_A);
+ *packed_instr |= QPU_SET_FIELD(mux_b, VC5_QPU_ADD_B);
+ *packed_instr |= QPU_SET_FIELD(opcode, VC5_QPU_OP_ADD);
+ *packed_instr |= QPU_SET_FIELD(waddr, V3D_QPU_WADDR_A);
+ if (instr->alu.add.magic_write)
+ *packed_instr |= VC5_QPU_MA;
+
+ return true;
+}
+
+static bool
+v3d_qpu_mul_pack(const struct v3d_device_info *devinfo,
+ const struct v3d_qpu_instr *instr, uint64_t *packed_instr)
+{
+ uint32_t mux_a = instr->alu.mul.a;
+ uint32_t mux_b = instr->alu.mul.b;
+ int nsrc = v3d_qpu_mul_op_num_src(instr->alu.mul.op);
+ const struct opcode_desc *desc;
+
+ for (desc = mul_ops; desc != &mul_ops[ARRAY_SIZE(mul_ops)];
+ desc++) {
+ if (desc->op == instr->alu.mul.op)
+ break;
+ }
+ if (desc == &mul_ops[ARRAY_SIZE(mul_ops)])
+ return false;
+
+ uint32_t opcode = desc->opcode_first;
+
+ /* Some opcodes have a single valid value for their mux a/b, so set
+ * that here. If mux a/b determine packing, it will be set below.
+ */
+ if (nsrc < 2)
+ mux_b = ffs(desc->mux_b_mask) - 1;
+
+ if (nsrc < 1)
+ mux_a = ffs(desc->mux_a_mask) - 1;
+
+ switch (instr->alu.mul.op) {
+ case V3D_QPU_M_FMUL: {
+ uint32_t packed;
+
+ if (!v3d_qpu_float32_pack_pack(instr->alu.mul.output_pack,
+ &packed)) {
+ return false;
+ }
+ /* No need for a +1 because desc->opcode_first has a 1 in this
+ * field.
+ */
+ opcode += packed << 4;
+
+ if (!v3d_qpu_float32_unpack_pack(instr->alu.mul.a_unpack,
+ &packed)) {
+ return false;
+ }
+ opcode |= packed << 2;
+
+ if (!v3d_qpu_float32_unpack_pack(instr->alu.mul.b_unpack,
+ &packed)) {
+ return false;
+ }
+ opcode |= packed << 0;
+ break;
+ }
+
+ case V3D_QPU_M_FMOV: {
+ uint32_t packed;
+
+ if (!v3d_qpu_float32_pack_pack(instr->alu.mul.output_pack,
+ &packed)) {
+ return false;
+ }
+ opcode |= (packed >> 1) & 1;
+ mux_b = (packed & 1) << 2;
+
+ if (!v3d_qpu_float32_unpack_pack(instr->alu.mul.a_unpack,
+ &packed)) {
+ return false;
+ }
+ mux_b |= packed;
+ break;
+ }
+
+ default:
+ break;
+ }
+
+ *packed_instr |= QPU_SET_FIELD(mux_a, VC5_QPU_MUL_A);
+ *packed_instr |= QPU_SET_FIELD(mux_b, VC5_QPU_MUL_B);
+
+ *packed_instr |= QPU_SET_FIELD(opcode, VC5_QPU_OP_MUL);
+ *packed_instr |= QPU_SET_FIELD(instr->alu.mul.waddr, V3D_QPU_WADDR_M);
+ if (instr->alu.mul.magic_write)
+ *packed_instr |= VC5_QPU_MM;
+
+ return true;
+}
+
+static bool
+v3d_qpu_instr_unpack_alu(const struct v3d_device_info *devinfo,
+ uint64_t packed_instr,
+ struct v3d_qpu_instr *instr)
+{
+ instr->type = V3D_QPU_INSTR_TYPE_ALU;
+
+ if (!v3d_qpu_sig_unpack(devinfo,
+ QPU_GET_FIELD(packed_instr, VC5_QPU_SIG),
+ &instr->sig))
+ return false;
+
+ if (!v3d_qpu_flags_unpack(devinfo,
+ QPU_GET_FIELD(packed_instr, VC5_QPU_COND),
+ &instr->flags))
+ return false;
+
+ instr->raddr_a = QPU_GET_FIELD(packed_instr, VC5_QPU_RADDR_A);
+ instr->raddr_b = QPU_GET_FIELD(packed_instr, VC5_QPU_RADDR_B);
+
+ if (!v3d_qpu_add_unpack(devinfo, packed_instr, instr))
+ return false;
+
+ if (!v3d_qpu_mul_unpack(devinfo, packed_instr, instr))
+ return false;
+
+ return true;
+}
+
+static bool
+v3d_qpu_instr_unpack_branch(const struct v3d_device_info *devinfo,
+ uint64_t packed_instr,
+ struct v3d_qpu_instr *instr)
+{
+ instr->type = V3D_QPU_INSTR_TYPE_BRANCH;
+
+ uint32_t cond = QPU_GET_FIELD(packed_instr, VC5_QPU_BRANCH_COND);
+ if (cond == 0)
+ instr->branch.cond = V3D_QPU_BRANCH_COND_ALWAYS;
+ else if (V3D_QPU_BRANCH_COND_A0 + (cond - 2) <=
+ V3D_QPU_BRANCH_COND_ALLNA)
+ instr->branch.cond = V3D_QPU_BRANCH_COND_A0 + (cond - 2);
+ else
+ return false;
+
+ uint32_t msfign = QPU_GET_FIELD(packed_instr, VC5_QPU_BRANCH_MSFIGN);
+ if (msfign == 3)
+ return false;
+ instr->branch.msfign = msfign;
+
+ instr->branch.bdi = QPU_GET_FIELD(packed_instr, VC5_QPU_BRANCH_BDI);
+
+ instr->branch.ub = packed_instr & VC5_QPU_BRANCH_UB;
+ if (instr->branch.ub) {
+ instr->branch.bdu = QPU_GET_FIELD(packed_instr,
+ VC5_QPU_BRANCH_BDU);
+ }
+
+ instr->branch.raddr_a = QPU_GET_FIELD(packed_instr,
+ VC5_QPU_RADDR_A);
+
+ instr->branch.offset = 0;
+
+ instr->branch.offset +=
+ QPU_GET_FIELD(packed_instr,
+ VC5_QPU_BRANCH_ADDR_LOW) << 3;
+
+ instr->branch.offset +=
+ QPU_GET_FIELD(packed_instr,
+ VC5_QPU_BRANCH_ADDR_HIGH) << 24;
+
+ return true;
+}
+
+bool
+v3d_qpu_instr_unpack(const struct v3d_device_info *devinfo,
+ uint64_t packed_instr,
+ struct v3d_qpu_instr *instr)
+{
+ if (QPU_GET_FIELD(packed_instr, VC5_QPU_OP_MUL) != 0) {
+ return v3d_qpu_instr_unpack_alu(devinfo, packed_instr, instr);
+ } else {
+ uint32_t sig = QPU_GET_FIELD(packed_instr, VC5_QPU_SIG);
+
+ if ((sig & 24) == 16) {
+ return v3d_qpu_instr_unpack_branch(devinfo, packed_instr,
+ instr);
+ } else {
+ return false;
+ }
+ }
+}
+
+static bool
+v3d_qpu_instr_pack_alu(const struct v3d_device_info *devinfo,
+ const struct v3d_qpu_instr *instr,
+ uint64_t *packed_instr)
+{
+ uint32_t sig;
+ if (!v3d_qpu_sig_pack(devinfo, &instr->sig, &sig))
+ return false;
+ *packed_instr |= QPU_SET_FIELD(sig, VC5_QPU_SIG);
+
+ if (instr->type == V3D_QPU_INSTR_TYPE_ALU) {
+ *packed_instr |= QPU_SET_FIELD(instr->raddr_a, VC5_QPU_RADDR_A);
+ *packed_instr |= QPU_SET_FIELD(instr->raddr_b, VC5_QPU_RADDR_B);
+
+ if (!v3d_qpu_add_pack(devinfo, instr, packed_instr))
+ return false;
+ if (!v3d_qpu_mul_pack(devinfo, instr, packed_instr))
+ return false;
+
+ uint32_t flags;
+ if (!v3d_qpu_flags_pack(devinfo, &instr->flags, &flags))
+ return false;
+ *packed_instr |= QPU_SET_FIELD(flags, VC5_QPU_COND);
+ }
+
+ return true;
+}
+
+static bool
+v3d_qpu_instr_pack_branch(const struct v3d_device_info *devinfo,
+ const struct v3d_qpu_instr *instr,
+ uint64_t *packed_instr)
+{
+ *packed_instr |= QPU_SET_FIELD(16, VC5_QPU_SIG);
+
+ if (instr->branch.cond != V3D_QPU_BRANCH_COND_ALWAYS) {
+ *packed_instr |= QPU_SET_FIELD(2 + (instr->branch.cond -
+ V3D_QPU_BRANCH_COND_A0),
+ VC5_QPU_BRANCH_COND);
+ }
+
+ *packed_instr |= QPU_SET_FIELD(instr->branch.msfign,
+ VC5_QPU_BRANCH_MSFIGN);
+
+ *packed_instr |= QPU_SET_FIELD(instr->branch.bdi,
+ VC5_QPU_BRANCH_BDI);
+
+ if (instr->branch.ub) {
+ *packed_instr |= VC5_QPU_BRANCH_UB;
+ *packed_instr |= QPU_SET_FIELD(instr->branch.bdu,
+ VC5_QPU_BRANCH_BDU);
+ }
+
+ switch (instr->branch.bdi) {
+ case V3D_QPU_BRANCH_DEST_ABS:
+ case V3D_QPU_BRANCH_DEST_REL:
+ *packed_instr |= QPU_SET_FIELD(instr->branch.msfign,
+ VC5_QPU_BRANCH_MSFIGN);
+
+ *packed_instr |= QPU_SET_FIELD((instr->branch.offset &
+ ~0xff000000) >> 3,
+ VC5_QPU_BRANCH_ADDR_LOW);
+
+ *packed_instr |= QPU_SET_FIELD(instr->branch.offset >> 24,
+ VC5_QPU_BRANCH_ADDR_HIGH);
+
+ case V3D_QPU_BRANCH_DEST_REGFILE:
+ *packed_instr |= QPU_SET_FIELD(instr->branch.raddr_a,
+ VC5_QPU_RADDR_A);
+ break;
+
+ default:
+ break;
+ }
+
+ return true;
+}
+
+bool
+v3d_qpu_instr_pack(const struct v3d_device_info *devinfo,
+ const struct v3d_qpu_instr *instr,
+ uint64_t *packed_instr)
+{
+ *packed_instr = 0;
+
+ switch (instr->type) {
+ case V3D_QPU_INSTR_TYPE_ALU:
+ return v3d_qpu_instr_pack_alu(devinfo, instr, packed_instr);
+ case V3D_QPU_INSTR_TYPE_BRANCH:
+ return v3d_qpu_instr_pack_branch(devinfo, instr, packed_instr);
+ default:
+ return false;
+ }
+}
diff --git a/lib/mesa/src/broadcom/qpu/tests/qpu_disasm.c b/lib/mesa/src/broadcom/qpu/tests/qpu_disasm.c
new file mode 100644
index 000000000..c7f6476de
--- /dev/null
+++ b/lib/mesa/src/broadcom/qpu/tests/qpu_disasm.c
@@ -0,0 +1,146 @@
+/*
+ * Copyright © 2016 Broadcom
+ *
+ * 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 <stdio.h>
+#include <string.h>
+#include "util/macros.h"
+#include "broadcom/common/v3d_device_info.h"
+#include "broadcom/qpu/qpu_disasm.h"
+#include "broadcom/qpu/qpu_instr.h"
+
+static const struct {
+ int ver;
+ uint64_t inst;
+ const char *expected;
+} tests[] = {
+ { 33, 0x3d003186bb800000ull, "nop ; nop ; ldvary" },
+ { 33, 0x3c20318105829000ull, "fadd r1, r1, r5 ; nop ; thrsw" },
+ { 33, 0x3c403186bb81d000ull, "vpmsetup -, r5 ; nop ; ldunif" },
+ { 33, 0x3f003186bb800000ull, "nop ; nop ; ldvpm" },
+ { 33, 0x3c002380b6edb000ull, "or rf0, r3, r3 ; mov vpm, r3" },
+ { 33, 0x57403006bbb80000ull, "nop ; fmul r0, rf0, r5 ; ldvpm; ldunif" },
+
+ /* branch conditions */
+ { 33, 0x02000006002034c0ull, "b.anyap rf19" },
+ { 33, 0x02679356b4201000ull, "b.anyap -1268280496" },
+ { 33, 0x02b76a2dd0400000ull, "b.anynaq zero_addr+0xd0b76a28" },
+ { 33, 0x0200000500402000ull, "b.anynaq lri" },
+ { 33, 0x0216fe167301c8c0ull, "bu.anya zero_addr+0x7316fe10, rf35" },
+ { 33, 0x020000050040e000ull, "bu.anynaq lri, r:unif" },
+ { 33, 0x0200000300006000ull, "bu.na0 lri, a:unif" },
+
+ /* Special waddr names */
+ { 33, 0x3c00318735808000ull, "vfpack tlb, r0, r1 ; nop" },
+ { 33, 0xe0571c938e8d5000ull, "fmax.andc recip, r5.h, r2.l; fmul.ifb rf50.h, r3.l, r4.abs; ldunif" },
+ { 33, 0xc04098d4382c9000ull, "add.pushn rsqrt, r1, r1; fmul rf35.h, r3.abs, r1.abs; ldunif" },
+ { 33, 0x481edcd6b3184500ull, "vfmin.norn log, r4.hh, r0; fmul.ifnb rf51, rf20.abs, r0.l" },
+ { 33, 0x041618d57c453000ull, "shl.andn exp, r3, r2; add.ifb rf35, r1, r2" },
+ { 33, 0x7048e5da49272800ull, "fsub.ifa rf26, r2.l, rf32; fmul.pushc sin, r1.h, r1.abs; ldunif" },
+
+};
+
+static void
+swap_mux(enum v3d_qpu_mux *a, enum v3d_qpu_mux *b)
+{
+ enum v3d_qpu_mux t = *a;
+ *a = *b;
+ *b = t;
+}
+
+static void
+swap_pack(enum v3d_qpu_input_unpack *a, enum v3d_qpu_input_unpack *b)
+{
+ enum v3d_qpu_input_unpack t = *a;
+ *a = *b;
+ *b = t;
+}
+
+int
+main(int argc, char **argv)
+{
+ struct v3d_device_info devinfo = { };
+ int retval = 0;
+
+ for (int i = 0; i < ARRAY_SIZE(tests); i++) {
+ devinfo.ver = tests[i].ver;
+
+ printf("Testing v%d.%d 0x%016llx... ",
+ devinfo.ver / 10, devinfo.ver % 10,
+ (long long)tests[i].inst);
+
+ const char *disasm_output = v3d_qpu_disasm(&devinfo,
+ tests[i].inst);
+
+ if (strcmp(disasm_output, tests[i].expected) != 0) {
+ printf("FAIL\n");
+ printf(" Expected: \"%s\"\n", tests[i].expected);
+ printf(" Got: \"%s\"\n", disasm_output);
+ retval = 1;
+ continue;
+ }
+
+ struct v3d_qpu_instr instr;
+ if (!v3d_qpu_instr_unpack(&devinfo, tests[i].inst, &instr)) {
+ printf("FAIL (unpack) %s\n", tests[i].expected);
+ retval = 1;
+ continue;
+ }
+
+ if (instr.type == V3D_QPU_INSTR_TYPE_ALU) {
+ switch (instr.alu.add.op) {
+ case V3D_QPU_A_FADD:
+ case V3D_QPU_A_FADDNF:
+ case V3D_QPU_A_FMIN:
+ case V3D_QPU_A_FMAX:
+ /* Swap the operands to be sure that we test
+ * how the QPUs distinguish between these ops.
+ */
+ swap_mux(&instr.alu.add.a,
+ &instr.alu.add.b);
+ swap_pack(&instr.alu.add.a_unpack,
+ &instr.alu.add.b_unpack);
+ default:
+ break;
+ }
+ }
+
+ uint64_t repack;
+ if (!v3d_qpu_instr_pack(&devinfo, &instr, &repack)) {
+ printf("FAIL (pack) %s\n", tests[i].expected);
+ retval = 1;
+ continue;
+ }
+
+ if (repack != tests[i].inst) {
+ printf("FAIL (repack) 0x%016llx\n", (long long)repack);
+ printf(" Expected: \"%s\"\n", tests[i].expected);
+ const char *redisasm = v3d_qpu_disasm(&devinfo, repack);
+ printf(" Got: \"%s\"\n", redisasm);
+ retval = 1;
+ }
+
+ printf("PASS\n");
+ }
+
+ return retval;
+}
diff --git a/lib/mesa/src/egl/SConscript b/lib/mesa/src/egl/SConscript
index 8f8b11a61..927092d22 100644
--- a/lib/mesa/src/egl/SConscript
+++ b/lib/mesa/src/egl/SConscript
@@ -24,6 +24,8 @@ env.Append(CPPDEFINES = [
])
egl_sources.append('drivers/haiku/egl_haiku.cpp')
+env.Prepend(LIBS = [mesautil])
+
egl = env.SharedLibrary(
target = 'EGL',
source = egl_sources,
diff --git a/lib/mesa/src/egl/drivers/dri2/platform_x11_dri3.h b/lib/mesa/src/egl/drivers/dri2/platform_x11_dri3.h
index 13d857242..96e7ee972 100644
--- a/lib/mesa/src/egl/drivers/dri2/platform_x11_dri3.h
+++ b/lib/mesa/src/egl/drivers/dri2/platform_x11_dri3.h
@@ -28,7 +28,7 @@
_EGL_DRIVER_TYPECAST(dri3_egl_surface, _EGLSurface, obj)
struct dri3_egl_surface {
- _EGLSurface base;
+ struct dri2_egl_surface surf;
struct loader_dri3_drawable loader_drawable;
};
diff --git a/lib/mesa/src/egl/main/eglcurrent.h b/lib/mesa/src/egl/main/eglcurrent.h
index 9ec07bac8..d9a4a9017 100644
--- a/lib/mesa/src/egl/main/eglcurrent.h
+++ b/lib/mesa/src/egl/main/eglcurrent.h
@@ -99,13 +99,6 @@ _eglGetCurrentContext(void);
extern EGLBoolean
_eglError(EGLint errCode, const char *msg);
-extern EGLLabelKHR
-_eglGetThreadLabel(void);
-
-extern void
-_eglDebugReportFull(EGLenum error, const char *command, const char *funcName,
- EGLint type, EGLLabelKHR objectLabel, const char *message, ...);
-
extern void
_eglDebugReport(EGLenum error, const char *funcName,
EGLint type, const char *message, ...);
diff --git a/lib/mesa/src/egl/main/egldriver.c b/lib/mesa/src/egl/main/egldriver.c
index b9b21dec5..34a90ae5d 100644
--- a/lib/mesa/src/egl/main/egldriver.c
+++ b/lib/mesa/src/egl/main/egldriver.c
@@ -44,250 +44,48 @@
#include "egldriver.h"
#include "egllog.h"
-typedef struct _egl_module {
- char *Name;
- _EGLMain_t BuiltIn;
- _EGLDriver *Driver;
-} _EGLModule;
+#include "util/debug.h"
static mtx_t _eglModuleMutex = _MTX_INITIALIZER_NP;
-static _EGLArray *_eglModules;
+static _EGLDriver *_eglDriver;
-const struct {
- const char *name;
- _EGLMain_t main;
-} _eglBuiltInDrivers[] = {
-#ifdef _EGL_BUILT_IN_DRIVER_DRI2
- { "egl_dri2", _eglBuiltInDriverDRI2 },
-#endif
-#ifdef _EGL_BUILT_IN_DRIVER_HAIKU
- { "egl_haiku", _eglBuiltInDriverHaiku },
-#endif
- { NULL, NULL }
-};
-
-/**
- * Load a module and create the driver object.
- */
-static EGLBoolean
-_eglLoadModule(_EGLModule *mod)
-{
- _EGLDriver *drv;
-
- if (mod->Driver)
- return EGL_TRUE;
-
- if (!mod->BuiltIn)
- return EGL_FALSE;
-
- drv = mod->BuiltIn(NULL);
- if (!drv || !drv->Name)
- return EGL_FALSE;
-
- mod->Driver = drv;
-
- return EGL_TRUE;
-}
-
-
-/**
- * Unload a module.
- */
-static void
-_eglUnloadModule(_EGLModule *mod)
-{
- /* destroy the driver */
- if (mod->Driver && mod->Driver->Unload)
- mod->Driver->Unload(mod->Driver);
-
- mod->Driver = NULL;
-}
-
-
-/**
- * Add a module to the module array.
- */
-static _EGLModule *
-_eglAddModule(const char *name)
-{
- _EGLModule *mod;
- EGLint i;
-
- if (!_eglModules) {
- _eglModules = _eglCreateArray("Module", 8);
- if (!_eglModules)
- return NULL;
- }
-
- /* find duplicates */
- for (i = 0; i < _eglModules->Size; i++) {
- mod = _eglModules->Elements[i];
- if (strcmp(mod->Name, name) == 0)
- return mod;
- }
-
- /* allocate a new one */
- mod = calloc(1, sizeof(*mod));
- if (mod) {
- mod->Name = strdup(name);
- if (!mod->Name) {
- free(mod);
- mod = NULL;
- }
- }
- if (mod) {
- _eglAppendArray(_eglModules, (void *) mod);
- _eglLog(_EGL_DEBUG, "added %s to module array", mod->Name);
- }
-
- return mod;
-}
-
-
-/**
- * Free a module.
- */
-static void
-_eglFreeModule(void *module)
-{
- _EGLModule *mod = (_EGLModule *) module;
-
- _eglUnloadModule(mod);
- free(mod->Name);
- free(mod);
-}
-
-
-/**
- * Add the user driver to the module array.
- *
- * The user driver is specified by EGL_DRIVER.
- */
-static EGLBoolean
-_eglAddUserDriver(void)
-{
- char *env;
-
- env = getenv("EGL_DRIVER");
- if (env) {
- EGLint i;
-
- for (i = 0; _eglBuiltInDrivers[i].name; i++) {
- if (!strcmp(_eglBuiltInDrivers[i].name, env)) {
- _EGLModule *mod = _eglAddModule(env);
- if (mod)
- mod->BuiltIn = _eglBuiltInDrivers[i].main;
-
- return EGL_TRUE;
- }
- }
- }
-
- return EGL_FALSE;
-}
-
-
-/**
- * Add built-in drivers to the module array.
- */
-static void
-_eglAddBuiltInDrivers(void)
+static _EGLDriver *
+_eglGetDriver(void)
{
- _EGLModule *mod;
- EGLint i;
-
- for (i = 0; _eglBuiltInDrivers[i].name; i++) {
- mod = _eglAddModule(_eglBuiltInDrivers[i].name);
- if (mod)
- mod->BuiltIn = _eglBuiltInDrivers[i].main;
- }
-}
+ mtx_lock(&_eglModuleMutex);
+ if (!_eglDriver)
+ _eglDriver = _eglBuiltInDriver();
-/**
- * Add drivers to the module array. Drivers will be loaded as they are matched
- * to displays.
- */
-static EGLBoolean
-_eglAddDrivers(void)
-{
- if (_eglModules)
- return EGL_TRUE;
-
- if (!_eglAddUserDriver()) {
- /*
- * Add other drivers only when EGL_DRIVER is not set. The order here
- * decides the priorities.
- */
- _eglAddBuiltInDrivers();
- }
+ mtx_unlock(&_eglModuleMutex);
- return (_eglModules != NULL);
+ return _eglDriver;
}
-
-/**
- * A helper function for _eglMatchDriver. It finds the first driver that can
- * initialize the display and return.
- */
static _EGLDriver *
_eglMatchAndInitialize(_EGLDisplay *dpy)
{
- _EGLDriver *drv = NULL;
- EGLint i = 0;
-
- if (!_eglAddDrivers()) {
- _eglLog(_EGL_WARNING, "failed to find any driver");
- return NULL;
- }
-
- if (dpy->Driver) {
- drv = dpy->Driver;
- /* no re-matching? */
- if (!drv->API.Initialize(drv, dpy))
- drv = NULL;
- return drv;
- }
-
- while (i < _eglModules->Size) {
- _EGLModule *mod = (_EGLModule *) _eglModules->Elements[i];
+ if (_eglGetDriver())
+ if (_eglDriver->API.Initialize(_eglDriver, dpy))
+ return _eglDriver;
- if (!_eglLoadModule(mod)) {
- /* remove invalid modules */
- _eglEraseArray(_eglModules, i, _eglFreeModule);
- continue;
- }
-
- if (mod->Driver->API.Initialize(mod->Driver, dpy)) {
- drv = mod->Driver;
- break;
- }
- else {
- i++;
- }
- }
-
- return drv;
+ return NULL;
}
-
/**
- * Match a display to a driver. The display is initialized unless test_only is
- * true. The matching is done by finding the first driver that can initialize
- * the display.
+ * Match a display to a driver. The matching is done by finding the first
+ * driver that can initialize the display.
*/
_EGLDriver *
-_eglMatchDriver(_EGLDisplay *dpy, EGLBoolean test_only)
+_eglMatchDriver(_EGLDisplay *dpy)
{
_EGLDriver *best_drv;
assert(!dpy->Initialized);
- mtx_lock(&_eglModuleMutex);
-
/* set options */
- dpy->Options.TestOnly = test_only;
- dpy->Options.UseFallback = EGL_FALSE;
+ dpy->Options.UseFallback =
+ env_var_as_boolean("LIBGL_ALWAYS_SOFTWARE", false);
best_drv = _eglMatchAndInitialize(dpy);
if (!best_drv) {
@@ -295,49 +93,25 @@ _eglMatchDriver(_EGLDisplay *dpy, EGLBoolean test_only)
best_drv = _eglMatchAndInitialize(dpy);
}
- mtx_unlock(&_eglModuleMutex);
-
if (best_drv) {
- _eglLog(_EGL_DEBUG, "the best driver is %s%s",
- best_drv->Name, (test_only) ? " (test only) " : "");
- if (!test_only) {
- dpy->Driver = best_drv;
- dpy->Initialized = EGL_TRUE;
- }
+ _eglLog(_EGL_DEBUG, "the best driver is %s",
+ best_drv->Name);
+ dpy->Driver = best_drv;
+ dpy->Initialized = EGL_TRUE;
}
return best_drv;
}
-
__eglMustCastToProperFunctionPointerType
_eglGetDriverProc(const char *procname)
{
- EGLint i;
- _EGLProc proc = NULL;
-
- if (!_eglModules) {
- /* load the driver for the default display */
- EGLDisplay egldpy = eglGetDisplay(EGL_DEFAULT_DISPLAY);
- _EGLDisplay *dpy = _eglLookupDisplay(egldpy);
- if (!dpy || !_eglMatchDriver(dpy, EGL_TRUE))
- return NULL;
- }
+ if (_eglGetDriver())
+ return _eglDriver->API.GetProcAddress(_eglDriver, procname);
- for (i = 0; i < _eglModules->Size; i++) {
- _EGLModule *mod = (_EGLModule *) _eglModules->Elements[i];
-
- if (!mod->Driver)
- break;
- proc = mod->Driver->API.GetProcAddress(mod->Driver, procname);
- if (proc)
- break;
- }
-
- return proc;
+ return NULL;
}
-
/**
* Unload all drivers.
*/
@@ -345,8 +119,6 @@ void
_eglUnloadDrivers(void)
{
/* this is called at atexit time */
- if (_eglModules) {
- _eglDestroyArray(_eglModules, _eglFreeModule);
- _eglModules = NULL;
- }
+ free(_eglDriver);
+ _eglDriver = NULL;
}
diff --git a/lib/mesa/src/egl/main/egldriver.h b/lib/mesa/src/egl/main/egldriver.h
index 1cf662844..6ab667c4e 100644
--- a/lib/mesa/src/egl/main/egldriver.h
+++ b/lib/mesa/src/egl/main/egldriver.h
@@ -70,9 +70,6 @@ extern "C" {
_EGL_DRIVER_TYPECAST(drvname ## _config, _EGLConfig, obj)
-typedef _EGLDriver *(*_EGLMain_t)(const char *args);
-
-
/**
* Base class for device drivers.
*/
@@ -80,27 +77,16 @@ struct _egl_driver
{
const char *Name; /**< name of this driver */
- /**
- * Release the driver resource.
- *
- * It is called before dlclose().
- */
- void (*Unload)(_EGLDriver *drv);
-
_EGLAPI API; /**< EGL API dispatch table */
};
-extern _EGLDriver *
-_eglBuiltInDriverDRI2(const char *args);
-
-
extern _EGLDriver*
-_eglBuiltInDriverHaiku(const char* args);
+_eglBuiltInDriver(void);
extern _EGLDriver *
-_eglMatchDriver(_EGLDisplay *dpy, EGLBoolean test_only);
+_eglMatchDriver(_EGLDisplay *dpy);
extern __eglMustCastToProperFunctionPointerType
diff --git a/lib/mesa/src/egl/wayland/wayland-drm/Makefile.am b/lib/mesa/src/egl/wayland/wayland-drm/Makefile.am
index f40ff4841..b27edddaf 100644
--- a/lib/mesa/src/egl/wayland/wayland-drm/Makefile.am
+++ b/lib/mesa/src/egl/wayland/wayland-drm/Makefile.am
@@ -2,7 +2,7 @@ AM_CFLAGS = -I$(top_srcdir)/src/egl/main \
-I$(top_srcdir)/include \
$(DEFINES) \
$(VISIBILITY_CFLAGS) \
- $(WAYLAND_CFLAGS)
+ $(WAYLAND_SERVER_CFLAGS)
noinst_LTLIBRARIES = libwayland-drm.la
libwayland_drm_la_SOURCES = \
diff --git a/lib/mesa/src/egl/wayland/wayland-drm/wayland-drm.h b/lib/mesa/src/egl/wayland/wayland-drm/wayland-drm.h
index 7892d561f..111383ff1 100644
--- a/lib/mesa/src/egl/wayland/wayland-drm/wayland-drm.h
+++ b/lib/mesa/src/egl/wayland/wayland-drm/wayland-drm.h
@@ -3,71 +3,9 @@
#include <wayland-server.h>
-#ifndef WL_DRM_FORMAT_ENUM
-#define WL_DRM_FORMAT_ENUM
-enum wl_drm_format {
- WL_DRM_FORMAT_C8 = 0x20203843,
- WL_DRM_FORMAT_RGB332 = 0x38424752,
- WL_DRM_FORMAT_BGR233 = 0x38524742,
- WL_DRM_FORMAT_XRGB4444 = 0x32315258,
- WL_DRM_FORMAT_XBGR4444 = 0x32314258,
- WL_DRM_FORMAT_RGBX4444 = 0x32315852,
- WL_DRM_FORMAT_BGRX4444 = 0x32315842,
- WL_DRM_FORMAT_ARGB4444 = 0x32315241,
- WL_DRM_FORMAT_ABGR4444 = 0x32314241,
- WL_DRM_FORMAT_RGBA4444 = 0x32314152,
- WL_DRM_FORMAT_BGRA4444 = 0x32314142,
- WL_DRM_FORMAT_XRGB1555 = 0x35315258,
- WL_DRM_FORMAT_XBGR1555 = 0x35314258,
- WL_DRM_FORMAT_RGBX5551 = 0x35315852,
- WL_DRM_FORMAT_BGRX5551 = 0x35315842,
- WL_DRM_FORMAT_ARGB1555 = 0x35315241,
- WL_DRM_FORMAT_ABGR1555 = 0x35314241,
- WL_DRM_FORMAT_RGBA5551 = 0x35314152,
- WL_DRM_FORMAT_BGRA5551 = 0x35314142,
- WL_DRM_FORMAT_RGB565 = 0x36314752,
- WL_DRM_FORMAT_BGR565 = 0x36314742,
- WL_DRM_FORMAT_RGB888 = 0x34324752,
- WL_DRM_FORMAT_BGR888 = 0x34324742,
- WL_DRM_FORMAT_XRGB8888 = 0x34325258,
- WL_DRM_FORMAT_XBGR8888 = 0x34324258,
- WL_DRM_FORMAT_RGBX8888 = 0x34325852,
- WL_DRM_FORMAT_BGRX8888 = 0x34325842,
- WL_DRM_FORMAT_ARGB8888 = 0x34325241,
- WL_DRM_FORMAT_ABGR8888 = 0x34324241,
- WL_DRM_FORMAT_RGBA8888 = 0x34324152,
- WL_DRM_FORMAT_BGRA8888 = 0x34324142,
- WL_DRM_FORMAT_XRGB2101010 = 0x30335258,
- WL_DRM_FORMAT_XBGR2101010 = 0x30334258,
- WL_DRM_FORMAT_RGBX1010102 = 0x30335852,
- WL_DRM_FORMAT_BGRX1010102 = 0x30335842,
- WL_DRM_FORMAT_ARGB2101010 = 0x30335241,
- WL_DRM_FORMAT_ABGR2101010 = 0x30334241,
- WL_DRM_FORMAT_RGBA1010102 = 0x30334152,
- WL_DRM_FORMAT_BGRA1010102 = 0x30334142,
- WL_DRM_FORMAT_YUYV = 0x56595559,
- WL_DRM_FORMAT_YVYU = 0x55595659,
- WL_DRM_FORMAT_UYVY = 0x59565955,
- WL_DRM_FORMAT_VYUY = 0x59555956,
- WL_DRM_FORMAT_AYUV = 0x56555941,
- WL_DRM_FORMAT_NV12 = 0x3231564e,
- WL_DRM_FORMAT_NV21 = 0x3132564e,
- WL_DRM_FORMAT_NV16 = 0x3631564e,
- WL_DRM_FORMAT_NV61 = 0x3136564e,
- WL_DRM_FORMAT_YUV410 = 0x39565559,
- WL_DRM_FORMAT_YVU410 = 0x39555659,
- WL_DRM_FORMAT_YUV411 = 0x31315559,
- WL_DRM_FORMAT_YVU411 = 0x31315659,
- WL_DRM_FORMAT_YUV420 = 0x32315559,
- WL_DRM_FORMAT_YVU420 = 0x32315659,
- WL_DRM_FORMAT_YUV422 = 0x36315559,
- WL_DRM_FORMAT_YVU422 = 0x36315659,
- WL_DRM_FORMAT_YUV444 = 0x34325559,
- WL_DRM_FORMAT_YVU444 = 0x34325659,
-};
-#endif /* WL_DRM_FORMAT_ENUM */
-
+struct wl_display;
struct wl_drm;
+struct wl_resource;
struct wl_drm_buffer {
struct wl_resource *resource;
@@ -96,16 +34,10 @@ wayland_drm_buffer_get(struct wl_drm *drm, struct wl_resource *resource);
struct wl_drm *
wayland_drm_init(struct wl_display *display, char *device_name,
- struct wayland_drm_callbacks *callbacks, void *user_data,
+ const struct wayland_drm_callbacks *callbacks, void *user_data,
uint32_t flags);
void
wayland_drm_uninit(struct wl_drm *drm);
-uint32_t
-wayland_drm_buffer_get_format(struct wl_drm_buffer *buffer);
-
-void *
-wayland_drm_buffer_get_buffer(struct wl_drm_buffer *buffer);
-
#endif
diff --git a/lib/mesa/src/egl/wayland/wayland-egl/wayland-egl-backend.h b/lib/mesa/src/egl/wayland/wayland-egl/wayland-egl-backend.h
new file mode 100644
index 000000000..82f025cb5
--- /dev/null
+++ b/lib/mesa/src/egl/wayland/wayland-egl/wayland-egl-backend.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright © 2011 Benjamin Franzke
+ *
+ * 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.
+ *
+ * Authors:
+ * Benjamin Franzke <benjaminfranzke@googlemail.com>
+ */
+
+#ifndef _WAYLAND_EGL_PRIV_H
+#define _WAYLAND_EGL_PRIV_H
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define WL_EGL_WINDOW_VERSION 3
+
+struct wl_surface;
+
+struct wl_egl_window {
+ const intptr_t version;
+
+ int width;
+ int height;
+ int dx;
+ int dy;
+
+ int attached_width;
+ int attached_height;
+
+ void *private;
+ void (*resize_callback)(struct wl_egl_window *, void *);
+ void (*destroy_window_callback)(void *);
+
+ struct wl_surface *surface;
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/mesa/src/glx/apple/apple_glapi.c b/lib/mesa/src/glx/apple/apple_glapi.c
index 4d19f7f6a..f2248ab01 100644
--- a/lib/mesa/src/glx/apple/apple_glapi.c
+++ b/lib/mesa/src/glx/apple/apple_glapi.c
@@ -41,7 +41,6 @@
#include "main/glheader.h"
#include "glapi.h"
#include "glapitable.h"
-#include "main/dispatch.h"
#include "apple_glx.h"
#include "apple_xgl_api.h"
@@ -61,12 +60,11 @@ static void _apple_glapi_create_table(void) {
assert(__applegl_api);
memcpy(__applegl_api, __ogl_framework_api, sizeof(struct _glapi_table));
- SET_ReadPixels(__applegl_api, __applegl_glReadPixels);
- SET_CopyPixels(__applegl_api, __applegl_glCopyPixels);
- SET_CopyColorTable(__applegl_api, __applegl_glCopyColorTable);
- SET_DrawBuffer(__applegl_api, __applegl_glDrawBuffer);
- SET_DrawBuffers(__applegl_api, __applegl_glDrawBuffers);
- SET_Viewport(__applegl_api, __applegl_glViewport);
+ _glapi_table_patch(__applegl_api, "ReadPixels", __applegl_glReadPixels);
+ _glapi_table_patch(__applegl_api, "CopyPixels", __applegl_glCopyPixels);
+ _glapi_table_patch(__applegl_api, "CopyColorTable", __applegl_glCopyColorTable);
+ _glapi_table_patch(__applegl_api, "DrawBuffers", __applegl_glDrawBuffer);
+ _glapi_table_patch(__applegl_api, "Viewport", __applegl_glViewport);
}
void apple_glapi_set_dispatch(void) {
diff --git a/lib/mesa/src/glx/apple/apple_glx_context.c b/lib/mesa/src/glx/apple/apple_glx_context.c
index 5650b4f32..ff66ed499 100644
--- a/lib/mesa/src/glx/apple/apple_glx_context.c
+++ b/lib/mesa/src/glx/apple/apple_glx_context.c
@@ -55,6 +55,8 @@
#include "apple_cgl.h"
#include "apple_glx_drawable.h"
+#include "util/debug.h"
+
static pthread_mutex_t context_lock = PTHREAD_MUTEX_INITIALIZER;
/*
@@ -181,7 +183,7 @@ apple_glx_create_context(void **ptr, Display * dpy, int screen,
*x11errorptr = false;
}
- if (getenv("LIBGL_DIAGNOSTIC"))
+ if (env_var_as_boolean("LIBGL_DIAGNOSTIC", false))
fprintf(stderr, "error: %s\n", apple_cgl.error_string(error));
return true;
diff --git a/lib/mesa/src/glx/apple/apple_glx_log.c b/lib/mesa/src/glx/apple/apple_glx_log.c
index 5b9a865b6..a3f446c26 100644
--- a/lib/mesa/src/glx/apple/apple_glx_log.c
+++ b/lib/mesa/src/glx/apple/apple_glx_log.c
@@ -36,12 +36,13 @@
#include <inttypes.h>
#include <pthread.h>
#include "apple_glx_log.h"
+#include "util/debug.h"
static bool diagnostic = false;
static aslclient aslc;
void apple_glx_log_init(void) {
- if (getenv("LIBGL_DIAGNOSTIC")) {
+ if (env_var_as_boolean("LIBGL_DIAGNOSTIC", false)) {
diagnostic = true;
}
diff --git a/lib/mesa/src/glx/apple/apple_glx_pbuffer.c b/lib/mesa/src/glx/apple/apple_glx_pbuffer.c
index 142f4cce9..8c94d2010 100644
--- a/lib/mesa/src/glx/apple/apple_glx_pbuffer.c
+++ b/lib/mesa/src/glx/apple/apple_glx_pbuffer.c
@@ -40,12 +40,14 @@
#include "apple_glx_context.h"
#include "apple_glx_drawable.h"
+#include <stdbool.h>
#include <stdlib.h>
#include <pthread.h>
#include <assert.h>
#include "apple_glx.h"
#include "glxconfig.h"
#include "apple_cgl.h"
+#include "util/debug.h"
/* mesa defines in glew.h, Apple in glext.h.
* Due to namespace nightmares, just do it here.
@@ -208,7 +210,7 @@ get_max_size(int *widthresult, int *heightresult)
err = apple_cgl.choose_pixel_format(attr, &pfobj, &vsref);
if (kCGLNoError != err) {
- if (getenv("LIBGL_DIAGNOSTIC")) {
+ if (env_var_as_boolean("LIBGL_DIAGNOSTIC", false)) {
printf("choose_pixel_format error in %s: %s\n", __func__,
apple_cgl.error_string(err));
}
@@ -220,7 +222,7 @@ get_max_size(int *widthresult, int *heightresult)
err = apple_cgl.create_context(pfobj, NULL, &newcontext);
if (kCGLNoError != err) {
- if (getenv("LIBGL_DIAGNOSTIC")) {
+ if (env_var_as_boolean("LIBGL_DIAGNOSTIC", false)) {
printf("create_context error in %s: %s\n", __func__,
apple_cgl.error_string(err));
}
diff --git a/lib/mesa/src/glx/apple/apple_visual.c b/lib/mesa/src/glx/apple/apple_visual.c
index d665cd7e0..4a90d77c3 100644
--- a/lib/mesa/src/glx/apple/apple_visual.c
+++ b/lib/mesa/src/glx/apple/apple_visual.c
@@ -32,6 +32,7 @@
#include <stdlib.h>
#include <assert.h>
#include <GL/gl.h>
+#include <util/debug.h>
/* <rdar://problem/6953344> */
#define glTexImage1D glTexImage1D_OSX
@@ -82,7 +83,7 @@ apple_visual_create_pfobj(CGLPixelFormatObj * pfobj, const struct glx_config * m
int numattr = 0;
GLint vsref = 0;
CGLError error = 0;
- bool use_core_profile = getenv("LIBGL_PROFILE_CORE");
+ bool use_core_profile = env_var_as_boolean("LIBGL_PROFILE_CORE", false);
if (offscreen) {
apple_glx_diagnostic
@@ -90,13 +91,13 @@ apple_visual_create_pfobj(CGLPixelFormatObj * pfobj, const struct glx_config * m
attr[numattr++] = kCGLPFAOffScreen;
}
- else if (getenv("LIBGL_ALWAYS_SOFTWARE") != NULL) {
+ else if (env_var_as_boolean("LIBGL_ALWAYS_SOFTWARE", false)) {
apple_glx_diagnostic
("Software rendering requested. Using kCGLRendererGenericFloatID.\n");
attr[numattr++] = kCGLPFARendererID;
attr[numattr++] = kCGLRendererGenericFloatID;
}
- else if (getenv("LIBGL_ALLOW_SOFTWARE") != NULL) {
+ else if (env_var_as_boolean("LIBGL_ALLOW_SOFTWARE", false)) {
apple_glx_diagnostic
("Software rendering is not being excluded. Not using kCGLPFAAccelerated.\n");
}
@@ -190,7 +191,7 @@ apple_visual_create_pfobj(CGLPixelFormatObj * pfobj, const struct glx_config * m
if (!*pfobj) {
snprintf(__crashreporter_info_buff__, sizeof(__crashreporter_info_buff__),
- "No matching pixelformats found, perhaps try using LIBGL_ALLOW_SOFTWARE\n");
+ "No matching pixelformats found, perhaps try setting LIBGL_ALLOW_SOFTWARE=true\n");
fprintf(stderr, "%s", __crashreporter_info_buff__);
abort();
}
diff --git a/lib/mesa/src/glx/driwindows_glx.c b/lib/mesa/src/glx/driwindows_glx.c
index 02d95e7bf..85525431b 100644
--- a/lib/mesa/src/glx/driwindows_glx.c
+++ b/lib/mesa/src/glx/driwindows_glx.c
@@ -24,6 +24,7 @@
#include "glxclient.h"
#include "glx_error.h"
#include "dri_common.h"
+#include "util/macros.h"
#include "windows/xwindowsdri.h"
#include "windows/windowsgl.h"
@@ -427,7 +428,7 @@ driwindowsBindExtensions(struct driwindows_screen *psc)
windows_extensions(&gl_extensions, &wgl_extensions);
- for (i = 0; i < sizeof(extensionMap)/sizeof(extensionMap[0]); i++) {
+ for (i = 0; i < ARRAY_SIZE(extensionMap); i++) {
if (strstr(wgl_extensions, extensionMap[i].wglext)) {
__glXEnableDirectExtension(&psc->base, extensionMap[i].glxext);
InfoMessageF("enabled %s\n", extensionMap[i].glxext);
diff --git a/lib/mesa/src/glx/glxext.c b/lib/mesa/src/glx/glxext.c
index 9ef7ff5f6..5f23d3717 100644
--- a/lib/mesa/src/glx/glxext.c
+++ b/lib/mesa/src/glx/glxext.c
@@ -38,6 +38,8 @@
*/
#include <assert.h>
+#include <stdbool.h>
+
#include "glxclient.h"
#include <X11/extensions/Xext.h>
#include <X11/extensions/extutil.h>
@@ -47,6 +49,8 @@
#endif
#include "glxextensions.h"
+#include "util/debug.h"
+
#include <X11/Xlib-xcb.h>
#include <xcb/xcb.h>
#include <xcb/glx.h>
@@ -524,7 +528,17 @@ __glXInitializeVisualConfigFromTags(struct glx_config * config, int count,
config->visualSelectGroup = *bp++;
break;
case GLX_SWAP_METHOD_OML:
- config->swapMethod = *bp++;
+ if (*bp == GLX_SWAP_UNDEFINED_OML ||
+ *bp == GLX_SWAP_COPY_OML ||
+ *bp == GLX_SWAP_EXCHANGE_OML) {
+ config->swapMethod = *bp++;
+ } else {
+ /* X servers with old HW drivers may return any value here, so
+ * assume GLX_SWAP_METHOD_UNDEFINED.
+ */
+ config->swapMethod = GLX_SWAP_UNDEFINED_OML;
+ bp++;
+ }
break;
#endif
case GLX_SAMPLE_BUFFERS_SGIS:
@@ -567,7 +581,7 @@ __glXInitializeVisualConfigFromTags(struct glx_config * config, int count,
i = count;
break;
default:
- if(getenv("LIBGL_DIAGNOSTIC")) {
+ if(env_var_as_boolean("LIBGL_DIAGNOSTIC", false)) {
long int tagvalue = *bp++;
fprintf(stderr, "WARNING: unknown GLX tag from server: "
"tag 0x%lx value 0x%lx\n", tag, tagvalue);
@@ -893,8 +907,8 @@ __glXInitialize(Display * dpy)
dpyPriv->glXDrawHash = __glxHashCreate();
#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
- glx_direct = (getenv("LIBGL_ALWAYS_INDIRECT") == NULL);
- glx_accel = (getenv("LIBGL_ALWAYS_SOFTWARE") == NULL);
+ glx_direct = !env_var_as_boolean("LIBGL_ALWAYS_INDIRECT", false);
+ glx_accel = !env_var_as_boolean("LIBGL_ALWAYS_SOFTWARE", false);
dpyPriv->drawHash = __glxHashCreate();
@@ -906,7 +920,7 @@ __glXInitialize(Display * dpy)
#if defined(GLX_USE_DRM)
if (glx_direct && glx_accel) {
#if defined(HAVE_DRI3)
- if (!getenv("LIBGL_DRI3_DISABLE"))
+ if (!env_var_as_boolean("LIBGL_DRI3_DISABLE", false))
dpyPriv->dri3Display = dri3_create_display(dpy);
#endif /* HAVE_DRI3 */
dpyPriv->dri2Display = dri2CreateDisplay(dpy);
diff --git a/lib/mesa/src/glx/glxextensions.c b/lib/mesa/src/glx/glxextensions.c
index 22b078ce4..6882e442f 100644
--- a/lib/mesa/src/glx/glxextensions.c
+++ b/lib/mesa/src/glx/glxextensions.c
@@ -139,14 +139,17 @@ static const struct extension_info known_glx_extensions[] = {
{ GLX(ARB_framebuffer_sRGB), VER(0,0), Y, Y, N, N },
{ GLX(ARB_get_proc_address), VER(1,4), Y, N, Y, N },
{ GLX(ARB_multisample), VER(1,4), Y, Y, N, N },
- { GLX(ATI_pixel_format_float), VER(0,0), N, N, N, N },
+ { GLX(EXT_buffer_age), VER(0,0), Y, N, N, Y },
+ { GLX(EXT_create_context_es2_profile), VER(0,0), Y, N, N, N },
+ { GLX(EXT_create_context_es_profile), VER(0,0), Y, N, N, N },
+ { GLX(EXT_fbconfig_packed_float), VER(0,0), Y, Y, N, N },
+ { GLX(EXT_framebuffer_sRGB), VER(0,0), Y, Y, N, N },
{ GLX(EXT_import_context), VER(0,0), Y, Y, N, N },
+ { GLX(EXT_texture_from_pixmap), VER(0,0), Y, N, N, N },
{ GLX(EXT_visual_info), VER(0,0), Y, Y, N, N },
{ GLX(EXT_visual_rating), VER(0,0), Y, Y, N, N },
- { GLX(EXT_fbconfig_packed_float), VER(0,0), Y, Y, N, N },
- { GLX(EXT_framebuffer_sRGB), VER(0,0), Y, Y, N, N },
- { GLX(EXT_create_context_es2_profile), VER(0,0), Y, N, N, N },
- { GLX(EXT_create_context_es_profile), VER(0,0), Y, N, N, N },
+ { GLX(ATI_pixel_format_float), VER(0,0), N, N, N, N },
+ { GLX(INTEL_swap_event), VER(0,0), Y, N, N, N },
{ GLX(MESA_copy_sub_buffer), VER(0,0), Y, N, N, N },
{ GLX(MESA_multithread_makecurrent),VER(0,0), Y, N, Y, N },
{ GLX(MESA_query_renderer), VER(0,0), Y, N, N, Y },
@@ -154,18 +157,15 @@ static const struct extension_info known_glx_extensions[] = {
{ GLX(NV_float_buffer), VER(0,0), N, N, N, N },
{ GLX(OML_swap_method), VER(0,0), Y, Y, N, N },
{ GLX(OML_sync_control), VER(0,0), Y, N, N, Y },
- { GLX(SGI_make_current_read), VER(1,3), Y, N, N, N },
- { GLX(SGI_swap_control), VER(0,0), Y, N, N, N },
- { GLX(SGI_video_sync), VER(0,0), Y, N, N, Y },
{ GLX(SGIS_multisample), VER(0,0), Y, Y, N, N },
{ GLX(SGIX_fbconfig), VER(1,3), Y, Y, N, N },
{ GLX(SGIX_pbuffer), VER(1,3), Y, Y, N, N },
{ GLX(SGIX_swap_barrier), VER(0,0), N, N, N, N },
{ GLX(SGIX_swap_group), VER(0,0), N, N, N, N },
{ GLX(SGIX_visual_select_group), VER(0,0), Y, Y, N, N },
- { GLX(EXT_texture_from_pixmap), VER(0,0), Y, N, N, N },
- { GLX(INTEL_swap_event), VER(0,0), Y, N, N, N },
- { GLX(EXT_buffer_age), VER(0,0), Y, N, N, Y },
+ { GLX(SGI_make_current_read), VER(1,3), Y, N, N, N },
+ { GLX(SGI_swap_control), VER(0,0), Y, N, N, N },
+ { GLX(SGI_video_sync), VER(0,0), Y, N, N, Y },
{ NULL }
};
@@ -190,6 +190,7 @@ static const struct extension_info known_gl_extensions[] = {
{ GL(ARB_texture_env_combine), VER(1,3), Y, N, N, N },
{ GL(ARB_texture_env_crossbar), VER(1,4), Y, N, N, N },
{ GL(ARB_texture_env_dot3), VER(1,3), Y, N, N, N },
+ { GL(ARB_texture_filter_anisotropic), VER(0,0), Y, N, N, N },
{ GL(ARB_texture_mirrored_repeat), VER(1,4), Y, N, N, N },
{ GL(ARB_texture_non_power_of_two), VER(1,5), Y, N, N, N },
{ GL(ARB_texture_rectangle), VER(0,0), Y, N, N, N },
diff --git a/lib/mesa/src/glx/indirect_glx.c b/lib/mesa/src/glx/indirect_glx.c
index 51dd2cacb..4302a8ff2 100644
--- a/lib/mesa/src/glx/indirect_glx.c
+++ b/lib/mesa/src/glx/indirect_glx.c
@@ -30,9 +30,13 @@
* Kristian Høgsberg (krh@bitplanet.net)
*/
+#include <stdbool.h>
+
#include "glapi.h"
#include "glxclient.h"
+#include "util/debug.h"
+
#ifndef GLX_USE_APPLEGL
extern struct _glapi_table *__glXNewIndirectAPI(void);
@@ -371,7 +375,7 @@ indirect_create_context(struct glx_screen *psc,
return NULL;
}
gc->client_state_private = state;
- state->NoDrawArraysProtocol = (getenv("LIBGL_NO_DRAWARRAYS") != NULL);
+ state->NoDrawArraysProtocol = env_var_as_boolean("LIBGL_NO_DRAWARRAYS", false);
/*
** Create a temporary buffer to hold GLX rendering commands. The size
diff --git a/lib/mesa/src/glx/tests/enum_sizes.cpp b/lib/mesa/src/glx/tests/enum_sizes.cpp
index 20fc75879..6119dcbc4 100644
--- a/lib/mesa/src/glx/tests/enum_sizes.cpp
+++ b/lib/mesa/src/glx/tests/enum_sizes.cpp
@@ -36,7 +36,7 @@
#include <gtest/gtest.h>
#include <GL/gl.h>
extern "C" {
-#include "../indirect_size.h"
+#include "indirect_size.h"
}
TEST(ValidEnumSizes, CallLists)
diff --git a/lib/mesa/src/intel/compiler/brw_nir_lower_cs_intrinsics.c b/lib/mesa/src/intel/compiler/brw_nir_lower_cs_intrinsics.c
new file mode 100644
index 000000000..f9322654e
--- /dev/null
+++ b/lib/mesa/src/intel/compiler/brw_nir_lower_cs_intrinsics.c
@@ -0,0 +1,184 @@
+/*
+ * Copyright (c) 2016 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 (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 "brw_nir.h"
+#include "compiler/nir/nir_builder.h"
+
+struct lower_intrinsics_state {
+ nir_shader *nir;
+ struct brw_cs_prog_data *prog_data;
+ nir_function_impl *impl;
+ bool progress;
+ nir_builder builder;
+ int thread_local_id_index;
+};
+
+static nir_ssa_def *
+read_thread_local_id(struct lower_intrinsics_state *state)
+{
+ struct brw_cs_prog_data *prog_data = state->prog_data;
+ nir_builder *b = &state->builder;
+ nir_shader *nir = state->nir;
+ const unsigned *sizes = nir->info.cs.local_size;
+ const unsigned group_size = sizes[0] * sizes[1] * sizes[2];
+
+ /* Some programs have local_size dimensions so small that the thread local
+ * ID will always be 0.
+ */
+ if (group_size <= 8)
+ return nir_imm_int(b, 0);
+
+ if (state->thread_local_id_index == -1) {
+ state->thread_local_id_index = prog_data->base.nr_params;
+ uint32_t *param = brw_stage_prog_data_add_params(&prog_data->base, 1);
+ *param = BRW_PARAM_BUILTIN_THREAD_LOCAL_ID;
+ nir->num_uniforms += 4;
+ }
+ unsigned id_index = state->thread_local_id_index;
+
+ nir_intrinsic_instr *load =
+ nir_intrinsic_instr_create(nir, nir_intrinsic_load_uniform);
+ load->num_components = 1;
+ load->src[0] = nir_src_for_ssa(nir_imm_int(b, 0));
+ nir_ssa_dest_init(&load->instr, &load->dest, 1, 32, NULL);
+ nir_intrinsic_set_base(load, id_index * sizeof(uint32_t));
+ nir_intrinsic_set_range(load, sizeof(uint32_t));
+ nir_builder_instr_insert(b, &load->instr);
+ return &load->dest.ssa;
+}
+
+static bool
+lower_cs_intrinsics_convert_block(struct lower_intrinsics_state *state,
+ nir_block *block)
+{
+ bool progress = false;
+ nir_builder *b = &state->builder;
+ nir_shader *nir = state->nir;
+
+ nir_foreach_instr_safe(instr, block) {
+ if (instr->type != nir_instr_type_intrinsic)
+ continue;
+
+ nir_intrinsic_instr *intrinsic = nir_instr_as_intrinsic(instr);
+
+ b->cursor = nir_after_instr(&intrinsic->instr);
+
+ nir_ssa_def *sysval;
+ switch (intrinsic->intrinsic) {
+ case nir_intrinsic_load_local_invocation_index: {
+ /* We construct the local invocation index from:
+ *
+ * gl_LocalInvocationIndex =
+ * cs_thread_local_id + subgroup_invocation;
+ */
+ nir_ssa_def *thread_local_id = read_thread_local_id(state);
+ nir_ssa_def *channel = nir_load_subgroup_invocation(b);
+ sysval = nir_iadd(b, channel, thread_local_id);
+ break;
+ }
+
+ case nir_intrinsic_load_local_invocation_id: {
+ /* We lower gl_LocalInvocationID from gl_LocalInvocationIndex based
+ * on this formula:
+ *
+ * gl_LocalInvocationID.x =
+ * gl_LocalInvocationIndex % gl_WorkGroupSize.x;
+ * gl_LocalInvocationID.y =
+ * (gl_LocalInvocationIndex / gl_WorkGroupSize.x) %
+ * gl_WorkGroupSize.y;
+ * gl_LocalInvocationID.z =
+ * (gl_LocalInvocationIndex /
+ * (gl_WorkGroupSize.x * gl_WorkGroupSize.y)) %
+ * gl_WorkGroupSize.z;
+ */
+ unsigned *size = nir->info.cs.local_size;
+
+ nir_ssa_def *local_index = nir_load_local_invocation_index(b);
+
+ nir_const_value uvec3;
+ uvec3.u32[0] = 1;
+ uvec3.u32[1] = size[0];
+ uvec3.u32[2] = size[0] * size[1];
+ nir_ssa_def *div_val = nir_build_imm(b, 3, 32, uvec3);
+ uvec3.u32[0] = size[0];
+ uvec3.u32[1] = size[1];
+ uvec3.u32[2] = size[2];
+ nir_ssa_def *mod_val = nir_build_imm(b, 3, 32, uvec3);
+
+ sysval = nir_umod(b, nir_udiv(b, local_index, div_val), mod_val);
+ break;
+ }
+
+ default:
+ continue;
+ }
+
+ nir_ssa_def_rewrite_uses(&intrinsic->dest.ssa, nir_src_for_ssa(sysval));
+ nir_instr_remove(&intrinsic->instr);
+
+ state->progress = true;
+ }
+
+ return progress;
+}
+
+static void
+lower_cs_intrinsics_convert_impl(struct lower_intrinsics_state *state)
+{
+ nir_builder_init(&state->builder, state->impl);
+
+ nir_foreach_block(block, state->impl) {
+ lower_cs_intrinsics_convert_block(state, block);
+ }
+
+ nir_metadata_preserve(state->impl,
+ nir_metadata_block_index | nir_metadata_dominance);
+}
+
+bool
+brw_nir_lower_cs_intrinsics(nir_shader *nir,
+ struct brw_cs_prog_data *prog_data)
+{
+ assert(nir->info.stage == MESA_SHADER_COMPUTE);
+
+ bool progress = false;
+ struct lower_intrinsics_state state;
+ memset(&state, 0, sizeof(state));
+ state.nir = nir;
+ state.prog_data = prog_data;
+
+ state.thread_local_id_index = -1;
+
+ do {
+ state.progress = false;
+ nir_foreach_function(function, nir) {
+ if (function->impl) {
+ state.impl = function->impl;
+ lower_cs_intrinsics_convert_impl(&state);
+ }
+ }
+ progress |= state.progress;
+ } while (state.progress);
+
+ return progress;
+}
diff --git a/lib/mesa/src/intel/compiler/brw_reg_type.c b/lib/mesa/src/intel/compiler/brw_reg_type.c
new file mode 100644
index 000000000..b7fff0867
--- /dev/null
+++ b/lib/mesa/src/intel/compiler/brw_reg_type.c
@@ -0,0 +1,299 @@
+/*
+ * Copyright © 2017 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 (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 "brw_reg.h"
+#include "brw_eu_defines.h"
+#include "common/gen_device_info.h"
+
+#define INVALID (-1)
+
+enum hw_reg_type {
+ BRW_HW_REG_TYPE_UD = 0,
+ BRW_HW_REG_TYPE_D = 1,
+ BRW_HW_REG_TYPE_UW = 2,
+ BRW_HW_REG_TYPE_W = 3,
+ BRW_HW_REG_TYPE_F = 7,
+ GEN8_HW_REG_TYPE_UQ = 8,
+ GEN8_HW_REG_TYPE_Q = 9,
+
+ BRW_HW_REG_TYPE_UB = 4,
+ BRW_HW_REG_TYPE_B = 5,
+ GEN7_HW_REG_TYPE_DF = 6,
+ GEN8_HW_REG_TYPE_HF = 10,
+};
+
+enum hw_imm_type {
+ BRW_HW_IMM_TYPE_UD = 0,
+ BRW_HW_IMM_TYPE_D = 1,
+ BRW_HW_IMM_TYPE_UW = 2,
+ BRW_HW_IMM_TYPE_W = 3,
+ BRW_HW_IMM_TYPE_F = 7,
+ GEN8_HW_IMM_TYPE_UQ = 8,
+ GEN8_HW_IMM_TYPE_Q = 9,
+
+ BRW_HW_IMM_TYPE_UV = 4,
+ BRW_HW_IMM_TYPE_VF = 5,
+ BRW_HW_IMM_TYPE_V = 6,
+ GEN8_HW_IMM_TYPE_DF = 10,
+ GEN8_HW_IMM_TYPE_HF = 11,
+};
+
+static const struct {
+ enum hw_reg_type reg_type;
+ enum hw_imm_type imm_type;
+} gen4_hw_type[] = {
+ [BRW_REGISTER_TYPE_DF] = { GEN7_HW_REG_TYPE_DF, GEN8_HW_IMM_TYPE_DF },
+ [BRW_REGISTER_TYPE_F] = { BRW_HW_REG_TYPE_F, BRW_HW_IMM_TYPE_F },
+ [BRW_REGISTER_TYPE_HF] = { GEN8_HW_REG_TYPE_HF, GEN8_HW_IMM_TYPE_HF },
+ [BRW_REGISTER_TYPE_VF] = { INVALID, BRW_HW_IMM_TYPE_VF },
+
+ [BRW_REGISTER_TYPE_Q] = { GEN8_HW_REG_TYPE_Q, GEN8_HW_IMM_TYPE_Q },
+ [BRW_REGISTER_TYPE_UQ] = { GEN8_HW_REG_TYPE_UQ, GEN8_HW_IMM_TYPE_UQ },
+ [BRW_REGISTER_TYPE_D] = { BRW_HW_REG_TYPE_D, BRW_HW_IMM_TYPE_D },
+ [BRW_REGISTER_TYPE_UD] = { BRW_HW_REG_TYPE_UD, BRW_HW_IMM_TYPE_UD },
+ [BRW_REGISTER_TYPE_W] = { BRW_HW_REG_TYPE_W, BRW_HW_IMM_TYPE_W },
+ [BRW_REGISTER_TYPE_UW] = { BRW_HW_REG_TYPE_UW, BRW_HW_IMM_TYPE_UW },
+ [BRW_REGISTER_TYPE_B] = { BRW_HW_REG_TYPE_B, INVALID },
+ [BRW_REGISTER_TYPE_UB] = { BRW_HW_REG_TYPE_UB, INVALID },
+ [BRW_REGISTER_TYPE_V] = { INVALID, BRW_HW_IMM_TYPE_V },
+ [BRW_REGISTER_TYPE_UV] = { INVALID, BRW_HW_IMM_TYPE_UV },
+};
+
+/* SNB adds 3-src instructions (MAD and LRP) that only operate on floats, so
+ * the types were implied. IVB adds BFE and BFI2 that operate on doublewords
+ * and unsigned doublewords, so a new field is also available in the da3src
+ * struct (part of struct brw_instruction.bits1 in brw_structs.h) to select
+ * dst and shared-src types.
+ *
+ * CNL adds support for 3-src instructions in align1 mode, and with it support
+ * for most register types.
+ */
+enum hw_3src_reg_type {
+ GEN7_3SRC_TYPE_F = 0,
+ GEN7_3SRC_TYPE_D = 1,
+ GEN7_3SRC_TYPE_UD = 2,
+ GEN7_3SRC_TYPE_DF = 3,
+
+ /** When ExecutionDatatype is 1: @{ */
+ GEN10_ALIGN1_3SRC_REG_TYPE_HF = 0b000,
+ GEN10_ALIGN1_3SRC_REG_TYPE_F = 0b001,
+ GEN10_ALIGN1_3SRC_REG_TYPE_DF = 0b010,
+ /** @} */
+
+ /** When ExecutionDatatype is 0: @{ */
+ GEN10_ALIGN1_3SRC_REG_TYPE_UD = 0b000,
+ GEN10_ALIGN1_3SRC_REG_TYPE_D = 0b001,
+ GEN10_ALIGN1_3SRC_REG_TYPE_UW = 0b010,
+ GEN10_ALIGN1_3SRC_REG_TYPE_W = 0b011,
+ GEN10_ALIGN1_3SRC_REG_TYPE_UB = 0b100,
+ GEN10_ALIGN1_3SRC_REG_TYPE_B = 0b101,
+ /** @} */
+};
+
+static const struct hw_3src_type {
+ enum hw_3src_reg_type reg_type;
+ enum gen10_align1_3src_exec_type exec_type;
+} gen7_hw_3src_type[] = {
+ [0 ... BRW_REGISTER_TYPE_LAST] = { INVALID },
+
+ [BRW_REGISTER_TYPE_F] = { GEN7_3SRC_TYPE_F },
+ [BRW_REGISTER_TYPE_D] = { GEN7_3SRC_TYPE_D },
+ [BRW_REGISTER_TYPE_UD] = { GEN7_3SRC_TYPE_UD },
+ [BRW_REGISTER_TYPE_DF] = { GEN7_3SRC_TYPE_DF },
+}, gen10_hw_3src_align1_type[] = {
+#define E(x) BRW_ALIGN1_3SRC_EXEC_TYPE_##x
+ [0 ... BRW_REGISTER_TYPE_LAST] = { INVALID },
+
+ [BRW_REGISTER_TYPE_DF] = { GEN10_ALIGN1_3SRC_REG_TYPE_DF, E(FLOAT) },
+ [BRW_REGISTER_TYPE_F] = { GEN10_ALIGN1_3SRC_REG_TYPE_F, E(FLOAT) },
+ [BRW_REGISTER_TYPE_HF] = { GEN10_ALIGN1_3SRC_REG_TYPE_HF, E(FLOAT) },
+
+ [BRW_REGISTER_TYPE_D] = { GEN10_ALIGN1_3SRC_REG_TYPE_D, E(INT) },
+ [BRW_REGISTER_TYPE_UD] = { GEN10_ALIGN1_3SRC_REG_TYPE_UD, E(INT) },
+ [BRW_REGISTER_TYPE_W] = { GEN10_ALIGN1_3SRC_REG_TYPE_W, E(INT) },
+ [BRW_REGISTER_TYPE_UW] = { GEN10_ALIGN1_3SRC_REG_TYPE_UW, E(INT) },
+ [BRW_REGISTER_TYPE_B] = { GEN10_ALIGN1_3SRC_REG_TYPE_B, E(INT) },
+ [BRW_REGISTER_TYPE_UB] = { GEN10_ALIGN1_3SRC_REG_TYPE_UB, E(INT) },
+#undef E
+};
+
+/**
+ * Convert a brw_reg_type enumeration value into the hardware representation.
+ *
+ * The hardware encoding may depend on whether the value is an immediate.
+ */
+unsigned
+brw_reg_type_to_hw_type(const struct gen_device_info *devinfo,
+ enum brw_reg_file file,
+ enum brw_reg_type type)
+{
+ assert(type < ARRAY_SIZE(gen4_hw_type));
+
+ if (file == BRW_IMMEDIATE_VALUE) {
+ assert(gen4_hw_type[type].imm_type != (enum hw_imm_type)INVALID);
+ return gen4_hw_type[type].imm_type;
+ } else {
+ assert(gen4_hw_type[type].reg_type != (enum hw_reg_type)INVALID);
+ return gen4_hw_type[type].reg_type;
+ }
+}
+
+/**
+ * Convert the hardware representation into a brw_reg_type enumeration value.
+ *
+ * The hardware encoding may depend on whether the value is an immediate.
+ */
+enum brw_reg_type
+brw_hw_type_to_reg_type(const struct gen_device_info *devinfo,
+ enum brw_reg_file file, unsigned hw_type)
+{
+ if (file == BRW_IMMEDIATE_VALUE) {
+ for (enum brw_reg_type i = 0; i <= BRW_REGISTER_TYPE_LAST; i++) {
+ if (gen4_hw_type[i].imm_type == (enum hw_imm_type)hw_type) {
+ return i;
+ }
+ }
+ } else {
+ for (enum brw_reg_type i = 0; i <= BRW_REGISTER_TYPE_LAST; i++) {
+ if (gen4_hw_type[i].reg_type == (enum hw_reg_type)hw_type) {
+ return i;
+ }
+ }
+ }
+ unreachable("not reached");
+}
+
+/**
+ * Convert a brw_reg_type enumeration value into the hardware representation
+ * for a 3-src align16 instruction
+ */
+unsigned
+brw_reg_type_to_a16_hw_3src_type(const struct gen_device_info *devinfo,
+ enum brw_reg_type type)
+{
+ assert(type < ARRAY_SIZE(gen7_hw_3src_type));
+ assert(gen7_hw_3src_type[type].reg_type != (enum hw_3src_reg_type)INVALID);
+ return gen7_hw_3src_type[type].reg_type;
+}
+
+/**
+ * Convert a brw_reg_type enumeration value into the hardware representation
+ * for a 3-src align1 instruction
+ */
+unsigned
+brw_reg_type_to_a1_hw_3src_type(const struct gen_device_info *devinfo,
+ enum brw_reg_type type)
+{
+ assert(type < ARRAY_SIZE(gen10_hw_3src_align1_type));
+ assert(gen10_hw_3src_align1_type[type].reg_type != (enum hw_3src_reg_type)INVALID);
+ return gen10_hw_3src_align1_type[type].reg_type;
+}
+
+/**
+ * Convert the hardware representation for a 3-src align16 instruction into a
+ * brw_reg_type enumeration value.
+ */
+enum brw_reg_type
+brw_a16_hw_3src_type_to_reg_type(const struct gen_device_info *devinfo,
+ unsigned hw_type)
+{
+ for (enum brw_reg_type i = 0; i <= BRW_REGISTER_TYPE_LAST; i++) {
+ if (gen7_hw_3src_type[i].reg_type == hw_type) {
+ return i;
+ }
+ }
+ unreachable("not reached");
+}
+
+/**
+ * Convert the hardware representation for a 3-src align1 instruction into a
+ * brw_reg_type enumeration value.
+ */
+enum brw_reg_type
+brw_a1_hw_3src_type_to_reg_type(const struct gen_device_info *devinfo,
+ unsigned hw_type, unsigned exec_type)
+{
+ for (enum brw_reg_type i = 0; i <= BRW_REGISTER_TYPE_LAST; i++) {
+ if (gen10_hw_3src_align1_type[i].reg_type == hw_type &&
+ gen10_hw_3src_align1_type[i].exec_type == exec_type) {
+ return i;
+ }
+ }
+ unreachable("not reached");
+}
+
+/**
+ * Return the element size given a register type.
+ */
+unsigned
+brw_reg_type_to_size(enum brw_reg_type type)
+{
+ static const unsigned type_size[] = {
+ [BRW_REGISTER_TYPE_DF] = 8,
+ [BRW_REGISTER_TYPE_F] = 4,
+ [BRW_REGISTER_TYPE_HF] = 2,
+ [BRW_REGISTER_TYPE_VF] = 4,
+
+ [BRW_REGISTER_TYPE_Q] = 8,
+ [BRW_REGISTER_TYPE_UQ] = 8,
+ [BRW_REGISTER_TYPE_D] = 4,
+ [BRW_REGISTER_TYPE_UD] = 4,
+ [BRW_REGISTER_TYPE_W] = 2,
+ [BRW_REGISTER_TYPE_UW] = 2,
+ [BRW_REGISTER_TYPE_B] = 1,
+ [BRW_REGISTER_TYPE_UB] = 1,
+ [BRW_REGISTER_TYPE_V] = 2,
+ [BRW_REGISTER_TYPE_UV] = 2,
+ };
+ return type_size[type];
+}
+
+/**
+ * Converts a BRW_REGISTER_TYPE_* enum to a short string (F, UD, and so on).
+ *
+ * This is different than reg_encoding from brw_disasm.c in that it operates
+ * on the abstract enum values, rather than the generation-specific encoding.
+ */
+const char *
+brw_reg_type_to_letters(enum brw_reg_type type)
+{
+ static const char letters[][3] = {
+ [BRW_REGISTER_TYPE_DF] = "DF",
+ [BRW_REGISTER_TYPE_F] = "F",
+ [BRW_REGISTER_TYPE_HF] = "HF",
+ [BRW_REGISTER_TYPE_VF] = "VF",
+
+ [BRW_REGISTER_TYPE_Q] = "Q",
+ [BRW_REGISTER_TYPE_UQ] = "UQ",
+ [BRW_REGISTER_TYPE_D] = "D",
+ [BRW_REGISTER_TYPE_UD] = "UD",
+ [BRW_REGISTER_TYPE_W] = "W",
+ [BRW_REGISTER_TYPE_UW] = "UW",
+ [BRW_REGISTER_TYPE_B] = "B",
+ [BRW_REGISTER_TYPE_UB] = "UB",
+ [BRW_REGISTER_TYPE_V] = "V",
+ [BRW_REGISTER_TYPE_UV] = "UV",
+ };
+ assert(type < ARRAY_SIZE(letters));
+ return letters[type];
+}
diff --git a/lib/mesa/src/intel/compiler/brw_reg_type.h b/lib/mesa/src/intel/compiler/brw_reg_type.h
new file mode 100644
index 000000000..3bc9a36e7
--- /dev/null
+++ b/lib/mesa/src/intel/compiler/brw_reg_type.h
@@ -0,0 +1,117 @@
+/*
+ * Copyright © 2017 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 (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.
+ */
+
+#ifndef BRW_REG_TYPE_H
+#define BRW_REG_TYPE_H
+
+#include <stdbool.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef HAVE_FUNC_ATTRIBUTE_PURE
+#define ATTRIBUTE_PURE __attribute__((__pure__))
+#else
+#define ATTRIBUTE_PURE
+#endif
+
+enum brw_reg_file;
+struct gen_device_info;
+
+/*
+ * The ordering has been chosen so that no enum value is the same as a
+ * compatible hardware encoding.
+ */
+enum PACKED brw_reg_type {
+ /** Floating-point types: @{ */
+ BRW_REGISTER_TYPE_DF,
+ BRW_REGISTER_TYPE_F,
+ BRW_REGISTER_TYPE_HF,
+ BRW_REGISTER_TYPE_VF,
+ /** @} */
+
+ /** Integer types: @{ */
+ BRW_REGISTER_TYPE_Q,
+ BRW_REGISTER_TYPE_UQ,
+ BRW_REGISTER_TYPE_D,
+ BRW_REGISTER_TYPE_UD,
+ BRW_REGISTER_TYPE_W,
+ BRW_REGISTER_TYPE_UW,
+ BRW_REGISTER_TYPE_B,
+ BRW_REGISTER_TYPE_UB,
+ BRW_REGISTER_TYPE_V,
+ BRW_REGISTER_TYPE_UV,
+ /** @} */
+
+ BRW_REGISTER_TYPE_LAST = BRW_REGISTER_TYPE_UV
+};
+
+static inline bool
+brw_reg_type_is_floating_point(enum brw_reg_type type)
+{
+ switch (type) {
+ case BRW_REGISTER_TYPE_DF:
+ case BRW_REGISTER_TYPE_F:
+ case BRW_REGISTER_TYPE_HF:
+ return true;
+ default:
+ return false;
+ }
+}
+
+unsigned
+brw_reg_type_to_hw_type(const struct gen_device_info *devinfo,
+ enum brw_reg_file file, enum brw_reg_type type);
+
+enum brw_reg_type ATTRIBUTE_PURE
+brw_hw_type_to_reg_type(const struct gen_device_info *devinfo,
+ enum brw_reg_file file, unsigned hw_type);
+
+unsigned
+brw_reg_type_to_a16_hw_3src_type(const struct gen_device_info *devinfo,
+ enum brw_reg_type type);
+
+unsigned
+brw_reg_type_to_a1_hw_3src_type(const struct gen_device_info *devinfo,
+ enum brw_reg_type type);
+
+enum brw_reg_type
+brw_a16_hw_3src_type_to_reg_type(const struct gen_device_info *devinfo,
+ unsigned hw_type);
+
+enum brw_reg_type
+brw_a1_hw_3src_type_to_reg_type(const struct gen_device_info *devinfo,
+ unsigned hw_type, unsigned exec_type);
+
+unsigned
+brw_reg_type_to_size(enum brw_reg_type type);
+
+const char *
+brw_reg_type_to_letters(enum brw_reg_type type);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/mesa/src/mesa/drivers/SConscript b/lib/mesa/src/mesa/drivers/SConscript
index 476425be2..f54991033 100644
--- a/lib/mesa/src/mesa/drivers/SConscript
+++ b/lib/mesa/src/mesa/drivers/SConscript
@@ -7,6 +7,5 @@ if env['x11']:
if env['dri']:
SConscript([
- 'dri/common/xmlpool/SConscript',
'dri/common/SConscript',
])
diff --git a/lib/mesa/src/mesa/drivers/dri/common/Makefile.sources b/lib/mesa/src/mesa/drivers/dri/common/Makefile.sources
index 9d3cdd38f..d592e99b8 100644
--- a/lib/mesa/src/mesa/drivers/dri/common/Makefile.sources
+++ b/lib/mesa/src/mesa/drivers/dri/common/Makefile.sources
@@ -4,10 +4,6 @@ DRI_COMMON_FILES := \
dri_util.c \
dri_util.h
-XMLCONFIG_FILES := \
- xmlconfig.c \
- xmlconfig.h
-
# Paths are relative to MESA_TOP.
mesa_dri_common_INCLUDES := \
include \
@@ -15,7 +11,8 @@ mesa_dri_common_INCLUDES := \
src/egl/main \
src/mapi \
src/mesa \
- src/mesa/drivers/dri/common
+ src/mesa/drivers/dri/common \
+ src/util
megadriver_stub_FILES := \
megadriver_stub.c
diff --git a/lib/mesa/src/mesa/drivers/dri/common/SConscript b/lib/mesa/src/mesa/drivers/dri/common/SConscript
index 52d201f89..defd6bfb4 100644
--- a/lib/mesa/src/mesa/drivers/dri/common/SConscript
+++ b/lib/mesa/src/mesa/drivers/dri/common/SConscript
@@ -7,7 +7,6 @@ drienv = env.Clone()
drienv.Replace(CPPPATH = [
'#src/mesa/drivers/dri/common',
- xmlpool_options.dir.dir, # Dir to generated xmlpool/options.h
'#include',
'#include/GL/internal',
'#src',
@@ -26,13 +25,10 @@ drienv.Replace(CPPPATH = [
'#src/mesa/swrast_setup',
'#src/egl/main',
'#src/egl/drivers/dri',
+ xmlpool_options.dir.dir,
])
-drienv.AppendUnique(LIBS = [
- 'expat',
-])
-
-sources = drienv.ParseSourceList('Makefile.sources', ['DRI_COMMON_FILES', 'XMLCONFIG_FILES' ])
+sources = drienv.ParseSourceList('Makefile.sources', ['DRI_COMMON_FILES'])
dri_common = drienv.ConvenienceLibrary(
target = 'dri_common',
diff --git a/lib/mesa/src/mesa/drivers/dri/common/utils.c b/lib/mesa/src/mesa/drivers/dri/common/utils.c
index c37d446a1..e944754a4 100644
--- a/lib/mesa/src/mesa/drivers/dri/common/utils.c
+++ b/lib/mesa/src/mesa/drivers/dri/common/utils.c
@@ -284,8 +284,9 @@ driCreateConfigs(mesa_format format,
modes->transparentIndex = GLX_DONT_CARE;
modes->rgbMode = GL_TRUE;
- if ( db_modes[i] == GLX_NONE ) {
+ if (db_modes[i] == __DRI_ATTRIB_SWAP_NONE) {
modes->doubleBufferMode = GL_FALSE;
+ modes->swapMethod = __DRI_ATTRIB_SWAP_UNDEFINED;
}
else {
modes->doubleBufferMode = GL_TRUE;
@@ -403,7 +404,6 @@ static const struct { unsigned int attrib, offset; } attribMap[] = {
* so the iterator includes them though.*/
__ATTRIB(__DRI_ATTRIB_RENDER_TYPE, level),
__ATTRIB(__DRI_ATTRIB_CONFIG_CAVEAT, level),
- __ATTRIB(__DRI_ATTRIB_SWAP_METHOD, level)
};
@@ -428,10 +428,6 @@ driGetConfigAttribIndex(const __DRIconfig *config,
else
*value = 0;
break;
- case __DRI_ATTRIB_SWAP_METHOD:
- /* XXX no return value??? */
- break;
-
default:
/* any other int-sized field */
*value = *(unsigned int *)
diff --git a/lib/mesa/src/mesa/main/barrier.h b/lib/mesa/src/mesa/main/barrier.h
index d54c02af6..53ecf863f 100644
--- a/lib/mesa/src/mesa/main/barrier.h
+++ b/lib/mesa/src/mesa/main/barrier.h
@@ -45,6 +45,9 @@ void GLAPIENTRY
_mesa_MemoryBarrier(GLbitfield barriers);
void GLAPIENTRY
+_mesa_MemoryBarrierByRegion_no_error(GLbitfield barriers);
+
+void GLAPIENTRY
_mesa_MemoryBarrierByRegion(GLbitfield barriers);
void GLAPIENTRY
diff --git a/lib/mesa/src/mesa/main/condrender.h b/lib/mesa/src/mesa/main/condrender.h
index 90d7fb722..e7672512f 100644
--- a/lib/mesa/src/mesa/main/condrender.h
+++ b/lib/mesa/src/mesa/main/condrender.h
@@ -31,9 +31,15 @@
#include "context.h"
+void GLAPIENTRY
+_mesa_BeginConditionalRender_no_error(GLuint queryId, GLenum mode);
+
extern void GLAPIENTRY
_mesa_BeginConditionalRender(GLuint queryId, GLenum mode);
+void APIENTRY
+_mesa_EndConditionalRender_no_error(void);
+
extern void APIENTRY
_mesa_EndConditionalRender(void);
diff --git a/lib/mesa/src/mesa/main/execmem.h b/lib/mesa/src/mesa/main/execmem.h
new file mode 100644
index 000000000..bc51a8c84
--- /dev/null
+++ b/lib/mesa/src/mesa/main/execmem.h
@@ -0,0 +1,37 @@
+/*
+ * Mesa 3-D graphics library
+ *
+ * Copyright (C) 1999-2005 Brian Paul All Rights Reserved.
+ *
+ * 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.
+ */
+
+
+#ifndef EXECMEM_H
+#define EXECMEM_H
+
+
+extern void *
+_mesa_exec_malloc(GLuint size);
+
+extern void
+_mesa_exec_free(void *addr);
+
+
+#endif /* EXECMEM_H */
diff --git a/lib/mesa/src/mesa/main/extensions.c b/lib/mesa/src/mesa/main/extensions.c
index 62a731675..f185aa5aa 100644
--- a/lib/mesa/src/mesa/main/extensions.c
+++ b/lib/mesa/src/mesa/main/extensions.c
@@ -130,6 +130,7 @@ _mesa_enable_sw_extensions(struct gl_context *ctx)
ctx->Extensions.ARB_texture_env_combine = GL_TRUE;
ctx->Extensions.ARB_texture_env_crossbar = GL_TRUE;
ctx->Extensions.ARB_texture_env_dot3 = GL_TRUE;
+ ctx->Extensions.ARB_texture_filter_anisotropic = GL_TRUE;
#ifdef TEXTURE_FLOAT_ENABLED
ctx->Extensions.ARB_texture_float = GL_TRUE;
#endif
@@ -176,10 +177,8 @@ _mesa_enable_sw_extensions(struct gl_context *ctx)
ctx->Extensions.EXT_gpu_program_parameters = GL_TRUE;
ctx->Extensions.OES_standard_derivatives = GL_TRUE;
ctx->Extensions.TDFX_texture_compression_FXT1 = GL_TRUE;
- if (ctx->Mesa_DXTn) {
- ctx->Extensions.ANGLE_texture_compression_dxt = GL_TRUE;
- ctx->Extensions.EXT_texture_compression_s3tc = GL_TRUE;
- }
+ ctx->Extensions.ANGLE_texture_compression_dxt = GL_TRUE;
+ ctx->Extensions.EXT_texture_compression_s3tc = GL_TRUE;
}
/**
diff --git a/lib/mesa/src/mesa/main/externalobjects.c b/lib/mesa/src/mesa/main/externalobjects.c
new file mode 100644
index 000000000..e70280c96
--- /dev/null
+++ b/lib/mesa/src/mesa/main/externalobjects.c
@@ -0,0 +1,640 @@
+/*
+ * Copyright © 2016 Red Hat.
+ *
+ * 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 "macros.h"
+#include "mtypes.h"
+#include "externalobjects.h"
+#include "teximage.h"
+#include "texobj.h"
+#include "glformats.h"
+#include "texstorage.h"
+
+/**
+ * Allocate and initialize a new memory object. But don't put it into the
+ * memory object hash table.
+ *
+ * Called via ctx->Driver.NewMemoryObject, unless overridden by a device
+ * driver.
+ *
+ * \return pointer to new memory object.
+ */
+static struct gl_memory_object *
+_mesa_new_memory_object(struct gl_context *ctx, GLuint name)
+{
+ struct gl_memory_object *obj = MALLOC_STRUCT(gl_memory_object);
+ if (!obj)
+ return NULL;
+
+ _mesa_initialize_memory_object(ctx, obj, name);
+ return obj;
+}
+
+/**
+ * Delete a memory object. Called via ctx->Driver.DeleteMemory().
+ * Not removed from hash table here.
+ */
+void
+_mesa_delete_memory_object(struct gl_context *ctx,
+ struct gl_memory_object *memObj)
+{
+ free(memObj);
+}
+
+void
+_mesa_init_memory_object_functions(struct dd_function_table *driver)
+{
+ driver->NewMemoryObject = _mesa_new_memory_object;
+ driver->DeleteMemoryObject = _mesa_delete_memory_object;
+}
+
+/**
+ * Initialize a buffer object to default values.
+ */
+void
+_mesa_initialize_memory_object(struct gl_context *ctx,
+ struct gl_memory_object *obj,
+ GLuint name)
+{
+ memset(obj, 0, sizeof(struct gl_memory_object));
+ obj->Name = name;
+ obj->Dedicated = GL_FALSE;
+}
+
+void GLAPIENTRY
+_mesa_DeleteMemoryObjectsEXT(GLsizei n, const GLuint *memoryObjects)
+{
+ GET_CURRENT_CONTEXT(ctx);
+
+ if (MESA_VERBOSE & (VERBOSE_API)) {
+ _mesa_debug(ctx, "glDeleteMemoryObjectsEXT(%d, %p)\n", n,
+ memoryObjects);
+ }
+
+ if (!ctx->Extensions.EXT_memory_object) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glDeleteMemoryObjectsEXT(unsupported)");
+ return;
+ }
+
+ if (n < 0) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glDeleteMemoryObjectsEXT(n < 0)");
+ return;
+ }
+
+ if (!memoryObjects)
+ return;
+
+ _mesa_HashLockMutex(ctx->Shared->MemoryObjects);
+ for (GLint i = 0; i < n; i++) {
+ if (memoryObjects[i] > 0) {
+ struct gl_memory_object *delObj
+ = _mesa_lookup_memory_object_locked(ctx, memoryObjects[i]);
+
+ if (delObj) {
+ _mesa_HashRemoveLocked(ctx->Shared->MemoryObjects,
+ memoryObjects[i]);
+ ctx->Driver.DeleteMemoryObject(ctx, delObj);
+ }
+ }
+ }
+ _mesa_HashUnlockMutex(ctx->Shared->MemoryObjects);
+}
+
+GLboolean GLAPIENTRY
+_mesa_IsMemoryObjectEXT(GLuint memoryObject)
+{
+ GET_CURRENT_CONTEXT(ctx);
+
+ if (!ctx->Extensions.EXT_memory_object) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glIsMemoryObjectEXT(unsupported)");
+ return GL_FALSE;
+ }
+
+ struct gl_memory_object *obj =
+ _mesa_lookup_memory_object(ctx, memoryObject);
+
+ return obj ? GL_TRUE : GL_FALSE;
+}
+
+void GLAPIENTRY
+_mesa_CreateMemoryObjectsEXT(GLsizei n, GLuint *memoryObjects)
+{
+ GET_CURRENT_CONTEXT(ctx);
+
+ const char *func = "glCreateMemoryObjectsEXT";
+
+ if (MESA_VERBOSE & (VERBOSE_API))
+ _mesa_debug(ctx, "%s(%d, %p)", func, n, memoryObjects);
+
+ if (!ctx->Extensions.EXT_memory_object) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glCreateMemoryObjectsEXT(unsupported)");
+ return;
+ }
+
+ if (n < 0) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "%s(n < 0)", func);
+ return;
+ }
+
+ if (!memoryObjects)
+ return;
+
+ _mesa_HashLockMutex(ctx->Shared->MemoryObjects);
+ GLuint first = _mesa_HashFindFreeKeyBlock(ctx->Shared->MemoryObjects, n);
+ if (first) {
+ for (GLsizei i = 0; i < n; i++) {
+ struct gl_memory_object *memObj;
+
+ memoryObjects[i] = first + i;
+
+ /* allocate memory object */
+ memObj = ctx->Driver.NewMemoryObject(ctx, memoryObjects[i]);
+ if (!memObj) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s()", func);
+ _mesa_HashUnlockMutex(ctx->Shared->MemoryObjects);
+ return;
+ }
+
+ /* insert into hash table */
+ _mesa_HashInsertLocked(ctx->Shared->MemoryObjects,
+ memoryObjects[i],
+ memObj);
+ }
+ }
+
+ _mesa_HashUnlockMutex(ctx->Shared->MemoryObjects);
+}
+
+void GLAPIENTRY
+_mesa_MemoryObjectParameterivEXT(GLuint memoryObject,
+ GLenum pname,
+ const GLint *params)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ struct gl_memory_object *memObj;
+
+ if (!ctx->Extensions.EXT_memory_object) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glMemoryObjectParameterivEXT(unsupported)");
+ return;
+ }
+
+ memObj = _mesa_lookup_memory_object(ctx, memoryObject);
+ if (!memObj)
+ return;
+
+ if (memObj->Immutable) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glMemoryObjectParameterivEXT(memoryObject is immutable");
+ return;
+ }
+
+ switch (pname) {
+ case GL_DEDICATED_MEMORY_OBJECT_EXT:
+ memObj->Dedicated = (GLboolean) params[0];
+ break;
+ case GL_PROTECTED_MEMORY_OBJECT_EXT:
+ /* EXT_protected_textures not supported */
+ goto invalid_pname;
+ default:
+ goto invalid_pname;
+ }
+ return;
+
+invalid_pname:
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glMemoryObjectParameterivEXT(pname=0x%x)", pname);
+}
+
+void GLAPIENTRY
+_mesa_GetMemoryObjectParameterivEXT(GLuint memoryObject,
+ GLenum pname,
+ GLint *params)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ struct gl_memory_object *memObj;
+
+ if (!ctx->Extensions.EXT_memory_object) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glGetMemoryObjectParameterivEXT(unsupported)");
+ return;
+ }
+
+ memObj = _mesa_lookup_memory_object(ctx, memoryObject);
+ if (!memObj)
+ return;
+
+ switch (pname) {
+ case GL_DEDICATED_MEMORY_OBJECT_EXT:
+ *params = (GLint) memObj->Dedicated;
+ break;
+ case GL_PROTECTED_MEMORY_OBJECT_EXT:
+ /* EXT_protected_textures not supported */
+ goto invalid_pname;
+ default:
+ goto invalid_pname;
+ }
+ return;
+
+invalid_pname:
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glGetMemoryObjectParameterivEXT(pname=0x%x)", pname);
+}
+
+static struct gl_memory_object *
+lookup_memory_object_err(struct gl_context *ctx, unsigned memory,
+ const char* func)
+{
+ if (memory == 0) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "%s(memory=0)", func);
+ return NULL;
+ }
+
+ struct gl_memory_object *memObj = _mesa_lookup_memory_object(ctx, memory);
+ if (!memObj)
+ return NULL;
+
+ if (!memObj->Immutable) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "%s(no associated memory)",
+ func);
+ return NULL;
+ }
+
+ return memObj;
+}
+
+/**
+ * Helper used by _mesa_TexStorageMem1/2/3DEXT().
+ */
+static void
+texstorage_memory(GLuint dims, GLenum target, GLsizei levels,
+ GLenum internalFormat, GLsizei width, GLsizei height,
+ GLsizei depth, GLuint memory, GLuint64 offset,
+ const char *func)
+{
+ struct gl_texture_object *texObj;
+ struct gl_memory_object *memObj;
+
+ GET_CURRENT_CONTEXT(ctx);
+
+ if (!ctx->Extensions.EXT_memory_object) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "%s(unsupported)", func);
+ return;
+ }
+
+ texObj = _mesa_get_current_tex_object(ctx, target);
+ if (!texObj)
+ return;
+
+ memObj = lookup_memory_object_err(ctx, memory, func);
+ if (!memObj)
+ return;
+
+ _mesa_texture_storage_memory(ctx, dims, texObj, memObj, target,
+ levels, internalFormat,
+ width, height, depth, offset, false);
+}
+
+static void
+texstorage_memory_ms(GLuint dims, GLenum target, GLsizei samples,
+ GLenum internalFormat, GLsizei width, GLsizei height,
+ GLsizei depth, GLboolean fixedSampleLocations,
+ GLuint memory, GLuint64 offset, const char* func)
+{
+ struct gl_texture_object *texObj;
+ struct gl_memory_object *memObj;
+
+ GET_CURRENT_CONTEXT(ctx);
+
+ if (!ctx->Extensions.EXT_memory_object) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "%s(unsupported)", func);
+ return;
+ }
+
+ texObj = _mesa_get_current_tex_object(ctx, target);
+ if (!texObj)
+ return;
+
+ memObj = lookup_memory_object_err(ctx, memory, func);
+ if (!memObj)
+ return;
+
+ _mesa_texture_storage_ms_memory(ctx, dims, texObj, memObj, target, samples,
+ internalFormat, width, height, depth,
+ fixedSampleLocations, offset, func);
+}
+
+/**
+ * Helper used by _mesa_TextureStorageMem1/2/3DEXT().
+ */
+static void
+texturestorage_memory(GLuint dims, GLuint texture, GLsizei levels,
+ GLenum internalFormat, GLsizei width, GLsizei height,
+ GLsizei depth, GLuint memory, GLuint64 offset,
+ const char *func)
+{
+ struct gl_texture_object *texObj;
+ struct gl_memory_object *memObj;
+
+ GET_CURRENT_CONTEXT(ctx);
+
+ if (!ctx->Extensions.EXT_memory_object) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "%s(unsupported)", func);
+ return;
+ }
+
+ texObj = _mesa_lookup_texture(ctx, texture);
+ if (!texObj)
+ return;
+
+ memObj = lookup_memory_object_err(ctx, memory, func);
+ if (!memObj)
+ return;
+
+ _mesa_texture_storage_memory(ctx, dims, texObj, memObj, texObj->Target,
+ levels, internalFormat,
+ width, height, depth, offset, true);
+}
+
+static void
+texturestorage_memory_ms(GLuint dims, GLuint texture, GLsizei samples,
+ GLenum internalFormat, GLsizei width, GLsizei height,
+ GLsizei depth, GLboolean fixedSampleLocations,
+ GLuint memory, GLuint64 offset, const char* func)
+{
+ struct gl_texture_object *texObj;
+ struct gl_memory_object *memObj;
+
+ GET_CURRENT_CONTEXT(ctx);
+
+ if (!ctx->Extensions.EXT_memory_object) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "%s(unsupported)", func);
+ return;
+ }
+
+ texObj = _mesa_lookup_texture(ctx, texture);
+ if (!texObj)
+ return;
+
+ memObj = lookup_memory_object_err(ctx, memory, func);
+ if (!memObj)
+ return;
+
+ _mesa_texture_storage_ms_memory(ctx, dims, texObj, memObj, texObj->Target,
+ samples, internalFormat, width, height,
+ depth, fixedSampleLocations, offset, func);
+}
+
+void GLAPIENTRY
+_mesa_TexStorageMem2DEXT(GLenum target,
+ GLsizei levels,
+ GLenum internalFormat,
+ GLsizei width,
+ GLsizei height,
+ GLuint memory,
+ GLuint64 offset)
+{
+ texstorage_memory(2, target, levels, internalFormat, width, height, 1,
+ memory, offset, "glTexStorageMem2DEXT");
+}
+
+void GLAPIENTRY
+_mesa_TexStorageMem2DMultisampleEXT(GLenum target,
+ GLsizei samples,
+ GLenum internalFormat,
+ GLsizei width,
+ GLsizei height,
+ GLboolean fixedSampleLocations,
+ GLuint memory,
+ GLuint64 offset)
+{
+ texstorage_memory_ms(2, target, samples, internalFormat, width, height, 1,
+ fixedSampleLocations, memory, offset,
+ "glTexStorageMem2DMultisampleEXT");
+}
+
+void GLAPIENTRY
+_mesa_TexStorageMem3DEXT(GLenum target,
+ GLsizei levels,
+ GLenum internalFormat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLuint memory,
+ GLuint64 offset)
+{
+ texstorage_memory(3, target, levels, internalFormat, width, height, depth,
+ memory, offset, "glTexStorageMem3DEXT");
+}
+
+void GLAPIENTRY
+_mesa_TexStorageMem3DMultisampleEXT(GLenum target,
+ GLsizei samples,
+ GLenum internalFormat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLboolean fixedSampleLocations,
+ GLuint memory,
+ GLuint64 offset)
+{
+ texstorage_memory_ms(3, target, samples, internalFormat, width, height,
+ depth, fixedSampleLocations, memory, offset,
+ "glTexStorageMem3DMultisampleEXT");
+}
+
+void GLAPIENTRY
+_mesa_TextureStorageMem2DEXT(GLuint texture,
+ GLsizei levels,
+ GLenum internalFormat,
+ GLsizei width,
+ GLsizei height,
+ GLuint memory,
+ GLuint64 offset)
+{
+ texturestorage_memory(2, texture, levels, internalFormat, width, height, 1,
+ memory, offset, "glTexureStorageMem2DEXT");
+}
+
+void GLAPIENTRY
+_mesa_TextureStorageMem2DMultisampleEXT(GLuint texture,
+ GLsizei samples,
+ GLenum internalFormat,
+ GLsizei width,
+ GLsizei height,
+ GLboolean fixedSampleLocations,
+ GLuint memory,
+ GLuint64 offset)
+{
+ texturestorage_memory_ms(2, texture, samples, internalFormat, width, height,
+ 1, fixedSampleLocations, memory, offset,
+ "glTextureStorageMem2DMultisampleEXT");
+}
+
+void GLAPIENTRY
+_mesa_TextureStorageMem3DEXT(GLuint texture,
+ GLsizei levels,
+ GLenum internalFormat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLuint memory,
+ GLuint64 offset)
+{
+ texturestorage_memory(3, texture, levels, internalFormat, width, height,
+ depth, memory, offset, "glTextureStorageMem3DEXT");
+}
+
+void GLAPIENTRY
+_mesa_TextureStorageMem3DMultisampleEXT(GLuint texture,
+ GLsizei samples,
+ GLenum internalFormat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLboolean fixedSampleLocations,
+ GLuint memory,
+ GLuint64 offset)
+{
+ texturestorage_memory_ms(3, texture, samples, internalFormat, width, height,
+ depth, fixedSampleLocations, memory, offset,
+ "glTextureStorageMem3DMultisampleEXT");
+}
+
+void GLAPIENTRY
+_mesa_TexStorageMem1DEXT(GLenum target,
+ GLsizei levels,
+ GLenum internalFormat,
+ GLsizei width,
+ GLuint memory,
+ GLuint64 offset)
+{
+ texstorage_memory(1, target, levels, internalFormat, width, 1, 1, memory,
+ offset, "glTexStorageMem1DEXT");
+}
+
+void GLAPIENTRY
+_mesa_TextureStorageMem1DEXT(GLuint texture,
+ GLsizei levels,
+ GLenum internalFormat,
+ GLsizei width,
+ GLuint memory,
+ GLuint64 offset)
+{
+ texturestorage_memory(1, texture, levels, internalFormat, width, 1, 1,
+ memory, offset, "glTextureStorageMem1DEXT");
+}
+
+void GLAPIENTRY
+_mesa_GenSemaphoresEXT(GLsizei n, GLuint *semaphores)
+{
+
+}
+
+void GLAPIENTRY
+_mesa_DeleteSemaphoresEXT(GLsizei n, const GLuint *semaphores)
+{
+
+}
+
+GLboolean GLAPIENTRY
+_mesa_IsSemaphoreEXT(GLuint semaphore)
+{
+ return GL_FALSE;
+}
+
+void GLAPIENTRY
+_mesa_SemaphoreParameterui64vEXT(GLuint semaphore,
+ GLenum pname,
+ const GLuint64 *params)
+{
+
+}
+
+void GLAPIENTRY
+_mesa_GetSemaphoreParameterui64vEXT(GLuint semaphore,
+ GLenum pname,
+ GLuint64 *params)
+{
+
+}
+
+void GLAPIENTRY
+_mesa_WaitSemaphoreEXT(GLuint semaphore,
+ GLuint numBufferBarriers,
+ const GLuint *buffers,
+ GLuint numTextureBarriers,
+ const GLuint *textures,
+ const GLenum *srcLayouts)
+{
+
+}
+
+void GLAPIENTRY
+_mesa_SignalSemaphoreEXT(GLuint semaphore,
+ GLuint numBufferBarriers,
+ const GLuint *buffers,
+ GLuint numTextureBarriers,
+ const GLuint *textures,
+ const GLenum *dstLayouts)
+{
+
+}
+
+void GLAPIENTRY
+_mesa_ImportMemoryFdEXT(GLuint memory,
+ GLuint64 size,
+ GLenum handleType,
+ GLint fd)
+{
+ GET_CURRENT_CONTEXT(ctx);
+
+ if (!ctx->Extensions.EXT_memory_object_fd) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glImportMemoryFdEXT(unsupported)");
+ return;
+ }
+
+ if (handleType != GL_HANDLE_TYPE_OPAQUE_FD_EXT) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glImportMemoryFdEXT(handleType=%u)",
+ handleType);
+ return;
+ }
+
+ struct gl_memory_object *memObj = _mesa_lookup_memory_object(ctx, memory);
+ if (!memObj)
+ return;
+
+ ctx->Driver.ImportMemoryObjectFd(ctx, memObj, size, fd);
+ memObj->Immutable = GL_TRUE;
+}
+
+void GLAPIENTRY
+_mesa_ImportSemaphoreFdEXT(GLuint semaphore,
+ GLenum handleType,
+ GLint fd)
+{
+
+}
diff --git a/lib/mesa/src/mesa/main/externalobjects.h b/lib/mesa/src/mesa/main/externalobjects.h
new file mode 100644
index 000000000..a9a12b821
--- /dev/null
+++ b/lib/mesa/src/mesa/main/externalobjects.h
@@ -0,0 +1,231 @@
+/*
+ * Mesa 3-D graphics library
+ *
+ * Copyright (C) 2017 Red Hat.
+ *
+ * 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.
+ *
+ * Authors: Dave Airlie <airlied@gmail.com>
+ * Andres Rodriguez <andresx7@gmail.com>
+ */
+
+/**
+ * \file externalobjects.h
+ *
+ * Declarations of functions related to the API interop extensions.
+ */
+
+#ifndef EXTERNALOBJECTS_H
+#define EXTERNALOBJECTS_H
+
+#include "glheader.h"
+#include "hash.h"
+
+static inline struct gl_memory_object *
+_mesa_lookup_memory_object(struct gl_context *ctx, GLuint memory)
+{
+ if (!memory)
+ return NULL;
+
+ return (struct gl_memory_object *)
+ _mesa_HashLookup(ctx->Shared->MemoryObjects, memory);
+}
+
+static inline struct gl_memory_object *
+_mesa_lookup_memory_object_locked(struct gl_context *ctx, GLuint memory)
+{
+ if (!memory)
+ return NULL;
+
+ return (struct gl_memory_object *)
+ _mesa_HashLookupLocked(ctx->Shared->MemoryObjects, memory);
+}
+
+extern void
+_mesa_init_memory_object_functions(struct dd_function_table *driver);
+
+extern void
+_mesa_initialize_memory_object(struct gl_context *ctx,
+ struct gl_memory_object *obj,
+ GLuint name);
+extern void
+_mesa_delete_memory_object(struct gl_context *ctx, struct gl_memory_object *mo);
+
+extern void GLAPIENTRY
+_mesa_DeleteMemoryObjectsEXT(GLsizei n, const GLuint *memoryObjects);
+
+extern GLboolean GLAPIENTRY
+_mesa_IsMemoryObjectEXT(GLuint memoryObject);
+
+extern void GLAPIENTRY
+_mesa_CreateMemoryObjectsEXT(GLsizei n, GLuint *memoryObjects);
+
+extern void GLAPIENTRY
+_mesa_MemoryObjectParameterivEXT(GLuint memoryObject,
+ GLenum pname,
+ const GLint *params);
+
+extern void GLAPIENTRY
+_mesa_GetMemoryObjectParameterivEXT(GLuint memoryObject,
+ GLenum pname,
+ GLint *params);
+
+extern void GLAPIENTRY
+_mesa_TexStorageMem2DEXT(GLenum target,
+ GLsizei levels,
+ GLenum internalFormat,
+ GLsizei width,
+ GLsizei height,
+ GLuint memory,
+ GLuint64 offset);
+
+extern void GLAPIENTRY
+_mesa_TexStorageMem2DMultisampleEXT(GLenum target,
+ GLsizei samples,
+ GLenum internalFormat,
+ GLsizei width,
+ GLsizei height,
+ GLboolean fixedSampleLocations,
+ GLuint memory,
+ GLuint64 offset);
+
+extern void GLAPIENTRY
+_mesa_TexStorageMem3DEXT(GLenum target,
+ GLsizei levels,
+ GLenum internalFormat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLuint memory,
+ GLuint64 offset);
+
+extern void GLAPIENTRY
+_mesa_TexStorageMem3DMultisampleEXT(GLenum target,
+ GLsizei samples,
+ GLenum internalFormat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLboolean fixedSampleLocations,
+ GLuint memory,
+ GLuint64 offset);
+
+extern void GLAPIENTRY
+_mesa_TextureStorageMem2DEXT(GLuint texture,
+ GLsizei levels,
+ GLenum internalFormat,
+ GLsizei width,
+ GLsizei height,
+ GLuint memory,
+ GLuint64 offset);
+
+extern void GLAPIENTRY
+_mesa_TextureStorageMem2DMultisampleEXT(GLuint texture,
+ GLsizei samples,
+ GLenum internalFormat,
+ GLsizei width,
+ GLsizei height,
+ GLboolean fixedSampleLocations,
+ GLuint memory,
+ GLuint64 offset);
+
+extern void GLAPIENTRY
+_mesa_TextureStorageMem3DEXT(GLuint texture,
+ GLsizei levels,
+ GLenum internalFormat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLuint memory,
+ GLuint64 offset);
+
+extern void GLAPIENTRY
+_mesa_TextureStorageMem3DMultisampleEXT(GLuint texture,
+ GLsizei samples,
+ GLenum internalFormat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLboolean fixedSampleLocations,
+ GLuint memory,
+ GLuint64 offset);
+
+extern void GLAPIENTRY
+_mesa_TexStorageMem1DEXT(GLenum target,
+ GLsizei levels,
+ GLenum internalFormat,
+ GLsizei width,
+ GLuint memory,
+ GLuint64 offset);
+
+extern void GLAPIENTRY
+_mesa_TextureStorageMem1DEXT(GLuint texture,
+ GLsizei levels,
+ GLenum internalFormat,
+ GLsizei width,
+ GLuint memory,
+ GLuint64 offset);
+
+extern void GLAPIENTRY
+_mesa_GenSemaphoresEXT(GLsizei n, GLuint *semaphores);
+
+extern void GLAPIENTRY
+_mesa_DeleteSemaphoresEXT(GLsizei n, const GLuint *semaphores);
+
+extern GLboolean GLAPIENTRY
+_mesa_IsSemaphoreEXT(GLuint semaphore);
+
+extern void GLAPIENTRY
+_mesa_SemaphoreParameterui64vEXT(GLuint semaphore,
+ GLenum pname,
+ const GLuint64 *params);
+
+extern void GLAPIENTRY
+_mesa_GetSemaphoreParameterui64vEXT(GLuint semaphore,
+ GLenum pname,
+ GLuint64 *params);
+
+extern void GLAPIENTRY
+_mesa_WaitSemaphoreEXT(GLuint semaphore,
+ GLuint numBufferBarriers,
+ const GLuint *buffers,
+ GLuint numTextureBarriers,
+ const GLuint *textures,
+ const GLenum *srcLayouts);
+
+extern void GLAPIENTRY
+_mesa_SignalSemaphoreEXT(GLuint semaphore,
+ GLuint numBufferBarriers,
+ const GLuint *buffers,
+ GLuint numTextureBarriers,
+ const GLuint *textures,
+ const GLenum *dstLayouts);
+
+extern void GLAPIENTRY
+_mesa_ImportMemoryFdEXT(GLuint memory,
+ GLuint64 size,
+ GLenum handleType,
+ GLint fd);
+
+extern void GLAPIENTRY
+_mesa_ImportSemaphoreFdEXT(GLuint semaphore,
+ GLenum handleType,
+ GLint fd);
+
+#endif
diff --git a/lib/mesa/src/mesa/main/format_pack.c b/lib/mesa/src/mesa/main/format_pack.c
index 3408081d4..f9e194d31 100644
--- a/lib/mesa/src/mesa/main/format_pack.c
+++ b/lib/mesa/src/mesa/main/format_pack.c
@@ -452,6 +452,30 @@ pack_ubyte_a1b5g5r5_unorm(const GLubyte src[4], void *dst)
}
static inline void
+pack_ubyte_x1b5g5r5_unorm(const GLubyte src[4], void *dst)
+{
+
+
+
+ uint8_t b =
+ _mesa_unorm_to_unorm(src[2], 8, 5);
+
+
+ uint8_t g =
+ _mesa_unorm_to_unorm(src[1], 8, 5);
+
+
+ uint8_t r =
+ _mesa_unorm_to_unorm(src[0], 8, 5);
+
+ uint16_t d = 0;
+ d |= PACK(b, 1, 5);
+ d |= PACK(g, 6, 5);
+ d |= PACK(r, 11, 5);
+ (*(uint16_t *)dst) = d;
+}
+
+static inline void
pack_ubyte_b5g5r5a1_unorm(const GLubyte src[4], void *dst)
{
@@ -3635,7 +3659,7 @@ pack_ubyte_r11g11b10_float(const GLubyte src[4], void *dst)
/* uint packing functions */
-
+
static inline void
pack_uint_a8b8g8r8_uint(const GLuint src[4], void *dst)
{
@@ -5502,6 +5526,30 @@ pack_float_a1b5g5r5_unorm(const GLfloat src[4], void *dst)
}
static inline void
+pack_float_x1b5g5r5_unorm(const GLfloat src[4], void *dst)
+{
+
+
+
+ uint8_t b =
+ _mesa_float_to_unorm(src[2], 5);
+
+
+ uint8_t g =
+ _mesa_float_to_unorm(src[1], 5);
+
+
+ uint8_t r =
+ _mesa_float_to_unorm(src[0], 5);
+
+ uint16_t d = 0;
+ d |= PACK(b, 1, 5);
+ d |= PACK(g, 6, 5);
+ d |= PACK(r, 11, 5);
+ (*(uint16_t *)dst) = d;
+}
+
+static inline void
pack_float_b5g5r5a1_unorm(const GLfloat src[4], void *dst)
{
@@ -7267,6 +7315,9 @@ _mesa_get_pack_ubyte_rgba_function(mesa_format format)
case MESA_FORMAT_A1B5G5R5_UNORM:
return pack_ubyte_a1b5g5r5_unorm;
+ case MESA_FORMAT_X1B5G5R5_UNORM:
+ return pack_ubyte_x1b5g5r5_unorm;
+
case MESA_FORMAT_B5G5R5A1_UNORM:
return pack_ubyte_b5g5r5a1_unorm;
@@ -7810,6 +7861,9 @@ _mesa_get_pack_float_rgba_function(mesa_format format)
case MESA_FORMAT_A1B5G5R5_UNORM:
return pack_float_a1b5g5r5_unorm;
+ case MESA_FORMAT_X1B5G5R5_UNORM:
+ return pack_float_x1b5g5r5_unorm;
+
case MESA_FORMAT_B5G5R5A1_UNORM:
return pack_float_b5g5r5a1_unorm;
@@ -8199,6 +8253,13 @@ _mesa_pack_ubyte_rgba_row(mesa_format format, GLuint n,
}
break;
+ case MESA_FORMAT_X1B5G5R5_UNORM:
+ for (i = 0; i < n; ++i) {
+ pack_ubyte_x1b5g5r5_unorm(src[i], d);
+ d += 2;
+ }
+ break;
+
case MESA_FORMAT_B5G5R5A1_UNORM:
for (i = 0; i < n; ++i) {
pack_ubyte_b5g5r5a1_unorm(src[i], d);
@@ -9341,7 +9402,7 @@ _mesa_pack_uint_rgba_row(mesa_format format, GLuint n,
GLubyte *d = dst;
switch (format) {
-
+
case MESA_FORMAT_A8B8G8R8_UINT:
for (i = 0; i < n; ++i) {
pack_uint_a8b8g8r8_uint(src[i], d);
@@ -9988,6 +10049,13 @@ _mesa_pack_float_rgba_row(mesa_format format, GLuint n,
}
break;
+ case MESA_FORMAT_X1B5G5R5_UNORM:
+ for (i = 0; i < n; ++i) {
+ pack_float_x1b5g5r5_unorm(src[i], d);
+ d += 2;
+ }
+ break;
+
case MESA_FORMAT_B5G5R5A1_UNORM:
for (i = 0; i < n; ++i) {
pack_float_b5g5r5a1_unorm(src[i], d);
diff --git a/lib/mesa/src/mesa/main/format_unpack.c b/lib/mesa/src/mesa/main/format_unpack.c
index 760cbc267..21c55416b 100644
--- a/lib/mesa/src/mesa/main/format_unpack.c
+++ b/lib/mesa/src/mesa/main/format_unpack.c
@@ -403,6 +403,27 @@ unpack_float_a1b5g5r5_unorm(const void *void_src, GLfloat dst[4])
}
static inline void
+unpack_float_x1b5g5r5_unorm(const void *void_src, GLfloat dst[4])
+{
+ uint16_t *src = (uint16_t *)void_src;
+ uint8_t b = UNPACK(*src, 1, 5);
+ uint8_t g = UNPACK(*src, 6, 5);
+ uint8_t r = UNPACK(*src, 11, 5);
+
+
+
+ dst[0] = _mesa_unorm_to_float(r, 5);
+
+
+ dst[1] = _mesa_unorm_to_float(g, 5);
+
+
+ dst[2] = _mesa_unorm_to_float(b, 5);
+
+ dst[3] = 1.0f;
+}
+
+static inline void
unpack_float_b5g5r5a1_unorm(const void *void_src, GLfloat dst[4])
{
uint16_t *src = (uint16_t *)void_src;
@@ -2582,6 +2603,27 @@ unpack_ubyte_a1b5g5r5_unorm(const void *void_src, GLubyte dst[4])
}
static inline void
+unpack_ubyte_x1b5g5r5_unorm(const void *void_src, GLubyte dst[4])
+{
+ uint16_t *src = (uint16_t *)void_src;
+ uint8_t b = UNPACK(*src, 1, 5);
+ uint8_t g = UNPACK(*src, 6, 5);
+ uint8_t r = UNPACK(*src, 11, 5);
+
+
+
+ dst[0] = _mesa_unorm_to_unorm(r, 5, 8);
+
+
+ dst[1] = _mesa_unorm_to_unorm(g, 5, 8);
+
+
+ dst[2] = _mesa_unorm_to_unorm(b, 5, 8);
+
+ dst[3] = 255;
+}
+
+static inline void
unpack_ubyte_b5g5r5a1_unorm(const void *void_src, GLubyte dst[4])
{
uint16_t *src = (uint16_t *)void_src;
@@ -3989,7 +4031,7 @@ unpack_ubyte_bgr_srgb8(const void *void_src, GLubyte dst[4])
/* integer packing functions */
-
+
static inline void
unpack_int_a8b8g8r8_uint(const void *void_src, GLuint dst[4])
{
@@ -5389,6 +5431,12 @@ _mesa_unpack_rgba_row(mesa_format format, GLuint n,
s += 2;
}
break;
+ case MESA_FORMAT_X1B5G5R5_UNORM:
+ for (i = 0; i < n; ++i) {
+ unpack_float_x1b5g5r5_unorm(s, dst[i]);
+ s += 2;
+ }
+ break;
case MESA_FORMAT_B5G5R5A1_UNORM:
for (i = 0; i < n; ++i) {
unpack_float_b5g5r5a1_unorm(s, dst[i]);
@@ -6045,6 +6093,13 @@ _mesa_unpack_ubyte_rgba_row(mesa_format format, GLuint n,
}
break;
+ case MESA_FORMAT_X1B5G5R5_UNORM:
+ for (i = 0; i < n; ++i) {
+ unpack_ubyte_x1b5g5r5_unorm(s, dst[i]);
+ s += 2;
+ }
+ break;
+
case MESA_FORMAT_B5G5R5A1_UNORM:
for (i = 0; i < n; ++i) {
unpack_ubyte_b5g5r5a1_unorm(s, dst[i]);
@@ -6541,7 +6596,7 @@ _mesa_unpack_uint_rgba_row(mesa_format format, GLuint n,
GLuint i;
switch (format) {
-
+
case MESA_FORMAT_A8B8G8R8_UINT:
for (i = 0; i < n; ++i) {
unpack_int_a8b8g8r8_uint(s, dst[i]);
diff --git a/lib/mesa/src/mesa/main/format_utils.c b/lib/mesa/src/mesa/main/format_utils.c
index d16d69c37..31580750b 100644
--- a/lib/mesa/src/mesa/main/format_utils.c
+++ b/lib/mesa/src/mesa/main/format_utils.c
@@ -312,6 +312,20 @@ _mesa_format_convert(void *void_dst, uint32_t dst_format, size_t dst_stride,
* enable it for specific combinations that are known to work.
*/
if (!rebase_swizzle) {
+ /* Do a direct memcpy where possible */
+ if ((dst_format_is_mesa_array_format &&
+ src_format_is_mesa_array_format &&
+ src_array_format == dst_array_format) ||
+ src_format == dst_format) {
+ int format_size = _mesa_get_format_bytes(src_format);
+ for (row = 0; row < height; row++) {
+ memcpy(dst, src, width * format_size);
+ src += src_stride;
+ dst += dst_stride;
+ }
+ return;
+ }
+
/* Handle the cases where we can directly unpack */
if (!src_format_is_mesa_array_format) {
if (dst_array_format == RGBA32_FLOAT) {
diff --git a/lib/mesa/src/mesa/main/formats.csv b/lib/mesa/src/mesa/main/formats.csv
index 285921ed4..ce53f8f05 100644
--- a/lib/mesa/src/mesa/main/formats.csv
+++ b/lib/mesa/src/mesa/main/formats.csv
@@ -68,6 +68,7 @@ MESA_FORMAT_B4G4R4A4_UNORM , packed, 1, 1, 1, un4 , un4 , un4 , u
MESA_FORMAT_B4G4R4X4_UNORM , packed, 1, 1, 1, un4 , un4 , un4 , x4 , zyx1, rgb
MESA_FORMAT_A4R4G4B4_UNORM , packed, 1, 1, 1, un4 , un4 , un4 , un4 , yzwx, rgb
MESA_FORMAT_A1B5G5R5_UNORM , packed, 1, 1, 1, un1 , un5 , un5 , un5 , wzyx, rgb
+MESA_FORMAT_X1B5G5R5_UNORM , packed, 1, 1, 1, x1 , un5 , un5 , un5 , wzy1, rgb
MESA_FORMAT_B5G5R5A1_UNORM , packed, 1, 1, 1, un5 , un5 , un5 , un1 , zyxw, rgb
MESA_FORMAT_B5G5R5X1_UNORM , packed, 1, 1, 1, un5 , un5 , un5 , x1 , zyx1, rgb
MESA_FORMAT_A1R5G5B5_UNORM , packed, 1, 1, 1, un1 , un5 , un5 , un5 , yzwx, rgb
diff --git a/lib/mesa/src/mesa/main/get.h b/lib/mesa/src/mesa/main/get.h
index ce97cc586..34cb9381f 100644
--- a/lib/mesa/src/mesa/main/get.h
+++ b/lib/mesa/src/mesa/main/get.h
@@ -54,6 +54,9 @@ extern void GLAPIENTRY
_mesa_GetFixedv(GLenum pname, GLfixed *params);
extern void GLAPIENTRY
+_mesa_GetUnsignedBytevEXT(GLenum pname, GLubyte *data);
+
+extern void GLAPIENTRY
_mesa_GetBooleani_v( GLenum pname, GLuint index, GLboolean *params );
extern void GLAPIENTRY
@@ -71,6 +74,9 @@ _mesa_GetFloati_v(GLenum target, GLuint index, GLfloat *data);
extern void GLAPIENTRY
_mesa_GetDoublei_v(GLenum target, GLuint index, GLdouble *data);
+extern void GLAPIENTRY
+_mesa_GetUnsignedBytei_vEXT(GLenum target, GLuint index, GLubyte *data);
+
extern const GLubyte * GLAPIENTRY
_mesa_GetString( GLenum name );
diff --git a/lib/mesa/src/mesa/main/lines.h b/lib/mesa/src/mesa/main/lines.h
index fa15e50ac..78a405cba 100644
--- a/lib/mesa/src/mesa/main/lines.h
+++ b/lib/mesa/src/mesa/main/lines.h
@@ -37,13 +37,16 @@
struct gl_context;
+void GLAPIENTRY
+_mesa_LineWidth_no_error(GLfloat width);
+
extern void GLAPIENTRY
_mesa_LineWidth( GLfloat width );
extern void GLAPIENTRY
_mesa_LineStipple( GLint factor, GLushort pattern );
-extern void GLAPIENTRY
+extern void
_mesa_init_line( struct gl_context * ctx );
#endif
diff --git a/lib/mesa/src/mesa/main/multisample.h b/lib/mesa/src/mesa/main/multisample.h
index 7441d3ee9..a7cd2918d 100644
--- a/lib/mesa/src/mesa/main/multisample.h
+++ b/lib/mesa/src/mesa/main/multisample.h
@@ -41,9 +41,15 @@ _mesa_init_multisample(struct gl_context *ctx);
extern void GLAPIENTRY
_mesa_GetMultisamplefv(GLenum pname, GLuint index, GLfloat* val);
+void GLAPIENTRY
+_mesa_SampleMaski_no_error(GLuint index, GLbitfield mask);
+
extern void GLAPIENTRY
_mesa_SampleMaski(GLuint index, GLbitfield mask);
+void GLAPIENTRY
+_mesa_MinSampleShading_no_error(GLclampf value);
+
extern void GLAPIENTRY
_mesa_MinSampleShading(GLclampf value);
diff --git a/lib/mesa/src/mesa/main/points.c b/lib/mesa/src/mesa/main/points.c
index 2d62e73c1..095e2a3d7 100644
--- a/lib/mesa/src/mesa/main/points.c
+++ b/lib/mesa/src/mesa/main/points.c
@@ -40,18 +40,16 @@
* \param size point diameter in pixels
* \sa glPointSize().
*/
-void GLAPIENTRY
-_mesa_PointSize( GLfloat size )
+static ALWAYS_INLINE void
+point_size(struct gl_context *ctx, GLfloat size, bool no_error)
{
- GET_CURRENT_CONTEXT(ctx);
-
- if (size <= 0.0F) {
- _mesa_error( ctx, GL_INVALID_VALUE, "glPointSize" );
+ if (ctx->Point.Size == size)
return;
- }
- if (ctx->Point.Size == size)
+ if (!no_error && size <= 0.0F) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glPointSize");
return;
+ }
FLUSH_VERTICES(ctx, _NEW_POINT);
ctx->Point.Size = size;
@@ -62,6 +60,22 @@ _mesa_PointSize( GLfloat size )
void GLAPIENTRY
+_mesa_PointSize_no_error(GLfloat size)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ point_size(ctx, size, true);
+}
+
+
+void GLAPIENTRY
+_mesa_PointSize( GLfloat size )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ point_size(ctx, size, false);
+}
+
+
+void GLAPIENTRY
_mesa_PointParameteri( GLenum pname, GLint param )
{
GLfloat p[3];
diff --git a/lib/mesa/src/mesa/main/points.h b/lib/mesa/src/mesa/main/points.h
index c3d0f691b..c2b67a371 100644
--- a/lib/mesa/src/mesa/main/points.h
+++ b/lib/mesa/src/mesa/main/points.h
@@ -37,6 +37,9 @@
struct gl_context;
+void GLAPIENTRY
+_mesa_PointSize_no_error(GLfloat size);
+
extern void GLAPIENTRY
_mesa_PointSize( GLfloat size );
diff --git a/lib/mesa/src/mesa/main/readpix.h b/lib/mesa/src/mesa/main/readpix.h
index 481ad9d9c..eff8e0290 100644
--- a/lib/mesa/src/mesa/main/readpix.h
+++ b/lib/mesa/src/mesa/main/readpix.h
@@ -58,10 +58,19 @@ _mesa_readpixels(struct gl_context *ctx,
const struct gl_pixelstore_attrib *packing,
GLvoid *pixels);
+void GLAPIENTRY
+_mesa_ReadPixels_no_error(GLint x, GLint y, GLsizei width, GLsizei height,
+ GLenum format, GLenum type, GLvoid *pixels);
+
extern void GLAPIENTRY
_mesa_ReadPixels( GLint x, GLint y, GLsizei width, GLsizei height,
GLenum format, GLenum type, GLvoid *pixels );
+void GLAPIENTRY
+_mesa_ReadnPixelsARB_no_error(GLint x, GLint y, GLsizei width, GLsizei height,
+ GLenum format, GLenum type, GLsizei bufSize,
+ GLvoid *pixels);
+
extern void GLAPIENTRY
_mesa_ReadnPixelsARB( GLint x, GLint y, GLsizei width, GLsizei height,
GLenum format, GLenum type, GLsizei bufSize,
diff --git a/lib/mesa/src/mesa/main/texcompress_s3tc.c b/lib/mesa/src/mesa/main/texcompress_s3tc.c
index 992ad058b..1c6cbba89 100644
--- a/lib/mesa/src/mesa/main/texcompress_s3tc.c
+++ b/lib/mesa/src/mesa/main/texcompress_s3tc.c
@@ -31,91 +31,17 @@
#include "glheader.h"
#include "imports.h"
-#include "dlopen.h"
#include "image.h"
#include "macros.h"
#include "mtypes.h"
#include "texcompress.h"
#include "texcompress_s3tc.h"
+#include "texcompress_s3tc_tmp.h"
#include "texstore.h"
#include "format_unpack.h"
#include "util/format_srgb.h"
-#if defined(_WIN32) || defined(WIN32)
-#define DXTN_LIBNAME "dxtn.dll"
-#define RTLD_LAZY 0
-#define RTLD_GLOBAL 0
-#elif defined(__CYGWIN__)
-#define DXTN_LIBNAME "cygtxc_dxtn.dll"
-#else
-#define DXTN_LIBNAME "libtxc_dxtn.so"
-#endif
-
-typedef void (*dxtFetchTexelFuncExt)( GLint srcRowstride, const GLubyte *pixdata, GLint col, GLint row, GLvoid *texelOut );
-
-static dxtFetchTexelFuncExt fetch_ext_rgb_dxt1 = NULL;
-static dxtFetchTexelFuncExt fetch_ext_rgba_dxt1 = NULL;
-static dxtFetchTexelFuncExt fetch_ext_rgba_dxt3 = NULL;
-static dxtFetchTexelFuncExt fetch_ext_rgba_dxt5 = NULL;
-
-typedef void (*dxtCompressTexFuncExt)(GLint srccomps, GLint width,
- GLint height, const GLubyte *srcPixData,
- GLenum destformat, GLubyte *dest,
- GLint dstRowStride);
-
-static dxtCompressTexFuncExt ext_tx_compress_dxtn = NULL;
-
-static void *dxtlibhandle = NULL;
-
-
-void
-_mesa_init_texture_s3tc( struct gl_context *ctx )
-{
- /* called during context initialization */
- ctx->Mesa_DXTn = GL_FALSE;
- if (!dxtlibhandle) {
- dxtlibhandle = _mesa_dlopen(DXTN_LIBNAME, 0);
- if (!dxtlibhandle) {
- _mesa_warning(ctx, "couldn't open " DXTN_LIBNAME ", software DXTn "
- "compression/decompression unavailable");
- }
- else {
- /* the fetch functions are not per context! Might be problematic... */
- fetch_ext_rgb_dxt1 = (dxtFetchTexelFuncExt)
- _mesa_dlsym(dxtlibhandle, "fetch_2d_texel_rgb_dxt1");
- fetch_ext_rgba_dxt1 = (dxtFetchTexelFuncExt)
- _mesa_dlsym(dxtlibhandle, "fetch_2d_texel_rgba_dxt1");
- fetch_ext_rgba_dxt3 = (dxtFetchTexelFuncExt)
- _mesa_dlsym(dxtlibhandle, "fetch_2d_texel_rgba_dxt3");
- fetch_ext_rgba_dxt5 = (dxtFetchTexelFuncExt)
- _mesa_dlsym(dxtlibhandle, "fetch_2d_texel_rgba_dxt5");
- ext_tx_compress_dxtn = (dxtCompressTexFuncExt)
- _mesa_dlsym(dxtlibhandle, "tx_compress_dxtn");
-
- if (!fetch_ext_rgb_dxt1 ||
- !fetch_ext_rgba_dxt1 ||
- !fetch_ext_rgba_dxt3 ||
- !fetch_ext_rgba_dxt5 ||
- !ext_tx_compress_dxtn) {
- _mesa_warning(ctx, "couldn't reference all symbols in "
- DXTN_LIBNAME ", software DXTn compression/decompression "
- "unavailable");
- fetch_ext_rgb_dxt1 = NULL;
- fetch_ext_rgba_dxt1 = NULL;
- fetch_ext_rgba_dxt3 = NULL;
- fetch_ext_rgba_dxt5 = NULL;
- ext_tx_compress_dxtn = NULL;
- _mesa_dlclose(dxtlibhandle);
- dxtlibhandle = NULL;
- }
- }
- }
- if (dxtlibhandle) {
- ctx->Mesa_DXTn = GL_TRUE;
- }
-}
-
/**
* Store user's image in rgb_dxt1 format.
*/
@@ -158,14 +84,9 @@ _mesa_texstore_rgb_dxt1(TEXSTORE_PARAMS)
dst = dstSlices[0];
- if (ext_tx_compress_dxtn) {
- (*ext_tx_compress_dxtn)(3, srcWidth, srcHeight, pixels,
- GL_COMPRESSED_RGB_S3TC_DXT1_EXT,
- dst, dstRowStride);
- }
- else {
- _mesa_warning(ctx, "external dxt library not available: texstore_rgb_dxt1");
- }
+ tx_compress_dxtn(3, srcWidth, srcHeight, pixels,
+ GL_COMPRESSED_RGB_S3TC_DXT1_EXT,
+ dst, dstRowStride);
free((void *) tempImage);
@@ -216,14 +137,9 @@ _mesa_texstore_rgba_dxt1(TEXSTORE_PARAMS)
dst = dstSlices[0];
- if (ext_tx_compress_dxtn) {
- (*ext_tx_compress_dxtn)(4, srcWidth, srcHeight, pixels,
- GL_COMPRESSED_RGBA_S3TC_DXT1_EXT,
- dst, dstRowStride);
- }
- else {
- _mesa_warning(ctx, "external dxt library not available: texstore_rgba_dxt1");
- }
+ tx_compress_dxtn(4, srcWidth, srcHeight, pixels,
+ GL_COMPRESSED_RGBA_S3TC_DXT1_EXT,
+ dst, dstRowStride);
free((void*) tempImage);
@@ -273,14 +189,9 @@ _mesa_texstore_rgba_dxt3(TEXSTORE_PARAMS)
dst = dstSlices[0];
- if (ext_tx_compress_dxtn) {
- (*ext_tx_compress_dxtn)(4, srcWidth, srcHeight, pixels,
- GL_COMPRESSED_RGBA_S3TC_DXT3_EXT,
- dst, dstRowStride);
- }
- else {
- _mesa_warning(ctx, "external dxt library not available: texstore_rgba_dxt3");
- }
+ tx_compress_dxtn(4, srcWidth, srcHeight, pixels,
+ GL_COMPRESSED_RGBA_S3TC_DXT3_EXT,
+ dst, dstRowStride);
free((void *) tempImage);
@@ -330,14 +241,9 @@ _mesa_texstore_rgba_dxt5(TEXSTORE_PARAMS)
dst = dstSlices[0];
- if (ext_tx_compress_dxtn) {
- (*ext_tx_compress_dxtn)(4, srcWidth, srcHeight, pixels,
- GL_COMPRESSED_RGBA_S3TC_DXT5_EXT,
- dst, dstRowStride);
- }
- else {
- _mesa_warning(ctx, "external dxt library not available: texstore_rgba_dxt5");
- }
+ tx_compress_dxtn(4, srcWidth, srcHeight, pixels,
+ GL_COMPRESSED_RGBA_S3TC_DXT5_EXT,
+ dst, dstRowStride);
free((void *) tempImage);
@@ -345,85 +251,52 @@ _mesa_texstore_rgba_dxt5(TEXSTORE_PARAMS)
}
-/** Report problem with dxt texture decompression, once */
-static void
-problem(const char *func)
-{
- static GLboolean warned = GL_FALSE;
- if (!warned) {
- _mesa_debug(NULL, "attempted to decode DXT texture without "
- "library available: %s\n", func);
- warned = GL_TRUE;
- }
-}
-
-
static void
fetch_rgb_dxt1(const GLubyte *map,
GLint rowStride, GLint i, GLint j, GLfloat *texel)
{
- if (fetch_ext_rgb_dxt1) {
- GLubyte tex[4];
- fetch_ext_rgb_dxt1(rowStride, map, i, j, tex);
- texel[RCOMP] = UBYTE_TO_FLOAT(tex[RCOMP]);
- texel[GCOMP] = UBYTE_TO_FLOAT(tex[GCOMP]);
- texel[BCOMP] = UBYTE_TO_FLOAT(tex[BCOMP]);
- texel[ACOMP] = UBYTE_TO_FLOAT(tex[ACOMP]);
- }
- else {
- problem("rgb_dxt1");
- }
+ GLubyte tex[4];
+ fetch_2d_texel_rgb_dxt1(rowStride, map, i, j, tex);
+ texel[RCOMP] = UBYTE_TO_FLOAT(tex[RCOMP]);
+ texel[GCOMP] = UBYTE_TO_FLOAT(tex[GCOMP]);
+ texel[BCOMP] = UBYTE_TO_FLOAT(tex[BCOMP]);
+ texel[ACOMP] = UBYTE_TO_FLOAT(tex[ACOMP]);
}
static void
fetch_rgba_dxt1(const GLubyte *map,
GLint rowStride, GLint i, GLint j, GLfloat *texel)
{
- if (fetch_ext_rgba_dxt1) {
- GLubyte tex[4];
- fetch_ext_rgba_dxt1(rowStride, map, i, j, tex);
- texel[RCOMP] = UBYTE_TO_FLOAT(tex[RCOMP]);
- texel[GCOMP] = UBYTE_TO_FLOAT(tex[GCOMP]);
- texel[BCOMP] = UBYTE_TO_FLOAT(tex[BCOMP]);
- texel[ACOMP] = UBYTE_TO_FLOAT(tex[ACOMP]);
- }
- else {
- problem("rgba_dxt1");
- }
+ GLubyte tex[4];
+ fetch_2d_texel_rgba_dxt1(rowStride, map, i, j, tex);
+ texel[RCOMP] = UBYTE_TO_FLOAT(tex[RCOMP]);
+ texel[GCOMP] = UBYTE_TO_FLOAT(tex[GCOMP]);
+ texel[BCOMP] = UBYTE_TO_FLOAT(tex[BCOMP]);
+ texel[ACOMP] = UBYTE_TO_FLOAT(tex[ACOMP]);
}
static void
fetch_rgba_dxt3(const GLubyte *map,
GLint rowStride, GLint i, GLint j, GLfloat *texel)
{
- if (fetch_ext_rgba_dxt3) {
- GLubyte tex[4];
- fetch_ext_rgba_dxt3(rowStride, map, i, j, tex);
- texel[RCOMP] = UBYTE_TO_FLOAT(tex[RCOMP]);
- texel[GCOMP] = UBYTE_TO_FLOAT(tex[GCOMP]);
- texel[BCOMP] = UBYTE_TO_FLOAT(tex[BCOMP]);
- texel[ACOMP] = UBYTE_TO_FLOAT(tex[ACOMP]);
- }
- else {
- problem("rgba_dxt3");
- }
+ GLubyte tex[4];
+ fetch_2d_texel_rgba_dxt3(rowStride, map, i, j, tex);
+ texel[RCOMP] = UBYTE_TO_FLOAT(tex[RCOMP]);
+ texel[GCOMP] = UBYTE_TO_FLOAT(tex[GCOMP]);
+ texel[BCOMP] = UBYTE_TO_FLOAT(tex[BCOMP]);
+ texel[ACOMP] = UBYTE_TO_FLOAT(tex[ACOMP]);
}
static void
fetch_rgba_dxt5(const GLubyte *map,
GLint rowStride, GLint i, GLint j, GLfloat *texel)
{
- if (fetch_ext_rgba_dxt5) {
- GLubyte tex[4];
- fetch_ext_rgba_dxt5(rowStride, map, i, j, tex);
- texel[RCOMP] = UBYTE_TO_FLOAT(tex[RCOMP]);
- texel[GCOMP] = UBYTE_TO_FLOAT(tex[GCOMP]);
- texel[BCOMP] = UBYTE_TO_FLOAT(tex[BCOMP]);
- texel[ACOMP] = UBYTE_TO_FLOAT(tex[ACOMP]);
- }
- else {
- problem("rgba_dxt5");
- }
+ GLubyte tex[4];
+ fetch_2d_texel_rgba_dxt5(rowStride, map, i, j, tex);
+ texel[RCOMP] = UBYTE_TO_FLOAT(tex[RCOMP]);
+ texel[GCOMP] = UBYTE_TO_FLOAT(tex[GCOMP]);
+ texel[BCOMP] = UBYTE_TO_FLOAT(tex[BCOMP]);
+ texel[ACOMP] = UBYTE_TO_FLOAT(tex[ACOMP]);
}
@@ -431,68 +304,48 @@ static void
fetch_srgb_dxt1(const GLubyte *map,
GLint rowStride, GLint i, GLint j, GLfloat *texel)
{
- if (fetch_ext_rgb_dxt1) {
- GLubyte tex[4];
- fetch_ext_rgb_dxt1(rowStride, map, i, j, tex);
- texel[RCOMP] = util_format_srgb_8unorm_to_linear_float(tex[RCOMP]);
- texel[GCOMP] = util_format_srgb_8unorm_to_linear_float(tex[GCOMP]);
- texel[BCOMP] = util_format_srgb_8unorm_to_linear_float(tex[BCOMP]);
- texel[ACOMP] = UBYTE_TO_FLOAT(tex[ACOMP]);
- }
- else {
- problem("srgb_dxt1");
- }
+ GLubyte tex[4];
+ fetch_2d_texel_rgb_dxt1(rowStride, map, i, j, tex);
+ texel[RCOMP] = util_format_srgb_8unorm_to_linear_float(tex[RCOMP]);
+ texel[GCOMP] = util_format_srgb_8unorm_to_linear_float(tex[GCOMP]);
+ texel[BCOMP] = util_format_srgb_8unorm_to_linear_float(tex[BCOMP]);
+ texel[ACOMP] = UBYTE_TO_FLOAT(tex[ACOMP]);
}
static void
fetch_srgba_dxt1(const GLubyte *map,
GLint rowStride, GLint i, GLint j, GLfloat *texel)
{
- if (fetch_ext_rgba_dxt1) {
- GLubyte tex[4];
- fetch_ext_rgba_dxt1(rowStride, map, i, j, tex);
- texel[RCOMP] = util_format_srgb_8unorm_to_linear_float(tex[RCOMP]);
- texel[GCOMP] = util_format_srgb_8unorm_to_linear_float(tex[GCOMP]);
- texel[BCOMP] = util_format_srgb_8unorm_to_linear_float(tex[BCOMP]);
- texel[ACOMP] = UBYTE_TO_FLOAT(tex[ACOMP]);
- }
- else {
- problem("srgba_dxt1");
- }
+ GLubyte tex[4];
+ fetch_2d_texel_rgba_dxt1(rowStride, map, i, j, tex);
+ texel[RCOMP] = util_format_srgb_8unorm_to_linear_float(tex[RCOMP]);
+ texel[GCOMP] = util_format_srgb_8unorm_to_linear_float(tex[GCOMP]);
+ texel[BCOMP] = util_format_srgb_8unorm_to_linear_float(tex[BCOMP]);
+ texel[ACOMP] = UBYTE_TO_FLOAT(tex[ACOMP]);
}
static void
fetch_srgba_dxt3(const GLubyte *map,
GLint rowStride, GLint i, GLint j, GLfloat *texel)
{
- if (fetch_ext_rgba_dxt3) {
- GLubyte tex[4];
- fetch_ext_rgba_dxt3(rowStride, map, i, j, tex);
- texel[RCOMP] = util_format_srgb_8unorm_to_linear_float(tex[RCOMP]);
- texel[GCOMP] = util_format_srgb_8unorm_to_linear_float(tex[GCOMP]);
- texel[BCOMP] = util_format_srgb_8unorm_to_linear_float(tex[BCOMP]);
- texel[ACOMP] = UBYTE_TO_FLOAT(tex[ACOMP]);
- }
- else {
- problem("srgba_dxt3");
- }
+ GLubyte tex[4];
+ fetch_2d_texel_rgba_dxt3(rowStride, map, i, j, tex);
+ texel[RCOMP] = util_format_srgb_8unorm_to_linear_float(tex[RCOMP]);
+ texel[GCOMP] = util_format_srgb_8unorm_to_linear_float(tex[GCOMP]);
+ texel[BCOMP] = util_format_srgb_8unorm_to_linear_float(tex[BCOMP]);
+ texel[ACOMP] = UBYTE_TO_FLOAT(tex[ACOMP]);
}
static void
fetch_srgba_dxt5(const GLubyte *map,
GLint rowStride, GLint i, GLint j, GLfloat *texel)
{
- if (fetch_ext_rgba_dxt5) {
- GLubyte tex[4];
- fetch_ext_rgba_dxt5(rowStride, map, i, j, tex);
- texel[RCOMP] = util_format_srgb_8unorm_to_linear_float(tex[RCOMP]);
- texel[GCOMP] = util_format_srgb_8unorm_to_linear_float(tex[GCOMP]);
- texel[BCOMP] = util_format_srgb_8unorm_to_linear_float(tex[BCOMP]);
- texel[ACOMP] = UBYTE_TO_FLOAT(tex[ACOMP]);
- }
- else {
- problem("srgba_dxt5");
- }
+ GLubyte tex[4];
+ fetch_2d_texel_rgba_dxt5(rowStride, map, i, j, tex);
+ texel[RCOMP] = util_format_srgb_8unorm_to_linear_float(tex[RCOMP]);
+ texel[GCOMP] = util_format_srgb_8unorm_to_linear_float(tex[GCOMP]);
+ texel[BCOMP] = util_format_srgb_8unorm_to_linear_float(tex[BCOMP]);
+ texel[ACOMP] = UBYTE_TO_FLOAT(tex[ACOMP]);
}
diff --git a/lib/mesa/src/mesa/main/texcompress_s3tc.h b/lib/mesa/src/mesa/main/texcompress_s3tc.h
index 438b71fe3..0dbb5fc53 100644
--- a/lib/mesa/src/mesa/main/texcompress_s3tc.h
+++ b/lib/mesa/src/mesa/main/texcompress_s3tc.h
@@ -44,9 +44,6 @@ extern GLboolean
_mesa_texstore_rgba_dxt5(TEXSTORE_PARAMS);
-extern void
-_mesa_init_texture_s3tc(struct gl_context *ctx);
-
extern compressed_fetch_func
_mesa_get_dxt_fetch_func(mesa_format format);
diff --git a/lib/mesa/src/mesa/main/texcompress_s3tc_tmp.h b/lib/mesa/src/mesa/main/texcompress_s3tc_tmp.h
new file mode 100644
index 000000000..61630f247
--- /dev/null
+++ b/lib/mesa/src/mesa/main/texcompress_s3tc_tmp.h
@@ -0,0 +1,989 @@
+/*
+ * libtxc_dxtn
+ * Version: 1.0
+ *
+ * Copyright (C) 2004 Roland Scheidegger All Rights Reserved.
+ *
+ * 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
+ * BRIAN PAUL 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.
+ */
+
+#ifdef __APPLE__
+#include <OpenGL/gl.h>
+#else
+#include <GL/gl.h>
+#endif
+
+typedef GLubyte GLchan;
+#define UBYTE_TO_CHAN(b) (b)
+#define CHAN_MAX 255
+#define RCOMP 0
+#define GCOMP 1
+#define BCOMP 2
+#define ACOMP 3
+
+#define EXP5TO8R(packedcol) \
+ ((((packedcol) >> 8) & 0xf8) | (((packedcol) >> 13) & 0x7))
+
+#define EXP6TO8G(packedcol) \
+ ((((packedcol) >> 3) & 0xfc) | (((packedcol) >> 9) & 0x3))
+
+#define EXP5TO8B(packedcol) \
+ ((((packedcol) << 3) & 0xf8) | (((packedcol) >> 2) & 0x7))
+
+#define EXP4TO8(col) \
+ ((col) | ((col) << 4))
+
+/* inefficient. To be efficient, it would be necessary to decode 16 pixels at once */
+
+static void dxt135_decode_imageblock ( const GLubyte *img_block_src,
+ GLint i, GLint j, GLuint dxt_type, GLvoid *texel ) {
+ GLchan *rgba = (GLchan *) texel;
+ const GLushort color0 = img_block_src[0] | (img_block_src[1] << 8);
+ const GLushort color1 = img_block_src[2] | (img_block_src[3] << 8);
+ const GLuint bits = img_block_src[4] | (img_block_src[5] << 8) |
+ (img_block_src[6] << 16) | (img_block_src[7] << 24);
+ /* What about big/little endian? */
+ GLubyte bit_pos = 2 * (j * 4 + i) ;
+ GLubyte code = (GLubyte) ((bits >> bit_pos) & 3);
+
+ rgba[ACOMP] = CHAN_MAX;
+ switch (code) {
+ case 0:
+ rgba[RCOMP] = UBYTE_TO_CHAN( EXP5TO8R(color0) );
+ rgba[GCOMP] = UBYTE_TO_CHAN( EXP6TO8G(color0) );
+ rgba[BCOMP] = UBYTE_TO_CHAN( EXP5TO8B(color0) );
+ break;
+ case 1:
+ rgba[RCOMP] = UBYTE_TO_CHAN( EXP5TO8R(color1) );
+ rgba[GCOMP] = UBYTE_TO_CHAN( EXP6TO8G(color1) );
+ rgba[BCOMP] = UBYTE_TO_CHAN( EXP5TO8B(color1) );
+ break;
+ case 2:
+ if ((dxt_type > 1) || (color0 > color1)) {
+ rgba[RCOMP] = UBYTE_TO_CHAN( ((EXP5TO8R(color0) * 2 + EXP5TO8R(color1)) / 3) );
+ rgba[GCOMP] = UBYTE_TO_CHAN( ((EXP6TO8G(color0) * 2 + EXP6TO8G(color1)) / 3) );
+ rgba[BCOMP] = UBYTE_TO_CHAN( ((EXP5TO8B(color0) * 2 + EXP5TO8B(color1)) / 3) );
+ }
+ else {
+ rgba[RCOMP] = UBYTE_TO_CHAN( ((EXP5TO8R(color0) + EXP5TO8R(color1)) / 2) );
+ rgba[GCOMP] = UBYTE_TO_CHAN( ((EXP6TO8G(color0) + EXP6TO8G(color1)) / 2) );
+ rgba[BCOMP] = UBYTE_TO_CHAN( ((EXP5TO8B(color0) + EXP5TO8B(color1)) / 2) );
+ }
+ break;
+ case 3:
+ if ((dxt_type > 1) || (color0 > color1)) {
+ rgba[RCOMP] = UBYTE_TO_CHAN( ((EXP5TO8R(color0) + EXP5TO8R(color1) * 2) / 3) );
+ rgba[GCOMP] = UBYTE_TO_CHAN( ((EXP6TO8G(color0) + EXP6TO8G(color1) * 2) / 3) );
+ rgba[BCOMP] = UBYTE_TO_CHAN( ((EXP5TO8B(color0) + EXP5TO8B(color1) * 2) / 3) );
+ }
+ else {
+ rgba[RCOMP] = 0;
+ rgba[GCOMP] = 0;
+ rgba[BCOMP] = 0;
+ if (dxt_type == 1) rgba[ACOMP] = UBYTE_TO_CHAN(0);
+ }
+ break;
+ default:
+ /* CANNOT happen (I hope) */
+ break;
+ }
+}
+
+
+static void fetch_2d_texel_rgb_dxt1(GLint srcRowStride, const GLubyte *pixdata,
+ GLint i, GLint j, GLvoid *texel)
+{
+ /* Extract the (i,j) pixel from pixdata and return it
+ * in texel[RCOMP], texel[GCOMP], texel[BCOMP], texel[ACOMP].
+ */
+
+ const GLubyte *blksrc = (pixdata + ((srcRowStride + 3) / 4 * (j / 4) + (i / 4)) * 8);
+ dxt135_decode_imageblock(blksrc, (i&3), (j&3), 0, texel);
+}
+
+
+static void fetch_2d_texel_rgba_dxt1(GLint srcRowStride, const GLubyte *pixdata,
+ GLint i, GLint j, GLvoid *texel)
+{
+ /* Extract the (i,j) pixel from pixdata and return it
+ * in texel[RCOMP], texel[GCOMP], texel[BCOMP], texel[ACOMP].
+ */
+
+ const GLubyte *blksrc = (pixdata + ((srcRowStride + 3) / 4 * (j / 4) + (i / 4)) * 8);
+ dxt135_decode_imageblock(blksrc, (i&3), (j&3), 1, texel);
+}
+
+static void fetch_2d_texel_rgba_dxt3(GLint srcRowStride, const GLubyte *pixdata,
+ GLint i, GLint j, GLvoid *texel) {
+
+ /* Extract the (i,j) pixel from pixdata and return it
+ * in texel[RCOMP], texel[GCOMP], texel[BCOMP], texel[ACOMP].
+ */
+
+ GLchan *rgba = (GLchan *) texel;
+ const GLubyte *blksrc = (pixdata + ((srcRowStride + 3) / 4 * (j / 4) + (i / 4)) * 16);
+ const GLubyte anibble = (blksrc[((j&3) * 4 + (i&3)) / 2] >> (4 * (i&1))) & 0xf;
+ dxt135_decode_imageblock(blksrc + 8, (i&3), (j&3), 2, texel);
+ rgba[ACOMP] = UBYTE_TO_CHAN( (GLubyte)(EXP4TO8(anibble)) );
+}
+
+static void fetch_2d_texel_rgba_dxt5(GLint srcRowStride, const GLubyte *pixdata,
+ GLint i, GLint j, GLvoid *texel) {
+
+ /* Extract the (i,j) pixel from pixdata and return it
+ * in texel[RCOMP], texel[GCOMP], texel[BCOMP], texel[ACOMP].
+ */
+
+ GLchan *rgba = (GLchan *) texel;
+ const GLubyte *blksrc = (pixdata + ((srcRowStride + 3) / 4 * (j / 4) + (i / 4)) * 16);
+ const GLubyte alpha0 = blksrc[0];
+ const GLubyte alpha1 = blksrc[1];
+ const GLubyte bit_pos = ((j&3) * 4 + (i&3)) * 3;
+ const GLubyte acodelow = blksrc[2 + bit_pos / 8];
+ const GLubyte acodehigh = blksrc[3 + bit_pos / 8];
+ const GLubyte code = (acodelow >> (bit_pos & 0x7) |
+ (acodehigh << (8 - (bit_pos & 0x7)))) & 0x7;
+ dxt135_decode_imageblock(blksrc + 8, (i&3), (j&3), 2, texel);
+ if (code == 0)
+ rgba[ACOMP] = UBYTE_TO_CHAN( alpha0 );
+ else if (code == 1)
+ rgba[ACOMP] = UBYTE_TO_CHAN( alpha1 );
+ else if (alpha0 > alpha1)
+ rgba[ACOMP] = UBYTE_TO_CHAN( ((alpha0 * (8 - code) + (alpha1 * (code - 1))) / 7) );
+ else if (code < 6)
+ rgba[ACOMP] = UBYTE_TO_CHAN( ((alpha0 * (6 - code) + (alpha1 * (code - 1))) / 5) );
+ else if (code == 6)
+ rgba[ACOMP] = 0;
+ else
+ rgba[ACOMP] = CHAN_MAX;
+}
+
+
+/* weights used for error function, basically weights (unsquared 2/4/1) according to rgb->luminance conversion
+ not sure if this really reflects visual perception */
+#define REDWEIGHT 4
+#define GREENWEIGHT 16
+#define BLUEWEIGHT 1
+
+#define ALPHACUT 127
+
+static void fancybasecolorsearch( GLubyte *blkaddr, GLubyte srccolors[4][4][4], GLubyte *bestcolor[2],
+ GLint numxpixels, GLint numypixels, GLint type, GLboolean haveAlpha)
+{
+ /* use same luminance-weighted distance metric to determine encoding as for finding the base colors */
+
+ /* TODO could also try to find a better encoding for the 3-color-encoding type, this really should be done
+ if it's rgba_dxt1 and we have alpha in the block, currently even values which will be mapped to black
+ due to their alpha value will influence the result */
+ GLint i, j, colors, z;
+ GLuint pixerror, pixerrorred, pixerrorgreen, pixerrorblue, pixerrorbest;
+ GLint colordist, blockerrlin[2][3];
+ GLubyte nrcolor[2];
+ GLint pixerrorcolorbest[3];
+ GLubyte enc = 0;
+ GLubyte cv[4][4];
+ GLubyte testcolor[2][3];
+
+/* fprintf(stderr, "color begin 0 r/g/b %d/%d/%d, 1 r/g/b %d/%d/%d\n",
+ bestcolor[0][0], bestcolor[0][1], bestcolor[0][2], bestcolor[1][0], bestcolor[1][1], bestcolor[1][2]);*/
+ if (((bestcolor[0][0] & 0xf8) << 8 | (bestcolor[0][1] & 0xfc) << 3 | bestcolor[0][2] >> 3) <
+ ((bestcolor[1][0] & 0xf8) << 8 | (bestcolor[1][1] & 0xfc) << 3 | bestcolor[1][2] >> 3)) {
+ testcolor[0][0] = bestcolor[0][0];
+ testcolor[0][1] = bestcolor[0][1];
+ testcolor[0][2] = bestcolor[0][2];
+ testcolor[1][0] = bestcolor[1][0];
+ testcolor[1][1] = bestcolor[1][1];
+ testcolor[1][2] = bestcolor[1][2];
+ }
+ else {
+ testcolor[1][0] = bestcolor[0][0];
+ testcolor[1][1] = bestcolor[0][1];
+ testcolor[1][2] = bestcolor[0][2];
+ testcolor[0][0] = bestcolor[1][0];
+ testcolor[0][1] = bestcolor[1][1];
+ testcolor[0][2] = bestcolor[1][2];
+ }
+
+ for (i = 0; i < 3; i ++) {
+ cv[0][i] = testcolor[0][i];
+ cv[1][i] = testcolor[1][i];
+ cv[2][i] = (testcolor[0][i] * 2 + testcolor[1][i]) / 3;
+ cv[3][i] = (testcolor[0][i] + testcolor[1][i] * 2) / 3;
+ }
+
+ blockerrlin[0][0] = 0;
+ blockerrlin[0][1] = 0;
+ blockerrlin[0][2] = 0;
+ blockerrlin[1][0] = 0;
+ blockerrlin[1][1] = 0;
+ blockerrlin[1][2] = 0;
+
+ nrcolor[0] = 0;
+ nrcolor[1] = 0;
+
+ for (j = 0; j < numypixels; j++) {
+ for (i = 0; i < numxpixels; i++) {
+ pixerrorbest = 0xffffffff;
+ for (colors = 0; colors < 4; colors++) {
+ colordist = srccolors[j][i][0] - (cv[colors][0]);
+ pixerror = colordist * colordist * REDWEIGHT;
+ pixerrorred = colordist;
+ colordist = srccolors[j][i][1] - (cv[colors][1]);
+ pixerror += colordist * colordist * GREENWEIGHT;
+ pixerrorgreen = colordist;
+ colordist = srccolors[j][i][2] - (cv[colors][2]);
+ pixerror += colordist * colordist * BLUEWEIGHT;
+ pixerrorblue = colordist;
+ if (pixerror < pixerrorbest) {
+ enc = colors;
+ pixerrorbest = pixerror;
+ pixerrorcolorbest[0] = pixerrorred;
+ pixerrorcolorbest[1] = pixerrorgreen;
+ pixerrorcolorbest[2] = pixerrorblue;
+ }
+ }
+ if (enc == 0) {
+ for (z = 0; z < 3; z++) {
+ blockerrlin[0][z] += 3 * pixerrorcolorbest[z];
+ }
+ nrcolor[0] += 3;
+ }
+ else if (enc == 2) {
+ for (z = 0; z < 3; z++) {
+ blockerrlin[0][z] += 2 * pixerrorcolorbest[z];
+ }
+ nrcolor[0] += 2;
+ for (z = 0; z < 3; z++) {
+ blockerrlin[1][z] += 1 * pixerrorcolorbest[z];
+ }
+ nrcolor[1] += 1;
+ }
+ else if (enc == 3) {
+ for (z = 0; z < 3; z++) {
+ blockerrlin[0][z] += 1 * pixerrorcolorbest[z];
+ }
+ nrcolor[0] += 1;
+ for (z = 0; z < 3; z++) {
+ blockerrlin[1][z] += 2 * pixerrorcolorbest[z];
+ }
+ nrcolor[1] += 2;
+ }
+ else if (enc == 1) {
+ for (z = 0; z < 3; z++) {
+ blockerrlin[1][z] += 3 * pixerrorcolorbest[z];
+ }
+ nrcolor[1] += 3;
+ }
+ }
+ }
+ if (nrcolor[0] == 0) nrcolor[0] = 1;
+ if (nrcolor[1] == 0) nrcolor[1] = 1;
+ for (j = 0; j < 2; j++) {
+ for (i = 0; i < 3; i++) {
+ GLint newvalue = testcolor[j][i] + blockerrlin[j][i] / nrcolor[j];
+ if (newvalue <= 0)
+ testcolor[j][i] = 0;
+ else if (newvalue >= 255)
+ testcolor[j][i] = 255;
+ else testcolor[j][i] = newvalue;
+ }
+ }
+
+ if ((abs(testcolor[0][0] - testcolor[1][0]) < 8) &&
+ (abs(testcolor[0][1] - testcolor[1][1]) < 4) &&
+ (abs(testcolor[0][2] - testcolor[1][2]) < 8)) {
+ /* both colors are so close they might get encoded as the same 16bit values */
+ GLubyte coldiffred, coldiffgreen, coldiffblue, coldiffmax, factor, ind0, ind1;
+
+ coldiffred = abs(testcolor[0][0] - testcolor[1][0]);
+ coldiffgreen = 2 * abs(testcolor[0][1] - testcolor[1][1]);
+ coldiffblue = abs(testcolor[0][2] - testcolor[1][2]);
+ coldiffmax = coldiffred;
+ if (coldiffmax < coldiffgreen) coldiffmax = coldiffgreen;
+ if (coldiffmax < coldiffblue) coldiffmax = coldiffblue;
+ if (coldiffmax > 0) {
+ if (coldiffmax > 4) factor = 2;
+ else if (coldiffmax > 2) factor = 3;
+ else factor = 4;
+ /* Won't do much if the color value is near 255... */
+ /* argh so many ifs */
+ if (testcolor[1][1] >= testcolor[0][1]) {
+ ind1 = 1; ind0 = 0;
+ }
+ else {
+ ind1 = 0; ind0 = 1;
+ }
+ if ((testcolor[ind1][1] + factor * coldiffgreen) <= 255)
+ testcolor[ind1][1] += factor * coldiffgreen;
+ else testcolor[ind1][1] = 255;
+ if ((testcolor[ind1][0] - testcolor[ind0][1]) > 0) {
+ if ((testcolor[ind1][0] + factor * coldiffred) <= 255)
+ testcolor[ind1][0] += factor * coldiffred;
+ else testcolor[ind1][0] = 255;
+ }
+ else {
+ if ((testcolor[ind0][0] + factor * coldiffred) <= 255)
+ testcolor[ind0][0] += factor * coldiffred;
+ else testcolor[ind0][0] = 255;
+ }
+ if ((testcolor[ind1][2] - testcolor[ind0][2]) > 0) {
+ if ((testcolor[ind1][2] + factor * coldiffblue) <= 255)
+ testcolor[ind1][2] += factor * coldiffblue;
+ else testcolor[ind1][2] = 255;
+ }
+ else {
+ if ((testcolor[ind0][2] + factor * coldiffblue) <= 255)
+ testcolor[ind0][2] += factor * coldiffblue;
+ else testcolor[ind0][2] = 255;
+ }
+ }
+ }
+
+ if (((testcolor[0][0] & 0xf8) << 8 | (testcolor[0][1] & 0xfc) << 3 | testcolor[0][2] >> 3) <
+ ((testcolor[1][0] & 0xf8) << 8 | (testcolor[1][1] & 0xfc) << 3 | testcolor[1][2]) >> 3) {
+ for (i = 0; i < 3; i++) {
+ bestcolor[0][i] = testcolor[0][i];
+ bestcolor[1][i] = testcolor[1][i];
+ }
+ }
+ else {
+ for (i = 0; i < 3; i++) {
+ bestcolor[0][i] = testcolor[1][i];
+ bestcolor[1][i] = testcolor[0][i];
+ }
+ }
+
+/* fprintf(stderr, "color end 0 r/g/b %d/%d/%d, 1 r/g/b %d/%d/%d\n",
+ bestcolor[0][0], bestcolor[0][1], bestcolor[0][2], bestcolor[1][0], bestcolor[1][1], bestcolor[1][2]);*/
+}
+
+
+
+static void storedxtencodedblock( GLubyte *blkaddr, GLubyte srccolors[4][4][4], GLubyte *bestcolor[2],
+ GLint numxpixels, GLint numypixels, GLuint type, GLboolean haveAlpha)
+{
+ /* use same luminance-weighted distance metric to determine encoding as for finding the base colors */
+
+ GLint i, j, colors;
+ GLuint testerror, testerror2, pixerror, pixerrorbest;
+ GLint colordist;
+ GLushort color0, color1, tempcolor;
+ GLuint bits = 0, bits2 = 0;
+ GLubyte *colorptr;
+ GLubyte enc = 0;
+ GLubyte cv[4][4];
+
+ bestcolor[0][0] = bestcolor[0][0] & 0xf8;
+ bestcolor[0][1] = bestcolor[0][1] & 0xfc;
+ bestcolor[0][2] = bestcolor[0][2] & 0xf8;
+ bestcolor[1][0] = bestcolor[1][0] & 0xf8;
+ bestcolor[1][1] = bestcolor[1][1] & 0xfc;
+ bestcolor[1][2] = bestcolor[1][2] & 0xf8;
+
+ color0 = bestcolor[0][0] << 8 | bestcolor[0][1] << 3 | bestcolor[0][2] >> 3;
+ color1 = bestcolor[1][0] << 8 | bestcolor[1][1] << 3 | bestcolor[1][2] >> 3;
+ if (color0 < color1) {
+ tempcolor = color0; color0 = color1; color1 = tempcolor;
+ colorptr = bestcolor[0]; bestcolor[0] = bestcolor[1]; bestcolor[1] = colorptr;
+ }
+
+
+ for (i = 0; i < 3; i++) {
+ cv[0][i] = bestcolor[0][i];
+ cv[1][i] = bestcolor[1][i];
+ cv[2][i] = (bestcolor[0][i] * 2 + bestcolor[1][i]) / 3;
+ cv[3][i] = (bestcolor[0][i] + bestcolor[1][i] * 2) / 3;
+ }
+
+ testerror = 0;
+ for (j = 0; j < numypixels; j++) {
+ for (i = 0; i < numxpixels; i++) {
+ pixerrorbest = 0xffffffff;
+ for (colors = 0; colors < 4; colors++) {
+ colordist = srccolors[j][i][0] - cv[colors][0];
+ pixerror = colordist * colordist * REDWEIGHT;
+ colordist = srccolors[j][i][1] - cv[colors][1];
+ pixerror += colordist * colordist * GREENWEIGHT;
+ colordist = srccolors[j][i][2] - cv[colors][2];
+ pixerror += colordist * colordist * BLUEWEIGHT;
+ if (pixerror < pixerrorbest) {
+ pixerrorbest = pixerror;
+ enc = colors;
+ }
+ }
+ testerror += pixerrorbest;
+ bits |= enc << (2 * (j * 4 + i));
+ }
+ }
+ /* some hw might disagree but actually decoding should always use 4-color encoding
+ for non-dxt1 formats */
+ if (type == GL_COMPRESSED_RGB_S3TC_DXT1_EXT || type == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT) {
+ for (i = 0; i < 3; i++) {
+ cv[2][i] = (bestcolor[0][i] + bestcolor[1][i]) / 2;
+ /* this isn't used. Looks like the black color constant can only be used
+ with RGB_DXT1 if I read the spec correctly (note though that the radeon gpu disagrees,
+ it will decode 3 to black even with DXT3/5), and due to how the color searching works
+ it won't get used even then */
+ cv[3][i] = 0;
+ }
+ testerror2 = 0;
+ for (j = 0; j < numypixels; j++) {
+ for (i = 0; i < numxpixels; i++) {
+ pixerrorbest = 0xffffffff;
+ if ((type == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT) && (srccolors[j][i][3] <= ALPHACUT)) {
+ enc = 3;
+ pixerrorbest = 0; /* don't calculate error */
+ }
+ else {
+ /* we're calculating the same what we have done already for colors 0-1 above... */
+ for (colors = 0; colors < 3; colors++) {
+ colordist = srccolors[j][i][0] - cv[colors][0];
+ pixerror = colordist * colordist * REDWEIGHT;
+ colordist = srccolors[j][i][1] - cv[colors][1];
+ pixerror += colordist * colordist * GREENWEIGHT;
+ colordist = srccolors[j][i][2] - cv[colors][2];
+ pixerror += colordist * colordist * BLUEWEIGHT;
+ if (pixerror < pixerrorbest) {
+ pixerrorbest = pixerror;
+ /* need to exchange colors later */
+ if (colors > 1) enc = colors;
+ else enc = colors ^ 1;
+ }
+ }
+ }
+ testerror2 += pixerrorbest;
+ bits2 |= enc << (2 * (j * 4 + i));
+ }
+ }
+ } else {
+ testerror2 = 0xffffffff;
+ }
+
+ /* finally we're finished, write back colors and bits */
+ if ((testerror > testerror2) || (haveAlpha)) {
+ *blkaddr++ = color1 & 0xff;
+ *blkaddr++ = color1 >> 8;
+ *blkaddr++ = color0 & 0xff;
+ *blkaddr++ = color0 >> 8;
+ *blkaddr++ = bits2 & 0xff;
+ *blkaddr++ = ( bits2 >> 8) & 0xff;
+ *blkaddr++ = ( bits2 >> 16) & 0xff;
+ *blkaddr = bits2 >> 24;
+ }
+ else {
+ *blkaddr++ = color0 & 0xff;
+ *blkaddr++ = color0 >> 8;
+ *blkaddr++ = color1 & 0xff;
+ *blkaddr++ = color1 >> 8;
+ *blkaddr++ = bits & 0xff;
+ *blkaddr++ = ( bits >> 8) & 0xff;
+ *blkaddr++ = ( bits >> 16) & 0xff;
+ *blkaddr = bits >> 24;
+ }
+}
+
+static void encodedxtcolorblockfaster( GLubyte *blkaddr, GLubyte srccolors[4][4][4],
+ GLint numxpixels, GLint numypixels, GLuint type )
+{
+/* simplistic approach. We need two base colors, simply use the "highest" and the "lowest" color
+ present in the picture as base colors */
+
+ /* define lowest and highest color as shortest and longest vector to 0/0/0, though the
+ vectors are weighted similar to their importance in rgb-luminance conversion
+ doesn't work too well though...
+ This seems to be a rather difficult problem */
+
+ GLubyte *bestcolor[2];
+ GLubyte basecolors[2][3];
+ GLubyte i, j;
+ GLuint lowcv, highcv, testcv;
+ GLboolean haveAlpha = GL_FALSE;
+
+ lowcv = highcv = srccolors[0][0][0] * srccolors[0][0][0] * REDWEIGHT +
+ srccolors[0][0][1] * srccolors[0][0][1] * GREENWEIGHT +
+ srccolors[0][0][2] * srccolors[0][0][2] * BLUEWEIGHT;
+ bestcolor[0] = bestcolor[1] = srccolors[0][0];
+ for (j = 0; j < numypixels; j++) {
+ for (i = 0; i < numxpixels; i++) {
+ /* don't use this as a base color if the pixel will get black/transparent anyway */
+ if ((type != GL_COMPRESSED_RGBA_S3TC_DXT1_EXT) || (srccolors[j][i][3] > ALPHACUT)) {
+ testcv = srccolors[j][i][0] * srccolors[j][i][0] * REDWEIGHT +
+ srccolors[j][i][1] * srccolors[j][i][1] * GREENWEIGHT +
+ srccolors[j][i][2] * srccolors[j][i][2] * BLUEWEIGHT;
+ if (testcv > highcv) {
+ highcv = testcv;
+ bestcolor[1] = srccolors[j][i];
+ }
+ else if (testcv < lowcv) {
+ lowcv = testcv;
+ bestcolor[0] = srccolors[j][i];
+ }
+ }
+ else haveAlpha = GL_TRUE;
+ }
+ }
+ /* make sure the original color values won't get touched... */
+ for (j = 0; j < 2; j++) {
+ for (i = 0; i < 3; i++) {
+ basecolors[j][i] = bestcolor[j][i];
+ }
+ }
+ bestcolor[0] = basecolors[0];
+ bestcolor[1] = basecolors[1];
+
+ /* try to find better base colors */
+ fancybasecolorsearch(blkaddr, srccolors, bestcolor, numxpixels, numypixels, type, haveAlpha);
+ /* find the best encoding for these colors, and store the result */
+ storedxtencodedblock(blkaddr, srccolors, bestcolor, numxpixels, numypixels, type, haveAlpha);
+}
+
+static void writedxt5encodedalphablock( GLubyte *blkaddr, GLubyte alphabase1, GLubyte alphabase2,
+ GLubyte alphaenc[16])
+{
+ *blkaddr++ = alphabase1;
+ *blkaddr++ = alphabase2;
+ *blkaddr++ = alphaenc[0] | (alphaenc[1] << 3) | ((alphaenc[2] & 3) << 6);
+ *blkaddr++ = (alphaenc[2] >> 2) | (alphaenc[3] << 1) | (alphaenc[4] << 4) | ((alphaenc[5] & 1) << 7);
+ *blkaddr++ = (alphaenc[5] >> 1) | (alphaenc[6] << 2) | (alphaenc[7] << 5);
+ *blkaddr++ = alphaenc[8] | (alphaenc[9] << 3) | ((alphaenc[10] & 3) << 6);
+ *blkaddr++ = (alphaenc[10] >> 2) | (alphaenc[11] << 1) | (alphaenc[12] << 4) | ((alphaenc[13] & 1) << 7);
+ *blkaddr++ = (alphaenc[13] >> 1) | (alphaenc[14] << 2) | (alphaenc[15] << 5);
+}
+
+static void encodedxt5alpha(GLubyte *blkaddr, GLubyte srccolors[4][4][4],
+ GLint numxpixels, GLint numypixels)
+{
+ GLubyte alphabase[2], alphause[2];
+ GLshort alphatest[2];
+ GLuint alphablockerror1, alphablockerror2, alphablockerror3;
+ GLubyte i, j, aindex, acutValues[7];
+ GLubyte alphaenc1[16], alphaenc2[16], alphaenc3[16];
+ GLboolean alphaabsmin = GL_FALSE;
+ GLboolean alphaabsmax = GL_FALSE;
+ GLshort alphadist;
+
+ /* find lowest and highest alpha value in block, alphabase[0] lowest, alphabase[1] highest */
+ alphabase[0] = 0xff; alphabase[1] = 0x0;
+ for (j = 0; j < numypixels; j++) {
+ for (i = 0; i < numxpixels; i++) {
+ if (srccolors[j][i][3] == 0)
+ alphaabsmin = GL_TRUE;
+ else if (srccolors[j][i][3] == 255)
+ alphaabsmax = GL_TRUE;
+ else {
+ if (srccolors[j][i][3] > alphabase[1])
+ alphabase[1] = srccolors[j][i][3];
+ if (srccolors[j][i][3] < alphabase[0])
+ alphabase[0] = srccolors[j][i][3];
+ }
+ }
+ }
+
+
+ if ((alphabase[0] > alphabase[1]) && !(alphaabsmin && alphaabsmax)) { /* one color, either max or min */
+ /* shortcut here since it is a very common case (and also avoids later problems) */
+ /* || (alphabase[0] == alphabase[1] && !alphaabsmin && !alphaabsmax) */
+ /* could also thest for alpha0 == alpha1 (and not min/max), but probably not common, so don't bother */
+
+ *blkaddr++ = srccolors[0][0][3];
+ blkaddr++;
+ *blkaddr++ = 0;
+ *blkaddr++ = 0;
+ *blkaddr++ = 0;
+ *blkaddr++ = 0;
+ *blkaddr++ = 0;
+ *blkaddr++ = 0;
+/* fprintf(stderr, "enc0 used\n");*/
+ return;
+ }
+
+ /* find best encoding for alpha0 > alpha1 */
+ /* it's possible this encoding is better even if both alphaabsmin and alphaabsmax are true */
+ alphablockerror1 = 0x0;
+ alphablockerror2 = 0xffffffff;
+ alphablockerror3 = 0xffffffff;
+ if (alphaabsmin) alphause[0] = 0;
+ else alphause[0] = alphabase[0];
+ if (alphaabsmax) alphause[1] = 255;
+ else alphause[1] = alphabase[1];
+ /* calculate the 7 cut values, just the middle between 2 of the computed alpha values */
+ for (aindex = 0; aindex < 7; aindex++) {
+ /* don't forget here is always rounded down */
+ acutValues[aindex] = (alphause[0] * (2*aindex + 1) + alphause[1] * (14 - (2*aindex + 1))) / 14;
+ }
+
+ for (j = 0; j < numypixels; j++) {
+ for (i = 0; i < numxpixels; i++) {
+ /* maybe it's overkill to have the most complicated calculation just for the error
+ calculation which we only need to figure out if encoding1 or encoding2 is better... */
+ if (srccolors[j][i][3] > acutValues[0]) {
+ alphaenc1[4*j + i] = 0;
+ alphadist = srccolors[j][i][3] - alphause[1];
+ }
+ else if (srccolors[j][i][3] > acutValues[1]) {
+ alphaenc1[4*j + i] = 2;
+ alphadist = srccolors[j][i][3] - (alphause[1] * 6 + alphause[0] * 1) / 7;
+ }
+ else if (srccolors[j][i][3] > acutValues[2]) {
+ alphaenc1[4*j + i] = 3;
+ alphadist = srccolors[j][i][3] - (alphause[1] * 5 + alphause[0] * 2) / 7;
+ }
+ else if (srccolors[j][i][3] > acutValues[3]) {
+ alphaenc1[4*j + i] = 4;
+ alphadist = srccolors[j][i][3] - (alphause[1] * 4 + alphause[0] * 3) / 7;
+ }
+ else if (srccolors[j][i][3] > acutValues[4]) {
+ alphaenc1[4*j + i] = 5;
+ alphadist = srccolors[j][i][3] - (alphause[1] * 3 + alphause[0] * 4) / 7;
+ }
+ else if (srccolors[j][i][3] > acutValues[5]) {
+ alphaenc1[4*j + i] = 6;
+ alphadist = srccolors[j][i][3] - (alphause[1] * 2 + alphause[0] * 5) / 7;
+ }
+ else if (srccolors[j][i][3] > acutValues[6]) {
+ alphaenc1[4*j + i] = 7;
+ alphadist = srccolors[j][i][3] - (alphause[1] * 1 + alphause[0] * 6) / 7;
+ }
+ else {
+ alphaenc1[4*j + i] = 1;
+ alphadist = srccolors[j][i][3] - alphause[0];
+ }
+ alphablockerror1 += alphadist * alphadist;
+ }
+ }
+/* for (i = 0; i < 16; i++) {
+ fprintf(stderr, "%d ", alphaenc1[i]);
+ }
+ fprintf(stderr, "cutVals ");
+ for (i = 0; i < 8; i++) {
+ fprintf(stderr, "%d ", acutValues[i]);
+ }
+ fprintf(stderr, "srcVals ");
+ for (j = 0; j < numypixels; j++)
+ for (i = 0; i < numxpixels; i++) {
+ fprintf(stderr, "%d ", srccolors[j][i][3]);
+ }
+
+ fprintf(stderr, "\n");
+ }*/
+ /* it's not very likely this encoding is better if both alphaabsmin and alphaabsmax
+ are false but try it anyway */
+ if (alphablockerror1 >= 32) {
+
+ /* don't bother if encoding is already very good, this condition should also imply
+ we have valid alphabase colors which we absolutely need (alphabase[0] <= alphabase[1]) */
+ alphablockerror2 = 0;
+ for (aindex = 0; aindex < 5; aindex++) {
+ /* don't forget here is always rounded down */
+ acutValues[aindex] = (alphabase[0] * (10 - (2*aindex + 1)) + alphabase[1] * (2*aindex + 1)) / 10;
+ }
+ for (j = 0; j < numypixels; j++) {
+ for (i = 0; i < numxpixels; i++) {
+ /* maybe it's overkill to have the most complicated calculation just for the error
+ calculation which we only need to figure out if encoding1 or encoding2 is better... */
+ if (srccolors[j][i][3] == 0) {
+ alphaenc2[4*j + i] = 6;
+ alphadist = 0;
+ }
+ else if (srccolors[j][i][3] == 255) {
+ alphaenc2[4*j + i] = 7;
+ alphadist = 0;
+ }
+ else if (srccolors[j][i][3] <= acutValues[0]) {
+ alphaenc2[4*j + i] = 0;
+ alphadist = srccolors[j][i][3] - alphabase[0];
+ }
+ else if (srccolors[j][i][3] <= acutValues[1]) {
+ alphaenc2[4*j + i] = 2;
+ alphadist = srccolors[j][i][3] - (alphabase[0] * 4 + alphabase[1] * 1) / 5;
+ }
+ else if (srccolors[j][i][3] <= acutValues[2]) {
+ alphaenc2[4*j + i] = 3;
+ alphadist = srccolors[j][i][3] - (alphabase[0] * 3 + alphabase[1] * 2) / 5;
+ }
+ else if (srccolors[j][i][3] <= acutValues[3]) {
+ alphaenc2[4*j + i] = 4;
+ alphadist = srccolors[j][i][3] - (alphabase[0] * 2 + alphabase[1] * 3) / 5;
+ }
+ else if (srccolors[j][i][3] <= acutValues[4]) {
+ alphaenc2[4*j + i] = 5;
+ alphadist = srccolors[j][i][3] - (alphabase[0] * 1 + alphabase[1] * 4) / 5;
+ }
+ else {
+ alphaenc2[4*j + i] = 1;
+ alphadist = srccolors[j][i][3] - alphabase[1];
+ }
+ alphablockerror2 += alphadist * alphadist;
+ }
+ }
+
+
+ /* skip this if the error is already very small
+ this encoding is MUCH better on average than #2 though, but expensive! */
+ if ((alphablockerror2 > 96) && (alphablockerror1 > 96)) {
+ GLshort blockerrlin1 = 0;
+ GLshort blockerrlin2 = 0;
+ GLubyte nralphainrangelow = 0;
+ GLubyte nralphainrangehigh = 0;
+ alphatest[0] = 0xff;
+ alphatest[1] = 0x0;
+ /* if we have large range it's likely there are values close to 0/255, try to map them to 0/255 */
+ for (j = 0; j < numypixels; j++) {
+ for (i = 0; i < numxpixels; i++) {
+ if ((srccolors[j][i][3] > alphatest[1]) && (srccolors[j][i][3] < (255 -(alphabase[1] - alphabase[0]) / 28)))
+ alphatest[1] = srccolors[j][i][3];
+ if ((srccolors[j][i][3] < alphatest[0]) && (srccolors[j][i][3] > (alphabase[1] - alphabase[0]) / 28))
+ alphatest[0] = srccolors[j][i][3];
+ }
+ }
+ /* shouldn't happen too often, don't really care about those degenerated cases */
+ if (alphatest[1] <= alphatest[0]) {
+ alphatest[0] = 1;
+ alphatest[1] = 254;
+/* fprintf(stderr, "only 1 or 0 colors for encoding!\n");*/
+ }
+ for (aindex = 0; aindex < 5; aindex++) {
+ /* don't forget here is always rounded down */
+ acutValues[aindex] = (alphatest[0] * (10 - (2*aindex + 1)) + alphatest[1] * (2*aindex + 1)) / 10;
+ }
+
+ /* find the "average" difference between the alpha values and the next encoded value.
+ This is then used to calculate new base values.
+ Should there be some weighting, i.e. those values closer to alphatest[x] have more weight,
+ since they will see more improvement, and also because the values in the middle are somewhat
+ likely to get no improvement at all (because the base values might move in different directions)?
+ OTOH it would mean the values in the middle are even less likely to get an improvement
+ */
+ for (j = 0; j < numypixels; j++) {
+ for (i = 0; i < numxpixels; i++) {
+ if (srccolors[j][i][3] <= alphatest[0] / 2) {
+ }
+ else if (srccolors[j][i][3] > ((255 + alphatest[1]) / 2)) {
+ }
+ else if (srccolors[j][i][3] <= acutValues[0]) {
+ blockerrlin1 += (srccolors[j][i][3] - alphatest[0]);
+ nralphainrangelow += 1;
+ }
+ else if (srccolors[j][i][3] <= acutValues[1]) {
+ blockerrlin1 += (srccolors[j][i][3] - (alphatest[0] * 4 + alphatest[1] * 1) / 5);
+ blockerrlin2 += (srccolors[j][i][3] - (alphatest[0] * 4 + alphatest[1] * 1) / 5);
+ nralphainrangelow += 1;
+ nralphainrangehigh += 1;
+ }
+ else if (srccolors[j][i][3] <= acutValues[2]) {
+ blockerrlin1 += (srccolors[j][i][3] - (alphatest[0] * 3 + alphatest[1] * 2) / 5);
+ blockerrlin2 += (srccolors[j][i][3] - (alphatest[0] * 3 + alphatest[1] * 2) / 5);
+ nralphainrangelow += 1;
+ nralphainrangehigh += 1;
+ }
+ else if (srccolors[j][i][3] <= acutValues[3]) {
+ blockerrlin1 += (srccolors[j][i][3] - (alphatest[0] * 2 + alphatest[1] * 3) / 5);
+ blockerrlin2 += (srccolors[j][i][3] - (alphatest[0] * 2 + alphatest[1] * 3) / 5);
+ nralphainrangelow += 1;
+ nralphainrangehigh += 1;
+ }
+ else if (srccolors[j][i][3] <= acutValues[4]) {
+ blockerrlin1 += (srccolors[j][i][3] - (alphatest[0] * 1 + alphatest[1] * 4) / 5);
+ blockerrlin2 += (srccolors[j][i][3] - (alphatest[0] * 1 + alphatest[1] * 4) / 5);
+ nralphainrangelow += 1;
+ nralphainrangehigh += 1;
+ }
+ else {
+ blockerrlin2 += (srccolors[j][i][3] - alphatest[1]);
+ nralphainrangehigh += 1;
+ }
+ }
+ }
+ /* shouldn't happen often, needed to avoid div by zero */
+ if (nralphainrangelow == 0) nralphainrangelow = 1;
+ if (nralphainrangehigh == 0) nralphainrangehigh = 1;
+ alphatest[0] = alphatest[0] + (blockerrlin1 / nralphainrangelow);
+/* fprintf(stderr, "block err lin low %d, nr %d\n", blockerrlin1, nralphainrangelow);
+ fprintf(stderr, "block err lin high %d, nr %d\n", blockerrlin2, nralphainrangehigh);*/
+ /* again shouldn't really happen often... */
+ if (alphatest[0] < 0) {
+ alphatest[0] = 0;
+/* fprintf(stderr, "adj alpha base val to 0\n");*/
+ }
+ alphatest[1] = alphatest[1] + (blockerrlin2 / nralphainrangehigh);
+ if (alphatest[1] > 255) {
+ alphatest[1] = 255;
+/* fprintf(stderr, "adj alpha base val to 255\n");*/
+ }
+
+ alphablockerror3 = 0;
+ for (aindex = 0; aindex < 5; aindex++) {
+ /* don't forget here is always rounded down */
+ acutValues[aindex] = (alphatest[0] * (10 - (2*aindex + 1)) + alphatest[1] * (2*aindex + 1)) / 10;
+ }
+ for (j = 0; j < numypixels; j++) {
+ for (i = 0; i < numxpixels; i++) {
+ /* maybe it's overkill to have the most complicated calculation just for the error
+ calculation which we only need to figure out if encoding1 or encoding2 is better... */
+ if (srccolors[j][i][3] <= alphatest[0] / 2) {
+ alphaenc3[4*j + i] = 6;
+ alphadist = srccolors[j][i][3];
+ }
+ else if (srccolors[j][i][3] > ((255 + alphatest[1]) / 2)) {
+ alphaenc3[4*j + i] = 7;
+ alphadist = 255 - srccolors[j][i][3];
+ }
+ else if (srccolors[j][i][3] <= acutValues[0]) {
+ alphaenc3[4*j + i] = 0;
+ alphadist = srccolors[j][i][3] - alphatest[0];
+ }
+ else if (srccolors[j][i][3] <= acutValues[1]) {
+ alphaenc3[4*j + i] = 2;
+ alphadist = srccolors[j][i][3] - (alphatest[0] * 4 + alphatest[1] * 1) / 5;
+ }
+ else if (srccolors[j][i][3] <= acutValues[2]) {
+ alphaenc3[4*j + i] = 3;
+ alphadist = srccolors[j][i][3] - (alphatest[0] * 3 + alphatest[1] * 2) / 5;
+ }
+ else if (srccolors[j][i][3] <= acutValues[3]) {
+ alphaenc3[4*j + i] = 4;
+ alphadist = srccolors[j][i][3] - (alphatest[0] * 2 + alphatest[1] * 3) / 5;
+ }
+ else if (srccolors[j][i][3] <= acutValues[4]) {
+ alphaenc3[4*j + i] = 5;
+ alphadist = srccolors[j][i][3] - (alphatest[0] * 1 + alphatest[1] * 4) / 5;
+ }
+ else {
+ alphaenc3[4*j + i] = 1;
+ alphadist = srccolors[j][i][3] - alphatest[1];
+ }
+ alphablockerror3 += alphadist * alphadist;
+ }
+ }
+ }
+ }
+ /* write the alpha values and encoding back. */
+ if ((alphablockerror1 <= alphablockerror2) && (alphablockerror1 <= alphablockerror3)) {
+/* if (alphablockerror1 > 96) fprintf(stderr, "enc1 used, error %d\n", alphablockerror1);*/
+ writedxt5encodedalphablock( blkaddr, alphause[1], alphause[0], alphaenc1 );
+ }
+ else if (alphablockerror2 <= alphablockerror3) {
+/* if (alphablockerror2 > 96) fprintf(stderr, "enc2 used, error %d\n", alphablockerror2);*/
+ writedxt5encodedalphablock( blkaddr, alphabase[0], alphabase[1], alphaenc2 );
+ }
+ else {
+/* fprintf(stderr, "enc3 used, error %d\n", alphablockerror3);*/
+ writedxt5encodedalphablock( blkaddr, (GLubyte)alphatest[0], (GLubyte)alphatest[1], alphaenc3 );
+ }
+}
+
+static void extractsrccolors( GLubyte srcpixels[4][4][4], const GLchan *srcaddr,
+ GLint srcRowStride, GLint numxpixels, GLint numypixels, GLint comps)
+{
+ GLubyte i, j, c;
+ const GLchan *curaddr;
+ for (j = 0; j < numypixels; j++) {
+ curaddr = srcaddr + j * srcRowStride * comps;
+ for (i = 0; i < numxpixels; i++) {
+ for (c = 0; c < comps; c++) {
+ srcpixels[j][i][c] = *curaddr++ / (CHAN_MAX / 255);
+ }
+ }
+ }
+}
+
+
+static void tx_compress_dxtn(GLint srccomps, GLint width, GLint height, const GLubyte *srcPixData,
+ GLenum destFormat, GLubyte *dest, GLint dstRowStride)
+{
+ GLubyte *blkaddr = dest;
+ GLubyte srcpixels[4][4][4];
+ const GLchan *srcaddr = srcPixData;
+ GLint numxpixels, numypixels;
+ GLint i, j;
+ GLint dstRowDiff;
+
+ switch (destFormat) {
+ case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
+ case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
+ /* hmm we used to get called without dstRowStride... */
+ dstRowDiff = dstRowStride >= (width * 2) ? dstRowStride - (((width + 3) & ~3) * 2) : 0;
+/* fprintf(stderr, "dxt1 tex width %d tex height %d dstRowStride %d\n",
+ width, height, dstRowStride); */
+ for (j = 0; j < height; j += 4) {
+ if (height > j + 3) numypixels = 4;
+ else numypixels = height - j;
+ srcaddr = srcPixData + j * width * srccomps;
+ for (i = 0; i < width; i += 4) {
+ if (width > i + 3) numxpixels = 4;
+ else numxpixels = width - i;
+ extractsrccolors(srcpixels, srcaddr, width, numxpixels, numypixels, srccomps);
+ encodedxtcolorblockfaster(blkaddr, srcpixels, numxpixels, numypixels, destFormat);
+ srcaddr += srccomps * numxpixels;
+ blkaddr += 8;
+ }
+ blkaddr += dstRowDiff;
+ }
+ break;
+ case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
+ dstRowDiff = dstRowStride >= (width * 4) ? dstRowStride - (((width + 3) & ~3) * 4) : 0;
+/* fprintf(stderr, "dxt3 tex width %d tex height %d dstRowStride %d\n",
+ width, height, dstRowStride); */
+ for (j = 0; j < height; j += 4) {
+ if (height > j + 3) numypixels = 4;
+ else numypixels = height - j;
+ srcaddr = srcPixData + j * width * srccomps;
+ for (i = 0; i < width; i += 4) {
+ if (width > i + 3) numxpixels = 4;
+ else numxpixels = width - i;
+ extractsrccolors(srcpixels, srcaddr, width, numxpixels, numypixels, srccomps);
+ *blkaddr++ = (srcpixels[0][0][3] >> 4) | (srcpixels[0][1][3] & 0xf0);
+ *blkaddr++ = (srcpixels[0][2][3] >> 4) | (srcpixels[0][3][3] & 0xf0);
+ *blkaddr++ = (srcpixels[1][0][3] >> 4) | (srcpixels[1][1][3] & 0xf0);
+ *blkaddr++ = (srcpixels[1][2][3] >> 4) | (srcpixels[1][3][3] & 0xf0);
+ *blkaddr++ = (srcpixels[2][0][3] >> 4) | (srcpixels[2][1][3] & 0xf0);
+ *blkaddr++ = (srcpixels[2][2][3] >> 4) | (srcpixels[2][3][3] & 0xf0);
+ *blkaddr++ = (srcpixels[3][0][3] >> 4) | (srcpixels[3][1][3] & 0xf0);
+ *blkaddr++ = (srcpixels[3][2][3] >> 4) | (srcpixels[3][3][3] & 0xf0);
+ encodedxtcolorblockfaster(blkaddr, srcpixels, numxpixels, numypixels, destFormat);
+ srcaddr += srccomps * numxpixels;
+ blkaddr += 8;
+ }
+ blkaddr += dstRowDiff;
+ }
+ break;
+ case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
+ dstRowDiff = dstRowStride >= (width * 4) ? dstRowStride - (((width + 3) & ~3) * 4) : 0;
+/* fprintf(stderr, "dxt5 tex width %d tex height %d dstRowStride %d\n",
+ width, height, dstRowStride); */
+ for (j = 0; j < height; j += 4) {
+ if (height > j + 3) numypixels = 4;
+ else numypixels = height - j;
+ srcaddr = srcPixData + j * width * srccomps;
+ for (i = 0; i < width; i += 4) {
+ if (width > i + 3) numxpixels = 4;
+ else numxpixels = width - i;
+ extractsrccolors(srcpixels, srcaddr, width, numxpixels, numypixels, srccomps);
+ encodedxt5alpha(blkaddr, srcpixels, numxpixels, numypixels);
+ encodedxtcolorblockfaster(blkaddr + 8, srcpixels, numxpixels, numypixels, destFormat);
+ srcaddr += srccomps * numxpixels;
+ blkaddr += 16;
+ }
+ blkaddr += dstRowDiff;
+ }
+ break;
+ default:
+ assert(false);
+ return;
+ }
+}
diff --git a/lib/mesa/src/mesa/main/texformat.c b/lib/mesa/src/mesa/main/texformat.c
index baa3988f0..822f80f89 100644
--- a/lib/mesa/src/mesa/main/texformat.c
+++ b/lib/mesa/src/mesa/main/texformat.c
@@ -88,6 +88,7 @@ _mesa_choose_tex_format(struct gl_context *ctx, GLenum target,
break;
case GL_RGB5_A1:
RETURN_IF_SUPPORTED(MESA_FORMAT_B5G5R5A1_UNORM);
+ RETURN_IF_SUPPORTED(MESA_FORMAT_A1B5G5R5_UNORM);
break;
case GL_RGBA2:
RETURN_IF_SUPPORTED(MESA_FORMAT_A4R4G4B4_UNORM); /* just to test another format*/
@@ -117,6 +118,9 @@ _mesa_choose_tex_format(struct gl_context *ctx, GLenum target,
if (type == GL_UNSIGNED_INT_2_10_10_10_REV) {
RETURN_IF_SUPPORTED(MESA_FORMAT_B10G10R10A2_UNORM);
}
+ if (type == GL_UNSIGNED_SHORT_5_6_5) {
+ RETURN_IF_SUPPORTED(MESA_FORMAT_B5G6R5_UNORM);
+ }
/* fallthrough */
case GL_RGB8:
RETURN_IF_SUPPORTED(MESA_FORMAT_RGB_UNORM8);
@@ -249,9 +253,7 @@ _mesa_choose_tex_format(struct gl_context *ctx, GLenum target,
* 1D ARRAY textures in S3TC format.
*/
if (target != GL_TEXTURE_1D && target != GL_TEXTURE_1D_ARRAY) {
- if (ctx->Mesa_DXTn)
- RETURN_IF_SUPPORTED(MESA_FORMAT_RGB_DXT1);
- RETURN_IF_SUPPORTED(MESA_FORMAT_RGB_FXT1);
+ RETURN_IF_SUPPORTED(MESA_FORMAT_RGB_DXT1);
}
RETURN_IF_SUPPORTED(MESA_FORMAT_BGR_UNORM8);
RETURN_IF_SUPPORTED(MESA_FORMAT_B8G8R8X8_UNORM);
@@ -260,9 +262,7 @@ _mesa_choose_tex_format(struct gl_context *ctx, GLenum target,
case GL_COMPRESSED_RGBA_ARB:
/* We don't use texture compression for 1D and 1D array textures. */
if (target != GL_TEXTURE_1D && target != GL_TEXTURE_1D_ARRAY) {
- if (ctx->Mesa_DXTn)
- RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_DXT3); /* Not rgba_dxt1, see spec */
- RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_FXT1);
+ RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_DXT3); /* Not rgba_dxt1, see spec */
}
RETURN_IF_SUPPORTED(MESA_FORMAT_A8B8G8R8_UNORM);
RETURN_IF_SUPPORTED(MESA_FORMAT_B8G8R8A8_UNORM);
@@ -502,15 +502,13 @@ _mesa_choose_tex_format(struct gl_context *ctx, GLenum target,
RETURN_IF_SUPPORTED(MESA_FORMAT_A8R8G8B8_SRGB);
break;
case GL_COMPRESSED_SRGB_EXT:
- if (ctx->Mesa_DXTn)
- RETURN_IF_SUPPORTED(MESA_FORMAT_SRGB_DXT1);
+ RETURN_IF_SUPPORTED(MESA_FORMAT_SRGB_DXT1);
RETURN_IF_SUPPORTED(MESA_FORMAT_BGR_SRGB8);
RETURN_IF_SUPPORTED(MESA_FORMAT_B8G8R8A8_SRGB);
RETURN_IF_SUPPORTED(MESA_FORMAT_A8R8G8B8_SRGB);
break;
case GL_COMPRESSED_SRGB_ALPHA_EXT:
- if (ctx->Mesa_DXTn)
- RETURN_IF_SUPPORTED(MESA_FORMAT_SRGBA_DXT3); /* Not srgba_dxt1, see spec */
+ RETURN_IF_SUPPORTED(MESA_FORMAT_SRGBA_DXT3); /* Not srgba_dxt1, see spec */
RETURN_IF_SUPPORTED(MESA_FORMAT_A8B8G8R8_SRGB);
RETURN_IF_SUPPORTED(MESA_FORMAT_B8G8R8A8_SRGB);
RETURN_IF_SUPPORTED(MESA_FORMAT_A8R8G8B8_SRGB);
diff --git a/lib/mesa/src/mesa/main/textureview.h b/lib/mesa/src/mesa/main/textureview.h
index 39b415d87..e2f18aed0 100644
--- a/lib/mesa/src/mesa/main/textureview.h
+++ b/lib/mesa/src/mesa/main/textureview.h
@@ -42,6 +42,12 @@ GLenum
_mesa_texture_view_lookup_view_class(const struct gl_context *ctx,
GLenum internalformat);
+void GLAPIENTRY
+_mesa_TextureView_no_error(GLuint texture, GLenum target, GLuint origtexture,
+ GLenum internalformat,
+ GLuint minlevel, GLuint numlevels,
+ GLuint minlayer, GLuint numlayers);
+
extern void GLAPIENTRY
_mesa_TextureView(GLuint texture, GLenum target, GLuint origtexture,
GLenum internalformat,
diff --git a/lib/mesa/src/mesa/main/version.h b/lib/mesa/src/mesa/main/version.h
index ee7cb7501..adfec6f82 100644
--- a/lib/mesa/src/mesa/main/version.h
+++ b/lib/mesa/src/mesa/main/version.h
@@ -47,4 +47,15 @@ _mesa_override_gl_version(struct gl_context *ctx);
extern void
_mesa_override_glsl_version(struct gl_constants *consts);
+extern void
+_mesa_get_driver_uuid(struct gl_context *ctx, GLint *uuid);
+
+extern void
+_mesa_get_device_uuid(struct gl_context *ctx, GLint *uuid);
+
+extern int
+_mesa_get_shading_language_version(const struct gl_context *ctx,
+ int index,
+ char **versionOut);
+
#endif /* VERSION_H */
diff --git a/lib/mesa/src/mesa/state_tracker/st_cb_bufferobjects.h b/lib/mesa/src/mesa/state_tracker/st_cb_bufferobjects.h
index 54e6a21ce..b9f91b074 100644
--- a/lib/mesa/src/mesa/state_tracker/st_cb_bufferobjects.h
+++ b/lib/mesa/src/mesa/state_tracker/st_cb_bufferobjects.h
@@ -57,12 +57,6 @@ st_buffer_object(struct gl_buffer_object *obj)
extern void
-st_bufferobj_validate_usage(struct st_context *st,
- struct st_buffer_object *obj,
- unsigned usage);
-
-
-extern void
st_init_bufferobject_functions(struct pipe_screen *screen,
struct dd_function_table *functions);
diff --git a/lib/mesa/src/mesa/state_tracker/st_cb_drawpixels_shader.c b/lib/mesa/src/mesa/state_tracker/st_cb_drawpixels_shader.c
index 35a9da064..83dcfeab4 100644
--- a/lib/mesa/src/mesa/state_tracker/st_cb_drawpixels_shader.c
+++ b/lib/mesa/src/mesa/state_tracker/st_cb_drawpixels_shader.c
@@ -204,6 +204,8 @@ transform_inst:
ctx->info.input_semantic_index[reg] == 0) {
src->Register.File = TGSI_FILE_CONSTANT;
src->Register.Index = ctx->texcoord_const;
+ src->Register.Dimension = 1;
+ src->Dimension.Index = 0;
}
}
diff --git a/lib/mesa/src/mesa/state_tracker/st_cb_flush.c b/lib/mesa/src/mesa/state_tracker/st_cb_flush.c
index 6442fc922..d9ec0a846 100644
--- a/lib/mesa/src/mesa/state_tracker/st_cb_flush.c
+++ b/lib/mesa/src/mesa/state_tracker/st_cb_flush.c
@@ -46,35 +46,6 @@
#include "util/u_gen_mipmap.h"
-/** Check if we have a front color buffer and if it's been drawn to. */
-static inline GLboolean
-is_front_buffer_dirty(struct st_context *st)
-{
- struct gl_framebuffer *fb = st->ctx->DrawBuffer;
- struct st_renderbuffer *strb
- = st_renderbuffer(fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer);
- return strb && strb->defined;
-}
-
-
-/**
- * Tell the screen to display the front color buffer on-screen.
- */
-static void
-display_front_buffer(struct st_context *st)
-{
- struct gl_framebuffer *fb = st->ctx->DrawBuffer;
- struct st_renderbuffer *strb
- = st_renderbuffer(fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer);
-
- if (strb) {
- /* Hook for copying "fake" frontbuffer if necessary:
- */
- st_manager_flush_frontbuffer(st);
- }
-}
-
-
void st_flush(struct st_context *st,
struct pipe_fence_handle **fence,
unsigned flags)
@@ -102,6 +73,8 @@ void st_finish( struct st_context *st )
PIPE_TIMEOUT_INFINITE);
st->pipe->screen->fence_reference(st->pipe->screen, &fence, NULL);
}
+
+ st_manager_flush_swapbuffers();
}
@@ -120,9 +93,7 @@ static void st_glFlush(struct gl_context *ctx)
*/
st_flush(st, NULL, 0);
- if (is_front_buffer_dirty(st)) {
- display_front_buffer(st);
- }
+ st_manager_flush_frontbuffer(st);
}
@@ -135,9 +106,7 @@ static void st_glFinish(struct gl_context *ctx)
st_finish(st);
- if (is_front_buffer_dirty(st)) {
- display_front_buffer(st);
- }
+ st_manager_flush_frontbuffer(st);
}
@@ -214,16 +183,4 @@ void st_init_flush_functions(struct pipe_screen *screen,
if (screen->get_param(screen, PIPE_CAP_DEVICE_RESET_STATUS_QUERY))
functions->GetGraphicsResetStatus = st_get_graphics_reset_status;
-
- /* Windows opengl32.dll calls glFinish prior to every swapbuffers.
- * This is unnecessary and degrades performance. Luckily we have some
- * scope to work around this, as the externally-visible behaviour of
- * Finish() is identical to Flush() in all cases - no differences in
- * rendering or ReadPixels are visible if we opt not to wait here.
- *
- * Only set this up on Windows to avoid surprise elsewhere.
- */
-#ifdef PIPE_OS_WINDOWS
- functions->Finish = st_glFlush;
-#endif
}
diff --git a/lib/mesa/src/mesa/state_tracker/st_cb_memoryobjects.c b/lib/mesa/src/mesa/state_tracker/st_cb_memoryobjects.c
new file mode 100644
index 000000000..7a4376326
--- /dev/null
+++ b/lib/mesa/src/mesa/state_tracker/st_cb_memoryobjects.c
@@ -0,0 +1,66 @@
+#include "main/imports.h"
+#include "main/mtypes.h"
+
+#include "main/externalobjects.h"
+
+#include "st_context.h"
+#include "st_cb_memoryobjects.h"
+
+#include "state_tracker/drm_driver.h"
+#include "pipe/p_context.h"
+#include "pipe/p_screen.h"
+
+static struct gl_memory_object *
+st_memoryobj_alloc(struct gl_context *ctx, GLuint name)
+{
+ struct st_memory_object *st_obj = ST_CALLOC_STRUCT(st_memory_object);
+ if (!st_obj)
+ return NULL;
+
+ _mesa_initialize_memory_object(ctx, &st_obj->Base, name);
+ return &st_obj->Base;
+}
+
+static void
+st_memoryobj_free(struct gl_context *ctx,
+ struct gl_memory_object *obj)
+{
+ _mesa_delete_memory_object(ctx, obj);
+}
+
+
+static void
+st_import_memoryobj_fd(struct gl_context *ctx,
+ struct gl_memory_object *obj,
+ GLuint64 size,
+ int fd)
+{
+ struct st_memory_object *st_obj = st_memory_object(obj);
+ struct st_context *st = st_context(ctx);
+ struct pipe_context *pipe = st->pipe;
+ struct pipe_screen *screen = pipe->screen;
+ struct winsys_handle whandle;
+
+ whandle.type = DRM_API_HANDLE_TYPE_FD;
+ whandle.handle = fd;
+ whandle.offset = 0;
+ whandle.layer = 0;
+ whandle.stride = 0;
+
+ st_obj->memory = screen->memobj_create_from_handle(screen,
+ &whandle,
+ obj->Dedicated);
+
+#if !defined(_WIN32)
+ /* We own fd, but we no longer need it. So get rid of it */
+ close(fd);
+#endif
+}
+
+void
+st_init_memoryobject_functions(struct dd_function_table *functions)
+{
+ functions->NewMemoryObject = st_memoryobj_alloc;
+ functions->DeleteMemoryObject = st_memoryobj_free;
+ functions->ImportMemoryObjectFd = st_import_memoryobj_fd;
+}
diff --git a/lib/mesa/src/mesa/state_tracker/st_cb_memoryobjects.h b/lib/mesa/src/mesa/state_tracker/st_cb_memoryobjects.h
new file mode 100644
index 000000000..66065169e
--- /dev/null
+++ b/lib/mesa/src/mesa/state_tracker/st_cb_memoryobjects.h
@@ -0,0 +1,25 @@
+#ifndef ST_CB_MEMORYOBJECTS_H
+#define ST_CB_MEMORYOBJECTS_H
+
+#include "main/compiler.h"
+#include "main/mtypes.h"
+
+struct dd_function_table;
+struct pipe_screen;
+
+struct st_memory_object
+{
+ struct gl_memory_object Base;
+ struct pipe_memory_object *memory;
+};
+
+static inline struct st_memory_object *
+st_memory_object(struct gl_memory_object *obj)
+{
+ return (struct st_memory_object *)obj;
+}
+
+extern void
+st_init_memoryobject_functions(struct dd_function_table *functions);
+
+#endif
diff --git a/lib/mesa/src/mesa/state_tracker/st_cb_syncobj.c b/lib/mesa/src/mesa/state_tracker/st_cb_syncobj.c
index 7a4ba71b3..637fbe3b7 100644
--- a/lib/mesa/src/mesa/state_tracker/st_cb_syncobj.c
+++ b/lib/mesa/src/mesa/state_tracker/st_cb_syncobj.c
@@ -45,17 +45,12 @@ struct st_sync_object {
};
-static struct gl_sync_object * st_new_sync_object(struct gl_context *ctx,
- GLenum type)
+static struct gl_sync_object *st_new_sync_object(struct gl_context *ctx)
{
- if (type == GL_SYNC_FENCE) {
- struct st_sync_object *so = CALLOC_STRUCT(st_sync_object);
+ struct st_sync_object *so = CALLOC_STRUCT(st_sync_object);
- mtx_init(&so->mutex, mtx_plain);
- return &so->b;
- } else {
- return NULL;
- }
+ mtx_init(&so->mutex, mtx_plain);
+ return &so->b;
}
static void st_delete_sync_object(struct gl_context *ctx,
diff --git a/lib/mesa/src/mesa/state_tracker/st_extensions.h b/lib/mesa/src/mesa/state_tracker/st_extensions.h
index faff11fd5..951185caa 100644
--- a/lib/mesa/src/mesa/state_tracker/st_extensions.h
+++ b/lib/mesa/src/mesa/state_tracker/st_extensions.h
@@ -40,8 +40,7 @@ extern void st_init_limits(struct pipe_screen *screen,
extern void st_init_extensions(struct pipe_screen *screen,
struct gl_constants *consts,
struct gl_extensions *extensions,
- struct st_config_options *options,
- boolean has_lib_dxtc);
+ struct st_config_options *options);
#endif /* ST_EXTENSIONS_H */
diff --git a/lib/mesa/src/mesa/state_tracker/st_glsl_to_tgsi_private.cpp b/lib/mesa/src/mesa/state_tracker/st_glsl_to_tgsi_private.cpp
new file mode 100644
index 000000000..b664fa7ec
--- /dev/null
+++ b/lib/mesa/src/mesa/state_tracker/st_glsl_to_tgsi_private.cpp
@@ -0,0 +1,252 @@
+/*
+ * Copyright © 2010 Intel Corporation
+ * Copyright © 2011 Bryan Cain
+ * Copyright © 2017 Gert Wollny
+ *
+ * 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 "st_glsl_to_tgsi_private.h"
+#include <tgsi/tgsi_info.h>
+#include <mesa/program/prog_instruction.h>
+
+static int swizzle_for_type(const glsl_type *type, int component = 0)
+{
+ unsigned num_elements = 4;
+
+ if (type) {
+ type = type->without_array();
+ if (type->is_scalar() || type->is_vector() || type->is_matrix())
+ num_elements = type->vector_elements;
+ }
+
+ int swizzle = swizzle_for_size(num_elements);
+ assert(num_elements + component <= 4);
+
+ swizzle += component * MAKE_SWIZZLE4(1, 1, 1, 1);
+ return swizzle;
+}
+
+static st_src_reg *
+dup_reladdr(const st_src_reg *input)
+{
+ if (!input)
+ return NULL;
+
+ st_src_reg *reg = ralloc(input, st_src_reg);
+ if (!reg) {
+ assert(!"can't create reladdr, expect shader breakage");
+ return NULL;
+ }
+
+ *reg = *input;
+ return reg;
+}
+
+st_src_reg::st_src_reg(gl_register_file file, int index, const glsl_type *type,
+ int component, unsigned array_id)
+{
+ assert(file != PROGRAM_ARRAY || array_id != 0);
+ this->file = file;
+ this->index = index;
+ this->swizzle = swizzle_for_type(type, component);
+ this->negate = 0;
+ this->abs = 0;
+ this->index2D = 0;
+ this->type = type ? type->base_type : GLSL_TYPE_ERROR;
+ this->reladdr = NULL;
+ this->reladdr2 = NULL;
+ this->has_index2 = false;
+ this->double_reg2 = false;
+ this->array_id = array_id;
+ this->is_double_vertex_input = false;
+}
+
+st_src_reg::st_src_reg(gl_register_file file, int index, enum glsl_base_type type)
+{
+ assert(file != PROGRAM_ARRAY); /* need array_id > 0 */
+ this->type = type;
+ this->file = file;
+ this->index = index;
+ this->index2D = 0;
+ this->swizzle = SWIZZLE_XYZW;
+ this->negate = 0;
+ this->abs = 0;
+ this->reladdr = NULL;
+ this->reladdr2 = NULL;
+ this->has_index2 = false;
+ this->double_reg2 = false;
+ this->array_id = 0;
+ this->is_double_vertex_input = false;
+}
+
+st_src_reg::st_src_reg(gl_register_file file, int index, enum glsl_base_type type, int index2D)
+{
+ assert(file != PROGRAM_ARRAY); /* need array_id > 0 */
+ this->type = type;
+ this->file = file;
+ this->index = index;
+ this->index2D = index2D;
+ this->swizzle = SWIZZLE_XYZW;
+ this->negate = 0;
+ this->abs = 0;
+ this->reladdr = NULL;
+ this->reladdr2 = NULL;
+ this->has_index2 = false;
+ this->double_reg2 = false;
+ this->array_id = 0;
+ this->is_double_vertex_input = false;
+}
+
+st_src_reg::st_src_reg()
+{
+ this->type = GLSL_TYPE_ERROR;
+ this->file = PROGRAM_UNDEFINED;
+ this->index = 0;
+ this->index2D = 0;
+ this->swizzle = 0;
+ this->negate = 0;
+ this->abs = 0;
+ this->reladdr = NULL;
+ this->reladdr2 = NULL;
+ this->has_index2 = false;
+ this->double_reg2 = false;
+ this->array_id = 0;
+ this->is_double_vertex_input = false;
+}
+
+st_src_reg::st_src_reg(const st_src_reg &reg)
+{
+ *this = reg;
+}
+
+void st_src_reg::operator=(const st_src_reg &reg)
+{
+ this->type = reg.type;
+ this->file = reg.file;
+ this->index = reg.index;
+ this->index2D = reg.index2D;
+ this->swizzle = reg.swizzle;
+ this->negate = reg.negate;
+ this->abs = reg.abs;
+ this->reladdr = dup_reladdr(reg.reladdr);
+ this->reladdr2 = dup_reladdr(reg.reladdr2);
+ this->has_index2 = reg.has_index2;
+ this->double_reg2 = reg.double_reg2;
+ this->array_id = reg.array_id;
+ this->is_double_vertex_input = reg.is_double_vertex_input;
+}
+
+st_src_reg::st_src_reg(st_dst_reg reg)
+{
+ this->type = reg.type;
+ this->file = reg.file;
+ this->index = reg.index;
+ this->swizzle = SWIZZLE_XYZW;
+ this->negate = 0;
+ this->abs = 0;
+ this->reladdr = dup_reladdr(reg.reladdr);
+ this->index2D = reg.index2D;
+ this->reladdr2 = dup_reladdr(reg.reladdr2);
+ this->has_index2 = reg.has_index2;
+ this->double_reg2 = false;
+ this->array_id = reg.array_id;
+ this->is_double_vertex_input = false;
+}
+
+st_src_reg st_src_reg::get_abs()
+{
+ st_src_reg reg = *this;
+ reg.negate = 0;
+ reg.abs = 1;
+ return reg;
+}
+
+st_dst_reg::st_dst_reg(st_src_reg reg)
+{
+ this->type = reg.type;
+ this->file = reg.file;
+ this->index = reg.index;
+ this->writemask = WRITEMASK_XYZW;
+ this->reladdr = dup_reladdr(reg.reladdr);
+ this->index2D = reg.index2D;
+ this->reladdr2 = dup_reladdr(reg.reladdr2);
+ this->has_index2 = reg.has_index2;
+ this->array_id = reg.array_id;
+}
+
+st_dst_reg::st_dst_reg(gl_register_file file, int writemask, enum glsl_base_type type, int index)
+{
+ assert(file != PROGRAM_ARRAY); /* need array_id > 0 */
+ this->file = file;
+ this->index = index;
+ this->index2D = 0;
+ this->writemask = writemask;
+ this->reladdr = NULL;
+ this->reladdr2 = NULL;
+ this->has_index2 = false;
+ this->type = type;
+ this->array_id = 0;
+}
+
+st_dst_reg::st_dst_reg(gl_register_file file, int writemask, enum glsl_base_type type)
+{
+ assert(file != PROGRAM_ARRAY); /* need array_id > 0 */
+ this->file = file;
+ this->index = 0;
+ this->index2D = 0;
+ this->writemask = writemask;
+ this->reladdr = NULL;
+ this->reladdr2 = NULL;
+ this->has_index2 = false;
+ this->type = type;
+ this->array_id = 0;
+}
+
+st_dst_reg::st_dst_reg()
+{
+ this->type = GLSL_TYPE_ERROR;
+ this->file = PROGRAM_UNDEFINED;
+ this->index = 0;
+ this->index2D = 0;
+ this->writemask = 0;
+ this->reladdr = NULL;
+ this->reladdr2 = NULL;
+ this->has_index2 = false;
+ this->array_id = 0;
+}
+
+st_dst_reg::st_dst_reg(const st_dst_reg &reg)
+{
+ *this = reg;
+}
+
+void st_dst_reg::operator=(const st_dst_reg &reg)
+{
+ this->type = reg.type;
+ this->file = reg.file;
+ this->index = reg.index;
+ this->writemask = reg.writemask;
+ this->reladdr = dup_reladdr(reg.reladdr);
+ this->index2D = reg.index2D;
+ this->reladdr2 = dup_reladdr(reg.reladdr2);
+ this->has_index2 = reg.has_index2;
+ this->array_id = reg.array_id;
+}
diff --git a/lib/mesa/src/mesa/state_tracker/st_glsl_to_tgsi_private.h b/lib/mesa/src/mesa/state_tracker/st_glsl_to_tgsi_private.h
new file mode 100644
index 000000000..d57525d9c
--- /dev/null
+++ b/lib/mesa/src/mesa/state_tracker/st_glsl_to_tgsi_private.h
@@ -0,0 +1,180 @@
+/*
+ * Copyright © 2010 Intel Corporation
+ * Copyright © 2011 Bryan Cain
+ * Copyright © 2017 Gert Wollny
+ *
+ * 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.
+ */
+
+#ifndef ST_GLSL_TO_TGSI_PRIVATE_H
+#define ST_GLSL_TO_TGSI_PRIVATE_H
+
+#include <mesa/main/mtypes.h>
+#include <compiler/glsl_types.h>
+#include <compiler/glsl/ir.h>
+#include <tgsi/tgsi_info.h>
+
+int swizzle_for_size(int size);
+
+class st_dst_reg;
+/**
+ * This struct is a corresponding struct to TGSI ureg_src.
+ */
+class st_src_reg {
+public:
+ st_src_reg(gl_register_file file, int index, const glsl_type *type,
+ int component = 0, unsigned array_id = 0);
+
+ st_src_reg(gl_register_file file, int index, enum glsl_base_type type);
+
+ st_src_reg(gl_register_file file, int index, enum glsl_base_type type, int index2D);
+
+ st_src_reg();
+ st_src_reg(const st_src_reg &reg);
+ void operator=(const st_src_reg &reg);
+
+ explicit st_src_reg(st_dst_reg reg);
+
+ st_src_reg get_abs();
+
+ int32_t index; /**< temporary index, VERT_ATTRIB_*, VARYING_SLOT_*, etc. */
+ int16_t index2D;
+
+ uint16_t swizzle; /**< SWIZZLE_XYZWONEZERO swizzles from Mesa. */
+ int negate:4; /**< NEGATE_XYZW mask from mesa */
+ unsigned abs:1;
+ enum glsl_base_type type:5; /** GLSL_TYPE_* from GLSL IR (enum glsl_base_type) */
+ unsigned has_index2:1;
+ gl_register_file file:5; /**< PROGRAM_* from Mesa */
+ /*
+ * Is this the second half of a double register pair?
+ * currently used for input mapping only.
+ */
+ unsigned double_reg2:1;
+ unsigned is_double_vertex_input:1;
+ unsigned array_id:10;
+ /** Register index should be offset by the integer in this reg. */
+ st_src_reg *reladdr;
+ st_src_reg *reladdr2;
+
+ bool is_legal_tgsi_address_operand() const
+ {
+ /* 2D registers can't be used as an address operand, or if the address
+ * operand itself is a result of indirect addressing.
+ */
+ return (type == GLSL_TYPE_INT || type == GLSL_TYPE_UINT) &&
+ !has_index2 && !reladdr && !reladdr2;
+ }
+};
+
+class st_dst_reg {
+public:
+ st_dst_reg(gl_register_file file, int writemask, enum glsl_base_type type, int index);
+
+ st_dst_reg(gl_register_file file, int writemask, enum glsl_base_type type);
+
+ st_dst_reg();
+ st_dst_reg(const st_dst_reg &reg);
+ void operator=(const st_dst_reg &reg);
+
+ explicit st_dst_reg(st_src_reg reg);
+
+ int32_t index; /**< temporary index, VERT_ATTRIB_*, VARYING_SLOT_*, etc. */
+ int16_t index2D;
+ gl_register_file file:5; /**< PROGRAM_* from Mesa */
+ unsigned writemask:4; /**< Bitfield of WRITEMASK_[XYZW] */
+ enum glsl_base_type type:5; /** GLSL_TYPE_* from GLSL IR (enum glsl_base_type) */
+ unsigned has_index2:1;
+ unsigned array_id:10;
+
+ /** Register index should be offset by the integer in this reg. */
+ st_src_reg *reladdr;
+ st_src_reg *reladdr2;
+};
+
+class glsl_to_tgsi_instruction : public exec_node {
+public:
+ DECLARE_RALLOC_CXX_OPERATORS(glsl_to_tgsi_instruction)
+
+ st_dst_reg dst[2];
+ st_src_reg src[4];
+ st_src_reg resource; /**< sampler or buffer register */
+ st_src_reg *tex_offsets;
+
+ /** Pointer to the ir source this tree came fe02549fdrom for debugging */
+ ir_instruction *ir;
+
+ unsigned op:8; /**< TGSI opcode */
+ unsigned precise:1;
+ unsigned saturate:1;
+ unsigned is_64bit_expanded:1;
+ unsigned sampler_base:5;
+ unsigned sampler_array_size:6; /**< 1-based size of sampler array, 1 if not array */
+ unsigned tex_target:4; /**< One of TEXTURE_*_INDEX */
+ glsl_base_type tex_type:5;
+ unsigned tex_shadow:1;
+ unsigned image_format:9;
+ unsigned tex_offset_num_offset:3;
+ unsigned dead_mask:4; /**< Used in dead code elimination */
+ unsigned buffer_access:3; /**< buffer access type */
+
+ const struct tgsi_opcode_info *info;
+};
+
+struct rename_reg_pair {
+ bool valid;
+ int new_reg;
+};
+
+inline static bool
+is_resource_instruction(unsigned opcode)
+{
+ switch (opcode) {
+ case TGSI_OPCODE_RESQ:
+ case TGSI_OPCODE_LOAD:
+ case TGSI_OPCODE_ATOMUADD:
+ case TGSI_OPCODE_ATOMXCHG:
+ case TGSI_OPCODE_ATOMCAS:
+ case TGSI_OPCODE_ATOMAND:
+ case TGSI_OPCODE_ATOMOR:
+ case TGSI_OPCODE_ATOMXOR:
+ case TGSI_OPCODE_ATOMUMIN:
+ case TGSI_OPCODE_ATOMUMAX:
+ case TGSI_OPCODE_ATOMIMIN:
+ case TGSI_OPCODE_ATOMIMAX:
+ return true;
+ default:
+ return false;
+ }
+}
+
+inline static unsigned
+num_inst_dst_regs(const glsl_to_tgsi_instruction *op)
+{
+ return op->info->num_dst;
+}
+
+inline static unsigned
+num_inst_src_regs(const glsl_to_tgsi_instruction *op)
+{
+ return op->info->is_tex || is_resource_instruction(op->op) ?
+ op->info->num_src - 1 : op->info->num_src;
+}
+#endif
diff --git a/lib/mesa/src/mesa/state_tracker/st_glsl_to_tgsi_temprename.cpp b/lib/mesa/src/mesa/state_tracker/st_glsl_to_tgsi_temprename.cpp
new file mode 100644
index 000000000..76c198e16
--- /dev/null
+++ b/lib/mesa/src/mesa/state_tracker/st_glsl_to_tgsi_temprename.cpp
@@ -0,0 +1,1010 @@
+/*
+ * Copyright © 2017 Gert Wollny
+ *
+ * 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 "st_glsl_to_tgsi_temprename.h"
+#include <tgsi/tgsi_info.h>
+#include <tgsi/tgsi_strings.h>
+#include <program/prog_instruction.h>
+#include <limits>
+#include <cstdlib>
+
+/* std::sort is significantly faster than qsort */
+#define USE_STL_SORT
+#ifdef USE_STL_SORT
+#include <algorithm>
+#endif
+
+#ifndef NDEBUG
+#include <iostream>
+#include <iomanip>
+#include <program/prog_print.h>
+#include <util/debug.h>
+using std::cerr;
+using std::setw;
+#endif
+
+/* If <windows.h> is included this is defined and clashes with
+ * std::numeric_limits<>::max()
+ */
+#ifdef max
+#undef max
+#endif
+
+using std::numeric_limits;
+
+/* Without c++11 define the nullptr for forward-compatibility
+ * and better readibility */
+#if __cplusplus < 201103L
+#define nullptr 0
+#endif
+
+#ifndef NDEBUG
+/* Helper function to check whether we want to seen debugging output */
+static inline bool is_debug_enabled ()
+{
+ static int debug_enabled = -1;
+ if (debug_enabled < 0)
+ debug_enabled = env_var_as_boolean("GLSL_TO_TGSI_RENAME_DEBUG", false);
+ return debug_enabled > 0;
+}
+#define RENAME_DEBUG(X) if (is_debug_enabled()) do { X; } while (false);
+#else
+#define RENAME_DEBUG(X)
+#endif
+
+namespace {
+
+enum prog_scope_type {
+ outer_scope, /* Outer program scope */
+ loop_body, /* Inside a loop */
+ if_branch, /* Inside if branch */
+ else_branch, /* Inside else branch */
+ switch_body, /* Inside switch statmenet */
+ switch_case_branch, /* Inside switch case statmenet */
+ switch_default_branch, /* Inside switch default statmenet */
+ undefined_scope
+};
+
+class prog_scope {
+public:
+ prog_scope(prog_scope *parent, prog_scope_type type, int id,
+ int depth, int begin);
+
+ prog_scope_type type() const;
+ prog_scope *parent() const;
+ int nesting_depth() const;
+ int id() const;
+ int end() const;
+ int begin() const;
+ int loop_break_line() const;
+
+ const prog_scope *in_ifelse_scope() const;
+ const prog_scope *in_switchcase_scope() const;
+ const prog_scope *innermost_loop() const;
+ const prog_scope *outermost_loop() const;
+ const prog_scope *enclosing_conditional() const;
+
+ bool is_loop() const;
+ bool is_in_loop() const;
+ bool is_conditional() const;
+
+ bool break_is_for_switchcase() const;
+ bool contains_range_of(const prog_scope& other) const;
+
+ void set_end(int end);
+ void set_loop_break_line(int line);
+
+private:
+ prog_scope_type scope_type;
+ int scope_id;
+ int scope_nesting_depth;
+ int scope_begin;
+ int scope_end;
+ int break_loop_line;
+ prog_scope *parent_scope;
+};
+
+/* Some storage class to encapsulate the prog_scope (de-)allocations */
+class prog_scope_storage {
+public:
+ prog_scope_storage(void *mem_ctx, int n);
+ ~prog_scope_storage();
+ prog_scope * create(prog_scope *p, prog_scope_type type, int id,
+ int lvl, int s_begin);
+private:
+ void *mem_ctx;
+ int current_slot;
+ prog_scope *storage;
+};
+
+class temp_comp_access {
+public:
+ temp_comp_access();
+ void record_read(int line, prog_scope *scope);
+ void record_write(int line, prog_scope *scope);
+ lifetime get_required_lifetime();
+private:
+ void propagate_lifetime_to_dominant_write_scope();
+
+ prog_scope *last_read_scope;
+ prog_scope *first_read_scope;
+ prog_scope *first_write_scope;
+ int first_write;
+ int last_read;
+ int last_write;
+ int first_read;
+ bool keep_for_full_loop;
+};
+
+class temp_access {
+public:
+ temp_access();
+ void record_read(int line, prog_scope *scope, int swizzle);
+ void record_write(int line, prog_scope *scope, int writemask);
+ lifetime get_required_lifetime();
+private:
+ void update_access_mask(int mask);
+
+ temp_comp_access comp[4];
+ int access_mask;
+ bool needs_component_tracking;
+};
+
+prog_scope_storage::prog_scope_storage(void *mc, int n):
+ mem_ctx(mc),
+ current_slot(0)
+{
+ storage = ralloc_array(mem_ctx, prog_scope, n);
+}
+
+prog_scope_storage::~prog_scope_storage()
+{
+ ralloc_free(storage);
+}
+
+prog_scope*
+prog_scope_storage::create(prog_scope *p, prog_scope_type type, int id,
+ int lvl, int s_begin)
+{
+ storage[current_slot] = prog_scope(p, type, id, lvl, s_begin);
+ return &storage[current_slot++];
+}
+
+prog_scope::prog_scope(prog_scope *parent, prog_scope_type type, int id,
+ int depth, int scope_begin):
+ scope_type(type),
+ scope_id(id),
+ scope_nesting_depth(depth),
+ scope_begin(scope_begin),
+ scope_end(-1),
+ break_loop_line(numeric_limits<int>::max()),
+ parent_scope(parent)
+{
+}
+
+prog_scope_type prog_scope::type() const
+{
+ return scope_type;
+}
+
+prog_scope *prog_scope::parent() const
+{
+ return parent_scope;
+}
+
+int prog_scope::nesting_depth() const
+{
+ return scope_nesting_depth;
+}
+
+bool prog_scope::is_loop() const
+{
+ return (scope_type == loop_body);
+}
+
+bool prog_scope::is_in_loop() const
+{
+ if (scope_type == loop_body)
+ return true;
+
+ if (parent_scope)
+ return parent_scope->is_in_loop();
+
+ return false;
+}
+
+const prog_scope *prog_scope::innermost_loop() const
+{
+ if (scope_type == loop_body)
+ return this;
+
+ if (parent_scope)
+ return parent_scope->innermost_loop();
+
+ return nullptr;
+}
+
+const prog_scope *prog_scope::outermost_loop() const
+{
+ const prog_scope *loop = nullptr;
+ const prog_scope *p = this;
+
+ do {
+ if (p->type() == loop_body)
+ loop = p;
+ p = p->parent();
+ } while (p);
+
+ return loop;
+}
+
+const prog_scope *prog_scope::enclosing_conditional() const
+{
+ if (is_conditional())
+ return this;
+
+ if (parent_scope)
+ return parent_scope->enclosing_conditional();
+
+ return nullptr;
+}
+
+bool prog_scope::contains_range_of(const prog_scope& other) const
+{
+ return (begin() <= other.begin()) && (end() >= other.end());
+}
+
+bool prog_scope::is_conditional() const
+{
+ return scope_type == if_branch ||
+ scope_type == else_branch ||
+ scope_type == switch_case_branch ||
+ scope_type == switch_default_branch;
+}
+
+const prog_scope *prog_scope::in_ifelse_scope() const
+{
+ if (scope_type == if_branch ||
+ scope_type == else_branch)
+ return this;
+
+ if (parent_scope)
+ return parent_scope->in_ifelse_scope();
+
+ return nullptr;
+}
+
+const prog_scope *prog_scope::in_switchcase_scope() const
+{
+ if (scope_type == switch_case_branch ||
+ scope_type == switch_default_branch)
+ return this;
+
+ if (parent_scope)
+ return parent_scope->in_switchcase_scope();
+
+ return nullptr;
+}
+
+bool prog_scope::break_is_for_switchcase() const
+{
+ if (scope_type == loop_body)
+ return false;
+
+ if (scope_type == switch_case_branch ||
+ scope_type == switch_default_branch ||
+ scope_type == switch_body)
+ return true;
+
+ if (parent_scope)
+ return parent_scope->break_is_for_switchcase();
+
+ return false;
+}
+
+int prog_scope::id() const
+{
+ return scope_id;
+}
+
+int prog_scope::begin() const
+{
+ return scope_begin;
+}
+
+int prog_scope::end() const
+{
+ return scope_end;
+}
+
+void prog_scope::set_end(int end)
+{
+ if (scope_end == -1)
+ scope_end = end;
+}
+
+void prog_scope::set_loop_break_line(int line)
+{
+ if (scope_type == loop_body) {
+ break_loop_line = MIN2(break_loop_line, line);
+ } else {
+ if (parent_scope)
+ parent()->set_loop_break_line(line);
+ }
+}
+
+int prog_scope::loop_break_line() const
+{
+ return break_loop_line;
+}
+
+temp_access::temp_access():
+ access_mask(0),
+ needs_component_tracking(false)
+{
+}
+
+void temp_access::update_access_mask(int mask)
+{
+ if (access_mask && access_mask != mask)
+ needs_component_tracking = true;
+ access_mask |= mask;
+}
+
+void temp_access::record_write(int line, prog_scope *scope, int writemask)
+{
+ update_access_mask(writemask);
+
+ if (writemask & WRITEMASK_X)
+ comp[0].record_write(line, scope);
+ if (writemask & WRITEMASK_Y)
+ comp[1].record_write(line, scope);
+ if (writemask & WRITEMASK_Z)
+ comp[2].record_write(line, scope);
+ if (writemask & WRITEMASK_W)
+ comp[3].record_write(line, scope);
+}
+
+void temp_access::record_read(int line, prog_scope *scope, int swizzle)
+{
+ int readmask = 0;
+ for (int idx = 0; idx < 4; ++idx) {
+ int swz = GET_SWZ(swizzle, idx);
+ readmask |= (1 << swz) & 0xF;
+ }
+ update_access_mask(readmask);
+
+ if (readmask & WRITEMASK_X)
+ comp[0].record_read(line, scope);
+ if (readmask & WRITEMASK_Y)
+ comp[1].record_read(line, scope);
+ if (readmask & WRITEMASK_Z)
+ comp[2].record_read(line, scope);
+ if (readmask & WRITEMASK_W)
+ comp[3].record_read(line, scope);
+}
+
+inline static lifetime make_lifetime(int b, int e)
+{
+ lifetime lt;
+ lt.begin = b;
+ lt.end = e;
+ return lt;
+}
+
+lifetime temp_access::get_required_lifetime()
+{
+ lifetime result = make_lifetime(-1, -1);
+
+ unsigned mask = access_mask;
+ while (mask) {
+ unsigned chan = u_bit_scan(&mask);
+ lifetime lt = comp[chan].get_required_lifetime();
+
+ if (lt.begin >= 0) {
+ if ((result.begin < 0) || (result.begin > lt.begin))
+ result.begin = lt.begin;
+ }
+
+ if (lt.end > result.end)
+ result.end = lt.end;
+
+ if (!needs_component_tracking)
+ break;
+ }
+ return result;
+}
+
+temp_comp_access::temp_comp_access():
+ last_read_scope(nullptr),
+ first_read_scope(nullptr),
+ first_write_scope(nullptr),
+ first_write(-1),
+ last_read(-1),
+ last_write(-1),
+ first_read(numeric_limits<int>::max())
+{
+}
+
+void temp_comp_access::record_read(int line, prog_scope *scope)
+{
+ last_read_scope = scope;
+ last_read = line;
+
+ if (first_read > line) {
+ first_read = line;
+ first_read_scope = scope;
+ }
+}
+
+void temp_comp_access::record_write(int line, prog_scope *scope)
+{
+ last_write = line;
+
+ if (first_write < 0) {
+ first_write = line;
+ first_write_scope = scope;
+ }
+}
+
+void temp_comp_access::propagate_lifetime_to_dominant_write_scope()
+{
+ first_write = first_write_scope->begin();
+ int lr = first_write_scope->end();
+
+ if (last_read < lr)
+ last_read = lr;
+}
+
+lifetime temp_comp_access::get_required_lifetime()
+{
+ bool keep_for_full_loop = false;
+
+ /* This register component is not used at all, or only read,
+ * mark it as unused and ignore it when renaming.
+ * glsl_to_tgsi_visitor::renumber_registers will take care of
+ * eliminating registers that are not written to.
+ */
+ if (last_write < 0)
+ return make_lifetime(-1, -1);
+
+ assert(first_write_scope);
+
+ /* Only written to, just make sure the register component is not
+ * reused in the range it is used to write to
+ */
+ if (!last_read_scope)
+ return make_lifetime(first_write, last_write + 1);
+
+ const prog_scope *enclosing_scope_first_read = first_read_scope;
+ const prog_scope *enclosing_scope_first_write = first_write_scope;
+
+ /* We read before writing in a loop
+ * hence the value must survive the loops
+ */
+ if ((first_read <= first_write) &&
+ first_read_scope->is_in_loop()) {
+ keep_for_full_loop = true;
+ enclosing_scope_first_read = first_read_scope->outermost_loop();
+ }
+
+ /* A conditional write within a nested loop must survive
+ * the outermost loop, but only if it is read outside
+ * the condition scope where we write.
+ */
+ const prog_scope *conditional = enclosing_scope_first_write->enclosing_conditional();
+ if (conditional && conditional->is_in_loop() &&
+ !conditional->contains_range_of(*last_read_scope)) {
+ keep_for_full_loop = true;
+ enclosing_scope_first_write = conditional->outermost_loop();
+ }
+
+ /* Evaluate the scope that is shared by all: required first write scope,
+ * required first read before write scope, and last read scope.
+ */
+ const prog_scope *enclosing_scope = enclosing_scope_first_read;
+ if (enclosing_scope_first_write->contains_range_of(*enclosing_scope))
+ enclosing_scope = enclosing_scope_first_write;
+
+ if (last_read_scope->contains_range_of(*enclosing_scope))
+ enclosing_scope = last_read_scope;
+
+ while (!enclosing_scope->contains_range_of(*enclosing_scope_first_write) ||
+ !enclosing_scope->contains_range_of(*last_read_scope)) {
+ enclosing_scope = enclosing_scope->parent();
+ assert(enclosing_scope);
+ }
+
+ /* Propagate the last read scope to the target scope */
+ while (enclosing_scope->nesting_depth() < last_read_scope->nesting_depth()) {
+ /* If the read is in a loop and we have to move up the scope we need to
+ * extend the life time to the end of this current loop because at this
+ * point we don't know whether the component was written before
+ * un-conditionally in the same loop.
+ */
+ if (last_read_scope->is_loop())
+ last_read = last_read_scope->end();
+
+ last_read_scope = last_read_scope->parent();
+ }
+
+ /* If the variable has to be kept for the whole loop, and we
+ * are currently in a loop, then propagate the life time.
+ */
+ if (keep_for_full_loop && first_write_scope->is_loop())
+ propagate_lifetime_to_dominant_write_scope();
+
+ /* Propagate the first_dominant_write scope to the target scope */
+ while (enclosing_scope->nesting_depth() < first_write_scope->nesting_depth()) {
+ /* Propagate lifetime if there was a break in a loop and the write was
+ * after the break inside that loop. Note, that this is only needed if
+ * we move up in the scopes.
+ */
+ if (first_write_scope->loop_break_line() < first_write) {
+ keep_for_full_loop = true;
+ propagate_lifetime_to_dominant_write_scope();
+ }
+
+ first_write_scope = first_write_scope->parent();
+
+ /* Propagte lifetime if we are now in a loop */
+ if (keep_for_full_loop && first_write_scope->is_loop())
+ propagate_lifetime_to_dominant_write_scope();
+ }
+
+ /* The last write past the last read is dead code, but we have to
+ * ensure that the component is not reused too early, hence extend the
+ * lifetime past the last write.
+ */
+ if (last_write >= last_read)
+ last_read = last_write + 1;
+
+ /* Here we are at the same scope, all is resolved */
+ return make_lifetime(first_write, last_read);
+}
+
+/* Helper class for sorting and searching the registers based
+ * on life times. */
+class access_record {
+public:
+ int begin;
+ int end;
+ int reg;
+ bool erase;
+
+ bool operator < (const access_record& rhs) const {
+ return begin < rhs.begin;
+ }
+};
+
+}
+
+#ifndef NDEBUG
+/* Function used for debugging. */
+static void dump_instruction(int line, prog_scope *scope,
+ const glsl_to_tgsi_instruction& inst);
+#endif
+
+/* Scan the program and estimate the required register life times.
+ * The array lifetimes must be pre-allocated
+ */
+bool
+get_temp_registers_required_lifetimes(void *mem_ctx, exec_list *instructions,
+ int ntemps, struct lifetime *lifetimes)
+{
+ int line = 0;
+ int loop_id = 0;
+ int if_id = 0;
+ int switch_id = 0;
+ bool is_at_end = false;
+ bool ok = true;
+ int n_scopes = 1;
+
+ /* Count scopes to allocate the needed space without the need for
+ * re-allocation
+ */
+ foreach_in_list(glsl_to_tgsi_instruction, inst, instructions) {
+ if (inst->op == TGSI_OPCODE_BGNLOOP ||
+ inst->op == TGSI_OPCODE_SWITCH ||
+ inst->op == TGSI_OPCODE_CASE ||
+ inst->op == TGSI_OPCODE_IF ||
+ inst->op == TGSI_OPCODE_UIF ||
+ inst->op == TGSI_OPCODE_ELSE ||
+ inst->op == TGSI_OPCODE_DEFAULT)
+ ++n_scopes;
+ }
+
+ prog_scope_storage scopes(mem_ctx, n_scopes);
+ temp_access *acc = new temp_access[ntemps];
+
+ prog_scope *cur_scope = scopes.create(nullptr, outer_scope, 0, 0, line);
+
+ RENAME_DEBUG(cerr << "========= Begin shader ============\n");
+
+ foreach_in_list(glsl_to_tgsi_instruction, inst, instructions) {
+ if (is_at_end) {
+ assert(!"GLSL_TO_TGSI: shader has instructions past end marker");
+ break;
+ }
+
+ RENAME_DEBUG(dump_instruction(line, cur_scope, *inst));
+
+ switch (inst->op) {
+ case TGSI_OPCODE_BGNLOOP: {
+ cur_scope = scopes.create(cur_scope, loop_body, loop_id++,
+ cur_scope->nesting_depth() + 1, line);
+ break;
+ }
+ case TGSI_OPCODE_ENDLOOP: {
+ cur_scope->set_end(line);
+ cur_scope = cur_scope->parent();
+ assert(cur_scope);
+ break;
+ }
+ case TGSI_OPCODE_IF:
+ case TGSI_OPCODE_UIF: {
+ assert(num_inst_src_regs(inst) == 1);
+ const st_src_reg& src = inst->src[0];
+ if (src.file == PROGRAM_TEMPORARY)
+ acc[src.index].record_read(line, cur_scope, src.swizzle);
+ cur_scope = scopes.create(cur_scope, if_branch, if_id++,
+ cur_scope->nesting_depth() + 1, line + 1);
+ break;
+ }
+ case TGSI_OPCODE_ELSE: {
+ assert(cur_scope->type() == if_branch);
+ cur_scope->set_end(line - 1);
+ cur_scope = scopes.create(cur_scope->parent(), else_branch,
+ cur_scope->id(), cur_scope->nesting_depth(),
+ line + 1);
+ break;
+ }
+ case TGSI_OPCODE_END: {
+ cur_scope->set_end(line);
+ is_at_end = true;
+ break;
+ }
+ case TGSI_OPCODE_ENDIF: {
+ cur_scope->set_end(line - 1);
+ cur_scope = cur_scope->parent();
+ assert(cur_scope);
+ break;
+ }
+ case TGSI_OPCODE_SWITCH: {
+ assert(num_inst_src_regs(inst) == 1);
+ const st_src_reg& src = inst->src[0];
+ prog_scope *scope = scopes.create(cur_scope, switch_body, switch_id++,
+ cur_scope->nesting_depth() + 1, line);
+ /* We record the read only for the SWITCH statement itself, like it
+ * is used by the only consumer of TGSI_OPCODE_SWITCH in tgsi_exec.c.
+ */
+ if (src.file == PROGRAM_TEMPORARY)
+ acc[src.index].record_read(line, cur_scope, src.swizzle);
+ cur_scope = scope;
+ break;
+ }
+ case TGSI_OPCODE_ENDSWITCH: {
+ cur_scope->set_end(line - 1);
+ /* Remove the case level, it might not have been
+ * closed with a break.
+ */
+ if (cur_scope->type() != switch_body)
+ cur_scope = cur_scope->parent();
+
+ cur_scope = cur_scope->parent();
+ assert(cur_scope);
+ break;
+ }
+ case TGSI_OPCODE_CASE: {
+ /* Take care of tracking the registers. */
+ prog_scope *switch_scope = cur_scope->type() == switch_body ?
+ cur_scope : cur_scope->parent();
+
+ assert(num_inst_src_regs(inst) == 1);
+ const st_src_reg& src = inst->src[0];
+ if (src.file == PROGRAM_TEMPORARY)
+ acc[src.index].record_read(line, switch_scope, src.swizzle);
+
+ /* Fall through to allocate the scope. */
+ }
+ case TGSI_OPCODE_DEFAULT: {
+ prog_scope_type t = inst->op == TGSI_OPCODE_CASE ? switch_case_branch
+ : switch_default_branch;
+ prog_scope *switch_scope = (cur_scope->type() == switch_body) ?
+ cur_scope : cur_scope->parent();
+ assert(switch_scope->type() == switch_body);
+ prog_scope *scope = scopes.create(switch_scope, t,
+ switch_scope->id(),
+ switch_scope->nesting_depth() + 1,
+ line);
+ /* Previous case falls through, so scope was not yet closed. */
+ if ((cur_scope != switch_scope) && (cur_scope->end() == -1))
+ cur_scope->set_end(line - 1);
+ cur_scope = scope;
+ break;
+ }
+ case TGSI_OPCODE_BRK: {
+ if (cur_scope->break_is_for_switchcase()) {
+ cur_scope->set_end(line - 1);
+ } else {
+ cur_scope->set_loop_break_line(line);
+ }
+ break;
+ }
+ case TGSI_OPCODE_CAL:
+ case TGSI_OPCODE_RET:
+ /* These opcodes are not supported and if a subroutine would
+ * be called in a shader, then the lifetime tracking would have
+ * to follow that call to see which registers are used there.
+ * Since this is not done, we have to bail out here and signal
+ * that no register merge will take place.
+ */
+ ok = false;
+ goto out;
+ default: {
+ for (unsigned j = 0; j < num_inst_src_regs(inst); j++) {
+ const st_src_reg& src = inst->src[j];
+ if (src.file == PROGRAM_TEMPORARY)
+ acc[src.index].record_read(line, cur_scope, src.swizzle);
+ }
+ for (unsigned j = 0; j < inst->tex_offset_num_offset; j++) {
+ const st_src_reg& src = inst->tex_offsets[j];
+ if (src.file == PROGRAM_TEMPORARY)
+ acc[src.index].record_read(line, cur_scope, src.swizzle);
+ }
+ for (unsigned j = 0; j < num_inst_dst_regs(inst); j++) {
+ const st_dst_reg& dst = inst->dst[j];
+ if (dst.file == PROGRAM_TEMPORARY)
+ acc[dst.index].record_write(line, cur_scope, dst.writemask);
+ }
+ }
+ }
+ ++line;
+ }
+
+ RENAME_DEBUG(cerr << "==================================\n\n");
+
+ /* Make sure last scope is closed, even though no
+ * TGSI_OPCODE_END was given.
+ */
+ if (cur_scope->end() < 0)
+ cur_scope->set_end(line - 1);
+
+ RENAME_DEBUG(cerr << "========= lifetimes ==============\n");
+ for(int i = 0; i < ntemps; ++i) {
+ RENAME_DEBUG(cerr << setw(4) << i);
+ lifetimes[i] = acc[i].get_required_lifetime();
+ RENAME_DEBUG(cerr << ": [" << lifetimes[i].begin << ", "
+ << lifetimes[i].end << "]\n");
+ }
+ RENAME_DEBUG(cerr << "==================================\n\n");
+
+out:
+ delete[] acc;
+ return ok;
+}
+
+/* Find the next register between [start, end) that has a life time starting
+ * at or after bound by using a binary search.
+ * start points at the beginning of the search range,
+ * end points at the element past the end of the search range, and
+ * the array comprising [start, end) must be sorted in ascending order.
+ */
+static access_record*
+find_next_rename(access_record* start, access_record* end, int bound)
+{
+ int delta = (end - start);
+
+ while (delta > 0) {
+ int half = delta >> 1;
+ access_record* middle = start + half;
+
+ if (bound <= middle->begin) {
+ delta = half;
+ } else {
+ start = middle;
+ ++start;
+ delta -= half + 1;
+ }
+ }
+
+ return start;
+}
+
+#ifndef USE_STL_SORT
+static int access_record_compare (const void *a, const void *b) {
+ const access_record *aa = static_cast<const access_record*>(a);
+ const access_record *bb = static_cast<const access_record*>(b);
+ return aa->begin < bb->begin ? -1 : (aa->begin > bb->begin ? 1 : 0);
+}
+#endif
+
+/* This functions evaluates the register merges by using a binary
+ * search to find suitable merge candidates. */
+void get_temp_registers_remapping(void *mem_ctx, int ntemps,
+ const struct lifetime* lifetimes,
+ struct rename_reg_pair *result)
+{
+ access_record *reg_access = ralloc_array(mem_ctx, access_record, ntemps);
+
+ int used_temps = 0;
+ for (int i = 0; i < ntemps; ++i) {
+ if (lifetimes[i].begin >= 0) {
+ reg_access[used_temps].begin = lifetimes[i].begin;
+ reg_access[used_temps].end = lifetimes[i].end;
+ reg_access[used_temps].reg = i;
+ reg_access[used_temps].erase = false;
+ ++used_temps;
+ }
+ }
+
+#ifdef USE_STL_SORT
+ std::sort(reg_access, reg_access + used_temps);
+#else
+ std::qsort(reg_access, used_temps, sizeof(access_record), access_record_compare);
+#endif
+
+ access_record *trgt = reg_access;
+ access_record *reg_access_end = reg_access + used_temps;
+ access_record *first_erase = reg_access_end;
+ access_record *search_start = trgt + 1;
+
+ while (trgt != reg_access_end) {
+ access_record *src = find_next_rename(search_start, reg_access_end,
+ trgt->end);
+ if (src != reg_access_end) {
+ result[src->reg].new_reg = trgt->reg;
+ result[src->reg].valid = true;
+ trgt->end = src->end;
+
+ /* Since we only search forward, don't remove the renamed
+ * register just now, only mark it. */
+ src->erase = true;
+
+ if (first_erase == reg_access_end)
+ first_erase = src;
+
+ search_start = src + 1;
+ } else {
+ /* Moving to the next target register it is time to remove
+ * the already merged registers from the search range */
+ if (first_erase != reg_access_end) {
+ access_record *outp = first_erase;
+ access_record *inp = first_erase + 1;
+
+ while (inp != reg_access_end) {
+ if (!inp->erase)
+ *outp++ = *inp;
+ ++inp;
+ }
+
+ reg_access_end = outp;
+ first_erase = reg_access_end;
+ }
+ ++trgt;
+ search_start = trgt + 1;
+ }
+ }
+ ralloc_free(reg_access);
+}
+
+/* Code below used for debugging */
+#ifndef NDEBUG
+static const char swizzle_txt[] = "xyzw";
+
+static const char *tgsi_file_names[PROGRAM_FILE_MAX] = {
+ "TEMP", "ARRAY", "IN", "OUT", "STATE", "CONST",
+ "UNIFORM", "WO", "ADDR", "SAMPLER", "SV", "UNDEF",
+ "IMM", "BUF", "MEM", "IMAGE"
+};
+
+static
+void dump_instruction(int line, prog_scope *scope,
+ const glsl_to_tgsi_instruction& inst)
+{
+ const struct tgsi_opcode_info *info = tgsi_get_opcode_info(inst.op);
+
+ int indent = scope->nesting_depth();
+ if ((scope->type() == switch_case_branch ||
+ scope->type() == switch_default_branch) &&
+ (info->opcode == TGSI_OPCODE_CASE ||
+ info->opcode == TGSI_OPCODE_DEFAULT))
+ --indent;
+
+ if (info->opcode == TGSI_OPCODE_ENDIF ||
+ info->opcode == TGSI_OPCODE_ELSE ||
+ info->opcode == TGSI_OPCODE_ENDLOOP ||
+ info->opcode == TGSI_OPCODE_ENDSWITCH)
+ --indent;
+
+ cerr << setw(4) << line << ": ";
+ for (int i = 0; i < indent; ++i)
+ cerr << " ";
+ cerr << tgsi_get_opcode_name(info->opcode) << " ";
+
+ bool has_operators = false;
+ for (unsigned j = 0; j < num_inst_dst_regs(&inst); j++) {
+ has_operators = true;
+ if (j > 0)
+ cerr << ", ";
+
+ const st_dst_reg& dst = inst.dst[j];
+ cerr << tgsi_file_names[dst.file];
+
+ if (dst.file == PROGRAM_ARRAY)
+ cerr << "(" << dst.array_id << ")";
+
+ cerr << "[" << dst.index << "]";
+
+ if (dst.writemask != TGSI_WRITEMASK_XYZW) {
+ cerr << ".";
+ if (dst.writemask & TGSI_WRITEMASK_X) cerr << "x";
+ if (dst.writemask & TGSI_WRITEMASK_Y) cerr << "y";
+ if (dst.writemask & TGSI_WRITEMASK_Z) cerr << "z";
+ if (dst.writemask & TGSI_WRITEMASK_W) cerr << "w";
+ }
+ }
+ if (has_operators)
+ cerr << " := ";
+
+ for (unsigned j = 0; j < num_inst_src_regs(&inst); j++) {
+ if (j > 0)
+ cerr << ", ";
+
+ const st_src_reg& src = inst.src[j];
+ cerr << tgsi_file_names[src.file]
+ << "[" << src.index << "]";
+ if (src.swizzle != SWIZZLE_XYZW) {
+ cerr << ".";
+ for (int idx = 0; idx < 4; ++idx) {
+ int swz = GET_SWZ(src.swizzle, idx);
+ if (swz < 4) {
+ cerr << swizzle_txt[swz];
+ }
+ }
+ }
+ }
+
+ if (inst.tex_offset_num_offset > 0) {
+ cerr << ", TEXOFS: ";
+ for (unsigned j = 0; j < inst.tex_offset_num_offset; j++) {
+ if (j > 0)
+ cerr << ", ";
+
+ const st_src_reg& src = inst.tex_offsets[j];
+ cerr << tgsi_file_names[src.file]
+ << "[" << src.index << "]";
+ if (src.swizzle != SWIZZLE_XYZW) {
+ cerr << ".";
+ for (int idx = 0; idx < 4; ++idx) {
+ int swz = GET_SWZ(src.swizzle, idx);
+ if (swz < 4) {
+ cerr << swizzle_txt[swz];
+ }
+ }
+ }
+ }
+ }
+ cerr << "\n";
+}
+#endif
diff --git a/lib/mesa/src/mesa/state_tracker/st_glsl_to_tgsi_temprename.h b/lib/mesa/src/mesa/state_tracker/st_glsl_to_tgsi_temprename.h
new file mode 100644
index 000000000..3f21b1317
--- /dev/null
+++ b/lib/mesa/src/mesa/state_tracker/st_glsl_to_tgsi_temprename.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright © 2017 Gert Wollny
+ *
+ * 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.
+ */
+
+#ifndef MESA_GLSL_TO_TGSI_TEMPRENAME_H
+#define MESA_GLSL_TO_TGSI_TEMPRENAME_H
+
+#include "st_glsl_to_tgsi_private.h"
+
+/** Storage to record the required life time of a temporary register
+ * begin == end == -1 indicates that the register can be reused without
+ * limitations. Otherwise, "begin" indicates the first instruction in which
+ * a write operation may target this temporary, and end indicates the
+ * last instruction in which a value can be read from this temporary.
+ * Hence, a register R2 can be merged with a register R1 if R1.end <= R2.begin.
+ */
+struct lifetime {
+ int begin;
+ int end;
+};
+
+/** Evaluates the required life times of temporary registers in a shader.
+ * The life time estimation can only be run sucessfully if the shader doesn't
+ * call a subroutine.
+ * @param[in] mem_ctx a memory context that can be used with the ralloc_* functions
+ * @param[in] instructions the shader to be anlzyed
+ * @param[in] ntemps number of temporaries reserved for this shader
+ * @param[in,out] lifetimes memory location to store the estimated required
+ * life times for each temporary register. The parameter must point to
+ * allocated memory that can hold ntemps lifetime structures. On output
+ * the life times contains the life times for the registers with the
+ * exception of TEMP[0].
+ * @returns: true if the lifetimes were estimated, false if not (i.e. if a
+ * subroutine was called).
+ */
+bool
+get_temp_registers_required_lifetimes(void *mem_ctx, exec_list *instructions,
+ int ntemps, struct lifetime *lifetimes);
+/** Estimate the merge remapping of the registers.
+ * @param[in] mem_ctx a memory context that can be used with the ralloc_* functions
+ * @param[in] ntemps number of temporaries reserved for this shader
+ * @param[in] lifetimes required life time for each temporary register.
+ * @param[in,out] result memory location to store the register remapping table.
+ * On input the parameter must point to allocated memory that can hold the
+ * renaming information for ntemps registers, on output the mapping is stored.
+ * Note that TEMP[0] is not considered for register renaming.
+ */
+void get_temp_registers_remapping(void *mem_ctx, int ntemps,
+ const struct lifetime* lifetimes,
+ struct rename_reg_pair *result);
+
+#endif \ No newline at end of file
diff --git a/lib/mesa/src/mesa/state_tracker/st_glsl_types.h b/lib/mesa/src/mesa/state_tracker/st_glsl_types.h
index 3a39ceefe..915816d1f 100644
--- a/lib/mesa/src/mesa/state_tracker/st_glsl_types.h
+++ b/lib/mesa/src/mesa/state_tracker/st_glsl_types.h
@@ -33,8 +33,8 @@
extern "C" {
#endif
-int st_glsl_attrib_type_size(const struct glsl_type *type, bool is_vs_input);
-int st_glsl_type_size(const struct glsl_type *type);
+int st_glsl_storage_type_size(const struct glsl_type *type,
+ bool is_bindless);
#ifdef __cplusplus
diff --git a/lib/mesa/src/mesa/state_tracker/st_vdpau.c b/lib/mesa/src/mesa/state_tracker/st_vdpau.c
index 027381530..19611e719 100644
--- a/lib/mesa/src/mesa/state_tracker/st_vdpau.c
+++ b/lib/mesa/src/mesa/state_tracker/st_vdpau.c
@@ -221,7 +221,7 @@ st_vdpau_map_surface(struct gl_context *ctx, GLenum target, GLenum access,
/* switch to surface based */
if (!stObj->surface_based) {
- _mesa_clear_texture_object(ctx, texObj);
+ _mesa_clear_texture_object(ctx, texObj, NULL);
stObj->surface_based = GL_TRUE;
}
@@ -236,6 +236,7 @@ st_vdpau_map_surface(struct gl_context *ctx, GLenum target, GLenum access,
pipe_resource_reference(&stImage->pt, res);
stObj->surface_format = res->format;
+ stObj->level_override = 0;
stObj->layer_override = layer_override;
_mesa_dirty_texobj(ctx, texObj);
@@ -256,6 +257,7 @@ st_vdpau_unmap_surface(struct gl_context *ctx, GLenum target, GLenum access,
st_texture_release_all_sampler_views(st, stObj);
pipe_resource_reference(&stImage->pt, NULL);
+ stObj->level_override = 0;
stObj->layer_override = 0;
_mesa_dirty_texobj(ctx, texObj);
diff --git a/lib/mesa/src/mesa/state_tracker/tests/Makefile.am b/lib/mesa/src/mesa/state_tracker/tests/Makefile.am
new file mode 100644
index 000000000..f32957608
--- /dev/null
+++ b/lib/mesa/src/mesa/state_tracker/tests/Makefile.am
@@ -0,0 +1,34 @@
+include $(top_srcdir)/src/gallium/Automake.inc
+
+AM_CFLAGS = \
+ $(PTHREAD_CFLAGS)
+
+AM_CXXFLAGS = \
+ $(GALLIUM_DRIVER_CXXFLAGS) \
+ -std=c++11
+
+AM_CPPFLAGS = \
+ -I$(top_srcdir)/src/gtest/include \
+ -I$(top_srcdir)/src/mapi \
+ -I$(top_builddir)/src/mesa \
+ -I$(top_srcdir)/src/mesa \
+ -I$(top_builddir)/src/compiler/glsl \
+ $(DEFINES)
+
+TESTS = st-renumerate-test
+check_PROGRAMS = st-renumerate-test
+
+st_renumerate_test_SOURCES = \
+ test_glsl_to_tgsi_lifetime.cpp
+
+st_renumerate_test_LDFLAGS = \
+ $(LLVM_LDFLAGS)
+
+st_renumerate_test_LDADD = \
+ $(top_builddir)/src/mesa/libmesagallium.la \
+ $(top_builddir)/src/mapi/shared-glapi/libglapi.la \
+ $(top_builddir)/src/gallium/auxiliary/libgallium.la \
+ $(top_builddir)/src/util/libmesautil.la \
+ $(top_builddir)/src/gtest/libgtest.la \
+ $(GALLIUM_COMMON_LIB_DEPS) \
+ $(LLVM_LIBS)
diff --git a/lib/mesa/src/mesa/state_tracker/tests/Makefile.in b/lib/mesa/src/mesa/state_tracker/tests/Makefile.in
new file mode 100644
index 000000000..6b9c67a3a
--- /dev/null
+++ b/lib/mesa/src/mesa/state_tracker/tests/Makefile.in
@@ -0,0 +1,1266 @@
+# Makefile.in generated by automake 1.15.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2017 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+VPATH = @srcdir@
+am__is_gnu_make = { \
+ if test -z '$(MAKELEVEL)'; then \
+ false; \
+ elif test -n '$(MAKE_HOST)'; then \
+ true; \
+ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+ true; \
+ else \
+ false; \
+ fi; \
+}
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+target_triplet = @target@
+@HAVE_LIBDRM_TRUE@am__append_1 = \
+@HAVE_LIBDRM_TRUE@ $(LIBDRM_LIBS)
+
+@HAVE_DRISW_TRUE@am__append_2 = \
+@HAVE_DRISW_TRUE@ $(top_builddir)/src/gallium/winsys/sw/dri/libswdri.la
+
+@HAVE_DRISW_KMS_TRUE@am__append_3 = \
+@HAVE_DRISW_KMS_TRUE@ $(top_builddir)/src/gallium/winsys/sw/kms-dri/libswkmsdri.la \
+@HAVE_DRISW_KMS_TRUE@ $(LIBDRM_LIBS)
+
+TESTS = st-renumerate-test$(EXEEXT)
+check_PROGRAMS = st-renumerate-test$(EXEEXT)
+subdir = src/mesa/state_tracker/tests
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_compile_flag.m4 \
+ $(top_srcdir)/m4/ax_check_gnu_make.m4 \
+ $(top_srcdir)/m4/ax_check_python_mako_module.m4 \
+ $(top_srcdir)/m4/ax_gcc_builtin.m4 \
+ $(top_srcdir)/m4/ax_gcc_func_attribute.m4 \
+ $(top_srcdir)/m4/ax_prog_bison.m4 \
+ $(top_srcdir)/m4/ax_prog_flex.m4 \
+ $(top_srcdir)/m4/ax_pthread.m4 $(top_srcdir)/m4/libtool.m4 \
+ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
+ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/VERSION $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am_st_renumerate_test_OBJECTS = test_glsl_to_tgsi_lifetime.$(OBJEXT)
+st_renumerate_test_OBJECTS = $(am_st_renumerate_test_OBJECTS)
+am__DEPENDENCIES_1 =
+@HAVE_LIBDRM_TRUE@am__DEPENDENCIES_2 = $(am__DEPENDENCIES_1)
+am__DEPENDENCIES_3 = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2)
+st_renumerate_test_DEPENDENCIES = \
+ $(top_builddir)/src/mesa/libmesagallium.la \
+ $(top_builddir)/src/mapi/shared-glapi/libglapi.la \
+ $(top_builddir)/src/gallium/auxiliary/libgallium.la \
+ $(top_builddir)/src/util/libmesautil.la \
+ $(top_builddir)/src/gtest/libgtest.la $(am__DEPENDENCIES_3) \
+ $(am__DEPENDENCIES_1)
+AM_V_lt = $(am__v_lt_@AM_V@)
+am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 =
+st_renumerate_test_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
+ $(AM_CXXFLAGS) $(CXXFLAGS) $(st_renumerate_test_LDFLAGS) \
+ $(LDFLAGS) -o $@
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+DEFAULT_INCLUDES = -I.@am__isrc@
+depcomp = $(SHELL) $(top_srcdir)/bin/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CXXFLAGS) $(CXXFLAGS)
+AM_V_CXX = $(am__v_CXX_@AM_V@)
+am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@)
+am__v_CXX_0 = @echo " CXX " $@;
+am__v_CXX_1 =
+CXXLD = $(CXX)
+CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
+ $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CXXLD = $(am__v_CXXLD_@AM_V@)
+am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@)
+am__v_CXXLD_0 = @echo " CXXLD " $@;
+am__v_CXXLD_1 =
+SOURCES = $(st_renumerate_test_SOURCES)
+DIST_SOURCES = $(st_renumerate_test_SOURCES)
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates. Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+ BEGIN { nonempty = 0; } \
+ { items[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique. This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+ list='$(am__tagged_files)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+am__tty_colors_dummy = \
+ mgn= red= grn= lgn= blu= brg= std=; \
+ am__color_tests=no
+am__tty_colors = { \
+ $(am__tty_colors_dummy); \
+ if test "X$(AM_COLOR_TESTS)" = Xno; then \
+ am__color_tests=no; \
+ elif test "X$(AM_COLOR_TESTS)" = Xalways; then \
+ am__color_tests=yes; \
+ elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \
+ am__color_tests=yes; \
+ fi; \
+ if test $$am__color_tests = yes; then \
+ red=''; \
+ grn=''; \
+ lgn=''; \
+ blu=''; \
+ mgn=''; \
+ brg=''; \
+ std=''; \
+ fi; \
+}
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+ test -z "$$files" \
+ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+ $(am__cd) "$$dir" && rm -f $$files; }; \
+ }
+am__recheck_rx = ^[ ]*:recheck:[ ]*
+am__global_test_result_rx = ^[ ]*:global-test-result:[ ]*
+am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]*
+# A command that, given a newline-separated list of test names on the
+# standard input, print the name of the tests that are to be re-run
+# upon "make recheck".
+am__list_recheck_tests = $(AWK) '{ \
+ recheck = 1; \
+ while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+ { \
+ if (rc < 0) \
+ { \
+ if ((getline line2 < ($$0 ".log")) < 0) \
+ recheck = 0; \
+ break; \
+ } \
+ else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \
+ { \
+ recheck = 0; \
+ break; \
+ } \
+ else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \
+ { \
+ break; \
+ } \
+ }; \
+ if (recheck) \
+ print $$0; \
+ close ($$0 ".trs"); \
+ close ($$0 ".log"); \
+}'
+# A command that, given a newline-separated list of test names on the
+# standard input, create the global log from their .trs and .log files.
+am__create_global_log = $(AWK) ' \
+function fatal(msg) \
+{ \
+ print "fatal: making $@: " msg | "cat >&2"; \
+ exit 1; \
+} \
+function rst_section(header) \
+{ \
+ print header; \
+ len = length(header); \
+ for (i = 1; i <= len; i = i + 1) \
+ printf "="; \
+ printf "\n\n"; \
+} \
+{ \
+ copy_in_global_log = 1; \
+ global_test_result = "RUN"; \
+ while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+ { \
+ if (rc < 0) \
+ fatal("failed to read from " $$0 ".trs"); \
+ if (line ~ /$(am__global_test_result_rx)/) \
+ { \
+ sub("$(am__global_test_result_rx)", "", line); \
+ sub("[ ]*$$", "", line); \
+ global_test_result = line; \
+ } \
+ else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \
+ copy_in_global_log = 0; \
+ }; \
+ if (copy_in_global_log) \
+ { \
+ rst_section(global_test_result ": " $$0); \
+ while ((rc = (getline line < ($$0 ".log"))) != 0) \
+ { \
+ if (rc < 0) \
+ fatal("failed to read from " $$0 ".log"); \
+ print line; \
+ }; \
+ printf "\n"; \
+ }; \
+ close ($$0 ".trs"); \
+ close ($$0 ".log"); \
+}'
+# Restructured Text title.
+am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; }
+# Solaris 10 'make', and several other traditional 'make' implementations,
+# pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it
+# by disabling -e (using the XSI extension "set +e") if it's set.
+am__sh_e_setup = case $$- in *e*) set +e;; esac
+# Default flags passed to test drivers.
+am__common_driver_flags = \
+ --color-tests "$$am__color_tests" \
+ --enable-hard-errors "$$am__enable_hard_errors" \
+ --expect-failure "$$am__expect_failure"
+# To be inserted before the command running the test. Creates the
+# directory for the log if needed. Stores in $dir the directory
+# containing $f, in $tst the test, in $log the log. Executes the
+# developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and
+# passes TESTS_ENVIRONMENT. Set up options for the wrapper that
+# will run the test scripts (or their associated LOG_COMPILER, if
+# thy have one).
+am__check_pre = \
+$(am__sh_e_setup); \
+$(am__vpath_adj_setup) $(am__vpath_adj) \
+$(am__tty_colors); \
+srcdir=$(srcdir); export srcdir; \
+case "$@" in \
+ */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \
+ *) am__odir=.;; \
+esac; \
+test "x$$am__odir" = x"." || test -d "$$am__odir" \
+ || $(MKDIR_P) "$$am__odir" || exit $$?; \
+if test -f "./$$f"; then dir=./; \
+elif test -f "$$f"; then dir=; \
+else dir="$(srcdir)/"; fi; \
+tst=$$dir$$f; log='$@'; \
+if test -n '$(DISABLE_HARD_ERRORS)'; then \
+ am__enable_hard_errors=no; \
+else \
+ am__enable_hard_errors=yes; \
+fi; \
+case " $(XFAIL_TESTS) " in \
+ *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \
+ am__expect_failure=yes;; \
+ *) \
+ am__expect_failure=no;; \
+esac; \
+$(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT)
+# A shell command to get the names of the tests scripts with any registered
+# extension removed (i.e., equivalently, the names of the test logs, with
+# the '.log' extension removed). The result is saved in the shell variable
+# '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly,
+# we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)",
+# since that might cause problem with VPATH rewrites for suffix-less tests.
+# See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'.
+am__set_TESTS_bases = \
+ bases='$(TEST_LOGS)'; \
+ bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \
+ bases=`echo $$bases`
+RECHECK_LOGS = $(TEST_LOGS)
+AM_RECURSIVE_TARGETS = check recheck
+TEST_SUITE_LOG = test-suite.log
+TEST_EXTENSIONS = @EXEEXT@ .test
+LOG_DRIVER = $(SHELL) $(top_srcdir)/bin/test-driver
+LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS)
+am__set_b = \
+ case '$@' in \
+ */*) \
+ case '$*' in \
+ */*) b='$*';; \
+ *) b=`echo '$@' | sed 's/\.log$$//'`; \
+ esac;; \
+ *) \
+ b='$*';; \
+ esac
+am__test_logs1 = $(TESTS:=.log)
+am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log)
+TEST_LOGS = $(am__test_logs2:.test.log=.log)
+TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/bin/test-driver
+TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \
+ $(TEST_LOG_FLAGS)
+am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/bin/depcomp \
+ $(top_srcdir)/bin/test-driver \
+ $(top_srcdir)/src/gallium/Automake.inc
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMDGPU_CFLAGS = @AMDGPU_CFLAGS@
+AMDGPU_LIBS = @AMDGPU_LIBS@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+ANDROID_CFLAGS = @ANDROID_CFLAGS@
+ANDROID_LIBS = @ANDROID_LIBS@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BSYMBOLIC = @BSYMBOLIC@
+CC = @CC@
+CCAS = @CCAS@
+CCASDEPMODE = @CCASDEPMODE@
+CCASFLAGS = @CCASFLAGS@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CLANG_RESOURCE_DIR = @CLANG_RESOURCE_DIR@
+CLOCK_LIB = @CLOCK_LIB@
+CLOVER_STD_OVERRIDE = @CLOVER_STD_OVERRIDE@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+D3D_DRIVER_INSTALL_DIR = @D3D_DRIVER_INSTALL_DIR@
+DEFINES = @DEFINES@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DLOPEN_LIBS = @DLOPEN_LIBS@
+DRI2PROTO_CFLAGS = @DRI2PROTO_CFLAGS@
+DRI2PROTO_LIBS = @DRI2PROTO_LIBS@
+DRIGL_CFLAGS = @DRIGL_CFLAGS@
+DRIGL_LIBS = @DRIGL_LIBS@
+DRI_DRIVER_INSTALL_DIR = @DRI_DRIVER_INSTALL_DIR@
+DRI_DRIVER_SEARCH_DIR = @DRI_DRIVER_SEARCH_DIR@
+DRI_LIB_DEPS = @DRI_LIB_DEPS@
+DRI_PC_REQ_PRIV = @DRI_PC_REQ_PRIV@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGL_CFLAGS = @EGL_CFLAGS@
+EGL_LIB_DEPS = @EGL_LIB_DEPS@
+EGL_NATIVE_PLATFORM = @EGL_NATIVE_PLATFORM@
+EGREP = @EGREP@
+ETNAVIV_CFLAGS = @ETNAVIV_CFLAGS@
+ETNAVIV_LIBS = @ETNAVIV_LIBS@
+EXEEXT = @EXEEXT@
+EXPAT_CFLAGS = @EXPAT_CFLAGS@
+EXPAT_LIBS = @EXPAT_LIBS@
+FGREP = @FGREP@
+FREEDRENO_CFLAGS = @FREEDRENO_CFLAGS@
+FREEDRENO_LIBS = @FREEDRENO_LIBS@
+GALLIUM_PIPE_LOADER_DEFINES = @GALLIUM_PIPE_LOADER_DEFINES@
+GBM_PC_LIB_PRIV = @GBM_PC_LIB_PRIV@
+GBM_PC_REQ_PRIV = @GBM_PC_REQ_PRIV@
+GC_SECTIONS = @GC_SECTIONS@
+GLESv1_CM_LIB_DEPS = @GLESv1_CM_LIB_DEPS@
+GLESv1_CM_PC_LIB_PRIV = @GLESv1_CM_PC_LIB_PRIV@
+GLESv2_LIB_DEPS = @GLESv2_LIB_DEPS@
+GLESv2_PC_LIB_PRIV = @GLESv2_PC_LIB_PRIV@
+GLPROTO_CFLAGS = @GLPROTO_CFLAGS@
+GLPROTO_LIBS = @GLPROTO_LIBS@
+GLVND_CFLAGS = @GLVND_CFLAGS@
+GLVND_LIBS = @GLVND_LIBS@
+GLX_TLS = @GLX_TLS@
+GL_LIB = @GL_LIB@
+GL_LIB_DEPS = @GL_LIB_DEPS@
+GL_PC_CFLAGS = @GL_PC_CFLAGS@
+GL_PC_LIB_PRIV = @GL_PC_LIB_PRIV@
+GL_PC_REQ_PRIV = @GL_PC_REQ_PRIV@
+GREP = @GREP@
+HAVE_XF86VIDMODE = @HAVE_XF86VIDMODE@
+I915_CFLAGS = @I915_CFLAGS@
+I915_LIBS = @I915_LIBS@
+INDENT = @INDENT@
+INDENT_FLAGS = @INDENT_FLAGS@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LD_NO_UNDEFINED = @LD_NO_UNDEFINED@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBATOMIC_LIBS = @LIBATOMIC_LIBS@
+LIBCLC_INCLUDEDIR = @LIBCLC_INCLUDEDIR@
+LIBCLC_LIBEXECDIR = @LIBCLC_LIBEXECDIR@
+LIBDRM_CFLAGS = @LIBDRM_CFLAGS@
+LIBDRM_LIBS = @LIBDRM_LIBS@
+LIBELF_CFLAGS = @LIBELF_CFLAGS@
+LIBELF_LIBS = @LIBELF_LIBS@
+LIBGLVND_DATADIR = @LIBGLVND_DATADIR@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBSENSORS_LIBS = @LIBSENSORS_LIBS@
+LIBTOOL = @LIBTOOL@
+LIBUNWIND_CFLAGS = @LIBUNWIND_CFLAGS@
+LIBUNWIND_LIBS = @LIBUNWIND_LIBS@
+LIB_DIR = @LIB_DIR@
+LIB_EXT = @LIB_EXT@
+LIPO = @LIPO@
+LLVM_CFLAGS = @LLVM_CFLAGS@
+LLVM_CONFIG = @LLVM_CONFIG@
+LLVM_CXXFLAGS = @LLVM_CXXFLAGS@
+LLVM_INCLUDEDIR = @LLVM_INCLUDEDIR@
+LLVM_LDFLAGS = @LLVM_LDFLAGS@
+LLVM_LIBS = @LLVM_LIBS@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+MSVC2013_COMPAT_CFLAGS = @MSVC2013_COMPAT_CFLAGS@
+MSVC2013_COMPAT_CXXFLAGS = @MSVC2013_COMPAT_CXXFLAGS@
+NINE_MAJOR = @NINE_MAJOR@
+NINE_MINOR = @NINE_MINOR@
+NINE_TINY = @NINE_TINY@
+NINE_VERSION = @NINE_VERSION@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NOUVEAU_CFLAGS = @NOUVEAU_CFLAGS@
+NOUVEAU_LIBS = @NOUVEAU_LIBS@
+NVVIEUX_CFLAGS = @NVVIEUX_CFLAGS@
+NVVIEUX_LIBS = @NVVIEUX_LIBS@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OMX_BELLAGIO_CFLAGS = @OMX_BELLAGIO_CFLAGS@
+OMX_BELLAGIO_LIBS = @OMX_BELLAGIO_LIBS@
+OMX_BELLAGIO_LIB_INSTALL_DIR = @OMX_BELLAGIO_LIB_INSTALL_DIR@
+OPENCL_LIBNAME = @OPENCL_LIBNAME@
+OPENCL_VERSION = @OPENCL_VERSION@
+OSMESA_LIB = @OSMESA_LIB@
+OSMESA_LIB_DEPS = @OSMESA_LIB_DEPS@
+OSMESA_PC_LIB_PRIV = @OSMESA_PC_LIB_PRIV@
+OSMESA_PC_REQ = @OSMESA_PC_REQ@
+OSMESA_VERSION = @OSMESA_VERSION@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+POSIX_SHELL = @POSIX_SHELL@
+PTHREADSTUBS_CFLAGS = @PTHREADSTUBS_CFLAGS@
+PTHREADSTUBS_LIBS = @PTHREADSTUBS_LIBS@
+PTHREAD_CC = @PTHREAD_CC@
+PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
+PTHREAD_LIBS = @PTHREAD_LIBS@
+PWR8_CFLAGS = @PWR8_CFLAGS@
+PYTHON2 = @PYTHON2@
+RADEON_CFLAGS = @RADEON_CFLAGS@
+RADEON_LIBS = @RADEON_LIBS@
+RANLIB = @RANLIB@
+RM = @RM@
+SED = @SED@
+SELINUX_CFLAGS = @SELINUX_CFLAGS@
+SELINUX_LIBS = @SELINUX_LIBS@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SIMPENROSE_CFLAGS = @SIMPENROSE_CFLAGS@
+SIMPENROSE_LIBS = @SIMPENROSE_LIBS@
+SSE41_CFLAGS = @SSE41_CFLAGS@
+STRIP = @STRIP@
+SWR_AVX2_CXXFLAGS = @SWR_AVX2_CXXFLAGS@
+SWR_AVX_CXXFLAGS = @SWR_AVX_CXXFLAGS@
+SWR_CXX11_CXXFLAGS = @SWR_CXX11_CXXFLAGS@
+SWR_KNL_CXXFLAGS = @SWR_KNL_CXXFLAGS@
+SWR_SKX_CXXFLAGS = @SWR_SKX_CXXFLAGS@
+VALGRIND_CFLAGS = @VALGRIND_CFLAGS@
+VALGRIND_LIBS = @VALGRIND_LIBS@
+VA_CFLAGS = @VA_CFLAGS@
+VA_LIBS = @VA_LIBS@
+VA_LIB_INSTALL_DIR = @VA_LIB_INSTALL_DIR@
+VA_MAJOR = @VA_MAJOR@
+VA_MINOR = @VA_MINOR@
+VC5_SIMULATOR_CFLAGS = @VC5_SIMULATOR_CFLAGS@
+VC5_SIMULATOR_LIBS = @VC5_SIMULATOR_LIBS@
+VDPAU_CFLAGS = @VDPAU_CFLAGS@
+VDPAU_LIBS = @VDPAU_LIBS@
+VDPAU_LIB_INSTALL_DIR = @VDPAU_LIB_INSTALL_DIR@
+VDPAU_MAJOR = @VDPAU_MAJOR@
+VDPAU_MINOR = @VDPAU_MINOR@
+VERSION = @VERSION@
+VISIBILITY_CFLAGS = @VISIBILITY_CFLAGS@
+VISIBILITY_CXXFLAGS = @VISIBILITY_CXXFLAGS@
+VL_CFLAGS = @VL_CFLAGS@
+VL_LIBS = @VL_LIBS@
+VULKAN_ICD_INSTALL_DIR = @VULKAN_ICD_INSTALL_DIR@
+WAYLAND_CLIENT_CFLAGS = @WAYLAND_CLIENT_CFLAGS@
+WAYLAND_CLIENT_LIBS = @WAYLAND_CLIENT_LIBS@
+WAYLAND_PROTOCOLS_DATADIR = @WAYLAND_PROTOCOLS_DATADIR@
+WAYLAND_SCANNER = @WAYLAND_SCANNER@
+WAYLAND_SCANNER_CFLAGS = @WAYLAND_SCANNER_CFLAGS@
+WAYLAND_SCANNER_LIBS = @WAYLAND_SCANNER_LIBS@
+WAYLAND_SERVER_CFLAGS = @WAYLAND_SERVER_CFLAGS@
+WAYLAND_SERVER_LIBS = @WAYLAND_SERVER_LIBS@
+WNO_OVERRIDE_INIT = @WNO_OVERRIDE_INIT@
+X11_INCLUDES = @X11_INCLUDES@
+XA_MAJOR = @XA_MAJOR@
+XA_MINOR = @XA_MINOR@
+XA_TINY = @XA_TINY@
+XA_VERSION = @XA_VERSION@
+XCB_DRI2_CFLAGS = @XCB_DRI2_CFLAGS@
+XCB_DRI2_LIBS = @XCB_DRI2_LIBS@
+XCB_DRI3_CFLAGS = @XCB_DRI3_CFLAGS@
+XCB_DRI3_LIBS = @XCB_DRI3_LIBS@
+XF86VIDMODE_CFLAGS = @XF86VIDMODE_CFLAGS@
+XF86VIDMODE_LIBS = @XF86VIDMODE_LIBS@
+XLIBGL_CFLAGS = @XLIBGL_CFLAGS@
+XLIBGL_LIBS = @XLIBGL_LIBS@
+XVMC_CFLAGS = @XVMC_CFLAGS@
+XVMC_LIBS = @XVMC_LIBS@
+XVMC_LIB_INSTALL_DIR = @XVMC_LIB_INSTALL_DIR@
+XVMC_MAJOR = @XVMC_MAJOR@
+XVMC_MINOR = @XVMC_MINOR@
+YACC = @YACC@
+YFLAGS = @YFLAGS@
+ZLIB_CFLAGS = @ZLIB_CFLAGS@
+ZLIB_LIBS = @ZLIB_LIBS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+acv_mako_found = @acv_mako_found@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+ax_pthread_config = @ax_pthread_config@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+ifGNUmake = @ifGNUmake@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+runstatedir = @runstatedir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+GALLIUM_CFLAGS = \
+ -I$(top_srcdir)/include \
+ -I$(top_srcdir)/src \
+ -I$(top_srcdir)/src/gallium/include \
+ -I$(top_srcdir)/src/gallium/auxiliary \
+ $(DEFINES)
+
+
+# src/gallium/auxiliary must appear before src/gallium/drivers
+# because there are stupidly two rbug_context.h files in
+# different directories, and which one is included by the
+# preprocessor is determined by the ordering of the -I flags.
+GALLIUM_DRIVER_CFLAGS = \
+ -I$(srcdir)/include \
+ -I$(top_srcdir)/src \
+ -I$(top_srcdir)/include \
+ -I$(top_srcdir)/src/gallium/include \
+ -I$(top_srcdir)/src/gallium/auxiliary \
+ -I$(top_srcdir)/src/gallium/drivers \
+ -I$(top_srcdir)/src/gallium/winsys \
+ $(DEFINES) \
+ $(VISIBILITY_CFLAGS)
+
+GALLIUM_DRIVER_CXXFLAGS = \
+ -I$(srcdir)/include \
+ -I$(top_srcdir)/src \
+ -I$(top_srcdir)/include \
+ -I$(top_srcdir)/src/gallium/include \
+ -I$(top_srcdir)/src/gallium/auxiliary \
+ -I$(top_srcdir)/src/gallium/drivers \
+ -I$(top_srcdir)/src/gallium/winsys \
+ $(DEFINES) \
+ $(VISIBILITY_CXXFLAGS)
+
+GALLIUM_TARGET_CFLAGS = \
+ -I$(top_srcdir)/src \
+ -I$(top_srcdir)/include \
+ -I$(top_srcdir)/src/loader \
+ -I$(top_srcdir)/src/gallium/include \
+ -I$(top_srcdir)/src/gallium/auxiliary \
+ -I$(top_srcdir)/src/gallium/drivers \
+ -I$(top_srcdir)/src/gallium/winsys \
+ -I$(top_builddir)/src/util/ \
+ -I$(top_builddir)/src/gallium/drivers/ \
+ $(DEFINES) \
+ $(PTHREAD_CFLAGS) \
+ $(LIBDRM_CFLAGS) \
+ $(VISIBILITY_CFLAGS)
+
+GALLIUM_COMMON_LIB_DEPS = -lm $(LIBUNWIND_LIBS) $(LIBSENSORS_LIBS) \
+ $(CLOCK_LIB) $(PTHREAD_LIBS) $(DLOPEN_LIBS) $(am__append_1)
+GALLIUM_WINSYS_CFLAGS = \
+ -I$(top_srcdir)/src \
+ -I$(top_srcdir)/include \
+ -I$(top_srcdir)/src/gallium/include \
+ -I$(top_srcdir)/src/gallium/auxiliary \
+ $(DEFINES) \
+ $(VISIBILITY_CFLAGS)
+
+GALLIUM_PIPE_LOADER_WINSYS_LIBS = \
+ $(top_builddir)/src/gallium/winsys/sw/null/libws_null.la \
+ $(top_builddir)/src/gallium/winsys/sw/wrapper/libwsw.la \
+ $(am__append_2) $(am__append_3)
+AM_CFLAGS = \
+ $(PTHREAD_CFLAGS)
+
+AM_CXXFLAGS = \
+ $(GALLIUM_DRIVER_CXXFLAGS) \
+ -std=c++11
+
+AM_CPPFLAGS = \
+ -I$(top_srcdir)/src/gtest/include \
+ -I$(top_srcdir)/src/mapi \
+ -I$(top_builddir)/src/mesa \
+ -I$(top_srcdir)/src/mesa \
+ -I$(top_builddir)/src/compiler/glsl \
+ $(DEFINES)
+
+st_renumerate_test_SOURCES = \
+ test_glsl_to_tgsi_lifetime.cpp
+
+st_renumerate_test_LDFLAGS = \
+ $(LLVM_LDFLAGS)
+
+st_renumerate_test_LDADD = \
+ $(top_builddir)/src/mesa/libmesagallium.la \
+ $(top_builddir)/src/mapi/shared-glapi/libglapi.la \
+ $(top_builddir)/src/gallium/auxiliary/libgallium.la \
+ $(top_builddir)/src/util/libmesautil.la \
+ $(top_builddir)/src/gtest/libgtest.la \
+ $(GALLIUM_COMMON_LIB_DEPS) \
+ $(LLVM_LIBS)
+
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .cpp .lo .log .o .obj .test .test$(EXEEXT) .trs
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(top_srcdir)/src/gallium/Automake.inc $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/mesa/state_tracker/tests/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --foreign src/mesa/state_tracker/tests/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+$(top_srcdir)/src/gallium/Automake.inc $(am__empty):
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+clean-checkPROGRAMS:
+ @list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \
+ echo " rm -f" $$list; \
+ rm -f $$list || exit $$?; \
+ test -n "$(EXEEXT)" || exit 0; \
+ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f" $$list; \
+ rm -f $$list
+
+st-renumerate-test$(EXEEXT): $(st_renumerate_test_OBJECTS) $(st_renumerate_test_DEPENDENCIES) $(EXTRA_st_renumerate_test_DEPENDENCIES)
+ @rm -f st-renumerate-test$(EXEEXT)
+ $(AM_V_CXXLD)$(st_renumerate_test_LINK) $(st_renumerate_test_OBJECTS) $(st_renumerate_test_LDADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_glsl_to_tgsi_lifetime.Po@am__quote@
+
+.cpp.o:
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
+@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+@am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $<
+
+.cpp.obj:
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
+@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
+@am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.cpp.lo:
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
+@am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+@am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+ID: $(am__tagged_files)
+ $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ set x; \
+ here=`pwd`; \
+ $(am__define_uniq_tagged_files); \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ $(am__define_uniq_tagged_files); \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+ list='$(am__tagged_files)'; \
+ case "$(srcdir)" in \
+ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+ *) sdir=$(subdir)/$(srcdir) ;; \
+ esac; \
+ for i in $$list; do \
+ if test -f "$$i"; then \
+ echo "$(subdir)/$$i"; \
+ else \
+ echo "$$sdir/$$i"; \
+ fi; \
+ done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+# Recover from deleted '.trs' file; this should ensure that
+# "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create
+# both 'foo.log' and 'foo.trs'. Break the recipe in two subshells
+# to avoid problems with "make -n".
+.log.trs:
+ rm -f $< $@
+ $(MAKE) $(AM_MAKEFLAGS) $<
+
+# Leading 'am--fnord' is there to ensure the list of targets does not
+# expand to empty, as could happen e.g. with make check TESTS=''.
+am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck)
+am--force-recheck:
+ @:
+
+$(TEST_SUITE_LOG): $(TEST_LOGS)
+ @$(am__set_TESTS_bases); \
+ am__f_ok () { test -f "$$1" && test -r "$$1"; }; \
+ redo_bases=`for i in $$bases; do \
+ am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \
+ done`; \
+ if test -n "$$redo_bases"; then \
+ redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \
+ redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \
+ if $(am__make_dryrun); then :; else \
+ rm -f $$redo_logs && rm -f $$redo_results || exit 1; \
+ fi; \
+ fi; \
+ if test -n "$$am__remaking_logs"; then \
+ echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \
+ "recursion detected" >&2; \
+ elif test -n "$$redo_logs"; then \
+ am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \
+ fi; \
+ if $(am__make_dryrun); then :; else \
+ st=0; \
+ errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \
+ for i in $$redo_bases; do \
+ test -f $$i.trs && test -r $$i.trs \
+ || { echo "$$errmsg $$i.trs" >&2; st=1; }; \
+ test -f $$i.log && test -r $$i.log \
+ || { echo "$$errmsg $$i.log" >&2; st=1; }; \
+ done; \
+ test $$st -eq 0 || exit 1; \
+ fi
+ @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \
+ ws='[ ]'; \
+ results=`for b in $$bases; do echo $$b.trs; done`; \
+ test -n "$$results" || results=/dev/null; \
+ all=` grep "^$$ws*:test-result:" $$results | wc -l`; \
+ pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \
+ fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \
+ skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \
+ xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \
+ xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \
+ error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \
+ if test `expr $$fail + $$xpass + $$error` -eq 0; then \
+ success=true; \
+ else \
+ success=false; \
+ fi; \
+ br='==================='; br=$$br$$br$$br$$br; \
+ result_count () \
+ { \
+ if test x"$$1" = x"--maybe-color"; then \
+ maybe_colorize=yes; \
+ elif test x"$$1" = x"--no-color"; then \
+ maybe_colorize=no; \
+ else \
+ echo "$@: invalid 'result_count' usage" >&2; exit 4; \
+ fi; \
+ shift; \
+ desc=$$1 count=$$2; \
+ if test $$maybe_colorize = yes && test $$count -gt 0; then \
+ color_start=$$3 color_end=$$std; \
+ else \
+ color_start= color_end=; \
+ fi; \
+ echo "$${color_start}# $$desc $$count$${color_end}"; \
+ }; \
+ create_testsuite_report () \
+ { \
+ result_count $$1 "TOTAL:" $$all "$$brg"; \
+ result_count $$1 "PASS: " $$pass "$$grn"; \
+ result_count $$1 "SKIP: " $$skip "$$blu"; \
+ result_count $$1 "XFAIL:" $$xfail "$$lgn"; \
+ result_count $$1 "FAIL: " $$fail "$$red"; \
+ result_count $$1 "XPASS:" $$xpass "$$red"; \
+ result_count $$1 "ERROR:" $$error "$$mgn"; \
+ }; \
+ { \
+ echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \
+ $(am__rst_title); \
+ create_testsuite_report --no-color; \
+ echo; \
+ echo ".. contents:: :depth: 2"; \
+ echo; \
+ for b in $$bases; do echo $$b; done \
+ | $(am__create_global_log); \
+ } >$(TEST_SUITE_LOG).tmp || exit 1; \
+ mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \
+ if $$success; then \
+ col="$$grn"; \
+ else \
+ col="$$red"; \
+ test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \
+ fi; \
+ echo "$${col}$$br$${std}"; \
+ echo "$${col}Testsuite summary for $(PACKAGE_STRING)$${std}"; \
+ echo "$${col}$$br$${std}"; \
+ create_testsuite_report --maybe-color; \
+ echo "$$col$$br$$std"; \
+ if $$success; then :; else \
+ echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \
+ if test -n "$(PACKAGE_BUGREPORT)"; then \
+ echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \
+ fi; \
+ echo "$$col$$br$$std"; \
+ fi; \
+ $$success || exit 1
+
+check-TESTS:
+ @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list
+ @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list
+ @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+ @set +e; $(am__set_TESTS_bases); \
+ log_list=`for i in $$bases; do echo $$i.log; done`; \
+ trs_list=`for i in $$bases; do echo $$i.trs; done`; \
+ log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \
+ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \
+ exit $$?;
+recheck: all $(check_PROGRAMS)
+ @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+ @set +e; $(am__set_TESTS_bases); \
+ bases=`for i in $$bases; do echo $$i; done \
+ | $(am__list_recheck_tests)` || exit 1; \
+ log_list=`for i in $$bases; do echo $$i.log; done`; \
+ log_list=`echo $$log_list`; \
+ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \
+ am__force_recheck=am--force-recheck \
+ TEST_LOGS="$$log_list"; \
+ exit $$?
+st-renumerate-test.log: st-renumerate-test$(EXEEXT)
+ @p='st-renumerate-test$(EXEEXT)'; \
+ b='st-renumerate-test'; \
+ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+.test.log:
+ @p='$<'; \
+ $(am__set_b); \
+ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+@am__EXEEXT_TRUE@.test$(EXEEXT).log:
+@am__EXEEXT_TRUE@ @p='$<'; \
+@am__EXEEXT_TRUE@ $(am__set_b); \
+@am__EXEEXT_TRUE@ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+@am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \
+@am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+@am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT)
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+ $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS)
+ $(MAKE) $(AM_MAKEFLAGS) check-TESTS
+check: check-am
+all-am: Makefile
+installdirs:
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+ -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS)
+ -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs)
+ -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-checkPROGRAMS clean-generic clean-libtool \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: check-am install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am check check-TESTS check-am clean \
+ clean-checkPROGRAMS clean-generic clean-libtool cscopelist-am \
+ ctags ctags-am distclean distclean-compile distclean-generic \
+ distclean-libtool distclean-tags distdir dvi dvi-am html \
+ html-am info info-am install install-am install-data \
+ install-data-am install-dvi install-dvi-am install-exec \
+ install-exec-am install-html install-html-am install-info \
+ install-info-am install-man install-pdf install-pdf-am \
+ install-ps install-ps-am install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ recheck tags tags-am uninstall uninstall-am
+
+.PRECIOUS: Makefile
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/lib/mesa/src/mesa/state_tracker/tests/test_glsl_to_tgsi_lifetime.cpp b/lib/mesa/src/mesa/state_tracker/tests/test_glsl_to_tgsi_lifetime.cpp
new file mode 100644
index 000000000..93f4020eb
--- /dev/null
+++ b/lib/mesa/src/mesa/state_tracker/tests/test_glsl_to_tgsi_lifetime.cpp
@@ -0,0 +1,1600 @@
+/*
+ * Copyright © 2017 Gert Wollny
+ *
+ * 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 <state_tracker/st_glsl_to_tgsi_temprename.h>
+#include <tgsi/tgsi_ureg.h>
+#include <tgsi/tgsi_info.h>
+#include <compiler/glsl/list.h>
+#include <mesa/program/prog_instruction.h>
+
+#include <utility>
+#include <gtest/gtest.h>
+
+using std::vector;
+using std::pair;
+using std::make_pair;
+
+/* A line to describe a TGSI instruction for building mock shaders. */
+struct MockCodeline {
+ MockCodeline(unsigned _op): op(_op) {}
+ MockCodeline(unsigned _op, const vector<int>& _dst, const vector<int>& _src, const vector<int>&_to):
+ op(_op), dst(_dst), src(_src), tex_offsets(_to){}
+ unsigned op;
+ vector<int> dst;
+ vector<int> src;
+ vector<int> tex_offsets;
+};
+
+/* A line to describe a TGSI instruction with swizzeling and write makss
+ * for building mock shaders.
+ */
+struct MockCodelineWithSwizzle {
+ MockCodelineWithSwizzle(unsigned _op): op(_op) {}
+ MockCodelineWithSwizzle(unsigned _op, const vector<pair<int,int>>& _dst,
+ const vector<pair<int, const char *>>& _src,
+ const vector<pair<int, const char *>>&_to):
+ op(_op), dst(_dst), src(_src), tex_offsets(_to){}
+ unsigned op;
+ vector<pair<int,int>> dst;
+ vector<pair<int, const char *>> src;
+ vector<pair<int, const char *>> tex_offsets;
+};
+
+/* A few constants that will notbe tracked as temporary registers by the
+ * mock shader.
+ */
+const int in0 = -1;
+const int in1 = -2;
+const int in2 = -3;
+
+const int out0 = -1;
+const int out1 = -2;
+
+class MockShader {
+public:
+ MockShader(const vector<MockCodeline>& source);
+ MockShader(const vector<MockCodelineWithSwizzle>& source);
+ ~MockShader();
+
+ void free();
+
+ exec_list* get_program() const;
+ int get_num_temps() const;
+private:
+ st_src_reg create_src_register(int src_idx);
+ st_dst_reg create_dst_register(int dst_idx);
+ st_src_reg create_src_register(int src_idx, const char *swizzle);
+ st_dst_reg create_dst_register(int dst_idx,int writemask);
+ exec_list* program;
+ int num_temps;
+ void *mem_ctx;
+};
+
+using expectation = vector<vector<int>>;
+
+class MesaTestWithMemCtx : public testing::Test {
+ void SetUp();
+ void TearDown();
+protected:
+ void *mem_ctx;
+};
+
+class LifetimeEvaluatorTest : public MesaTestWithMemCtx {
+protected:
+ void run(const vector<MockCodeline>& code, const expectation& e);
+ void run(const vector<MockCodelineWithSwizzle>& code, const expectation& e);
+private:
+ virtual void check(const vector<lifetime>& result, const expectation& e) = 0;
+};
+
+/* This is a test class to check the exact life times of
+ * registers. */
+class LifetimeEvaluatorExactTest : public LifetimeEvaluatorTest {
+protected:
+ void check(const vector<lifetime>& result, const expectation& e);
+};
+
+/* This test class checks that the life time covers at least
+ * in the expected range. It is used for cases where we know that
+ * a the implementation could be improved on estimating the minimal
+ * life time.
+ */
+class LifetimeEvaluatorAtLeastTest : public LifetimeEvaluatorTest {
+protected:
+ void check(const vector<lifetime>& result, const expectation& e);
+};
+
+/* With this test class the renaming mapping estimation is tested */
+class RegisterRemappingTest : public MesaTestWithMemCtx {
+protected:
+ void run(const vector<lifetime>& lt, const vector<int>& expect);
+};
+
+/* With this test class the combined lifetime estimation and renaming
+ * mepping estimation is tested
+ */
+class RegisterLifetimeAndRemappingTest : public RegisterRemappingTest {
+protected:
+ using RegisterRemappingTest::run;
+ template <typename CodeLine>
+ void run(const vector<CodeLine>& code, const vector<int>& expect);
+};
+
+template <typename CodeLine>
+void RegisterLifetimeAndRemappingTest::run(const vector<CodeLine>& code,
+ const vector<int>& expect)
+{
+ MockShader shader(code);
+ std::vector<lifetime> lt(shader.get_num_temps());
+ get_temp_registers_required_lifetimes(mem_ctx, shader.get_program(),
+ shader.get_num_temps(), &lt[0]);
+ this->run(lt, expect);
+}
+
+TEST_F(LifetimeEvaluatorExactTest, SimpleMoveAdd)
+{
+ const vector<MockCodeline> code = {
+ { TGSI_OPCODE_MOV, {1}, {in0}, {}},
+ { TGSI_OPCODE_UADD, {out0}, {1,in0}, {}},
+ { TGSI_OPCODE_END}
+ };
+ run(code, expectation({{-1,-1}, {0,1}}));
+}
+
+TEST_F(LifetimeEvaluatorExactTest, SimpleMoveAddMove)
+{
+ const vector<MockCodeline> code = {
+ { TGSI_OPCODE_MOV, {1}, {in0}, {}},
+ { TGSI_OPCODE_UADD, {2}, {1,in0}, {}},
+ { TGSI_OPCODE_MOV, {out0}, {2}, {}},
+ { TGSI_OPCODE_END}
+ };
+ run(code, expectation({{-1, -1}, {0,1}, {1,2}}));
+}
+
+/* Test whether the texoffst are actually visited by the
+ * merge algorithm. Note that it is of no importance
+ * what instruction is actually used, the MockShader class
+ * does not consider the details of the operation, only
+ * the number of arguments is of importance.
+ */
+TEST_F(LifetimeEvaluatorExactTest, SimpleOpWithTexoffset)
+{
+ const vector<MockCodeline> code = {
+ { TGSI_OPCODE_MOV, {1}, {in0}, {}},
+ { TGSI_OPCODE_MOV, {2}, {in1}, {}},
+ { TGSI_OPCODE_TEX, {out0}, {in0}, {1,2}},
+ { TGSI_OPCODE_END}
+ };
+ run(code, expectation({{-1, -1}, {0,2}, {1,2}}));
+}
+
+/* Simple register access involving a loop
+ * 1: must life up to then end of the loop
+ * 2: only needs to life from write to read
+ * 3: only needs to life from write to read outside the loop
+ */
+TEST_F(LifetimeEvaluatorExactTest, SimpleMoveInLoop)
+{
+ const vector<MockCodeline> code = {
+ { TGSI_OPCODE_MOV, {1}, {in0}, {}},
+ { TGSI_OPCODE_BGNLOOP },
+ { TGSI_OPCODE_UADD, {2}, {1,in0}, {}},
+ { TGSI_OPCODE_UADD, {3}, {1,2}, {}},
+ { TGSI_OPCODE_UADD, {3}, {3,in1}, {}},
+ { TGSI_OPCODE_ENDLOOP },
+ { TGSI_OPCODE_MOV, {out0}, {3}, {}},
+ { TGSI_OPCODE_END}
+ };
+ run (code, expectation({{-1,-1}, {0,5}, {2,3}, {3,6}}));
+}
+
+/* In loop if/else value written only in one path, and read later
+ * - value must survive the whole loop.
+ */
+TEST_F(LifetimeEvaluatorExactTest, MoveInIfInLoop)
+{
+ const vector<MockCodeline> code = {
+ { TGSI_OPCODE_MOV, {1}, {in0}, {}},
+ { TGSI_OPCODE_BGNLOOP },
+ { TGSI_OPCODE_IF, {}, {in1}, {}},
+ { TGSI_OPCODE_UADD, {2}, {1,in0}, {}},
+ { TGSI_OPCODE_ENDIF},
+ { TGSI_OPCODE_UADD, {3}, {1,2}, {}},
+ { TGSI_OPCODE_UADD, {3}, {3,in1}, {}},
+ { TGSI_OPCODE_ENDLOOP },
+ { TGSI_OPCODE_MOV, {out0}, {3}, {}},
+ { TGSI_OPCODE_END}
+ };
+ run (code, expectation({{-1,-1}, {0,7}, {1,7}, {5,8}}));
+}
+
+/* A non-dominant write within an IF can be ignored (if it is read
+ * later)
+ */
+TEST_F(LifetimeEvaluatorExactTest, NonDominantWriteinIfInLoop)
+{
+ const vector<MockCodeline> code = {
+ { TGSI_OPCODE_BGNLOOP },
+ { TGSI_OPCODE_MOV, {1}, {in0}, {}},
+ { TGSI_OPCODE_IF, {}, {in1}, {}},
+ { TGSI_OPCODE_MOV, {1}, {in1}, {}},
+ { TGSI_OPCODE_ENDIF},
+ { TGSI_OPCODE_UADD, {2}, {1,in1}, {}},
+ { TGSI_OPCODE_IF, {}, {2}, {}},
+ { TGSI_OPCODE_BRK},
+ { TGSI_OPCODE_ENDIF},
+ { TGSI_OPCODE_ENDLOOP },
+ { TGSI_OPCODE_MOV, {out0}, {2}, {}},
+ { TGSI_OPCODE_END}
+ };
+ run (code, expectation({{-1,-1}, {1,5}, {5,10}}));
+}
+
+/* In Nested loop if/else value written only in one path, and read later
+ * - value must survive the outer loop.
+ */
+TEST_F(LifetimeEvaluatorExactTest, MoveInIfInNestedLoop)
+{
+ const vector<MockCodeline> code = {
+ { TGSI_OPCODE_MOV, {1}, {in0}, {}},
+ { TGSI_OPCODE_BGNLOOP },
+ { TGSI_OPCODE_BGNLOOP },
+ { TGSI_OPCODE_IF, {}, {in1}, {} },
+ { TGSI_OPCODE_UADD, {2}, {1,in0}, {}},
+ { TGSI_OPCODE_ENDIF},
+ { TGSI_OPCODE_UADD, {3}, {1,2}, {}},
+ { TGSI_OPCODE_ENDLOOP },
+ { TGSI_OPCODE_ENDLOOP },
+ { TGSI_OPCODE_MOV, {out0}, {3}, {}},
+ { TGSI_OPCODE_END}
+ };
+ run (code, expectation({{-1,-1}, {0,8}, {1,8}, {6,9}}));
+}
+
+/* In loop if/else value written in both path, and read later
+ * - value must survive from first write to last read in loop
+ * for now we only check that the minimum life time is correct.
+ */
+TEST_F(LifetimeEvaluatorAtLeastTest, WriteInIfAndElseInLoop)
+{
+ const vector<MockCodeline> code = {
+ { TGSI_OPCODE_MOV, {1}, {in0}, {}},
+ { TGSI_OPCODE_BGNLOOP },
+ { TGSI_OPCODE_IF, {}, {1}, {}},
+ { TGSI_OPCODE_UADD, {2}, {1,in0}, {}},
+ { TGSI_OPCODE_ELSE },
+ { TGSI_OPCODE_MOV, {2}, {1}, {}},
+ { TGSI_OPCODE_ENDIF},
+ { TGSI_OPCODE_UADD, {3}, {1,2}, {}},
+ { TGSI_OPCODE_UADD, {3}, {3,in1}, {}},
+ { TGSI_OPCODE_ENDLOOP },
+ { TGSI_OPCODE_MOV, {out0}, {3}, {}},
+ { TGSI_OPCODE_END}
+ };
+ run (code, expectation({{-1,-1}, {0,9}, {3,7}, {7,10}}));
+}
+
+/* In loop if/else value written in both path, read in else path
+ * before write and also read later
+ * - value must survive the whole loop
+ */
+TEST_F(LifetimeEvaluatorExactTest, WriteInIfAndElseReadInElseInLoop)
+{
+ const vector<MockCodeline> code = {
+ { TGSI_OPCODE_MOV, {1}, {in0}, {}},
+ { TGSI_OPCODE_BGNLOOP },
+ { TGSI_OPCODE_IF, {}, {1}, {}},
+ { TGSI_OPCODE_UADD, {2}, {1,in0}, {}},
+ { TGSI_OPCODE_ELSE },
+ { TGSI_OPCODE_ADD, {2}, {1,2}, {}},
+ { TGSI_OPCODE_ENDIF},
+ { TGSI_OPCODE_UADD, {3}, {1,2}, {}},
+ { TGSI_OPCODE_UADD, {3}, {3,in1}, {}},
+ { TGSI_OPCODE_ENDLOOP },
+ { TGSI_OPCODE_MOV, {out0}, {3}, {}},
+ { TGSI_OPCODE_END}
+ };
+ run (code, expectation({{-1,-1}, {0,9}, {1,9}, {7,10}}));
+}
+
+/* In loop if/else read in one path before written in the same loop
+ * - value must survive the whole loop
+ */
+TEST_F(LifetimeEvaluatorExactTest, ReadInIfInLoopBeforeWrite)
+{
+ const vector<MockCodeline> code = {
+ { TGSI_OPCODE_MOV, {1}, {in0}, {}},
+ { TGSI_OPCODE_BGNLOOP },
+ { TGSI_OPCODE_IF, {}, {in0}, {}},
+ { TGSI_OPCODE_UADD, {2}, {1,3}, {}},
+ { TGSI_OPCODE_ENDIF},
+ { TGSI_OPCODE_UADD, {3}, {1,2}, {}},
+ { TGSI_OPCODE_UADD, {3}, {3,in1}, {}},
+ { TGSI_OPCODE_ENDLOOP },
+ { TGSI_OPCODE_MOV, {out0}, {3}, {}},
+ { TGSI_OPCODE_END}
+ };
+ run (code, expectation({{-1,-1}, {0,7}, {1,7}, {1,8}}));
+}
+
+/* In loop if/else read in one path before written in the same loop
+ * read after the loop, value must survivethe whole loop and
+ * to the read.
+ */
+TEST_F(LifetimeEvaluatorExactTest, ReadInLoopInIfBeforeWriteAndLifeToTheEnd)
+{
+ const vector<MockCodeline> code = {
+ { TGSI_OPCODE_BGNLOOP },
+ { TGSI_OPCODE_IF, {}, {in0}, {}},
+ { TGSI_OPCODE_MUL, {1}, {1,in1}, {}},
+ { TGSI_OPCODE_ENDIF},
+ { TGSI_OPCODE_UADD, {1}, {1,in1}, {}},
+ { TGSI_OPCODE_ENDLOOP },
+ { TGSI_OPCODE_MOV, {out0}, {1}, {}},
+ { TGSI_OPCODE_END}
+ };
+ run (code, expectation({{-1,-1}, {0,6}}));
+}
+
+/* In loop if/else read in one path before written in the same loop
+ * read after the loop, value must survivethe whole loop and
+ * to the read.
+ */
+TEST_F(LifetimeEvaluatorExactTest, ReadInLoopBeforeWriteAndLifeToTheEnd)
+{
+ const vector<MockCodeline> code = {
+ { TGSI_OPCODE_BGNLOOP },
+ { TGSI_OPCODE_MUL, {1}, {1,in1}, {}},
+ { TGSI_OPCODE_UADD, {1}, {1,in1}, {}},
+ { TGSI_OPCODE_ENDLOOP },
+ { TGSI_OPCODE_MOV, {out0}, {1}, {}},
+ { TGSI_OPCODE_END}
+ };
+ run (code, expectation({{-1,-1}, {0,4}}));
+}
+
+
+/* Write in nested ifs in loop, for now we do test whether the
+ * life time is at least what is required, but we know that the
+ * implementation doesn't do a full check and sets larger boundaries
+ */
+TEST_F(LifetimeEvaluatorAtLeastTest, NestedIfInLoopAlwaysWriteButNotPropagated)
+{
+ const vector<MockCodeline> code = {
+ { TGSI_OPCODE_BGNLOOP },
+ { TGSI_OPCODE_IF, {}, {in0}, {}},
+ { TGSI_OPCODE_IF, {}, {in0}, {}},
+ { TGSI_OPCODE_MOV, {1}, {in0}, {}},
+ { TGSI_OPCODE_ELSE},
+ { TGSI_OPCODE_MOV, {1}, {in0}, {}},
+ { TGSI_OPCODE_ENDIF},
+ { TGSI_OPCODE_ELSE},
+ { TGSI_OPCODE_IF, {}, {in0}, {}},
+ { TGSI_OPCODE_MOV, {1}, {in0}, {}},
+ { TGSI_OPCODE_ELSE},
+ { TGSI_OPCODE_MOV, {1}, {in0}, {}},
+ { TGSI_OPCODE_ENDIF},
+ { TGSI_OPCODE_ENDIF},
+ { TGSI_OPCODE_MOV, {out0}, {1}, {}},
+ { TGSI_OPCODE_ENDLOOP },
+ { TGSI_OPCODE_END}
+ };
+ run (code, expectation({{-1,-1}, {3,14}}));
+}
+
+/* The value is written in a loop and in a nested if, but
+ * not in all code paths, hence the value must survive the loop.
+ */
+TEST_F(LifetimeEvaluatorExactTest, NestedIfInLoopWriteNotAlways)
+{
+ const vector<MockCodeline> code = {
+ { TGSI_OPCODE_BGNLOOP },
+ { TGSI_OPCODE_IF, {}, {in0}, {}},
+ { TGSI_OPCODE_IF, {}, {in0}, {}},
+ { TGSI_OPCODE_MOV, {1}, {in0}, {}},
+ { TGSI_OPCODE_ELSE},
+ { TGSI_OPCODE_MOV, {1}, {in0}, {}},
+ { TGSI_OPCODE_ENDIF},
+ { TGSI_OPCODE_ELSE},
+ { TGSI_OPCODE_IF, {}, {in0}, {}},
+ { TGSI_OPCODE_MOV, {1}, {in0}, {}},
+ { TGSI_OPCODE_ENDIF},
+ { TGSI_OPCODE_ENDIF},
+ { TGSI_OPCODE_MOV, {out0}, {1}, {}},
+ { TGSI_OPCODE_ENDLOOP },
+ { TGSI_OPCODE_END}
+ };
+ run (code, expectation({{-1,-1}, {0,13}}));
+}
+
+/* A continue in the loop is not relevant */
+TEST_F(LifetimeEvaluatorExactTest, LoopWithWriteAfterContinue)
+{
+ const vector<MockCodeline> code = {
+ { TGSI_OPCODE_BGNLOOP },
+ { TGSI_OPCODE_IF, {}, {in0}, {}},
+ { TGSI_OPCODE_CONT},
+ { TGSI_OPCODE_ENDIF},
+ { TGSI_OPCODE_MOV, {1}, {in0}, {}},
+ { TGSI_OPCODE_ENDLOOP },
+ { TGSI_OPCODE_MOV, {out0}, {1}, {}},
+ { TGSI_OPCODE_END}
+ };
+ run (code, expectation({{-1,-1}, {4,6}}));
+}
+
+/* Temporary used to in case must live up to the case
+ * statement where it is used, the switch we only keep
+ * for the actual SWITCH opcode like it is in tgsi_exec.c, the
+ * only current use case.
+ */
+TEST_F(LifetimeEvaluatorExactTest, UseSwitchCase)
+{
+ const vector<MockCodeline> code = {
+ { TGSI_OPCODE_MOV, {1}, {in0}, {}},
+ { TGSI_OPCODE_MOV, {2}, {in1}, {}},
+ { TGSI_OPCODE_MOV, {3}, {in2}, {}},
+ { TGSI_OPCODE_SWITCH, {}, {3}, {}},
+ { TGSI_OPCODE_CASE, {}, {2}, {}},
+ { TGSI_OPCODE_CASE, {}, {1}, {}},
+ { TGSI_OPCODE_BRK},
+ { TGSI_OPCODE_DEFAULT},
+ { TGSI_OPCODE_ENDSWITCH},
+ { TGSI_OPCODE_END}
+ };
+ run (code, expectation({{-1,-1}, {0,5}, {1,4}, {2,3}}));
+}
+
+/* With two destinations, if one result is thrown away, the
+ * register must be kept past the writing instructions.
+ */
+TEST_F(LifetimeEvaluatorExactTest, WriteTwoOnlyUseOne)
+{
+ const vector<MockCodeline> code = {
+ { TGSI_OPCODE_DFRACEXP , {1,2}, {in0}, {}},
+ { TGSI_OPCODE_ADD , {3}, {2,in0}, {}},
+ { TGSI_OPCODE_MOV, {out1}, {3}, {}},
+ { TGSI_OPCODE_END},
+
+ };
+ run (code, expectation({{-1,-1}, {0,1}, {0,1}, {1,2}}));
+}
+
+/* If a break is in the loop, all variables written after the
+ * break and used outside the loop must be maintained for the
+ * whole loop
+ */
+TEST_F(LifetimeEvaluatorExactTest, LoopWithWriteAfterBreak)
+{
+ const vector<MockCodeline> code = {
+ { TGSI_OPCODE_BGNLOOP },
+ { TGSI_OPCODE_IF, {}, {in0}, {}},
+ { TGSI_OPCODE_BRK},
+ { TGSI_OPCODE_ENDIF},
+ { TGSI_OPCODE_MOV, {1}, {in0}, {}},
+ { TGSI_OPCODE_ENDLOOP },
+ { TGSI_OPCODE_MOV, {out0}, {1}, {}},
+ { TGSI_OPCODE_END}
+ };
+ run (code, expectation({{-1,-1}, {0,6}}));
+}
+
+/* If a break is in the loop, all variables written after the
+ * break and used outside the loop must be maintained for the
+ * whole loop. The first break in the loop is the defining one.
+ */
+TEST_F(LifetimeEvaluatorExactTest, LoopWithWriteAfterBreak2Breaks)
+{
+ const vector<MockCodeline> code = {
+ { TGSI_OPCODE_BGNLOOP },
+ { TGSI_OPCODE_IF, {}, {in0}, {}},
+ { TGSI_OPCODE_BRK},
+ { TGSI_OPCODE_ENDIF},
+ { TGSI_OPCODE_MOV, {1}, {in0}, {}},
+ { TGSI_OPCODE_BRK},
+ { TGSI_OPCODE_ENDLOOP },
+ { TGSI_OPCODE_MOV, {out0}, {1}, {}},
+ { TGSI_OPCODE_END}
+ };
+ run (code, expectation({{-1,-1}, {0,7}}));
+}
+
+/* Loop with a break at the beginning and read/write in the post
+ * break loop scope. The value written and read within the loop
+ * can be limited to [write, read], but the value read outside the
+ * loop must survive the whole loop. This is the typical code for
+ * while and for loops, where the breaking condition is tested at
+ * the beginning.
+ */
+TEST_F(LifetimeEvaluatorExactTest, LoopWithWriteAndReadAfterBreak)
+{
+ const vector<MockCodeline> code = {
+ { TGSI_OPCODE_BGNLOOP },
+ { TGSI_OPCODE_IF, {}, {in0}, {}},
+ { TGSI_OPCODE_BRK},
+ { TGSI_OPCODE_ENDIF},
+ { TGSI_OPCODE_MOV, {1}, {in0}, {}},
+ { TGSI_OPCODE_MOV, {2}, {1}, {}},
+ { TGSI_OPCODE_ENDLOOP },
+ { TGSI_OPCODE_MOV, {out0}, {2}, {}},
+ { TGSI_OPCODE_END}
+ };
+ run (code, expectation({{-1,-1}, {4,5}, {0,7}}));
+}
+
+/* Same as above, just make sure that the life time of the local variable
+ * in the outer loop (3) is not accidently promoted to the whole loop.
+ */
+TEST_F(LifetimeEvaluatorExactTest, NestedLoopWithWriteAndReadAfterBreak)
+{
+ const vector<MockCodeline> code = {
+ { TGSI_OPCODE_BGNLOOP },
+ { TGSI_OPCODE_IF, {}, {in1}, {}},
+ { TGSI_OPCODE_BRK},
+ { TGSI_OPCODE_ENDIF},
+ { TGSI_OPCODE_BGNLOOP},
+ { TGSI_OPCODE_IF, {}, {in0}, {}},
+ { TGSI_OPCODE_BRK},
+ { TGSI_OPCODE_ENDIF},
+ { TGSI_OPCODE_MOV, {1}, {in0}, {}},
+ { TGSI_OPCODE_MOV, {2}, {1}, {}},
+ { TGSI_OPCODE_ENDLOOP },
+ { TGSI_OPCODE_ADD, {3}, {2,in0}, {}},
+ { TGSI_OPCODE_ADD, {4}, {3,in2}, {}},
+ { TGSI_OPCODE_ENDLOOP },
+ { TGSI_OPCODE_MOV, {out0}, {4}, {}},
+ { TGSI_OPCODE_END}
+ };
+ run (code, expectation({{-1,-1}, {8,9}, {0,13}, {11,12}, {0,14}}));
+}
+
+/* If a break is in the loop inside a switch case, make sure it is
+ * interpreted as breaking that inner loop, i.e. the variable has to
+ * survive the loop.
+ */
+TEST_F(LifetimeEvaluatorExactTest, LoopWithWriteAfterBreakInSwitchInLoop)
+{
+ const vector<MockCodeline> code = {
+ { TGSI_OPCODE_SWITCH, {}, {in1}, {}},
+ { TGSI_OPCODE_CASE, {}, {in1}, {}},
+ { TGSI_OPCODE_BGNLOOP },
+ { TGSI_OPCODE_IF, {}, {in0}, {}},
+ { TGSI_OPCODE_BRK},
+ { TGSI_OPCODE_ENDIF},
+ { TGSI_OPCODE_MOV, {1}, {in0}, {}},
+ { TGSI_OPCODE_ENDLOOP },
+ { TGSI_OPCODE_DEFAULT, {}, {}, {}},
+ { TGSI_OPCODE_ENDSWITCH, {}, {}, {}},
+ { TGSI_OPCODE_MOV, {out0}, {1}, {}},
+ { TGSI_OPCODE_END}
+ };
+ run (code, expectation({{-1,-1}, {2,10}}));
+}
+
+/* Value written conditionally in one loop and read in another loop,
+ * and both of these loops are within yet another loop. Here the value
+ * has to survive the outer loop.
+ */
+TEST_F(LifetimeEvaluatorExactTest, LoopsWithDifferntScopesConditionalWrite)
+{
+ const vector<MockCodeline> code = {
+ { TGSI_OPCODE_BGNLOOP },
+ { TGSI_OPCODE_IF, {}, {in0}, {}},
+ { TGSI_OPCODE_MOV, {1}, {in0}, {}},
+ { TGSI_OPCODE_ENDIF},
+ { TGSI_OPCODE_ENDLOOP },
+ { TGSI_OPCODE_BGNLOOP },
+ { TGSI_OPCODE_MOV, {out0}, {1}, {}},
+ { TGSI_OPCODE_ENDLOOP },
+ { TGSI_OPCODE_END}
+ };
+ run (code, expectation({{-1,-1}, {0,7}}));
+}
+
+/* Value written and read in one loop and last read in another loop,
+ * Here the value has to survive both loops.
+ */
+TEST_F(LifetimeEvaluatorExactTest, LoopsWithDifferntScopesFirstReadBeforeWrite)
+{
+ const vector<MockCodeline> code = {
+ { TGSI_OPCODE_BGNLOOP },
+ { TGSI_OPCODE_MUL, {1}, {1,in0}, {}},
+ { TGSI_OPCODE_ENDLOOP },
+ { TGSI_OPCODE_BGNLOOP },
+ { TGSI_OPCODE_MOV, {out0}, {1}, {}},
+ { TGSI_OPCODE_ENDLOOP },
+ { TGSI_OPCODE_END}
+ };
+ run (code, expectation({{-1,-1}, {0,5}}));
+}
+
+
+/* Value is written in one switch code path within a loop
+ * must survive the full loop.
+ */
+TEST_F(LifetimeEvaluatorExactTest, LoopWithWriteInSwitch)
+{
+ const vector<MockCodeline> code = {
+ { TGSI_OPCODE_BGNLOOP },
+ { TGSI_OPCODE_SWITCH, {}, {in0}, {} },
+ { TGSI_OPCODE_CASE, {}, {in0}, {} },
+ { TGSI_OPCODE_MOV, {1}, {in0}, {}},
+ { TGSI_OPCODE_BRK },
+ { TGSI_OPCODE_DEFAULT },
+ { TGSI_OPCODE_BRK },
+ { TGSI_OPCODE_ENDSWITCH },
+ { TGSI_OPCODE_MOV, {out0}, {1}, {}},
+ { TGSI_OPCODE_ENDLOOP },
+ { TGSI_OPCODE_END}
+ };
+ run (code, expectation({{-1,-1}, {0,9}}));
+}
+
+/* Value written in one case, and read in other,in loop
+ * - must survive the loop.
+ */
+TEST_F(LifetimeEvaluatorExactTest, LoopWithReadWriteInSwitchDifferentCase)
+{
+ const vector<MockCodeline> code = {
+ { TGSI_OPCODE_BGNLOOP },
+ { TGSI_OPCODE_SWITCH, {}, {in0}, {} },
+ { TGSI_OPCODE_CASE, {}, {in0}, {} },
+ { TGSI_OPCODE_MOV, {1}, {in0}, {}},
+ { TGSI_OPCODE_BRK },
+ { TGSI_OPCODE_DEFAULT },
+ { TGSI_OPCODE_MOV, {out0}, {1}, {}},
+ { TGSI_OPCODE_BRK },
+ { TGSI_OPCODE_ENDSWITCH },
+ { TGSI_OPCODE_ENDLOOP },
+ { TGSI_OPCODE_END}
+ };
+ run (code, expectation({{-1,-1}, {0,9}}));
+}
+
+/* Value written in one case, and read in other,in loop
+ * - must survive the loop, even if the write case falls through.
+ */
+TEST_F(LifetimeEvaluatorExactTest, LoopWithReadWriteInSwitchDifferentCaseFallThrough)
+{
+ const vector<MockCodeline> code = {
+ { TGSI_OPCODE_BGNLOOP },
+ { TGSI_OPCODE_SWITCH, {}, {in0}, {} },
+ { TGSI_OPCODE_CASE, {}, {in0}, {} },
+ { TGSI_OPCODE_MOV, {1}, {in0}, {}},
+ { TGSI_OPCODE_DEFAULT },
+ { TGSI_OPCODE_MOV, {out0}, {1}, {}},
+ { TGSI_OPCODE_BRK },
+ { TGSI_OPCODE_ENDSWITCH },
+ { TGSI_OPCODE_ENDLOOP },
+ { TGSI_OPCODE_END}
+ };
+ run (code, expectation({{-1,-1}, {0,8}}));
+}
+
+
+/* Here we read and write from an to the same temp in the same instruction,
+ * but the read is conditional (select operation), hence the lifetime must
+ * start with the first write.
+ */
+TEST_F(LifetimeEvaluatorExactTest, WriteSelectFromSelf)
+{
+ const vector<MockCodeline> code = {
+ {TGSI_OPCODE_USEQ, {5}, {in0,in1}, {}},
+ {TGSI_OPCODE_UCMP, {1}, {5,in1,1}, {}},
+ {TGSI_OPCODE_UCMP, {1}, {5,in1,1}, {}},
+ {TGSI_OPCODE_UCMP, {1}, {5,in1,1}, {}},
+ {TGSI_OPCODE_UCMP, {1}, {5,in1,1}, {}},
+ {TGSI_OPCODE_FSLT, {2}, {1,in1}, {}},
+ {TGSI_OPCODE_UIF, {}, {2}, {}},
+ { TGSI_OPCODE_MOV, {3}, {in1}, {}},
+ {TGSI_OPCODE_ELSE},
+ { TGSI_OPCODE_MOV, {4}, {in1}, {}},
+ { TGSI_OPCODE_MOV, {4}, {4}, {}},
+ { TGSI_OPCODE_MOV, {3}, {4}, {}},
+ {TGSI_OPCODE_ENDIF},
+ {TGSI_OPCODE_MOV, {out1}, {3}, {}},
+ {TGSI_OPCODE_END}
+ };
+ run (code, expectation({{-1,-1}, {1,5}, {5,6}, {7,13}, {9,11}, {0,4}}));
+}
+
+/* This test checks wheter the ENDSWITCH is handled properly if the
+ * last switch case/default doesn't stop with a BRK.
+ */
+TEST_F(LifetimeEvaluatorExactTest, LoopRWInSwitchCaseLastCaseWithoutBreak)
+{
+ const vector<MockCodeline> code = {
+ { TGSI_OPCODE_BGNLOOP },
+ { TGSI_OPCODE_SWITCH, {}, {in0}, {} },
+ { TGSI_OPCODE_CASE, {}, {in0}, {} },
+ { TGSI_OPCODE_MOV, {1}, {in0}, {}},
+ { TGSI_OPCODE_BRK },
+ { TGSI_OPCODE_DEFAULT },
+ { TGSI_OPCODE_MOV, {out0}, {1}, {}},
+ { TGSI_OPCODE_ENDSWITCH },
+ { TGSI_OPCODE_ENDLOOP },
+ { TGSI_OPCODE_END}
+ };
+ run (code, expectation({{-1,-1}, {0,8}}));
+}
+
+/* Value read/write in same case, stays there */
+TEST_F(LifetimeEvaluatorExactTest, LoopWithReadWriteInSwitchSameCase)
+{
+ const vector<MockCodeline> code = {
+ { TGSI_OPCODE_BGNLOOP },
+ { TGSI_OPCODE_SWITCH, {}, {in0}, {} },
+ { TGSI_OPCODE_CASE, {}, {in0}, {} },
+ { TGSI_OPCODE_MOV, {1}, {in0}, {}},
+ { TGSI_OPCODE_MOV, {out0}, {1}, {}},
+ { TGSI_OPCODE_BRK },
+ { TGSI_OPCODE_DEFAULT },
+ { TGSI_OPCODE_BRK },
+ { TGSI_OPCODE_ENDSWITCH },
+ { TGSI_OPCODE_ENDLOOP },
+ { TGSI_OPCODE_END}
+ };
+ run (code, expectation({{-1,-1}, {3,4}}));
+}
+
+/* Value read/write in all cases, should only live from first
+ * write to last read, but currently the whole loop is used.
+ */
+TEST_F(LifetimeEvaluatorAtLeastTest, LoopWithReadWriteInSwitchSameCase)
+{
+ const vector<MockCodeline> code = {
+ { TGSI_OPCODE_BGNLOOP },
+ { TGSI_OPCODE_SWITCH, {}, {in0}, {}},
+ { TGSI_OPCODE_CASE, {}, {in0}, {} },
+ { TGSI_OPCODE_MOV, {1}, {in0}, {}},
+ { TGSI_OPCODE_BRK },
+ { TGSI_OPCODE_DEFAULT },
+ { TGSI_OPCODE_MOV, {1}, {in0}, {}},
+ { TGSI_OPCODE_BRK },
+ { TGSI_OPCODE_ENDSWITCH },
+ { TGSI_OPCODE_MOV, {out0}, {1}, {}},
+ { TGSI_OPCODE_ENDLOOP },
+ { TGSI_OPCODE_END}
+ };
+ run (code, expectation({{-1,-1}, {3,9}}));
+}
+
+/* First read before first write with nested loops */
+TEST_F(LifetimeEvaluatorExactTest, LoopsWithDifferentScopesCondReadBeforeWrite)
+{
+ const vector<MockCodeline> code = {
+ { TGSI_OPCODE_BGNLOOP },
+ { TGSI_OPCODE_BGNLOOP },
+ { TGSI_OPCODE_IF, {}, {in0}, {}},
+ { TGSI_OPCODE_MOV, {out0}, {1}, {}},
+ { TGSI_OPCODE_ENDIF},
+ { TGSI_OPCODE_ENDLOOP },
+ { TGSI_OPCODE_BGNLOOP },
+ { TGSI_OPCODE_MOV, {1}, {in0}, {}},
+ { TGSI_OPCODE_ENDLOOP },
+ { TGSI_OPCODE_ENDLOOP },
+ { TGSI_OPCODE_END}
+ };
+ run (code, expectation({{-1,-1}, {0,9}}));
+}
+
+/* First read before first write wiredness with nested loops.
+ * Here the first read of 2 is logically before the first, dominant
+ * write, therfore, the 2 has to survive both loops.
+ */
+TEST_F(LifetimeEvaluatorExactTest, FirstWriteAtferReadInNestedLoop)
+{
+ const vector<MockCodeline> code = {
+ { TGSI_OPCODE_MOV, {1}, {in0}, {}},
+ { TGSI_OPCODE_BGNLOOP },
+ { TGSI_OPCODE_BGNLOOP },
+ { TGSI_OPCODE_MUL, {2}, {2,1}, {}},
+ { TGSI_OPCODE_MOV, {3}, {2}, {}},
+ { TGSI_OPCODE_ENDLOOP },
+ { TGSI_OPCODE_ADD, {1}, {1,in1}, {}},
+ { TGSI_OPCODE_ENDLOOP },
+ { TGSI_OPCODE_MOV, {out0}, {3}, {}},
+ { TGSI_OPCODE_END}
+ };
+ run (code, expectation({{-1,-1}, {0,7}, {1,7}, {4,8}}));
+}
+
+
+#define DST(X, W) vector<pair<int,int>>(1, make_pair(X, W))
+#define SRC(X, S) vector<pair<int, const char *>>(1, make_pair(X, S))
+#define SRC2(X, S, Y, T) vector<pair<int, const char *>>({make_pair(X, S), make_pair(Y, T)})
+
+/* Partial write to components: one component was written unconditionally
+ * but another conditionally, temporary must survive the whole loop.
+ * Test series for all components.
+ */
+TEST_F(LifetimeEvaluatorExactTest, LoopWithConditionalComponentWrite_X)
+{
+ const vector<MockCodelineWithSwizzle> code = {
+ MockCodelineWithSwizzle(TGSI_OPCODE_BGNLOOP),
+ MockCodelineWithSwizzle(TGSI_OPCODE_MOV, DST(1, WRITEMASK_Y), SRC(in1, "x"), {}),
+ MockCodelineWithSwizzle(TGSI_OPCODE_IF, {}, SRC(in0, "xxxx"), {}),
+ MockCodelineWithSwizzle(TGSI_OPCODE_MOV, DST(1, WRITEMASK_X), SRC(in1, "y"), {}),
+ MockCodelineWithSwizzle(TGSI_OPCODE_ENDIF),
+ MockCodelineWithSwizzle(TGSI_OPCODE_MOV, DST(2, WRITEMASK_XY), SRC(1, "xy"), {}),
+ MockCodelineWithSwizzle(TGSI_OPCODE_ENDLOOP),
+ MockCodelineWithSwizzle(TGSI_OPCODE_MOV, DST(out0, WRITEMASK_XYZW), SRC(2, "xyxy"), {}),
+ MockCodelineWithSwizzle(TGSI_OPCODE_END)
+ };
+ run (code, expectation({{-1,-1}, {0,6}, {5,7}}));
+}
+
+TEST_F(LifetimeEvaluatorExactTest, LoopWithConditionalComponentWrite_Y)
+{
+ const vector<MockCodelineWithSwizzle> code = {
+ MockCodelineWithSwizzle(TGSI_OPCODE_BGNLOOP),
+ MockCodelineWithSwizzle(TGSI_OPCODE_MOV, DST(1, WRITEMASK_X), SRC(in1, "x"), {}),
+ MockCodelineWithSwizzle(TGSI_OPCODE_IF, {}, SRC(in0, "xxxx"), {}),
+ MockCodelineWithSwizzle(TGSI_OPCODE_MOV, DST(1, WRITEMASK_Y), SRC(in1, "y"), {}),
+ MockCodelineWithSwizzle(TGSI_OPCODE_ENDIF),
+ MockCodelineWithSwizzle(TGSI_OPCODE_MOV, DST(2, WRITEMASK_XY), SRC(1, "xy"), {}),
+ MockCodelineWithSwizzle(TGSI_OPCODE_ENDLOOP),
+ MockCodelineWithSwizzle(TGSI_OPCODE_MOV, DST(out0, WRITEMASK_XYZW), SRC(2, "xyxy"), {}),
+ MockCodelineWithSwizzle(TGSI_OPCODE_END)
+ };
+ run (code, expectation({{-1,-1}, {0,6}, {5,7}}));
+}
+
+TEST_F(LifetimeEvaluatorExactTest, LoopWithConditionalComponentWrite_Z)
+{
+ const vector<MockCodelineWithSwizzle> code = {
+ MockCodelineWithSwizzle(TGSI_OPCODE_BGNLOOP),
+ MockCodelineWithSwizzle(TGSI_OPCODE_MOV, DST(1, WRITEMASK_X), SRC(in1, "x"), {}),
+ MockCodelineWithSwizzle(TGSI_OPCODE_IF, {}, SRC(in0, "xxxx"), {}),
+ MockCodelineWithSwizzle(TGSI_OPCODE_MOV, DST(1, WRITEMASK_Z), SRC(in1, "y"), {}),
+ MockCodelineWithSwizzle(TGSI_OPCODE_ENDIF),
+ MockCodelineWithSwizzle(TGSI_OPCODE_MOV, DST(2, WRITEMASK_XY), SRC(1, "xz"), {}),
+ MockCodelineWithSwizzle(TGSI_OPCODE_ENDLOOP),
+ MockCodelineWithSwizzle(TGSI_OPCODE_MOV, DST(out0, WRITEMASK_XYZW), SRC(2, "xyxy"), {}),
+ MockCodelineWithSwizzle(TGSI_OPCODE_END)
+ };
+ run (code, expectation({{-1,-1}, {0,6}, {5,7}}));
+}
+
+TEST_F(LifetimeEvaluatorExactTest, LoopWithConditionalComponentWrite_W)
+{
+ const vector<MockCodelineWithSwizzle> code = {
+ MockCodelineWithSwizzle(TGSI_OPCODE_BGNLOOP),
+ MockCodelineWithSwizzle(TGSI_OPCODE_MOV, DST(1, WRITEMASK_X), SRC(in1, "x"), {}),
+ MockCodelineWithSwizzle(TGSI_OPCODE_IF, {}, SRC(in0, "xxxx"), {}),
+ MockCodelineWithSwizzle(TGSI_OPCODE_MOV, DST(1, WRITEMASK_W), SRC(in1, "y"), {}),
+ MockCodelineWithSwizzle(TGSI_OPCODE_ENDIF),
+ MockCodelineWithSwizzle(TGSI_OPCODE_MOV, DST(2, WRITEMASK_XY), SRC(1, "xw"), {}),
+ MockCodelineWithSwizzle(TGSI_OPCODE_ENDLOOP),
+ MockCodelineWithSwizzle(TGSI_OPCODE_MOV, DST(out0, WRITEMASK_XYZW), SRC(2, "xyxy"), {}),
+ MockCodelineWithSwizzle(TGSI_OPCODE_END)
+ };
+ run (code, expectation({{-1,-1}, {0,6}, {5,7}}));
+}
+
+TEST_F(LifetimeEvaluatorExactTest, LoopWithConditionalComponentWrite_X_Read_Y_Before)
+{
+ const vector<MockCodelineWithSwizzle> code = {
+ MockCodelineWithSwizzle(TGSI_OPCODE_BGNLOOP),
+ MockCodelineWithSwizzle(TGSI_OPCODE_MOV, DST(1, WRITEMASK_X), SRC(in1, "x"), {}),
+ MockCodelineWithSwizzle(TGSI_OPCODE_IF, {}, SRC(in0, "xxxx"), {}),
+ MockCodelineWithSwizzle(TGSI_OPCODE_MOV, DST(2, WRITEMASK_XYZW), SRC(1, "yyyy"), {}),
+ MockCodelineWithSwizzle(TGSI_OPCODE_ENDIF),
+ MockCodelineWithSwizzle(TGSI_OPCODE_MOV, DST(1, WRITEMASK_YZW), SRC(2, "yyzw"), {}),
+ MockCodelineWithSwizzle(TGSI_OPCODE_ENDLOOP),
+ MockCodelineWithSwizzle(TGSI_OPCODE_ADD, DST(out0, WRITEMASK_XYZW), SRC2(2, "yyzw", 1, "xyxy"), {}),
+ MockCodelineWithSwizzle(TGSI_OPCODE_END)
+ };
+ run (code, expectation({{-1,-1}, {0,7}, {0,7}}));
+}
+
+/* The variable is conditionally read before first written, so
+ * it has to surive all the loops.
+ */
+TEST_F(LifetimeEvaluatorExactTest, FRaWSameInstructionInLoopAndCondition)
+{
+ const vector<MockCodeline> code = {
+ { TGSI_OPCODE_BGNLOOP },
+ { TGSI_OPCODE_BGNLOOP },
+ { TGSI_OPCODE_IF, {0}, {in0}, {} },
+ { TGSI_OPCODE_ADD, {1}, {1,in0}, {}},
+ { TGSI_OPCODE_ENDIF},
+ { TGSI_OPCODE_MOV, {1}, {in1}, {}},
+ { TGSI_OPCODE_ENDLOOP },
+ { TGSI_OPCODE_ENDLOOP },
+ { TGSI_OPCODE_END},
+
+ };
+ run (code, expectation({{-1,-1}, {0,7}}));
+}
+
+/* If unconditionally first written and read in the same
+ * instruction, then the register must be kept for the
+ * one write, but not more (undefined behaviour)
+ */
+TEST_F(LifetimeEvaluatorExactTest, FRaWSameInstruction)
+{
+ const vector<MockCodeline> code = {
+ { TGSI_OPCODE_ADD, {1}, {1,in0}, {}},
+ { TGSI_OPCODE_END},
+
+ };
+ run (code, expectation({{-1,-1}, {0,1}}));
+}
+
+/* If unconditionally written and read in the same
+ * instruction, various times then the register must be
+ * kept past the last write, but not longer (undefined behaviour)
+ */
+TEST_F(LifetimeEvaluatorExactTest, FRaWSameInstructionMoreThenOnce)
+{
+ const vector<MockCodeline> code = {
+ { TGSI_OPCODE_ADD, {1}, {1,in0}, {}},
+ { TGSI_OPCODE_ADD, {1}, {1,in0}, {}},
+ { TGSI_OPCODE_MOV, {out0}, {in0}, {}},
+ { TGSI_OPCODE_END},
+
+ };
+ run (code, expectation({{-1,-1}, {0,2}}));
+}
+
+/* Register is only written. This should not happen,
+ * but to handle the case we want the register to life
+ * at least one instruction
+ */
+TEST_F(LifetimeEvaluatorExactTest, WriteOnly)
+{
+ const vector<MockCodeline> code = {
+ { TGSI_OPCODE_MOV, {1}, {in0}, {}},
+ { TGSI_OPCODE_END}
+ };
+ run (code, expectation({{-1,-1}, {0,1}}));
+}
+
+/* Register is read in IF.
+ */
+TEST_F(LifetimeEvaluatorExactTest, SimpleReadForIf)
+{
+ const vector<MockCodeline> code = {
+ { TGSI_OPCODE_MOV, {1}, {in0}, {}},
+ { TGSI_OPCODE_ADD, {out0}, {in0,in1}, {}},
+ { TGSI_OPCODE_IF, {}, {1}, {}},
+ { TGSI_OPCODE_ENDIF}
+ };
+ run (code, expectation({{-1,-1}, {0,2}}));
+}
+
+TEST_F(LifetimeEvaluatorExactTest, WriteTwoReadOne)
+{
+ const vector<MockCodeline> code = {
+ { TGSI_OPCODE_DFRACEXP , {1,2}, {in0}, {}},
+ { TGSI_OPCODE_ADD , {3}, {2,in0}, {}},
+ { TGSI_OPCODE_MOV, {out1}, {3}, {}},
+ { TGSI_OPCODE_END},
+ };
+ run (code, expectation({{-1,-1}, {0,1}, {0,1}, {1,2}}));
+}
+
+TEST_F(LifetimeEvaluatorExactTest, ReadOnly)
+{
+ const vector<MockCodeline> code = {
+ { TGSI_OPCODE_MOV, {out0}, {1}, {}},
+ { TGSI_OPCODE_END},
+ };
+ run (code, expectation({{-1,-1}, {-1,-1}}));
+}
+
+
+/* Test handling of missing END marker
+*/
+TEST_F(LifetimeEvaluatorExactTest, SomeScopesAndNoEndProgramId)
+{
+ const vector<MockCodeline> code = {
+ { TGSI_OPCODE_MOV, {1}, {in0}, {}},
+ { TGSI_OPCODE_IF, {}, {1}, {}},
+ { TGSI_OPCODE_MOV, {2}, {1}, {}},
+ { TGSI_OPCODE_ENDIF},
+ { TGSI_OPCODE_IF, {}, {1}, {}},
+ { TGSI_OPCODE_MOV, {out0}, {2}, {}},
+ { TGSI_OPCODE_ENDIF},
+ };
+ run (code, expectation({{-1,-1}, {0,4}, {2,5}}));
+}
+
+TEST_F(LifetimeEvaluatorExactTest, SerialReadWrite)
+{
+ const vector<MockCodeline> code = {
+ { TGSI_OPCODE_MOV, {1}, {in0}, {}},
+ { TGSI_OPCODE_MOV, {2}, {1}, {}},
+ { TGSI_OPCODE_MOV, {3}, {2}, {}},
+ { TGSI_OPCODE_MOV, {out0}, {3}, {}},
+ { TGSI_OPCODE_END},
+ };
+ run (code, expectation({{-1,-1}, {0,1}, {1,2}, {2,3}}));
+}
+
+/* Check that two destination registers are used */
+TEST_F(LifetimeEvaluatorExactTest, TwoDestRegisters)
+{
+ const vector<MockCodeline> code = {
+ { TGSI_OPCODE_DFRACEXP , {1,2}, {in0}, {}},
+ { TGSI_OPCODE_ADD, {out0}, {1,2}, {}},
+ { TGSI_OPCODE_END}
+ };
+ run (code, expectation({{-1,-1}, {0,1}, {0,1}}));
+}
+
+/* Check that writing within a loop in a conditional is propagated
+ * to the outer loop.
+ */
+TEST_F(LifetimeEvaluatorExactTest, WriteInLoopInConditionalReadOutside)
+{
+ const vector<MockCodeline> code = {
+ { TGSI_OPCODE_BGNLOOP},
+ { TGSI_OPCODE_IF, {}, {in0}, {}},
+ { TGSI_OPCODE_BGNLOOP},
+ { TGSI_OPCODE_MOV, {1}, {in1}, {}},
+ { TGSI_OPCODE_ENDLOOP},
+ { TGSI_OPCODE_ENDIF},
+ { TGSI_OPCODE_ADD, {2}, {1,in1}, {}},
+ { TGSI_OPCODE_ENDLOOP},
+ { TGSI_OPCODE_MOV, {out0}, {2}, {}},
+ { TGSI_OPCODE_END}
+ };
+ run (code, expectation({{-1,-1}, {0,7}, {6,8}}));
+}
+
+/* Check that a register written in a loop that is inside a conditional
+ * is not propagated past that loop if last read is also within the
+ * conditional
+*/
+TEST_F(LifetimeEvaluatorExactTest, WriteInLoopInCondReadInCondOutsideLoop)
+{
+ const vector<MockCodeline> code = {
+ { TGSI_OPCODE_BGNLOOP},
+ { TGSI_OPCODE_IF, {}, {in0}, {}},
+ { TGSI_OPCODE_BGNLOOP},
+ { TGSI_OPCODE_MUL, {1}, {in2,in1}, {}},
+ { TGSI_OPCODE_ENDLOOP},
+ { TGSI_OPCODE_ADD, {2}, {1,in1}, {}},
+ { TGSI_OPCODE_ENDIF},
+ { TGSI_OPCODE_ENDLOOP},
+ { TGSI_OPCODE_MOV, {out0}, {2}, {}},
+ { TGSI_OPCODE_END}
+ };
+ run (code, expectation({{-1,-1}, {3,5}, {0,8}}));
+}
+
+/* Check that a register read before written in a loop that is
+ * inside a conditional is propagated to the outer loop.
+ */
+TEST_F(LifetimeEvaluatorExactTest, ReadWriteInLoopInCondReadInCondOutsideLoop)
+{
+ const vector<MockCodeline> code = {
+ { TGSI_OPCODE_BGNLOOP},
+ { TGSI_OPCODE_IF, {}, {in0}, {}},
+ { TGSI_OPCODE_BGNLOOP},
+ { TGSI_OPCODE_MUL, {1}, {1,in1}, {}},
+ { TGSI_OPCODE_ENDLOOP},
+ { TGSI_OPCODE_ADD, {2}, {1,in1}, {}},
+ { TGSI_OPCODE_ENDIF},
+ { TGSI_OPCODE_ENDLOOP},
+ { TGSI_OPCODE_MOV, {out0}, {2}, {}},
+ { TGSI_OPCODE_END}
+ };
+ run (code, expectation({{-1,-1}, {0,7}, {0,8}}));
+}
+
+/* With two destinations if one value is thrown away, we must
+ * ensure that the two output registers don't merge. In this test
+ * case the last access for 2 and 3 is in line 4, but 4 can only
+ * be merged with 3 because it is read,2 on the other hand is written
+ * to, and merging it with 4 would result in a bug.
+ */
+TEST_F(LifetimeEvaluatorExactTest, WritePastLastRead2)
+{
+ const vector<MockCodeline> code = {
+ { TGSI_OPCODE_MOV, {1}, {in0}, {}},
+ { TGSI_OPCODE_MOV, {2}, {in0}, {}},
+ { TGSI_OPCODE_ADD, {3}, {1,2}, {}},
+ { TGSI_OPCODE_DFRACEXP , {2,4}, {3}, {}},
+ { TGSI_OPCODE_MOV, {out1}, {4}, {}},
+ { TGSI_OPCODE_END}
+ };
+ run (code, expectation({{-1,-1}, {0,2}, {1,4}, {2,3}, {3,4}}));
+}
+
+/* Check that three source registers are used */
+TEST_F(LifetimeEvaluatorExactTest, ThreeSourceRegisters)
+{
+ const vector<MockCodeline> code = {
+ { TGSI_OPCODE_DFRACEXP , {1,2}, {in0}, {}},
+ { TGSI_OPCODE_ADD , {3}, {in0,in1}, {}},
+ { TGSI_OPCODE_MAD, {out0}, {1,2,3}, {}},
+ { TGSI_OPCODE_END}
+ };
+ run (code, expectation({{-1,-1}, {0,2}, {0,2}, {1,2}}));
+}
+
+/* Check minimal lifetime for registers only written to */
+TEST_F(LifetimeEvaluatorExactTest, OverwriteWrittenOnlyTemps)
+{
+ const vector<MockCodeline> code = {
+ { TGSI_OPCODE_MOV , {1}, {in0}, {}},
+ { TGSI_OPCODE_MOV , {2}, {in1}, {}},
+ { TGSI_OPCODE_END}
+ };
+ run (code, expectation({{-1,-1}, {0,1}, {1,2}}));
+}
+
+/* Same register is only written twice. This should not happen,
+ * but to handle the case we want the register to life
+ * at least past the last write instruction
+ */
+TEST_F(LifetimeEvaluatorExactTest, WriteOnlyTwiceSame)
+{
+ const vector<MockCodeline> code = {
+ { TGSI_OPCODE_MOV, {1}, {in0}, {}},
+ { TGSI_OPCODE_MOV, {1}, {in0}, {}},
+ { TGSI_OPCODE_END}
+ };
+ run (code, expectation({{-1,-1}, {0,2}}));
+}
+
+/* Dead code elimination should catch and remove the case
+ * when a variable is written after its last read, but
+ * we want the code to be aware of this case.
+ * The life time of this uselessly written variable is set
+ * to the instruction after the write, because
+ * otherwise it could be re-used too early.
+ */
+TEST_F(LifetimeEvaluatorExactTest, WritePastLastRead)
+{
+ const vector<MockCodeline> code = {
+ { TGSI_OPCODE_MOV, {1}, {in0}, {}},
+ { TGSI_OPCODE_MOV, {2}, {1}, {}},
+ { TGSI_OPCODE_MOV, {1}, {2}, {}},
+ { TGSI_OPCODE_END},
+
+ };
+ run (code, expectation({{-1,-1}, {0,3}, {1,2}}));
+}
+
+/* If a break is in the loop, all variables written after the
+ * break and used outside the loop the variable must survive the
+ * outer loop
+ */
+TEST_F(LifetimeEvaluatorExactTest, NestedLoopWithWriteAfterBreak)
+{
+ const vector<MockCodeline> code = {
+ { TGSI_OPCODE_BGNLOOP },
+ { TGSI_OPCODE_BGNLOOP },
+ { TGSI_OPCODE_IF, {}, {in0}, {}},
+ { TGSI_OPCODE_BRK},
+ { TGSI_OPCODE_ENDIF},
+ { TGSI_OPCODE_MOV, {1}, {in0}, {}},
+ { TGSI_OPCODE_ENDLOOP },
+ { TGSI_OPCODE_MOV, {out0}, {1}, {}},
+ { TGSI_OPCODE_ENDLOOP },
+ { TGSI_OPCODE_END}
+ };
+ run (code, expectation({{-1,-1}, {0,8}}));
+}
+
+/* Test remapping table of registers. The tests don't assume
+ * that the sorting algorithm used to sort the lifetimes
+ * based on their 'begin' is stable.
+ */
+TEST_F(RegisterRemappingTest, RegisterRemapping1)
+{
+ vector<lifetime> lt({{-1,-1},
+ {0,1},
+ {0,2},
+ {1,2},
+ {2,10},
+ {3,5},
+ {5,10}
+ });
+
+ vector<int> expect({0,1,2,1,1,2,2});
+ run(lt, expect);
+}
+
+TEST_F(RegisterRemappingTest, RegisterRemapping2)
+{
+ vector<lifetime> lt({{-1,-1},
+ {0,1},
+ {0,2},
+ {3,4},
+ {4,5},
+ });
+ vector<int> expect({0,1,2,1,1});
+ run(lt, expect);
+}
+
+TEST_F(RegisterRemappingTest, RegisterRemappingMergeAllToOne)
+{
+ vector<lifetime> lt({{-1,-1},
+ {0,1},
+ {1,2},
+ {2,3},
+ {3,4},
+ });
+ vector<int> expect({0,1,1,1,1});
+ run(lt, expect);
+}
+
+TEST_F(RegisterRemappingTest, RegisterRemappingIgnoreUnused)
+{
+ vector<lifetime> lt({{-1,-1},
+ {0,1},
+ {1,2},
+ {2,3},
+ {-1,-1},
+ {3,4},
+ });
+ vector<int> expect({0,1,1,1,4,1});
+ run(lt, expect);
+}
+
+TEST_F(RegisterRemappingTest, RegisterRemappingMergeZeroLifetimeRegisters)
+{
+ vector<lifetime> lt({{-1,-1},
+ {0,1},
+ {1,2},
+ {2,3},
+ {3,3},
+ {3,4},
+ });
+ vector<int> expect({0,1,1,1,1,1});
+ run(lt, expect);
+}
+
+TEST_F(RegisterLifetimeAndRemappingTest, LifetimeAndRemapping)
+{
+ const vector<MockCodeline> code = {
+ {TGSI_OPCODE_USEQ, {5}, {in0,in1}, {}},
+ {TGSI_OPCODE_UCMP, {1}, {5,in1,1}, {}},
+ {TGSI_OPCODE_UCMP, {1}, {5,in1,1}, {}},
+ {TGSI_OPCODE_UCMP, {1}, {5,in1,1}, {}},
+ {TGSI_OPCODE_UCMP, {1}, {5,in1,1}, {}},
+ {TGSI_OPCODE_FSLT, {2}, {1,in1}, {}},
+ {TGSI_OPCODE_UIF, {}, {2}, {}},
+ { TGSI_OPCODE_MOV, {3}, {in1}, {}},
+ {TGSI_OPCODE_ELSE},
+ { TGSI_OPCODE_MOV, {4}, {in1}, {}},
+ { TGSI_OPCODE_MOV, {4}, {4}, {}},
+ { TGSI_OPCODE_MOV, {3}, {4}, {}},
+ {TGSI_OPCODE_ENDIF},
+ {TGSI_OPCODE_MOV, {out1}, {3}, {}},
+ {TGSI_OPCODE_END}
+ };
+ run (code, vector<int>({0,1,5,5,1,5}));
+}
+
+TEST_F(RegisterLifetimeAndRemappingTest, LifetimeAndRemappingWithUnusedReadOnlyIgnored)
+{
+ const vector<MockCodeline> code = {
+ {TGSI_OPCODE_USEQ, {1}, {in0,in1}, {}},
+ {TGSI_OPCODE_UCMP, {2}, {1,in1,2}, {}},
+ {TGSI_OPCODE_UCMP, {4}, {2,in1,1}, {}},
+ {TGSI_OPCODE_ADD, {5}, {2,4}, {}},
+ {TGSI_OPCODE_UIF, {}, {7}, {}},
+ { TGSI_OPCODE_ADD, {8}, {5,4}, {}},
+ {TGSI_OPCODE_ENDIF},
+ {TGSI_OPCODE_MOV, {out1}, {8}, {}},
+ {TGSI_OPCODE_END}
+ };
+ /* lt: 1: 0-2,2: 1-3 3: u 4: 2-5 5: 3-5 6: u 7: 0-(-1),8: 5-7 */
+ run (code, vector<int>({0,1,2,3,1,2,6,7,1}));
+}
+
+TEST_F(RegisterLifetimeAndRemappingTest, LifetimeAndRemappingWithUnusedReadOnlyRemappedTo)
+{
+ const vector<MockCodeline> code = {
+ {TGSI_OPCODE_USEQ, {1}, {in0,in1}, {}},
+ {TGSI_OPCODE_UIF, {}, {7}, {}},
+ { TGSI_OPCODE_UCMP, {2}, {1,in1,2}, {}},
+ { TGSI_OPCODE_UCMP, {4}, {2,in1,1}, {}},
+ { TGSI_OPCODE_ADD, {5}, {2,4}, {}},
+ { TGSI_OPCODE_ADD, {8}, {5,4}, {}},
+ {TGSI_OPCODE_ENDIF},
+ {TGSI_OPCODE_MOV, {out1}, {8}, {}},
+ {TGSI_OPCODE_END}
+ };
+ /* lt: 1: 0-3,2: 2-4 3: u 4: 3-5 5: 4-5 6: u 7: 1-1,8: 5-7 */
+ run (code, vector<int>({0,1,2,3,1,2,6,7,1}));
+}
+
+TEST_F(RegisterLifetimeAndRemappingTest, LifetimeAndRemappingWithUnusedReadOnlyRemapped)
+{
+ const vector<MockCodeline> code = {
+ {TGSI_OPCODE_USEQ, {0}, {in0,in1}, {}},
+ {TGSI_OPCODE_UCMP, {2}, {0,in1,2}, {}},
+ {TGSI_OPCODE_UCMP, {4}, {2,in1,0}, {}},
+ {TGSI_OPCODE_UIF, {}, {7}, {}},
+ { TGSI_OPCODE_ADD, {5}, {4,4}, {}},
+ { TGSI_OPCODE_ADD, {8}, {5,4}, {}},
+ {TGSI_OPCODE_ENDIF},
+ {TGSI_OPCODE_MOV, {out1}, {8}, {}},
+ {TGSI_OPCODE_END}
+ };
+ /* lt: 0: 0-2 1: u 2: 1-2 3: u 4: 2-5 5: 4-5 6: u 7:ro 8: 5-7 */
+ run (code, vector<int>({0,1,2,3,0,2,6,7,0}));
+}
+
+/* Implementation of helper and test classes */
+MockShader::~MockShader()
+{
+ free();
+ ralloc_free(mem_ctx);
+}
+
+MockShader::MockShader(const vector<MockCodelineWithSwizzle>& source):
+ num_temps(0)
+{
+ mem_ctx = ralloc_context(NULL);
+
+ program = new(mem_ctx) exec_list();
+
+ for (MockCodelineWithSwizzle i: source) {
+ glsl_to_tgsi_instruction *next_instr = new(mem_ctx) glsl_to_tgsi_instruction();
+ next_instr->op = i.op;
+ next_instr->info = tgsi_get_opcode_info(i.op);
+
+ assert(i.src.size() < 4);
+ assert(i.dst.size() < 3);
+ assert(i.tex_offsets.size() < 3);
+
+ for (unsigned k = 0; k < i.src.size(); ++k) {
+ next_instr->src[k] = create_src_register(i.src[k].first, i.src[k].second);
+ }
+ for (unsigned k = 0; k < i.dst.size(); ++k) {
+ next_instr->dst[k] = create_dst_register(i.dst[k].first, i.dst[k].second);
+ }
+ next_instr->tex_offset_num_offset = i.tex_offsets.size();
+ next_instr->tex_offsets = new st_src_reg[i.tex_offsets.size()];
+ for (unsigned k = 0; k < i.tex_offsets.size(); ++k) {
+ next_instr->tex_offsets[k] = create_src_register(i.tex_offsets[k].first,
+ i.tex_offsets[k].second);
+ }
+ program->push_tail(next_instr);
+ }
+ ++num_temps;
+}
+
+MockShader::MockShader(const vector<MockCodeline>& source):
+ num_temps(0)
+{
+ mem_ctx = ralloc_context(NULL);
+
+ program = new(mem_ctx) exec_list();
+
+ for (MockCodeline i: source) {
+ glsl_to_tgsi_instruction *next_instr = new(mem_ctx) glsl_to_tgsi_instruction();
+ next_instr->op = i.op;
+ next_instr->info = tgsi_get_opcode_info(i.op);
+
+ assert(i.src.size() < 4);
+ assert(i.dst.size() < 3);
+ assert(i.tex_offsets.size() < 3);
+
+ for (unsigned k = 0; k < i.src.size(); ++k) {
+ next_instr->src[k] = create_src_register(i.src[k]);
+ }
+ for (unsigned k = 0; k < i.dst.size(); ++k) {
+ next_instr->dst[k] = create_dst_register(i.dst[k]);
+ }
+ next_instr->tex_offset_num_offset = i.tex_offsets.size();
+ next_instr->tex_offsets = new st_src_reg[i.tex_offsets.size()];
+ for (unsigned k = 0; k < i.tex_offsets.size(); ++k) {
+ next_instr->tex_offsets[k] = create_src_register(i.tex_offsets[k]);
+ }
+ program->push_tail(next_instr);
+ }
+ ++num_temps;
+}
+
+int MockShader::get_num_temps() const
+{
+ return num_temps;
+}
+
+
+exec_list* MockShader::get_program() const
+{
+ return program;
+}
+
+void MockShader::free()
+{
+ /* The list is not fully initialized, so
+ * tearing it down also must be done manually. */
+ exec_node *p;
+ while ((p = program->pop_head())) {
+ glsl_to_tgsi_instruction * instr = static_cast<glsl_to_tgsi_instruction *>(p);
+ if (instr->tex_offset_num_offset > 0)
+ delete[] instr->tex_offsets;
+ delete p;
+ }
+ program = 0;
+ num_temps = 0;
+}
+
+st_src_reg MockShader::create_src_register(int src_idx)
+{
+ gl_register_file file;
+ int idx = 0;
+ if (src_idx >= 0) {
+ file = PROGRAM_TEMPORARY;
+ idx = src_idx;
+ if (num_temps < idx)
+ num_temps = idx;
+ } else {
+ file = PROGRAM_INPUT;
+ idx = 1 - src_idx;
+ }
+ return st_src_reg(file, idx, GLSL_TYPE_INT);
+}
+
+st_src_reg MockShader::create_src_register(int src_idx, const char *sw)
+{
+ uint16_t swizzle = 0;
+ for (int i = 0; i < 4; ++i) {
+ switch (sw[i]) {
+ case 'x': break; /* is zero */
+ case 'y': swizzle |= SWIZZLE_Y << 3 * i; break;
+ case 'z': swizzle |= SWIZZLE_Z << 3 * i; break;
+ case 'w': swizzle |= SWIZZLE_W << 3 * i; break;
+ }
+ }
+
+ gl_register_file file;
+ int idx = 0;
+ if (src_idx >= 0) {
+ file = PROGRAM_TEMPORARY;
+ idx = src_idx;
+ if (num_temps < idx)
+ num_temps = idx;
+ } else {
+ file = PROGRAM_INPUT;
+ idx = 1 - src_idx;
+ }
+ st_src_reg result(file, idx, GLSL_TYPE_INT);
+ result.swizzle = swizzle;
+ return result;
+}
+
+st_dst_reg MockShader::create_dst_register(int dst_idx,int writemask)
+{
+ gl_register_file file;
+ int idx = 0;
+ if (dst_idx >= 0) {
+ file = PROGRAM_TEMPORARY;
+ idx = dst_idx;
+ if (num_temps < idx)
+ num_temps = idx;
+ } else {
+ file = PROGRAM_OUTPUT;
+ idx = 1 - dst_idx;
+ }
+ return st_dst_reg(file, writemask, GLSL_TYPE_INT, idx);
+}
+
+st_dst_reg MockShader::create_dst_register(int dst_idx)
+{
+ gl_register_file file;
+ int idx = 0;
+ if (dst_idx >= 0) {
+ file = PROGRAM_TEMPORARY;
+ idx = dst_idx;
+ if (num_temps < idx)
+ num_temps = idx;
+ } else {
+ file = PROGRAM_OUTPUT;
+ idx = 1 - dst_idx;
+ }
+ return st_dst_reg(file,0xF, GLSL_TYPE_INT, idx);
+}
+
+
+void MesaTestWithMemCtx::SetUp()
+{
+ mem_ctx = ralloc_context(nullptr);
+}
+
+void MesaTestWithMemCtx::TearDown()
+{
+ ralloc_free(mem_ctx);
+ mem_ctx = nullptr;
+}
+
+void LifetimeEvaluatorTest::run(const vector<MockCodeline>& code, const expectation& e)
+{
+ MockShader shader(code);
+ std::vector<lifetime> result(shader.get_num_temps());
+
+ bool success =
+ get_temp_registers_required_lifetimes(mem_ctx, shader.get_program(),
+ shader.get_num_temps(), &result[0]);
+
+ ASSERT_TRUE(success);
+ ASSERT_EQ(result.size(), e.size());
+ check(result, e);
+}
+
+void LifetimeEvaluatorTest::run(const vector<MockCodelineWithSwizzle>& code,
+ const expectation& e)
+{
+ MockShader shader(code);
+ std::vector<lifetime> result(shader.get_num_temps());
+
+ bool success =
+ get_temp_registers_required_lifetimes(mem_ctx, shader.get_program(),
+ shader.get_num_temps(), &result[0]);
+ ASSERT_TRUE(success);
+ ASSERT_EQ(result.size(), e.size());
+ check(result, e);
+}
+
+void LifetimeEvaluatorExactTest::check( const vector<lifetime>& lifetimes,
+ const expectation& e)
+{
+ for (unsigned i = 1; i < lifetimes.size(); ++i) {
+ EXPECT_EQ(lifetimes[i].begin, e[i][0]);
+ EXPECT_EQ(lifetimes[i].end, e[i][1]);
+ }
+}
+
+void LifetimeEvaluatorAtLeastTest::check( const vector<lifetime>& lifetimes,
+ const expectation& e)
+{
+ for (unsigned i = 1; i < lifetimes.size(); ++i) {
+ EXPECT_LE(lifetimes[i].begin, e[i][0]);
+ EXPECT_GE(lifetimes[i].end, e[i][1]);
+ }
+}
+
+void RegisterRemappingTest::run(const vector<lifetime>& lt,
+ const vector<int>& expect)
+{
+ rename_reg_pair proto{false,0};
+ vector<rename_reg_pair> result(lt.size(), proto);
+
+ get_temp_registers_remapping(mem_ctx, lt.size(), &lt[0], &result[0]);
+
+ vector<int> remap(lt.size());
+ for (unsigned i = 0; i < lt.size(); ++i) {
+ remap[i] = result[i].valid ? result[i].new_reg : i;
+ }
+
+ std::transform(remap.begin(), remap.end(), result.begin(), remap.begin(),
+ [](int x, const rename_reg_pair& rn) {
+ return rn.valid ? rn.new_reg : x;
+ });
+
+ for(unsigned i = 1; i < remap.size(); ++i) {
+ EXPECT_EQ(remap[i], expect[i]);
+ }
+}
diff --git a/lib/mesa/src/mesa/tnl/t_vertex.c b/lib/mesa/src/mesa/tnl/t_vertex.c
index c3294b007..76ff97720 100644
--- a/lib/mesa/src/mesa/tnl/t_vertex.c
+++ b/lib/mesa/src/mesa/tnl/t_vertex.c
@@ -28,6 +28,7 @@
#include <stdio.h>
#include "main/glheader.h"
#include "main/context.h"
+#include "main/execmem.h"
#include "swrast/s_chan.h"
#include "t_context.h"
#include "t_vertex.h"
diff --git a/lib/mesa/src/mesa/x86/rtasm/x86sse.c b/lib/mesa/src/mesa/x86/rtasm/x86sse.c
index c9f52a44d..ddb2ec373 100644
--- a/lib/mesa/src/mesa/x86/rtasm/x86sse.c
+++ b/lib/mesa/src/mesa/x86/rtasm/x86sse.c
@@ -4,6 +4,7 @@
#include <stdio.h>
#include "main/imports.h"
+#include "main/execmem.h"
#include "x86sse.h"
#define DISASSEM 0
diff --git a/lib/mesa/src/util/debug.h b/lib/mesa/src/util/debug.h
index 11a8561eb..75ebc2ebf 100644
--- a/lib/mesa/src/util/debug.h
+++ b/lib/mesa/src/util/debug.h
@@ -21,8 +21,8 @@
* IN THE SOFTWARE.
*/
-#ifndef _DEBUG_H
-#define _DEBUG_H
+#ifndef _UTIL_DEBUG_H
+#define _UTIL_DEBUG_H
#include <stdint.h>
#include <stdbool.h>
@@ -46,4 +46,4 @@ env_var_as_boolean(const char *var_name, bool default_value);
} /* extern C */
#endif
-#endif /* _DEBUG_H */
+#endif /* _UTIL_DEBUG_H */
diff --git a/lib/mesa/src/util/drirc b/lib/mesa/src/util/drirc
new file mode 100644
index 000000000..6ed35d8f4
--- /dev/null
+++ b/lib/mesa/src/util/drirc
@@ -0,0 +1,286 @@
+<!--
+
+============================================
+Application bugs worked around in this file:
+============================================
+
+* Unigine Heaven 3.0 and older contain too many bugs and can't be supported
+ by drivers that want to be compliant.
+
+* Various Unigine products don't use the #version and #extension GLSL
+ directives, meaning they only get GLSL 1.10 and no extensions for their
+ shaders.
+ Enabling all extensions for Unigine fixes most issues, but the GLSL version
+ is still 1.10.
+
+* If ARB_sample_shading is supported, Unigine Heaven 4.0 and Valley 1.0 uses
+ an #extension directive in the middle of its shaders, which is illegal
+ in GLSL.
+
+* Dying Light and Dead Island Definitive Edition redeclare vertex shader
+ built-ins (specifically gl_VertexID), which causes the vertex shaders to fail
+ to compile.
+
+TODO: document the other workarounds.
+
+-->
+
+<driconf>
+ <!-- Please always enable app-specific workarounds for all drivers and
+ screens. -->
+ <device>
+ <application name="Unigine Sanctuary" executable="Sanctuary">
+ <option name="force_glsl_extensions_warn" value="true" />
+ <option name="disable_blend_func_extended" value="true" />
+ </application>
+
+ <application name="Unigine Tropics" executable="Tropics">
+ <option name="force_glsl_extensions_warn" value="true" />
+ <option name="disable_blend_func_extended" value="true" />
+ </application>
+
+ <application name="Unigine Heaven (32-bit)" executable="heaven_x86">
+ <option name="allow_glsl_extension_directive_midshader" value="true" />
+ <!-- remove dual_color_blend_by_location if 4.1 ever comes out -->
+ <option name="dual_color_blend_by_location" value="true" />
+ </application>
+
+ <application name="Unigine Heaven (64-bit)" executable="heaven_x64">
+ <option name="allow_glsl_extension_directive_midshader" value="true" />
+ <!-- remove dual_color_blend_by_location if 4.1 ever comes out -->
+ <option name="dual_color_blend_by_location" value="true" />
+ </application>
+
+ <application name="Unigine Valley (32-bit)" executable="valley_x86">
+ <option name="allow_glsl_extension_directive_midshader" value="true" />
+ <!-- remove dual_color_blend_by_location if 1.1 ever comes out -->
+ <option name="dual_color_blend_by_location" value="true" />
+ </application>
+
+ <application name="Unigine Valley (64-bit)" executable="valley_x64">
+ <option name="allow_glsl_extension_directive_midshader" value="true" />
+ <!-- remove dual_color_blend_by_location if 1.1 ever comes out -->
+ <option name="dual_color_blend_by_location" value="true" />
+ </application>
+
+ <application name="Unigine OilRush (32-bit)" executable="OilRush_x86">
+ <option name="disable_blend_func_extended" value="true" />
+ <option name="allow_glsl_extension_directive_midshader" value="true" />
+ </application>
+
+ <application name="Unigine OilRush (64-bit)" executable="OilRush_x64">
+ <option name="disable_blend_func_extended" value="true" />
+ <option name="allow_glsl_extension_directive_midshader" value="true" />
+ </application>
+
+ <application name="Savage 2" executable="savage2.bin">
+ <option name="disable_glsl_line_continuations" value="true" />
+ </application>
+
+ <application name="Topogun (32-bit)" executable="topogun32">
+ <option name="always_have_depth_buffer" value="true" />
+ </application>
+
+ <application name="Topogun (64-bit)" executable="topogun64">
+ <option name="always_have_depth_buffer" value="true" />
+ </application>
+
+ <application name="Dead Island (incl. Definitive Edition)" executable="DeadIslandGame">
+ <option name="allow_glsl_extension_directive_midshader" value="true" />
+
+ <!-- For the Definitive Edition which shares the same executable name -->
+ <option name="allow_glsl_builtin_variable_redeclaration" value="true" />
+ </application>
+
+ <application name="Dead Island Riptide Definitive Edition" executable="DeadIslandRiptideGame">
+ <option name="allow_glsl_builtin_variable_redeclaration" value="true" />
+ </application>
+
+ <application name="Dying Light" executable="DyingLightGame">
+ <option name="allow_glsl_builtin_variable_redeclaration" value="true" />
+ </application>
+
+ <application name="Second Life" executable="do-not-directly-run-secondlife-bin">
+ <option name="allow_glsl_extension_directive_midshader" value="true" />
+ </application>
+
+ <application name="Warsow (32-bit)" executable="warsow.i386">
+ <option name="allow_glsl_extension_directive_midshader" value="true" />
+ </application>
+
+ <application name="Warsow (64-bit)" executable="warsow.x86_64">
+ <option name="allow_glsl_extension_directive_midshader" value="true" />
+ </application>
+
+ <application name="Rust" executable="rust">
+ <option name="glsl_zero_init" value="true"/>
+ </application>
+
+ <application name="Divinity: Original Sin Enhanced Edition" executable="EoCApp">
+ <option name="allow_glsl_extension_directive_midshader" value="true" />
+ </application>
+
+ <application name="Worms W.M.D" executable="Worms W.M.Dx64">
+ <option name="allow_higher_compat_version" value="true" />
+ </application>
+
+ <application name="Crookz - The Big Heist" executable="Crookz">
+ <option name="allow_higher_compat_version" value="true" />
+ </application>
+
+ <application name="Tropico 5" executable="Tropico5">
+ <option name="allow_higher_compat_version" value="true" />
+ </application>
+
+ <application name="The Culling" executable="Victory">
+ <option name="force_glsl_version" value="440" />
+ </application>
+
+ <application name="Spec Ops: The Line (32-bit)" executable="specops.i386">
+ <option name="force_glsl_abs_sqrt" value="true" />
+ </application>
+
+ <application name="Spec Ops: The Line (64-bit)" executable="specops">
+ <option name="force_glsl_abs_sqrt" value="true" />
+ </application>
+
+ <application name="Kerbal Space Program (32-bit)" executable="KSP.x86">
+ <option name="glsl_zero_init" value="true"/>
+ </application>
+
+ <application name="Kerbal Space Program (64-bit)" executable="KSP.x86_64">
+ <option name="glsl_zero_init" value="true"/>
+ </application>
+
+ <application name="Rocket League" executable="RocketLeague">
+ <option name="glsl_correct_derivatives_after_discard" value="true"/>
+ </application>
+
+ <application name="The Witcher 2" executable="witcher2">
+ <option name="glsl_correct_derivatives_after_discard" value="true"/>
+ </application>
+
+ <application name="Unreal 4 Editor" executable="UE4Editor">
+ <option name="allow_glsl_cross_stage_interpolation_mismatch" value="true"/>
+ </application>
+
+ <application name="Observer" executable="TheObserver-Linux-Shipping">
+ <option name="allow_glsl_cross_stage_interpolation_mismatch" value="true"/>
+ </application>
+
+ <application name="Steamroll" executable="Steamroll-Linux-Shipping">
+ <option name="allow_glsl_cross_stage_interpolation_mismatch" value="true"/>
+ </application>
+
+ <application name="Refunct" executable="Refunct-Linux-Shipping">
+ <option name="allow_glsl_cross_stage_interpolation_mismatch" value="true"/>
+ </application>
+
+ <!-- The GL thread whitelist is below, workarounds are above.
+ Keep it that way. -->
+
+ <application name="Alien Isolation" executable="AlienIsolation">
+ <option name="mesa_glthread" value="true"/>
+ </application>
+
+ <application name="BioShock Infinite" executable="bioshock.i386">
+ <option name="mesa_glthread" value="true"/>
+ </application>
+
+ <application name="Borderlands 2" executable="Borderlands2">
+ <option name="mesa_glthread" value="true"/>
+ </application>
+
+ <application name="Civilization 5" executable="Civ5XP">
+ <option name="mesa_glthread" value="true"/>
+ </application>
+ <application name="Civilization 6" executable="Civ6">
+ <option name="mesa_glthread" value="true"/>
+ </application>
+
+ <application name="Dreamfall Chapters" executable="Dreamfall Chapters">
+ <option name="mesa_glthread" value="true"/>
+ </application>
+
+ <application name="Hitman" executable="HitmanPro">
+ <option name="mesa_glthread" value="true"/>
+ </application>
+
+ <application name="Renowned Explorers: International Society" executable="abbeycore_steam">
+ <option name="mesa_glthread" value="true"/>
+ </application>
+
+ <application name="Saints Row 2" executable="saintsrow2.i386">
+ <option name="mesa_glthread" value="true"/>
+ </application>
+ <application name="Saints Row: The Third" executable="SaintsRow3.i386">
+ <option name="mesa_glthread" value="true"/>
+ </application>
+ <application name="Saints Row IV" executable="SaintsRow4.i386">
+ <option name="mesa_glthread" value="true"/>
+ </application>
+ <application name="Saints Row: Gat out of Hell" executable="SaintsRow4GooH.i386">
+ <option name="mesa_glthread" value="true"/>
+ </application>
+
+ <application name="Sid Meier's: Civilization Beyond Earth" executable="CivBE">
+ <option name="mesa_glthread" value="true"/>
+ </application>
+
+ <application name="The Witcher 2" executable="witcher2">
+ <option name="mesa_glthread" value="true"/>
+ </application>
+
+ <application name="American Truck Simulator" executable="amtrucks">
+ <option name="mesa_glthread" value="true"/>
+ </application>
+ <application name="Euro Truck Simulator 2" executable="eurotrucks2">
+ <option name="mesa_glthread" value="true"/>
+ </application>
+
+ <application name="Overlord" executable="overlord.i386">
+ <option name="mesa_glthread" value="true"/>
+ </application>
+ <application name="Overlord 2" executable="overlord2.i386">
+ <option name="mesa_glthread" value="true"/>
+ </application>
+
+ <application name="Oil Rush" executable="OilRush_x86">
+ <option name="mesa_glthread" value="true"/>
+ </application>
+
+ <application name="War Thunder" executable="aces">
+ <option name="mesa_glthread" value="true"/>
+ </application>
+ <application name="War Thunder (Wine)" executable="aces.exe">
+ <option name="mesa_glthread" value="true"/>
+ </application>
+
+ <application name="Outlast" executable="OLGame.x86_64">
+ <option name="mesa_glthread" value="true"/>
+ </application>
+
+ <application name="Spec Ops: The Line (32-bit)" executable="specops.i386">
+ <option name="mesa_glthread" value="true"/>
+ </application>
+ <application name="Spec Ops: The Line (64-bit)" executable="specops">
+ <option name="mesa_glthread" value="true"/>
+ </application>
+ </device>
+ <!-- vmwgfx doesn't like full buffer swaps and can't sync to vertical retraces.-->
+ <device driver="vmwgfx">
+ <application name="gnome-shell" executable="gnome-shell">
+ <option name="glx_disable_ext_buffer_age" value="true" />
+ <option name="glx_disable_oml_sync_control" value="true" />
+ </application>
+ <application name="Compiz" executable="Compiz">
+ <option name="glx_disable_ext_buffer_age" value="true" />
+ <option name="glx_disable_oml_sync_control" value="true" />
+ </application>
+ </device>
+ <device driver="radeonsi">
+ <application name="ARK: Survival Evolved (and unintentionally the UE4 demo template)" executable="ShooterGame">
+ <option name="radeonsi_clear_db_cache_before_clear" value="true" />
+ </application>
+ </device>
+</driconf>
diff --git a/lib/mesa/src/util/half_float.h b/lib/mesa/src/util/half_float.h
index 64f204210..b3bc3f687 100644
--- a/lib/mesa/src/util/half_float.h
+++ b/lib/mesa/src/util/half_float.h
@@ -25,6 +25,7 @@
#ifndef _HALF_FLOAT_H_
#define _HALF_FLOAT_H_
+#include <stdbool.h>
#include <stdint.h>
#ifdef __cplusplus
@@ -34,6 +35,13 @@ extern "C" {
uint16_t _mesa_float_to_half(float val);
float _mesa_half_to_float(uint16_t val);
+static inline bool
+_mesa_half_is_negative(uint16_t h)
+{
+ return !!(h & 0x8000);
+}
+
+
#ifdef __cplusplus
} /* extern C */
#endif
diff --git a/lib/mesa/src/util/merge_driinfo.py b/lib/mesa/src/util/merge_driinfo.py
new file mode 100644
index 000000000..e6ccca5e0
--- /dev/null
+++ b/lib/mesa/src/util/merge_driinfo.py
@@ -0,0 +1,222 @@
+#
+# Copyright 2017 Advanced Micro Devices, 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
+# on the rights to use, copy, modify, merge, publish, distribute, sub
+# license, 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 NON-INFRINGEMENT. IN NO EVENT SHALL
+# THE AUTHOR(S) AND/OR THEIR SUPPLIERS 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.
+
+"""
+usage: merge_driinfo.py <list of input files>
+
+Generates a source file which contains the DRI_CONF_xxx macros for generating
+the driinfo XML that describes the available DriConf options for a driver and
+its supported state trackers, based on the merged information from the input
+files.
+"""
+
+from __future__ import print_function
+
+import mako.template
+import re
+import sys
+
+
+# Some regexps used during input parsing
+RE_section_begin = re.compile(r'DRI_CONF_SECTION_(.*)')
+RE_option = re.compile(r'DRI_CONF_(.*)\((.*)\)')
+
+
+class Option(object):
+ """
+ Represent a config option as:
+ * name: the xxx part of the DRI_CONF_xxx macro
+ * defaults: the defaults parameters that are passed into the macro
+ """
+ def __init__(self, name, defaults):
+ self.name = name
+ self.defaults = defaults
+
+
+class Section(object):
+ """
+ Represent a config section description as:
+ * name: the xxx part of the DRI_CONF_SECTION_xxx macro
+ * options: list of options
+ """
+ def __init__(self, name):
+ self.name = name
+ self.options = []
+
+
+def parse_inputs(input_filenames):
+ success = True
+ sections_lists = []
+
+ for input_filename in input_filenames:
+ with open(input_filename, 'r') as infile:
+ sections = []
+ sections_lists.append(sections)
+
+ section = None
+
+ linenum = 0
+ for line in infile:
+ linenum += 1
+ line = line.strip()
+ if not line:
+ continue
+
+ if line.startswith('//'):
+ continue
+
+ if line == 'DRI_CONF_SECTION_END':
+ if section is None:
+ print('{}:{}: no open section'
+ .format(input_filename, linenum))
+ success = False
+ continue
+ section = None
+ continue
+
+ m = RE_section_begin.match(line)
+ if m:
+ if section is not None:
+ print('{}:{}: nested sections are not supported'
+ .format(input_filename, linenum))
+ success = False
+ continue
+ if sections is None:
+ print('{}:{}: missing DRIINFO line'
+ .format(input_filename, linenum))
+ success = False
+ break # parsing the rest really makes no sense
+ section = Section(m.group(1))
+ sections.append(section)
+ continue
+
+ m = RE_option.match(line)
+ if m:
+ if section is None:
+ print('{}:{}: no open section'
+ .format(input_filename, linenum))
+ success = False
+ break
+ section.options.append(Option(m.group(1), m.group(2)))
+ continue
+
+ print('{}:{}: do not understand this line'
+ .format(input_filename, linenum))
+ success = False
+
+ if section is not None:
+ print('{}:end-of-file: missing end of section'
+ .format(input_filename))
+ success = False
+
+ if success:
+ return sections_lists
+ return None
+
+
+def merge_sections(section_list):
+ """
+ section_list: list of Section objects to be merged, all of the same name
+ Return a merged Section object (everything is deeply copied)
+ """
+ merged_section = Section(section_list[0].name)
+
+ for section in section_list:
+ assert section.name == merged_section.name
+
+ for orig_option in section.options:
+ for merged_option in merged_section.options:
+ if orig_option.name == merged_option.name:
+ merged_option.defaults = orig_option.defaults
+ break
+ else:
+ merged_section.options.append(Option(orig_option.name, orig_option.defaults))
+
+ return merged_section
+
+
+def merge_sections_lists(sections_lists):
+ """
+ sections_lists: list of lists of Section objects to be merged
+ Return a merged list of merged Section objects; everything is deeply copied.
+ Default values for options in later lists override earlier default values.
+ """
+ merged_sections = []
+
+ for idx,sections in enumerate(sections_lists):
+ for base_section in sections:
+ original_sections = [base_section]
+ for next_sections in sections_lists[idx+1:]:
+ for j,section in enumerate(next_sections):
+ if section.name == base_section.name:
+ original_sections.append(section)
+ del next_sections[j]
+ break
+
+ merged_section = merge_sections(original_sections)
+
+ merged_sections.append(merged_section)
+
+ return merged_sections
+
+
+def main(input_filenames):
+ sections_lists = parse_inputs(input_filenames)
+ if sections_lists is None:
+ return False
+
+ merged_sections_list = merge_sections_lists(sections_lists)
+
+ driinfo_h_template = mako.template.Template("""\
+// DO NOT EDIT - this file is automatically generated by merge_driinfo.py
+
+/*
+Use as:
+
+#include "xmlpool.h"
+
+static const char driinfo_xml[] =
+#include "this_file"
+;
+*/
+
+DRI_CONF_BEGIN
+% for section in sections:
+ DRI_CONF_SECTION_${section.name}
+% for option in section.options:
+ DRI_CONF_${option.name}(${option.defaults})
+% endfor
+ DRI_CONF_SECTION_END
+% endfor
+DRI_CONF_END""")
+
+ print(driinfo_h_template.render(sections=merged_sections_list))
+ return True
+
+
+if __name__ == '__main__':
+ if len(sys.argv) <= 1:
+ print('Missing arguments')
+ sys.exit(1)
+
+ if not main(sys.argv[1:]):
+ sys.exit(1)
diff --git a/lib/mesa/src/util/register_allocate.c b/lib/mesa/src/util/register_allocate.c
index 8af93c040..de8978bb9 100644
--- a/lib/mesa/src/util/register_allocate.c
+++ b/lib/mesa/src/util/register_allocate.c
@@ -174,6 +174,10 @@ struct ra_graph {
* stack.
*/
unsigned int stack_optimistic_start;
+
+ unsigned int (*select_reg_callback)(struct ra_graph *g, BITSET_WORD *regs,
+ void *data);
+ void *select_reg_callback_data;
};
/**
@@ -392,11 +396,11 @@ ra_add_node_adjacency(struct ra_graph *g, unsigned int n1, unsigned int n2)
{
BITSET_SET(g->nodes[n1].adjacency, n2);
- if (n1 != n2) {
- int n1_class = g->nodes[n1].class;
- int n2_class = g->nodes[n2].class;
- g->nodes[n1].q_total += g->regs->classes[n1_class]->q[n2_class];
- }
+ assert(n1 != n2);
+
+ int n1_class = g->nodes[n1].class;
+ int n2_class = g->nodes[n2].class;
+ g->nodes[n1].q_total += g->regs->classes[n1_class]->q[n2_class];
if (g->nodes[n1].adjacency_count >=
g->nodes[n1].adjacency_list_size) {
@@ -433,13 +437,22 @@ ra_alloc_interference_graph(struct ra_regs *regs, unsigned int count)
g->nodes[i].adjacency_count = 0;
g->nodes[i].q_total = 0;
- ra_add_node_adjacency(g, i, i);
g->nodes[i].reg = NO_REG;
}
return g;
}
+void ra_set_select_reg_callback(struct ra_graph *g,
+ unsigned int (*callback)(struct ra_graph *g,
+ BITSET_WORD *regs,
+ void *data),
+ void *data)
+{
+ g->select_reg_callback = callback;
+ g->select_reg_callback_data = data;
+}
+
void
ra_set_node_class(struct ra_graph *g,
unsigned int n, unsigned int class)
@@ -451,7 +464,7 @@ void
ra_add_node_interference(struct ra_graph *g,
unsigned int n1, unsigned int n2)
{
- if (!BITSET_TEST(g->nodes[n1].adjacency, n2)) {
+ if (n1 != n2 && !BITSET_TEST(g->nodes[n1].adjacency, n2)) {
ra_add_node_adjacency(g, n1, n2);
ra_add_node_adjacency(g, n2, n1);
}
@@ -475,7 +488,7 @@ decrement_q(struct ra_graph *g, unsigned int n)
unsigned int n2 = g->nodes[n].adjacency_list[i];
unsigned int n2_class = g->nodes[n2].class;
- if (n != n2 && !g->nodes[n2].in_stack) {
+ if (!g->nodes[n2].in_stack) {
assert(g->nodes[n2].q_total >= g->regs->classes[n2_class]->q[n_class]);
g->nodes[n2].q_total -= g->regs->classes[n2_class]->q[n_class];
}
@@ -539,6 +552,58 @@ ra_simplify(struct ra_graph *g)
g->stack_optimistic_start = stack_optimistic_start;
}
+static bool
+ra_any_neighbors_conflict(struct ra_graph *g, unsigned int n, unsigned int r)
+{
+ unsigned int i;
+
+ for (i = 0; i < g->nodes[n].adjacency_count; i++) {
+ unsigned int n2 = g->nodes[n].adjacency_list[i];
+
+ if (!g->nodes[n2].in_stack &&
+ BITSET_TEST(g->regs->regs[r].conflicts, g->nodes[n2].reg)) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+/* Computes a bitfield of what regs are available for a given register
+ * selection.
+ *
+ * This lets drivers implement a more complicated policy than our simple first
+ * or round robin policies (which don't require knowing the whole bitset)
+ */
+static bool
+ra_compute_available_regs(struct ra_graph *g, unsigned int n, BITSET_WORD *regs)
+{
+ struct ra_class *c = g->regs->classes[g->nodes[n].class];
+
+ /* Populate with the set of regs that are in the node's class. */
+ memcpy(regs, c->regs, BITSET_WORDS(g->regs->count) * sizeof(BITSET_WORD));
+
+ /* Remove any regs that conflict with nodes that we're adjacent to and have
+ * already colored.
+ */
+ for (int i = 0; i < g->nodes[n].adjacency_count; i++) {
+ unsigned int n2 = g->nodes[n].adjacency_list[i];
+ unsigned int r = g->nodes[n2].reg;
+
+ if (!g->nodes[n2].in_stack) {
+ for (int j = 0; j < BITSET_WORDS(g->regs->count); j++)
+ regs[j] &= ~g->regs->regs[r].conflicts[j];
+ }
+ }
+
+ for (int i = 0; i < BITSET_WORDS(g->regs->count); i++) {
+ if (regs[i])
+ return true;
+ }
+
+ return false;
+}
+
/**
* Pops nodes from the stack back into the graph, coloring them with
* registers as they go.
@@ -550,42 +615,45 @@ static bool
ra_select(struct ra_graph *g)
{
int start_search_reg = 0;
+ BITSET_WORD *select_regs = NULL;
+
+ if (g->select_reg_callback)
+ select_regs = malloc(BITSET_WORDS(g->regs->count) * sizeof(BITSET_WORD));
while (g->stack_count != 0) {
- unsigned int i;
unsigned int ri;
unsigned int r = -1;
int n = g->stack[g->stack_count - 1];
struct ra_class *c = g->regs->classes[g->nodes[n].class];
- /* Find the lowest-numbered reg which is not used by a member
- * of the graph adjacent to us.
- */
- for (ri = 0; ri < g->regs->count; ri++) {
- r = (start_search_reg + ri) % g->regs->count;
- if (!reg_belongs_to_class(r, c))
- continue;
-
- /* Check if any of our neighbors conflict with this register choice. */
- for (i = 0; i < g->nodes[n].adjacency_count; i++) {
- unsigned int n2 = g->nodes[n].adjacency_list[i];
-
- if (!g->nodes[n2].in_stack &&
- BITSET_TEST(g->regs->regs[r].conflicts, g->nodes[n2].reg)) {
- break;
- }
- }
- if (i == g->nodes[n].adjacency_count)
- break;
- }
-
/* set this to false even if we return here so that
* ra_get_best_spill_node() considers this node later.
*/
g->nodes[n].in_stack = false;
- if (ri == g->regs->count)
- return false;
+ if (g->select_reg_callback) {
+ if (!ra_compute_available_regs(g, n, select_regs)) {
+ free(select_regs);
+ return false;
+ }
+
+ r = g->select_reg_callback(g, select_regs, g->select_reg_callback_data);
+ } else {
+ /* Find the lowest-numbered reg which is not used by a member
+ * of the graph adjacent to us.
+ */
+ for (ri = 0; ri < g->regs->count; ri++) {
+ r = (start_search_reg + ri) % g->regs->count;
+ if (!reg_belongs_to_class(r, c))
+ continue;
+
+ if (!ra_any_neighbors_conflict(g, n, r))
+ break;
+ }
+
+ if (ri >= g->regs->count)
+ return false;
+ }
g->nodes[n].reg = r;
g->stack_count--;
@@ -604,6 +672,8 @@ ra_select(struct ra_graph *g)
start_search_reg = r + 1;
}
+ free(select_regs);
+
return true;
}
@@ -654,11 +724,9 @@ ra_get_spill_benefit(struct ra_graph *g, unsigned int n)
*/
for (j = 0; j < g->nodes[n].adjacency_count; j++) {
unsigned int n2 = g->nodes[n].adjacency_list[j];
- if (n != n2) {
- unsigned int n2_class = g->nodes[n2].class;
- benefit += ((float)g->regs->classes[n_class]->q[n2_class] /
- g->regs->classes[n_class]->p);
- }
+ unsigned int n2_class = g->nodes[n2].class;
+ benefit += ((float)g->regs->classes[n_class]->q[n2_class] /
+ g->regs->classes[n_class]->p);
}
return benefit;
diff --git a/lib/mesa/src/util/string_buffer.c b/lib/mesa/src/util/string_buffer.c
new file mode 100644
index 000000000..c33173bfa
--- /dev/null
+++ b/lib/mesa/src/util/string_buffer.c
@@ -0,0 +1,148 @@
+/*
+ * Copyright © 2017 Thomas Helland
+ *
+ * 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 "string_buffer.h"
+
+static bool
+ensure_capacity(struct _mesa_string_buffer *str, uint32_t needed_capacity)
+{
+ if (needed_capacity <= str->capacity)
+ return true;
+
+ /* Too small, double until we can fit the new string */
+ uint32_t new_capacity = str->capacity * 2;
+ while (needed_capacity > new_capacity)
+ new_capacity *= 2;
+
+ str->buf = reralloc_array_size(str, str->buf, sizeof(char), new_capacity);
+ if (str->buf == NULL)
+ return false;
+
+ str->capacity = new_capacity;
+ return true;
+}
+
+struct _mesa_string_buffer *
+_mesa_string_buffer_create(void *mem_ctx, uint32_t initial_capacity)
+{
+ struct _mesa_string_buffer *str;
+ str = ralloc(mem_ctx, struct _mesa_string_buffer);
+
+ if (str == NULL)
+ return NULL;
+
+ /* If no initial capacity is set then set it to something */
+ str->capacity = initial_capacity ? initial_capacity : 32;
+ str->buf = ralloc_array(str, char, str->capacity);
+
+ if (!str->buf) {
+ ralloc_free(str);
+ return NULL;
+ }
+
+ str->length = 0;
+ str->buf[str->length] = '\0';
+ return str;
+}
+
+bool
+_mesa_string_buffer_append_all(struct _mesa_string_buffer *str,
+ uint32_t num_args, ...)
+{
+ int i;
+ char* s;
+ va_list args;
+ va_start(args, num_args);
+ for (i = 0; i < num_args; i++) {
+ s = va_arg(args, char*);
+ if (!_mesa_string_buffer_append_len(str, s, strlen(s))) {
+ va_end(args);
+ return false;
+ }
+ }
+ va_end(args);
+ return true;
+}
+
+bool
+_mesa_string_buffer_append_len(struct _mesa_string_buffer *str,
+ const char *c, uint32_t len)
+{
+ uint32_t needed_length = str->length + len + 1;
+
+ /* Check if we're overflowing uint32_t */
+ if (needed_length < str->length)
+ return false;
+
+ if (!ensure_capacity(str, needed_length))
+ return false;
+
+ memcpy(str->buf + str->length, c, len);
+ str->length += len;
+ str->buf[str->length] = '\0';
+ return true;
+}
+
+bool
+_mesa_string_buffer_vprintf(struct _mesa_string_buffer *str,
+ const char *format, va_list args)
+{
+ /* We're looping two times to avoid duplicating code */
+ for (uint32_t i = 0; i < 2; i++) {
+ va_list arg_copy;
+ va_copy(arg_copy, args);
+ uint32_t space_left = str->capacity - str->length;
+
+ int32_t len = util_vsnprintf(str->buf + str->length,
+ space_left, format, arg_copy);
+ va_end(arg_copy);
+
+ /* Error in vsnprintf() or measured len overflows size_t */
+ if (unlikely(len < 0 || str->length + len + 1 < str->length))
+ return false;
+
+ /* There was enough space for the string; we're done */
+ if (len < space_left) {
+ str->length += len;
+ return true;
+ }
+
+ /* Not enough space, resize and retry */
+ ensure_capacity(str, str->length + len + 1);
+ }
+
+ return false;
+}
+
+bool
+_mesa_string_buffer_printf(struct _mesa_string_buffer *str,
+ const char *format, ...)
+{
+ bool res;
+ va_list args;
+ va_start(args, format);
+ res = _mesa_string_buffer_vprintf(str, format, args);
+ va_end(args);
+ return res;
+}
diff --git a/lib/mesa/src/util/string_buffer.h b/lib/mesa/src/util/string_buffer.h
new file mode 100644
index 000000000..eaaf5f33d
--- /dev/null
+++ b/lib/mesa/src/util/string_buffer.h
@@ -0,0 +1,104 @@
+/*
+ * Copyright © 2017 Thomas Helland
+ *
+ * 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.
+ *
+ */
+#ifndef _STRING_BUFFER_H
+#define _STRING_BUFFER_H
+
+#include "ralloc.h"
+#include "u_string.h"
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct _mesa_string_buffer {
+ char *buf;
+ uint32_t length;
+ uint32_t capacity;
+};
+
+struct _mesa_string_buffer *
+_mesa_string_buffer_create(void *mem_ctx, uint32_t initial_capacity);
+
+static inline void
+_mesa_string_buffer_destroy(struct _mesa_string_buffer *str)
+{
+ ralloc_free(str);
+}
+
+bool
+_mesa_string_buffer_append_all(struct _mesa_string_buffer *str,
+ uint32_t num_args, ...);
+bool
+_mesa_string_buffer_append_len(struct _mesa_string_buffer *str,
+ const char *c, uint32_t len);
+
+static inline bool
+_mesa_string_buffer_append_char(struct _mesa_string_buffer *str, char c)
+{
+ return _mesa_string_buffer_append_len(str, &c, 1);
+}
+
+static inline bool
+_mesa_string_buffer_append(struct _mesa_string_buffer *str, const char *c)
+{
+ return _mesa_string_buffer_append_len(str, c, strlen(c));
+}
+
+static inline void
+_mesa_string_buffer_clear(struct _mesa_string_buffer *str)
+{
+ str->length = 0;
+ str->buf[str->length] = '\0';
+}
+
+static inline void
+_mesa_string_buffer_crimp_to_fit(struct _mesa_string_buffer *str)
+{
+ char *crimped =
+ (char *) reralloc_array_size(str, str->buf, sizeof(char),
+ str->capacity);
+ if (!crimped)
+ return;
+
+ str->capacity = str->length + 1;
+ str->buf = crimped;
+}
+
+bool
+_mesa_string_buffer_vprintf(struct _mesa_string_buffer *str,
+ const char *format, va_list args);
+
+bool
+_mesa_string_buffer_printf(struct _mesa_string_buffer *str,
+ const char *format, ...);
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /* _STRING_BUFFER_H */
diff --git a/lib/mesa/src/util/tests/string_buffer/Makefile.am b/lib/mesa/src/util/tests/string_buffer/Makefile.am
new file mode 100644
index 000000000..bd04d8634
--- /dev/null
+++ b/lib/mesa/src/util/tests/string_buffer/Makefile.am
@@ -0,0 +1,40 @@
+# Copyright © 2017 Thomas Helland
+#
+# 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.
+
+AM_CPPFLAGS = \
+ -I$(top_srcdir)/src \
+ -I$(top_srcdir)/include \
+ -I$(top_srcdir)/src/gtest/include \
+ $(PTHREAD_CFLAGS) \
+ $(DEFINES)
+
+TESTS = string_buffer_test
+
+check_PROGRAMS = $(TESTS)
+
+string_buffer_test_SOURCES = \
+ string_buffer_test.cpp
+
+string_buffer_test_LDADD = \
+ $(top_builddir)/src/gtest/libgtest.la \
+ $(top_builddir)/src/util/libmesautil.la \
+ $(PTHREAD_LIBS) \
+ $(DLOPEN_LIBS)
diff --git a/lib/mesa/src/util/tests/string_buffer/Makefile.in b/lib/mesa/src/util/tests/string_buffer/Makefile.in
new file mode 100644
index 000000000..a509e8305
--- /dev/null
+++ b/lib/mesa/src/util/tests/string_buffer/Makefile.in
@@ -0,0 +1,1188 @@
+# Makefile.in generated by automake 1.15.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2017 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+# Copyright © 2017 Thomas Helland
+#
+# 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.
+VPATH = @srcdir@
+am__is_gnu_make = { \
+ if test -z '$(MAKELEVEL)'; then \
+ false; \
+ elif test -n '$(MAKE_HOST)'; then \
+ true; \
+ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+ true; \
+ else \
+ false; \
+ fi; \
+}
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+target_triplet = @target@
+TESTS = string_buffer_test$(EXEEXT)
+check_PROGRAMS = $(am__EXEEXT_1)
+subdir = src/util/tests/string_buffer
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_compile_flag.m4 \
+ $(top_srcdir)/m4/ax_check_gnu_make.m4 \
+ $(top_srcdir)/m4/ax_check_python_mako_module.m4 \
+ $(top_srcdir)/m4/ax_gcc_builtin.m4 \
+ $(top_srcdir)/m4/ax_gcc_func_attribute.m4 \
+ $(top_srcdir)/m4/ax_prog_bison.m4 \
+ $(top_srcdir)/m4/ax_prog_flex.m4 \
+ $(top_srcdir)/m4/ax_pthread.m4 $(top_srcdir)/m4/libtool.m4 \
+ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
+ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/VERSION $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am__EXEEXT_1 = string_buffer_test$(EXEEXT)
+am_string_buffer_test_OBJECTS = string_buffer_test.$(OBJEXT)
+string_buffer_test_OBJECTS = $(am_string_buffer_test_OBJECTS)
+am__DEPENDENCIES_1 =
+string_buffer_test_DEPENDENCIES = \
+ $(top_builddir)/src/gtest/libgtest.la \
+ $(top_builddir)/src/util/libmesautil.la $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_1)
+AM_V_lt = $(am__v_lt_@AM_V@)
+am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 =
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+DEFAULT_INCLUDES = -I.@am__isrc@
+depcomp = $(SHELL) $(top_srcdir)/bin/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CXXFLAGS) $(CXXFLAGS)
+AM_V_CXX = $(am__v_CXX_@AM_V@)
+am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@)
+am__v_CXX_0 = @echo " CXX " $@;
+am__v_CXX_1 =
+CXXLD = $(CXX)
+CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
+ $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CXXLD = $(am__v_CXXLD_@AM_V@)
+am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@)
+am__v_CXXLD_0 = @echo " CXXLD " $@;
+am__v_CXXLD_1 =
+SOURCES = $(string_buffer_test_SOURCES)
+DIST_SOURCES = $(string_buffer_test_SOURCES)
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates. Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+ BEGIN { nonempty = 0; } \
+ { items[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique. This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+ list='$(am__tagged_files)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+am__tty_colors_dummy = \
+ mgn= red= grn= lgn= blu= brg= std=; \
+ am__color_tests=no
+am__tty_colors = { \
+ $(am__tty_colors_dummy); \
+ if test "X$(AM_COLOR_TESTS)" = Xno; then \
+ am__color_tests=no; \
+ elif test "X$(AM_COLOR_TESTS)" = Xalways; then \
+ am__color_tests=yes; \
+ elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \
+ am__color_tests=yes; \
+ fi; \
+ if test $$am__color_tests = yes; then \
+ red=''; \
+ grn=''; \
+ lgn=''; \
+ blu=''; \
+ mgn=''; \
+ brg=''; \
+ std=''; \
+ fi; \
+}
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+ test -z "$$files" \
+ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+ $(am__cd) "$$dir" && rm -f $$files; }; \
+ }
+am__recheck_rx = ^[ ]*:recheck:[ ]*
+am__global_test_result_rx = ^[ ]*:global-test-result:[ ]*
+am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]*
+# A command that, given a newline-separated list of test names on the
+# standard input, print the name of the tests that are to be re-run
+# upon "make recheck".
+am__list_recheck_tests = $(AWK) '{ \
+ recheck = 1; \
+ while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+ { \
+ if (rc < 0) \
+ { \
+ if ((getline line2 < ($$0 ".log")) < 0) \
+ recheck = 0; \
+ break; \
+ } \
+ else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \
+ { \
+ recheck = 0; \
+ break; \
+ } \
+ else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \
+ { \
+ break; \
+ } \
+ }; \
+ if (recheck) \
+ print $$0; \
+ close ($$0 ".trs"); \
+ close ($$0 ".log"); \
+}'
+# A command that, given a newline-separated list of test names on the
+# standard input, create the global log from their .trs and .log files.
+am__create_global_log = $(AWK) ' \
+function fatal(msg) \
+{ \
+ print "fatal: making $@: " msg | "cat >&2"; \
+ exit 1; \
+} \
+function rst_section(header) \
+{ \
+ print header; \
+ len = length(header); \
+ for (i = 1; i <= len; i = i + 1) \
+ printf "="; \
+ printf "\n\n"; \
+} \
+{ \
+ copy_in_global_log = 1; \
+ global_test_result = "RUN"; \
+ while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+ { \
+ if (rc < 0) \
+ fatal("failed to read from " $$0 ".trs"); \
+ if (line ~ /$(am__global_test_result_rx)/) \
+ { \
+ sub("$(am__global_test_result_rx)", "", line); \
+ sub("[ ]*$$", "", line); \
+ global_test_result = line; \
+ } \
+ else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \
+ copy_in_global_log = 0; \
+ }; \
+ if (copy_in_global_log) \
+ { \
+ rst_section(global_test_result ": " $$0); \
+ while ((rc = (getline line < ($$0 ".log"))) != 0) \
+ { \
+ if (rc < 0) \
+ fatal("failed to read from " $$0 ".log"); \
+ print line; \
+ }; \
+ printf "\n"; \
+ }; \
+ close ($$0 ".trs"); \
+ close ($$0 ".log"); \
+}'
+# Restructured Text title.
+am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; }
+# Solaris 10 'make', and several other traditional 'make' implementations,
+# pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it
+# by disabling -e (using the XSI extension "set +e") if it's set.
+am__sh_e_setup = case $$- in *e*) set +e;; esac
+# Default flags passed to test drivers.
+am__common_driver_flags = \
+ --color-tests "$$am__color_tests" \
+ --enable-hard-errors "$$am__enable_hard_errors" \
+ --expect-failure "$$am__expect_failure"
+# To be inserted before the command running the test. Creates the
+# directory for the log if needed. Stores in $dir the directory
+# containing $f, in $tst the test, in $log the log. Executes the
+# developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and
+# passes TESTS_ENVIRONMENT. Set up options for the wrapper that
+# will run the test scripts (or their associated LOG_COMPILER, if
+# thy have one).
+am__check_pre = \
+$(am__sh_e_setup); \
+$(am__vpath_adj_setup) $(am__vpath_adj) \
+$(am__tty_colors); \
+srcdir=$(srcdir); export srcdir; \
+case "$@" in \
+ */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \
+ *) am__odir=.;; \
+esac; \
+test "x$$am__odir" = x"." || test -d "$$am__odir" \
+ || $(MKDIR_P) "$$am__odir" || exit $$?; \
+if test -f "./$$f"; then dir=./; \
+elif test -f "$$f"; then dir=; \
+else dir="$(srcdir)/"; fi; \
+tst=$$dir$$f; log='$@'; \
+if test -n '$(DISABLE_HARD_ERRORS)'; then \
+ am__enable_hard_errors=no; \
+else \
+ am__enable_hard_errors=yes; \
+fi; \
+case " $(XFAIL_TESTS) " in \
+ *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \
+ am__expect_failure=yes;; \
+ *) \
+ am__expect_failure=no;; \
+esac; \
+$(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT)
+# A shell command to get the names of the tests scripts with any registered
+# extension removed (i.e., equivalently, the names of the test logs, with
+# the '.log' extension removed). The result is saved in the shell variable
+# '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly,
+# we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)",
+# since that might cause problem with VPATH rewrites for suffix-less tests.
+# See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'.
+am__set_TESTS_bases = \
+ bases='$(TEST_LOGS)'; \
+ bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \
+ bases=`echo $$bases`
+RECHECK_LOGS = $(TEST_LOGS)
+AM_RECURSIVE_TARGETS = check recheck
+TEST_SUITE_LOG = test-suite.log
+TEST_EXTENSIONS = @EXEEXT@ .test
+LOG_DRIVER = $(SHELL) $(top_srcdir)/bin/test-driver
+LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS)
+am__set_b = \
+ case '$@' in \
+ */*) \
+ case '$*' in \
+ */*) b='$*';; \
+ *) b=`echo '$@' | sed 's/\.log$$//'`; \
+ esac;; \
+ *) \
+ b='$*';; \
+ esac
+am__test_logs1 = $(TESTS:=.log)
+am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log)
+TEST_LOGS = $(am__test_logs2:.test.log=.log)
+TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/bin/test-driver
+TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \
+ $(TEST_LOG_FLAGS)
+am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/bin/depcomp \
+ $(top_srcdir)/bin/test-driver
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMDGPU_CFLAGS = @AMDGPU_CFLAGS@
+AMDGPU_LIBS = @AMDGPU_LIBS@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+ANDROID_CFLAGS = @ANDROID_CFLAGS@
+ANDROID_LIBS = @ANDROID_LIBS@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BSYMBOLIC = @BSYMBOLIC@
+CC = @CC@
+CCAS = @CCAS@
+CCASDEPMODE = @CCASDEPMODE@
+CCASFLAGS = @CCASFLAGS@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CLANG_RESOURCE_DIR = @CLANG_RESOURCE_DIR@
+CLOCK_LIB = @CLOCK_LIB@
+CLOVER_STD_OVERRIDE = @CLOVER_STD_OVERRIDE@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+D3D_DRIVER_INSTALL_DIR = @D3D_DRIVER_INSTALL_DIR@
+DEFINES = @DEFINES@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DLOPEN_LIBS = @DLOPEN_LIBS@
+DRI2PROTO_CFLAGS = @DRI2PROTO_CFLAGS@
+DRI2PROTO_LIBS = @DRI2PROTO_LIBS@
+DRIGL_CFLAGS = @DRIGL_CFLAGS@
+DRIGL_LIBS = @DRIGL_LIBS@
+DRI_DRIVER_INSTALL_DIR = @DRI_DRIVER_INSTALL_DIR@
+DRI_DRIVER_SEARCH_DIR = @DRI_DRIVER_SEARCH_DIR@
+DRI_LIB_DEPS = @DRI_LIB_DEPS@
+DRI_PC_REQ_PRIV = @DRI_PC_REQ_PRIV@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGL_CFLAGS = @EGL_CFLAGS@
+EGL_LIB_DEPS = @EGL_LIB_DEPS@
+EGL_NATIVE_PLATFORM = @EGL_NATIVE_PLATFORM@
+EGREP = @EGREP@
+ETNAVIV_CFLAGS = @ETNAVIV_CFLAGS@
+ETNAVIV_LIBS = @ETNAVIV_LIBS@
+EXEEXT = @EXEEXT@
+EXPAT_CFLAGS = @EXPAT_CFLAGS@
+EXPAT_LIBS = @EXPAT_LIBS@
+FGREP = @FGREP@
+FREEDRENO_CFLAGS = @FREEDRENO_CFLAGS@
+FREEDRENO_LIBS = @FREEDRENO_LIBS@
+GALLIUM_PIPE_LOADER_DEFINES = @GALLIUM_PIPE_LOADER_DEFINES@
+GBM_PC_LIB_PRIV = @GBM_PC_LIB_PRIV@
+GBM_PC_REQ_PRIV = @GBM_PC_REQ_PRIV@
+GC_SECTIONS = @GC_SECTIONS@
+GLESv1_CM_LIB_DEPS = @GLESv1_CM_LIB_DEPS@
+GLESv1_CM_PC_LIB_PRIV = @GLESv1_CM_PC_LIB_PRIV@
+GLESv2_LIB_DEPS = @GLESv2_LIB_DEPS@
+GLESv2_PC_LIB_PRIV = @GLESv2_PC_LIB_PRIV@
+GLPROTO_CFLAGS = @GLPROTO_CFLAGS@
+GLPROTO_LIBS = @GLPROTO_LIBS@
+GLVND_CFLAGS = @GLVND_CFLAGS@
+GLVND_LIBS = @GLVND_LIBS@
+GLX_TLS = @GLX_TLS@
+GL_LIB = @GL_LIB@
+GL_LIB_DEPS = @GL_LIB_DEPS@
+GL_PC_CFLAGS = @GL_PC_CFLAGS@
+GL_PC_LIB_PRIV = @GL_PC_LIB_PRIV@
+GL_PC_REQ_PRIV = @GL_PC_REQ_PRIV@
+GREP = @GREP@
+HAVE_XF86VIDMODE = @HAVE_XF86VIDMODE@
+I915_CFLAGS = @I915_CFLAGS@
+I915_LIBS = @I915_LIBS@
+INDENT = @INDENT@
+INDENT_FLAGS = @INDENT_FLAGS@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LD_NO_UNDEFINED = @LD_NO_UNDEFINED@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBATOMIC_LIBS = @LIBATOMIC_LIBS@
+LIBCLC_INCLUDEDIR = @LIBCLC_INCLUDEDIR@
+LIBCLC_LIBEXECDIR = @LIBCLC_LIBEXECDIR@
+LIBDRM_CFLAGS = @LIBDRM_CFLAGS@
+LIBDRM_LIBS = @LIBDRM_LIBS@
+LIBELF_CFLAGS = @LIBELF_CFLAGS@
+LIBELF_LIBS = @LIBELF_LIBS@
+LIBGLVND_DATADIR = @LIBGLVND_DATADIR@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBSENSORS_LIBS = @LIBSENSORS_LIBS@
+LIBTOOL = @LIBTOOL@
+LIBUNWIND_CFLAGS = @LIBUNWIND_CFLAGS@
+LIBUNWIND_LIBS = @LIBUNWIND_LIBS@
+LIB_DIR = @LIB_DIR@
+LIB_EXT = @LIB_EXT@
+LIPO = @LIPO@
+LLVM_CFLAGS = @LLVM_CFLAGS@
+LLVM_CONFIG = @LLVM_CONFIG@
+LLVM_CXXFLAGS = @LLVM_CXXFLAGS@
+LLVM_INCLUDEDIR = @LLVM_INCLUDEDIR@
+LLVM_LDFLAGS = @LLVM_LDFLAGS@
+LLVM_LIBS = @LLVM_LIBS@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+MSVC2013_COMPAT_CFLAGS = @MSVC2013_COMPAT_CFLAGS@
+MSVC2013_COMPAT_CXXFLAGS = @MSVC2013_COMPAT_CXXFLAGS@
+NINE_MAJOR = @NINE_MAJOR@
+NINE_MINOR = @NINE_MINOR@
+NINE_TINY = @NINE_TINY@
+NINE_VERSION = @NINE_VERSION@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NOUVEAU_CFLAGS = @NOUVEAU_CFLAGS@
+NOUVEAU_LIBS = @NOUVEAU_LIBS@
+NVVIEUX_CFLAGS = @NVVIEUX_CFLAGS@
+NVVIEUX_LIBS = @NVVIEUX_LIBS@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OMX_BELLAGIO_CFLAGS = @OMX_BELLAGIO_CFLAGS@
+OMX_BELLAGIO_LIBS = @OMX_BELLAGIO_LIBS@
+OMX_BELLAGIO_LIB_INSTALL_DIR = @OMX_BELLAGIO_LIB_INSTALL_DIR@
+OPENCL_LIBNAME = @OPENCL_LIBNAME@
+OPENCL_VERSION = @OPENCL_VERSION@
+OSMESA_LIB = @OSMESA_LIB@
+OSMESA_LIB_DEPS = @OSMESA_LIB_DEPS@
+OSMESA_PC_LIB_PRIV = @OSMESA_PC_LIB_PRIV@
+OSMESA_PC_REQ = @OSMESA_PC_REQ@
+OSMESA_VERSION = @OSMESA_VERSION@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+POSIX_SHELL = @POSIX_SHELL@
+PTHREADSTUBS_CFLAGS = @PTHREADSTUBS_CFLAGS@
+PTHREADSTUBS_LIBS = @PTHREADSTUBS_LIBS@
+PTHREAD_CC = @PTHREAD_CC@
+PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
+PTHREAD_LIBS = @PTHREAD_LIBS@
+PWR8_CFLAGS = @PWR8_CFLAGS@
+PYTHON2 = @PYTHON2@
+RADEON_CFLAGS = @RADEON_CFLAGS@
+RADEON_LIBS = @RADEON_LIBS@
+RANLIB = @RANLIB@
+RM = @RM@
+SED = @SED@
+SELINUX_CFLAGS = @SELINUX_CFLAGS@
+SELINUX_LIBS = @SELINUX_LIBS@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SIMPENROSE_CFLAGS = @SIMPENROSE_CFLAGS@
+SIMPENROSE_LIBS = @SIMPENROSE_LIBS@
+SSE41_CFLAGS = @SSE41_CFLAGS@
+STRIP = @STRIP@
+SWR_AVX2_CXXFLAGS = @SWR_AVX2_CXXFLAGS@
+SWR_AVX_CXXFLAGS = @SWR_AVX_CXXFLAGS@
+SWR_CXX11_CXXFLAGS = @SWR_CXX11_CXXFLAGS@
+SWR_KNL_CXXFLAGS = @SWR_KNL_CXXFLAGS@
+SWR_SKX_CXXFLAGS = @SWR_SKX_CXXFLAGS@
+VALGRIND_CFLAGS = @VALGRIND_CFLAGS@
+VALGRIND_LIBS = @VALGRIND_LIBS@
+VA_CFLAGS = @VA_CFLAGS@
+VA_LIBS = @VA_LIBS@
+VA_LIB_INSTALL_DIR = @VA_LIB_INSTALL_DIR@
+VA_MAJOR = @VA_MAJOR@
+VA_MINOR = @VA_MINOR@
+VC5_SIMULATOR_CFLAGS = @VC5_SIMULATOR_CFLAGS@
+VC5_SIMULATOR_LIBS = @VC5_SIMULATOR_LIBS@
+VDPAU_CFLAGS = @VDPAU_CFLAGS@
+VDPAU_LIBS = @VDPAU_LIBS@
+VDPAU_LIB_INSTALL_DIR = @VDPAU_LIB_INSTALL_DIR@
+VDPAU_MAJOR = @VDPAU_MAJOR@
+VDPAU_MINOR = @VDPAU_MINOR@
+VERSION = @VERSION@
+VISIBILITY_CFLAGS = @VISIBILITY_CFLAGS@
+VISIBILITY_CXXFLAGS = @VISIBILITY_CXXFLAGS@
+VL_CFLAGS = @VL_CFLAGS@
+VL_LIBS = @VL_LIBS@
+VULKAN_ICD_INSTALL_DIR = @VULKAN_ICD_INSTALL_DIR@
+WAYLAND_CLIENT_CFLAGS = @WAYLAND_CLIENT_CFLAGS@
+WAYLAND_CLIENT_LIBS = @WAYLAND_CLIENT_LIBS@
+WAYLAND_PROTOCOLS_DATADIR = @WAYLAND_PROTOCOLS_DATADIR@
+WAYLAND_SCANNER = @WAYLAND_SCANNER@
+WAYLAND_SCANNER_CFLAGS = @WAYLAND_SCANNER_CFLAGS@
+WAYLAND_SCANNER_LIBS = @WAYLAND_SCANNER_LIBS@
+WAYLAND_SERVER_CFLAGS = @WAYLAND_SERVER_CFLAGS@
+WAYLAND_SERVER_LIBS = @WAYLAND_SERVER_LIBS@
+WNO_OVERRIDE_INIT = @WNO_OVERRIDE_INIT@
+X11_INCLUDES = @X11_INCLUDES@
+XA_MAJOR = @XA_MAJOR@
+XA_MINOR = @XA_MINOR@
+XA_TINY = @XA_TINY@
+XA_VERSION = @XA_VERSION@
+XCB_DRI2_CFLAGS = @XCB_DRI2_CFLAGS@
+XCB_DRI2_LIBS = @XCB_DRI2_LIBS@
+XCB_DRI3_CFLAGS = @XCB_DRI3_CFLAGS@
+XCB_DRI3_LIBS = @XCB_DRI3_LIBS@
+XF86VIDMODE_CFLAGS = @XF86VIDMODE_CFLAGS@
+XF86VIDMODE_LIBS = @XF86VIDMODE_LIBS@
+XLIBGL_CFLAGS = @XLIBGL_CFLAGS@
+XLIBGL_LIBS = @XLIBGL_LIBS@
+XVMC_CFLAGS = @XVMC_CFLAGS@
+XVMC_LIBS = @XVMC_LIBS@
+XVMC_LIB_INSTALL_DIR = @XVMC_LIB_INSTALL_DIR@
+XVMC_MAJOR = @XVMC_MAJOR@
+XVMC_MINOR = @XVMC_MINOR@
+YACC = @YACC@
+YFLAGS = @YFLAGS@
+ZLIB_CFLAGS = @ZLIB_CFLAGS@
+ZLIB_LIBS = @ZLIB_LIBS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+acv_mako_found = @acv_mako_found@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+ax_pthread_config = @ax_pthread_config@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+ifGNUmake = @ifGNUmake@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+runstatedir = @runstatedir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+AM_CPPFLAGS = \
+ -I$(top_srcdir)/src \
+ -I$(top_srcdir)/include \
+ -I$(top_srcdir)/src/gtest/include \
+ $(PTHREAD_CFLAGS) \
+ $(DEFINES)
+
+string_buffer_test_SOURCES = \
+ string_buffer_test.cpp
+
+string_buffer_test_LDADD = \
+ $(top_builddir)/src/gtest/libgtest.la \
+ $(top_builddir)/src/util/libmesautil.la \
+ $(PTHREAD_LIBS) \
+ $(DLOPEN_LIBS)
+
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .cpp .lo .log .o .obj .test .test$(EXEEXT) .trs
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/util/tests/string_buffer/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --foreign src/util/tests/string_buffer/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+clean-checkPROGRAMS:
+ @list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \
+ echo " rm -f" $$list; \
+ rm -f $$list || exit $$?; \
+ test -n "$(EXEEXT)" || exit 0; \
+ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f" $$list; \
+ rm -f $$list
+
+string_buffer_test$(EXEEXT): $(string_buffer_test_OBJECTS) $(string_buffer_test_DEPENDENCIES) $(EXTRA_string_buffer_test_DEPENDENCIES)
+ @rm -f string_buffer_test$(EXEEXT)
+ $(AM_V_CXXLD)$(CXXLINK) $(string_buffer_test_OBJECTS) $(string_buffer_test_LDADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/string_buffer_test.Po@am__quote@
+
+.cpp.o:
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
+@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+@am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $<
+
+.cpp.obj:
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
+@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
+@am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.cpp.lo:
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
+@am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+@am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+ID: $(am__tagged_files)
+ $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ set x; \
+ here=`pwd`; \
+ $(am__define_uniq_tagged_files); \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ $(am__define_uniq_tagged_files); \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+ list='$(am__tagged_files)'; \
+ case "$(srcdir)" in \
+ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+ *) sdir=$(subdir)/$(srcdir) ;; \
+ esac; \
+ for i in $$list; do \
+ if test -f "$$i"; then \
+ echo "$(subdir)/$$i"; \
+ else \
+ echo "$$sdir/$$i"; \
+ fi; \
+ done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+# Recover from deleted '.trs' file; this should ensure that
+# "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create
+# both 'foo.log' and 'foo.trs'. Break the recipe in two subshells
+# to avoid problems with "make -n".
+.log.trs:
+ rm -f $< $@
+ $(MAKE) $(AM_MAKEFLAGS) $<
+
+# Leading 'am--fnord' is there to ensure the list of targets does not
+# expand to empty, as could happen e.g. with make check TESTS=''.
+am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck)
+am--force-recheck:
+ @:
+
+$(TEST_SUITE_LOG): $(TEST_LOGS)
+ @$(am__set_TESTS_bases); \
+ am__f_ok () { test -f "$$1" && test -r "$$1"; }; \
+ redo_bases=`for i in $$bases; do \
+ am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \
+ done`; \
+ if test -n "$$redo_bases"; then \
+ redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \
+ redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \
+ if $(am__make_dryrun); then :; else \
+ rm -f $$redo_logs && rm -f $$redo_results || exit 1; \
+ fi; \
+ fi; \
+ if test -n "$$am__remaking_logs"; then \
+ echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \
+ "recursion detected" >&2; \
+ elif test -n "$$redo_logs"; then \
+ am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \
+ fi; \
+ if $(am__make_dryrun); then :; else \
+ st=0; \
+ errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \
+ for i in $$redo_bases; do \
+ test -f $$i.trs && test -r $$i.trs \
+ || { echo "$$errmsg $$i.trs" >&2; st=1; }; \
+ test -f $$i.log && test -r $$i.log \
+ || { echo "$$errmsg $$i.log" >&2; st=1; }; \
+ done; \
+ test $$st -eq 0 || exit 1; \
+ fi
+ @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \
+ ws='[ ]'; \
+ results=`for b in $$bases; do echo $$b.trs; done`; \
+ test -n "$$results" || results=/dev/null; \
+ all=` grep "^$$ws*:test-result:" $$results | wc -l`; \
+ pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \
+ fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \
+ skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \
+ xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \
+ xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \
+ error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \
+ if test `expr $$fail + $$xpass + $$error` -eq 0; then \
+ success=true; \
+ else \
+ success=false; \
+ fi; \
+ br='==================='; br=$$br$$br$$br$$br; \
+ result_count () \
+ { \
+ if test x"$$1" = x"--maybe-color"; then \
+ maybe_colorize=yes; \
+ elif test x"$$1" = x"--no-color"; then \
+ maybe_colorize=no; \
+ else \
+ echo "$@: invalid 'result_count' usage" >&2; exit 4; \
+ fi; \
+ shift; \
+ desc=$$1 count=$$2; \
+ if test $$maybe_colorize = yes && test $$count -gt 0; then \
+ color_start=$$3 color_end=$$std; \
+ else \
+ color_start= color_end=; \
+ fi; \
+ echo "$${color_start}# $$desc $$count$${color_end}"; \
+ }; \
+ create_testsuite_report () \
+ { \
+ result_count $$1 "TOTAL:" $$all "$$brg"; \
+ result_count $$1 "PASS: " $$pass "$$grn"; \
+ result_count $$1 "SKIP: " $$skip "$$blu"; \
+ result_count $$1 "XFAIL:" $$xfail "$$lgn"; \
+ result_count $$1 "FAIL: " $$fail "$$red"; \
+ result_count $$1 "XPASS:" $$xpass "$$red"; \
+ result_count $$1 "ERROR:" $$error "$$mgn"; \
+ }; \
+ { \
+ echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \
+ $(am__rst_title); \
+ create_testsuite_report --no-color; \
+ echo; \
+ echo ".. contents:: :depth: 2"; \
+ echo; \
+ for b in $$bases; do echo $$b; done \
+ | $(am__create_global_log); \
+ } >$(TEST_SUITE_LOG).tmp || exit 1; \
+ mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \
+ if $$success; then \
+ col="$$grn"; \
+ else \
+ col="$$red"; \
+ test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \
+ fi; \
+ echo "$${col}$$br$${std}"; \
+ echo "$${col}Testsuite summary for $(PACKAGE_STRING)$${std}"; \
+ echo "$${col}$$br$${std}"; \
+ create_testsuite_report --maybe-color; \
+ echo "$$col$$br$$std"; \
+ if $$success; then :; else \
+ echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \
+ if test -n "$(PACKAGE_BUGREPORT)"; then \
+ echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \
+ fi; \
+ echo "$$col$$br$$std"; \
+ fi; \
+ $$success || exit 1
+
+check-TESTS:
+ @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list
+ @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list
+ @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+ @set +e; $(am__set_TESTS_bases); \
+ log_list=`for i in $$bases; do echo $$i.log; done`; \
+ trs_list=`for i in $$bases; do echo $$i.trs; done`; \
+ log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \
+ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \
+ exit $$?;
+recheck: all $(check_PROGRAMS)
+ @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+ @set +e; $(am__set_TESTS_bases); \
+ bases=`for i in $$bases; do echo $$i; done \
+ | $(am__list_recheck_tests)` || exit 1; \
+ log_list=`for i in $$bases; do echo $$i.log; done`; \
+ log_list=`echo $$log_list`; \
+ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \
+ am__force_recheck=am--force-recheck \
+ TEST_LOGS="$$log_list"; \
+ exit $$?
+string_buffer_test.log: string_buffer_test$(EXEEXT)
+ @p='string_buffer_test$(EXEEXT)'; \
+ b='string_buffer_test'; \
+ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+.test.log:
+ @p='$<'; \
+ $(am__set_b); \
+ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+@am__EXEEXT_TRUE@.test$(EXEEXT).log:
+@am__EXEEXT_TRUE@ @p='$<'; \
+@am__EXEEXT_TRUE@ $(am__set_b); \
+@am__EXEEXT_TRUE@ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+@am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \
+@am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+@am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT)
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+ $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS)
+ $(MAKE) $(AM_MAKEFLAGS) check-TESTS
+check: check-am
+all-am: Makefile
+installdirs:
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+ -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS)
+ -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs)
+ -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-checkPROGRAMS clean-generic clean-libtool \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: check-am install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am check check-TESTS check-am clean \
+ clean-checkPROGRAMS clean-generic clean-libtool cscopelist-am \
+ ctags ctags-am distclean distclean-compile distclean-generic \
+ distclean-libtool distclean-tags distdir dvi dvi-am html \
+ html-am info info-am install install-am install-data \
+ install-data-am install-dvi install-dvi-am install-exec \
+ install-exec-am install-html install-html-am install-info \
+ install-info-am install-man install-pdf install-pdf-am \
+ install-ps install-ps-am install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ recheck tags tags-am uninstall uninstall-am
+
+.PRECIOUS: Makefile
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/lib/mesa/src/util/tests/string_buffer/string_buffer_test.cpp b/lib/mesa/src/util/tests/string_buffer/string_buffer_test.cpp
new file mode 100644
index 000000000..545f607fa
--- /dev/null
+++ b/lib/mesa/src/util/tests/string_buffer/string_buffer_test.cpp
@@ -0,0 +1,122 @@
+/*
+ * Copyright © 2017 Thomas Helland
+ *
+ * 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 <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+#include <gtest/gtest.h>
+#include "util/string_buffer.h"
+
+/**
+ * \file string_buffer_test.cpp
+ *
+ * Test the string buffer implementation
+ */
+
+#define INITIAL_BUF_SIZE 6
+class string_buffer : public ::testing::Test {
+public:
+
+ struct _mesa_string_buffer *buf;
+ const char *str1;
+ const char *str2;
+ const char *str3;
+ char str4[80];
+ char str5[40];
+
+ virtual void SetUp();
+ virtual void TearDown();
+};
+
+void
+string_buffer::SetUp()
+{
+ str1 = "test1";
+ str2 = "test2";
+ str3 = "test1test2";
+ buf = _mesa_string_buffer_create(NULL, INITIAL_BUF_SIZE);
+}
+
+void
+string_buffer::TearDown()
+{
+ /* Finally, clean up after us */
+ _mesa_string_buffer_destroy(buf);
+}
+
+static uint32_t
+space_left_in_buffer(_mesa_string_buffer *buf)
+{
+ return buf->capacity - buf->length - 1;
+}
+
+TEST_F(string_buffer, string_buffer_tests)
+{
+ /* The string terminator needs one byte, so there should one "missing" */
+ EXPECT_TRUE(space_left_in_buffer(buf) == INITIAL_BUF_SIZE - 1);
+
+ /* Start by appending str1 */
+ EXPECT_TRUE(_mesa_string_buffer_append(buf, str1));
+ EXPECT_TRUE(space_left_in_buffer(buf) ==
+ INITIAL_BUF_SIZE - strlen(str1) - 1);
+ EXPECT_TRUE(strcmp(buf->buf, str1) == 0);
+
+ /* Add more, so that the string is resized */
+ EXPECT_TRUE(_mesa_string_buffer_append(buf, str2));
+
+ /* The string should now be equal to str3 */
+ EXPECT_TRUE(strcmp(buf->buf, str3) == 0);
+
+ /* Check that the length of the string is reset when clearing */
+ _mesa_string_buffer_clear(buf);
+ EXPECT_TRUE(buf->length == 0);
+ EXPECT_TRUE(strlen(buf->buf) == 0);
+
+ /* Test a string with some formatting */
+ sprintf(str4, "Testing formatting %d, %f", 100, 1.0);
+ EXPECT_TRUE(_mesa_string_buffer_printf(buf, "Testing formatting %d, %f", 100, 1.0));
+ EXPECT_TRUE(strcmp(buf->buf, str4) == 0);
+
+ /* Compile a string with some other formatting */
+ sprintf(str5, "Testing formatting %d, %x", 100, 0xDEADBEAF);
+
+ /* Concatenate str5 to str4 */
+ strcat(str4, str5);
+
+ /* Now use the formatted append function again */
+ EXPECT_TRUE(_mesa_string_buffer_printf(buf, "Testing formatting %d, %x", 100, 0xDEADBEAF));
+
+ /* The string buffer should now be equal to str4 */
+ EXPECT_TRUE(strcmp(buf->buf, str4) == 0);
+
+ _mesa_string_buffer_clear(buf);
+
+ /* Test appending by one char at a time */
+ EXPECT_TRUE(_mesa_string_buffer_append_char(buf, 'a'));
+ EXPECT_TRUE(buf->length == 1);
+ EXPECT_TRUE(strcmp(buf->buf, "a") == 0);
+ EXPECT_TRUE(_mesa_string_buffer_append_char(buf, 'a'));
+ EXPECT_TRUE(strcmp(buf->buf, "aa") == 0);
+}
diff --git a/lib/mesa/src/util/xmlconfig.c b/lib/mesa/src/util/xmlconfig.c
new file mode 100644
index 000000000..60a6331c8
--- /dev/null
+++ b/lib/mesa/src/util/xmlconfig.c
@@ -0,0 +1,1113 @@
+/*
+ * XML DRI client-side driver configuration
+ * Copyright (C) 2003 Felix Kuehling
+ *
+ * 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
+ * FELIX KUEHLING, OR ANY OTHER CONTRIBUTORS 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 xmlconfig.c
+ * \brief Driver-independent client-side part of the XML configuration
+ * \author Felix Kuehling
+ */
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+#include <expat.h>
+#include <fcntl.h>
+#include <math.h>
+#include <unistd.h>
+#include <errno.h>
+#include "xmlconfig.h"
+
+#undef GET_PROGRAM_NAME
+
+#if (defined(__GNU_LIBRARY__) || defined(__GLIBC__)) && !defined(__UCLIBC__)
+# if !defined(__GLIBC__) || (__GLIBC__ < 2)
+/* These aren't declared in any libc5 header */
+extern char *program_invocation_name, *program_invocation_short_name;
+# endif
+# define GET_PROGRAM_NAME() program_invocation_short_name
+#elif defined(__CYGWIN__)
+# define GET_PROGRAM_NAME() program_invocation_short_name
+#elif defined(__FreeBSD__) && (__FreeBSD__ >= 2)
+# include <osreldate.h>
+# if (__FreeBSD_version >= 440000)
+# include <stdlib.h>
+# define GET_PROGRAM_NAME() getprogname()
+# endif
+#elif defined(__NetBSD__) && defined(__NetBSD_Version__) && (__NetBSD_Version__ >= 106000100)
+# include <stdlib.h>
+# define GET_PROGRAM_NAME() getprogname()
+#elif defined(__DragonFly__)
+# include <stdlib.h>
+# define GET_PROGRAM_NAME() getprogname()
+#elif defined(__APPLE__)
+# include <stdlib.h>
+# define GET_PROGRAM_NAME() getprogname()
+#elif defined(__sun)
+/* Solaris has getexecname() which returns the full path - return just
+ the basename to match BSD getprogname() */
+# include <stdlib.h>
+# include <libgen.h>
+
+static const char *
+__getProgramName()
+{
+ static const char *progname;
+
+ if (progname == NULL) {
+ const char *e = getexecname();
+ if (e != NULL) {
+ /* Have to make a copy since getexecname can return a readonly
+ string, but basename expects to be able to modify its arg. */
+ char *n = strdup(e);
+ if (n != NULL) {
+ progname = basename(n);
+ }
+ }
+ }
+ return progname;
+}
+
+# define GET_PROGRAM_NAME() __getProgramName()
+#endif
+
+#if !defined(GET_PROGRAM_NAME)
+# if defined(__OpenBSD__) || defined(NetBSD) || defined(__UCLIBC__) || defined(ANDROID)
+/* This is a hack. It's said to work on OpenBSD, NetBSD and GNU.
+ * Rogelio M.Serrano Jr. reported it's also working with UCLIBC. It's
+ * used as a last resort, if there is no documented facility available. */
+static const char *
+__getProgramName()
+{
+ extern const char *__progname;
+ char * arg = strrchr(__progname, '/');
+ if (arg)
+ return arg+1;
+ else
+ return __progname;
+}
+# define GET_PROGRAM_NAME() __getProgramName()
+# else
+# define GET_PROGRAM_NAME() ""
+# warning "Per application configuration won't work with your OS version."
+# endif
+#endif
+
+/** \brief Find an option in an option cache with the name as key */
+static uint32_t
+findOption(const driOptionCache *cache, const char *name)
+{
+ uint32_t len = strlen (name);
+ uint32_t size = 1 << cache->tableSize, mask = size - 1;
+ uint32_t hash = 0;
+ uint32_t i, shift;
+
+ /* compute a hash from the variable length name */
+ for (i = 0, shift = 0; i < len; ++i, shift = (shift+8) & 31)
+ hash += (uint32_t)name[i] << shift;
+ hash *= hash;
+ hash = (hash >> (16-cache->tableSize/2)) & mask;
+
+ /* this is just the starting point of the linear search for the option */
+ for (i = 0; i < size; ++i, hash = (hash+1) & mask) {
+ /* if we hit an empty entry then the option is not defined (yet) */
+ if (cache->info[hash].name == 0)
+ break;
+ else if (!strcmp (name, cache->info[hash].name))
+ break;
+ }
+ /* this assertion fails if the hash table is full */
+ assert (i < size);
+
+ return hash;
+}
+
+/** \brief Like strdup but using malloc and with error checking. */
+#define XSTRDUP(dest,source) do { \
+ uint32_t len = strlen (source); \
+ if (!(dest = malloc(len+1))) { \
+ fprintf (stderr, "%s: %d: out of memory.\n", __FILE__, __LINE__); \
+ abort(); \
+ } \
+ memcpy (dest, source, len+1); \
+} while (0)
+
+static int compare (const void *a, const void *b) {
+ return strcmp (*(char *const*)a, *(char *const*)b);
+}
+/** \brief Binary search in a string array. */
+static uint32_t
+bsearchStr (const XML_Char *name, const XML_Char *elems[], uint32_t count)
+{
+ const XML_Char **found;
+ found = bsearch (&name, elems, count, sizeof (XML_Char *), compare);
+ if (found)
+ return found - elems;
+ else
+ return count;
+}
+
+/** \brief Locale-independent integer parser.
+ *
+ * Works similar to strtol. Leading space is NOT skipped. The input
+ * number may have an optional sign. Radix is specified by base. If
+ * base is 0 then decimal is assumed unless the input number is
+ * prefixed by 0x or 0X for hexadecimal or 0 for octal. After
+ * returning tail points to the first character that is not part of
+ * the integer number. If no number was found then tail points to the
+ * start of the input string. */
+static int
+strToI(const XML_Char *string, const XML_Char **tail, int base)
+{
+ int radix = base == 0 ? 10 : base;
+ int result = 0;
+ int sign = 1;
+ bool numberFound = false;
+ const XML_Char *start = string;
+
+ assert (radix >= 2 && radix <= 36);
+
+ if (*string == '-') {
+ sign = -1;
+ string++;
+ } else if (*string == '+')
+ string++;
+ if (base == 0 && *string == '0') {
+ numberFound = true;
+ if (*(string+1) == 'x' || *(string+1) == 'X') {
+ radix = 16;
+ string += 2;
+ } else {
+ radix = 8;
+ string++;
+ }
+ }
+ do {
+ int digit = -1;
+ if (radix <= 10) {
+ if (*string >= '0' && *string < '0' + radix)
+ digit = *string - '0';
+ } else {
+ if (*string >= '0' && *string <= '9')
+ digit = *string - '0';
+ else if (*string >= 'a' && *string < 'a' + radix - 10)
+ digit = *string - 'a' + 10;
+ else if (*string >= 'A' && *string < 'A' + radix - 10)
+ digit = *string - 'A' + 10;
+ }
+ if (digit != -1) {
+ numberFound = true;
+ result = radix*result + digit;
+ string++;
+ } else
+ break;
+ } while (true);
+ *tail = numberFound ? string : start;
+ return sign * result;
+}
+
+/** \brief Locale-independent floating-point parser.
+ *
+ * Works similar to strtod. Leading space is NOT skipped. The input
+ * number may have an optional sign. '.' is interpreted as decimal
+ * point and may occur at most once. Optionally the number may end in
+ * [eE]<exponent>, where <exponent> is an integer as recognized by
+ * strToI. In that case the result is number * 10^exponent. After
+ * returning tail points to the first character that is not part of
+ * the floating point number. If no number was found then tail points
+ * to the start of the input string.
+ *
+ * Uses two passes for maximum accuracy. */
+static float
+strToF(const XML_Char *string, const XML_Char **tail)
+{
+ int nDigits = 0, pointPos, exponent;
+ float sign = 1.0f, result = 0.0f, scale;
+ const XML_Char *start = string, *numStart;
+
+ /* sign */
+ if (*string == '-') {
+ sign = -1.0f;
+ string++;
+ } else if (*string == '+')
+ string++;
+
+ /* first pass: determine position of decimal point, number of
+ * digits, exponent and the end of the number. */
+ numStart = string;
+ while (*string >= '0' && *string <= '9') {
+ string++;
+ nDigits++;
+ }
+ pointPos = nDigits;
+ if (*string == '.') {
+ string++;
+ while (*string >= '0' && *string <= '9') {
+ string++;
+ nDigits++;
+ }
+ }
+ if (nDigits == 0) {
+ /* no digits, no number */
+ *tail = start;
+ return 0.0f;
+ }
+ *tail = string;
+ if (*string == 'e' || *string == 'E') {
+ const XML_Char *expTail;
+ exponent = strToI (string+1, &expTail, 10);
+ if (expTail == string+1)
+ exponent = 0;
+ else
+ *tail = expTail;
+ } else
+ exponent = 0;
+ string = numStart;
+
+ /* scale of the first digit */
+ scale = sign * (float)pow (10.0, (double)(pointPos-1 + exponent));
+
+ /* second pass: parse digits */
+ do {
+ if (*string != '.') {
+ assert (*string >= '0' && *string <= '9');
+ result += scale * (float)(*string - '0');
+ scale *= 0.1f;
+ nDigits--;
+ }
+ string++;
+ } while (nDigits > 0);
+
+ return result;
+}
+
+/** \brief Parse a value of a given type. */
+static unsigned char
+parseValue(driOptionValue *v, driOptionType type, const XML_Char *string)
+{
+ const XML_Char *tail = NULL;
+ /* skip leading white-space */
+ string += strspn (string, " \f\n\r\t\v");
+ switch (type) {
+ case DRI_BOOL:
+ if (!strcmp (string, "false")) {
+ v->_bool = false;
+ tail = string + 5;
+ } else if (!strcmp (string, "true")) {
+ v->_bool = true;
+ tail = string + 4;
+ }
+ else
+ return false;
+ break;
+ case DRI_ENUM: /* enum is just a special integer */
+ case DRI_INT:
+ v->_int = strToI (string, &tail, 0);
+ break;
+ case DRI_FLOAT:
+ v->_float = strToF (string, &tail);
+ break;
+ case DRI_STRING:
+ free (v->_string);
+ v->_string = strndup(string, STRING_CONF_MAXLEN);
+ return true;
+ }
+
+ if (tail == string)
+ return false; /* empty string (or containing only white-space) */
+ /* skip trailing white space */
+ if (*tail)
+ tail += strspn (tail, " \f\n\r\t\v");
+ if (*tail)
+ return false; /* something left over that is not part of value */
+
+ return true;
+}
+
+/** \brief Parse a list of ranges of type info->type. */
+static unsigned char
+parseRanges(driOptionInfo *info, const XML_Char *string)
+{
+ XML_Char *cp, *range;
+ uint32_t nRanges, i;
+ driOptionRange *ranges;
+
+ XSTRDUP (cp, string);
+ /* pass 1: determine the number of ranges (number of commas + 1) */
+ range = cp;
+ for (nRanges = 1; *range; ++range)
+ if (*range == ',')
+ ++nRanges;
+
+ if ((ranges = malloc(nRanges*sizeof(driOptionRange))) == NULL) {
+ fprintf (stderr, "%s: %d: out of memory.\n", __FILE__, __LINE__);
+ abort();
+ }
+
+ /* pass 2: parse all ranges into preallocated array */
+ range = cp;
+ for (i = 0; i < nRanges; ++i) {
+ XML_Char *end, *sep;
+ assert (range);
+ end = strchr (range, ',');
+ if (end)
+ *end = '\0';
+ sep = strchr (range, ':');
+ if (sep) { /* non-empty interval */
+ *sep = '\0';
+ if (!parseValue (&ranges[i].start, info->type, range) ||
+ !parseValue (&ranges[i].end, info->type, sep+1))
+ break;
+ if (info->type == DRI_INT &&
+ ranges[i].start._int > ranges[i].end._int)
+ break;
+ if (info->type == DRI_FLOAT &&
+ ranges[i].start._float > ranges[i].end._float)
+ break;
+ } else { /* empty interval */
+ if (!parseValue (&ranges[i].start, info->type, range))
+ break;
+ ranges[i].end = ranges[i].start;
+ }
+ if (end)
+ range = end+1;
+ else
+ range = NULL;
+ }
+ free(cp);
+ if (i < nRanges) {
+ free(ranges);
+ return false;
+ } else
+ assert (range == NULL);
+
+ info->nRanges = nRanges;
+ info->ranges = ranges;
+ return true;
+}
+
+/** \brief Check if a value is in one of info->ranges. */
+static bool
+checkValue(const driOptionValue *v, const driOptionInfo *info)
+{
+ uint32_t i;
+ assert (info->type != DRI_BOOL); /* should be caught by the parser */
+ if (info->nRanges == 0)
+ return true;
+ switch (info->type) {
+ case DRI_ENUM: /* enum is just a special integer */
+ case DRI_INT:
+ for (i = 0; i < info->nRanges; ++i)
+ if (v->_int >= info->ranges[i].start._int &&
+ v->_int <= info->ranges[i].end._int)
+ return true;
+ break;
+ case DRI_FLOAT:
+ for (i = 0; i < info->nRanges; ++i)
+ if (v->_float >= info->ranges[i].start._float &&
+ v->_float <= info->ranges[i].end._float)
+ return true;
+ break;
+ case DRI_STRING:
+ break;
+ default:
+ assert (0); /* should never happen */
+ }
+ return false;
+}
+
+/**
+ * Print message to \c stderr if the \c LIBGL_DEBUG environment variable
+ * is set.
+ *
+ * Is called from the drivers.
+ *
+ * \param f \c printf like format string.
+ */
+static void
+__driUtilMessage(const char *f, ...)
+{
+ va_list args;
+ const char *libgl_debug;
+
+ libgl_debug=getenv("LIBGL_DEBUG");
+ if (libgl_debug && !strstr(libgl_debug, "quiet")) {
+ fprintf(stderr, "libGL: ");
+ va_start(args, f);
+ vfprintf(stderr, f, args);
+ va_end(args);
+ fprintf(stderr, "\n");
+ }
+}
+
+/** \brief Output a warning message. */
+#define XML_WARNING1(msg) do {\
+ __driUtilMessage ("Warning in %s line %d, column %d: "msg, data->name, \
+ (int) XML_GetCurrentLineNumber(data->parser), \
+ (int) XML_GetCurrentColumnNumber(data->parser)); \
+} while (0)
+#define XML_WARNING(msg, ...) do { \
+ __driUtilMessage ("Warning in %s line %d, column %d: "msg, data->name, \
+ (int) XML_GetCurrentLineNumber(data->parser), \
+ (int) XML_GetCurrentColumnNumber(data->parser), \
+ ##__VA_ARGS__); \
+} while (0)
+/** \brief Output an error message. */
+#define XML_ERROR1(msg) do { \
+ __driUtilMessage ("Error in %s line %d, column %d: "msg, data->name, \
+ (int) XML_GetCurrentLineNumber(data->parser), \
+ (int) XML_GetCurrentColumnNumber(data->parser)); \
+} while (0)
+#define XML_ERROR(msg, ...) do { \
+ __driUtilMessage ("Error in %s line %d, column %d: "msg, data->name, \
+ (int) XML_GetCurrentLineNumber(data->parser), \
+ (int) XML_GetCurrentColumnNumber(data->parser), \
+ ##__VA_ARGS__); \
+} while (0)
+/** \brief Output a fatal error message and abort. */
+#define XML_FATAL1(msg) do { \
+ fprintf (stderr, "Fatal error in %s line %d, column %d: "msg"\n", \
+ data->name, \
+ (int) XML_GetCurrentLineNumber(data->parser), \
+ (int) XML_GetCurrentColumnNumber(data->parser)); \
+ abort();\
+} while (0)
+#define XML_FATAL(msg, ...) do { \
+ fprintf (stderr, "Fatal error in %s line %d, column %d: "msg"\n", \
+ data->name, \
+ (int) XML_GetCurrentLineNumber(data->parser), \
+ (int) XML_GetCurrentColumnNumber(data->parser), \
+ ##__VA_ARGS__); \
+ abort();\
+} while (0)
+
+/** \brief Parser context for __driConfigOptions. */
+struct OptInfoData {
+ const char *name;
+ XML_Parser parser;
+ driOptionCache *cache;
+ bool inDriInfo;
+ bool inSection;
+ bool inDesc;
+ bool inOption;
+ bool inEnum;
+ int curOption;
+};
+
+/** \brief Elements in __driConfigOptions. */
+enum OptInfoElem {
+ OI_DESCRIPTION = 0, OI_DRIINFO, OI_ENUM, OI_OPTION, OI_SECTION, OI_COUNT
+};
+static const XML_Char *OptInfoElems[] = {
+ "description", "driinfo", "enum", "option", "section"
+};
+
+/** \brief Parse attributes of an enum element.
+ *
+ * We're not actually interested in the data. Just make sure this is ok
+ * for external configuration tools.
+ */
+static void
+parseEnumAttr(struct OptInfoData *data, const XML_Char **attr)
+{
+ uint32_t i;
+ const XML_Char *value = NULL, *text = NULL;
+ driOptionValue v;
+ uint32_t opt = data->curOption;
+ for (i = 0; attr[i]; i += 2) {
+ if (!strcmp (attr[i], "value")) value = attr[i+1];
+ else if (!strcmp (attr[i], "text")) text = attr[i+1];
+ else XML_FATAL("illegal enum attribute: %s.", attr[i]);
+ }
+ if (!value) XML_FATAL1 ("value attribute missing in enum.");
+ if (!text) XML_FATAL1 ("text attribute missing in enum.");
+ if (!parseValue (&v, data->cache->info[opt].type, value))
+ XML_FATAL ("illegal enum value: %s.", value);
+ if (!checkValue (&v, &data->cache->info[opt]))
+ XML_FATAL ("enum value out of valid range: %s.", value);
+}
+
+/** \brief Parse attributes of a description element.
+ *
+ * We're not actually interested in the data. Just make sure this is ok
+ * for external configuration tools.
+ */
+static void
+parseDescAttr(struct OptInfoData *data, const XML_Char **attr)
+{
+ uint32_t i;
+ const XML_Char *lang = NULL, *text = NULL;
+ for (i = 0; attr[i]; i += 2) {
+ if (!strcmp (attr[i], "lang")) lang = attr[i+1];
+ else if (!strcmp (attr[i], "text")) text = attr[i+1];
+ else XML_FATAL("illegal description attribute: %s.", attr[i]);
+ }
+ if (!lang) XML_FATAL1 ("lang attribute missing in description.");
+ if (!text) XML_FATAL1 ("text attribute missing in description.");
+}
+
+/** \brief Parse attributes of an option element. */
+static void
+parseOptInfoAttr(struct OptInfoData *data, const XML_Char **attr)
+{
+ enum OptAttr {OA_DEFAULT = 0, OA_NAME, OA_TYPE, OA_VALID, OA_COUNT};
+ static const XML_Char *optAttr[] = {"default", "name", "type", "valid"};
+ const XML_Char *attrVal[OA_COUNT] = {NULL, NULL, NULL, NULL};
+ const char *defaultVal;
+ driOptionCache *cache = data->cache;
+ uint32_t opt, i;
+ for (i = 0; attr[i]; i += 2) {
+ uint32_t attrName = bsearchStr (attr[i], optAttr, OA_COUNT);
+ if (attrName >= OA_COUNT)
+ XML_FATAL ("illegal option attribute: %s", attr[i]);
+ attrVal[attrName] = attr[i+1];
+ }
+ if (!attrVal[OA_NAME]) XML_FATAL1 ("name attribute missing in option.");
+ if (!attrVal[OA_TYPE]) XML_FATAL1 ("type attribute missing in option.");
+ if (!attrVal[OA_DEFAULT]) XML_FATAL1 ("default attribute missing in option.");
+
+ opt = findOption (cache, attrVal[OA_NAME]);
+ if (cache->info[opt].name)
+ XML_FATAL ("option %s redefined.", attrVal[OA_NAME]);
+ data->curOption = opt;
+
+ XSTRDUP (cache->info[opt].name, attrVal[OA_NAME]);
+
+ if (!strcmp (attrVal[OA_TYPE], "bool"))
+ cache->info[opt].type = DRI_BOOL;
+ else if (!strcmp (attrVal[OA_TYPE], "enum"))
+ cache->info[opt].type = DRI_ENUM;
+ else if (!strcmp (attrVal[OA_TYPE], "int"))
+ cache->info[opt].type = DRI_INT;
+ else if (!strcmp (attrVal[OA_TYPE], "float"))
+ cache->info[opt].type = DRI_FLOAT;
+ else if (!strcmp (attrVal[OA_TYPE], "string"))
+ cache->info[opt].type = DRI_STRING;
+ else
+ XML_FATAL ("illegal type in option: %s.", attrVal[OA_TYPE]);
+
+ defaultVal = getenv (cache->info[opt].name);
+ if (defaultVal != NULL) {
+ /* don't use XML_WARNING, we want the user to see this! */
+ fprintf (stderr,
+ "ATTENTION: default value of option %s overridden by environment.\n",
+ cache->info[opt].name);
+ } else
+ defaultVal = attrVal[OA_DEFAULT];
+ if (!parseValue (&cache->values[opt], cache->info[opt].type, defaultVal))
+ XML_FATAL ("illegal default value for %s: %s.", cache->info[opt].name, defaultVal);
+
+ if (attrVal[OA_VALID]) {
+ if (cache->info[opt].type == DRI_BOOL)
+ XML_FATAL1 ("boolean option with valid attribute.");
+ if (!parseRanges (&cache->info[opt], attrVal[OA_VALID]))
+ XML_FATAL ("illegal valid attribute: %s.", attrVal[OA_VALID]);
+ if (!checkValue (&cache->values[opt], &cache->info[opt]))
+ XML_FATAL ("default value out of valid range '%s': %s.",
+ attrVal[OA_VALID], defaultVal);
+ } else if (cache->info[opt].type == DRI_ENUM) {
+ XML_FATAL1 ("valid attribute missing in option (mandatory for enums).");
+ } else {
+ cache->info[opt].nRanges = 0;
+ cache->info[opt].ranges = NULL;
+ }
+}
+
+/** \brief Handler for start element events. */
+static void
+optInfoStartElem(void *userData, const XML_Char *name, const XML_Char **attr)
+{
+ struct OptInfoData *data = (struct OptInfoData *)userData;
+ enum OptInfoElem elem = bsearchStr (name, OptInfoElems, OI_COUNT);
+ switch (elem) {
+ case OI_DRIINFO:
+ if (data->inDriInfo)
+ XML_FATAL1 ("nested <driinfo> elements.");
+ if (attr[0])
+ XML_FATAL1 ("attributes specified on <driinfo> element.");
+ data->inDriInfo = true;
+ break;
+ case OI_SECTION:
+ if (!data->inDriInfo)
+ XML_FATAL1 ("<section> must be inside <driinfo>.");
+ if (data->inSection)
+ XML_FATAL1 ("nested <section> elements.");
+ if (attr[0])
+ XML_FATAL1 ("attributes specified on <section> element.");
+ data->inSection = true;
+ break;
+ case OI_DESCRIPTION:
+ if (!data->inSection && !data->inOption)
+ XML_FATAL1 ("<description> must be inside <description> or <option.");
+ if (data->inDesc)
+ XML_FATAL1 ("nested <description> elements.");
+ data->inDesc = true;
+ parseDescAttr (data, attr);
+ break;
+ case OI_OPTION:
+ if (!data->inSection)
+ XML_FATAL1 ("<option> must be inside <section>.");
+ if (data->inDesc)
+ XML_FATAL1 ("<option> nested in <description> element.");
+ if (data->inOption)
+ XML_FATAL1 ("nested <option> elements.");
+ data->inOption = true;
+ parseOptInfoAttr (data, attr);
+ break;
+ case OI_ENUM:
+ if (!(data->inOption && data->inDesc))
+ XML_FATAL1 ("<enum> must be inside <option> and <description>.");
+ if (data->inEnum)
+ XML_FATAL1 ("nested <enum> elements.");
+ data->inEnum = true;
+ parseEnumAttr (data, attr);
+ break;
+ default:
+ XML_FATAL ("unknown element: %s.", name);
+ }
+}
+
+/** \brief Handler for end element events. */
+static void
+optInfoEndElem(void *userData, const XML_Char *name)
+{
+ struct OptInfoData *data = (struct OptInfoData *)userData;
+ enum OptInfoElem elem = bsearchStr (name, OptInfoElems, OI_COUNT);
+ switch (elem) {
+ case OI_DRIINFO:
+ data->inDriInfo = false;
+ break;
+ case OI_SECTION:
+ data->inSection = false;
+ break;
+ case OI_DESCRIPTION:
+ data->inDesc = false;
+ break;
+ case OI_OPTION:
+ data->inOption = false;
+ break;
+ case OI_ENUM:
+ data->inEnum = false;
+ break;
+ default:
+ assert (0); /* should have been caught by StartElem */
+ }
+}
+
+void
+driParseOptionInfo(driOptionCache *info, const char *configOptions)
+{
+ XML_Parser p;
+ int status;
+ struct OptInfoData userData;
+ struct OptInfoData *data = &userData;
+
+ /* Make the hash table big enough to fit more than the maximum number of
+ * config options we've ever seen in a driver.
+ */
+ info->tableSize = 6;
+ info->info = calloc(1 << info->tableSize, sizeof (driOptionInfo));
+ info->values = calloc(1 << info->tableSize, sizeof (driOptionValue));
+ if (info->info == NULL || info->values == NULL) {
+ fprintf (stderr, "%s: %d: out of memory.\n", __FILE__, __LINE__);
+ abort();
+ }
+
+ p = XML_ParserCreate ("UTF-8"); /* always UTF-8 */
+ XML_SetElementHandler (p, optInfoStartElem, optInfoEndElem);
+ XML_SetUserData (p, data);
+
+ userData.name = "__driConfigOptions";
+ userData.parser = p;
+ userData.cache = info;
+ userData.inDriInfo = false;
+ userData.inSection = false;
+ userData.inDesc = false;
+ userData.inOption = false;
+ userData.inEnum = false;
+ userData.curOption = -1;
+
+ status = XML_Parse (p, configOptions, strlen (configOptions), 1);
+ if (!status)
+ XML_FATAL ("%s.", XML_ErrorString(XML_GetErrorCode(p)));
+
+ XML_ParserFree (p);
+}
+
+/** \brief Parser context for configuration files. */
+struct OptConfData {
+ const char *name;
+ XML_Parser parser;
+ driOptionCache *cache;
+ int screenNum;
+ const char *driverName, *execName;
+ uint32_t ignoringDevice;
+ uint32_t ignoringApp;
+ uint32_t inDriConf;
+ uint32_t inDevice;
+ uint32_t inApp;
+ uint32_t inOption;
+};
+
+/** \brief Elements in configuration files. */
+enum OptConfElem {
+ OC_APPLICATION = 0, OC_DEVICE, OC_DRICONF, OC_OPTION, OC_COUNT
+};
+static const XML_Char *OptConfElems[] = {
+ [OC_APPLICATION] = "application",
+ [OC_DEVICE] = "device",
+ [OC_DRICONF] = "driconf",
+ [OC_OPTION] = "option",
+};
+
+/** \brief Parse attributes of a device element. */
+static void
+parseDeviceAttr(struct OptConfData *data, const XML_Char **attr)
+{
+ uint32_t i;
+ const XML_Char *driver = NULL, *screen = NULL;
+ for (i = 0; attr[i]; i += 2) {
+ if (!strcmp (attr[i], "driver")) driver = attr[i+1];
+ else if (!strcmp (attr[i], "screen")) screen = attr[i+1];
+ else XML_WARNING("unknown device attribute: %s.", attr[i]);
+ }
+ if (driver && strcmp (driver, data->driverName))
+ data->ignoringDevice = data->inDevice;
+ else if (screen) {
+ driOptionValue screenNum;
+ if (!parseValue (&screenNum, DRI_INT, screen))
+ XML_WARNING("illegal screen number: %s.", screen);
+ else if (screenNum._int != data->screenNum)
+ data->ignoringDevice = data->inDevice;
+ }
+}
+
+/** \brief Parse attributes of an application element. */
+static void
+parseAppAttr(struct OptConfData *data, const XML_Char **attr)
+{
+ uint32_t i;
+ const XML_Char *exec = NULL;
+ for (i = 0; attr[i]; i += 2) {
+ if (!strcmp (attr[i], "name")) /* not needed here */;
+ else if (!strcmp (attr[i], "executable")) exec = attr[i+1];
+ else XML_WARNING("unknown application attribute: %s.", attr[i]);
+ }
+ if (exec && strcmp (exec, data->execName))
+ data->ignoringApp = data->inApp;
+}
+
+/** \brief Parse attributes of an option element. */
+static void
+parseOptConfAttr(struct OptConfData *data, const XML_Char **attr)
+{
+ uint32_t i;
+ const XML_Char *name = NULL, *value = NULL;
+ for (i = 0; attr[i]; i += 2) {
+ if (!strcmp (attr[i], "name")) name = attr[i+1];
+ else if (!strcmp (attr[i], "value")) value = attr[i+1];
+ else XML_WARNING("unknown option attribute: %s.", attr[i]);
+ }
+ if (!name) XML_WARNING1 ("name attribute missing in option.");
+ if (!value) XML_WARNING1 ("value attribute missing in option.");
+ if (name && value) {
+ driOptionCache *cache = data->cache;
+ uint32_t opt = findOption (cache, name);
+ if (cache->info[opt].name == NULL)
+ /* don't use XML_WARNING, drirc defines options for all drivers,
+ * but not all drivers support them */
+ return;
+ else if (getenv (cache->info[opt].name))
+ /* don't use XML_WARNING, we want the user to see this! */
+ fprintf (stderr, "ATTENTION: option value of option %s ignored.\n",
+ cache->info[opt].name);
+ else if (!parseValue (&cache->values[opt], cache->info[opt].type, value))
+ XML_WARNING ("illegal option value: %s.", value);
+ }
+}
+
+/** \brief Handler for start element events. */
+static void
+optConfStartElem(void *userData, const XML_Char *name,
+ const XML_Char **attr)
+{
+ struct OptConfData *data = (struct OptConfData *)userData;
+ enum OptConfElem elem = bsearchStr (name, OptConfElems, OC_COUNT);
+ switch (elem) {
+ case OC_DRICONF:
+ if (data->inDriConf)
+ XML_WARNING1 ("nested <driconf> elements.");
+ if (attr[0])
+ XML_WARNING1 ("attributes specified on <driconf> element.");
+ data->inDriConf++;
+ break;
+ case OC_DEVICE:
+ if (!data->inDriConf)
+ XML_WARNING1 ("<device> should be inside <driconf>.");
+ if (data->inDevice)
+ XML_WARNING1 ("nested <device> elements.");
+ data->inDevice++;
+ if (!data->ignoringDevice && !data->ignoringApp)
+ parseDeviceAttr (data, attr);
+ break;
+ case OC_APPLICATION:
+ if (!data->inDevice)
+ XML_WARNING1 ("<application> should be inside <device>.");
+ if (data->inApp)
+ XML_WARNING1 ("nested <application> elements.");
+ data->inApp++;
+ if (!data->ignoringDevice && !data->ignoringApp)
+ parseAppAttr (data, attr);
+ break;
+ case OC_OPTION:
+ if (!data->inApp)
+ XML_WARNING1 ("<option> should be inside <application>.");
+ if (data->inOption)
+ XML_WARNING1 ("nested <option> elements.");
+ data->inOption++;
+ if (!data->ignoringDevice && !data->ignoringApp)
+ parseOptConfAttr (data, attr);
+ break;
+ default:
+ XML_WARNING ("unknown element: %s.", name);
+ }
+}
+
+/** \brief Handler for end element events. */
+static void
+optConfEndElem(void *userData, const XML_Char *name)
+{
+ struct OptConfData *data = (struct OptConfData *)userData;
+ enum OptConfElem elem = bsearchStr (name, OptConfElems, OC_COUNT);
+ switch (elem) {
+ case OC_DRICONF:
+ data->inDriConf--;
+ break;
+ case OC_DEVICE:
+ if (data->inDevice-- == data->ignoringDevice)
+ data->ignoringDevice = 0;
+ break;
+ case OC_APPLICATION:
+ if (data->inApp-- == data->ignoringApp)
+ data->ignoringApp = 0;
+ break;
+ case OC_OPTION:
+ data->inOption--;
+ break;
+ default:
+ /* unknown element, warning was produced on start tag */;
+ }
+}
+
+/** \brief Initialize an option cache based on info */
+static void
+initOptionCache(driOptionCache *cache, const driOptionCache *info)
+{
+ unsigned i, size = 1 << info->tableSize;
+ cache->info = info->info;
+ cache->tableSize = info->tableSize;
+ cache->values = malloc((1<<info->tableSize) * sizeof (driOptionValue));
+ if (cache->values == NULL) {
+ fprintf (stderr, "%s: %d: out of memory.\n", __FILE__, __LINE__);
+ abort();
+ }
+ memcpy (cache->values, info->values,
+ (1<<info->tableSize) * sizeof (driOptionValue));
+ for (i = 0; i < size; ++i) {
+ if (cache->info[i].type == DRI_STRING)
+ XSTRDUP(cache->values[i]._string, info->values[i]._string);
+ }
+}
+
+/** \brief Parse the named configuration file */
+static void
+parseOneConfigFile(XML_Parser p)
+{
+#define BUF_SIZE 0x1000
+ struct OptConfData *data = (struct OptConfData *)XML_GetUserData (p);
+ int status;
+ int fd;
+
+ if ((fd = open (data->name, O_RDONLY)) == -1) {
+ __driUtilMessage ("Can't open configuration file %s: %s.",
+ data->name, strerror (errno));
+ return;
+ }
+
+ while (1) {
+ int bytesRead;
+ void *buffer = XML_GetBuffer (p, BUF_SIZE);
+ if (!buffer) {
+ __driUtilMessage ("Can't allocate parser buffer.");
+ break;
+ }
+ bytesRead = read (fd, buffer, BUF_SIZE);
+ if (bytesRead == -1) {
+ __driUtilMessage ("Error reading from configuration file %s: %s.",
+ data->name, strerror (errno));
+ break;
+ }
+ status = XML_ParseBuffer (p, bytesRead, bytesRead == 0);
+ if (!status) {
+ XML_ERROR ("%s.", XML_ErrorString(XML_GetErrorCode(p)));
+ break;
+ }
+ if (bytesRead == 0)
+ break;
+ }
+
+ close (fd);
+#undef BUF_SIZE
+}
+
+#ifndef SYSCONFDIR
+#define SYSCONFDIR "/etc"
+#endif
+
+void
+driParseConfigFiles(driOptionCache *cache, const driOptionCache *info,
+ int screenNum, const char *driverName)
+{
+ char *filenames[2] = { SYSCONFDIR "/drirc", NULL};
+ char *home;
+ uint32_t i;
+ struct OptConfData userData;
+
+ initOptionCache (cache, info);
+
+ userData.cache = cache;
+ userData.screenNum = screenNum;
+ userData.driverName = driverName;
+ userData.execName = GET_PROGRAM_NAME();
+
+ if ((home = getenv ("HOME"))) {
+ uint32_t len = strlen (home);
+ filenames[1] = malloc(len + 7+1);
+ if (filenames[1] == NULL)
+ __driUtilMessage ("Can't allocate memory for %s/.drirc.", home);
+ else {
+ memcpy (filenames[1], home, len);
+ memcpy (filenames[1] + len, "/.drirc", 7+1);
+ }
+ }
+
+ for (i = 0; i < 2; ++i) {
+ XML_Parser p;
+ if (filenames[i] == NULL)
+ continue;
+
+ p = XML_ParserCreate (NULL); /* use encoding specified by file */
+ XML_SetElementHandler (p, optConfStartElem, optConfEndElem);
+ XML_SetUserData (p, &userData);
+ userData.parser = p;
+ userData.name = filenames[i];
+ userData.ignoringDevice = 0;
+ userData.ignoringApp = 0;
+ userData.inDriConf = 0;
+ userData.inDevice = 0;
+ userData.inApp = 0;
+ userData.inOption = 0;
+
+ parseOneConfigFile (p);
+ XML_ParserFree (p);
+ }
+
+ free(filenames[1]);
+}
+
+void
+driDestroyOptionInfo(driOptionCache *info)
+{
+ driDestroyOptionCache(info);
+ if (info->info) {
+ uint32_t i, size = 1 << info->tableSize;
+ for (i = 0; i < size; ++i) {
+ if (info->info[i].name) {
+ free(info->info[i].name);
+ free(info->info[i].ranges);
+ }
+ }
+ free(info->info);
+ }
+}
+
+void
+driDestroyOptionCache(driOptionCache *cache)
+{
+ if (cache->info) {
+ unsigned i, size = 1 << cache->tableSize;
+ for (i = 0; i < size; ++i) {
+ if (cache->info[i].type == DRI_STRING)
+ free(cache->values[i]._string);
+ }
+ }
+ free(cache->values);
+}
+
+unsigned char
+driCheckOption(const driOptionCache *cache, const char *name,
+ driOptionType type)
+{
+ uint32_t i = findOption (cache, name);
+ return cache->info[i].name != NULL && cache->info[i].type == type;
+}
+
+unsigned char
+driQueryOptionb(const driOptionCache *cache, const char *name)
+{
+ uint32_t i = findOption (cache, name);
+ /* make sure the option is defined and has the correct type */
+ assert (cache->info[i].name != NULL);
+ assert (cache->info[i].type == DRI_BOOL);
+ return cache->values[i]._bool;
+}
+
+int
+driQueryOptioni(const driOptionCache *cache, const char *name)
+{
+ uint32_t i = findOption (cache, name);
+ /* make sure the option is defined and has the correct type */
+ assert (cache->info[i].name != NULL);
+ assert (cache->info[i].type == DRI_INT || cache->info[i].type == DRI_ENUM);
+ return cache->values[i]._int;
+}
+
+float
+driQueryOptionf(const driOptionCache *cache, const char *name)
+{
+ uint32_t i = findOption (cache, name);
+ /* make sure the option is defined and has the correct type */
+ assert (cache->info[i].name != NULL);
+ assert (cache->info[i].type == DRI_FLOAT);
+ return cache->values[i]._float;
+}
+
+char *
+driQueryOptionstr(const driOptionCache *cache, const char *name)
+{
+ uint32_t i = findOption (cache, name);
+ /* make sure the option is defined and has the correct type */
+ assert (cache->info[i].name != NULL);
+ assert (cache->info[i].type == DRI_STRING);
+ return cache->values[i]._string;
+}
diff --git a/lib/mesa/src/util/xmlconfig.h b/lib/mesa/src/util/xmlconfig.h
new file mode 100644
index 000000000..77aa14c20
--- /dev/null
+++ b/lib/mesa/src/util/xmlconfig.h
@@ -0,0 +1,179 @@
+/*
+ * XML DRI client-side driver configuration
+ * Copyright (C) 2003 Felix Kuehling
+ *
+ * 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
+ * FELIX KUEHLING, OR ANY OTHER CONTRIBUTORS 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 xmlconfig.h
+ * \brief Driver-independent client-side part of the XML configuration
+ * \author Felix Kuehling
+ */
+
+#ifndef __XMLCONFIG_H
+#define __XMLCONFIG_H
+
+#include "util/mesa-sha1.h"
+#include "util/ralloc.h"
+
+#define STRING_CONF_MAXLEN 25
+
+/** \brief Option data types */
+typedef enum driOptionType {
+ DRI_BOOL, DRI_ENUM, DRI_INT, DRI_FLOAT, DRI_STRING
+} driOptionType;
+
+/** \brief Option value */
+typedef union driOptionValue {
+ unsigned char _bool; /**< \brief Boolean */
+ int _int; /**< \brief Integer or Enum */
+ float _float; /**< \brief Floating-point */
+ char *_string; /**< \brief String */
+} driOptionValue;
+
+/** \brief Single range of valid values
+ *
+ * For empty ranges (a single value) start == end */
+typedef struct driOptionRange {
+ driOptionValue start; /**< \brief Start */
+ driOptionValue end; /**< \brief End */
+} driOptionRange;
+
+/** \brief Information about an option */
+typedef struct driOptionInfo {
+ char *name; /**< \brief Name */
+ driOptionType type; /**< \brief Type */
+ driOptionRange *ranges; /**< \brief Array of ranges */
+ unsigned int nRanges; /**< \brief Number of ranges */
+} driOptionInfo;
+
+/** \brief Option cache
+ *
+ * \li One in <driver>Screen caching option info and the default values
+ * \li One in each <driver>Context with the actual values for that context */
+typedef struct driOptionCache {
+ driOptionInfo *info;
+ /**< \brief Array of option infos
+ *
+ * Points to the same array in the screen and all contexts */
+ driOptionValue *values;
+ /**< \brief Array of option values
+ *
+ * \li Default values in screen
+ * \li Actual values in contexts
+ */
+ unsigned int tableSize;
+ /**< \brief Size of the arrays
+ *
+ * In the current implementation it's not actually a size but log2(size).
+ * The value is the same in the screen and all contexts. */
+} driOptionCache;
+
+/** \brief Parse XML option info from configOptions
+ *
+ * To be called in <driver>CreateScreen
+ *
+ * \param info pointer to a driOptionCache that will store the option info
+ * \param configOptions XML document describing available configuration opts
+ *
+ * For the option information to be available to external configuration tools
+ * it must be a public symbol __driConfigOptions. It is also passed as a
+ * parameter to driParseOptionInfo in order to avoid driver-independent code
+ * depending on symbols in driver-specific code. */
+void driParseOptionInfo (driOptionCache *info,
+ const char *configOptions);
+/** \brief Initialize option cache from info and parse configuration files
+ *
+ * To be called in <driver>CreateContext. screenNum and driverName select
+ * device sections. */
+void driParseConfigFiles (driOptionCache *cache, const driOptionCache *info,
+ int screenNum, const char *driverName);
+/** \brief Destroy option info
+ *
+ * To be called in <driver>DestroyScreen */
+void driDestroyOptionInfo (driOptionCache *info);
+/** \brief Destroy option cache
+ *
+ * To be called in <driver>DestroyContext */
+void driDestroyOptionCache (driOptionCache *cache);
+
+/** \brief Check if there exists a certain option */
+unsigned char driCheckOption (const driOptionCache *cache, const char *name,
+ driOptionType type);
+
+/** \brief Query a boolean option value */
+unsigned char driQueryOptionb (const driOptionCache *cache, const char *name);
+/** \brief Query an integer option value */
+int driQueryOptioni (const driOptionCache *cache, const char *name);
+/** \brief Query a floating-point option value */
+float driQueryOptionf (const driOptionCache *cache, const char *name);
+/** \brief Query a string option value */
+char *driQueryOptionstr (const driOptionCache *cache, const char *name);
+
+/**
+ * Returns a hash of the options for this application.
+ */
+static inline void
+driComputeOptionsSha1(const driOptionCache *cache, unsigned char *sha1)
+{
+ void *ctx = ralloc_context(NULL);
+ char *dri_options = ralloc_strdup(ctx, "");
+
+ for (int i = 0; i < 1 << cache->tableSize; i++) {
+ if (cache->info[i].name == NULL)
+ continue;
+
+ bool ret = false;
+ switch (cache->info[i].type) {
+ case DRI_BOOL:
+ ret = ralloc_asprintf_append(&dri_options, "%s:%u,",
+ cache->info[i].name,
+ cache->values[i]._bool);
+ break;
+ case DRI_INT:
+ case DRI_ENUM:
+ ret = ralloc_asprintf_append(&dri_options, "%s:%d,",
+ cache->info[i].name,
+ cache->values[i]._int);
+ break;
+ case DRI_FLOAT:
+ ret = ralloc_asprintf_append(&dri_options, "%s:%f,",
+ cache->info[i].name,
+ cache->values[i]._float);
+ break;
+ case DRI_STRING:
+ ret = ralloc_asprintf_append(&dri_options, "%s:%s,",
+ cache->info[i].name,
+ cache->values[i]._string);
+ break;
+ default:
+ unreachable("unsupported dri config type!");
+ }
+
+ if (!ret) {
+ break;
+ }
+ }
+
+ _mesa_sha1_compute(dri_options, strlen(dri_options), sha1);
+ ralloc_free(ctx);
+}
+
+#endif
diff --git a/lib/mesa/src/util/xmlpool.h b/lib/mesa/src/util/xmlpool.h
new file mode 100644
index 000000000..ebd4e7c86
--- /dev/null
+++ b/lib/mesa/src/util/xmlpool.h
@@ -0,0 +1,105 @@
+/*
+ * XML DRI client-side driver configuration
+ * Copyright (C) 2003 Felix Kuehling
+ *
+ * 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
+ * FELIX KUEHLING, OR ANY OTHER CONTRIBUTORS 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 xmlpool.h
+ * \brief Pool of common options
+ * \author Felix Kuehling
+ *
+ * This file defines macros that can be used to construct
+ * driConfigOptions in the drivers. Common options are defined in
+ * xmlpool/t_options.h from which xmlpool/options.h is generated with
+ * translations. This file defines generic helper macros and includes
+ * xmlpool/options.h.
+ */
+
+#ifndef __XMLPOOL_H
+#define __XMLPOOL_H
+
+/*
+ * generic macros
+ */
+
+/** \brief Begin __driConfigOptions */
+#define DRI_CONF_BEGIN \
+"<driinfo>\n"
+
+/** \brief End __driConfigOptions */
+#define DRI_CONF_END \
+"</driinfo>\n"
+
+/** \brief Begin a section of related options */
+#define DRI_CONF_SECTION_BEGIN \
+"<section>\n"
+
+/** \brief End a section of related options */
+#define DRI_CONF_SECTION_END \
+"</section>\n"
+
+/** \brief Begin an option definition */
+#define DRI_CONF_OPT_BEGIN(name,type,def) \
+"<option name=\""#name"\" type=\""#type"\" default=\""#def"\">\n"
+
+/**
+ * \brief Begin a boolean option definition, with the default value passed in
+ * as a string
+ */
+#define DRI_CONF_OPT_BEGIN_B(name,def) \
+"<option name=\""#name"\" type=\"bool\" default="#def">\n"
+
+/** \brief Begin an option definition with quoted default value */
+#define DRI_CONF_OPT_BEGIN_Q(name,type,def) \
+"<option name=\""#name"\" type=\""#type"\" default="#def">\n"
+
+/** \brief Begin an option definition with restrictions on valid values */
+#define DRI_CONF_OPT_BEGIN_V(name,type,def,valid) \
+"<option name=\""#name"\" type=\""#type"\" default=\""#def"\" valid=\""valid"\">\n"
+
+/** \brief End an option description */
+#define DRI_CONF_OPT_END \
+"</option>\n"
+
+/** \brief A verbal description in a specified language (empty version) */
+#define DRI_CONF_DESC(lang,text) \
+"<description lang=\""#lang"\" text=\""text"\"/>\n"
+
+/** \brief A verbal description in a specified language */
+#define DRI_CONF_DESC_BEGIN(lang,text) \
+"<description lang=\""#lang"\" text=\""text"\">\n"
+
+/** \brief End a description */
+#define DRI_CONF_DESC_END \
+"</description>\n"
+
+/** \brief A verbal description of an enum value */
+#define DRI_CONF_ENUM(value,text) \
+"<enum value=\""#value"\" text=\""text"\"/>\n"
+
+
+/*
+ * Predefined option sections and options with multi-lingual descriptions
+ * are now automatically generated.
+ */
+#include "xmlpool/options.h"
+
+#endif
diff --git a/lib/mesa/src/util/xmlpool/Makefile.am b/lib/mesa/src/util/xmlpool/Makefile.am
new file mode 100644
index 000000000..dfd8fb8dc
--- /dev/null
+++ b/lib/mesa/src/util/xmlpool/Makefile.am
@@ -0,0 +1,101 @@
+# Convenient makefile for managing translations.
+
+# Prerequisites:
+# - GNU gettext
+# - Python
+
+# Adding new translations
+# -----------------------
+
+# To start working on a new translation edit the POS=... line
+# below. If you want to add for example a french translation, add
+# fr.po.
+
+# Then run "make po" to generate a fresh .po file from translatable
+# strings in t_options.h. Now you can edit the new .po file (fr.po in
+# the example above) to translate the strings. Please make sure that
+# your editor encodes the file in UTF-8.
+
+# Updating existing translations
+# ------------------------------
+
+# Run "make po" to update .po files with new translatable strings from
+# t_options.h. Now you can edit the .po files you're interested
+# in. Please make sure that your editor encodes the file in UTF-8.
+
+# Updating options.h
+# ------------------
+
+# Finally run "make" to generate options.h from t_options.h with all
+# translations. Now you can rebuild the drivers. Any common options
+# used by the drivers will have option descriptions with the latest
+# translations.
+
+# Publishing translations
+# -----------------------
+
+# To get your translation(s) into Mesa CVS, please send me your
+# <lang>.po file.
+
+# More information:
+# - info gettext
+
+# The set of supported languages. Add languages as needed.
+POS=ca.po de.po es.po nl.po fr.po sv.po
+
+#
+# Don't change anything below, unless you know what you're doing.
+#
+LANGS=$(POS:%.po=%)
+MOS=$(POS:%.po=%/LC_MESSAGES/options.mo)
+POT=xmlpool.pot
+
+.PHONY: all clean pot po mo
+
+EXTRA_DIST = \
+ gen_xmlpool.py \
+ options.h \
+ t_options.h \
+ $(POS) \
+ $(MOS) \
+ SConscript
+
+BUILT_SOURCES = options.h
+CLEANFILES = \
+ options.h
+ $(POS) \
+ $(MOS)
+
+# Default target options.h
+LOCALEDIR := .
+options.h: t_options.h $(MOS)
+ $(AM_V_GEN) $(PYTHON2) $(PYTHON_FLAGS) $(srcdir)/gen_xmlpool.py $(srcdir)/t_options.h $(LOCALEDIR) $(LANGS) > options.h
+
+# Update .mo files from the corresponding .po files.
+%/LC_MESSAGES/options.mo: %.po
+ @mo="$@"; \
+ lang=$${mo%%/*}; \
+ echo "Updating ($$lang) $@ from $?."; \
+ $(MKDIR_P) $$lang/LC_MESSAGES; \
+ msgfmt -o $@ $?
+
+# Use this target to create or update .po files with new messages in
+# driconf.py.
+po: $(POT)
+ @for po in $(POS); do \
+ if [ -f $$po ]; then \
+ echo "Merging new strings from $(POT) into $@."; \
+ mv $$po $$po~; \
+ msgmerge -o $$po $$po~ $(POT); \
+ else \
+ echo "Initializing $$po from $(POT)."; \
+ msginit -i $(POT) -o $$po~ --locale=$*; \
+ sed -e 's/charset=.*\\n/charset=UTF-8\\n/' $$po~ > $$po; \
+ fi \
+ done
+
+pot: $(POT)
+
+# Extract message catalog from driconf.py.
+$(POT): t_options.h
+ xgettext -L C --from-code utf-8 -o $(POT) t_options.h
diff --git a/lib/mesa/src/util/xmlpool/Makefile.in b/lib/mesa/src/util/xmlpool/Makefile.in
new file mode 100644
index 000000000..3bb8efbf1
--- /dev/null
+++ b/lib/mesa/src/util/xmlpool/Makefile.in
@@ -0,0 +1,732 @@
+# Makefile.in generated by automake 1.15.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2017 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+# Convenient makefile for managing translations.
+
+# Prerequisites:
+# - GNU gettext
+# - Python
+
+# Adding new translations
+# -----------------------
+
+# To start working on a new translation edit the POS=... line
+# below. If you want to add for example a french translation, add
+# fr.po.
+
+# Then run "make po" to generate a fresh .po file from translatable
+# strings in t_options.h. Now you can edit the new .po file (fr.po in
+# the example above) to translate the strings. Please make sure that
+# your editor encodes the file in UTF-8.
+
+# Updating existing translations
+# ------------------------------
+
+# Run "make po" to update .po files with new translatable strings from
+# t_options.h. Now you can edit the .po files you're interested
+# in. Please make sure that your editor encodes the file in UTF-8.
+
+# Updating options.h
+# ------------------
+
+# Finally run "make" to generate options.h from t_options.h with all
+# translations. Now you can rebuild the drivers. Any common options
+# used by the drivers will have option descriptions with the latest
+# translations.
+
+# Publishing translations
+# -----------------------
+
+# To get your translation(s) into Mesa CVS, please send me your
+# <lang>.po file.
+
+# More information:
+# - info gettext
+VPATH = @srcdir@
+am__is_gnu_make = { \
+ if test -z '$(MAKELEVEL)'; then \
+ false; \
+ elif test -n '$(MAKE_HOST)'; then \
+ true; \
+ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+ true; \
+ else \
+ false; \
+ fi; \
+}
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+target_triplet = @target@
+subdir = src/util/xmlpool
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_compile_flag.m4 \
+ $(top_srcdir)/m4/ax_check_gnu_make.m4 \
+ $(top_srcdir)/m4/ax_check_python_mako_module.m4 \
+ $(top_srcdir)/m4/ax_gcc_builtin.m4 \
+ $(top_srcdir)/m4/ax_gcc_func_attribute.m4 \
+ $(top_srcdir)/m4/ax_prog_bison.m4 \
+ $(top_srcdir)/m4/ax_prog_flex.m4 \
+ $(top_srcdir)/m4/ax_pthread.m4 $(top_srcdir)/m4/libtool.m4 \
+ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
+ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/VERSION $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+SOURCES =
+DIST_SOURCES =
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+am__DIST_COMMON = $(srcdir)/Makefile.in
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMDGPU_CFLAGS = @AMDGPU_CFLAGS@
+AMDGPU_LIBS = @AMDGPU_LIBS@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+ANDROID_CFLAGS = @ANDROID_CFLAGS@
+ANDROID_LIBS = @ANDROID_LIBS@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BSYMBOLIC = @BSYMBOLIC@
+CC = @CC@
+CCAS = @CCAS@
+CCASDEPMODE = @CCASDEPMODE@
+CCASFLAGS = @CCASFLAGS@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CLANG_RESOURCE_DIR = @CLANG_RESOURCE_DIR@
+CLOCK_LIB = @CLOCK_LIB@
+CLOVER_STD_OVERRIDE = @CLOVER_STD_OVERRIDE@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+D3D_DRIVER_INSTALL_DIR = @D3D_DRIVER_INSTALL_DIR@
+DEFINES = @DEFINES@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DLOPEN_LIBS = @DLOPEN_LIBS@
+DRI2PROTO_CFLAGS = @DRI2PROTO_CFLAGS@
+DRI2PROTO_LIBS = @DRI2PROTO_LIBS@
+DRIGL_CFLAGS = @DRIGL_CFLAGS@
+DRIGL_LIBS = @DRIGL_LIBS@
+DRI_DRIVER_INSTALL_DIR = @DRI_DRIVER_INSTALL_DIR@
+DRI_DRIVER_SEARCH_DIR = @DRI_DRIVER_SEARCH_DIR@
+DRI_LIB_DEPS = @DRI_LIB_DEPS@
+DRI_PC_REQ_PRIV = @DRI_PC_REQ_PRIV@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGL_CFLAGS = @EGL_CFLAGS@
+EGL_LIB_DEPS = @EGL_LIB_DEPS@
+EGL_NATIVE_PLATFORM = @EGL_NATIVE_PLATFORM@
+EGREP = @EGREP@
+ETNAVIV_CFLAGS = @ETNAVIV_CFLAGS@
+ETNAVIV_LIBS = @ETNAVIV_LIBS@
+EXEEXT = @EXEEXT@
+EXPAT_CFLAGS = @EXPAT_CFLAGS@
+EXPAT_LIBS = @EXPAT_LIBS@
+FGREP = @FGREP@
+FREEDRENO_CFLAGS = @FREEDRENO_CFLAGS@
+FREEDRENO_LIBS = @FREEDRENO_LIBS@
+GALLIUM_PIPE_LOADER_DEFINES = @GALLIUM_PIPE_LOADER_DEFINES@
+GBM_PC_LIB_PRIV = @GBM_PC_LIB_PRIV@
+GBM_PC_REQ_PRIV = @GBM_PC_REQ_PRIV@
+GC_SECTIONS = @GC_SECTIONS@
+GLESv1_CM_LIB_DEPS = @GLESv1_CM_LIB_DEPS@
+GLESv1_CM_PC_LIB_PRIV = @GLESv1_CM_PC_LIB_PRIV@
+GLESv2_LIB_DEPS = @GLESv2_LIB_DEPS@
+GLESv2_PC_LIB_PRIV = @GLESv2_PC_LIB_PRIV@
+GLPROTO_CFLAGS = @GLPROTO_CFLAGS@
+GLPROTO_LIBS = @GLPROTO_LIBS@
+GLVND_CFLAGS = @GLVND_CFLAGS@
+GLVND_LIBS = @GLVND_LIBS@
+GLX_TLS = @GLX_TLS@
+GL_LIB = @GL_LIB@
+GL_LIB_DEPS = @GL_LIB_DEPS@
+GL_PC_CFLAGS = @GL_PC_CFLAGS@
+GL_PC_LIB_PRIV = @GL_PC_LIB_PRIV@
+GL_PC_REQ_PRIV = @GL_PC_REQ_PRIV@
+GREP = @GREP@
+HAVE_XF86VIDMODE = @HAVE_XF86VIDMODE@
+I915_CFLAGS = @I915_CFLAGS@
+I915_LIBS = @I915_LIBS@
+INDENT = @INDENT@
+INDENT_FLAGS = @INDENT_FLAGS@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LD_NO_UNDEFINED = @LD_NO_UNDEFINED@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBATOMIC_LIBS = @LIBATOMIC_LIBS@
+LIBCLC_INCLUDEDIR = @LIBCLC_INCLUDEDIR@
+LIBCLC_LIBEXECDIR = @LIBCLC_LIBEXECDIR@
+LIBDRM_CFLAGS = @LIBDRM_CFLAGS@
+LIBDRM_LIBS = @LIBDRM_LIBS@
+LIBELF_CFLAGS = @LIBELF_CFLAGS@
+LIBELF_LIBS = @LIBELF_LIBS@
+LIBGLVND_DATADIR = @LIBGLVND_DATADIR@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBSENSORS_LIBS = @LIBSENSORS_LIBS@
+LIBTOOL = @LIBTOOL@
+LIBUNWIND_CFLAGS = @LIBUNWIND_CFLAGS@
+LIBUNWIND_LIBS = @LIBUNWIND_LIBS@
+LIB_DIR = @LIB_DIR@
+LIB_EXT = @LIB_EXT@
+LIPO = @LIPO@
+LLVM_CFLAGS = @LLVM_CFLAGS@
+LLVM_CONFIG = @LLVM_CONFIG@
+LLVM_CXXFLAGS = @LLVM_CXXFLAGS@
+LLVM_INCLUDEDIR = @LLVM_INCLUDEDIR@
+LLVM_LDFLAGS = @LLVM_LDFLAGS@
+LLVM_LIBS = @LLVM_LIBS@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+MSVC2013_COMPAT_CFLAGS = @MSVC2013_COMPAT_CFLAGS@
+MSVC2013_COMPAT_CXXFLAGS = @MSVC2013_COMPAT_CXXFLAGS@
+NINE_MAJOR = @NINE_MAJOR@
+NINE_MINOR = @NINE_MINOR@
+NINE_TINY = @NINE_TINY@
+NINE_VERSION = @NINE_VERSION@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NOUVEAU_CFLAGS = @NOUVEAU_CFLAGS@
+NOUVEAU_LIBS = @NOUVEAU_LIBS@
+NVVIEUX_CFLAGS = @NVVIEUX_CFLAGS@
+NVVIEUX_LIBS = @NVVIEUX_LIBS@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OMX_BELLAGIO_CFLAGS = @OMX_BELLAGIO_CFLAGS@
+OMX_BELLAGIO_LIBS = @OMX_BELLAGIO_LIBS@
+OMX_BELLAGIO_LIB_INSTALL_DIR = @OMX_BELLAGIO_LIB_INSTALL_DIR@
+OPENCL_LIBNAME = @OPENCL_LIBNAME@
+OPENCL_VERSION = @OPENCL_VERSION@
+OSMESA_LIB = @OSMESA_LIB@
+OSMESA_LIB_DEPS = @OSMESA_LIB_DEPS@
+OSMESA_PC_LIB_PRIV = @OSMESA_PC_LIB_PRIV@
+OSMESA_PC_REQ = @OSMESA_PC_REQ@
+OSMESA_VERSION = @OSMESA_VERSION@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+POSIX_SHELL = @POSIX_SHELL@
+PTHREADSTUBS_CFLAGS = @PTHREADSTUBS_CFLAGS@
+PTHREADSTUBS_LIBS = @PTHREADSTUBS_LIBS@
+PTHREAD_CC = @PTHREAD_CC@
+PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
+PTHREAD_LIBS = @PTHREAD_LIBS@
+PWR8_CFLAGS = @PWR8_CFLAGS@
+PYTHON2 = @PYTHON2@
+RADEON_CFLAGS = @RADEON_CFLAGS@
+RADEON_LIBS = @RADEON_LIBS@
+RANLIB = @RANLIB@
+RM = @RM@
+SED = @SED@
+SELINUX_CFLAGS = @SELINUX_CFLAGS@
+SELINUX_LIBS = @SELINUX_LIBS@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SIMPENROSE_CFLAGS = @SIMPENROSE_CFLAGS@
+SIMPENROSE_LIBS = @SIMPENROSE_LIBS@
+SSE41_CFLAGS = @SSE41_CFLAGS@
+STRIP = @STRIP@
+SWR_AVX2_CXXFLAGS = @SWR_AVX2_CXXFLAGS@
+SWR_AVX_CXXFLAGS = @SWR_AVX_CXXFLAGS@
+SWR_CXX11_CXXFLAGS = @SWR_CXX11_CXXFLAGS@
+SWR_KNL_CXXFLAGS = @SWR_KNL_CXXFLAGS@
+SWR_SKX_CXXFLAGS = @SWR_SKX_CXXFLAGS@
+VALGRIND_CFLAGS = @VALGRIND_CFLAGS@
+VALGRIND_LIBS = @VALGRIND_LIBS@
+VA_CFLAGS = @VA_CFLAGS@
+VA_LIBS = @VA_LIBS@
+VA_LIB_INSTALL_DIR = @VA_LIB_INSTALL_DIR@
+VA_MAJOR = @VA_MAJOR@
+VA_MINOR = @VA_MINOR@
+VC5_SIMULATOR_CFLAGS = @VC5_SIMULATOR_CFLAGS@
+VC5_SIMULATOR_LIBS = @VC5_SIMULATOR_LIBS@
+VDPAU_CFLAGS = @VDPAU_CFLAGS@
+VDPAU_LIBS = @VDPAU_LIBS@
+VDPAU_LIB_INSTALL_DIR = @VDPAU_LIB_INSTALL_DIR@
+VDPAU_MAJOR = @VDPAU_MAJOR@
+VDPAU_MINOR = @VDPAU_MINOR@
+VERSION = @VERSION@
+VISIBILITY_CFLAGS = @VISIBILITY_CFLAGS@
+VISIBILITY_CXXFLAGS = @VISIBILITY_CXXFLAGS@
+VL_CFLAGS = @VL_CFLAGS@
+VL_LIBS = @VL_LIBS@
+VULKAN_ICD_INSTALL_DIR = @VULKAN_ICD_INSTALL_DIR@
+WAYLAND_CLIENT_CFLAGS = @WAYLAND_CLIENT_CFLAGS@
+WAYLAND_CLIENT_LIBS = @WAYLAND_CLIENT_LIBS@
+WAYLAND_PROTOCOLS_DATADIR = @WAYLAND_PROTOCOLS_DATADIR@
+WAYLAND_SCANNER = @WAYLAND_SCANNER@
+WAYLAND_SCANNER_CFLAGS = @WAYLAND_SCANNER_CFLAGS@
+WAYLAND_SCANNER_LIBS = @WAYLAND_SCANNER_LIBS@
+WAYLAND_SERVER_CFLAGS = @WAYLAND_SERVER_CFLAGS@
+WAYLAND_SERVER_LIBS = @WAYLAND_SERVER_LIBS@
+WNO_OVERRIDE_INIT = @WNO_OVERRIDE_INIT@
+X11_INCLUDES = @X11_INCLUDES@
+XA_MAJOR = @XA_MAJOR@
+XA_MINOR = @XA_MINOR@
+XA_TINY = @XA_TINY@
+XA_VERSION = @XA_VERSION@
+XCB_DRI2_CFLAGS = @XCB_DRI2_CFLAGS@
+XCB_DRI2_LIBS = @XCB_DRI2_LIBS@
+XCB_DRI3_CFLAGS = @XCB_DRI3_CFLAGS@
+XCB_DRI3_LIBS = @XCB_DRI3_LIBS@
+XF86VIDMODE_CFLAGS = @XF86VIDMODE_CFLAGS@
+XF86VIDMODE_LIBS = @XF86VIDMODE_LIBS@
+XLIBGL_CFLAGS = @XLIBGL_CFLAGS@
+XLIBGL_LIBS = @XLIBGL_LIBS@
+XVMC_CFLAGS = @XVMC_CFLAGS@
+XVMC_LIBS = @XVMC_LIBS@
+XVMC_LIB_INSTALL_DIR = @XVMC_LIB_INSTALL_DIR@
+XVMC_MAJOR = @XVMC_MAJOR@
+XVMC_MINOR = @XVMC_MINOR@
+YACC = @YACC@
+YFLAGS = @YFLAGS@
+ZLIB_CFLAGS = @ZLIB_CFLAGS@
+ZLIB_LIBS = @ZLIB_LIBS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+acv_mako_found = @acv_mako_found@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+ax_pthread_config = @ax_pthread_config@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+ifGNUmake = @ifGNUmake@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+runstatedir = @runstatedir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+
+# The set of supported languages. Add languages as needed.
+POS = ca.po de.po es.po nl.po fr.po sv.po
+
+#
+# Don't change anything below, unless you know what you're doing.
+#
+LANGS = $(POS:%.po=%)
+MOS = $(POS:%.po=%/LC_MESSAGES/options.mo)
+POT = xmlpool.pot
+EXTRA_DIST = \
+ gen_xmlpool.py \
+ options.h \
+ t_options.h \
+ $(POS) \
+ $(MOS) \
+ SConscript
+
+BUILT_SOURCES = options.h
+CLEANFILES = \
+ options.h
+
+
+# Default target options.h
+LOCALEDIR := .
+all: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) all-am
+
+.SUFFIXES:
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/util/xmlpool/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --foreign src/util/xmlpool/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+tags TAGS:
+
+ctags CTAGS:
+
+cscope cscopelist:
+
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) check-am
+all-am: Makefile
+installdirs:
+install: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+
+clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+ -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES)
+clean: clean-am
+
+clean-am: clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-am
+ -rm -f Makefile
+distclean-am: clean-am distclean-generic
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: all check install install-am install-strip
+
+.PHONY: all all-am check check-am clean clean-generic clean-libtool \
+ cscopelist-am ctags-am distclean distclean-generic \
+ distclean-libtool distdir dvi dvi-am html html-am info info-am \
+ install install-am install-data install-data-am install-dvi \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-info install-info-am install-man \
+ install-pdf install-pdf-am install-ps install-ps-am \
+ install-strip installcheck installcheck-am installdirs \
+ maintainer-clean maintainer-clean-generic mostlyclean \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags-am uninstall uninstall-am
+
+.PRECIOUS: Makefile
+
+
+.PHONY: all clean pot po mo
+ $(POS) \
+ $(MOS)
+options.h: t_options.h $(MOS)
+ $(AM_V_GEN) $(PYTHON2) $(PYTHON_FLAGS) $(srcdir)/gen_xmlpool.py $(srcdir)/t_options.h $(LOCALEDIR) $(LANGS) > options.h
+
+# Update .mo files from the corresponding .po files.
+%/LC_MESSAGES/options.mo: %.po
+ @mo="$@"; \
+ lang=$${mo%%/*}; \
+ echo "Updating ($$lang) $@ from $?."; \
+ $(MKDIR_P) $$lang/LC_MESSAGES; \
+ msgfmt -o $@ $?
+
+# Use this target to create or update .po files with new messages in
+# driconf.py.
+po: $(POT)
+ @for po in $(POS); do \
+ if [ -f $$po ]; then \
+ echo "Merging new strings from $(POT) into $@."; \
+ mv $$po $$po~; \
+ msgmerge -o $$po $$po~ $(POT); \
+ else \
+ echo "Initializing $$po from $(POT)."; \
+ msginit -i $(POT) -o $$po~ --locale=$*; \
+ sed -e 's/charset=.*\\n/charset=UTF-8\\n/' $$po~ > $$po; \
+ fi \
+ done
+
+pot: $(POT)
+
+# Extract message catalog from driconf.py.
+$(POT): t_options.h
+ xgettext -L C --from-code utf-8 -o $(POT) t_options.h
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/lib/mesa/src/util/xmlpool/SConscript b/lib/mesa/src/util/xmlpool/SConscript
new file mode 100644
index 000000000..fa42554d3
--- /dev/null
+++ b/lib/mesa/src/util/xmlpool/SConscript
@@ -0,0 +1,14 @@
+Import('*')
+
+from sys import executable as python_cmd
+
+LOCALEDIR = env.Dir('.').srcnode().abspath
+
+xmlpool_options, = env.CodeGenerate(
+ target = 'options.h',
+ script = 'gen_xmlpool.py',
+ source = ['t_options.h'],
+ command = python_cmd + ' $SCRIPT $SOURCE ' + LOCALEDIR + ' > $TARGET'
+)
+
+Export('xmlpool_options')
diff --git a/lib/mesa/src/util/xmlpool/ca.po b/lib/mesa/src/util/xmlpool/ca.po
new file mode 100644
index 000000000..03bf29613
--- /dev/null
+++ b/lib/mesa/src/util/xmlpool/ca.po
@@ -0,0 +1,348 @@
+# Language translations for Mesa package
+# Traduccions al català del paquet «Mesa».
+#
+# Copyright © 2014 Alex Henrie <alexhenrie24@gmail.com>
+#
+# 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.
+msgid ""
+msgstr ""
+"Project-Id-Version: Mesa 10.1.0-devel\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2015-02-07 02:08-0700\n"
+"PO-Revision-Date: 2015-02-23 14:28-0700\n"
+"Last-Translator: Alex Henrie <alexhenrie24@gmail.com>\n"
+"Language-Team: Catalan <ca@li.org>\n"
+"Language: ca\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Generator: Poedit 1.7.4\n"
+
+#: t_options.h:56
+msgid "Debugging"
+msgstr "Depuració"
+
+#: t_options.h:60
+msgid "Disable 3D acceleration"
+msgstr "Deshabilita l'acceleració 3D"
+
+#: t_options.h:65
+msgid "Show performance boxes"
+msgstr "Mostra les caixes de rendiment"
+
+#: t_options.h:70
+msgid "Enable flushing batchbuffer after each draw call"
+msgstr "Habilita el buidatge del batchbuffer després de cada trucada de dibuix"
+
+#: t_options.h:75
+msgid "Enable flushing GPU caches with each draw call"
+msgstr ""
+"Habilita el buidatge de les memòries cau de GPU amb cada trucada de dibuix"
+
+#: t_options.h:80
+msgid "Disable throttling on first batch after flush"
+msgstr "Deshabilita la regulació en el primer lot després de buidar"
+
+#: t_options.h:85
+msgid "Force GLSL extension default behavior to 'warn'"
+msgstr ""
+"Força que el comportament per defecte de les extensions GLSL sigui 'warn'"
+
+#: t_options.h:90
+msgid "Disable dual source blending"
+msgstr "Deshabilita la barreja de font dual"
+
+#: t_options.h:95
+msgid "Disable backslash-based line continuations in GLSL source"
+msgstr ""
+"Deshabilita les continuacions de línia basades en barra invertida en la font "
+"GLSL"
+
+#: t_options.h:100
+msgid "Disable GL_ARB_shader_bit_encoding"
+msgstr "Deshabilita el GL_ARB_shader_bit_encoding"
+
+#: t_options.h:105
+msgid ""
+"Force a default GLSL version for shaders that lack an explicit #version line"
+msgstr ""
+"Força una versió GLSL per defecte en els shaders als quals lis manca una "
+"línia #version explícita"
+
+#: t_options.h:110
+msgid "Allow GLSL #extension directives in the middle of shaders"
+msgstr "Permet les directives #extension GLSL en el mitjà dels shaders"
+
+#: t_options.h:120
+msgid "Image Quality"
+msgstr "Qualitat d'imatge"
+
+#: t_options.h:133
+msgid "Texture color depth"
+msgstr "Profunditat de color de textura"
+
+#: t_options.h:134
+msgid "Prefer frame buffer color depth"
+msgstr "Prefereix profunditat de color del framebuffer"
+
+#: t_options.h:135
+msgid "Prefer 32 bits per texel"
+msgstr "Prefereix 32 bits per texel"
+
+#: t_options.h:136
+msgid "Prefer 16 bits per texel"
+msgstr "Prefereix 16 bits per texel"
+
+#: t_options.h:137
+msgid "Force 16 bits per texel"
+msgstr "Força 16 bits per texel"
+
+#: t_options.h:143
+msgid "Initial maximum value for anisotropic texture filtering"
+msgstr "Valor màxim inicial per a la filtració de textura anisòtropa"
+
+#: t_options.h:148
+msgid "Forbid negative texture LOD bias"
+msgstr ""
+"Prohibeix una parcialitat negativa del Nivell de Detalle (LOD) de les "
+"textures"
+
+#: t_options.h:153
+msgid ""
+"Enable S3TC texture compression even if software support is not available"
+msgstr ""
+"Habilita la compressió de textures S3TC encara que el suport de programari "
+"no estigui disponible"
+
+#: t_options.h:160
+msgid "Initial color reduction method"
+msgstr "Mètode inicial de reducció de color"
+
+#: t_options.h:161
+msgid "Round colors"
+msgstr "Colors arrodonits"
+
+#: t_options.h:162
+msgid "Dither colors"
+msgstr "Colors tramats"
+
+#: t_options.h:170
+msgid "Color rounding method"
+msgstr "Mètode d'arrodoniment de color"
+
+#: t_options.h:171
+msgid "Round color components downward"
+msgstr "Arrodoneix els components de color a baix"
+
+#: t_options.h:172
+msgid "Round to nearest color"
+msgstr "Arrodoneix al color més proper"
+
+#: t_options.h:181
+msgid "Color dithering method"
+msgstr "Mètode de tramat de color"
+
+#: t_options.h:182
+msgid "Horizontal error diffusion"
+msgstr "Difusió d'error horitzontal"
+
+#: t_options.h:183
+msgid "Horizontal error diffusion, reset error at line start"
+msgstr "Difusió d'error horitzontal, reinicia l'error a l'inici de la línia"
+
+#: t_options.h:184
+msgid "Ordered 2D color dithering"
+msgstr "Tramat de color 2D ordenat"
+
+#: t_options.h:190
+msgid "Floating point depth buffer"
+msgstr "Buffer de profunditat de punt flotant"
+
+#: t_options.h:195
+msgid "A post-processing filter to cel-shade the output"
+msgstr "Un filtre de postprocessament per a aplicar cel shading a la sortida"
+
+#: t_options.h:200
+msgid "A post-processing filter to remove the red channel"
+msgstr "Un filtre de postprocessament per a eliminar el canal vermell"
+
+#: t_options.h:205
+msgid "A post-processing filter to remove the green channel"
+msgstr "Un filtre de postprocessament per a eliminar el canal verd"
+
+#: t_options.h:210
+msgid "A post-processing filter to remove the blue channel"
+msgstr "Un filtre de postprocessament per a eliminar el canal blau"
+
+#: t_options.h:215
+msgid ""
+"Morphological anti-aliasing based on Jimenez\\' MLAA. 0 to disable, 8 for "
+"default quality"
+msgstr ""
+"Antialiàsing morfològic basat en el MLAA de Jimenez. 0 per deshabilitar, 8 "
+"per qualitat per defecte"
+
+#: t_options.h:220
+msgid ""
+"Morphological anti-aliasing based on Jimenez\\' MLAA. 0 to disable, 8 for "
+"default quality. Color version, usable with 2d GL apps"
+msgstr ""
+"Antialiàsing morfològic basat en el MLAA de Jimenez. 0 per deshabilitar, 8 "
+"per qualitat per defecte. Versió en color, utilitzable amb les aplicacions "
+"GL 2D"
+
+#: t_options.h:230
+msgid "Performance"
+msgstr "Rendiment"
+
+#: t_options.h:238
+msgid "TCL mode (Transformation, Clipping, Lighting)"
+msgstr "Mode TCL (Transformació, Retall, Il·luminació)"
+
+#: t_options.h:239
+msgid "Use software TCL pipeline"
+msgstr "Utilitza la canonada TCL de programari"
+
+#: t_options.h:240
+msgid "Use hardware TCL as first TCL pipeline stage"
+msgstr "Utilitza el TCL de maquinari com a la primera fase de la canonada TCL"
+
+#: t_options.h:241
+msgid "Bypass the TCL pipeline"
+msgstr "Passa per alt la canonada TCL"
+
+#: t_options.h:242
+msgid ""
+"Bypass the TCL pipeline with state-based machine code generated on-the-fly"
+msgstr ""
+"Passa per alt la canonada TCL amb codi de màquina basat en estats, generat "
+"sobre la marxa"
+
+#: t_options.h:251
+msgid "Method to limit rendering latency"
+msgstr "Mètode per a limitar la latència de renderització"
+
+#: t_options.h:252
+msgid "Busy waiting for the graphics hardware"
+msgstr "Espera activa pel maquinari de gràfics"
+
+#: t_options.h:253
+msgid "Sleep for brief intervals while waiting for the graphics hardware"
+msgstr "Dorm per intervals breus mentre s'espera al maquinari de gràfics"
+
+#: t_options.h:254
+msgid "Let the graphics hardware emit a software interrupt and sleep"
+msgstr ""
+"Deixa que el maquinari de gràfics emeti una interrupció de programari i dormi"
+
+#: t_options.h:264
+msgid "Synchronization with vertical refresh (swap intervals)"
+msgstr "Sincronització amb refresc vertical (intervals d'intercanvi)"
+
+#: t_options.h:265
+msgid "Never synchronize with vertical refresh, ignore application's choice"
+msgstr ""
+"Mai sincronitzis amb el refresc vertical, ignora l'elecció de l'aplicació"
+
+#: t_options.h:266
+msgid "Initial swap interval 0, obey application's choice"
+msgstr "Interval d'intercanvi inicial 0, obeeix l'elecció de l'aplicació"
+
+#: t_options.h:267
+msgid "Initial swap interval 1, obey application's choice"
+msgstr "Interval d'intercanvi inicial 1, obeeix l'elecció de l'aplicació"
+
+#: t_options.h:268
+msgid ""
+"Always synchronize with vertical refresh, application chooses the minimum "
+"swap interval"
+msgstr ""
+"Sempre sincronitza amb el refresc vertical, l'aplicació tria l'interval "
+"mínim d'intercanvi"
+
+#: t_options.h:276
+msgid "Use HyperZ to boost performance"
+msgstr "Utilitza el HyperZ per a augmentar el rendiment"
+
+#: t_options.h:281
+msgid "Number of texture units used"
+msgstr "Nombre d'unitats de textura utilitzades"
+
+#: t_options.h:286
+msgid "Texture filtering quality vs. speed, AKA “brilinear” texture filtering"
+msgstr ""
+"Qualitat vs. velocitat de filtració de textura, àlies filtració \"brilinear"
+"\" de textura"
+
+#: t_options.h:294
+msgid "Used types of texture memory"
+msgstr "Tipus utilitzats de memòria de textura"
+
+#: t_options.h:295
+msgid "All available memory"
+msgstr "Tota la memòria disponible"
+
+#: t_options.h:296
+msgid "Only card memory (if available)"
+msgstr "Només memòria de targeta (si està disponible)"
+
+#: t_options.h:297
+msgid "Only GART (AGP/PCIE) memory (if available)"
+msgstr "Només memòria GART (AGP/PCIE) (si està disponible)"
+
+#: t_options.h:309
+msgid "Features that are not hardware-accelerated"
+msgstr "Característiques no accelerades per maquinari"
+
+#: t_options.h:313
+msgid "Enable extension GL_ARB_vertex_program"
+msgstr "Habilita l'extensió GL_ARB_vertex_program"
+
+#: t_options.h:323
+msgid "Miscellaneous"
+msgstr "Miscel·lània"
+
+#: t_options.h:327
+msgid "Create all visuals with a depth buffer"
+msgstr "Crea tots els visuals amb buffer de profunditat"
+
+#: t_options.h:337
+msgid "Initialization"
+msgstr "Inicialització"
+
+#: t_options.h:341
+msgid "Define the graphic device to use if possible"
+msgstr "Defineix el dispositiu de gràfics que utilitzar si és possible"
+
+#: t_options.h:350
+msgid "Gallium Nine"
+msgstr "Gallium Nine"
+
+#: t_options.h:354
+msgid ""
+"Define the throttling value. -1 for no throttling, -2 for default (usually "
+"2), 0 for glfinish behaviour"
+msgstr ""
+"Defineix el valor de regulació. -1 per a no regular, -2 per al predeterminat "
+"(generalment 2), 0 per al comportament de glfinish"
+
+#: t_options.h:359
+msgid "Use an additional thread to submit buffers."
+msgstr "Utilitza un fil addicional per a entregar els buffers."
diff --git a/lib/mesa/src/util/xmlpool/ca/LC_MESSAGES/options.mo b/lib/mesa/src/util/xmlpool/ca/LC_MESSAGES/options.mo
new file mode 100644
index 000000000..f2b0d5e16
--- /dev/null
+++ b/lib/mesa/src/util/xmlpool/ca/LC_MESSAGES/options.mo
Binary files differ
diff --git a/lib/mesa/src/util/xmlpool/de.po b/lib/mesa/src/util/xmlpool/de.po
new file mode 100644
index 000000000..7b20d00a6
--- /dev/null
+++ b/lib/mesa/src/util/xmlpool/de.po
@@ -0,0 +1,320 @@
+# German translations for DRI driver options.
+# Copyright (C) 2005 Felix Kuehling
+# This file is distributed under the same license as the Mesa package.
+# Felix Kuehling <fxkuehl@gmx.de>, 2005.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Mesa 6.3\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2014-09-25 22:29-0600\n"
+"PO-Revision-Date: 2005-04-11 01:34+0200\n"
+"Last-Translator: Felix Kuehling <fxkuehl@gmx.de>\n"
+"Language-Team: German <de@li.org>\n"
+"Language: de\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#: t_options.h:56
+msgid "Debugging"
+msgstr "Fehlersuche"
+
+#: t_options.h:60
+msgid "Disable 3D acceleration"
+msgstr "3D-Beschleunigung abschalten"
+
+#: t_options.h:65
+msgid "Show performance boxes"
+msgstr "Zeige Performanceboxen"
+
+#: t_options.h:70
+msgid "Enable flushing batchbuffer after each draw call"
+msgstr "Aktiviere sofortige Leerung des Stapelpuffers nach jedem Zeichenaufruf"
+
+#: t_options.h:75
+msgid "Enable flushing GPU caches with each draw call"
+msgstr ""
+"Aktiviere sofortige Leerung der GPU-Zwischenspeicher mit jedem Zeichenaufruf"
+
+#: t_options.h:80
+msgid "Disable throttling on first batch after flush"
+msgstr ""
+
+#: t_options.h:85
+msgid "Force GLSL extension default behavior to 'warn'"
+msgstr ""
+
+#: t_options.h:90
+msgid "Disable dual source blending"
+msgstr ""
+
+#: t_options.h:95
+msgid "Disable backslash-based line continuations in GLSL source"
+msgstr ""
+
+#: t_options.h:100
+msgid "Disable GL_ARB_shader_bit_encoding"
+msgstr ""
+
+#: t_options.h:105
+msgid ""
+"Force a default GLSL version for shaders that lack an explicit #version line"
+msgstr ""
+
+#: t_options.h:110
+msgid "Allow GLSL #extension directives in the middle of shaders"
+msgstr ""
+
+#: t_options.h:120
+msgid "Image Quality"
+msgstr "Bildqualität"
+
+#: t_options.h:133
+msgid "Texture color depth"
+msgstr "Texturfarbtiefe"
+
+#: t_options.h:134
+msgid "Prefer frame buffer color depth"
+msgstr "Bevorzuge Farbtiefe des Framebuffers"
+
+#: t_options.h:135
+msgid "Prefer 32 bits per texel"
+msgstr "Bevorzuge 32 bits pro Texel"
+
+#: t_options.h:136
+msgid "Prefer 16 bits per texel"
+msgstr "Bevorzuge 16 bits pro Texel"
+
+#: t_options.h:137
+msgid "Force 16 bits per texel"
+msgstr "Erzwinge 16 bits pro Texel"
+
+#: t_options.h:143
+msgid "Initial maximum value for anisotropic texture filtering"
+msgstr "Initialer Maximalwert für anisotropische Texturfilterung"
+
+#: t_options.h:148
+msgid "Forbid negative texture LOD bias"
+msgstr "Verbiete negative Textur-Detailgradverschiebung"
+
+#: t_options.h:153
+msgid ""
+"Enable S3TC texture compression even if software support is not available"
+msgstr ""
+"Aktiviere S3TC Texturkomprimierung auch wenn die nötige "
+"Softwareunterstützung fehlt"
+
+#: t_options.h:160
+msgid "Initial color reduction method"
+msgstr "Initiale Farbreduktionsmethode"
+
+#: t_options.h:161
+msgid "Round colors"
+msgstr "Farben runden"
+
+#: t_options.h:162
+msgid "Dither colors"
+msgstr "Farben rastern"
+
+#: t_options.h:170
+msgid "Color rounding method"
+msgstr "Farbrundungsmethode"
+
+#: t_options.h:171
+msgid "Round color components downward"
+msgstr "Farbkomponenten abrunden"
+
+#: t_options.h:172
+msgid "Round to nearest color"
+msgstr "Zur ähnlichsten Farbe runden"
+
+#: t_options.h:181
+msgid "Color dithering method"
+msgstr "Farbrasterungsmethode"
+
+#: t_options.h:182
+msgid "Horizontal error diffusion"
+msgstr "Horizontale Fehlerstreuung"
+
+#: t_options.h:183
+msgid "Horizontal error diffusion, reset error at line start"
+msgstr "Horizontale Fehlerstreuung, Fehler am Zeilenanfang zurücksetzen"
+
+#: t_options.h:184
+msgid "Ordered 2D color dithering"
+msgstr "Geordnete 2D Farbrasterung"
+
+#: t_options.h:190
+msgid "Floating point depth buffer"
+msgstr "Fließkomma z-Puffer"
+
+#: t_options.h:195
+msgid "A post-processing filter to cel-shade the output"
+msgstr "Nachbearbeitungsfilter für Cell Shading"
+
+#: t_options.h:200
+msgid "A post-processing filter to remove the red channel"
+msgstr "Nachbearbeitungsfilter zum Entfernen des Rotkanals"
+
+#: t_options.h:205
+msgid "A post-processing filter to remove the green channel"
+msgstr "Nachbearbeitungsfilter zum Entfernen des Grünkanals"
+
+#: t_options.h:210
+msgid "A post-processing filter to remove the blue channel"
+msgstr "Nachbearbeitungsfilter zum Entfernen des Blaukanals"
+
+#: t_options.h:215
+msgid ""
+"Morphological anti-aliasing based on Jimenez\\' MLAA. 0 to disable, 8 for "
+"default quality"
+msgstr ""
+"Morphologische Kantenglättung (Anti-Aliasing) basierend auf Jimenez' MLAA. 0 "
+"für deaktiviert, 8 für Standardqualität"
+
+#: t_options.h:220
+msgid ""
+"Morphological anti-aliasing based on Jimenez\\' MLAA. 0 to disable, 8 for "
+"default quality. Color version, usable with 2d GL apps"
+msgstr ""
+"Morphologische Kantenglättung (Anti-Aliasing) basierend auf Jimenez' MLAA. 0 "
+"für deaktiviert, 8 für Standardqualität. Farbversion, für 2D-Anwendungen"
+
+#: t_options.h:230
+msgid "Performance"
+msgstr "Leistung"
+
+#: t_options.h:238
+msgid "TCL mode (Transformation, Clipping, Lighting)"
+msgstr "TCL-Modus (Transformation, Clipping, Licht)"
+
+#: t_options.h:239
+msgid "Use software TCL pipeline"
+msgstr "Benutze die Software-TCL-Pipeline"
+
+#: t_options.h:240
+msgid "Use hardware TCL as first TCL pipeline stage"
+msgstr "Benutze Hardware TCL als erste Stufe der TCL-Pipeline"
+
+#: t_options.h:241
+msgid "Bypass the TCL pipeline"
+msgstr "Umgehe die TCL-Pipeline"
+
+#: t_options.h:242
+msgid ""
+"Bypass the TCL pipeline with state-based machine code generated on-the-fly"
+msgstr ""
+"Umgehe die TCL-Pipeline mit zur Laufzeit erzeugtem, zustandsbasiertem "
+"Maschinencode"
+
+#: t_options.h:251
+msgid "Method to limit rendering latency"
+msgstr "Methode zur Begrenzung der Bildverzögerung"
+
+#: t_options.h:252
+msgid "Busy waiting for the graphics hardware"
+msgstr "Aktives Warten auf die Grafikhardware"
+
+#: t_options.h:253
+msgid "Sleep for brief intervals while waiting for the graphics hardware"
+msgstr "Kurze Schlafintervalle beim Warten auf die Grafikhardware"
+
+#: t_options.h:254
+msgid "Let the graphics hardware emit a software interrupt and sleep"
+msgstr ""
+"Die Grafikhardware eine Softwareunterbrechnung erzeugen lassen und schlafen"
+
+#: t_options.h:264
+msgid "Synchronization with vertical refresh (swap intervals)"
+msgstr "Synchronisation mit der vertikalen Bildwiederholung"
+
+#: t_options.h:265
+msgid "Never synchronize with vertical refresh, ignore application's choice"
+msgstr ""
+"Niemals mit der Bildwiederholung synchronisieren, Anweisungen der Anwendung "
+"ignorieren"
+
+#: t_options.h:266
+msgid "Initial swap interval 0, obey application's choice"
+msgstr "Initiales Bildinterval 0, Anweisungen der Anwendung gehorchen"
+
+#: t_options.h:267
+msgid "Initial swap interval 1, obey application's choice"
+msgstr "Initiales Bildinterval 1, Anweisungen der Anwendung gehorchen"
+
+#: t_options.h:268
+msgid ""
+"Always synchronize with vertical refresh, application chooses the minimum "
+"swap interval"
+msgstr ""
+"Immer mit der Bildwiederholung synchronisieren, Anwendung wählt das minimale "
+"Bildintervall"
+
+#: t_options.h:276
+msgid "Use HyperZ to boost performance"
+msgstr "HyperZ zur Leistungssteigerung verwenden"
+
+#: t_options.h:281
+msgid "Number of texture units used"
+msgstr "Anzahl der benutzten Textureinheiten"
+
+#: t_options.h:286
+msgid "Texture filtering quality vs. speed, AKA “brilinear” texture filtering"
+msgstr ""
+"Texturfilterqualität versus -geschwindigkeit, auch bekannt als „brilineare“ "
+"Texturfilterung"
+
+#: t_options.h:294
+msgid "Used types of texture memory"
+msgstr "Benutzte Arten von Texturspeicher"
+
+#: t_options.h:295
+msgid "All available memory"
+msgstr "Aller verfügbarer Speicher"
+
+#: t_options.h:296
+msgid "Only card memory (if available)"
+msgstr "Nur Grafikspeicher (falls verfügbar)"
+
+#: t_options.h:297
+msgid "Only GART (AGP/PCIE) memory (if available)"
+msgstr "Nur GART-Speicher (AGP/PCIE) (falls verfügbar)"
+
+#: t_options.h:309
+msgid "Features that are not hardware-accelerated"
+msgstr "Funktionalität, die nicht hardwarebeschleunigt ist"
+
+#: t_options.h:313
+msgid "Enable extension GL_ARB_vertex_program"
+msgstr "Erweiterung GL_ARB_vertex_program aktivieren"
+
+#: t_options.h:323
+msgid "Miscellaneous"
+msgstr ""
+
+#: t_options.h:327
+msgid "Create all visuals with a depth buffer"
+msgstr ""
+
+#: t_options.h:337
+msgid "Initialization"
+msgstr ""
+
+#: t_options.h:341
+msgid "Define the graphic device to use if possible"
+msgstr ""
+
+#~ msgid "Support larger textures not guaranteed to fit into graphics memory"
+#~ msgstr ""
+#~ "Unterstütze grosse Texturen die evtl. nicht in den Grafikspeicher passen"
+
+#~ msgid "No"
+#~ msgstr "Nein"
+
+#~ msgid "At least 1 texture must fit under worst-case assumptions"
+#~ msgstr "Mindestens 1 Textur muss auch im schlechtesten Fall Platz haben"
+
+#~ msgid "Announce hardware limits"
+#~ msgstr "Benutze Hardware-Limits"
diff --git a/lib/mesa/src/util/xmlpool/de/LC_MESSAGES/options.mo b/lib/mesa/src/util/xmlpool/de/LC_MESSAGES/options.mo
new file mode 100644
index 000000000..41c2b9bed
--- /dev/null
+++ b/lib/mesa/src/util/xmlpool/de/LC_MESSAGES/options.mo
Binary files differ
diff --git a/lib/mesa/src/util/xmlpool/es.po b/lib/mesa/src/util/xmlpool/es.po
new file mode 100644
index 000000000..f9d950ac1
--- /dev/null
+++ b/lib/mesa/src/util/xmlpool/es.po
@@ -0,0 +1,332 @@
+# translation of es.po to Spanish
+# Spanish translations for PACKAGE package.
+# Copyright (C) 2005 THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# David <deifo@ono.com>, 2005.
+# David Rubio Miguélez <deifo@ono.com>, 2005.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: es\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2015-02-07 02:08-0700\n"
+"PO-Revision-Date: 2015-02-23 14:54-0700\n"
+"Last-Translator: Alex Henrie <alexhenrie24@gmail.com>\n"
+"Language-Team: Spanish <es@li.org>\n"
+"Language: es\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+"X-Generator: Poedit 1.7.4\n"
+
+#: t_options.h:56
+msgid "Debugging"
+msgstr "Depuración"
+
+#: t_options.h:60
+msgid "Disable 3D acceleration"
+msgstr "Deshabilitar aceleración 3D"
+
+#: t_options.h:65
+msgid "Show performance boxes"
+msgstr "Mostrar cajas de rendimiento"
+
+#: t_options.h:70
+msgid "Enable flushing batchbuffer after each draw call"
+msgstr "Habilitar vaciado del batchbuffer después de cada llamada de dibujo"
+
+#: t_options.h:75
+msgid "Enable flushing GPU caches with each draw call"
+msgstr "Habilitar vaciado de los cachés GPU con cada llamada de dibujo"
+
+#: t_options.h:80
+msgid "Disable throttling on first batch after flush"
+msgstr "Deshabilitar regulación del primer lote después de vaciar"
+
+#: t_options.h:85
+msgid "Force GLSL extension default behavior to 'warn'"
+msgstr ""
+"Forzar que el comportamiento por defecto de las extensiones GLSL sea 'warn'"
+
+#: t_options.h:90
+msgid "Disable dual source blending"
+msgstr "Deshabilitar mezcla de fuente dual"
+
+#: t_options.h:95
+msgid "Disable backslash-based line continuations in GLSL source"
+msgstr ""
+"Deshabilitar continuaciones de línea basadas en barra inversa en el código "
+"GLSL"
+
+#: t_options.h:100
+msgid "Disable GL_ARB_shader_bit_encoding"
+msgstr "Deshabilitar GL_ARB_shader_bit_encoding"
+
+#: t_options.h:105
+msgid ""
+"Force a default GLSL version for shaders that lack an explicit #version line"
+msgstr ""
+"Forzar una versión de GLSL por defecto en los shaders a los cuales les falta "
+"una línea #version explícita"
+
+#: t_options.h:110
+msgid "Allow GLSL #extension directives in the middle of shaders"
+msgstr "Permite directivas #extension GLSL en medio de los shaders"
+
+#: t_options.h:120
+msgid "Image Quality"
+msgstr "Calidad de imagen"
+
+#: t_options.h:133
+msgid "Texture color depth"
+msgstr "Profundidad de color de textura"
+
+#: t_options.h:134
+msgid "Prefer frame buffer color depth"
+msgstr "Preferir profundidad de color del framebuffer"
+
+#: t_options.h:135
+msgid "Prefer 32 bits per texel"
+msgstr "Preferir 32 bits por texel"
+
+#: t_options.h:136
+msgid "Prefer 16 bits per texel"
+msgstr "Preferir 16 bits por texel"
+
+#: t_options.h:137
+msgid "Force 16 bits per texel"
+msgstr "Forzar a 16 bits por texel"
+
+#: t_options.h:143
+msgid "Initial maximum value for anisotropic texture filtering"
+msgstr "Valor máximo inicial para filtrado anisotrópico de textura"
+
+#: t_options.h:148
+msgid "Forbid negative texture LOD bias"
+msgstr "Prohibir valores negativos de Nivel De Detalle (LOD) de texturas"
+
+#: t_options.h:153
+msgid ""
+"Enable S3TC texture compression even if software support is not available"
+msgstr ""
+"Habilitar la compresión de texturas S3TC incluso si el soporte por software "
+"no está disponible"
+
+#: t_options.h:160
+msgid "Initial color reduction method"
+msgstr "Método inicial de reducción de color"
+
+#: t_options.h:161
+msgid "Round colors"
+msgstr "Colores redondeados"
+
+#: t_options.h:162
+msgid "Dither colors"
+msgstr "Colores suavizados"
+
+#: t_options.h:170
+msgid "Color rounding method"
+msgstr "Método de redondeo de colores"
+
+#: t_options.h:171
+msgid "Round color components downward"
+msgstr "Redondear hacia abajo los componentes de color"
+
+#: t_options.h:172
+msgid "Round to nearest color"
+msgstr "Redondear al color más cercano"
+
+#: t_options.h:181
+msgid "Color dithering method"
+msgstr "Método de suavizado de color"
+
+#: t_options.h:182
+msgid "Horizontal error diffusion"
+msgstr "Difusión de error horizontal"
+
+#: t_options.h:183
+msgid "Horizontal error diffusion, reset error at line start"
+msgstr "Difusión de error horizontal, reiniciar error al comienzo de línea"
+
+#: t_options.h:184
+msgid "Ordered 2D color dithering"
+msgstr "Suavizado de color 2D ordenado"
+
+#: t_options.h:190
+msgid "Floating point depth buffer"
+msgstr "Búfer de profundidad en coma flotante"
+
+#: t_options.h:195
+msgid "A post-processing filter to cel-shade the output"
+msgstr "Un filtro de postprocesamiento para aplicar cel shading a la salida"
+
+#: t_options.h:200
+msgid "A post-processing filter to remove the red channel"
+msgstr "Un filtro de postprocesamiento para eliminar el canal rojo"
+
+#: t_options.h:205
+msgid "A post-processing filter to remove the green channel"
+msgstr "Un filtro de postprocesamiento para eliminar el canal verde"
+
+#: t_options.h:210
+msgid "A post-processing filter to remove the blue channel"
+msgstr "Un filtro de postprocesamiento para eliminar el canal azul"
+
+#: t_options.h:215
+msgid ""
+"Morphological anti-aliasing based on Jimenez\\' MLAA. 0 to disable, 8 for "
+"default quality"
+msgstr ""
+"Antialiasing morfológico basado en el MLAA de Jimenez. 0 para deshabilitar, "
+"8 para calidad por defecto"
+
+#: t_options.h:220
+msgid ""
+"Morphological anti-aliasing based on Jimenez\\' MLAA. 0 to disable, 8 for "
+"default quality. Color version, usable with 2d GL apps"
+msgstr ""
+"Antialiasing morfológico basado en el MLAA de Jimenez. 0 para deshabilitar, "
+"8 para calidad por defecto. Versión en color, usable con aplicaciones GL 2D"
+
+#: t_options.h:230
+msgid "Performance"
+msgstr "Rendimiento"
+
+#: t_options.h:238
+msgid "TCL mode (Transformation, Clipping, Lighting)"
+msgstr "Modo TCL (Transformación, Recorte, Iluminación)"
+
+#: t_options.h:239
+msgid "Use software TCL pipeline"
+msgstr "Usar tubería TCL por software"
+
+#: t_options.h:240
+msgid "Use hardware TCL as first TCL pipeline stage"
+msgstr "Usar TCL por hardware en la primera fase de la tubería TCL"
+
+#: t_options.h:241
+msgid "Bypass the TCL pipeline"
+msgstr "Pasar por alto la tubería TCL"
+
+#: t_options.h:242
+msgid ""
+"Bypass the TCL pipeline with state-based machine code generated on-the-fly"
+msgstr ""
+"Pasar por alto la tubería TCL con código máquina basado en estados, generado "
+"al vuelo"
+
+#: t_options.h:251
+msgid "Method to limit rendering latency"
+msgstr "Método para limitar la latencia de renderización"
+
+#: t_options.h:252
+msgid "Busy waiting for the graphics hardware"
+msgstr "Esperar activamente al hardware gráfico"
+
+#: t_options.h:253
+msgid "Sleep for brief intervals while waiting for the graphics hardware"
+msgstr "Dormir en intervalos cortos mientras se espera al hardware gráfico"
+
+#: t_options.h:254
+msgid "Let the graphics hardware emit a software interrupt and sleep"
+msgstr ""
+"Permitir que el hardware gráfico emita una interrupción de software y duerma"
+
+#: t_options.h:264
+msgid "Synchronization with vertical refresh (swap intervals)"
+msgstr "Sincronización con el refresco vertical (intervalos de intercambio)"
+
+#: t_options.h:265
+msgid "Never synchronize with vertical refresh, ignore application's choice"
+msgstr ""
+"No sincronizar nunca con el refresco vertical, ignorar la elección de la "
+"aplicación"
+
+#: t_options.h:266
+msgid "Initial swap interval 0, obey application's choice"
+msgstr ""
+"Intervalo de intercambio inicial 0, obedecer la elección de la aplicación"
+
+#: t_options.h:267
+msgid "Initial swap interval 1, obey application's choice"
+msgstr ""
+"Intervalo de intercambio inicial 1, obedecer la elección de la aplicación"
+
+#: t_options.h:268
+msgid ""
+"Always synchronize with vertical refresh, application chooses the minimum "
+"swap interval"
+msgstr ""
+"Sincronizar siempre con el refresco vertical, la aplicación elige el "
+"intervalo de intercambio mínimo"
+
+#: t_options.h:276
+msgid "Use HyperZ to boost performance"
+msgstr "Usar HyperZ para potenciar rendimiento"
+
+#: t_options.h:281
+msgid "Number of texture units used"
+msgstr "Número de unidades de textura usadas"
+
+#: t_options.h:286
+msgid "Texture filtering quality vs. speed, AKA “brilinear” texture filtering"
+msgstr ""
+"Calidad de filtrado de textura vs. velocidad, alias filtrado \"brilinear\" "
+"de textura"
+
+#: t_options.h:294
+msgid "Used types of texture memory"
+msgstr "Tipos de memoria de textura usados"
+
+#: t_options.h:295
+msgid "All available memory"
+msgstr "Toda la memoria disponible"
+
+#: t_options.h:296
+msgid "Only card memory (if available)"
+msgstr "Solo memoria de tarjeta (si está disponible)"
+
+#: t_options.h:297
+msgid "Only GART (AGP/PCIE) memory (if available)"
+msgstr "Solo memoria GART (AGP/PCIE) (si está disponible)"
+
+#: t_options.h:309
+msgid "Features that are not hardware-accelerated"
+msgstr "Características no aceleradas por hardware"
+
+#: t_options.h:313
+msgid "Enable extension GL_ARB_vertex_program"
+msgstr "Habilitar la extensión GL_ARB_vertex_program"
+
+#: t_options.h:323
+msgid "Miscellaneous"
+msgstr "Misceláneos"
+
+#: t_options.h:327
+msgid "Create all visuals with a depth buffer"
+msgstr "Crear todos los visuales con búfer de profundidad"
+
+#: t_options.h:337
+msgid "Initialization"
+msgstr "Inicialización"
+
+#: t_options.h:341
+msgid "Define the graphic device to use if possible"
+msgstr "Define el dispositivo de gráficos que usar si es posible"
+
+#: t_options.h:350
+msgid "Gallium Nine"
+msgstr "Gallium Nine"
+
+#: t_options.h:354
+msgid ""
+"Define the throttling value. -1 for no throttling, -2 for default (usually "
+"2), 0 for glfinish behaviour"
+msgstr ""
+"Define el valor de regulación. -1 para no regular, -2 para el por defecto "
+"(generalmente 2), 0 para el comportamiento de glfinish"
+
+#: t_options.h:359
+msgid "Use an additional thread to submit buffers."
+msgstr "Usar un hilo adicional para entregar los búfer."
diff --git a/lib/mesa/src/util/xmlpool/es/LC_MESSAGES/options.mo b/lib/mesa/src/util/xmlpool/es/LC_MESSAGES/options.mo
new file mode 100644
index 000000000..0145c680d
--- /dev/null
+++ b/lib/mesa/src/util/xmlpool/es/LC_MESSAGES/options.mo
Binary files differ
diff --git a/lib/mesa/src/util/xmlpool/fr.po b/lib/mesa/src/util/xmlpool/fr.po
new file mode 100644
index 000000000..fa069652c
--- /dev/null
+++ b/lib/mesa/src/util/xmlpool/fr.po
@@ -0,0 +1,310 @@
+# French translations for DRI driver options.
+# Copyright (C) 2005 Stephane Marchesin
+# This file is distributed under the same license as the Mesa package.
+# Stephane Marchesin <marchesin@icps.u-strasbg.fr>, 2005.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Mesa 6.3\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2014-09-25 22:29-0600\n"
+"PO-Revision-Date: 2005-04-11 01:34+0200\n"
+"Last-Translator: Stephane Marchesin <marchesin@icps.u-strasbg.fr>\n"
+"Language-Team: French <fr@li.org>\n"
+"Language: fr\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#: t_options.h:56
+msgid "Debugging"
+msgstr "Debogage"
+
+#: t_options.h:60
+msgid "Disable 3D acceleration"
+msgstr "Désactiver l'accélération 3D"
+
+#: t_options.h:65
+msgid "Show performance boxes"
+msgstr "Afficher les boîtes de performance"
+
+#: t_options.h:70
+msgid "Enable flushing batchbuffer after each draw call"
+msgstr ""
+
+#: t_options.h:75
+msgid "Enable flushing GPU caches with each draw call"
+msgstr ""
+
+#: t_options.h:80
+msgid "Disable throttling on first batch after flush"
+msgstr ""
+
+#: t_options.h:85
+msgid "Force GLSL extension default behavior to 'warn'"
+msgstr ""
+
+#: t_options.h:90
+msgid "Disable dual source blending"
+msgstr ""
+
+#: t_options.h:95
+msgid "Disable backslash-based line continuations in GLSL source"
+msgstr ""
+
+#: t_options.h:100
+msgid "Disable GL_ARB_shader_bit_encoding"
+msgstr ""
+
+#: t_options.h:105
+msgid ""
+"Force a default GLSL version for shaders that lack an explicit #version line"
+msgstr ""
+
+#: t_options.h:110
+msgid "Allow GLSL #extension directives in the middle of shaders"
+msgstr ""
+
+#: t_options.h:120
+msgid "Image Quality"
+msgstr "Qualité d'image"
+
+#: t_options.h:133
+msgid "Texture color depth"
+msgstr "Profondeur de texture"
+
+#: t_options.h:134
+msgid "Prefer frame buffer color depth"
+msgstr "Profondeur de couleur"
+
+#: t_options.h:135
+msgid "Prefer 32 bits per texel"
+msgstr "Préférer 32 bits par texel"
+
+#: t_options.h:136
+msgid "Prefer 16 bits per texel"
+msgstr "Prérérer 16 bits par texel"
+
+#: t_options.h:137
+msgid "Force 16 bits per texel"
+msgstr "Forcer 16 bits par texel"
+
+#: t_options.h:143
+msgid "Initial maximum value for anisotropic texture filtering"
+msgstr "Valeur maximale initiale pour le filtrage anisotropique de texture"
+
+#: t_options.h:148
+msgid "Forbid negative texture LOD bias"
+msgstr "Interdire le LOD bias negatif"
+
+#: t_options.h:153
+msgid ""
+"Enable S3TC texture compression even if software support is not available"
+msgstr ""
+"Activer la compression de texture S3TC même si le support logiciel est absent"
+
+#: t_options.h:160
+msgid "Initial color reduction method"
+msgstr "Technique de réduction de couleurs"
+
+#: t_options.h:161
+msgid "Round colors"
+msgstr "Arrondir les valeurs de couleur"
+
+#: t_options.h:162
+msgid "Dither colors"
+msgstr "Tramer les couleurs"
+
+#: t_options.h:170
+msgid "Color rounding method"
+msgstr "Méthode d'arrondi des couleurs"
+
+#: t_options.h:171
+msgid "Round color components downward"
+msgstr "Arrondi à l'inférieur"
+
+#: t_options.h:172
+msgid "Round to nearest color"
+msgstr "Arrondi au plus proche"
+
+#: t_options.h:181
+msgid "Color dithering method"
+msgstr "Méthode de tramage"
+
+#: t_options.h:182
+msgid "Horizontal error diffusion"
+msgstr "Diffusion d'erreur horizontale"
+
+#: t_options.h:183
+msgid "Horizontal error diffusion, reset error at line start"
+msgstr "Diffusion d'erreur horizontale, réinitialisé pour chaque ligne"
+
+#: t_options.h:184
+msgid "Ordered 2D color dithering"
+msgstr "Tramage ordonné des couleurs"
+
+#: t_options.h:190
+msgid "Floating point depth buffer"
+msgstr "Z-buffer en virgule flottante"
+
+#: t_options.h:195
+msgid "A post-processing filter to cel-shade the output"
+msgstr ""
+
+#: t_options.h:200
+msgid "A post-processing filter to remove the red channel"
+msgstr ""
+
+#: t_options.h:205
+msgid "A post-processing filter to remove the green channel"
+msgstr ""
+
+#: t_options.h:210
+msgid "A post-processing filter to remove the blue channel"
+msgstr ""
+
+#: t_options.h:215
+msgid ""
+"Morphological anti-aliasing based on Jimenez\\' MLAA. 0 to disable, 8 for "
+"default quality"
+msgstr ""
+
+#: t_options.h:220
+msgid ""
+"Morphological anti-aliasing based on Jimenez\\' MLAA. 0 to disable, 8 for "
+"default quality. Color version, usable with 2d GL apps"
+msgstr ""
+
+#: t_options.h:230
+msgid "Performance"
+msgstr "Performance"
+
+#: t_options.h:238
+msgid "TCL mode (Transformation, Clipping, Lighting)"
+msgstr "Mode de TCL (Transformation, Clipping, Eclairage)"
+
+#: t_options.h:239
+msgid "Use software TCL pipeline"
+msgstr "Utiliser un pipeline TCL logiciel"
+
+#: t_options.h:240
+msgid "Use hardware TCL as first TCL pipeline stage"
+msgstr "Utiliser le TCL matériel pour le premier niveau de pipeline"
+
+#: t_options.h:241
+msgid "Bypass the TCL pipeline"
+msgstr "Court-circuiter le pipeline TCL"
+
+#: t_options.h:242
+msgid ""
+"Bypass the TCL pipeline with state-based machine code generated on-the-fly"
+msgstr ""
+"Court-circuiter le pipeline TCL par une machine à états qui génère le codede "
+"TCL à la volée"
+
+#: t_options.h:251
+msgid "Method to limit rendering latency"
+msgstr "Méthode d'attente de la carte graphique"
+
+#: t_options.h:252
+msgid "Busy waiting for the graphics hardware"
+msgstr "Attente active de la carte graphique"
+
+#: t_options.h:253
+msgid "Sleep for brief intervals while waiting for the graphics hardware"
+msgstr "Attente utilisant usleep()"
+
+#: t_options.h:254
+msgid "Let the graphics hardware emit a software interrupt and sleep"
+msgstr "Utiliser les interruptions"
+
+#: t_options.h:264
+msgid "Synchronization with vertical refresh (swap intervals)"
+msgstr "Synchronisation de l'affichage avec le balayage vertical"
+
+#: t_options.h:265
+msgid "Never synchronize with vertical refresh, ignore application's choice"
+msgstr ""
+"Ne jamais synchroniser avec le balayage vertical, ignorer le choix de "
+"l'application"
+
+#: t_options.h:266
+msgid "Initial swap interval 0, obey application's choice"
+msgstr ""
+"Ne pas synchroniser avec le balayage vertical par défaut, mais obéir au "
+"choix de l'application"
+
+#: t_options.h:267
+msgid "Initial swap interval 1, obey application's choice"
+msgstr ""
+"Synchroniser avec le balayage vertical par défaut, mais obéir au choix de "
+"l'application"
+
+#: t_options.h:268
+msgid ""
+"Always synchronize with vertical refresh, application chooses the minimum "
+"swap interval"
+msgstr ""
+"Toujours synchroniser avec le balayage vertical, l'application choisit "
+"l'intervalle minimal"
+
+#: t_options.h:276
+msgid "Use HyperZ to boost performance"
+msgstr "Utiliser le HyperZ pour améliorer les performances"
+
+#: t_options.h:281
+msgid "Number of texture units used"
+msgstr "Nombre d'unités de texture"
+
+#: t_options.h:286
+msgid "Texture filtering quality vs. speed, AKA “brilinear” texture filtering"
+msgstr ""
+"Qualité/performance du filtrage trilinéaire de texture (filtrage brilinéaire)"
+
+#: t_options.h:294
+msgid "Used types of texture memory"
+msgstr "Types de mémoire de texture"
+
+#: t_options.h:295
+msgid "All available memory"
+msgstr "Utiliser toute la mémoire disponible"
+
+#: t_options.h:296
+msgid "Only card memory (if available)"
+msgstr "Utiliser uniquement la mémoire graphique (si disponible)"
+
+#: t_options.h:297
+msgid "Only GART (AGP/PCIE) memory (if available)"
+msgstr "Utiliser uniquement la mémoire GART (AGP/PCIE) (si disponible)"
+
+#: t_options.h:309
+msgid "Features that are not hardware-accelerated"
+msgstr "Fonctionnalités ne bénéficiant pas d'une accélération matérielle"
+
+#: t_options.h:313
+msgid "Enable extension GL_ARB_vertex_program"
+msgstr "Activer l'extension GL_ARB_vertex_program"
+
+#: t_options.h:323
+msgid "Miscellaneous"
+msgstr ""
+
+#: t_options.h:327
+msgid "Create all visuals with a depth buffer"
+msgstr ""
+
+#: t_options.h:337
+msgid "Initialization"
+msgstr ""
+
+#: t_options.h:341
+msgid "Define the graphic device to use if possible"
+msgstr ""
+
+#~ msgid ""
+#~ "Enable hack to allow larger textures with texture compression on radeon/"
+#~ "r200"
+#~ msgstr ""
+#~ "Activer le hack permettant l'utilisation de textures de grande taille "
+#~ "avec la compression de textures sur radeon/r200"
diff --git a/lib/mesa/src/util/xmlpool/fr/LC_MESSAGES/options.mo b/lib/mesa/src/util/xmlpool/fr/LC_MESSAGES/options.mo
new file mode 100644
index 000000000..af05db896
--- /dev/null
+++ b/lib/mesa/src/util/xmlpool/fr/LC_MESSAGES/options.mo
Binary files differ
diff --git a/lib/mesa/src/util/xmlpool/gen_xmlpool.py b/lib/mesa/src/util/xmlpool/gen_xmlpool.py
new file mode 100644
index 000000000..eb68a6517
--- /dev/null
+++ b/lib/mesa/src/util/xmlpool/gen_xmlpool.py
@@ -0,0 +1,203 @@
+
+#
+# Usage:
+# gen_xmlpool.py /path/to/t_option.h localedir lang lang lang ...
+#
+# For each given language, this script expects to find a .mo file at
+# `{localedir}/{language}/LC_MESSAGES/options.mo`.
+#
+
+import sys
+import gettext
+import re
+
+# Path to t_options.h
+template_header_path = sys.argv[1]
+
+localedir = sys.argv[2]
+
+# List of supported languages
+languages = sys.argv[3:]
+
+# Escape special characters in C strings
+def escapeCString (s):
+ escapeSeqs = {'\a' : '\\a', '\b' : '\\b', '\f' : '\\f', '\n' : '\\n',
+ '\r' : '\\r', '\t' : '\\t', '\v' : '\\v', '\\' : '\\\\'}
+ # " -> '' is a hack. Quotes (") aren't possible in XML attributes.
+ # Better use Unicode characters for typographic quotes in option
+ # descriptions and translations.
+ i = 0
+ r = ''
+ while i < len(s):
+ # Special case: escape double quote with \u201c or \u201d, depending
+ # on whether it's an open or close quote. This is needed because plain
+ # double quotes are not possible in XML attributes.
+ if s[i] == '"':
+ if i == len(s)-1 or s[i+1].isspace():
+ # close quote
+ q = u'\u201c'
+ else:
+ # open quote
+ q = u'\u201d'
+ r = r + q
+ elif escapeSeqs.has_key(s[i]):
+ r = r + escapeSeqs[s[i]]
+ else:
+ r = r + s[i]
+ i = i + 1
+ return r
+
+# Expand escape sequences in C strings (needed for gettext lookup)
+def expandCString (s):
+ escapeSeqs = {'a' : '\a', 'b' : '\b', 'f' : '\f', 'n' : '\n',
+ 'r' : '\r', 't' : '\t', 'v' : '\v',
+ '"' : '"', '\\' : '\\'}
+ i = 0
+ escape = False
+ hexa = False
+ octa = False
+ num = 0
+ digits = 0
+ r = ''
+ while i < len(s):
+ if not escape:
+ if s[i] == '\\':
+ escape = True
+ else:
+ r = r + s[i]
+ elif hexa:
+ if (s[i] >= '0' and s[i] <= '9') or \
+ (s[i] >= 'a' and s[i] <= 'f') or \
+ (s[i] >= 'A' and s[i] <= 'F'):
+ num = num * 16 + int(s[i],16)
+ digits = digits + 1
+ else:
+ digits = 2
+ if digits >= 2:
+ hexa = False
+ escape = False
+ r = r + chr(num)
+ elif octa:
+ if s[i] >= '0' and s[i] <= '7':
+ num = num * 8 + int(s[i],8)
+ digits = digits + 1
+ else:
+ digits = 3
+ if digits >= 3:
+ octa = False
+ escape = False
+ r = r + chr(num)
+ else:
+ if escapeSeqs.has_key(s[i]):
+ r = r + escapeSeqs[s[i]]
+ escape = False
+ elif s[i] >= '0' and s[i] <= '7':
+ octa = True
+ num = int(s[i],8)
+ if num <= 3:
+ digits = 1
+ else:
+ digits = 2
+ elif s[i] == 'x' or s[i] == 'X':
+ hexa = True
+ num = 0
+ digits = 0
+ else:
+ r = r + s[i]
+ escape = False
+ i = i + 1
+ return r
+
+# Expand matches. The first match is always a DESC or DESC_BEGIN match.
+# Subsequent matches are ENUM matches.
+#
+# DESC, DESC_BEGIN format: \1 \2=<lang> \3 \4=gettext(" \5=<text> \6=") \7
+# ENUM format: \1 \2=gettext(" \3=<text> \4=") \5
+def expandMatches (matches, translations, end=None):
+ assert len(matches) > 0
+ nTranslations = len(translations)
+ i = 0
+ # Expand the description+enums for all translations
+ for lang,trans in translations:
+ i = i + 1
+ # Make sure that all but the last line of a simple description
+ # are extended with a backslash.
+ suffix = ''
+ if len(matches) == 1 and i < len(translations) and \
+ not matches[0].expand (r'\7').endswith('\\'):
+ suffix = ' \\'
+ # Expand the description line. Need to use ugettext in order to allow
+ # non-ascii unicode chars in the original English descriptions.
+ text = escapeCString (trans.ugettext (unicode (expandCString (
+ matches[0].expand (r'\5')), "utf-8"))).encode("utf-8")
+ print matches[0].expand (r'\1' + lang + r'\3"' + text + r'"\7') + suffix
+ # Expand any subsequent enum lines
+ for match in matches[1:]:
+ text = escapeCString (trans.ugettext (unicode (expandCString (
+ match.expand (r'\3')), "utf-8"))).encode("utf-8")
+ print match.expand (r'\1"' + text + r'"\5')
+
+ # Expand description end
+ if end:
+ print end,
+
+# Compile a list of translation classes to all supported languages.
+# The first translation is always a NullTranslations.
+translations = [("en", gettext.NullTranslations())]
+for lang in languages:
+ try:
+ trans = gettext.translation ("options", localedir, [lang])
+ except IOError:
+ sys.stderr.write ("Warning: language '%s' not found.\n" % lang)
+ continue
+ translations.append ((lang, trans))
+
+# Regular expressions:
+reLibintl_h = re.compile (r'#\s*include\s*<libintl.h>')
+reDESC = re.compile (r'(\s*DRI_CONF_DESC\s*\(\s*)([a-z]+)(\s*,\s*)(gettext\s*\(\s*")(.*)("\s*\))(\s*\)[ \t]*\\?)$')
+reDESC_BEGIN = re.compile (r'(\s*DRI_CONF_DESC_BEGIN\s*\(\s*)([a-z]+)(\s*,\s*)(gettext\s*\(\s*")(.*)("\s*\))(\s*\)[ \t]*\\?)$')
+reENUM = re.compile (r'(\s*DRI_CONF_ENUM\s*\([^,]+,\s*)(gettext\s*\(\s*")(.*)("\s*\))(\s*\)[ \t]*\\?)$')
+reDESC_END = re.compile (r'\s*DRI_CONF_DESC_END')
+
+# Print a header
+print \
+"/***********************************************************************\n" \
+" *** THIS FILE IS GENERATED AUTOMATICALLY. DON'T EDIT! ***\n" \
+" ***********************************************************************/"
+
+# Process the options template and generate options.h with all
+# translations.
+template = file (template_header_path, "r")
+descMatches = []
+for line in template:
+ if len(descMatches) > 0:
+ matchENUM = reENUM .match (line)
+ matchDESC_END = reDESC_END.match (line)
+ if matchENUM:
+ descMatches.append (matchENUM)
+ elif matchDESC_END:
+ expandMatches (descMatches, translations, line)
+ descMatches = []
+ else:
+ sys.stderr.write (
+ "Warning: unexpected line inside description dropped:\n%s\n" \
+ % line)
+ continue
+ if reLibintl_h.search (line):
+ # Ignore (comment out) #include <libintl.h>
+ print "/* %s * commented out by gen_xmlpool.py */" % line
+ continue
+ matchDESC = reDESC .match (line)
+ matchDESC_BEGIN = reDESC_BEGIN.match (line)
+ if matchDESC:
+ assert len(descMatches) == 0
+ expandMatches ([matchDESC], translations)
+ elif matchDESC_BEGIN:
+ assert len(descMatches) == 0
+ descMatches = [matchDESC_BEGIN]
+ else:
+ print line,
+
+if len(descMatches) > 0:
+ sys.stderr.write ("Warning: unterminated description at end of file.\n")
+ expandMatches (descMatches, translations)
diff --git a/lib/mesa/src/util/xmlpool/nl.po b/lib/mesa/src/util/xmlpool/nl.po
new file mode 100644
index 000000000..86cb6e96d
--- /dev/null
+++ b/lib/mesa/src/util/xmlpool/nl.po
@@ -0,0 +1,311 @@
+# Dutch translations for PACKAGE package.
+# Copyright (C) 2005 THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# <manfred.stienstra@dwerg.net>, 2005.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2014-09-25 22:29-0600\n"
+"PO-Revision-Date: 2005-04-12 20:09+0200\n"
+"Last-Translator: Manfred Stienstra <manfred.stienstra@dwerg.net>\n"
+"Language-Team: Dutch <vertaling@nl.linux.org>\n"
+"Language: nl\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#: t_options.h:56
+msgid "Debugging"
+msgstr "Debuggen"
+
+#: t_options.h:60
+msgid "Disable 3D acceleration"
+msgstr "3D versnelling uitschakelen"
+
+#: t_options.h:65
+msgid "Show performance boxes"
+msgstr "Laat prestatie boxjes zien"
+
+#: t_options.h:70
+msgid "Enable flushing batchbuffer after each draw call"
+msgstr ""
+
+#: t_options.h:75
+msgid "Enable flushing GPU caches with each draw call"
+msgstr ""
+
+#: t_options.h:80
+msgid "Disable throttling on first batch after flush"
+msgstr ""
+
+#: t_options.h:85
+msgid "Force GLSL extension default behavior to 'warn'"
+msgstr ""
+
+#: t_options.h:90
+msgid "Disable dual source blending"
+msgstr ""
+
+#: t_options.h:95
+msgid "Disable backslash-based line continuations in GLSL source"
+msgstr ""
+
+#: t_options.h:100
+msgid "Disable GL_ARB_shader_bit_encoding"
+msgstr ""
+
+#: t_options.h:105
+msgid ""
+"Force a default GLSL version for shaders that lack an explicit #version line"
+msgstr ""
+
+#: t_options.h:110
+msgid "Allow GLSL #extension directives in the middle of shaders"
+msgstr ""
+
+#: t_options.h:120
+msgid "Image Quality"
+msgstr "Beeldkwaliteit"
+
+#: t_options.h:133
+msgid "Texture color depth"
+msgstr "Textuurkleurendiepte"
+
+#: t_options.h:134
+msgid "Prefer frame buffer color depth"
+msgstr "Prefereer kaderbufferkleurdiepte"
+
+#: t_options.h:135
+msgid "Prefer 32 bits per texel"
+msgstr "Prefereer 32 bits per texel"
+
+#: t_options.h:136
+msgid "Prefer 16 bits per texel"
+msgstr "Prefereer 16 bits per texel"
+
+#: t_options.h:137
+msgid "Force 16 bits per texel"
+msgstr "Dwing 16 bits per texel af"
+
+#: t_options.h:143
+msgid "Initial maximum value for anisotropic texture filtering"
+msgstr "Initïele maximum waarde voor anisotrophische textuur filtering"
+
+#: t_options.h:148
+msgid "Forbid negative texture LOD bias"
+msgstr "Verbied negatief niveau detailonderscheid (LOD) van texturen"
+
+#: t_options.h:153
+msgid ""
+"Enable S3TC texture compression even if software support is not available"
+msgstr ""
+"Schakel S3TC textuurcompressie in, zelfs als softwareondersteuning niet "
+"aanwezig is"
+
+#: t_options.h:160
+msgid "Initial color reduction method"
+msgstr "Initïele kleurreductie methode"
+
+#: t_options.h:161
+msgid "Round colors"
+msgstr "Rond kleuren af"
+
+#: t_options.h:162
+msgid "Dither colors"
+msgstr "Rasteriseer kleuren"
+
+#: t_options.h:170
+msgid "Color rounding method"
+msgstr "Kleurafrondingmethode"
+
+#: t_options.h:171
+msgid "Round color components downward"
+msgstr "Rond kleurencomponenten af naar beneden"
+
+#: t_options.h:172
+msgid "Round to nearest color"
+msgstr "Rond af naar dichtsbijzijnde kleur"
+
+#: t_options.h:181
+msgid "Color dithering method"
+msgstr "Kleurrasteriseringsmethode"
+
+#: t_options.h:182
+msgid "Horizontal error diffusion"
+msgstr "Horizontale foutdiffusie"
+
+#: t_options.h:183
+msgid "Horizontal error diffusion, reset error at line start"
+msgstr "Horizontale foutdiffusie, zet fout bij lijnbegin terug"
+
+#: t_options.h:184
+msgid "Ordered 2D color dithering"
+msgstr "Geordende 2D kleurrasterisering"
+
+#: t_options.h:190
+msgid "Floating point depth buffer"
+msgstr "Dieptebuffer als commagetal"
+
+#: t_options.h:195
+msgid "A post-processing filter to cel-shade the output"
+msgstr ""
+
+#: t_options.h:200
+msgid "A post-processing filter to remove the red channel"
+msgstr ""
+
+#: t_options.h:205
+msgid "A post-processing filter to remove the green channel"
+msgstr ""
+
+#: t_options.h:210
+msgid "A post-processing filter to remove the blue channel"
+msgstr ""
+
+#: t_options.h:215
+msgid ""
+"Morphological anti-aliasing based on Jimenez\\' MLAA. 0 to disable, 8 for "
+"default quality"
+msgstr ""
+
+#: t_options.h:220
+msgid ""
+"Morphological anti-aliasing based on Jimenez\\' MLAA. 0 to disable, 8 for "
+"default quality. Color version, usable with 2d GL apps"
+msgstr ""
+
+#: t_options.h:230
+msgid "Performance"
+msgstr "Prestatie"
+
+#: t_options.h:238
+msgid "TCL mode (Transformation, Clipping, Lighting)"
+msgstr "TCL-modus (Transformatie, Clipping, Licht)"
+
+#: t_options.h:239
+msgid "Use software TCL pipeline"
+msgstr "Gebruik software TCL pijpleiding"
+
+#: t_options.h:240
+msgid "Use hardware TCL as first TCL pipeline stage"
+msgstr "Gebruik hardware TCL as eerste TCL pijpleiding trap"
+
+#: t_options.h:241
+msgid "Bypass the TCL pipeline"
+msgstr "Omzeil de TCL pijpleiding"
+
+#: t_options.h:242
+msgid ""
+"Bypass the TCL pipeline with state-based machine code generated on-the-fly"
+msgstr ""
+"Omzeil de TCL pijpleiding met staatgebaseerde machinecode die tijdens "
+"executie gegenereerd wordt"
+
+#: t_options.h:251
+msgid "Method to limit rendering latency"
+msgstr "Methode om beeldopbouwvertraging te onderdrukken"
+
+#: t_options.h:252
+msgid "Busy waiting for the graphics hardware"
+msgstr "Actief wachten voor de grafische hardware"
+
+#: t_options.h:253
+msgid "Sleep for brief intervals while waiting for the graphics hardware"
+msgstr ""
+"Slaap voor korte intervallen tijdens het wachten op de grafische hardware"
+
+#: t_options.h:254
+msgid "Let the graphics hardware emit a software interrupt and sleep"
+msgstr ""
+"Laat de grafische hardware een software onderbreking uitzenden en in slaap "
+"vallen"
+
+#: t_options.h:264
+msgid "Synchronization with vertical refresh (swap intervals)"
+msgstr "Synchronisatie met verticale verversing (interval omwisselen)"
+
+#: t_options.h:265
+msgid "Never synchronize with vertical refresh, ignore application's choice"
+msgstr ""
+"Nooit synchroniseren met verticale verversing, negeer de keuze van de "
+"applicatie"
+
+#: t_options.h:266
+msgid "Initial swap interval 0, obey application's choice"
+msgstr "Initïeel omwisselingsinterval 0, honoreer de keuze van de applicatie"
+
+#: t_options.h:267
+msgid "Initial swap interval 1, obey application's choice"
+msgstr "Initïeel omwisselingsinterval 1, honoreer de keuze van de applicatie"
+
+#: t_options.h:268
+msgid ""
+"Always synchronize with vertical refresh, application chooses the minimum "
+"swap interval"
+msgstr ""
+"Synchroniseer altijd met verticale verversing, de applicatie kiest het "
+"minimum omwisselingsinterval"
+
+#: t_options.h:276
+msgid "Use HyperZ to boost performance"
+msgstr "Gebruik HyperZ om de prestaties te verbeteren"
+
+#: t_options.h:281
+msgid "Number of texture units used"
+msgstr "Aantal textuureenheden in gebruik"
+
+#: t_options.h:286
+msgid "Texture filtering quality vs. speed, AKA “brilinear” texture filtering"
+msgstr ""
+"Textuurfilterkwaliteit versus -snelheid, ookwel bekend als “brilineaire” "
+"textuurfiltering"
+
+#: t_options.h:294
+msgid "Used types of texture memory"
+msgstr "Gebruikte soorten textuurgeheugen"
+
+#: t_options.h:295
+msgid "All available memory"
+msgstr "Al het beschikbaar geheugen"
+
+#: t_options.h:296
+msgid "Only card memory (if available)"
+msgstr "Alleen geheugen op de kaart (als het aanwezig is)"
+
+#: t_options.h:297
+msgid "Only GART (AGP/PCIE) memory (if available)"
+msgstr "Alleen GART (AGP/PCIE) geheugen (als het aanwezig is)"
+
+#: t_options.h:309
+msgid "Features that are not hardware-accelerated"
+msgstr "Eigenschappen die niet hardwareversneld zijn"
+
+#: t_options.h:313
+msgid "Enable extension GL_ARB_vertex_program"
+msgstr "Zet uitbreiding GL_ARB_vertex_program aan"
+
+#: t_options.h:323
+msgid "Miscellaneous"
+msgstr ""
+
+#: t_options.h:327
+msgid "Create all visuals with a depth buffer"
+msgstr ""
+
+#: t_options.h:337
+msgid "Initialization"
+msgstr ""
+
+#: t_options.h:341
+msgid "Define the graphic device to use if possible"
+msgstr ""
+
+#~ msgid ""
+#~ "Enable hack to allow larger textures with texture compression on radeon/"
+#~ "r200"
+#~ msgstr ""
+#~ "Schakel hack in om met textuurcompressie grotere texturen toe te staan op "
+#~ "een radeon/r200"
diff --git a/lib/mesa/src/util/xmlpool/nl/LC_MESSAGES/options.mo b/lib/mesa/src/util/xmlpool/nl/LC_MESSAGES/options.mo
new file mode 100644
index 000000000..7bf40f7bd
--- /dev/null
+++ b/lib/mesa/src/util/xmlpool/nl/LC_MESSAGES/options.mo
Binary files differ
diff --git a/lib/mesa/src/util/xmlpool/options.h b/lib/mesa/src/util/xmlpool/options.h
new file mode 100644
index 000000000..ebf969d46
--- /dev/null
+++ b/lib/mesa/src/util/xmlpool/options.h
@@ -0,0 +1,1028 @@
+/***********************************************************************
+ *** THIS FILE IS GENERATED AUTOMATICALLY. DON'T EDIT! ***
+ ***********************************************************************/
+/*
+ * XML DRI client-side driver configuration
+ * Copyright (C) 2003 Felix Kuehling
+ *
+ * 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
+ * FELIX KUEHLING, OR ANY OTHER CONTRIBUTORS 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 t_options.h
+ * \brief Templates of common options
+ * \author Felix Kuehling
+ *
+ * This file defines macros for common options that can be used to
+ * construct driConfigOptions in the drivers. This file is only a
+ * template containing English descriptions for options wrapped in
+ * gettext(). xgettext can be used to extract translatable
+ * strings. These strings can then be translated by anyone familiar
+ * with GNU gettext. gen_xmlpool.py takes this template and fills in
+ * all the translations. The result (options.h) is included by
+ * xmlpool.h which in turn can be included by drivers.
+ *
+ * The macros used to describe otions in this file are defined in
+ * ../xmlpool.h.
+ */
+
+/* This is needed for xgettext to extract translatable strings.
+ * gen_xmlpool.py will discard this line. */
+/* #include <libintl.h>
+ * commented out by gen_xmlpool.py */
+
+/*
+ * predefined option sections and options with multi-lingual descriptions
+ */
+
+
+/**
+ * \brief Debugging options
+ */
+#define DRI_CONF_SECTION_DEBUG \
+DRI_CONF_SECTION_BEGIN \
+ DRI_CONF_DESC(en,"Debugging") \
+ DRI_CONF_DESC(ca,"Depuració") \
+ DRI_CONF_DESC(de,"Fehlersuche") \
+ DRI_CONF_DESC(es,"Depuración") \
+ DRI_CONF_DESC(nl,"Debuggen") \
+ DRI_CONF_DESC(fr,"Debogage") \
+ DRI_CONF_DESC(sv,"Felsökning")
+
+#define DRI_CONF_NO_RAST(def) \
+DRI_CONF_OPT_BEGIN_B(no_rast, def) \
+ DRI_CONF_DESC(en,"Disable 3D acceleration") \
+ DRI_CONF_DESC(ca,"Deshabilita l'acceleració 3D") \
+ DRI_CONF_DESC(de,"3D-Beschleunigung abschalten") \
+ DRI_CONF_DESC(es,"Deshabilitar aceleración 3D") \
+ DRI_CONF_DESC(nl,"3D versnelling uitschakelen") \
+ DRI_CONF_DESC(fr,"Désactiver l'accélération 3D") \
+ DRI_CONF_DESC(sv,"Inaktivera 3D-accelerering") \
+DRI_CONF_OPT_END
+
+#define DRI_CONF_PERFORMANCE_BOXES(def) \
+DRI_CONF_OPT_BEGIN_B(performance_boxes, def) \
+ DRI_CONF_DESC(en,"Show performance boxes") \
+ DRI_CONF_DESC(ca,"Mostra les caixes de rendiment") \
+ DRI_CONF_DESC(de,"Zeige Performanceboxen") \
+ DRI_CONF_DESC(es,"Mostrar cajas de rendimiento") \
+ DRI_CONF_DESC(nl,"Laat prestatie boxjes zien") \
+ DRI_CONF_DESC(fr,"Afficher les boîtes de performance") \
+ DRI_CONF_DESC(sv,"Visa prestandarutor") \
+DRI_CONF_OPT_END
+
+#define DRI_CONF_ALWAYS_FLUSH_BATCH(def) \
+DRI_CONF_OPT_BEGIN_B(always_flush_batch, def) \
+ DRI_CONF_DESC(en,"Enable flushing batchbuffer after each draw call") \
+ DRI_CONF_DESC(ca,"Habilita el buidatge del batchbuffer després de cada trucada de dibuix") \
+ DRI_CONF_DESC(de,"Aktiviere sofortige Leerung des Stapelpuffers nach jedem Zeichenaufruf") \
+ DRI_CONF_DESC(es,"Habilitar vaciado del batchbuffer después de cada llamada de dibujo") \
+ DRI_CONF_DESC(nl,"Enable flushing batchbuffer after each draw call") \
+ DRI_CONF_DESC(fr,"Enable flushing batchbuffer after each draw call") \
+ DRI_CONF_DESC(sv,"Enable flushing batchbuffer after each draw call") \
+DRI_CONF_OPT_END
+
+#define DRI_CONF_ALWAYS_FLUSH_CACHE(def) \
+DRI_CONF_OPT_BEGIN_B(always_flush_cache, def) \
+ DRI_CONF_DESC(en,"Enable flushing GPU caches with each draw call") \
+ DRI_CONF_DESC(ca,"Habilita el buidatge de les memòries cau de GPU amb cada trucada de dibuix") \
+ DRI_CONF_DESC(de,"Aktiviere sofortige Leerung der GPU-Zwischenspeicher mit jedem Zeichenaufruf") \
+ DRI_CONF_DESC(es,"Habilitar vaciado de los cachés GPU con cada llamada de dibujo") \
+ DRI_CONF_DESC(nl,"Enable flushing GPU caches with each draw call") \
+ DRI_CONF_DESC(fr,"Enable flushing GPU caches with each draw call") \
+ DRI_CONF_DESC(sv,"Enable flushing GPU caches with each draw call") \
+DRI_CONF_OPT_END
+
+#define DRI_CONF_DISABLE_THROTTLING(def) \
+DRI_CONF_OPT_BEGIN_B(disable_throttling, def) \
+ DRI_CONF_DESC(en,"Disable throttling on first batch after flush") \
+ DRI_CONF_DESC(ca,"Deshabilita la regulació en el primer lot després de buidar") \
+ DRI_CONF_DESC(de,"Disable throttling on first batch after flush") \
+ DRI_CONF_DESC(es,"Deshabilitar regulación del primer lote después de vaciar") \
+ DRI_CONF_DESC(nl,"Disable throttling on first batch after flush") \
+ DRI_CONF_DESC(fr,"Disable throttling on first batch after flush") \
+ DRI_CONF_DESC(sv,"Disable throttling on first batch after flush") \
+DRI_CONF_OPT_END
+
+#define DRI_CONF_FORCE_GLSL_EXTENSIONS_WARN(def) \
+DRI_CONF_OPT_BEGIN_B(force_glsl_extensions_warn, def) \
+ DRI_CONF_DESC(en,"Force GLSL extension default behavior to 'warn'") \
+ DRI_CONF_DESC(ca,"Força que el comportament per defecte de les extensions GLSL sigui 'warn'") \
+ DRI_CONF_DESC(de,"Force GLSL extension default behavior to 'warn'") \
+ DRI_CONF_DESC(es,"Forzar que el comportamiento por defecto de las extensiones GLSL sea 'warn'") \
+ DRI_CONF_DESC(nl,"Force GLSL extension default behavior to 'warn'") \
+ DRI_CONF_DESC(fr,"Force GLSL extension default behavior to 'warn'") \
+ DRI_CONF_DESC(sv,"Force GLSL extension default behavior to 'warn'") \
+DRI_CONF_OPT_END
+
+#define DRI_CONF_DISABLE_BLEND_FUNC_EXTENDED(def) \
+DRI_CONF_OPT_BEGIN_B(disable_blend_func_extended, def) \
+ DRI_CONF_DESC(en,"Disable dual source blending") \
+ DRI_CONF_DESC(ca,"Deshabilita la barreja de font dual") \
+ DRI_CONF_DESC(de,"Disable dual source blending") \
+ DRI_CONF_DESC(es,"Deshabilitar mezcla de fuente dual") \
+ DRI_CONF_DESC(nl,"Disable dual source blending") \
+ DRI_CONF_DESC(fr,"Disable dual source blending") \
+ DRI_CONF_DESC(sv,"Disable dual source blending") \
+DRI_CONF_OPT_END
+
+#define DRI_CONF_DUAL_COLOR_BLEND_BY_LOCATION(def) \
+DRI_CONF_OPT_BEGIN_B(dual_color_blend_by_location, def) \
+ DRI_CONF_DESC(en,"Identify dual color blending sources by location rather than index") \
+ DRI_CONF_DESC(ca,"Identify dual color blending sources by location rather than index") \
+ DRI_CONF_DESC(de,"Identify dual color blending sources by location rather than index") \
+ DRI_CONF_DESC(es,"Identify dual color blending sources by location rather than index") \
+ DRI_CONF_DESC(nl,"Identify dual color blending sources by location rather than index") \
+ DRI_CONF_DESC(fr,"Identify dual color blending sources by location rather than index") \
+ DRI_CONF_DESC(sv,"Identify dual color blending sources by location rather than index") \
+DRI_CONF_OPT_END
+
+#define DRI_CONF_DISABLE_GLSL_LINE_CONTINUATIONS(def) \
+DRI_CONF_OPT_BEGIN_B(disable_glsl_line_continuations, def) \
+ DRI_CONF_DESC(en,"Disable backslash-based line continuations in GLSL source") \
+ DRI_CONF_DESC(ca,"Deshabilita les continuacions de línia basades en barra invertida en la font GLSL") \
+ DRI_CONF_DESC(de,"Disable backslash-based line continuations in GLSL source") \
+ DRI_CONF_DESC(es,"Deshabilitar continuaciones de línea basadas en barra inversa en el código GLSL") \
+ DRI_CONF_DESC(nl,"Disable backslash-based line continuations in GLSL source") \
+ DRI_CONF_DESC(fr,"Disable backslash-based line continuations in GLSL source") \
+ DRI_CONF_DESC(sv,"Disable backslash-based line continuations in GLSL source") \
+DRI_CONF_OPT_END
+
+#define DRI_CONF_DISABLE_SHADER_BIT_ENCODING(def) \
+DRI_CONF_OPT_BEGIN_B(disable_shader_bit_encoding, def) \
+ DRI_CONF_DESC(en,"Disable GL_ARB_shader_bit_encoding") \
+ DRI_CONF_DESC(ca,"Deshabilita el GL_ARB_shader_bit_encoding") \
+ DRI_CONF_DESC(de,"Disable GL_ARB_shader_bit_encoding") \
+ DRI_CONF_DESC(es,"Deshabilitar GL_ARB_shader_bit_encoding") \
+ DRI_CONF_DESC(nl,"Disable GL_ARB_shader_bit_encoding") \
+ DRI_CONF_DESC(fr,"Disable GL_ARB_shader_bit_encoding") \
+ DRI_CONF_DESC(sv,"Disable GL_ARB_shader_bit_encoding") \
+DRI_CONF_OPT_END
+
+#define DRI_CONF_FORCE_GLSL_VERSION(def) \
+DRI_CONF_OPT_BEGIN_V(force_glsl_version, int, def, "0:999") \
+ DRI_CONF_DESC(en,"Force a default GLSL version for shaders that lack an explicit #version line") \
+ DRI_CONF_DESC(ca,"Força una versió GLSL per defecte en els shaders als quals lis manca una línia #version explícita") \
+ DRI_CONF_DESC(de,"Force a default GLSL version for shaders that lack an explicit #version line") \
+ DRI_CONF_DESC(es,"Forzar una versión de GLSL por defecto en los shaders a los cuales les falta una línea #version explícita") \
+ DRI_CONF_DESC(nl,"Force a default GLSL version for shaders that lack an explicit #version line") \
+ DRI_CONF_DESC(fr,"Force a default GLSL version for shaders that lack an explicit #version line") \
+ DRI_CONF_DESC(sv,"Force a default GLSL version for shaders that lack an explicit #version line") \
+DRI_CONF_OPT_END
+
+#define DRI_CONF_ALLOW_GLSL_EXTENSION_DIRECTIVE_MIDSHADER(def) \
+DRI_CONF_OPT_BEGIN_B(allow_glsl_extension_directive_midshader, def) \
+ DRI_CONF_DESC(en,"Allow GLSL #extension directives in the middle of shaders") \
+ DRI_CONF_DESC(ca,"Permet les directives #extension GLSL en el mitjà dels shaders") \
+ DRI_CONF_DESC(de,"Allow GLSL #extension directives in the middle of shaders") \
+ DRI_CONF_DESC(es,"Permite directivas #extension GLSL en medio de los shaders") \
+ DRI_CONF_DESC(nl,"Allow GLSL #extension directives in the middle of shaders") \
+ DRI_CONF_DESC(fr,"Allow GLSL #extension directives in the middle of shaders") \
+ DRI_CONF_DESC(sv,"Allow GLSL #extension directives in the middle of shaders") \
+DRI_CONF_OPT_END
+
+#define DRI_CONF_ALLOW_GLSL_BUILTIN_VARIABLE_REDECLARATION(def) \
+DRI_CONF_OPT_BEGIN_B(allow_glsl_builtin_variable_redeclaration, def) \
+ DRI_CONF_DESC(en,"Allow GLSL built-in variables to be redeclared verbatim") \
+ DRI_CONF_DESC(ca,"Allow GLSL built-in variables to be redeclared verbatim") \
+ DRI_CONF_DESC(de,"Allow GLSL built-in variables to be redeclared verbatim") \
+ DRI_CONF_DESC(es,"Allow GLSL built-in variables to be redeclared verbatim") \
+ DRI_CONF_DESC(nl,"Allow GLSL built-in variables to be redeclared verbatim") \
+ DRI_CONF_DESC(fr,"Allow GLSL built-in variables to be redeclared verbatim") \
+ DRI_CONF_DESC(sv,"Allow GLSL built-in variables to be redeclared verbatim") \
+DRI_CONF_OPT_END
+
+#define DRI_CONF_ALLOW_HIGHER_COMPAT_VERSION(def) \
+DRI_CONF_OPT_BEGIN_B(allow_higher_compat_version, def) \
+ DRI_CONF_DESC(en,"Allow a higher compat profile (version 3.1+) for apps that request it") \
+ DRI_CONF_DESC(ca,"Allow a higher compat profile (version 3.1+) for apps that request it") \
+ DRI_CONF_DESC(de,"Allow a higher compat profile (version 3.1+) for apps that request it") \
+ DRI_CONF_DESC(es,"Allow a higher compat profile (version 3.1+) for apps that request it") \
+ DRI_CONF_DESC(nl,"Allow a higher compat profile (version 3.1+) for apps that request it") \
+ DRI_CONF_DESC(fr,"Allow a higher compat profile (version 3.1+) for apps that request it") \
+ DRI_CONF_DESC(sv,"Allow a higher compat profile (version 3.1+) for apps that request it") \
+DRI_CONF_OPT_END
+
+#define DRI_CONF_FORCE_GLSL_ABS_SQRT(def) \
+DRI_CONF_OPT_BEGIN_B(force_glsl_abs_sqrt, def) \
+ DRI_CONF_DESC(en,"Force computing the absolute value for sqrt() and inversesqrt()") \
+ DRI_CONF_DESC(ca,"Force computing the absolute value for sqrt() and inversesqrt()") \
+ DRI_CONF_DESC(de,"Force computing the absolute value for sqrt() and inversesqrt()") \
+ DRI_CONF_DESC(es,"Force computing the absolute value for sqrt() and inversesqrt()") \
+ DRI_CONF_DESC(nl,"Force computing the absolute value for sqrt() and inversesqrt()") \
+ DRI_CONF_DESC(fr,"Force computing the absolute value for sqrt() and inversesqrt()") \
+ DRI_CONF_DESC(sv,"Force computing the absolute value for sqrt() and inversesqrt()") \
+DRI_CONF_OPT_END
+
+#define DRI_CONF_GLSL_CORRECT_DERIVATIVES_AFTER_DISCARD(def) \
+DRI_CONF_OPT_BEGIN_B(glsl_correct_derivatives_after_discard, def) \
+ DRI_CONF_DESC(en,"Implicit and explicit derivatives after a discard behave as if the discard didn't happen") \
+ DRI_CONF_DESC(ca,"Implicit and explicit derivatives after a discard behave as if the discard didn't happen") \
+ DRI_CONF_DESC(de,"Implicit and explicit derivatives after a discard behave as if the discard didn't happen") \
+ DRI_CONF_DESC(es,"Implicit and explicit derivatives after a discard behave as if the discard didn't happen") \
+ DRI_CONF_DESC(nl,"Implicit and explicit derivatives after a discard behave as if the discard didn't happen") \
+ DRI_CONF_DESC(fr,"Implicit and explicit derivatives after a discard behave as if the discard didn't happen") \
+ DRI_CONF_DESC(sv,"Implicit and explicit derivatives after a discard behave as if the discard didn't happen") \
+DRI_CONF_OPT_END
+
+#define DRI_CONF_ALLOW_GLSL_CROSS_STAGE_INTERPOLATION_MISMATCH(def) \
+DRI_CONF_OPT_BEGIN_B(allow_glsl_cross_stage_interpolation_mismatch, def) \
+ DRI_CONF_DESC(en,"Allow interpolation qualifier mismatch across shader stages") \
+ DRI_CONF_DESC(ca,"Allow interpolation qualifier mismatch across shader stages") \
+ DRI_CONF_DESC(de,"Allow interpolation qualifier mismatch across shader stages") \
+ DRI_CONF_DESC(es,"Allow interpolation qualifier mismatch across shader stages") \
+ DRI_CONF_DESC(nl,"Allow interpolation qualifier mismatch across shader stages") \
+ DRI_CONF_DESC(fr,"Allow interpolation qualifier mismatch across shader stages") \
+ DRI_CONF_DESC(sv,"Allow interpolation qualifier mismatch across shader stages") \
+DRI_CONF_OPT_END
+
+/**
+ * \brief Image quality-related options
+ */
+#define DRI_CONF_SECTION_QUALITY \
+DRI_CONF_SECTION_BEGIN \
+ DRI_CONF_DESC(en,"Image Quality") \
+ DRI_CONF_DESC(ca,"Qualitat d'imatge") \
+ DRI_CONF_DESC(de,"Bildqualität") \
+ DRI_CONF_DESC(es,"Calidad de imagen") \
+ DRI_CONF_DESC(nl,"Beeldkwaliteit") \
+ DRI_CONF_DESC(fr,"Qualité d'image") \
+ DRI_CONF_DESC(sv,"Bildkvalitet")
+
+#define DRI_CONF_EXCESS_MIPMAP(def) \
+DRI_CONF_OPT_BEGIN_B(excess_mipmap, def) \
+ DRI_CONF_DESC(en,"Enable extra mipmap level") \
+DRI_CONF_OPT_END
+
+#define DRI_CONF_TEXTURE_DEPTH_FB 0
+#define DRI_CONF_TEXTURE_DEPTH_32 1
+#define DRI_CONF_TEXTURE_DEPTH_16 2
+#define DRI_CONF_TEXTURE_DEPTH_FORCE_16 3
+#define DRI_CONF_TEXTURE_DEPTH(def) \
+DRI_CONF_OPT_BEGIN_V(texture_depth,enum,def,"0:3") \
+ DRI_CONF_DESC_BEGIN(en,"Texture color depth") \
+ DRI_CONF_ENUM(0,"Prefer frame buffer color depth") \
+ DRI_CONF_ENUM(1,"Prefer 32 bits per texel") \
+ DRI_CONF_ENUM(2,"Prefer 16 bits per texel") \
+ DRI_CONF_ENUM(3,"Force 16 bits per texel") \
+ DRI_CONF_DESC_END \
+ DRI_CONF_DESC_BEGIN(ca,"Profunditat de color de textura") \
+ DRI_CONF_ENUM(0,"Prefereix profunditat de color del framebuffer") \
+ DRI_CONF_ENUM(1,"Prefereix 32 bits per texel") \
+ DRI_CONF_ENUM(2,"Prefereix 16 bits per texel") \
+ DRI_CONF_ENUM(3,"Força 16 bits per texel") \
+ DRI_CONF_DESC_END \
+ DRI_CONF_DESC_BEGIN(de,"Texturfarbtiefe") \
+ DRI_CONF_ENUM(0,"Bevorzuge Farbtiefe des Framebuffers") \
+ DRI_CONF_ENUM(1,"Bevorzuge 32 bits pro Texel") \
+ DRI_CONF_ENUM(2,"Bevorzuge 16 bits pro Texel") \
+ DRI_CONF_ENUM(3,"Erzwinge 16 bits pro Texel") \
+ DRI_CONF_DESC_END \
+ DRI_CONF_DESC_BEGIN(es,"Profundidad de color de textura") \
+ DRI_CONF_ENUM(0,"Preferir profundidad de color del framebuffer") \
+ DRI_CONF_ENUM(1,"Preferir 32 bits por texel") \
+ DRI_CONF_ENUM(2,"Preferir 16 bits por texel") \
+ DRI_CONF_ENUM(3,"Forzar a 16 bits por texel") \
+ DRI_CONF_DESC_END \
+ DRI_CONF_DESC_BEGIN(nl,"Textuurkleurendiepte") \
+ DRI_CONF_ENUM(0,"Prefereer kaderbufferkleurdiepte") \
+ DRI_CONF_ENUM(1,"Prefereer 32 bits per texel") \
+ DRI_CONF_ENUM(2,"Prefereer 16 bits per texel") \
+ DRI_CONF_ENUM(3,"Dwing 16 bits per texel af") \
+ DRI_CONF_DESC_END \
+ DRI_CONF_DESC_BEGIN(fr,"Profondeur de texture") \
+ DRI_CONF_ENUM(0,"Profondeur de couleur") \
+ DRI_CONF_ENUM(1,"Préférer 32 bits par texel") \
+ DRI_CONF_ENUM(2,"Prérérer 16 bits par texel") \
+ DRI_CONF_ENUM(3,"Forcer 16 bits par texel") \
+ DRI_CONF_DESC_END \
+ DRI_CONF_DESC_BEGIN(sv,"Färgdjup för texturer") \
+ DRI_CONF_ENUM(0,"Föredra färgdjupet för framebuffer") \
+ DRI_CONF_ENUM(1,"Föredra 32 bitar per texel") \
+ DRI_CONF_ENUM(2,"Föredra 16 bitar per texel") \
+ DRI_CONF_ENUM(3,"Tvinga 16 bitar per texel") \
+ DRI_CONF_DESC_END \
+DRI_CONF_OPT_END
+
+#define DRI_CONF_DEF_MAX_ANISOTROPY(def,range) \
+DRI_CONF_OPT_BEGIN_V(def_max_anisotropy,float,def,range) \
+ DRI_CONF_DESC(en,"Initial maximum value for anisotropic texture filtering") \
+ DRI_CONF_DESC(ca,"Valor màxim inicial per a la filtració de textura anisòtropa") \
+ DRI_CONF_DESC(de,"Initialer Maximalwert für anisotropische Texturfilterung") \
+ DRI_CONF_DESC(es,"Valor máximo inicial para filtrado anisotrópico de textura") \
+ DRI_CONF_DESC(nl,"Initïele maximum waarde voor anisotrophische textuur filtering") \
+ DRI_CONF_DESC(fr,"Valeur maximale initiale pour le filtrage anisotropique de texture") \
+ DRI_CONF_DESC(sv,"Initialt maximalt värde för anisotropisk texturfiltrering") \
+DRI_CONF_OPT_END
+
+#define DRI_CONF_NO_NEG_LOD_BIAS(def) \
+DRI_CONF_OPT_BEGIN_B(no_neg_lod_bias, def) \
+ DRI_CONF_DESC(en,"Forbid negative texture LOD bias") \
+ DRI_CONF_DESC(ca,"Prohibeix una parcialitat negativa del Nivell de Detalle (LOD) de les textures") \
+ DRI_CONF_DESC(de,"Verbiete negative Textur-Detailgradverschiebung") \
+ DRI_CONF_DESC(es,"Prohibir valores negativos de Nivel De Detalle (LOD) de texturas") \
+ DRI_CONF_DESC(nl,"Verbied negatief niveau detailonderscheid (LOD) van texturen") \
+ DRI_CONF_DESC(fr,"Interdire le LOD bias negatif") \
+ DRI_CONF_DESC(sv,"Förbjud negativ LOD-kompensation för texturer") \
+DRI_CONF_OPT_END
+
+#define DRI_CONF_PRECISE_TRIG(def) \
+DRI_CONF_OPT_BEGIN_B(precise_trig, def) \
+ DRI_CONF_DESC(en,"Prefer accuracy over performance in trig functions") \
+ DRI_CONF_DESC(ca,"Prefer accuracy over performance in trig functions") \
+ DRI_CONF_DESC(de,"Prefer accuracy over performance in trig functions") \
+ DRI_CONF_DESC(es,"Prefer accuracy over performance in trig functions") \
+ DRI_CONF_DESC(nl,"Prefer accuracy over performance in trig functions") \
+ DRI_CONF_DESC(fr,"Prefer accuracy over performance in trig functions") \
+ DRI_CONF_DESC(sv,"Prefer accuracy over performance in trig functions") \
+DRI_CONF_OPT_END
+
+#define DRI_CONF_COLOR_REDUCTION_ROUND 0
+#define DRI_CONF_COLOR_REDUCTION_DITHER 1
+#define DRI_CONF_COLOR_REDUCTION(def) \
+DRI_CONF_OPT_BEGIN_V(color_reduction,enum,def,"0:1") \
+ DRI_CONF_DESC_BEGIN(en,"Initial color reduction method") \
+ DRI_CONF_ENUM(0,"Round colors") \
+ DRI_CONF_ENUM(1,"Dither colors") \
+ DRI_CONF_DESC_END \
+ DRI_CONF_DESC_BEGIN(ca,"Mètode inicial de reducció de color") \
+ DRI_CONF_ENUM(0,"Colors arrodonits") \
+ DRI_CONF_ENUM(1,"Colors tramats") \
+ DRI_CONF_DESC_END \
+ DRI_CONF_DESC_BEGIN(de,"Initiale Farbreduktionsmethode") \
+ DRI_CONF_ENUM(0,"Farben runden") \
+ DRI_CONF_ENUM(1,"Farben rastern") \
+ DRI_CONF_DESC_END \
+ DRI_CONF_DESC_BEGIN(es,"Método inicial de reducción de color") \
+ DRI_CONF_ENUM(0,"Colores redondeados") \
+ DRI_CONF_ENUM(1,"Colores suavizados") \
+ DRI_CONF_DESC_END \
+ DRI_CONF_DESC_BEGIN(nl,"Initïele kleurreductie methode") \
+ DRI_CONF_ENUM(0,"Rond kleuren af") \
+ DRI_CONF_ENUM(1,"Rasteriseer kleuren") \
+ DRI_CONF_DESC_END \
+ DRI_CONF_DESC_BEGIN(fr,"Technique de réduction de couleurs") \
+ DRI_CONF_ENUM(0,"Arrondir les valeurs de couleur") \
+ DRI_CONF_ENUM(1,"Tramer les couleurs") \
+ DRI_CONF_DESC_END \
+ DRI_CONF_DESC_BEGIN(sv,"Initial färgminskningsmetod") \
+ DRI_CONF_ENUM(0,"Avrunda färger") \
+ DRI_CONF_ENUM(1,"Utjämna färger") \
+ DRI_CONF_DESC_END \
+DRI_CONF_OPT_END
+
+#define DRI_CONF_ROUND_TRUNC 0
+#define DRI_CONF_ROUND_ROUND 1
+#define DRI_CONF_ROUND_MODE(def) \
+DRI_CONF_OPT_BEGIN_V(round_mode,enum,def,"0:1") \
+ DRI_CONF_DESC_BEGIN(en,"Color rounding method") \
+ DRI_CONF_ENUM(0,"Round color components downward") \
+ DRI_CONF_ENUM(1,"Round to nearest color") \
+ DRI_CONF_DESC_END \
+ DRI_CONF_DESC_BEGIN(ca,"Mètode d'arrodoniment de color") \
+ DRI_CONF_ENUM(0,"Arrodoneix els components de color a baix") \
+ DRI_CONF_ENUM(1,"Arrodoneix al color més proper") \
+ DRI_CONF_DESC_END \
+ DRI_CONF_DESC_BEGIN(de,"Farbrundungsmethode") \
+ DRI_CONF_ENUM(0,"Farbkomponenten abrunden") \
+ DRI_CONF_ENUM(1,"Zur ähnlichsten Farbe runden") \
+ DRI_CONF_DESC_END \
+ DRI_CONF_DESC_BEGIN(es,"Método de redondeo de colores") \
+ DRI_CONF_ENUM(0,"Redondear hacia abajo los componentes de color") \
+ DRI_CONF_ENUM(1,"Redondear al color más cercano") \
+ DRI_CONF_DESC_END \
+ DRI_CONF_DESC_BEGIN(nl,"Kleurafrondingmethode") \
+ DRI_CONF_ENUM(0,"Rond kleurencomponenten af naar beneden") \
+ DRI_CONF_ENUM(1,"Rond af naar dichtsbijzijnde kleur") \
+ DRI_CONF_DESC_END \
+ DRI_CONF_DESC_BEGIN(fr,"Méthode d'arrondi des couleurs") \
+ DRI_CONF_ENUM(0,"Arrondi à l'inférieur") \
+ DRI_CONF_ENUM(1,"Arrondi au plus proche") \
+ DRI_CONF_DESC_END \
+ DRI_CONF_DESC_BEGIN(sv,"Färgavrundningsmetod") \
+ DRI_CONF_ENUM(0,"Avrunda färdkomponenter nedåt") \
+ DRI_CONF_ENUM(1,"Avrunda till närmsta färg") \
+ DRI_CONF_DESC_END \
+DRI_CONF_OPT_END
+
+#define DRI_CONF_DITHER_XERRORDIFF 0
+#define DRI_CONF_DITHER_XERRORDIFFRESET 1
+#define DRI_CONF_DITHER_ORDERED 2
+#define DRI_CONF_DITHER_MODE(def) \
+DRI_CONF_OPT_BEGIN_V(dither_mode,enum,def,"0:2") \
+ DRI_CONF_DESC_BEGIN(en,"Color dithering method") \
+ DRI_CONF_ENUM(0,"Horizontal error diffusion") \
+ DRI_CONF_ENUM(1,"Horizontal error diffusion, reset error at line start") \
+ DRI_CONF_ENUM(2,"Ordered 2D color dithering") \
+ DRI_CONF_DESC_END \
+ DRI_CONF_DESC_BEGIN(ca,"Mètode de tramat de color") \
+ DRI_CONF_ENUM(0,"Difusió d'error horitzontal") \
+ DRI_CONF_ENUM(1,"Difusió d'error horitzontal, reinicia l'error a l'inici de la línia") \
+ DRI_CONF_ENUM(2,"Tramat de color 2D ordenat") \
+ DRI_CONF_DESC_END \
+ DRI_CONF_DESC_BEGIN(de,"Farbrasterungsmethode") \
+ DRI_CONF_ENUM(0,"Horizontale Fehlerstreuung") \
+ DRI_CONF_ENUM(1,"Horizontale Fehlerstreuung, Fehler am Zeilenanfang zurücksetzen") \
+ DRI_CONF_ENUM(2,"Geordnete 2D Farbrasterung") \
+ DRI_CONF_DESC_END \
+ DRI_CONF_DESC_BEGIN(es,"Método de suavizado de color") \
+ DRI_CONF_ENUM(0,"Difusión de error horizontal") \
+ DRI_CONF_ENUM(1,"Difusión de error horizontal, reiniciar error al comienzo de línea") \
+ DRI_CONF_ENUM(2,"Suavizado de color 2D ordenado") \
+ DRI_CONF_DESC_END \
+ DRI_CONF_DESC_BEGIN(nl,"Kleurrasteriseringsmethode") \
+ DRI_CONF_ENUM(0,"Horizontale foutdiffusie") \
+ DRI_CONF_ENUM(1,"Horizontale foutdiffusie, zet fout bij lijnbegin terug") \
+ DRI_CONF_ENUM(2,"Geordende 2D kleurrasterisering") \
+ DRI_CONF_DESC_END \
+ DRI_CONF_DESC_BEGIN(fr,"Méthode de tramage") \
+ DRI_CONF_ENUM(0,"Diffusion d'erreur horizontale") \
+ DRI_CONF_ENUM(1,"Diffusion d'erreur horizontale, réinitialisé pour chaque ligne") \
+ DRI_CONF_ENUM(2,"Tramage ordonné des couleurs") \
+ DRI_CONF_DESC_END \
+ DRI_CONF_DESC_BEGIN(sv,"Färgutjämningsmetod") \
+ DRI_CONF_ENUM(0,"Horisontell felspridning") \
+ DRI_CONF_ENUM(1,"Horisontell felspridning, återställ fel vid radbörjan") \
+ DRI_CONF_ENUM(2,"Ordnad 2D-färgutjämning") \
+ DRI_CONF_DESC_END \
+DRI_CONF_OPT_END
+
+#define DRI_CONF_FLOAT_DEPTH(def) \
+DRI_CONF_OPT_BEGIN_B(float_depth, def) \
+ DRI_CONF_DESC(en,"Floating point depth buffer") \
+ DRI_CONF_DESC(ca,"Buffer de profunditat de punt flotant") \
+ DRI_CONF_DESC(de,"Fließkomma z-Puffer") \
+ DRI_CONF_DESC(es,"Búfer de profundidad en coma flotante") \
+ DRI_CONF_DESC(nl,"Dieptebuffer als commagetal") \
+ DRI_CONF_DESC(fr,"Z-buffer en virgule flottante") \
+ DRI_CONF_DESC(sv,"Buffert för flytande punktdjup") \
+DRI_CONF_OPT_END
+
+#define DRI_CONF_PP_CELSHADE(def) \
+DRI_CONF_OPT_BEGIN_V(pp_celshade,enum,def,"0:1") \
+ DRI_CONF_DESC(en,"A post-processing filter to cel-shade the output") \
+ DRI_CONF_DESC(ca,"Un filtre de postprocessament per a aplicar cel shading a la sortida") \
+ DRI_CONF_DESC(de,"Nachbearbeitungsfilter für Cell Shading") \
+ DRI_CONF_DESC(es,"Un filtro de postprocesamiento para aplicar cel shading a la salida") \
+ DRI_CONF_DESC(nl,"A post-processing filter to cel-shade the output") \
+ DRI_CONF_DESC(fr,"A post-processing filter to cel-shade the output") \
+ DRI_CONF_DESC(sv,"A post-processing filter to cel-shade the output") \
+DRI_CONF_OPT_END
+
+#define DRI_CONF_PP_NORED(def) \
+DRI_CONF_OPT_BEGIN_V(pp_nored,enum,def,"0:1") \
+ DRI_CONF_DESC(en,"A post-processing filter to remove the red channel") \
+ DRI_CONF_DESC(ca,"Un filtre de postprocessament per a eliminar el canal vermell") \
+ DRI_CONF_DESC(de,"Nachbearbeitungsfilter zum Entfernen des Rotkanals") \
+ DRI_CONF_DESC(es,"Un filtro de postprocesamiento para eliminar el canal rojo") \
+ DRI_CONF_DESC(nl,"A post-processing filter to remove the red channel") \
+ DRI_CONF_DESC(fr,"A post-processing filter to remove the red channel") \
+ DRI_CONF_DESC(sv,"A post-processing filter to remove the red channel") \
+DRI_CONF_OPT_END
+
+#define DRI_CONF_PP_NOGREEN(def) \
+DRI_CONF_OPT_BEGIN_V(pp_nogreen,enum,def,"0:1") \
+ DRI_CONF_DESC(en,"A post-processing filter to remove the green channel") \
+ DRI_CONF_DESC(ca,"Un filtre de postprocessament per a eliminar el canal verd") \
+ DRI_CONF_DESC(de,"Nachbearbeitungsfilter zum Entfernen des Grünkanals") \
+ DRI_CONF_DESC(es,"Un filtro de postprocesamiento para eliminar el canal verde") \
+ DRI_CONF_DESC(nl,"A post-processing filter to remove the green channel") \
+ DRI_CONF_DESC(fr,"A post-processing filter to remove the green channel") \
+ DRI_CONF_DESC(sv,"A post-processing filter to remove the green channel") \
+DRI_CONF_OPT_END
+
+#define DRI_CONF_PP_NOBLUE(def) \
+DRI_CONF_OPT_BEGIN_V(pp_noblue,enum,def,"0:1") \
+ DRI_CONF_DESC(en,"A post-processing filter to remove the blue channel") \
+ DRI_CONF_DESC(ca,"Un filtre de postprocessament per a eliminar el canal blau") \
+ DRI_CONF_DESC(de,"Nachbearbeitungsfilter zum Entfernen des Blaukanals") \
+ DRI_CONF_DESC(es,"Un filtro de postprocesamiento para eliminar el canal azul") \
+ DRI_CONF_DESC(nl,"A post-processing filter to remove the blue channel") \
+ DRI_CONF_DESC(fr,"A post-processing filter to remove the blue channel") \
+ DRI_CONF_DESC(sv,"A post-processing filter to remove the blue channel") \
+DRI_CONF_OPT_END
+
+#define DRI_CONF_PP_JIMENEZMLAA(def,min,max) \
+DRI_CONF_OPT_BEGIN_V(pp_jimenezmlaa,int,def, # min ":" # max ) \
+ DRI_CONF_DESC(en,"Morphological anti-aliasing based on Jimenez\' MLAA. 0 to disable, 8 for default quality") \
+ DRI_CONF_DESC(ca,"Antialiàsing morfològic basat en el MLAA de Jimenez. 0 per deshabilitar, 8 per qualitat per defecte") \
+ DRI_CONF_DESC(de,"Morphologische Kantenglättung (Anti-Aliasing) basierend auf Jimenez' MLAA. 0 für deaktiviert, 8 für Standardqualität") \
+ DRI_CONF_DESC(es,"Antialiasing morfológico basado en el MLAA de Jimenez. 0 para deshabilitar, 8 para calidad por defecto") \
+ DRI_CONF_DESC(nl,"Morphological anti-aliasing based on Jimenez\' MLAA. 0 to disable, 8 for default quality") \
+ DRI_CONF_DESC(fr,"Morphological anti-aliasing based on Jimenez\' MLAA. 0 to disable, 8 for default quality") \
+ DRI_CONF_DESC(sv,"Morphological anti-aliasing based on Jimenez\' MLAA. 0 to disable, 8 for default quality") \
+DRI_CONF_OPT_END
+
+#define DRI_CONF_PP_JIMENEZMLAA_COLOR(def,min,max) \
+DRI_CONF_OPT_BEGIN_V(pp_jimenezmlaa_color,int,def, # min ":" # max ) \
+ DRI_CONF_DESC(en,"Morphological anti-aliasing based on Jimenez\' MLAA. 0 to disable, 8 for default quality. Color version, usable with 2d GL apps") \
+ DRI_CONF_DESC(ca,"Antialiàsing morfològic basat en el MLAA de Jimenez. 0 per deshabilitar, 8 per qualitat per defecte. Versió en color, utilitzable amb les aplicacions GL 2D") \
+ DRI_CONF_DESC(de,"Morphologische Kantenglättung (Anti-Aliasing) basierend auf Jimenez' MLAA. 0 für deaktiviert, 8 für Standardqualität. Farbversion, für 2D-Anwendungen") \
+ DRI_CONF_DESC(es,"Antialiasing morfológico basado en el MLAA de Jimenez. 0 para deshabilitar, 8 para calidad por defecto. Versión en color, usable con aplicaciones GL 2D") \
+ DRI_CONF_DESC(nl,"Morphological anti-aliasing based on Jimenez\' MLAA. 0 to disable, 8 for default quality. Color version, usable with 2d GL apps") \
+ DRI_CONF_DESC(fr,"Morphological anti-aliasing based on Jimenez\' MLAA. 0 to disable, 8 for default quality. Color version, usable with 2d GL apps") \
+ DRI_CONF_DESC(sv,"Morphological anti-aliasing based on Jimenez\' MLAA. 0 to disable, 8 for default quality. Color version, usable with 2d GL apps") \
+DRI_CONF_OPT_END
+
+
+
+/**
+ * \brief Performance-related options
+ */
+#define DRI_CONF_SECTION_PERFORMANCE \
+DRI_CONF_SECTION_BEGIN \
+ DRI_CONF_DESC(en,"Performance") \
+ DRI_CONF_DESC(ca,"Rendiment") \
+ DRI_CONF_DESC(de,"Leistung") \
+ DRI_CONF_DESC(es,"Rendimiento") \
+ DRI_CONF_DESC(nl,"Prestatie") \
+ DRI_CONF_DESC(fr,"Performance") \
+ DRI_CONF_DESC(sv,"Prestanda")
+
+#define DRI_CONF_TCL_SW 0
+#define DRI_CONF_TCL_PIPELINED 1
+#define DRI_CONF_TCL_VTXFMT 2
+#define DRI_CONF_TCL_CODEGEN 3
+#define DRI_CONF_TCL_MODE(def) \
+DRI_CONF_OPT_BEGIN_V(tcl_mode,enum,def,"0:3") \
+ DRI_CONF_DESC_BEGIN(en,"TCL mode (Transformation, Clipping, Lighting)") \
+ DRI_CONF_ENUM(0,"Use software TCL pipeline") \
+ DRI_CONF_ENUM(1,"Use hardware TCL as first TCL pipeline stage") \
+ DRI_CONF_ENUM(2,"Bypass the TCL pipeline") \
+ DRI_CONF_ENUM(3,"Bypass the TCL pipeline with state-based machine code generated on-the-fly") \
+ DRI_CONF_DESC_END \
+ DRI_CONF_DESC_BEGIN(ca,"Mode TCL (Transformació, Retall, Il·luminació)") \
+ DRI_CONF_ENUM(0,"Utilitza la canonada TCL de programari") \
+ DRI_CONF_ENUM(1,"Utilitza el TCL de maquinari com a la primera fase de la canonada TCL") \
+ DRI_CONF_ENUM(2,"Passa per alt la canonada TCL") \
+ DRI_CONF_ENUM(3,"Passa per alt la canonada TCL amb codi de màquina basat en estats, generat sobre la marxa") \
+ DRI_CONF_DESC_END \
+ DRI_CONF_DESC_BEGIN(de,"TCL-Modus (Transformation, Clipping, Licht)") \
+ DRI_CONF_ENUM(0,"Benutze die Software-TCL-Pipeline") \
+ DRI_CONF_ENUM(1,"Benutze Hardware TCL als erste Stufe der TCL-Pipeline") \
+ DRI_CONF_ENUM(2,"Umgehe die TCL-Pipeline") \
+ DRI_CONF_ENUM(3,"Umgehe die TCL-Pipeline mit zur Laufzeit erzeugtem, zustandsbasiertem Maschinencode") \
+ DRI_CONF_DESC_END \
+ DRI_CONF_DESC_BEGIN(es,"Modo TCL (Transformación, Recorte, Iluminación)") \
+ DRI_CONF_ENUM(0,"Usar tubería TCL por software") \
+ DRI_CONF_ENUM(1,"Usar TCL por hardware en la primera fase de la tubería TCL") \
+ DRI_CONF_ENUM(2,"Pasar por alto la tubería TCL") \
+ DRI_CONF_ENUM(3,"Pasar por alto la tubería TCL con código máquina basado en estados, generado al vuelo") \
+ DRI_CONF_DESC_END \
+ DRI_CONF_DESC_BEGIN(nl,"TCL-modus (Transformatie, Clipping, Licht)") \
+ DRI_CONF_ENUM(0,"Gebruik software TCL pijpleiding") \
+ DRI_CONF_ENUM(1,"Gebruik hardware TCL as eerste TCL pijpleiding trap") \
+ DRI_CONF_ENUM(2,"Omzeil de TCL pijpleiding") \
+ DRI_CONF_ENUM(3,"Omzeil de TCL pijpleiding met staatgebaseerde machinecode die tijdens executie gegenereerd wordt") \
+ DRI_CONF_DESC_END \
+ DRI_CONF_DESC_BEGIN(fr,"Mode de TCL (Transformation, Clipping, Eclairage)") \
+ DRI_CONF_ENUM(0,"Utiliser un pipeline TCL logiciel") \
+ DRI_CONF_ENUM(1,"Utiliser le TCL matériel pour le premier niveau de pipeline") \
+ DRI_CONF_ENUM(2,"Court-circuiter le pipeline TCL") \
+ DRI_CONF_ENUM(3,"Court-circuiter le pipeline TCL par une machine à états qui génère le codede TCL à la volée") \
+ DRI_CONF_DESC_END \
+ DRI_CONF_DESC_BEGIN(sv,"TCL-läge (Transformation, Clipping, Lighting)") \
+ DRI_CONF_ENUM(0,"Använd programvaru-TCL-rörledning") \
+ DRI_CONF_ENUM(1,"Använd maskinvaru-TCL som första TCL-rörledningssteg") \
+ DRI_CONF_ENUM(2,"Kringgå TCL-rörledningen") \
+ DRI_CONF_ENUM(3,"Kringgå TCL-rörledningen med tillståndsbaserad maskinkod som direktgenereras") \
+ DRI_CONF_DESC_END \
+DRI_CONF_OPT_END
+
+#define DRI_CONF_FTHROTTLE_BUSY 0
+#define DRI_CONF_FTHROTTLE_USLEEPS 1
+#define DRI_CONF_FTHROTTLE_IRQS 2
+#define DRI_CONF_FTHROTTLE_MODE(def) \
+DRI_CONF_OPT_BEGIN_V(fthrottle_mode,enum,def,"0:2") \
+ DRI_CONF_DESC_BEGIN(en,"Method to limit rendering latency") \
+ DRI_CONF_ENUM(0,"Busy waiting for the graphics hardware") \
+ DRI_CONF_ENUM(1,"Sleep for brief intervals while waiting for the graphics hardware") \
+ DRI_CONF_ENUM(2,"Let the graphics hardware emit a software interrupt and sleep") \
+ DRI_CONF_DESC_END \
+ DRI_CONF_DESC_BEGIN(ca,"Mètode per a limitar la latència de renderització") \
+ DRI_CONF_ENUM(0,"Espera activa pel maquinari de gràfics") \
+ DRI_CONF_ENUM(1,"Dorm per intervals breus mentre s'espera al maquinari de gràfics") \
+ DRI_CONF_ENUM(2,"Deixa que el maquinari de gràfics emeti una interrupció de programari i dormi") \
+ DRI_CONF_DESC_END \
+ DRI_CONF_DESC_BEGIN(de,"Methode zur Begrenzung der Bildverzögerung") \
+ DRI_CONF_ENUM(0,"Aktives Warten auf die Grafikhardware") \
+ DRI_CONF_ENUM(1,"Kurze Schlafintervalle beim Warten auf die Grafikhardware") \
+ DRI_CONF_ENUM(2,"Die Grafikhardware eine Softwareunterbrechnung erzeugen lassen und schlafen") \
+ DRI_CONF_DESC_END \
+ DRI_CONF_DESC_BEGIN(es,"Método para limitar la latencia de renderización") \
+ DRI_CONF_ENUM(0,"Esperar activamente al hardware gráfico") \
+ DRI_CONF_ENUM(1,"Dormir en intervalos cortos mientras se espera al hardware gráfico") \
+ DRI_CONF_ENUM(2,"Permitir que el hardware gráfico emita una interrupción de software y duerma") \
+ DRI_CONF_DESC_END \
+ DRI_CONF_DESC_BEGIN(nl,"Methode om beeldopbouwvertraging te onderdrukken") \
+ DRI_CONF_ENUM(0,"Actief wachten voor de grafische hardware") \
+ DRI_CONF_ENUM(1,"Slaap voor korte intervallen tijdens het wachten op de grafische hardware") \
+ DRI_CONF_ENUM(2,"Laat de grafische hardware een software onderbreking uitzenden en in slaap vallen") \
+ DRI_CONF_DESC_END \
+ DRI_CONF_DESC_BEGIN(fr,"Méthode d'attente de la carte graphique") \
+ DRI_CONF_ENUM(0,"Attente active de la carte graphique") \
+ DRI_CONF_ENUM(1,"Attente utilisant usleep()") \
+ DRI_CONF_ENUM(2,"Utiliser les interruptions") \
+ DRI_CONF_DESC_END \
+ DRI_CONF_DESC_BEGIN(sv,"Metod för att begränsa renderingslatens") \
+ DRI_CONF_ENUM(0,"Upptagen med att vänta på grafikhårdvaran") \
+ DRI_CONF_ENUM(1,"Sov i korta intervall under väntan på grafikhårdvaran") \
+ DRI_CONF_ENUM(2,"Låt grafikhårdvaran sända ut ett programvaruavbrott och sov") \
+ DRI_CONF_DESC_END \
+DRI_CONF_OPT_END
+
+#define DRI_CONF_VBLANK_NEVER 0
+#define DRI_CONF_VBLANK_DEF_INTERVAL_0 1
+#define DRI_CONF_VBLANK_DEF_INTERVAL_1 2
+#define DRI_CONF_VBLANK_ALWAYS_SYNC 3
+#define DRI_CONF_VBLANK_MODE(def) \
+DRI_CONF_OPT_BEGIN_V(vblank_mode,enum,def,"0:3") \
+ DRI_CONF_DESC_BEGIN(en,"Synchronization with vertical refresh (swap intervals)") \
+ DRI_CONF_ENUM(0,"Never synchronize with vertical refresh, ignore application's choice") \
+ DRI_CONF_ENUM(1,"Initial swap interval 0, obey application's choice") \
+ DRI_CONF_ENUM(2,"Initial swap interval 1, obey application's choice") \
+ DRI_CONF_ENUM(3,"Always synchronize with vertical refresh, application chooses the minimum swap interval") \
+ DRI_CONF_DESC_END \
+ DRI_CONF_DESC_BEGIN(ca,"Sincronització amb refresc vertical (intervals d'intercanvi)") \
+ DRI_CONF_ENUM(0,"Mai sincronitzis amb el refresc vertical, ignora l'elecció de l'aplicació") \
+ DRI_CONF_ENUM(1,"Interval d'intercanvi inicial 0, obeeix l'elecció de l'aplicació") \
+ DRI_CONF_ENUM(2,"Interval d'intercanvi inicial 1, obeeix l'elecció de l'aplicació") \
+ DRI_CONF_ENUM(3,"Sempre sincronitza amb el refresc vertical, l'aplicació tria l'interval mínim d'intercanvi") \
+ DRI_CONF_DESC_END \
+ DRI_CONF_DESC_BEGIN(de,"Synchronisation mit der vertikalen Bildwiederholung") \
+ DRI_CONF_ENUM(0,"Niemals mit der Bildwiederholung synchronisieren, Anweisungen der Anwendung ignorieren") \
+ DRI_CONF_ENUM(1,"Initiales Bildinterval 0, Anweisungen der Anwendung gehorchen") \
+ DRI_CONF_ENUM(2,"Initiales Bildinterval 1, Anweisungen der Anwendung gehorchen") \
+ DRI_CONF_ENUM(3,"Immer mit der Bildwiederholung synchronisieren, Anwendung wählt das minimale Bildintervall") \
+ DRI_CONF_DESC_END \
+ DRI_CONF_DESC_BEGIN(es,"Sincronización con el refresco vertical (intervalos de intercambio)") \
+ DRI_CONF_ENUM(0,"No sincronizar nunca con el refresco vertical, ignorar la elección de la aplicación") \
+ DRI_CONF_ENUM(1,"Intervalo de intercambio inicial 0, obedecer la elección de la aplicación") \
+ DRI_CONF_ENUM(2,"Intervalo de intercambio inicial 1, obedecer la elección de la aplicación") \
+ DRI_CONF_ENUM(3,"Sincronizar siempre con el refresco vertical, la aplicación elige el intervalo de intercambio mínimo") \
+ DRI_CONF_DESC_END \
+ DRI_CONF_DESC_BEGIN(nl,"Synchronisatie met verticale verversing (interval omwisselen)") \
+ DRI_CONF_ENUM(0,"Nooit synchroniseren met verticale verversing, negeer de keuze van de applicatie") \
+ DRI_CONF_ENUM(1,"Initïeel omwisselingsinterval 0, honoreer de keuze van de applicatie") \
+ DRI_CONF_ENUM(2,"Initïeel omwisselingsinterval 1, honoreer de keuze van de applicatie") \
+ DRI_CONF_ENUM(3,"Synchroniseer altijd met verticale verversing, de applicatie kiest het minimum omwisselingsinterval") \
+ DRI_CONF_DESC_END \
+ DRI_CONF_DESC_BEGIN(fr,"Synchronisation de l'affichage avec le balayage vertical") \
+ DRI_CONF_ENUM(0,"Ne jamais synchroniser avec le balayage vertical, ignorer le choix de l'application") \
+ DRI_CONF_ENUM(1,"Ne pas synchroniser avec le balayage vertical par défaut, mais obéir au choix de l'application") \
+ DRI_CONF_ENUM(2,"Synchroniser avec le balayage vertical par défaut, mais obéir au choix de l'application") \
+ DRI_CONF_ENUM(3,"Toujours synchroniser avec le balayage vertical, l'application choisit l'intervalle minimal") \
+ DRI_CONF_DESC_END \
+ DRI_CONF_DESC_BEGIN(sv,"Synkronisering med vertikal uppdatering (växlingsintervall)") \
+ DRI_CONF_ENUM(0,"Synkronisera aldrig med vertikal uppdatering, ignorera programmets val") \
+ DRI_CONF_ENUM(1,"Initialt växlingsintervall 0, följ programmets val") \
+ DRI_CONF_ENUM(2,"Initialt växlingsintervall 1, följ programmets val") \
+ DRI_CONF_ENUM(3,"Synkronisera alltid med vertikal uppdatering, programmet väljer den minsta växlingsintervallen") \
+ DRI_CONF_DESC_END \
+DRI_CONF_OPT_END
+
+#define DRI_CONF_HYPERZ_DISABLED 0
+#define DRI_CONF_HYPERZ_ENABLED 1
+#define DRI_CONF_HYPERZ(def) \
+DRI_CONF_OPT_BEGIN_B(hyperz, def) \
+ DRI_CONF_DESC(en,"Use HyperZ to boost performance") \
+ DRI_CONF_DESC(ca,"Utilitza el HyperZ per a augmentar el rendiment") \
+ DRI_CONF_DESC(de,"HyperZ zur Leistungssteigerung verwenden") \
+ DRI_CONF_DESC(es,"Usar HyperZ para potenciar rendimiento") \
+ DRI_CONF_DESC(nl,"Gebruik HyperZ om de prestaties te verbeteren") \
+ DRI_CONF_DESC(fr,"Utiliser le HyperZ pour améliorer les performances") \
+ DRI_CONF_DESC(sv,"Använd HyperZ för att maximera prestandan") \
+DRI_CONF_OPT_END
+
+#define DRI_CONF_MAX_TEXTURE_UNITS(def,min,max) \
+DRI_CONF_OPT_BEGIN_V(texture_units,int,def, # min ":" # max ) \
+ DRI_CONF_DESC(en,"Number of texture units used") \
+ DRI_CONF_DESC(ca,"Nombre d'unitats de textura utilitzades") \
+ DRI_CONF_DESC(de,"Anzahl der benutzten Textureinheiten") \
+ DRI_CONF_DESC(es,"Número de unidades de textura usadas") \
+ DRI_CONF_DESC(nl,"Aantal textuureenheden in gebruik") \
+ DRI_CONF_DESC(fr,"Nombre d'unités de texture") \
+ DRI_CONF_DESC(sv,"Antal använda texturenheter") \
+DRI_CONF_OPT_END
+
+#define DRI_CONF_TEXTURE_BLEND_QUALITY(def,range) \
+DRI_CONF_OPT_BEGIN_V(texture_blend_quality,float,def,range) \
+ DRI_CONF_DESC(en,"Texture filtering quality vs. speed, AKA “brilinear” texture filtering") \
+ DRI_CONF_DESC(ca,"Qualitat vs. velocitat de filtració de textura, àlies filtració ”brilinear“ de textura") \
+ DRI_CONF_DESC(de,"Texturfilterqualität versus -geschwindigkeit, auch bekannt als „brilineare“ Texturfilterung") \
+ DRI_CONF_DESC(es,"Calidad de filtrado de textura vs. velocidad, alias filtrado ”brilinear“ de textura") \
+ DRI_CONF_DESC(nl,"Textuurfilterkwaliteit versus -snelheid, ookwel bekend als “brilineaire” textuurfiltering") \
+ DRI_CONF_DESC(fr,"Qualité/performance du filtrage trilinéaire de texture (filtrage brilinéaire)") \
+ DRI_CONF_DESC(sv,"Texturfiltreringskvalitet mot hastighet, även kallad ”brilinear”-texturfiltrering") \
+DRI_CONF_OPT_END
+
+#define DRI_CONF_TEXTURE_HEAPS_ALL 0
+#define DRI_CONF_TEXTURE_HEAPS_CARD 1
+#define DRI_CONF_TEXTURE_HEAPS_GART 2
+#define DRI_CONF_TEXTURE_HEAPS(def) \
+DRI_CONF_OPT_BEGIN_V(texture_heaps,enum,def,"0:2") \
+ DRI_CONF_DESC_BEGIN(en,"Used types of texture memory") \
+ DRI_CONF_ENUM(0,"All available memory") \
+ DRI_CONF_ENUM(1,"Only card memory (if available)") \
+ DRI_CONF_ENUM(2,"Only GART (AGP/PCIE) memory (if available)") \
+ DRI_CONF_DESC_END \
+ DRI_CONF_DESC_BEGIN(ca,"Tipus utilitzats de memòria de textura") \
+ DRI_CONF_ENUM(0,"Tota la memòria disponible") \
+ DRI_CONF_ENUM(1,"Només memòria de targeta (si està disponible)") \
+ DRI_CONF_ENUM(2,"Només memòria GART (AGP/PCIE) (si està disponible)") \
+ DRI_CONF_DESC_END \
+ DRI_CONF_DESC_BEGIN(de,"Benutzte Arten von Texturspeicher") \
+ DRI_CONF_ENUM(0,"Aller verfügbarer Speicher") \
+ DRI_CONF_ENUM(1,"Nur Grafikspeicher (falls verfügbar)") \
+ DRI_CONF_ENUM(2,"Nur GART-Speicher (AGP/PCIE) (falls verfügbar)") \
+ DRI_CONF_DESC_END \
+ DRI_CONF_DESC_BEGIN(es,"Tipos de memoria de textura usados") \
+ DRI_CONF_ENUM(0,"Toda la memoria disponible") \
+ DRI_CONF_ENUM(1,"Solo memoria de tarjeta (si está disponible)") \
+ DRI_CONF_ENUM(2,"Solo memoria GART (AGP/PCIE) (si está disponible)") \
+ DRI_CONF_DESC_END \
+ DRI_CONF_DESC_BEGIN(nl,"Gebruikte soorten textuurgeheugen") \
+ DRI_CONF_ENUM(0,"Al het beschikbaar geheugen") \
+ DRI_CONF_ENUM(1,"Alleen geheugen op de kaart (als het aanwezig is)") \
+ DRI_CONF_ENUM(2,"Alleen GART (AGP/PCIE) geheugen (als het aanwezig is)") \
+ DRI_CONF_DESC_END \
+ DRI_CONF_DESC_BEGIN(fr,"Types de mémoire de texture") \
+ DRI_CONF_ENUM(0,"Utiliser toute la mémoire disponible") \
+ DRI_CONF_ENUM(1,"Utiliser uniquement la mémoire graphique (si disponible)") \
+ DRI_CONF_ENUM(2,"Utiliser uniquement la mémoire GART (AGP/PCIE) (si disponible)") \
+ DRI_CONF_DESC_END \
+ DRI_CONF_DESC_BEGIN(sv,"Använda typer av texturminne") \
+ DRI_CONF_ENUM(0,"Allt tillgängligt minne") \
+ DRI_CONF_ENUM(1,"Endast kortminne (om tillgängligt)") \
+ DRI_CONF_ENUM(2,"Endast GART-minne (AGP/PCIE) (om tillgängligt)") \
+ DRI_CONF_DESC_END \
+DRI_CONF_OPT_END
+
+#define DRI_CONF_MESA_GLTHREAD(def) \
+DRI_CONF_OPT_BEGIN_B(mesa_glthread, def) \
+ DRI_CONF_DESC(en,"Enable offloading GL driver work to a separate thread") \
+ DRI_CONF_DESC(ca,"Enable offloading GL driver work to a separate thread") \
+ DRI_CONF_DESC(de,"Enable offloading GL driver work to a separate thread") \
+ DRI_CONF_DESC(es,"Enable offloading GL driver work to a separate thread") \
+ DRI_CONF_DESC(nl,"Enable offloading GL driver work to a separate thread") \
+ DRI_CONF_DESC(fr,"Enable offloading GL driver work to a separate thread") \
+ DRI_CONF_DESC(sv,"Enable offloading GL driver work to a separate thread") \
+DRI_CONF_OPT_END
+
+#define DRI_CONF_MESA_NO_ERROR(def) \
+DRI_CONF_OPT_BEGIN_B(mesa_no_error, def) \
+ DRI_CONF_DESC(en,"Disable GL driver error checking") \
+ DRI_CONF_DESC(ca,"Disable GL driver error checking") \
+ DRI_CONF_DESC(de,"Disable GL driver error checking") \
+ DRI_CONF_DESC(es,"Disable GL driver error checking") \
+ DRI_CONF_DESC(nl,"Disable GL driver error checking") \
+ DRI_CONF_DESC(fr,"Disable GL driver error checking") \
+ DRI_CONF_DESC(sv,"Disable GL driver error checking") \
+DRI_CONF_OPT_END
+
+#define DRI_CONF_DISABLE_EXT_BUFFER_AGE(def) \
+DRI_CONF_OPT_BEGIN_B(glx_disable_ext_buffer_age, def) \
+ DRI_CONF_DESC(en, "Disable the GLX_EXT_buffer_age extension") \
+ DRI_CONF_DESC(ca, "Disable the GLX_EXT_buffer_age extension") \
+ DRI_CONF_DESC(de, "Disable the GLX_EXT_buffer_age extension") \
+ DRI_CONF_DESC(es, "Disable the GLX_EXT_buffer_age extension") \
+ DRI_CONF_DESC(nl, "Disable the GLX_EXT_buffer_age extension") \
+ DRI_CONF_DESC(fr, "Disable the GLX_EXT_buffer_age extension") \
+ DRI_CONF_DESC(sv, "Disable the GLX_EXT_buffer_age extension") \
+DRI_CONF_OPT_END
+
+#define DRI_CONF_DISABLE_OML_SYNC_CONTROL(def) \
+DRI_CONF_OPT_BEGIN_B(glx_disable_oml_sync_control, def) \
+ DRI_CONF_DESC(en, "Disable the GLX_OML_sync_control extension") \
+ DRI_CONF_DESC(ca, "Disable the GLX_OML_sync_control extension") \
+ DRI_CONF_DESC(de, "Disable the GLX_OML_sync_control extension") \
+ DRI_CONF_DESC(es, "Disable the GLX_OML_sync_control extension") \
+ DRI_CONF_DESC(nl, "Disable the GLX_OML_sync_control extension") \
+ DRI_CONF_DESC(fr, "Disable the GLX_OML_sync_control extension") \
+ DRI_CONF_DESC(sv, "Disable the GLX_OML_sync_control extension") \
+DRI_CONF_OPT_END
+
+
+/**
+ * \brief Software-fallback options. To allow using features (like
+ * GL_ARB_vertex_program) on GPUs that don't otherwise support the feature.
+ */
+#define DRI_CONF_SECTION_SOFTWARE \
+DRI_CONF_SECTION_BEGIN \
+ DRI_CONF_DESC(en,"Features that are not hardware-accelerated") \
+ DRI_CONF_DESC(ca,"Característiques no accelerades per maquinari") \
+ DRI_CONF_DESC(de,"Funktionalität, die nicht hardwarebeschleunigt ist") \
+ DRI_CONF_DESC(es,"Características no aceleradas por hardware") \
+ DRI_CONF_DESC(nl,"Eigenschappen die niet hardwareversneld zijn") \
+ DRI_CONF_DESC(fr,"Fonctionnalités ne bénéficiant pas d'une accélération matérielle") \
+ DRI_CONF_DESC(sv,"Funktioner som inte är hårdvaruaccelererade")
+
+#define DRI_CONF_ARB_VERTEX_PROGRAM(def) \
+DRI_CONF_OPT_BEGIN_B(arb_vertex_program, def) \
+ DRI_CONF_DESC(en,"Enable extension GL_ARB_vertex_program") \
+ DRI_CONF_DESC(ca,"Habilita l'extensió GL_ARB_vertex_program") \
+ DRI_CONF_DESC(de,"Erweiterung GL_ARB_vertex_program aktivieren") \
+ DRI_CONF_DESC(es,"Habilitar la extensión GL_ARB_vertex_program") \
+ DRI_CONF_DESC(nl,"Zet uitbreiding GL_ARB_vertex_program aan") \
+ DRI_CONF_DESC(fr,"Activer l'extension GL_ARB_vertex_program") \
+ DRI_CONF_DESC(sv,"Aktivera tillägget GL_ARB_vertex_program") \
+DRI_CONF_OPT_END
+
+
+
+/**
+ * \brief Miscellaneous configuration options
+ */
+#define DRI_CONF_SECTION_MISCELLANEOUS \
+DRI_CONF_SECTION_BEGIN \
+ DRI_CONF_DESC(en,"Miscellaneous") \
+ DRI_CONF_DESC(ca,"Miscel·lània") \
+ DRI_CONF_DESC(de,"Miscellaneous") \
+ DRI_CONF_DESC(es,"Misceláneos") \
+ DRI_CONF_DESC(nl,"Miscellaneous") \
+ DRI_CONF_DESC(fr,"Miscellaneous") \
+ DRI_CONF_DESC(sv,"Miscellaneous")
+
+#define DRI_CONF_ALWAYS_HAVE_DEPTH_BUFFER(def) \
+DRI_CONF_OPT_BEGIN_B(always_have_depth_buffer, def) \
+ DRI_CONF_DESC(en,"Create all visuals with a depth buffer") \
+ DRI_CONF_DESC(ca,"Crea tots els visuals amb buffer de profunditat") \
+ DRI_CONF_DESC(de,"Create all visuals with a depth buffer") \
+ DRI_CONF_DESC(es,"Crear todos los visuales con búfer de profundidad") \
+ DRI_CONF_DESC(nl,"Create all visuals with a depth buffer") \
+ DRI_CONF_DESC(fr,"Create all visuals with a depth buffer") \
+ DRI_CONF_DESC(sv,"Create all visuals with a depth buffer") \
+DRI_CONF_OPT_END
+
+#define DRI_CONF_GLSL_ZERO_INIT(def) \
+DRI_CONF_OPT_BEGIN_B(glsl_zero_init, def) \
+ DRI_CONF_DESC(en,"Force uninitialized variables to default to zero") \
+ DRI_CONF_DESC(ca,"Force uninitialized variables to default to zero") \
+ DRI_CONF_DESC(de,"Force uninitialized variables to default to zero") \
+ DRI_CONF_DESC(es,"Force uninitialized variables to default to zero") \
+ DRI_CONF_DESC(nl,"Force uninitialized variables to default to zero") \
+ DRI_CONF_DESC(fr,"Force uninitialized variables to default to zero") \
+ DRI_CONF_DESC(sv,"Force uninitialized variables to default to zero") \
+DRI_CONF_OPT_END
+
+/**
+ * \brief Initialization configuration options
+ */
+#define DRI_CONF_SECTION_INITIALIZATION \
+DRI_CONF_SECTION_BEGIN \
+ DRI_CONF_DESC(en,"Initialization") \
+ DRI_CONF_DESC(ca,"Inicialització") \
+ DRI_CONF_DESC(de,"Initialization") \
+ DRI_CONF_DESC(es,"Inicialización") \
+ DRI_CONF_DESC(nl,"Initialization") \
+ DRI_CONF_DESC(fr,"Initialization") \
+ DRI_CONF_DESC(sv,"Initialization")
+
+#define DRI_CONF_DEVICE_ID_PATH_TAG(def) \
+DRI_CONF_OPT_BEGIN(device_id, string, def) \
+ DRI_CONF_DESC(en,"Define the graphic device to use if possible") \
+ DRI_CONF_DESC(ca,"Defineix el dispositiu de gràfics que utilitzar si és possible") \
+ DRI_CONF_DESC(de,"Define the graphic device to use if possible") \
+ DRI_CONF_DESC(es,"Define el dispositivo de gráficos que usar si es posible") \
+ DRI_CONF_DESC(nl,"Define the graphic device to use if possible") \
+ DRI_CONF_DESC(fr,"Define the graphic device to use if possible") \
+ DRI_CONF_DESC(sv,"Define the graphic device to use if possible") \
+DRI_CONF_OPT_END
+
+/**
+ * \brief Gallium-Nine specific configuration options
+ */
+
+#define DRI_CONF_SECTION_NINE \
+DRI_CONF_SECTION_BEGIN \
+ DRI_CONF_DESC(en,"Gallium Nine") \
+ DRI_CONF_DESC(ca,"Gallium Nine") \
+ DRI_CONF_DESC(de,"Gallium Nine") \
+ DRI_CONF_DESC(es,"Gallium Nine") \
+ DRI_CONF_DESC(nl,"Gallium Nine") \
+ DRI_CONF_DESC(fr,"Gallium Nine") \
+ DRI_CONF_DESC(sv,"Gallium Nine")
+
+#define DRI_CONF_NINE_THROTTLE(def) \
+DRI_CONF_OPT_BEGIN(throttle_value, int, def) \
+ DRI_CONF_DESC(en,"Define the throttling value. -1 for no throttling, -2 for default (usually 2), 0 for glfinish behaviour") \
+ DRI_CONF_DESC(ca,"Defineix el valor de regulació. -1 per a no regular, -2 per al predeterminat (generalment 2), 0 per al comportament de glfinish") \
+ DRI_CONF_DESC(de,"Define the throttling value. -1 for no throttling, -2 for default (usually 2), 0 for glfinish behaviour") \
+ DRI_CONF_DESC(es,"Define el valor de regulación. -1 para no regular, -2 para el por defecto (generalmente 2), 0 para el comportamiento de glfinish") \
+ DRI_CONF_DESC(nl,"Define the throttling value. -1 for no throttling, -2 for default (usually 2), 0 for glfinish behaviour") \
+ DRI_CONF_DESC(fr,"Define the throttling value. -1 for no throttling, -2 for default (usually 2), 0 for glfinish behaviour") \
+ DRI_CONF_DESC(sv,"Define the throttling value. -1 for no throttling, -2 for default (usually 2), 0 for glfinish behaviour") \
+DRI_CONF_OPT_END
+
+#define DRI_CONF_NINE_THREADSUBMIT(def) \
+DRI_CONF_OPT_BEGIN_B(thread_submit, def) \
+ DRI_CONF_DESC(en,"Use an additional thread to submit buffers.") \
+ DRI_CONF_DESC(ca,"Utilitza un fil addicional per a entregar els buffers.") \
+ DRI_CONF_DESC(de,"Use an additional thread to submit buffers.") \
+ DRI_CONF_DESC(es,"Usar un hilo adicional para entregar los búfer.") \
+ DRI_CONF_DESC(nl,"Use an additional thread to submit buffers.") \
+ DRI_CONF_DESC(fr,"Use an additional thread to submit buffers.") \
+ DRI_CONF_DESC(sv,"Use an additional thread to submit buffers.") \
+DRI_CONF_OPT_END
+
+#define DRI_CONF_NINE_OVERRIDEVENDOR(def) \
+DRI_CONF_OPT_BEGIN(override_vendorid, int, def) \
+ DRI_CONF_DESC(en,"Define the vendor_id to report. This allows faking another hardware vendor.") \
+ DRI_CONF_DESC(ca,"Define the vendor_id to report. This allows faking another hardware vendor.") \
+ DRI_CONF_DESC(de,"Define the vendor_id to report. This allows faking another hardware vendor.") \
+ DRI_CONF_DESC(es,"Define the vendor_id to report. This allows faking another hardware vendor.") \
+ DRI_CONF_DESC(nl,"Define the vendor_id to report. This allows faking another hardware vendor.") \
+ DRI_CONF_DESC(fr,"Define the vendor_id to report. This allows faking another hardware vendor.") \
+ DRI_CONF_DESC(sv,"Define the vendor_id to report. This allows faking another hardware vendor.") \
+DRI_CONF_OPT_END
+
+#define DRI_CONF_NINE_ALLOWDISCARDDELAYEDRELEASE(def) \
+DRI_CONF_OPT_BEGIN_B(discard_delayed_release, def) \
+ DRI_CONF_DESC(en,"Whether to allow the display server to release buffers with a delay when using d3d's presentation mode DISCARD. Default to true. Set to false if suffering from lag (thread_submit=true can also help in this situation).") \
+ DRI_CONF_DESC(ca,"Whether to allow the display server to release buffers with a delay when using d3d's presentation mode DISCARD. Default to true. Set to false if suffering from lag (thread_submit=true can also help in this situation).") \
+ DRI_CONF_DESC(de,"Whether to allow the display server to release buffers with a delay when using d3d's presentation mode DISCARD. Default to true. Set to false if suffering from lag (thread_submit=true can also help in this situation).") \
+ DRI_CONF_DESC(es,"Whether to allow the display server to release buffers with a delay when using d3d's presentation mode DISCARD. Default to true. Set to false if suffering from lag (thread_submit=true can also help in this situation).") \
+ DRI_CONF_DESC(nl,"Whether to allow the display server to release buffers with a delay when using d3d's presentation mode DISCARD. Default to true. Set to false if suffering from lag (thread_submit=true can also help in this situation).") \
+ DRI_CONF_DESC(fr,"Whether to allow the display server to release buffers with a delay when using d3d's presentation mode DISCARD. Default to true. Set to false if suffering from lag (thread_submit=true can also help in this situation).") \
+ DRI_CONF_DESC(sv,"Whether to allow the display server to release buffers with a delay when using d3d's presentation mode DISCARD. Default to true. Set to false if suffering from lag (thread_submit=true can also help in this situation).") \
+DRI_CONF_OPT_END
+
+#define DRI_CONF_NINE_TEARFREEDISCARD(def) \
+DRI_CONF_OPT_BEGIN_B(tearfree_discard, def) \
+ DRI_CONF_DESC(en,"Whether to make d3d's presentation mode DISCARD (games usually use that mode) Tear Free. If rendering above screen refresh, some frames will get skipped. false by default.") \
+ DRI_CONF_DESC(ca,"Whether to make d3d's presentation mode DISCARD (games usually use that mode) Tear Free. If rendering above screen refresh, some frames will get skipped. false by default.") \
+ DRI_CONF_DESC(de,"Whether to make d3d's presentation mode DISCARD (games usually use that mode) Tear Free. If rendering above screen refresh, some frames will get skipped. false by default.") \
+ DRI_CONF_DESC(es,"Whether to make d3d's presentation mode DISCARD (games usually use that mode) Tear Free. If rendering above screen refresh, some frames will get skipped. false by default.") \
+ DRI_CONF_DESC(nl,"Whether to make d3d's presentation mode DISCARD (games usually use that mode) Tear Free. If rendering above screen refresh, some frames will get skipped. false by default.") \
+ DRI_CONF_DESC(fr,"Whether to make d3d's presentation mode DISCARD (games usually use that mode) Tear Free. If rendering above screen refresh, some frames will get skipped. false by default.") \
+ DRI_CONF_DESC(sv,"Whether to make d3d's presentation mode DISCARD (games usually use that mode) Tear Free. If rendering above screen refresh, some frames will get skipped. false by default.") \
+DRI_CONF_OPT_END
+
+#define DRI_CONF_NINE_CSMT(def) \
+DRI_CONF_OPT_BEGIN(csmt_force, int, def) \
+ DRI_CONF_DESC(en,"If set to 1, force gallium nine CSMT. If set to 0, disable it. By default (-1) CSMT is enabled on known thread-safe drivers.") \
+ DRI_CONF_DESC(ca,"If set to 1, force gallium nine CSMT. If set to 0, disable it. By default (-1) CSMT is enabled on known thread-safe drivers.") \
+ DRI_CONF_DESC(de,"If set to 1, force gallium nine CSMT. If set to 0, disable it. By default (-1) CSMT is enabled on known thread-safe drivers.") \
+ DRI_CONF_DESC(es,"If set to 1, force gallium nine CSMT. If set to 0, disable it. By default (-1) CSMT is enabled on known thread-safe drivers.") \
+ DRI_CONF_DESC(nl,"If set to 1, force gallium nine CSMT. If set to 0, disable it. By default (-1) CSMT is enabled on known thread-safe drivers.") \
+ DRI_CONF_DESC(fr,"If set to 1, force gallium nine CSMT. If set to 0, disable it. By default (-1) CSMT is enabled on known thread-safe drivers.") \
+ DRI_CONF_DESC(sv,"If set to 1, force gallium nine CSMT. If set to 0, disable it. By default (-1) CSMT is enabled on known thread-safe drivers.") \
+DRI_CONF_OPT_END
+
+/**
+ * \brief radeonsi specific configuration options
+ */
+
+#define DRI_CONF_RADEONSI_ENABLE_SISCHED(def) \
+DRI_CONF_OPT_BEGIN_B(radeonsi_enable_sisched, def) \
+ DRI_CONF_DESC(en,"Use the LLVM sisched option for shader compiles") \
+ DRI_CONF_DESC(ca,"Use the LLVM sisched option for shader compiles") \
+ DRI_CONF_DESC(de,"Use the LLVM sisched option for shader compiles") \
+ DRI_CONF_DESC(es,"Use the LLVM sisched option for shader compiles") \
+ DRI_CONF_DESC(nl,"Use the LLVM sisched option for shader compiles") \
+ DRI_CONF_DESC(fr,"Use the LLVM sisched option for shader compiles") \
+ DRI_CONF_DESC(sv,"Use the LLVM sisched option for shader compiles") \
+DRI_CONF_OPT_END
+
+#define DRI_CONF_RADEONSI_ASSUME_NO_Z_FIGHTS(def) \
+DRI_CONF_OPT_BEGIN_B(radeonsi_assume_no_z_fights, def) \
+ DRI_CONF_DESC(en,"Assume no Z fights (enables aggressive out-of-order rasterization to improve performance; may cause rendering errors)") \
+ DRI_CONF_DESC(ca,"Assume no Z fights (enables aggressive out-of-order rasterization to improve performance; may cause rendering errors)") \
+ DRI_CONF_DESC(de,"Assume no Z fights (enables aggressive out-of-order rasterization to improve performance; may cause rendering errors)") \
+ DRI_CONF_DESC(es,"Assume no Z fights (enables aggressive out-of-order rasterization to improve performance; may cause rendering errors)") \
+ DRI_CONF_DESC(nl,"Assume no Z fights (enables aggressive out-of-order rasterization to improve performance; may cause rendering errors)") \
+ DRI_CONF_DESC(fr,"Assume no Z fights (enables aggressive out-of-order rasterization to improve performance; may cause rendering errors)") \
+ DRI_CONF_DESC(sv,"Assume no Z fights (enables aggressive out-of-order rasterization to improve performance; may cause rendering errors)") \
+DRI_CONF_OPT_END
+
+#define DRI_CONF_RADEONSI_COMMUTATIVE_BLEND_ADD(def) \
+DRI_CONF_OPT_BEGIN_B(radeonsi_commutative_blend_add, def) \
+ DRI_CONF_DESC(en,"Commutative additive blending optimizations (may cause rendering errors)") \
+ DRI_CONF_DESC(ca,"Commutative additive blending optimizations (may cause rendering errors)") \
+ DRI_CONF_DESC(de,"Commutative additive blending optimizations (may cause rendering errors)") \
+ DRI_CONF_DESC(es,"Commutative additive blending optimizations (may cause rendering errors)") \
+ DRI_CONF_DESC(nl,"Commutative additive blending optimizations (may cause rendering errors)") \
+ DRI_CONF_DESC(fr,"Commutative additive blending optimizations (may cause rendering errors)") \
+ DRI_CONF_DESC(sv,"Commutative additive blending optimizations (may cause rendering errors)") \
+DRI_CONF_OPT_END
+
+#define DRI_CONF_RADEONSI_CLEAR_DB_CACHE_BEFORE_CLEAR(def) \
+DRI_CONF_OPT_BEGIN_B(radeonsi_clear_db_cache_before_clear, def) \
+ DRI_CONF_DESC(en,"Clear DB cache before fast depth clear") \
+DRI_CONF_OPT_END
diff --git a/lib/mesa/src/util/xmlpool/sv.po b/lib/mesa/src/util/xmlpool/sv.po
new file mode 100644
index 000000000..d8d7353f4
--- /dev/null
+++ b/lib/mesa/src/util/xmlpool/sv.po
@@ -0,0 +1,309 @@
+# Swedish translation of DRI driver options.
+# Copyright (C) Free Software Foundation, Inc.
+# This file is distributed under the same license as the Mesa package.
+# Daniel Nylander <po@danielnylander.se>, 2006.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Mesa DRI\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2014-09-25 22:29-0600\n"
+"PO-Revision-Date: 2006-09-18 10:56+0100\n"
+"Last-Translator: Daniel Nylander <po@danielnylander.se>\n"
+"Language-Team: Swedish <tp-sv@listor.tp-sv.se>\n"
+"Language: sv\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#: t_options.h:56
+msgid "Debugging"
+msgstr "Felsökning"
+
+#: t_options.h:60
+msgid "Disable 3D acceleration"
+msgstr "Inaktivera 3D-accelerering"
+
+#: t_options.h:65
+msgid "Show performance boxes"
+msgstr "Visa prestandarutor"
+
+#: t_options.h:70
+msgid "Enable flushing batchbuffer after each draw call"
+msgstr ""
+
+#: t_options.h:75
+msgid "Enable flushing GPU caches with each draw call"
+msgstr ""
+
+#: t_options.h:80
+msgid "Disable throttling on first batch after flush"
+msgstr ""
+
+#: t_options.h:85
+msgid "Force GLSL extension default behavior to 'warn'"
+msgstr ""
+
+#: t_options.h:90
+msgid "Disable dual source blending"
+msgstr ""
+
+#: t_options.h:95
+msgid "Disable backslash-based line continuations in GLSL source"
+msgstr ""
+
+#: t_options.h:100
+msgid "Disable GL_ARB_shader_bit_encoding"
+msgstr ""
+
+#: t_options.h:105
+msgid ""
+"Force a default GLSL version for shaders that lack an explicit #version line"
+msgstr ""
+
+#: t_options.h:110
+msgid "Allow GLSL #extension directives in the middle of shaders"
+msgstr ""
+
+#: t_options.h:120
+msgid "Image Quality"
+msgstr "Bildkvalitet"
+
+#: t_options.h:133
+msgid "Texture color depth"
+msgstr "Färgdjup för texturer"
+
+#: t_options.h:134
+msgid "Prefer frame buffer color depth"
+msgstr "Föredra färgdjupet för framebuffer"
+
+#: t_options.h:135
+msgid "Prefer 32 bits per texel"
+msgstr "Föredra 32 bitar per texel"
+
+#: t_options.h:136
+msgid "Prefer 16 bits per texel"
+msgstr "Föredra 16 bitar per texel"
+
+#: t_options.h:137
+msgid "Force 16 bits per texel"
+msgstr "Tvinga 16 bitar per texel"
+
+#: t_options.h:143
+msgid "Initial maximum value for anisotropic texture filtering"
+msgstr "Initialt maximalt värde för anisotropisk texturfiltrering"
+
+#: t_options.h:148
+msgid "Forbid negative texture LOD bias"
+msgstr "Förbjud negativ LOD-kompensation för texturer"
+
+#: t_options.h:153
+msgid ""
+"Enable S3TC texture compression even if software support is not available"
+msgstr "Aktivera S3TC-texturkomprimering även om programvarustöd saknas"
+
+#: t_options.h:160
+msgid "Initial color reduction method"
+msgstr "Initial färgminskningsmetod"
+
+#: t_options.h:161
+msgid "Round colors"
+msgstr "Avrunda färger"
+
+#: t_options.h:162
+msgid "Dither colors"
+msgstr "Utjämna färger"
+
+#: t_options.h:170
+msgid "Color rounding method"
+msgstr "Färgavrundningsmetod"
+
+#: t_options.h:171
+msgid "Round color components downward"
+msgstr "Avrunda färdkomponenter nedåt"
+
+#: t_options.h:172
+msgid "Round to nearest color"
+msgstr "Avrunda till närmsta färg"
+
+#: t_options.h:181
+msgid "Color dithering method"
+msgstr "Färgutjämningsmetod"
+
+#: t_options.h:182
+msgid "Horizontal error diffusion"
+msgstr "Horisontell felspridning"
+
+#: t_options.h:183
+msgid "Horizontal error diffusion, reset error at line start"
+msgstr "Horisontell felspridning, återställ fel vid radbörjan"
+
+#: t_options.h:184
+msgid "Ordered 2D color dithering"
+msgstr "Ordnad 2D-färgutjämning"
+
+#: t_options.h:190
+msgid "Floating point depth buffer"
+msgstr "Buffert för flytande punktdjup"
+
+#: t_options.h:195
+msgid "A post-processing filter to cel-shade the output"
+msgstr ""
+
+#: t_options.h:200
+msgid "A post-processing filter to remove the red channel"
+msgstr ""
+
+#: t_options.h:205
+msgid "A post-processing filter to remove the green channel"
+msgstr ""
+
+#: t_options.h:210
+msgid "A post-processing filter to remove the blue channel"
+msgstr ""
+
+#: t_options.h:215
+msgid ""
+"Morphological anti-aliasing based on Jimenez\\' MLAA. 0 to disable, 8 for "
+"default quality"
+msgstr ""
+
+#: t_options.h:220
+msgid ""
+"Morphological anti-aliasing based on Jimenez\\' MLAA. 0 to disable, 8 for "
+"default quality. Color version, usable with 2d GL apps"
+msgstr ""
+
+#: t_options.h:230
+msgid "Performance"
+msgstr "Prestanda"
+
+#: t_options.h:238
+msgid "TCL mode (Transformation, Clipping, Lighting)"
+msgstr "TCL-läge (Transformation, Clipping, Lighting)"
+
+#: t_options.h:239
+msgid "Use software TCL pipeline"
+msgstr "Använd programvaru-TCL-rörledning"
+
+#: t_options.h:240
+msgid "Use hardware TCL as first TCL pipeline stage"
+msgstr "Använd maskinvaru-TCL som första TCL-rörledningssteg"
+
+#: t_options.h:241
+msgid "Bypass the TCL pipeline"
+msgstr "Kringgå TCL-rörledningen"
+
+#: t_options.h:242
+msgid ""
+"Bypass the TCL pipeline with state-based machine code generated on-the-fly"
+msgstr ""
+"Kringgå TCL-rörledningen med tillståndsbaserad maskinkod som direktgenereras"
+
+#: t_options.h:251
+msgid "Method to limit rendering latency"
+msgstr "Metod för att begränsa renderingslatens"
+
+#: t_options.h:252
+msgid "Busy waiting for the graphics hardware"
+msgstr "Upptagen med att vänta på grafikhårdvaran"
+
+#: t_options.h:253
+msgid "Sleep for brief intervals while waiting for the graphics hardware"
+msgstr "Sov i korta intervall under väntan på grafikhårdvaran"
+
+#: t_options.h:254
+msgid "Let the graphics hardware emit a software interrupt and sleep"
+msgstr "Låt grafikhårdvaran sända ut ett programvaruavbrott och sov"
+
+#: t_options.h:264
+msgid "Synchronization with vertical refresh (swap intervals)"
+msgstr "Synkronisering med vertikal uppdatering (växlingsintervall)"
+
+#: t_options.h:265
+msgid "Never synchronize with vertical refresh, ignore application's choice"
+msgstr "Synkronisera aldrig med vertikal uppdatering, ignorera programmets val"
+
+#: t_options.h:266
+msgid "Initial swap interval 0, obey application's choice"
+msgstr "Initialt växlingsintervall 0, följ programmets val"
+
+#: t_options.h:267
+msgid "Initial swap interval 1, obey application's choice"
+msgstr "Initialt växlingsintervall 1, följ programmets val"
+
+#: t_options.h:268
+msgid ""
+"Always synchronize with vertical refresh, application chooses the minimum "
+"swap interval"
+msgstr ""
+"Synkronisera alltid med vertikal uppdatering, programmet väljer den minsta "
+"växlingsintervallen"
+
+#: t_options.h:276
+msgid "Use HyperZ to boost performance"
+msgstr "Använd HyperZ för att maximera prestandan"
+
+#: t_options.h:281
+msgid "Number of texture units used"
+msgstr "Antal använda texturenheter"
+
+#: t_options.h:286
+msgid "Texture filtering quality vs. speed, AKA “brilinear” texture filtering"
+msgstr ""
+"Texturfiltreringskvalitet mot hastighet, även kallad \"brilinear\"-"
+"texturfiltrering"
+
+#: t_options.h:294
+msgid "Used types of texture memory"
+msgstr "Använda typer av texturminne"
+
+#: t_options.h:295
+msgid "All available memory"
+msgstr "Allt tillgängligt minne"
+
+#: t_options.h:296
+msgid "Only card memory (if available)"
+msgstr "Endast kortminne (om tillgängligt)"
+
+#: t_options.h:297
+msgid "Only GART (AGP/PCIE) memory (if available)"
+msgstr "Endast GART-minne (AGP/PCIE) (om tillgängligt)"
+
+#: t_options.h:309
+msgid "Features that are not hardware-accelerated"
+msgstr "Funktioner som inte är hårdvaruaccelererade"
+
+#: t_options.h:313
+msgid "Enable extension GL_ARB_vertex_program"
+msgstr "Aktivera tillägget GL_ARB_vertex_program"
+
+#: t_options.h:323
+msgid "Miscellaneous"
+msgstr ""
+
+#: t_options.h:327
+msgid "Create all visuals with a depth buffer"
+msgstr ""
+
+#: t_options.h:337
+msgid "Initialization"
+msgstr ""
+
+#: t_options.h:341
+msgid "Define the graphic device to use if possible"
+msgstr ""
+
+#~ msgid "Support larger textures not guaranteed to fit into graphics memory"
+#~ msgstr ""
+#~ "Stöd för större texturer är inte garanterat att passa i grafikminnet"
+
+#~ msgid "No"
+#~ msgstr "Nej"
+
+#~ msgid "At least 1 texture must fit under worst-case assumptions"
+#~ msgstr "Åtminstone en textur måste passa för antaget sämsta förhållande"
+
+#~ msgid "Announce hardware limits"
+#~ msgstr "Annonsera hårdvarubegränsningar"
diff --git a/lib/mesa/src/util/xmlpool/sv/LC_MESSAGES/options.mo b/lib/mesa/src/util/xmlpool/sv/LC_MESSAGES/options.mo
new file mode 100644
index 000000000..3bf610a42
--- /dev/null
+++ b/lib/mesa/src/util/xmlpool/sv/LC_MESSAGES/options.mo
Binary files differ
diff --git a/lib/mesa/src/util/xmlpool/t_options.h b/lib/mesa/src/util/xmlpool/t_options.h
new file mode 100644
index 000000000..bd553085c
--- /dev/null
+++ b/lib/mesa/src/util/xmlpool/t_options.h
@@ -0,0 +1,454 @@
+/*
+ * XML DRI client-side driver configuration
+ * Copyright (C) 2003 Felix Kuehling
+ *
+ * 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
+ * FELIX KUEHLING, OR ANY OTHER CONTRIBUTORS 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 t_options.h
+ * \brief Templates of common options
+ * \author Felix Kuehling
+ *
+ * This file defines macros for common options that can be used to
+ * construct driConfigOptions in the drivers. This file is only a
+ * template containing English descriptions for options wrapped in
+ * gettext(). xgettext can be used to extract translatable
+ * strings. These strings can then be translated by anyone familiar
+ * with GNU gettext. gen_xmlpool.py takes this template and fills in
+ * all the translations. The result (options.h) is included by
+ * xmlpool.h which in turn can be included by drivers.
+ *
+ * The macros used to describe otions in this file are defined in
+ * ../xmlpool.h.
+ */
+
+/* This is needed for xgettext to extract translatable strings.
+ * gen_xmlpool.py will discard this line. */
+#include <libintl.h>
+
+/*
+ * predefined option sections and options with multi-lingual descriptions
+ */
+
+
+/**
+ * \brief Debugging options
+ */
+#define DRI_CONF_SECTION_DEBUG \
+DRI_CONF_SECTION_BEGIN \
+ DRI_CONF_DESC(en,gettext("Debugging"))
+
+#define DRI_CONF_NO_RAST(def) \
+DRI_CONF_OPT_BEGIN_B(no_rast, def) \
+ DRI_CONF_DESC(en,gettext("Disable 3D acceleration")) \
+DRI_CONF_OPT_END
+
+#define DRI_CONF_PERFORMANCE_BOXES(def) \
+DRI_CONF_OPT_BEGIN_B(performance_boxes, def) \
+ DRI_CONF_DESC(en,gettext("Show performance boxes")) \
+DRI_CONF_OPT_END
+
+#define DRI_CONF_ALWAYS_FLUSH_BATCH(def) \
+DRI_CONF_OPT_BEGIN_B(always_flush_batch, def) \
+ DRI_CONF_DESC(en,gettext("Enable flushing batchbuffer after each draw call")) \
+DRI_CONF_OPT_END
+
+#define DRI_CONF_ALWAYS_FLUSH_CACHE(def) \
+DRI_CONF_OPT_BEGIN_B(always_flush_cache, def) \
+ DRI_CONF_DESC(en,gettext("Enable flushing GPU caches with each draw call")) \
+DRI_CONF_OPT_END
+
+#define DRI_CONF_DISABLE_THROTTLING(def) \
+DRI_CONF_OPT_BEGIN_B(disable_throttling, def) \
+ DRI_CONF_DESC(en,gettext("Disable throttling on first batch after flush")) \
+DRI_CONF_OPT_END
+
+#define DRI_CONF_FORCE_GLSL_EXTENSIONS_WARN(def) \
+DRI_CONF_OPT_BEGIN_B(force_glsl_extensions_warn, def) \
+ DRI_CONF_DESC(en,gettext("Force GLSL extension default behavior to 'warn'")) \
+DRI_CONF_OPT_END
+
+#define DRI_CONF_DISABLE_BLEND_FUNC_EXTENDED(def) \
+DRI_CONF_OPT_BEGIN_B(disable_blend_func_extended, def) \
+ DRI_CONF_DESC(en,gettext("Disable dual source blending")) \
+DRI_CONF_OPT_END
+
+#define DRI_CONF_DUAL_COLOR_BLEND_BY_LOCATION(def) \
+DRI_CONF_OPT_BEGIN_B(dual_color_blend_by_location, def) \
+ DRI_CONF_DESC(en,gettext("Identify dual color blending sources by location rather than index")) \
+DRI_CONF_OPT_END
+
+#define DRI_CONF_DISABLE_GLSL_LINE_CONTINUATIONS(def) \
+DRI_CONF_OPT_BEGIN_B(disable_glsl_line_continuations, def) \
+ DRI_CONF_DESC(en,gettext("Disable backslash-based line continuations in GLSL source")) \
+DRI_CONF_OPT_END
+
+#define DRI_CONF_DISABLE_SHADER_BIT_ENCODING(def) \
+DRI_CONF_OPT_BEGIN_B(disable_shader_bit_encoding, def) \
+ DRI_CONF_DESC(en,gettext("Disable GL_ARB_shader_bit_encoding")) \
+DRI_CONF_OPT_END
+
+#define DRI_CONF_FORCE_GLSL_VERSION(def) \
+DRI_CONF_OPT_BEGIN_V(force_glsl_version, int, def, "0:999") \
+ DRI_CONF_DESC(en,gettext("Force a default GLSL version for shaders that lack an explicit #version line")) \
+DRI_CONF_OPT_END
+
+#define DRI_CONF_ALLOW_GLSL_EXTENSION_DIRECTIVE_MIDSHADER(def) \
+DRI_CONF_OPT_BEGIN_B(allow_glsl_extension_directive_midshader, def) \
+ DRI_CONF_DESC(en,gettext("Allow GLSL #extension directives in the middle of shaders")) \
+DRI_CONF_OPT_END
+
+#define DRI_CONF_ALLOW_GLSL_BUILTIN_VARIABLE_REDECLARATION(def) \
+DRI_CONF_OPT_BEGIN_B(allow_glsl_builtin_variable_redeclaration, def) \
+ DRI_CONF_DESC(en,gettext("Allow GLSL built-in variables to be redeclared verbatim")) \
+DRI_CONF_OPT_END
+
+#define DRI_CONF_ALLOW_HIGHER_COMPAT_VERSION(def) \
+DRI_CONF_OPT_BEGIN_B(allow_higher_compat_version, def) \
+ DRI_CONF_DESC(en,gettext("Allow a higher compat profile (version 3.1+) for apps that request it")) \
+DRI_CONF_OPT_END
+
+#define DRI_CONF_FORCE_GLSL_ABS_SQRT(def) \
+DRI_CONF_OPT_BEGIN_B(force_glsl_abs_sqrt, def) \
+ DRI_CONF_DESC(en,gettext("Force computing the absolute value for sqrt() and inversesqrt()")) \
+DRI_CONF_OPT_END
+
+#define DRI_CONF_GLSL_CORRECT_DERIVATIVES_AFTER_DISCARD(def) \
+DRI_CONF_OPT_BEGIN_B(glsl_correct_derivatives_after_discard, def) \
+ DRI_CONF_DESC(en,gettext("Implicit and explicit derivatives after a discard behave as if the discard didn't happen")) \
+DRI_CONF_OPT_END
+
+#define DRI_CONF_ALLOW_GLSL_CROSS_STAGE_INTERPOLATION_MISMATCH(def) \
+DRI_CONF_OPT_BEGIN_B(allow_glsl_cross_stage_interpolation_mismatch, def) \
+ DRI_CONF_DESC(en,gettext("Allow interpolation qualifier mismatch across shader stages")) \
+DRI_CONF_OPT_END
+
+/**
+ * \brief Image quality-related options
+ */
+#define DRI_CONF_SECTION_QUALITY \
+DRI_CONF_SECTION_BEGIN \
+ DRI_CONF_DESC(en,gettext("Image Quality"))
+
+#define DRI_CONF_EXCESS_MIPMAP(def) \
+DRI_CONF_OPT_BEGIN_B(excess_mipmap, def) \
+ DRI_CONF_DESC(en,"Enable extra mipmap level") \
+DRI_CONF_OPT_END
+
+#define DRI_CONF_TEXTURE_DEPTH_FB 0
+#define DRI_CONF_TEXTURE_DEPTH_32 1
+#define DRI_CONF_TEXTURE_DEPTH_16 2
+#define DRI_CONF_TEXTURE_DEPTH_FORCE_16 3
+#define DRI_CONF_TEXTURE_DEPTH(def) \
+DRI_CONF_OPT_BEGIN_V(texture_depth,enum,def,"0:3") \
+ DRI_CONF_DESC_BEGIN(en,gettext("Texture color depth")) \
+ DRI_CONF_ENUM(0,gettext("Prefer frame buffer color depth")) \
+ DRI_CONF_ENUM(1,gettext("Prefer 32 bits per texel")) \
+ DRI_CONF_ENUM(2,gettext("Prefer 16 bits per texel")) \
+ DRI_CONF_ENUM(3,gettext("Force 16 bits per texel")) \
+ DRI_CONF_DESC_END \
+DRI_CONF_OPT_END
+
+#define DRI_CONF_DEF_MAX_ANISOTROPY(def,range) \
+DRI_CONF_OPT_BEGIN_V(def_max_anisotropy,float,def,range) \
+ DRI_CONF_DESC(en,gettext("Initial maximum value for anisotropic texture filtering")) \
+DRI_CONF_OPT_END
+
+#define DRI_CONF_NO_NEG_LOD_BIAS(def) \
+DRI_CONF_OPT_BEGIN_B(no_neg_lod_bias, def) \
+ DRI_CONF_DESC(en,gettext("Forbid negative texture LOD bias")) \
+DRI_CONF_OPT_END
+
+#define DRI_CONF_PRECISE_TRIG(def) \
+DRI_CONF_OPT_BEGIN_B(precise_trig, def) \
+ DRI_CONF_DESC(en,gettext("Prefer accuracy over performance in trig functions")) \
+DRI_CONF_OPT_END
+
+#define DRI_CONF_COLOR_REDUCTION_ROUND 0
+#define DRI_CONF_COLOR_REDUCTION_DITHER 1
+#define DRI_CONF_COLOR_REDUCTION(def) \
+DRI_CONF_OPT_BEGIN_V(color_reduction,enum,def,"0:1") \
+ DRI_CONF_DESC_BEGIN(en,gettext("Initial color reduction method")) \
+ DRI_CONF_ENUM(0,gettext("Round colors")) \
+ DRI_CONF_ENUM(1,gettext("Dither colors")) \
+ DRI_CONF_DESC_END \
+DRI_CONF_OPT_END
+
+#define DRI_CONF_ROUND_TRUNC 0
+#define DRI_CONF_ROUND_ROUND 1
+#define DRI_CONF_ROUND_MODE(def) \
+DRI_CONF_OPT_BEGIN_V(round_mode,enum,def,"0:1") \
+ DRI_CONF_DESC_BEGIN(en,gettext("Color rounding method")) \
+ DRI_CONF_ENUM(0,gettext("Round color components downward")) \
+ DRI_CONF_ENUM(1,gettext("Round to nearest color")) \
+ DRI_CONF_DESC_END \
+DRI_CONF_OPT_END
+
+#define DRI_CONF_DITHER_XERRORDIFF 0
+#define DRI_CONF_DITHER_XERRORDIFFRESET 1
+#define DRI_CONF_DITHER_ORDERED 2
+#define DRI_CONF_DITHER_MODE(def) \
+DRI_CONF_OPT_BEGIN_V(dither_mode,enum,def,"0:2") \
+ DRI_CONF_DESC_BEGIN(en,gettext("Color dithering method")) \
+ DRI_CONF_ENUM(0,gettext("Horizontal error diffusion")) \
+ DRI_CONF_ENUM(1,gettext("Horizontal error diffusion, reset error at line start")) \
+ DRI_CONF_ENUM(2,gettext("Ordered 2D color dithering")) \
+ DRI_CONF_DESC_END \
+DRI_CONF_OPT_END
+
+#define DRI_CONF_FLOAT_DEPTH(def) \
+DRI_CONF_OPT_BEGIN_B(float_depth, def) \
+ DRI_CONF_DESC(en,gettext("Floating point depth buffer")) \
+DRI_CONF_OPT_END
+
+#define DRI_CONF_PP_CELSHADE(def) \
+DRI_CONF_OPT_BEGIN_V(pp_celshade,enum,def,"0:1") \
+ DRI_CONF_DESC(en,gettext("A post-processing filter to cel-shade the output")) \
+DRI_CONF_OPT_END
+
+#define DRI_CONF_PP_NORED(def) \
+DRI_CONF_OPT_BEGIN_V(pp_nored,enum,def,"0:1") \
+ DRI_CONF_DESC(en,gettext("A post-processing filter to remove the red channel")) \
+DRI_CONF_OPT_END
+
+#define DRI_CONF_PP_NOGREEN(def) \
+DRI_CONF_OPT_BEGIN_V(pp_nogreen,enum,def,"0:1") \
+ DRI_CONF_DESC(en,gettext("A post-processing filter to remove the green channel")) \
+DRI_CONF_OPT_END
+
+#define DRI_CONF_PP_NOBLUE(def) \
+DRI_CONF_OPT_BEGIN_V(pp_noblue,enum,def,"0:1") \
+ DRI_CONF_DESC(en,gettext("A post-processing filter to remove the blue channel")) \
+DRI_CONF_OPT_END
+
+#define DRI_CONF_PP_JIMENEZMLAA(def,min,max) \
+DRI_CONF_OPT_BEGIN_V(pp_jimenezmlaa,int,def, # min ":" # max ) \
+ DRI_CONF_DESC(en,gettext("Morphological anti-aliasing based on Jimenez\\\' MLAA. 0 to disable, 8 for default quality")) \
+DRI_CONF_OPT_END
+
+#define DRI_CONF_PP_JIMENEZMLAA_COLOR(def,min,max) \
+DRI_CONF_OPT_BEGIN_V(pp_jimenezmlaa_color,int,def, # min ":" # max ) \
+ DRI_CONF_DESC(en,gettext("Morphological anti-aliasing based on Jimenez\\\' MLAA. 0 to disable, 8 for default quality. Color version, usable with 2d GL apps")) \
+DRI_CONF_OPT_END
+
+
+
+/**
+ * \brief Performance-related options
+ */
+#define DRI_CONF_SECTION_PERFORMANCE \
+DRI_CONF_SECTION_BEGIN \
+ DRI_CONF_DESC(en,gettext("Performance"))
+
+#define DRI_CONF_TCL_SW 0
+#define DRI_CONF_TCL_PIPELINED 1
+#define DRI_CONF_TCL_VTXFMT 2
+#define DRI_CONF_TCL_CODEGEN 3
+#define DRI_CONF_TCL_MODE(def) \
+DRI_CONF_OPT_BEGIN_V(tcl_mode,enum,def,"0:3") \
+ DRI_CONF_DESC_BEGIN(en,gettext("TCL mode (Transformation, Clipping, Lighting)")) \
+ DRI_CONF_ENUM(0,gettext("Use software TCL pipeline")) \
+ DRI_CONF_ENUM(1,gettext("Use hardware TCL as first TCL pipeline stage")) \
+ DRI_CONF_ENUM(2,gettext("Bypass the TCL pipeline")) \
+ DRI_CONF_ENUM(3,gettext("Bypass the TCL pipeline with state-based machine code generated on-the-fly")) \
+ DRI_CONF_DESC_END \
+DRI_CONF_OPT_END
+
+#define DRI_CONF_FTHROTTLE_BUSY 0
+#define DRI_CONF_FTHROTTLE_USLEEPS 1
+#define DRI_CONF_FTHROTTLE_IRQS 2
+#define DRI_CONF_FTHROTTLE_MODE(def) \
+DRI_CONF_OPT_BEGIN_V(fthrottle_mode,enum,def,"0:2") \
+ DRI_CONF_DESC_BEGIN(en,gettext("Method to limit rendering latency")) \
+ DRI_CONF_ENUM(0,gettext("Busy waiting for the graphics hardware")) \
+ DRI_CONF_ENUM(1,gettext("Sleep for brief intervals while waiting for the graphics hardware")) \
+ DRI_CONF_ENUM(2,gettext("Let the graphics hardware emit a software interrupt and sleep")) \
+ DRI_CONF_DESC_END \
+DRI_CONF_OPT_END
+
+#define DRI_CONF_VBLANK_NEVER 0
+#define DRI_CONF_VBLANK_DEF_INTERVAL_0 1
+#define DRI_CONF_VBLANK_DEF_INTERVAL_1 2
+#define DRI_CONF_VBLANK_ALWAYS_SYNC 3
+#define DRI_CONF_VBLANK_MODE(def) \
+DRI_CONF_OPT_BEGIN_V(vblank_mode,enum,def,"0:3") \
+ DRI_CONF_DESC_BEGIN(en,gettext("Synchronization with vertical refresh (swap intervals)")) \
+ DRI_CONF_ENUM(0,gettext("Never synchronize with vertical refresh, ignore application's choice")) \
+ DRI_CONF_ENUM(1,gettext("Initial swap interval 0, obey application's choice")) \
+ DRI_CONF_ENUM(2,gettext("Initial swap interval 1, obey application's choice")) \
+ DRI_CONF_ENUM(3,gettext("Always synchronize with vertical refresh, application chooses the minimum swap interval")) \
+ DRI_CONF_DESC_END \
+DRI_CONF_OPT_END
+
+#define DRI_CONF_HYPERZ_DISABLED 0
+#define DRI_CONF_HYPERZ_ENABLED 1
+#define DRI_CONF_HYPERZ(def) \
+DRI_CONF_OPT_BEGIN_B(hyperz, def) \
+ DRI_CONF_DESC(en,gettext("Use HyperZ to boost performance")) \
+DRI_CONF_OPT_END
+
+#define DRI_CONF_MAX_TEXTURE_UNITS(def,min,max) \
+DRI_CONF_OPT_BEGIN_V(texture_units,int,def, # min ":" # max ) \
+ DRI_CONF_DESC(en,gettext("Number of texture units used")) \
+DRI_CONF_OPT_END
+
+#define DRI_CONF_TEXTURE_BLEND_QUALITY(def,range) \
+DRI_CONF_OPT_BEGIN_V(texture_blend_quality,float,def,range) \
+ DRI_CONF_DESC(en,gettext("Texture filtering quality vs. speed, AKA “brilinear” texture filtering")) \
+DRI_CONF_OPT_END
+
+#define DRI_CONF_TEXTURE_HEAPS_ALL 0
+#define DRI_CONF_TEXTURE_HEAPS_CARD 1
+#define DRI_CONF_TEXTURE_HEAPS_GART 2
+#define DRI_CONF_TEXTURE_HEAPS(def) \
+DRI_CONF_OPT_BEGIN_V(texture_heaps,enum,def,"0:2") \
+ DRI_CONF_DESC_BEGIN(en,gettext("Used types of texture memory")) \
+ DRI_CONF_ENUM(0,gettext("All available memory")) \
+ DRI_CONF_ENUM(1,gettext("Only card memory (if available)")) \
+ DRI_CONF_ENUM(2,gettext("Only GART (AGP/PCIE) memory (if available)")) \
+ DRI_CONF_DESC_END \
+DRI_CONF_OPT_END
+
+#define DRI_CONF_MESA_GLTHREAD(def) \
+DRI_CONF_OPT_BEGIN_B(mesa_glthread, def) \
+ DRI_CONF_DESC(en,gettext("Enable offloading GL driver work to a separate thread")) \
+DRI_CONF_OPT_END
+
+#define DRI_CONF_MESA_NO_ERROR(def) \
+DRI_CONF_OPT_BEGIN_B(mesa_no_error, def) \
+ DRI_CONF_DESC(en,gettext("Disable GL driver error checking")) \
+DRI_CONF_OPT_END
+
+#define DRI_CONF_DISABLE_EXT_BUFFER_AGE(def) \
+DRI_CONF_OPT_BEGIN_B(glx_disable_ext_buffer_age, def) \
+ DRI_CONF_DESC(en, gettext("Disable the GLX_EXT_buffer_age extension")) \
+DRI_CONF_OPT_END
+
+#define DRI_CONF_DISABLE_OML_SYNC_CONTROL(def) \
+DRI_CONF_OPT_BEGIN_B(glx_disable_oml_sync_control, def) \
+ DRI_CONF_DESC(en, gettext("Disable the GLX_OML_sync_control extension")) \
+DRI_CONF_OPT_END
+
+
+/**
+ * \brief Software-fallback options. To allow using features (like
+ * GL_ARB_vertex_program) on GPUs that don't otherwise support the feature.
+ */
+#define DRI_CONF_SECTION_SOFTWARE \
+DRI_CONF_SECTION_BEGIN \
+ DRI_CONF_DESC(en,gettext("Features that are not hardware-accelerated"))
+
+#define DRI_CONF_ARB_VERTEX_PROGRAM(def) \
+DRI_CONF_OPT_BEGIN_B(arb_vertex_program, def) \
+ DRI_CONF_DESC(en,gettext("Enable extension GL_ARB_vertex_program")) \
+DRI_CONF_OPT_END
+
+
+
+/**
+ * \brief Miscellaneous configuration options
+ */
+#define DRI_CONF_SECTION_MISCELLANEOUS \
+DRI_CONF_SECTION_BEGIN \
+ DRI_CONF_DESC(en,gettext("Miscellaneous"))
+
+#define DRI_CONF_ALWAYS_HAVE_DEPTH_BUFFER(def) \
+DRI_CONF_OPT_BEGIN_B(always_have_depth_buffer, def) \
+ DRI_CONF_DESC(en,gettext("Create all visuals with a depth buffer")) \
+DRI_CONF_OPT_END
+
+#define DRI_CONF_GLSL_ZERO_INIT(def) \
+DRI_CONF_OPT_BEGIN_B(glsl_zero_init, def) \
+ DRI_CONF_DESC(en,gettext("Force uninitialized variables to default to zero")) \
+DRI_CONF_OPT_END
+
+/**
+ * \brief Initialization configuration options
+ */
+#define DRI_CONF_SECTION_INITIALIZATION \
+DRI_CONF_SECTION_BEGIN \
+ DRI_CONF_DESC(en,gettext("Initialization"))
+
+#define DRI_CONF_DEVICE_ID_PATH_TAG(def) \
+DRI_CONF_OPT_BEGIN(device_id, string, def) \
+ DRI_CONF_DESC(en,gettext("Define the graphic device to use if possible")) \
+DRI_CONF_OPT_END
+
+/**
+ * \brief Gallium-Nine specific configuration options
+ */
+
+#define DRI_CONF_SECTION_NINE \
+DRI_CONF_SECTION_BEGIN \
+ DRI_CONF_DESC(en,gettext("Gallium Nine"))
+
+#define DRI_CONF_NINE_THROTTLE(def) \
+DRI_CONF_OPT_BEGIN(throttle_value, int, def) \
+ DRI_CONF_DESC(en,gettext("Define the throttling value. -1 for no throttling, -2 for default (usually 2), 0 for glfinish behaviour")) \
+DRI_CONF_OPT_END
+
+#define DRI_CONF_NINE_THREADSUBMIT(def) \
+DRI_CONF_OPT_BEGIN_B(thread_submit, def) \
+ DRI_CONF_DESC(en,gettext("Use an additional thread to submit buffers.")) \
+DRI_CONF_OPT_END
+
+#define DRI_CONF_NINE_OVERRIDEVENDOR(def) \
+DRI_CONF_OPT_BEGIN(override_vendorid, int, def) \
+ DRI_CONF_DESC(en,gettext("Define the vendor_id to report. This allows faking another hardware vendor.")) \
+DRI_CONF_OPT_END
+
+#define DRI_CONF_NINE_ALLOWDISCARDDELAYEDRELEASE(def) \
+DRI_CONF_OPT_BEGIN_B(discard_delayed_release, def) \
+ DRI_CONF_DESC(en,gettext("Whether to allow the display server to release buffers with a delay when using d3d's presentation mode DISCARD. Default to true. Set to false if suffering from lag (thread_submit=true can also help in this situation).")) \
+DRI_CONF_OPT_END
+
+#define DRI_CONF_NINE_TEARFREEDISCARD(def) \
+DRI_CONF_OPT_BEGIN_B(tearfree_discard, def) \
+ DRI_CONF_DESC(en,gettext("Whether to make d3d's presentation mode DISCARD (games usually use that mode) Tear Free. If rendering above screen refresh, some frames will get skipped. false by default.")) \
+DRI_CONF_OPT_END
+
+#define DRI_CONF_NINE_CSMT(def) \
+DRI_CONF_OPT_BEGIN(csmt_force, int, def) \
+ DRI_CONF_DESC(en,gettext("If set to 1, force gallium nine CSMT. If set to 0, disable it. By default (-1) CSMT is enabled on known thread-safe drivers.")) \
+DRI_CONF_OPT_END
+
+/**
+ * \brief radeonsi specific configuration options
+ */
+
+#define DRI_CONF_RADEONSI_ENABLE_SISCHED(def) \
+DRI_CONF_OPT_BEGIN_B(radeonsi_enable_sisched, def) \
+ DRI_CONF_DESC(en,gettext("Use the LLVM sisched option for shader compiles")) \
+DRI_CONF_OPT_END
+
+#define DRI_CONF_RADEONSI_ASSUME_NO_Z_FIGHTS(def) \
+DRI_CONF_OPT_BEGIN_B(radeonsi_assume_no_z_fights, def) \
+ DRI_CONF_DESC(en,gettext("Assume no Z fights (enables aggressive out-of-order rasterization to improve performance; may cause rendering errors)")) \
+DRI_CONF_OPT_END
+
+#define DRI_CONF_RADEONSI_COMMUTATIVE_BLEND_ADD(def) \
+DRI_CONF_OPT_BEGIN_B(radeonsi_commutative_blend_add, def) \
+ DRI_CONF_DESC(en,gettext("Commutative additive blending optimizations (may cause rendering errors)")) \
+DRI_CONF_OPT_END
+
+#define DRI_CONF_RADEONSI_CLEAR_DB_CACHE_BEFORE_CLEAR(def) \
+DRI_CONF_OPT_BEGIN_B(radeonsi_clear_db_cache_before_clear, def) \
+ DRI_CONF_DESC(en,"Clear DB cache before fast depth clear") \
+DRI_CONF_OPT_END
diff --git a/lib/mesa/src/vulkan/registry/vk_android_native_buffer.xml b/lib/mesa/src/vulkan/registry/vk_android_native_buffer.xml
new file mode 100644
index 000000000..2738908aa
--- /dev/null
+++ b/lib/mesa/src/vulkan/registry/vk_android_native_buffer.xml
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<registry>
+ <types>
+ <type category="struct" name="VkNativeBufferANDROID">
+ <member values="VK_STRUCTURE_TYPE_NATIVE_BUFFER_ANDROID"><type>VkStructureType</type> <name>sType</name></member>
+ <member>const <type>void</type>* <name>pNext</name></member>
+ <member><type>buffer_handle_t</type> <name>handle</name></member>
+ <member><type>int</type> <name>stride</name></member>
+ <member><type>int</type> <name>format</name></member>
+ <member><type>int</type> <name>usage</name></member>
+ </type>
+ </types>
+ <commands>
+ <command>
+ <proto><type>VkResult</type> <name>vkGetSwapchainGrallocUsageANDROID</name></proto>
+ <param><type>VkDevice</type> <name>device</name></param>
+ <param><type>VkFormat</type> <name>format</name></param>
+ <param><type>VkImageUsageFlags</type> <name>imageUsage</name></param>
+ <param><type>int</type>* <name>grallocUsage</name></param>
+ </command>
+ <command>
+ <proto><type>VkResult</type> <name>vkAcquireImageANDROID</name></proto>
+ <param><type>VkDevice</type> <name>device</name></param>
+ <param><type>VkImage</type> <name>image</name></param>
+ <param><type>int</type> <name>nativeFenceFd</name></param>
+ <param><type>VkSemaphore</type> <name>semaphore</name></param>
+ <param><type>VkFence</type> <name>fence</name></param>
+ </command>
+ <command>
+ <proto><type>VkResult</type> <name>vkQueueSignalReleaseImageANDROID</name></proto>
+ <param><type>VkQueue</type> <name>queue</name></param>
+ <param><type>uint32_t</type> <name>waitSemaphoreCount</name></param>
+ <param>const <type>VkSemaphore</type>* <name>pWaitSemaphores</name></param>
+ <param><type>VkImage</type> <name>image</name></param>
+ <param><type>int</type>* <name>pNativeFenceFd</name></param>
+ </command>
+ </commands>
+ <extensions>
+ <extension name="VK_ANDROID_native_buffer" number="11" type="device" protect="ANDROID" supported="vulkan">
+ <require>
+ <enum value="5" name="VK_ANDROID_NATIVE_BUFFER_SPEC_VERSION"/>
+ <enum value="11" name="VK_ANDROID_NATIVE_BUFFER_NUMBER"/>
+ <enum value="&quot;VK_ANDROID_native_buffer&quot;" name="VK_ANDROID_NATIVE_BUFFER_NAME"/>
+ <enum offset="0" extends="VkStructureType" name="VK_STRUCTURE_TYPE_NATIVE_BUFFER_ANDROID"/>
+ <type name="VkNativeBufferANDROID"/>
+ <command name="vkGetSwapchainGrallocUsageANDROID"/>
+ <command name="vkAcquireImageANDROID"/>
+ <command name="vkQueueSignalReleaseImageANDROID"/>
+ </require>
+ </extension>
+ </extensions>
+</registry>