diff --git a/Android.mk b/Android.mk index 418570e607b..9203c87a4e3 100644 --- a/Android.mk +++ b/Android.mk @@ -112,6 +112,7 @@ SUBDIRS := \ src/util \ src/egl \ src/amd \ + src/broadcom \ src/intel \ src/mesa/drivers/dri \ src/vulkan diff --git a/configure.ac b/configure.ac index 7fade23b6af..1e7a3be73f8 100644 --- a/configure.ac +++ b/configure.ac @@ -2746,6 +2746,7 @@ AC_CONFIG_FILES([Makefile src/Makefile src/amd/Makefile src/amd/vulkan/Makefile + src/broadcom/Makefile src/compiler/Makefile src/egl/Makefile src/egl/main/egl.pc diff --git a/src/Makefile.am b/src/Makefile.am index d8a2ee59fca..36995e08a45 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -82,6 +82,10 @@ if HAVE_INTEL_DRIVERS SUBDIRS += intel endif +if HAVE_GALLIUM_VC4 +SUBDIRS += broadcom +endif + if NEED_OPENGL_COMMON SUBDIRS += mesa endif diff --git a/src/broadcom/.gitignore b/src/broadcom/.gitignore new file mode 100644 index 00000000000..fcc603f0cf0 --- /dev/null +++ b/src/broadcom/.gitignore @@ -0,0 +1 @@ +cle/*_pack.h diff --git a/src/broadcom/Android.genxml.mk b/src/broadcom/Android.genxml.mk new file mode 100644 index 00000000000..df44b2ec0b7 --- /dev/null +++ b/src/broadcom/Android.genxml.mk @@ -0,0 +1,58 @@ +# Copyright © 2016 Intel Corporation +# Copyright © 2016 Mauro Rossi +# +# 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. +# + +include $(CLEAR_VARS) + +LOCAL_MODULE := libmesa_broadcom_genxml + +LOCAL_MODULE_CLASS := STATIC_LIBRARIES + +intermediates := $(call local-generated-sources-dir) + +# dummy.c source file is generated to meet the build system's rules. +LOCAL_GENERATED_SOURCES += $(intermediates)/dummy.c + +$(intermediates)/dummy.c: + @mkdir -p $(dir $@) + @echo "Gen Dummy: $(PRIVATE_MODULE) <= $(notdir $(@))" + $(hide) touch $@ + +# This is the list of auto-generated files headers +LOCAL_GENERATED_SOURCES += $(addprefix $(intermediates)/, $(BROADCOM_GENXML_GENERATED_FILES)) + +define header-gen + @mkdir -p $(dir $@) + @echo "Gen Header: $(PRIVATE_MODULE) <= $(notdir $(@))" + $(hide) $(PRIVATE_SCRIPT) $(PRIVATE_SCRIPT_FLAGS) $(PRIVATE_XML) > $@ +endef + +$(intermediates)/cle/v3d_packet_v21_pack.h: PRIVATE_SCRIPT := $(MESA_PYTHON2) $(LOCAL_PATH)/cle/gen_pack_header.py +$(intermediates)/cle/v3d_packet_v21_pack.h: PRIVATE_XML := $(LOCAL_PATH)/cle/v3d_packet_v21.xml +$(intermediates)/cle/v3d_packet_v21_pack.h: $(LOCAL_PATH)/cle/v3d_packet_v21.xml $(LOCAL_PATH)/cle/gen_pack_header.py + $(call header-gen) + +LOCAL_EXPORT_C_INCLUDE_DIRS := \ + $(MESA_TOP)/src/broadcom \ + $(intermediates) + +include $(MESA_COMMON_MK) +include $(BUILD_STATIC_LIBRARY) diff --git a/src/broadcom/Android.mk b/src/broadcom/Android.mk new file mode 100644 index 00000000000..d2da907a210 --- /dev/null +++ b/src/broadcom/Android.mk @@ -0,0 +1,28 @@ +# Copyright © 2016 Intel Corporation +# Copyright © 2016 Mauro Rossi +# +# 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. +# + +LOCAL_PATH := $(call my-dir) + +# Import variables +include $(LOCAL_PATH)/Makefile.sources + +include $(LOCAL_PATH)/Android.genxml.mk diff --git a/src/broadcom/Makefile.am b/src/broadcom/Makefile.am new file mode 100644 index 00000000000..fa14e4a4447 --- /dev/null +++ b/src/broadcom/Makefile.am @@ -0,0 +1,42 @@ +# Copyright © 2016 Broadcom +# Copyright © 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 Makefile.sources + +lib_LTLIBRARIES = +check_LTLIBRARIES = +noinst_DATA = +noinst_HEADERS = +noinst_LTLIBRARIES = +noinst_PROGRAMS = +check_PROGRAMS = +TESTS = +BUILT_SOURCES = +CLEANFILES = +EXTRA_DIST = + +MKDIR_GEN = $(AM_V_at)$(MKDIR_P) $(@D) +PYTHON_GEN = $(AM_V_GEN)$(PYTHON2) $(PYTHON_FLAGS) + +include Makefile.genxml.am + +CLEANFILES += $(BUILT_SOURCES) diff --git a/src/broadcom/Makefile.genxml.am b/src/broadcom/Makefile.genxml.am new file mode 100644 index 00000000000..b5ff528f209 --- /dev/null +++ b/src/broadcom/Makefile.genxml.am @@ -0,0 +1,37 @@ +# Copyright © 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. + +BUILT_SOURCES += $(BROADCOM_GENXML_GENERATED_FILES) + +EXTRA_DIST += $(BROADCOM_GENXML_XML_FILES) +EXTRA_DIST += $(BROADCOM_GENXML_GENERATED_FILES) + +SUFFIXES = _pack.h .xml + +$(BROADCOM_GENXML_GENERATED_FILES): cle/gen_pack_header.py + +.xml_pack.h: + $(MKDIR_GEN) + $(PYTHON_GEN) $(srcdir)/cle/gen_pack_header.py $< > $@ || ($(RM) $@; false) + +EXTRA_DIST += \ + cle/gen_pack_header.py \ + $() diff --git a/src/broadcom/Makefile.sources b/src/broadcom/Makefile.sources new file mode 100644 index 00000000000..cbba2c182b4 --- /dev/null +++ b/src/broadcom/Makefile.sources @@ -0,0 +1,12 @@ +BROADCOM_GENXML_GENERATED_FILES = \ + cle/v3d_packet_v21_pack.h \ + $() + +BROADCOM_GENXML_XML_FILES = \ + cle/v3d_packet_v21.xml \ + $() + +BROADCOM_FILES = \ + cle/v3d_packet_helpers.h \ + $() + diff --git a/src/broadcom/cle/gen_pack_header.py b/src/broadcom/cle/gen_pack_header.py new file mode 100644 index 00000000000..d9ead68749e --- /dev/null +++ b/src/broadcom/cle/gen_pack_header.py @@ -0,0 +1,546 @@ +#encoding=utf-8 + +# Copyright (C) 2016 Intel Corporation +# Copyright (C) 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. + +from __future__ import ( + absolute_import, division, print_function, unicode_literals +) +import xml.parsers.expat +import re +import sys +import copy + +license = """/* Generated code, see packets.xml and gen_packet_header.py */ +""" + +pack_header = """%(license)s + +/* Packets, enums and structures for %(platform)s. + * + * This file has been generated, do not hand edit. + */ + +#ifndef %(guard)s +#define %(guard)s + +#include "v3d_packet_helpers.h" + +""" + +def to_alphanum(name): + substitutions = { + ' ': '_', + '/': '_', + '[': '', + ']': '', + '(': '', + ')': '', + '-': '_', + ':': '', + '.': '', + ',': '', + '=': '', + '>': '', + '#': '', + 'α': 'alpha', + '&': '', + '*': '', + '"': '', + '+': '', + '\'': '', + } + + for i, j in substitutions.items(): + name = name.replace(i, j) + + return name + +def safe_name(name): + name = to_alphanum(name) + if not name[0].isalpha(): + name = '_' + name + + return name + +def num_from_str(num_str): + if num_str.lower().startswith('0x'): + return int(num_str, base=16) + else: + assert(not num_str.startswith('0') and 'octals numbers not allowed') + return int(num_str) + +class Field(object): + ufixed_pattern = re.compile(r"u(\d+)\.(\d+)") + sfixed_pattern = re.compile(r"s(\d+)\.(\d+)") + + def __init__(self, parser, attrs): + self.parser = parser + if "name" in attrs: + self.name = safe_name(attrs["name"]).lower() + + if str(attrs["start"]).endswith("b"): + self.start = int(attrs["start"][:-1]) * 8 + else: + self.start = int(attrs["start"]) + # packet entries in XML start from the bit after the + # opcode, so shift everything up by 8 since we'll also have a + # Field for the opcode. + if not parser.struct: + self.start += 8 + + self.end = self.start + int(attrs["size"]) - 1 + self.type = attrs["type"] + + if "prefix" in attrs: + self.prefix = safe_name(attrs["prefix"]).upper() + else: + self.prefix = None + + if "default" in attrs: + self.default = int(attrs["default"]) + else: + self.default = None + + ufixed_match = Field.ufixed_pattern.match(self.type) + if ufixed_match: + self.type = 'ufixed' + self.fractional_size = int(ufixed_match.group(2)) + + sfixed_match = Field.sfixed_pattern.match(self.type) + if sfixed_match: + self.type = 'sfixed' + self.fractional_size = int(sfixed_match.group(2)) + + def emit_template_struct(self, dim): + if self.type == 'address': + type = '__gen_address_type' + elif self.type == 'bool': + type = 'bool' + elif self.type == 'float': + type = 'float' + elif self.type == 'ufixed': + type = 'float' + elif self.type == 'sfixed': + type = 'float' + elif self.type == 'uint' and self.end - self.start > 32: + type = 'uint64_t' + elif self.type == 'offset': + type = 'uint64_t' + elif self.type == 'int': + type = 'int32_t' + elif self.type == 'uint': + type = 'uint32_t' + elif self.type in self.parser.structs: + type = 'struct ' + self.parser.gen_prefix(safe_name(self.type)) + elif self.type == 'mbo': + return + else: + print("#error unhandled type: %s" % self.type) + + print(" %-36s %s%s;" % (type, self.name, dim)) + + if len(self.values) > 0 and self.default == None: + if self.prefix: + prefix = self.prefix + "_" + else: + prefix = "" + + for value in self.values: + print("#define %-40s %d" % ((prefix + value.name).replace("__", "_"), + value.value)) + + def overlaps(self, field): + return self != field and max(self.start, field.start) <= min(self.end, field.end) + + +class Group(object): + def __init__(self, parser, parent, start, count): + self.parser = parser + self.parent = parent + self.start = start + self.count = count + self.size = 0 + self.fields = [] + + def emit_template_struct(self, dim): + if self.count == 0: + print(" /* variable length fields follow */") + else: + if self.count > 1: + dim = "%s[%d]" % (dim, self.count) + + for field in self.fields: + field.emit_template_struct(dim) + + class Byte: + def __init__(self): + self.size = 8 + self.fields = [] + self.address = None + + def collect_bytes(self, bytes): + for field in self.fields: + first_byte = field.start // 8 + last_byte = field.end // 8 + + for b in xrange(first_byte, last_byte + 1): + if not b in bytes: + bytes[b] = self.Byte() + + bytes[b].fields.append(field) + + if field.type == "address": + # assert bytes[index].address == None + bytes[b].address = field + + def emit_pack_function(self, start): + # Determine number of bytes in this group. + self.length = max(field.end // 8 for field in self.fields) + 1 + + bytes = {} + self.collect_bytes(bytes) + + relocs_emitted = set() + memcpy_fields = set() + + for index in range(self.length): + # Handle MBZ bytes + if not index in bytes: + print(" cl[%2d] = 0;" % index) + continue + byte = bytes[index] + + # Call out to the driver to note our relocations. Inside of the + # packet we only store offsets within the BOs, and we store the + # handle to the packet outside. Unlike Intel genxml, we don't + # need to have the other bits that will be stored together with + # the address during the reloc process, so there's no need for the + # complicated combine_address() function. + if byte.address and byte.address not in relocs_emitted: + print(" __gen_emit_reloc(data, &values->%s);" % byte.address.name) + relocs_emitted.add(byte.address) + + # Special case: floats can't have any other fields packed into + # them (since they'd change the meaning of the float), and the + # per-byte bitshifting math below bloats the pack code for floats, + # so just copy them directly here. Also handle 16/32-bit + # uints/ints with no merged fields. + if len(byte.fields) == 1: + field = byte.fields[0] + if field.type in ["float", "uint", "int"] and field.start % 8 == 0 and field.end - field.start == 31: + if field in memcpy_fields: + continue + + if not any(field.overlaps(scan_field) for scan_field in self.fields): + assert(field.start == index * 8) + print("") + print(" memcpy(&cl[%d], &values->%s, sizeof(values->%s));" % + (index, field.name, field.name)) + memcpy_fields.add(field) + continue + + byte_start = index * 8 + + v = None + prefix = " cl[%2d] =" % index + + field_index = 0 + for field in byte.fields: + if field.type != "mbo": + name = field.name + + start = field.start + end = field.end + field_byte_start = (field.start // 8) * 8 + start -= field_byte_start + end -= field_byte_start + + if field.type == "mbo": + s = "__gen_mbo(%d, %d)" % \ + (start, end) + elif field.type == "address": + s = "__gen_address_offset(&values->%s)" % byte.address.name + elif field.type == "uint": + s = "__gen_uint(values->%s, %d, %d)" % \ + (name, start, end) + elif field.type == "int": + s = "__gen_sint(values->%s, %d, %d)" % \ + (name, start, end) + elif field.type == "bool": + s = "__gen_uint(values->%s, %d, %d)" % \ + (name, start, end) + elif field.type == "float": + s = "#error %s float value mixed in with other fields" % name + elif field.type == "offset": + s = "__gen_offset(values->%s, %d, %d)" % \ + (name, start, end) + elif field.type == 'ufixed': + s = "__gen_ufixed(values->%s, %d, %d, %d)" % \ + (name, start, end, field.fractional_size) + elif field.type == 'sfixed': + s = "__gen_sfixed(values->%s, %d, %d, %d)" % \ + (name, start, end, field.fractional_size) + elif field.type in self.parser.structs: + s = "__gen_uint(v%d_%d, %d, %d)" % \ + (index, field_index, start, end) + field_index = field_index + 1 + else: + print("/* unhandled field %s, type %s */\n" % (name, field.type)) + s = None + + if not s == None: + if byte_start - field_byte_start != 0: + s = "%s >> %d" % (s, byte_start - field_byte_start) + + if field == byte.fields[-1]: + print("%s %s;" % (prefix, s)) + else: + print("%s %s |" % (prefix, s)) + prefix = " " + + print("") + continue + + def emit_unpack_function(self, start): + for field in self.fields: + if field.type != "mbo": + convert = None + + if field.type == "address": + convert = "__gen_unpack_address" + elif field.type == "uint": + convert = "__gen_unpack_uint" + elif field.type == "int": + convert = "__gen_unpack_sint" + elif field.type == "bool": + convert = "__gen_unpack_uint" + elif field.type == "float": + convert = "__gen_unpack_float" + elif field.type == "offset": + convert = "__gen_unpack_offset" + elif field.type == 'ufixed': + convert = "__gen_unpack_ufixed" + elif field.type == 'sfixed': + convert = "__gen_unpack_sfixed" + else: + print("/* unhandled field %s, type %s */\n" % (name, field.type)) + s = None + + print(" values->%s = %s(cl, %s, %s);" % \ + (field.name, convert, \ + start + field.start, start + field.end)) + + +class Value(object): + def __init__(self, attrs): + self.name = safe_name(attrs["name"]).upper() + self.value = int(attrs["value"]) + +class Parser(object): + def __init__(self): + self.parser = xml.parsers.expat.ParserCreate() + self.parser.StartElementHandler = self.start_element + self.parser.EndElementHandler = self.end_element + + self.packet = None + self.struct = None + self.structs = {} + self.registers = {} + + def gen_prefix(self, name): + if name[0] == "_": + return 'V3D%s%s' % (self.ver, name) + else: + return 'V3D%s_%s' % (self.ver, name) + + def gen_guard(self): + return self.gen_prefix("PACK_H") + + def start_element(self, name, attrs): + if name == "vcxml": + self.platform = "V3D {}".format(attrs["ver"]) + self.ver = attrs["ver"].replace('.', '') + print(pack_header % {'license': license, 'platform': self.platform, 'guard': self.gen_guard()}) + elif name in ("packet", "struct", "register"): + default_field = None + + object_name = self.gen_prefix(safe_name(attrs["name"].upper())) + if name == "packet": + self.packet = object_name + + # Add a fixed Field for the opcode. We only make s in + # the XML for the fields listed in the spec, and all of those + # start from bit 0 after of the opcode. + default_field = { + "name" : "opcode", + "default" : attrs["code"], + "type" : "uint", + "start" : -8, + "size" : 8, + } + elif name == "struct": + self.struct = object_name + self.structs[attrs["name"]] = 1 + elif name == "register": + self.register = object_name + self.reg_num = num_from_str(attrs["num"]) + self.registers[attrs["name"]] = 1 + + self.group = Group(self, None, 0, 1) + if default_field: + field = Field(self, default_field) + field.values = [] + self.group.fields.append(field) + + elif name == "field": + self.group.fields.append(Field(self, attrs)) + self.values = [] + elif name == "enum": + self.values = [] + self.enum = safe_name(attrs["name"]) + if "prefix" in attrs: + self.prefix = safe_name(attrs["prefix"]) + else: + self.prefix= None + elif name == "value": + self.values.append(Value(attrs)) + + def end_element(self, name): + if name == "packet": + self.emit_packet() + self.packet = None + self.group = None + elif name == "struct": + self.emit_struct() + self.struct = None + self.group = None + elif name == "register": + self.emit_register() + self.register = None + self.reg_num = None + self.group = None + elif name == "field": + self.group.fields[-1].values = self.values + elif name == "enum": + self.emit_enum() + self.enum = None + elif name == "vcxml": + print('#endif /* %s */' % self.gen_guard()) + + def emit_template_struct(self, name, group): + print("struct %s {" % name) + group.emit_template_struct("") + print("};\n") + + def emit_pack_function(self, name, group): + print("static inline void\n%s_pack(__gen_user_data *data, uint8_t * restrict cl,\n%sconst struct %s * restrict values)\n{" % + (name, ' ' * (len(name) + 6), name)) + + group.emit_pack_function(0) + + print("}\n") + + print('#define %-33s %6d' % + (name + "_length", self.group.length)) + + def emit_unpack_function(self, name, group): + print("#ifdef __gen_unpack_address") + print("static inline void") + print("%s_unpack(const uint8_t * restrict cl,\n%sstruct %s * restrict values)\n{" % + (name, ' ' * (len(name) + 8), name)) + + group.emit_unpack_function(0) + + print("}\n#endif\n") + + def emit_packet(self): + name = self.packet + + assert(self.group.fields[0].name == "opcode") + print('#define %-33s %6d' % + (name + "_opcode", self.group.fields[0].default)) + + default_fields = [] + for field in self.group.fields: + if not type(field) is Field: + continue + if field.default == None: + continue + default_fields.append(" .%-35s = %6d" % (field.name, field.default)) + + if default_fields: + print('#define %-40s\\' % (name + '_header')) + print(", \\\n".join(default_fields)) + print('') + + self.emit_template_struct(self.packet, self.group) + self.emit_pack_function(self.packet, self.group) + self.emit_unpack_function(self.packet, self.group) + + print('') + + def emit_register(self): + name = self.register + if not self.reg_num == None: + print('#define %-33s 0x%04x' % + (self.gen_prefix(name + "_num"), self.reg_num)) + + self.emit_template_struct(self.register, self.group) + self.emit_pack_function(self.register, self.group) + self.emit_unpack_function(self.register, self.group) + + def emit_struct(self): + name = self.struct + # Emit an empty header define so that we can use the CL pack functions + # with structs. + print('#define ' + name + '_header') + + self.emit_template_struct(self.struct, self.group) + self.emit_pack_function(self.struct, self.group) + self.emit_unpack_function(self.struct, self.group) + + print('') + + def emit_enum(self): + print('/* enum %s */' % self.gen_prefix(self.enum)) + for value in self.values: + if self.prefix: + name = self.prefix + "_" + value.name + else: + name = value.name + print('#define %-36s %6d' % (name.upper(), value.value)) + print('') + + def parse(self, filename): + file = open(filename, "rb") + self.parser.ParseFile(file) + file.close() + +if len(sys.argv) < 2: + print("No input xml file specified") + sys.exit(1) + +input_file = sys.argv[1] + +p = Parser() +p.parse(input_file) diff --git a/src/broadcom/cle/v3d_packet_helpers.h b/src/broadcom/cle/v3d_packet_helpers.h new file mode 100644 index 00000000000..d01ff6ef0ad --- /dev/null +++ b/src/broadcom/cle/v3d_packet_helpers.h @@ -0,0 +1,189 @@ +/* + * 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 +#include +#include +#include +#include + +#ifdef HAVE_VALGRIND +#include +#include +#define VG(x) x +#define __gen_validate_value(x) VALGRIND_CHECK_MEM_IS_DEFINED(&(x), sizeof(x)) +#else +#define VG(x) +#endif + +#ifndef __gen_validate_value +#define __gen_validate_value(x) +#endif +/* +#ifndef __gen_address_type +#error #define __gen_address_type before including this file +#endif + +#ifndef __gen_user_data +#error #define __gen_combine_address before including this file +#endif +*/ +union __gen_value { + float f; + uint32_t dw; +}; + +static inline uint64_t +__gen_mbo(uint32_t start, uint32_t end) +{ + return (~0ull >> (64 - (end - start + 1))) << start; +} + +static inline uint64_t +__gen_uint(uint64_t v, uint32_t start, uint32_t end) +{ + __gen_validate_value(v); + +#if DEBUG + const int width = end - start + 1; + if (width < 64) { + const uint64_t max = (1ull << width) - 1; + assert(v <= max); + } +#endif + + return v << start; +} + +static inline uint64_t +__gen_sint(int64_t v, uint32_t start, uint32_t end) +{ + const int width = end - start + 1; + + __gen_validate_value(v); + +#if DEBUG + if (width < 64) { + const int64_t max = (1ll << (width - 1)) - 1; + const int64_t min = -(1ll << (width - 1)); + assert(min <= v && v <= max); + } +#endif + + const uint64_t mask = ~0ull >> (64 - width); + + return (v & mask) << start; +} + +static inline uint64_t +__gen_offset(uint64_t v, uint32_t start, uint32_t end) +{ + __gen_validate_value(v); +#if DEBUG + uint64_t mask = (~0ull >> (64 - (end - start + 1))) << start; + + assert((v & ~mask) == 0); +#endif + + return v; +} + +static inline uint32_t +__gen_float(float v) +{ + __gen_validate_value(v); + return ((union __gen_value) { .f = (v) }).dw; +} + +static inline uint64_t +__gen_sfixed(float v, uint32_t start, uint32_t end, uint32_t fract_bits) +{ + __gen_validate_value(v); + + const float factor = (1 << fract_bits); + +#if DEBUG + const float max = ((1 << (end - start)) - 1) / factor; + const float min = -(1 << (end - start)) / factor; + assert(min <= v && v <= max); +#endif + + const int64_t int_val = llroundf(v * factor); + const uint64_t mask = ~0ull >> (64 - (end - start + 1)); + + return (int_val & mask) << start; +} + +static inline uint64_t +__gen_ufixed(float v, uint32_t start, uint32_t end, uint32_t fract_bits) +{ + __gen_validate_value(v); + + const float factor = (1 << fract_bits); + +#if DEBUG + const float max = ((1 << (end - start + 1)) - 1) / factor; + const float min = 0.0f; + assert(min <= v && v <= max); +#endif + + const uint64_t uint_val = llroundf(v * factor); + + return uint_val << start; +} + +static inline uint64_t +__gen_unpack_uint(const uint8_t *restrict cl, uint32_t start, uint32_t end) +{ + uint64_t val = 0; + const int width = end - start + 1; + const uint32_t mask = (width == 32 ? ~0 : (1 << width) - 1 ); + + for (int byte = start / 8; byte <= end / 8; byte++) { + val |= cl[byte] << ((byte - start / 8) * 8); + } + + return (val >> (start % 8)) & mask; +} + +static inline uint64_t +__gen_unpack_sint(const uint8_t *restrict cl, uint32_t start, uint32_t end) +{ + int size = end - start + 1; + int64_t val = __gen_unpack_uint(cl, start, end); + + /* Get the sign bit extended. */ + return (val << (64 - size)) >> (64 - size); +} + +static inline float +__gen_unpack_float(const uint8_t *restrict cl, uint32_t start, uint32_t end) +{ + assert(start % 8 == 0); + assert(end - start == 31); + + struct PACKED { float f; } *f = (void *)(cl + (start / 8)); + + return f->f; +} + diff --git a/src/broadcom/cle/v3d_packet_v21.xml b/src/broadcom/cle/v3d_packet_v21.xml new file mode 100644 index 00000000000..1d5b5b7d0e4 --- /dev/null +++ b/src/broadcom/cle/v3d_packet_v21.xml @@ -0,0 +1,220 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/gallium/drivers/vc4/Android.mk b/src/gallium/drivers/vc4/Android.mk index 715c021afb8..f7541385958 100644 --- a/src/gallium/drivers/vc4/Android.mk +++ b/src/gallium/drivers/vc4/Android.mk @@ -31,7 +31,10 @@ LOCAL_SRC_FILES := \ LOCAL_GENERATED_SOURCES := $(MESA_GEN_NIR_H) # We need libmesa_nir to get NIR's generated include directories. -LOCAL_STATIC_LIBRARIES := libmesa_nir +LOCAL_STATIC_LIBRARIES := \ + libmesa_nir \ + libmesa_broadcom_genxml + LOCAL_MODULE := libmesa_pipe_vc4 include $(GALLIUM_COMMON_MK)