1
0
mirror of https://github.com/Yours3lf/rpi-vk-driver.git synced 2025-02-20 17:54:17 +01:00

added control list dumping

This commit is contained in:
Unknown 2018-08-21 21:03:43 +01:00
parent 366578d118
commit 73b1866a24
46 changed files with 16361 additions and 14 deletions

View File

@ -22,5 +22,6 @@ link_directories(${EXTERNAL_PATH}/lib)
include_directories(${EXTERNAL_PATH}/include)
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
add_subdirectory(brcm)
add_subdirectory(driver)
add_subdirectory(test)

28
brcm/CMakeLists.txt Normal file
View File

@ -0,0 +1,28 @@
file(GLOB brcmSrc
"cle/*.h"
"cle/*.c"
"clif/*.h"
"clif/*.c"
"common/*.h"
"common/*.c"
"qpu/*.h"
"qpu/*.c"
)
execute_process(COMMAND "python" "${CMAKE_CURRENT_SOURCE_DIR}/cle/gen_pack_header.py" "${CMAKE_CURRENT_SOURCE_DIR}/cle/v3d_packet_v21.xml" "21" OUTPUT_VARIABLE V3D_PACKET_V21_PACK ERROR_VARIABLE CMD_ERROR)
if(CMD_ERROR STREQUAL "")
file(WRITE "${CMAKE_CURRENT_SOURCE_DIR}/cle/v3d_packet_v21_pack.h" "${V3D_PACKET_V21_PACK}" )
else(CMD_ERROR STREQUAL "")
message(FATAL_ERROR ${CMD_ERROR})
endif(CMD_ERROR STREQUAL "")
execute_process(COMMAND "python" "${CMAKE_CURRENT_SOURCE_DIR}/cle/gen_zipped_file.py" "${CMAKE_CURRENT_SOURCE_DIR}/cle/v3d_packet_v21.xml" OUTPUT_VARIABLE V3D_XML ERROR_VARIABLE CMD_ERROR2)
if(CMD_ERROR2 STREQUAL "")
file(WRITE "${CMAKE_CURRENT_SOURCE_DIR}/cle/v3d_xml.h" "${V3D_XML}" )
else(CMD_ERROR2 STREQUAL "")
message(FATAL_ERROR ${CMD_ERROR2})
endif(CMD_ERROR2 STREQUAL "")
add_library(brcm SHARED ${brcmSrc})
target_compile_options(brcm PRIVATE -Wall -std=c99)
target_link_libraries(brcm expat z)
target_compile_definitions(brcm PRIVATE V3D_VERSION=21)

627
brcm/cle/gen_pack_header.py Normal file
View File

@ -0,0 +1,627 @@
#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 prefixed_upper_name(prefix, name):
if prefix:
name = prefix + "_" + name
return safe_name(name).upper()
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 <field> 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 self.type == 'bool' and self.start != self.end:
print("#error Field {} has bool type but more than one bit of size".format(self.name));
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
if "minus_one" in attrs:
assert(attrs["minus_one"] == "true")
self.minus_one = True
else:
self.minus_one = False
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 == 'f187':
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 in self.parser.enums:
type = 'enum ' + self.parser.gen_prefix(safe_name(self.type))
elif self.type == 'mbo':
return
else:
print("#error unhandled type: %s" % self.type)
type = "uint32_t"
print(" %-36s %s%s;" % (type, self.name, dim))
for value in self.values:
name = prefixed_upper_name(self.prefix, value.name)
print("#define %-40s %d" % (name, 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 = []
self.min_ver = 0
self.max_ver = 0
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 range(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 field in self.fields:
if field.minus_one:
print(" assert(values->%s >= 1);" % field.name)
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 and not field.minus_one:
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
extra_shift = 0
value = "values->%s" % name
if field.minus_one:
value = "%s - 1" % value
if field.type == "mbo":
s = "__gen_mbo(%d, %d)" % \
(start, end)
elif field.type == "address":
extra_shift = (31 - (end - start)) // 8 * 8
s = "__gen_address_offset(&values->%s)" % byte.address.name
elif field.type == "uint":
s = "__gen_uint(%s, %d, %d)" % \
(value, start, end)
elif field.type in self.parser.enums:
s = "__gen_uint(%s, %d, %d)" % \
(value, start, end)
elif field.type == "int":
s = "__gen_sint(%s, %d, %d)" % \
(value, start, end)
elif field.type == "bool":
s = "__gen_uint(%s, %d, %d)" % \
(value, start, end)
elif field.type == "float":
s = "#error %s float value mixed in with other fields" % name
elif field.type == "f187":
s = "__gen_uint(fui(%s) >> 16, %d, %d)" % \
(value, start, end)
elif field.type == "offset":
s = "__gen_offset(%s, %d, %d)" % \
(value, start, end)
elif field.type == 'ufixed':
s = "__gen_ufixed(%s, %d, %d, %d)" % \
(value, start, end, field.fractional_size)
elif field.type == 'sfixed':
s = "__gen_sfixed(%s, %d, %d, %d)" % \
(value, 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:
shift = byte_start - field_byte_start + extra_shift
if shift:
s = "%s >> %d" % (s, shift)
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
args = []
args.append('cl')
args.append(str(start + field.start))
args.append(str(start + field.end))
if field.type == "address":
convert = "__gen_unpack_address"
elif field.type == "uint":
convert = "__gen_unpack_uint"
elif field.type in self.parser.enums:
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 == "f187":
convert = "__gen_unpack_f187"
elif field.type == "offset":
convert = "__gen_unpack_offset"
elif field.type == 'ufixed':
args.append(str(field.fractional_size))
convert = "__gen_unpack_ufixed"
elif field.type == 'sfixed':
args.append(str(field.fractional_size))
convert = "__gen_unpack_sfixed"
else:
print("/* unhandled field %s, type %s */\n" % (field.name, field.type))
s = None
plusone = ""
if field.minus_one:
plusone = " + 1"
print(" values->%s = %s(%s)%s;" % \
(field.name, convert, ', '.join(args), plusone))
class Value(object):
def __init__(self, attrs):
self.name = attrs["name"]
self.value = int(attrs["value"])
class Parser(object):
def __init__(self, ver):
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 = {}
# Set of enum names we've seen.
self.enums = set()
self.registers = {}
self.ver = ver
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 attrs_version_valid(self, attrs):
if "min_ver" in attrs and self.ver < attrs["min_ver"]:
return False
if "max_ver" in attrs and self.ver > attrs["max_ver"]:
return False
return True
def group_enabled(self):
if self.group.min_ver != 0 and self.ver < self.group.min_ver:
return False
if self.group.max_ver != 0 and self.ver > self.group.max_ver:
return False
return True
def start_element(self, name, attrs):
if name == "vcxml":
self.platform = "V3D {}.{}".format(self.ver[0], self.ver[1])
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 <field>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)
if "min_ver" in attrs:
self.group.min_ver = attrs["min_ver"]
if "max_ver" in attrs:
self.group.max_ver = attrs["max_ver"]
elif name == "field":
self.group.fields.append(Field(self, attrs))
self.values = []
elif name == "enum":
self.values = []
self.enum = safe_name(attrs["name"])
self.enums.add(attrs["name"])
self.enum_enabled = self.attrs_version_valid(attrs)
if "prefix" in attrs:
self.prefix = attrs["prefix"]
else:
self.prefix= None
elif name == "value":
if self.attrs_version_valid(attrs):
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":
if self.enum_enabled:
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_header(self, name):
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))
print('#define %-40s\\' % (name + '_header'))
print(", \\\n".join(default_fields))
print('')
def emit_packet(self):
if not self.group_enabled():
return
name = self.packet
assert(self.group.fields[0].name == "opcode")
print('#define %-33s %6d' %
(name + "_opcode", self.group.fields[0].default))
self.emit_header(name)
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):
if not self.group_enabled():
return
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):
if not self.group_enabled():
return
name = self.struct
self.emit_header(name)
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:
name = value.name
if self.prefix:
name = self.prefix + "_" + name
name = safe_name(name).upper()
print(' % -36s = %6d,' % (name, value.value))
print('};\n')
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(sys.argv[2])
p.parse(input_file)

View File

@ -0,0 +1,71 @@
#encoding=utf-8
#
# 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.
#
from __future__ import print_function
import os
import sys
import zlib
import xml.etree.cElementTree as et
def main():
if len(sys.argv) < 2:
print("No input xml file specified")
sys.exit(1)
compress = zlib.compressobj()
print("static const struct {")
print(" uint32_t gen_10;")
print(" uint32_t offset;")
print(" uint32_t length;")
print("} genxml_files_table[] = {")
xml_offset = 0
compressed_data = b''
for i in range(1, len(sys.argv)):
filename = sys.argv[i]
xml = open(filename, "rb").read()
xml_length = len(xml)
root = et.fromstring(xml)
print(" { %i, %i, %i }," %
(int(float(root.attrib['gen']) * 10), xml_offset, xml_length))
compressed_data += compress.compress(xml)
xml_offset += xml_length
print("};")
compressed_data += compress.flush()
print("")
print("static const uint8_t compress_genxmls[] = {")
print(" ", end='')
for i, c in enumerate(bytearray(compressed_data), start=1):
print("0x%.2x, " % c, end='\n ' if not i % 12 else '')
print('\n};')
if __name__ == '__main__':
main()

1004
brcm/cle/v3d_decoder.c Normal file
View File

@ -0,0 +1,1004 @@
/*
* 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 "../common/macros.h"
#include "../common/ralloc.h"
#include "v3d_decoder.h"
#include "../cle/v3d_packet_helpers.h"
#include "../cle/v3d_xml.h"
#include "../clif/clif_private.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;
const struct v3d_device_info *devinfo;
int foo;
struct location loc;
struct v3d_group *group;
struct v3d_enum *enoom;
int nvalues;
struct v3d_value *values[256];
struct v3d_spec *spec;
int parse_depth;
int parse_skip_depth;
};
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, "f187") == 0)
return (struct v3d_type) { .kind = V3D_TYPE_F187 };
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);
} else if (strcmp(atts[i], "minus_one") == 0) {
assert(strcmp(atts[i + 1], "true") == 0);
field->minus_one = true;
}
}
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 bool
ver_in_range(int ver, int min_ver, int max_ver)
{
return ((min_ver == 0 || ver >= min_ver) &&
(max_ver == 0 || ver <= max_ver));
}
static bool
skip_if_ver_mismatch(struct parser_context *ctx, int min_ver, int max_ver)
{
if (!ctx->parse_skip_depth && !ver_in_range(ctx->devinfo->ver,
min_ver, max_ver)) {
assert(ctx->parse_depth != 0);
ctx->parse_skip_depth = ctx->parse_depth;
}
return ctx->parse_skip_depth;
}
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;
int min_ver = 0;
int max_ver = 0;
ctx->loc.line_number = XML_GetCurrentLineNumber(ctx->parser);
for (i = 0; atts[i]; i += 2) {
if (strcmp(atts[i], "shortname") == 0)
name = atts[i + 1];
else if (strcmp(atts[i], "name") == 0 && !name)
name = atts[i + 1];
else if (strcmp(atts[i], "gen") == 0)
ver = atts[i + 1];
else if (strcmp(atts[i], "min_ver") == 0)
min_ver = strtoul(atts[i + 1], NULL, 0);
else if (strcmp(atts[i], "max_ver") == 0)
max_ver = strtoul(atts[i + 1], NULL, 0);
}
if (skip_if_ver_mismatch(ctx, min_ver, max_ver))
goto skip;
if (strcmp(element_name, "vcxml") == 0) {
if (ver == NULL)
fail(&ctx->loc, "no ver given");
/* Make sure that we picked an XML that matched our version.
*/
assert(ver_in_range(ctx->devinfo->ver, min_ver, max_ver));
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));
}
skip:
ctx->parse_depth++;
}
static int
field_offset_compare(const void *a, const void *b)
{
return ((*(const struct v3d_field **)a)->start -
(*(const struct v3d_field **)b)->start);
}
static void
end_element(void *data, const char *name)
{
struct parser_context *ctx = data;
struct v3d_spec *spec = ctx->spec;
ctx->parse_depth--;
if (ctx->parse_skip_depth) {
if (ctx->parse_skip_depth == ctx->parse_depth)
ctx->parse_skip_depth = 0;
return;
}
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;
/* Sort the fields in increasing offset order. The XML might
* be specified in any order, but we'll want to iterate from
* the bottom.
*/
qsort(group->fields, group->nfields, sizeof(*group->fields),
field_offset_compare);
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 (i != 0) {
assert(genxml_files_table[i - 1].gen_10 <
genxml_files_table[i].gen_10);
}
if (genxml_files_table[i].gen_10 <= devinfo->ver) {
text_offset = genxml_files_table[i].offset;
text_length = genxml_files_table[i].length;
}
}
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);
ctx.devinfo = devinfo;
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)
{
memset(iter, 0, sizeof(*iter));
iter->group = group;
iter->p = p;
}
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)
snprintf(iter->name, sizeof(iter->name), "%s", iter->field->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 clif_dump *clif, struct v3d_field_iterator *iter)
{
if (!iter_advance_field(iter))
return false;
const char *enum_name = NULL;
int group_member_offset =
iter_group_offset_bits(iter, iter->group_iter);
int s = group_member_offset + iter->field->start;
int e = group_member_offset + iter->field->end;
assert(!iter->field->minus_one ||
iter->field->type.kind == V3D_TYPE_INT ||
iter->field->type.kind == V3D_TYPE_UINT);
switch (iter->field->type.kind) {
case V3D_TYPE_UNKNOWN:
case V3D_TYPE_INT: {
uint32_t value = __gen_unpack_sint(iter->p, s, e);
if (iter->field->minus_one)
value++;
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);
if (iter->field->minus_one)
value++;
if (strcmp(iter->field->name, "Vec size") == 0 && value == 0)
value = 1 << (e - s);
snprintf(iter->value, sizeof(iter->value), "%u", value);
enum_name = v3d_get_enum_name(&iter->field->inline_enum, value);
break;
}
case V3D_TYPE_BOOL:
snprintf(iter->value, sizeof(iter->value), "%s",
__gen_unpack_uint(iter->p, s, e) ?
"1 /* true */" : "0 /* false */");
break;
case V3D_TYPE_FLOAT:
snprintf(iter->value, sizeof(iter->value), "%f",
__gen_unpack_float(iter->p, s, e));
break;
case V3D_TYPE_F187:
snprintf(iter->value, sizeof(iter->value), "%f",
__gen_unpack_f187(iter->p, s, e));
break;
case V3D_TYPE_ADDRESS: {
uint32_t addr =
__gen_unpack_uint(iter->p, s, e) << (31 - (e - s));
struct clif_bo *bo = clif_lookup_bo(clif, addr);
if (bo) {
snprintf(iter->value, sizeof(iter->value),
"[%s+0x%08x] /* 0x%08x */",
bo->name, addr - bo->offset, addr);
} else if (addr) {
snprintf(iter->value, sizeof(iter->value),
"/* XXX: BO unknown */ 0x%08x", addr);
} else {
snprintf(iter->value, sizeof(iter->value),
"[null]");
}
break;
}
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:
if (clif->pretty) {
snprintf(iter->value, sizeof(iter->value), "%f",
__gen_unpack_sfixed(iter->p, s, e,
iter->field->type.f));
} else {
snprintf(iter->value, sizeof(iter->value), "%u",
(unsigned)__gen_unpack_uint(iter->p, s, e));
}
break;
case V3D_TYPE_UFIXED:
if (clif->pretty) {
snprintf(iter->value, sizeof(iter->value), "%f",
__gen_unpack_ufixed(iter->p, s, e,
iter->field->type.f));
} else {
snprintf(iter->value, sizeof(iter->value), "%u",
(unsigned)__gen_unpack_uint(iter->p, s, e));
}
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(struct clif_dump *clif, struct v3d_group *group,
uint64_t offset, const uint8_t *p)
{
struct v3d_field_iterator iter;
v3d_field_iterator_init(&iter, group, p);
while (v3d_field_iterator_next(clif, &iter)) {
/* Clif parsing uses the packet name, and expects no
* sub-id.
*/
if (strcmp(iter.field->name, "sub-id") == 0 ||
strcmp(iter.field->name, "unused") == 0 ||
strcmp(iter.field->name, "Pad") == 0)
continue;
if (clif->pretty) {
fprintf(clif->out, " %s: %s\n",
iter.name, iter.value);
} else {
fprintf(clif->out, " /* %30s: */ %s\n",
iter.name, iter.value);
}
if (iter.struct_desc) {
uint64_t struct_offset = offset + iter.offset;
v3d_print_group(clif, iter.struct_desc,
struct_offset,
&p[iter.offset]);
}
}
}

147
brcm/cle/v3d_decoder.h Normal file
View File

@ -0,0 +1,147 @@
/*
* 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 "../common/v3d_device_info.h"
struct v3d_spec;
struct v3d_group;
struct v3d_field;
struct clif_dump;
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;
};
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_F187,
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 minus_one;
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 v3d_field_iterator_next(struct clif_dump *clif,
struct v3d_field_iterator *iter);
void v3d_print_group(struct clif_dump *clif,
struct v3d_group *group,
uint64_t offset, const uint8_t *p);
#endif /* V3D_DECODER_H */

View File

@ -24,14 +24,17 @@
#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
#include <assert.h>
#include "../../driver/CustomAssert.h"
#include <math.h>
//#include <gallium/auxiliary/util/u_math.h>
#ifdef HAVE_VALGRIND
#include <valgrind.h>
#include <memcheck.h>
#define VG(x) x
#ifndef NDEBUG
#define __gen_validate_value(x) VALGRIND_CHECK_MEM_IS_DEFINED(&(x), sizeof(x))
#endif
#else
#define VG(x)
#endif
@ -64,7 +67,7 @@ __gen_uint(uint64_t v, uint32_t start, uint32_t end)
{
__gen_validate_value(v);
#if DEBUG
#ifndef NDEBUG
const int width = end - start + 1;
if (width < 64) {
const uint64_t max = (1ull << width) - 1;
@ -82,7 +85,7 @@ __gen_sint(int64_t v, uint32_t start, uint32_t end)
__gen_validate_value(v);
#if DEBUG
#ifndef NDEBUG
if (width < 64) {
const int64_t max = (1ll << (width - 1)) - 1;
const int64_t min = -(1ll << (width - 1));
@ -99,7 +102,7 @@ static inline uint64_t
__gen_offset(uint64_t v, uint32_t start, uint32_t end)
{
__gen_validate_value(v);
#if DEBUG
#ifndef NDEBUG
uint64_t mask = (~0ull >> (64 - (end - start + 1))) << start;
assert((v & ~mask) == 0);
@ -122,7 +125,7 @@ __gen_sfixed(float v, uint32_t start, uint32_t end, uint32_t fract_bits)
const float factor = (1 << fract_bits);
#if DEBUG
#ifndef NDEBUG
const float max = ((1 << (end - start)) - 1) / factor;
const float min = -(1 << (end - start)) / factor;
assert(min <= v && v <= max);
@ -141,7 +144,7 @@ __gen_ufixed(float v, uint32_t start, uint32_t end, uint32_t fract_bits)
const float factor = (1 << fract_bits);
#if DEBUG
#ifndef NDEBUG
const float max = ((1 << (end - start + 1)) - 1) / factor;
const float min = 0.0f;
assert(min <= v && v <= max);
@ -203,3 +206,12 @@ __gen_unpack_float(const uint8_t *restrict cl, uint32_t start, uint32_t end)
return f->f;
}
static inline float
__gen_unpack_f187(const uint8_t *restrict cl, uint32_t start, uint32_t end)
{
assert(end - start == 15);
uint32_t bits = __gen_unpack_uint(cl, start, end);
bits = (bits << 16);
return *(float*)bits;
}

339
brcm/cle/v3d_packet_v21.xml Normal file
View File

@ -0,0 +1,339 @@
<vcxml gen="2.1" min_ver="21" max_ver="21">
<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="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"/>
</enum>
<packet name="Halt" code="0"/>
<packet name="NOP" code="1"/>
<packet name="Flush" code="4" cl="B"/>
<packet name="Flush All State" code="5" cl="B"/>
<packet name="Start Tile Binning" code="6" cl="B"/>
<packet name="Increment Semaphore" code="7"/>
<packet name="Wait on Semaphore" code="8"/>
<packet name="Branch" code="16">
<field name="Address" size="32" start="0" type="address"/>
</packet>
<packet name="Branch to sub-list" code="17">
<field name="Address" size="32" start="0" type="address"/>
</packet>
<packet name="Return from sub-list" code="18"/>
<packet name="Store Multi-sample Resolved Tile Color Buffer" code="24" cl="R"/>
<packet name="Store Multi-sample Resolved Tile Color Buffer and EOF" code="25" cl="R"/>
<packet name="Store Full Resolution Tile Buffer" cl="R" code="26">
<field name="Address" size="28" start="4" type="address"/>
<field name="Last Tile" size="1" start="3" type="bool"/>
<field name="Disable Clear on Write" size="1" start="2" type="bool"/>
<field name="Disable Z/Stencil Buffer write" size="1" start="1" type="bool"/>
<field name="Disable Color Buffer write" size="1" start="0" type="bool"/>
</packet>
<packet name="Re-load Full Resolution Tile Buffer" cl="R" code="27">
<field name="Address" size="28" start="4" type="address"/>
<field name="Disable Z/Stencil Buffer read" size="1" start="1" type="bool"/>
<field name="Disable Color Buffer read" size="1" start="0" type="bool"/>
</packet>
<packet name="Store Tile Buffer General" code="28" cl="R">
<field name="Memory base address of frame/tile dump buffer" size="28" start="20" type="address"/>
<field name="Last Tile of Frame" size="1" start="19" type="bool"/>
<field name="Disable VG-Mask buffer dump" size="1" start="18" type="bool"/>
<field name="Disable Z/Stencil buffer dump" size="1" start="17" type="bool"/>
<field name="Disable Color buffer dump" size="1" start="16" type="bool"/>
<field name="Disable VG-Mask buffer clear on store/dump" size="1" start="15" type="bool"/>
<field name="Disable Z/Stencil buffer clear on store/dump" size="1" start="14" type="bool"/>
<field name="Disable Color buffer clear on store/dump" size="1" start="13" type="bool"/>
<field name="Pixel Color Format" size="2" start="8" type="uint">
<value name="rgba8888" value="0"/>
<value name="bgr565 dithered" value="1"/>
<value name="bgr565 no dither" value="2"/>
</field>
<field name="Mode" size="2" start="6" type="uint">
<value name="Sample 0" value="0"/>
<value name="Decimate x4" value="1"/>
<value name="Decimate x16" value="2"/>
</field>
<field name="Format" size="2" start="4" type="uint">
<value name="Raster" value="0"/>
<value name="T" value="1"/>
<value name="LT" value="2"/>
</field>
<field name="Buffer to Store" size="3" start="0" type="uint">
<value name="None" value="0"/>
<value name="Color" value="1"/>
<value name="Z/stencil" value="2"/>
<value name="Z" value="3"/>
<value name="VG-Mask" value="4"/>
</field>
</packet>
<packet name="Load Tile Buffer General" code="29" cl="R">
<field name="Memory base address of frame/tile dump buffer" size="28" start="20" type="address"/>
<field name="Disable VG-Mask buffer load" size="1" start="18" type="bool"/>
<field name="Disable Z/Stencil buffer load" size="1" start="17" type="bool"/>
<field name="Disable Color buffer load" size="1" start="16" type="bool"/>
<field name="Pixel Color Format" size="2" start="8" type="uint">
<value name="rgba8888" value="0"/>
<value name="bgr565 dithered" value="1"/>
<value name="bgr565 no dither" value="2"/>
</field>
<field name="Mode" size="2" start="6" type="uint">
<value name="Sample 0" value="0"/>
<value name="Decimate x4" value="1"/>
<value name="Decimate x16" value="2"/>
</field>
<field name="Format" size="2" start="4" type="uint">
<value name="Raster" value="0"/>
<value name="T" value="1"/>
<value name="LT" value="2"/>
</field>
<field name="Buffer to Store" size="3" start="0" type="uint">
<value name="None" value="0"/>
<value name="Color" value="1"/>
<value name="Z/stencil" value="2"/>
<value name="Z" value="3"/>
<value name="VG-Mask" value="4"/>
</field>
</packet>
<packet name="Indexed Primitive List" code="32">
<field name="Maximum Index" size="32" start="72" type="uint"/>
<field name="Address of Indices List" size="32" start="40" type="uint"/>
<field name="Length" size="32" start="8" type="uint"/>
<field name="Index type" size="4" start="4" type="uint">
<value name="8-bit" value="0"/>
<value name="16-bit" value="1"/>
</field>
<field name="Primitive mode" size="4" start="0" type="Primitive"/>
</packet>
<packet name="Vertex Array Primitives" code="33">
<field name="Index of First Vertex" size="32" start="40" type="uint"/>
<field name="Length" size="32" start="8" type="uint"/>
<field name="Primitive mode" size="4" start="0" type="Primitive"/>
</packet>
<packet name="Primitive List Format" cl="R" code="56">
<field name="Data Type" size="4" start="4" type="uint">
<value name="16-bit index" value="1"/>
<value name="32-bit x/y" value="3"/>
</field>
<field name="Primitive Type" size="4" start="0" type="uint">
<value name="Points List" value="0"/>
<value name="Lines List" value="1"/>
<value name="Triangles List" value="2"/>
<value name="RHY List" value="3"/>
</field>
</packet>
<packet name="GL Shader State" code="64">
<!-- The address field will be filled in by kernel validation code. -->
<field name="Address" size="28" start="0" type="uint"/>
<field name="Extended shader record" size="1" start="3" type="bool"/>
<field name="Number of attribute arrays" size="3" start="0" type="uint"/>
</packet>
<packet name="Clear Colors" cl="R" code="114">
<field name="Clear Stencil" size="8" start="96" type="uint"/>
<field name="Clear VG Mask" size="8" start="88" type="uint"/>
<field name="Clear ZS" size="24" start="64" type="uint"/>
<field name="Clear Color" size="64" start="0" type="uint"/>
</packet>
<packet name="Configuration Bits" code="96">
<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="Coverage Read Mode" size="1" start="11" type="uint"/>
<!-- add values -->
<field name="Coverage Pipe Select" size="1" start="8" type="bool"/>
<field name="Rasteriser Oversample Mode" size="2" start="6" type="uint"/>
<!-- add values -->
<field name="Coverage Read Type" size="1" start="5" type="uint"/>
<!-- add values -->
<field name="Antialiased Points and Lines" size="1" start="4" type="bool"/>
<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 name="Flat Shade Flags" code="97">
<field name="Flat-shading Flags" size="32" start="0" type="uint"/>
</packet>
<packet name="Point size" code="98">
<field name="Point Size" size="32" start="0" type="float"/>
</packet>
<packet name="Line width" code="99">
<field name="Line width" size="32" start="0" type="float"/>
</packet>
<packet name="RHT X boundary" code="100">
<field name="RHT primitive X boundary" size="16" start="0" type="int"/>
</packet>
<packet name="Depth Offset" code="101">
<!-- 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="102">
<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="103">
<field name="Viewport Centre Y-coordinate" size="16" start="16" type="s12.4"/>
<field name="Viewport Centre X-coordinate" size="16" start="0" type="s12.4"/>
</packet>
<packet name="Z min and max clipping planes" code="104">
<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="105" cl="B">
<field name="Viewport Half-Height in 1/16th of pixel" size="32" start="32" type="float"/>
<field name="Viewport Half-Width in 1/16th of pixel" size="32" start="0" type="float"/>
</packet>
<packet name="Clipper Z Scale and Offset" code="106" 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 name="Tile Binning Mode Configuration" code="112" cl="B">
<field name="Double-buffer in non-ms mode" size="1" start="119" type="bool"/>
<field name="Tile Allocation Block Size" size="2" start="117" type="uint">
<value name="block size 32" value="0"/>
<value name="block size 64" value="1"/>
<value name="block size 128" value="2"/>
<value name="block size 256" value="3"/>
</field>
<field name="Tile Allocation Initial Block Size" size="2" start="115" type="uint">
<value name="block size 32" value="0"/>
<value name="block size 64" value="1"/>
<value name="block size 128" value="2"/>
<value name="block size 256" value="3"/>
</field>
<field name="Auto-initialise Tile State Data Array" size="1" start="114" type="bool"/>
<field name="Tile Buffer 64-bit Color Depth" size="1" start="113" type="bool"/>
<field name="Multisample Mode (4x)" size="1" start="112" type="bool"/>
<field name="Height (in tiles)" size="8" start="104" type="uint"/>
<field name="Width (in tiles)" size="8" start="96" type="uint"/>
<field name="Tile State Data Array Address" size="32" start="64" type="uint"/>
<field name="Tile Allocation memory size" size="32" start="32" type="uint"/>
<field name="Tile Allocation memory address" size="32" start="0" type="uint"/>
</packet>
<packet name="Tile Rendering Mode Configuration" code="113" cl="R">
<field name="Double-buffer in non-ms mode" size="1" start="76" type="bool"/>
<field name="Early-Z/Early-Cov disable" size="1" start="75" type="bool"/>
<field name="Early-Z Update Direction GT/GE" size="1" start="74" type="bool"/>
<field name="Select Coverage Mode" size="1" start="73" type="bool"/>
<field name="Enable VG Mask Buffer" size="1" start="72" type="bool"/>
<field name="Memory Format" size="2" start="70" type="uint">
<value name="Raster" value="0"/>
<value name="T" value="1"/>
<value name="LT" value="2"/>
</field>
<field name="Decimate Mode" size="2" start="68" type="uint"/>
<field name="Non-HDR Frame Buffer Color Format" size="2" start="66" type="uint">
<value name="rendering config bgr565 dithered" value="0"/>
<value name="rendering config rgba8888" value="1"/>
<value name="rendering config bgr565 no dither" value="2"/>
</field>
<field name="Tile Buffer 64-bit Color Depth" size="1" start="65" type="bool"/>
<field name="Multisample Mode (4x)" size="1" start="64" type="bool"/>
<field name="Height (pixels)" size="16" start="48" type="uint"/>
<field name="Width (pixels)" size="16" start="32" type="uint"/>
<field name="Memory Address" size="32" start="0" type="address"/>
</packet>
<packet name="Tile Coordinates" code="115" cl="R">
<field name="Tile Row Number" size="8" start="8" type="uint"/>
<field name="Tile Column Number" size="8" start="0" type="uint"/>
</packet>
<packet name="Gem Relocations" code="254" cl="B">
<field name="buffer 1" size="32" start="32" type="uint"/>
<field name="buffer 0" size="32" start="0" type="uint"/>
</packet>
<struct name="Shader Record">
<field name="Fragment Shader is single threaded" size="1" start="0" type="bool"/>
<field name="Point Size included in shaded vertex data" size="1" start="1" type="bool"/>
<field name="Enable Clipping" size="1" start="2" type="bool"/>
<field name="Fragment Shader Number of Uniforms (not used currently)" size="16" start="2b" type="uint"/>
<field name="Fragment Shader Number of Varyings" size="8" start="3b" type="uint"/>
<field name="Fragment Shader Code Address" size="32" start="4b" type="address"/>
<!-- set up by the kernel -->
<field name="Fragment Shader Uniforms Address" size="32" start="8b" type="uint"/>
<field name="Vertex Shader Number of Uniforms (not used currently)" size="16" start="12b" type="uint"/>
<field name="Vertex Shader Attribute Array select bits" size="8" start="14b" type="uint"/>
<field name="Vertex Shader Total Attributes Size" size="8" start="15b" type="uint"/>
<field name="Vertex Shader Code Address" size="32" start="16b" type="address"/>
<!-- set up by the kernel -->
<field name="Vertex Shader Uniforms Address" size="32" start="16b" type="uint"/>
<field name="Coordinate Shader Number of Uniforms (not used currently)" size="16" start="24b" type="uint"/>
<field name="Coordinate Shader Attribute Array select bits" size="8" start="26b" type="uint"/>
<field name="Coordinate Shader Total Attributes Size" size="8" start="27b" type="uint"/>
<field name="Coordinate Shader Code Address" size="32" start="28b" type="address"/>
<!-- set up by the kernel -->
<field name="Coordinate Shader Uniforms Address" size="32" start="32b" type="uint"/>
</struct>
<struct name="Attribute Record">
<field name="Address" size="32" start="0b" type="address"/>
<field name="Number of Bytes minus 1" size="8" start="4b" type="uint"/>
<field name="Stride" size="8" start="5b" type="uint"/>
<field name="Vertex Shader VPM offset" size="8" start="6b" type="uint"/>
<field name="Coordinate Shader VPM offset" size="8" start="7b" type="uint"/>
</struct>
</vcxml>

1541
brcm/cle/v3d_packet_v33.xml Normal file
View File

@ -0,0 +1,1541 @@
<vcxml gen="3.3" min_ver="33" max_ver="42">
<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>
<enum name="TMU Filter" prefix="V3D_TMU_FILTER" max_ver="33">
<!-- Names are mip filter, min filter, mag filter -->
<value name="MIN_LIN_MIP_NONE_MAG_LIN" value="0"/>
<value name="MIN_LIN_MIP_NONE_MAG_NEAR" value="1"/>
<value name="MIN_NEAR_MIP_NONE_MAG_LIN" value="2"/>
<value name="MIN_NEAR_MIP_NONE_MAG_NEAR" value="3"/>
<value name="MIN_NEAR_MIP_NEAR_MAG_LIN" value="4"/>
<value name="MIN_NEAR_MIP_NEAR_MAG_NEAR" value="5"/>
<value name="MIN_NEAR_MIP_LIN_MAG_LIN" value="6"/>
<value name="MIN_NEAR_MIP_LIN_MAG_NEAR" value="7"/>
<value name="MIN_LIN_MIP_NEAR_MAG_LIN" value="8"/>
<value name="MIN_LIN_MIP_NEAR_MAG_NEAR" value="9"/>
<value name="MIN_LIN_MIP_LIN_MAG_LIN" value="10"/>
<value name="MIN_LIN_MIP_LIN_MAG_NEAR" value="11"/>
<value name="ANISOTROPIC_2_1" value="12"/>
<value name="ANISOTROPIC_4_1" value="13"/>
<value name="ANISOTROPIC_8_1" value="14"/>
<value name="ANISOTROPIC_16_1" value="15"/>
</enum>
<enum name="Border Color Mode" prefix="V3D_BORDER_COLOR" min_ver="41">
<value name="0000" value="0"/>
<value name="0001" value="1"/>
<value name="1111" value="2"/>
<value name="Follows" value="7"/>
</enum>
<enum name="Wrap Mode" prefix="V3D_WRAP_MODE" min_ver="41">
<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"/>
</enum>
<enum name="TMU Op" prefix="V3D_TMU_OP" min_ver="41">
<value name="Write ADD, Read Prefetch" value="0"/>
<value name="Write SUB, Read Clear" value="1"/>
<value name="Write XCHG, Read Flush" value="2"/>
<value name="Write CMPXCHG, Read Flush" value="3"/>
<value name="Write UMIN, Full L1 Clear" value="4"/>
<value name="Write UMAX" value="5"/>
<value name="Write SMIN" value="6"/>
<value name="Write SMAX" value="7"/>
<value name="Write AND, Read INC" value="8"/>
<value name="Write OR, Read DEC" value="9"/>
<value name="Write XOR, Read NOT" value="10"/>
<value name="Regular" value="15"/>
</enum>
<enum name="Varying Flags Action" prefix="V3D_VARYING_FLAGS_ACTION">
<value name="unchanged" value="0"/>
<value name="zeroed" value="1"/>
<value name="set" value="2"/>
</enum>
<enum name="Memory Format" prefix="V3D_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"/>
</enum>
<enum name="Decimate Mode" prefix="V3D_DECIMATE_MODE">
<value name="sample 0" value="0"/>
<value name="4x" value="1"/>
<value name="all samples" value="3"/>
</enum>
<enum name="Internal Type" prefix="V3D_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"/>
</enum>
<enum name="Internal BPP" prefix="V3D_INTERNAL_BPP">
<value name="32" value="0"/>
<value name="64" value="1"/>
<value name="128" value="2"/>
</enum>
<enum name="Internal Depth Type" prefix="V3D_INTERNAL_TYPE">
<value name="depth_32f" value="0"/>
<value name="depth_24" value="1"/>
<value name="depth_16" value="2"/>
</enum>
<enum name="Render Target Clamp" prefix="V3D_RENDER_TARGET_CLAMP" min_ver="41">
<value name="none" value="0"/> <!-- no clamping -->
<value name="norm" value="1"/> <!-- [0,1] for f16 -->
<value name="pos" value="2"/> <!-- [0, for f16 -->
<value name="int" value="3" min_ver="42"/> <!-- clamp to integer RT's range -->
</enum>
<enum name="Output Image Format" prefix="V3D_OUTPUT_IMAGE_FORMAT">
<!--
Formats appear with their channels named from the low bits to
the high bits.
-->
<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" max_ver="33"/>
<value name="rgbx8" value="38" max_ver="33"/>
<value name="bstc" value="39" min_ver="41"/>
<value name="d32f" value="40" min_ver="41"/>
<value name="d24" value="41" min_ver="41"/>
<value name="d16" value="42" min_ver="41"/>
<value name="d24s8" value="43" min_ver="41"/>
<value name="s8" value="44" min_ver="41"/>
</enum>
<enum name="Z/S Output Image Format" prefix="V3D_OUTPUT_IMAGE_FORMAT_ZS" max_ver="33">
<value name="depth_component32f" value="0"/>
<value name="depth_component24" value="1"/> <!-- depth low, pad high -->
<value name="depth_component16" value="2"/>
<value name="depth24_stencil8" value="3"/> <!-- stencil low, depth high -->
</enum>
<enum name="Dither Mode" prefix="V3D_DITHER_MODE">
<value name="None" value="0"/>
<value name="RGB" value="1"/>
<value name="A" value="2"/>
<value name="RGBA" value="3"/>
</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" shortname="incr_semaphore" name="Increment Semaphore"/>
<packet code="8" shortname="wait_semaphore" name="Wait on Semaphore"/>
<packet code="9" shortname="wait_prev_frame" name="Wait for previous frame"/>
<packet code="10" shortname="enable_z_only" name="Enable Z-only rendering" cl="R"/>
<packet code="11" shortname="disable_z_only" name="Disable Z-only rendering" cl="R"/>
<packet code="12" shortname="end_z_only" name="End of Z-only rendering in frame"/>
<packet code="13" shortname="end_render" name="End of rendering"/>
<packet code="14" shortname="wait_transform_feedback" name="Wait for transform feedback" cl="B">
<field name="Block count" size="8" start="0" type="uint"/>
</packet>
<packet code="15" shortname="branch_sub_autochain" 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" shortname="branch_sub" name="Branch to Sub-list">
<field name="address" size="32" start="0" type="address"/>
</packet>
<packet code="18" shortname="return" name="Return from sub-list"/>
<packet code="19" shortname="clear_vcd_cache" name="Flush VCD cache"/>
<packet code="20" shortname="generic_tile_list" 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" shortname="branch_implicit_tile" name="Branch to Implicit Tile List">
<field name="tile list set number" size="8" start="0" type="uint"/>
</packet>
<packet code="22" shortname="branch_explicit_supertile" 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" shortname="supertile_coords" 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" shortname="store_subsample" name="Store Multi-Sample Resolved Tile Color Buffer" cl="R" max_ver="33"/>
<packet code="25" shortname="store_subsample_ex" name="Store Multi-Sample Resolved Tile Color Buffer (extended)" cl="R" max_ver="33">
<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 Color 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="25" shortname="clear" name="Clear Tile Buffers" cl="R" min_ver="41">
<field name="Clear Z/Stencil Buffer" size="1" start="1" type="bool"/>
<field name="Clear all Render Targets" size="1" start="0" type="bool"/>
</packet>
<packet code="26" shortname="load" name="Reload Tile Color Buffer" cl="R" max_ver="33">
<field name="Disable Color 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="26" shortname="end_loads" name="End of Loads" cl="R" min_ver="41"/>
<packet code="27" shortname="end_tile" name="End of Tile Marker" cl="R"/>
<packet code="29" shortname="store_general" name="Store Tile Buffer General" cl="R" max_ver="33">
<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="Last Tile of Frame" size="1" start="8" type="bool"/>
<field name="Disable Color 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="29" shortname="store" name="Store Tile Buffer General" cl="R" min_ver="41">
<field name="Address" size="32" start="64" type="address"/>
<!-- used for y flip -->
<field name="Height" size="16" start="48" type="uint"/>
<!-- height in ub for UIF, byte stride for raster -->
<field name="Height in UB or Stride" size="20" start="28" type="uint"/>
<field name="R/B swap" size="1" start="20" type="bool"/>
<field name="Channel Reverse" size="1" start="19" type="bool"/>
<field name="Clear buffer being stored" size="1" start="18" type="bool"/>
<field name="Output Image Format" size="6" start="12" type="Output Image Format"/>
<field name="Decimate mode" size="2" start="10" type="Decimate Mode"/>
<field name="Dither Mode" size="2" start="8" type="Dither Mode"/>
<field name="Flip Y" size="1" start="7" type="bool"/>
<field name="Memory Format" size="3" start="4" type="Memory Format"/>
<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" shortname="load_general" name="Load Tile Buffer General" cl="R" max_ver="33">
<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="30" shortname="load" name="Load Tile Buffer General" cl="R" min_ver="41">
<field name="Address" size="32" start="64" type="address"/>
<!-- used for y flip -->
<field name="Height" size="16" start="48" type="uint"/>
<!-- height in ub for UIF, byte stride for raster -->
<field name="Height in UB or Stride" size="20" start="28" type="uint"/>
<field name="R/B swap" size="1" start="20" type="bool"/>
<field name="Channel Reverse" size="1" start="19" type="bool"/>
<field name="Input Image Format" size="6" start="12" type="Output Image Format"/>
<field name="Decimate mode" size="2" start="10" type="Decimate Mode"/>
<field name="Flip Y" size="1" start="7" type="bool"/>
<field name="Memory Format" size="3" start="4" type="Memory Format"/>
<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="31" shortname="tf_draw_flush_and_count" name="Transform Feedback Flush and Count"/>
<packet code="32" name="Indexed Prim List" cl="B" max_ver="33">
<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="Primitive"/>
</packet>
<packet code="32" name="Indexed Prim List" cl="B" min_ver="41">
<field name="Index Offset" size="32" start="40" type="uint"/>
<field name="Enable Primitive Restarts" size="1" start="39" type="bool"/>
<field name="Length" size="31" 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="6" start="0" type="Primitive"/>
</packet>
<packet code="34" name="Indexed Instanced Prim List" cl="B" max_ver="33">
<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="34" name="Indexed Instanced Prim List" cl="B" min_ver="41">
<field name="Index Offset" size="32" start="72" type="uint"/>
<field name="Number of Instances" size="32" start="40" type="uint"/>
<field name="Enable Primitive Restarts" size="1" start="39" type="bool"/>
<field name="Instance Length" size="31" 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="6" start="0" type="Primitive"/>
</packet>
<packet code="36" name="Vertex Array Prims" 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 Prims" 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="44" name="Index Buffer Setup" cl="B" min_ver="41">
<field name="Address" size="32" start="0" type="address"/>
<field name="Size" size="32" start="32" type="uint"/>
</packet>
<packet code="56" name="Prim List Format">
<field name="tri strip or fan" size="1" start="7" type="bool"/>
<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" shortname="gl_shader" 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="71" name="VCM Cache Size" min_ver="41">
<field name="Number of 16-vertex batches for rendering" size="4" start="4" type="uint"/>
<field name="Number of 16-vertex batches for binning" size="4" start="0" type="uint"/>
</packet>
<packet code="73" name="VCM Cache Size" max_ver="33">
<field name="Number of 16-vertex batches for rendering" size="4" start="4" type="uint"/>
<field name="Number of 16-vertex batches for binning" size="4" start="0" type="uint"/>
</packet>
<packet code="73" name="Transform Feedback Buffer" min_ver="41">
<field name="Buffer Address" size="32" start="32" type="address"/>
<field name="Buffer Size in 32-bit words" size="30" start="2" type="uint"/>
<field name="Buffer Number" size="2" start="0" type="uint"/>
</packet>
<packet code="74" name="Transform Feedback Enable" max_ver="33">
<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="74" name="Transform Feedback Specs" min_ver="41">
<field name="Enable" size="1" start="7" type="bool"/>
<field name="Number of 16-bit Output Data Specs following" size="5" start="0" type="uint"/>
</packet>
<packet code="75" name="Flush Transform Feedback Data"/>
<struct name="Transform Feedback Output Data Spec" max_ver="33">
<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" size="4" start="8" type="uint" minus_one="true"/>
<field name="Output Buffer to write to" size="2" start="12" type="uint"/>
</struct>
<struct name="Transform Feedback Output Data Spec" min_ver="41">
<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" size="4" start="8" type="uint" minus_one="true"/>
<field name="Output Buffer to write to" size="2" start="12" type="uint"/>
<field name="Stream number" size="2" start="14" type="uint"/>
</struct>
<struct name="Transform Feedback Output Address">
<field name="address" size="32" start="0" type="address"/>
</struct>
<packet code="80" name="Stencil Cfg">
<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="83" name="Blend Enables" min_ver="41">
<field name="Mask" size="8" start="0" type="uint"/>
</packet>
<packet code="84" name="Blend Cfg" max_ver="33">
<field name="Color blend dst factor" size="4" start="20" type="Blend Factor"/>
<field name="Color blend src factor" size="4" start="16" type="Blend Factor"/>
<field name="Color 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="84" name="Blend Cfg" min_ver="41">
<field name="Render Target Mask" size="4" start="24" type="uint"/>
<field name="Color blend dst factor" size="4" start="20" type="Blend Factor"/>
<field name="Color blend src factor" size="4" start="16" type="Blend Factor"/>
<field name="Color 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" shortname="blend_ccolor" name="Blend Constant Color">
<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" shortname="color_wmasks" name="Color Write Masks">
<field name="Mask" size="32" start="0" type="uint"/>
</packet>
<packet code="88" name="Zero All Centroid Flags" min_ver="41"/>
<packet code="89" name="Centroid Flags" min_ver="41">
<field name="Centroid Flags for varyings V0*24" size="24" start="8" type="uint"/>
<field name="Action for Centroid Flags of higher numbered varyings" size="2" start="6" type="Varying Flags Action"/>
<field name="Action for Centroid Flags of lower numbered varyings" size="2" start="4" type="Varying Flags Action"/>
<field name="Varying offset V0" size="4" start="0" type="uint"/>
</packet>
<packet code="91" name="Sample State" min_ver="41">
<field name="Coverage" size="16" start="16" type="f187"/>
<field name="Mask" size="4" start="0" type="uint"/>
</packet>
<packet code="92" shortname="occlusion_query_counter_enable" name="Occlusion Query Counter">
<field name="address" size="32" start="0" type="address"/>
</packet>
<packet code="96" name="Cfg 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="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" shortname="zero_all_flatshade_flags" name="Zero All Flat Shade Flags"/>
<packet code="98" shortname="flatshade_flags" 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="Varying Flags Action"/>
<field name="Action for Flat Shade Flags of lower numbered varyings" size="2" start="4" type="Varying Flags Action"/>
<field name="Varying offset V0" size="4" start="0" type="uint"/>
</packet>
<packet code="99" shortname="zero_all_noperspective_flags" name="Zero All Non-perspective Flags" min_ver="41"/>
<packet code="100" shortname="noperspective_flags" name="Non-perspective Flags" min_ver="41">
<field name="Non-perspective Flags for varyings V0*24" size="24" start="8" type="uint"/>
<field name="Action for Non-perspective Flags of higher numbered varyings" size="2" start="6" type="Varying Flags Action"/>
<field name="Action for Non-perspective Flags of lower numbered varyings" size="2" start="4" type="Varying Flags Action"/>
<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" max_ver="33">
<field name="Depth Offset Units" size="16" start="16" type="f187"/>
<field name="Depth Offset Factor" size="16" start="0" type="f187"/>
</packet>
<packet name="Depth Offset" code="106" min_ver="41">
<field name="Limit" size="32" start="32" type="float"/>
<field name="Depth Offset Units" size="16" start="16" type="f187"/>
<field name="Depth Offset Factor" size="16" start="0" type="f187"/>
</packet>
<packet shortname="clip" 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" max_ver="33">
<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="Viewport Offset" code="108" min_ver="41">
<field name="Coarse Y" size="10" start="54" type="uint"/>
<field name="Viewport Centre Y-coordinate" size="22" start="32" type="s14.8"/>
<field name="Coarse X" size="10" start="22" type="uint"/>
<field name="Viewport Centre X-coordinate" size="22" start="0" type="s14.8"/>
</packet>
<packet shortname="clipz" 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 shortname="clipper_xy" 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 shortname="clipper_z" 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 name="Number of Layers" code="119" min_ver="41">
<field name="Number of Layers" size="8" start="0" type="uint" minus_one="true"/>
</packet>
<packet code="120" name="Tile Binning Mode Cfg (Part1)" max_ver="33">
<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="Internal BPP"/>
<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="26" start="6" 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 Cfg" min_ver="41">
<field name="Height (in pixels)" size="12" start="48" type="uint" minus_one="true"/>
<field name="Width (in pixels)" size="12" start="32" type="uint" minus_one="true"/>
<field name="Double-buffer in non-ms mode" size="1" start="15" type="bool"/>
<field name="Multisample Mode (4x)" size="1" start="14" type="bool"/>
<field name="Maximum BPP of all render targets" size="2" start="12" 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="8" type="uint" minus_one="true"/>
<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>
</packet>
<packet code="120" name="Tile Binning Mode Cfg (Part2)" cl="B" max_ver="33">
<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 Cfg (Common)" cl="R" max_ver="33">
<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="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" size="4" start="4" type="uint" minus_one="true"/>
<field name="sub-id" size="4" start="0" type="uint" default="0"/>
</packet>
<packet code="121" name="Tile Rendering Mode Cfg (Common)" cl="R" min_ver="41">
<field name="Pad" size="12" start="52" type="uint"/>
<field name="Early Depth/Stencil Clear" size="1" start="51" type="bool"/>
<field name="Internal Depth Type" size="4" start="47" type="Internal Depth Type"/>
<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="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="Internal BPP"/>
<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" size="4" start="4" type="uint" minus_one="true"/>
<field name="sub-id" size="4" start="0" type="uint" default="0"/>
</packet>
<packet code="121" name="Tile Rendering Mode Cfg (Color)" cl="R" max_ver="33">
<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="Memory Format"/>
<field name="Dither Mode" size="2" start="22" type="Dither Mode"/>
<field name="Output image format" size="6" start="16" type="Output Image Format"/>
<field name="Decimate mode" size="2" start="14" type="Decimate Mode"/>
<field name="Internal Type" size="4" start="10" type="Internal Type"/>
<field name="Internal BPP" size="2" start="8" type="Internal BPP"/>
<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 Cfg (Color)" cl="R" min_ver="41">
<field name="Pad" size="28" start="34" type="uint"/>
<field name="Render Target 3 Clamp" size="2" start="32" type="Render Target Clamp"/>
<field name="Render Target 3 Internal Type" size="4" start="30" type="Internal Type"/>
<field name="Render Target 3 Internal BPP" size="2" start="28" type="Internal BPP"/>
<field name="Render Target 2 Clamp" size="2" start="26" type="Render Target Clamp"/>
<field name="Render Target 2 Internal Type" size="4" start="22" type="Internal Type"/>
<field name="Render Target 2 Internal BPP" size="2" start="20" type="Internal BPP"/>
<field name="Render Target 1 Clamp" size="2" start="18" type="Render Target Clamp"/>
<field name="Render Target 1 Internal Type" size="4" start="14" type="Internal Type"/>
<field name="Render Target 1 Internal BPP" size="2" start="12" type="Internal BPP"/>
<field name="Render Target 0 Clamp" size="2" start="10" type="Render Target Clamp"/>
<field name="Render Target 0 Internal Type" size="4" start="6" type="Internal Type"/>
<field name="Render Target 0 Internal BPP" size="2" start="4" type="Internal BPP"/>
<field name="sub-id" size="4" start="0" type="uint" default="1"/>
</packet>
<packet code="121" name="Tile Rendering Mode Cfg (Z/Stencil)" cl="R" max_ver="33">
<field name="Address" size="26" start="38" 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="Memory Format"/>
<field name="Output image format" size="6" start="16" type="Z/S Output Image Format"/>
<field name="Decimate mode" size="2" start="14" type="uint"/>
<field name="Internal Type" size="4" start="10" type="Internal Depth Type"/>
<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 Cfg (ZS Clear Values)" cl="R" max_ver="33">
<field name="unused" size="16" start="48" type="uint"/>
<field name="Z Clear Value" size="32" start="16" type="float"/>
<field name="Stencil 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 Cfg (ZS Clear Values)" cl="R" min_ver="41">
<field name="unused" size="16" start="48" type="uint"/>
<field name="Z Clear Value" size="32" start="16" type="float"/>
<field name="Stencil Clear Value" size="8" start="8" type="uint"/>
<field name="sub-id" size="4" start="0" type="uint" default="2"/>
</packet>
<packet code="121" name="Tile Rendering Mode Cfg (Clear Colors Part1)" cl="R" max_ver="33">
<!-- 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 Cfg (Clear Colors Part1)" cl="R" min_ver="41">
<!-- 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="3"/>
</packet>
<packet code="121" name="Tile Rendering Mode Cfg (Clear Colors Part2)" cl="R" max_ver="33">
<!-- 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 Cfg (Clear Colors Part2)" cl="R" min_ver="41">
<!-- 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="4"/>
</packet>
<packet code="121" name="Tile Rendering Mode Cfg (Clear Colors Part3)" cl="R" max_ver="33">
<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="121" name="Tile Rendering Mode Cfg (Clear Colors Part3)" cl="R" min_ver="41">
<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="5"/>
</packet>
<packet code="124" shortname="tile_coords" 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 Cfg" cl="R">
<field name="Number of Bin Tile Lists" size="3" start="61" type="uint" minus_one="true"/>
<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" size="8" start="8" type="uint" minus_one="true"/>
<field name="Supertile Width in Tiles" size="8" start="0" type="uint" minus_one="true"/>
</packet>
<packet code="123" shortname="multicore_rendering_tile_list_base" 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" shortname="implicit_tile_coords" 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" max_ver="33">
<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="Fragment Shader 2-way threadable" size="1" start="96" type="bool"/>
<field name="Fragment Shader 4-way threadable" size="1" start="97" type="bool"/>
<field name="Fragment Shader 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 2-way threadable" size="1" start="160" type="bool"/>
<field name="Vertex Shader 4-way threadable" size="1" start="161" type="bool"/>
<field name="Vertex Shader Propagate NaNs" size="1" start="162" type="bool"/>
<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 2-way threadable" size="1" start="224" type="bool"/>
<field name="Coordinate Shader 4-way threadable" size="1" start="225" type="bool"/>
<field name="Coordinate Shader Propagate NaNs" size="1" start="226" type="bool"/>
<field name="Coordinate Shader Uniforms Address" size="32" start="32b" type="address"/>
</struct>
<struct name="GL Shader State Record" min_ver="41">
<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="Base Instance ID read by coordinate shader" size="1" start="4" type="bool"/>
<field name="Vertex ID read by vertex shader" size="1" start="5" type="bool"/>
<field name="Instance ID read by vertex shader" size="1" start="6" type="bool"/>
<field name="Base Instance ID read by vertex shader" size="1" start="7" type="bool"/>
<field name="Fragment shader does Z writes" size="1" start="8" type="bool"/>
<field name="Turn off early-z test" size="1" start="9" type="bool"/>
<field name="Coordinate shader has separate input and output VPM blocks" size="1" start="10" type="bool"/>
<field name="Vertex shader has separate input and output VPM blocks" size="1" start="11" type="bool"/>
<field name="Fragment shader uses real pixel centre W in addition to centroid W2" size="1" start="12" type="bool"/>
<field name="Enable Sample Rate Shading" size="1" start="13" type="bool"/>
<field name="Any shader reads hardware-written Primitive ID" size="1" start="14" type="bool"/>
<field name="Insert Primitive ID as first varying to fragment shader" size="1" start="15" type="bool"/>
<field name="Turn off scoreboard" size="1" start="16" type="bool"/>
<field name="Do scoreboard wait on first thread switch" size="1" start="17" type="bool"/>
<field name="Disable implicit point/line varyings" size="1" start="18" type="bool"/>
<field name="No prim pack" size="1" start="19" type="bool"/>
<field name="Number of varyings in Fragment Shader" size="8" start="3b" type="uint"/>
<field name="Coordinate Shader output VPM segment size" size="4" start="4b" type="uint"/>
<field name="Min Coord Shader output segments required in play in addition to VCM cache size" size="4" start="36" type="uint"/>
<field name="Coordinate Shader input VPM segment size" size="4" start="5b" type="uint"/>
<field name="Min Coord Shader input segments required in play" size="4" start="44" type="uint" minus_one="true"/>
<field name="Vertex Shader output VPM segment size" size="4" start="6b" type="uint"/>
<field name="Min Vertex Shader output segments required in play in addition to VCM cache size" size="4" start="52" type="uint"/>
<field name="Vertex Shader input VPM segment size" size="4" start="7b" type="uint"/>
<field name="Min Vertex Shader input segments required in play" size="4" start="60" type="uint" minus_one="true"/>
<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="Fragment Shader 4-way threadable" size="1" start="96" type="bool"/>
<field name="Fragment Shader start in final thread section" size="1" start="97" type="bool"/>
<field name="Fragment Shader 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="29" start="163" type="address"/>
<field name="Vertex Shader 4-way threadable" size="1" start="160" type="bool"/>
<field name="Vertex Shader start in final thread section" size="1" start="161" type="bool"/>
<field name="Vertex Shader Propagate NaNs" size="1" start="162" type="bool"/>
<field name="Vertex Shader Uniforms Address" size="32" start="24b" type="address"/>
<field name="Coordinate Shader Code Address" size="29" start="227" type="address"/>
<field name="Coordinate Shader 4-way threadable" size="1" start="224" type="bool"/>
<field name="Coordinate Shader start in final thread section" size="1" start="225" type="bool"/>
<field name="Coordinate Shader Propagate NaNs" size="1" start="226" type="bool"/>
<field name="Coordinate Shader Uniforms Address" size="32" start="32b" type="address"/>
</struct>
<struct name="Geometry Shader State Record" min_ver="41">
<field name="Geometry Bin Mode Shader Code Address" size="32" start="0b" type="address"/>
<field name="4-way threadable" size="1" start="0" type="bool"/>
<field name="Start in final thread section" size="1" start="1" type="bool"/>
<field name="Propagate NaNs" size="1" start="2" type="bool"/>
<field name="Geometry Bin Mode Shader Uniforms Address" size="32" start="4b" type="address"/>
<field name="Geometry Render Mode Shader Code Address" size="32" start="8b" type="address"/>
<field name="Geometry Render Mode Shader Uniforms Address" size="32" start="12b" type="address"/>
</struct>
<struct name="Tessellation Shader State Record" min_ver="41">
<field name="Tessellation Bin Mode Control Shader Code Address" size="32" start="0b" type="address"/>
<field name="Tessellation Bin Mode Control Shader Uniforms Address" size="32" start="4b" type="address"/>
<field name="Tessellation Render Mode Control Shader Code Address" size="32" start="8b" type="address"/>
<field name="Tessellation Render Mode Control Shader Uniforms Address" size="32" start="12b" type="address"/>
<field name="Tessellation Bin Mode Evaluation Shader Code Address" size="32" start="16b" type="address"/>
<field name="Tessellation Bin Mode Evaluation Shader Uniforms Address" size="32" start="20b" type="address"/>
<field name="Tessellation Render Mode Evaluation Shader Code Address" size="32" start="24b" type="address"/>
<field name="Tessellation Render Mode Evaluation Shader Uniforms Address" size="32" start="28b" type="address"/>
</struct>
<struct name="GL Shader State Attribute Record" max_ver="33">
<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="GL Shader State Attribute Record" min_ver="41">
<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"/>
<field name="Maximum Index" size="32" start="12b" 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" max_ver="33">
<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="uint">
<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" max_ver="33">
<field name="Texture state record base address" size="28" start="4" type="address"/>
<field name="Return words of texture data" size="4" start="0" type="uint"/>
</struct>
<struct name="TMU Config Parameter 0" min_ver="41">
<field name="Texture state address" size="32" start="0" type="address"/>
<field name="Return words of texture data" size="4" start="0" type="uint"/>
</struct>
<struct name="TMU Config Parameter 1" min_ver="41">
<field name="Sampler state address" size="32" start="0" type="address"/>
<field name="Per-pixel mask enable" size="1" start="2" type="bool"/>
<field name="Unnormalized coordinates" size="1" start="1" type="bool"/>
<field name="Output Type 32-bit" size="1" start="0" type="bool"/>
</struct>
<struct name="TMU Config Parameter 2" min_ver="41" max_ver="41">
<field name="Pad" size="24" start="8" type="uint"/>
<field name="Op" size="4" start="20" type="TMU Op"/>
<field name="Offset R" size="4" start="16" type="int"/>
<field name="Offset T" size="4" start="12" type="int"/>
<field name="Offset S" size="4" start="8" type="int"/>
<field name="Gather Mode" size="1" start="7" type="bool"/>
<field name="Gather Component" size="2" start="5" type="uint"/>
<field name="Coefficient Mode" size="1" start="4" type="bool"/>
<field name="Sample Number" size="2" start="2" type="uint"/>
<field name="Disable AutoLOD" size="1" start="1" type="bool"/>
<field name="Offset Format 8" size="1" start="0" type="bool"/>
</struct>
<struct name="TMU Config Parameter 2" min_ver="42">
<field name="Pad" size="23" start="9" type="uint"/>
<field name="LOD Query" size="1" start="8" type="bool"/>
<field name="Op" size="4" start="20" type="TMU Op"/>
<field name="Offset R" size="4" start="16" type="int"/>
<field name="Offset T" size="4" start="12" type="int"/>
<field name="Offset S" size="4" start="8" type="int"/>
<field name="Gather Mode" size="1" start="7" type="bool"/>
<field name="Gather Component" size="2" start="5" type="uint"/>
<field name="Coefficient Mode" size="1" start="4" type="bool"/>
<field name="Sample Number" size="2" start="2" type="uint"/>
<field name="Disable AutoLOD" size="1" start="1" type="bool"/>
<field name="Offset Format 8" size="1" start="0" type="bool"/>
</struct>
<struct name="Texture Shader State" max_ver="33">
<field name="UIF XOR disable" size="1" start="255" type="bool"/>
<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="Output 32-bit" size="1" start="246" type="bool"/>
<field name="Sample Number" size="2" start="244" 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="30" start="2" type="address"/>
<field name="Filter" size="4" start="0" type="TMU Filter"/>
</struct>
<struct name="Texture Shader State" min_ver="41">
<field name="Pad" size="56" start="136" type="uint"/>
<field name="UIF XOR disable" size="1" start="135" type="bool"/>
<field name="Level 0 is strictly UIF" size="1" start="134" type="bool"/>
<field name="Level 0 XOR enable" size="1" start="132" type="bool"/>
<field name="Level 0 UB_PAD" size="4" start="128" type="uint"/>
<field name="Base Level" size="4" start="124" type="uint"/>
<field name="Max Level" size="4" start="120" type="uint"/>
<field name="Swizzle A" size="3" start="117" 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="114" type="uint"/>
<field name="Swizzle G" size="3" start="111" type="uint"/>
<field name="Swizzle R" size="3" start="108" type="uint"/>
<field name="Extended" 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="Reverse Standard Border Color" size="1" start="5" type="bool"/>
<field name="AHDR" size="1" start="4" type="bool"/>
<field name="sRGB" size="1" start="3" type="bool"/>
<field name="Flip S and T on incoming request" size="1" start="2" type="bool"/>
<field name="Flip texture Y Axis" size="1" start="1" type="bool"/>
<field name="Flip texture X Axis" size="1" start="0" type="bool"/>
</struct>
<struct name="Sampler State" min_ver="41">
<field name="Border color Alpha" size="32" start="160" type="uint"/>
<field name="Border color Blue" size="32" start="128" type="uint"/>
<field name="Border color Green" size="32" start="96" type="uint"/>
<field name="Border color Red" size="32" start="64" type="uint"/>
<field name="Maximum Anisotropy" size="2" start="61" type="uint"/>
<field name="Border Color Mode" size="3" start="58" type="Border Color Mode"/>
<field name="Wrap I Border" size="1" start="57" type="bool"/>
<field name="Wrap R" size="3" start="54" type="Wrap Mode"/>
<field name="Wrap T" size="3" start="51" type="Wrap Mode"/>
<field name="Wrap S" size="3" start="48" type="Wrap Mode"/>
<field name="Fixed Bias" size="16" start="32" type="s8.8"/>
<field name="Max Level-of-Detail" size="12" start="20" type="u4.8"/>
<field name="Min Level-of-Detail" size="12" start="8" type="u4.8"/>
<field name="sRGB Disable" size="1" start="7" type="bool"/>
<field name="Depth Compare Function" size="3" start="4" type="Compare Function"/>
<field name="Anisotropy Enable" size="1" start="3" type="bool"/>
<field name="Mip filter Nearest" size="1" start="2" type="bool"/>
<field name="Min filter Nearest" size="1" start="1" type="bool"/>
<field name="Mag filter Nearest" size="1" start="0" type="bool"/>
</struct>
<enum name="Texture Data Formats">
<!--
most formats here have R in the low bits, A in the high bits.
Exceptions noted.
-->
<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"/> <!-- B in low bits -->
<value name="Texture Data Format RGBA4" value="7"/> <!-- A low, R high -->
<value name="Texture Data Format RGB5_A1" value="8"/> <!-- A low, R high -->
<value name="Texture Data Format RGB10_A2" value="9"/> <!-- R low, A high -->
<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"/> <!-- X low, D high -->
<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"/>
<value name="Texture Data Format R8I" value="96"/>
<value name="Texture Data Format R8UI" value="97"/>
<value name="Texture Data Format RG8I" value="98"/>
<value name="Texture Data Format RG8UI" value="99"/>
<value name="Texture Data Format RGBA8I" value="100"/>
<value name="Texture Data Format RGBA8UI" value="101"/>
<value name="Texture Data Format R16I" value="102"/>
<value name="Texture Data Format R16UI" value="103"/>
<value name="Texture Data Format RG16I" value="104"/>
<value name="Texture Data Format RG16UI" value="105"/>
<value name="Texture Data Format RGBA16I" value="106"/>
<value name="Texture Data Format RGBA16UI" value="107"/>
<value name="Texture Data Format R32I" value="108"/>
<value name="Texture Data Format R32UI" value="109"/>
<value name="Texture Data Format RG32I" value="110"/>
<value name="Texture Data Format RG32UI" value="111"/>
<value name="Texture Data Format RGBA32I" value="112"/>
<value name="Texture Data Format RGBA32UI" value="113"/>
<value name="Texture Data Format RGB10_A2UI" value="114"/>
</enum>
</vcxml>

238
brcm/cle/v3d_xml.h Normal file
View File

@ -0,0 +1,238 @@
static const struct {
uint32_t gen_10;
uint32_t offset;
uint32_t length;
} genxml_files_table[] = {
{ 21, 0, 15538 },
};
static const uint8_t compress_genxmls[] = {
0x78, 0x9c, 0xed, 0x5b, 0x5b, 0x73, 0xda, 0x38, 0x1b, 0xbe, 0xef, 0xaf,
0xd0, 0x72, 0x95, 0x5e, 0x50, 0x62, 0x02, 0x86, 0xcc, 0x24, 0x3b, 0x43,
0x12, 0x72, 0x98, 0x21, 0x87, 0x0f, 0x68, 0xda, 0x72, 0xd3, 0x11, 0xb6,
0x20, 0x9a, 0xfa, 0xc0, 0xd8, 0x72, 0x42, 0xf6, 0xd7, 0x7f, 0xaf, 0x24,
0x1f, 0xb1, 0x8c, 0x6c, 0xda, 0xdd, 0xbd, 0xd8, 0xf6, 0x66, 0x9b, 0xe6,
0xd5, 0x23, 0xbd, 0xe7, 0x93, 0xf7, 0xec, 0xd5, 0xda, 0xba, 0x0e, 0x5a,
0x13, 0xef, 0xbc, 0xd5, 0xfd, 0x64, 0xb4, 0x90, 0x4b, 0xbd, 0xef, 0xaf,
0x24, 0x80, 0x9f, 0xf8, 0x0f, 0x78, 0x9b, 0xfe, 0xf0, 0xe7, 0x87, 0x0f,
0x08, 0x9d, 0x11, 0x2f, 0x72, 0x91, 0x87, 0x5d, 0x72, 0xde, 0xba, 0xf4,
0xdd, 0x0d, 0x0e, 0x08, 0xba, 0x8e, 0x3c, 0x8b, 0x51, 0xdf, 0x6b, 0xa1,
0x4d, 0x40, 0x56, 0x74, 0x7b, 0xde, 0x7a, 0x3e, 0xb9, 0xfa, 0x7e, 0xf9,
0x78, 0xff, 0x34, 0x9a, 0x8e, 0xbf, 0x5f, 0x7f, 0x7e, 0xb8, 0x84, 0xb3,
0x08, 0xfe, 0x9c, 0xbd, 0x62, 0x27, 0x22, 0xf1, 0xe9, 0x87, 0xf1, 0xf3,
0x78, 0xda, 0x42, 0xe2, 0x9f, 0xce, 0x5b, 0xc7, 0xad, 0x8e, 0x82, 0x66,
0x32, 0x9e, 0xcd, 0x52, 0x12, 0x43, 0x49, 0x32, 0xfe, 0xdf, 0xe7, 0xd1,
0x24, 0xa5, 0xe9, 0x56, 0xc0, 0x14, 0x88, 0x4e, 0x94, 0x44, 0x37, 0xd3,
0xf1, 0x68, 0x9e, 0x7b, 0x51, 0x4f, 0x49, 0xf5, 0xf0, 0x38, 0x2f, 0x82,
0xf5, 0xd5, 0x60, 0x45, 0x22, 0x53, 0x49, 0x34, 0x9a, 0x7c, 0x19, 0x7d,
0xcb, 0xf8, 0x1b, 0x48, 0xa2, 0xb3, 0x0e, 0x17, 0x71, 0x49, 0xd8, 0x4f,
0x01, 0x75, 0x29, 0xa3, 0xaf, 0xa4, 0x28, 0xe5, 0xa7, 0xe9, 0xdd, 0xbd,
0x4a, 0xba, 0x4f, 0x8f, 0x77, 0x0f, 0xf3, 0x99, 0x4e, 0xbc, 0x77, 0x0f,
0x63, 0x9d, 0x7c, 0x39, 0xcd, 0xf7, 0xc9, 0xe3, 0xe3, 0x93, 0x4e, 0xc6,
0x9c, 0x6e, 0x36, 0x9f, 0xde, 0x3d, 0x69, 0xe4, 0x0c, 0x24, 0xa3, 0x87,
0x9b, 0x49, 0xee, 0x62, 0xb5, 0xa4, 0x13, 0xba, 0x1d, 0x50, 0xb5, 0xbc,
0x53, 0xe2, 0xeb, 0xd1, 0xc3, 0xae, 0xd4, 0xf3, 0x02, 0xdd, 0x60, 0xeb,
0x07, 0x61, 0xf1, 0xa1, 0x5b, 0xec, 0xb0, 0x16, 0xb2, 0x7c, 0x3b, 0x13,
0x50, 0x91, 0xe0, 0x81, 0x73, 0x2d, 0x7f, 0x6f, 0xa8, 0x7e, 0x7f, 0xed,
0x44, 0xe1, 0x4b, 0x42, 0xd1, 0x83, 0xbf, 0x38, 0xe7, 0xad, 0x8b, 0x4a,
0x42, 0x34, 0x72, 0x1c, 0x34, 0x63, 0x98, 0x91, 0xe4, 0x48, 0x7f, 0xcf,
0x11, 0x20, 0x0c, 0x18, 0x9a, 0x53, 0x87, 0xa0, 0x0b, 0xea, 0x79, 0xd4,
0x5b, 0x27, 0xa7, 0xcc, 0x3d, 0xa7, 0xee, 0x3c, 0x2b, 0x20, 0x2e, 0xf1,
0x18, 0x9a, 0x11, 0x17, 0x6f, 0x5e, 0xfc, 0x20, 0xbd, 0x6c, 0xa0, 0xa2,
0xff, 0x82, 0x29, 0x43, 0xbe, 0x57, 0xa6, 0x1e, 0xaa, 0xa8, 0x2f, 0x02,
0xec, 0x59, 0x29, 0xc3, 0x86, 0x99, 0x18, 0xde, 0x8a, 0x12, 0xc7, 0x4e,
0x8c, 0xda, 0xb6, 0x03, 0x12, 0x86, 0x2d, 0x14, 0xd2, 0xbf, 0xb8, 0x0d,
0x74, 0xe1, 0x6f, 0x9c, 0x15, 0x2e, 0x62, 0xc4, 0xde, 0x37, 0xf0, 0x6f,
0x38, 0x26, 0x89, 0xb5, 0x23, 0xaf, 0xa8, 0xba, 0x0d, 0x31, 0x1f, 0x85,
0xd1, 0xb2, 0xed, 0xd0, 0x30, 0x55, 0x96, 0x31, 0xf8, 0x7b, 0x6f, 0x9e,
0x12, 0x16, 0x05, 0x1e, 0x5a, 0x05, 0xbe, 0x5b, 0xbe, 0x5b, 0x48, 0x46,
0xa1, 0x2e, 0x10, 0x1e, 0xba, 0x8f, 0x1c, 0x46, 0xdb, 0x21, 0x76, 0x37,
0xa0, 0xb6, 0x29, 0x09, 0x7d, 0xe7, 0x95, 0xd8, 0x52, 0x89, 0x97, 0xbe,
0xe3, 0x07, 0xe8, 0x22, 0x5a, 0xad, 0x48, 0x90, 0x60, 0x75, 0x63, 0x9b,
0x99, 0xaa, 0x0d, 0xa0, 0x01, 0x22, 0xc2, 0x9e, 0x8d, 0xc6, 0x8f, 0xd7,
0x29, 0x72, 0x3f, 0x87, 0x5c, 0x01, 0x7d, 0x1d, 0x81, 0x3d, 0x0a, 0xc8,
0x88, 0x47, 0xef, 0xd8, 0xd6, 0x92, 0x07, 0x8a, 0xc3, 0x09, 0x5a, 0x1d,
0x4d, 0x77, 0x87, 0xa9, 0xbc, 0x7b, 0x4a, 0x79, 0xef, 0x1c, 0x9f, 0xe0,
0x50, 0xda, 0x77, 0x02, 0x60, 0xa4, 0xe7, 0x4f, 0x92, 0xf3, 0x4b, 0xdf,
0x77, 0x94, 0x87, 0xaf, 0x68, 0x88, 0x97, 0x5c, 0x06, 0x0e, 0xc1, 0x01,
0x37, 0xe0, 0x2f, 0x01, 0x65, 0x0a, 0xa4, 0x6e, 0x6d, 0xa4, 0x45, 0x67,
0xc6, 0x88, 0x67, 0x51, 0x27, 0x91, 0xe8, 0x9b, 0x1a, 0xd1, 0xa8, 0xff,
0xb6, 0xbc, 0x7e, 0x2a, 0xd0, 0x8e, 0xcb, 0x68, 0x99, 0x59, 0x2a, 0xec,
0xb2, 0xed, 0xf8, 0xd8, 0x6e, 0xa2, 0xb9, 0x3a, 0x9e, 0xd2, 0x54, 0x73,
0x95, 0x22, 0x0b, 0x08, 0xb6, 0x7f, 0x99, 0xc4, 0xd4, 0x60, 0xcd, 0x04,
0x26, 0x0d, 0x3d, 0x27, 0x1e, 0x74, 0x43, 0x3c, 0x12, 0x60, 0x27, 0x95,
0xcf, 0x30, 0x11, 0x98, 0xe2, 0x59, 0xf7, 0xc4, 0xf5, 0x83, 0x77, 0xb4,
0xc4, 0x21, 0x41, 0xb1, 0x3c, 0x90, 0xbf, 0x82, 0xb0, 0x00, 0xbf, 0xed,
0x30, 0x0e, 0x6a, 0x47, 0xee, 0x06, 0x2d, 0x63, 0xc1, 0x97, 0x84, 0xd9,
0x55, 0xc7, 0x9d, 0x2a, 0x3f, 0xe0, 0xd8, 0xd7, 0x1c, 0x5b, 0x21, 0xc2,
0xd3, 0xda, 0x32, 0x7c, 0xbe, 0x69, 0xdf, 0xe3, 0xf0, 0x47, 0xfc, 0x2a,
0xf1, 0x42, 0x05, 0xde, 0xf0, 0x00, 0xbf, 0xd8, 0x8f, 0x38, 0x68, 0xa8,
0xe5, 0xfd, 0x68, 0xe6, 0xa1, 0xfc, 0x5a, 0x49, 0x40, 0x08, 0xb9, 0xea,
0x3b, 0x15, 0xf0, 0xfd, 0xc3, 0xd9, 0xaf, 0x77, 0x41, 0xef, 0x30, 0x69,
0xd4, 0x03, 0x2f, 0x85, 0xc7, 0x32, 0xfa, 0x13, 0xdd, 0x12, 0x27, 0xc6,
0xbe, 0xf6, 0x03, 0x17, 0xb3, 0xd4, 0x3e, 0x53, 0x9c, 0xd4, 0x06, 0x22,
0xea, 0xb1, 0xd8, 0xfe, 0x77, 0xca, 0xaa, 0x60, 0xbd, 0xc4, 0x43, 0xf8,
0x53, 0xae, 0x23, 0x77, 0x08, 0x97, 0xeb, 0xa0, 0x6f, 0xf6, 0x91, 0x4d,
0xd9, 0x0b, 0x09, 0x88, 0x5d, 0xae, 0x29, 0xd5, 0xf4, 0x9e, 0x1f, 0x1f,
0x51, 0x14, 0x97, 0x1d, 0xc1, 0x8f, 0x8a, 0xb9, 0x7b, 0x70, 0xdd, 0x32,
0x3b, 0xa6, 0x9e, 0x9d, 0x99, 0x4c, 0xa3, 0xc7, 0x5a, 0x76, 0xae, 0x88,
0x45, 0x41, 0x66, 0x04, 0x6d, 0x7b, 0x5a, 0x56, 0x32, 0x5a, 0x6e, 0xb5,
0x0d, 0xd8, 0xa8, 0xd2, 0x4b, 0x4f, 0xcf, 0xc8, 0x14, 0x62, 0x46, 0x4e,
0x68, 0x55, 0x6c, 0xcc, 0xb5, 0x8f, 0x9f, 0xcc, 0x1b, 0x3d, 0x39, 0x0e,
0xa2, 0x50, 0x92, 0x89, 0xc8, 0x9a, 0x96, 0x5a, 0xe5, 0xf0, 0x5c, 0xfd,
0xf6, 0x07, 0xdf, 0x23, 0xda, 0x97, 0x0b, 0xcb, 0xd5, 0xbe, 0x7e, 0xd1,
0x09, 0xa5, 0x73, 0x96, 0x99, 0xd8, 0xa5, 0x2c, 0x37, 0x25, 0x3b, 0x14,
0x71, 0x1c, 0x51, 0x34, 0x25, 0x89, 0x38, 0xf6, 0x66, 0x9a, 0x09, 0xcf,
0xcb, 0xfb, 0x12, 0xcd, 0xe9, 0xbf, 0x9e, 0x68, 0x2a, 0x22, 0x26, 0xaf,
0x28, 0x7e, 0x6d, 0x86, 0xa8, 0x40, 0x3c, 0x30, 0x43, 0x54, 0xa0, 0x95,
0x32, 0xc4, 0xef, 0x20, 0xf8, 0x3b, 0x08, 0xfe, 0x0e, 0x82, 0xff, 0x6a,
0x10, 0xbc, 0xf3, 0x6c, 0xb2, 0x85, 0xf6, 0x34, 0x9d, 0x55, 0xa1, 0x49,
0xae, 0x73, 0x86, 0x86, 0x5c, 0x15, 0xfb, 0xf0, 0x96, 0xba, 0x91, 0x8b,
0xc4, 0x59, 0x45, 0xef, 0x3e, 0xe8, 0x16, 0xa4, 0xa9, 0x0a, 0x1b, 0xa3,
0x2c, 0x64, 0x02, 0x0a, 0xb5, 0x48, 0x18, 0xdf, 0x5b, 0x02, 0xeb, 0x1d,
0x6b, 0xc1, 0x26, 0xc4, 0x5b, 0xb3, 0x17, 0xc5, 0xd9, 0xa1, 0xf6, 0xa8,
0x60, 0x41, 0x10, 0x25, 0xc7, 0x7b, 0x4d, 0xec, 0x79, 0xd8, 0x5e, 0x52,
0xa6, 0x35, 0x0a, 0xc3, 0x2c, 0x90, 0x19, 0x0a, 0x0d, 0xed, 0x86, 0xc1,
0x54, 0x1b, 0x6e, 0x2e, 0x66, 0xf4, 0xca, 0xe6, 0x9a, 0x8d, 0x18, 0x75,
0x7d, 0xd5, 0x33, 0x09, 0x18, 0xb0, 0x3a, 0x0a, 0x02, 0xfc, 0x9e, 0x69,
0x3b, 0x4c, 0x35, 0x7d, 0xa2, 0xd2, 0xb4, 0x14, 0x0f, 0x6f, 0x72, 0x68,
0x00, 0x2d, 0x8f, 0xc4, 0xf8, 0xc7, 0x95, 0xf4, 0x37, 0x48, 0xa3, 0x68,
0xee, 0x69, 0xaa, 0x29, 0x34, 0xe2, 0x7d, 0xe5, 0x08, 0xe5, 0x0a, 0x33,
0x8c, 0xe6, 0x87, 0x1a, 0x8c, 0x34, 0x05, 0x44, 0xa5, 0xe7, 0x68, 0xc2,
0xc4, 0x49, 0x57, 0x10, 0x6f, 0x3b, 0xef, 0x8a, 0xf9, 0x6c, 0x75, 0xb0,
0xcb, 0x78, 0x53, 0x3f, 0xb3, 0x46, 0xac, 0x7b, 0xf2, 0xe1, 0x57, 0x89,
0x4b, 0x6a, 0xac, 0x7b, 0x42, 0x3d, 0xb2, 0x43, 0x5a, 0xc5, 0xd0, 0x3c,
0xa0, 0xd8, 0x5b, 0x3b, 0xbb, 0xe4, 0x55, 0xc1, 0x6f, 0x7a, 0xfb, 0xad,
0x48, 0x58, 0xe6, 0x7e, 0xaf, 0x92, 0x6f, 0x26, 0x68, 0xf6, 0x82, 0x6d,
0x08, 0xfc, 0x85, 0x11, 0xae, 0xd9, 0x4b, 0xf4, 0xfa, 0x47, 0xbb, 0x8d,
0xe6, 0x2f, 0x59, 0x01, 0x27, 0xa5, 0xf8, 0x46, 0x1d, 0xa8, 0x8b, 0x08,
0xfc, 0xe4, 0x38, 0x10, 0x19, 0xa9, 0x87, 0x96, 0xef, 0xe8, 0x07, 0x09,
0x3c, 0xa8, 0x4c, 0xe0, 0x21, 0xd4, 0xc6, 0x62, 0x82, 0xc3, 0xc1, 0x3e,
0xa1, 0x76, 0xbb, 0xd1, 0xb0, 0x46, 0xef, 0x27, 0xe3, 0x2d, 0xa4, 0x06,
0x1b, 0xee, 0x0d, 0xe5, 0xd3, 0x03, 0x62, 0xf9, 0x81, 0xa2, 0x9a, 0xd2,
0x0f, 0xdc, 0x1e, 0x22, 0x77, 0x09, 0x00, 0xe0, 0xbd, 0x98, 0xb1, 0x80,
0x2e, 0x23, 0xc8, 0xf5, 0x98, 0xbb, 0x7f, 0xa8, 0xcb, 0x7f, 0x3a, 0xef,
0x91, 0x23, 0x3c, 0x91, 0xeb, 0xc2, 0x1d, 0xa7, 0x31, 0x8c, 0x9e, 0xca,
0x6b, 0xe4, 0x89, 0x59, 0x92, 0xf5, 0xe4, 0xf5, 0x99, 0x58, 0x4e, 0x4d,
0xad, 0x5c, 0x24, 0xc2, 0xf3, 0x0d, 0x92, 0xd9, 0x6e, 0x17, 0x61, 0xa8,
0x0f, 0x23, 0x12, 0x61, 0x31, 0x4b, 0xd5, 0x92, 0xb9, 0x84, 0xd9, 0xab,
0x79, 0x3a, 0xce, 0xef, 0x12, 0xc0, 0xac, 0xf2, 0x29, 0xad, 0xfc, 0x7c,
0x6f, 0x45, 0xd7, 0x51, 0x20, 0x0d, 0xe9, 0x82, 0xb2, 0x34, 0x0c, 0x9f,
0x2a, 0x63, 0xce, 0x18, 0x07, 0xce, 0x3b, 0x5a, 0xa0, 0x68, 0x03, 0xb6,
0x07, 0xde, 0x43, 0x3c, 0x5e, 0x73, 0x1f, 0x54, 0xaf, 0x27, 0x50, 0x95,
0x10, 0xfa, 0x31, 0x4e, 0x8d, 0x77, 0xd4, 0x18, 0xd6, 0x90, 0x0d, 0x7b,
0x69, 0xcf, 0x09, 0x0f, 0xbe, 0xe9, 0x2e, 0x72, 0xd7, 0x2a, 0x8d, 0xb4,
0x90, 0x28, 0xed, 0x2d, 0x95, 0x2a, 0xf2, 0x5f, 0xa1, 0x7f, 0x5b, 0xf3,
0xa1, 0x3b, 0x74, 0x76, 0xf9, 0x6a, 0x3b, 0xf7, 0x34, 0x43, 0xa9, 0x69,
0x1e, 0x09, 0x20, 0x0a, 0xc8, 0x40, 0x13, 0xaa, 0xbd, 0x3a, 0x85, 0x7f,
0xa2, 0x1b, 0x82, 0x66, 0xc4, 0x21, 0x16, 0x2b, 0x5f, 0xa0, 0x6f, 0xc2,
0x64, 0x11, 0x4c, 0x43, 0xf0, 0xcd, 0x47, 0x40, 0x8c, 0x17, 0x05, 0x75,
0x9a, 0x83, 0x83, 0x5e, 0x2b, 0x84, 0x91, 0xcf, 0x04, 0xd9, 0x5b, 0xfb,
0x07, 0xa3, 0x8f, 0x3c, 0x46, 0x21, 0x14, 0x42, 0xf7, 0x0b, 0xa5, 0xa3,
0x4c, 0x16, 0x7c, 0x9d, 0x21, 0x72, 0x41, 0xf9, 0x1e, 0xfd, 0x68, 0x6d,
0x2c, 0x2c, 0x09, 0x09, 0xab, 0x40, 0x8f, 0xab, 0x55, 0x48, 0x14, 0xa2,
0xd5, 0x87, 0xbc, 0x4b, 0xc7, 0xb7, 0x7e, 0xbc, 0x81, 0x68, 0x0b, 0x15,
0x4e, 0xf3, 0x0d, 0x43, 0xfc, 0x9c, 0x29, 0xe1, 0xfa, 0x01, 0xab, 0xc3,
0x16, 0xf5, 0xd6, 0x28, 0xb7, 0xcf, 0x6d, 0x3e, 0x30, 0x8f, 0x21, 0xa1,
0xd2, 0x78, 0xc3, 0x81, 0x5d, 0x03, 0xb2, 0xd9, 0xd8, 0xfc, 0xda, 0xc1,
0x4c, 0x66, 0x3b, 0x04, 0x7f, 0x5d, 0x67, 0x01, 0x45, 0xb9, 0x4d, 0xe0,
0xd4, 0x6d, 0x9e, 0x60, 0xf8, 0x1b, 0x62, 0xfa, 0xea, 0x15, 0x5c, 0xad,
0x98, 0x26, 0xac, 0x40, 0x80, 0xa4, 0x57, 0x0f, 0x55, 0x57, 0x4b, 0xba,
0x99, 0xa0, 0xab, 0xbe, 0x72, 0xe5, 0xf8, 0x58, 0x7f, 0x27, 0x37, 0x37,
0x48, 0xd7, 0x36, 0x4b, 0x17, 0x9c, 0xa7, 0xa7, 0xaa, 0x3b, 0xf3, 0x74,
0x3f, 0x7b, 0xe7, 0xf4, 0x76, 0x8e, 0xbe, 0xa2, 0xa5, 0x1f, 0x79, 0x36,
0x0e, 0xde, 0xd3, 0xb4, 0x77, 0x7c, 0xac, 0xba, 0x98, 0x13, 0x6f, 0xd2,
0x72, 0x2c, 0x7f, 0x2c, 0xd6, 0xb6, 0x59, 0x7e, 0x46, 0x1d, 0x61, 0x17,
0xfd, 0x24, 0x79, 0x82, 0x91, 0xaf, 0x6b, 0xd8, 0x0b, 0x09, 0x89, 0xac,
0x68, 0xc0, 0x37, 0x21, 0x74, 0x2e, 0x7d, 0x38, 0x22, 0x78, 0x6c, 0x1b,
0xed, 0x61, 0x7b, 0x00, 0xd1, 0x9b, 0x1f, 0xb4, 0xd1, 0x11, 0xf3, 0x37,
0xc8, 0x30, 0x11, 0xd4, 0x9a, 0xa2, 0x21, 0xc3, 0x92, 0xea, 0xa4, 0xfb,
0x51, 0xed, 0xfb, 0xf9, 0xcb, 0xd1, 0x67, 0x4f, 0x64, 0xaf, 0x12, 0x3b,
0x86, 0x3e, 0xa3, 0x17, 0x70, 0xc0, 0x1f, 0x58, 0x96, 0x59, 0x55, 0x72,
0xa9, 0x59, 0x99, 0xd0, 0x0d, 0xfa, 0x02, 0xe5, 0xb5, 0xff, 0x96, 0xc9,
0x45, 0xd9, 0xc4, 0xe6, 0x28, 0xd1, 0x2d, 0xa1, 0xeb, 0x17, 0x5e, 0x95,
0xa3, 0x0d, 0x9f, 0x3f, 0xa9, 0xf8, 0xe9, 0xd5, 0xa9, 0x2f, 0x32, 0xc4,
0x2f, 0xdc, 0xd8, 0xf6, 0x02, 0x9e, 0xe8, 0x9b, 0xe4, 0x3c, 0xe0, 0x85,
0xcf, 0x98, 0xef, 0xa2, 0x64, 0x3e, 0x06, 0x25, 0x21, 0xf5, 0x70, 0x6e,
0x3d, 0xd9, 0x48, 0xf2, 0x79, 0xe0, 0x09, 0x59, 0xb1, 0x3a, 0xb0, 0xcd,
0xf4, 0xf0, 0x4c, 0xc9, 0xdb, 0xc6, 0x0f, 0x58, 0xc9, 0x46, 0x95, 0x6d,
0x66, 0x4a, 0x7d, 0x49, 0x3c, 0x06, 0xa6, 0xfa, 0xad, 0x6d, 0xd5, 0xe3,
0x30, 0x34, 0xba, 0x9f, 0x7a, 0x4a, 0x16, 0x77, 0x21, 0xbf, 0xee, 0x87,
0x3c, 0x56, 0x20, 0xee, 0x61, 0x6f, 0xc1, 0x3f, 0xb9, 0x12, 0x19, 0xcf,
0xc5, 0x5b, 0x28, 0x80, 0xe9, 0x66, 0xc3, 0x23, 0xe9, 0xc6, 0xc1, 0x5e,
0xd6, 0x52, 0x1b, 0xc7, 0xca, 0x52, 0x38, 0x99, 0x9e, 0x2c, 0xde, 0x14,
0xc1, 0x28, 0xb3, 0x8a, 0x5c, 0x34, 0xda, 0x05, 0xa0, 0x5e, 0x35, 0x40,
0xc3, 0x68, 0xc6, 0x2d, 0x61, 0x03, 0x85, 0xc8, 0xd7, 0x6f, 0x68, 0x66,
0x41, 0x42, 0xcf, 0x3e, 0x59, 0x31, 0x8e, 0xd3, 0x4f, 0x5d, 0xf6, 0x89,
0xf7, 0x16, 0x3b, 0xab, 0x76, 0xe6, 0x3f, 0x46, 0xc7, 0x30, 0xc1, 0xf0,
0x21, 0x8a, 0x08, 0xc3, 0x3f, 0x90, 0xc3, 0x22, 0x7a, 0xea, 0x4b, 0x7a,
0xf0, 0x03, 0xb9, 0x5f, 0x08, 0xe6, 0x89, 0x50, 0xe8, 0xae, 0xc1, 0x9a,
0x75, 0xa4, 0xb0, 0x48, 0xc2, 0xd8, 0xd1, 0xc2, 0xe2, 0x53, 0xc6, 0x45,
0xf8, 0xf1, 0x67, 0x59, 0x4f, 0xde, 0xb4, 0x17, 0xb1, 0x21, 0xbf, 0xf9,
0x4f, 0x93, 0x44, 0xc1, 0x89, 0x0a, 0x9d, 0x48, 0xd6, 0xc3, 0x75, 0xf7,
0x30, 0x7d, 0xe5, 0x47, 0x50, 0xc8, 0xb4, 0xe3, 0x51, 0x3f, 0xa8, 0xc5,
0xf3, 0xbd, 0xb6, 0x1b, 0x16, 0x66, 0x33, 0xf9, 0x7a, 0xbb, 0xb4, 0x07,
0x2f, 0x43, 0x8a, 0x77, 0x8d, 0x1c, 0x28, 0xde, 0xe2, 0x8e, 0x88, 0x97,
0x71, 0x85, 0x1a, 0xa1, 0x9b, 0x03, 0x1c, 0x14, 0x22, 0x91, 0x7a, 0x4c,
0x2f, 0x00, 0xf8, 0x51, 0xc4, 0xa5, 0xa5, 0x5b, 0x02, 0x64, 0xd4, 0xa6,
0x7e, 0x6e, 0x9e, 0xa3, 0x36, 0xba, 0x43, 0xed, 0x10, 0x23, 0x47, 0xde,
0xed, 0x9b, 0x8d, 0x06, 0x39, 0xbb, 0x62, 0xb9, 0x83, 0x5c, 0x0b, 0x55,
0xb7, 0x46, 0x3c, 0xfd, 0xff, 0x8a, 0x78, 0x46, 0x11, 0xf3, 0xdb, 0x54,
0xca, 0x84, 0x97, 0xfc, 0x42, 0x5c, 0x62, 0xd2, 0x83, 0xc4, 0x90, 0x4e,
0x8c, 0x3a, 0x55, 0x16, 0xa9, 0x6f, 0x47, 0xf2, 0x5b, 0x41, 0xb3, 0x27,
0xa6, 0x70, 0x72, 0x27, 0x25, 0x6a, 0x16, 0x15, 0xa6, 0xbe, 0x37, 0x11,
0x9f, 0x85, 0xe5, 0x9a, 0x3d, 0x74, 0xd4, 0xdb, 0x7e, 0x54, 0x41, 0x95,
0xda, 0x93, 0x32, 0x56, 0x1c, 0x70, 0x8f, 0xc0, 0xfb, 0xf8, 0xae, 0x31,
0x8b, 0x0d, 0xd9, 0x40, 0x84, 0x67, 0x1f, 0x5d, 0x1d, 0x20, 0x23, 0xeb,
0x3e, 0x94, 0xf2, 0x60, 0xa6, 0x42, 0x58, 0xbb, 0x72, 0x47, 0xd5, 0x9f,
0xf6, 0xd5, 0x18, 0xb6, 0xec, 0x5a, 0xbe, 0x2b, 0xb7, 0xad, 0xa1, 0xba,
0x6b, 0xa8, 0x51, 0x4a, 0x55, 0x00, 0x62, 0xfd, 0xf7, 0x87, 0x39, 0xbe,
0x75, 0x91, 0x75, 0xca, 0x07, 0x77, 0x81, 0x2e, 0xb6, 0x9e, 0xec, 0xd9,
0x2a, 0x37, 0x8b, 0xad, 0x03, 0xfd, 0xac, 0x46, 0x8c, 0x7b, 0xda, 0x8b,
0x8e, 0xfc, 0xef, 0xa5, 0xff, 0x8a, 0x6c, 0xb9, 0xb0, 0x55, 0xa0, 0xe9,
0x87, 0x36, 0x31, 0x1a, 0xfa, 0x2c, 0xe6, 0x3f, 0xe8, 0x8a, 0x06, 0x44,
0x4c, 0x63, 0xd0, 0xcd, 0xbc, 0x73, 0x33, 0x56, 0x40, 0xea, 0x3d, 0x4d,
0x8e, 0x51, 0x50, 0x3a, 0xad, 0x50, 0x4f, 0x6d, 0x06, 0x7a, 0xf7, 0x8a,
0xfb, 0xeb, 0x78, 0x40, 0x98, 0x7e, 0x5a, 0x57, 0x42, 0xd2, 0x37, 0xff,
0xf1, 0x6a, 0xbf, 0x6a, 0xcd, 0x39, 0xa8, 0x31, 0x3f, 0xff, 0x67, 0xf6,
0x9c, 0x8a, 0x8e, 0x2a, 0x5e, 0xe9, 0x56, 0x0c, 0x93, 0x4a, 0x3d, 0x8c,
0x62, 0x68, 0x0c, 0x06, 0x77, 0x7b, 0x35, 0x95, 0x5f, 0xb5, 0x25, 0x21,
0x70, 0xff, 0x3e, 0xde, 0xac, 0xb1, 0xc1, 0x0e, 0x52, 0xd7, 0xb0, 0x84,
0x57, 0xa0, 0xaa, 0xc5, 0x7b, 0x95, 0xa8, 0x4a, 0x00, 0xa5, 0x15, 0x7f,
0x95, 0x08, 0xab, 0xae, 0x3e, 0x6c, 0x87, 0xdf, 0x34, 0x33, 0x98, 0x7a,
0xaf, 0xaa, 0x99, 0x18, 0x4c, 0xbd, 0x33, 0x25, 0x69, 0x41, 0x36, 0x9d,
0x19, 0x46, 0xa3, 0x36, 0x36, 0x4e, 0x0a, 0xd5, 0x18, 0x35, 0xc2, 0x6d,
0xec, 0x42, 0x87, 0x7f, 0xde, 0xad, 0x0e, 0xb0, 0x59, 0x83, 0x9a, 0x35,
0x59, 0x46, 0x7f, 0x4f, 0x3c, 0x95, 0x61, 0x19, 0xba, 0x5c, 0xb9, 0x0b,
0x51, 0xac, 0x0d, 0xea, 0x65, 0x0e, 0x50, 0x71, 0xe4, 0x7a, 0x95, 0x28,
0xcd, 0x7a, 0xe3, 0x1b, 0xe2, 0x42, 0xaa, 0x48, 0x52, 0x51, 0xca, 0x49,
0xb7, 0xdf, 0xdb, 0x53, 0x75, 0xc7, 0x29, 0xc1, 0x38, 0x2c, 0xfd, 0xc5,
0xa7, 0x8f, 0x0f, 0x99, 0xf2, 0x85, 0x2c, 0x88, 0xac, 0xf4, 0xeb, 0x5c,
0xb9, 0x94, 0x9a, 0xca, 0xa5, 0x94, 0x6a, 0xb2, 0x08, 0x51, 0x5c, 0xfe,
0xcf, 0x0c, 0x92, 0x92, 0x86, 0x70, 0x25, 0xdf, 0xf9, 0x21, 0xf6, 0xc2,
0x3f, 0x0f, 0x26, 0xf5, 0x3e, 0x10, 0xae, 0x1c, 0x1a, 0x42, 0x52, 0xb4,
0x9c, 0xc8, 0x96, 0x7b, 0x39, 0xb1, 0x22, 0xb3, 0xd1, 0xab, 0x5c, 0x6d,
0x43, 0x4e, 0xc2, 0x3f, 0x31, 0x99, 0xbd, 0x8c, 0xbb, 0xf8, 0x1a, 0xf3,
0x62, 0x3d, 0xdb, 0xd9, 0xee, 0xed, 0xb3, 0x47, 0x57, 0x10, 0x38, 0x43,
0x74, 0xe4, 0xf9, 0x0c, 0x45, 0x7c, 0x60, 0x6e, 0x45, 0x01, 0x04, 0x25,
0xe6, 0xbc, 0xab, 0xbc, 0xab, 0xbb, 0xd4, 0x6a, 0xb3, 0xfa, 0xb2, 0x67,
0x1c, 0xbc, 0x03, 0x0b, 0x61, 0xd9, 0x44, 0x4f, 0x9a, 0xc3, 0x5e, 0xf2,
0x58, 0x54, 0xed, 0xc2, 0xbd, 0xa5, 0xd2, 0x87, 0xe3, 0xf1, 0x23, 0x6f,
0x86, 0xa3, 0x0d, 0xdf, 0x9c, 0x42, 0x88, 0x4d, 0xb6, 0xa7, 0xca, 0x71,
0xe2, 0xee, 0xb5, 0xa9, 0xc0, 0xaa, 0xaf, 0x1e, 0x96, 0x98, 0x51, 0x34,
0xd2, 0xd2, 0x28, 0x7e, 0x5a, 0x1f, 0x46, 0x0d, 0x85, 0x14, 0xef, 0x1a,
0xa5, 0xdb, 0x56, 0x59, 0x09, 0x87, 0xb2, 0xc4, 0x59, 0xe6, 0x06, 0xa5,
0xb9, 0x32, 0xbd, 0xd7, 0x14, 0x7e, 0xee, 0x33, 0xe8, 0x01, 0xd3, 0x4b,
0xc2, 0x42, 0x23, 0x98, 0x03, 0xee, 0x37, 0x05, 0xd6, 0xe8, 0xdb, 0x30,
0x7f, 0x91, 0xc2, 0x8b, 0xb7, 0xd6, 0x50, 0x77, 0xee, 0xe6, 0x6a, 0x7d,
0x67, 0xb9, 0xe1, 0x17, 0xf8, 0x60, 0x0d, 0xa5, 0x94, 0xef, 0x6b, 0xa4,
0xf7, 0x6e, 0x99, 0xa7, 0x1a, 0x57, 0xd4, 0xd4, 0x7d, 0x77, 0x70, 0x08,
0xb8, 0x46, 0xff, 0xdd, 0xe1, 0x2f, 0xd2, 0x7f, 0xf9, 0xe6, 0x1a, 0x36,
0x70, 0xa2, 0x72, 0xc3, 0xb3, 0x8e, 0x4c, 0x4e, 0x8a, 0x44, 0x95, 0x29,
0xa3, 0x3a, 0x57, 0xed, 0x29, 0x4f, 0x2a, 0x59, 0x55, 0x7f, 0x60, 0x71,
0xf1, 0xce, 0x95, 0xe1, 0x52, 0x2f, 0x0a, 0xb3, 0x14, 0x3d, 0x54, 0x84,
0xca, 0x4a, 0x75, 0xcc, 0xe0, 0xb9, 0xb6, 0x42, 0x95, 0x8d, 0xbd, 0xf8,
0xf9, 0xe9, 0x1e, 0x5e, 0x94, 0x5f, 0xa0, 0x66, 0x60, 0x07, 0xd9, 0xdc,
0x3e, 0x40, 0x95, 0x9d, 0xe5, 0x94, 0x72, 0xd6, 0x11, 0xff, 0xa7, 0xf2,
0x9f, 0x1f, 0xfe, 0x0f, 0x39, 0x09, 0x85, 0x9f,
};

44
brcm/cle/v3dx_pack.h Normal file
View File

@ -0,0 +1,44 @@
/*
* Copyright © 2015 Intel Corporation
* 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.
*/
#ifndef V3DX_PACK_H
#define V3DX_PACK_H
#ifndef V3D_VERSION
# error "The V3D_VERSION macro must be defined"
#endif
#if (V3D_VERSION == 21)
# include "v3d_packet_v21_pack.h"
#elif (V3D_VERSION == 33)
# include "v3d_packet_v33_pack.h"
#elif (V3D_VERSION == 41)
# include "v3d_packet_v41_pack.h"
#elif (V3D_VERSION == 42)
# include "v3d_packet_v42_pack.h"
#else
# error "Need to add a pack header include for this v3d version"
#endif
#endif /* V3DX_PACK_H */

444
brcm/clif/clif_dump.c Normal file
View File

@ -0,0 +1,444 @@
/*
* 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 "drm-uapi/v3d_drm.h"
#include "clif_dump.h"
#include "clif_private.h"
#include "../common/list.h"
#include "../common/ralloc.h"
#include "../cle/v3d_decoder.h"
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 =
calloc(1, sizeof(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 pretty)
{
struct clif_dump *clif = calloc(1, sizeof(struct clif_dump));
clif->devinfo = devinfo;
clif->out = out;
clif->spec = v3d_spec_load(devinfo);
clif->pretty = pretty;
list_inithead(&clif->worklist);
return clif;
}
void
clif_dump_destroy(struct clif_dump *clif)
{
ralloc_free(clif);
}
struct clif_bo *
clif_lookup_bo(struct clif_dump *clif, uint32_t addr)
{
for (int i = 0; i < clif->bo_count; i++) {
struct clif_bo *bo = &clif->bo[i];
if (addr >= bo->offset &&
addr < bo->offset + bo->size) {
return bo;
}
}
return NULL;
}
static bool
clif_lookup_vaddr(struct clif_dump *clif, uint32_t addr, void **vaddr)
{
struct clif_bo *bo = clif_lookup_bo(clif, addr);
if (!bo)
return false;
*vaddr = bo->vaddr + addr - bo->offset;
return true;
}
#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, bool reloc_mode)
{
return 1;
/*if (clif->devinfo->ver >= 41)
return v3d41_clif_dump_packet(clif, offset, cl, size, reloc_mode);
else
return v3d33_clif_dump_packet(clif, offset, cl, size, reloc_mode);*/
}
static uint32_t
clif_dump_cl(struct clif_dump *clif, uint32_t start, uint32_t end,
bool reloc_mode)
{
struct clif_bo *bo = clif_lookup_bo(clif, start);
if (!bo) {
out(clif, "Failed to look up address 0x%08x\n",
start);
return 0;
}
void *start_vaddr = bo->vaddr + start - bo->offset;
/* 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, end, &end_vaddr)) {
out(clif, "Failed to look up address 0x%08x\n",
end);
return 0;
}
if (!reloc_mode)
out(clif, "@format ctrllist /* [%s+0x%08x] */\n",
bo->name, start - bo->offset);
uint32_t size;
uint8_t *cl = start_vaddr;
while (clif_dump_packet(clif, start, cl, &size, reloc_mode)) {
cl += size;
start += size;
if (cl == end_vaddr)
break;
}
return (void *)cl - bo->vaddr;
}
/* Walks the worklist, parsing the relocs for any memory regions that might
* themselves have additional relocations.
*/
static uint32_t
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);
uint32_t offset = 0;
out(clif, "@format shadrec_gl_main\n");
v3d_print_group(clif, state, 0, vaddr + offset);
offset += v3d_group_get_length(state);
for (int i = 0; i < reloc->shader_state.num_attrs; i++) {
out(clif, "@format shadrec_gl_attr /* %d */\n", i);
v3d_print_group(clif, attr, 0, vaddr + offset);
offset += v3d_group_get_length(attr);
}
return offset;
}
static void
clif_process_worklist(struct clif_dump *clif)
{
list_for_each_entry_safe(struct reloc_worklist_entry, reloc,
&clif->worklist, link) {
void *vaddr;
if (!clif_lookup_vaddr(clif, reloc->addr, &vaddr)) {
out(clif, "Failed to look up address 0x%08x\n",
reloc->addr);
continue;
}
switch (reloc->type) {
case reloc_cl:
clif_dump_cl(clif, reloc->addr, reloc->cl.end, true);
break;
case reloc_gl_shader_state:
break;
case reloc_generic_tile_list:
clif_dump_cl(clif, reloc->addr,
reloc->generic_tile_list.end, true);
break;
}
}
}
static int
worklist_entry_compare(const void *a, const void *b)
{
return ((*(struct reloc_worklist_entry **)a)->addr -
(*(struct reloc_worklist_entry **)b)->addr);
}
static bool
clif_dump_if_blank(struct clif_dump *clif, struct clif_bo *bo,
uint32_t start, uint32_t end)
{
for (int i = start; i < end; i++) {
if (((uint8_t *)bo->vaddr)[i] != 0)
return false;
}
out(clif, "\n");
out(clif, "@format blank %d /* [%s+0x%08x..0x%08x] */\n", end - start,
bo->name, start, end - 1);
return true;
}
/* Dumps the binary data in the BO from start to end (relative to the start of
* the BO).
*/
static void
clif_dump_binary(struct clif_dump *clif, struct clif_bo *bo,
uint32_t start, uint32_t end)
{
if (start == end)
return;
if (clif_dump_if_blank(clif, bo, start, end))
return;
out(clif, "@format binary /* [%s+0x%08x] */\n",
bo->name, start);
uint32_t offset = start;
int dumped_in_line = 0;
while (offset < end) {
if (clif_dump_if_blank(clif, bo, offset, end))
return;
if (end - offset >= 4) {
out(clif, "0x%08x ", *(uint32_t *)(bo->vaddr + offset));
offset += 4;
} else {
out(clif, "0x%02x ", *(uint8_t *)(bo->vaddr + offset));
offset++;
}
if (++dumped_in_line == 8) {
out(clif, "\n");
dumped_in_line = 0;
}
}
if (dumped_in_line)
out(clif, "\n");
}
/* Walks the list of relocations, dumping each buffer's contents (using our
* codegenned dump routines for pretty printing, and most importantly proper
* address references so that the CLIF parser can relocate buffers).
*/
static void
clif_dump_buffers(struct clif_dump *clif)
{
int num_relocs = 0;
list_for_each_entry(struct reloc_worklist_entry, reloc,
&clif->worklist, link) {
num_relocs++;
}
struct reloc_worklist_entry **relocs =
malloc(sizeof(struct reloc_worklist_entry *) * num_relocs);
int i = 0;
list_for_each_entry(struct reloc_worklist_entry, reloc,
&clif->worklist, link) {
relocs[i++] = reloc;
}
qsort(relocs, num_relocs, sizeof(*relocs), worklist_entry_compare);
struct clif_bo *bo = NULL;
uint32_t offset = 0;
for (i = 0; i < num_relocs; i++) {
struct reloc_worklist_entry *reloc = relocs[i];
struct clif_bo *new_bo = clif_lookup_bo(clif, reloc->addr);
if (!new_bo) {
out(clif, "Failed to look up address 0x%08x\n",
reloc->addr);
continue;
}
if (new_bo != bo) {
if (bo) {
/* Finish out the last of the last BO. */
clif_dump_binary(clif, bo,
offset,
bo->size);
}
out(clif, "\n");
out(clif, "@buffer %s\n", new_bo->name);
bo = new_bo;
offset = 0;
bo->dumped = true;
}
int reloc_offset = reloc->addr - bo->offset;
if (offset != reloc_offset)
clif_dump_binary(clif, bo, offset, reloc_offset);
offset = reloc_offset;
switch (reloc->type) {
case reloc_cl:
offset = clif_dump_cl(clif, reloc->addr, reloc->cl.end,
false);
out(clif, "\n");
break;
case reloc_gl_shader_state:
offset += clif_dump_gl_shader_state_record(clif,
reloc,
bo->vaddr +
offset);
break;
case reloc_generic_tile_list:
offset = clif_dump_cl(clif, reloc->addr,
reloc->generic_tile_list.end,
false);
break;
}
out(clif, "\n");
}
if (bo) {
clif_dump_binary(clif, bo, offset, bo->size);
}
/* For any BOs that didn't have relocations, just dump them raw. */
for (int i = 0; i < clif->bo_count; i++) {
bo = &clif->bo[i];
if (bo->dumped)
continue;
out(clif, "@buffer %s\n", bo->name);
clif_dump_binary(clif, bo, 0, bo->size);
out(clif, "\n");
}
}
void
clif_dump_add_cl(struct clif_dump *clif, uint32_t start, uint32_t end)
{
struct reloc_worklist_entry *entry =
clif_dump_add_address_to_worklist(clif, reloc_cl, start);
entry->cl.end = end;
}
static int
clif_bo_offset_compare(const void *a, const void *b)
{
return ((struct clif_bo *)a)->offset - ((struct clif_bo *)b)->offset;
}
void
clif_dump(struct clif_dump *clif, const struct drm_v3d_submit_cl *submit)
{
clif_dump_add_cl(clif, submit->bcl_start, submit->bcl_end);
clif_dump_add_cl(clif, submit->rcl_start, submit->rcl_end);
qsort(clif->bo, clif->bo_count, sizeof(clif->bo[0]),
clif_bo_offset_compare);
/* A buffer needs to be defined before we can emit a CLIF address
* referencing it, so emit them all now.
*/
for (int i = 0; i < clif->bo_count; i++) {
out(clif, "@createbuf_aligned 4096 %s\n", clif->bo[i].name);
}
/* Walk the worklist figuring out the locations of structs based on
* the CL contents.
*/
clif_process_worklist(clif);
/* Dump the contents of the buffers using the relocations we found to
* pretty-print structures.
*/
clif_dump_buffers(clif);
out(clif, "@add_bin 0\n ");
out_address(clif, submit->bcl_start);
out(clif, "\n ");
out_address(clif, submit->bcl_end);
out(clif, "\n ");
out_address(clif, submit->qma);
out(clif, "\n %d\n ", submit->qms);
out_address(clif, submit->qts);
out(clif, "\n");
out(clif, "@wait_bin_all_cores\n");
out(clif, "@add_render 0\n ");
out_address(clif, submit->rcl_start);
out(clif, "\n ");
out_address(clif, submit->rcl_end);
out(clif, "\n ");
out_address(clif, submit->qma);
out(clif, "\n");
out(clif, "@wait_render_all_cores\n");
}
void
clif_dump_add_bo(struct clif_dump *clif, const char *name,
uint32_t offset, uint32_t size, void *vaddr)
{
if (clif->bo_count >= clif->bo_array_size) {
clif->bo_array_size = MAX2(4, clif->bo_array_size * 2);
clif->bo = realloc(clif->bo, sizeof(struct clif_bo) * clif->bo_array_size);
}
/* CLIF relocs use the buffer name, so make sure they're unique. */
for (int i = 0; i < clif->bo_count; i++)
assert(strcmp(clif->bo[i].name, name) != 0);
clif->bo[clif->bo_count].name = ralloc_strdup(clif, name);
clif->bo[clif->bo_count].offset = offset;
clif->bo[clif->bo_count].size = size;
clif->bo[clif->bo_count].vaddr = vaddr;
clif->bo[clif->bo_count].dumped = false;
clif->bo_count++;
}

43
brcm/clif/clif_dump.h Normal file
View File

@ -0,0 +1,43 @@
/*
* 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 drm_v3d_submit_cl;
struct clif_dump *clif_dump_init(const struct v3d_device_info *devinfo,
FILE *output, bool pretty);
void clif_dump(struct clif_dump *clif, const struct drm_v3d_submit_cl *submit);
void clif_dump_destroy(struct clif_dump *clif);
void clif_dump_add_bo(struct clif_dump *clif, const char *name,
uint32_t offset, uint32_t size, void *vaddr);
void clif_dump_add_cl(struct clif_dump *clif, uint32_t start, uint32_t end);
#endif

123
brcm/clif/clif_private.h Normal file
View File

@ -0,0 +1,123 @@
/*
* Copyright © 2016-2018 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_PRIVATE_H
#define CLIF_PRIVATE_H
#include <stdint.h>
#include <stdarg.h>
#include "../common/list.h"
struct clif_bo {
const char *name;
uint32_t offset;
uint32_t size;
void *vaddr;
bool dumped;
};
struct clif_dump {
const struct v3d_device_info *devinfo;
FILE *out;
struct v3d_spec *spec;
/* List of struct reloc_worklist_entry */
struct list_head worklist;
struct clif_bo *bo;
int bo_count;
int bo_array_size;
/**
* Flag to switch from CLIF ABI to slightly more human-readable
* output.
*/
bool pretty;
};
enum reloc_worklist_type {
reloc_cl,
reloc_gl_shader_state,
reloc_generic_tile_list,
};
struct reloc_worklist_entry {
struct list_head link;
enum reloc_worklist_type type;
uint32_t addr;
union {
struct {
uint32_t end;
} cl;
struct {
uint32_t num_attrs;
} shader_state;
struct {
uint32_t end;
} generic_tile_list;
};
};
struct clif_bo *
clif_lookup_bo(struct clif_dump *clif, uint32_t addr);
struct reloc_worklist_entry *
clif_dump_add_address_to_worklist(struct clif_dump *clif,
enum reloc_worklist_type type,
uint32_t addr);
bool v3d33_clif_dump_packet(struct clif_dump *clif, uint32_t offset,
const uint8_t *cl, uint32_t *size, bool reloc_mode);
bool v3d41_clif_dump_packet(struct clif_dump *clif, uint32_t offset,
const uint8_t *cl, uint32_t *size, bool reloc_mode);
bool v3d42_clif_dump_packet(struct clif_dump *clif, uint32_t offset,
const uint8_t *cl, uint32_t *size, bool reloc_mode);
static inline void
out(struct clif_dump *clif, const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
vfprintf(clif->out, fmt, args);
va_end(args);
}
static inline void
out_address(struct clif_dump *clif, uint32_t addr)
{
struct clif_bo *bo = clif_lookup_bo(clif, addr);
if (bo) {
out(clif, "[%s+0x%08x] /* 0x%08x */",
bo->name, addr - bo->offset, addr);
} else if (addr) {
out(clif, "/* XXX: BO unknown */ 0x%08x", addr);
} else {
out(clif, "[null]");
}
}
#endif /* CLIF_PRIVATE_H */

174
brcm/clif/v3dx_dump.c Normal file
View File

@ -0,0 +1,174 @@
/*
* Copyright © 2016-2018 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 <ctype.h>
#include <stdlib.h>
#include <string.h>
#include "../common/macros.h"
#include "../cle/v3d_decoder.h"
#include "clif_dump.h"
#include "clif_private.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)))
#include "../cle/v3dx_pack.h"
#include "../common/v3d_macros.h"
static char *
clif_name(const char *xml_name)
{
char *name = malloc(strlen(xml_name) + 1);
int j = 0;
for (int i = 0; i < strlen(xml_name); i++) {
if (xml_name[i] == ' ') {
name[j++] = '_';
} else if (xml_name[i] == '(' || xml_name[i] == ')') {
/* skip */
} else {
name[j++] = toupper(xml_name[i]);
}
}
name[j++] = 0;
return name;
}
bool
v3dX(clif_dump_packet)(struct clif_dump *clif, uint32_t offset,
const uint8_t *cl, uint32_t *size, bool reloc_mode)
{
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);
if (!reloc_mode) {
char *name = clif_name(v3d_group_get_name(inst));
out(clif, "%s\n", name);
free(name);
v3d_print_group(clif, inst, 0, cl);
}
switch (*cl) {
case V3DX(GL_SHADER_STATE_opcode): {
struct V3DX(GL_SHADER_STATE) values;
V3DX(GL_SHADER_STATE_unpack)(cl, &values);
if (reloc_mode) {
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;
}
#if V3D_VERSION < 40
/*case V3DX(STORE_MULTI_SAMPLE_RESOLVED_TILE_COLOR_BUFFER_EXTENDED_opcode): {
struct V3DX(STORE_MULTI_SAMPLE_RESOLVED_TILE_COLOR_BUFFER_EXTENDED) values;
V3DX(STORE_MULTI_SAMPLE_RESOLVED_TILE_COLOR_BUFFER_EXTENDED_unpack)(cl, &values);
if (values.last_tile_of_frame)
return false;
break;
}*/
#endif /* V3D_VERSION < 40 */
#if V3D_VERSION > 40
case V3DX(TRANSFORM_FEEDBACK_SPECS_opcode): {
struct V3DX(TRANSFORM_FEEDBACK_SPECS) values;
V3DX(TRANSFORM_FEEDBACK_SPECS_unpack)(cl, &values);
struct v3d_group *spec = v3d_spec_find_struct(clif->spec,
"Transform Feedback Output Data Spec");
assert(spec);
cl += *size;
for (int i = 0; i < values.number_of_16_bit_output_data_specs_following; i++) {
if (!reloc_mode)
v3d_print_group(clif, spec, 0, cl);
cl += v3d_group_get_length(spec);
*size += v3d_group_get_length(spec);
}
if (!reloc_mode)
out(clif, "@format ctrllist\n");
break;
}
#else /* V3D_VERSION < 40 */
/*case V3DX(TRANSFORM_FEEDBACK_ENABLE_opcode): {
struct V3DX(TRANSFORM_FEEDBACK_ENABLE) values;
V3DX(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++) {
if (!reloc_mode)
v3d_print_group(clif, 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++) {
if (!reloc_mode)
v3d_print_group(clif, addr, 0, cl);
cl += v3d_group_get_length(addr);
*size += v3d_group_get_length(addr);
}
break;
}*/
#endif /* V3D_VERSION < 40 */
/*case V3DX(START_ADDRESS_OF_GENERIC_TILE_LIST_opcode): {
struct V3DX(START_ADDRESS_OF_GENERIC_TILE_LIST) values;
V3DX(START_ADDRESS_OF_GENERIC_TILE_LIST_unpack)(cl, &values);
struct reloc_worklist_entry *reloc =
clif_dump_add_address_to_worklist(clif,
reloc_generic_tile_list,
values.start);
reloc->generic_tile_list.end = values.end;
break;
}*/
case V3DX(HALT_opcode):
return false;
}
return true;
}

248
brcm/common/list.h Normal file
View File

@ -0,0 +1,248 @@
/**************************************************************************
*
* Copyright 2006 VMware, Inc., Bismarck, ND. USA.
* 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, 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 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 COPYRIGHT HOLDERS, AUTHORS 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.
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial portions
* of the Software.
*
**************************************************************************/
/**
* \file
* List macros heavily inspired by the Linux kernel
* list handling. No list looping yet.
*
* Is not threadsafe, so common operations need to
* be protected using an external mutex.
*/
#ifndef _UTIL_LIST_H_
#define _UTIL_LIST_H_
#include <stdbool.h>
#include <stddef.h>
//#include "c99_compat.h"
//#include "../../driver/CustomAssert.h"
typedef struct list_head
{
struct list_head *prev;
struct list_head *next;
};
static inline void list_inithead(struct list_head *item)
{
item->prev = item;
item->next = item;
}
static inline void list_add(struct list_head *item, struct list_head *list)
{
item->prev = list;
item->next = list->next;
list->next->prev = item;
list->next = item;
}
static inline void list_addtail(struct list_head *item, struct list_head *list)
{
item->next = list;
item->prev = list->prev;
list->prev->next = item;
list->prev = item;
}
static inline bool list_empty(const struct list_head *list);
static inline void list_replace(struct list_head *from, struct list_head *to)
{
if (list_empty(from)) {
list_inithead(to);
} else {
to->prev = from->prev;
to->next = from->next;
from->next->prev = to;
from->prev->next = to;
}
}
static inline void list_del(struct list_head *item)
{
item->prev->next = item->next;
item->next->prev = item->prev;
item->prev = item->next = NULL;
}
static inline void list_delinit(struct list_head *item)
{
item->prev->next = item->next;
item->next->prev = item->prev;
item->next = item;
item->prev = item;
}
static inline bool list_empty(const struct list_head *list)
{
return list->next == list;
}
/**
* Returns whether the list has exactly one element.
*/
static inline bool list_is_singular(const struct list_head *list)
{
return list->next != NULL && list->next != list && list->next->next == list;
}
static inline unsigned list_length(const struct list_head *list)
{
struct list_head *node;
unsigned length = 0;
for (node = list->next; node != list; node = node->next)
length++;
return length;
}
static inline void list_splice(struct list_head *src, struct list_head *dst)
{
if (list_empty(src))
return;
src->next->prev = dst;
src->prev->next = dst->next;
dst->next->prev = src->prev;
dst->next = src->next;
}
static inline void list_splicetail(struct list_head *src, struct list_head *dst)
{
if (list_empty(src))
return;
src->prev->next = dst;
src->next->prev = dst->prev;
dst->prev->next = src->next;
dst->prev = src->prev;
}
static inline void list_validate(const struct list_head *list)
{
struct list_head *node;
assert(list->next->prev == list && list->prev->next == list);
for (node = list->next; node != list; node = node->next)
assert(node->next->prev == node && node->prev->next == node);
}
#define LIST_INITHEAD(__item) list_inithead(__item)
#define LIST_ADD(__item, __list) list_add(__item, __list)
#define LIST_ADDTAIL(__item, __list) list_addtail(__item, __list)
#define LIST_REPLACE(__from, __to) list_replace(__from, __to)
#define LIST_DEL(__item) list_del(__item)
#define LIST_DELINIT(__item) list_delinit(__item)
#define LIST_ENTRY(__type, __item, __field) \
((__type *)(((char *)(__item)) - offsetof(__type, __field)))
#define LIST_IS_EMPTY(__list) \
((__list)->next == (__list))
/**
* Cast from a pointer to a member of a struct back to the containing struct.
*
* 'sample' MUST be initialized, or else the result is undefined!
*/
#ifndef container_of
#define container_of(ptr, sample, member) \
(void *)((char *)(ptr) \
- ((char *)&(sample)->member - (char *)(sample)))
#endif
#define list_first_entry(ptr, type, member) \
LIST_ENTRY(type, (ptr)->next, member)
#define list_last_entry(ptr, type, member) \
LIST_ENTRY(type, (ptr)->prev, member)
#define LIST_FOR_EACH_ENTRY(pos, head, member) \
for (pos = NULL, pos = container_of((head)->next, pos, member); \
&pos->member != (head); \
pos = container_of(pos->member.next, pos, member))
#define LIST_FOR_EACH_ENTRY_SAFE(pos, storage, head, member) \
for (pos = NULL, pos = container_of((head)->next, pos, member), \
storage = container_of(pos->member.next, pos, member); \
&pos->member != (head); \
pos = storage, storage = container_of(storage->member.next, storage, member))
#define LIST_FOR_EACH_ENTRY_SAFE_REV(pos, storage, head, member) \
for (pos = NULL, pos = container_of((head)->prev, pos, member), \
storage = container_of(pos->member.prev, pos, member); \
&pos->member != (head); \
pos = storage, storage = container_of(storage->member.prev, storage, member))
#define LIST_FOR_EACH_ENTRY_FROM(pos, start, head, member) \
for (pos = NULL, pos = container_of((start), pos, member); \
&pos->member != (head); \
pos = container_of(pos->member.next, pos, member))
#define LIST_FOR_EACH_ENTRY_FROM_REV(pos, start, head, member) \
for (pos = NULL, pos = container_of((start), pos, member); \
&pos->member != (head); \
pos = container_of(pos->member.prev, pos, member))
#define list_for_each_entry(type, pos, head, member) \
for (type *pos = LIST_ENTRY(type, (head)->next, member); \
&pos->member != (head); \
pos = LIST_ENTRY(type, pos->member.next, member))
#define list_for_each_entry_safe(type, pos, head, member) \
for (type *pos = LIST_ENTRY(type, (head)->next, member), \
*__next = LIST_ENTRY(type, pos->member.next, member); \
&pos->member != (head); \
pos = __next, \
__next = LIST_ENTRY(type, __next->member.next, member))
#define list_for_each_entry_rev(type, pos, head, member) \
for (type *pos = LIST_ENTRY(type, (head)->prev, member); \
&pos->member != (head); \
pos = LIST_ENTRY(type, pos->member.prev, member))
#define list_for_each_entry_safe_rev(type, pos, head, member) \
for (type *pos = LIST_ENTRY(type, (head)->prev, member), \
*__prev = LIST_ENTRY(type, pos->member.prev, member); \
&pos->member != (head); \
pos = __prev, \
__prev = LIST_ENTRY(type, __prev->member.prev, member))
#define list_for_each_entry_from(type, pos, start, head, member) \
for (type *pos = LIST_ENTRY(type, (start), member); \
&pos->member != (head); \
pos = LIST_ENTRY(type, pos->member.next, member))
#define list_for_each_entry_from_rev(type, pos, start, head, member) \
for (type *pos = LIST_ENTRY(type, (start), member); \
&pos->member != (head); \
pos = LIST_ENTRY(type, pos->member.prev, member))
#endif /*_UTIL_LIST_H_*/

301
brcm/common/macros.h Normal file
View File

@ -0,0 +1,301 @@
/*
* Copyright © 2014 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 UTIL_MACROS_H
#define UTIL_MACROS_H
#include "../../driver/CustomAssert.h"
//#include "c99_compat.h"
/* Compute the size of an array */
#ifndef ARRAY_SIZE
# define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
#endif
/* For compatibility with Clang's __has_builtin() */
#ifndef __has_builtin
# define __has_builtin(x) 0
#endif
/**
* __builtin_expect macros
*/
#if !defined(HAVE___BUILTIN_EXPECT)
# define __builtin_expect(x, y) (x)
#endif
#ifndef likely
# ifdef HAVE___BUILTIN_EXPECT
# define likely(x) __builtin_expect(!!(x), 1)
# define unlikely(x) __builtin_expect(!!(x), 0)
# else
# define likely(x) (x)
# define unlikely(x) (x)
# endif
#endif
/**
* Static (compile-time) assertion.
* Basically, use COND to dimension an array. If COND is false/zero the
* array size will be -1 and we'll get a compilation error.
*/
#define STATIC_ASSERT(COND) \
do { \
(void) sizeof(char [1 - 2*!(COND)]); \
} while (0)
/**
* Unreachable macro. Useful for suppressing "control reaches end of non-void
* function" warnings.
*/
#ifdef HAVE___BUILTIN_UNREACHABLE
#define unreachable(str) \
do { \
assert(!str); \
__builtin_unreachable(); \
} while (0)
#elif defined (_MSC_VER)
#define unreachable(str) \
do { \
assert(!str); \
__assume(0); \
} while (0)
#else
#define unreachable(str) assert(!str)
#endif
/**
* Assume macro. Useful for expressing our assumptions to the compiler,
* typically for purposes of silencing warnings.
*/
#if __has_builtin(__builtin_assume)
#define assume(expr) \
do { \
assert(expr); \
__builtin_assume(expr); \
} while (0)
#elif defined HAVE___BUILTIN_UNREACHABLE
#define assume(expr) ((expr) ? ((void) 0) \
: (assert(!"assumption failed"), \
__builtin_unreachable()))
#elif defined (_MSC_VER)
#define assume(expr) __assume(expr)
#else
#define assume(expr) assert(expr)
#endif
/* Attribute const is used for functions that have no effects other than their
* return value, and only rely on the argument values to compute the return
* value. As a result, calls to it can be CSEed. Note that using memory
* pointed to by the arguments is not allowed for const functions.
*/
#ifdef HAVE_FUNC_ATTRIBUTE_CONST
#define ATTRIBUTE_CONST __attribute__((__const__))
#else
#define ATTRIBUTE_CONST
#endif
#ifdef HAVE_FUNC_ATTRIBUTE_FLATTEN
#define FLATTEN __attribute__((__flatten__))
#else
#define FLATTEN
#endif
#ifdef HAVE_FUNC_ATTRIBUTE_FORMAT
#define PRINTFLIKE(f, a) __attribute__ ((format(__printf__, f, a)))
#else
#define PRINTFLIKE(f, a)
#endif
#ifdef HAVE_FUNC_ATTRIBUTE_MALLOC
#define MALLOCLIKE __attribute__((__malloc__))
#else
#define MALLOCLIKE
#endif
/* Forced function inlining */
/* Note: Clang also sets __GNUC__ (see other cases below) */
#ifndef ALWAYS_INLINE
# if defined(__GNUC__)
# define ALWAYS_INLINE inline __attribute__((always_inline))
# elif defined(_MSC_VER)
# define ALWAYS_INLINE __forceinline
# else
# define ALWAYS_INLINE inline
# endif
#endif
/* Used to optionally mark structures with misaligned elements or size as
* packed, to trade off performance for space.
*/
#ifdef HAVE_FUNC_ATTRIBUTE_PACKED
#define PACKED __attribute__((__packed__))
#else
#define PACKED
#endif
/* Attribute pure is used for functions that have no effects other than their
* return value. As a result, calls to it can be dead code eliminated.
*/
#ifdef HAVE_FUNC_ATTRIBUTE_PURE
#define ATTRIBUTE_PURE __attribute__((__pure__))
#else
#define ATTRIBUTE_PURE
#endif
#ifdef HAVE_FUNC_ATTRIBUTE_RETURNS_NONNULL
#define ATTRIBUTE_RETURNS_NONNULL __attribute__((__returns_nonnull__))
#else
#define ATTRIBUTE_RETURNS_NONNULL
#endif
#ifndef NORETURN
# ifdef _MSC_VER
# define NORETURN __declspec(noreturn)
# elif defined HAVE_FUNC_ATTRIBUTE_NORETURN
# define NORETURN __attribute__((__noreturn__))
# else
# define NORETURN
# endif
#endif
#ifdef __cplusplus
/**
* Macro function that evaluates to true if T is a trivially
* destructible type -- that is, if its (non-virtual) destructor
* performs no action and all member variables and base classes are
* trivially destructible themselves.
*/
# if (defined(__clang__) && defined(__has_feature))
# if __has_feature(has_trivial_destructor)
# define HAS_TRIVIAL_DESTRUCTOR(T) __has_trivial_destructor(T)
# endif
# elif defined(__GNUC__)
# if ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 3)))
# define HAS_TRIVIAL_DESTRUCTOR(T) __has_trivial_destructor(T)
# endif
# elif defined(_MSC_VER) && !defined(__INTEL_COMPILER)
# if _MSC_VER >= 1800
# define HAS_TRIVIAL_DESTRUCTOR(T) __has_trivial_destructor(T)
# endif
# endif
# ifndef HAS_TRIVIAL_DESTRUCTOR
/* It's always safe (if inefficient) to assume that a
* destructor is non-trivial.
*/
# define HAS_TRIVIAL_DESTRUCTOR(T) (false)
# endif
#endif
/**
* PUBLIC/USED macros
*
* If we build the library with gcc's -fvisibility=hidden flag, we'll
* use the PUBLIC macro to mark functions that are to be exported.
*
* We also need to define a USED attribute, so the optimizer doesn't
* inline a static function that we later use in an alias. - ajax
*/
#ifndef PUBLIC
# if defined(__GNUC__)
# define PUBLIC __attribute__((visibility("default")))
# define USED __attribute__((used))
# elif defined(_MSC_VER)
# define PUBLIC __declspec(dllexport)
# define USED
# else
# define PUBLIC
# define USED
# endif
#endif
#ifdef HAVE_FUNC_ATTRIBUTE_UNUSED
#define UNUSED __attribute__((unused))
#else
#define UNUSED
#endif
#define MAYBE_UNUSED UNUSED
#ifdef HAVE_FUNC_ATTRIBUTE_WARN_UNUSED_RESULT
#define MUST_CHECK __attribute__((warn_unused_result))
#else
#define MUST_CHECK
#endif
#if defined(__GNUC__)
#define ATTRIBUTE_NOINLINE __attribute__((noinline))
#else
#define ATTRIBUTE_NOINLINE
#endif
/**
* Check that STRUCT::FIELD can hold MAXVAL. We use a lot of bitfields
* in Mesa/gallium. We have to be sure they're of sufficient size to
* hold the largest expected value.
* Note that with MSVC, enums are signed and enum bitfields need one extra
* high bit (always zero) to ensure the max value is handled correctly.
* This macro will detect that with MSVC, but not GCC.
*/
#define ASSERT_BITFIELD_SIZE(STRUCT, FIELD, MAXVAL) \
do { \
MAYBE_UNUSED STRUCT s; \
s.FIELD = (MAXVAL); \
assert((int) s.FIELD == (MAXVAL) && "Insufficient bitfield size!"); \
} while (0)
/** Compute ceiling of integer quotient of A divided by B. */
#define DIV_ROUND_UP( A, B ) ( (A) % (B) == 0 ? (A)/(B) : (A)/(B)+1 )
/** Clamp X to [MIN,MAX]. Turn NaN into MIN, arbitrarily. */
#define CLAMP( X, MIN, MAX ) ( (X)>(MIN) ? ((X)>(MAX) ? (MAX) : (X)) : (MIN) )
/** Minimum of two values: */
#define MIN2( A, B ) ( (A)<(B) ? (A) : (B) )
/** Maximum of two values: */
#define MAX2( A, B ) ( (A)>(B) ? (A) : (B) )
/** Minimum and maximum of three values: */
#define MIN3( A, B, C ) ((A) < (B) ? MIN2(A, C) : MIN2(B, C))
#define MAX3( A, B, C ) ((A) > (B) ? MAX2(A, C) : MAX2(B, C))
/** Align a value to a power of two */
#define ALIGN_POT(x, pot_align) (((x) + (pot_align) - 1) & ~((pot_align) - 1))
/**
* Macro for declaring an explicit conversion operator. Defaults to an
* implicit conversion if C++11 is not supported.
*/
#if __cplusplus >= 201103L
#define EXPLICIT_CONVERSION explicit
#elif defined(__cplusplus)
#define EXPLICIT_CONVERSION
#endif
#endif /* UTIL_MACROS_H */

48
brcm/common/no_extern_c.h Normal file
View File

@ -0,0 +1,48 @@
/**************************************************************************
*
* Copyright 2014 VMware, Inc.
* 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.
*
**************************************************************************/
/*
* Including system's headers inside `extern "C" { ... }` is not safe, as system
* headers may have C++ code in them, and C++ code inside extern "C"
* leads to syntatically incorrect code.
*
* This is because putting code inside extern "C" won't make __cplusplus define
* go away, that is, the system header being included thinks is free to use C++
* as it sees fits.
*
* Including non-system headers inside extern "C" is not safe either, because
* non-system headers end up including system headers, hence fall in the above
* case too.
*
* Conclusion, includes inside extern "C" is simply not portable.
*
*
* This header helps surface these issues.
*/
#ifdef __cplusplus
template<class T> class _IncludeInsideExternCNotPortable;
#endif

895
brcm/common/ralloc.c Normal file
View File

@ -0,0 +1,895 @@
/*
* Copyright © 2010 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 "../../driver/CustomAssert.h"
#include <stdlib.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include <stdint.h>
/* Some versions of MinGW are missing _vscprintf's declaration, although they
* still provide the symbol in the import library. */
#ifdef __MINGW32__
_CRTIMP int _vscprintf(const char *format, va_list argptr);
#endif
#include "ralloc.h"
#ifndef va_copy
#ifdef __va_copy
#define va_copy(dest, src) __va_copy((dest), (src))
#else
#define va_copy(dest, src) (dest) = (src)
#endif
#endif
#define CANARY 0x5A1106
/* Align the header's size so that ralloc() allocations will return with the
* same alignment as a libc malloc would have (8 on 32-bit GLIBC, 16 on
* 64-bit), avoiding performance penalities on x86 and alignment faults on
* ARM.
*/
struct
#ifdef _MSC_VER
__declspec(align(8))
#elif defined(__LP64__)
__attribute__((aligned(16)))
#else
__attribute__((aligned(8)))
#endif
ralloc_header
{
#ifdef DEBUG
/* A canary value used to determine whether a pointer is ralloc'd. */
unsigned canary;
#endif
struct ralloc_header *parent;
/* The first child (head of a linked list) */
struct ralloc_header *child;
/* Linked list of siblings */
struct ralloc_header *prev;
struct ralloc_header *next;
void (*destructor)(void *);
};
typedef struct ralloc_header ralloc_header;
static void unlink_block(ralloc_header *info);
static void unsafe_free(ralloc_header *info);
static ralloc_header *
get_header(const void *ptr)
{
ralloc_header *info = (ralloc_header *) (((char *) ptr) -
sizeof(ralloc_header));
#ifdef DEBUG
assert(info->canary == CANARY);
#endif
return info;
}
#define PTR_FROM_HEADER(info) (((char *) info) + sizeof(ralloc_header))
static void
add_child(ralloc_header *parent, ralloc_header *info)
{
if (parent != NULL) {
info->parent = parent;
info->next = parent->child;
parent->child = info;
if (info->next != NULL)
info->next->prev = info;
}
}
void *
ralloc_context(const void *ctx)
{
return ralloc_size(ctx, 0);
}
void *
ralloc_size(const void *ctx, size_t size)
{
void *block = malloc(size + sizeof(ralloc_header));
ralloc_header *info;
ralloc_header *parent;
if (unlikely(block == NULL))
return NULL;
info = (ralloc_header *) block;
/* measurements have shown that calloc is slower (because of
* the multiplication overflow checking?), so clear things
* manually
*/
info->parent = NULL;
info->child = NULL;
info->prev = NULL;
info->next = NULL;
info->destructor = NULL;
parent = ctx != NULL ? get_header(ctx) : NULL;
add_child(parent, info);
#ifdef DEBUG
info->canary = CANARY;
#endif
return PTR_FROM_HEADER(info);
}
void *
rzalloc_size(const void *ctx, size_t size)
{
void *ptr = ralloc_size(ctx, size);
if (likely(ptr))
memset(ptr, 0, size);
return ptr;
}
/* helper function - assumes ptr != NULL */
static void *
resize(void *ptr, size_t size)
{
ralloc_header *child, *old, *info;
old = get_header(ptr);
info = realloc(old, size + sizeof(ralloc_header));
if (info == NULL)
return NULL;
/* Update parent and sibling's links to the reallocated node. */
if (info != old && info->parent != NULL) {
if (info->parent->child == old)
info->parent->child = info;
if (info->prev != NULL)
info->prev->next = info;
if (info->next != NULL)
info->next->prev = info;
}
/* Update child->parent links for all children */
for (child = info->child; child != NULL; child = child->next)
child->parent = info;
return PTR_FROM_HEADER(info);
}
void *
reralloc_size(const void *ctx, void *ptr, size_t size)
{
if (unlikely(ptr == NULL))
return ralloc_size(ctx, size);
assert(ralloc_parent(ptr) == ctx);
return resize(ptr, size);
}
void *
ralloc_array_size(const void *ctx, size_t size, unsigned count)
{
if (count > SIZE_MAX/size)
return NULL;
return ralloc_size(ctx, size * count);
}
void *
rzalloc_array_size(const void *ctx, size_t size, unsigned count)
{
if (count > SIZE_MAX/size)
return NULL;
return rzalloc_size(ctx, size * count);
}
void *
reralloc_array_size(const void *ctx, void *ptr, size_t size, unsigned count)
{
if (count > SIZE_MAX/size)
return NULL;
return reralloc_size(ctx, ptr, size * count);
}
void
ralloc_free(void *ptr)
{
ralloc_header *info;
if (ptr == NULL)
return;
info = get_header(ptr);
unlink_block(info);
unsafe_free(info);
}
static void
unlink_block(ralloc_header *info)
{
/* Unlink from parent & siblings */
if (info->parent != NULL) {
if (info->parent->child == info)
info->parent->child = info->next;
if (info->prev != NULL)
info->prev->next = info->next;
if (info->next != NULL)
info->next->prev = info->prev;
}
info->parent = NULL;
info->prev = NULL;
info->next = NULL;
}
static void
unsafe_free(ralloc_header *info)
{
/* Recursively free any children...don't waste time unlinking them. */
ralloc_header *temp;
while (info->child != NULL) {
temp = info->child;
info->child = temp->next;
unsafe_free(temp);
}
/* Free the block itself. Call the destructor first, if any. */
if (info->destructor != NULL)
info->destructor(PTR_FROM_HEADER(info));
free(info);
}
void
ralloc_steal(const void *new_ctx, void *ptr)
{
ralloc_header *info, *parent;
if (unlikely(ptr == NULL))
return;
info = get_header(ptr);
parent = new_ctx ? get_header(new_ctx) : NULL;
unlink_block(info);
add_child(parent, info);
}
void
ralloc_adopt(const void *new_ctx, void *old_ctx)
{
ralloc_header *new_info, *old_info, *child;
if (unlikely(old_ctx == NULL))
return;
old_info = get_header(old_ctx);
new_info = get_header(new_ctx);
/* If there are no children, bail. */
if (unlikely(old_info->child == NULL))
return;
/* Set all the children's parent to new_ctx; get a pointer to the last child. */
for (child = old_info->child; child->next != NULL; child = child->next) {
child->parent = new_info;
}
child->parent = new_info;
/* Connect the two lists together; parent them to new_ctx; make old_ctx empty. */
child->next = new_info->child;
if (child->next)
child->next->prev = child;
new_info->child = old_info->child;
old_info->child = NULL;
}
void *
ralloc_parent(const void *ptr)
{
ralloc_header *info;
if (unlikely(ptr == NULL))
return NULL;
info = get_header(ptr);
return info->parent ? PTR_FROM_HEADER(info->parent) : NULL;
}
void
ralloc_set_destructor(const void *ptr, void(*destructor)(void *))
{
ralloc_header *info = get_header(ptr);
info->destructor = destructor;
}
char *
ralloc_strdup(const void *ctx, const char *str)
{
size_t n;
char *ptr;
if (unlikely(str == NULL))
return NULL;
n = strlen(str);
ptr = ralloc_array(ctx, char, n + 1);
memcpy(ptr, str, n);
ptr[n] = '\0';
return ptr;
}
char *
ralloc_strndup(const void *ctx, const char *str, size_t max)
{
size_t n;
char *ptr;
if (unlikely(str == NULL))
return NULL;
n = strnlen(str, max);
ptr = ralloc_array(ctx, char, n + 1);
memcpy(ptr, str, n);
ptr[n] = '\0';
return ptr;
}
/* helper routine for strcat/strncat - n is the exact amount to copy */
static bool
cat(char **dest, const char *str, size_t n)
{
char *both;
size_t existing_length;
assert(dest != NULL && *dest != NULL);
existing_length = strlen(*dest);
both = resize(*dest, existing_length + n + 1);
if (unlikely(both == NULL))
return false;
memcpy(both + existing_length, str, n);
both[existing_length + n] = '\0';
*dest = both;
return true;
}
bool
ralloc_strcat(char **dest, const char *str)
{
return cat(dest, str, strlen(str));
}
bool
ralloc_strncat(char **dest, const char *str, size_t n)
{
return cat(dest, str, strnlen(str, n));
}
bool
ralloc_str_append(char **dest, const char *str,
size_t existing_length, size_t str_size)
{
char *both;
assert(dest != NULL && *dest != NULL);
both = resize(*dest, existing_length + str_size + 1);
if (unlikely(both == NULL))
return false;
memcpy(both + existing_length, str, str_size);
both[existing_length + str_size] = '\0';
*dest = both;
return true;
}
char *
ralloc_asprintf(const void *ctx, const char *fmt, ...)
{
char *ptr;
va_list args;
va_start(args, fmt);
ptr = ralloc_vasprintf(ctx, fmt, args);
va_end(args);
return ptr;
}
/* Return the length of the string that would be generated by a printf-style
* format and argument list, not including the \0 byte.
*/
static size_t
printf_length(const char *fmt, va_list untouched_args)
{
int size;
char junk;
/* Make a copy of the va_list so the original caller can still use it */
va_list args;
va_copy(args, untouched_args);
#ifdef _WIN32
/* We need to use _vcsprintf to calculate the size as vsnprintf returns -1
* if the number of characters to write is greater than count.
*/
size = _vscprintf(fmt, args);
(void)junk;
#else
size = vsnprintf(&junk, 1, fmt, args);
#endif
assert(size >= 0);
va_end(args);
return size;
}
char *
ralloc_vasprintf(const void *ctx, const char *fmt, va_list args)
{
size_t size = printf_length(fmt, args) + 1;
char *ptr = ralloc_size(ctx, size);
if (ptr != NULL)
vsnprintf(ptr, size, fmt, args);
return ptr;
}
bool
ralloc_asprintf_append(char **str, const char *fmt, ...)
{
bool success;
va_list args;
va_start(args, fmt);
success = ralloc_vasprintf_append(str, fmt, args);
va_end(args);
return success;
}
bool
ralloc_vasprintf_append(char **str, const char *fmt, va_list args)
{
size_t existing_length;
assert(str != NULL);
existing_length = *str ? strlen(*str) : 0;
return ralloc_vasprintf_rewrite_tail(str, &existing_length, fmt, args);
}
bool
ralloc_asprintf_rewrite_tail(char **str, size_t *start, const char *fmt, ...)
{
bool success;
va_list args;
va_start(args, fmt);
success = ralloc_vasprintf_rewrite_tail(str, start, fmt, args);
va_end(args);
return success;
}
bool
ralloc_vasprintf_rewrite_tail(char **str, size_t *start, const char *fmt,
va_list args)
{
size_t new_length;
char *ptr;
assert(str != NULL);
if (unlikely(*str == NULL)) {
// Assuming a NULL context is probably bad, but it's expected behavior.
*str = ralloc_vasprintf(NULL, fmt, args);
*start = strlen(*str);
return true;
}
new_length = printf_length(fmt, args);
ptr = resize(*str, *start + new_length + 1);
if (unlikely(ptr == NULL))
return false;
vsnprintf(ptr + *start, new_length + 1, fmt, args);
*str = ptr;
*start += new_length;
return true;
}
/***************************************************************************
* Linear allocator for short-lived allocations.
***************************************************************************
*
* The allocator consists of a parent node (2K buffer), which requires
* a ralloc parent, and child nodes (allocations). Child nodes can't be freed
* directly, because the parent doesn't track them. You have to release
* the parent node in order to release all its children.
*
* The allocator uses a fixed-sized buffer with a monotonically increasing
* offset after each allocation. If the buffer is all used, another buffer
* is allocated, sharing the same ralloc parent, so all buffers are at
* the same level in the ralloc hierarchy.
*
* The linear parent node is always the first buffer and keeps track of all
* other buffers.
*/
#define MIN_LINEAR_BUFSIZE 2048
#define SUBALLOC_ALIGNMENT sizeof(uintptr_t)
#define LMAGIC 0x87b9c7d3
struct linear_header {
#ifdef DEBUG
unsigned magic; /* for debugging */
#endif
unsigned offset; /* points to the first unused byte in the buffer */
unsigned size; /* size of the buffer */
void *ralloc_parent; /* new buffers will use this */
struct linear_header *next; /* next buffer if we have more */
struct linear_header *latest; /* the only buffer that has free space */
/* After this structure, the buffer begins.
* Each suballocation consists of linear_size_chunk as its header followed
* by the suballocation, so it goes:
*
* - linear_size_chunk
* - allocated space
* - linear_size_chunk
* - allocated space
* etc.
*
* linear_size_chunk is only needed by linear_realloc.
*/
};
struct linear_size_chunk {
unsigned size; /* for realloc */
unsigned _padding;
};
typedef struct linear_header linear_header;
typedef struct linear_size_chunk linear_size_chunk;
#define LINEAR_PARENT_TO_HEADER(parent) \
(linear_header*) \
((char*)(parent) - sizeof(linear_size_chunk) - sizeof(linear_header))
/* Allocate the linear buffer with its header. */
static linear_header *
create_linear_node(void *ralloc_ctx, unsigned min_size)
{
linear_header *node;
min_size += sizeof(linear_size_chunk);
if (likely(min_size < MIN_LINEAR_BUFSIZE))
min_size = MIN_LINEAR_BUFSIZE;
node = ralloc_size(ralloc_ctx, sizeof(linear_header) + min_size);
if (unlikely(!node))
return NULL;
#ifdef DEBUG
node->magic = LMAGIC;
#endif
node->offset = 0;
node->size = min_size;
node->ralloc_parent = ralloc_ctx;
node->next = NULL;
node->latest = node;
return node;
}
void *
linear_alloc_child(void *parent, unsigned size)
{
linear_header *first = LINEAR_PARENT_TO_HEADER(parent);
linear_header *latest = first->latest;
linear_header *new_node;
linear_size_chunk *ptr;
unsigned full_size;
#ifdef DEBUG
assert(first->magic == LMAGIC);
#endif
assert(!latest->next);
size = ALIGN_POT(size, SUBALLOC_ALIGNMENT);
full_size = sizeof(linear_size_chunk) + size;
if (unlikely(latest->offset + full_size > latest->size)) {
/* allocate a new node */
new_node = create_linear_node(latest->ralloc_parent, size);
if (unlikely(!new_node))
return NULL;
first->latest = new_node;
latest->latest = new_node;
latest->next = new_node;
latest = new_node;
}
ptr = (linear_size_chunk *)((char*)&latest[1] + latest->offset);
ptr->size = size;
latest->offset += full_size;
return &ptr[1];
}
void *
linear_alloc_parent(void *ralloc_ctx, unsigned size)
{
linear_header *node;
if (unlikely(!ralloc_ctx))
return NULL;
size = ALIGN_POT(size, SUBALLOC_ALIGNMENT);
node = create_linear_node(ralloc_ctx, size);
if (unlikely(!node))
return NULL;
return linear_alloc_child((char*)node +
sizeof(linear_header) +
sizeof(linear_size_chunk), size);
}
void *
linear_zalloc_child(void *parent, unsigned size)
{
void *ptr = linear_alloc_child(parent, size);
if (likely(ptr))
memset(ptr, 0, size);
return ptr;
}
void *
linear_zalloc_parent(void *parent, unsigned size)
{
void *ptr = linear_alloc_parent(parent, size);
if (likely(ptr))
memset(ptr, 0, size);
return ptr;
}
void
linear_free_parent(void *ptr)
{
linear_header *node;
if (unlikely(!ptr))
return;
node = LINEAR_PARENT_TO_HEADER(ptr);
#ifdef DEBUG
assert(node->magic == LMAGIC);
#endif
while (node) {
void *ptr = node;
node = node->next;
ralloc_free(ptr);
}
}
void
ralloc_steal_linear_parent(void *new_ralloc_ctx, void *ptr)
{
linear_header *node;
if (unlikely(!ptr))
return;
node = LINEAR_PARENT_TO_HEADER(ptr);
#ifdef DEBUG
assert(node->magic == LMAGIC);
#endif
while (node) {
ralloc_steal(new_ralloc_ctx, node);
node->ralloc_parent = new_ralloc_ctx;
node = node->next;
}
}
void *
ralloc_parent_of_linear_parent(void *ptr)
{
linear_header *node = LINEAR_PARENT_TO_HEADER(ptr);
#ifdef DEBUG
assert(node->magic == LMAGIC);
#endif
return node->ralloc_parent;
}
void *
linear_realloc(void *parent, void *old, unsigned new_size)
{
unsigned old_size = 0;
ralloc_header *new_ptr;
new_ptr = linear_alloc_child(parent, new_size);
if (unlikely(!old))
return new_ptr;
old_size = ((linear_size_chunk*)old)[-1].size;
if (likely(new_ptr && old_size))
memcpy(new_ptr, old, MIN2(old_size, new_size));
return new_ptr;
}
/* All code below is pretty much copied from ralloc and only the alloc
* calls are different.
*/
char *
linear_strdup(void *parent, const char *str)
{
unsigned n;
char *ptr;
if (unlikely(!str))
return NULL;
n = strlen(str);
ptr = linear_alloc_child(parent, n + 1);
if (unlikely(!ptr))
return NULL;
memcpy(ptr, str, n);
ptr[n] = '\0';
return ptr;
}
char *
linear_asprintf(void *parent, const char *fmt, ...)
{
char *ptr;
va_list args;
va_start(args, fmt);
ptr = linear_vasprintf(parent, fmt, args);
va_end(args);
return ptr;
}
char *
linear_vasprintf(void *parent, const char *fmt, va_list args)
{
unsigned size = printf_length(fmt, args) + 1;
char *ptr = linear_alloc_child(parent, size);
if (ptr != NULL)
vsnprintf(ptr, size, fmt, args);
return ptr;
}
bool
linear_asprintf_append(void *parent, char **str, const char *fmt, ...)
{
bool success;
va_list args;
va_start(args, fmt);
success = linear_vasprintf_append(parent, str, fmt, args);
va_end(args);
return success;
}
bool
linear_vasprintf_append(void *parent, char **str, const char *fmt, va_list args)
{
size_t existing_length;
assert(str != NULL);
existing_length = *str ? strlen(*str) : 0;
return linear_vasprintf_rewrite_tail(parent, str, &existing_length, fmt, args);
}
bool
linear_asprintf_rewrite_tail(void *parent, char **str, size_t *start,
const char *fmt, ...)
{
bool success;
va_list args;
va_start(args, fmt);
success = linear_vasprintf_rewrite_tail(parent, str, start, fmt, args);
va_end(args);
return success;
}
bool
linear_vasprintf_rewrite_tail(void *parent, char **str, size_t *start,
const char *fmt, va_list args)
{
size_t new_length;
char *ptr;
assert(str != NULL);
if (unlikely(*str == NULL)) {
*str = linear_vasprintf(parent, fmt, args);
*start = strlen(*str);
return true;
}
new_length = printf_length(fmt, args);
ptr = linear_realloc(parent, *str, *start + new_length + 1);
if (unlikely(ptr == NULL))
return false;
vsnprintf(ptr + *start, new_length + 1, fmt, args);
*str = ptr;
*start += new_length;
return true;
}
/* helper routine for strcat/strncat - n is the exact amount to copy */
static bool
linear_cat(void *parent, char **dest, const char *str, unsigned n)
{
char *both;
unsigned existing_length;
assert(dest != NULL && *dest != NULL);
existing_length = strlen(*dest);
both = linear_realloc(parent, *dest, existing_length + n + 1);
if (unlikely(both == NULL))
return false;
memcpy(both + existing_length, str, n);
both[existing_length + n] = '\0';
*dest = both;
return true;
}
bool
linear_strcat(void *parent, char **dest, const char *str)
{
return linear_cat(parent, dest, str, strlen(str));
}

542
brcm/common/ralloc.h Normal file
View File

@ -0,0 +1,542 @@
/*
* Copyright © 2010 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.
*/
/**
* \file ralloc.h
*
* ralloc: a recursive memory allocator
*
* The ralloc memory allocator creates a hierarchy of allocated
* objects. Every allocation is in reference to some parent, and
* every allocated object can in turn be used as the parent of a
* subsequent allocation. This allows for extremely convenient
* discarding of an entire tree/sub-tree of allocations by calling
* ralloc_free on any particular object to free it and all of its
* children.
*
* The conceptual working of ralloc was directly inspired by Andrew
* Tridgell's talloc, but ralloc is an independent implementation
* released under the MIT license and tuned for Mesa.
*
* talloc is more sophisticated than ralloc in that it includes reference
* counting and useful debugging features. However, it is released under
* a non-permissive open source license.
*/
#ifndef RALLOC_H
#define RALLOC_H
#include <stddef.h>
#include <stdarg.h>
#include <stdbool.h>
#include "macros.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* \def ralloc(ctx, type)
* Allocate a new object chained off of the given context.
*
* This is equivalent to:
* \code
* ((type *) ralloc_size(ctx, sizeof(type))
* \endcode
*/
#define ralloc(ctx, type) ((type *) ralloc_size(ctx, sizeof(type)))
/**
* \def rzalloc(ctx, type)
* Allocate a new object out of the given context and initialize it to zero.
*
* This is equivalent to:
* \code
* ((type *) rzalloc_size(ctx, sizeof(type))
* \endcode
*/
#define rzalloc(ctx, type) ((type *) rzalloc_size(ctx, sizeof(type)))
/**
* Allocate a new ralloc context.
*
* While any ralloc'd pointer can be used as a context, sometimes it is useful
* to simply allocate a context with no associated memory.
*
* It is equivalent to:
* \code
* ((type *) ralloc_size(ctx, 0)
* \endcode
*/
void *ralloc_context(const void *ctx);
/**
* Allocate memory chained off of the given context.
*
* This is the core allocation routine which is used by all others. It
* simply allocates storage for \p size bytes and returns the pointer,
* similar to \c malloc.
*/
void *ralloc_size(const void *ctx, size_t size) MALLOCLIKE;
/**
* Allocate zero-initialized memory chained off of the given context.
*
* This is similar to \c calloc with a size of 1.
*/
void *rzalloc_size(const void *ctx, size_t size) MALLOCLIKE;
/**
* Resize a piece of ralloc-managed memory, preserving data.
*
* Similar to \c realloc. Unlike C89, passing 0 for \p size does not free the
* memory. Instead, it resizes it to a 0-byte ralloc context, just like
* calling ralloc_size(ctx, 0). This is different from talloc.
*
* \param ctx The context to use for new allocation. If \p ptr != NULL,
* it must be the same as ralloc_parent(\p ptr).
* \param ptr Pointer to the memory to be resized. May be NULL.
* \param size The amount of memory to allocate, in bytes.
*/
void *reralloc_size(const void *ctx, void *ptr, size_t size);
/// \defgroup array Array Allocators @{
/**
* \def ralloc_array(ctx, type, count)
* Allocate an array of objects chained off the given context.
*
* Similar to \c calloc, but does not initialize the memory to zero.
*
* More than a convenience function, this also checks for integer overflow when
* multiplying \c sizeof(type) and \p count. This is necessary for security.
*
* This is equivalent to:
* \code
* ((type *) ralloc_array_size(ctx, sizeof(type), count)
* \endcode
*/
#define ralloc_array(ctx, type, count) \
((type *) ralloc_array_size(ctx, sizeof(type), count))
/**
* \def rzalloc_array(ctx, type, count)
* Allocate a zero-initialized array chained off the given context.
*
* Similar to \c calloc.
*
* More than a convenience function, this also checks for integer overflow when
* multiplying \c sizeof(type) and \p count. This is necessary for security.
*
* This is equivalent to:
* \code
* ((type *) rzalloc_array_size(ctx, sizeof(type), count)
* \endcode
*/
#define rzalloc_array(ctx, type, count) \
((type *) rzalloc_array_size(ctx, sizeof(type), count))
/**
* \def reralloc(ctx, ptr, type, count)
* Resize a ralloc-managed array, preserving data.
*
* Similar to \c realloc. Unlike C89, passing 0 for \p size does not free the
* memory. Instead, it resizes it to a 0-byte ralloc context, just like
* calling ralloc_size(ctx, 0). This is different from talloc.
*
* More than a convenience function, this also checks for integer overflow when
* multiplying \c sizeof(type) and \p count. This is necessary for security.
*
* \param ctx The context to use for new allocation. If \p ptr != NULL,
* it must be the same as ralloc_parent(\p ptr).
* \param ptr Pointer to the array to be resized. May be NULL.
* \param type The element type.
* \param count The number of elements to allocate.
*/
#define reralloc(ctx, ptr, type, count) \
((type *) reralloc_array_size(ctx, ptr, sizeof(type), count))
/**
* Allocate memory for an array chained off the given context.
*
* Similar to \c calloc, but does not initialize the memory to zero.
*
* More than a convenience function, this also checks for integer overflow when
* multiplying \p size and \p count. This is necessary for security.
*/
void *ralloc_array_size(const void *ctx, size_t size, unsigned count) MALLOCLIKE;
/**
* Allocate a zero-initialized array chained off the given context.
*
* Similar to \c calloc.
*
* More than a convenience function, this also checks for integer overflow when
* multiplying \p size and \p count. This is necessary for security.
*/
void *rzalloc_array_size(const void *ctx, size_t size, unsigned count) MALLOCLIKE;
/**
* Resize a ralloc-managed array, preserving data.
*
* Similar to \c realloc. Unlike C89, passing 0 for \p size does not free the
* memory. Instead, it resizes it to a 0-byte ralloc context, just like
* calling ralloc_size(ctx, 0). This is different from talloc.
*
* More than a convenience function, this also checks for integer overflow when
* multiplying \c sizeof(type) and \p count. This is necessary for security.
*
* \param ctx The context to use for new allocation. If \p ptr != NULL,
* it must be the same as ralloc_parent(\p ptr).
* \param ptr Pointer to the array to be resized. May be NULL.
* \param size The size of an individual element.
* \param count The number of elements to allocate.
*
* \return True unless allocation failed.
*/
void *reralloc_array_size(const void *ctx, void *ptr, size_t size,
unsigned count);
/// @}
/**
* Free a piece of ralloc-managed memory.
*
* This will also free the memory of any children allocated this context.
*/
void ralloc_free(void *ptr);
/**
* "Steal" memory from one context, changing it to another.
*
* This changes \p ptr's context to \p new_ctx. This is quite useful if
* memory is allocated out of a temporary context.
*/
void ralloc_steal(const void *new_ctx, void *ptr);
/**
* Reparent all children from one context to another.
*
* This effectively calls ralloc_steal(new_ctx, child) for all children of \p old_ctx.
*/
void ralloc_adopt(const void *new_ctx, void *old_ctx);
/**
* Return the given pointer's ralloc context.
*/
void *ralloc_parent(const void *ptr);
/**
* Set a callback to occur just before an object is freed.
*/
void ralloc_set_destructor(const void *ptr, void(*destructor)(void *));
/// \defgroup array String Functions @{
/**
* Duplicate a string, allocating the memory from the given context.
*/
char *ralloc_strdup(const void *ctx, const char *str) MALLOCLIKE;
/**
* Duplicate a string, allocating the memory from the given context.
*
* Like \c strndup, at most \p n characters are copied. If \p str is longer
* than \p n characters, \p n are copied, and a termining \c '\0' byte is added.
*/
char *ralloc_strndup(const void *ctx, const char *str, size_t n) MALLOCLIKE;
/**
* Concatenate two strings, allocating the necessary space.
*
* This appends \p str to \p *dest, similar to \c strcat, using ralloc_resize
* to expand \p *dest to the appropriate size. \p dest will be updated to the
* new pointer unless allocation fails.
*
* The result will always be null-terminated.
*
* \return True unless allocation failed.
*/
bool ralloc_strcat(char **dest, const char *str);
/**
* Concatenate two strings, allocating the necessary space.
*
* This appends at most \p n bytes of \p str to \p *dest, using ralloc_resize
* to expand \p *dest to the appropriate size. \p dest will be updated to the
* new pointer unless allocation fails.
*
* The result will always be null-terminated; \p str does not need to be null
* terminated if it is longer than \p n.
*
* \return True unless allocation failed.
*/
bool ralloc_strncat(char **dest, const char *str, size_t n);
/**
* Concatenate two strings, allocating the necessary space.
*
* This appends \p n bytes of \p str to \p *dest, using ralloc_resize
* to expand \p *dest to the appropriate size. \p dest will be updated to the
* new pointer unless allocation fails.
*
* The result will always be null-terminated.
*
* This function differs from ralloc_strcat() and ralloc_strncat() in that it
* does not do any strlen() calls which can become costly on large strings.
*
* \return True unless allocation failed.
*/
bool
ralloc_str_append(char **dest, const char *str,
size_t existing_length, size_t str_size);
/**
* Print to a string.
*
* This is analogous to \c sprintf, but allocates enough space (using \p ctx
* as the context) for the resulting string.
*
* \return The newly allocated string.
*/
char *ralloc_asprintf (const void *ctx, const char *fmt, ...) PRINTFLIKE(2, 3) MALLOCLIKE;
/**
* Print to a string, given a va_list.
*
* This is analogous to \c vsprintf, but allocates enough space (using \p ctx
* as the context) for the resulting string.
*
* \return The newly allocated string.
*/
char *ralloc_vasprintf(const void *ctx, const char *fmt, va_list args) MALLOCLIKE;
/**
* Rewrite the tail of an existing string, starting at a given index.
*
* Overwrites the contents of *str starting at \p start with newly formatted
* text, including a new null-terminator. Allocates more memory as necessary.
*
* This can be used to append formatted text when the length of the existing
* string is already known, saving a strlen() call.
*
* \sa ralloc_asprintf_append
*
* \param str The string to be updated.
* \param start The index to start appending new data at.
* \param fmt A printf-style formatting string
*
* \p str will be updated to the new pointer unless allocation fails.
* \p start will be increased by the length of the newly formatted text.
*
* \return True unless allocation failed.
*/
bool ralloc_asprintf_rewrite_tail(char **str, size_t *start,
const char *fmt, ...)
PRINTFLIKE(3, 4);
/**
* Rewrite the tail of an existing string, starting at a given index.
*
* Overwrites the contents of *str starting at \p start with newly formatted
* text, including a new null-terminator. Allocates more memory as necessary.
*
* This can be used to append formatted text when the length of the existing
* string is already known, saving a strlen() call.
*
* \sa ralloc_vasprintf_append
*
* \param str The string to be updated.
* \param start The index to start appending new data at.
* \param fmt A printf-style formatting string
* \param args A va_list containing the data to be formatted
*
* \p str will be updated to the new pointer unless allocation fails.
* \p start will be increased by the length of the newly formatted text.
*
* \return True unless allocation failed.
*/
bool ralloc_vasprintf_rewrite_tail(char **str, size_t *start, const char *fmt,
va_list args);
/**
* Append formatted text to the supplied string.
*
* This is equivalent to
* \code
* ralloc_asprintf_rewrite_tail(str, strlen(*str), fmt, ...)
* \endcode
*
* \sa ralloc_asprintf
* \sa ralloc_asprintf_rewrite_tail
* \sa ralloc_strcat
*
* \p str will be updated to the new pointer unless allocation fails.
*
* \return True unless allocation failed.
*/
bool ralloc_asprintf_append (char **str, const char *fmt, ...)
PRINTFLIKE(2, 3);
/**
* Append formatted text to the supplied string, given a va_list.
*
* This is equivalent to
* \code
* ralloc_vasprintf_rewrite_tail(str, strlen(*str), fmt, args)
* \endcode
*
* \sa ralloc_vasprintf
* \sa ralloc_vasprintf_rewrite_tail
* \sa ralloc_strcat
*
* \p str will be updated to the new pointer unless allocation fails.
*
* \return True unless allocation failed.
*/
bool ralloc_vasprintf_append(char **str, const char *fmt, va_list args);
/// @}
/**
* Declare C++ new and delete operators which use ralloc.
*
* Placing this macro in the body of a class makes it possible to do:
*
* TYPE *var = new(mem_ctx) TYPE(...);
* delete var;
*
* which is more idiomatic in C++ than calling ralloc.
*/
#define DECLARE_ALLOC_CXX_OPERATORS_TEMPLATE(TYPE, ALLOC_FUNC) \
private: \
static void _ralloc_destructor(void *p) \
{ \
reinterpret_cast<TYPE *>(p)->~TYPE(); \
} \
public: \
static void* operator new(size_t size, void *mem_ctx) \
{ \
void *p = ALLOC_FUNC(mem_ctx, size); \
assert(p != NULL); \
if (!HAS_TRIVIAL_DESTRUCTOR(TYPE)) \
ralloc_set_destructor(p, _ralloc_destructor); \
return p; \
} \
\
static void operator delete(void *p) \
{ \
/* The object's destructor is guaranteed to have already been \
* called by the delete operator at this point -- Make sure it's \
* not called again. \
*/ \
if (!HAS_TRIVIAL_DESTRUCTOR(TYPE)) \
ralloc_set_destructor(p, NULL); \
ralloc_free(p); \
}
#define DECLARE_RALLOC_CXX_OPERATORS(type) \
DECLARE_ALLOC_CXX_OPERATORS_TEMPLATE(type, ralloc_size)
#define DECLARE_RZALLOC_CXX_OPERATORS(type) \
DECLARE_ALLOC_CXX_OPERATORS_TEMPLATE(type, rzalloc_size)
#define DECLARE_LINEAR_ALLOC_CXX_OPERATORS(type) \
DECLARE_ALLOC_CXX_OPERATORS_TEMPLATE(type, linear_alloc_child)
#define DECLARE_LINEAR_ZALLOC_CXX_OPERATORS(type) \
DECLARE_ALLOC_CXX_OPERATORS_TEMPLATE(type, linear_zalloc_child)
/**
* Do a fast allocation from the linear buffer, also known as the child node
* from the allocator's point of view. It can't be freed directly. You have
* to free the parent or the ralloc parent.
*
* \param parent parent node of the linear allocator
* \param size size to allocate (max 32 bits)
*/
void *linear_alloc_child(void *parent, unsigned size);
/**
* Allocate a parent node that will hold linear buffers. The returned
* allocation is actually the first child node, but it's also the handle
* of the parent node. Use it for all child node allocations.
*
* \param ralloc_ctx ralloc context, must not be NULL
* \param size size to allocate (max 32 bits)
*/
void *linear_alloc_parent(void *ralloc_ctx, unsigned size);
/**
* Same as linear_alloc_child, but also clears memory.
*/
void *linear_zalloc_child(void *parent, unsigned size);
/**
* Same as linear_alloc_parent, but also clears memory.
*/
void *linear_zalloc_parent(void *ralloc_ctx, unsigned size);
/**
* Free the linear parent node. This will free all child nodes too.
* Freeing the ralloc parent will also free this.
*/
void linear_free_parent(void *ptr);
/**
* Same as ralloc_steal, but steals the linear parent node.
*/
void ralloc_steal_linear_parent(void *new_ralloc_ctx, void *ptr);
/**
* Return the ralloc parent of the linear parent node.
*/
void *ralloc_parent_of_linear_parent(void *ptr);
/**
* Same as realloc except that the linear allocator doesn't free child nodes,
* so it's reduced to memory duplication. It's used in places where
* reallocation is required. Don't use it often. It's much slower than
* realloc.
*/
void *linear_realloc(void *parent, void *old, unsigned new_size);
/* The functions below have the same semantics as their ralloc counterparts,
* except that they always allocate a linear child node.
*/
char *linear_strdup(void *parent, const char *str);
char *linear_asprintf(void *parent, const char *fmt, ...);
char *linear_vasprintf(void *parent, const char *fmt, va_list args);
bool linear_asprintf_append(void *parent, char **str, const char *fmt, ...);
bool linear_vasprintf_append(void *parent, char **str, const char *fmt,
va_list args);
bool linear_asprintf_rewrite_tail(void *parent, char **str, size_t *start,
const char *fmt, ...);
bool linear_vasprintf_rewrite_tail(void *parent, char **str, size_t *start,
const char *fmt, va_list args);
bool linear_strcat(void *parent, char **dest, const char *str);
#ifdef __cplusplus
} /* end of extern "C" */
#endif
#endif

View File

@ -0,0 +1,40 @@
/*
* 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_CHIP_H
#define V3D_CHIP_H
#include <stdint.h>
/**
* Struct for tracking features of the V3D chip across driver and compiler.
*/
struct v3d_device_info {
/** Simple V3D version: major * 10 + minor */
uint8_t ver;
/** Size of the VPM, in bytes. */
int vpm_size;
};
#endif

48
brcm/common/v3d_macros.h Normal file
View File

@ -0,0 +1,48 @@
/*
* Copyright © 2015 Intel Corporation
* 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.
*/
#ifndef V3DX_MACROS_H
#define V3DX_MACROS_H
#ifndef V3D_VERSION
# error "The V3D_VERSION macro must be defined"
#endif
#if (V3D_VERSION == 21)
# define V3DX(x) V3D21_##x
# define v3dX(x) v3d21_##x
#elif (V3D_VERSION == 33)
# define V3DX(x) V3D33_##x
# define v3dX(x) v3d33_##x
#elif (V3D_VERSION == 41)
# define V3DX(x) V3D41_##x
# define v3dX(x) v3d41_##x
#elif (V3D_VERSION == 42)
# define V3DX(x) V3D42_##x
# define v3dX(x) v3d42_##x
#else
# error "Need to add prefixing macros for this v3d version"
#endif
#endif /* V3DX_MACROS_H */

358
brcm/qpu/qpu_disasm.c Normal file
View File

@ -0,0 +1,358 @@
/*
* 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 <stdarg.h>
#include "../common/ralloc.h"
#include "../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) {
if (instr->sig.small_imm) {
uint32_t val;
/*MAYBE_UNUSED*/ bool ok =
v3d_qpu_small_imm_unpack(disasm->devinfo,
instr->raddr_b,
&val);
if ((int)val >= -16 && (int)val <= 15)
append(disasm, "%d", val);
else
append(disasm, "0x%08x", val);
assert(ok);
} else {
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));
if (!v3d_qpu_sig_writes_address(disasm->devinfo, &instr->sig))
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));
if (!v3d_qpu_sig_writes_address(disasm->devinfo, &instr->sig))
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_addr(struct disasm_state *disasm,
const struct v3d_qpu_instr *instr)
{
if (disasm->devinfo->ver < 41)
return;
if (!instr->sig_magic)
append(disasm, ".rf%d", instr->sig_addr);
else {
const char *name = v3d_qpu_magic_waddr_name(instr->sig_addr);
if (name)
append(disasm, ".%s", name);
else
append(disasm, ".UNKNOWN%d", instr->sig_addr);
}
}
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->ldunifrf &&
!sig->ldunifa &&
!sig->ldunifarf &&
!sig->wrtmuc) {
return;
}
pad_to(disasm, 41);
if (sig->thrsw)
append(disasm, "; thrsw");
if (sig->ldvary) {
append(disasm, "; ldvary");
v3d_qpu_disasm_sig_addr(disasm, instr);
}
if (sig->ldvpm)
append(disasm, "; ldvpm");
if (sig->ldtmu) {
append(disasm, "; ldtmu");
v3d_qpu_disasm_sig_addr(disasm, instr);
}
if (sig->ldtlb) {
append(disasm, "; ldtlb");
v3d_qpu_disasm_sig_addr(disasm, instr);
}
if (sig->ldtlbu) {
append(disasm, "; ldtlbu");
v3d_qpu_disasm_sig_addr(disasm, instr);
}
if (sig->ldunif)
append(disasm, "; ldunif");
if (sig->ldunifrf) {
append(disasm, "; ldunifrf");
v3d_qpu_disasm_sig_addr(disasm, instr);
}
if (sig->ldunifa)
append(disasm, "; ldunifa");
if (sig->ldunifarf) {
append(disasm, "; ldunifarf");
v3d_qpu_disasm_sig_addr(disasm, instr);
}
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);
}

39
brcm/qpu/qpu_disasm.h Normal file
View File

@ -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 "../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 */

796
brcm/qpu/qpu_instr.c Normal file
View File

@ -0,0 +1,796 @@
/*
* 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 "../common/macros.h"
#include "../common/v3d_device_info.h"
#include "qpu_instr.h"
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_SYNCB] = "syncb",
[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",
[V3D_QPU_WADDR_TMUC] = "tmuc",
[V3D_QPU_WADDR_TMUS] = "tmus",
[V3D_QPU_WADDR_TMUT] = "tmut",
[V3D_QPU_WADDR_TMUR] = "tmur",
[V3D_QPU_WADDR_TMUI] = "tmui",
[V3D_QPU_WADDR_TMUB] = "tmub",
[V3D_QPU_WADDR_TMUDREF] = "tmudref",
[V3D_QPU_WADDR_TMUOFF] = "tmuoff",
[V3D_QPU_WADDR_TMUSCM] = "tmuscm",
[V3D_QPU_WADDR_TMUSF] = "tmusf",
[V3D_QPU_WADDR_TMUSLOD] = "tmuslod",
[V3D_QPU_WADDR_TMUHS] = "tmuhs",
[V3D_QPU_WADDR_TMUHSCM] = "tmuscm",
[V3D_QPU_WADDR_TMUHSF] = "tmuhsf",
[V3D_QPU_WADDR_TMUHSLOD] = "tmuhslod",
[V3D_QPU_WADDR_R5REP] = "r5rep",
};
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_FLPOP] = "flpop",
[V3D_QPU_A_RECIP] = "recip",
[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_BARRIERID] = "barrierid",
[V3D_QPU_A_TMUWT] = "tmuwt",
[V3D_QPU_A_VPMSETUP] = "vpmsetup",
[V3D_QPU_A_VPMWT] = "vpmwt",
[V3D_QPU_A_LDVPMV_IN] = "ldvpmv_in",
[V3D_QPU_A_LDVPMV_OUT] = "ldvpmv_out",
[V3D_QPU_A_LDVPMD_IN] = "ldvpmd_in",
[V3D_QPU_A_LDVPMD_OUT] = "ldvpmd_out",
[V3D_QPU_A_LDVPMP] = "ldvpmp",
[V3D_QPU_A_RSQRT] = "rsqrt",
[V3D_QPU_A_EXP] = "exp",
[V3D_QPU_A_LOG] = "log",
[V3D_QPU_A_SIN] = "sin",
[V3D_QPU_A_RSQRT2] = "rsqrt2",
[V3D_QPU_A_LDVPMG_IN] = "ldvpmg_in",
[V3D_QPU_A_LDVPMG_OUT] = "ldvpmg_out",
[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_FLPOP] = D | A,
[V3D_QPU_A_RECIP] = 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_BARRIERID] = D,
[V3D_QPU_A_TMUWT] = D,
[V3D_QPU_A_VPMWT] = D,
[V3D_QPU_A_VPMSETUP] = D | A,
[V3D_QPU_A_LDVPMV_IN] = D | A,
[V3D_QPU_A_LDVPMV_OUT] = D | A,
[V3D_QPU_A_LDVPMD_IN] = D | A,
[V3D_QPU_A_LDVPMD_OUT] = D | A,
[V3D_QPU_A_LDVPMP] = D | A,
[V3D_QPU_A_RSQRT] = D | A,
[V3D_QPU_A_EXP] = D | A,
[V3D_QPU_A_LOG] = D | A,
[V3D_QPU_A_SIN] = D | A,
[V3D_QPU_A_RSQRT2] = D | A,
[V3D_QPU_A_LDVPMG_IN] = D | A | B,
[V3D_QPU_A_LDVPMG_OUT] = 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)
{
/* XXX: WADDR_TMU changed to UNIFA on 4.x */
return ((waddr >= V3D_QPU_WADDR_TMU &&
waddr <= V3D_QPU_WADDR_TMUAU) ||
(waddr >= V3D_QPU_WADDR_TMUC &&
waddr <= V3D_QPU_WADDR_TMUHSLOD));
}
bool
v3d_qpu_waits_on_tmu(const struct v3d_qpu_instr *inst)
{
return (inst->sig.ldtmu ||
(inst->type == V3D_QPU_INSTR_TYPE_ALU &&
inst->alu.add.op == V3D_QPU_A_TMUWT));
}
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);
}
static bool
v3d_qpu_add_op_reads_vpm(enum v3d_qpu_add_op op)
{
switch (op) {
case V3D_QPU_A_VPMSETUP:
case V3D_QPU_A_VPMWT:
case V3D_QPU_A_LDVPMV_IN:
case V3D_QPU_A_LDVPMV_OUT:
case V3D_QPU_A_LDVPMD_IN:
case V3D_QPU_A_LDVPMD_OUT:
case V3D_QPU_A_LDVPMP:
case V3D_QPU_A_LDVPMG_IN:
case V3D_QPU_A_LDVPMG_OUT:
return true;
default:
return false;
}
}
static bool
v3d_qpu_add_op_writes_vpm(enum v3d_qpu_add_op op)
{
switch (op) {
case V3D_QPU_A_VPMSETUP:
case V3D_QPU_A_VPMWT:
case V3D_QPU_A_STVPMV:
case V3D_QPU_A_STVPMD:
case V3D_QPU_A_STVPMP:
return true;
default:
return false;
}
}
bool
v3d_qpu_uses_tlb(const struct v3d_qpu_instr *inst)
{
if (inst->sig.ldtlb ||
inst->sig.ldtlbu)
return true;
if (inst->type == V3D_QPU_INSTR_TYPE_ALU) {
if (inst->alu.add.magic_write &&
v3d_qpu_magic_waddr_is_tlb(inst->alu.add.waddr)) {
return true;
}
if (inst->alu.mul.magic_write &&
v3d_qpu_magic_waddr_is_tlb(inst->alu.mul.waddr)) {
return true;
}
}
return false;
}
bool
v3d_qpu_uses_sfu(const struct v3d_qpu_instr *inst)
{
if (inst->type == V3D_QPU_INSTR_TYPE_ALU) {
switch (inst->alu.add.op) {
case V3D_QPU_A_RECIP:
case V3D_QPU_A_RSQRT:
case V3D_QPU_A_EXP:
case V3D_QPU_A_LOG:
case V3D_QPU_A_SIN:
case V3D_QPU_A_RSQRT2:
return true;
default:
break;
}
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_tmu(const struct v3d_qpu_instr *inst)
{
return (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))));
}
bool
v3d_qpu_reads_vpm(const struct v3d_qpu_instr *inst)
{
if (inst->sig.ldvpm)
return true;
if (inst->type == V3D_QPU_INSTR_TYPE_ALU) {
if (v3d_qpu_add_op_reads_vpm(inst->alu.add.op))
return true;
}
return false;
}
bool
v3d_qpu_writes_vpm(const struct v3d_qpu_instr *inst)
{
if (inst->type == V3D_QPU_INSTR_TYPE_ALU) {
if (v3d_qpu_add_op_writes_vpm(inst->alu.add.op))
return true;
if (inst->alu.add.magic_write &&
v3d_qpu_magic_waddr_is_vpm(inst->alu.add.waddr)) {
return true;
}
if (inst->alu.mul.magic_write &&
v3d_qpu_magic_waddr_is_vpm(inst->alu.mul.waddr)) {
return true;
}
}
return false;
}
bool
v3d_qpu_uses_vpm(const struct v3d_qpu_instr *inst)
{
return v3d_qpu_reads_vpm(inst) || v3d_qpu_writes_vpm(inst);
}
bool
v3d_qpu_writes_r3(const struct v3d_device_info *devinfo,
const struct v3d_qpu_instr *inst)
{
if (inst->type == V3D_QPU_INSTR_TYPE_ALU) {
if (inst->alu.add.magic_write &&
inst->alu.add.waddr == V3D_QPU_WADDR_R3) {
return true;
}
if (inst->alu.mul.magic_write &&
inst->alu.mul.waddr == V3D_QPU_WADDR_R3) {
return true;
}
}
if (v3d_qpu_sig_writes_address(devinfo, &inst->sig) &&
inst->sig_magic && inst->sig_addr == V3D_QPU_WADDR_R3) {
return true;
}
return inst->sig.ldvary || inst->sig.ldvpm;
}
bool
v3d_qpu_writes_r4(const struct v3d_device_info *devinfo,
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 &&
(inst->alu.add.waddr == V3D_QPU_WADDR_R4 ||
v3d_qpu_magic_waddr_is_sfu(inst->alu.add.waddr))) {
return true;
}
if (inst->alu.mul.magic_write &&
(inst->alu.mul.waddr == V3D_QPU_WADDR_R4 ||
v3d_qpu_magic_waddr_is_sfu(inst->alu.mul.waddr))) {
return true;
}
}
if (v3d_qpu_sig_writes_address(devinfo, &inst->sig) &&
inst->sig_magic && inst->sig_addr == V3D_QPU_WADDR_R4) {
return true;
}
return false;
}
bool
v3d_qpu_writes_r5(const struct v3d_device_info *devinfo,
const struct v3d_qpu_instr *inst)
{
if (inst->type == V3D_QPU_INSTR_TYPE_ALU) {
if (inst->alu.add.magic_write &&
inst->alu.add.waddr == V3D_QPU_WADDR_R5) {
return true;
}
if (inst->alu.mul.magic_write &&
inst->alu.mul.waddr == V3D_QPU_WADDR_R5) {
return true;
}
}
if (v3d_qpu_sig_writes_address(devinfo, &inst->sig) &&
inst->sig_magic && inst->sig_addr == V3D_QPU_WADDR_R5) {
return true;
}
return inst->sig.ldvary || inst->sig.ldunif || inst->sig.ldunifa;
}
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));
}
bool
v3d_qpu_sig_writes_address(const struct v3d_device_info *devinfo,
const struct v3d_qpu_sig *sig)
{
if (devinfo->ver < 41)
return false;
return (sig->ldunifrf ||
sig->ldunifarf ||
sig->ldvary ||
sig->ldtmu ||
sig->ldtlb ||
sig->ldtlbu);
}

463
brcm/qpu/qpu_instr.h Normal file
View File

@ -0,0 +1,463 @@
/*
* 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 "../common/macros.h"
struct v3d_device_info;
struct v3d_qpu_sig {
bool thrsw:1;
bool ldunif:1;
bool ldunifa:1;
bool ldunifrf:1;
bool ldunifarf: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,
V3D_QPU_WADDR_SYNCB = 18,
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,
V3D_QPU_WADDR_TMUC = 32,
V3D_QPU_WADDR_TMUS = 33,
V3D_QPU_WADDR_TMUT = 34,
V3D_QPU_WADDR_TMUR = 35,
V3D_QPU_WADDR_TMUI = 36,
V3D_QPU_WADDR_TMUB = 37,
V3D_QPU_WADDR_TMUDREF = 38,
V3D_QPU_WADDR_TMUOFF = 39,
V3D_QPU_WADDR_TMUSCM = 40,
V3D_QPU_WADDR_TMUSF = 41,
V3D_QPU_WADDR_TMUSLOD = 42,
V3D_QPU_WADDR_TMUHS = 43,
V3D_QPU_WADDR_TMUHSCM = 44,
V3D_QPU_WADDR_TMUHSF = 45,
V3D_QPU_WADDR_TMUHSLOD = 46,
V3D_QPU_WADDR_R5REP = 55,
};
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_FLPOP,
V3D_QPU_A_RECIP,
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_BARRIERID,
V3D_QPU_A_TMUWT,
V3D_QPU_A_VPMSETUP,
V3D_QPU_A_VPMWT,
V3D_QPU_A_LDVPMV_IN,
V3D_QPU_A_LDVPMV_OUT,
V3D_QPU_A_LDVPMD_IN,
V3D_QPU_A_LDVPMD_OUT,
V3D_QPU_A_LDVPMP,
V3D_QPU_A_RSQRT,
V3D_QPU_A_EXP,
V3D_QPU_A_LOG,
V3D_QPU_A_SIN,
V3D_QPU_A_RSQRT2,
V3D_QPU_A_LDVPMG_IN,
V3D_QPU_A_LDVPMG_OUT,
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 sig_addr;
bool sig_magic; /* If the signal writes to a magic address */
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_small_imm_pack(const struct v3d_device_info *devinfo,
uint32_t value,
uint32_t *packed_small_immediate);
bool
v3d_qpu_small_imm_unpack(const struct v3d_device_info *devinfo,
uint32_t packed_small_immediate,
uint32_t *small_immediate);
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);
#define ATTRIBUTE_CONST
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_uses_tlb(const struct v3d_qpu_instr *inst) ATTRIBUTE_CONST;
bool v3d_qpu_uses_sfu(const struct v3d_qpu_instr *inst) ATTRIBUTE_CONST;
bool v3d_qpu_writes_tmu(const struct v3d_qpu_instr *inst) ATTRIBUTE_CONST;
bool v3d_qpu_writes_r3(const struct v3d_device_info *devinfo,
const struct v3d_qpu_instr *instr) ATTRIBUTE_CONST;
bool v3d_qpu_writes_r4(const struct v3d_device_info *devinfo,
const struct v3d_qpu_instr *instr) ATTRIBUTE_CONST;
bool v3d_qpu_writes_r5(const struct v3d_device_info *devinfo,
const struct v3d_qpu_instr *instr) ATTRIBUTE_CONST;
bool v3d_qpu_waits_on_tmu(const struct v3d_qpu_instr *inst) ATTRIBUTE_CONST;
bool v3d_qpu_uses_mux(const struct v3d_qpu_instr *inst, enum v3d_qpu_mux mux);
bool v3d_qpu_uses_vpm(const struct v3d_qpu_instr *inst) ATTRIBUTE_CONST;
bool v3d_qpu_reads_vpm(const struct v3d_qpu_instr *inst) ATTRIBUTE_CONST;
bool v3d_qpu_writes_vpm(const struct v3d_qpu_instr *inst) ATTRIBUTE_CONST;
bool v3d_qpu_sig_writes_address(const struct v3d_device_info *devinfo,
const struct v3d_qpu_sig *sig) ATTRIBUTE_CONST;
#endif

1449
brcm/qpu/qpu_pack.c Normal file
View File

@ -0,0 +1,1449 @@
/*
* 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 "../common/macros.h"
#include "../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_COND_SHIFT 46
#define VC5_QPU_COND_MASK QPU_MASK(52, 46)
#define VC5_QPU_COND_SIG_MAGIC_ADDR (1 << 6)
#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 LDUNIFRF .ldunifrf = true
#define LDUNIFA .ldunifa = true
#define LDUNIFARF .ldunifarf = 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, },
};
static const struct v3d_qpu_sig v40_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-13 reserved */
[14] = { SMIMM, LDVARY, },
[15] = { SMIMM, },
[16] = { LDTLB, },
[17] = { LDTLBU, },
[18] = { WRTMUC },
[19] = { THRSW, WRTMUC },
[20] = { LDVARY, WRTMUC },
[21] = { THRSW, LDVARY, WRTMUC },
[22] = { UCB, },
[23] = { ROT, },
/* 24-30 reserved */
[31] = { SMIMM, LDTMU, },
};
static const struct v3d_qpu_sig v41_sig_map[] = {
/* MISC phys 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] = { LDUNIFRF },
[13] = { THRSW, LDUNIFRF },
[14] = { SMIMM, LDVARY, },
[15] = { SMIMM, },
[16] = { LDTLB, },
[17] = { LDTLBU, },
[18] = { WRTMUC },
[19] = { THRSW, WRTMUC },
[20] = { LDVARY, WRTMUC },
[21] = { THRSW, LDVARY, WRTMUC },
[22] = { UCB, },
[23] = { ROT, },
/* 24-30 reserved */
[24] = { LDUNIFA},
[25] = { LDUNIFARF },
[31] = { SMIMM, LDTMU, },
};
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;
if (devinfo->ver >= 41)
*sig = v41_sig_map[packed_sig];
else if (devinfo->ver == 40)
*sig = v40_sig_map[packed_sig];
else
*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;
if (devinfo->ver >= 41)
map = v41_sig_map;
else if (devinfo->ver == 40)
map = v40_sig_map;
else
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;
}
static inline unsigned
fui( float f )
{
union {float f; unsigned ui;} fi;
fi.f = f;
return fi.ui;
}
static const uint32_t small_immediates[] = {
0, 1, 2, 3,
4, 5, 6, 7,
8, 9, 10, 11,
12, 13, 14, 15,
-16, -15, -14, -13,
-12, -11, -10, -9,
-8, -7, -6, -5,
-4, -3, -2, -1,
0x3b800000, /* 2.0^-8 */
0x3c000000, /* 2.0^-7 */
0x3c800000, /* 2.0^-6 */
0x3d000000, /* 2.0^-5 */
0x3d800000, /* 2.0^-4 */
0x3e000000, /* 2.0^-3 */
0x3e800000, /* 2.0^-2 */
0x3f000000, /* 2.0^-1 */
0x3f800000, /* 2.0^0 */
0x40000000, /* 2.0^1 */
0x40800000, /* 2.0^2 */
0x41000000, /* 2.0^3 */
0x41800000, /* 2.0^4 */
0x42000000, /* 2.0^5 */
0x42800000, /* 2.0^6 */
0x43000000, /* 2.0^7 */
};
bool
v3d_qpu_small_imm_unpack(const struct v3d_device_info *devinfo,
uint32_t packed_small_immediate,
uint32_t *small_immediate)
{
if (packed_small_immediate >= ARRAY_SIZE(small_immediates))
return false;
*small_immediate = small_immediates[packed_small_immediate];
return true;
}
bool
v3d_qpu_small_imm_pack(const struct v3d_device_info *devinfo,
uint32_t value,
uint32_t *packed_small_immediate)
{
STATIC_ASSERT(ARRAY_SIZE(small_immediates) == 48);
for (int i = 0; i < ARRAY_SIZE(small_immediates); i++) {
if (small_immediates[i] == value) {
*packed_small_immediate = 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_FLPOP },
{ 186, 186, 1 << 5, ANYMUX, V3D_QPU_A_RECIP },
{ 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, 33 },
{ 187, 187, 1 << 2, 1 << 2, V3D_QPU_A_IID, 40 },
{ 187, 187, 1 << 2, 1 << 3, V3D_QPU_A_SAMPID, 40 },
{ 187, 187, 1 << 2, 1 << 4, V3D_QPU_A_BARRIERID, 40 },
{ 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, 33 },
{ 188, 188, 1 << 0, ANYMUX, V3D_QPU_A_LDVPMV_IN, 40 },
{ 188, 188, 1 << 1, ANYMUX, V3D_QPU_A_LDVPMD_IN, 40 },
{ 188, 188, 1 << 2, ANYMUX, V3D_QPU_A_LDVPMP, 40 },
{ 188, 188, 1 << 3, ANYMUX, V3D_QPU_A_RSQRT, 41 },
{ 188, 188, 1 << 4, ANYMUX, V3D_QPU_A_EXP, 41 },
{ 188, 188, 1 << 5, ANYMUX, V3D_QPU_A_LOG, 41 },
{ 188, 188, 1 << 6, ANYMUX, V3D_QPU_A_SIN, 41 },
{ 188, 188, 1 << 7, ANYMUX, V3D_QPU_A_RSQRT2, 41 },
{ 189, 189, ANYMUX, ANYMUX, V3D_QPU_A_LDVPMG_IN, 40 },
/* 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 = false;
if (packed_inst & VC5_QPU_MA) {
switch (instr->alu.add.op) {
case V3D_QPU_A_LDVPMV_IN:
instr->alu.add.op = V3D_QPU_A_LDVPMV_OUT;
break;
case V3D_QPU_A_LDVPMD_IN:
instr->alu.add.op = V3D_QPU_A_LDVPMD_OUT;
break;
case V3D_QPU_A_LDVPMG_IN:
instr->alu.add.op = V3D_QPU_A_LDVPMG_OUT;
break;
default:
instr->alu.add.magic_write = true;
break;
}
}
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;
case V3D_QPU_M_VFMUL:
instr->alu.mul.output_pack = V3D_QPU_PACK_NONE;
if (!v3d_qpu_float16_unpack_unpack(((op & 0x7) - 4) & 7,
&instr->alu.mul.a_unpack)) {
return false;
}
instr->alu.mul.b_unpack = V3D_QPU_UNPACK_NONE;
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;
bool no_magic_write = false;
switch (instr->alu.add.op) {
case V3D_QPU_A_STVPMV:
waddr = 0;
no_magic_write = true;
break;
case V3D_QPU_A_STVPMD:
waddr = 1;
no_magic_write = true;
break;
case V3D_QPU_A_STVPMP:
waddr = 2;
no_magic_write = true;
break;
case V3D_QPU_A_LDVPMV_IN:
case V3D_QPU_A_LDVPMD_IN:
case V3D_QPU_A_LDVPMP:
case V3D_QPU_A_LDVPMG_IN:
assert(!instr->alu.add.magic_write);
break;
case V3D_QPU_A_LDVPMV_OUT:
case V3D_QPU_A_LDVPMD_OUT:
case V3D_QPU_A_LDVPMG_OUT:
assert(!instr->alu.add.magic_write);
*packed_instr |= VC5_QPU_MA;
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 && !no_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;
}
case V3D_QPU_M_VFMUL: {
uint32_t packed;
if (instr->alu.mul.output_pack != V3D_QPU_PACK_NONE)
return false;
if (!v3d_qpu_float16_unpack_pack(instr->alu.mul.a_unpack,
&packed)) {
return false;
}
if (instr->alu.mul.a_unpack == V3D_QPU_UNPACK_SWAP_16)
opcode = 8;
else
opcode |= (packed + 4) & 7;
if (instr->alu.mul.b_unpack != V3D_QPU_UNPACK_NONE)
return false;
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;
uint32_t packed_cond = QPU_GET_FIELD(packed_instr, VC5_QPU_COND);
if (v3d_qpu_sig_writes_address(devinfo, &instr->sig)) {
instr->sig_addr = packed_cond & ~VC5_QPU_COND_SIG_MAGIC_ADDR;
instr->sig_magic = packed_cond & VC5_QPU_COND_SIG_MAGIC_ADDR;
instr->flags.ac = V3D_QPU_COND_NONE;
instr->flags.mc = V3D_QPU_COND_NONE;
instr->flags.apf = V3D_QPU_PF_NONE;
instr->flags.mpf = V3D_QPU_PF_NONE;
instr->flags.auf = V3D_QPU_UF_NONE;
instr->flags.muf = V3D_QPU_UF_NONE;
} else {
if (!v3d_qpu_flags_unpack(devinfo, packed_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_sig_writes_address(devinfo, &instr->sig)) {
if (instr->flags.ac != V3D_QPU_COND_NONE ||
instr->flags.mc != V3D_QPU_COND_NONE ||
instr->flags.apf != V3D_QPU_PF_NONE ||
instr->flags.mpf != V3D_QPU_PF_NONE ||
instr->flags.auf != V3D_QPU_UF_NONE ||
instr->flags.muf != V3D_QPU_UF_NONE) {
return false;
}
flags = instr->sig_addr;
if (instr->sig_magic)
flags |= VC5_QPU_COND_SIG_MAGIC_ADDR;
} else {
if (!v3d_qpu_flags_pack(devinfo, &instr->flags, &flags))
return false;
}
*packed_instr |= QPU_SET_FIELD(flags, VC5_QPU_COND);
} else {
if (v3d_qpu_sig_writes_address(devinfo, &instr->sig))
return false;
}
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;
}
}

0
brcm/qpu/qpu_validate.c Normal file
View File

View File

@ -6,4 +6,4 @@ file(GLOB driverSrc
add_library(vulkan-1-rpi SHARED ${driverSrc})
target_compile_options(vulkan-1-rpi PRIVATE -Wall -std=c99)
target_link_libraries(vulkan-1-rpi drm pthread)
target_link_libraries(vulkan-1-rpi drm pthread brcm)

View File

@ -28,7 +28,7 @@ static inline void clEmitShaderRelocation(ControlList* cl, const ControlListAddr
#define __gen_address_offset(reloc) ((reloc)->offset)
#define __gen_emit_reloc clEmitShaderRelocation
#include <broadcom/v3d_packet_v21_pack.h>
#include "brcm/cle/v3d_packet_v21_pack.h"
uint32_t divRoundUp(uint32_t n, uint32_t d)
{

View File

@ -20,6 +20,8 @@
#include "LinearAllocator.h"
#include "kernel/vc4_packet.h"
#include "../brcm/cle/v3d_decoder.h"
#include "../brcm/clif/clif_dump.h"
#ifndef min
#define min(a, b) (a < b ? a : b)
@ -118,6 +120,57 @@ void clFit(VkCommandBuffer cb, ControlList* cl, uint32_t commandSize)
}
}
void clDump(void* cl, uint32_t size)
{
struct v3d_device_info devinfo = {
/* While the driver supports V3D 2.1 and 2.6, we haven't split
* off a 2.6 XML yet (there are a couple of fields different
* in render target formatting)
*/
.ver = 21,
};
struct v3d_spec* spec = v3d_spec_load(&devinfo);
struct clif_dump *clif = clif_dump_init(&devinfo, stderr, true);
uint32_t offset = 0, hw_offset = 0;
uint8_t *p = cl;
while (offset < size) {
struct v3d_group *inst = v3d_spec_find_instruction(spec, p);
uint8_t header = *p;
uint32_t length;
if (inst == NULL) {
printf("0x%08x 0x%08x: Unknown packet 0x%02x (%d)!\n",
offset, hw_offset, header, header);
return;
}
length = v3d_group_get_length(inst);
printf("0x%08x 0x%08x: 0x%02x %s\n",
offset, hw_offset, header, v3d_group_get_name(inst));
v3d_print_group(clif, inst, offset, p);
switch (header) {
case VC4_PACKET_HALT:
case VC4_PACKET_STORE_MS_TILE_BUFFER_AND_EOF:
return;
default:
break;
}
offset += length;
if (header != VC4_PACKET_GEM_HANDLES)
hw_offset += length;
p += length;
}
clif_dump_destroy(clif);
}
/*
* https://www.khronos.org/registry/vulkan/specs/1.1-extensions/html/vkspec.html#vkEnumerateInstanceExtensionProperties
* When pLayerName parameter is NULL, only extensions provided by the Vulkan implementation or by implicitly enabled layers are returned. When pLayerName is the name of a layer,
@ -1051,6 +1104,104 @@ VKAPI_ATTR void VKAPI_CALL vkCmdPipelineBarrier(
//TODO
}
/*static inline void
util_pack_color(const float rgba[4], enum pipe_format format, union util_color *uc)
{
ubyte r = 0;
ubyte g = 0;
ubyte b = 0;
ubyte a = 0;
if (util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_RGB, 0) <= 8) {
r = float_to_ubyte(rgba[0]);
g = float_to_ubyte(rgba[1]);
b = float_to_ubyte(rgba[2]);
a = float_to_ubyte(rgba[3]);
}
switch (format) {
case PIPE_FORMAT_ABGR8888_UNORM:
{
uc->ui[0] = (r << 24) | (g << 16) | (b << 8) | a;
}
return;
case PIPE_FORMAT_XBGR8888_UNORM:
{
uc->ui[0] = (r << 24) | (g << 16) | (b << 8) | 0xff;
}
return;
case PIPE_FORMAT_BGRA8888_UNORM:
{
uc->ui[0] = (a << 24) | (r << 16) | (g << 8) | b;
}
return;
case PIPE_FORMAT_BGRX8888_UNORM:
{
uc->ui[0] = (0xffu << 24) | (r << 16) | (g << 8) | b;
}
return;
case PIPE_FORMAT_ARGB8888_UNORM:
{
uc->ui[0] = (b << 24) | (g << 16) | (r << 8) | a;
}
return;
case PIPE_FORMAT_XRGB8888_UNORM:
{
uc->ui[0] = (b << 24) | (g << 16) | (r << 8) | 0xff;
}
return;
case PIPE_FORMAT_B5G6R5_UNORM:
{
uc->us = ((r & 0xf8) << 8) | ((g & 0xfc) << 3) | (b >> 3);
}
return;
case PIPE_FORMAT_B5G5R5X1_UNORM:
{
uc->us = ((0x80) << 8) | ((r & 0xf8) << 7) | ((g & 0xf8) << 2) | (b >> 3);
}
return;
case PIPE_FORMAT_B5G5R5A1_UNORM:
{
uc->us = ((a & 0x80) << 8) | ((r & 0xf8) << 7) | ((g & 0xf8) << 2) | (b >> 3);
}
return;
case PIPE_FORMAT_B4G4R4A4_UNORM:
{
uc->us = ((a & 0xf0) << 8) | ((r & 0xf0) << 4) | ((g & 0xf0) << 0) | (b >> 4);
}
return;
case PIPE_FORMAT_A8_UNORM:
{
uc->ub = a;
}
return;
case PIPE_FORMAT_L8_UNORM:
case PIPE_FORMAT_I8_UNORM:
{
uc->ub = r;
}
return;
case PIPE_FORMAT_R32G32B32A32_FLOAT:
{
uc->f[0] = rgba[0];
uc->f[1] = rgba[1];
uc->f[2] = rgba[2];
uc->f[3] = rgba[3];
}
return;
case PIPE_FORMAT_R32G32B32_FLOAT:
{
uc->f[0] = rgba[0];
uc->f[1] = rgba[1];
uc->f[2] = rgba[2];
}
return;
default:
util_format_write_4f(format, rgba, 0, uc, 0, 0, 0, 1, 1);
}
}*/
uint32_t packVec4IntoRGBA8(const float rgba[4])
{
uint8_t r, g, b, a;
@ -1124,9 +1275,10 @@ VKAPI_ATTR void VKAPI_CALL vkCmdClearColorImage(
1, //16 bit
2); //tris
//TODO primitive list format must be followed by shader state
clFit(commandBuffer, &commandBuffer->binCl, V3D21_GL_SHADER_STATE_length);
clInsertShaderState(&commandBuffer->binCl, 0, 0, 0);
//clFit(commandBuffer, &commandBuffer->binCl, V3D21_GL_SHADER_STATE_length);
//clInsertShaderState(&commandBuffer->binCl, 0, 0, 0);
clFit(commandBuffer, &commandBuffer->handlesCl, 4);
uint32_t idx = clGetHandleIndex(&commandBuffer->handlesCl, i->handle);
@ -1136,7 +1288,7 @@ VKAPI_ATTR void VKAPI_CALL vkCmdClearColorImage(
//TODO format, tiling
commandBuffer->submitCl.color_write.bits =
VC4_SET_FIELD(VC4_RENDER_CONFIG_FORMAT_RGBA8888, VC4_RENDER_CONFIG_FORMAT) |
VC4_SET_FIELD(VC4_TILING_FORMAT_LINEAR, VC4_RENDER_CONFIG_MEMORY_FORMAT);
VC4_SET_FIELD(VC4_TILING_FORMAT_T, VC4_RENDER_CONFIG_MEMORY_FORMAT);
//TODO msaa?
@ -1153,9 +1305,10 @@ VKAPI_ATTR void VKAPI_CALL vkCmdClearColorImage(
commandBuffer->submitCl.clear_z = 0; //TODO
commandBuffer->submitCl.clear_s = 0;
clFit(commandBuffer, &commandBuffer->binCl, V3D21_CLIP_WINDOW_length);
clInsertClipWindow(&commandBuffer->binCl, i->width, i->height, 0, 0); //TODO should this be configurable?
//clFit(commandBuffer, &commandBuffer->binCl, V3D21_CLIP_WINDOW_length);
//clInsertClipWindow(&commandBuffer->binCl, i->width, i->height, 0, 0); //TODO should this be configurable?
/*
//TODO
clFit(commandBuffer, &commandBuffer->binCl, V3D21_CONFIGURATION_BITS_length);
clInsertConfigurationBits(&commandBuffer->binCl,
@ -1198,6 +1351,7 @@ VKAPI_ATTR void VKAPI_CALL vkCmdClearColorImage(
clInsertFlatShadeFlags(&commandBuffer->binCl, 0);
//TODO I suppose this should be a submit itself?
*/
}
/*
@ -1340,6 +1494,8 @@ VKAPI_ATTR VkResult VKAPI_CALL vkQueueSubmit(
cmdbuf->submitCl.uniforms = cmdbuf->uniformsCl.buffer;
cmdbuf->submitCl.uniforms_size = clSize(&cmdbuf->uniformsCl);
clDump(cmdbuf->submitCl.bin_cl, cmdbuf->submitCl.bin_cl_size);
//submit ioctl
uint64_t lastEmitSequno; //TODO
uint64_t lastFinishedSequno;

21
external/include/drm-uapi/README vendored Normal file
View File

@ -0,0 +1,21 @@
This directory contains a copy of the installed kernel headers
required by the anv & i965 drivers to communicate with the kernel.
Whenever either of those driver needs new definitions for new kernel
APIs, these files should be updated.
These files in master should only be updated once the changes have landed
in the drm-next tree.
You can copy files installed after running this from the kernel
repository, at version the drivers require :
$ make headers_install INSTALL_HDR_PATH=/path/to/install
The last update was done at the following kernel commit :
commit 78230c46ec0a91dd4256c9e54934b3c7095a7ee3
Merge: b65bd4031156 037f03155b7d
Author: Dave Airlie <airlied@redhat.com>
Date: Wed Mar 21 14:07:03 2018 +1000
Merge tag 'omapdrm-4.17' of git://git.kernel.org/pub/scm/linux/kernel/git/tomba/linux into drm-next

988
external/include/drm-uapi/drm.h vendored Normal file
View File

@ -0,0 +1,988 @@
/**
* \file drm.h
* Header for the Direct Rendering Manager
*
* \author Rickard E. (Rik) Faith <faith@valinux.com>
*
* \par Acknowledgments:
* Dec 1999, Richard Henderson <rth@twiddle.net>, move to generic \c cmpxchg.
*/
/*
* Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
* Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
* 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 (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
* VA LINUX SYSTEMS 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 _DRM_H_
#define _DRM_H_
#if defined(__linux__)
#include <linux/types.h>
#include <asm/ioctl.h>
typedef unsigned int drm_handle_t;
#else /* One of the BSDs */
#include <sys/ioccom.h>
#include <sys/types.h>
typedef int8_t __s8;
typedef uint8_t __u8;
typedef int16_t __s16;
typedef uint16_t __u16;
typedef int32_t __s32;
typedef uint32_t __u32;
typedef int64_t __s64;
typedef uint64_t __u64;
typedef size_t __kernel_size_t;
typedef unsigned long drm_handle_t;
#endif
#if defined(__cplusplus)
extern "C" {
#endif
#define DRM_NAME "drm" /**< Name in kernel, /dev, and /proc */
#define DRM_MIN_ORDER 5 /**< At least 2^5 bytes = 32 bytes */
#define DRM_MAX_ORDER 22 /**< Up to 2^22 bytes = 4MB */
#define DRM_RAM_PERCENT 10 /**< How much system ram can we lock? */
#define _DRM_LOCK_HELD 0x80000000U /**< Hardware lock is held */
#define _DRM_LOCK_CONT 0x40000000U /**< Hardware lock is contended */
#define _DRM_LOCK_IS_HELD(lock) ((lock) & _DRM_LOCK_HELD)
#define _DRM_LOCK_IS_CONT(lock) ((lock) & _DRM_LOCK_CONT)
#define _DRM_LOCKING_CONTEXT(lock) ((lock) & ~(_DRM_LOCK_HELD|_DRM_LOCK_CONT))
typedef unsigned int drm_context_t;
typedef unsigned int drm_drawable_t;
typedef unsigned int drm_magic_t;
/**
* Cliprect.
*
* \warning: If you change this structure, make sure you change
* XF86DRIClipRectRec in the server as well
*
* \note KW: Actually it's illegal to change either for
* backwards-compatibility reasons.
*/
struct drm_clip_rect {
unsigned short x1;
unsigned short y1;
unsigned short x2;
unsigned short y2;
};
/**
* Drawable information.
*/
struct drm_drawable_info {
unsigned int num_rects;
struct drm_clip_rect *rects;
};
/**
* Texture region,
*/
struct drm_tex_region {
unsigned char next;
unsigned char prev;
unsigned char in_use;
unsigned char padding;
unsigned int age;
};
/**
* Hardware lock.
*
* The lock structure is a simple cache-line aligned integer. To avoid
* processor bus contention on a multiprocessor system, there should not be any
* other data stored in the same cache line.
*/
struct drm_hw_lock {
__volatile__ unsigned int lock; /**< lock variable */
char padding[60]; /**< Pad to cache line */
};
/**
* DRM_IOCTL_VERSION ioctl argument type.
*
* \sa drmGetVersion().
*/
struct drm_version {
int version_major; /**< Major version */
int version_minor; /**< Minor version */
int version_patchlevel; /**< Patch level */
__kernel_size_t name_len; /**< Length of name buffer */
char *name; /**< Name of driver */
__kernel_size_t date_len; /**< Length of date buffer */
char *date; /**< User-space buffer to hold date */
__kernel_size_t desc_len; /**< Length of desc buffer */
char *desc; /**< User-space buffer to hold desc */
};
/**
* DRM_IOCTL_GET_UNIQUE ioctl argument type.
*
* \sa drmGetBusid() and drmSetBusId().
*/
struct drm_unique {
__kernel_size_t unique_len; /**< Length of unique */
char *unique; /**< Unique name for driver instantiation */
};
struct drm_list {
int count; /**< Length of user-space structures */
struct drm_version *version;
};
struct drm_block {
int unused;
};
/**
* DRM_IOCTL_CONTROL ioctl argument type.
*
* \sa drmCtlInstHandler() and drmCtlUninstHandler().
*/
struct drm_control {
enum {
DRM_ADD_COMMAND,
DRM_RM_COMMAND,
DRM_INST_HANDLER,
DRM_UNINST_HANDLER
} func;
int irq;
};
/**
* Type of memory to map.
*/
enum drm_map_type {
_DRM_FRAME_BUFFER = 0, /**< WC (no caching), no core dump */
_DRM_REGISTERS = 1, /**< no caching, no core dump */
_DRM_SHM = 2, /**< shared, cached */
_DRM_AGP = 3, /**< AGP/GART */
_DRM_SCATTER_GATHER = 4, /**< Scatter/gather memory for PCI DMA */
_DRM_CONSISTENT = 5 /**< Consistent memory for PCI DMA */
};
/**
* Memory mapping flags.
*/
enum drm_map_flags {
_DRM_RESTRICTED = 0x01, /**< Cannot be mapped to user-virtual */
_DRM_READ_ONLY = 0x02,
_DRM_LOCKED = 0x04, /**< shared, cached, locked */
_DRM_KERNEL = 0x08, /**< kernel requires access */
_DRM_WRITE_COMBINING = 0x10, /**< use write-combining if available */
_DRM_CONTAINS_LOCK = 0x20, /**< SHM page that contains lock */
_DRM_REMOVABLE = 0x40, /**< Removable mapping */
_DRM_DRIVER = 0x80 /**< Managed by driver */
};
struct drm_ctx_priv_map {
unsigned int ctx_id; /**< Context requesting private mapping */
void *handle; /**< Handle of map */
};
/**
* DRM_IOCTL_GET_MAP, DRM_IOCTL_ADD_MAP and DRM_IOCTL_RM_MAP ioctls
* argument type.
*
* \sa drmAddMap().
*/
struct drm_map {
unsigned long offset; /**< Requested physical address (0 for SAREA)*/
unsigned long size; /**< Requested physical size (bytes) */
enum drm_map_type type; /**< Type of memory to map */
enum drm_map_flags flags; /**< Flags */
void *handle; /**< User-space: "Handle" to pass to mmap() */
/**< Kernel-space: kernel-virtual address */
int mtrr; /**< MTRR slot used */
/* Private data */
};
/**
* DRM_IOCTL_GET_CLIENT ioctl argument type.
*/
struct drm_client {
int idx; /**< Which client desired? */
int auth; /**< Is client authenticated? */
unsigned long pid; /**< Process ID */
unsigned long uid; /**< User ID */
unsigned long magic; /**< Magic */
unsigned long iocs; /**< Ioctl count */
};
enum drm_stat_type {
_DRM_STAT_LOCK,
_DRM_STAT_OPENS,
_DRM_STAT_CLOSES,
_DRM_STAT_IOCTLS,
_DRM_STAT_LOCKS,
_DRM_STAT_UNLOCKS,
_DRM_STAT_VALUE, /**< Generic value */
_DRM_STAT_BYTE, /**< Generic byte counter (1024bytes/K) */
_DRM_STAT_COUNT, /**< Generic non-byte counter (1000/k) */
_DRM_STAT_IRQ, /**< IRQ */
_DRM_STAT_PRIMARY, /**< Primary DMA bytes */
_DRM_STAT_SECONDARY, /**< Secondary DMA bytes */
_DRM_STAT_DMA, /**< DMA */
_DRM_STAT_SPECIAL, /**< Special DMA (e.g., priority or polled) */
_DRM_STAT_MISSED /**< Missed DMA opportunity */
/* Add to the *END* of the list */
};
/**
* DRM_IOCTL_GET_STATS ioctl argument type.
*/
struct drm_stats {
unsigned long count;
struct {
unsigned long value;
enum drm_stat_type type;
} data[15];
};
/**
* Hardware locking flags.
*/
enum drm_lock_flags {
_DRM_LOCK_READY = 0x01, /**< Wait until hardware is ready for DMA */
_DRM_LOCK_QUIESCENT = 0x02, /**< Wait until hardware quiescent */
_DRM_LOCK_FLUSH = 0x04, /**< Flush this context's DMA queue first */
_DRM_LOCK_FLUSH_ALL = 0x08, /**< Flush all DMA queues first */
/* These *HALT* flags aren't supported yet
-- they will be used to support the
full-screen DGA-like mode. */
_DRM_HALT_ALL_QUEUES = 0x10, /**< Halt all current and future queues */
_DRM_HALT_CUR_QUEUES = 0x20 /**< Halt all current queues */
};
/**
* DRM_IOCTL_LOCK, DRM_IOCTL_UNLOCK and DRM_IOCTL_FINISH ioctl argument type.
*
* \sa drmGetLock() and drmUnlock().
*/
struct drm_lock {
int context;
enum drm_lock_flags flags;
};
/**
* DMA flags
*
* \warning
* These values \e must match xf86drm.h.
*
* \sa drm_dma.
*/
enum drm_dma_flags {
/* Flags for DMA buffer dispatch */
_DRM_DMA_BLOCK = 0x01, /**<
* Block until buffer dispatched.
*
* \note The buffer may not yet have
* been processed by the hardware --
* getting a hardware lock with the
* hardware quiescent will ensure
* that the buffer has been
* processed.
*/
_DRM_DMA_WHILE_LOCKED = 0x02, /**< Dispatch while lock held */
_DRM_DMA_PRIORITY = 0x04, /**< High priority dispatch */
/* Flags for DMA buffer request */
_DRM_DMA_WAIT = 0x10, /**< Wait for free buffers */
_DRM_DMA_SMALLER_OK = 0x20, /**< Smaller-than-requested buffers OK */
_DRM_DMA_LARGER_OK = 0x40 /**< Larger-than-requested buffers OK */
};
/**
* DRM_IOCTL_ADD_BUFS and DRM_IOCTL_MARK_BUFS ioctl argument type.
*
* \sa drmAddBufs().
*/
struct drm_buf_desc {
int count; /**< Number of buffers of this size */
int size; /**< Size in bytes */
int low_mark; /**< Low water mark */
int high_mark; /**< High water mark */
enum {
_DRM_PAGE_ALIGN = 0x01, /**< Align on page boundaries for DMA */
_DRM_AGP_BUFFER = 0x02, /**< Buffer is in AGP space */
_DRM_SG_BUFFER = 0x04, /**< Scatter/gather memory buffer */
_DRM_FB_BUFFER = 0x08, /**< Buffer is in frame buffer */
_DRM_PCI_BUFFER_RO = 0x10 /**< Map PCI DMA buffer read-only */
} flags;
unsigned long agp_start; /**<
* Start address of where the AGP buffers are
* in the AGP aperture
*/
};
/**
* DRM_IOCTL_INFO_BUFS ioctl argument type.
*/
struct drm_buf_info {
int count; /**< Entries in list */
struct drm_buf_desc *list;
};
/**
* DRM_IOCTL_FREE_BUFS ioctl argument type.
*/
struct drm_buf_free {
int count;
int *list;
};
/**
* Buffer information
*
* \sa drm_buf_map.
*/
struct drm_buf_pub {
int idx; /**< Index into the master buffer list */
int total; /**< Buffer size */
int used; /**< Amount of buffer in use (for DMA) */
void *address; /**< Address of buffer */
};
/**
* DRM_IOCTL_MAP_BUFS ioctl argument type.
*/
struct drm_buf_map {
int count; /**< Length of the buffer list */
#ifdef __cplusplus
void *virt;
#else
void *virtual; /**< Mmap'd area in user-virtual */
#endif
struct drm_buf_pub *list; /**< Buffer information */
};
/**
* DRM_IOCTL_DMA ioctl argument type.
*
* Indices here refer to the offset into the buffer list in drm_buf_get.
*
* \sa drmDMA().
*/
struct drm_dma {
int context; /**< Context handle */
int send_count; /**< Number of buffers to send */
int *send_indices; /**< List of handles to buffers */
int *send_sizes; /**< Lengths of data to send */
enum drm_dma_flags flags; /**< Flags */
int request_count; /**< Number of buffers requested */
int request_size; /**< Desired size for buffers */
int *request_indices; /**< Buffer information */
int *request_sizes;
int granted_count; /**< Number of buffers granted */
};
enum drm_ctx_flags {
_DRM_CONTEXT_PRESERVED = 0x01,
_DRM_CONTEXT_2DONLY = 0x02
};
/**
* DRM_IOCTL_ADD_CTX ioctl argument type.
*
* \sa drmCreateContext() and drmDestroyContext().
*/
struct drm_ctx {
drm_context_t handle;
enum drm_ctx_flags flags;
};
/**
* DRM_IOCTL_RES_CTX ioctl argument type.
*/
struct drm_ctx_res {
int count;
struct drm_ctx *contexts;
};
/**
* DRM_IOCTL_ADD_DRAW and DRM_IOCTL_RM_DRAW ioctl argument type.
*/
struct drm_draw {
drm_drawable_t handle;
};
/**
* DRM_IOCTL_UPDATE_DRAW ioctl argument type.
*/
typedef enum {
DRM_DRAWABLE_CLIPRECTS
} drm_drawable_info_type_t;
struct drm_update_draw {
drm_drawable_t handle;
unsigned int type;
unsigned int num;
unsigned long long data;
};
/**
* DRM_IOCTL_GET_MAGIC and DRM_IOCTL_AUTH_MAGIC ioctl argument type.
*/
struct drm_auth {
drm_magic_t magic;
};
/**
* DRM_IOCTL_IRQ_BUSID ioctl argument type.
*
* \sa drmGetInterruptFromBusID().
*/
struct drm_irq_busid {
int irq; /**< IRQ number */
int busnum; /**< bus number */
int devnum; /**< device number */
int funcnum; /**< function number */
};
enum drm_vblank_seq_type {
_DRM_VBLANK_ABSOLUTE = 0x0, /**< Wait for specific vblank sequence number */
_DRM_VBLANK_RELATIVE = 0x1, /**< Wait for given number of vblanks */
/* bits 1-6 are reserved for high crtcs */
_DRM_VBLANK_HIGH_CRTC_MASK = 0x0000003e,
_DRM_VBLANK_EVENT = 0x4000000, /**< Send event instead of blocking */
_DRM_VBLANK_FLIP = 0x8000000, /**< Scheduled buffer swap should flip */
_DRM_VBLANK_NEXTONMISS = 0x10000000, /**< If missed, wait for next vblank */
_DRM_VBLANK_SECONDARY = 0x20000000, /**< Secondary display controller */
_DRM_VBLANK_SIGNAL = 0x40000000 /**< Send signal instead of blocking, unsupported */
};
#define _DRM_VBLANK_HIGH_CRTC_SHIFT 1
#define _DRM_VBLANK_TYPES_MASK (_DRM_VBLANK_ABSOLUTE | _DRM_VBLANK_RELATIVE)
#define _DRM_VBLANK_FLAGS_MASK (_DRM_VBLANK_EVENT | _DRM_VBLANK_SIGNAL | \
_DRM_VBLANK_SECONDARY | _DRM_VBLANK_NEXTONMISS)
struct drm_wait_vblank_request {
enum drm_vblank_seq_type type;
unsigned int sequence;
unsigned long signal;
};
struct drm_wait_vblank_reply {
enum drm_vblank_seq_type type;
unsigned int sequence;
long tval_sec;
long tval_usec;
};
/**
* DRM_IOCTL_WAIT_VBLANK ioctl argument type.
*
* \sa drmWaitVBlank().
*/
union drm_wait_vblank {
struct drm_wait_vblank_request request;
struct drm_wait_vblank_reply reply;
};
#define _DRM_PRE_MODESET 1
#define _DRM_POST_MODESET 2
/**
* DRM_IOCTL_MODESET_CTL ioctl argument type
*
* \sa drmModesetCtl().
*/
struct drm_modeset_ctl {
__u32 crtc;
__u32 cmd;
};
/**
* DRM_IOCTL_AGP_ENABLE ioctl argument type.
*
* \sa drmAgpEnable().
*/
struct drm_agp_mode {
unsigned long mode; /**< AGP mode */
};
/**
* DRM_IOCTL_AGP_ALLOC and DRM_IOCTL_AGP_FREE ioctls argument type.
*
* \sa drmAgpAlloc() and drmAgpFree().
*/
struct drm_agp_buffer {
unsigned long size; /**< In bytes -- will round to page boundary */
unsigned long handle; /**< Used for binding / unbinding */
unsigned long type; /**< Type of memory to allocate */
unsigned long physical; /**< Physical used by i810 */
};
/**
* DRM_IOCTL_AGP_BIND and DRM_IOCTL_AGP_UNBIND ioctls argument type.
*
* \sa drmAgpBind() and drmAgpUnbind().
*/
struct drm_agp_binding {
unsigned long handle; /**< From drm_agp_buffer */
unsigned long offset; /**< In bytes -- will round to page boundary */
};
/**
* DRM_IOCTL_AGP_INFO ioctl argument type.
*
* \sa drmAgpVersionMajor(), drmAgpVersionMinor(), drmAgpGetMode(),
* drmAgpBase(), drmAgpSize(), drmAgpMemoryUsed(), drmAgpMemoryAvail(),
* drmAgpVendorId() and drmAgpDeviceId().
*/
struct drm_agp_info {
int agp_version_major;
int agp_version_minor;
unsigned long mode;
unsigned long aperture_base; /* physical address */
unsigned long aperture_size; /* bytes */
unsigned long memory_allowed; /* bytes */
unsigned long memory_used;
/* PCI information */
unsigned short id_vendor;
unsigned short id_device;
};
/**
* DRM_IOCTL_SG_ALLOC ioctl argument type.
*/
struct drm_scatter_gather {
unsigned long size; /**< In bytes -- will round to page boundary */
unsigned long handle; /**< Used for mapping / unmapping */
};
/**
* DRM_IOCTL_SET_VERSION ioctl argument type.
*/
struct drm_set_version {
int drm_di_major;
int drm_di_minor;
int drm_dd_major;
int drm_dd_minor;
};
/** DRM_IOCTL_GEM_CLOSE ioctl argument type */
struct drm_gem_close {
/** Handle of the object to be closed. */
__u32 handle;
__u32 pad;
};
/** DRM_IOCTL_GEM_FLINK ioctl argument type */
struct drm_gem_flink {
/** Handle for the object being named */
__u32 handle;
/** Returned global name */
__u32 name;
};
/** DRM_IOCTL_GEM_OPEN ioctl argument type */
struct drm_gem_open {
/** Name of object being opened */
__u32 name;
/** Returned handle for the object */
__u32 handle;
/** Returned size of the object */
__u64 size;
};
#define DRM_CAP_DUMB_BUFFER 0x1
#define DRM_CAP_VBLANK_HIGH_CRTC 0x2
#define DRM_CAP_DUMB_PREFERRED_DEPTH 0x3
#define DRM_CAP_DUMB_PREFER_SHADOW 0x4
#define DRM_CAP_PRIME 0x5
#define DRM_PRIME_CAP_IMPORT 0x1
#define DRM_PRIME_CAP_EXPORT 0x2
#define DRM_CAP_TIMESTAMP_MONOTONIC 0x6
#define DRM_CAP_ASYNC_PAGE_FLIP 0x7
/*
* The CURSOR_WIDTH and CURSOR_HEIGHT capabilities return a valid widthxheight
* combination for the hardware cursor. The intention is that a hardware
* agnostic userspace can query a cursor plane size to use.
*
* Note that the cross-driver contract is to merely return a valid size;
* drivers are free to attach another meaning on top, eg. i915 returns the
* maximum plane size.
*/
#define DRM_CAP_CURSOR_WIDTH 0x8
#define DRM_CAP_CURSOR_HEIGHT 0x9
#define DRM_CAP_ADDFB2_MODIFIERS 0x10
#define DRM_CAP_PAGE_FLIP_TARGET 0x11
#define DRM_CAP_CRTC_IN_VBLANK_EVENT 0x12
#define DRM_CAP_SYNCOBJ 0x13
/** DRM_IOCTL_GET_CAP ioctl argument type */
struct drm_get_cap {
__u64 capability;
__u64 value;
};
/**
* DRM_CLIENT_CAP_STEREO_3D
*
* if set to 1, the DRM core will expose the stereo 3D capabilities of the
* monitor by advertising the supported 3D layouts in the flags of struct
* drm_mode_modeinfo.
*/
#define DRM_CLIENT_CAP_STEREO_3D 1
/**
* DRM_CLIENT_CAP_UNIVERSAL_PLANES
*
* If set to 1, the DRM core will expose all planes (overlay, primary, and
* cursor) to userspace.
*/
#define DRM_CLIENT_CAP_UNIVERSAL_PLANES 2
/**
* DRM_CLIENT_CAP_ATOMIC
*
* If set to 1, the DRM core will expose atomic properties to userspace
*/
#define DRM_CLIENT_CAP_ATOMIC 3
/** DRM_IOCTL_SET_CLIENT_CAP ioctl argument type */
struct drm_set_client_cap {
__u64 capability;
__u64 value;
};
#define DRM_RDWR O_RDWR
#define DRM_CLOEXEC O_CLOEXEC
struct drm_prime_handle {
__u32 handle;
/** Flags.. only applicable for handle->fd */
__u32 flags;
/** Returned dmabuf file descriptor */
__s32 fd;
};
struct drm_syncobj_create {
__u32 handle;
#define DRM_SYNCOBJ_CREATE_SIGNALED (1 << 0)
__u32 flags;
};
struct drm_syncobj_destroy {
__u32 handle;
__u32 pad;
};
#define DRM_SYNCOBJ_FD_TO_HANDLE_FLAGS_IMPORT_SYNC_FILE (1 << 0)
#define DRM_SYNCOBJ_HANDLE_TO_FD_FLAGS_EXPORT_SYNC_FILE (1 << 0)
struct drm_syncobj_handle {
__u32 handle;
__u32 flags;
__s32 fd;
__u32 pad;
};
#define DRM_SYNCOBJ_WAIT_FLAGS_WAIT_ALL (1 << 0)
#define DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT (1 << 1)
struct drm_syncobj_wait {
__u64 handles;
/* absolute timeout */
__s64 timeout_nsec;
__u32 count_handles;
__u32 flags;
__u32 first_signaled; /* only valid when not waiting all */
__u32 pad;
};
struct drm_syncobj_array {
__u64 handles;
__u32 count_handles;
__u32 pad;
};
/* Query current scanout sequence number */
struct drm_crtc_get_sequence {
__u32 crtc_id; /* requested crtc_id */
__u32 active; /* return: crtc output is active */
__u64 sequence; /* return: most recent vblank sequence */
__s64 sequence_ns; /* return: most recent time of first pixel out */
};
/* Queue event to be delivered at specified sequence. Time stamp marks
* when the first pixel of the refresh cycle leaves the display engine
* for the display
*/
#define DRM_CRTC_SEQUENCE_RELATIVE 0x00000001 /* sequence is relative to current */
#define DRM_CRTC_SEQUENCE_NEXT_ON_MISS 0x00000002 /* Use next sequence if we've missed */
struct drm_crtc_queue_sequence {
__u32 crtc_id;
__u32 flags;
__u64 sequence; /* on input, target sequence. on output, actual sequence */
__u64 user_data; /* user data passed to event */
};
#if defined(__cplusplus)
}
#endif
#include "drm_mode.h"
#if defined(__cplusplus)
extern "C" {
#endif
#define DRM_IOCTL_BASE 'd'
#define DRM_IO(nr) _IO(DRM_IOCTL_BASE,nr)
#define DRM_IOR(nr,type) _IOR(DRM_IOCTL_BASE,nr,type)
#define DRM_IOW(nr,type) _IOW(DRM_IOCTL_BASE,nr,type)
#define DRM_IOWR(nr,type) _IOWR(DRM_IOCTL_BASE,nr,type)
#define DRM_IOCTL_VERSION DRM_IOWR(0x00, struct drm_version)
#define DRM_IOCTL_GET_UNIQUE DRM_IOWR(0x01, struct drm_unique)
#define DRM_IOCTL_GET_MAGIC DRM_IOR( 0x02, struct drm_auth)
#define DRM_IOCTL_IRQ_BUSID DRM_IOWR(0x03, struct drm_irq_busid)
#define DRM_IOCTL_GET_MAP DRM_IOWR(0x04, struct drm_map)
#define DRM_IOCTL_GET_CLIENT DRM_IOWR(0x05, struct drm_client)
#define DRM_IOCTL_GET_STATS DRM_IOR( 0x06, struct drm_stats)
#define DRM_IOCTL_SET_VERSION DRM_IOWR(0x07, struct drm_set_version)
#define DRM_IOCTL_MODESET_CTL DRM_IOW(0x08, struct drm_modeset_ctl)
#define DRM_IOCTL_GEM_CLOSE DRM_IOW (0x09, struct drm_gem_close)
#define DRM_IOCTL_GEM_FLINK DRM_IOWR(0x0a, struct drm_gem_flink)
#define DRM_IOCTL_GEM_OPEN DRM_IOWR(0x0b, struct drm_gem_open)
#define DRM_IOCTL_GET_CAP DRM_IOWR(0x0c, struct drm_get_cap)
#define DRM_IOCTL_SET_CLIENT_CAP DRM_IOW( 0x0d, struct drm_set_client_cap)
#define DRM_IOCTL_SET_UNIQUE DRM_IOW( 0x10, struct drm_unique)
#define DRM_IOCTL_AUTH_MAGIC DRM_IOW( 0x11, struct drm_auth)
#define DRM_IOCTL_BLOCK DRM_IOWR(0x12, struct drm_block)
#define DRM_IOCTL_UNBLOCK DRM_IOWR(0x13, struct drm_block)
#define DRM_IOCTL_CONTROL DRM_IOW( 0x14, struct drm_control)
#define DRM_IOCTL_ADD_MAP DRM_IOWR(0x15, struct drm_map)
#define DRM_IOCTL_ADD_BUFS DRM_IOWR(0x16, struct drm_buf_desc)
#define DRM_IOCTL_MARK_BUFS DRM_IOW( 0x17, struct drm_buf_desc)
#define DRM_IOCTL_INFO_BUFS DRM_IOWR(0x18, struct drm_buf_info)
#define DRM_IOCTL_MAP_BUFS DRM_IOWR(0x19, struct drm_buf_map)
#define DRM_IOCTL_FREE_BUFS DRM_IOW( 0x1a, struct drm_buf_free)
#define DRM_IOCTL_RM_MAP DRM_IOW( 0x1b, struct drm_map)
#define DRM_IOCTL_SET_SAREA_CTX DRM_IOW( 0x1c, struct drm_ctx_priv_map)
#define DRM_IOCTL_GET_SAREA_CTX DRM_IOWR(0x1d, struct drm_ctx_priv_map)
#define DRM_IOCTL_SET_MASTER DRM_IO(0x1e)
#define DRM_IOCTL_DROP_MASTER DRM_IO(0x1f)
#define DRM_IOCTL_ADD_CTX DRM_IOWR(0x20, struct drm_ctx)
#define DRM_IOCTL_RM_CTX DRM_IOWR(0x21, struct drm_ctx)
#define DRM_IOCTL_MOD_CTX DRM_IOW( 0x22, struct drm_ctx)
#define DRM_IOCTL_GET_CTX DRM_IOWR(0x23, struct drm_ctx)
#define DRM_IOCTL_SWITCH_CTX DRM_IOW( 0x24, struct drm_ctx)
#define DRM_IOCTL_NEW_CTX DRM_IOW( 0x25, struct drm_ctx)
#define DRM_IOCTL_RES_CTX DRM_IOWR(0x26, struct drm_ctx_res)
#define DRM_IOCTL_ADD_DRAW DRM_IOWR(0x27, struct drm_draw)
#define DRM_IOCTL_RM_DRAW DRM_IOWR(0x28, struct drm_draw)
#define DRM_IOCTL_DMA DRM_IOWR(0x29, struct drm_dma)
#define DRM_IOCTL_LOCK DRM_IOW( 0x2a, struct drm_lock)
#define DRM_IOCTL_UNLOCK DRM_IOW( 0x2b, struct drm_lock)
#define DRM_IOCTL_FINISH DRM_IOW( 0x2c, struct drm_lock)
#define DRM_IOCTL_PRIME_HANDLE_TO_FD DRM_IOWR(0x2d, struct drm_prime_handle)
#define DRM_IOCTL_PRIME_FD_TO_HANDLE DRM_IOWR(0x2e, struct drm_prime_handle)
#define DRM_IOCTL_AGP_ACQUIRE DRM_IO( 0x30)
#define DRM_IOCTL_AGP_RELEASE DRM_IO( 0x31)
#define DRM_IOCTL_AGP_ENABLE DRM_IOW( 0x32, struct drm_agp_mode)
#define DRM_IOCTL_AGP_INFO DRM_IOR( 0x33, struct drm_agp_info)
#define DRM_IOCTL_AGP_ALLOC DRM_IOWR(0x34, struct drm_agp_buffer)
#define DRM_IOCTL_AGP_FREE DRM_IOW( 0x35, struct drm_agp_buffer)
#define DRM_IOCTL_AGP_BIND DRM_IOW( 0x36, struct drm_agp_binding)
#define DRM_IOCTL_AGP_UNBIND DRM_IOW( 0x37, struct drm_agp_binding)
#define DRM_IOCTL_SG_ALLOC DRM_IOWR(0x38, struct drm_scatter_gather)
#define DRM_IOCTL_SG_FREE DRM_IOW( 0x39, struct drm_scatter_gather)
#define DRM_IOCTL_WAIT_VBLANK DRM_IOWR(0x3a, union drm_wait_vblank)
#define DRM_IOCTL_CRTC_GET_SEQUENCE DRM_IOWR(0x3b, struct drm_crtc_get_sequence)
#define DRM_IOCTL_CRTC_QUEUE_SEQUENCE DRM_IOWR(0x3c, struct drm_crtc_queue_sequence)
#define DRM_IOCTL_UPDATE_DRAW DRM_IOW(0x3f, struct drm_update_draw)
#define DRM_IOCTL_MODE_GETRESOURCES DRM_IOWR(0xA0, struct drm_mode_card_res)
#define DRM_IOCTL_MODE_GETCRTC DRM_IOWR(0xA1, struct drm_mode_crtc)
#define DRM_IOCTL_MODE_SETCRTC DRM_IOWR(0xA2, struct drm_mode_crtc)
#define DRM_IOCTL_MODE_CURSOR DRM_IOWR(0xA3, struct drm_mode_cursor)
#define DRM_IOCTL_MODE_GETGAMMA DRM_IOWR(0xA4, struct drm_mode_crtc_lut)
#define DRM_IOCTL_MODE_SETGAMMA DRM_IOWR(0xA5, struct drm_mode_crtc_lut)
#define DRM_IOCTL_MODE_GETENCODER DRM_IOWR(0xA6, struct drm_mode_get_encoder)
#define DRM_IOCTL_MODE_GETCONNECTOR DRM_IOWR(0xA7, struct drm_mode_get_connector)
#define DRM_IOCTL_MODE_ATTACHMODE DRM_IOWR(0xA8, struct drm_mode_mode_cmd) /* deprecated (never worked) */
#define DRM_IOCTL_MODE_DETACHMODE DRM_IOWR(0xA9, struct drm_mode_mode_cmd) /* deprecated (never worked) */
#define DRM_IOCTL_MODE_GETPROPERTY DRM_IOWR(0xAA, struct drm_mode_get_property)
#define DRM_IOCTL_MODE_SETPROPERTY DRM_IOWR(0xAB, struct drm_mode_connector_set_property)
#define DRM_IOCTL_MODE_GETPROPBLOB DRM_IOWR(0xAC, struct drm_mode_get_blob)
#define DRM_IOCTL_MODE_GETFB DRM_IOWR(0xAD, struct drm_mode_fb_cmd)
#define DRM_IOCTL_MODE_ADDFB DRM_IOWR(0xAE, struct drm_mode_fb_cmd)
#define DRM_IOCTL_MODE_RMFB DRM_IOWR(0xAF, unsigned int)
#define DRM_IOCTL_MODE_PAGE_FLIP DRM_IOWR(0xB0, struct drm_mode_crtc_page_flip)
#define DRM_IOCTL_MODE_DIRTYFB DRM_IOWR(0xB1, struct drm_mode_fb_dirty_cmd)
#define DRM_IOCTL_MODE_CREATE_DUMB DRM_IOWR(0xB2, struct drm_mode_create_dumb)
#define DRM_IOCTL_MODE_MAP_DUMB DRM_IOWR(0xB3, struct drm_mode_map_dumb)
#define DRM_IOCTL_MODE_DESTROY_DUMB DRM_IOWR(0xB4, struct drm_mode_destroy_dumb)
#define DRM_IOCTL_MODE_GETPLANERESOURCES DRM_IOWR(0xB5, struct drm_mode_get_plane_res)
#define DRM_IOCTL_MODE_GETPLANE DRM_IOWR(0xB6, struct drm_mode_get_plane)
#define DRM_IOCTL_MODE_SETPLANE DRM_IOWR(0xB7, struct drm_mode_set_plane)
#define DRM_IOCTL_MODE_ADDFB2 DRM_IOWR(0xB8, struct drm_mode_fb_cmd2)
#define DRM_IOCTL_MODE_OBJ_GETPROPERTIES DRM_IOWR(0xB9, struct drm_mode_obj_get_properties)
#define DRM_IOCTL_MODE_OBJ_SETPROPERTY DRM_IOWR(0xBA, struct drm_mode_obj_set_property)
#define DRM_IOCTL_MODE_CURSOR2 DRM_IOWR(0xBB, struct drm_mode_cursor2)
#define DRM_IOCTL_MODE_ATOMIC DRM_IOWR(0xBC, struct drm_mode_atomic)
#define DRM_IOCTL_MODE_CREATEPROPBLOB DRM_IOWR(0xBD, struct drm_mode_create_blob)
#define DRM_IOCTL_MODE_DESTROYPROPBLOB DRM_IOWR(0xBE, struct drm_mode_destroy_blob)
#define DRM_IOCTL_SYNCOBJ_CREATE DRM_IOWR(0xBF, struct drm_syncobj_create)
#define DRM_IOCTL_SYNCOBJ_DESTROY DRM_IOWR(0xC0, struct drm_syncobj_destroy)
#define DRM_IOCTL_SYNCOBJ_HANDLE_TO_FD DRM_IOWR(0xC1, struct drm_syncobj_handle)
#define DRM_IOCTL_SYNCOBJ_FD_TO_HANDLE DRM_IOWR(0xC2, struct drm_syncobj_handle)
#define DRM_IOCTL_SYNCOBJ_WAIT DRM_IOWR(0xC3, struct drm_syncobj_wait)
#define DRM_IOCTL_SYNCOBJ_RESET DRM_IOWR(0xC4, struct drm_syncobj_array)
#define DRM_IOCTL_SYNCOBJ_SIGNAL DRM_IOWR(0xC5, struct drm_syncobj_array)
#define DRM_IOCTL_MODE_CREATE_LEASE DRM_IOWR(0xC6, struct drm_mode_create_lease)
#define DRM_IOCTL_MODE_LIST_LESSEES DRM_IOWR(0xC7, struct drm_mode_list_lessees)
#define DRM_IOCTL_MODE_GET_LEASE DRM_IOWR(0xC8, struct drm_mode_get_lease)
#define DRM_IOCTL_MODE_REVOKE_LEASE DRM_IOWR(0xC9, struct drm_mode_revoke_lease)
/**
* Device specific ioctls should only be in their respective headers
* The device specific ioctl range is from 0x40 to 0x9f.
* Generic IOCTLS restart at 0xA0.
*
* \sa drmCommandNone(), drmCommandRead(), drmCommandWrite(), and
* drmCommandReadWrite().
*/
#define DRM_COMMAND_BASE 0x40
#define DRM_COMMAND_END 0xA0
/**
* Header for events written back to userspace on the drm fd. The
* type defines the type of event, the length specifies the total
* length of the event (including the header), and user_data is
* typically a 64 bit value passed with the ioctl that triggered the
* event. A read on the drm fd will always only return complete
* events, that is, if for example the read buffer is 100 bytes, and
* there are two 64 byte events pending, only one will be returned.
*
* Event types 0 - 0x7fffffff are generic drm events, 0x80000000 and
* up are chipset specific.
*/
struct drm_event {
__u32 type;
__u32 length;
};
#define DRM_EVENT_VBLANK 0x01
#define DRM_EVENT_FLIP_COMPLETE 0x02
#define DRM_EVENT_CRTC_SEQUENCE 0x03
struct drm_event_vblank {
struct drm_event base;
__u64 user_data;
__u32 tv_sec;
__u32 tv_usec;
__u32 sequence;
__u32 crtc_id; /* 0 on older kernels that do not support this */
};
/* Event delivered at sequence. Time stamp marks when the first pixel
* of the refresh cycle leaves the display engine for the display
*/
struct drm_event_crtc_sequence {
struct drm_event base;
__u64 user_data;
__s64 time_ns;
__u64 sequence;
};
/* typedef area */
typedef struct drm_clip_rect drm_clip_rect_t;
typedef struct drm_drawable_info drm_drawable_info_t;
typedef struct drm_tex_region drm_tex_region_t;
typedef struct drm_hw_lock drm_hw_lock_t;
typedef struct drm_version drm_version_t;
typedef struct drm_unique drm_unique_t;
typedef struct drm_list drm_list_t;
typedef struct drm_block drm_block_t;
typedef struct drm_control drm_control_t;
typedef enum drm_map_type drm_map_type_t;
typedef enum drm_map_flags drm_map_flags_t;
typedef struct drm_ctx_priv_map drm_ctx_priv_map_t;
typedef struct drm_map drm_map_t;
typedef struct drm_client drm_client_t;
typedef enum drm_stat_type drm_stat_type_t;
typedef struct drm_stats drm_stats_t;
typedef enum drm_lock_flags drm_lock_flags_t;
typedef struct drm_lock drm_lock_t;
typedef enum drm_dma_flags drm_dma_flags_t;
typedef struct drm_buf_desc drm_buf_desc_t;
typedef struct drm_buf_info drm_buf_info_t;
typedef struct drm_buf_free drm_buf_free_t;
typedef struct drm_buf_pub drm_buf_pub_t;
typedef struct drm_buf_map drm_buf_map_t;
typedef struct drm_dma drm_dma_t;
typedef union drm_wait_vblank drm_wait_vblank_t;
typedef struct drm_agp_mode drm_agp_mode_t;
typedef enum drm_ctx_flags drm_ctx_flags_t;
typedef struct drm_ctx drm_ctx_t;
typedef struct drm_ctx_res drm_ctx_res_t;
typedef struct drm_draw drm_draw_t;
typedef struct drm_update_draw drm_update_draw_t;
typedef struct drm_auth drm_auth_t;
typedef struct drm_irq_busid drm_irq_busid_t;
typedef enum drm_vblank_seq_type drm_vblank_seq_type_t;
typedef struct drm_agp_buffer drm_agp_buffer_t;
typedef struct drm_agp_binding drm_agp_binding_t;
typedef struct drm_agp_info drm_agp_info_t;
typedef struct drm_scatter_gather drm_scatter_gather_t;
typedef struct drm_set_version drm_set_version_t;
#if defined(__cplusplus)
}
#endif
#endif

492
external/include/drm-uapi/drm_fourcc.h vendored Normal file
View File

@ -0,0 +1,492 @@
/*
* Copyright 2011 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
* VA LINUX SYSTEMS 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 DRM_FOURCC_H
#define DRM_FOURCC_H
#include "drm.h"
#if defined(__cplusplus)
extern "C" {
#endif
#define fourcc_code(a, b, c, d) ((__u32)(a) | ((__u32)(b) << 8) | \
((__u32)(c) << 16) | ((__u32)(d) << 24))
#define DRM_FORMAT_BIG_ENDIAN (1<<31) /* format is big endian instead of little endian */
/* color index */
#define DRM_FORMAT_C8 fourcc_code('C', '8', ' ', ' ') /* [7:0] C */
/* 8 bpp Red */
#define DRM_FORMAT_R8 fourcc_code('R', '8', ' ', ' ') /* [7:0] R */
/* 16 bpp Red */
#define DRM_FORMAT_R16 fourcc_code('R', '1', '6', ' ') /* [15:0] R little endian */
/* 16 bpp RG */
#define DRM_FORMAT_RG88 fourcc_code('R', 'G', '8', '8') /* [15:0] R:G 8:8 little endian */
#define DRM_FORMAT_GR88 fourcc_code('G', 'R', '8', '8') /* [15:0] G:R 8:8 little endian */
/* 32 bpp RG */
#define DRM_FORMAT_RG1616 fourcc_code('R', 'G', '3', '2') /* [31:0] R:G 16:16 little endian */
#define DRM_FORMAT_GR1616 fourcc_code('G', 'R', '3', '2') /* [31:0] G:R 16:16 little endian */
/* 8 bpp RGB */
#define DRM_FORMAT_RGB332 fourcc_code('R', 'G', 'B', '8') /* [7:0] R:G:B 3:3:2 */
#define DRM_FORMAT_BGR233 fourcc_code('B', 'G', 'R', '8') /* [7:0] B:G:R 2:3:3 */
/* 16 bpp RGB */
#define DRM_FORMAT_XRGB4444 fourcc_code('X', 'R', '1', '2') /* [15:0] x:R:G:B 4:4:4:4 little endian */
#define DRM_FORMAT_XBGR4444 fourcc_code('X', 'B', '1', '2') /* [15:0] x:B:G:R 4:4:4:4 little endian */
#define DRM_FORMAT_RGBX4444 fourcc_code('R', 'X', '1', '2') /* [15:0] R:G:B:x 4:4:4:4 little endian */
#define DRM_FORMAT_BGRX4444 fourcc_code('B', 'X', '1', '2') /* [15:0] B:G:R:x 4:4:4:4 little endian */
#define DRM_FORMAT_ARGB4444 fourcc_code('A', 'R', '1', '2') /* [15:0] A:R:G:B 4:4:4:4 little endian */
#define DRM_FORMAT_ABGR4444 fourcc_code('A', 'B', '1', '2') /* [15:0] A:B:G:R 4:4:4:4 little endian */
#define DRM_FORMAT_RGBA4444 fourcc_code('R', 'A', '1', '2') /* [15:0] R:G:B:A 4:4:4:4 little endian */
#define DRM_FORMAT_BGRA4444 fourcc_code('B', 'A', '1', '2') /* [15:0] B:G:R:A 4:4:4:4 little endian */
#define DRM_FORMAT_XRGB1555 fourcc_code('X', 'R', '1', '5') /* [15:0] x:R:G:B 1:5:5:5 little endian */
#define DRM_FORMAT_XBGR1555 fourcc_code('X', 'B', '1', '5') /* [15:0] x:B:G:R 1:5:5:5 little endian */
#define DRM_FORMAT_RGBX5551 fourcc_code('R', 'X', '1', '5') /* [15:0] R:G:B:x 5:5:5:1 little endian */
#define DRM_FORMAT_BGRX5551 fourcc_code('B', 'X', '1', '5') /* [15:0] B:G:R:x 5:5:5:1 little endian */
#define DRM_FORMAT_ARGB1555 fourcc_code('A', 'R', '1', '5') /* [15:0] A:R:G:B 1:5:5:5 little endian */
#define DRM_FORMAT_ABGR1555 fourcc_code('A', 'B', '1', '5') /* [15:0] A:B:G:R 1:5:5:5 little endian */
#define DRM_FORMAT_RGBA5551 fourcc_code('R', 'A', '1', '5') /* [15:0] R:G:B:A 5:5:5:1 little endian */
#define DRM_FORMAT_BGRA5551 fourcc_code('B', 'A', '1', '5') /* [15:0] B:G:R:A 5:5:5:1 little endian */
#define DRM_FORMAT_RGB565 fourcc_code('R', 'G', '1', '6') /* [15:0] R:G:B 5:6:5 little endian */
#define DRM_FORMAT_BGR565 fourcc_code('B', 'G', '1', '6') /* [15:0] B:G:R 5:6:5 little endian */
/* 24 bpp RGB */
#define DRM_FORMAT_RGB888 fourcc_code('R', 'G', '2', '4') /* [23:0] R:G:B little endian */
#define DRM_FORMAT_BGR888 fourcc_code('B', 'G', '2', '4') /* [23:0] B:G:R little endian */
/* 32 bpp RGB */
#define DRM_FORMAT_XRGB8888 fourcc_code('X', 'R', '2', '4') /* [31:0] x:R:G:B 8:8:8:8 little endian */
#define DRM_FORMAT_XBGR8888 fourcc_code('X', 'B', '2', '4') /* [31:0] x:B:G:R 8:8:8:8 little endian */
#define DRM_FORMAT_RGBX8888 fourcc_code('R', 'X', '2', '4') /* [31:0] R:G:B:x 8:8:8:8 little endian */
#define DRM_FORMAT_BGRX8888 fourcc_code('B', 'X', '2', '4') /* [31:0] B:G:R:x 8:8:8:8 little endian */
#define DRM_FORMAT_ARGB8888 fourcc_code('A', 'R', '2', '4') /* [31:0] A:R:G:B 8:8:8:8 little endian */
#define DRM_FORMAT_ABGR8888 fourcc_code('A', 'B', '2', '4') /* [31:0] A:B:G:R 8:8:8:8 little endian */
#define DRM_FORMAT_RGBA8888 fourcc_code('R', 'A', '2', '4') /* [31:0] R:G:B:A 8:8:8:8 little endian */
#define DRM_FORMAT_BGRA8888 fourcc_code('B', 'A', '2', '4') /* [31:0] B:G:R:A 8:8:8:8 little endian */
#define DRM_FORMAT_XRGB2101010 fourcc_code('X', 'R', '3', '0') /* [31:0] x:R:G:B 2:10:10:10 little endian */
#define DRM_FORMAT_XBGR2101010 fourcc_code('X', 'B', '3', '0') /* [31:0] x:B:G:R 2:10:10:10 little endian */
#define DRM_FORMAT_RGBX1010102 fourcc_code('R', 'X', '3', '0') /* [31:0] R:G:B:x 10:10:10:2 little endian */
#define DRM_FORMAT_BGRX1010102 fourcc_code('B', 'X', '3', '0') /* [31:0] B:G:R:x 10:10:10:2 little endian */
#define DRM_FORMAT_ARGB2101010 fourcc_code('A', 'R', '3', '0') /* [31:0] A:R:G:B 2:10:10:10 little endian */
#define DRM_FORMAT_ABGR2101010 fourcc_code('A', 'B', '3', '0') /* [31:0] A:B:G:R 2:10:10:10 little endian */
#define DRM_FORMAT_RGBA1010102 fourcc_code('R', 'A', '3', '0') /* [31:0] R:G:B:A 10:10:10:2 little endian */
#define DRM_FORMAT_BGRA1010102 fourcc_code('B', 'A', '3', '0') /* [31:0] B:G:R:A 10:10:10:2 little endian */
/* packed YCbCr */
#define DRM_FORMAT_YUYV fourcc_code('Y', 'U', 'Y', 'V') /* [31:0] Cr0:Y1:Cb0:Y0 8:8:8:8 little endian */
#define DRM_FORMAT_YVYU fourcc_code('Y', 'V', 'Y', 'U') /* [31:0] Cb0:Y1:Cr0:Y0 8:8:8:8 little endian */
#define DRM_FORMAT_UYVY fourcc_code('U', 'Y', 'V', 'Y') /* [31:0] Y1:Cr0:Y0:Cb0 8:8:8:8 little endian */
#define DRM_FORMAT_VYUY fourcc_code('V', 'Y', 'U', 'Y') /* [31:0] Y1:Cb0:Y0:Cr0 8:8:8:8 little endian */
#define DRM_FORMAT_AYUV fourcc_code('A', 'Y', 'U', 'V') /* [31:0] A:Y:Cb:Cr 8:8:8:8 little endian */
/*
* 2 plane RGB + A
* index 0 = RGB plane, same format as the corresponding non _A8 format has
* index 1 = A plane, [7:0] A
*/
#define DRM_FORMAT_XRGB8888_A8 fourcc_code('X', 'R', 'A', '8')
#define DRM_FORMAT_XBGR8888_A8 fourcc_code('X', 'B', 'A', '8')
#define DRM_FORMAT_RGBX8888_A8 fourcc_code('R', 'X', 'A', '8')
#define DRM_FORMAT_BGRX8888_A8 fourcc_code('B', 'X', 'A', '8')
#define DRM_FORMAT_RGB888_A8 fourcc_code('R', '8', 'A', '8')
#define DRM_FORMAT_BGR888_A8 fourcc_code('B', '8', 'A', '8')
#define DRM_FORMAT_RGB565_A8 fourcc_code('R', '5', 'A', '8')
#define DRM_FORMAT_BGR565_A8 fourcc_code('B', '5', 'A', '8')
/*
* 2 plane YCbCr
* index 0 = Y plane, [7:0] Y
* index 1 = Cr:Cb plane, [15:0] Cr:Cb little endian
* or
* index 1 = Cb:Cr plane, [15:0] Cb:Cr little endian
*/
#define DRM_FORMAT_NV12 fourcc_code('N', 'V', '1', '2') /* 2x2 subsampled Cr:Cb plane */
#define DRM_FORMAT_NV21 fourcc_code('N', 'V', '2', '1') /* 2x2 subsampled Cb:Cr plane */
#define DRM_FORMAT_NV16 fourcc_code('N', 'V', '1', '6') /* 2x1 subsampled Cr:Cb plane */
#define DRM_FORMAT_NV61 fourcc_code('N', 'V', '6', '1') /* 2x1 subsampled Cb:Cr plane */
#define DRM_FORMAT_NV24 fourcc_code('N', 'V', '2', '4') /* non-subsampled Cr:Cb plane */
#define DRM_FORMAT_NV42 fourcc_code('N', 'V', '4', '2') /* non-subsampled Cb:Cr plane */
/*
* 3 plane YCbCr
* index 0: Y plane, [7:0] Y
* index 1: Cb plane, [7:0] Cb
* index 2: Cr plane, [7:0] Cr
* or
* index 1: Cr plane, [7:0] Cr
* index 2: Cb plane, [7:0] Cb
*/
#define DRM_FORMAT_YUV410 fourcc_code('Y', 'U', 'V', '9') /* 4x4 subsampled Cb (1) and Cr (2) planes */
#define DRM_FORMAT_YVU410 fourcc_code('Y', 'V', 'U', '9') /* 4x4 subsampled Cr (1) and Cb (2) planes */
#define DRM_FORMAT_YUV411 fourcc_code('Y', 'U', '1', '1') /* 4x1 subsampled Cb (1) and Cr (2) planes */
#define DRM_FORMAT_YVU411 fourcc_code('Y', 'V', '1', '1') /* 4x1 subsampled Cr (1) and Cb (2) planes */
#define DRM_FORMAT_YUV420 fourcc_code('Y', 'U', '1', '2') /* 2x2 subsampled Cb (1) and Cr (2) planes */
#define DRM_FORMAT_YVU420 fourcc_code('Y', 'V', '1', '2') /* 2x2 subsampled Cr (1) and Cb (2) planes */
#define DRM_FORMAT_YUV422 fourcc_code('Y', 'U', '1', '6') /* 2x1 subsampled Cb (1) and Cr (2) planes */
#define DRM_FORMAT_YVU422 fourcc_code('Y', 'V', '1', '6') /* 2x1 subsampled Cr (1) and Cb (2) planes */
#define DRM_FORMAT_YUV444 fourcc_code('Y', 'U', '2', '4') /* non-subsampled Cb (1) and Cr (2) planes */
#define DRM_FORMAT_YVU444 fourcc_code('Y', 'V', '2', '4') /* non-subsampled Cr (1) and Cb (2) planes */
/*
* Format Modifiers:
*
* Format modifiers describe, typically, a re-ordering or modification
* of the data in a plane of an FB. This can be used to express tiled/
* swizzled formats, or compression, or a combination of the two.
*
* The upper 8 bits of the format modifier are a vendor-id as assigned
* below. The lower 56 bits are assigned as vendor sees fit.
*/
/* Vendor Ids: */
#define DRM_FORMAT_MOD_NONE 0
#define DRM_FORMAT_MOD_VENDOR_NONE 0
#define DRM_FORMAT_MOD_VENDOR_INTEL 0x01
#define DRM_FORMAT_MOD_VENDOR_AMD 0x02
#define DRM_FORMAT_MOD_VENDOR_NVIDIA 0x03
#define DRM_FORMAT_MOD_VENDOR_SAMSUNG 0x04
#define DRM_FORMAT_MOD_VENDOR_QCOM 0x05
#define DRM_FORMAT_MOD_VENDOR_VIVANTE 0x06
#define DRM_FORMAT_MOD_VENDOR_BROADCOM 0x07
/* add more to the end as needed */
#define DRM_FORMAT_RESERVED ((1ULL << 56) - 1)
#define fourcc_mod_code(vendor, val) \
((((__u64)DRM_FORMAT_MOD_VENDOR_## vendor) << 56) | ((val) & 0x00ffffffffffffffULL))
/*
* Format Modifier tokens:
*
* When adding a new token please document the layout with a code comment,
* similar to the fourcc codes above. drm_fourcc.h is considered the
* authoritative source for all of these.
*/
/*
* Invalid Modifier
*
* This modifier can be used as a sentinel to terminate the format modifiers
* list, or to initialize a variable with an invalid modifier. It might also be
* used to report an error back to userspace for certain APIs.
*/
#define DRM_FORMAT_MOD_INVALID fourcc_mod_code(NONE, DRM_FORMAT_RESERVED)
/*
* Linear Layout
*
* Just plain linear layout. Note that this is different from no specifying any
* modifier (e.g. not setting DRM_MODE_FB_MODIFIERS in the DRM_ADDFB2 ioctl),
* which tells the driver to also take driver-internal information into account
* and so might actually result in a tiled framebuffer.
*/
#define DRM_FORMAT_MOD_LINEAR fourcc_mod_code(NONE, 0)
/* Intel framebuffer modifiers */
/*
* Intel X-tiling layout
*
* This is a tiled layout using 4Kb tiles (except on gen2 where the tiles 2Kb)
* in row-major layout. Within the tile bytes are laid out row-major, with
* a platform-dependent stride. On top of that the memory can apply
* platform-depending swizzling of some higher address bits into bit6.
*
* This format is highly platforms specific and not useful for cross-driver
* sharing. It exists since on a given platform it does uniquely identify the
* layout in a simple way for i915-specific userspace.
*/
#define I915_FORMAT_MOD_X_TILED fourcc_mod_code(INTEL, 1)
/*
* Intel Y-tiling layout
*
* This is a tiled layout using 4Kb tiles (except on gen2 where the tiles 2Kb)
* in row-major layout. Within the tile bytes are laid out in OWORD (16 bytes)
* chunks column-major, with a platform-dependent height. On top of that the
* memory can apply platform-depending swizzling of some higher address bits
* into bit6.
*
* This format is highly platforms specific and not useful for cross-driver
* sharing. It exists since on a given platform it does uniquely identify the
* layout in a simple way for i915-specific userspace.
*/
#define I915_FORMAT_MOD_Y_TILED fourcc_mod_code(INTEL, 2)
/*
* Intel Yf-tiling layout
*
* This is a tiled layout using 4Kb tiles in row-major layout.
* Within the tile pixels are laid out in 16 256 byte units / sub-tiles which
* are arranged in four groups (two wide, two high) with column-major layout.
* Each group therefore consits out of four 256 byte units, which are also laid
* out as 2x2 column-major.
* 256 byte units are made out of four 64 byte blocks of pixels, producing
* either a square block or a 2:1 unit.
* 64 byte blocks of pixels contain four pixel rows of 16 bytes, where the width
* in pixel depends on the pixel depth.
*/
#define I915_FORMAT_MOD_Yf_TILED fourcc_mod_code(INTEL, 3)
/*
* Intel color control surface (CCS) for render compression
*
* The framebuffer format must be one of the 8:8:8:8 RGB formats.
* The main surface will be plane index 0 and must be Y/Yf-tiled,
* the CCS will be plane index 1.
*
* Each CCS tile matches a 1024x512 pixel area of the main surface.
* To match certain aspects of the 3D hardware the CCS is
* considered to be made up of normal 128Bx32 Y tiles, Thus
* the CCS pitch must be specified in multiples of 128 bytes.
*
* In reality the CCS tile appears to be a 64Bx64 Y tile, composed
* of QWORD (8 bytes) chunks instead of OWORD (16 bytes) chunks.
* But that fact is not relevant unless the memory is accessed
* directly.
*/
#define I915_FORMAT_MOD_Y_TILED_CCS fourcc_mod_code(INTEL, 4)
#define I915_FORMAT_MOD_Yf_TILED_CCS fourcc_mod_code(INTEL, 5)
/*
* Tiled, NV12MT, grouped in 64 (pixels) x 32 (lines) -sized macroblocks
*
* Macroblocks are laid in a Z-shape, and each pixel data is following the
* standard NV12 style.
* As for NV12, an image is the result of two frame buffers: one for Y,
* one for the interleaved Cb/Cr components (1/2 the height of the Y buffer).
* Alignment requirements are (for each buffer):
* - multiple of 128 pixels for the width
* - multiple of 32 pixels for the height
*
* For more information: see https://linuxtv.org/downloads/v4l-dvb-apis/re32.html
*/
#define DRM_FORMAT_MOD_SAMSUNG_64_32_TILE fourcc_mod_code(SAMSUNG, 1)
/* Vivante framebuffer modifiers */
/*
* Vivante 4x4 tiling layout
*
* This is a simple tiled layout using tiles of 4x4 pixels in a row-major
* layout.
*/
#define DRM_FORMAT_MOD_VIVANTE_TILED fourcc_mod_code(VIVANTE, 1)
/*
* Vivante 64x64 super-tiling layout
*
* This is a tiled layout using 64x64 pixel super-tiles, where each super-tile
* contains 8x4 groups of 2x4 tiles of 4x4 pixels (like above) each, all in row-
* major layout.
*
* For more information: see
* https://github.com/etnaviv/etna_viv/blob/master/doc/hardware.md#texture-tiling
*/
#define DRM_FORMAT_MOD_VIVANTE_SUPER_TILED fourcc_mod_code(VIVANTE, 2)
/*
* Vivante 4x4 tiling layout for dual-pipe
*
* Same as the 4x4 tiling layout, except every second 4x4 pixel tile starts at a
* different base address. Offsets from the base addresses are therefore halved
* compared to the non-split tiled layout.
*/
#define DRM_FORMAT_MOD_VIVANTE_SPLIT_TILED fourcc_mod_code(VIVANTE, 3)
/*
* Vivante 64x64 super-tiling layout for dual-pipe
*
* Same as the 64x64 super-tiling layout, except every second 4x4 pixel tile
* starts at a different base address. Offsets from the base addresses are
* therefore halved compared to the non-split super-tiled layout.
*/
#define DRM_FORMAT_MOD_VIVANTE_SPLIT_SUPER_TILED fourcc_mod_code(VIVANTE, 4)
/* NVIDIA frame buffer modifiers */
/*
* Tegra Tiled Layout, used by Tegra 2, 3 and 4.
*
* Pixels are arranged in simple tiles of 16 x 16 bytes.
*/
#define DRM_FORMAT_MOD_NVIDIA_TEGRA_TILED fourcc_mod_code(NVIDIA, 1)
/*
* 16Bx2 Block Linear layout, used by desktop GPUs, and Tegra K1 and later
*
* Pixels are arranged in 64x8 Groups Of Bytes (GOBs). GOBs are then stacked
* vertically by a power of 2 (1 to 32 GOBs) to form a block.
*
* Within a GOB, data is ordered as 16B x 2 lines sectors laid in Z-shape.
*
* Parameter 'v' is the log2 encoding of the number of GOBs stacked vertically.
* Valid values are:
*
* 0 == ONE_GOB
* 1 == TWO_GOBS
* 2 == FOUR_GOBS
* 3 == EIGHT_GOBS
* 4 == SIXTEEN_GOBS
* 5 == THIRTYTWO_GOBS
*
* Chapter 20 "Pixel Memory Formats" of the Tegra X1 TRM describes this format
* in full detail.
*/
#define DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK(v) \
fourcc_mod_code(NVIDIA, 0x10 | ((v) & 0xf))
#define DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK_ONE_GOB \
fourcc_mod_code(NVIDIA, 0x10)
#define DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK_TWO_GOB \
fourcc_mod_code(NVIDIA, 0x11)
#define DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK_FOUR_GOB \
fourcc_mod_code(NVIDIA, 0x12)
#define DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK_EIGHT_GOB \
fourcc_mod_code(NVIDIA, 0x13)
#define DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK_SIXTEEN_GOB \
fourcc_mod_code(NVIDIA, 0x14)
#define DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK_THIRTYTWO_GOB \
fourcc_mod_code(NVIDIA, 0x15)
/*
* Some Broadcom modifiers take parameters, for example the number of
* vertical lines in the image. Reserve the lower 32 bits for modifier
* type, and the next 24 bits for parameters. Top 8 bits are the
* vendor code.
*/
#define __fourcc_mod_broadcom_param_shift 8
#define __fourcc_mod_broadcom_param_bits 48
#define fourcc_mod_broadcom_code(val, params) \
fourcc_mod_code(BROADCOM, ((((__u64)params) << __fourcc_mod_broadcom_param_shift) | val))
#define fourcc_mod_broadcom_param(m) \
((int)(((m) >> __fourcc_mod_broadcom_param_shift) & \
((1ULL << __fourcc_mod_broadcom_param_bits) - 1)))
#define fourcc_mod_broadcom_mod(m) \
((m) & ~(((1ULL << __fourcc_mod_broadcom_param_bits) - 1) << \
__fourcc_mod_broadcom_param_shift))
/*
* Broadcom VC4 "T" format
*
* This is the primary layout that the V3D GPU can texture from (it
* can't do linear). The T format has:
*
* - 64b utiles of pixels in a raster-order grid according to cpp. It's 4x4
* pixels at 32 bit depth.
*
* - 1k subtiles made of a 4x4 raster-order grid of 64b utiles (so usually
* 16x16 pixels).
*
* - 4k tiles made of a 2x2 grid of 1k subtiles (so usually 32x32 pixels). On
* even 4k tile rows, they're arranged as (BL, TL, TR, BR), and on odd rows
* they're (TR, BR, BL, TL), where bottom left is start of memory.
*
* - an image made of 4k tiles in rows either left-to-right (even rows of 4k
* tiles) or right-to-left (odd rows of 4k tiles).
*/
#define DRM_FORMAT_MOD_BROADCOM_VC4_T_TILED fourcc_mod_code(BROADCOM, 1)
/*
* Broadcom SAND format
*
* This is the native format that the H.264 codec block uses. For VC4
* HVS, it is only valid for H.264 (NV12/21) and RGBA modes.
*
* The image can be considered to be split into columns, and the
* columns are placed consecutively into memory. The width of those
* columns can be either 32, 64, 128, or 256 pixels, but in practice
* only 128 pixel columns are used.
*
* The pitch between the start of each column is set to optimally
* switch between SDRAM banks. This is passed as the number of lines
* of column width in the modifier (we can't use the stride value due
* to various core checks that look at it , so you should set the
* stride to width*cpp).
*
* Note that the column height for this format modifier is the same
* for all of the planes, assuming that each column contains both Y
* and UV. Some SAND-using hardware stores UV in a separate tiled
* image from Y to reduce the column height, which is not supported
* with these modifiers.
*/
#define DRM_FORMAT_MOD_BROADCOM_SAND32_COL_HEIGHT(v) \
fourcc_mod_broadcom_code(2, v)
#define DRM_FORMAT_MOD_BROADCOM_SAND64_COL_HEIGHT(v) \
fourcc_mod_broadcom_code(3, v)
#define DRM_FORMAT_MOD_BROADCOM_SAND128_COL_HEIGHT(v) \
fourcc_mod_broadcom_code(4, v)
#define DRM_FORMAT_MOD_BROADCOM_SAND256_COL_HEIGHT(v) \
fourcc_mod_broadcom_code(5, v)
#define DRM_FORMAT_MOD_BROADCOM_SAND32 \
DRM_FORMAT_MOD_BROADCOM_SAND32_COL_HEIGHT(0)
#define DRM_FORMAT_MOD_BROADCOM_SAND64 \
DRM_FORMAT_MOD_BROADCOM_SAND64_COL_HEIGHT(0)
#define DRM_FORMAT_MOD_BROADCOM_SAND128 \
DRM_FORMAT_MOD_BROADCOM_SAND128_COL_HEIGHT(0)
#define DRM_FORMAT_MOD_BROADCOM_SAND256 \
DRM_FORMAT_MOD_BROADCOM_SAND256_COL_HEIGHT(0)
/* Broadcom UIF format
*
* This is the common format for the current Broadcom multimedia
* blocks, including V3D 3.x and newer, newer video codecs, and
* displays.
*
* The image consists of utiles (64b blocks), UIF blocks (2x2 utiles),
* and macroblocks (4x4 UIF blocks). Those 4x4 UIF block groups are
* stored in columns, with padding between the columns to ensure that
* moving from one column to the next doesn't hit the same SDRAM page
* bank.
*
* To calculate the padding, it is assumed that each hardware block
* and the software driving it knows the platform's SDRAM page size,
* number of banks, and XOR address, and that it's identical between
* all blocks using the format. This tiling modifier will use XOR as
* necessary to reduce the padding. If a hardware block can't do XOR,
* the assumption is that a no-XOR tiling modifier will be created.
*/
#define DRM_FORMAT_MOD_BROADCOM_UIF fourcc_mod_code(BROADCOM, 6)
#if defined(__cplusplus)
}
#endif
#endif /* DRM_FOURCC_H */

880
external/include/drm-uapi/drm_mode.h vendored Normal file
View File

@ -0,0 +1,880 @@
/*
* Copyright (c) 2007 Dave Airlie <airlied@linux.ie>
* Copyright (c) 2007 Jakob Bornecrantz <wallbraker@gmail.com>
* Copyright (c) 2008 Red Hat Inc.
* Copyright (c) 2007-2008 Tungsten Graphics, Inc., Cedar Park, TX., USA
* Copyright (c) 2007-2008 Intel Corporation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
#ifndef _DRM_MODE_H
#define _DRM_MODE_H
#include "drm.h"
#if defined(__cplusplus)
extern "C" {
#endif
#define DRM_DISPLAY_INFO_LEN 32
#define DRM_CONNECTOR_NAME_LEN 32
#define DRM_DISPLAY_MODE_LEN 32
#define DRM_PROP_NAME_LEN 32
#define DRM_MODE_TYPE_BUILTIN (1<<0) /* deprecated */
#define DRM_MODE_TYPE_CLOCK_C ((1<<1) | DRM_MODE_TYPE_BUILTIN) /* deprecated */
#define DRM_MODE_TYPE_CRTC_C ((1<<2) | DRM_MODE_TYPE_BUILTIN) /* deprecated */
#define DRM_MODE_TYPE_PREFERRED (1<<3)
#define DRM_MODE_TYPE_DEFAULT (1<<4) /* deprecated */
#define DRM_MODE_TYPE_USERDEF (1<<5)
#define DRM_MODE_TYPE_DRIVER (1<<6)
#define DRM_MODE_TYPE_ALL (DRM_MODE_TYPE_PREFERRED | \
DRM_MODE_TYPE_USERDEF | \
DRM_MODE_TYPE_DRIVER)
/* Video mode flags */
/* bit compatible with the xrandr RR_ definitions (bits 0-13)
*
* ABI warning: Existing userspace really expects
* the mode flags to match the xrandr definitions. Any
* changes that don't match the xrandr definitions will
* likely need a new client cap or some other mechanism
* to avoid breaking existing userspace. This includes
* allocating new flags in the previously unused bits!
*/
#define DRM_MODE_FLAG_PHSYNC (1<<0)
#define DRM_MODE_FLAG_NHSYNC (1<<1)
#define DRM_MODE_FLAG_PVSYNC (1<<2)
#define DRM_MODE_FLAG_NVSYNC (1<<3)
#define DRM_MODE_FLAG_INTERLACE (1<<4)
#define DRM_MODE_FLAG_DBLSCAN (1<<5)
#define DRM_MODE_FLAG_CSYNC (1<<6)
#define DRM_MODE_FLAG_PCSYNC (1<<7)
#define DRM_MODE_FLAG_NCSYNC (1<<8)
#define DRM_MODE_FLAG_HSKEW (1<<9) /* hskew provided */
#define DRM_MODE_FLAG_BCAST (1<<10) /* deprecated */
#define DRM_MODE_FLAG_PIXMUX (1<<11) /* deprecated */
#define DRM_MODE_FLAG_DBLCLK (1<<12)
#define DRM_MODE_FLAG_CLKDIV2 (1<<13)
/*
* When adding a new stereo mode don't forget to adjust DRM_MODE_FLAGS_3D_MAX
* (define not exposed to user space).
*/
#define DRM_MODE_FLAG_3D_MASK (0x1f<<14)
#define DRM_MODE_FLAG_3D_NONE (0<<14)
#define DRM_MODE_FLAG_3D_FRAME_PACKING (1<<14)
#define DRM_MODE_FLAG_3D_FIELD_ALTERNATIVE (2<<14)
#define DRM_MODE_FLAG_3D_LINE_ALTERNATIVE (3<<14)
#define DRM_MODE_FLAG_3D_SIDE_BY_SIDE_FULL (4<<14)
#define DRM_MODE_FLAG_3D_L_DEPTH (5<<14)
#define DRM_MODE_FLAG_3D_L_DEPTH_GFX_GFX_DEPTH (6<<14)
#define DRM_MODE_FLAG_3D_TOP_AND_BOTTOM (7<<14)
#define DRM_MODE_FLAG_3D_SIDE_BY_SIDE_HALF (8<<14)
/* Picture aspect ratio options */
#define DRM_MODE_PICTURE_ASPECT_NONE 0
#define DRM_MODE_PICTURE_ASPECT_4_3 1
#define DRM_MODE_PICTURE_ASPECT_16_9 2
/* Aspect ratio flag bitmask (4 bits 22:19) */
#define DRM_MODE_FLAG_PIC_AR_MASK (0x0F<<19)
#define DRM_MODE_FLAG_PIC_AR_NONE \
(DRM_MODE_PICTURE_ASPECT_NONE<<19)
#define DRM_MODE_FLAG_PIC_AR_4_3 \
(DRM_MODE_PICTURE_ASPECT_4_3<<19)
#define DRM_MODE_FLAG_PIC_AR_16_9 \
(DRM_MODE_PICTURE_ASPECT_16_9<<19)
#define DRM_MODE_FLAG_ALL (DRM_MODE_FLAG_PHSYNC | \
DRM_MODE_FLAG_NHSYNC | \
DRM_MODE_FLAG_PVSYNC | \
DRM_MODE_FLAG_NVSYNC | \
DRM_MODE_FLAG_INTERLACE | \
DRM_MODE_FLAG_DBLSCAN | \
DRM_MODE_FLAG_CSYNC | \
DRM_MODE_FLAG_PCSYNC | \
DRM_MODE_FLAG_NCSYNC | \
DRM_MODE_FLAG_HSKEW | \
DRM_MODE_FLAG_DBLCLK | \
DRM_MODE_FLAG_CLKDIV2 | \
DRM_MODE_FLAG_3D_MASK)
/* DPMS flags */
/* bit compatible with the xorg definitions. */
#define DRM_MODE_DPMS_ON 0
#define DRM_MODE_DPMS_STANDBY 1
#define DRM_MODE_DPMS_SUSPEND 2
#define DRM_MODE_DPMS_OFF 3
/* Scaling mode options */
#define DRM_MODE_SCALE_NONE 0 /* Unmodified timing (display or
software can still scale) */
#define DRM_MODE_SCALE_FULLSCREEN 1 /* Full screen, ignore aspect */
#define DRM_MODE_SCALE_CENTER 2 /* Centered, no scaling */
#define DRM_MODE_SCALE_ASPECT 3 /* Full screen, preserve aspect */
/* Dithering mode options */
#define DRM_MODE_DITHERING_OFF 0
#define DRM_MODE_DITHERING_ON 1
#define DRM_MODE_DITHERING_AUTO 2
/* Dirty info options */
#define DRM_MODE_DIRTY_OFF 0
#define DRM_MODE_DIRTY_ON 1
#define DRM_MODE_DIRTY_ANNOTATE 2
/* Link Status options */
#define DRM_MODE_LINK_STATUS_GOOD 0
#define DRM_MODE_LINK_STATUS_BAD 1
/*
* DRM_MODE_ROTATE_<degrees>
*
* Signals that a drm plane is been rotated <degrees> degrees in counter
* clockwise direction.
*
* This define is provided as a convenience, looking up the property id
* using the name->prop id lookup is the preferred method.
*/
#define DRM_MODE_ROTATE_0 (1<<0)
#define DRM_MODE_ROTATE_90 (1<<1)
#define DRM_MODE_ROTATE_180 (1<<2)
#define DRM_MODE_ROTATE_270 (1<<3)
/*
* DRM_MODE_ROTATE_MASK
*
* Bitmask used to look for drm plane rotations.
*/
#define DRM_MODE_ROTATE_MASK (\
DRM_MODE_ROTATE_0 | \
DRM_MODE_ROTATE_90 | \
DRM_MODE_ROTATE_180 | \
DRM_MODE_ROTATE_270)
/*
* DRM_MODE_REFLECT_<axis>
*
* Signals that the contents of a drm plane is reflected in the <axis> axis,
* in the same way as mirroring.
*
* This define is provided as a convenience, looking up the property id
* using the name->prop id lookup is the preferred method.
*/
#define DRM_MODE_REFLECT_X (1<<4)
#define DRM_MODE_REFLECT_Y (1<<5)
/*
* DRM_MODE_REFLECT_MASK
*
* Bitmask used to look for drm plane reflections.
*/
#define DRM_MODE_REFLECT_MASK (\
DRM_MODE_REFLECT_X | \
DRM_MODE_REFLECT_Y)
/* Content Protection Flags */
#define DRM_MODE_CONTENT_PROTECTION_UNDESIRED 0
#define DRM_MODE_CONTENT_PROTECTION_DESIRED 1
#define DRM_MODE_CONTENT_PROTECTION_ENABLED 2
struct drm_mode_modeinfo {
__u32 clock;
__u16 hdisplay;
__u16 hsync_start;
__u16 hsync_end;
__u16 htotal;
__u16 hskew;
__u16 vdisplay;
__u16 vsync_start;
__u16 vsync_end;
__u16 vtotal;
__u16 vscan;
__u32 vrefresh;
__u32 flags;
__u32 type;
char name[DRM_DISPLAY_MODE_LEN];
};
struct drm_mode_card_res {
__u64 fb_id_ptr;
__u64 crtc_id_ptr;
__u64 connector_id_ptr;
__u64 encoder_id_ptr;
__u32 count_fbs;
__u32 count_crtcs;
__u32 count_connectors;
__u32 count_encoders;
__u32 min_width;
__u32 max_width;
__u32 min_height;
__u32 max_height;
};
struct drm_mode_crtc {
__u64 set_connectors_ptr;
__u32 count_connectors;
__u32 crtc_id; /**< Id */
__u32 fb_id; /**< Id of framebuffer */
__u32 x; /**< x Position on the framebuffer */
__u32 y; /**< y Position on the framebuffer */
__u32 gamma_size;
__u32 mode_valid;
struct drm_mode_modeinfo mode;
};
#define DRM_MODE_PRESENT_TOP_FIELD (1<<0)
#define DRM_MODE_PRESENT_BOTTOM_FIELD (1<<1)
/* Planes blend with or override other bits on the CRTC */
struct drm_mode_set_plane {
__u32 plane_id;
__u32 crtc_id;
__u32 fb_id; /* fb object contains surface format type */
__u32 flags; /* see above flags */
/* Signed dest location allows it to be partially off screen */
__s32 crtc_x;
__s32 crtc_y;
__u32 crtc_w;
__u32 crtc_h;
/* Source values are 16.16 fixed point */
__u32 src_x;
__u32 src_y;
__u32 src_h;
__u32 src_w;
};
struct drm_mode_get_plane {
__u32 plane_id;
__u32 crtc_id;
__u32 fb_id;
__u32 possible_crtcs;
__u32 gamma_size;
__u32 count_format_types;
__u64 format_type_ptr;
};
struct drm_mode_get_plane_res {
__u64 plane_id_ptr;
__u32 count_planes;
};
#define DRM_MODE_ENCODER_NONE 0
#define DRM_MODE_ENCODER_DAC 1
#define DRM_MODE_ENCODER_TMDS 2
#define DRM_MODE_ENCODER_LVDS 3
#define DRM_MODE_ENCODER_TVDAC 4
#define DRM_MODE_ENCODER_VIRTUAL 5
#define DRM_MODE_ENCODER_DSI 6
#define DRM_MODE_ENCODER_DPMST 7
#define DRM_MODE_ENCODER_DPI 8
struct drm_mode_get_encoder {
__u32 encoder_id;
__u32 encoder_type;
__u32 crtc_id; /**< Id of crtc */
__u32 possible_crtcs;
__u32 possible_clones;
};
/* This is for connectors with multiple signal types. */
/* Try to match DRM_MODE_CONNECTOR_X as closely as possible. */
enum drm_mode_subconnector {
DRM_MODE_SUBCONNECTOR_Automatic = 0,
DRM_MODE_SUBCONNECTOR_Unknown = 0,
DRM_MODE_SUBCONNECTOR_DVID = 3,
DRM_MODE_SUBCONNECTOR_DVIA = 4,
DRM_MODE_SUBCONNECTOR_Composite = 5,
DRM_MODE_SUBCONNECTOR_SVIDEO = 6,
DRM_MODE_SUBCONNECTOR_Component = 8,
DRM_MODE_SUBCONNECTOR_SCART = 9,
};
#define DRM_MODE_CONNECTOR_Unknown 0
#define DRM_MODE_CONNECTOR_VGA 1
#define DRM_MODE_CONNECTOR_DVII 2
#define DRM_MODE_CONNECTOR_DVID 3
#define DRM_MODE_CONNECTOR_DVIA 4
#define DRM_MODE_CONNECTOR_Composite 5
#define DRM_MODE_CONNECTOR_SVIDEO 6
#define DRM_MODE_CONNECTOR_LVDS 7
#define DRM_MODE_CONNECTOR_Component 8
#define DRM_MODE_CONNECTOR_9PinDIN 9
#define DRM_MODE_CONNECTOR_DisplayPort 10
#define DRM_MODE_CONNECTOR_HDMIA 11
#define DRM_MODE_CONNECTOR_HDMIB 12
#define DRM_MODE_CONNECTOR_TV 13
#define DRM_MODE_CONNECTOR_eDP 14
#define DRM_MODE_CONNECTOR_VIRTUAL 15
#define DRM_MODE_CONNECTOR_DSI 16
#define DRM_MODE_CONNECTOR_DPI 17
struct drm_mode_get_connector {
__u64 encoders_ptr;
__u64 modes_ptr;
__u64 props_ptr;
__u64 prop_values_ptr;
__u32 count_modes;
__u32 count_props;
__u32 count_encoders;
__u32 encoder_id; /**< Current Encoder */
__u32 connector_id; /**< Id */
__u32 connector_type;
__u32 connector_type_id;
__u32 connection;
__u32 mm_width; /**< width in millimeters */
__u32 mm_height; /**< height in millimeters */
__u32 subpixel;
__u32 pad;
};
#define DRM_MODE_PROP_PENDING (1<<0) /* deprecated, do not use */
#define DRM_MODE_PROP_RANGE (1<<1)
#define DRM_MODE_PROP_IMMUTABLE (1<<2)
#define DRM_MODE_PROP_ENUM (1<<3) /* enumerated type with text strings */
#define DRM_MODE_PROP_BLOB (1<<4)
#define DRM_MODE_PROP_BITMASK (1<<5) /* bitmask of enumerated types */
/* non-extended types: legacy bitmask, one bit per type: */
#define DRM_MODE_PROP_LEGACY_TYPE ( \
DRM_MODE_PROP_RANGE | \
DRM_MODE_PROP_ENUM | \
DRM_MODE_PROP_BLOB | \
DRM_MODE_PROP_BITMASK)
/* extended-types: rather than continue to consume a bit per type,
* grab a chunk of the bits to use as integer type id.
*/
#define DRM_MODE_PROP_EXTENDED_TYPE 0x0000ffc0
#define DRM_MODE_PROP_TYPE(n) ((n) << 6)
#define DRM_MODE_PROP_OBJECT DRM_MODE_PROP_TYPE(1)
#define DRM_MODE_PROP_SIGNED_RANGE DRM_MODE_PROP_TYPE(2)
/* the PROP_ATOMIC flag is used to hide properties from userspace that
* is not aware of atomic properties. This is mostly to work around
* older userspace (DDX drivers) that read/write each prop they find,
* witout being aware that this could be triggering a lengthy modeset.
*/
#define DRM_MODE_PROP_ATOMIC 0x80000000
struct drm_mode_property_enum {
__u64 value;
char name[DRM_PROP_NAME_LEN];
};
struct drm_mode_get_property {
__u64 values_ptr; /* values and blob lengths */
__u64 enum_blob_ptr; /* enum and blob id ptrs */
__u32 prop_id;
__u32 flags;
char name[DRM_PROP_NAME_LEN];
__u32 count_values;
/* This is only used to count enum values, not blobs. The _blobs is
* simply because of a historical reason, i.e. backwards compat. */
__u32 count_enum_blobs;
};
struct drm_mode_connector_set_property {
__u64 value;
__u32 prop_id;
__u32 connector_id;
};
#define DRM_MODE_OBJECT_CRTC 0xcccccccc
#define DRM_MODE_OBJECT_CONNECTOR 0xc0c0c0c0
#define DRM_MODE_OBJECT_ENCODER 0xe0e0e0e0
#define DRM_MODE_OBJECT_MODE 0xdededede
#define DRM_MODE_OBJECT_PROPERTY 0xb0b0b0b0
#define DRM_MODE_OBJECT_FB 0xfbfbfbfb
#define DRM_MODE_OBJECT_BLOB 0xbbbbbbbb
#define DRM_MODE_OBJECT_PLANE 0xeeeeeeee
#define DRM_MODE_OBJECT_ANY 0
struct drm_mode_obj_get_properties {
__u64 props_ptr;
__u64 prop_values_ptr;
__u32 count_props;
__u32 obj_id;
__u32 obj_type;
};
struct drm_mode_obj_set_property {
__u64 value;
__u32 prop_id;
__u32 obj_id;
__u32 obj_type;
};
struct drm_mode_get_blob {
__u32 blob_id;
__u32 length;
__u64 data;
};
struct drm_mode_fb_cmd {
__u32 fb_id;
__u32 width;
__u32 height;
__u32 pitch;
__u32 bpp;
__u32 depth;
/* driver specific handle */
__u32 handle;
};
#define DRM_MODE_FB_INTERLACED (1<<0) /* for interlaced framebuffers */
#define DRM_MODE_FB_MODIFIERS (1<<1) /* enables ->modifer[] */
struct drm_mode_fb_cmd2 {
__u32 fb_id;
__u32 width;
__u32 height;
__u32 pixel_format; /* fourcc code from drm_fourcc.h */
__u32 flags; /* see above flags */
/*
* In case of planar formats, this ioctl allows up to 4
* buffer objects with offsets and pitches per plane.
* The pitch and offset order is dictated by the fourcc,
* e.g. NV12 (http://fourcc.org/yuv.php#NV12) is described as:
*
* YUV 4:2:0 image with a plane of 8 bit Y samples
* followed by an interleaved U/V plane containing
* 8 bit 2x2 subsampled colour difference samples.
*
* So it would consist of Y as offsets[0] and UV as
* offsets[1]. Note that offsets[0] will generally
* be 0 (but this is not required).
*
* To accommodate tiled, compressed, etc formats, a
* modifier can be specified. The default value of zero
* indicates "native" format as specified by the fourcc.
* Vendor specific modifier token. Note that even though
* it looks like we have a modifier per-plane, we in fact
* do not. The modifier for each plane must be identical.
* Thus all combinations of different data layouts for
* multi plane formats must be enumerated as separate
* modifiers.
*/
__u32 handles[4];
__u32 pitches[4]; /* pitch for each plane */
__u32 offsets[4]; /* offset of each plane */
__u64 modifier[4]; /* ie, tiling, compress */
};
#define DRM_MODE_FB_DIRTY_ANNOTATE_COPY 0x01
#define DRM_MODE_FB_DIRTY_ANNOTATE_FILL 0x02
#define DRM_MODE_FB_DIRTY_FLAGS 0x03
#define DRM_MODE_FB_DIRTY_MAX_CLIPS 256
/*
* Mark a region of a framebuffer as dirty.
*
* Some hardware does not automatically update display contents
* as a hardware or software draw to a framebuffer. This ioctl
* allows userspace to tell the kernel and the hardware what
* regions of the framebuffer have changed.
*
* The kernel or hardware is free to update more then just the
* region specified by the clip rects. The kernel or hardware
* may also delay and/or coalesce several calls to dirty into a
* single update.
*
* Userspace may annotate the updates, the annotates are a
* promise made by the caller that the change is either a copy
* of pixels or a fill of a single color in the region specified.
*
* If the DRM_MODE_FB_DIRTY_ANNOTATE_COPY flag is given then
* the number of updated regions are half of num_clips given,
* where the clip rects are paired in src and dst. The width and
* height of each one of the pairs must match.
*
* If the DRM_MODE_FB_DIRTY_ANNOTATE_FILL flag is given the caller
* promises that the region specified of the clip rects is filled
* completely with a single color as given in the color argument.
*/
struct drm_mode_fb_dirty_cmd {
__u32 fb_id;
__u32 flags;
__u32 color;
__u32 num_clips;
__u64 clips_ptr;
};
struct drm_mode_mode_cmd {
__u32 connector_id;
struct drm_mode_modeinfo mode;
};
#define DRM_MODE_CURSOR_BO 0x01
#define DRM_MODE_CURSOR_MOVE 0x02
#define DRM_MODE_CURSOR_FLAGS 0x03
/*
* depending on the value in flags different members are used.
*
* CURSOR_BO uses
* crtc_id
* width
* height
* handle - if 0 turns the cursor off
*
* CURSOR_MOVE uses
* crtc_id
* x
* y
*/
struct drm_mode_cursor {
__u32 flags;
__u32 crtc_id;
__s32 x;
__s32 y;
__u32 width;
__u32 height;
/* driver specific handle */
__u32 handle;
};
struct drm_mode_cursor2 {
__u32 flags;
__u32 crtc_id;
__s32 x;
__s32 y;
__u32 width;
__u32 height;
/* driver specific handle */
__u32 handle;
__s32 hot_x;
__s32 hot_y;
};
struct drm_mode_crtc_lut {
__u32 crtc_id;
__u32 gamma_size;
/* pointers to arrays */
__u64 red;
__u64 green;
__u64 blue;
};
struct drm_color_ctm {
/*
* Conversion matrix in S31.32 sign-magnitude
* (not two's complement!) format.
*/
__u64 matrix[9];
};
struct drm_color_lut {
/*
* Data is U0.16 fixed point format.
*/
__u16 red;
__u16 green;
__u16 blue;
__u16 reserved;
};
#define DRM_MODE_PAGE_FLIP_EVENT 0x01
#define DRM_MODE_PAGE_FLIP_ASYNC 0x02
#define DRM_MODE_PAGE_FLIP_TARGET_ABSOLUTE 0x4
#define DRM_MODE_PAGE_FLIP_TARGET_RELATIVE 0x8
#define DRM_MODE_PAGE_FLIP_TARGET (DRM_MODE_PAGE_FLIP_TARGET_ABSOLUTE | \
DRM_MODE_PAGE_FLIP_TARGET_RELATIVE)
#define DRM_MODE_PAGE_FLIP_FLAGS (DRM_MODE_PAGE_FLIP_EVENT | \
DRM_MODE_PAGE_FLIP_ASYNC | \
DRM_MODE_PAGE_FLIP_TARGET)
/*
* Request a page flip on the specified crtc.
*
* This ioctl will ask KMS to schedule a page flip for the specified
* crtc. Once any pending rendering targeting the specified fb (as of
* ioctl time) has completed, the crtc will be reprogrammed to display
* that fb after the next vertical refresh. The ioctl returns
* immediately, but subsequent rendering to the current fb will block
* in the execbuffer ioctl until the page flip happens. If a page
* flip is already pending as the ioctl is called, EBUSY will be
* returned.
*
* Flag DRM_MODE_PAGE_FLIP_EVENT requests that drm sends back a vblank
* event (see drm.h: struct drm_event_vblank) when the page flip is
* done. The user_data field passed in with this ioctl will be
* returned as the user_data field in the vblank event struct.
*
* Flag DRM_MODE_PAGE_FLIP_ASYNC requests that the flip happen
* 'as soon as possible', meaning that it not delay waiting for vblank.
* This may cause tearing on the screen.
*
* The reserved field must be zero.
*/
struct drm_mode_crtc_page_flip {
__u32 crtc_id;
__u32 fb_id;
__u32 flags;
__u32 reserved;
__u64 user_data;
};
/*
* Request a page flip on the specified crtc.
*
* Same as struct drm_mode_crtc_page_flip, but supports new flags and
* re-purposes the reserved field:
*
* The sequence field must be zero unless either of the
* DRM_MODE_PAGE_FLIP_TARGET_ABSOLUTE/RELATIVE flags is specified. When
* the ABSOLUTE flag is specified, the sequence field denotes the absolute
* vblank sequence when the flip should take effect. When the RELATIVE
* flag is specified, the sequence field denotes the relative (to the
* current one when the ioctl is called) vblank sequence when the flip
* should take effect. NOTE: DRM_IOCTL_WAIT_VBLANK must still be used to
* make sure the vblank sequence before the target one has passed before
* calling this ioctl. The purpose of the
* DRM_MODE_PAGE_FLIP_TARGET_ABSOLUTE/RELATIVE flags is merely to clarify
* the target for when code dealing with a page flip runs during a
* vertical blank period.
*/
struct drm_mode_crtc_page_flip_target {
__u32 crtc_id;
__u32 fb_id;
__u32 flags;
__u32 sequence;
__u64 user_data;
};
/* create a dumb scanout buffer */
struct drm_mode_create_dumb {
__u32 height;
__u32 width;
__u32 bpp;
__u32 flags;
/* handle, pitch, size will be returned */
__u32 handle;
__u32 pitch;
__u64 size;
};
/* set up for mmap of a dumb scanout buffer */
struct drm_mode_map_dumb {
/** Handle for the object being mapped. */
__u32 handle;
__u32 pad;
/**
* Fake offset to use for subsequent mmap call
*
* This is a fixed-size type for 32/64 compatibility.
*/
__u64 offset;
};
struct drm_mode_destroy_dumb {
__u32 handle;
};
/* page-flip flags are valid, plus: */
#define DRM_MODE_ATOMIC_TEST_ONLY 0x0100
#define DRM_MODE_ATOMIC_NONBLOCK 0x0200
#define DRM_MODE_ATOMIC_ALLOW_MODESET 0x0400
#define DRM_MODE_ATOMIC_FLAGS (\
DRM_MODE_PAGE_FLIP_EVENT |\
DRM_MODE_PAGE_FLIP_ASYNC |\
DRM_MODE_ATOMIC_TEST_ONLY |\
DRM_MODE_ATOMIC_NONBLOCK |\
DRM_MODE_ATOMIC_ALLOW_MODESET)
struct drm_mode_atomic {
__u32 flags;
__u32 count_objs;
__u64 objs_ptr;
__u64 count_props_ptr;
__u64 props_ptr;
__u64 prop_values_ptr;
__u64 reserved;
__u64 user_data;
};
struct drm_format_modifier_blob {
#define FORMAT_BLOB_CURRENT 1
/* Version of this blob format */
__u32 version;
/* Flags */
__u32 flags;
/* Number of fourcc formats supported */
__u32 count_formats;
/* Where in this blob the formats exist (in bytes) */
__u32 formats_offset;
/* Number of drm_format_modifiers */
__u32 count_modifiers;
/* Where in this blob the modifiers exist (in bytes) */
__u32 modifiers_offset;
/* __u32 formats[] */
/* struct drm_format_modifier modifiers[] */
};
struct drm_format_modifier {
/* Bitmask of formats in get_plane format list this info applies to. The
* offset allows a sliding window of which 64 formats (bits).
*
* Some examples:
* In today's world with < 65 formats, and formats 0, and 2 are
* supported
* 0x0000000000000005
* ^-offset = 0, formats = 5
*
* If the number formats grew to 128, and formats 98-102 are
* supported with the modifier:
*
* 0x0000007c00000000 0000000000000000
* ^
* |__offset = 64, formats = 0x7c00000000
*
*/
__u64 formats;
__u32 offset;
__u32 pad;
/* The modifier that applies to the >get_plane format list bitmask. */
__u64 modifier;
};
/**
* Create a new 'blob' data property, copying length bytes from data pointer,
* and returning new blob ID.
*/
struct drm_mode_create_blob {
/** Pointer to data to copy. */
__u64 data;
/** Length of data to copy. */
__u32 length;
/** Return: new property ID. */
__u32 blob_id;
};
/**
* Destroy a user-created blob property.
*/
struct drm_mode_destroy_blob {
__u32 blob_id;
};
/**
* Lease mode resources, creating another drm_master.
*/
struct drm_mode_create_lease {
/** Pointer to array of object ids (__u32) */
__u64 object_ids;
/** Number of object ids */
__u32 object_count;
/** flags for new FD (O_CLOEXEC, etc) */
__u32 flags;
/** Return: unique identifier for lessee. */
__u32 lessee_id;
/** Return: file descriptor to new drm_master file */
__u32 fd;
};
/**
* List lesses from a drm_master
*/
struct drm_mode_list_lessees {
/** Number of lessees.
* On input, provides length of the array.
* On output, provides total number. No
* more than the input number will be written
* back, so two calls can be used to get
* the size and then the data.
*/
__u32 count_lessees;
__u32 pad;
/** Pointer to lessees.
* pointer to __u64 array of lessee ids
*/
__u64 lessees_ptr;
};
/**
* Get leased objects
*/
struct drm_mode_get_lease {
/** Number of leased objects.
* On input, provides length of the array.
* On output, provides total number. No
* more than the input number will be written
* back, so two calls can be used to get
* the size and then the data.
*/
__u32 count_objects;
__u32 pad;
/** Pointer to objects.
* pointer to __u32 array of object ids
*/
__u64 objects_ptr;
};
/**
* Revoke lease
*/
struct drm_mode_revoke_lease {
/** Unique ID of lessee
*/
__u32 lessee_id;
};
#if defined(__cplusplus)
}
#endif
#endif

1724
external/include/drm-uapi/i915_drm.h vendored Normal file
View File

@ -0,0 +1,1724 @@
/*
* Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
* 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, 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 TUNGSTEN GRAPHICS 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 _I915_DRM_H_
#define _I915_DRM_H_
#include "drm.h"
#if defined(__cplusplus)
extern "C" {
#endif
/* Please note that modifications to all structs defined here are
* subject to backwards-compatibility constraints.
*/
/**
* DOC: uevents generated by i915 on it's device node
*
* I915_L3_PARITY_UEVENT - Generated when the driver receives a parity mismatch
* event from the gpu l3 cache. Additional information supplied is ROW,
* BANK, SUBBANK, SLICE of the affected cacheline. Userspace should keep
* track of these events and if a specific cache-line seems to have a
* persistent error remap it with the l3 remapping tool supplied in
* intel-gpu-tools. The value supplied with the event is always 1.
*
* I915_ERROR_UEVENT - Generated upon error detection, currently only via
* hangcheck. The error detection event is a good indicator of when things
* began to go badly. The value supplied with the event is a 1 upon error
* detection, and a 0 upon reset completion, signifying no more error
* exists. NOTE: Disabling hangcheck or reset via module parameter will
* cause the related events to not be seen.
*
* I915_RESET_UEVENT - Event is generated just before an attempt to reset the
* the GPU. The value supplied with the event is always 1. NOTE: Disable
* reset via module parameter will cause this event to not be seen.
*/
#define I915_L3_PARITY_UEVENT "L3_PARITY_ERROR"
#define I915_ERROR_UEVENT "ERROR"
#define I915_RESET_UEVENT "RESET"
/*
* MOCS indexes used for GPU surfaces, defining the cacheability of the
* surface data and the coherency for this data wrt. CPU vs. GPU accesses.
*/
enum i915_mocs_table_index {
/*
* Not cached anywhere, coherency between CPU and GPU accesses is
* guaranteed.
*/
I915_MOCS_UNCACHED,
/*
* Cacheability and coherency controlled by the kernel automatically
* based on the DRM_I915_GEM_SET_CACHING IOCTL setting and the current
* usage of the surface (used for display scanout or not).
*/
I915_MOCS_PTE,
/*
* Cached in all GPU caches available on the platform.
* Coherency between CPU and GPU accesses to the surface is not
* guaranteed without extra synchronization.
*/
I915_MOCS_CACHED,
};
/*
* Different engines serve different roles, and there may be more than one
* engine serving each role. enum drm_i915_gem_engine_class provides a
* classification of the role of the engine, which may be used when requesting
* operations to be performed on a certain subset of engines, or for providing
* information about that group.
*/
enum drm_i915_gem_engine_class {
I915_ENGINE_CLASS_RENDER = 0,
I915_ENGINE_CLASS_COPY = 1,
I915_ENGINE_CLASS_VIDEO = 2,
I915_ENGINE_CLASS_VIDEO_ENHANCE = 3,
I915_ENGINE_CLASS_INVALID = -1
};
/**
* DOC: perf_events exposed by i915 through /sys/bus/event_sources/drivers/i915
*
*/
enum drm_i915_pmu_engine_sample {
I915_SAMPLE_BUSY = 0,
I915_SAMPLE_WAIT = 1,
I915_SAMPLE_SEMA = 2
};
#define I915_PMU_SAMPLE_BITS (4)
#define I915_PMU_SAMPLE_MASK (0xf)
#define I915_PMU_SAMPLE_INSTANCE_BITS (8)
#define I915_PMU_CLASS_SHIFT \
(I915_PMU_SAMPLE_BITS + I915_PMU_SAMPLE_INSTANCE_BITS)
#define __I915_PMU_ENGINE(class, instance, sample) \
((class) << I915_PMU_CLASS_SHIFT | \
(instance) << I915_PMU_SAMPLE_BITS | \
(sample))
#define I915_PMU_ENGINE_BUSY(class, instance) \
__I915_PMU_ENGINE(class, instance, I915_SAMPLE_BUSY)
#define I915_PMU_ENGINE_WAIT(class, instance) \
__I915_PMU_ENGINE(class, instance, I915_SAMPLE_WAIT)
#define I915_PMU_ENGINE_SEMA(class, instance) \
__I915_PMU_ENGINE(class, instance, I915_SAMPLE_SEMA)
#define __I915_PMU_OTHER(x) (__I915_PMU_ENGINE(0xff, 0xff, 0xf) + 1 + (x))
#define I915_PMU_ACTUAL_FREQUENCY __I915_PMU_OTHER(0)
#define I915_PMU_REQUESTED_FREQUENCY __I915_PMU_OTHER(1)
#define I915_PMU_INTERRUPTS __I915_PMU_OTHER(2)
#define I915_PMU_RC6_RESIDENCY __I915_PMU_OTHER(3)
#define I915_PMU_LAST I915_PMU_RC6_RESIDENCY
/* Each region is a minimum of 16k, and there are at most 255 of them.
*/
#define I915_NR_TEX_REGIONS 255 /* table size 2k - maximum due to use
* of chars for next/prev indices */
#define I915_LOG_MIN_TEX_REGION_SIZE 14
typedef struct _drm_i915_init {
enum {
I915_INIT_DMA = 0x01,
I915_CLEANUP_DMA = 0x02,
I915_RESUME_DMA = 0x03
} func;
unsigned int mmio_offset;
int sarea_priv_offset;
unsigned int ring_start;
unsigned int ring_end;
unsigned int ring_size;
unsigned int front_offset;
unsigned int back_offset;
unsigned int depth_offset;
unsigned int w;
unsigned int h;
unsigned int pitch;
unsigned int pitch_bits;
unsigned int back_pitch;
unsigned int depth_pitch;
unsigned int cpp;
unsigned int chipset;
} drm_i915_init_t;
typedef struct _drm_i915_sarea {
struct drm_tex_region texList[I915_NR_TEX_REGIONS + 1];
int last_upload; /* last time texture was uploaded */
int last_enqueue; /* last time a buffer was enqueued */
int last_dispatch; /* age of the most recently dispatched buffer */
int ctxOwner; /* last context to upload state */
int texAge;
int pf_enabled; /* is pageflipping allowed? */
int pf_active;
int pf_current_page; /* which buffer is being displayed? */
int perf_boxes; /* performance boxes to be displayed */
int width, height; /* screen size in pixels */
drm_handle_t front_handle;
int front_offset;
int front_size;
drm_handle_t back_handle;
int back_offset;
int back_size;
drm_handle_t depth_handle;
int depth_offset;
int depth_size;
drm_handle_t tex_handle;
int tex_offset;
int tex_size;
int log_tex_granularity;
int pitch;
int rotation; /* 0, 90, 180 or 270 */
int rotated_offset;
int rotated_size;
int rotated_pitch;
int virtualX, virtualY;
unsigned int front_tiled;
unsigned int back_tiled;
unsigned int depth_tiled;
unsigned int rotated_tiled;
unsigned int rotated2_tiled;
int pipeA_x;
int pipeA_y;
int pipeA_w;
int pipeA_h;
int pipeB_x;
int pipeB_y;
int pipeB_w;
int pipeB_h;
/* fill out some space for old userspace triple buffer */
drm_handle_t unused_handle;
__u32 unused1, unused2, unused3;
/* buffer object handles for static buffers. May change
* over the lifetime of the client.
*/
__u32 front_bo_handle;
__u32 back_bo_handle;
__u32 unused_bo_handle;
__u32 depth_bo_handle;
} drm_i915_sarea_t;
/* due to userspace building against these headers we need some compat here */
#define planeA_x pipeA_x
#define planeA_y pipeA_y
#define planeA_w pipeA_w
#define planeA_h pipeA_h
#define planeB_x pipeB_x
#define planeB_y pipeB_y
#define planeB_w pipeB_w
#define planeB_h pipeB_h
/* Flags for perf_boxes
*/
#define I915_BOX_RING_EMPTY 0x1
#define I915_BOX_FLIP 0x2
#define I915_BOX_WAIT 0x4
#define I915_BOX_TEXTURE_LOAD 0x8
#define I915_BOX_LOST_CONTEXT 0x10
/*
* i915 specific ioctls.
*
* The device specific ioctl range is [DRM_COMMAND_BASE, DRM_COMMAND_END) ie
* [0x40, 0xa0) (a0 is excluded). The numbers below are defined as offset
* against DRM_COMMAND_BASE and should be between [0x0, 0x60).
*/
#define DRM_I915_INIT 0x00
#define DRM_I915_FLUSH 0x01
#define DRM_I915_FLIP 0x02
#define DRM_I915_BATCHBUFFER 0x03
#define DRM_I915_IRQ_EMIT 0x04
#define DRM_I915_IRQ_WAIT 0x05
#define DRM_I915_GETPARAM 0x06
#define DRM_I915_SETPARAM 0x07
#define DRM_I915_ALLOC 0x08
#define DRM_I915_FREE 0x09
#define DRM_I915_INIT_HEAP 0x0a
#define DRM_I915_CMDBUFFER 0x0b
#define DRM_I915_DESTROY_HEAP 0x0c
#define DRM_I915_SET_VBLANK_PIPE 0x0d
#define DRM_I915_GET_VBLANK_PIPE 0x0e
#define DRM_I915_VBLANK_SWAP 0x0f
#define DRM_I915_HWS_ADDR 0x11
#define DRM_I915_GEM_INIT 0x13
#define DRM_I915_GEM_EXECBUFFER 0x14
#define DRM_I915_GEM_PIN 0x15
#define DRM_I915_GEM_UNPIN 0x16
#define DRM_I915_GEM_BUSY 0x17
#define DRM_I915_GEM_THROTTLE 0x18
#define DRM_I915_GEM_ENTERVT 0x19
#define DRM_I915_GEM_LEAVEVT 0x1a
#define DRM_I915_GEM_CREATE 0x1b
#define DRM_I915_GEM_PREAD 0x1c
#define DRM_I915_GEM_PWRITE 0x1d
#define DRM_I915_GEM_MMAP 0x1e
#define DRM_I915_GEM_SET_DOMAIN 0x1f
#define DRM_I915_GEM_SW_FINISH 0x20
#define DRM_I915_GEM_SET_TILING 0x21
#define DRM_I915_GEM_GET_TILING 0x22
#define DRM_I915_GEM_GET_APERTURE 0x23
#define DRM_I915_GEM_MMAP_GTT 0x24
#define DRM_I915_GET_PIPE_FROM_CRTC_ID 0x25
#define DRM_I915_GEM_MADVISE 0x26
#define DRM_I915_OVERLAY_PUT_IMAGE 0x27
#define DRM_I915_OVERLAY_ATTRS 0x28
#define DRM_I915_GEM_EXECBUFFER2 0x29
#define DRM_I915_GEM_EXECBUFFER2_WR DRM_I915_GEM_EXECBUFFER2
#define DRM_I915_GET_SPRITE_COLORKEY 0x2a
#define DRM_I915_SET_SPRITE_COLORKEY 0x2b
#define DRM_I915_GEM_WAIT 0x2c
#define DRM_I915_GEM_CONTEXT_CREATE 0x2d
#define DRM_I915_GEM_CONTEXT_DESTROY 0x2e
#define DRM_I915_GEM_SET_CACHING 0x2f
#define DRM_I915_GEM_GET_CACHING 0x30
#define DRM_I915_REG_READ 0x31
#define DRM_I915_GET_RESET_STATS 0x32
#define DRM_I915_GEM_USERPTR 0x33
#define DRM_I915_GEM_CONTEXT_GETPARAM 0x34
#define DRM_I915_GEM_CONTEXT_SETPARAM 0x35
#define DRM_I915_PERF_OPEN 0x36
#define DRM_I915_PERF_ADD_CONFIG 0x37
#define DRM_I915_PERF_REMOVE_CONFIG 0x38
#define DRM_I915_QUERY 0x39
#define DRM_IOCTL_I915_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_I915_INIT, drm_i915_init_t)
#define DRM_IOCTL_I915_FLUSH DRM_IO ( DRM_COMMAND_BASE + DRM_I915_FLUSH)
#define DRM_IOCTL_I915_FLIP DRM_IO ( DRM_COMMAND_BASE + DRM_I915_FLIP)
#define DRM_IOCTL_I915_BATCHBUFFER DRM_IOW( DRM_COMMAND_BASE + DRM_I915_BATCHBUFFER, drm_i915_batchbuffer_t)
#define DRM_IOCTL_I915_IRQ_EMIT DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_IRQ_EMIT, drm_i915_irq_emit_t)
#define DRM_IOCTL_I915_IRQ_WAIT DRM_IOW( DRM_COMMAND_BASE + DRM_I915_IRQ_WAIT, drm_i915_irq_wait_t)
#define DRM_IOCTL_I915_GETPARAM DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GETPARAM, drm_i915_getparam_t)
#define DRM_IOCTL_I915_SETPARAM DRM_IOW( DRM_COMMAND_BASE + DRM_I915_SETPARAM, drm_i915_setparam_t)
#define DRM_IOCTL_I915_ALLOC DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_ALLOC, drm_i915_mem_alloc_t)
#define DRM_IOCTL_I915_FREE DRM_IOW( DRM_COMMAND_BASE + DRM_I915_FREE, drm_i915_mem_free_t)
#define DRM_IOCTL_I915_INIT_HEAP DRM_IOW( DRM_COMMAND_BASE + DRM_I915_INIT_HEAP, drm_i915_mem_init_heap_t)
#define DRM_IOCTL_I915_CMDBUFFER DRM_IOW( DRM_COMMAND_BASE + DRM_I915_CMDBUFFER, drm_i915_cmdbuffer_t)
#define DRM_IOCTL_I915_DESTROY_HEAP DRM_IOW( DRM_COMMAND_BASE + DRM_I915_DESTROY_HEAP, drm_i915_mem_destroy_heap_t)
#define DRM_IOCTL_I915_SET_VBLANK_PIPE DRM_IOW( DRM_COMMAND_BASE + DRM_I915_SET_VBLANK_PIPE, drm_i915_vblank_pipe_t)
#define DRM_IOCTL_I915_GET_VBLANK_PIPE DRM_IOR( DRM_COMMAND_BASE + DRM_I915_GET_VBLANK_PIPE, drm_i915_vblank_pipe_t)
#define DRM_IOCTL_I915_VBLANK_SWAP DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_VBLANK_SWAP, drm_i915_vblank_swap_t)
#define DRM_IOCTL_I915_HWS_ADDR DRM_IOW(DRM_COMMAND_BASE + DRM_I915_HWS_ADDR, struct drm_i915_gem_init)
#define DRM_IOCTL_I915_GEM_INIT DRM_IOW(DRM_COMMAND_BASE + DRM_I915_GEM_INIT, struct drm_i915_gem_init)
#define DRM_IOCTL_I915_GEM_EXECBUFFER DRM_IOW(DRM_COMMAND_BASE + DRM_I915_GEM_EXECBUFFER, struct drm_i915_gem_execbuffer)
#define DRM_IOCTL_I915_GEM_EXECBUFFER2 DRM_IOW(DRM_COMMAND_BASE + DRM_I915_GEM_EXECBUFFER2, struct drm_i915_gem_execbuffer2)
#define DRM_IOCTL_I915_GEM_EXECBUFFER2_WR DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_EXECBUFFER2_WR, struct drm_i915_gem_execbuffer2)
#define DRM_IOCTL_I915_GEM_PIN DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_PIN, struct drm_i915_gem_pin)
#define DRM_IOCTL_I915_GEM_UNPIN DRM_IOW(DRM_COMMAND_BASE + DRM_I915_GEM_UNPIN, struct drm_i915_gem_unpin)
#define DRM_IOCTL_I915_GEM_BUSY DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_BUSY, struct drm_i915_gem_busy)
#define DRM_IOCTL_I915_GEM_SET_CACHING DRM_IOW(DRM_COMMAND_BASE + DRM_I915_GEM_SET_CACHING, struct drm_i915_gem_caching)
#define DRM_IOCTL_I915_GEM_GET_CACHING DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_GET_CACHING, struct drm_i915_gem_caching)
#define DRM_IOCTL_I915_GEM_THROTTLE DRM_IO ( DRM_COMMAND_BASE + DRM_I915_GEM_THROTTLE)
#define DRM_IOCTL_I915_GEM_ENTERVT DRM_IO(DRM_COMMAND_BASE + DRM_I915_GEM_ENTERVT)
#define DRM_IOCTL_I915_GEM_LEAVEVT DRM_IO(DRM_COMMAND_BASE + DRM_I915_GEM_LEAVEVT)
#define DRM_IOCTL_I915_GEM_CREATE DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_CREATE, struct drm_i915_gem_create)
#define DRM_IOCTL_I915_GEM_PREAD DRM_IOW (DRM_COMMAND_BASE + DRM_I915_GEM_PREAD, struct drm_i915_gem_pread)
#define DRM_IOCTL_I915_GEM_PWRITE DRM_IOW (DRM_COMMAND_BASE + DRM_I915_GEM_PWRITE, struct drm_i915_gem_pwrite)
#define DRM_IOCTL_I915_GEM_MMAP DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_MMAP, struct drm_i915_gem_mmap)
#define DRM_IOCTL_I915_GEM_MMAP_GTT DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_MMAP_GTT, struct drm_i915_gem_mmap_gtt)
#define DRM_IOCTL_I915_GEM_SET_DOMAIN DRM_IOW (DRM_COMMAND_BASE + DRM_I915_GEM_SET_DOMAIN, struct drm_i915_gem_set_domain)
#define DRM_IOCTL_I915_GEM_SW_FINISH DRM_IOW (DRM_COMMAND_BASE + DRM_I915_GEM_SW_FINISH, struct drm_i915_gem_sw_finish)
#define DRM_IOCTL_I915_GEM_SET_TILING DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_GEM_SET_TILING, struct drm_i915_gem_set_tiling)
#define DRM_IOCTL_I915_GEM_GET_TILING DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_GEM_GET_TILING, struct drm_i915_gem_get_tiling)
#define DRM_IOCTL_I915_GEM_GET_APERTURE DRM_IOR (DRM_COMMAND_BASE + DRM_I915_GEM_GET_APERTURE, struct drm_i915_gem_get_aperture)
#define DRM_IOCTL_I915_GET_PIPE_FROM_CRTC_ID DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GET_PIPE_FROM_CRTC_ID, struct drm_i915_get_pipe_from_crtc_id)
#define DRM_IOCTL_I915_GEM_MADVISE DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_MADVISE, struct drm_i915_gem_madvise)
#define DRM_IOCTL_I915_OVERLAY_PUT_IMAGE DRM_IOW(DRM_COMMAND_BASE + DRM_I915_OVERLAY_PUT_IMAGE, struct drm_intel_overlay_put_image)
#define DRM_IOCTL_I915_OVERLAY_ATTRS DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_OVERLAY_ATTRS, struct drm_intel_overlay_attrs)
#define DRM_IOCTL_I915_SET_SPRITE_COLORKEY DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_SET_SPRITE_COLORKEY, struct drm_intel_sprite_colorkey)
#define DRM_IOCTL_I915_GET_SPRITE_COLORKEY DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GET_SPRITE_COLORKEY, struct drm_intel_sprite_colorkey)
#define DRM_IOCTL_I915_GEM_WAIT DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_WAIT, struct drm_i915_gem_wait)
#define DRM_IOCTL_I915_GEM_CONTEXT_CREATE DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_GEM_CONTEXT_CREATE, struct drm_i915_gem_context_create)
#define DRM_IOCTL_I915_GEM_CONTEXT_DESTROY DRM_IOW (DRM_COMMAND_BASE + DRM_I915_GEM_CONTEXT_DESTROY, struct drm_i915_gem_context_destroy)
#define DRM_IOCTL_I915_REG_READ DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_REG_READ, struct drm_i915_reg_read)
#define DRM_IOCTL_I915_GET_RESET_STATS DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_GET_RESET_STATS, struct drm_i915_reset_stats)
#define DRM_IOCTL_I915_GEM_USERPTR DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_GEM_USERPTR, struct drm_i915_gem_userptr)
#define DRM_IOCTL_I915_GEM_CONTEXT_GETPARAM DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_GEM_CONTEXT_GETPARAM, struct drm_i915_gem_context_param)
#define DRM_IOCTL_I915_GEM_CONTEXT_SETPARAM DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_GEM_CONTEXT_SETPARAM, struct drm_i915_gem_context_param)
#define DRM_IOCTL_I915_PERF_OPEN DRM_IOW(DRM_COMMAND_BASE + DRM_I915_PERF_OPEN, struct drm_i915_perf_open_param)
#define DRM_IOCTL_I915_PERF_ADD_CONFIG DRM_IOW(DRM_COMMAND_BASE + DRM_I915_PERF_ADD_CONFIG, struct drm_i915_perf_oa_config)
#define DRM_IOCTL_I915_PERF_REMOVE_CONFIG DRM_IOW(DRM_COMMAND_BASE + DRM_I915_PERF_REMOVE_CONFIG, __u64)
#define DRM_IOCTL_I915_QUERY DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_QUERY, struct drm_i915_query)
/* Allow drivers to submit batchbuffers directly to hardware, relying
* on the security mechanisms provided by hardware.
*/
typedef struct drm_i915_batchbuffer {
int start; /* agp offset */
int used; /* nr bytes in use */
int DR1; /* hw flags for GFX_OP_DRAWRECT_INFO */
int DR4; /* window origin for GFX_OP_DRAWRECT_INFO */
int num_cliprects; /* mulitpass with multiple cliprects? */
struct drm_clip_rect *cliprects; /* pointer to userspace cliprects */
} drm_i915_batchbuffer_t;
/* As above, but pass a pointer to userspace buffer which can be
* validated by the kernel prior to sending to hardware.
*/
typedef struct _drm_i915_cmdbuffer {
char *buf; /* pointer to userspace command buffer */
int sz; /* nr bytes in buf */
int DR1; /* hw flags for GFX_OP_DRAWRECT_INFO */
int DR4; /* window origin for GFX_OP_DRAWRECT_INFO */
int num_cliprects; /* mulitpass with multiple cliprects? */
struct drm_clip_rect *cliprects; /* pointer to userspace cliprects */
} drm_i915_cmdbuffer_t;
/* Userspace can request & wait on irq's:
*/
typedef struct drm_i915_irq_emit {
int *irq_seq;
} drm_i915_irq_emit_t;
typedef struct drm_i915_irq_wait {
int irq_seq;
} drm_i915_irq_wait_t;
/* Ioctl to query kernel params:
*/
#define I915_PARAM_IRQ_ACTIVE 1
#define I915_PARAM_ALLOW_BATCHBUFFER 2
#define I915_PARAM_LAST_DISPATCH 3
#define I915_PARAM_CHIPSET_ID 4
#define I915_PARAM_HAS_GEM 5
#define I915_PARAM_NUM_FENCES_AVAIL 6
#define I915_PARAM_HAS_OVERLAY 7
#define I915_PARAM_HAS_PAGEFLIPPING 8
#define I915_PARAM_HAS_EXECBUF2 9
#define I915_PARAM_HAS_BSD 10
#define I915_PARAM_HAS_BLT 11
#define I915_PARAM_HAS_RELAXED_FENCING 12
#define I915_PARAM_HAS_COHERENT_RINGS 13
#define I915_PARAM_HAS_EXEC_CONSTANTS 14
#define I915_PARAM_HAS_RELAXED_DELTA 15
#define I915_PARAM_HAS_GEN7_SOL_RESET 16
#define I915_PARAM_HAS_LLC 17
#define I915_PARAM_HAS_ALIASING_PPGTT 18
#define I915_PARAM_HAS_WAIT_TIMEOUT 19
#define I915_PARAM_HAS_SEMAPHORES 20
#define I915_PARAM_HAS_PRIME_VMAP_FLUSH 21
#define I915_PARAM_HAS_VEBOX 22
#define I915_PARAM_HAS_SECURE_BATCHES 23
#define I915_PARAM_HAS_PINNED_BATCHES 24
#define I915_PARAM_HAS_EXEC_NO_RELOC 25
#define I915_PARAM_HAS_EXEC_HANDLE_LUT 26
#define I915_PARAM_HAS_WT 27
#define I915_PARAM_CMD_PARSER_VERSION 28
#define I915_PARAM_HAS_COHERENT_PHYS_GTT 29
#define I915_PARAM_MMAP_VERSION 30
#define I915_PARAM_HAS_BSD2 31
#define I915_PARAM_REVISION 32
#define I915_PARAM_SUBSLICE_TOTAL 33
#define I915_PARAM_EU_TOTAL 34
#define I915_PARAM_HAS_GPU_RESET 35
#define I915_PARAM_HAS_RESOURCE_STREAMER 36
#define I915_PARAM_HAS_EXEC_SOFTPIN 37
#define I915_PARAM_HAS_POOLED_EU 38
#define I915_PARAM_MIN_EU_IN_POOL 39
#define I915_PARAM_MMAP_GTT_VERSION 40
/*
* Query whether DRM_I915_GEM_EXECBUFFER2 supports user defined execution
* priorities and the driver will attempt to execute batches in priority order.
* The param returns a capability bitmask, nonzero implies that the scheduler
* is enabled, with different features present according to the mask.
*
* The initial priority for each batch is supplied by the context and is
* controlled via I915_CONTEXT_PARAM_PRIORITY.
*/
#define I915_PARAM_HAS_SCHEDULER 41
#define I915_SCHEDULER_CAP_ENABLED (1ul << 0)
#define I915_SCHEDULER_CAP_PRIORITY (1ul << 1)
#define I915_SCHEDULER_CAP_PREEMPTION (1ul << 2)
#define I915_PARAM_HUC_STATUS 42
/* Query whether DRM_I915_GEM_EXECBUFFER2 supports the ability to opt-out of
* synchronisation with implicit fencing on individual objects.
* See EXEC_OBJECT_ASYNC.
*/
#define I915_PARAM_HAS_EXEC_ASYNC 43
/* Query whether DRM_I915_GEM_EXECBUFFER2 supports explicit fence support -
* both being able to pass in a sync_file fd to wait upon before executing,
* and being able to return a new sync_file fd that is signaled when the
* current request is complete. See I915_EXEC_FENCE_IN and I915_EXEC_FENCE_OUT.
*/
#define I915_PARAM_HAS_EXEC_FENCE 44
/* Query whether DRM_I915_GEM_EXECBUFFER2 supports the ability to capture
* user specified bufffers for post-mortem debugging of GPU hangs. See
* EXEC_OBJECT_CAPTURE.
*/
#define I915_PARAM_HAS_EXEC_CAPTURE 45
#define I915_PARAM_SLICE_MASK 46
/* Assuming it's uniform for each slice, this queries the mask of subslices
* per-slice for this system.
*/
#define I915_PARAM_SUBSLICE_MASK 47
/*
* Query whether DRM_I915_GEM_EXECBUFFER2 supports supplying the batch buffer
* as the first execobject as opposed to the last. See I915_EXEC_BATCH_FIRST.
*/
#define I915_PARAM_HAS_EXEC_BATCH_FIRST 48
/* Query whether DRM_I915_GEM_EXECBUFFER2 supports supplying an array of
* drm_i915_gem_exec_fence structures. See I915_EXEC_FENCE_ARRAY.
*/
#define I915_PARAM_HAS_EXEC_FENCE_ARRAY 49
/*
* Query whether every context (both per-file default and user created) is
* isolated (insofar as HW supports). If this parameter is not true, then
* freshly created contexts may inherit values from an existing context,
* rather than default HW values. If true, it also ensures (insofar as HW
* supports) that all state set by this context will not leak to any other
* context.
*
* As not every engine across every gen support contexts, the returned
* value reports the support of context isolation for individual engines by
* returning a bitmask of each engine class set to true if that class supports
* isolation.
*/
#define I915_PARAM_HAS_CONTEXT_ISOLATION 50
/* Frequency of the command streamer timestamps given by the *_TIMESTAMP
* registers. This used to be fixed per platform but from CNL onwards, this
* might vary depending on the parts.
*/
#define I915_PARAM_CS_TIMESTAMP_FREQUENCY 51
typedef struct drm_i915_getparam {
__s32 param;
/*
* WARNING: Using pointers instead of fixed-size u64 means we need to write
* compat32 code. Don't repeat this mistake.
*/
int *value;
} drm_i915_getparam_t;
/* Ioctl to set kernel params:
*/
#define I915_SETPARAM_USE_MI_BATCHBUFFER_START 1
#define I915_SETPARAM_TEX_LRU_LOG_GRANULARITY 2
#define I915_SETPARAM_ALLOW_BATCHBUFFER 3
#define I915_SETPARAM_NUM_USED_FENCES 4
typedef struct drm_i915_setparam {
int param;
int value;
} drm_i915_setparam_t;
/* A memory manager for regions of shared memory:
*/
#define I915_MEM_REGION_AGP 1
typedef struct drm_i915_mem_alloc {
int region;
int alignment;
int size;
int *region_offset; /* offset from start of fb or agp */
} drm_i915_mem_alloc_t;
typedef struct drm_i915_mem_free {
int region;
int region_offset;
} drm_i915_mem_free_t;
typedef struct drm_i915_mem_init_heap {
int region;
int size;
int start;
} drm_i915_mem_init_heap_t;
/* Allow memory manager to be torn down and re-initialized (eg on
* rotate):
*/
typedef struct drm_i915_mem_destroy_heap {
int region;
} drm_i915_mem_destroy_heap_t;
/* Allow X server to configure which pipes to monitor for vblank signals
*/
#define DRM_I915_VBLANK_PIPE_A 1
#define DRM_I915_VBLANK_PIPE_B 2
typedef struct drm_i915_vblank_pipe {
int pipe;
} drm_i915_vblank_pipe_t;
/* Schedule buffer swap at given vertical blank:
*/
typedef struct drm_i915_vblank_swap {
drm_drawable_t drawable;
enum drm_vblank_seq_type seqtype;
unsigned int sequence;
} drm_i915_vblank_swap_t;
typedef struct drm_i915_hws_addr {
__u64 addr;
} drm_i915_hws_addr_t;
struct drm_i915_gem_init {
/**
* Beginning offset in the GTT to be managed by the DRM memory
* manager.
*/
__u64 gtt_start;
/**
* Ending offset in the GTT to be managed by the DRM memory
* manager.
*/
__u64 gtt_end;
};
struct drm_i915_gem_create {
/**
* Requested size for the object.
*
* The (page-aligned) allocated size for the object will be returned.
*/
__u64 size;
/**
* Returned handle for the object.
*
* Object handles are nonzero.
*/
__u32 handle;
__u32 pad;
};
struct drm_i915_gem_pread {
/** Handle for the object being read. */
__u32 handle;
__u32 pad;
/** Offset into the object to read from */
__u64 offset;
/** Length of data to read */
__u64 size;
/**
* Pointer to write the data into.
*
* This is a fixed-size type for 32/64 compatibility.
*/
__u64 data_ptr;
};
struct drm_i915_gem_pwrite {
/** Handle for the object being written to. */
__u32 handle;
__u32 pad;
/** Offset into the object to write to */
__u64 offset;
/** Length of data to write */
__u64 size;
/**
* Pointer to read the data from.
*
* This is a fixed-size type for 32/64 compatibility.
*/
__u64 data_ptr;
};
struct drm_i915_gem_mmap {
/** Handle for the object being mapped. */
__u32 handle;
__u32 pad;
/** Offset in the object to map. */
__u64 offset;
/**
* Length of data to map.
*
* The value will be page-aligned.
*/
__u64 size;
/**
* Returned pointer the data was mapped at.
*
* This is a fixed-size type for 32/64 compatibility.
*/
__u64 addr_ptr;
/**
* Flags for extended behaviour.
*
* Added in version 2.
*/
__u64 flags;
#define I915_MMAP_WC 0x1
};
struct drm_i915_gem_mmap_gtt {
/** Handle for the object being mapped. */
__u32 handle;
__u32 pad;
/**
* Fake offset to use for subsequent mmap call
*
* This is a fixed-size type for 32/64 compatibility.
*/
__u64 offset;
};
struct drm_i915_gem_set_domain {
/** Handle for the object */
__u32 handle;
/** New read domains */
__u32 read_domains;
/** New write domain */
__u32 write_domain;
};
struct drm_i915_gem_sw_finish {
/** Handle for the object */
__u32 handle;
};
struct drm_i915_gem_relocation_entry {
/**
* Handle of the buffer being pointed to by this relocation entry.
*
* It's appealing to make this be an index into the mm_validate_entry
* list to refer to the buffer, but this allows the driver to create
* a relocation list for state buffers and not re-write it per
* exec using the buffer.
*/
__u32 target_handle;
/**
* Value to be added to the offset of the target buffer to make up
* the relocation entry.
*/
__u32 delta;
/** Offset in the buffer the relocation entry will be written into */
__u64 offset;
/**
* Offset value of the target buffer that the relocation entry was last
* written as.
*
* If the buffer has the same offset as last time, we can skip syncing
* and writing the relocation. This value is written back out by
* the execbuffer ioctl when the relocation is written.
*/
__u64 presumed_offset;
/**
* Target memory domains read by this operation.
*/
__u32 read_domains;
/**
* Target memory domains written by this operation.
*
* Note that only one domain may be written by the whole
* execbuffer operation, so that where there are conflicts,
* the application will get -EINVAL back.
*/
__u32 write_domain;
};
/** @{
* Intel memory domains
*
* Most of these just align with the various caches in
* the system and are used to flush and invalidate as
* objects end up cached in different domains.
*/
/** CPU cache */
#define I915_GEM_DOMAIN_CPU 0x00000001
/** Render cache, used by 2D and 3D drawing */
#define I915_GEM_DOMAIN_RENDER 0x00000002
/** Sampler cache, used by texture engine */
#define I915_GEM_DOMAIN_SAMPLER 0x00000004
/** Command queue, used to load batch buffers */
#define I915_GEM_DOMAIN_COMMAND 0x00000008
/** Instruction cache, used by shader programs */
#define I915_GEM_DOMAIN_INSTRUCTION 0x00000010
/** Vertex address cache */
#define I915_GEM_DOMAIN_VERTEX 0x00000020
/** GTT domain - aperture and scanout */
#define I915_GEM_DOMAIN_GTT 0x00000040
/** WC domain - uncached access */
#define I915_GEM_DOMAIN_WC 0x00000080
/** @} */
struct drm_i915_gem_exec_object {
/**
* User's handle for a buffer to be bound into the GTT for this
* operation.
*/
__u32 handle;
/** Number of relocations to be performed on this buffer */
__u32 relocation_count;
/**
* Pointer to array of struct drm_i915_gem_relocation_entry containing
* the relocations to be performed in this buffer.
*/
__u64 relocs_ptr;
/** Required alignment in graphics aperture */
__u64 alignment;
/**
* Returned value of the updated offset of the object, for future
* presumed_offset writes.
*/
__u64 offset;
};
struct drm_i915_gem_execbuffer {
/**
* List of buffers to be validated with their relocations to be
* performend on them.
*
* This is a pointer to an array of struct drm_i915_gem_validate_entry.
*
* These buffers must be listed in an order such that all relocations
* a buffer is performing refer to buffers that have already appeared
* in the validate list.
*/
__u64 buffers_ptr;
__u32 buffer_count;
/** Offset in the batchbuffer to start execution from. */
__u32 batch_start_offset;
/** Bytes used in batchbuffer from batch_start_offset */
__u32 batch_len;
__u32 DR1;
__u32 DR4;
__u32 num_cliprects;
/** This is a struct drm_clip_rect *cliprects */
__u64 cliprects_ptr;
};
struct drm_i915_gem_exec_object2 {
/**
* User's handle for a buffer to be bound into the GTT for this
* operation.
*/
__u32 handle;
/** Number of relocations to be performed on this buffer */
__u32 relocation_count;
/**
* Pointer to array of struct drm_i915_gem_relocation_entry containing
* the relocations to be performed in this buffer.
*/
__u64 relocs_ptr;
/** Required alignment in graphics aperture */
__u64 alignment;
/**
* When the EXEC_OBJECT_PINNED flag is specified this is populated by
* the user with the GTT offset at which this object will be pinned.
* When the I915_EXEC_NO_RELOC flag is specified this must contain the
* presumed_offset of the object.
* During execbuffer2 the kernel populates it with the value of the
* current GTT offset of the object, for future presumed_offset writes.
*/
__u64 offset;
#define EXEC_OBJECT_NEEDS_FENCE (1<<0)
#define EXEC_OBJECT_NEEDS_GTT (1<<1)
#define EXEC_OBJECT_WRITE (1<<2)
#define EXEC_OBJECT_SUPPORTS_48B_ADDRESS (1<<3)
#define EXEC_OBJECT_PINNED (1<<4)
#define EXEC_OBJECT_PAD_TO_SIZE (1<<5)
/* The kernel implicitly tracks GPU activity on all GEM objects, and
* synchronises operations with outstanding rendering. This includes
* rendering on other devices if exported via dma-buf. However, sometimes
* this tracking is too coarse and the user knows better. For example,
* if the object is split into non-overlapping ranges shared between different
* clients or engines (i.e. suballocating objects), the implicit tracking
* by kernel assumes that each operation affects the whole object rather
* than an individual range, causing needless synchronisation between clients.
* The kernel will also forgo any CPU cache flushes prior to rendering from
* the object as the client is expected to be also handling such domain
* tracking.
*
* The kernel maintains the implicit tracking in order to manage resources
* used by the GPU - this flag only disables the synchronisation prior to
* rendering with this object in this execbuf.
*
* Opting out of implicit synhronisation requires the user to do its own
* explicit tracking to avoid rendering corruption. See, for example,
* I915_PARAM_HAS_EXEC_FENCE to order execbufs and execute them asynchronously.
*/
#define EXEC_OBJECT_ASYNC (1<<6)
/* Request that the contents of this execobject be copied into the error
* state upon a GPU hang involving this batch for post-mortem debugging.
* These buffers are recorded in no particular order as "user" in
* /sys/class/drm/cardN/error. Query I915_PARAM_HAS_EXEC_CAPTURE to see
* if the kernel supports this flag.
*/
#define EXEC_OBJECT_CAPTURE (1<<7)
/* All remaining bits are MBZ and RESERVED FOR FUTURE USE */
#define __EXEC_OBJECT_UNKNOWN_FLAGS -(EXEC_OBJECT_CAPTURE<<1)
__u64 flags;
union {
__u64 rsvd1;
__u64 pad_to_size;
};
__u64 rsvd2;
};
struct drm_i915_gem_exec_fence {
/**
* User's handle for a drm_syncobj to wait on or signal.
*/
__u32 handle;
#define I915_EXEC_FENCE_WAIT (1<<0)
#define I915_EXEC_FENCE_SIGNAL (1<<1)
#define __I915_EXEC_FENCE_UNKNOWN_FLAGS (-(I915_EXEC_FENCE_SIGNAL << 1))
__u32 flags;
};
struct drm_i915_gem_execbuffer2 {
/**
* List of gem_exec_object2 structs
*/
__u64 buffers_ptr;
__u32 buffer_count;
/** Offset in the batchbuffer to start execution from. */
__u32 batch_start_offset;
/** Bytes used in batchbuffer from batch_start_offset */
__u32 batch_len;
__u32 DR1;
__u32 DR4;
__u32 num_cliprects;
/**
* This is a struct drm_clip_rect *cliprects if I915_EXEC_FENCE_ARRAY
* is not set. If I915_EXEC_FENCE_ARRAY is set, then this is a
* struct drm_i915_gem_exec_fence *fences.
*/
__u64 cliprects_ptr;
#define I915_EXEC_RING_MASK (7<<0)
#define I915_EXEC_DEFAULT (0<<0)
#define I915_EXEC_RENDER (1<<0)
#define I915_EXEC_BSD (2<<0)
#define I915_EXEC_BLT (3<<0)
#define I915_EXEC_VEBOX (4<<0)
/* Used for switching the constants addressing mode on gen4+ RENDER ring.
* Gen6+ only supports relative addressing to dynamic state (default) and
* absolute addressing.
*
* These flags are ignored for the BSD and BLT rings.
*/
#define I915_EXEC_CONSTANTS_MASK (3<<6)
#define I915_EXEC_CONSTANTS_REL_GENERAL (0<<6) /* default */
#define I915_EXEC_CONSTANTS_ABSOLUTE (1<<6)
#define I915_EXEC_CONSTANTS_REL_SURFACE (2<<6) /* gen4/5 only */
__u64 flags;
__u64 rsvd1; /* now used for context info */
__u64 rsvd2;
};
/** Resets the SO write offset registers for transform feedback on gen7. */
#define I915_EXEC_GEN7_SOL_RESET (1<<8)
/** Request a privileged ("secure") batch buffer. Note only available for
* DRM_ROOT_ONLY | DRM_MASTER processes.
*/
#define I915_EXEC_SECURE (1<<9)
/** Inform the kernel that the batch is and will always be pinned. This
* negates the requirement for a workaround to be performed to avoid
* an incoherent CS (such as can be found on 830/845). If this flag is
* not passed, the kernel will endeavour to make sure the batch is
* coherent with the CS before execution. If this flag is passed,
* userspace assumes the responsibility for ensuring the same.
*/
#define I915_EXEC_IS_PINNED (1<<10)
/** Provide a hint to the kernel that the command stream and auxiliary
* state buffers already holds the correct presumed addresses and so the
* relocation process may be skipped if no buffers need to be moved in
* preparation for the execbuffer.
*/
#define I915_EXEC_NO_RELOC (1<<11)
/** Use the reloc.handle as an index into the exec object array rather
* than as the per-file handle.
*/
#define I915_EXEC_HANDLE_LUT (1<<12)
/** Used for switching BSD rings on the platforms with two BSD rings */
#define I915_EXEC_BSD_SHIFT (13)
#define I915_EXEC_BSD_MASK (3 << I915_EXEC_BSD_SHIFT)
/* default ping-pong mode */
#define I915_EXEC_BSD_DEFAULT (0 << I915_EXEC_BSD_SHIFT)
#define I915_EXEC_BSD_RING1 (1 << I915_EXEC_BSD_SHIFT)
#define I915_EXEC_BSD_RING2 (2 << I915_EXEC_BSD_SHIFT)
/** Tell the kernel that the batchbuffer is processed by
* the resource streamer.
*/
#define I915_EXEC_RESOURCE_STREAMER (1<<15)
/* Setting I915_EXEC_FENCE_IN implies that lower_32_bits(rsvd2) represent
* a sync_file fd to wait upon (in a nonblocking manner) prior to executing
* the batch.
*
* Returns -EINVAL if the sync_file fd cannot be found.
*/
#define I915_EXEC_FENCE_IN (1<<16)
/* Setting I915_EXEC_FENCE_OUT causes the ioctl to return a sync_file fd
* in the upper_32_bits(rsvd2) upon success. Ownership of the fd is given
* to the caller, and it should be close() after use. (The fd is a regular
* file descriptor and will be cleaned up on process termination. It holds
* a reference to the request, but nothing else.)
*
* The sync_file fd can be combined with other sync_file and passed either
* to execbuf using I915_EXEC_FENCE_IN, to atomic KMS ioctls (so that a flip
* will only occur after this request completes), or to other devices.
*
* Using I915_EXEC_FENCE_OUT requires use of
* DRM_IOCTL_I915_GEM_EXECBUFFER2_WR ioctl so that the result is written
* back to userspace. Failure to do so will cause the out-fence to always
* be reported as zero, and the real fence fd to be leaked.
*/
#define I915_EXEC_FENCE_OUT (1<<17)
/*
* Traditionally the execbuf ioctl has only considered the final element in
* the execobject[] to be the executable batch. Often though, the client
* will known the batch object prior to construction and being able to place
* it into the execobject[] array first can simplify the relocation tracking.
* Setting I915_EXEC_BATCH_FIRST tells execbuf to use element 0 of the
* execobject[] as the * batch instead (the default is to use the last
* element).
*/
#define I915_EXEC_BATCH_FIRST (1<<18)
/* Setting I915_FENCE_ARRAY implies that num_cliprects and cliprects_ptr
* define an array of i915_gem_exec_fence structures which specify a set of
* dma fences to wait upon or signal.
*/
#define I915_EXEC_FENCE_ARRAY (1<<19)
#define __I915_EXEC_UNKNOWN_FLAGS (-(I915_EXEC_FENCE_ARRAY<<1))
#define I915_EXEC_CONTEXT_ID_MASK (0xffffffff)
#define i915_execbuffer2_set_context_id(eb2, context) \
(eb2).rsvd1 = context & I915_EXEC_CONTEXT_ID_MASK
#define i915_execbuffer2_get_context_id(eb2) \
((eb2).rsvd1 & I915_EXEC_CONTEXT_ID_MASK)
struct drm_i915_gem_pin {
/** Handle of the buffer to be pinned. */
__u32 handle;
__u32 pad;
/** alignment required within the aperture */
__u64 alignment;
/** Returned GTT offset of the buffer. */
__u64 offset;
};
struct drm_i915_gem_unpin {
/** Handle of the buffer to be unpinned. */
__u32 handle;
__u32 pad;
};
struct drm_i915_gem_busy {
/** Handle of the buffer to check for busy */
__u32 handle;
/** Return busy status
*
* A return of 0 implies that the object is idle (after
* having flushed any pending activity), and a non-zero return that
* the object is still in-flight on the GPU. (The GPU has not yet
* signaled completion for all pending requests that reference the
* object.) An object is guaranteed to become idle eventually (so
* long as no new GPU commands are executed upon it). Due to the
* asynchronous nature of the hardware, an object reported
* as busy may become idle before the ioctl is completed.
*
* Furthermore, if the object is busy, which engine is busy is only
* provided as a guide. There are race conditions which prevent the
* report of which engines are busy from being always accurate.
* However, the converse is not true. If the object is idle, the
* result of the ioctl, that all engines are idle, is accurate.
*
* The returned dword is split into two fields to indicate both
* the engines on which the object is being read, and the
* engine on which it is currently being written (if any).
*
* The low word (bits 0:15) indicate if the object is being written
* to by any engine (there can only be one, as the GEM implicit
* synchronisation rules force writes to be serialised). Only the
* engine for the last write is reported.
*
* The high word (bits 16:31) are a bitmask of which engines are
* currently reading from the object. Multiple engines may be
* reading from the object simultaneously.
*
* The value of each engine is the same as specified in the
* EXECBUFFER2 ioctl, i.e. I915_EXEC_RENDER, I915_EXEC_BSD etc.
* Note I915_EXEC_DEFAULT is a symbolic value and is mapped to
* the I915_EXEC_RENDER engine for execution, and so it is never
* reported as active itself. Some hardware may have parallel
* execution engines, e.g. multiple media engines, which are
* mapped to the same identifier in the EXECBUFFER2 ioctl and
* so are not separately reported for busyness.
*
* Caveat emptor:
* Only the boolean result of this query is reliable; that is whether
* the object is idle or busy. The report of which engines are busy
* should be only used as a heuristic.
*/
__u32 busy;
};
/**
* I915_CACHING_NONE
*
* GPU access is not coherent with cpu caches. Default for machines without an
* LLC.
*/
#define I915_CACHING_NONE 0
/**
* I915_CACHING_CACHED
*
* GPU access is coherent with cpu caches and furthermore the data is cached in
* last-level caches shared between cpu cores and the gpu GT. Default on
* machines with HAS_LLC.
*/
#define I915_CACHING_CACHED 1
/**
* I915_CACHING_DISPLAY
*
* Special GPU caching mode which is coherent with the scanout engines.
* Transparently falls back to I915_CACHING_NONE on platforms where no special
* cache mode (like write-through or gfdt flushing) is available. The kernel
* automatically sets this mode when using a buffer as a scanout target.
* Userspace can manually set this mode to avoid a costly stall and clflush in
* the hotpath of drawing the first frame.
*/
#define I915_CACHING_DISPLAY 2
struct drm_i915_gem_caching {
/**
* Handle of the buffer to set/get the caching level of. */
__u32 handle;
/**
* Cacheing level to apply or return value
*
* bits0-15 are for generic caching control (i.e. the above defined
* values). bits16-31 are reserved for platform-specific variations
* (e.g. l3$ caching on gen7). */
__u32 caching;
};
#define I915_TILING_NONE 0
#define I915_TILING_X 1
#define I915_TILING_Y 2
#define I915_TILING_LAST I915_TILING_Y
#define I915_BIT_6_SWIZZLE_NONE 0
#define I915_BIT_6_SWIZZLE_9 1
#define I915_BIT_6_SWIZZLE_9_10 2
#define I915_BIT_6_SWIZZLE_9_11 3
#define I915_BIT_6_SWIZZLE_9_10_11 4
/* Not seen by userland */
#define I915_BIT_6_SWIZZLE_UNKNOWN 5
/* Seen by userland. */
#define I915_BIT_6_SWIZZLE_9_17 6
#define I915_BIT_6_SWIZZLE_9_10_17 7
struct drm_i915_gem_set_tiling {
/** Handle of the buffer to have its tiling state updated */
__u32 handle;
/**
* Tiling mode for the object (I915_TILING_NONE, I915_TILING_X,
* I915_TILING_Y).
*
* This value is to be set on request, and will be updated by the
* kernel on successful return with the actual chosen tiling layout.
*
* The tiling mode may be demoted to I915_TILING_NONE when the system
* has bit 6 swizzling that can't be managed correctly by GEM.
*
* Buffer contents become undefined when changing tiling_mode.
*/
__u32 tiling_mode;
/**
* Stride in bytes for the object when in I915_TILING_X or
* I915_TILING_Y.
*/
__u32 stride;
/**
* Returned address bit 6 swizzling required for CPU access through
* mmap mapping.
*/
__u32 swizzle_mode;
};
struct drm_i915_gem_get_tiling {
/** Handle of the buffer to get tiling state for. */
__u32 handle;
/**
* Current tiling mode for the object (I915_TILING_NONE, I915_TILING_X,
* I915_TILING_Y).
*/
__u32 tiling_mode;
/**
* Returned address bit 6 swizzling required for CPU access through
* mmap mapping.
*/
__u32 swizzle_mode;
/**
* Returned address bit 6 swizzling required for CPU access through
* mmap mapping whilst bound.
*/
__u32 phys_swizzle_mode;
};
struct drm_i915_gem_get_aperture {
/** Total size of the aperture used by i915_gem_execbuffer, in bytes */
__u64 aper_size;
/**
* Available space in the aperture used by i915_gem_execbuffer, in
* bytes
*/
__u64 aper_available_size;
};
struct drm_i915_get_pipe_from_crtc_id {
/** ID of CRTC being requested **/
__u32 crtc_id;
/** pipe of requested CRTC **/
__u32 pipe;
};
#define I915_MADV_WILLNEED 0
#define I915_MADV_DONTNEED 1
#define __I915_MADV_PURGED 2 /* internal state */
struct drm_i915_gem_madvise {
/** Handle of the buffer to change the backing store advice */
__u32 handle;
/* Advice: either the buffer will be needed again in the near future,
* or wont be and could be discarded under memory pressure.
*/
__u32 madv;
/** Whether the backing store still exists. */
__u32 retained;
};
/* flags */
#define I915_OVERLAY_TYPE_MASK 0xff
#define I915_OVERLAY_YUV_PLANAR 0x01
#define I915_OVERLAY_YUV_PACKED 0x02
#define I915_OVERLAY_RGB 0x03
#define I915_OVERLAY_DEPTH_MASK 0xff00
#define I915_OVERLAY_RGB24 0x1000
#define I915_OVERLAY_RGB16 0x2000
#define I915_OVERLAY_RGB15 0x3000
#define I915_OVERLAY_YUV422 0x0100
#define I915_OVERLAY_YUV411 0x0200
#define I915_OVERLAY_YUV420 0x0300
#define I915_OVERLAY_YUV410 0x0400
#define I915_OVERLAY_SWAP_MASK 0xff0000
#define I915_OVERLAY_NO_SWAP 0x000000
#define I915_OVERLAY_UV_SWAP 0x010000
#define I915_OVERLAY_Y_SWAP 0x020000
#define I915_OVERLAY_Y_AND_UV_SWAP 0x030000
#define I915_OVERLAY_FLAGS_MASK 0xff000000
#define I915_OVERLAY_ENABLE 0x01000000
struct drm_intel_overlay_put_image {
/* various flags and src format description */
__u32 flags;
/* source picture description */
__u32 bo_handle;
/* stride values and offsets are in bytes, buffer relative */
__u16 stride_Y; /* stride for packed formats */
__u16 stride_UV;
__u32 offset_Y; /* offset for packet formats */
__u32 offset_U;
__u32 offset_V;
/* in pixels */
__u16 src_width;
__u16 src_height;
/* to compensate the scaling factors for partially covered surfaces */
__u16 src_scan_width;
__u16 src_scan_height;
/* output crtc description */
__u32 crtc_id;
__u16 dst_x;
__u16 dst_y;
__u16 dst_width;
__u16 dst_height;
};
/* flags */
#define I915_OVERLAY_UPDATE_ATTRS (1<<0)
#define I915_OVERLAY_UPDATE_GAMMA (1<<1)
#define I915_OVERLAY_DISABLE_DEST_COLORKEY (1<<2)
struct drm_intel_overlay_attrs {
__u32 flags;
__u32 color_key;
__s32 brightness;
__u32 contrast;
__u32 saturation;
__u32 gamma0;
__u32 gamma1;
__u32 gamma2;
__u32 gamma3;
__u32 gamma4;
__u32 gamma5;
};
/*
* Intel sprite handling
*
* Color keying works with a min/mask/max tuple. Both source and destination
* color keying is allowed.
*
* Source keying:
* Sprite pixels within the min & max values, masked against the color channels
* specified in the mask field, will be transparent. All other pixels will
* be displayed on top of the primary plane. For RGB surfaces, only the min
* and mask fields will be used; ranged compares are not allowed.
*
* Destination keying:
* Primary plane pixels that match the min value, masked against the color
* channels specified in the mask field, will be replaced by corresponding
* pixels from the sprite plane.
*
* Note that source & destination keying are exclusive; only one can be
* active on a given plane.
*/
#define I915_SET_COLORKEY_NONE (1<<0) /* Deprecated. Instead set
* flags==0 to disable colorkeying.
*/
#define I915_SET_COLORKEY_DESTINATION (1<<1)
#define I915_SET_COLORKEY_SOURCE (1<<2)
struct drm_intel_sprite_colorkey {
__u32 plane_id;
__u32 min_value;
__u32 channel_mask;
__u32 max_value;
__u32 flags;
};
struct drm_i915_gem_wait {
/** Handle of BO we shall wait on */
__u32 bo_handle;
__u32 flags;
/** Number of nanoseconds to wait, Returns time remaining. */
__s64 timeout_ns;
};
struct drm_i915_gem_context_create {
/* output: id of new context*/
__u32 ctx_id;
__u32 pad;
};
struct drm_i915_gem_context_destroy {
__u32 ctx_id;
__u32 pad;
};
struct drm_i915_reg_read {
/*
* Register offset.
* For 64bit wide registers where the upper 32bits don't immediately
* follow the lower 32bits, the offset of the lower 32bits must
* be specified
*/
__u64 offset;
#define I915_REG_READ_8B_WA (1ul << 0)
__u64 val; /* Return value */
};
/* Known registers:
*
* Render engine timestamp - 0x2358 + 64bit - gen7+
* - Note this register returns an invalid value if using the default
* single instruction 8byte read, in order to workaround that pass
* flag I915_REG_READ_8B_WA in offset field.
*
*/
struct drm_i915_reset_stats {
__u32 ctx_id;
__u32 flags;
/* All resets since boot/module reload, for all contexts */
__u32 reset_count;
/* Number of batches lost when active in GPU, for this context */
__u32 batch_active;
/* Number of batches lost pending for execution, for this context */
__u32 batch_pending;
__u32 pad;
};
struct drm_i915_gem_userptr {
__u64 user_ptr;
__u64 user_size;
__u32 flags;
#define I915_USERPTR_READ_ONLY 0x1
#define I915_USERPTR_UNSYNCHRONIZED 0x80000000
/**
* Returned handle for the object.
*
* Object handles are nonzero.
*/
__u32 handle;
};
struct drm_i915_gem_context_param {
__u32 ctx_id;
__u32 size;
__u64 param;
#define I915_CONTEXT_PARAM_BAN_PERIOD 0x1
#define I915_CONTEXT_PARAM_NO_ZEROMAP 0x2
#define I915_CONTEXT_PARAM_GTT_SIZE 0x3
#define I915_CONTEXT_PARAM_NO_ERROR_CAPTURE 0x4
#define I915_CONTEXT_PARAM_BANNABLE 0x5
#define I915_CONTEXT_PARAM_PRIORITY 0x6
#define I915_CONTEXT_MAX_USER_PRIORITY 1023 /* inclusive */
#define I915_CONTEXT_DEFAULT_PRIORITY 0
#define I915_CONTEXT_MIN_USER_PRIORITY -1023 /* inclusive */
__u64 value;
};
enum drm_i915_oa_format {
I915_OA_FORMAT_A13 = 1, /* HSW only */
I915_OA_FORMAT_A29, /* HSW only */
I915_OA_FORMAT_A13_B8_C8, /* HSW only */
I915_OA_FORMAT_B4_C8, /* HSW only */
I915_OA_FORMAT_A45_B8_C8, /* HSW only */
I915_OA_FORMAT_B4_C8_A16, /* HSW only */
I915_OA_FORMAT_C4_B8, /* HSW+ */
/* Gen8+ */
I915_OA_FORMAT_A12,
I915_OA_FORMAT_A12_B8_C8,
I915_OA_FORMAT_A32u40_A4u32_B8_C8,
I915_OA_FORMAT_MAX /* non-ABI */
};
enum drm_i915_perf_property_id {
/**
* Open the stream for a specific context handle (as used with
* execbuffer2). A stream opened for a specific context this way
* won't typically require root privileges.
*/
DRM_I915_PERF_PROP_CTX_HANDLE = 1,
/**
* A value of 1 requests the inclusion of raw OA unit reports as
* part of stream samples.
*/
DRM_I915_PERF_PROP_SAMPLE_OA,
/**
* The value specifies which set of OA unit metrics should be
* be configured, defining the contents of any OA unit reports.
*/
DRM_I915_PERF_PROP_OA_METRICS_SET,
/**
* The value specifies the size and layout of OA unit reports.
*/
DRM_I915_PERF_PROP_OA_FORMAT,
/**
* Specifying this property implicitly requests periodic OA unit
* sampling and (at least on Haswell) the sampling frequency is derived
* from this exponent as follows:
*
* 80ns * 2^(period_exponent + 1)
*/
DRM_I915_PERF_PROP_OA_EXPONENT,
DRM_I915_PERF_PROP_MAX /* non-ABI */
};
struct drm_i915_perf_open_param {
__u32 flags;
#define I915_PERF_FLAG_FD_CLOEXEC (1<<0)
#define I915_PERF_FLAG_FD_NONBLOCK (1<<1)
#define I915_PERF_FLAG_DISABLED (1<<2)
/** The number of u64 (id, value) pairs */
__u32 num_properties;
/**
* Pointer to array of u64 (id, value) pairs configuring the stream
* to open.
*/
__u64 properties_ptr;
};
/**
* Enable data capture for a stream that was either opened in a disabled state
* via I915_PERF_FLAG_DISABLED or was later disabled via
* I915_PERF_IOCTL_DISABLE.
*
* It is intended to be cheaper to disable and enable a stream than it may be
* to close and re-open a stream with the same configuration.
*
* It's undefined whether any pending data for the stream will be lost.
*/
#define I915_PERF_IOCTL_ENABLE _IO('i', 0x0)
/**
* Disable data capture for a stream.
*
* It is an error to try and read a stream that is disabled.
*/
#define I915_PERF_IOCTL_DISABLE _IO('i', 0x1)
/**
* Common to all i915 perf records
*/
struct drm_i915_perf_record_header {
__u32 type;
__u16 pad;
__u16 size;
};
enum drm_i915_perf_record_type {
/**
* Samples are the work horse record type whose contents are extensible
* and defined when opening an i915 perf stream based on the given
* properties.
*
* Boolean properties following the naming convention
* DRM_I915_PERF_SAMPLE_xyz_PROP request the inclusion of 'xyz' data in
* every sample.
*
* The order of these sample properties given by userspace has no
* affect on the ordering of data within a sample. The order is
* documented here.
*
* struct {
* struct drm_i915_perf_record_header header;
*
* { u32 oa_report[]; } && DRM_I915_PERF_PROP_SAMPLE_OA
* };
*/
DRM_I915_PERF_RECORD_SAMPLE = 1,
/*
* Indicates that one or more OA reports were not written by the
* hardware. This can happen for example if an MI_REPORT_PERF_COUNT
* command collides with periodic sampling - which would be more likely
* at higher sampling frequencies.
*/
DRM_I915_PERF_RECORD_OA_REPORT_LOST = 2,
/**
* An error occurred that resulted in all pending OA reports being lost.
*/
DRM_I915_PERF_RECORD_OA_BUFFER_LOST = 3,
DRM_I915_PERF_RECORD_MAX /* non-ABI */
};
/**
* Structure to upload perf dynamic configuration into the kernel.
*/
struct drm_i915_perf_oa_config {
/** String formatted like "%08x-%04x-%04x-%04x-%012x" */
char uuid[36];
__u32 n_mux_regs;
__u32 n_boolean_regs;
__u32 n_flex_regs;
/*
* These fields are pointers to tuples of u32 values (register address,
* value). For example the expected length of the buffer pointed by
* mux_regs_ptr is (2 * sizeof(u32) * n_mux_regs).
*/
__u64 mux_regs_ptr;
__u64 boolean_regs_ptr;
__u64 flex_regs_ptr;
};
struct drm_i915_query_item {
__u64 query_id;
#define DRM_I915_QUERY_TOPOLOGY_INFO 1
/*
* When set to zero by userspace, this is filled with the size of the
* data to be written at the data_ptr pointer. The kernel sets this
* value to a negative value to signal an error on a particular query
* item.
*/
__s32 length;
/*
* Unused for now. Must be cleared to zero.
*/
__u32 flags;
/*
* Data will be written at the location pointed by data_ptr when the
* value of length matches the length of the data to be written by the
* kernel.
*/
__u64 data_ptr;
};
struct drm_i915_query {
__u32 num_items;
/*
* Unused for now. Must be cleared to zero.
*/
__u32 flags;
/*
* This points to an array of num_items drm_i915_query_item structures.
*/
__u64 items_ptr;
};
/*
* Data written by the kernel with query DRM_I915_QUERY_TOPOLOGY_INFO :
*
* data: contains the 3 pieces of information :
*
* - the slice mask with one bit per slice telling whether a slice is
* available. The availability of slice X can be queried with the following
* formula :
*
* (data[X / 8] >> (X % 8)) & 1
*
* - the subslice mask for each slice with one bit per subslice telling
* whether a subslice is available. The availability of subslice Y in slice
* X can be queried with the following formula :
*
* (data[subslice_offset +
* X * subslice_stride +
* Y / 8] >> (Y % 8)) & 1
*
* - the EU mask for each subslice in each slice with one bit per EU telling
* whether an EU is available. The availability of EU Z in subslice Y in
* slice X can be queried with the following formula :
*
* (data[eu_offset +
* (X * max_subslices + Y) * eu_stride +
* Z / 8] >> (Z % 8)) & 1
*/
struct drm_i915_query_topology_info {
/*
* Unused for now. Must be cleared to zero.
*/
__u16 flags;
__u16 max_slices;
__u16 max_subslices;
__u16 max_eus_per_subslice;
/*
* Offset in data[] at which the subslice masks are stored.
*/
__u16 subslice_offset;
/*
* Stride at which each of the subslice masks for each slice are
* stored.
*/
__u16 subslice_stride;
/*
* Offset in data[] at which the EU masks are stored.
*/
__u16 eu_offset;
/*
* Stride at which each of the EU masks for each subslice are stored.
*/
__u16 eu_stride;
__u8 data[];
};
#if defined(__cplusplus)
}
#endif
#endif /* _I915_DRM_H_ */

209
external/include/drm-uapi/tegra_drm.h vendored Normal file
View File

@ -0,0 +1,209 @@
/*
* Copyright (c) 2012-2013, NVIDIA CORPORATION. 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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 _TEGRA_DRM_H_
#define _TEGRA_DRM_H_
#include "drm.h"
#if defined(__cplusplus)
extern "C" {
#endif
#define DRM_TEGRA_GEM_CREATE_TILED (1 << 0)
#define DRM_TEGRA_GEM_CREATE_BOTTOM_UP (1 << 1)
struct drm_tegra_gem_create {
__u64 size;
__u32 flags;
__u32 handle;
};
struct drm_tegra_gem_mmap {
__u32 handle;
__u32 pad;
__u64 offset;
};
struct drm_tegra_syncpt_read {
__u32 id;
__u32 value;
};
struct drm_tegra_syncpt_incr {
__u32 id;
__u32 pad;
};
struct drm_tegra_syncpt_wait {
__u32 id;
__u32 thresh;
__u32 timeout;
__u32 value;
};
#define DRM_TEGRA_NO_TIMEOUT (0xffffffff)
struct drm_tegra_open_channel {
__u32 client;
__u32 pad;
__u64 context;
};
struct drm_tegra_close_channel {
__u64 context;
};
struct drm_tegra_get_syncpt {
__u64 context;
__u32 index;
__u32 id;
};
struct drm_tegra_get_syncpt_base {
__u64 context;
__u32 syncpt;
__u32 id;
};
struct drm_tegra_syncpt {
__u32 id;
__u32 incrs;
};
struct drm_tegra_cmdbuf {
__u32 handle;
__u32 offset;
__u32 words;
__u32 pad;
};
struct drm_tegra_reloc {
struct {
__u32 handle;
__u32 offset;
} cmdbuf;
struct {
__u32 handle;
__u32 offset;
} target;
__u32 shift;
__u32 pad;
};
struct drm_tegra_waitchk {
__u32 handle;
__u32 offset;
__u32 syncpt;
__u32 thresh;
};
struct drm_tegra_submit {
__u64 context;
__u32 num_syncpts;
__u32 num_cmdbufs;
__u32 num_relocs;
__u32 num_waitchks;
__u32 waitchk_mask;
__u32 timeout;
__u64 syncpts;
__u64 cmdbufs;
__u64 relocs;
__u64 waitchks;
__u32 fence; /* Return value */
__u32 reserved[5]; /* future expansion */
};
#define DRM_TEGRA_GEM_TILING_MODE_PITCH 0
#define DRM_TEGRA_GEM_TILING_MODE_TILED 1
#define DRM_TEGRA_GEM_TILING_MODE_BLOCK 2
struct drm_tegra_gem_set_tiling {
/* input */
__u32 handle;
__u32 mode;
__u32 value;
__u32 pad;
};
struct drm_tegra_gem_get_tiling {
/* input */
__u32 handle;
/* output */
__u32 mode;
__u32 value;
__u32 pad;
};
#define DRM_TEGRA_GEM_BOTTOM_UP (1 << 0)
#define DRM_TEGRA_GEM_FLAGS (DRM_TEGRA_GEM_BOTTOM_UP)
struct drm_tegra_gem_set_flags {
/* input */
__u32 handle;
/* output */
__u32 flags;
};
struct drm_tegra_gem_get_flags {
/* input */
__u32 handle;
/* output */
__u32 flags;
};
#define DRM_TEGRA_GEM_CREATE 0x00
#define DRM_TEGRA_GEM_MMAP 0x01
#define DRM_TEGRA_SYNCPT_READ 0x02
#define DRM_TEGRA_SYNCPT_INCR 0x03
#define DRM_TEGRA_SYNCPT_WAIT 0x04
#define DRM_TEGRA_OPEN_CHANNEL 0x05
#define DRM_TEGRA_CLOSE_CHANNEL 0x06
#define DRM_TEGRA_GET_SYNCPT 0x07
#define DRM_TEGRA_SUBMIT 0x08
#define DRM_TEGRA_GET_SYNCPT_BASE 0x09
#define DRM_TEGRA_GEM_SET_TILING 0x0a
#define DRM_TEGRA_GEM_GET_TILING 0x0b
#define DRM_TEGRA_GEM_SET_FLAGS 0x0c
#define DRM_TEGRA_GEM_GET_FLAGS 0x0d
#define DRM_IOCTL_TEGRA_GEM_CREATE DRM_IOWR(DRM_COMMAND_BASE + DRM_TEGRA_GEM_CREATE, struct drm_tegra_gem_create)
#define DRM_IOCTL_TEGRA_GEM_MMAP DRM_IOWR(DRM_COMMAND_BASE + DRM_TEGRA_GEM_MMAP, struct drm_tegra_gem_mmap)
#define DRM_IOCTL_TEGRA_SYNCPT_READ DRM_IOWR(DRM_COMMAND_BASE + DRM_TEGRA_SYNCPT_READ, struct drm_tegra_syncpt_read)
#define DRM_IOCTL_TEGRA_SYNCPT_INCR DRM_IOWR(DRM_COMMAND_BASE + DRM_TEGRA_SYNCPT_INCR, struct drm_tegra_syncpt_incr)
#define DRM_IOCTL_TEGRA_SYNCPT_WAIT DRM_IOWR(DRM_COMMAND_BASE + DRM_TEGRA_SYNCPT_WAIT, struct drm_tegra_syncpt_wait)
#define DRM_IOCTL_TEGRA_OPEN_CHANNEL DRM_IOWR(DRM_COMMAND_BASE + DRM_TEGRA_OPEN_CHANNEL, struct drm_tegra_open_channel)
#define DRM_IOCTL_TEGRA_CLOSE_CHANNEL DRM_IOWR(DRM_COMMAND_BASE + DRM_TEGRA_CLOSE_CHANNEL, struct drm_tegra_open_channel)
#define DRM_IOCTL_TEGRA_GET_SYNCPT DRM_IOWR(DRM_COMMAND_BASE + DRM_TEGRA_GET_SYNCPT, struct drm_tegra_get_syncpt)
#define DRM_IOCTL_TEGRA_SUBMIT DRM_IOWR(DRM_COMMAND_BASE + DRM_TEGRA_SUBMIT, struct drm_tegra_submit)
#define DRM_IOCTL_TEGRA_GET_SYNCPT_BASE DRM_IOWR(DRM_COMMAND_BASE + DRM_TEGRA_GET_SYNCPT_BASE, struct drm_tegra_get_syncpt_base)
#define DRM_IOCTL_TEGRA_GEM_SET_TILING DRM_IOWR(DRM_COMMAND_BASE + DRM_TEGRA_GEM_SET_TILING, struct drm_tegra_gem_set_tiling)
#define DRM_IOCTL_TEGRA_GEM_GET_TILING DRM_IOWR(DRM_COMMAND_BASE + DRM_TEGRA_GEM_GET_TILING, struct drm_tegra_gem_get_tiling)
#define DRM_IOCTL_TEGRA_GEM_SET_FLAGS DRM_IOWR(DRM_COMMAND_BASE + DRM_TEGRA_GEM_SET_FLAGS, struct drm_tegra_gem_set_flags)
#define DRM_IOCTL_TEGRA_GEM_GET_FLAGS DRM_IOWR(DRM_COMMAND_BASE + DRM_TEGRA_GEM_GET_FLAGS, struct drm_tegra_gem_get_flags)
#if defined(__cplusplus)
}
#endif
#endif

194
external/include/drm-uapi/v3d_drm.h vendored Normal file
View File

@ -0,0 +1,194 @@
/*
* Copyright © 2014-2018 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_DRM_H_
#define _V3D_DRM_H_
#include "drm.h"
#if defined(__cplusplus)
extern "C" {
#endif
#define DRM_V3D_SUBMIT_CL 0x00
#define DRM_V3D_WAIT_BO 0x01
#define DRM_V3D_CREATE_BO 0x02
#define DRM_V3D_MMAP_BO 0x03
#define DRM_V3D_GET_PARAM 0x04
#define DRM_V3D_GET_BO_OFFSET 0x05
#define DRM_IOCTL_V3D_SUBMIT_CL DRM_IOWR(DRM_COMMAND_BASE + DRM_V3D_SUBMIT_CL, struct drm_v3d_submit_cl)
#define DRM_IOCTL_V3D_WAIT_BO DRM_IOWR(DRM_COMMAND_BASE + DRM_V3D_WAIT_BO, struct drm_v3d_wait_bo)
#define DRM_IOCTL_V3D_CREATE_BO DRM_IOWR(DRM_COMMAND_BASE + DRM_V3D_CREATE_BO, struct drm_v3d_create_bo)
#define DRM_IOCTL_V3D_MMAP_BO DRM_IOWR(DRM_COMMAND_BASE + DRM_V3D_MMAP_BO, struct drm_v3d_mmap_bo)
#define DRM_IOCTL_V3D_GET_PARAM DRM_IOWR(DRM_COMMAND_BASE + DRM_V3D_GET_PARAM, struct drm_v3d_get_param)
#define DRM_IOCTL_V3D_GET_BO_OFFSET DRM_IOWR(DRM_COMMAND_BASE + DRM_V3D_GET_BO_OFFSET, struct drm_v3d_get_bo_offset)
/**
* struct drm_v3d_submit_cl - ioctl argument for submitting commands to the 3D
* engine.
*
* This asks the kernel to have the GPU execute an optional binner
* command list, and a render command list.
*/
struct drm_v3d_submit_cl {
/* Pointer to the binner command list.
*
* This is the first set of commands executed, which runs the
* coordinate shader to determine where primitives land on the screen,
* then writes out the state updates and draw calls necessary per tile
* to the tile allocation BO.
*/
__u32 bcl_start;
/** End address of the BCL (first byte after the BCL) */
__u32 bcl_end;
/* Offset of the render command list.
*
* This is the second set of commands executed, which will either
* execute the tiles that have been set up by the BCL, or a fixed set
* of tiles (in the case of RCL-only blits).
*/
__u32 rcl_start;
/** End address of the RCL (first byte after the RCL) */
__u32 rcl_end;
/** An optional sync object to wait on before starting the BCL. */
__u32 in_sync_bcl;
/** An optional sync object to wait on before starting the RCL. */
__u32 in_sync_rcl;
/** An optional sync object to place the completion fence in. */
__u32 out_sync;
/* Offset of the tile alloc memory
*
* This is optional on V3D 3.3 (where the CL can set the value) but
* required on V3D 4.1.
*/
__u32 qma;
/** Size of the tile alloc memory. */
__u32 qms;
/** Offset of the tile state data array. */
__u32 qts;
/* Pointer to a u32 array of the BOs that are referenced by the job.
*/
__u64 bo_handles;
/* Number of BO handles passed in (size is that times 4). */
__u32 bo_handle_count;
/* Pad, must be zero-filled. */
__u32 pad;
};
/**
* struct drm_v3d_wait_bo - ioctl argument for waiting for
* completion of the last DRM_V3D_SUBMIT_CL on a BO.
*
* This is useful for cases where multiple processes might be
* rendering to a BO and you want to wait for all rendering to be
* completed.
*/
struct drm_v3d_wait_bo {
__u32 handle;
__u32 pad;
__u64 timeout_ns;
};
/**
* struct drm_v3d_create_bo - ioctl argument for creating V3D BOs.
*
* There are currently no values for the flags argument, but it may be
* used in a future extension.
*/
struct drm_v3d_create_bo {
__u32 size;
__u32 flags;
/** Returned GEM handle for the BO. */
__u32 handle;
/**
* Returned offset for the BO in the V3D address space. This offset
* is private to the DRM fd and is valid for the lifetime of the GEM
* handle.
*
* This offset value will always be nonzero, since various HW
* units treat 0 specially.
*/
__u32 offset;
};
/**
* struct drm_v3d_mmap_bo - ioctl argument for mapping V3D BOs.
*
* This doesn't actually perform an mmap. Instead, it returns the
* offset you need to use in an mmap on the DRM device node. This
* means that tools like valgrind end up knowing about the mapped
* memory.
*
* There are currently no values for the flags argument, but it may be
* used in a future extension.
*/
struct drm_v3d_mmap_bo {
/** Handle for the object being mapped. */
__u32 handle;
__u32 flags;
/** offset into the drm node to use for subsequent mmap call. */
__u64 offset;
};
enum drm_v3d_param {
DRM_V3D_PARAM_V3D_UIFCFG,
DRM_V3D_PARAM_V3D_HUB_IDENT1,
DRM_V3D_PARAM_V3D_HUB_IDENT2,
DRM_V3D_PARAM_V3D_HUB_IDENT3,
DRM_V3D_PARAM_V3D_CORE0_IDENT0,
DRM_V3D_PARAM_V3D_CORE0_IDENT1,
DRM_V3D_PARAM_V3D_CORE0_IDENT2,
};
struct drm_v3d_get_param {
__u32 param;
__u32 pad;
__u64 value;
};
/**
* Returns the offset for the BO in the V3D address space for this DRM fd.
* This is the same value returned by drm_v3d_create_bo, if that was called
* from this DRM fd.
*/
struct drm_v3d_get_bo_offset {
__u32 handle;
__u32 offset;
};
#if defined(__cplusplus)
}
#endif
#endif /* _V3D_DRM_H_ */

442
external/include/drm-uapi/vc4_drm.h vendored Normal file
View File

@ -0,0 +1,442 @@
/*
* Copyright © 2014-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.
*/
#ifndef _VC4_DRM_H_
#define _VC4_DRM_H_
#include "drm.h"
#if defined(__cplusplus)
extern "C" {
#endif
#define DRM_VC4_SUBMIT_CL 0x00
#define DRM_VC4_WAIT_SEQNO 0x01
#define DRM_VC4_WAIT_BO 0x02
#define DRM_VC4_CREATE_BO 0x03
#define DRM_VC4_MMAP_BO 0x04
#define DRM_VC4_CREATE_SHADER_BO 0x05
#define DRM_VC4_GET_HANG_STATE 0x06
#define DRM_VC4_GET_PARAM 0x07
#define DRM_VC4_SET_TILING 0x08
#define DRM_VC4_GET_TILING 0x09
#define DRM_VC4_LABEL_BO 0x0a
#define DRM_VC4_GEM_MADVISE 0x0b
#define DRM_VC4_PERFMON_CREATE 0x0c
#define DRM_VC4_PERFMON_DESTROY 0x0d
#define DRM_VC4_PERFMON_GET_VALUES 0x0e
#define DRM_IOCTL_VC4_SUBMIT_CL DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_SUBMIT_CL, struct drm_vc4_submit_cl)
#define DRM_IOCTL_VC4_WAIT_SEQNO DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_WAIT_SEQNO, struct drm_vc4_wait_seqno)
#define DRM_IOCTL_VC4_WAIT_BO DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_WAIT_BO, struct drm_vc4_wait_bo)
#define DRM_IOCTL_VC4_CREATE_BO DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_CREATE_BO, struct drm_vc4_create_bo)
#define DRM_IOCTL_VC4_MMAP_BO DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_MMAP_BO, struct drm_vc4_mmap_bo)
#define DRM_IOCTL_VC4_CREATE_SHADER_BO DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_CREATE_SHADER_BO, struct drm_vc4_create_shader_bo)
#define DRM_IOCTL_VC4_GET_HANG_STATE DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_GET_HANG_STATE, struct drm_vc4_get_hang_state)
#define DRM_IOCTL_VC4_GET_PARAM DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_GET_PARAM, struct drm_vc4_get_param)
#define DRM_IOCTL_VC4_SET_TILING DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_SET_TILING, struct drm_vc4_set_tiling)
#define DRM_IOCTL_VC4_GET_TILING DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_GET_TILING, struct drm_vc4_get_tiling)
#define DRM_IOCTL_VC4_LABEL_BO DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_LABEL_BO, struct drm_vc4_label_bo)
#define DRM_IOCTL_VC4_GEM_MADVISE DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_GEM_MADVISE, struct drm_vc4_gem_madvise)
#define DRM_IOCTL_VC4_PERFMON_CREATE DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_PERFMON_CREATE, struct drm_vc4_perfmon_create)
#define DRM_IOCTL_VC4_PERFMON_DESTROY DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_PERFMON_DESTROY, struct drm_vc4_perfmon_destroy)
#define DRM_IOCTL_VC4_PERFMON_GET_VALUES DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_PERFMON_GET_VALUES, struct drm_vc4_perfmon_get_values)
struct drm_vc4_submit_rcl_surface {
__u32 hindex; /* Handle index, or ~0 if not present. */
__u32 offset; /* Offset to start of buffer. */
/*
* Bits for either render config (color_write) or load/store packet.
* Bits should all be 0 for MSAA load/stores.
*/
__u16 bits;
#define VC4_SUBMIT_RCL_SURFACE_READ_IS_FULL_RES (1 << 0)
__u16 flags;
};
/**
* struct drm_vc4_submit_cl - ioctl argument for submitting commands to the 3D
* engine.
*
* Drivers typically use GPU BOs to store batchbuffers / command lists and
* their associated state. However, because the VC4 lacks an MMU, we have to
* do validation of memory accesses by the GPU commands. If we were to store
* our commands in BOs, we'd need to do uncached readback from them to do the
* validation process, which is too expensive. Instead, userspace accumulates
* commands and associated state in plain memory, then the kernel copies the
* data to its own address space, and then validates and stores it in a GPU
* BO.
*/
struct drm_vc4_submit_cl {
/* Pointer to the binner command list.
*
* This is the first set of commands executed, which runs the
* coordinate shader to determine where primitives land on the screen,
* then writes out the state updates and draw calls necessary per tile
* to the tile allocation BO.
*/
__u64 bin_cl;
/* Pointer to the shader records.
*
* Shader records are the structures read by the hardware that contain
* pointers to uniforms, shaders, and vertex attributes. The
* reference to the shader record has enough information to determine
* how many pointers are necessary (fixed number for shaders/uniforms,
* and an attribute count), so those BO indices into bo_handles are
* just stored as __u32s before each shader record passed in.
*/
__u64 shader_rec;
/* Pointer to uniform data and texture handles for the textures
* referenced by the shader.
*
* For each shader state record, there is a set of uniform data in the
* order referenced by the record (FS, VS, then CS). Each set of
* uniform data has a __u32 index into bo_handles per texture
* sample operation, in the order the QPU_W_TMUn_S writes appear in
* the program. Following the texture BO handle indices is the actual
* uniform data.
*
* The individual uniform state blocks don't have sizes passed in,
* because the kernel has to determine the sizes anyway during shader
* code validation.
*/
__u64 uniforms;
__u64 bo_handles;
/* Size in bytes of the binner command list. */
__u32 bin_cl_size;
/* Size in bytes of the set of shader records. */
__u32 shader_rec_size;
/* Number of shader records.
*
* This could just be computed from the contents of shader_records and
* the address bits of references to them from the bin CL, but it
* keeps the kernel from having to resize some allocations it makes.
*/
__u32 shader_rec_count;
/* Size in bytes of the uniform state. */
__u32 uniforms_size;
/* Number of BO handles passed in (size is that times 4). */
__u32 bo_handle_count;
/* RCL setup: */
__u16 width;
__u16 height;
__u8 min_x_tile;
__u8 min_y_tile;
__u8 max_x_tile;
__u8 max_y_tile;
struct drm_vc4_submit_rcl_surface color_read;
struct drm_vc4_submit_rcl_surface color_write;
struct drm_vc4_submit_rcl_surface zs_read;
struct drm_vc4_submit_rcl_surface zs_write;
struct drm_vc4_submit_rcl_surface msaa_color_write;
struct drm_vc4_submit_rcl_surface msaa_zs_write;
__u32 clear_color[2];
__u32 clear_z;
__u8 clear_s;
__u32 pad:24;
#define VC4_SUBMIT_CL_USE_CLEAR_COLOR (1 << 0)
/* By default, the kernel gets to choose the order that the tiles are
* rendered in. If this is set, then the tiles will be rendered in a
* raster order, with the right-to-left vs left-to-right and
* top-to-bottom vs bottom-to-top dictated by
* VC4_SUBMIT_CL_RCL_ORDER_INCREASING_*. This allows overlapping
* blits to be implemented using the 3D engine.
*/
#define VC4_SUBMIT_CL_FIXED_RCL_ORDER (1 << 1)
#define VC4_SUBMIT_CL_RCL_ORDER_INCREASING_X (1 << 2)
#define VC4_SUBMIT_CL_RCL_ORDER_INCREASING_Y (1 << 3)
__u32 flags;
/* Returned value of the seqno of this render job (for the
* wait ioctl).
*/
__u64 seqno;
/* ID of the perfmon to attach to this job. 0 means no perfmon. */
__u32 perfmonid;
/* Syncobj handle to wait on. If set, processing of this render job
* will not start until the syncobj is signaled. 0 means ignore.
*/
__u32 in_sync;
/* Syncobj handle to export fence to. If set, the fence in the syncobj
* will be replaced with a fence that signals upon completion of this
* render job. 0 means ignore.
*/
__u32 out_sync;
__u32 pad2;
};
/**
* struct drm_vc4_wait_seqno - ioctl argument for waiting for
* DRM_VC4_SUBMIT_CL completion using its returned seqno.
*
* timeout_ns is the timeout in nanoseconds, where "0" means "don't
* block, just return the status."
*/
struct drm_vc4_wait_seqno {
__u64 seqno;
__u64 timeout_ns;
};
/**
* struct drm_vc4_wait_bo - ioctl argument for waiting for
* completion of the last DRM_VC4_SUBMIT_CL on a BO.
*
* This is useful for cases where multiple processes might be
* rendering to a BO and you want to wait for all rendering to be
* completed.
*/
struct drm_vc4_wait_bo {
__u32 handle;
__u32 pad;
__u64 timeout_ns;
};
/**
* struct drm_vc4_create_bo - ioctl argument for creating VC4 BOs.
*
* There are currently no values for the flags argument, but it may be
* used in a future extension.
*/
struct drm_vc4_create_bo {
__u32 size;
__u32 flags;
/** Returned GEM handle for the BO. */
__u32 handle;
__u32 pad;
};
/**
* struct drm_vc4_mmap_bo - ioctl argument for mapping VC4 BOs.
*
* This doesn't actually perform an mmap. Instead, it returns the
* offset you need to use in an mmap on the DRM device node. This
* means that tools like valgrind end up knowing about the mapped
* memory.
*
* There are currently no values for the flags argument, but it may be
* used in a future extension.
*/
struct drm_vc4_mmap_bo {
/** Handle for the object being mapped. */
__u32 handle;
__u32 flags;
/** offset into the drm node to use for subsequent mmap call. */
__u64 offset;
};
/**
* struct drm_vc4_create_shader_bo - ioctl argument for creating VC4
* shader BOs.
*
* Since allowing a shader to be overwritten while it's also being
* executed from would allow privlege escalation, shaders must be
* created using this ioctl, and they can't be mmapped later.
*/
struct drm_vc4_create_shader_bo {
/* Size of the data argument. */
__u32 size;
/* Flags, currently must be 0. */
__u32 flags;
/* Pointer to the data. */
__u64 data;
/** Returned GEM handle for the BO. */
__u32 handle;
/* Pad, must be 0. */
__u32 pad;
};
struct drm_vc4_get_hang_state_bo {
__u32 handle;
__u32 paddr;
__u32 size;
__u32 pad;
};
/**
* struct drm_vc4_hang_state - ioctl argument for collecting state
* from a GPU hang for analysis.
*/
struct drm_vc4_get_hang_state {
/** Pointer to array of struct drm_vc4_get_hang_state_bo. */
__u64 bo;
/**
* On input, the size of the bo array. Output is the number
* of bos to be returned.
*/
__u32 bo_count;
__u32 start_bin, start_render;
__u32 ct0ca, ct0ea;
__u32 ct1ca, ct1ea;
__u32 ct0cs, ct1cs;
__u32 ct0ra0, ct1ra0;
__u32 bpca, bpcs;
__u32 bpoa, bpos;
__u32 vpmbase;
__u32 dbge;
__u32 fdbgo;
__u32 fdbgb;
__u32 fdbgr;
__u32 fdbgs;
__u32 errstat;
/* Pad that we may save more registers into in the future. */
__u32 pad[16];
};
#define DRM_VC4_PARAM_V3D_IDENT0 0
#define DRM_VC4_PARAM_V3D_IDENT1 1
#define DRM_VC4_PARAM_V3D_IDENT2 2
#define DRM_VC4_PARAM_SUPPORTS_BRANCHES 3
#define DRM_VC4_PARAM_SUPPORTS_ETC1 4
#define DRM_VC4_PARAM_SUPPORTS_THREADED_FS 5
#define DRM_VC4_PARAM_SUPPORTS_FIXED_RCL_ORDER 6
#define DRM_VC4_PARAM_SUPPORTS_MADVISE 7
#define DRM_VC4_PARAM_SUPPORTS_PERFMON 8
struct drm_vc4_get_param {
__u32 param;
__u32 pad;
__u64 value;
};
struct drm_vc4_get_tiling {
__u32 handle;
__u32 flags;
__u64 modifier;
};
struct drm_vc4_set_tiling {
__u32 handle;
__u32 flags;
__u64 modifier;
};
/**
* struct drm_vc4_label_bo - Attach a name to a BO for debug purposes.
*/
struct drm_vc4_label_bo {
__u32 handle;
__u32 len;
__u64 name;
};
/*
* States prefixed with '__' are internal states and cannot be passed to the
* DRM_IOCTL_VC4_GEM_MADVISE ioctl.
*/
#define VC4_MADV_WILLNEED 0
#define VC4_MADV_DONTNEED 1
#define __VC4_MADV_PURGED 2
#define __VC4_MADV_NOTSUPP 3
struct drm_vc4_gem_madvise {
__u32 handle;
__u32 madv;
__u32 retained;
__u32 pad;
};
enum {
VC4_PERFCNT_FEP_VALID_PRIMS_NO_RENDER,
VC4_PERFCNT_FEP_VALID_PRIMS_RENDER,
VC4_PERFCNT_FEP_CLIPPED_QUADS,
VC4_PERFCNT_FEP_VALID_QUADS,
VC4_PERFCNT_TLB_QUADS_NOT_PASSING_STENCIL,
VC4_PERFCNT_TLB_QUADS_NOT_PASSING_Z_AND_STENCIL,
VC4_PERFCNT_TLB_QUADS_PASSING_Z_AND_STENCIL,
VC4_PERFCNT_TLB_QUADS_ZERO_COVERAGE,
VC4_PERFCNT_TLB_QUADS_NON_ZERO_COVERAGE,
VC4_PERFCNT_TLB_QUADS_WRITTEN_TO_COLOR_BUF,
VC4_PERFCNT_PLB_PRIMS_OUTSIDE_VIEWPORT,
VC4_PERFCNT_PLB_PRIMS_NEED_CLIPPING,
VC4_PERFCNT_PSE_PRIMS_REVERSED,
VC4_PERFCNT_QPU_TOTAL_IDLE_CYCLES,
VC4_PERFCNT_QPU_TOTAL_CLK_CYCLES_VERTEX_COORD_SHADING,
VC4_PERFCNT_QPU_TOTAL_CLK_CYCLES_FRAGMENT_SHADING,
VC4_PERFCNT_QPU_TOTAL_CLK_CYCLES_EXEC_VALID_INST,
VC4_PERFCNT_QPU_TOTAL_CLK_CYCLES_WAITING_TMUS,
VC4_PERFCNT_QPU_TOTAL_CLK_CYCLES_WAITING_SCOREBOARD,
VC4_PERFCNT_QPU_TOTAL_CLK_CYCLES_WAITING_VARYINGS,
VC4_PERFCNT_QPU_TOTAL_INST_CACHE_HIT,
VC4_PERFCNT_QPU_TOTAL_INST_CACHE_MISS,
VC4_PERFCNT_QPU_TOTAL_UNIFORM_CACHE_HIT,
VC4_PERFCNT_QPU_TOTAL_UNIFORM_CACHE_MISS,
VC4_PERFCNT_TMU_TOTAL_TEXT_QUADS_PROCESSED,
VC4_PERFCNT_TMU_TOTAL_TEXT_CACHE_MISS,
VC4_PERFCNT_VPM_TOTAL_CLK_CYCLES_VDW_STALLED,
VC4_PERFCNT_VPM_TOTAL_CLK_CYCLES_VCD_STALLED,
VC4_PERFCNT_L2C_TOTAL_L2_CACHE_HIT,
VC4_PERFCNT_L2C_TOTAL_L2_CACHE_MISS,
VC4_PERFCNT_NUM_EVENTS,
};
#define DRM_VC4_MAX_PERF_COUNTERS 16
struct drm_vc4_perfmon_create {
__u32 id;
__u32 ncounters;
__u8 events[DRM_VC4_MAX_PERF_COUNTERS];
};
struct drm_vc4_perfmon_destroy {
__u32 id;
};
/*
* Returns the values of the performance counters tracked by this
* perfmon (as an array of ncounters u64 values).
*
* No implicit synchronization is performed, so the user has to
* guarantee that any jobs using this perfmon have already been
* completed (probably by blocking on the seqno returned by the
* last exec that used the perfmon).
*/
struct drm_vc4_perfmon_get_values {
__u32 id;
__u64 values_ptr;
};
#if defined(__cplusplus)
}
#endif
#endif /* _VC4_DRM_H_ */

1048
external/include/expat.h vendored Normal file
View File

@ -0,0 +1,1048 @@
/* Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd
See the file COPYING for copying permission.
*/
#ifndef Expat_INCLUDED
#define Expat_INCLUDED 1
#ifdef __VMS
/* 0 1 2 3 0 1 2 3
1234567890123456789012345678901 1234567890123456789012345678901 */
#define XML_SetProcessingInstructionHandler XML_SetProcessingInstrHandler
#define XML_SetUnparsedEntityDeclHandler XML_SetUnparsedEntDeclHandler
#define XML_SetStartNamespaceDeclHandler XML_SetStartNamespcDeclHandler
#define XML_SetExternalEntityRefHandlerArg XML_SetExternalEntRefHandlerArg
#endif
#include <stdlib.h>
#include "expat_external.h"
#ifdef __cplusplus
extern "C" {
#endif
struct XML_ParserStruct;
typedef struct XML_ParserStruct *XML_Parser;
/* Should this be defined using stdbool.h when C99 is available? */
typedef unsigned char XML_Bool;
#define XML_TRUE ((XML_Bool) 1)
#define XML_FALSE ((XML_Bool) 0)
/* The XML_Status enum gives the possible return values for several
API functions. The preprocessor #defines are included so this
stanza can be added to code that still needs to support older
versions of Expat 1.95.x:
#ifndef XML_STATUS_OK
#define XML_STATUS_OK 1
#define XML_STATUS_ERROR 0
#endif
Otherwise, the #define hackery is quite ugly and would have been
dropped.
*/
enum XML_Status {
XML_STATUS_ERROR = 0,
#define XML_STATUS_ERROR XML_STATUS_ERROR
XML_STATUS_OK = 1,
#define XML_STATUS_OK XML_STATUS_OK
XML_STATUS_SUSPENDED = 2
#define XML_STATUS_SUSPENDED XML_STATUS_SUSPENDED
};
enum XML_Error {
XML_ERROR_NONE,
XML_ERROR_NO_MEMORY,
XML_ERROR_SYNTAX,
XML_ERROR_NO_ELEMENTS,
XML_ERROR_INVALID_TOKEN,
XML_ERROR_UNCLOSED_TOKEN,
XML_ERROR_PARTIAL_CHAR,
XML_ERROR_TAG_MISMATCH,
XML_ERROR_DUPLICATE_ATTRIBUTE,
XML_ERROR_JUNK_AFTER_DOC_ELEMENT,
XML_ERROR_PARAM_ENTITY_REF,
XML_ERROR_UNDEFINED_ENTITY,
XML_ERROR_RECURSIVE_ENTITY_REF,
XML_ERROR_ASYNC_ENTITY,
XML_ERROR_BAD_CHAR_REF,
XML_ERROR_BINARY_ENTITY_REF,
XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF,
XML_ERROR_MISPLACED_XML_PI,
XML_ERROR_UNKNOWN_ENCODING,
XML_ERROR_INCORRECT_ENCODING,
XML_ERROR_UNCLOSED_CDATA_SECTION,
XML_ERROR_EXTERNAL_ENTITY_HANDLING,
XML_ERROR_NOT_STANDALONE,
XML_ERROR_UNEXPECTED_STATE,
XML_ERROR_ENTITY_DECLARED_IN_PE,
XML_ERROR_FEATURE_REQUIRES_XML_DTD,
XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING,
/* Added in 1.95.7. */
XML_ERROR_UNBOUND_PREFIX,
/* Added in 1.95.8. */
XML_ERROR_UNDECLARING_PREFIX,
XML_ERROR_INCOMPLETE_PE,
XML_ERROR_XML_DECL,
XML_ERROR_TEXT_DECL,
XML_ERROR_PUBLICID,
XML_ERROR_SUSPENDED,
XML_ERROR_NOT_SUSPENDED,
XML_ERROR_ABORTED,
XML_ERROR_FINISHED,
XML_ERROR_SUSPEND_PE,
/* Added in 2.0. */
XML_ERROR_RESERVED_PREFIX_XML,
XML_ERROR_RESERVED_PREFIX_XMLNS,
XML_ERROR_RESERVED_NAMESPACE_URI
};
enum XML_Content_Type {
XML_CTYPE_EMPTY = 1,
XML_CTYPE_ANY,
XML_CTYPE_MIXED,
XML_CTYPE_NAME,
XML_CTYPE_CHOICE,
XML_CTYPE_SEQ
};
enum XML_Content_Quant {
XML_CQUANT_NONE,
XML_CQUANT_OPT,
XML_CQUANT_REP,
XML_CQUANT_PLUS
};
/* If type == XML_CTYPE_EMPTY or XML_CTYPE_ANY, then quant will be
XML_CQUANT_NONE, and the other fields will be zero or NULL.
If type == XML_CTYPE_MIXED, then quant will be NONE or REP and
numchildren will contain number of elements that may be mixed in
and children point to an array of XML_Content cells that will be
all of XML_CTYPE_NAME type with no quantification.
If type == XML_CTYPE_NAME, then the name points to the name, and
the numchildren field will be zero and children will be NULL. The
quant fields indicates any quantifiers placed on the name.
CHOICE and SEQ will have name NULL, the number of children in
numchildren and children will point, recursively, to an array
of XML_Content cells.
The EMPTY, ANY, and MIXED types will only occur at top level.
*/
typedef struct XML_cp XML_Content;
struct XML_cp {
enum XML_Content_Type type;
enum XML_Content_Quant quant;
XML_Char * name;
unsigned int numchildren;
XML_Content * children;
};
/* This is called for an element declaration. See above for
description of the model argument. It's the caller's responsibility
to free model when finished with it.
*/
typedef void (XMLCALL *XML_ElementDeclHandler) (void *userData,
const XML_Char *name,
XML_Content *model);
XMLPARSEAPI(void)
XML_SetElementDeclHandler(XML_Parser parser,
XML_ElementDeclHandler eldecl);
/* The Attlist declaration handler is called for *each* attribute. So
a single Attlist declaration with multiple attributes declared will
generate multiple calls to this handler. The "default" parameter
may be NULL in the case of the "#IMPLIED" or "#REQUIRED"
keyword. The "isrequired" parameter will be true and the default
value will be NULL in the case of "#REQUIRED". If "isrequired" is
true and default is non-NULL, then this is a "#FIXED" default.
*/
typedef void (XMLCALL *XML_AttlistDeclHandler) (
void *userData,
const XML_Char *elname,
const XML_Char *attname,
const XML_Char *att_type,
const XML_Char *dflt,
int isrequired);
XMLPARSEAPI(void)
XML_SetAttlistDeclHandler(XML_Parser parser,
XML_AttlistDeclHandler attdecl);
/* The XML declaration handler is called for *both* XML declarations
and text declarations. The way to distinguish is that the version
parameter will be NULL for text declarations. The encoding
parameter may be NULL for XML declarations. The standalone
parameter will be -1, 0, or 1 indicating respectively that there
was no standalone parameter in the declaration, that it was given
as no, or that it was given as yes.
*/
typedef void (XMLCALL *XML_XmlDeclHandler) (void *userData,
const XML_Char *version,
const XML_Char *encoding,
int standalone);
XMLPARSEAPI(void)
XML_SetXmlDeclHandler(XML_Parser parser,
XML_XmlDeclHandler xmldecl);
typedef struct {
void *(*malloc_fcn)(size_t size);
void *(*realloc_fcn)(void *ptr, size_t size);
void (*free_fcn)(void *ptr);
} XML_Memory_Handling_Suite;
/* Constructs a new parser; encoding is the encoding specified by the
external protocol or NULL if there is none specified.
*/
XMLPARSEAPI(XML_Parser)
XML_ParserCreate(const XML_Char *encoding);
/* Constructs a new parser and namespace processor. Element type
names and attribute names that belong to a namespace will be
expanded; unprefixed attribute names are never expanded; unprefixed
element type names are expanded only if there is a default
namespace. The expanded name is the concatenation of the namespace
URI, the namespace separator character, and the local part of the
name. If the namespace separator is '\0' then the namespace URI
and the local part will be concatenated without any separator.
It is a programming error to use the separator '\0' with namespace
triplets (see XML_SetReturnNSTriplet).
*/
XMLPARSEAPI(XML_Parser)
XML_ParserCreateNS(const XML_Char *encoding, XML_Char namespaceSeparator);
/* Constructs a new parser using the memory management suite referred to
by memsuite. If memsuite is NULL, then use the standard library memory
suite. If namespaceSeparator is non-NULL it creates a parser with
namespace processing as described above. The character pointed at
will serve as the namespace separator.
All further memory operations used for the created parser will come from
the given suite.
*/
XMLPARSEAPI(XML_Parser)
XML_ParserCreate_MM(const XML_Char *encoding,
const XML_Memory_Handling_Suite *memsuite,
const XML_Char *namespaceSeparator);
/* Prepare a parser object to be re-used. This is particularly
valuable when memory allocation overhead is disproportionatly high,
such as when a large number of small documnents need to be parsed.
All handlers are cleared from the parser, except for the
unknownEncodingHandler. The parser's external state is re-initialized
except for the values of ns and ns_triplets.
Added in Expat 1.95.3.
*/
XMLPARSEAPI(XML_Bool)
XML_ParserReset(XML_Parser parser, const XML_Char *encoding);
/* atts is array of name/value pairs, terminated by 0;
names and values are 0 terminated.
*/
typedef void (XMLCALL *XML_StartElementHandler) (void *userData,
const XML_Char *name,
const XML_Char **atts);
typedef void (XMLCALL *XML_EndElementHandler) (void *userData,
const XML_Char *name);
/* s is not 0 terminated. */
typedef void (XMLCALL *XML_CharacterDataHandler) (void *userData,
const XML_Char *s,
int len);
/* target and data are 0 terminated */
typedef void (XMLCALL *XML_ProcessingInstructionHandler) (
void *userData,
const XML_Char *target,
const XML_Char *data);
/* data is 0 terminated */
typedef void (XMLCALL *XML_CommentHandler) (void *userData,
const XML_Char *data);
typedef void (XMLCALL *XML_StartCdataSectionHandler) (void *userData);
typedef void (XMLCALL *XML_EndCdataSectionHandler) (void *userData);
/* This is called for any characters in the XML document for which
there is no applicable handler. This includes both characters that
are part of markup which is of a kind that is not reported
(comments, markup declarations), or characters that are part of a
construct which could be reported but for which no handler has been
supplied. The characters are passed exactly as they were in the XML
document except that they will be encoded in UTF-8 or UTF-16.
Line boundaries are not normalized. Note that a byte order mark
character is not passed to the default handler. There are no
guarantees about how characters are divided between calls to the
default handler: for example, a comment might be split between
multiple calls.
*/
typedef void (XMLCALL *XML_DefaultHandler) (void *userData,
const XML_Char *s,
int len);
/* This is called for the start of the DOCTYPE declaration, before
any DTD or internal subset is parsed.
*/
typedef void (XMLCALL *XML_StartDoctypeDeclHandler) (
void *userData,
const XML_Char *doctypeName,
const XML_Char *sysid,
const XML_Char *pubid,
int has_internal_subset);
/* This is called for the start of the DOCTYPE declaration when the
closing > is encountered, but after processing any external
subset.
*/
typedef void (XMLCALL *XML_EndDoctypeDeclHandler)(void *userData);
/* This is called for entity declarations. The is_parameter_entity
argument will be non-zero if the entity is a parameter entity, zero
otherwise.
For internal entities (<!ENTITY foo "bar">), value will
be non-NULL and systemId, publicID, and notationName will be NULL.
The value string is NOT nul-terminated; the length is provided in
the value_length argument. Since it is legal to have zero-length
values, do not use this argument to test for internal entities.
For external entities, value will be NULL and systemId will be
non-NULL. The publicId argument will be NULL unless a public
identifier was provided. The notationName argument will have a
non-NULL value only for unparsed entity declarations.
Note that is_parameter_entity can't be changed to XML_Bool, since
that would break binary compatibility.
*/
typedef void (XMLCALL *XML_EntityDeclHandler) (
void *userData,
const XML_Char *entityName,
int is_parameter_entity,
const XML_Char *value,
int value_length,
const XML_Char *base,
const XML_Char *systemId,
const XML_Char *publicId,
const XML_Char *notationName);
XMLPARSEAPI(void)
XML_SetEntityDeclHandler(XML_Parser parser,
XML_EntityDeclHandler handler);
/* OBSOLETE -- OBSOLETE -- OBSOLETE
This handler has been superseded by the EntityDeclHandler above.
It is provided here for backward compatibility.
This is called for a declaration of an unparsed (NDATA) entity.
The base argument is whatever was set by XML_SetBase. The
entityName, systemId and notationName arguments will never be
NULL. The other arguments may be.
*/
typedef void (XMLCALL *XML_UnparsedEntityDeclHandler) (
void *userData,
const XML_Char *entityName,
const XML_Char *base,
const XML_Char *systemId,
const XML_Char *publicId,
const XML_Char *notationName);
/* This is called for a declaration of notation. The base argument is
whatever was set by XML_SetBase. The notationName will never be
NULL. The other arguments can be.
*/
typedef void (XMLCALL *XML_NotationDeclHandler) (
void *userData,
const XML_Char *notationName,
const XML_Char *base,
const XML_Char *systemId,
const XML_Char *publicId);
/* When namespace processing is enabled, these are called once for
each namespace declaration. The call to the start and end element
handlers occur between the calls to the start and end namespace
declaration handlers. For an xmlns attribute, prefix will be
NULL. For an xmlns="" attribute, uri will be NULL.
*/
typedef void (XMLCALL *XML_StartNamespaceDeclHandler) (
void *userData,
const XML_Char *prefix,
const XML_Char *uri);
typedef void (XMLCALL *XML_EndNamespaceDeclHandler) (
void *userData,
const XML_Char *prefix);
/* This is called if the document is not standalone, that is, it has an
external subset or a reference to a parameter entity, but does not
have standalone="yes". If this handler returns XML_STATUS_ERROR,
then processing will not continue, and the parser will return a
XML_ERROR_NOT_STANDALONE error.
If parameter entity parsing is enabled, then in addition to the
conditions above this handler will only be called if the referenced
entity was actually read.
*/
typedef int (XMLCALL *XML_NotStandaloneHandler) (void *userData);
/* This is called for a reference to an external parsed general
entity. The referenced entity is not automatically parsed. The
application can parse it immediately or later using
XML_ExternalEntityParserCreate.
The parser argument is the parser parsing the entity containing the
reference; it can be passed as the parser argument to
XML_ExternalEntityParserCreate. The systemId argument is the
system identifier as specified in the entity declaration; it will
not be NULL.
The base argument is the system identifier that should be used as
the base for resolving systemId if systemId was relative; this is
set by XML_SetBase; it may be NULL.
The publicId argument is the public identifier as specified in the
entity declaration, or NULL if none was specified; the whitespace
in the public identifier will have been normalized as required by
the XML spec.
The context argument specifies the parsing context in the format
expected by the context argument to XML_ExternalEntityParserCreate;
context is valid only until the handler returns, so if the
referenced entity is to be parsed later, it must be copied.
context is NULL only when the entity is a parameter entity.
The handler should return XML_STATUS_ERROR if processing should not
continue because of a fatal error in the handling of the external
entity. In this case the calling parser will return an
XML_ERROR_EXTERNAL_ENTITY_HANDLING error.
Note that unlike other handlers the first argument is the parser,
not userData.
*/
typedef int (XMLCALL *XML_ExternalEntityRefHandler) (
XML_Parser parser,
const XML_Char *context,
const XML_Char *base,
const XML_Char *systemId,
const XML_Char *publicId);
/* This is called in two situations:
1) An entity reference is encountered for which no declaration
has been read *and* this is not an error.
2) An internal entity reference is read, but not expanded, because
XML_SetDefaultHandler has been called.
Note: skipped parameter entities in declarations and skipped general
entities in attribute values cannot be reported, because
the event would be out of sync with the reporting of the
declarations or attribute values
*/
typedef void (XMLCALL *XML_SkippedEntityHandler) (
void *userData,
const XML_Char *entityName,
int is_parameter_entity);
/* This structure is filled in by the XML_UnknownEncodingHandler to
provide information to the parser about encodings that are unknown
to the parser.
The map[b] member gives information about byte sequences whose
first byte is b.
If map[b] is c where c is >= 0, then b by itself encodes the
Unicode scalar value c.
If map[b] is -1, then the byte sequence is malformed.
If map[b] is -n, where n >= 2, then b is the first byte of an
n-byte sequence that encodes a single Unicode scalar value.
The data member will be passed as the first argument to the convert
function.
The convert function is used to convert multibyte sequences; s will
point to a n-byte sequence where map[(unsigned char)*s] == -n. The
convert function must return the Unicode scalar value represented
by this byte sequence or -1 if the byte sequence is malformed.
The convert function may be NULL if the encoding is a single-byte
encoding, that is if map[b] >= -1 for all bytes b.
When the parser is finished with the encoding, then if release is
not NULL, it will call release passing it the data member; once
release has been called, the convert function will not be called
again.
Expat places certain restrictions on the encodings that are supported
using this mechanism.
1. Every ASCII character that can appear in a well-formed XML document,
other than the characters
$@\^`{}~
must be represented by a single byte, and that byte must be the
same byte that represents that character in ASCII.
2. No character may require more than 4 bytes to encode.
3. All characters encoded must have Unicode scalar values <=
0xFFFF, (i.e., characters that would be encoded by surrogates in
UTF-16 are not allowed). Note that this restriction doesn't
apply to the built-in support for UTF-8 and UTF-16.
4. No Unicode character may be encoded by more than one distinct
sequence of bytes.
*/
typedef struct {
int map[256];
void *data;
int (XMLCALL *convert)(void *data, const char *s);
void (XMLCALL *release)(void *data);
} XML_Encoding;
/* This is called for an encoding that is unknown to the parser.
The encodingHandlerData argument is that which was passed as the
second argument to XML_SetUnknownEncodingHandler.
The name argument gives the name of the encoding as specified in
the encoding declaration.
If the callback can provide information about the encoding, it must
fill in the XML_Encoding structure, and return XML_STATUS_OK.
Otherwise it must return XML_STATUS_ERROR.
If info does not describe a suitable encoding, then the parser will
return an XML_UNKNOWN_ENCODING error.
*/
typedef int (XMLCALL *XML_UnknownEncodingHandler) (
void *encodingHandlerData,
const XML_Char *name,
XML_Encoding *info);
XMLPARSEAPI(void)
XML_SetElementHandler(XML_Parser parser,
XML_StartElementHandler start,
XML_EndElementHandler end);
XMLPARSEAPI(void)
XML_SetStartElementHandler(XML_Parser parser,
XML_StartElementHandler handler);
XMLPARSEAPI(void)
XML_SetEndElementHandler(XML_Parser parser,
XML_EndElementHandler handler);
XMLPARSEAPI(void)
XML_SetCharacterDataHandler(XML_Parser parser,
XML_CharacterDataHandler handler);
XMLPARSEAPI(void)
XML_SetProcessingInstructionHandler(XML_Parser parser,
XML_ProcessingInstructionHandler handler);
XMLPARSEAPI(void)
XML_SetCommentHandler(XML_Parser parser,
XML_CommentHandler handler);
XMLPARSEAPI(void)
XML_SetCdataSectionHandler(XML_Parser parser,
XML_StartCdataSectionHandler start,
XML_EndCdataSectionHandler end);
XMLPARSEAPI(void)
XML_SetStartCdataSectionHandler(XML_Parser parser,
XML_StartCdataSectionHandler start);
XMLPARSEAPI(void)
XML_SetEndCdataSectionHandler(XML_Parser parser,
XML_EndCdataSectionHandler end);
/* This sets the default handler and also inhibits expansion of
internal entities. These entity references will be passed to the
default handler, or to the skipped entity handler, if one is set.
*/
XMLPARSEAPI(void)
XML_SetDefaultHandler(XML_Parser parser,
XML_DefaultHandler handler);
/* This sets the default handler but does not inhibit expansion of
internal entities. The entity reference will not be passed to the
default handler.
*/
XMLPARSEAPI(void)
XML_SetDefaultHandlerExpand(XML_Parser parser,
XML_DefaultHandler handler);
XMLPARSEAPI(void)
XML_SetDoctypeDeclHandler(XML_Parser parser,
XML_StartDoctypeDeclHandler start,
XML_EndDoctypeDeclHandler end);
XMLPARSEAPI(void)
XML_SetStartDoctypeDeclHandler(XML_Parser parser,
XML_StartDoctypeDeclHandler start);
XMLPARSEAPI(void)
XML_SetEndDoctypeDeclHandler(XML_Parser parser,
XML_EndDoctypeDeclHandler end);
XMLPARSEAPI(void)
XML_SetUnparsedEntityDeclHandler(XML_Parser parser,
XML_UnparsedEntityDeclHandler handler);
XMLPARSEAPI(void)
XML_SetNotationDeclHandler(XML_Parser parser,
XML_NotationDeclHandler handler);
XMLPARSEAPI(void)
XML_SetNamespaceDeclHandler(XML_Parser parser,
XML_StartNamespaceDeclHandler start,
XML_EndNamespaceDeclHandler end);
XMLPARSEAPI(void)
XML_SetStartNamespaceDeclHandler(XML_Parser parser,
XML_StartNamespaceDeclHandler start);
XMLPARSEAPI(void)
XML_SetEndNamespaceDeclHandler(XML_Parser parser,
XML_EndNamespaceDeclHandler end);
XMLPARSEAPI(void)
XML_SetNotStandaloneHandler(XML_Parser parser,
XML_NotStandaloneHandler handler);
XMLPARSEAPI(void)
XML_SetExternalEntityRefHandler(XML_Parser parser,
XML_ExternalEntityRefHandler handler);
/* If a non-NULL value for arg is specified here, then it will be
passed as the first argument to the external entity ref handler
instead of the parser object.
*/
XMLPARSEAPI(void)
XML_SetExternalEntityRefHandlerArg(XML_Parser parser,
void *arg);
XMLPARSEAPI(void)
XML_SetSkippedEntityHandler(XML_Parser parser,
XML_SkippedEntityHandler handler);
XMLPARSEAPI(void)
XML_SetUnknownEncodingHandler(XML_Parser parser,
XML_UnknownEncodingHandler handler,
void *encodingHandlerData);
/* This can be called within a handler for a start element, end
element, processing instruction or character data. It causes the
corresponding markup to be passed to the default handler.
*/
XMLPARSEAPI(void)
XML_DefaultCurrent(XML_Parser parser);
/* If do_nst is non-zero, and namespace processing is in effect, and
a name has a prefix (i.e. an explicit namespace qualifier) then
that name is returned as a triplet in a single string separated by
the separator character specified when the parser was created: URI
+ sep + local_name + sep + prefix.
If do_nst is zero, then namespace information is returned in the
default manner (URI + sep + local_name) whether or not the name
has a prefix.
Note: Calling XML_SetReturnNSTriplet after XML_Parse or
XML_ParseBuffer has no effect.
*/
XMLPARSEAPI(void)
XML_SetReturnNSTriplet(XML_Parser parser, int do_nst);
/* This value is passed as the userData argument to callbacks. */
XMLPARSEAPI(void)
XML_SetUserData(XML_Parser parser, void *userData);
/* Returns the last value set by XML_SetUserData or NULL. */
#define XML_GetUserData(parser) (*(void **)(parser))
/* This is equivalent to supplying an encoding argument to
XML_ParserCreate. On success XML_SetEncoding returns non-zero,
zero otherwise.
Note: Calling XML_SetEncoding after XML_Parse or XML_ParseBuffer
has no effect and returns XML_STATUS_ERROR.
*/
XMLPARSEAPI(enum XML_Status)
XML_SetEncoding(XML_Parser parser, const XML_Char *encoding);
/* If this function is called, then the parser will be passed as the
first argument to callbacks instead of userData. The userData will
still be accessible using XML_GetUserData.
*/
XMLPARSEAPI(void)
XML_UseParserAsHandlerArg(XML_Parser parser);
/* If useDTD == XML_TRUE is passed to this function, then the parser
will assume that there is an external subset, even if none is
specified in the document. In such a case the parser will call the
externalEntityRefHandler with a value of NULL for the systemId
argument (the publicId and context arguments will be NULL as well).
Note: For the purpose of checking WFC: Entity Declared, passing
useDTD == XML_TRUE will make the parser behave as if the document
had a DTD with an external subset.
Note: If this function is called, then this must be done before
the first call to XML_Parse or XML_ParseBuffer, since it will
have no effect after that. Returns
XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING.
Note: If the document does not have a DOCTYPE declaration at all,
then startDoctypeDeclHandler and endDoctypeDeclHandler will not
be called, despite an external subset being parsed.
Note: If XML_DTD is not defined when Expat is compiled, returns
XML_ERROR_FEATURE_REQUIRES_XML_DTD.
*/
XMLPARSEAPI(enum XML_Error)
XML_UseForeignDTD(XML_Parser parser, XML_Bool useDTD);
/* Sets the base to be used for resolving relative URIs in system
identifiers in declarations. Resolving relative identifiers is
left to the application: this value will be passed through as the
base argument to the XML_ExternalEntityRefHandler,
XML_NotationDeclHandler and XML_UnparsedEntityDeclHandler. The base
argument will be copied. Returns XML_STATUS_ERROR if out of memory,
XML_STATUS_OK otherwise.
*/
XMLPARSEAPI(enum XML_Status)
XML_SetBase(XML_Parser parser, const XML_Char *base);
XMLPARSEAPI(const XML_Char *)
XML_GetBase(XML_Parser parser);
/* Returns the number of the attribute/value pairs passed in last call
to the XML_StartElementHandler that were specified in the start-tag
rather than defaulted. Each attribute/value pair counts as 2; thus
this correspondds to an index into the atts array passed to the
XML_StartElementHandler.
*/
XMLPARSEAPI(int)
XML_GetSpecifiedAttributeCount(XML_Parser parser);
/* Returns the index of the ID attribute passed in the last call to
XML_StartElementHandler, or -1 if there is no ID attribute. Each
attribute/value pair counts as 2; thus this correspondds to an
index into the atts array passed to the XML_StartElementHandler.
*/
XMLPARSEAPI(int)
XML_GetIdAttributeIndex(XML_Parser parser);
#ifdef XML_ATTR_INFO
/* Source file byte offsets for the start and end of attribute names and values.
The value indices are exclusive of surrounding quotes; thus in a UTF-8 source
file an attribute value of "blah" will yield:
info->valueEnd - info->valueStart = 4 bytes.
*/
typedef struct {
XML_Index nameStart; /* Offset to beginning of the attribute name. */
XML_Index nameEnd; /* Offset after the attribute name's last byte. */
XML_Index valueStart; /* Offset to beginning of the attribute value. */
XML_Index valueEnd; /* Offset after the attribute value's last byte. */
} XML_AttrInfo;
/* Returns an array of XML_AttrInfo structures for the attribute/value pairs
passed in last call to the XML_StartElementHandler that were specified
in the start-tag rather than defaulted. Each attribute/value pair counts
as 1; thus the number of entries in the array is
XML_GetSpecifiedAttributeCount(parser) / 2.
*/
XMLPARSEAPI(const XML_AttrInfo *)
XML_GetAttributeInfo(XML_Parser parser);
#endif
/* Parses some input. Returns XML_STATUS_ERROR if a fatal error is
detected. The last call to XML_Parse must have isFinal true; len
may be zero for this call (or any other).
Though the return values for these functions has always been
described as a Boolean value, the implementation, at least for the
1.95.x series, has always returned exactly one of the XML_Status
values.
*/
XMLPARSEAPI(enum XML_Status)
XML_Parse(XML_Parser parser, const char *s, int len, int isFinal);
XMLPARSEAPI(void *)
XML_GetBuffer(XML_Parser parser, int len);
XMLPARSEAPI(enum XML_Status)
XML_ParseBuffer(XML_Parser parser, int len, int isFinal);
/* Stops parsing, causing XML_Parse() or XML_ParseBuffer() to return.
Must be called from within a call-back handler, except when aborting
(resumable = 0) an already suspended parser. Some call-backs may
still follow because they would otherwise get lost. Examples:
- endElementHandler() for empty elements when stopped in
startElementHandler(),
- endNameSpaceDeclHandler() when stopped in endElementHandler(),
and possibly others.
Can be called from most handlers, including DTD related call-backs,
except when parsing an external parameter entity and resumable != 0.
Returns XML_STATUS_OK when successful, XML_STATUS_ERROR otherwise.
Possible error codes:
- XML_ERROR_SUSPENDED: when suspending an already suspended parser.
- XML_ERROR_FINISHED: when the parser has already finished.
- XML_ERROR_SUSPEND_PE: when suspending while parsing an external PE.
When resumable != 0 (true) then parsing is suspended, that is,
XML_Parse() and XML_ParseBuffer() return XML_STATUS_SUSPENDED.
Otherwise, parsing is aborted, that is, XML_Parse() and XML_ParseBuffer()
return XML_STATUS_ERROR with error code XML_ERROR_ABORTED.
*Note*:
This will be applied to the current parser instance only, that is, if
there is a parent parser then it will continue parsing when the
externalEntityRefHandler() returns. It is up to the implementation of
the externalEntityRefHandler() to call XML_StopParser() on the parent
parser (recursively), if one wants to stop parsing altogether.
When suspended, parsing can be resumed by calling XML_ResumeParser().
*/
XMLPARSEAPI(enum XML_Status)
XML_StopParser(XML_Parser parser, XML_Bool resumable);
/* Resumes parsing after it has been suspended with XML_StopParser().
Must not be called from within a handler call-back. Returns same
status codes as XML_Parse() or XML_ParseBuffer().
Additional error code XML_ERROR_NOT_SUSPENDED possible.
*Note*:
This must be called on the most deeply nested child parser instance
first, and on its parent parser only after the child parser has finished,
to be applied recursively until the document entity's parser is restarted.
That is, the parent parser will not resume by itself and it is up to the
application to call XML_ResumeParser() on it at the appropriate moment.
*/
XMLPARSEAPI(enum XML_Status)
XML_ResumeParser(XML_Parser parser);
enum XML_Parsing {
XML_INITIALIZED,
XML_PARSING,
XML_FINISHED,
XML_SUSPENDED
};
typedef struct {
enum XML_Parsing parsing;
XML_Bool finalBuffer;
} XML_ParsingStatus;
/* Returns status of parser with respect to being initialized, parsing,
finished, or suspended and processing the final buffer.
XXX XML_Parse() and XML_ParseBuffer() should return XML_ParsingStatus,
XXX with XML_FINISHED_OK or XML_FINISHED_ERROR replacing XML_FINISHED
*/
XMLPARSEAPI(void)
XML_GetParsingStatus(XML_Parser parser, XML_ParsingStatus *status);
/* Creates an XML_Parser object that can parse an external general
entity; context is a '\0'-terminated string specifying the parse
context; encoding is a '\0'-terminated string giving the name of
the externally specified encoding, or NULL if there is no
externally specified encoding. The context string consists of a
sequence of tokens separated by formfeeds (\f); a token consisting
of a name specifies that the general entity of the name is open; a
token of the form prefix=uri specifies the namespace for a
particular prefix; a token of the form =uri specifies the default
namespace. This can be called at any point after the first call to
an ExternalEntityRefHandler so longer as the parser has not yet
been freed. The new parser is completely independent and may
safely be used in a separate thread. The handlers and userData are
initialized from the parser argument. Returns NULL if out of memory.
Otherwise returns a new XML_Parser object.
*/
XMLPARSEAPI(XML_Parser)
XML_ExternalEntityParserCreate(XML_Parser parser,
const XML_Char *context,
const XML_Char *encoding);
enum XML_ParamEntityParsing {
XML_PARAM_ENTITY_PARSING_NEVER,
XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE,
XML_PARAM_ENTITY_PARSING_ALWAYS
};
/* Controls parsing of parameter entities (including the external DTD
subset). If parsing of parameter entities is enabled, then
references to external parameter entities (including the external
DTD subset) will be passed to the handler set with
XML_SetExternalEntityRefHandler. The context passed will be 0.
Unlike external general entities, external parameter entities can
only be parsed synchronously. If the external parameter entity is
to be parsed, it must be parsed during the call to the external
entity ref handler: the complete sequence of
XML_ExternalEntityParserCreate, XML_Parse/XML_ParseBuffer and
XML_ParserFree calls must be made during this call. After
XML_ExternalEntityParserCreate has been called to create the parser
for the external parameter entity (context must be 0 for this
call), it is illegal to make any calls on the old parser until
XML_ParserFree has been called on the newly created parser.
If the library has been compiled without support for parameter
entity parsing (ie without XML_DTD being defined), then
XML_SetParamEntityParsing will return 0 if parsing of parameter
entities is requested; otherwise it will return non-zero.
Note: If XML_SetParamEntityParsing is called after XML_Parse or
XML_ParseBuffer, then it has no effect and will always return 0.
*/
XMLPARSEAPI(int)
XML_SetParamEntityParsing(XML_Parser parser,
enum XML_ParamEntityParsing parsing);
/* Sets the hash salt to use for internal hash calculations.
Helps in preventing DoS attacks based on predicting hash
function behavior. This must be called before parsing is started.
Returns 1 if successful, 0 when called after parsing has started.
*/
XMLPARSEAPI(int)
XML_SetHashSalt(XML_Parser parser,
unsigned long hash_salt);
/* If XML_Parse or XML_ParseBuffer have returned XML_STATUS_ERROR, then
XML_GetErrorCode returns information about the error.
*/
XMLPARSEAPI(enum XML_Error)
XML_GetErrorCode(XML_Parser parser);
/* These functions return information about the current parse
location. They may be called from any callback called to report
some parse event; in this case the location is the location of the
first of the sequence of characters that generated the event. When
called from callbacks generated by declarations in the document
prologue, the location identified isn't as neatly defined, but will
be within the relevant markup. When called outside of the callback
functions, the position indicated will be just past the last parse
event (regardless of whether there was an associated callback).
They may also be called after returning from a call to XML_Parse
or XML_ParseBuffer. If the return value is XML_STATUS_ERROR then
the location is the location of the character at which the error
was detected; otherwise the location is the location of the last
parse event, as described above.
*/
XMLPARSEAPI(XML_Size) XML_GetCurrentLineNumber(XML_Parser parser);
XMLPARSEAPI(XML_Size) XML_GetCurrentColumnNumber(XML_Parser parser);
XMLPARSEAPI(XML_Index) XML_GetCurrentByteIndex(XML_Parser parser);
/* Return the number of bytes in the current event.
Returns 0 if the event is in an internal entity.
*/
XMLPARSEAPI(int)
XML_GetCurrentByteCount(XML_Parser parser);
/* If XML_CONTEXT_BYTES is defined, returns the input buffer, sets
the integer pointed to by offset to the offset within this buffer
of the current parse position, and sets the integer pointed to by size
to the size of this buffer (the number of input bytes). Otherwise
returns a NULL pointer. Also returns a NULL pointer if a parse isn't
active.
NOTE: The character pointer returned should not be used outside
the handler that makes the call.
*/
XMLPARSEAPI(const char *)
XML_GetInputContext(XML_Parser parser,
int *offset,
int *size);
/* For backwards compatibility with previous versions. */
#define XML_GetErrorLineNumber XML_GetCurrentLineNumber
#define XML_GetErrorColumnNumber XML_GetCurrentColumnNumber
#define XML_GetErrorByteIndex XML_GetCurrentByteIndex
/* Frees the content model passed to the element declaration handler */
XMLPARSEAPI(void)
XML_FreeContentModel(XML_Parser parser, XML_Content *model);
/* Exposing the memory handling functions used in Expat */
XMLPARSEAPI(void *)
XML_ATTR_MALLOC
XML_ATTR_ALLOC_SIZE(2)
XML_MemMalloc(XML_Parser parser, size_t size);
XMLPARSEAPI(void *)
XML_ATTR_ALLOC_SIZE(3)
XML_MemRealloc(XML_Parser parser, void *ptr, size_t size);
XMLPARSEAPI(void)
XML_MemFree(XML_Parser parser, void *ptr);
/* Frees memory used by the parser. */
XMLPARSEAPI(void)
XML_ParserFree(XML_Parser parser);
/* Returns a string describing the error. */
XMLPARSEAPI(const XML_LChar *)
XML_ErrorString(enum XML_Error code);
/* Return a string containing the version number of this expat */
XMLPARSEAPI(const XML_LChar *)
XML_ExpatVersion(void);
typedef struct {
int major;
int minor;
int micro;
} XML_Expat_Version;
/* Return an XML_Expat_Version structure containing numeric version
number information for this version of expat.
*/
XMLPARSEAPI(XML_Expat_Version)
XML_ExpatVersionInfo(void);
/* Added in Expat 1.95.5. */
enum XML_FeatureEnum {
XML_FEATURE_END = 0,
XML_FEATURE_UNICODE,
XML_FEATURE_UNICODE_WCHAR_T,
XML_FEATURE_DTD,
XML_FEATURE_CONTEXT_BYTES,
XML_FEATURE_MIN_SIZE,
XML_FEATURE_SIZEOF_XML_CHAR,
XML_FEATURE_SIZEOF_XML_LCHAR,
XML_FEATURE_NS,
XML_FEATURE_LARGE_SIZE,
XML_FEATURE_ATTR_INFO
/* Additional features must be added to the end of this enum. */
};
typedef struct {
enum XML_FeatureEnum feature;
const XML_LChar *name;
long int value;
} XML_Feature;
XMLPARSEAPI(const XML_Feature *)
XML_GetFeatureList(void);
/* Expat follows the semantic versioning convention.
See http://semver.org.
*/
#define XML_MAJOR_VERSION 2
#define XML_MINOR_VERSION 2
#define XML_MICRO_VERSION 0
#ifdef __cplusplus
}
#endif
#endif /* not Expat_INCLUDED */

129
external/include/expat_external.h vendored Normal file
View File

@ -0,0 +1,129 @@
/* Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd
See the file COPYING for copying permission.
*/
#ifndef Expat_External_INCLUDED
#define Expat_External_INCLUDED 1
/* External API definitions */
#if defined(_MSC_EXTENSIONS) && !defined(__BEOS__) && !defined(__CYGWIN__)
#define XML_USE_MSC_EXTENSIONS 1
#endif
/* Expat tries very hard to make the API boundary very specifically
defined. There are two macros defined to control this boundary;
each of these can be defined before including this header to
achieve some different behavior, but doing so it not recommended or
tested frequently.
XMLCALL - The calling convention to use for all calls across the
"library boundary." This will default to cdecl, and
try really hard to tell the compiler that's what we
want.
XMLIMPORT - Whatever magic is needed to note that a function is
to be imported from a dynamically loaded library
(.dll, .so, or .sl, depending on your platform).
The XMLCALL macro was added in Expat 1.95.7. The only one which is
expected to be directly useful in client code is XMLCALL.
Note that on at least some Unix versions, the Expat library must be
compiled with the cdecl calling convention as the default since
system headers may assume the cdecl convention.
*/
#ifndef XMLCALL
#if defined(_MSC_VER)
#define XMLCALL __cdecl
#elif defined(__GNUC__) && defined(__i386) && !defined(__INTEL_COMPILER)
#define XMLCALL __attribute__((cdecl))
#else
/* For any platform which uses this definition and supports more than
one calling convention, we need to extend this definition to
declare the convention used on that platform, if it's possible to
do so.
If this is the case for your platform, please file a bug report
with information on how to identify your platform via the C
pre-processor and how to specify the same calling convention as the
platform's malloc() implementation.
*/
#define XMLCALL
#endif
#endif /* not defined XMLCALL */
#if !defined(XML_STATIC) && !defined(XMLIMPORT)
#ifndef XML_BUILDING_EXPAT
/* using Expat from an application */
#ifdef XML_USE_MSC_EXTENSIONS
#define XMLIMPORT __declspec(dllimport)
#endif
#endif
#endif /* not defined XML_STATIC */
#if !defined(XMLIMPORT) && defined(__GNUC__) && (__GNUC__ >= 4)
#define XMLIMPORT __attribute__ ((visibility ("default")))
#endif
/* If we didn't define it above, define it away: */
#ifndef XMLIMPORT
#define XMLIMPORT
#endif
#if defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 96))
#define XML_ATTR_MALLOC __attribute__((__malloc__))
#else
#define XML_ATTR_MALLOC
#endif
#if defined(__GNUC__) && ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))
#define XML_ATTR_ALLOC_SIZE(x) __attribute__((__alloc_size__(x)))
#else
#define XML_ATTR_ALLOC_SIZE(x)
#endif
#define XMLPARSEAPI(type) XMLIMPORT type XMLCALL
#ifdef __cplusplus
extern "C" {
#endif
#ifdef XML_UNICODE_WCHAR_T
#define XML_UNICODE
#endif
#ifdef XML_UNICODE /* Information is UTF-16 encoded. */
#ifdef XML_UNICODE_WCHAR_T
typedef wchar_t XML_Char;
typedef wchar_t XML_LChar;
#else
typedef unsigned short XML_Char;
typedef char XML_LChar;
#endif /* XML_UNICODE_WCHAR_T */
#else /* Information is UTF-8 encoded. */
typedef char XML_Char;
typedef char XML_LChar;
#endif /* XML_UNICODE */
#ifdef XML_LARGE_SIZE /* Use large integers for file/stream positions. */
#if defined(XML_USE_MSC_EXTENSIONS) && _MSC_VER < 1400
typedef __int64 XML_Index;
typedef unsigned __int64 XML_Size;
#else
typedef long long XML_Index;
typedef unsigned long long XML_Size;
#endif
#else
typedef long XML_Index;
typedef unsigned long XML_Size;
#endif /* XML_LARGE_SIZE */
#ifdef __cplusplus
}
#endif
#endif /* not Expat_External_INCLUDED */

1
external/lib/libexpat.so vendored Symbolic link
View File

@ -0,0 +1 @@
libexpatw.so.1.6.2

BIN
external/lib/libexpatw.so.1.6.2 vendored Normal file

Binary file not shown.

BIN
external/lib/libz.so vendored Normal file

Binary file not shown.

View File

@ -547,7 +547,7 @@ void createCommandQueues() {
// Note: contains value for each subresource range
VkClearColorValue clearColor = {
{ 0.4f, 0.6f, 0.9f, 1.0f } // R, G, B, A
{ 0.8f, 0.2f, 0.5f, 1.0f } // R, G, B, A
};
VkImageSubresourceRange subResourceRange = {};