This commit is contained in:
elwrcl committed 2026-06-06 13:25:15 +03:00
1 parent 04d4dc8b09
commit 818cab85dc
12511 files changed
+6156641

No files matched your search

+113
View File
@@ -0,0 +1,113 @@
Intel Surface Layout
Introduction
============
isl is a small library that calculates the layout of Intel GPU surfaces, queries
those layouts, and queries the properties of surface formats.
Independence from User APIs
===========================
isl's API is independent of any user-facing graphics API, such as OpenGL and
Vulkan. This independence allows isl to be used a shared component by multiple
Intel drivers.
Rather than mimic the user-facing APIs, the isl API attempts to reflect Intel
hardware: the actual memory layout of Intel GPU surfaces and how one programs
the GPU to use those surfaces. For example:
- The tokens of `enum isl_format` (such as `ISL_FORMAT_R8G8B8A8_UNORM`)
match those of the hardware enum `SURFACE_FORMAT` rather than the OpenGL
or Vulkan format tokens. And the values of `isl_format` and
`SURFACE_FORMAT` are identical.
- The OpenGL and Vulkan APIs contain depth and stencil formats. However the
hardware enum `SURFACE_FORMAT` does not, and therefore neither does `enum
isl_format`. Rather than define new pixel formats that have no hardware
counterpart, isl records the intent to use a surface as a depth or stencil
buffer with the usage flags `ISL_SURF_USAGE_DEPTH_BIT` and
`ISL_SURF_USAGE_STENCIL_BIT`.
- `struct isl_surf` distinguishes between the surface's logical dimension
from the user API's perspective (`enum isl_surf_dim`, which may be 1D, 2D,
or 3D) and the layout of those dimensions in memory (`enum isl_dim_layout`).
Surface Units
=============
Intro
-----
ISL takes care in its equations to correctly handle conversion among surface
units (such as pixels and compression blocks) and to carefully distinguish
between a surface's logical layout in the client API and its physical layout
in memory.
Symbol names often explicitly declare their unit with a suffix:
- px: logical pixels
- sa: physical surface samples
- el: physical surface elements
- sa_rows: rows of physical surface samples
- el_rows: rows of physical surface elements
Logical units are independent of hardware generation and are closely related
to the user-facing API (OpenGL and Vulkan). Physical units are dependent on
hardware generation and reflect the surface's layout in memory.
Definitions
-----------
- Logical Pixels (px):
The surface's layout from the perspective of the client API (OpenGL and
Vulkan) is in units of logical pixels. Logical pixels are independent of the
surface's layout in memory.
A surface's width and height, in units of logical pixels, is not affected by
the surface's sample count. For example, consider a VkImage created with
VkImageCreateInfo{width=w0, height=h0, samples=s0}. The surface's width and
height at level 0 is, in units of logical pixels, w0 and h0 regardless of
the value of s0.
For example, the logical array length of a 3D surface is always 1, even on
Gfx9 where the surface's memory layout is that of an array surface
(ISL_DIM_LAYOUT_GFX4_2D).
- Physical Surface Samples (sa):
For a multisampled surface, this unit has the obvious meaning.
A singlesampled surface, from ISL's perspective, is simply a multisampled
surface whose sample count is 1.
For example, consider a 2D single-level non-array surface with samples=4,
width_px=64, and height_px=64 (note that the suffix 'px' indicates logical
pixels). If the surface's multisample layout is ISL_MSAA_LAYOUT_INTERLEAVED,
then the extent of level 0 is, in units of physical surface samples,
width_sa=128, height_sa=128, depth_sa=1, array_length_sa=1. If
ISL_MSAA_LAYOUT_ARRAY, then width_sa=64, height_sa=64, depth_sa=1,
array_length_sa=4.
- Physical Surface Elements (el):
This unit allows ISL to treat compressed and uncompressed formats
identically in many calculations.
If the surface's pixel format is compressed, such as ETC2, then a surface
element is equivalent to a compression block. If uncompressed, then
a surface element is equivalent to a surface sample. As a corollary, for
a given surface a surface element is at least as large as a surface sample.
Errata
------
ISL acquired the term 'surface element' from the Broadwell PRM [1], which
defines it as follows:
An element is defined as a pixel in uncompressed surface formats, and as
a compression block in compressed surface formats. For MSFMT_DEPTH_STENCIL
type multisampled surfaces, an element is a sample.
References
==========
[1]: Broadwell PRM >> Volume 2d: Command Reference: Structures >>
RENDER_SURFACE_STATE Surface Vertical Alignment (p325)
+308
View File
@@ -0,0 +1,308 @@
# encoding=utf-8
# Copyright © 2016 Intel Corporation
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
# The above copyright notice and this permission notice 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.
"""Generates isl_format_layout.c."""
import argparse
import csv
import re
from mako import template
# Load the template and set the bytes encoding to be utf-8.
TEMPLATE = template.Template(text="""\
/* This file is autogenerated by gen_format_layout.py. DO NOT EDIT! */
/*
* Copyright 2015 Intel Corporation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
#include "isl/isl.h"
const uint16_t isl_format_name_offsets[] = { <% offset = 0 %>
% for format in formats:
[ISL_FORMAT_${format.name}] = ${offset}, <% offset += 11 + len(format.name) + 1 %>
% endfor
};
const char isl_format_names[] = {
% for format in formats:
"ISL_FORMAT_${format.name}\\0"
% endfor
};
const struct isl_format_layout
isl_format_layouts[] = {
% for format in formats:
[ISL_FORMAT_${format.name}] = {
.format = ISL_FORMAT_${format.name},
.bpb = ${format.bpb},
.bw = ${format.bw},
.bh = ${format.bh},
.bd = ${format.bd},
.channels = {
% for mask in ['r', 'g', 'b', 'a', 'l', 'i', 'p']:
<% channel = getattr(format, mask, None) %>\\
% if channel.type is not None:
.${mask} = { ISL_${channel.type}, ${channel.start}, ${channel.size} },
% else:
.${mask} = {},
% endif
% endfor
},
.uniform_channel_type = ISL_${format.uniform_channel_type},
.colorspace = ISL_COLORSPACE_${format.colorspace},
.txc = ISL_TXC_${format.txc},
},
% endfor
};
bool
isl_format_is_valid(enum isl_format format)
{
if (format >= sizeof(isl_format_layouts) / sizeof(isl_format_layouts[0]))
return false;
/* Only ISL_FORMAT_R32G32B32A32_FLOAT == 0 but that's a valid format.
* For all others, if this doesn't match then the entry in the table
* must not exist.
*/
return isl_format_layouts[format].format == format;
}
enum isl_format
isl_format_srgb_to_linear(enum isl_format format)
{
switch (format) {
% for srgb, rgb in srgb_to_linear_map:
case ISL_FORMAT_${srgb}:
return ISL_FORMAT_${rgb};
%endfor
default:
return format;
}
}
""")
class Channel(object):
"""Class representing a Channel.
Converts the csv encoded data into the format that the template (and thus
the consuming C code) expects.
"""
# If the csv file grew very large this class could be put behind a factory
# to increase efficiency. Right now though it's fast enough that It didn't
# seem worthwhile to add all of the boilerplate
_types = {
'x': 'void',
'r': 'raw',
'un': 'unorm',
'sn': 'snorm',
'uf': 'ufloat',
'sf': 'sfloat',
'ux': 'ufixed',
'sx': 'sfixed',
'ui': 'uint',
'si': 'sint',
'us': 'uscaled',
'ss': 'sscaled',
}
_splitter = re.compile(r'\s*(?P<type>[a-z]+)(?P<size>[0-9]+)')
def __init__(self, line):
# If the line is just whitespace then just set everything to None to
# save on the regex cost and let the template skip on None.
if line.isspace():
self.size = None
self.type = None
else:
grouped = self._splitter.match(line)
self.type = self._types[grouped.group('type')].upper()
self.size = int(grouped.group('size'))
# Default the start bit to -1
self.start = -1
class Format(object):
"""Class that contains all values needed by the template."""
def __init__(self, line):
# pylint: disable=invalid-name
self.name = line[0].strip()
self.bpb = int(line[1])
self.bw = line[2].strip()
self.bh = line[3].strip()
self.bd = line[4].strip()
self.r = Channel(line[5])
self.g = Channel(line[6])
self.b = Channel(line[7])
self.a = Channel(line[8])
self.l = Channel(line[9])
self.i = Channel(line[10])
self.p = Channel(line[11])
# Set the start bit value for each channel
self.order = line[12].strip()
bit = 0
for c in self.order:
chan = getattr(self, c)
chan.start = bit
bit = bit + chan.size
# Set the uniform channel type, if the format has one.
#
# Iterate over all channels, not just those in self.order, because
# some formats have an empty 'order' field in the CSV (such as
# YCRCB_NORMAL).
self.uniform_channel_type = 'VOID'
for chan in self.channels:
if chan.type in (None, 'VOID'):
pass
elif self.uniform_channel_type == 'VOID':
self.uniform_channel_type = chan.type
elif self.uniform_channel_type == chan.type:
pass
else:
self.uniform_channel_type = 'VOID'
break
# alpha doesn't have a colorspace of it's own.
self.colorspace = line[13].strip().upper()
if self.colorspace in ['']:
self.colorspace = 'NONE'
# This sets it to the line value, or if it's an empty string 'NONE'
self.txc = line[14].strip().upper() or 'NONE'
@property
def channels(self):
yield self.r
yield self.g
yield self.b
yield self.a
yield self.l
yield self.i
yield self.p
def reader(csvfile):
"""Wrapper around csv.reader that skips comments and blanks."""
# csv.reader actually reads the file one line at a time (it was designed to
# open excel generated sheets), so hold the file until all of the lines are
# read.
with open(csvfile, 'r') as f:
for line in csv.reader(f):
if line and not line[0].startswith('#'):
yield line
def get_srgb_to_linear_map(formats):
"""Compute a map from sRGB to linear formats.
This function uses some probably somewhat fragile string munging to do
the conversion. However, we do assert that, if it's SRGB, the munging
succeeded so that gives some safety.
"""
names = {f.name for f in formats}
for fmt in formats:
if fmt.colorspace != 'SRGB':
continue
replacements = [
('_SRGB', ''),
('SRGB', 'RGB'),
('U8SRGB', 'FLT16'),
# Quirk: ETC2_EAC_SRGB8_A8 -> ETC2_EAC_RGBA8
('SRGB8_A8', 'RGBA8'),
]
found = False
for rep in replacements:
rgb_name = fmt.name.replace(rep[0], rep[1])
if rgb_name in names and rgb_name != fmt.name:
found = True
yield fmt.name, rgb_name
break
# We should have found a format name
assert found
def main():
"""Main function."""
parser = argparse.ArgumentParser()
parser.add_argument('--csv', action='store', help='The CSV file to parse.')
parser.add_argument(
'--out',
action='store',
help='The location to put the generated C file.')
args = parser.parse_args()
# This generator opens and writes the file itself, and it does so in bytes
# mode. This solves the locale problem: Unicode can be rendered even
# if the shell calling this script doesn't.
with open(args.out, 'w', encoding='utf-8') as f:
formats = [Format(l) for l in reader(args.csv)]
try:
# This basically does lazy evaluation and initialization, which
# saves on memory and startup overhead.
f.write(TEMPLATE.render(
formats = formats,
srgb_to_linear_map = list(get_srgb_to_linear_map(formats)),
))
except Exception:
# In the even there's an error this imports some helpers from mako
# to print a useful stack trace and prints it, then exits with
# status 1, if python is run with debug; otherwise it just raises
# the exception
if __debug__:
import sys
from mako import exceptions
print(exceptions.text_error_template().render(),
file=sys.stderr)
sys.exit(1)
raise
if __name__ == '__main__':
main()
+5782
View File
File diff suppressed because it is too large. Load diff
+3549
View File
File diff suppressed because it is too large. Load diff
+406
View File
@@ -0,0 +1,406 @@
/*
* Copyright 2019 Intel Corporation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (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 "isl/isl.h"
#include "dev/intel_device_info.h"
#ifdef IN_UNIT_TEST
/* STATIC_ASSERT is a do { ... } while(0) statement */
UNUSED static void static_assert_func(void) {
STATIC_ASSERT(ISL_AUX_OP_ASSERT == ((enum isl_aux_op) 0));
STATIC_ASSERT(ISL_AUX_STATE_ASSERT == ((enum isl_aux_state) 0));
}
#undef UNREACHABLE
#define UNREACHABLE(str) return 0
#undef assert
#define assert(cond) do { \
if (!(cond)) { \
return 0; \
} \
} while (0)
#endif
/* How writes with an isl_aux_usage behave. */
enum write_behavior {
/* Writes only touch the main surface. */
WRITES_ONLY_TOUCH_MAIN = 0,
/* Writes using the 3D engine are compressed. */
WRITES_COMPRESS,
/* Writes using the 3D engine are either compressed or substituted with
* fast-cleared blocks.
*/
WRITES_COMPRESS_CLEAR,
/* Writes using the 3D engine are compressed and potentially update
* the contents of the hierarchical depth buffer causing it to end
* up in non-passthrough state.
*/
WRITES_COMPRESS_HIZ,
/* Writes implicitly fully resolve the compression block and write the data
* uncompressed into the main surface. The resolved aux blocks are
* ambiguated and left in the pass-through state.
*/
WRITES_RESOLVE_AMBIGUATE,
};
/* A set of features supported by an isl_aux_usage. */
struct aux_usage_info {
/* How writes affect the surface(s) in use. */
enum write_behavior write_behavior;
/* Aux supports "real" compression beyond just fast-clears. */
bool compressed;
/* SW can perform ISL_AUX_OP_FAST_CLEAR. */
bool fast_clear;
/* SW can perform ISL_AUX_OP_PARTIAL_RESOLVE. */
bool partial_resolve;
/* Performing ISL_AUX_OP_FULL_RESOLVE includes ISL_AUX_OP_AMBIGUATE. */
bool full_resolves_ambiguate;
};
#define AUX(wb, c, fc, pr, fra, type) \
[ISL_AUX_USAGE_ ## type] = { WRITES_ ## wb, c, fc, pr, fra},
#define Y true
#define x false
static const struct aux_usage_info info[] = {
/* write_behavior c fc pr fra */
AUX( COMPRESS_HIZ, Y, Y, x, x, HIZ)
AUX( COMPRESS_HIZ, Y, Y, x, x, HIZ_CCS)
AUX( COMPRESS, Y, Y, x, x, HIZ_CCS_WT)
AUX( COMPRESS, Y, Y, Y, x, MCS)
AUX( COMPRESS, Y, Y, Y, x, MCS_CCS)
AUX( COMPRESS, Y, Y, Y, Y, CCS_E)
AUX( COMPRESS_CLEAR, Y, Y, Y, Y, FCV_CCS_E)
AUX(RESOLVE_AMBIGUATE, x, Y, x, Y, CCS_D)
AUX(RESOLVE_AMBIGUATE, Y, x, x, Y, MC)
AUX( COMPRESS, Y, x, x, Y, STC_CCS)
};
#undef x
#undef Y
#undef AUX
ASSERTED static bool
aux_state_possible(enum isl_aux_state state,
enum isl_aux_usage usage)
{
switch (state) {
case ISL_AUX_STATE_CLEAR:
case ISL_AUX_STATE_PARTIAL_CLEAR:
return info[usage].fast_clear;
case ISL_AUX_STATE_COMPRESSED_CLEAR:
return info[usage].fast_clear && info[usage].compressed;
case ISL_AUX_STATE_COMPRESSED_HIER_DEPTH:
return info[usage].write_behavior == WRITES_COMPRESS_HIZ;
case ISL_AUX_STATE_COMPRESSED_NO_CLEAR:
return info[usage].compressed;
case ISL_AUX_STATE_RESOLVED:
case ISL_AUX_STATE_PASS_THROUGH:
case ISL_AUX_STATE_AUX_INVALID:
return true;
#ifdef IN_UNIT_TEST
case ISL_AUX_STATE_ASSERT:
break;
#endif
}
UNREACHABLE("Invalid aux state.");
}
enum isl_aux_state
isl_aux_get_initial_state(const struct intel_device_info *devinfo,
enum isl_aux_usage usage,
bool zeroed)
{
switch (usage) {
case ISL_AUX_USAGE_HIZ:
case ISL_AUX_USAGE_HIZ_CCS:
case ISL_AUX_USAGE_HIZ_CCS_WT:
if (zeroed && devinfo->ver <= 11) {
/* On ICL and prior, fast-clearing a HiZ block fills it with zeroes.
* On gfx12+, it is filled with a non-zero value.
*/
return ISL_AUX_STATE_CLEAR;
} else {
return ISL_AUX_STATE_AUX_INVALID;
}
case ISL_AUX_USAGE_MCS:
case ISL_AUX_USAGE_MCS_CCS:
if (zeroed) {
/* From the Sky Lake PRM, "Compressed Multisampled Surfaces":
*
* "An MCS value of 0x00 indicates that both samples are stored in
* sample slice 0 (thus have the same color). This is the fully
* compressed case."
*
* This quote is from the 2x MSAA section, but the same mapping
* exists for 4-16x MSAA. This state can avoid the need to ambiguate
* in some cases.
*/
return ISL_AUX_STATE_COMPRESSED_NO_CLEAR;
} else {
return ISL_AUX_STATE_AUX_INVALID;
}
case ISL_AUX_USAGE_CCS_D:
case ISL_AUX_USAGE_CCS_E:
case ISL_AUX_USAGE_FCV_CCS_E:
case ISL_AUX_USAGE_STC_CCS:
if (zeroed) {
/* From the Sky Lake PRM, "MCS Buffer for Render Target(s)":
*
* "If Software wants to enable Color Compression without Fast
* clear, Software needs to initialize MCS with zeros."
*
* Although MCS is mentioned, CCS seems to have been intended. This
* can be seen in Bspec 14091, in the row containing
* WaDisableCCSClearsIfRtCompressionEnabledInGT3.
*
* A CCS surface initialized to zero is in the pass-through state.
* This state can avoid the need to ambiguate in some cases.
*/
return ISL_AUX_STATE_PASS_THROUGH;
} else if (devinfo->ver >= 12) {
/* From Bspec 47709, "MCS/CCS Buffers for Render Target(s)":
*
* "CCS surface does not require initialization. Illegal CCS
* [values] are treated as uncompressed memory."
*
* The above quote is from the render target section, but we assume
* it applies to CCS in general (e.g., STC_CCS). The uninitialized
* CCS may be in any aux state. We choose the one which is most
* convenient.
*
* We avoid states with CLEAR because stencil does not support it.
* Those states also create a dependency on the clear color, which
* can have negative performance implications. Even though some
* blocks may actually be encoded with CLEAR, we can get away with
* ignoring them - there are no known issues that require fast
* cleared blocks to be tracked and avoided.
*
* We specifically avoid the AUX_INVALID state because it could
* trigger an ambiguate. BLORP does not have support for ambiguating
* stencil. Also, ambiguating some LODs of mipmapped 8bpp surfaces
* seems to stomp on neighboring miplevels.
*
* There is only one remaining aux state which can give us correct
* behavior, COMPRESSED_NO_CLEAR.
*/
return ISL_AUX_STATE_COMPRESSED_NO_CLEAR;
} else if (devinfo->ver >= 9) {
return ISL_AUX_STATE_AUX_INVALID;
} else {
UNREACHABLE("Unsupported gfx version");
}
default:
UNREACHABLE("Unsupported aux mode");
}
}
enum isl_aux_op
isl_aux_prepare_access(enum isl_aux_state initial_state,
enum isl_aux_usage usage,
bool fast_clear_supported)
{
if (usage != ISL_AUX_USAGE_NONE) {
UNUSED const enum isl_aux_usage state_superset_usage =
usage == ISL_AUX_USAGE_CCS_D ? ISL_AUX_USAGE_CCS_E :
usage == ISL_AUX_USAGE_HIZ_CCS_WT ? ISL_AUX_USAGE_HIZ_CCS : usage;
assert(aux_state_possible(initial_state, state_superset_usage));
}
assert(!fast_clear_supported || info[usage].fast_clear);
switch (initial_state) {
case ISL_AUX_STATE_CLEAR:
if (!fast_clear_supported)
return info[usage].partial_resolve ?
ISL_AUX_OP_PARTIAL_RESOLVE : ISL_AUX_OP_FULL_RESOLVE;
else if (usage == ISL_AUX_USAGE_HIZ_CCS_WT)
return ISL_AUX_OP_PARTIAL_RESOLVE;
else
return ISL_AUX_OP_NONE;
case ISL_AUX_STATE_COMPRESSED_HIER_DEPTH:
if (!fast_clear_supported)
return ISL_AUX_OP_FULL_RESOLVE;
else if (info[usage].write_behavior != WRITES_COMPRESS_HIZ)
return ISL_AUX_OP_PARTIAL_RESOLVE;
FALLTHROUGH;
case ISL_AUX_STATE_COMPRESSED_CLEAR:
if (!info[usage].compressed)
return ISL_AUX_OP_FULL_RESOLVE;
FALLTHROUGH;
case ISL_AUX_STATE_PARTIAL_CLEAR:
return fast_clear_supported ?
ISL_AUX_OP_NONE :
info[usage].partial_resolve ?
ISL_AUX_OP_PARTIAL_RESOLVE : ISL_AUX_OP_FULL_RESOLVE;
case ISL_AUX_STATE_COMPRESSED_NO_CLEAR:
return info[usage].compressed ?
ISL_AUX_OP_NONE : ISL_AUX_OP_FULL_RESOLVE;
case ISL_AUX_STATE_RESOLVED:
case ISL_AUX_STATE_PASS_THROUGH:
return ISL_AUX_OP_NONE;
case ISL_AUX_STATE_AUX_INVALID:
return info[usage].write_behavior == WRITES_ONLY_TOUCH_MAIN ?
ISL_AUX_OP_NONE : ISL_AUX_OP_AMBIGUATE;
#ifdef IN_UNIT_TEST
case ISL_AUX_STATE_ASSERT:
break;
#endif
}
UNREACHABLE("Invalid aux state.");
}
enum isl_aux_state
isl_aux_state_transition_aux_op(enum isl_aux_state initial_state,
enum isl_aux_usage usage,
enum isl_aux_op op)
{
assert(aux_state_possible(initial_state, usage));
assert(usage != ISL_AUX_USAGE_NONE || op == ISL_AUX_OP_NONE);
switch (op) {
case ISL_AUX_OP_NONE:
return initial_state;
case ISL_AUX_OP_FAST_CLEAR:
assert(info[usage].fast_clear);
return ISL_AUX_STATE_CLEAR;
case ISL_AUX_OP_PARTIAL_RESOLVE:
assert(isl_aux_state_has_valid_aux(initial_state));
if (isl_aux_usage_has_hiz(usage)) {
assert(initial_state != ISL_AUX_STATE_PARTIAL_CLEAR);
if (isl_aux_usage_has_ccs(usage)) {
return initial_state == ISL_AUX_STATE_COMPRESSED_HIER_DEPTH ||
initial_state == ISL_AUX_STATE_CLEAR ?
ISL_AUX_STATE_COMPRESSED_CLEAR : initial_state;
} else {
return initial_state == ISL_AUX_STATE_COMPRESSED_HIER_DEPTH ||
initial_state == ISL_AUX_STATE_COMPRESSED_CLEAR ||
initial_state == ISL_AUX_STATE_COMPRESSED_NO_CLEAR ||
initial_state == ISL_AUX_STATE_CLEAR ?
ISL_AUX_STATE_RESOLVED : initial_state;
}
} else {
assert(info[usage].partial_resolve);
return initial_state == ISL_AUX_STATE_CLEAR ||
initial_state == ISL_AUX_STATE_PARTIAL_CLEAR ||
initial_state == ISL_AUX_STATE_COMPRESSED_CLEAR ?
ISL_AUX_STATE_COMPRESSED_NO_CLEAR : initial_state;
}
case ISL_AUX_OP_FULL_RESOLVE:
assert(isl_aux_state_has_valid_aux(initial_state));
return info[usage].full_resolves_ambiguate ||
initial_state == ISL_AUX_STATE_PASS_THROUGH ?
ISL_AUX_STATE_PASS_THROUGH : ISL_AUX_STATE_RESOLVED;
case ISL_AUX_OP_AMBIGUATE:
return ISL_AUX_STATE_PASS_THROUGH;
#if IN_UNIT_TEST
case ISL_AUX_OP_ASSERT:
break;
#endif
}
UNREACHABLE("Invalid aux op.");
}
enum isl_aux_state
isl_aux_state_transition_write(enum isl_aux_state initial_state,
enum isl_aux_usage usage,
bool full_surface)
{
if (info[usage].write_behavior == WRITES_ONLY_TOUCH_MAIN) {
assert(full_surface || isl_aux_state_has_valid_primary(initial_state));
return initial_state == ISL_AUX_STATE_PASS_THROUGH ?
ISL_AUX_STATE_PASS_THROUGH : ISL_AUX_STATE_AUX_INVALID;
}
assert(isl_aux_state_has_valid_aux(initial_state));
assert(aux_state_possible(initial_state, usage));
assert(info[usage].write_behavior == WRITES_COMPRESS ||
info[usage].write_behavior == WRITES_COMPRESS_CLEAR ||
info[usage].write_behavior == WRITES_COMPRESS_HIZ ||
info[usage].write_behavior == WRITES_RESOLVE_AMBIGUATE);
if (full_surface) {
return info[usage].write_behavior == WRITES_COMPRESS ?
ISL_AUX_STATE_COMPRESSED_NO_CLEAR :
info[usage].write_behavior == WRITES_COMPRESS_CLEAR ?
ISL_AUX_STATE_COMPRESSED_CLEAR :
info[usage].write_behavior == WRITES_COMPRESS_HIZ ?
ISL_AUX_STATE_COMPRESSED_HIER_DEPTH :
ISL_AUX_STATE_PASS_THROUGH;
}
switch (initial_state) {
case ISL_AUX_STATE_CLEAR:
case ISL_AUX_STATE_PARTIAL_CLEAR:
return info[usage].write_behavior == WRITES_RESOLVE_AMBIGUATE ?
ISL_AUX_STATE_PARTIAL_CLEAR :
info[usage].write_behavior == WRITES_COMPRESS_HIZ ?
ISL_AUX_STATE_COMPRESSED_HIER_DEPTH :
ISL_AUX_STATE_COMPRESSED_CLEAR;
case ISL_AUX_STATE_RESOLVED:
case ISL_AUX_STATE_PASS_THROUGH:
case ISL_AUX_STATE_COMPRESSED_NO_CLEAR:
return info[usage].write_behavior == WRITES_COMPRESS ?
ISL_AUX_STATE_COMPRESSED_NO_CLEAR :
info[usage].write_behavior == WRITES_COMPRESS_CLEAR ?
ISL_AUX_STATE_COMPRESSED_CLEAR :
info[usage].write_behavior == WRITES_COMPRESS_HIZ ?
ISL_AUX_STATE_COMPRESSED_HIER_DEPTH :
initial_state;
case ISL_AUX_STATE_COMPRESSED_CLEAR:
return info[usage].write_behavior == WRITES_COMPRESS_HIZ ?
ISL_AUX_STATE_COMPRESSED_HIER_DEPTH : initial_state;
case ISL_AUX_STATE_COMPRESSED_HIER_DEPTH:
case ISL_AUX_STATE_AUX_INVALID:
return initial_state;
#ifdef IN_UNIT_TEST
case ISL_AUX_STATE_ASSERT:
break;
#endif
}
UNREACHABLE("Invalid aux state.");
}
bool
isl_aux_usage_has_fast_clears(enum isl_aux_usage usage)
{
return info[usage].fast_clear;
}
bool
isl_aux_usage_has_compression(enum isl_aux_usage usage)
{
return info[usage].compressed;
}
+325
View File
@@ -0,0 +1,325 @@
/*
* Copyright 2017 Intel Corporation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
#include <assert.h>
#include <stdlib.h>
#include "drm-uapi/drm_fourcc.h"
#include "drm-uapi/i915_drm.h"
#include "isl.h"
#include "dev/intel_device_info.h"
#include "dev/intel_debug.h"
uint32_t
isl_tiling_to_i915_tiling(enum isl_tiling tiling)
{
switch (tiling) {
case ISL_TILING_LINEAR:
return I915_TILING_NONE;
case ISL_TILING_X:
return I915_TILING_X;
case ISL_TILING_Y0:
case ISL_TILING_HIZ:
case ISL_TILING_CCS:
return I915_TILING_Y;
case ISL_TILING_W:
case ISL_TILING_SKL_Yf:
case ISL_TILING_SKL_Ys:
case ISL_TILING_ICL_Yf:
case ISL_TILING_ICL_Ys:
case ISL_TILING_4:
case ISL_TILING_64:
case ISL_TILING_64_XE2:
return I915_TILING_NONE;
}
UNREACHABLE("Invalid ISL tiling");
}
enum isl_tiling
isl_tiling_from_i915_tiling(uint32_t tiling)
{
switch (tiling) {
case I915_TILING_NONE:
return ISL_TILING_LINEAR;
case I915_TILING_X:
return ISL_TILING_X;
case I915_TILING_Y:
return ISL_TILING_Y0;
}
UNREACHABLE("Invalid i915 tiling");
}
/** Sentinel is DRM_FORMAT_MOD_INVALID. */
const struct isl_drm_modifier_info
isl_drm_modifier_info_list[] = {
{
.modifier = DRM_FORMAT_MOD_NONE,
.name = "DRM_FORMAT_MOD_NONE",
.tiling = ISL_TILING_LINEAR,
},
{
.modifier = I915_FORMAT_MOD_X_TILED,
.name = "I915_FORMAT_MOD_X_TILED",
.tiling = ISL_TILING_X,
},
{
.modifier = I915_FORMAT_MOD_Y_TILED,
.name = "I915_FORMAT_MOD_Y_TILED",
.tiling = ISL_TILING_Y0,
},
{
.modifier = I915_FORMAT_MOD_Y_TILED_CCS,
.name = "I915_FORMAT_MOD_Y_TILED_CCS",
.tiling = ISL_TILING_Y0,
.supports_render_compression = true,
.supports_clear_color = false,
},
{
.modifier = I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS,
.name = "I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS",
.tiling = ISL_TILING_Y0,
.supports_render_compression = true,
.supports_clear_color = false,
},
{
.modifier = I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS,
.name = "I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS",
.tiling = ISL_TILING_Y0,
.supports_media_compression = true,
.supports_clear_color = false,
},
{
.modifier = I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS_CC,
.name = "I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS_CC",
.tiling = ISL_TILING_Y0,
.supports_render_compression = true,
.supports_clear_color = true,
},
{
.modifier = I915_FORMAT_MOD_4_TILED,
.name = "I915_FORMAT_MOD_4_TILED",
.tiling = ISL_TILING_4,
},
{
.modifier = I915_FORMAT_MOD_4_TILED_DG2_RC_CCS,
.name = "I915_FORMAT_MOD_4_TILED_DG2_RC_CCS",
.tiling = ISL_TILING_4,
.supports_render_compression = true,
.supports_clear_color = false,
},
{
.modifier = I915_FORMAT_MOD_4_TILED_DG2_MC_CCS,
.name = "I915_FORMAT_MOD_4_TILED_DG2_MC_CCS",
.tiling = ISL_TILING_4,
.supports_media_compression = true,
.supports_clear_color = false,
},
{
.modifier = I915_FORMAT_MOD_4_TILED_DG2_RC_CCS_CC,
.name = "I915_FORMAT_MOD_4_TILED_DG2_RC_CCS_CC",
.tiling = ISL_TILING_4,
.supports_render_compression = true,
.supports_clear_color = true,
},
{
.modifier = I915_FORMAT_MOD_4_TILED_MTL_RC_CCS,
.name = "I915_FORMAT_MOD_4_TILED_MTL_RC_CCS",
.tiling = ISL_TILING_4,
.supports_render_compression = true,
.supports_clear_color = false,
},
{
.modifier = I915_FORMAT_MOD_4_TILED_MTL_RC_CCS_CC,
.name = "I915_FORMAT_MOD_4_TILED_MTL_RC_CCS_CC",
.tiling = ISL_TILING_4,
.supports_render_compression = true,
.supports_clear_color = true,
},
{
.modifier = I915_FORMAT_MOD_4_TILED_MTL_MC_CCS,
.name = "I915_FORMAT_MOD_4_TILED_MTL_MC_CCS",
.tiling = ISL_TILING_4,
.supports_media_compression = true,
.supports_clear_color = false,
},
{
.modifier = I915_FORMAT_MOD_4_TILED_LNL_CCS,
.name = "I915_FORMAT_MOD_4_TILED_LNL_CCS",
.tiling = ISL_TILING_4,
.supports_render_compression = true,
.supports_clear_color = false,
},
{
.modifier = I915_FORMAT_MOD_4_TILED_BMG_CCS,
.name = "I915_FORMAT_MOD_4_TILED_BMG_CCS",
.tiling = ISL_TILING_4,
.supports_render_compression = true,
.supports_clear_color = false,
},
{
.modifier = DRM_FORMAT_MOD_INVALID,
},
};
const struct isl_drm_modifier_info *
isl_drm_modifier_get_info(uint64_t modifier)
{
isl_drm_modifier_info_for_each(info) {
if (info->modifier == modifier)
return info;
}
return NULL;
}
uint32_t
isl_drm_modifier_get_score(const struct intel_device_info *devinfo,
uint64_t modifier)
{
/* We want to know the absence of the debug environment variable
* and don't want to provide a default value either, so we don't
* use debug_get_num_option() here.
*/
const char *mod_str = os_get_option("INTEL_MODIFIER_OVERRIDE");
if (mod_str != NULL) {
return modifier == strtoul(mod_str, NULL, 0);
}
const struct isl_drm_modifier_info *mod_info =
isl_drm_modifier_get_info(modifier);
if (mod_info != NULL) {
if (mod_info->supports_render_compression &&
(INTEL_DEBUG(DEBUG_NO_CCS) || INTEL_DEBUG(DEBUG_NO_CCS_MODIFIER)))
return 0;
if (mod_info->supports_clear_color && INTEL_DEBUG(DEBUG_NO_FAST_CLEAR))
return 0;
}
/* FINISHME: Add gfx12 modifiers */
switch (modifier) {
default:
return 0;
case DRM_FORMAT_MOD_LINEAR:
return 1;
case I915_FORMAT_MOD_X_TILED:
return 2;
case I915_FORMAT_MOD_Y_TILED:
/* Gfx12.5 doesn't have Y-tiling. */
if (devinfo->verx10 >= 125)
return 0;
return 3;
case I915_FORMAT_MOD_Y_TILED_CCS:
/* Not supported before Gfx9 and also Gfx12's CCS layout differs from
* Gfx9-11.
*/
if (devinfo->ver <= 8 || devinfo->ver >= 12)
return 0;
return 4;
case I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS:
if (devinfo->verx10 != 120)
return 0;
return 4;
case I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS_CC:
if (devinfo->verx10 != 120)
return 0;
return 5;
case I915_FORMAT_MOD_4_TILED:
/* Gfx12.5 introduces Tile4. */
if (devinfo->verx10 < 125)
return 0;
return 3;
case I915_FORMAT_MOD_4_TILED_DG2_RC_CCS:
if (!intel_device_info_is_dg2(devinfo))
return 0;
return 4;
case I915_FORMAT_MOD_4_TILED_DG2_RC_CCS_CC:
if (!intel_device_info_is_dg2(devinfo))
return 0;
return 5;
case I915_FORMAT_MOD_4_TILED_MTL_RC_CCS:
if (!intel_device_info_is_mtl_or_arl(devinfo))
return 0;
return 4;
case I915_FORMAT_MOD_4_TILED_MTL_RC_CCS_CC:
if (!intel_device_info_is_mtl_or_arl(devinfo))
return 0;
return 5;
case I915_FORMAT_MOD_4_TILED_LNL_CCS:
if (devinfo->ver < 20 || devinfo->has_local_mem)
return 0;
return 4;
case I915_FORMAT_MOD_4_TILED_BMG_CCS:
if (devinfo->ver < 20 || !devinfo->has_local_mem)
return 0;
return 4;
}
}
uint32_t
isl_drm_modifier_get_plane_count(const struct intel_device_info *devinfo,
uint64_t modifier,
uint32_t fmt_planes)
{
/* This function could return the wrong value if the modifier is not
* supported by the device.
*/
assert(isl_drm_modifier_get_score(devinfo, modifier) > 0);
/* Planar images don't support clear color. */
if (isl_drm_modifier_get_info(modifier)->supports_clear_color)
assert(fmt_planes == 1);
if (devinfo->has_flat_ccs) {
if (isl_drm_modifier_get_info(modifier)->supports_clear_color)
return 2 * fmt_planes;
else
return 1 * fmt_planes;
} else {
if (isl_drm_modifier_get_info(modifier)->supports_clear_color)
return 3 * fmt_planes;
else if (isl_drm_modifier_has_aux(modifier))
return 2 * fmt_planes;
else
return 1 * fmt_planes;
}
}
+126
View File
@@ -0,0 +1,126 @@
/*
* Copyright 2020 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 <stdint.h>
#define __gen_address_type uint64_t
#define __gen_user_data void
static uint64_t
__gen_combine_address(__attribute__((unused)) void *data,
__attribute__((unused)) void *loc, uint64_t addr,
uint32_t delta)
{
return addr + delta;
}
#include "genxml/gen_macros.h"
#include "genxml/genX_pack.h"
#include "isl_priv.h"
#include "isl_genX_helpers.h"
#if GFX_VERx10 >= 125
static const uint8_t isl_encode_tiling[] = {
[ISL_TILING_4] = TILE4,
[ISL_TILING_64] = TILE64,
[ISL_TILING_64_XE2] = TILE64,
};
#endif
void
isl_genX(emit_cpb_control_s)(const struct isl_device *dev, void *batch,
const struct isl_cpb_emit_info *restrict info)
{
#if GFX_VERx10 >= 125
if (info->surf) {
assert((info->surf->usage & ISL_SURF_USAGE_CPB_BIT));
assert(info->surf->dim != ISL_SURF_DIM_3D);
assert(info->surf->tiling == ISL_TILING_4 ||
isl_tiling_is_64(info->surf->tiling));
assert(info->surf->format == ISL_FORMAT_R8_UINT);
}
struct GENX(3DSTATE_CPSIZE_CONTROL_BUFFER) cpb = {
GENX(3DSTATE_CPSIZE_CONTROL_BUFFER_header),
};
if (info->surf) {
/* BSpec 46962 has a number of restriction on the fields of this packet
* like :
*
* "The Width specified by this field must be less than or equal to
* the surface pitch (specified in bytes via the Surface Pitch field).
* For cube maps, Width must be set equal to Height.
*
* 1. The Width ofthis buffer must be the same as the Width of the
* render target(s) (defined in SURFACE_STATE), unless Surface
* Type is SURFTYPE_1D or SURFTYPE_2D with Depth = 0 (non-array)
* and LOD = 0 (non-mip mapped).
*
* 2. Depth buffer (defined in 3DSTATE_DEPTH_BUFFER) unless either
* the depth buffer or this buffer surf_typeare SURFTYPE_NULL"
*
* Unfortunately APIs like Vulkan do not give guarantees that every
* framebuffer attachment will match in size (RT & CPB surfaces for
* example). But at least it gives a guarantee that all the attachments
* of a render pass will be at least be large enough to handle the
* rendered area. So here we use the CPB surface values, even if they
* don't strictly match the various BSpec restrictions.
*/
cpb.Width = (info->surf->logical_level0_px.width * 8) - 1;
cpb.Height = (info->surf->logical_level0_px.height * 8) - 1;
cpb.Depth = info->view->array_len - 1;
cpb.RenderTargetViewExtent = cpb.Depth;
cpb.SurfLOD = info->view->base_level;
cpb.MinimumArrayElement = info->view->base_array_layer;
cpb.SurfaceType = SURFTYPE_2D;
cpb.SurfacePitch = info->surf->row_pitch_B - 1;
cpb.MOCS = info->mocs;
cpb.SurfaceQPitch = isl_surf_get_array_pitch_sa_rows(info->surf) >> 2;
cpb.TiledMode = isl_encode_tiling[info->surf->tiling];
assert(info->address % info->surf->alignment_B == 0);
cpb.SurfaceBaseAddress = info->address;
cpb.MipTailStartLOD = info->surf->miptail_start_level;
#if GFX_VER >= 20
cpb.CompressionFormat =
isl_get_render_compression_format(info->surf->format);
#else
cpb.LosslessCompressionEnable =
isl_aux_usage_has_compression(info->aux_usage);
#endif
} else {
cpb.SurfaceType = SURFTYPE_NULL;
cpb.TiledMode = TILE64;
}
/* Pack everything into the batch */
uint32_t *dw = batch;
GENX(3DSTATE_CPSIZE_CONTROL_BUFFER_pack)(NULL, dw, &cpb);
#else
UNREACHABLE("Coarse pixel shading not supported");
#endif
}
+461
View File
@@ -0,0 +1,461 @@
/*
* Copyright 2016 Intel Corporation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
#include <stdint.h>
#define __gen_address_type uint64_t
#define __gen_user_data void
static uint64_t
__gen_combine_address(__attribute__((unused)) void *data,
__attribute__((unused)) void *loc, uint64_t addr,
uint32_t delta)
{
return addr + delta;
}
#include "genxml/gen_macros.h"
#include "genxml/genX_pack.h"
#include "isl_priv.h"
#include "isl_genX_helpers.h"
static const uint32_t isl_encode_ds_surftype[] = {
#if GFX_VER >= 9
/* From the SKL PRM, "3DSTATE_DEPTH_STENCIL::SurfaceType":
*
* "If depth/stencil is enabled with 1D render target, depth/stencil
* surface type needs to be set to 2D surface type and height set to 1.
* Depth will use (legacy) TileY and stencil will use TileW. For this
* case only, the Surface Type of the depth buffer can be 2D while the
* Surface Type of the render target(s) are 1D, representing an
* exception to a programming note above.
*/
[ISL_SURF_DIM_1D] = SURFTYPE_2D,
#else
[ISL_SURF_DIM_1D] = SURFTYPE_1D,
#endif
[ISL_SURF_DIM_2D] = SURFTYPE_2D,
[ISL_SURF_DIM_3D] = SURFTYPE_3D,
};
#if GFX_VER >= 9
static const uint8_t isl_encode_tiling[] = {
#if GFX_VERx10 >= 125
[ISL_TILING_4] = TILE4,
[ISL_TILING_64] = TILE64,
[ISL_TILING_64_XE2] = TILE64,
#else
[ISL_TILING_Y0] = NONE,
[ISL_TILING_SKL_Yf] = TILEYF,
[ISL_TILING_SKL_Ys] = TILEYS,
[ISL_TILING_ICL_Yf] = TILEYF,
[ISL_TILING_ICL_Ys] = TILEYS,
#endif
};
#endif /* GFX_VER >= 9 */
void
isl_genX(emit_depth_stencil_hiz_s)(const struct isl_device *dev, void *batch,
const struct isl_depth_stencil_hiz_emit_info *restrict info)
{
if (info->depth_surf && info->stencil_surf) {
if (!dev->info->has_hiz_and_separate_stencil) {
assert(info->depth_surf == info->stencil_surf);
assert(info->depth_address == info->stencil_address);
}
assert(info->depth_surf->dim == info->stencil_surf->dim);
}
if (info->depth_surf) {
assert((info->depth_surf->usage & ISL_SURF_USAGE_DEPTH_BIT));
if (info->depth_surf->dim == ISL_SURF_DIM_3D) {
assert(info->view->base_array_layer + info->view->array_len <=
info->depth_surf->logical_level0_px.depth);
} else {
assert(info->view->base_array_layer + info->view->array_len <=
info->depth_surf->logical_level0_px.array_len);
}
}
if (info->stencil_surf) {
assert(info->stencil_surf->usage & (ISL_SURF_USAGE_STENCIL_BIT |
ISL_SURF_USAGE_CPB_BIT));
if (info->stencil_surf->dim == ISL_SURF_DIM_3D) {
assert(info->view->base_array_layer + info->view->array_len <=
info->stencil_surf->logical_level0_px.depth);
} else {
assert(info->view->base_array_layer + info->view->array_len <=
info->stencil_surf->logical_level0_px.array_len);
}
}
struct GENX(3DSTATE_DEPTH_BUFFER) db = {
GENX(3DSTATE_DEPTH_BUFFER_header),
#if GFX_VER >= 6
.MOCS = info->mocs,
#endif
};
if (info->depth_surf) {
db.SurfaceType = isl_encode_ds_surftype[info->depth_surf->dim];
db.SurfaceFormat = isl_surf_get_depth_format(dev, info->depth_surf);
db.Width = info->depth_surf->logical_level0_px.width - 1;
db.Height = info->depth_surf->logical_level0_px.height - 1;
if (db.SurfaceType == SURFTYPE_3D)
db.Depth = info->depth_surf->logical_level0_px.depth - 1;
} else if (info->stencil_surf) {
/* On Gfx12+ 3DSTATE_STENCIL_BUFFER has its own fields for all of
* this. No need to replicate it here.
*/
#if GFX_VER < 12
db.SurfaceType = isl_encode_ds_surftype[info->stencil_surf->dim];
db.SurfaceFormat = D32_FLOAT;
db.Width = info->stencil_surf->logical_level0_px.width - 1;
db.Height = info->stencil_surf->logical_level0_px.height - 1;
if (db.SurfaceType == SURFTYPE_3D)
db.Depth = info->stencil_surf->logical_level0_px.depth - 1;
#else
db.SurfaceType = SURFTYPE_NULL;
db.SurfaceFormat = D32_FLOAT;
#endif
} else {
db.SurfaceType = SURFTYPE_NULL;
db.SurfaceFormat = D32_FLOAT;
}
if (info->depth_surf || info->stencil_surf) {
/* These are based entirely on the view */
db.RenderTargetViewExtent = info->view->array_len - 1;
db.LOD = info->view->base_level;
db.MinimumArrayElement = info->view->base_array_layer;
/* From the Haswell PRM docs for 3DSTATE_DEPTH_BUFFER::Depth
*
* "This field specifies the total number of levels for a volume
* texture or the number of array elements allowed to be accessed
* starting at the Minimum Array Element for arrayed surfaces. If the
* volume texture is MIP-mapped, this field specifies the depth of
* the base MIP level."
*
* For 3D surfaces, we set it to the correct depth above. For non-3D
* surfaces, this is the same as RenderTargetViewExtent.
*/
if (db.SurfaceType != SURFTYPE_3D)
db.Depth = db.RenderTargetViewExtent;
}
if (info->depth_surf) {
#if GFX_VER >= 7
db.DepthWriteEnable = true;
#endif
#if GFX_VER >= 9
assert(info->depth_address % info->depth_surf->alignment_B == 0);
#endif
db.SurfaceBaseAddress = info->depth_address;
#if GFX_VERx10 >= 125
db.TiledMode = isl_encode_tiling[info->depth_surf->tiling];
db.MipTailStartLOD = info->depth_surf->miptail_start_level;
#if GFX_VERx10 < 20
db.CompressionMode = isl_aux_usage_has_ccs(info->hiz_usage);
#endif
db.RenderCompressionFormat =
isl_get_render_compression_format(info->depth_surf->format);
#elif GFX_VER >= 9
/* Gen9+ depth is always Y-tiled but it may be Y0, Yf, or Ys. */
assert(isl_tiling_is_any_y(info->depth_surf->tiling));
db.TiledResourceMode = isl_encode_tiling[info->depth_surf->tiling];
db.MipTailStartLOD = info->depth_surf->miptail_start_level;
#elif GFX_VER >= 7
/* Gen7+ depth is always Y-tiled. We don't even have a bit for it */
#else
assert(info->depth_surf->tiling == ISL_TILING_Y0);
db.TiledSurface = true;
db.TileWalk = TILEWALK_YMAJOR;
db.MIPMapLayoutMode = MIPLAYOUT_BELOW;
#endif
db.SurfacePitch = info->depth_surf->row_pitch_B - 1;
#if GFX_VER >= 8
db.SurfaceQPitch =
isl_surf_get_array_pitch_el_rows(info->depth_surf) >> 2;
#endif
#if GFX_VER == 12
db.ControlSurfaceEnable = db.DepthBufferCompressionEnable =
isl_aux_usage_has_ccs(info->hiz_usage);
#endif
#if GFX_VER >= 12
db.NullPageCoherencyEnable = info->depth_surf->usage & ISL_SURF_USAGE_SPARSE_BIT;
#endif
}
#if GFX_VER == 5 || GFX_VER == 6
const bool separate_stencil =
info->stencil_surf && info->stencil_surf->format == ISL_FORMAT_R8_UINT;
if (separate_stencil || info->hiz_usage == ISL_AUX_USAGE_HIZ) {
assert(dev->use_separate_stencil);
/* From the IronLake PRM, Vol 2 Part 1:
*
* 3DSTATE_DEPTH_BUFFER::Separate Stencil Buffer Enable
* If this field is enabled, Hierarchical Depth Buffer Enable must
* also be enabled.
*
* 3DSTATE_DEPTH_BUFFER::Tiled Surface
* When Hierarchical Depth Buffer is enabled, this bit must be set.
*/
db.SeparateStencilBufferEnable = true;
db.HierarchicalDepthBufferEnable = true;
db.TiledSurface = true;
}
#endif
#if GFX_VER >= 6
struct GENX(3DSTATE_STENCIL_BUFFER) sb = {
GENX(3DSTATE_STENCIL_BUFFER_header),
.MOCS = info->mocs,
};
#else
# define sb db
#endif
if (info->stencil_surf) {
#if GFX_VER >= 7 && GFX_VER < 12
db.StencilWriteEnable = true;
#endif
#if GFX_VERx10 >= 125
#if GFX_VER < 20
sb.CompressionMode = isl_aux_usage_has_ccs(info->stencil_aux_usage);
sb.RenderCompressionFormat =
isl_get_render_compression_format(info->stencil_surf->format);
#else
sb.CompressionFormat =
isl_get_render_compression_format(info->stencil_surf->format);
#endif
#endif
#if GFX_VER >= 12
sb.TiledMode = isl_encode_tiling[info->stencil_surf->tiling];
sb.MipTailStartLOD = info->stencil_surf->miptail_start_level;
sb.StencilWriteEnable = true;
sb.SurfaceType = SURFTYPE_2D;
sb.Width = info->stencil_surf->logical_level0_px.width - 1;
sb.Height = info->stencil_surf->logical_level0_px.height - 1;
sb.Depth = sb.RenderTargetViewExtent = info->view->array_len - 1;
sb.SurfLOD = info->view->base_level;
sb.MinimumArrayElement = info->view->base_array_layer;
assert(info->stencil_aux_usage == ISL_AUX_USAGE_NONE ||
info->stencil_aux_usage == ISL_AUX_USAGE_STC_CCS);
#if GFX_VER < 20
sb.ControlSurfaceEnable = sb.StencilCompressionEnable =
info->stencil_aux_usage == ISL_AUX_USAGE_STC_CCS;
#endif
#elif GFX_VERx10 >= 75
sb.StencilBufferEnable = true;
#endif
#if GFX_VER >= 9
assert(info->stencil_address % info->stencil_surf->alignment_B == 0);
#endif
sb.SurfaceBaseAddress = info->stencil_address;
sb.SurfacePitch = info->stencil_surf->row_pitch_B - 1;
#if GFX_VER >= 8
sb.SurfaceQPitch =
isl_surf_get_array_pitch_el_rows(info->stencil_surf) >> 2;
#endif
#if GFX_VER >= 12
sb.NullPageCoherencyEnable = info->stencil_surf->usage & ISL_SURF_USAGE_SPARSE_BIT;
#endif
} else {
#if GFX_VER >= 12
sb.SurfaceType = SURFTYPE_NULL;
/* The docs seem to indicate that if surf-type is null, then we may need
* to match the depth-buffer value for `Depth`. It may be a
* documentation bug, since the other fields don't require this.
*
* TODO: Confirm documentation and remove setting of `Depth` if not
* required.
*/
sb.Depth = db.Depth;
#endif
}
#if GFX_VER >= 6
struct GENX(3DSTATE_HIER_DEPTH_BUFFER) hiz = {
GENX(3DSTATE_HIER_DEPTH_BUFFER_header),
.MOCS = info->mocs,
};
#if GFX_VER < 20
struct GENX(3DSTATE_CLEAR_PARAMS) clear = {
GENX(3DSTATE_CLEAR_PARAMS_header),
};
#endif
assert(info->hiz_usage == ISL_AUX_USAGE_NONE ||
isl_aux_usage_has_hiz(info->hiz_usage));
if (isl_aux_usage_has_hiz(info->hiz_usage)) {
assert(GFX_VER >= 12 || info->hiz_usage == ISL_AUX_USAGE_HIZ);
db.HierarchicalDepthBufferEnable = true;
#if GFX_VER >= 9
assert(info->hiz_address % info->hiz_surf->alignment_B == 0);
#endif
hiz.SurfaceBaseAddress = info->hiz_address;
hiz.SurfacePitch = info->hiz_surf->row_pitch_B - 1;
#if GFX_VERx10 >= 125
/* From 3DSTATE_HIER_DEPTH_BUFFER_BODY::TiledMode,
*
* HZ buffer only supports Tile4 mode
*
* and from Bspec 47009, "Hierarchical Depth Buffer",
*
* The format of the data in the hierarchical depth buffer is not
* documented here, as this surface needs only to be allocated by
* software.
*
* We choose to apply the second quote to the first. ISL describes HiZ
* with a tiling that has the same extent as Tile4 (128Bx32), but a
* different internal layout. This has two benefits: 1) it allows us to
* have the correct allocation size and 2) we can continue to use a
* tiling that was determined to exist on some prior platforms.
*/
assert(info->hiz_surf->tiling == ISL_TILING_HIZ);
hiz.TiledMode = TILE4;
#elif GFX_VERx10 >= 120
/* From 3DSTATE_HIER_DEPTH_BUFFER_BODY::TiledMode,
*
* HZ buffer only supports Tile Y mode.
*
* and
*
* Value | Name
* ----------------------------------------
* 0h | No tiled resource (Tile Y Mode).
*/
assert(info->hiz_surf->tiling == ISL_TILING_HIZ);
hiz.TiledMode = NONE;
#endif
#if GFX_VER >= 12
hiz.HierarchicalDepthBufferWriteThruEnable =
info->hiz_usage == ISL_AUX_USAGE_HIZ_CCS_WT;
#if GFX_VERx10 == 120
/* The bspec docs up to GFX 12 for this bit are fairly unclear about
* exactly what is and isn't supported with HiZ write-through. It's
* fairly clear that you can't sample from a multisampled depth buffer
* with CCS on GFX12.0. This limitation isn't called out explicitly but
* the docs for the CCS_E value of
* RENDER_SURFACE_STATE::AuxiliarySurfaceMode say:
*
* "If Number of multisamples > 1, programming this value means MSAA
* compression is enabled for that surface. Auxiliary surface is MSC
* with tile y."
*
* Since this interpretation ignores whether the surface is
* depth/stencil or not and since multisampled depth buffers use
* ISL_MSAA_LAYOUT_INTERLEAVED which is incompatible with MCS
* compression, this means that we can't even specify MSAA depth CCS in
* RENDER_SURFACE_STATE::AuxiliarySurfaceMode. The BSpec also says, for
* 3DSTATE_HIER_DEPTH_BUFFER::HierarchicalDepthBufferWriteThruEnable,
*
* "This bit must NOT be set for >1x MSAA modes, since sampler
* doesn't support sampling from >1x MSAA depth buffer."
*
* Again, this is all focused around what the sampler can do and not
* what the depth hardware can do.
*
* Reading even more internal docs which can't be quoted here makes it
* pretty clear that, even if it's not currently called out in the
* BSpec, HiZ+CCS write-through isn't intended to work with MSAA and we
* shouldn't try to use it. Treat it as if it's disallowed even if the
* BSpec doesn't explicitly document that.
*/
if (hiz.HierarchicalDepthBufferWriteThruEnable)
assert(info->depth_surf->samples == 1);
#endif /* #if GFX_VERx10 == 120 */
#endif /* #if GFX_VER >= 12 */
#if GFX_VER >= 8
/* From the SKL PRM Vol2a:
*
* The interpretation of this field is dependent on Surface Type
* as follows:
* - SURFTYPE_1D: distance in pixels between array slices
* - SURFTYPE_2D/CUBE: distance in rows between array slices
* - SURFTYPE_3D: distance in rows between R - slices
*
* Unfortunately, the docs aren't 100% accurate here. They fail to
* mention that the 1-D rule only applies to linear 1-D images.
* Since depth and HiZ buffers are always tiled, they are treated as
* 2-D images. Prior to Sky Lake, this field is always in rows.
*/
hiz.SurfaceQPitch =
isl_surf_get_array_pitch_sa_rows(info->hiz_surf) >> 2;
#endif
#if GFX_VER < 20
clear.DepthClearValueValid = true;
#if GFX_VER >= 8
clear.DepthClearValue = info->depth_clear_value;
#else
switch (info->depth_surf->format) {
case ISL_FORMAT_R32_FLOAT: {
union { float f; uint32_t u; } fu;
fu.f = info->depth_clear_value;
clear.DepthClearValue = fu.u;
break;
}
case ISL_FORMAT_R24_UNORM_X8_TYPELESS:
clear.DepthClearValue = info->depth_clear_value * ((1u << 24) - 1);
break;
case ISL_FORMAT_R16_UNORM:
clear.DepthClearValue = info->depth_clear_value * ((1u << 16) - 1);
break;
default:
UNREACHABLE("Invalid depth type");
}
#endif
#endif
}
#endif /* GFX_VER >= 6 */
/* Pack everything into the batch */
uint32_t *dw = batch;
GENX(3DSTATE_DEPTH_BUFFER_pack)(NULL, dw, &db);
dw += GENX(3DSTATE_DEPTH_BUFFER_length);
#if GFX_VER >= 6
GENX(3DSTATE_STENCIL_BUFFER_pack)(NULL, dw, &sb);
dw += GENX(3DSTATE_STENCIL_BUFFER_length);
GENX(3DSTATE_HIER_DEPTH_BUFFER_pack)(NULL, dw, &hiz);
dw += GENX(3DSTATE_HIER_DEPTH_BUFFER_length);
#if GFX_VER < 20
GENX(3DSTATE_CLEAR_PARAMS_pack)(NULL, dw, &clear);
dw += GENX(3DSTATE_CLEAR_PARAMS_length);
#endif /* GFX_VER < 20 */
#endif /* GFX_VER >= 6 */
}
File diff suppressed because it is too large. Load diff
+359
View File
@@ -0,0 +1,359 @@
# Copyright 2015 Intel Corporation
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the "Software"),
# to deal in the Software without restriction, including without limitation
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
# and/or sell copies of the Software, and to permit persons to whom the
# Software is furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice (including the next
# paragraph) shall be included in all copies or substantial portions of the
# Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
# IN THE SOFTWARE.
#
# @file
# @brief Layout of all hardware surface formats
#
# For the official list, see Broadwell PRM: Volume 2b: Command Reference:
# Enumerations: SURFACE_FORMAT.
#
# Columns:
# name: format name in PRM
# bpb: bits per block
# bw: block width, in pixels
# bh: block height, in pixels
# bd: block depth, in pixels
# r: red channel, data type and bitwidth
# g: green channel
# b: blue channel
# a: alpha channel
# l: luminance channel
# i: intensity channel
# p: palette channel
# space: colorspace
# txc: texture compression
#
# Data Types:
# x: void
# r: raw
# un: unorm
# sn: snorm
# uf: ufloat
# sf: sfloat
# ux: ufixed
# sx: sfixed
# ui: uint
# si: sint
# us: uscaled
# ss: sscaled
# Table is aligned with the Vim commands below, using the Align plugin:
# :AlignCtrl lr+ p8000000000000P1
# /^# name/,$ Align,
# name , bpb, bw, bh, bd, r, g, b, a, l, i, p, order, space, txc
R32G32B32A32_FLOAT , 128, 1, 1, 1, sf32, sf32, sf32, sf32, , , , rgba, linear,
R32G32B32A32_SINT , 128, 1, 1, 1, si32, si32, si32, si32, , , , rgba, linear,
R32G32B32A32_UINT , 128, 1, 1, 1, ui32, ui32, ui32, ui32, , , , rgba, linear,
R32G32B32A32_UNORM , 128, 1, 1, 1, un32, un32, un32, un32, , , , rgba, linear,
R32G32B32A32_SNORM , 128, 1, 1, 1, sn32, sn32, sn32, sn32, , , , rgba, linear,
R64G64_FLOAT , 128, 1, 1, 1, sf64, sf64, , , , , , rg, linear,
R32G32B32X32_FLOAT , 128, 1, 1, 1, sf32, sf32, sf32, x32, , , , rgba, linear,
R32G32B32A32_SSCALED , 128, 1, 1, 1, ss32, ss32, ss32, ss32, , , , rgba, linear,
R32G32B32A32_USCALED , 128, 1, 1, 1, us32, us32, us32, us32, , , , rgba, linear,
R32G32B32A32_SFIXED , 128, 1, 1, 1, sx32, sx32, sx32, sx32, , , , rgba, linear,
R64G64_PASSTHRU , 128, 1, 1, 1, r64, r64, , , , , , rg, ,
R32G32B32_FLOAT , 96, 1, 1, 1, sf32, sf32, sf32, , , , , rgb, linear,
R32G32B32_SINT , 96, 1, 1, 1, si32, si32, si32, , , , , rgb, linear,
R32G32B32_UINT , 96, 1, 1, 1, ui32, ui32, ui32, , , , , rgb, linear,
R32G32B32_UNORM , 96, 1, 1, 1, un32, un32, un32, , , , , rgb, linear,
R32G32B32_SNORM , 96, 1, 1, 1, sn32, sn32, sn32, , , , , rgb, linear,
R32G32B32_SSCALED , 96, 1, 1, 1, ss32, ss32, ss32, , , , , rgb, linear,
R32G32B32_USCALED , 96, 1, 1, 1, us32, us32, us32, , , , , rgb, linear,
R32G32B32_SFIXED , 96, 1, 1, 1, sx32, sx32, sx32, , , , , rgb, linear,
R16G16B16A16_UNORM , 64, 1, 1, 1, un16, un16, un16, un16, , , , rgba, linear,
R16G16B16A16_SNORM , 64, 1, 1, 1, sn16, sn16, sn16, sn16, , , , rgba, linear,
R16G16B16A16_SINT , 64, 1, 1, 1, si16, si16, si16, si16, , , , rgba, linear,
R16G16B16A16_UINT , 64, 1, 1, 1, ui16, ui16, ui16, ui16, , , , rgba, linear,
R16G16B16A16_FLOAT , 64, 1, 1, 1, sf16, sf16, sf16, sf16, , , , rgba, linear,
R32G32_FLOAT , 64, 1, 1, 1, sf32, sf32, , , , , , rg, linear,
R32G32_SINT , 64, 1, 1, 1, si32, si32, , , , , , rg, linear,
R32G32_UINT , 64, 1, 1, 1, ui32, ui32, , , , , , rg, linear,
R32_FLOAT_X8X24_TYPELESS , 64, 1, 1, 1, sf32, x8, x24, , , , , rgb, linear,
X32_TYPELESS_G8X24_UINT , 64, 1, 1, 1, x32, ui8, x24, , , , , rgb, linear,
L32A32_FLOAT , 64, 1, 1, 1, , , , sf32, sf32, , , la, linear,
R32G32_UNORM , 64, 1, 1, 1, un32, un32, , , , , , rg, linear,
R32G32_SNORM , 64, 1, 1, 1, sn32, sn32, , , , , , rg, linear,
R64_FLOAT , 64, 1, 1, 1, sf64, , , , , , , r, linear,
R16G16B16X16_UNORM , 64, 1, 1, 1, un16, un16, un16, x16, , , , rgba, linear,
R16G16B16X16_FLOAT , 64, 1, 1, 1, sf16, sf16, sf16, x16, , , , rgba, linear,
A32X32_FLOAT , 64, 1, 1, 1, , , , sf32, x32, , , al, linear,
L32X32_FLOAT , 64, 1, 1, 1, , , , x32, sf32, , , la, linear,
I32X32_FLOAT , 64, 1, 1, 1, , , , x32, , sf32, , ia, linear,
R16G16B16A16_SSCALED , 64, 1, 1, 1, ss16, ss16, ss16, ss16, , , , rgba, linear,
R16G16B16A16_USCALED , 64, 1, 1, 1, us16, us16, us16, us16, , , , rgba, linear,
R32G32_SSCALED , 64, 1, 1, 1, ss32, ss32, , , , , , rg, linear,
R32G32_USCALED , 64, 1, 1, 1, us32, us32, , , , , , rg, linear,
R32G32_FLOAT_LD , 64, 1, 1, 1, sf32, sf32, , , , , , rg, linear,
R32G32_SFIXED , 64, 1, 1, 1, sx32, sx32, , , , , , rg, linear,
R64_PASSTHRU , 64, 1, 1, 1, r64, , , , , , , r, ,
B8G8R8A8_UNORM , 32, 1, 1, 1, un8, un8, un8, un8, , , , bgra, linear,
B8G8R8A8_UNORM_SRGB , 32, 1, 1, 1, un8, un8, un8, un8, , , , bgra, srgb,
R10G10B10A2_UNORM , 32, 1, 1, 1, un10, un10, un10, un2, , , , rgba, linear,
R10G10B10A2_UNORM_SRGB , 32, 1, 1, 1, un10, un10, un10, un2, , , , rgba, srgb,
R10G10B10A2_UINT , 32, 1, 1, 1, ui10, ui10, ui10, ui2, , , , rgba, linear,
R10G10B10_SNORM_A2_UNORM , 32, 1, 1, 1, sn10, sn10, sn10, un2, , , , rgba, linear,
R8G8B8A8_UNORM , 32, 1, 1, 1, un8, un8, un8, un8, , , , rgba, linear,
R8G8B8A8_UNORM_SRGB , 32, 1, 1, 1, un8, un8, un8, un8, , , , rgba, srgb,
R8G8B8A8_SNORM , 32, 1, 1, 1, sn8, sn8, sn8, sn8, , , , rgba, linear,
R8G8B8A8_SINT , 32, 1, 1, 1, si8, si8, si8, si8, , , , rgba, linear,
R8G8B8A8_UINT , 32, 1, 1, 1, ui8, ui8, ui8, ui8, , , , rgba, linear,
R16G16_UNORM , 32, 1, 1, 1, un16, un16, , , , , , rg, linear,
R16G16_SNORM , 32, 1, 1, 1, sn16, sn16, , , , , , rg, linear,
R16G16_SINT , 32, 1, 1, 1, si16, si16, , , , , , rg, linear,
R16G16_UINT , 32, 1, 1, 1, ui16, ui16, , , , , , rg, linear,
R16G16_FLOAT , 32, 1, 1, 1, sf16, sf16, , , , , , rg, linear,
B10G10R10A2_UNORM , 32, 1, 1, 1, un10, un10, un10, un2, , , , bgra, linear,
B10G10R10A2_UNORM_SRGB , 32, 1, 1, 1, un10, un10, un10, un2, , , , bgra, srgb,
R11G11B10_FLOAT , 32, 1, 1, 1, uf11, uf11, uf10, , , , , rgb, linear,
R10G10B10_FLOAT_A2_UNORM , 32, 1, 1, 1, uf10, uf10, uf10, un2, , , , rgba, linear,
R32_SINT , 32, 1, 1, 1, si32, , , , , , , r, linear,
R32_UINT , 32, 1, 1, 1, ui32, , , , , , , r, linear,
R32_FLOAT , 32, 1, 1, 1, sf32, , , , , , , r, linear,
R24_UNORM_X8_TYPELESS , 32, 1, 1, 1, un24, x8, , , , , , rg, linear,
X24_TYPELESS_G8_UINT , 32, 1, 1, 1, x24, ui8, , , , , , rg, linear,
L32_UNORM , 32, 1, 1, 1, , , , , un32, , , l, linear,
A32_UNORM , 32, 1, 1, 1, , , , un32, , , , a, linear,
L16A16_UNORM , 32, 1, 1, 1, , , , un16, un16, , , la, linear,
I24X8_UNORM , 32, 1, 1, 1, , , , x8, , un24, , ia, linear,
L24X8_UNORM , 32, 1, 1, 1, , , , x8, un24, , , la, linear,
A24X8_UNORM , 32, 1, 1, 1, , , , un24, x8, , , al, linear,
I32_FLOAT , 32, 1, 1, 1, , , , , , sf32, , i, linear,
L32_FLOAT , 32, 1, 1, 1, , , , , sf32, , , l, linear,
A32_FLOAT , 32, 1, 1, 1, , , , sf32, , , , a, linear,
X8B8_UNORM_G8R8_SNORM , 32, 1, 1, 1, sn8, sn8, un8, x8, , , , abgr, linear,
A8X8_UNORM_G8R8_SNORM , 32, 1, 1, 1, sn8, sn8, x8, un8, , , , abgr, linear,
B8X8_UNORM_G8R8_SNORM , 32, 1, 1, 1, sn8, sn8, un8, x8, , , , bagr, linear,
B8G8R8X8_UNORM , 32, 1, 1, 1, un8, un8, un8, x8, , , , bgra, linear,
B8G8R8X8_UNORM_SRGB , 32, 1, 1, 1, un8, un8, un8, x8, , , , bgra, srgb,
R8G8B8X8_UNORM , 32, 1, 1, 1, un8, un8, un8, x8, , , , rgba, linear,
R8G8B8X8_UNORM_SRGB , 32, 1, 1, 1, un8, un8, un8, x8, , , , rgba, srgb,
R9G9B9E5_SHAREDEXP , 32, 1, 1, 1, uf9, uf9, uf9, , , , , rgb, linear,
B10G10R10X2_UNORM , 32, 1, 1, 1, un10, un10, un10, x2, , , , bgra, linear,
L16A16_FLOAT , 32, 1, 1, 1, , , , sf16, sf16, , , la, linear,
R32_UNORM , 32, 1, 1, 1, un32, , , , , , , r, linear,
R32_SNORM , 32, 1, 1, 1, sn32, , , , , , , r, linear,
R10G10B10X2_USCALED , 32, 1, 1, 1, us10, us10, us10, x2, , , , rgba, linear,
R8G8B8A8_SSCALED , 32, 1, 1, 1, ss8, ss8, ss8, ss8, , , , rgba, linear,
R8G8B8A8_USCALED , 32, 1, 1, 1, us8, us8, us8, us8, , , , rgba, linear,
R16G16_SSCALED , 32, 1, 1, 1, ss16, ss6, , , , , , rg, linear,
R16G16_USCALED , 32, 1, 1, 1, us16, us16, , , , , , rg, linear,
R32_SSCALED , 32, 1, 1, 1, ss32, , , , , , , r, linear,
R32_USCALED , 32, 1, 1, 1, us32, , , , , , , r, linear,
B5G6R5_UNORM , 16, 1, 1, 1, un5, un6, un5, , , , , bgr, linear,
B5G6R5_UNORM_SRGB , 16, 1, 1, 1, un5, un6, un5, , , , , bgr, srgb,
B5G5R5A1_UNORM , 16, 1, 1, 1, un5, un5, un5, un1, , , , bgra, linear,
B5G5R5A1_UNORM_SRGB , 16, 1, 1, 1, un5, un5, un5, un1, , , , bgra, srgb,
B4G4R4A4_UNORM , 16, 1, 1, 1, un4, un4, un4, un4, , , , bgra, linear,
B4G4R4A4_UNORM_SRGB , 16, 1, 1, 1, un4, un4, un4, un4, , , , bgra, srgb,
R8G8_UNORM , 16, 1, 1, 1, un8, un8, , , , , , rg, linear,
R8G8_SNORM , 16, 1, 1, 1, sn8, sn8, , , , , , rg, linear,
R8G8_SINT , 16, 1, 1, 1, si8, si8, , , , , , rg, linear,
R8G8_UINT , 16, 1, 1, 1, ui8, ui8, , , , , , rg, linear,
R16_UNORM , 16, 1, 1, 1, un16, , , , , , , r, linear,
R16_SNORM , 16, 1, 1, 1, sn16, , , , , , , r, linear,
R16_SINT , 16, 1, 1, 1, si16, , , , , , , r, linear,
R16_UINT , 16, 1, 1, 1, ui16, , , , , , , r, linear,
R16_FLOAT , 16, 1, 1, 1, sf16, , , , , , , r, linear,
A8P8_UNORM_PALETTE0 , 16, 1, 1, 1, , , , un8, , , un8, ap, linear,
A8P8_UNORM_PALETTE1 , 16, 1, 1, 1, , , , un8, , , un8, ap, linear,
I16_UNORM , 16, 1, 1, 1, , , , , , un16, , i, linear,
L16_UNORM , 16, 1, 1, 1, , , , , un16, , , l, linear,
A16_UNORM , 16, 1, 1, 1, , , , un16, , , , a, linear,
L8A8_UNORM , 16, 1, 1, 1, , , , un8, un8, , , la, linear,
I16_FLOAT , 16, 1, 1, 1, , , , , , sf16, , i, linear,
L16_FLOAT , 16, 1, 1, 1, , , , , sf16, , , l, linear,
A16_FLOAT , 16, 1, 1, 1, , , , sf16, , , , a, linear,
L8A8_UNORM_SRGB , 16, 1, 1, 1, , , , un8, un8, , , la, srgb,
R5G5_SNORM_B6_UNORM , 16, 1, 1, 1, sn5, sn5, un6, , , , , rgb, linear,
B5G5R5X1_UNORM , 16, 1, 1, 1, un5, un5, un5, x1, , , , bgra, linear,
B5G5R5X1_UNORM_SRGB , 16, 1, 1, 1, un5, un5, un5, x1, , , , bgra, srgb,
R8G8_SSCALED , 16, 1, 1, 1, ss8, ss8, , , , , , rg, linear,
R8G8_USCALED , 16, 1, 1, 1, us8, us8, , , , , , rg, linear,
R16_SSCALED , 16, 1, 1, 1, ss16, , , , , , , r, linear,
R16_USCALED , 16, 1, 1, 1, us16, , , , , , , r, linear,
P8A8_UNORM_PALETTE0 , 16, 1, 1, 1, , , , un8, , , un8, pa, linear,
P8A8_UNORM_PALETTE1 , 16, 1, 1, 1, , , , un8, , , un8, pa, linear,
A1B5G5R5_UNORM , 16, 1, 1, 1, un5, un5, un5, un1, , , , abgr, linear,
A4B4G4R4_UNORM , 16, 1, 1, 1, un4, un4, un4, un4, , , , abgr, linear,
L8A8_UINT , 16, 1, 1, 1, , , , ui8, ui8, , , la, linear,
L8A8_SINT , 16, 1, 1, 1, , , , si8, si8, , , la, linear,
R8_UNORM , 8, 1, 1, 1, un8, , , , , , , r, linear,
R8_SNORM , 8, 1, 1, 1, sn8, , , , , , , r, linear,
R8_SINT , 8, 1, 1, 1, si8, , , , , , , r, linear,
R8_UINT , 8, 1, 1, 1, ui8, , , , , , , r, linear,
A8_UNORM , 8, 1, 1, 1, , , , un8, , , , a, linear,
I8_UNORM , 8, 1, 1, 1, , , , , , un8, , i, linear,
L8_UNORM , 8, 1, 1, 1, , , , , un8, , , l, linear,
P4A4_UNORM_PALETTE0 , 8, 1, 1, 1, , , , un4, , , un4, pa, linear,
A4P4_UNORM_PALETTE0 , 8, 1, 1, 1, , , , un4, , , un4, ap, linear,
R8_SSCALED , 8, 1, 1, 1, ss8, , , , , , , r, linear,
R8_USCALED , 8, 1, 1, 1, us8, , , , , , , r, linear,
P8_UNORM_PALETTE0 , 8, 1, 1, 1, , , , , , , un8, p, linear,
L8_UNORM_SRGB , 8, 1, 1, 1, , , , , un8, , , l, srgb,
P8_UNORM_PALETTE1 , 8, 1, 1, 1, , , , , , , un8, p, linear,
P4A4_UNORM_PALETTE1 , 8, 1, 1, 1, , , , un4, , , un4, pa, linear,
A4P4_UNORM_PALETTE1 , 8, 1, 1, 1, , , , un4, , , un4, ap, linear,
Y8_UNORM , 8, 1, 1, 1, , un8, , , , , , , yuv,
L8_UINT , 8, 1, 1, 1, , , , , ui8, , , l, linear,
L8_SINT , 8, 1, 1, 1, , , , , si8, , , l, linear,
I8_UINT , 8, 1, 1, 1, , , , , , ui8, , i, linear,
I8_SINT , 8, 1, 1, 1, , , , , , si8, , i, linear,
DXT1_RGB_SRGB , 64, 4, 4, 1, un4, un4, un4, , , , , , srgb, dxt1
R1_UNORM , 1, 1, 1, 1, un1, , , , , , , r, linear,
YCRCB_NORMAL , 16, 1, 1, 1, un8, un8, un8, , , , , , yuv,
YCRCB_SWAPUVY , 16, 1, 1, 1, un8, un8, un8, , , , , , yuv,
P2_UNORM_PALETTE0 , 2, 1, 1, 1, , , , , , , un2, p, linear,
P2_UNORM_PALETTE1 , 2, 1, 1, 1, , , , , , , un2, p, linear,
BC1_UNORM , 64, 4, 4, 1, un4, un4, un4, un4, , , , , linear, dxt1
BC2_UNORM , 128, 4, 4, 1, un4, un4, un4, un4, , , , , linear, dxt3
BC3_UNORM , 128, 4, 4, 1, un4, un4, un4, un4, , , , , linear, dxt5
BC4_UNORM , 64, 4, 4, 1, un8, , , , , , , , linear, rgtc1
BC5_UNORM , 128, 4, 4, 1, un8, un8, , , , , , , linear, rgtc2
BC1_UNORM_SRGB , 64, 4, 4, 1, un4, un4, un4, un4, , , , , srgb, dxt1
BC2_UNORM_SRGB , 128, 4, 4, 1, un4, un4, un4, un4, , , , , srgb, dxt3
BC3_UNORM_SRGB , 128, 4, 4, 1, un4, un4, un4, un4, , , , , srgb, dxt5
MONO8 , 1, 1, 1, 1, , , , , , , , , ,
YCRCB_SWAPUV , 16, 1, 1, 1, un8, un8, un8, , , , , , yuv,
YCRCB_SWAPY , 16, 1, 1, 1, un8, un8, un8, , , , , , yuv,
DXT1_RGB , 64, 4, 4, 1, un4, un4, un4, , , , , , linear, dxt1
FXT1 , 128, 8, 4, 1, un4, un4, un4, , , , , , linear, fxt1
R8G8B8_UNORM , 24, 1, 1, 1, un8, un8, un8, , , , , rgb, linear,
R8G8B8_SNORM , 24, 1, 1, 1, sn8, sn8, sn8, , , , , rgb, linear,
R8G8B8_SSCALED , 24, 1, 1, 1, ss8, ss8, ss8, , , , , rgb, linear,
R8G8B8_USCALED , 24, 1, 1, 1, us8, us8, us8, , , , , rgb, linear,
R64G64B64A64_FLOAT , 256, 1, 1, 1, sf64, sf64, sf64, sf64, , , , rgba, linear,
R64G64B64_FLOAT , 196, 1, 1, 1, sf64, sf64, sf64, , , , , rgb, linear,
BC4_SNORM , 64, 4, 4, 1, sn8, , , , , , , , linear, rgtc1
BC5_SNORM , 128, 4, 4, 1, sn8, sn8, , , , , , , linear, rgtc2
R16G16B16_FLOAT , 48, 1, 1, 1, sf16, sf16, sf16, , , , , rgb, linear,
R16G16B16_UNORM , 48, 1, 1, 1, un16, un16, un16, , , , , rgb, linear,
R16G16B16_SNORM , 48, 1, 1, 1, sn16, sn16, sn16, , , , , rgb, linear,
R16G16B16_SSCALED , 48, 1, 1, 1, ss16, ss16, ss16, , , , , rgb, linear,
R16G16B16_USCALED , 48, 1, 1, 1, us16, us16, us16, , , , , rgb, linear,
BC6H_SF16 , 128, 4, 4, 1, sf16, sf16, sf16, , , , , , linear, bptc
BC7_UNORM , 128, 4, 4, 1, un8, un8, un8, un8, , , , , linear, bptc
BC7_UNORM_SRGB , 128, 4, 4, 1, un8, un8, un8, un8, , , , , srgb, bptc
BC6H_UF16 , 128, 4, 4, 1, uf16, uf16, uf16, , , , , , linear, bptc
PLANAR_420_8 , 0, 0, 0, 0, , , , , , , , , yuv,
PLANAR_420_10 , 0, 0, 0, 0, , , , , , , , , yuv,
PLANAR_420_12 , 0, 0, 0, 0, , , , , , , , , yuv,
PLANAR_420_16 , 0, 0, 0, 0, , , , , , , , , yuv,
R8G8B8_UNORM_SRGB , 24, 1, 1, 1, un8, un8, un8, , , , , rgb, srgb,
ETC1_RGB8 , 64, 4, 4, 1, un8, un8, un8, , , , , , linear, etc1
ETC2_RGB8 , 64, 4, 4, 1, un8, un8, un8, , , , , , linear, etc2
EAC_R11 , 64, 4, 4, 1, un11, , , , , , , , linear, etc2
EAC_RG11 , 128, 4, 4, 1, un11, un11, , , , , , , linear, etc2
EAC_SIGNED_R11 , 64, 4, 4, 1, sn11, , , , , , , , linear, etc2
EAC_SIGNED_RG11 , 128, 4, 4, 1, sn11, sn11, , , , , , , linear, etc2
ETC2_SRGB8 , 64, 4, 4, 1, un8, un8, un8, , , , , , srgb, etc2
R16G16B16_UINT , 48, 1, 1, 1, ui16, ui16, ui16, , , , , rgb, linear,
R16G16B16_SINT , 48, 1, 1, 1, si16, si16, si16, , , , , rgb, linear,
R32_SFIXED , 32, 1, 1, 1, sx16, , , , , , , r, linear,
R10G10B10A2_SNORM , 32, 1, 1, 1, sn10, sn10, sn10, sn2, , , , rgba, linear,
R10G10B10A2_USCALED , 32, 1, 1, 1, us10, us10, us10, us2, , , , rgba, linear,
R10G10B10A2_SSCALED , 32, 1, 1, 1, ss10, ss10, ss10, ss2, , , , rgba, linear,
R10G10B10A2_SINT , 32, 1, 1, 1, si10, si10, si10, si2, , , , rgba, linear,
B10G10R10A2_SNORM , 32, 1, 1, 1, sn10, sn10, sn10, sn2, , , , rgba, linear,
B10G10R10A2_USCALED , 32, 1, 1, 1, us10, us10, us10, us2, , , , rgba, linear,
B10G10R10A2_SSCALED , 32, 1, 1, 1, ss10, ss10, ss10, ss2, , , , rgba, linear,
B10G10R10A2_UINT , 32, 1, 1, 1, ui10, ui10, ui10, ui2, , , , rgba, linear,
B10G10R10A2_SINT , 32, 1, 1, 1, si10, si10, si10, si2, , , , rgba, linear,
R64G64B64A64_PASSTHRU , 256, 1, 1, 1, r64, r64, r64, r64, , , , rgba, ,
R64G64B64_PASSTHRU , 192, 1, 1, 1, r64, r64, r64, , , , , rgb, ,
ETC2_RGB8_PTA , 64, 4, 4, 1, un8, un8, un8, un1, , , , , linear, etc2
ETC2_SRGB8_PTA , 64, 4, 4, 1, un8, un8, un8, un1, , , , , srgb, etc2
ETC2_EAC_RGBA8 , 128, 4, 4, 1, un8, un8, un8, un8, , , , , linear, etc2
ETC2_EAC_SRGB8_A8 , 128, 4, 4, 1, un8, un8, un8, un8, , , , , srgb, etc2
R8G8B8_UINT , 24, 1, 1, 1, ui8, ui8, ui8, , , , , rgb, linear,
R8G8B8_SINT , 24, 1, 1, 1, si8, si8, si8, , , , , rgb, linear,
RAW , 0, 0, 0, 0, , , , , , , , , ,
ASTC_LDR_2D_4X4_U8SRGB , 128, 4, 4, 1, un8, un8, un8, un8, , , , , srgb, astc
ASTC_LDR_2D_5X4_U8SRGB , 128, 5, 4, 1, un8, un8, un8, un8, , , , , srgb, astc
ASTC_LDR_2D_5X5_U8SRGB , 128, 5, 5, 1, un8, un8, un8, un8, , , , , srgb, astc
ASTC_LDR_2D_6X5_U8SRGB , 128, 6, 5, 1, un8, un8, un8, un8, , , , , srgb, astc
ASTC_LDR_2D_6X6_U8SRGB , 128, 6, 6, 1, un8, un8, un8, un8, , , , , srgb, astc
ASTC_LDR_2D_8X5_U8SRGB , 128, 8, 5, 1, un8, un8, un8, un8, , , , , srgb, astc
ASTC_LDR_2D_8X6_U8SRGB , 128, 8, 6, 1, un8, un8, un8, un8, , , , , srgb, astc
ASTC_LDR_2D_8X8_U8SRGB , 128, 8, 8, 1, un8, un8, un8, un8, , , , , srgb, astc
ASTC_LDR_2D_10X5_U8SRGB , 128, 10, 5, 1, un8, un8, un8, un8, , , , , srgb, astc
ASTC_LDR_2D_10X6_U8SRGB , 128, 10, 6, 1, un8, un8, un8, un8, , , , , srgb, astc
ASTC_LDR_2D_10X8_U8SRGB , 128, 10, 8, 1, un8, un8, un8, un8, , , , , srgb, astc
ASTC_LDR_2D_10X10_U8SRGB , 128, 10, 10, 1, un8, un8, un8, un8, , , , , srgb, astc
ASTC_LDR_2D_12X10_U8SRGB , 128, 12, 10, 1, un8, un8, un8, un8, , , , , srgb, astc
ASTC_LDR_2D_12X12_U8SRGB , 128, 12, 12, 1, un8, un8, un8, un8, , , , , srgb, astc
ASTC_LDR_2D_4X4_FLT16 , 128, 4, 4, 1, sf16, sf16, sf16, sf16, , , , , linear, astc
ASTC_LDR_2D_5X4_FLT16 , 128, 5, 4, 1, sf16, sf16, sf16, sf16, , , , , linear, astc
ASTC_LDR_2D_5X5_FLT16 , 128, 5, 5, 1, sf16, sf16, sf16, sf16, , , , , linear, astc
ASTC_LDR_2D_6X5_FLT16 , 128, 6, 5, 1, sf16, sf16, sf16, sf16, , , , , linear, astc
ASTC_LDR_2D_6X6_FLT16 , 128, 6, 6, 1, sf16, sf16, sf16, sf16, , , , , linear, astc
ASTC_LDR_2D_8X5_FLT16 , 128, 8, 5, 1, sf16, sf16, sf16, sf16, , , , , linear, astc
ASTC_LDR_2D_8X6_FLT16 , 128, 8, 6, 1, sf16, sf16, sf16, sf16, , , , , linear, astc
ASTC_LDR_2D_8X8_FLT16 , 128, 8, 8, 1, sf16, sf16, sf16, sf16, , , , , linear, astc
ASTC_LDR_2D_10X5_FLT16 , 128, 10, 5, 1, sf16, sf16, sf16, sf16, , , , , linear, astc
ASTC_LDR_2D_10X6_FLT16 , 128, 10, 6, 1, sf16, sf16, sf16, sf16, , , , , linear, astc
ASTC_LDR_2D_10X8_FLT16 , 128, 10, 8, 1, sf16, sf16, sf16, sf16, , , , , linear, astc
ASTC_LDR_2D_10X10_FLT16 , 128, 10, 10, 1, sf16, sf16, sf16, sf16, , , , , linear, astc
ASTC_LDR_2D_12X10_FLT16 , 128, 12, 10, 1, sf16, sf16, sf16, sf16, , , , , linear, astc
ASTC_LDR_2D_12X12_FLT16 , 128, 12, 12, 1, sf16, sf16, sf16, sf16, , , , , linear, astc
ASTC_HDR_2D_4X4_FLT16 , 128, 4, 4, 1, sf16, sf16, sf16, sf16, , , , , linear, astc
ASTC_HDR_2D_5X4_FLT16 , 128, 5, 4, 1, sf16, sf16, sf16, sf16, , , , , linear, astc
ASTC_HDR_2D_5X5_FLT16 , 128, 5, 5, 1, sf16, sf16, sf16, sf16, , , , , linear, astc
ASTC_HDR_2D_6X5_FLT16 , 128, 6, 5, 1, sf16, sf16, sf16, sf16, , , , , linear, astc
ASTC_HDR_2D_6X6_FLT16 , 128, 6, 6, 1, sf16, sf16, sf16, sf16, , , , , linear, astc
ASTC_HDR_2D_8X5_FLT16 , 128, 8, 5, 1, sf16, sf16, sf16, sf16, , , , , linear, astc
ASTC_HDR_2D_8X6_FLT16 , 128, 8, 6, 1, sf16, sf16, sf16, sf16, , , , , linear, astc
ASTC_HDR_2D_8X8_FLT16 , 128, 8, 8, 1, sf16, sf16, sf16, sf16, , , , , linear, astc
ASTC_HDR_2D_10X5_FLT16 , 128, 10, 5, 1, sf16, sf16, sf16, sf16, , , , , linear, astc
ASTC_HDR_2D_10X6_FLT16 , 128, 10, 6, 1, sf16, sf16, sf16, sf16, , , , , linear, astc
ASTC_HDR_2D_10X8_FLT16 , 128, 10, 8, 1, sf16, sf16, sf16, sf16, , , , , linear, astc
ASTC_HDR_2D_10X10_FLT16 , 128, 10, 10, 1, sf16, sf16, sf16, sf16, , , , , linear, astc
ASTC_HDR_2D_12X10_FLT16 , 128, 12, 10, 1, sf16, sf16, sf16, sf16, , , , , linear, astc
ASTC_HDR_2D_12X12_FLT16 , 128, 12, 12, 1, sf16, sf16, sf16, sf16, , , , , linear, astc
HIZ , 128, 8, 4, 1, , , , , , , , , , hiz
GFX125_HIZ , 128, 8, 8, 1, , , , , , , , , , hiz
MCS_2X , 8, 1, 1, 1, , , , , , , , , , mcs
MCS_4X , 8, 1, 1, 1, , , , , , , , , , mcs
MCS_8X , 32, 1, 1, 1, , , , , , , , , , mcs
MCS_16X , 64, 1, 1, 1, , , , , , , , , , mcs
GFX7_CCS_32BPP_X , 1, 16, 2, 1, , , , , , , , , , ccs
GFX7_CCS_64BPP_X , 1, 8, 2, 1, , , , , , , , , , ccs
GFX7_CCS_128BPP_X , 1, 4, 2, 1, , , , , , , , , , ccs
GFX7_CCS_32BPP_Y , 1, 8, 4, 1, , , , , , , , , , ccs
GFX7_CCS_64BPP_Y , 1, 4, 4, 1, , , , , , , , , , ccs
GFX7_CCS_128BPP_Y , 1, 2, 4, 1, , , , , , , , , , ccs
GFX9_CCS_32BPP , 2, 8, 4, 1, , , , , , , , , , ccs
GFX9_CCS_64BPP , 2, 4, 4, 1, , , , , , , , , , ccs
GFX9_CCS_128BPP , 2, 2, 4, 1, , , , , , , , , , ccs
GFX12_CCS_8BPP_Y0 , 4, 32, 4, 1, , , , , , , , , , ccs
GFX12_CCS_16BPP_Y0 , 4, 16, 4, 1, , , , , , , , , , ccs
GFX12_CCS_32BPP_Y0 , 4, 8, 4, 1, , , , , , , , , , ccs
GFX12_CCS_64BPP_Y0 , 4, 4, 4, 1, , , , , , , , , , ccs
GFX12_CCS_128BPP_Y0 , 4, 2, 4, 1, , , , , , , , , , ccs
GFX12_CCS_8BPP_Ys , 4, 8, 16, 1, , , , , , , , , , ccs
GFX12_CCS_16BPP_Ys , 4, 8, 8, 1, , , , , , , , , , ccs
GFX12_CCS_32BPP_Ys , 4, 4, 8, 1, , , , , , , , , , ccs
GFX12_CCS_64BPP_Ys , 4, 4, 4, 1, , , , , , , , , , ccs
GFX12_CCS_128BPP_Ys , 4, 2, 4, 1, , , , , , , , , , ccs
Can't render this file because it contains an unexpected character in line 4 and column 65.
+488
View File
@@ -0,0 +1,488 @@
/*
* Copyright 2016 Intel Corporation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
#ifndef ISL_SURFACE_STATE_H
#define ISL_SURFACE_STATE_H
#include <stdint.h>
/**
* @file isl_surface_state.h
*
* ============================= GENXML CODE =============================
* [This file is compiled once per generation.]
* =======================================================================
*
* Helpers for encoding SURFACE_STATE and XY_BLOCK_COPY_BLT commands.
*/
UNUSED static uint8_t
isl_encode_halign(uint8_t halign)
{
switch (halign) {
#if GFX_VERx10 >= 125
case 16: return HALIGN_16;
case 32: return HALIGN_32;
case 64: return HALIGN_64;
case 128: return HALIGN_128;
#elif GFX_VER >= 8
case 4: return HALIGN_4;
case 8: return HALIGN_8;
case 16: return HALIGN_16;
#elif GFX_VER >= 7
case 4: return HALIGN_4;
case 8: return HALIGN_8;
#endif
default: UNREACHABLE("Invalid halign");
}
}
UNUSED static uint8_t
isl_encode_valign(uint8_t valign)
{
switch (valign) {
#if GFX_VER >= 8
case 4: return VALIGN_4;
case 8: return VALIGN_8;
case 16: return VALIGN_16;
#elif GFX_VER >= 6
case 2: return VALIGN_2;
case 4: return VALIGN_4;
#endif
default: UNREACHABLE("Invalid valign");
}
}
/**
* Get the horizontal and vertical alignment in the units expected by the
* hardware. Note that this does NOT give you the actual hardware enum values
* but an index into the isl_encode_[hv]align arrays above.
*/
UNUSED static struct isl_extent3d
isl_get_image_alignment(const struct isl_surf *surf)
{
if (surf->levels == 1 &&
surf->logical_level0_px.depth == 1 &&
surf->logical_level0_px.array_len == 1) {
/* This alignment value is unused for single slice surfaces. */
return isl_extent3d(GFX_VERx10 >= 125 ? 128 : 4, 4, 1);
}
if (GFX_VERx10 >= 125) {
if (isl_tiling_is_64(surf->tiling)) {
/* The hardware ignores the alignment values. Anyway, the surface's
* true alignment is likely outside the enum range of HALIGN* and
* VALIGN*.
*/
return isl_extent3d(128, 4, 1);
} else if (isl_format_get_layout(surf->format)->bpb % 3 == 0) {
/* On XeHP, RENDER_SURFACE_STATE.SurfaceHorizontalAlignment is in
* units of elements for 24, 48, and 96 bpb formats.
*/
return isl_surf_get_image_alignment_el(surf);
} else {
/* On XeHP, RENDER_SURFACE_STATE.SurfaceHorizontalAlignment is in
* units of bytes for formats that are powers of two.
*/
const uint32_t bs = isl_format_get_layout(surf->format)->bpb / 8;
return isl_extent3d(surf->image_alignment_el.w * bs,
surf->image_alignment_el.h,
surf->image_alignment_el.d);
}
} else if (GFX_VER >= 9) {
if (isl_tiling_is_std_y(surf->tiling) ||
surf->dim_layout == ISL_DIM_LAYOUT_GFX9_1D) {
/* The hardware ignores the alignment values. Anyway, the surface's
* true alignment is likely outside the enum range of HALIGN* and
* VALIGN*.
*/
return isl_extent3d(4, 4, 1);
} else {
/* In Skylake, RENDER_SUFFACE_STATE.SurfaceVerticalAlignment is in units
* of surface elements (not pixels nor samples). For compressed formats,
* a "surface element" is defined as a compression block. For example,
* if SurfaceVerticalAlignment is VALIGN_4 and SurfaceFormat is an ETC2
* format (ETC2 has a block height of 4), then the vertical alignment is
* 4 compression blocks or, equivalently, 16 pixels.
*/
return isl_surf_get_image_alignment_el(surf);
}
} else {
/* Pre-Skylake, RENDER_SUFFACE_STATE.SurfaceVerticalAlignment is in
* units of surface samples. For example, if SurfaceVerticalAlignment
* is VALIGN_4 and the surface is singlesampled, then for any surface
* format (compressed or not) the vertical alignment is
* 4 pixels.
*/
return isl_surf_get_image_alignment_sa(surf);
}
}
UNUSED static uint32_t
isl_get_qpitch(const struct isl_surf *surf)
{
switch (surf->dim_layout) {
default:
UNREACHABLE("Bad isl_surf_dim");
case ISL_DIM_LAYOUT_GFX4_2D:
if (GFX_VER >= 9) {
if (surf->dim == ISL_SURF_DIM_3D && surf->tiling == ISL_TILING_W) {
/* This is rather annoying and completely undocumented. It
* appears that the hardware has a bug (or undocumented feature)
* regarding stencil buffers most likely related to the way
* W-tiling is handled as modified Y-tiling. If you bind a 3-D
* stencil buffer normally, and use texelFetch on it, the z or
* array index will get implicitly multiplied by 2 for no obvious
* reason. The fix appears to be to divide qpitch by 2 for
* W-tiled surfaces.
*/
return isl_surf_get_array_pitch_el_rows(surf) / 2;
} else {
return isl_surf_get_array_pitch_el_rows(surf);
}
} else {
/* From the Broadwell PRM for RENDER_SURFACE_STATE.QPitch
*
* "This field must be set to an integer multiple of the Surface
* Vertical Alignment. For compressed textures (BC*, FXT1,
* ETC*, and EAC* Surface Formats), this field is in units of
* rows in the uncompressed surface, and must be set to an
* integer multiple of the vertical alignment parameter "j"
* defined in the Common Surface Formats section."
*/
return isl_surf_get_array_pitch_sa_rows(surf);
}
case ISL_DIM_LAYOUT_GFX9_1D:
/* QPitch is usually expressed as rows of surface elements (where
* a surface element is an compression block or a single surface
* sample). Skylake 1D is an outlier.
*
* From the Skylake BSpec >> Memory Views >> Common Surface
* Formats >> Surface Layout and Tiling >> 1D Surfaces:
*
* Surface QPitch specifies the distance in pixels between array
* slices.
*/
return isl_surf_get_array_pitch_el(surf);
case ISL_DIM_LAYOUT_GFX4_3D:
/* QPitch doesn't make sense for ISL_DIM_LAYOUT_GFX4_3D since it uses a
* different pitch at each LOD. Also, the QPitch field is ignored for
* these surfaces. From the Broadwell PRM documentation for QPitch:
*
* This field specifies the distance in rows between array slices. It
* is used only in the following cases:
* - Surface Array is enabled OR
* - Number of Mulitsamples is not NUMSAMPLES_1 and Multisampled
* Surface Storage Format set to MSFMT_MSS OR
* - Surface Type is SURFTYPE_CUBE
*
* None of the three conditions above can possibly apply to a 3D surface
* so it is safe to just set QPitch to 0.
*/
return 0;
}
}
#if GFX_VER >= 20
/*
* Returns compression format encoding for Unified Lossless Compression
*/
UNUSED static uint8_t
isl_get_render_compression_format(enum isl_format format)
{
/* The spec gives no CMFs to NPOT RGB formats. Remap them to RGBA. */
if (isl_format_get_layout(format)->bpb % 3 == 0)
format = isl_format_rgb_to_rgba(format);
/* Bspec 63919 (r60413):
*
* Table "[Enumeration] UNIFIED_COMPRESSION_FORMAT"
*
* These ISL formats have explicitly defined CMF values in the spec.
*/
switch(format) {
case ISL_FORMAT_R8_UNORM:
case ISL_FORMAT_R8_UINT:
case ISL_FORMAT_R8_SNORM:
case ISL_FORMAT_R8_SINT:
case ISL_FORMAT_A8_UNORM:
case ISL_FORMAT_R24_UNORM_X8_TYPELESS:
return CMF_R8;
case ISL_FORMAT_R8G8_UNORM:
case ISL_FORMAT_R8G8_UINT:
case ISL_FORMAT_R8G8_SNORM:
case ISL_FORMAT_R8G8_SINT:
case ISL_FORMAT_B5G6R5_UNORM:
case ISL_FORMAT_B5G6R5_UNORM_SRGB:
case ISL_FORMAT_B5G5R5A1_UNORM:
case ISL_FORMAT_B5G5R5A1_UNORM_SRGB:
case ISL_FORMAT_B4G4R4A4_UNORM:
case ISL_FORMAT_B4G4R4A4_UNORM_SRGB:
case ISL_FORMAT_B5G5R5X1_UNORM:
case ISL_FORMAT_B5G5R5X1_UNORM_SRGB:
case ISL_FORMAT_A1B5G5R5_UNORM:
case ISL_FORMAT_A4B4G4R4_UNORM:
return CMF_R8_G8;
case ISL_FORMAT_R8G8B8A8_UNORM:
case ISL_FORMAT_R8G8B8A8_UINT:
case ISL_FORMAT_R8G8B8A8_SNORM:
case ISL_FORMAT_R8G8B8A8_SINT:
case ISL_FORMAT_R8G8B8A8_UNORM_SRGB:
case ISL_FORMAT_B8G8R8A8_UNORM_SRGB:
case ISL_FORMAT_B8G8R8A8_UNORM:
case ISL_FORMAT_B8G8R8X8_UNORM:
case ISL_FORMAT_YCRCB_NORMAL:
case ISL_FORMAT_YCRCB_SWAPUVY:
case ISL_FORMAT_YCRCB_SWAPUV:
case ISL_FORMAT_YCRCB_SWAPY:
return CMF_R8_G8_B8_A8;
case ISL_FORMAT_R10G10B10A2_UNORM:
case ISL_FORMAT_R10G10B10A2_UNORM_SRGB:
case ISL_FORMAT_R10G10B10_FLOAT_A2_UNORM:
case ISL_FORMAT_R10G10B10A2_UINT:
case ISL_FORMAT_B10G10R10A2_UNORM:
case ISL_FORMAT_B10G10R10X2_UNORM:
case ISL_FORMAT_B10G10R10A2_UNORM_SRGB:
return CMF_R10_G10_B10_A2;
case ISL_FORMAT_R11G11B10_FLOAT:
return CMF_R11_G11_B10;
case ISL_FORMAT_R16_UNORM:
case ISL_FORMAT_R16_UINT:
case ISL_FORMAT_R16_SNORM:
case ISL_FORMAT_R16_SINT:
case ISL_FORMAT_R16_FLOAT:
return CMF_R16;
case ISL_FORMAT_R16G16_UNORM:
case ISL_FORMAT_R16G16_UINT:
case ISL_FORMAT_R16G16_SNORM:
case ISL_FORMAT_R16G16_SINT:
case ISL_FORMAT_R16G16_FLOAT:
return CMF_R16_G16;
case ISL_FORMAT_R16G16B16A16_UNORM:
case ISL_FORMAT_R16G16B16A16_UINT:
case ISL_FORMAT_R16G16B16A16_SNORM:
case ISL_FORMAT_R16G16B16A16_SINT:
case ISL_FORMAT_R16G16B16A16_FLOAT:
case ISL_FORMAT_R16G16B16X16_FLOAT:
return CMF_R16_G16_B16_A16;
case ISL_FORMAT_R32_UNORM:
case ISL_FORMAT_R32_UINT:
case ISL_FORMAT_R32_SNORM:
case ISL_FORMAT_R32_SINT:
case ISL_FORMAT_R32_FLOAT:
return CMF_R32;
case ISL_FORMAT_R32G32_UNORM:
case ISL_FORMAT_R32G32_UINT:
case ISL_FORMAT_R32G32_SNORM:
case ISL_FORMAT_R32G32_SINT:
case ISL_FORMAT_R32G32_FLOAT:
return CMF_R32_G32;
case ISL_FORMAT_R32G32B32A32_UNORM:
case ISL_FORMAT_R32G32B32A32_UINT:
case ISL_FORMAT_R32G32B32A32_SNORM:
case ISL_FORMAT_R32G32B32A32_SINT:
case ISL_FORMAT_R32G32B32A32_FLOAT:
case ISL_FORMAT_R32G32B32X32_FLOAT:
return CMF_R32_G32_B32_A32;
case ISL_FORMAT_EAC_R11:
case ISL_FORMAT_EAC_RG11:
case ISL_FORMAT_EAC_SIGNED_R11:
case ISL_FORMAT_EAC_SIGNED_RG11:
case ISL_FORMAT_ETC1_RGB8:
case ISL_FORMAT_ETC2_RGB8:
case ISL_FORMAT_ETC2_SRGB8:
case ISL_FORMAT_ETC2_RGB8_PTA:
case ISL_FORMAT_ETC2_SRGB8_PTA:
case ISL_FORMAT_ETC2_EAC_RGBA8:
case ISL_FORMAT_ETC2_EAC_SRGB8_A8:
case ISL_FORMAT_BC1_UNORM:
case ISL_FORMAT_BC2_UNORM:
case ISL_FORMAT_BC3_UNORM:
case ISL_FORMAT_BC4_UNORM:
case ISL_FORMAT_BC5_UNORM:
case ISL_FORMAT_BC1_UNORM_SRGB:
case ISL_FORMAT_BC2_UNORM_SRGB:
case ISL_FORMAT_BC3_UNORM_SRGB:
case ISL_FORMAT_BC4_SNORM:
case ISL_FORMAT_BC5_SNORM:
case ISL_FORMAT_BC6H_SF16:
case ISL_FORMAT_BC7_UNORM:
case ISL_FORMAT_BC7_UNORM_SRGB:
case ISL_FORMAT_BC6H_UF16:
return CMF_ML8;
/* These formats are not in the CMF table in the Bspec 63919 (r60413).
* Although they are not supported for sampling, they are reinterpreted and
* used for transfer operations. Use the same CMF that we use for the other
* compressed formats.
*/
case ISL_FORMAT_ASTC_LDR_2D_4X4_U8SRGB:
case ISL_FORMAT_ASTC_LDR_2D_5X4_U8SRGB:
case ISL_FORMAT_ASTC_LDR_2D_5X5_U8SRGB:
case ISL_FORMAT_ASTC_LDR_2D_6X5_U8SRGB:
case ISL_FORMAT_ASTC_LDR_2D_6X6_U8SRGB:
case ISL_FORMAT_ASTC_LDR_2D_8X5_U8SRGB:
case ISL_FORMAT_ASTC_LDR_2D_8X6_U8SRGB:
case ISL_FORMAT_ASTC_LDR_2D_8X8_U8SRGB:
case ISL_FORMAT_ASTC_LDR_2D_10X5_U8SRGB:
case ISL_FORMAT_ASTC_LDR_2D_10X6_U8SRGB:
case ISL_FORMAT_ASTC_LDR_2D_10X8_U8SRGB:
case ISL_FORMAT_ASTC_LDR_2D_10X10_U8SRGB:
case ISL_FORMAT_ASTC_LDR_2D_12X10_U8SRGB:
case ISL_FORMAT_ASTC_LDR_2D_12X12_U8SRGB:
case ISL_FORMAT_ASTC_LDR_2D_4X4_FLT16:
case ISL_FORMAT_ASTC_LDR_2D_5X4_FLT16:
case ISL_FORMAT_ASTC_LDR_2D_5X5_FLT16:
case ISL_FORMAT_ASTC_LDR_2D_6X5_FLT16:
case ISL_FORMAT_ASTC_LDR_2D_6X6_FLT16:
case ISL_FORMAT_ASTC_LDR_2D_8X5_FLT16:
case ISL_FORMAT_ASTC_LDR_2D_8X6_FLT16:
case ISL_FORMAT_ASTC_LDR_2D_8X8_FLT16:
case ISL_FORMAT_ASTC_LDR_2D_10X5_FLT16:
case ISL_FORMAT_ASTC_LDR_2D_10X6_FLT16:
case ISL_FORMAT_ASTC_LDR_2D_10X8_FLT16:
case ISL_FORMAT_ASTC_LDR_2D_10X10_FLT16:
case ISL_FORMAT_ASTC_LDR_2D_12X10_FLT16:
case ISL_FORMAT_ASTC_LDR_2D_12X12_FLT16:
return CMF_ML8;
/* These formats are not in the CMF table in the Bspec 63919 (r60413).
* We choose CMF values for them by their number of channels x channel bit
* size.
*/
case ISL_FORMAT_L8A8_UNORM_SRGB:
return CMF_R8_G8;
case ISL_FORMAT_L8_UNORM_SRGB:
return CMF_R8;
case ISL_FORMAT_R9G9B9E5_SHAREDEXP:
return CMF_R11_G11_B10;
default:
UNREACHABLE("Unsupported render compression format!");
return 0;
}
}
#elif GFX_VERx10 >= 125
/*
* Returns compression format encoding for Unified Lossless Compression
*/
UNUSED static uint8_t
isl_get_render_compression_format(enum isl_format format)
{
/* From the Bspec, Enumeration_RenderCompressionFormat section (53726): */
switch(format) {
case ISL_FORMAT_R32G32B32A32_FLOAT:
case ISL_FORMAT_R32G32B32X32_FLOAT:
case ISL_FORMAT_R32G32B32A32_SINT:
return 0x0;
case ISL_FORMAT_R32G32B32A32_UINT:
return 0x1;
case ISL_FORMAT_R32G32_FLOAT:
case ISL_FORMAT_R32G32_SINT:
return 0x2;
case ISL_FORMAT_R32G32_UINT:
return 0x3;
case ISL_FORMAT_R16G16B16A16_UNORM:
case ISL_FORMAT_R16G16B16X16_UNORM:
case ISL_FORMAT_R16G16B16A16_UINT:
return 0x4;
case ISL_FORMAT_R16G16B16A16_SNORM:
case ISL_FORMAT_R16G16B16A16_SINT:
case ISL_FORMAT_R16G16B16A16_FLOAT:
case ISL_FORMAT_R16G16B16X16_FLOAT:
return 0x5;
case ISL_FORMAT_R16G16_UNORM:
case ISL_FORMAT_R16G16_UINT:
return 0x6;
case ISL_FORMAT_R16G16_SNORM:
case ISL_FORMAT_R16G16_SINT:
case ISL_FORMAT_R16G16_FLOAT:
return 0x7;
case ISL_FORMAT_B8G8R8A8_UNORM:
case ISL_FORMAT_B8G8R8X8_UNORM:
case ISL_FORMAT_B8G8R8A8_UNORM_SRGB:
case ISL_FORMAT_B8G8R8X8_UNORM_SRGB:
case ISL_FORMAT_R8G8B8A8_UNORM:
case ISL_FORMAT_R8G8B8X8_UNORM:
case ISL_FORMAT_R8G8B8A8_UNORM_SRGB:
case ISL_FORMAT_R8G8B8X8_UNORM_SRGB:
case ISL_FORMAT_R8G8B8A8_UINT:
return 0x8;
case ISL_FORMAT_R8G8B8A8_SNORM:
case ISL_FORMAT_R8G8B8A8_SINT:
return 0x9;
case ISL_FORMAT_B5G6R5_UNORM:
case ISL_FORMAT_B5G6R5_UNORM_SRGB:
case ISL_FORMAT_B5G5R5A1_UNORM:
case ISL_FORMAT_B5G5R5A1_UNORM_SRGB:
case ISL_FORMAT_B4G4R4A4_UNORM:
case ISL_FORMAT_B4G4R4A4_UNORM_SRGB:
case ISL_FORMAT_B5G5R5X1_UNORM:
case ISL_FORMAT_B5G5R5X1_UNORM_SRGB:
case ISL_FORMAT_A1B5G5R5_UNORM:
case ISL_FORMAT_A4B4G4R4_UNORM:
case ISL_FORMAT_R8G8_UNORM:
case ISL_FORMAT_R8G8_UINT:
return 0xA;
case ISL_FORMAT_R8G8_SNORM:
case ISL_FORMAT_R8G8_SINT:
return 0xB;
case ISL_FORMAT_R10G10B10A2_UNORM:
case ISL_FORMAT_R10G10B10A2_UNORM_SRGB:
case ISL_FORMAT_R10G10B10_FLOAT_A2_UNORM:
case ISL_FORMAT_R10G10B10A2_UINT:
case ISL_FORMAT_B10G10R10A2_UNORM:
case ISL_FORMAT_B10G10R10X2_UNORM:
case ISL_FORMAT_B10G10R10A2_UNORM_SRGB:
return 0xC;
case ISL_FORMAT_R11G11B10_FLOAT:
return 0xD;
case ISL_FORMAT_R32_SINT:
case ISL_FORMAT_R32_FLOAT:
return 0x10;
case ISL_FORMAT_R32_UINT:
case ISL_FORMAT_R24_UNORM_X8_TYPELESS:
return 0x11;
case ISL_FORMAT_R16_UNORM:
case ISL_FORMAT_R16_UINT:
return 0x14;
case ISL_FORMAT_R16_SNORM:
case ISL_FORMAT_R16_SINT:
case ISL_FORMAT_R16_FLOAT:
return 0x15;
case ISL_FORMAT_R8_UNORM:
case ISL_FORMAT_R8_UINT:
case ISL_FORMAT_A8_UNORM:
return 0x18;
case ISL_FORMAT_R8_SNORM:
case ISL_FORMAT_R8_SINT:
return 0x19;
default:
UNREACHABLE("Unsupported render compression format!");
return 0;
}
}
#endif /* #if GFX_VERx10 >= 125 */
#endif
+53
View File
@@ -0,0 +1,53 @@
/*
* 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.
*/
/*
* NOTE: The header can be included multiple times, from the same file.
*/
/*
* Gen-specific function declarations. This header must *not* be included
* directly. Instead, it is included multiple times by isl_priv.h
*
* In this header file, the usual isl_genX() macro is available.
*/
void
isl_genX(surf_fill_state_s)(const struct isl_device *dev, void *state,
const struct isl_surf_fill_state_info *restrict info);
void
isl_genX(buffer_fill_state_s)(const struct isl_device *dev, void *state,
const struct isl_buffer_fill_state_info *restrict info);
void
isl_genX(emit_depth_stencil_hiz_s)(const struct isl_device *dev, void *batch,
const struct isl_depth_stencil_hiz_emit_info *restrict info);
void
isl_genX(null_fill_state_s)(const struct isl_device *dev, void *state,
const struct isl_null_fill_state_info *restrict info);
void
isl_genX(emit_cpb_control_s)(const struct isl_device *dev, void *batch,
const struct isl_cpb_emit_info *restrict info);
+322
View File
@@ -0,0 +1,322 @@
/*
* Copyright (c) 2018 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 "isl_gfx9.h"
#include "isl_gfx12.h"
#include "isl_priv.h"
/**
* @brief Filter out tiling flags that are incompatible with the surface.
*
* The resultant outgoing @a flags is a subset of the incoming @a flags. The
* outgoing flags may be empty (0x0) if the incoming flags were too
* restrictive.
*
* For example, if the surface will be used for a display
* (ISL_SURF_USAGE_DISPLAY_BIT), then this function filters out all tiling
* flags except ISL_TILING_4_BIT, ISL_TILING_X_BIT, and ISL_TILING_LINEAR_BIT.
*/
void
isl_gfx125_filter_tiling(const struct isl_device *dev,
const struct isl_surf_init_info *restrict info,
isl_tiling_flags_t *flags)
{
/* Clear flags unsupported on this hardware */
assert(ISL_GFX_VERX10(dev) == 125);
*flags &= isl_device_get_supported_tilings(dev);
if (info->usage & ISL_SURF_USAGE_SOFTWARE_DETILING)
*flags &= (1 << dev->shader_tiling) | ISL_TILING_LINEAR_BIT;
if (isl_surf_usage_is_depth_or_stencil(info->usage)) {
*flags &= ISL_TILING_4_BIT | ISL_TILING_64_BIT;
/* We choose to avoid Tile64 for 3D depth/stencil buffers. The swizzle
* for Tile64 is dependent on the image dimension. So, reads and writes
* should specify the same dimension to consistently interpret the data.
* This is not possible for 3D depth/stencil buffers however. Such
* buffers can be sampled from with a 3D view, but rendering is only
* possible with a 2D view due to the limitations of
* 3DSTATE_(DEPTH|STENCIL)_BUFFER.
*/
if (info->dim == ISL_SURF_DIM_3D)
*flags &= ~ISL_TILING_64_BIT;
}
if (info->usage & ISL_SURF_USAGE_DISPLAY_BIT)
*flags &= ~ISL_TILING_64_BIT;
/* From RENDER_SURFACE_STATE::AuxiliarySurfaceMode,
*
* MCS tiling format is always Tile4
*/
if (info->usage & ISL_SURF_USAGE_MCS_BIT)
*flags &= ISL_TILING_4_BIT;
/* From RENDER_SURFACE_STATE::TileMode,
*
* TILEMODE_XMAJOR is only allowed if Surface Type is SURFTYPE_2D.
*
* X-tiling is only allowed for 2D surfaces.
*/
if (info->dim != ISL_SURF_DIM_2D)
*flags &= ~ISL_TILING_X_BIT;
/* From ATS-M PRMs, Volume 2d: Command Reference: Structures,
* RENDER_SURFACE_STATE:TileMode :
*
* "If Surface Type is SURFTYPE_1D this field must be TILEMODE_LINEAR,
* unless Sampler Legacy 1D Map Layout Disable is set to 0, in which
* case TILEMODE_YMAJOR is also allowed. Horizontal Alignment must be
* programmed for the required alignment between MIPs. MIP tails are
* not supported."
*
* Tile4 is the replacement for TileY0 on ACM.
*/
if (info->dim == ISL_SURF_DIM_1D)
*flags &= ISL_TILING_LINEAR_BIT | ISL_TILING_4_BIT;
/* TILE64 does not work with YCRCB formats, according to bspec 58767:
* "Packed YUV surface formats such as YCRCB_NORMAL, YCRCB_SWAPUVY etc.
* will not support as Tile64"
*/
if (isl_format_is_yuv(info->format))
*flags &= ~ISL_TILING_64_BIT;
/* Tile64 tilings for 3D have a different swizzling than a 2D surface. So
* filter them out if the usage wants 2D/3D compatibility.
*/
if (info->usage & ISL_SURF_USAGE_2D_3D_COMPATIBLE_BIT)
*flags &= ~ISL_TILING_64_BIT;
/* From RENDER_SURFACE_STATE::NumberofMultisamples,
*
* This field must not be programmed to anything other than
* [MULTISAMPLECOUNT_1] unless the Tile Mode field is programmed to
* Tile64.
*
* Tile64 is required for multisampling.
*/
if (info->samples > 1)
*flags &= ISL_TILING_64_BIT;
/* Tile64 is not defined for format sizes that are 24, 48, and 96 bpb. */
if (isl_format_get_layout(info->format)->bpb % 3 == 0)
*flags &= ~ISL_TILING_64_BIT;
/* From 3DSTATE_CPSIZE_CONTROL_BUFFER::TiledMode,
*
* - 3h Tile4 4KB tile mode
* - 1h Tile64 64KB tile mode
* - 2h, 0h Reserved
*
* Tile4 and Tile64 are the only two valid values.
*/
if (info->usage & ISL_SURF_USAGE_CPB_BIT)
*flags &= ISL_TILING_4_BIT | ISL_TILING_64_BIT;
/* From ATS-M PRMs, Volume 2a: Command Reference: Instructions,
* MFX_SURFACE_STATE,
*
* "For optimizing memory efficiency based on access patterns, only
* TileY is supported."
*
* The other media engines have similar limitations, TileY is the only
* well-supported tiling mode that can easily be used on all of them.
*/
if (info->usage & ISL_SURF_USAGE_VIDEO_DECODE_BIT)
*flags &= ISL_TILING_4_BIT;
}
void
isl_gfx125_choose_image_alignment_el(const struct isl_device *dev,
const struct isl_surf_init_info *restrict info,
const struct isl_tile_info *tile_info,
enum isl_dim_layout dim_layout,
enum isl_msaa_layout msaa_layout,
struct isl_extent3d *image_align_el)
{
enum isl_tiling tiling = tile_info->tiling;
/* Handled by isl_choose_image_alignment_el */
assert(info->format != ISL_FORMAT_GFX125_HIZ);
const struct isl_format_layout *fmtl = isl_format_get_layout(info->format);
if (tiling == ISL_TILING_64) {
/* From RENDER_SURFACE_STATE::SurfaceHorizontalAlignment,
*
* This field is ignored for Tile64 surface formats because horizontal
* alignment is always to the start of the next tile in that case.
*
* From RENDER_SURFACE_STATE::SurfaceQPitch,
*
* Because MSAA is only supported for Tile64, QPitch must also be
* programmed to an aligned tile boundary for MSAA surfaces.
*
* Images in this surface must be tile-aligned. The table on the Bspec
* page, "2D/CUBE Alignment Requirement", shows that the vertical
* alignment is also a tile height for non-MSAA as well.
*/
*image_align_el = isl_extent3d(tile_info->logical_extent_el.w,
tile_info->logical_extent_el.h,
1);
} else if (isl_surf_usage_is_depth(info->usage)) {
/* From RENDER_SURFACE_STATE::SurfaceHorizontalAlignment,
*
* - 16b Depth Surfaces Must Be HALIGN=16Bytes (8texels)
* - 32b Depth Surfaces Must Be HALIGN=32Bytes (8texels)
*
* From RENDER_SURFACE_STATE::SurfaceVerticalAlignment,
*
* This field is intended to be set to VALIGN_4 if the surface
* was rendered as a depth buffer [...]
*
* and
*
* This field should also be set to VALIGN_8 if the surface was
* rendered as a D16_UNORM depth buffer [...]
*/
*image_align_el =
info->format != ISL_FORMAT_R16_UNORM ?
isl_extent3d(8, 4, 1) :
isl_extent3d(8, 8, 1);
} else if (isl_surf_usage_is_stencil(info->usage) ||
isl_surf_usage_is_cpb(info->usage)) {
/* From RENDER_SURFACE_STATE::SurfaceHorizontalAlignment,
*
* - Stencil Surfaces (8b) Must be HALIGN=16Bytes (16texels)
*
* From RENDER_SURFACE_STATE::SurfaceVerticalAlignment,
*
* This field is intended to be set to VALIGN_8 only if
* the surface was rendered as a stencil buffer, since stencil buffer
* surfaces support only alignment of 8.
*
* TODO: Cite docs for CPB.
*/
*image_align_el = isl_extent3d(16, 8, 1);
} else if (!isl_is_pow2(fmtl->bpb)) {
/* From RENDER_SURFACE_STATE::SurfaceHorizontalAlignment,
*
* - Linear Surfaces surfaces must use HALIGN=128, including 1D which
* is always Linear. For 24,48 and 96bpp this means 128texels.
* - Tiled 24bpp, 48bpp and 96bpp surfaces must use HALIGN=16
*/
*image_align_el = tiling == ISL_TILING_LINEAR ?
isl_extent3d(128, 4, 1) :
isl_extent3d(16, 4, 1);
} else if (_isl_surf_info_supports_ccs(dev, info->format, info->usage) ||
tiling == ISL_TILING_LINEAR) {
/* From RENDER_SURFACE_STATE::SurfaceHorizontalAlignment,
*
* - Losslessly Compressed Surfaces Must be HALIGN=128 for all
* supported Bpp, if other restriction are not applied
* - Linear Surfaces surfaces must use HALIGN=128, including 1D which
* is always Linear.
*/
*image_align_el = isl_extent3d(128 * 8 / fmtl->bpb, 4, 1);
} else if (fmtl->bpb >= 64) {
assert(fmtl->bpb == 64 || fmtl->bpb == 128);
/* From RENDER_SURFACE_STATE::SurfaceHorizontalAlignment,
*
* - 64bpe and 128bpe Surfaces Must Be HALIGN=64Bytes or 128Bytes (4,
* 8 texels or 16 texels)
*
* HALIGN=128 is used for losslessly compressed or linear surfaces. For
* other surface types, pick the smaller alignment of HALIGN=64 to save
* space.
*/
*image_align_el = isl_extent3d(64 * 8 / fmtl->bpb, 4, 1);
} else {
/* From RENDER_SURFACE_STATE::SurfaceHorizontalAlignment,
*
* HALIGN=16Bytes(8 texels) is allowed only for 16b Depth, Stencil
* Surfaces (8b) and Tiled 24bpp, 48bpp and 96bpp surfaces
*
* HALIGN=16 would save the most space, but it is reserved for the cases
* handled earlier in this if-ladder. Choose the next smallest alignment
* possible, HALIGN=32.
*/
*image_align_el = isl_extent3d(32 * 8 / fmtl->bpb, 4, 1);
}
}
void
isl_gfx12_choose_image_alignment_el(const struct isl_device *dev,
const struct isl_surf_init_info *restrict info,
const struct isl_tile_info *tile_info,
enum isl_dim_layout dim_layout,
enum isl_msaa_layout msaa_layout,
struct isl_extent3d *image_align_el)
{
enum isl_tiling tiling = tile_info->tiling;
/* Handled by isl_choose_image_alignment_el */
assert(info->format != ISL_FORMAT_HIZ);
if (isl_tiling_is_std_y(tiling)) {
/* From RENDER_SURFACE_STATE::SurfaceHorizontalAlignment,
*
* This field is ignored for Tile64 surface formats because horizontal
* alignment is always to the start of the next tile in that case.
*
* From RENDER_SURFACE_STATE::SurfaceQPitch,
*
* Because MSAA is only supported for Tile64, QPitch must also be
* programmed to an aligned tile boundary for MSAA surfaces.
*
* Images in this surface must be tile-aligned. The table on the Bspec
* page, "2D/CUBE Alignment Requirement", shows that the vertical
* alignment is also a tile height for non-MSAA as well.
*/
*image_align_el = isl_extent3d(tile_info->logical_extent_el.w,
tile_info->logical_extent_el.h,
1);
} else if (isl_surf_usage_is_depth(info->usage)) {
/* The alignment parameters for depth buffers are summarized in the
* following table:
*
* Surface Format | MSAA | Align Width | Align Height
* -----------------+-------------+-------------+--------------
* D16_UNORM | 1x, 4x, 16x | 8 | 8
* ----------------+-------------+-------------+--------------
* D16_UNORM | 2x, 8x | 16 | 4
* ----------------+-------------+-------------+--------------
* other | any | 8 | 4
* -----------------+-------------+-------------+--------------
*/
assert(isl_is_pow2(info->samples));
*image_align_el =
info->format != ISL_FORMAT_R16_UNORM ?
isl_extent3d(8, 4, 1) :
(info->samples == 2 || info->samples == 8 ?
isl_extent3d(16, 4, 1) : isl_extent3d(8, 8, 1));
} else if (isl_surf_usage_is_stencil(info->usage)) {
*image_align_el = isl_extent3d(16, 8, 1);
} else {
isl_gfx9_choose_image_alignment_el(dev, info, tile_info, dim_layout,
msaa_layout, image_align_el);
}
}
+58
View File
@@ -0,0 +1,58 @@
/*
* Copyright (c) 2018 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 ISL_GFX12_H
#define ISL_GFX12_H
#include "isl.h"
#ifdef __cplusplus
extern "C" {
#endif
void
isl_gfx125_filter_tiling(const struct isl_device *dev,
const struct isl_surf_init_info *restrict info,
isl_tiling_flags_t *flags);
void
isl_gfx125_choose_image_alignment_el(const struct isl_device *dev,
const struct isl_surf_init_info *restrict info,
const struct isl_tile_info *tile_info,
enum isl_dim_layout dim_layout,
enum isl_msaa_layout msaa_layout,
struct isl_extent3d *image_align_el);
void
isl_gfx12_choose_image_alignment_el(const struct isl_device *dev,
const struct isl_surf_init_info *restrict info,
const struct isl_tile_info *tile_info,
enum isl_dim_layout dim_layout,
enum isl_msaa_layout msaa_layout,
struct isl_extent3d *image_align_el);
#ifdef __cplusplus
}
#endif
#endif /* ISL_GFX12_H */
+281
View File
@@ -0,0 +1,281 @@
/*
* Copyright (c) 2024 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 "dev/intel_debug.h"
#include "isl_gfx20.h"
#include "isl_priv.h"
/**
* @brief Filter out tiling flags that are incompatible with the surface.
*
* The resultant outgoing @a flags is a subset of the incoming @a flags. The
* outgoing flags may be empty (0x0) if the incoming flags were too
* restrictive.
*
* For example, if the surface will be used for a display
* (ISL_SURF_USAGE_DISPLAY_BIT), then this function filters out all tiling
* flags except ISL_TILING_4_BIT, ISL_TILING_X_BIT, and ISL_TILING_LINEAR_BIT.
*/
void
isl_gfx20_filter_tiling(const struct isl_device *dev,
const struct isl_surf_init_info *restrict info,
isl_tiling_flags_t *flags)
{
/* Clear flags unsupported on this hardware */
assert(ISL_GFX_VERX10(dev) >= 200);
*flags &= isl_device_get_supported_tilings(dev);
if (info->usage & ISL_SURF_USAGE_SOFTWARE_DETILING)
*flags &= (1 << dev->shader_tiling) | ISL_TILING_LINEAR_BIT;
if (isl_surf_usage_is_depth_or_stencil(info->usage)) {
*flags &= ISL_TILING_4_BIT | ISL_TILING_64_XE2_BIT;
/* We choose to avoid Tile64 for 3D depth/stencil buffers. The swizzle
* for Tile64 is dependent on the image dimension. So, reads and writes
* should specify the same dimension to consistently interpret the data.
* This is not possible for 3D depth/stencil buffers however. Such
* buffers can be sampled from with a 3D view, but rendering is only
* possible with a 2D view due to the limitations of
* 3DSTATE_(DEPTH|STENCIL)_BUFFER.
*/
if (info->dim == ISL_SURF_DIM_3D)
*flags &= ~ISL_TILING_64_XE2_BIT;
}
if (info->usage & ISL_SURF_USAGE_DISPLAY_BIT)
*flags &= ~ISL_TILING_64_XE2_BIT;
/* From RENDER_SURFACE_STATE::AuxiliarySurfaceMode,
*
* MCS tiling format is always Tile4
*/
if (info->usage & ISL_SURF_USAGE_MCS_BIT)
*flags &= ISL_TILING_4_BIT;
/* From RENDER_SURFACE_STATE::TileMode,
*
* TILEMODE_XMAJOR is only allowed if Surface Type is SURFTYPE_2D.
*
* X-tiling is only allowed for 2D surfaces.
*/
if (info->dim != ISL_SURF_DIM_2D)
*flags &= ~ISL_TILING_X_BIT;
/* From ATS-M PRMs, Volume 2d: Command Reference: Structures,
* RENDER_SURFACE_STATE:TileMode :
*
* "If Surface Type is SURFTYPE_1D this field must be TILEMODE_LINEAR,
* unless Sampler Legacy 1D Map Layout Disable is set to 0, in which
* case TILEMODE_YMAJOR is also allowed. Horizontal Alignment must be
* programmed for the required alignment between MIPs. MIP tails are
* not supported."
*
* Tile4 is the replacement for TileY0 on ACM.
*/
if (info->dim == ISL_SURF_DIM_1D)
*flags &= ISL_TILING_LINEAR_BIT | ISL_TILING_4_BIT;
/* TILE64 does not work with YCRCB formats, according to bspec 58767:
* "Packed YUV surface formats such as YCRCB_NORMAL, YCRCB_SWAPUVY etc.
* will not support as Tile64"
*/
if (isl_format_is_yuv(info->format))
*flags &= ~ISL_TILING_64_XE2_BIT;
/* Tile64 tilings for 3D have a different swizzling than a 2D surface. So
* filter them out if the usage wants 2D/3D compatibility.
*/
if (info->usage & ISL_SURF_USAGE_2D_3D_COMPATIBLE_BIT)
*flags &= ~ISL_TILING_64_XE2_BIT;
/* From RENDER_SURFACE_STATE::NumberofMultisamples,
*
* This field must not be programmed to anything other than
* [MULTISAMPLECOUNT_1] unless the Tile Mode field is programmed to
* Tile64.
*
* Tile64 is required for multisampling.
*/
if (info->samples > 1)
*flags &= ISL_TILING_64_XE2_BIT;
/* Tile64 is not defined for format sizes that are 24, 48, and 96 bpb. */
if (isl_format_get_layout(info->format)->bpb % 3 == 0)
*flags &= ~ISL_TILING_64_XE2_BIT;
/* From 3DSTATE_CPSIZE_CONTROL_BUFFER::TiledMode,
*
* - 3h Tile4 4KB tile mode
* - 1h Tile64 64KB tile mode
* - 2h, 0h Reserved
*
* Tile4 and Tile64 are the only two valid values.
*/
if (info->usage & ISL_SURF_USAGE_CPB_BIT)
*flags &= ISL_TILING_4_BIT | ISL_TILING_64_XE2_BIT;
/* From ATS-M PRMs, Volume 2a: Command Reference: Instructions,
* MFX_SURFACE_STATE,
*
* "For optimizing memory efficiency based on access patterns, only
* TileY is supported."
*
* The other media engines have similar limitations, TileY is the only
* well-supported tiling mode that can easily be used on all of them.
*/
if (info->usage & ISL_SURF_USAGE_VIDEO_DECODE_BIT)
*flags &= ISL_TILING_4_BIT;
}
void
isl_gfx20_choose_image_alignment_el(const struct isl_device *dev,
const struct isl_surf_init_info *restrict info,
const struct isl_tile_info *tile_info,
enum isl_dim_layout dim_layout,
enum isl_msaa_layout msaa_layout,
struct isl_extent3d *image_align_el)
{
enum isl_tiling tiling = tile_info->tiling;
/* Handled by isl_choose_image_alignment_el */
assert(info->format != ISL_FORMAT_GFX125_HIZ);
const struct isl_format_layout *fmtl = isl_format_get_layout(info->format);
if (tiling == ISL_TILING_64_XE2) {
/* From RENDER_SURFACE_STATE::SurfaceHorizontalAlignment,
*
* This field is ignored for Tile64 surface formats because horizontal
* alignment is always to the start of the next tile in that case.
*
* From RENDER_SURFACE_STATE::SurfaceQPitch,
*
* Because MSAA is only supported for Tile64, QPitch must also be
* programmed to an aligned tile boundary for MSAA surfaces.
*
* Images in this surface must be tile-aligned. The table on the Bspec
* page, "2D/CUBE Alignment Requirement", shows that the vertical
* alignment is also a tile height for non-MSAA as well.
*/
*image_align_el = isl_extent3d(tile_info->logical_extent_el.w,
tile_info->logical_extent_el.h,
1);
} else if (isl_surf_usage_is_depth(info->usage)) {
/* From RENDER_SURFACE_STATE::SurfaceHorizontalAlignment,
*
* - 16b Depth Surfaces Must Be HALIGN=16Bytes (8texels)
* - 32b Depth Surfaces Must Be HALIGN=32Bytes (8texels)
*
* From RENDER_SURFACE_STATE::SurfaceVerticalAlignment,
*
* This field is intended to be set to VALIGN_4 if the surface
* was rendered as a depth buffer [...]
*
* and
*
* This field should also be set to VALIGN_8 if the surface was
* rendered as a D16_UNORM depth buffer [...]
*/
*image_align_el =
info->format != ISL_FORMAT_R16_UNORM ?
isl_extent3d(8, 4, 1) :
isl_extent3d(8, 8, 1);
} else if (isl_surf_usage_is_stencil(info->usage) ||
isl_surf_usage_is_cpb(info->usage)) {
/* From RENDER_SURFACE_STATE::SurfaceHorizontalAlignment,
*
* - Stencil Surfaces (8b) Must be HALIGN=16Bytes (16texels)
*
* From RENDER_SURFACE_STATE::SurfaceVerticalAlignment,
*
* This field is intended to be set to VALIGN_8 only if
* the surface was rendered as a stencil buffer, since stencil buffer
* surfaces support only alignment of 8.
*
* TODO: Cite docs for CPB.
*/
*image_align_el = isl_extent3d(16, 8, 1);
} else if (!isl_is_pow2(fmtl->bpb)) {
/* From RENDER_SURFACE_STATE::SurfaceHorizontalAlignment,
*
* - Linear Surfaces surfaces must use HALIGN=128, including 1D which
* is always Linear. For 24,48 and 96bpp this means 128texels.
* - Tiled 24bpp, 48bpp and 96bpp surfaces must use HALIGN=16
*/
*image_align_el = tiling == ISL_TILING_LINEAR ?
isl_extent3d(128, 4, 1) :
isl_extent3d(16, 4, 1);
} else if (_isl_surf_info_supports_ccs(dev, info->format, info->usage) ||
tiling == ISL_TILING_LINEAR) {
/* From RENDER_SURFACE_STATE::SurfaceHorizontalAlignment,
*
* - Losslessly Compressed Surfaces Must be HALIGN=128 for all
* supported Bpp, if other restriction are not applied
* - Linear Surfaces surfaces must use HALIGN=128, including 1D which
* is always Linear.
*/
*image_align_el = isl_extent3d(128 * 8 / fmtl->bpb, 4, 1);
/* WA_22018390030:
*
* Don't choose VALIGN_4 on Xe2 for color, non-volumetric, Tile4
* surfaces which can be fast cleared. We choose the next smallest
* option instead, VALIGN_8.
*
* Bspec 57340 and HSD 22021327133 state that this also applies to
* Xe3P+.
*/
if (!INTEL_DEBUG(DEBUG_NO_FAST_CLEAR) &&
tiling == ISL_TILING_4 &&
info->dim != ISL_SURF_DIM_3D) {
assert(intel_needs_workaround(dev->info, 22018390030) ||
ISL_GFX_VER(dev) >= 35);
image_align_el->h = 8;
}
} else if (fmtl->bpb >= 64) {
assert(fmtl->bpb == 64 || fmtl->bpb == 128);
/* From RENDER_SURFACE_STATE::SurfaceHorizontalAlignment,
*
* - 64bpe and 128bpe Surfaces Must Be HALIGN=64Bytes or 128Bytes (4,
* 8 texels or 16 texels)
*
* HALIGN=128 is used for losslessly compressed or linear surfaces. For
* other surface types, pick the smaller alignment of HALIGN=64 to save
* space.
*/
*image_align_el = isl_extent3d(64 * 8 / fmtl->bpb, 4, 1);
} else {
/* From RENDER_SURFACE_STATE::SurfaceHorizontalAlignment,
*
* HALIGN=16Bytes(8 texels) is allowed only for 16b Depth, Stencil
* Surfaces (8b) and Tiled 24bpp, 48bpp and 96bpp surfaces
*
* HALIGN=16 would save the most space, but it is reserved for the cases
* handled earlier in this if-ladder. Choose the next smallest alignment
* possible, HALIGN=32.
*/
*image_align_el = isl_extent3d(32 * 8 / fmtl->bpb, 4, 1);
}
}
+49
View File
@@ -0,0 +1,49 @@
/*
* Copyright (c) 2024 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 ISL_GFX20_H
#define ISL_GFX20_H
#include "isl.h"
#ifdef __cplusplus
extern "C" {
#endif
void
isl_gfx20_filter_tiling(const struct isl_device *dev,
const struct isl_surf_init_info *restrict info,
isl_tiling_flags_t *flags);
void
isl_gfx20_choose_image_alignment_el(const struct isl_device *dev,
const struct isl_surf_init_info *restrict info,
const struct isl_tile_info *tile_info,
enum isl_dim_layout dim_layout,
enum isl_msaa_layout msaa_layout,
struct isl_extent3d *image_align_el);
#ifdef __cplusplus
}
#endif
#endif /* ISL_GFX20_H */
+120
View File
@@ -0,0 +1,120 @@
/*
* Copyright 2015 Intel Corporation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
#include "isl_gfx4.h"
#include "isl_priv.h"
bool
isl_gfx4_choose_msaa_layout(const struct isl_device *dev,
const struct isl_surf_init_info *info,
enum isl_tiling tiling,
enum isl_msaa_layout *msaa_layout)
{
/* Gfx4 and Gfx5 do not support MSAA */
assert(info->samples >= 1);
*msaa_layout = ISL_MSAA_LAYOUT_NONE;
return true;
}
void
isl_gfx4_filter_tiling(const struct isl_device *dev,
const struct isl_surf_init_info *restrict info,
isl_tiling_flags_t *flags)
{
*flags &= isl_device_get_supported_tilings(dev);
if (info->usage & ISL_SURF_USAGE_SOFTWARE_DETILING)
*flags &= (1 << dev->shader_tiling) | ISL_TILING_LINEAR_BIT;
if (isl_surf_usage_is_depth_or_stencil(info->usage)) {
assert(!dev->use_separate_stencil);
/* From the g35 PRM Vol. 2, 3DSTATE_DEPTH_BUFFER::Tile Walk:
*
* "The Depth Buffer, if tiled, must use Y-Major tiling"
*
* Errata Description Project
* BWT014 The Depth Buffer Must be Tiled, it cannot be linear. This
* field must be set to 1 on DevBW-A. [DevBW -A,B]
*
* In testing, the linear configuration doesn't seem to work on I965. We
* choose to be consistent and require tiling for gfx4-5.
*/
*flags &= ISL_TILING_Y0_BIT;
}
if (info->usage & ISL_SURF_USAGE_DISPLAY_BIT) {
/* Before Skylake, the display engine does not accept Y */
*flags &= (ISL_TILING_LINEAR_BIT | ISL_TILING_X_BIT);
}
assert(info->samples == 1);
/* From the g35 PRM, Volume 1, 11.5.5, "Per-Stream Tile Format Support":
*
* "NOTE: 128BPE Format Color buffer ( render target ) MUST be either
* TileX or Linear."
*
* This is required all the way up to Sandy Bridge.
*/
if (isl_format_get_layout(info->format)->bpb >= 128)
*flags &= ~ISL_TILING_Y0_BIT;
}
void
isl_gfx4_choose_image_alignment_el(const struct isl_device *dev,
const struct isl_surf_init_info *restrict info,
enum isl_tiling tiling,
enum isl_dim_layout dim_layout,
enum isl_msaa_layout msaa_layout,
struct isl_extent3d *image_align_el)
{
assert(info->samples == 1);
assert(msaa_layout == ISL_MSAA_LAYOUT_NONE);
assert(!isl_tiling_is_std_y(tiling));
/* Note that neither the surface's horizontal nor vertical image alignment
* is programmable on gfx4 nor gfx5.
*
* From the G35 PRM (2008-01), Volume 1 Graphics Core, Section 6.17.3.4
* Alignment Unit Size:
*
* Note that the compressed formats are padded to a full compression
* cell.
*
* +------------------------+--------+--------+
* | format | halign | valign |
* +------------------------+--------+--------+
* | YUV 4:2:2 formats | 4 | 2 |
* | uncompressed formats | 4 | 2 |
* +------------------------+--------+--------+
*/
if (isl_format_is_compressed(info->format)) {
*image_align_el = isl_extent3d(1, 1, 1);
return;
}
*image_align_el = isl_extent3d(4, 2, 1);
}
+56
View File
@@ -0,0 +1,56 @@
/*
* Copyright 2015 Intel Corporation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
#ifndef ISL_GFX4_H
#define ISL_GFX4_H
#include "isl.h"
#ifdef __cplusplus
extern "C" {
#endif
bool
isl_gfx4_choose_msaa_layout(const struct isl_device *dev,
const struct isl_surf_init_info *info,
enum isl_tiling tiling,
enum isl_msaa_layout *msaa_layout);
void
isl_gfx4_filter_tiling(const struct isl_device *dev,
const struct isl_surf_init_info *restrict info,
isl_tiling_flags_t *flags);
void
isl_gfx4_choose_image_alignment_el(const struct isl_device *dev,
const struct isl_surf_init_info *restrict info,
enum isl_tiling tiling,
enum isl_dim_layout dim_layout,
enum isl_msaa_layout msaa_layout,
struct isl_extent3d *image_align_el);
#ifdef __cplusplus
}
#endif
#endif /* ISL_GFX4_H */
+143
View File
@@ -0,0 +1,143 @@
/*
* Copyright 2015 Intel Corporation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
#include "isl_gfx6.h"
#include "isl_priv.h"
bool
isl_gfx6_choose_msaa_layout(const struct isl_device *dev,
const struct isl_surf_init_info *info,
enum isl_tiling tiling,
enum isl_msaa_layout *msaa_layout)
{
assert(ISL_GFX_VER(dev) == 6);
assert(info->samples >= 1);
if (info->samples == 1) {
*msaa_layout = ISL_MSAA_LAYOUT_NONE;
return true;
}
if (!isl_format_supports_multisampling(dev->info, info->format))
return notify_failure(info, "format does not support msaa");
/* From the Sandybridge PRM, Volume 4 Part 1 p85, SURFACE_STATE, Number of
* Multisamples:
*
* If this field is any value other than MULTISAMPLECOUNT_1 the
* following restrictions apply:
*
* - the Surface Type must be SURFTYPE_2D
* - [...]
*/
if (info->dim != ISL_SURF_DIM_2D)
return notify_failure(info, "msaa only supported on 2D surfaces");
/* Should have been filtered by isl_gfx6_filter_tiling() */
assert(!isl_surf_usage_is_display(info->usage));
assert(tiling != ISL_TILING_LINEAR);
/* More obvious restrictions */
if (info->levels > 1)
return notify_failure(info, "msaa not supported with LOD > 1");
*msaa_layout = ISL_MSAA_LAYOUT_INTERLEAVED;
return true;
}
void
isl_gfx6_choose_image_alignment_el(const struct isl_device *dev,
const struct isl_surf_init_info *restrict info,
enum isl_tiling tiling,
enum isl_dim_layout dim_layout,
enum isl_msaa_layout msaa_layout,
struct isl_extent3d *image_align_el)
{
/* Handled by isl_choose_image_alignment_el */
assert(info->format != ISL_FORMAT_HIZ);
/* Note that the surface's horizontal image alignment is not programmable
* on Sandybridge.
*
* From the Sandybridge PRM (2011-05), Volume 1, Part 1, Section 7.18.3.4
* Alignment Unit Size:
*
* Note that the compressed formats are padded to a full compression cell.
*
* +------------------------+--------+--------+
* | format | halign | valign |
* +------------------------+--------+--------+
* | YUV 4:2:2 formats | 4 | * |
* | BC1-5 | 4 | 4 |
* | FXT1 | 8 | 4 |
* | uncompressed formats | 4 | * |
* +------------------------+--------+--------+
*
* * For these formats, the vertical alignment factor “j” is determined
* as follows:
* - j = 4 for any depth buffer
* - j = 2 for separate stencil buffer
* - j = 4 for any render target surface is multisampled (4x)
* - j = 2 for all other render target surface
*
* From the Sandrybridge PRM (2011-05), Volume 4, Part 1, Section 2.11.2
* SURFACE_STATE, Surface Vertical Alignment:
*
* - This field must be set to VALIGN_2 if the Surface Format is 96 bits
* per element (BPE).
*
* - Value of 1 [VALIGN_4] is not supported for format YCRCB_NORMAL
* (0x182), YCRCB_SWAPUVY (0x183), YCRCB_SWAPUV (0x18f), YCRCB_SWAPY
* (0x190)
*/
if (isl_format_is_compressed(info->format)) {
/* Compressed formats have an alignment equal to their block size */
*image_align_el = isl_extent3d(1, 1, 1);
return;
}
/* Separate stencil requires 4x2 alignment */
if (isl_surf_usage_is_stencil(info->usage) &&
info->format == ISL_FORMAT_R8_UINT) {
*image_align_el = isl_extent3d(4, 2, 1);
return;
}
/* Depth or combined depth stencil surfaces require 4x4 alignment */
if (isl_surf_usage_is_depth_or_stencil(info->usage)) {
*image_align_el = isl_extent3d(4, 4, 1);
return;
}
if (info->samples > 1) {
*image_align_el = isl_extent3d(4, 4, 1);
return;
}
/* For everything else, 4x2 is always a valid alignment. Since this is
* also the smallest alignment we can specify, we use 4x2 for everything
* else because it uses the least memory.
*/
*image_align_el = isl_extent3d(4, 2, 1);
}
+51
View File
@@ -0,0 +1,51 @@
/*
* Copyright 2015 Intel Corporation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
#ifndef ISL_GFX6_H
#define ISL_GFX6_H
#include "isl.h"
#ifdef __cplusplus
extern "C" {
#endif
bool
isl_gfx6_choose_msaa_layout(const struct isl_device *dev,
const struct isl_surf_init_info *info,
enum isl_tiling tiling,
enum isl_msaa_layout *msaa_layout);
void
isl_gfx6_choose_image_alignment_el(const struct isl_device *dev,
const struct isl_surf_init_info *restrict info,
enum isl_tiling tiling,
enum isl_dim_layout dim_layout,
enum isl_msaa_layout msaa_layout,
struct isl_extent3d *image_align_el);
#ifdef __cplusplus
}
#endif
#endif /* ISL_GFX6_H */
+459
View File
@@ -0,0 +1,459 @@
/*
* Copyright 2015 Intel Corporation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
#include "isl_gfx7.h"
#include "isl_priv.h"
static bool
gfx7_format_needs_valign2(const struct isl_device *dev,
enum isl_format format)
{
assert(ISL_GFX_VER(dev) == 7);
/* From the Ivybridge PRM (2012-05-31), Volume 4, Part 1, Section 2.12.1,
* RENDER_SURFACE_STATE Surface Vertical Alignment:
*
* - Value of 1 [VALIGN_4] is not supported for format YCRCB_NORMAL
* (0x182), YCRCB_SWAPUVY (0x183), YCRCB_SWAPUV (0x18f), YCRCB_SWAPY
* (0x190)
*
* - VALIGN_4 is not supported for surface format R32G32B32_FLOAT.
*
* The R32G32B32_FLOAT restriction is dropped on Haswell.
*/
return isl_format_is_yuv(format) ||
(format == ISL_FORMAT_R32G32B32_FLOAT && !ISL_DEV_IS_HASWELL(dev));
}
bool
isl_gfx7_choose_msaa_layout(const struct isl_device *dev,
const struct isl_surf_init_info *info,
enum isl_tiling tiling,
enum isl_msaa_layout *msaa_layout)
{
bool require_array = false;
bool require_interleaved = false;
assert(ISL_GFX_VER(dev) == 7);
assert(info->samples >= 1);
if (info->samples == 1) {
*msaa_layout = ISL_MSAA_LAYOUT_NONE;
return true;
}
/* Should have been filtered by isl_gfx6_filter_tiling() */
assert(!isl_surf_usage_is_display(info->usage));
assert(tiling != ISL_TILING_LINEAR);
if (!isl_format_supports_multisampling(dev->info, info->format))
return notify_failure(info, "format does not support msaa");
/* From the Ivybridge PRM, Volume 4 Part 1 p73, SURFACE_STATE, Number of
* Multisamples:
*
* - If this field is any value other than MULTISAMPLECOUNT_1, the
* Surface Type must be SURFTYPE_2D.
*
* - If this field is any value other than MULTISAMPLECOUNT_1, Surface
* Min LOD, Mip Count / LOD, and Resource Min LOD must be set to zero
*/
if (info->dim != ISL_SURF_DIM_2D)
return notify_failure(info, "msaa only supported on 2D surfaces");
if (info->levels > 1)
return notify_failure(info, "msaa not supported with LOD > 1");
/* The Ivyrbridge PRM insists twice that signed integer formats cannot be
* multisampled.
*
* From the Ivybridge PRM, Volume 4 Part 1 p73, SURFACE_STATE, Number of
* Multisamples:
*
* - This field must be set to MULTISAMPLECOUNT_1 for SINT MSRTs when
* all RT channels are not written.
*
* And errata from the Ivybridge PRM, Volume 4 Part 1 p77,
* RENDER_SURFACE_STATE, MCS Enable:
*
* This field must be set to 0 [MULTISAMPLECOUNT_1] for all SINT MSRTs
* when all RT channels are not written.
*
* Note that the above SINT restrictions apply only to *MSRTs* (that is,
* *multisampled* render targets). The restrictions seem to permit an MCS
* if the render target is singlesampled.
*
* Moreover, empirically it looks that hardware can render multisampled
* surfaces with RGBA8I, RGBA16I and RGBA32I.
*/
/* Multisampling requires vertical alignment of four. */
if (info->samples > 1 && gfx7_format_needs_valign2(dev, info->format)) {
return notify_failure(info, "msaa requires vertical alignment of four, "
"but format requires vertical alignment of two");
}
/* From the Ivybridge PRM, Volume 4 Part 1 p72, SURFACE_STATE, Multisampled
* Surface Storage Format:
*
* +---------------------+----------------------------------------------------------------+
* | MSFMT_MSS | Multsampled surface was/is rendered as a render target |
* | MSFMT_DEPTH_STENCIL | Multisampled surface was rendered as a depth or stencil buffer |
* +---------------------+----------------------------------------------------------------+
*
* In the table above, MSFMT_MSS refers to ISL_MSAA_LAYOUT_ARRAY, and
* MSFMT_DEPTH_STENCIL refers to ISL_MSAA_LAYOUT_INTERLEAVED.
*/
if (isl_surf_usage_is_depth_or_stencil(info->usage) ||
(info->usage & ISL_SURF_USAGE_HIZ_BIT))
require_interleaved = true;
/* From the Ivybridge PRM, Volume 4 Part 1 p72, SURFACE_STATE, Multisampled
* Surface Storage Format:
*
* If the surface’s Number of Multisamples is MULTISAMPLECOUNT_8, Width
* is >= 8192 (meaning the actual surface width is >= 8193 pixels), this
* field must be set to MSFMT_MSS.
*/
if (info->samples == 8 && info->width > 8192)
require_array = true;
/* From the Ivybridge PRM, Volume 4 Part 1 p72, SURFACE_STATE, Multisampled
* Surface Storage Format:
*
* If the surface’s Number of Multisamples is MULTISAMPLECOUNT_8,
* ((Depth+1) * (Height+1)) is > 4,194,304, OR if the surface’s Number
* of Multisamples is MULTISAMPLECOUNT_4, ((Depth+1) * (Height+1)) is
* > 8,388,608, this field must be set to MSFMT_DEPTH_STENCIL.
*/
if ((info->samples == 8 && info->height > 4194304u) ||
(info->samples == 4 && info->height > 8388608u))
require_interleaved = true;
/* From the Ivybridge PRM, Volume 4 Part 1 p72, SURFACE_STATE, Multisampled
* Surface Storage Format:
*
* This field must be set to MSFMT_DEPTH_STENCIL if Surface Format is
* one of the following: I24X8_UNORM, L24X8_UNORM, A24X8_UNORM, or
* R24_UNORM_X8_TYPELESS.
*/
if (info->format == ISL_FORMAT_I24X8_UNORM ||
info->format == ISL_FORMAT_L24X8_UNORM ||
info->format == ISL_FORMAT_A24X8_UNORM ||
info->format == ISL_FORMAT_R24_UNORM_X8_TYPELESS)
require_interleaved = true;
if (require_array && require_interleaved)
return notify_failure(info, "cannot require array & interleaved msaa layouts");
if (require_interleaved) {
*msaa_layout = ISL_MSAA_LAYOUT_INTERLEAVED;
return true;
}
/* Default to the array layout because it permits multisample
* compression.
*/
*msaa_layout = ISL_MSAA_LAYOUT_ARRAY;
return true;
}
/**
* @brief Filter out tiling flags that are incompatible with the surface.
*
* The resultant outgoing @a flags is a subset of the incoming @a flags. The
* outgoing flags may be empty (0x0) if the incoming flags were too
* restrictive.
*
* For example, if the surface will be used for a display
* (ISL_SURF_USAGE_DISPLAY_BIT), then this function filters out all tiling
* flags except ISL_TILING_X_BIT and ISL_TILING_LINEAR_BIT.
*/
void
isl_gfx6_filter_tiling(const struct isl_device *dev,
const struct isl_surf_init_info *restrict info,
isl_tiling_flags_t *flags)
{
/* IVB+ requires separate stencil */
assert(dev->use_separate_stencil);
/* Clear flags unsupported on this hardware */
assert(ISL_GFX_VERX10(dev) < 125);
*flags &= isl_device_get_supported_tilings(dev);
if (info->usage & ISL_SURF_USAGE_SOFTWARE_DETILING)
*flags &= (1 << dev->shader_tiling) | ISL_TILING_LINEAR_BIT;
if (isl_surf_usage_is_depth(info->usage)) {
/* Depth requires Y. */
*flags &= ISL_TILING_ANY_Y_MASK;
}
if (isl_surf_usage_is_depth_or_stencil(info->usage)) {
/* We choose to avoid Yf/Ys for 3D depth/stencil buffers. The swizzles
* for the Yf and Ys tilings are dependent on the image dimension. So,
* reads and writes should specify the same dimension to consistently
* interpret the data. This is not possible for 3D depth/stencil buffers
* however. Such buffers can be sampled from with a 3D view, but
* rendering is only possible with a 2D view due to the limitations of
* 3DSTATE_(DEPTH|STENCIL)_BUFFER.
*/
if (info->dim == ISL_SURF_DIM_3D)
*flags &= ~ISL_TILING_STD_Y_MASK;
}
/* Again, Yf and Ys tilings for 3D have a different swizzling than a 2D
* surface. So filter them out if the usage wants 2D/3D compatibility.
*/
if (info->usage & ISL_SURF_USAGE_2D_3D_COMPATIBLE_BIT)
*flags &= ~ISL_TILING_STD_Y_MASK;
/* For 3D storage images, we appear to have an undocumented dataport issue,
* where the RENDER_SURFACE_STATE::MinimumArrayElement is ignored with
* TileYs/TileYf.
*
* This is breaking VK_EXT_image_sliced_view_of_3d which is trying to
* access 3D images with an offset.
*
* It's unclear what the issue is but the behavior does not match
* simulation and there is no workaround related to 3D images & TileYs/Yf.
*
* We could workaround this issue by reading the offset from memory and add
* it to the imageLoad/Store() coordinates.
*/
if (ISL_GFX_VER(dev) <= 11 &&
info->dim == ISL_SURF_DIM_3D &&
(info->usage & ISL_SURF_USAGE_STORAGE_BIT))
*flags &= ~ISL_TILING_STD_Y_MASK;
if (isl_surf_usage_is_stencil(info->usage)) {
if (ISL_GFX_VER(dev) >= 12) {
/* Stencil requires Y. */
*flags &= ISL_TILING_ANY_Y_MASK;
} else {
/* Stencil requires W. */
*flags &= ISL_TILING_W_BIT;
}
} else {
*flags &= ~ISL_TILING_W_BIT;
}
/* ICL PRMs, Volume 5: Memory Data Formats, 1D Alignment Requirements:
*
* Tiled Resource Mode | Bits per Element | Horizontal Alignment
* TRMODE_NONE | Any | 64
*
* The table does not list any other tiled resource modes. On the other hand,
* the SKL PRM has entries for TRMODE_64KB and TRMODE_4KB. This suggests that
* standard tilings are no longer officially supported for 1D surfaces. We don't
* really have a use-case for it anyway, so we choose to match the later docs.
*/
if (info->dim == ISL_SURF_DIM_1D)
*flags &= ~ISL_TILING_STD_Y_MASK;
/* MCS buffers are always Y-tiled */
if (isl_format_get_layout(info->format)->txc == ISL_TXC_MCS)
*flags &= ISL_TILING_Y0_BIT;
if (info->usage & ISL_SURF_USAGE_DISPLAY_BIT) {
if (ISL_GFX_VER(dev) >= 12) {
*flags &= (ISL_TILING_LINEAR_BIT | ISL_TILING_X_BIT |
ISL_TILING_Y0_BIT);
} else if (ISL_GFX_VER(dev) >= 9) {
*flags &= (ISL_TILING_LINEAR_BIT | ISL_TILING_X_BIT |
ISL_TILING_Y0_BIT |
ISL_TILING_SKL_Yf_BIT | ISL_TILING_ICL_Yf_BIT);
} else {
/* Before Skylake, the display engine does not accept Y */
*flags &= (ISL_TILING_LINEAR_BIT | ISL_TILING_X_BIT);
}
}
if (info->samples > 1) {
/* From the Sandybridge PRM, Volume 4 Part 1, SURFACE_STATE Tiled
* Surface:
*
* For multisample render targets, this field must be 1 (true). MSRTs
* can only be tiled.
*
* From the Broadwell PRM >> Volume2d: Command Structures >>
* RENDER_SURFACE_STATE Tile Mode:
*
* If Number of Multisamples is not MULTISAMPLECOUNT_1, this field
* must be YMAJOR.
*
* As usual, though, stencil is special and requires W-tiling.
*/
*flags &= (ISL_TILING_ANY_Y_MASK | ISL_TILING_W_BIT);
}
/* workaround */
if (ISL_GFX_VER(dev) == 7 &&
gfx7_format_needs_valign2(dev, info->format) &&
(info->usage & ISL_SURF_USAGE_RENDER_TARGET_BIT) &&
info->samples == 1) {
/* Y tiling is illegal. From the Ivybridge PRM, Vol4 Part1 2.12.2.1,
* SURFACE_STATE Surface Vertical Alignment:
*
* This field must be set to VALIGN_4 for all tiled Y Render Target
* surfaces.
*/
*flags &= ~ISL_TILING_Y0_BIT;
}
/* From the Sandybridge PRM, Volume 1, Part 2, page 32:
*
* "NOTE: 128BPE Format Color Buffer ( render target ) MUST be either
* TileX or Linear."
*
* This is necessary all the way back to 965, but is permitted on Gfx7+.
*/
if (ISL_GFX_VER(dev) < 7 && isl_format_get_layout(info->format)->bpb >= 128)
*flags &= ~ISL_TILING_Y0_BIT;
/* From the BDW and SKL PRMs, Volume 2d,
* RENDER_SURFACE_STATE::Width - Programming Notes:
*
* A known issue exists if a primitive is rendered to the first 2 rows and
* last 2 columns of a 16K width surface. If any geometry is drawn inside
* this square it will be copied to column X=2 and X=3 (arrangement on Y
* position will stay the same). If any geometry exceeds the boundaries of
* this 2x2 region it will be drawn normally. The issue also only occurs
* if the surface has TileMode != Linear.
*
* [Internal documentation notes that this issue isn't present on SKL GT4.]
* To prevent this rendering corruption, only allow linear tiling for
* surfaces with widths greater than 16K-2 pixels.
*
* TODO: Is this an issue for multisampled surfaces as well?
*/
if (info->width > 16382 && info->samples == 1 &&
info->usage & ISL_SURF_USAGE_RENDER_TARGET_BIT &&
(ISL_GFX_VER(dev) == 8 ||
(dev->info->platform == INTEL_PLATFORM_SKL && dev->info->gt != 4))) {
*flags &= ISL_TILING_LINEAR_BIT;
}
/* From HSW PRMs, Volume 2b: Command Reference: Instructions,
* MFX_SURFACE_STATE,
*
* "For optimizing memory efficiency based on access patterns, only
* TileY is supported."
*/
if (info->usage & ISL_SURF_USAGE_VIDEO_DECODE_BIT)
*flags &= ISL_TILING_Y0_BIT;
}
void
isl_gfx7_choose_image_alignment_el(const struct isl_device *dev,
const struct isl_surf_init_info *restrict info,
enum isl_tiling tiling,
enum isl_dim_layout dim_layout,
enum isl_msaa_layout msaa_layout,
struct isl_extent3d *image_align_el)
{
assert(ISL_GFX_VER(dev) == 7);
/* Handled by isl_choose_image_alignment_el */
assert(info->format != ISL_FORMAT_HIZ);
/* IVB+ does not support combined depthstencil. */
assert(!isl_surf_usage_is_depth_and_stencil(info->usage));
/* From the Ivy Bridge PRM, Vol. 2, Part 2, Section 6.18.4.4,
* "Alignment unit size", the alignment parameters are summarized in the
* following table:
*
* Surface Defined By | Surface Format | Align Width | Align Height
* --------------------+-----------------+-------------+--------------
* DEPTH_BUFFER | D16_UNORM | 8 | 4
* | other | 4 | 4
* --------------------+-----------------+-------------+--------------
* STENCIL_BUFFER | N/A | 8 | 8
* --------------------+-----------------+-------------+--------------
* SURFACE_STATE | BC*, ETC*, EAC* | 4 | 4
* | FXT1 | 8 | 4
* | all others | HALIGN | VALIGN
* -------------------------------------------------------------------
*/
if (isl_surf_usage_is_depth(info->usage)) {
*image_align_el = info->format == ISL_FORMAT_R16_UNORM ?
isl_extent3d(8, 4, 1) : isl_extent3d(4, 4, 1);
return;
} else if (isl_surf_usage_is_stencil(info->usage)) {
*image_align_el = isl_extent3d(8, 8, 1);
return;
} else if (isl_format_is_compressed(info->format)) {
/* Compressed formats all have alignment equal to block size. */
*image_align_el = isl_extent3d(1, 1, 1);
return;
}
/* Everything after this point is in the "set by Surface Horizontal or
* Vertical Alignment" case. Now it's just a matter of applying
* restrictions.
*/
/* There are no restrictions on halign beyond what's given in the table
* above. We set it to the minimum value of 4 because that uses the least
* memory.
*/
const uint32_t halign = 4;
bool require_valign4 = false;
/* From the Ivybridge PRM, Volume 4, Part 1, Section 2.12.1:
* RENDER_SURFACE_STATE Surface Vertical Alignment:
*
* * This field is intended to be set to VALIGN_4 if the surface was
* rendered as a depth buffer,
*
* * for a multisampled (4x) render target, or for a multisampled (8x)
* render target, since these surfaces support only alignment of 4.
*
* * This field must be set to VALIGN_4 for all tiled Y Render Target
* surfaces
*
* * Value of 1 is not supported for format YCRCB_NORMAL (0x182),
* YCRCB_SWAPUVY (0x183), YCRCB_SWAPUV (0x18f), YCRCB_SWAPY (0x190)
*
* * If Number of Multisamples is not MULTISAMPLECOUNT_1, this field
* must be set to VALIGN_4."
*
* The first restriction is already handled by the table above and the
* second restriction is redundant with the fifth.
*/
if (info->samples > 1)
require_valign4 = true;
if (tiling == ISL_TILING_Y0 &&
(info->usage & ISL_SURF_USAGE_RENDER_TARGET_BIT))
require_valign4 = true;
assert(!(require_valign4 && gfx7_format_needs_valign2(dev, info->format)));
/* We default to VALIGN_2 because it uses the least memory. */
const uint32_t valign = require_valign4 ? 4 : 2;
*image_align_el = isl_extent3d(halign, valign, 1);
}
+56
View File
@@ -0,0 +1,56 @@
/*
* Copyright 2015 Intel Corporation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
#ifndef ISL_GFX7_H
#define ISL_GFX7_H
#include "isl.h"
#ifdef __cplusplus
extern "C" {
#endif
void
isl_gfx6_filter_tiling(const struct isl_device *dev,
const struct isl_surf_init_info *restrict info,
isl_tiling_flags_t *flags);
bool
isl_gfx7_choose_msaa_layout(const struct isl_device *dev,
const struct isl_surf_init_info *info,
enum isl_tiling tiling,
enum isl_msaa_layout *msaa_layout);
void
isl_gfx7_choose_image_alignment_el(const struct isl_device *dev,
const struct isl_surf_init_info *restrict info,
enum isl_tiling tiling,
enum isl_dim_layout dim_layout,
enum isl_msaa_layout msaa_layout,
struct isl_extent3d *image_align_el);
#ifdef __cplusplus
}
#endif
#endif /* ISL_GFX7_H */
+191
View File
@@ -0,0 +1,191 @@
/*
* Copyright 2015 Intel Corporation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
#include "isl_gfx8.h"
#include "isl_priv.h"
bool
isl_gfx8_choose_msaa_layout(const struct isl_device *dev,
const struct isl_surf_init_info *info,
enum isl_tiling tiling,
enum isl_msaa_layout *msaa_layout)
{
bool require_array = false;
bool require_interleaved = false;
assert(info->samples >= 1);
if (info->samples == 1) {
*msaa_layout = ISL_MSAA_LAYOUT_NONE;
return true;
}
/* From the Broadwell PRM >> Volume2d: Command Structures >>
* RENDER_SURFACE_STATE Multisampled Surface Storage Format:
*
* All multisampled render target surfaces must have this field set to
* MSFMT_MSS
*/
if (info->usage & ISL_SURF_USAGE_RENDER_TARGET_BIT)
require_array = true;
/* From the Broadwell PRM >> Volume2d: Command Structures >>
* RENDER_SURFACE_STATE Number of Multisamples:
*
* - If this field is any value other than MULTISAMPLECOUNT_1, the
* Surface Type must be SURFTYPE_2D This field must be set to
* MULTISAMPLECOUNT_1 unless the surface is a Sampling Engine surface
* or Render Target surface.
*
* - If this field is any value other than MULTISAMPLECOUNT_1, Surface
* Min LOD, Mip Count / LOD, and Resource Min LOD must be set to zero.
*/
if (info->dim != ISL_SURF_DIM_2D)
return notify_failure(info, "msaa only supported on 2D surfaces");
if (info->levels > 1)
return notify_failure(info, "msaa not supported with LOD > 1");
/* More obvious restrictions */
assert(!isl_surf_usage_is_display(info->usage));
assert(tiling != ISL_TILING_LINEAR);
if (!isl_format_supports_multisampling(dev->info, info->format))
return notify_failure(info, "format does not support msaa");
if (isl_surf_usage_is_depth_or_stencil(info->usage) ||
(info->usage & ISL_SURF_USAGE_HIZ_BIT))
require_interleaved = true;
if (require_array && require_interleaved)
return notify_failure(info, "cannot require array & interleaved msaa layouts");
if (require_interleaved) {
*msaa_layout = ISL_MSAA_LAYOUT_INTERLEAVED;
return true;
}
*msaa_layout = ISL_MSAA_LAYOUT_ARRAY;
return true;
}
void
isl_gfx8_choose_image_alignment_el(const struct isl_device *dev,
const struct isl_surf_init_info *restrict info,
enum isl_tiling tiling,
enum isl_dim_layout dim_layout,
enum isl_msaa_layout msaa_layout,
struct isl_extent3d *image_align_el)
{
/* Handled by isl_choose_image_alignment_el */
assert(info->format != ISL_FORMAT_HIZ);
assert(!isl_tiling_is_std_y(tiling));
const struct isl_format_layout *fmtl = isl_format_get_layout(info->format);
if (fmtl->txc == ISL_TXC_CCS) {
/*
* Broadwell PRM Vol 7, "MCS Buffer for Render Target(s)" (p. 676):
*
* "Mip-mapped and arrayed surfaces are supported with MCS buffer
* layout with these alignments in the RT space: Horizontal
* Alignment = 256 and Vertical Alignment = 128.
*/
*image_align_el = isl_extent3d(256 / fmtl->bw, 128 / fmtl->bh, 1);
return;
}
/* From the Broadwell PRM, Volume 4, "Memory Views" p. 186, the alignment
* parameters are summarized in the following table:
*
* Surface Defined By | Surface Format | Align Width | Align Height
* --------------------+-----------------+-------------+--------------
* DEPTH_BUFFER | D16_UNORM | 8 | 4
* | other | 4 | 4
* --------------------+-----------------+-------------+--------------
* STENCIL_BUFFER | N/A | 8 | 8
* --------------------+-----------------+-------------+--------------
* SURFACE_STATE | BC*, ETC*, EAC* | 4 | 4
* | FXT1 | 8 | 4
* | all others | HALIGN | VALIGN
* -------------------------------------------------------------------
*/
if (isl_surf_usage_is_depth(info->usage)) {
*image_align_el = info->format == ISL_FORMAT_R16_UNORM ?
isl_extent3d(8, 4, 1) : isl_extent3d(4, 4, 1);
return;
} else if (isl_surf_usage_is_stencil(info->usage)) {
*image_align_el = isl_extent3d(8, 8, 1);
return;
} else if (isl_format_is_compressed(info->format)) {
/* Compressed formats all have alignment equal to block size. */
*image_align_el = isl_extent3d(1, 1, 1);
return;
}
/* For all other formats, the alignment is determined by the horizontal and
* vertical alignment fields of RENDER_SURFACE_STATE. There are a few
* restrictions, but we generally have a choice.
*/
/* Vertical alignment is unrestricted so we choose the smallest allowed
* alignment because that will use the least memory
*/
const uint32_t valign = 4;
/* XXX(chadv): I believe the hardware requires each image to be
* cache-aligned. If that's true, then defaulting to halign=4 is wrong for
* many formats. Depending on the format's block size, we may need to
* increase halign to 8.
*/
uint32_t halign = 4;
if (!(info->usage & ISL_SURF_USAGE_DISABLE_AUX_BIT)) {
/* From the Broadwell PRM, Volume 2d "Command Reference: Structures",
* RENDER_SURFACE_STATE Surface Horizontal Alignment, p326:
*
* - When Auxiliary Surface Mode is set to AUX_CCS_D or AUX_CCS_E,
* HALIGN 16 must be used.
*
* This case handles color surfaces that may own an auxiliary MCS, CCS_D,
* or CCS_E. Depth buffers, including those that own an auxiliary HiZ
* surface, are handled above and do not require HALIGN_16.
*/
assert(halign <= 16);
halign = 16;
}
if (ISL_GFX_VER(dev) >= 11 && isl_tiling_is_any_y(tiling) &&
fmtl->bpb == 32 && info->samples == 1) {
/* GEN_BUG_1406667188: Pixel Corruption in subspan combining (8x4
* combining) scenarios if halign=4.
*
* See RENDER_SURFACE_STATE in Ice Lake h/w spec:
*
* "For surface format = 32 bpp, num_multisamples = 1 , MIpcount > 0
* and surface walk = TiledY, HALIGN must be programmed to 8"
*/
halign = MAX(halign, 8);
}
*image_align_el = isl_extent3d(halign, valign, 1);
}
+51
View File
@@ -0,0 +1,51 @@
/*
* Copyright 2015 Intel Corporation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
#ifndef ISL_GFX8_H
#define ISL_GFX8_H
#include "isl.h"
#ifdef __cplusplus
extern "C" {
#endif
bool
isl_gfx8_choose_msaa_layout(const struct isl_device *dev,
const struct isl_surf_init_info *info,
enum isl_tiling tiling,
enum isl_msaa_layout *msaa_layout);
void
isl_gfx8_choose_image_alignment_el(const struct isl_device *dev,
const struct isl_surf_init_info *restrict info,
enum isl_tiling tiling,
enum isl_dim_layout dim_layout,
enum isl_msaa_layout msaa_layout,
struct isl_extent3d *image_align_el);
#ifdef __cplusplus
}
#endif
#endif /* ISL_GFX8_H */
+133
View File
@@ -0,0 +1,133 @@
/*
* Copyright 2015 Intel Corporation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
#include "isl_gfx8.h"
#include "isl_gfx9.h"
#include "isl_priv.h"
void
isl_gfx9_choose_image_alignment_el(const struct isl_device *dev,
const struct isl_surf_init_info *restrict info,
const struct isl_tile_info *tile_info,
enum isl_dim_layout dim_layout,
enum isl_msaa_layout msaa_layout,
struct isl_extent3d *image_align_el)
{
enum isl_tiling tiling = tile_info->tiling;
/* Handled by isl_choose_image_alignment_el */
assert(info->format != ISL_FORMAT_HIZ);
const struct isl_format_layout *fmtl = isl_format_get_layout(info->format);
if (fmtl->txc == ISL_TXC_CCS) {
/* Sky Lake PRM Vol. 7, "MCS Buffer for Render Target(s)" (p. 632):
*
* "Mip-mapped and arrayed surfaces are supported with MCS buffer
* layout with these alignments in the RT space: Horizontal
* Alignment = 128 and Vertical Alignment = 64."
*/
*image_align_el = isl_extent3d(128 / fmtl->bw, 64 / fmtl->bh, 1);
return;
}
/* This BSpec text provides some insight into the hardware's alignment
* requirements [Skylake BSpec > Memory Views > Common Surface Formats >
* Surface Layout and Tiling > 2D Surfaces]:
*
* An LOD must be aligned to a cache-line except for some special cases
* related to Planar YUV surfaces. In general, the cache-alignment
* restriction implies there is a minimum height for an LOD of 4 texels.
* So, LODs which are smaller than 4 high are padded.
*
* From the Skylake BSpec, RENDER_SURFACE_STATE Surface Vertical Alignment:
*
* - For Sampling Engine and Render Target Surfaces: This field
* specifies the vertical alignment requirement in elements for the
* surface. [...] An element is defined as a pixel in uncompressed
* surface formats, and as a compression block in compressed surface
* formats. For MSFMT_DEPTH_STENCIL type multisampled surfaces, an
* element is a sample.
*
* - This field is used for 2D, CUBE, and 3D surface alignment when Tiled
* Resource Mode is TRMODE_NONE (Tiled Resource Mode is disabled).
* This field is ignored for 1D surfaces and also when Tiled Resource
* Mode is not TRMODE_NONE (e.g. Tiled Resource Mode is enabled).
*
* See the appropriate Alignment table in the "Surface Layout and
* Tiling" section under Common Surface Formats for the table of
* alignment values for Tiled Resources.
*
* - For uncompressed surfaces, the units of "j" are rows of pixels on
* the physical surface. For compressed texture formats, the units of
* "j" are in compression blocks, thus each increment in "j" is equal
* to h pixels, where h is the height of the compression block in
* pixels.
*
* - Valid Values: VALIGN_4, VALIGN_8, VALIGN_16
*
* From the Skylake BSpec, RENDER_SURFACE_STATE Surface Horizontal
* Alignment:
*
* - For uncompressed surfaces, the units of "i" are pixels on the
* physical surface. For compressed texture formats, the units of "i"
* are in compression blocks, thus each increment in "i" is equal to
* w pixels, where w is the width of the compression block in pixels.
*
* - Valid Values: HALIGN_4, HALIGN_8, HALIGN_16
*/
if (isl_tiling_is_std_y(tiling)) {
/* Ys and Yf tiled images are aligned to the tile size */
*image_align_el = (struct isl_extent3d) {
.w = tile_info->logical_extent_el.w,
.h = tile_info->logical_extent_el.h,
.d = tile_info->logical_extent_el.d,
};
return;
}
if (dim_layout == ISL_DIM_LAYOUT_GFX9_1D) {
/* See the Skylake BSpec > Memory Views > Common Surface Formats > Surface
* Layout and Tiling > 1D Surfaces > 1D Alignment Requirements.
*/
*image_align_el = isl_extent3d(64, 1, 1);
return;
}
if (isl_format_is_compressed(info->format)) {
/* On Gfx9, the meaning of RENDER_SURFACE_STATE's
* SurfaceHorizontalAlignment and SurfaceVerticalAlignment changed for
* compressed formats. They now indicate a multiple of the compression
* block. For example, if the compression mode is ETC2 then HALIGN_4
* indicates a horizontal alignment of 16 pixels.
*
* To avoid wasting memory, choose the smallest alignment possible:
* HALIGN_4 and VALIGN_4.
*/
*image_align_el = isl_extent3d(4, 4, 1);
return;
}
isl_gfx8_choose_image_alignment_el(dev, info, tiling, dim_layout,
msaa_layout, image_align_el);
}
+45
View File
@@ -0,0 +1,45 @@
/*
* Copyright 2015 Intel Corporation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
#ifndef ISL_GFX9_H
#define ISL_GFX9_H
#include "isl.h"
#ifdef __cplusplus
extern "C" {
#endif
void
isl_gfx9_choose_image_alignment_el(const struct isl_device *dev,
const struct isl_surf_init_info *restrict info,
const struct isl_tile_info *tile_info,
enum isl_dim_layout dim_layout,
enum isl_msaa_layout msaa_layout,
struct isl_extent3d *image_align_el);
#ifdef __cplusplus
}
#endif
#endif /* ISL_GFX9_H */
+340
View File
@@ -0,0 +1,340 @@
/*
* Copyright 2015 Intel Corporation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
#ifndef ISL_PRIV_H
#define ISL_PRIV_H
#include <assert.h>
#include <stddef.h>
#include <strings.h>
#include "dev/intel_device_info.h"
#include "util/macros.h"
#include "isl.h"
typedef void (*isl_surf_fill_state_s_func)(
const struct isl_device *dev, void *state,
const struct isl_surf_fill_state_info *restrict info);
typedef void (*isl_buffer_fill_state_s_func)(
const struct isl_device *dev, void *state,
const struct isl_buffer_fill_state_info *restrict info);
typedef void (*isl_emit_depth_stencil_hiz_s_func)(
const struct isl_device *dev, void *state,
const struct isl_depth_stencil_hiz_emit_info *restrict info);
typedef void (*isl_null_fill_state_s_func)(const struct isl_device *dev, void *state,
const struct isl_null_fill_state_info *restrict info);
typedef void (*isl_emit_cpb_control_s_func)(const struct isl_device *dev, void *batch,
const struct isl_cpb_emit_info *restrict info);
#define isl_genX_declare_get_func(func) \
static inline isl_##func##_func \
isl_##func##_get_func(const struct isl_device *dev) { \
switch (ISL_GFX_VERX10(dev)) { \
case 40: \
return isl_gfx4_##func; \
case 45: \
/* G45 surface state is the same as gfx5 */ \
case 50: \
return isl_gfx5_##func; \
case 60: \
return isl_gfx6_##func; \
case 70: \
return isl_gfx7_##func; \
case 75: \
return isl_gfx75_##func; \
case 80: \
return isl_gfx8_##func; \
case 90: \
return isl_gfx9_##func; \
case 110: \
return isl_gfx11_##func; \
case 120: \
return isl_gfx12_##func; \
case 125: \
return isl_gfx125_##func; \
case 200: \
return isl_gfx20_##func; \
case 300: \
return isl_gfx30_##func; \
case 350: \
return isl_gfx35_##func; \
default: \
UNREACHABLE("Unknown hardware generation"); \
} \
}
#define isl_finishme(format, ...) \
do { \
static bool reported = false; \
if (!reported) { \
__isl_finishme(__FILE__, __LINE__, format, ##__VA_ARGS__); \
reported = true; \
} \
} while (0)
void PRINTFLIKE(3, 4) UNUSED
__isl_finishme(const char *file, int line, const char *fmt, ...);
#define MIN(a, b) ((a) < (b) ? (a) : (b))
#define MAX(a, b) ((a) > (b) ? (a) : (b))
typedef void *(*isl_mem_copy_fn)(void *dest, const void *src, size_t n);
static inline bool
isl_is_pow2(uintmax_t n)
{
return !(n & (n - 1));
}
/**
* Alignment must be a power of 2.
*/
static inline uintmax_t
isl_align(uintmax_t n, uintmax_t a)
{
assert(a != 0 && isl_is_pow2(a));
return (n + a - 1) & ~(a - 1);
}
static inline uintmax_t
isl_align_npot(uintmax_t n, uintmax_t a)
{
assert(a > 0);
return ((n + a - 1) / a) * a;
}
static inline uintmax_t
isl_assert_div(uintmax_t n, uintmax_t a)
{
assert(n % a == 0);
return n / a;
}
/**
* Alignment must be a power of 2.
*/
static inline uintmax_t
isl_align_div(uintmax_t n, uintmax_t a)
{
return isl_align(n, a) / a;
}
static inline uintmax_t
isl_align_div_npot(uintmax_t n, uintmax_t a)
{
return isl_align_npot(n, a) / a;
}
/**
* Log base 2, rounding towards zero.
*/
static inline uint32_t
isl_log2u(uint32_t n)
{
assert(n != 0);
return 31 - __builtin_clz(n);
}
static inline uint32_t
isl_round_up_to_power_of_two(uint32_t value)
{
if (value <= 1)
return value;
return 1 << (32 - __builtin_clz(value - 1));
}
static inline uint32_t
isl_minify(uint32_t n, uint32_t levels)
{
if (unlikely(n == 0))
return 0;
else
return MAX(n >> levels, 1);
}
/**
* Returns the greatest common divisor of a and b using Stein's algorithm.
*/
static uint32_t
isl_gcd_u32(uint32_t a, uint32_t b)
{
assert(a > 0 || b > 0);
uint32_t k;
for (k = 0; ((a | b) & 1) == 0; ++k) {
a >>= 1;
b >>= 1;
}
while ((a & 1) == 0)
a >>= 1;
do {
while ((b & 1) == 0)
b >>= 1;
if (a > b) {
uint32_t tmp = a;
a = b;
b = tmp;
}
b = (b - a);
} while (b != 0);
return a << k;
}
static inline uint32_t
isl_lcm_u32(uint32_t a, uint32_t b) {
return a / isl_gcd_u32(a, b) * b;
}
static inline struct isl_extent3d
isl_extent3d_sa_to_el(enum isl_format fmt, struct isl_extent3d extent_sa)
{
const struct isl_format_layout *fmtl = isl_format_get_layout(fmt);
assert(extent_sa.w % fmtl->bw == 0);
assert(extent_sa.h % fmtl->bh == 0);
assert(extent_sa.d % fmtl->bd == 0);
return (struct isl_extent3d) {
.w = extent_sa.w / fmtl->bw,
.h = extent_sa.h / fmtl->bh,
.d = extent_sa.d / fmtl->bd,
};
}
static inline struct isl_extent3d
isl_extent3d_el_to_sa(enum isl_format fmt, struct isl_extent3d extent_el)
{
const struct isl_format_layout *fmtl = isl_format_get_layout(fmt);
return (struct isl_extent3d) {
.w = extent_el.w * fmtl->bw,
.h = extent_el.h * fmtl->bh,
.d = extent_el.d * fmtl->bd,
};
}
bool
_isl_surf_info_supports_ccs(const struct isl_device *dev,
enum isl_format format,
isl_surf_usage_flags_t usage);
void
_isl_memcpy_linear_to_tiled(uint32_t xt1, uint32_t xt2,
uint32_t yt1, uint32_t yt2,
char *dst, const char *src,
uint32_t dst_pitch, int32_t src_pitch,
bool has_swizzling,
enum isl_tiling tiling,
isl_memcpy_type copy_type);
void
_isl_memcpy_tiled_to_linear(uint32_t xt1, uint32_t xt2,
uint32_t yt1, uint32_t yt2,
char *dst, const char *src,
int32_t dst_pitch, uint32_t src_pitch,
bool has_swizzling,
enum isl_tiling tiling,
isl_memcpy_type copy_type);
void
_isl_memcpy_linear_to_tiled_sse41(uint32_t xt1, uint32_t xt2,
uint32_t yt1, uint32_t yt2,
char *dst, const char *src,
uint32_t dst_pitch, int32_t src_pitch,
bool has_swizzling,
enum isl_tiling tiling,
isl_memcpy_type copy_type);
void
_isl_memcpy_tiled_to_linear_sse41(uint32_t xt1, uint32_t xt2,
uint32_t yt1, uint32_t yt2,
char *dst, const char *src,
int32_t dst_pitch, uint32_t src_pitch,
bool has_swizzling,
enum isl_tiling tiling,
isl_memcpy_type copy_type);
void PRINTFLIKE(4, 5)
_isl_notify_failure(const struct isl_surf_init_info *surf_info,
const char *file, int line, const char *fmt, ...);
#define notify_failure(surf_info, ...) \
(_isl_notify_failure(surf_info, __FILE__, __LINE__, __VA_ARGS__), false)
#define print_info(surf_info, ...) \
_isl_notify_failure(surf_info, __FILE__, __LINE__, __VA_ARGS__)
/* This is useful for adding the isl_prefix to genX functions */
#define isl_genX(x) CONCAT2(isl_, genX(x))
#ifdef genX
# include "isl_genX_priv.h"
#else
# define genX(x) gfx4_##x
# include "isl_genX_priv.h"
# undef genX
# define genX(x) gfx5_##x
# include "isl_genX_priv.h"
# undef genX
# define genX(x) gfx6_##x
# include "isl_genX_priv.h"
# undef genX
# define genX(x) gfx7_##x
# include "isl_genX_priv.h"
# undef genX
# define genX(x) gfx75_##x
# include "isl_genX_priv.h"
# undef genX
# define genX(x) gfx8_##x
# include "isl_genX_priv.h"
# undef genX
# define genX(x) gfx9_##x
# include "isl_genX_priv.h"
# undef genX
# define genX(x) gfx11_##x
# include "isl_genX_priv.h"
# undef genX
# define genX(x) gfx12_##x
# include "isl_genX_priv.h"
# undef genX
# define genX(x) gfx125_##x
# include "isl_genX_priv.h"
# undef genX
# define genX(x) gfx20_##x
# include "isl_genX_priv.h"
# undef genX
# define genX(x) gfx30_##x
# include "isl_genX_priv.h"
# undef genX
# define genX(x) gfx35_##x
# include "isl_genX_priv.h"
# undef genX
#endif
#endif /* ISL_PRIV_H */
+244
View File
@@ -0,0 +1,244 @@
/*
* Copyright © 2023 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 <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <unistd.h>
#include <inttypes.h>
#include <assert.h>
#include <getopt.h>
#include "dev/intel_debug.h"
#include "dev/intel_device_info.h"
#include "isl/isl.h"
const struct debug_control usages_control[] = {
{ "rt", ISL_SURF_USAGE_RENDER_TARGET_BIT, },
{ "depth", ISL_SURF_USAGE_DEPTH_BIT, },
{ "stencil", ISL_SURF_USAGE_STENCIL_BIT, },
{ "texture", ISL_SURF_USAGE_TEXTURE_BIT, },
{ "cube", ISL_SURF_USAGE_CUBE_BIT, },
{ "disable-aux", ISL_SURF_USAGE_DISABLE_AUX_BIT, },
{ "display", ISL_SURF_USAGE_DISPLAY_BIT, },
{ "storage", ISL_SURF_USAGE_STORAGE_BIT, },
{ "hiz", ISL_SURF_USAGE_HIZ_BIT, },
{ "mcs", ISL_SURF_USAGE_MCS_BIT, },
{ "ccs", ISL_SURF_USAGE_CCS_BIT, },
{ "vertex", ISL_SURF_USAGE_VERTEX_BUFFER_BIT, },
{ "index", ISL_SURF_USAGE_INDEX_BUFFER_BIT, },
{ "constant", ISL_SURF_USAGE_CONSTANT_BUFFER_BIT, },
{ "cpb", ISL_SURF_USAGE_CPB_BIT, },
};
static void
print_help(const char *name)
{
printf("Usage: %s [OPTION] ...\n", name);
printf("Prints out ISL surface parameters.\n");
printf(" --help Display this help and exit\n");
printf(" -p, --platform NAME Platform to use\n");
printf(" -D, --dimension DIM Dimension of the surface (1, 2, 3)\n");
printf(" -f, --format FORMAT Format of the surface (--list-formats to list them)\n");
printf(" -w, --width WIDTH Width of the surface\n");
printf(" -h, --height HEIGHT Height of the surface\n");
printf(" -d, --depth DEPTH Depth of the surface\n");
printf(" -a, --array ARRAY Array length of the surface\n");
printf(" -s, --samples SAMPLES Sample count of the surface\n");
printf(" -l, --levels LEVELS Miplevel count of the surface\n");
printf(" -P, --pitch PITCH Row pitch of the surface\n");
printf(" -u, --usages USAGE1,USAGE2,... Usage list of the surface\n");
printf(" usages: ");
for (uint32_t i = 0; i < ARRAY_SIZE(usages_control); i++)
printf("%s%s", i == 0 ? "" : ", ", usages_control[i].string);
printf("\n");
printf(" -F, --list-formats List format names\n");
printf("\n");
}
int
main(int argc, char *argv[])
{
int c, i;
bool help = false;
const struct option isl_opts[] = {
{ "help", no_argument, (int *) &help, true },
{ "platform", required_argument, NULL, 'p' },
{ "dimension", required_argument, NULL, 'D' },
{ "format", required_argument, NULL, 'f' },
{ "width", required_argument, NULL, 'w' },
{ "height", required_argument, NULL, 'h' },
{ "depth", required_argument, NULL, 'd' },
{ "array", required_argument, NULL, 'a' },
{ "samples", required_argument, NULL, 's' },
{ "levels", required_argument, NULL, 'l' },
{ "pitch", required_argument, NULL, 'P' },
{ "usages", required_argument, NULL, 'u' },
{ "list-formats", no_argument, NULL, 'F' },
{ NULL, 0, NULL, 0 }
};
const char *platform = "tgl";
enum isl_surf_dim dimension = ISL_SURF_DIM_2D;
enum isl_format format = ISL_FORMAT_R8G8B8A8_UNORM;
uint32_t width = 1;
uint32_t height = 1;
uint32_t depth = 1;
uint32_t array = 1;
uint32_t samples = 1;
uint32_t levels = 1;
uint32_t row_pitch = 0;
isl_surf_usage_flags_t usages = ISL_SURF_USAGE_RENDER_TARGET_BIT | ISL_SURF_USAGE_TEXTURE_BIT;
i = 0;
while ((c = getopt_long(argc, argv, "p:D:f:w:h:d:a:s:l:P:u:F", isl_opts, &i)) != -1) {
switch (c) {
case 'p':
platform = optarg;
break;
case 'D':
dimension = atoi(optarg) - 1;
break;
case 'f':
for (uint32_t i = 0; i < ISL_NUM_FORMATS; i++) {
if (isl_format_get_layout(i)->bpb != 0 &&
strcmp(optarg, isl_format_get_short_name(i)) == 0) {
format = i;
break;
}
}
break;
case 'w':
width = atoi(optarg);
break;
case 'h':
height = atoi(optarg);
break;
case 'd':
depth = atoi(optarg);
break;
case 'a':
array = atoi(optarg);
break;
case 's':
samples = atoi(optarg);
break;
case 'l':
levels = atoi(optarg);
break;
case 'P':
row_pitch = atoi(optarg);
break;
case 'u': {
usages = parse_debug_string(optarg, usages_control);
break;
}
case 'F':
printf("Format list:\n");
for (uint32_t i = 0; i < ISL_NUM_FORMATS; i++) {
if (isl_format_get_layout(i)->bpb != 0)
printf(" %s\n", isl_format_get_short_name(i));
}
exit(EXIT_SUCCESS);
break;
case '?':
print_help(argv[0]);
exit(EXIT_FAILURE);
default:
break;
}
}
process_intel_debug_variable();
int pci_id = intel_device_name_to_pci_device_id(platform);
if (pci_id == -1) {
printf("Unknown platform: %s\n", platform);
exit(EXIT_FAILURE);
}
struct intel_device_info devinfo;
if (!intel_get_device_info_from_pci_id(pci_id, &devinfo)) {
printf("Unable to identify devid=0x%x\n", pci_id);
exit(EXIT_FAILURE);
}
struct isl_device isl_dev;
isl_device_init(&isl_dev, &devinfo);
struct isl_surf surf;
bool ok = isl_surf_init(&isl_dev, &surf,
.format = format,
.dim = dimension,
.width = width,
.height = height,
.depth = depth,
.levels = levels,
.array_len = array,
.samples = samples,
.row_pitch_B = row_pitch,
.usage = usages,
.tiling_flags = ISL_TILING_ANY_MASK);
if (!ok) {
printf("Surface creation failed\n");
exit(EXIT_FAILURE);
}
#define _2d_vals(name) \
name.w, name.h
#define _3d_vals(name) \
name.w, name.h, name.d
#define _4d_vals(name) \
name.w, name.h, name.d, name.a
printf("Surface parameters:\n");
printf(" dim: %ud\n", surf.dim + 1);
printf(" dim_layout: %u\n", surf.dim_layout);
printf(" msaa_layout: %u\n", surf.msaa_layout);
printf(" tiling: %s\n", isl_tiling_to_name(surf.tiling));
printf(" format: %s\n", isl_format_get_short_name(surf.format));
printf(" img_align_el: %ux%ux%u\n", _3d_vals(surf.image_alignment_el));
printf(" logical_level0_px: %ux%ux%ux%u\n", _4d_vals(surf.logical_level0_px));
printf(" phys_level0_sa: %ux%ux%ux%u\n", _4d_vals(surf.phys_level0_sa));
printf(" levels: %u\n", surf.levels);
printf(" samples: %ux\n", surf.samples);
printf(" size_B: %"PRIu64"\n", surf.size_B);
printf(" alignment_B: %u\n", surf.alignment_B);
printf(" row_pitch_B: %u\n", surf.row_pitch_B);
printf(" array_pitch_el_rows: %u\n", surf.array_pitch_el_rows);
struct isl_tile_info tile_info;
isl_surf_get_tile_info(&surf, &tile_info);
printf(" tile_info:\n");
printf(" tiling: %s\n", isl_tiling_to_name(tile_info.tiling));
printf(" format_bpb: %u\n", tile_info.format_bpb);
printf(" logical_extent_el: %ux%ux%ux%u\n", _4d_vals(tile_info.logical_extent_el));
printf(" phys_extent_B: %ux%u = %u\n",
_2d_vals(tile_info.phys_extent_B),
tile_info.phys_extent_B.w * tile_info.phys_extent_B.h);
return EXIT_SUCCESS;
}
+362
View File
@@ -0,0 +1,362 @@
/*
* Copyright 2015 Intel Corporation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
#include "isl_priv.h"
#include "compiler/intel_shader_enums.h"
bool
isl_is_storage_image_format(const struct intel_device_info *devinfo,
enum isl_format format)
{
/* XXX: Maybe we should put this in the CSV? */
switch (format) {
case ISL_FORMAT_R32G32B32A32_UINT:
case ISL_FORMAT_R32G32B32A32_SINT:
case ISL_FORMAT_R32G32B32A32_FLOAT:
case ISL_FORMAT_R32_UINT:
case ISL_FORMAT_R32_SINT:
case ISL_FORMAT_R32_FLOAT:
case ISL_FORMAT_R16G16B16A16_UINT:
case ISL_FORMAT_R16G16B16A16_SINT:
case ISL_FORMAT_R16G16B16A16_FLOAT:
case ISL_FORMAT_R32G32_UINT:
case ISL_FORMAT_R32G32_SINT:
case ISL_FORMAT_R32G32_FLOAT:
case ISL_FORMAT_R8G8B8A8_UINT:
case ISL_FORMAT_R8G8B8A8_SINT:
case ISL_FORMAT_R16G16_UINT:
case ISL_FORMAT_R16G16_SINT:
case ISL_FORMAT_R16G16_FLOAT:
case ISL_FORMAT_R8G8_UINT:
case ISL_FORMAT_R8G8_SINT:
case ISL_FORMAT_R16_UINT:
case ISL_FORMAT_R16_FLOAT:
case ISL_FORMAT_R16_SINT:
case ISL_FORMAT_R8_UINT:
case ISL_FORMAT_R8_SINT:
case ISL_FORMAT_R10G10B10A2_UINT:
case ISL_FORMAT_R10G10B10A2_UNORM:
case ISL_FORMAT_R11G11B10_FLOAT:
case ISL_FORMAT_R16G16B16A16_UNORM:
case ISL_FORMAT_R16G16B16A16_SNORM:
case ISL_FORMAT_R8G8B8A8_UNORM:
case ISL_FORMAT_R8G8B8A8_SNORM:
case ISL_FORMAT_R16G16_UNORM:
case ISL_FORMAT_R16G16_SNORM:
case ISL_FORMAT_R8G8_UNORM:
case ISL_FORMAT_R8G8_SNORM:
case ISL_FORMAT_R16_UNORM:
case ISL_FORMAT_R16_SNORM:
case ISL_FORMAT_R8_UNORM:
case ISL_FORMAT_R8_SNORM:
return true;
default:
return false;
}
}
enum isl_format
isl_lower_storage_image_format(const struct intel_device_info *devinfo,
enum isl_format format)
{
switch (format) {
/* These are never lowered. Up to BDW we'll have to fall back to untyped
* surface access for 128bpp formats.
*/
case ISL_FORMAT_R32G32B32A32_UINT:
case ISL_FORMAT_R32G32B32A32_SINT:
case ISL_FORMAT_R32G32B32A32_FLOAT:
case ISL_FORMAT_R32_UINT:
case ISL_FORMAT_R32_SINT:
return format;
/* The Skylake PRM's "Surface Formats" section says:
*
* "The surface format for the typed atomic integer operations must
* be R32_UINT or R32_SINT."
*
* But checking the BSpec 1706, you find a different restriction. There the
* wording is :
*
* "The surface format must be one of R32_UINT, R32_SINT or R32_FLOAT"
*
* The confusion is probably related to atomic integer messages. For
* example an IADD instruction would require a R32_UINT/R32_SINT surface.
* But a CMPXCHG instruction does not really care about the type, it just
* does bit to bit comparison and swap.
*
* The confusion seems to have propagated to the simulation environment.
* Gfx12 has the same restrictions as Gfx11 regarding doing a CMPXCHG on a
* R32_FLOAT surface, but the Gfx11 environment will report an error while
* Gfx12 passes fine. More importantly HW doesn't seem to mind.
*/
case ISL_FORMAT_R32_FLOAT:
return format;
/* From HSW to BDW the only 64bpp format supported for typed access is
* RGBA_UINT16. IVB falls back to untyped.
*/
case ISL_FORMAT_R16G16B16A16_UINT:
case ISL_FORMAT_R16G16B16A16_SINT:
case ISL_FORMAT_R16G16B16A16_FLOAT:
case ISL_FORMAT_R32G32_UINT:
case ISL_FORMAT_R32G32_SINT:
case ISL_FORMAT_R32G32_FLOAT:
return (devinfo->ver >= 9 ? format :
devinfo->verx10 >= 75 ?
ISL_FORMAT_R16G16B16A16_UINT :
ISL_FORMAT_R32G32_UINT);
/* Up to BDW no SINT or FLOAT formats of less than 32 bits per component
* are supported. IVB doesn't support formats with more than one component
* for typed access. For 8 and 16 bpp formats IVB relies on the
* undocumented behavior that typed reads from R_UINT8 and R_UINT16
* surfaces actually do a 32-bit misaligned read. The alternative would be
* to use two surface state entries with different formats for each image,
* one for reading (using R_UINT32) and another one for writing (using
* R_UINT8 or R_UINT16), but that would complicate the shaders we generate
* even more.
*/
case ISL_FORMAT_R8G8B8A8_UINT:
case ISL_FORMAT_R8G8B8A8_SINT:
return (devinfo->ver >= 9 ? format :
devinfo->verx10 >= 75 ?
ISL_FORMAT_R8G8B8A8_UINT : ISL_FORMAT_R32_UINT);
case ISL_FORMAT_R16G16_UINT:
case ISL_FORMAT_R16G16_SINT:
case ISL_FORMAT_R16G16_FLOAT:
return (devinfo->ver >= 9 ? format :
devinfo->verx10 >= 75 ?
ISL_FORMAT_R16G16_UINT : ISL_FORMAT_R32_UINT);
case ISL_FORMAT_R8G8_UINT:
case ISL_FORMAT_R8G8_SINT:
return (devinfo->ver >= 9 ? format :
devinfo->verx10 >= 75 ?
ISL_FORMAT_R8G8_UINT : ISL_FORMAT_R16_UINT);
case ISL_FORMAT_R16_UINT:
case ISL_FORMAT_R16_FLOAT:
case ISL_FORMAT_R16_SINT:
return (devinfo->ver >= 9 ? format : ISL_FORMAT_R16_UINT);
case ISL_FORMAT_R8_UINT:
case ISL_FORMAT_R8_SINT:
return (devinfo->ver >= 9 ? format : ISL_FORMAT_R8_UINT);
/* Here the PRMs are a bit out of date. But according to BSpec 47635
* (Gfx12.5), the 2/10/10/10 and the 11/11/10 packed formats are supported
* by the hardware.
*/
case ISL_FORMAT_R10G10B10A2_UINT:
case ISL_FORMAT_R10G10B10A2_UNORM:
case ISL_FORMAT_R11G11B10_FLOAT:
return devinfo->verx10 >= 125 ? format : ISL_FORMAT_R32_UINT;
/* No normalized fixed-point formats are supported by the hardware until Gfx11. */
case ISL_FORMAT_R16G16B16A16_UNORM:
case ISL_FORMAT_R16G16B16A16_SNORM:
if (devinfo->ver >= 11)
return format;
if (devinfo->ver >= 9)
return ISL_FORMAT_R32G32_UINT;
if (devinfo->verx10 >= 75)
return ISL_FORMAT_R16G16B16A16_UINT;
return ISL_FORMAT_R32G32_UINT;
case ISL_FORMAT_R8G8B8A8_UNORM:
case ISL_FORMAT_R8G8B8A8_SNORM:
if (devinfo->ver >= 11)
return format;
if (devinfo->ver >= 9)
return ISL_FORMAT_R32_UINT;
if (devinfo->verx10 >= 75)
return ISL_FORMAT_R8G8B8A8_UINT;
return ISL_FORMAT_R32_UINT;
case ISL_FORMAT_R16G16_UNORM:
case ISL_FORMAT_R16G16_SNORM:
if (devinfo->ver >= 11)
return format;
if (devinfo->ver >= 9)
return ISL_FORMAT_R32_UINT;
if (devinfo->verx10 >= 75)
return ISL_FORMAT_R16G16_UINT;
return ISL_FORMAT_R32_UINT;
case ISL_FORMAT_R8G8_UNORM:
case ISL_FORMAT_R8G8_SNORM:
if (devinfo->ver >= 11)
return format;
if (devinfo->ver >= 9)
return ISL_FORMAT_R16_UINT;
if (devinfo->verx10 >= 75)
return ISL_FORMAT_R8G8_UINT;
return ISL_FORMAT_R16_UINT;
case ISL_FORMAT_R16_UNORM:
case ISL_FORMAT_R16_SNORM:
return (devinfo->ver >= 11 ? format : ISL_FORMAT_R16_UINT);
case ISL_FORMAT_R8_UNORM:
case ISL_FORMAT_R8_SNORM:
return (devinfo->ver >= 11 ? format : ISL_FORMAT_R8_UINT);
case ISL_FORMAT_R64_PASSTHRU:
return ISL_FORMAT_R32G32_UINT;
default:
UNREACHABLE("Unknown image format");
}
}
bool
isl_has_matching_typed_storage_image_format(const struct intel_device_info *devinfo,
enum isl_format fmt)
{
if (devinfo->ver >= 9) {
return true;
} else if (devinfo->verx10 >= 75) {
return isl_format_get_layout(fmt)->bpb <= 64;
} else {
return isl_format_get_layout(fmt)->bpb <= 32;
}
}
static const struct isl_image_param image_param_defaults = {
/* Set the swizzling shifts to all-ones to effectively disable
* swizzling -- See emit_address_calculation() in
* brw_fs_surface_builder.cpp for a more detailed explanation of
* these parameters.
*/
.swizzling = { 0xff, 0xff },
};
void
isl_surf_fill_image_param(const struct isl_device *dev,
struct isl_image_param *param,
const struct isl_surf *surf,
const struct isl_view *view)
{
*param = image_param_defaults;
if (surf->dim != ISL_SURF_DIM_3D) {
assert(view->base_array_layer + view->array_len <=
surf->logical_level0_px.array_len);
}
param->size[0] = isl_minify(surf->logical_level0_px.w, view->base_level);
param->size[1] = surf->dim == ISL_SURF_DIM_1D ?
view->array_len :
isl_minify(surf->logical_level0_px.h, view->base_level);
param->size[2] = surf->dim == ISL_SURF_DIM_2D ?
view->array_len :
isl_minify(surf->logical_level0_px.d, view->base_level);
uint32_t tile_z_el, phys_array_layer;
isl_surf_get_image_offset_el(surf, view->base_level,
surf->dim == ISL_SURF_DIM_3D ?
0 : view->base_array_layer,
surf->dim == ISL_SURF_DIM_3D ?
view->base_array_layer : 0,
&param->offset[0], &param->offset[1],
&tile_z_el, &phys_array_layer);
assert(tile_z_el == 0);
assert(phys_array_layer == 0);
const int cpp = isl_format_get_layout(surf->format)->bpb / 8;
param->stride[0] = cpp;
param->stride[1] = surf->row_pitch_B / cpp;
const struct isl_extent3d image_align_sa =
isl_surf_get_image_alignment_sa(surf);
if (ISL_GFX_VER(dev) < 9 && surf->dim == ISL_SURF_DIM_3D) {
param->stride[2] = isl_align_npot(param->size[0], image_align_sa.w);
param->stride[3] = isl_align_npot(param->size[1], image_align_sa.h);
} else {
param->stride[2] = 0;
param->stride[3] = isl_surf_get_array_pitch_el_rows(surf);
}
switch (surf->tiling) {
case ISL_TILING_LINEAR:
/* image_param_defaults is good enough */
break;
case ISL_TILING_X:
/* An X tile is a rectangular block of 512x8 bytes. */
param->tiling[0] = isl_log2u(512 / cpp);
param->tiling[1] = isl_log2u(8);
if (dev->has_bit6_swizzling) {
/* Right shifts required to swizzle bits 9 and 10 of the memory
* address with bit 6.
*/
param->swizzling[0] = 3;
param->swizzling[1] = 4;
}
break;
case ISL_TILING_Y0:
/* The layout of a Y-tiled surface in memory isn't really fundamentally
* different to the layout of an X-tiled surface, we simply pretend that
* the surface is broken up in a number of smaller 16Bx32 tiles, each
* one arranged in X-major order just like is the case for X-tiling.
*/
param->tiling[0] = isl_log2u(16 / cpp);
param->tiling[1] = isl_log2u(32);
if (dev->has_bit6_swizzling) {
/* Right shift required to swizzle bit 9 of the memory address with
* bit 6.
*/
param->swizzling[0] = 3;
param->swizzling[1] = 0xff;
}
break;
default:
UNREACHABLE("Unhandled storage image tiling");
}
/* 3D textures are arranged in 2D in memory with 2^lod slices per row. The
* address calculation algorithm (emit_address_calculation() in
* brw_fs_surface_builder.cpp) handles this as a sort of tiling with
* modulus equal to the LOD.
*/
param->tiling[2] = (ISL_GFX_VER(dev) < 9 && surf->dim == ISL_SURF_DIM_3D ?
view->base_level : 0);
}
void
isl_buffer_fill_image_param(const struct isl_device *dev,
struct isl_image_param *param,
enum isl_format format,
uint64_t size)
{
*param = image_param_defaults;
param->stride[0] = isl_format_get_layout(format)->bpb / 8;
param->size[0] = size / param->stride[0];
}
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
+59
View File
@@ -0,0 +1,59 @@
/*
* Mesa 3-D graphics library
*
* Copyright 2012 Intel Corporation
* Copyright 2013 Google
*
* 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 VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* Authors:
* Chad Versace <[email protected]>
* Frank Henigman <[email protected]>
*/
#include "isl_tiled_memcpy.c"
void
_isl_memcpy_linear_to_tiled(uint32_t xt1, uint32_t xt2,
uint32_t yt1, uint32_t yt2,
char *dst, const char *src,
uint32_t dst_pitch, int32_t src_pitch,
bool has_swizzling,
enum isl_tiling tiling,
isl_memcpy_type copy_type)
{
linear_to_tiled(xt1, xt2, yt1, yt2, dst, src, dst_pitch, src_pitch,
has_swizzling, tiling, copy_type);
}
void
_isl_memcpy_tiled_to_linear(uint32_t xt1, uint32_t xt2,
uint32_t yt1, uint32_t yt2,
char *dst, const char *src,
int32_t dst_pitch, uint32_t src_pitch,
bool has_swizzling,
enum isl_tiling tiling,
isl_memcpy_type copy_type)
{
tiled_to_linear(xt1, xt2, yt1, yt2, dst, src, dst_pitch, src_pitch,
has_swizzling, tiling, copy_type);
}
+60
View File
@@ -0,0 +1,60 @@
/*
* Mesa 3-D graphics library
*
* Copyright 2012 Intel Corporation
* Copyright 2013 Google
*
* 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 VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* Authors:
* Chad Versace <[email protected]>
* Frank Henigman <[email protected]>
*/
#define INLINE_SSE41
#include "isl_tiled_memcpy.c"
void
_isl_memcpy_linear_to_tiled_sse41(uint32_t xt1, uint32_t xt2,
uint32_t yt1, uint32_t yt2,
char *dst, const char *src,
uint32_t dst_pitch, int32_t src_pitch,
bool has_swizzling,
enum isl_tiling tiling,
isl_memcpy_type copy_type)
{
linear_to_tiled(xt1, xt2, yt1, yt2, dst, src, dst_pitch, src_pitch,
has_swizzling, tiling, copy_type);
}
void
_isl_memcpy_tiled_to_linear_sse41(uint32_t xt1, uint32_t xt2,
uint32_t yt1, uint32_t yt2,
char *dst, const char *src,
int32_t dst_pitch, uint32_t src_pitch,
bool has_swizzling,
enum isl_tiling tiling,
isl_memcpy_type copy_type)
{
tiled_to_linear(xt1, xt2, yt1, yt2, dst, src, dst_pitch, src_pitch,
has_swizzling, tiling, copy_type);
}
+215
View File
@@ -0,0 +1,215 @@
# Copyright © 2017 Intel Corporation
# SPDX-License-Identifier: MIT
isl_per_hw_ver_files = files(
'isl_emit_cpb.c',
'isl_emit_depth_stencil.c',
'isl_surface_state.c',
'isl_genX_helpers.h',
)
isl_gfx4_files = files(
'isl_gfx4.c',
'isl_gfx4.h',
)
isl_gfx6_files = files(
'isl_gfx6.c',
'isl_gfx6.h',
)
isl_gfx7_files = files(
'isl_gfx7.c',
'isl_gfx7.h',
)
isl_gfx8_files = files(
'isl_gfx8.c',
'isl_gfx8.h',
)
isl_gfx9_files = files(
'isl_gfx9.c',
'isl_gfx9.h',
)
isl_gfx12_files = files(
'isl_gfx12.c',
'isl_gfx12.h',
)
isl_gfx125_files = files(
'isl_gfx12.c',
'isl_gfx12.h',
)
isl_gfx20_files = files(
'isl_gfx20.c',
'isl_gfx20.h',
)
isl_per_hw_ver_libs = []
foreach g : [['40', isl_gfx4_files], ['50', []], ['60', isl_gfx6_files],
['70', isl_gfx7_files], ['75', []], ['80', isl_gfx8_files],
['90', isl_gfx9_files], ['110', []], ['120', isl_gfx12_files],
['125', isl_gfx12_files], ['200', isl_gfx20_files],
['300', isl_gfx20_files], ['350', isl_gfx20_files]]
_gfx_ver = g[0]
isl_per_hw_ver_libs += static_library(
'isl_per_hw_ver@0@'.format(_gfx_ver),
[g[1], isl_per_hw_ver_files],
include_directories : [inc_include, inc_src, inc_intel],
dependencies : [idep_mesautil, idep_intel_dev, idep_genxml],
c_args : [
no_override_init_args,
'-DGFX_VERx10=@0@'.format(_gfx_ver)
],
gnu_symbol_visibility : 'hidden',
)
endforeach
isl_format_layout_c = custom_target(
'isl_format_layout.c',
input : ['gen_format_layout.py', 'isl_format_layout.csv'],
output : 'isl_format_layout.c',
command : [prog_python, '@INPUT0@', '--csv', '@INPUT1@', '--out', '@OUTPUT@'],
)
files_isl_tiled_memcpy = files(
'isl_tiled_memcpy_normal.c'
)
files_isl_tiled_memcpy_sse41 = files(
'isl_tiled_memcpy_sse41.c',
)
isl_tiled_memcpy = static_library(
'isl_tiled_memcpy',
[files_isl_tiled_memcpy],
include_directories : [
inc_include, inc_src, inc_intel,
],
dependencies : [idep_mesautil, idep_intel_dev],
c_args : [no_override_init_args, soong_compat_c_args, sse2_arg],
gnu_symbol_visibility : 'hidden',
extra_files : ['isl_tiled_memcpy.c']
)
if with_sse41
isl_tiled_memcpy_sse41 = static_library(
'isl_tiled_memcpy_sse41',
[files_isl_tiled_memcpy_sse41],
include_directories : [
inc_include, inc_src, inc_intel,
],
dependencies : [idep_mesautil, idep_intel_dev],
link_args : ['-Wl,--exclude-libs=ALL'],
c_args : [no_override_init_args, sse2_arg, sse41_args],
gnu_symbol_visibility : 'hidden',
extra_files : ['isl_tiled_memcpy.c']
)
else
isl_tiled_memcpy_sse41 = []
endif
libisl_files = files(
'isl.c',
'isl.h',
'isl_aux_info.c',
'isl_drm.c',
'isl_genX_priv.h',
'isl_format.c',
'isl_priv.h',
'isl_storage_image.c',
)
libisl = static_library(
'isl',
[libisl_files, isl_format_layout_c, genX_bits_h],
include_directories : [inc_include, inc_src, inc_intel],
link_with : [isl_per_hw_ver_libs, isl_tiled_memcpy, isl_tiled_memcpy_sse41],
dependencies : [idep_mesautil, idep_intel_dev],
c_args : [no_override_init_args],
gnu_symbol_visibility : 'hidden',
)
if with_intel_tools
isl_query = executable(
'isl_query',
files('isl_query.c'),
dependencies : [idep_mesautil, dep_m, idep_intel_dev],
include_directories : [inc_include, inc_src, inc_intel],
link_with : [libisl],
c_args : [no_override_init_args],
gnu_symbol_visibility : 'hidden',
install : false
)
endif
if with_tests
test(
'isl_surf_get_image_offset',
executable(
'isl_surf_get_image_offset_test',
'tests/isl_surf_get_image_offset_test.c',
dependencies : [dep_m, idep_mesautil, idep_intel_dev],
link_with: libisl,
include_directories : [inc_include, inc_src, inc_intel],
),
suite : ['intel'],
)
test(
'isl_aux_info',
executable(
'isl_aux_info_test',
[
'tests/isl_aux_info_test.cpp',
'isl_aux_info.c',
],
dependencies : [dep_m, idep_gtest, idep_mesautil, idep_intel_dev],
include_directories : [inc_include, inc_src, inc_intel],
c_args : '-DIN_UNIT_TEST',
cpp_args : '-DIN_UNIT_TEST',
),
suite : ['intel'],
protocol : 'gtest',
)
test(
'isl_tile_std_y',
executable(
'isl_tile_std_y_test',
'tests/isl_tile_std_y_test.c',
dependencies : [dep_m, idep_mesautil],
include_directories : [inc_include, inc_src, inc_intel],
link_with : [libisl, libintel_dev],
),
suite : ['intel'],
)
test(
'isl_tilememcpy',
executable(
'isl_tilememcpy_test',
[
'tests/isl_tilememcpy_tiled_unittest.cpp',
],
dependencies : [dep_m, idep_gtest, idep_mesautil, idep_intel_dev],
include_directories : [inc_include, inc_src, inc_intel],
link_with : libisl,
c_args : '-DIN_UNIT_TEST',
cpp_args : ['-std=c++17', '-DIN_UNIT_TEST'],
),
suite : ['intel'],
)
test(
'isl_surf_get_image_range_B_tile',
executable(
'isl_surf_get_image_range_B_tile_test',
'tests/isl_surf_get_image_range_B_tile_test.c',
dependencies : [dep_m, idep_mesautil, idep_intel_dev],
link_with: libisl,
include_directories : [inc_include, inc_src, inc_intel],
),
suite : ['intel'],
)
endif
+495
View File
@@ -0,0 +1,495 @@
/*
* Copyright 2019 Intel Corporation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (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 "gtest/gtest.h"
#include "isl/isl.h"
void
PrintTo(const enum isl_aux_op &op, ::std::ostream* os) {
*os << (const char *[]) {
[ISL_AUX_OP_ASSERT ] = "ISL_AUX_OP_ASSERT",
[ISL_AUX_OP_NONE ] = "ISL_AUX_OP_NONE",
[ISL_AUX_OP_FAST_CLEAR ] = "ISL_AUX_OP_FAST_CLEAR",
[ISL_AUX_OP_FULL_RESOLVE ] = "ISL_AUX_OP_FULL_RESOLVE",
[ISL_AUX_OP_PARTIAL_RESOLVE] = "ISL_AUX_OP_PARTIAL_RESOLVE",
[ISL_AUX_OP_AMBIGUATE ] = "ISL_AUX_OP_AMBIGUATE",
}[op];
}
#define E(state, usage, fc, op) \
EXPECT_EQ(ISL_AUX_OP_ ## op, \
isl_aux_prepare_access(ISL_AUX_STATE_ ## state, \
ISL_AUX_USAGE_ ## usage, fc))
TEST(PrepareAccess, CompressedFalseFastClearFalsePartialResolveFalse) {
E(CLEAR, NONE, false, FULL_RESOLVE);
E(CLEAR, NONE, true, ASSERT);
E(PARTIAL_CLEAR, NONE, false, FULL_RESOLVE);
E(PARTIAL_CLEAR, NONE, true, ASSERT);
E(COMPRESSED_CLEAR, NONE, false, FULL_RESOLVE);
E(COMPRESSED_CLEAR, NONE, true, ASSERT);
E(COMPRESSED_NO_CLEAR, NONE, false, FULL_RESOLVE);
E(COMPRESSED_NO_CLEAR, NONE, true, ASSERT);
E(COMPRESSED_HIER_DEPTH, NONE, false, FULL_RESOLVE);
E(COMPRESSED_HIER_DEPTH, NONE, true, ASSERT);
E(RESOLVED, NONE, false, NONE);
E(RESOLVED, NONE, true, ASSERT);
E(PASS_THROUGH, NONE, false, NONE);
E(PASS_THROUGH, NONE, true, ASSERT);
E(AUX_INVALID, NONE, false, NONE);
E(AUX_INVALID, NONE, true, ASSERT);
}
TEST(PrepareAccess, CompressedFalseFastClearTruePartialResolveFalse) {
E(CLEAR, CCS_D, false, FULL_RESOLVE);
E(CLEAR, CCS_D, true, NONE);
E(PARTIAL_CLEAR, CCS_D, false, FULL_RESOLVE);
E(PARTIAL_CLEAR, CCS_D, true, NONE);
E(COMPRESSED_CLEAR, CCS_D, false, FULL_RESOLVE);
E(COMPRESSED_CLEAR, CCS_D, true, FULL_RESOLVE);
E(COMPRESSED_NO_CLEAR, CCS_D, false, FULL_RESOLVE);
E(COMPRESSED_NO_CLEAR, CCS_D, true, FULL_RESOLVE);
E(RESOLVED, CCS_D, false, NONE);
E(RESOLVED, CCS_D, true, NONE);
E(PASS_THROUGH, CCS_D, false, NONE);
E(PASS_THROUGH, CCS_D, true, NONE);
E(AUX_INVALID, CCS_D, false, AMBIGUATE);
E(AUX_INVALID, CCS_D, true, AMBIGUATE);
}
TEST(PrepareAccess, CompressedTrueFastClearFalsePartialResolveFalse) {
E(CLEAR, MC, false, ASSERT);
E(CLEAR, MC, true, ASSERT);
E(PARTIAL_CLEAR, MC, false, ASSERT);
E(PARTIAL_CLEAR, MC, true, ASSERT);
E(COMPRESSED_CLEAR, MC, false, ASSERT);
E(COMPRESSED_CLEAR, MC, true, ASSERT);
E(COMPRESSED_NO_CLEAR, MC, false, NONE);
E(COMPRESSED_NO_CLEAR, MC, true, ASSERT);
E(RESOLVED, MC, false, NONE);
E(RESOLVED, MC, true, ASSERT);
E(PASS_THROUGH, MC, false, NONE);
E(PASS_THROUGH, MC, true, ASSERT);
E(AUX_INVALID, MC, false, AMBIGUATE);
E(AUX_INVALID, MC, true, ASSERT);
}
TEST(PrepareAccess, CompressedTrueFastClearTruePartialResolveFalse) {
E(CLEAR, HIZ, false, FULL_RESOLVE);
E(CLEAR, HIZ, true, NONE);
E(PARTIAL_CLEAR, HIZ, false, FULL_RESOLVE);
E(PARTIAL_CLEAR, HIZ, true, NONE);
E(COMPRESSED_CLEAR, HIZ, false, FULL_RESOLVE);
E(COMPRESSED_CLEAR, HIZ, true, NONE);
E(COMPRESSED_NO_CLEAR, HIZ, false, NONE);
E(COMPRESSED_NO_CLEAR, HIZ, true, NONE);
E(COMPRESSED_HIER_DEPTH, HIZ, false, FULL_RESOLVE);
E(COMPRESSED_HIER_DEPTH, HIZ, true, NONE);
E(COMPRESSED_HIER_DEPTH, HIZ_CCS, false, FULL_RESOLVE);
E(COMPRESSED_HIER_DEPTH, HIZ_CCS, true, NONE);
E(COMPRESSED_HIER_DEPTH, HIZ_CCS_WT, false, FULL_RESOLVE);
E(COMPRESSED_HIER_DEPTH, HIZ_CCS_WT, true, PARTIAL_RESOLVE);
E(RESOLVED, HIZ, false, NONE);
E(RESOLVED, HIZ, true, NONE);
E(PASS_THROUGH, HIZ, false, NONE);
E(PASS_THROUGH, HIZ, true, NONE);
E(AUX_INVALID, HIZ, false, AMBIGUATE);
E(AUX_INVALID, HIZ, true, AMBIGUATE);
}
TEST(PrepareAccess, CompressedTrueFastClearTruePartialResolveTrue) {
E(CLEAR, MCS, false, PARTIAL_RESOLVE);
E(CLEAR, MCS, true, NONE);
E(PARTIAL_CLEAR, MCS, false, PARTIAL_RESOLVE);
E(PARTIAL_CLEAR, MCS, true, NONE);
E(COMPRESSED_CLEAR, MCS, false, PARTIAL_RESOLVE);
E(COMPRESSED_CLEAR, MCS, true, NONE);
E(COMPRESSED_NO_CLEAR, MCS, false, NONE);
E(COMPRESSED_NO_CLEAR, MCS, true, NONE);
E(COMPRESSED_HIER_DEPTH, MCS, false, ASSERT);
E(COMPRESSED_HIER_DEPTH, MCS, true, ASSERT);
E(RESOLVED, MCS, false, NONE);
E(RESOLVED, MCS, true, NONE);
E(PASS_THROUGH, MCS, false, NONE);
E(PASS_THROUGH, MCS, true, NONE);
E(AUX_INVALID, MCS, false, AMBIGUATE);
E(AUX_INVALID, MCS, true, AMBIGUATE);
}
void
PrintTo(const enum isl_aux_state &state, ::std::ostream* os) {
*os << (const char *[]) {
[ISL_AUX_STATE_ASSERT ] = "ISL_AUX_STATE_ASSERT",
[ISL_AUX_STATE_CLEAR ] = "ISL_AUX_STATE_CLEAR",
[ISL_AUX_STATE_PARTIAL_CLEAR ] = "ISL_AUX_STATE_PARTIAL_CLEAR",
[ISL_AUX_STATE_COMPRESSED_CLEAR ] = "ISL_AUX_STATE_COMPRESSED_CLEAR",
[ISL_AUX_STATE_COMPRESSED_NO_CLEAR] = "ISL_AUX_STATE_COMPRESSED_NO_CLEAR",
[ISL_AUX_STATE_COMPRESSED_HIER_DEPTH] = "ISL_AUX_STATE_COMPRESSED_HIER_DEPTH",
[ISL_AUX_STATE_RESOLVED ] = "ISL_AUX_STATE_RESOLVED",
[ISL_AUX_STATE_PASS_THROUGH ] = "ISL_AUX_STATE_PASS_THROUGH",
[ISL_AUX_STATE_AUX_INVALID ] = "ISL_AUX_STATE_AUX_INVALID"
}[state];
}
#undef E
#define E(state1, usage, op, state2) \
EXPECT_EQ(ISL_AUX_STATE_ ## state2, \
isl_aux_state_transition_aux_op(ISL_AUX_STATE_ ## state1, \
ISL_AUX_USAGE_ ## usage, \
ISL_AUX_OP_ ## op))
/* The usages used in each test of this suite represent all combinations of
* ::fast_clear and ::full_resolves_ambiguate.
*/
TEST(StateTransitionAuxOp, None) {
E(CLEAR, NONE, NONE, ASSERT);
E(PARTIAL_CLEAR, NONE, NONE, ASSERT);
E(COMPRESSED_CLEAR, NONE, NONE, ASSERT);
E(COMPRESSED_NO_CLEAR, NONE, NONE, ASSERT);
E(COMPRESSED_HIER_DEPTH, NONE, NONE, ASSERT);
E(RESOLVED, NONE, NONE, RESOLVED);
E(PASS_THROUGH, NONE, NONE, PASS_THROUGH);
E(AUX_INVALID, NONE, NONE, AUX_INVALID);
E(CLEAR, MC, NONE, ASSERT);
E(PARTIAL_CLEAR, MC, NONE, ASSERT);
E(COMPRESSED_CLEAR, MC, NONE, ASSERT);
E(COMPRESSED_NO_CLEAR, MC, NONE, COMPRESSED_NO_CLEAR);
E(COMPRESSED_HIER_DEPTH, MC, NONE, ASSERT);
E(RESOLVED, MC, NONE, RESOLVED);
E(PASS_THROUGH, MC, NONE, PASS_THROUGH);
E(AUX_INVALID, MC, NONE, AUX_INVALID);
E(CLEAR, HIZ, NONE, CLEAR);
E(PARTIAL_CLEAR, HIZ, NONE, PARTIAL_CLEAR);
E(COMPRESSED_CLEAR, HIZ, NONE, COMPRESSED_CLEAR);
E(COMPRESSED_NO_CLEAR, HIZ, NONE, COMPRESSED_NO_CLEAR);
E(COMPRESSED_HIER_DEPTH, HIZ, NONE, COMPRESSED_HIER_DEPTH);
E(RESOLVED, HIZ, NONE, RESOLVED);
E(PASS_THROUGH, HIZ, NONE, PASS_THROUGH);
E(AUX_INVALID, HIZ, NONE, AUX_INVALID);
E(CLEAR, CCS_E, NONE, CLEAR);
E(PARTIAL_CLEAR, CCS_E, NONE, PARTIAL_CLEAR);
E(COMPRESSED_CLEAR, CCS_E, NONE, COMPRESSED_CLEAR);
E(COMPRESSED_NO_CLEAR, CCS_E, NONE, COMPRESSED_NO_CLEAR);
E(COMPRESSED_HIER_DEPTH, CCS_E, NONE, ASSERT);
E(RESOLVED, CCS_E, NONE, RESOLVED);
E(PASS_THROUGH, CCS_E, NONE, PASS_THROUGH);
E(AUX_INVALID, CCS_E, NONE, AUX_INVALID);
}
TEST(StateTransitionAuxOp, FastClear) {
E(CLEAR, NONE, FAST_CLEAR, ASSERT);
E(PARTIAL_CLEAR, NONE, FAST_CLEAR, ASSERT);
E(COMPRESSED_CLEAR, NONE, FAST_CLEAR, ASSERT);
E(COMPRESSED_NO_CLEAR, NONE, FAST_CLEAR, ASSERT);
E(COMPRESSED_HIER_DEPTH, NONE, FAST_CLEAR, ASSERT);
E(RESOLVED, NONE, FAST_CLEAR, ASSERT);
E(PASS_THROUGH, NONE, FAST_CLEAR, ASSERT);
E(AUX_INVALID, NONE, FAST_CLEAR, ASSERT);
E(CLEAR, MC, FAST_CLEAR, ASSERT);
E(PARTIAL_CLEAR, MC, FAST_CLEAR, ASSERT);
E(COMPRESSED_CLEAR, MC, FAST_CLEAR, ASSERT);
E(COMPRESSED_NO_CLEAR, MC, FAST_CLEAR, ASSERT);
E(COMPRESSED_HIER_DEPTH, MC, FAST_CLEAR, ASSERT);
E(RESOLVED, MC, FAST_CLEAR, ASSERT);
E(PASS_THROUGH, MC, FAST_CLEAR, ASSERT);
E(AUX_INVALID, MC, FAST_CLEAR, ASSERT);
E(CLEAR, HIZ, FAST_CLEAR, CLEAR);
E(PARTIAL_CLEAR, HIZ, FAST_CLEAR, CLEAR);
E(COMPRESSED_CLEAR, HIZ, FAST_CLEAR, CLEAR);
E(COMPRESSED_NO_CLEAR, HIZ, FAST_CLEAR, CLEAR);
E(COMPRESSED_HIER_DEPTH, HIZ, FAST_CLEAR, CLEAR);
E(RESOLVED, HIZ, FAST_CLEAR, CLEAR);
E(PASS_THROUGH, HIZ, FAST_CLEAR, CLEAR);
E(AUX_INVALID, HIZ, FAST_CLEAR, CLEAR);
E(CLEAR, CCS_E, FAST_CLEAR, CLEAR);
E(PARTIAL_CLEAR, CCS_E, FAST_CLEAR, CLEAR);
E(COMPRESSED_CLEAR, CCS_E, FAST_CLEAR, CLEAR);
E(COMPRESSED_NO_CLEAR, CCS_E, FAST_CLEAR, CLEAR);
E(COMPRESSED_HIER_DEPTH, CCS_E, FAST_CLEAR, ASSERT);
E(RESOLVED, CCS_E, FAST_CLEAR, CLEAR);
E(PASS_THROUGH, CCS_E, FAST_CLEAR, CLEAR);
E(AUX_INVALID, CCS_E, FAST_CLEAR, CLEAR);
}
TEST(StateTransitionAuxOp, PartialResolve) {
E(CLEAR, NONE, PARTIAL_RESOLVE, ASSERT);
E(PARTIAL_CLEAR, NONE, PARTIAL_RESOLVE, ASSERT);
E(COMPRESSED_CLEAR, NONE, PARTIAL_RESOLVE, ASSERT);
E(COMPRESSED_NO_CLEAR, NONE, PARTIAL_RESOLVE, ASSERT);
E(COMPRESSED_HIER_DEPTH, NONE, PARTIAL_RESOLVE, ASSERT);
E(RESOLVED, NONE, PARTIAL_RESOLVE, ASSERT);
E(PASS_THROUGH, NONE, PARTIAL_RESOLVE, ASSERT);
E(AUX_INVALID, NONE, PARTIAL_RESOLVE, ASSERT);
E(CLEAR, MC, PARTIAL_RESOLVE, ASSERT);
E(PARTIAL_CLEAR, MC, PARTIAL_RESOLVE, ASSERT);
E(COMPRESSED_CLEAR, MC, PARTIAL_RESOLVE, ASSERT);
E(COMPRESSED_NO_CLEAR, MC, PARTIAL_RESOLVE, ASSERT);
E(COMPRESSED_HIER_DEPTH, MC, PARTIAL_RESOLVE, ASSERT);
E(RESOLVED, MC, PARTIAL_RESOLVE, ASSERT);
E(PASS_THROUGH, MC, PARTIAL_RESOLVE, ASSERT);
E(AUX_INVALID, MC, PARTIAL_RESOLVE, ASSERT);
E(CLEAR, HIZ, PARTIAL_RESOLVE, RESOLVED);
E(PARTIAL_CLEAR, HIZ, PARTIAL_RESOLVE, ASSERT);
E(COMPRESSED_CLEAR, HIZ, PARTIAL_RESOLVE, RESOLVED);
E(COMPRESSED_NO_CLEAR, HIZ, PARTIAL_RESOLVE, RESOLVED);
E(COMPRESSED_HIER_DEPTH, HIZ, PARTIAL_RESOLVE, RESOLVED);
E(RESOLVED, HIZ, PARTIAL_RESOLVE, RESOLVED);
E(PASS_THROUGH, HIZ, PARTIAL_RESOLVE, PASS_THROUGH);
E(AUX_INVALID, HIZ, PARTIAL_RESOLVE, ASSERT);
E(CLEAR, HIZ_CCS, PARTIAL_RESOLVE, COMPRESSED_CLEAR);
E(PARTIAL_CLEAR, HIZ_CCS, PARTIAL_RESOLVE, ASSERT);
E(COMPRESSED_CLEAR, HIZ_CCS, PARTIAL_RESOLVE, COMPRESSED_CLEAR);
E(COMPRESSED_NO_CLEAR, HIZ_CCS, PARTIAL_RESOLVE, COMPRESSED_NO_CLEAR);
E(COMPRESSED_HIER_DEPTH, HIZ_CCS, PARTIAL_RESOLVE, COMPRESSED_CLEAR);
E(RESOLVED, HIZ_CCS, PARTIAL_RESOLVE, RESOLVED);
E(PASS_THROUGH, HIZ_CCS, PARTIAL_RESOLVE, PASS_THROUGH);
E(AUX_INVALID, HIZ_CCS, PARTIAL_RESOLVE, ASSERT);
E(CLEAR, CCS_E, PARTIAL_RESOLVE, COMPRESSED_NO_CLEAR);
E(PARTIAL_CLEAR, CCS_E, PARTIAL_RESOLVE, COMPRESSED_NO_CLEAR);
E(COMPRESSED_CLEAR, CCS_E, PARTIAL_RESOLVE, COMPRESSED_NO_CLEAR);
E(COMPRESSED_NO_CLEAR, CCS_E, PARTIAL_RESOLVE, COMPRESSED_NO_CLEAR);
E(COMPRESSED_HIER_DEPTH, CCS_E, PARTIAL_RESOLVE, ASSERT);
E(RESOLVED, CCS_E, PARTIAL_RESOLVE, RESOLVED);
E(PASS_THROUGH, CCS_E, PARTIAL_RESOLVE, PASS_THROUGH);
E(AUX_INVALID, CCS_E, PARTIAL_RESOLVE, ASSERT);
}
TEST(StateTransitionAuxOp, FullResolve) {
E(CLEAR, NONE, FULL_RESOLVE, ASSERT);
E(PARTIAL_CLEAR, NONE, FULL_RESOLVE, ASSERT);
E(COMPRESSED_CLEAR, NONE, FULL_RESOLVE, ASSERT);
E(COMPRESSED_NO_CLEAR, NONE, FULL_RESOLVE, ASSERT);
E(COMPRESSED_HIER_DEPTH, NONE, FULL_RESOLVE, ASSERT);
E(RESOLVED, NONE, FULL_RESOLVE, ASSERT);
E(PASS_THROUGH, NONE, FULL_RESOLVE, ASSERT);
E(AUX_INVALID, NONE, FULL_RESOLVE, ASSERT);
E(CLEAR, MC, FULL_RESOLVE, ASSERT);
E(PARTIAL_CLEAR, MC, FULL_RESOLVE, ASSERT);
E(COMPRESSED_CLEAR, MC, FULL_RESOLVE, ASSERT);
E(COMPRESSED_NO_CLEAR, MC, FULL_RESOLVE, PASS_THROUGH);
E(COMPRESSED_HIER_DEPTH, MC, FULL_RESOLVE, ASSERT);
E(RESOLVED, MC, FULL_RESOLVE, PASS_THROUGH);
E(PASS_THROUGH, MC, FULL_RESOLVE, PASS_THROUGH);
E(AUX_INVALID, MC, FULL_RESOLVE, ASSERT);
E(CLEAR, HIZ, FULL_RESOLVE, RESOLVED);
E(PARTIAL_CLEAR, HIZ, FULL_RESOLVE, RESOLVED);
E(COMPRESSED_CLEAR, HIZ, FULL_RESOLVE, RESOLVED);
E(COMPRESSED_NO_CLEAR, HIZ, FULL_RESOLVE, RESOLVED);
E(COMPRESSED_HIER_DEPTH, HIZ, FULL_RESOLVE, RESOLVED);
E(RESOLVED, HIZ, FULL_RESOLVE, RESOLVED);
E(PASS_THROUGH, HIZ, FULL_RESOLVE, PASS_THROUGH);
E(AUX_INVALID, HIZ, FULL_RESOLVE, ASSERT);
E(CLEAR, CCS_E, FULL_RESOLVE, PASS_THROUGH);
E(PARTIAL_CLEAR, CCS_E, FULL_RESOLVE, PASS_THROUGH);
E(COMPRESSED_CLEAR, CCS_E, FULL_RESOLVE, PASS_THROUGH);
E(COMPRESSED_NO_CLEAR, CCS_E, FULL_RESOLVE, PASS_THROUGH);
E(COMPRESSED_HIER_DEPTH, CCS_E, FULL_RESOLVE, ASSERT);
E(RESOLVED, CCS_E, FULL_RESOLVE, PASS_THROUGH);
E(PASS_THROUGH, CCS_E, FULL_RESOLVE, PASS_THROUGH);
E(AUX_INVALID, CCS_E, FULL_RESOLVE, ASSERT);
}
TEST(StateTransitionAuxOp, Ambiguate) {
E(CLEAR, NONE, AMBIGUATE, ASSERT);
E(PARTIAL_CLEAR, NONE, AMBIGUATE, ASSERT);
E(COMPRESSED_CLEAR, NONE, AMBIGUATE, ASSERT);
E(COMPRESSED_NO_CLEAR, NONE, AMBIGUATE, ASSERT);
E(COMPRESSED_HIER_DEPTH, NONE, AMBIGUATE, ASSERT);
E(RESOLVED, NONE, AMBIGUATE, ASSERT);
E(PASS_THROUGH, NONE, AMBIGUATE, ASSERT);
E(AUX_INVALID, NONE, AMBIGUATE, ASSERT);
E(CLEAR, MC, AMBIGUATE, ASSERT);
E(PARTIAL_CLEAR, MC, AMBIGUATE, ASSERT);
E(COMPRESSED_CLEAR, MC, AMBIGUATE, ASSERT);
E(COMPRESSED_NO_CLEAR, MC, AMBIGUATE, PASS_THROUGH);
E(COMPRESSED_HIER_DEPTH, MC, AMBIGUATE, ASSERT);
E(RESOLVED, MC, AMBIGUATE, PASS_THROUGH);
E(PASS_THROUGH, MC, AMBIGUATE, PASS_THROUGH);
E(AUX_INVALID, MC, AMBIGUATE, PASS_THROUGH);
E(CLEAR, HIZ, AMBIGUATE, PASS_THROUGH);
E(PARTIAL_CLEAR, HIZ, AMBIGUATE, PASS_THROUGH);
E(COMPRESSED_CLEAR, HIZ, AMBIGUATE, PASS_THROUGH);
E(COMPRESSED_NO_CLEAR, HIZ, AMBIGUATE, PASS_THROUGH);
E(COMPRESSED_HIER_DEPTH, HIZ, AMBIGUATE, PASS_THROUGH);
E(RESOLVED, HIZ, AMBIGUATE, PASS_THROUGH);
E(PASS_THROUGH, HIZ, AMBIGUATE, PASS_THROUGH);
E(AUX_INVALID, HIZ, AMBIGUATE, PASS_THROUGH);
E(CLEAR, CCS_E, AMBIGUATE, PASS_THROUGH);
E(PARTIAL_CLEAR, CCS_E, AMBIGUATE, PASS_THROUGH);
E(COMPRESSED_CLEAR, CCS_E, AMBIGUATE, PASS_THROUGH);
E(COMPRESSED_NO_CLEAR, CCS_E, AMBIGUATE, PASS_THROUGH);
E(COMPRESSED_HIER_DEPTH, CCS_E, AMBIGUATE, ASSERT);
E(RESOLVED, CCS_E, AMBIGUATE, PASS_THROUGH);
E(PASS_THROUGH, CCS_E, AMBIGUATE, PASS_THROUGH);
E(AUX_INVALID, CCS_E, AMBIGUATE, PASS_THROUGH);
}
#undef E
#define E(state1, usage, full_surface, state2) \
EXPECT_EQ(ISL_AUX_STATE_ ## state2, \
isl_aux_state_transition_write(ISL_AUX_STATE_ ## state1, \
ISL_AUX_USAGE_ ## usage, \
full_surface))
TEST(StateTransitionWrite, WritesOnlyTouchMain) {
E(CLEAR, NONE, false, ASSERT);
E(CLEAR, NONE, true, AUX_INVALID);
E(PARTIAL_CLEAR, NONE, false, ASSERT);
E(PARTIAL_CLEAR, NONE, true, AUX_INVALID);
E(COMPRESSED_CLEAR, NONE, false, ASSERT);
E(COMPRESSED_CLEAR, NONE, true, AUX_INVALID);
E(COMPRESSED_NO_CLEAR, NONE, false, ASSERT);
E(COMPRESSED_NO_CLEAR, NONE, true, AUX_INVALID);
E(COMPRESSED_HIER_DEPTH, NONE, false, ASSERT);
E(COMPRESSED_HIER_DEPTH, NONE, true, AUX_INVALID);
E(RESOLVED, NONE, false, AUX_INVALID);
E(RESOLVED, NONE, true, AUX_INVALID);
E(PASS_THROUGH, NONE, false, PASS_THROUGH);
E(PASS_THROUGH, NONE, true, PASS_THROUGH);
E(AUX_INVALID, NONE, false, AUX_INVALID);
E(AUX_INVALID, NONE, true, AUX_INVALID);
}
TEST(StateTransitionWrite, WritesCompress) {
E(CLEAR, MCS, false, COMPRESSED_CLEAR);
E(CLEAR, MCS, true, COMPRESSED_NO_CLEAR);
E(PARTIAL_CLEAR, MCS, false, COMPRESSED_CLEAR);
E(PARTIAL_CLEAR, MCS, true, COMPRESSED_NO_CLEAR);
E(COMPRESSED_CLEAR, MCS, false, COMPRESSED_CLEAR);
E(COMPRESSED_CLEAR, MCS, true, COMPRESSED_NO_CLEAR);
E(COMPRESSED_NO_CLEAR, MCS, false, COMPRESSED_NO_CLEAR);
E(COMPRESSED_NO_CLEAR, MCS, true, COMPRESSED_NO_CLEAR);
E(COMPRESSED_HIER_DEPTH, MCS, false, ASSERT);
E(COMPRESSED_HIER_DEPTH, MCS, true, ASSERT);
E(RESOLVED, MCS, false, COMPRESSED_NO_CLEAR);
E(RESOLVED, MCS, true, COMPRESSED_NO_CLEAR);
E(PASS_THROUGH, MCS, false, COMPRESSED_NO_CLEAR);
E(PASS_THROUGH, MCS, true, COMPRESSED_NO_CLEAR);
E(AUX_INVALID, MCS, false, ASSERT);
E(AUX_INVALID, MCS, true, ASSERT);
E(CLEAR, STC_CCS, false, ASSERT);
E(CLEAR, STC_CCS, true, ASSERT);
E(PARTIAL_CLEAR, STC_CCS, false, ASSERT);
E(PARTIAL_CLEAR, STC_CCS, true, ASSERT);
E(COMPRESSED_CLEAR, STC_CCS, false, ASSERT);
E(COMPRESSED_CLEAR, STC_CCS, true, ASSERT);
E(COMPRESSED_NO_CLEAR, STC_CCS, false, COMPRESSED_NO_CLEAR);
E(COMPRESSED_NO_CLEAR, STC_CCS, true, COMPRESSED_NO_CLEAR);
E(RESOLVED, STC_CCS, false, COMPRESSED_NO_CLEAR);
E(RESOLVED, STC_CCS, true, COMPRESSED_NO_CLEAR);
E(PASS_THROUGH, STC_CCS, false, COMPRESSED_NO_CLEAR);
E(PASS_THROUGH, STC_CCS, true, COMPRESSED_NO_CLEAR);
E(AUX_INVALID, STC_CCS, false, ASSERT);
E(AUX_INVALID, STC_CCS, true, ASSERT);
}
TEST(StateTransitionWrite, WritesCompressClear) {
E(CLEAR, FCV_CCS_E, false, COMPRESSED_CLEAR);
E(CLEAR, FCV_CCS_E, true, COMPRESSED_CLEAR);
E(PARTIAL_CLEAR, FCV_CCS_E, false, COMPRESSED_CLEAR);
E(PARTIAL_CLEAR, FCV_CCS_E, true, COMPRESSED_CLEAR);
E(COMPRESSED_CLEAR, FCV_CCS_E, false, COMPRESSED_CLEAR);
E(COMPRESSED_CLEAR, FCV_CCS_E, true, COMPRESSED_CLEAR);
E(COMPRESSED_NO_CLEAR, FCV_CCS_E, false, COMPRESSED_CLEAR);
E(COMPRESSED_NO_CLEAR, FCV_CCS_E, true, COMPRESSED_CLEAR);
E(COMPRESSED_HIER_DEPTH, FCV_CCS_E, false, ASSERT);
E(COMPRESSED_HIER_DEPTH, FCV_CCS_E, true, ASSERT);
E(RESOLVED, FCV_CCS_E, false, COMPRESSED_CLEAR);
E(RESOLVED, FCV_CCS_E, true, COMPRESSED_CLEAR);
E(PASS_THROUGH, FCV_CCS_E, false, COMPRESSED_CLEAR);
E(PASS_THROUGH, FCV_CCS_E, true, COMPRESSED_CLEAR);
E(AUX_INVALID, FCV_CCS_E, false, ASSERT);
E(AUX_INVALID, FCV_CCS_E, true, ASSERT);
}
TEST(StateTransitionWrite, WritesResolveAmbiguate) {
E(CLEAR, CCS_D, false, PARTIAL_CLEAR);
E(CLEAR, CCS_D, true, PASS_THROUGH);
E(PARTIAL_CLEAR, CCS_D, false, PARTIAL_CLEAR);
E(PARTIAL_CLEAR, CCS_D, true, PASS_THROUGH);
E(COMPRESSED_CLEAR, CCS_D, false, ASSERT);
E(COMPRESSED_CLEAR, CCS_D, true, ASSERT);
E(COMPRESSED_NO_CLEAR, CCS_D, false, ASSERT);
E(COMPRESSED_NO_CLEAR, CCS_D, true, ASSERT);
E(COMPRESSED_HIER_DEPTH, CCS_D, false, ASSERT);
E(COMPRESSED_HIER_DEPTH, CCS_D, true, ASSERT);
E(RESOLVED, CCS_D, false, RESOLVED);
E(RESOLVED, CCS_D, true, PASS_THROUGH);
E(PASS_THROUGH, CCS_D, false, PASS_THROUGH);
E(PASS_THROUGH, CCS_D, true, PASS_THROUGH);
E(AUX_INVALID, CCS_D, false, ASSERT);
E(AUX_INVALID, CCS_D, true, ASSERT);
E(CLEAR, MC, false, ASSERT);
E(CLEAR, MC, true, ASSERT);
E(PARTIAL_CLEAR, MC, false, ASSERT);
E(PARTIAL_CLEAR, MC, true, ASSERT);
E(COMPRESSED_CLEAR, MC, false, ASSERT);
E(COMPRESSED_CLEAR, MC, true, ASSERT);
E(COMPRESSED_NO_CLEAR, MC, false, COMPRESSED_NO_CLEAR);
E(COMPRESSED_NO_CLEAR, MC, true, PASS_THROUGH);
E(RESOLVED, MC, false, RESOLVED);
E(RESOLVED, MC, true, PASS_THROUGH);
E(PASS_THROUGH, MC, false, PASS_THROUGH);
E(PASS_THROUGH, MC, true, PASS_THROUGH);
E(AUX_INVALID, MC, false, ASSERT);
E(AUX_INVALID, MC, true, ASSERT);
}
TEST(StateTransitionWrite, WritesCompressHiZ) {
E(CLEAR, HIZ_CCS, false, COMPRESSED_HIER_DEPTH);
E(CLEAR, HIZ_CCS, true, COMPRESSED_HIER_DEPTH);
E(PARTIAL_CLEAR, HIZ_CCS, false, COMPRESSED_HIER_DEPTH);
E(PARTIAL_CLEAR, HIZ_CCS, true, COMPRESSED_HIER_DEPTH);
E(COMPRESSED_CLEAR, HIZ_CCS, false, COMPRESSED_HIER_DEPTH);
E(COMPRESSED_CLEAR, HIZ_CCS, true, COMPRESSED_HIER_DEPTH);
E(COMPRESSED_NO_CLEAR, HIZ_CCS, false, COMPRESSED_HIER_DEPTH);
E(COMPRESSED_NO_CLEAR, HIZ_CCS, true, COMPRESSED_HIER_DEPTH);
E(COMPRESSED_HIER_DEPTH, HIZ_CCS, false, COMPRESSED_HIER_DEPTH);
E(COMPRESSED_HIER_DEPTH, HIZ_CCS, true, COMPRESSED_HIER_DEPTH);
E(RESOLVED, HIZ_CCS, false, COMPRESSED_HIER_DEPTH);
E(RESOLVED, HIZ_CCS, true, COMPRESSED_HIER_DEPTH);
E(PASS_THROUGH, HIZ_CCS, false, COMPRESSED_HIER_DEPTH);
E(PASS_THROUGH, HIZ_CCS, true, COMPRESSED_HIER_DEPTH);
E(AUX_INVALID, HIZ_CCS, false, ASSERT);
E(AUX_INVALID, HIZ_CCS, true, ASSERT);
}
#undef E
@@ -0,0 +1,283 @@
/*
* Copyright 2015 Intel Corporation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#include <assert.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include "dev/intel_device_info.h"
#include "isl/isl.h"
#include "isl/isl_priv.h"
#define BDW_GT2_DEVID 0x161a
// An assert that works regardless of NDEBUG.
#define t_assert(cond) \
do { \
if (!(cond)) { \
fprintf(stderr, "%s:%d: assertion failed\n", __FILE__, __LINE__); \
abort(); \
} \
} while (0)
static void
t_assert_extent4d(const struct isl_extent4d *e, uint32_t width,
uint32_t height, uint32_t depth, uint32_t array_len)
{
t_assert(e->width == width);
t_assert(e->height == height);
t_assert(e->depth == depth);
t_assert(e->array_len == array_len);
}
static void
t_assert_image_alignment_el(const struct isl_surf *surf,
uint32_t w, uint32_t h, uint32_t d)
{
struct isl_extent3d align_el;
align_el = isl_surf_get_image_alignment_el(surf);
t_assert(align_el.w == w);
t_assert(align_el.h == h);
t_assert(align_el.d == d);
}
static void
t_assert_image_alignment_sa(const struct isl_surf *surf,
uint32_t w, uint32_t h, uint32_t d)
{
struct isl_extent3d align_sa;
align_sa = isl_surf_get_image_alignment_sa(surf);
t_assert(align_sa.w == w);
t_assert(align_sa.h == h);
t_assert(align_sa.d == d);
}
static void
t_assert_offset_el(const struct isl_surf *surf,
uint32_t level,
uint32_t logical_array_layer,
uint32_t logical_z_offset_px,
uint32_t expected_x_offset_el,
uint32_t expected_y_offset_el)
{
uint32_t x, y, z, a;
isl_surf_get_image_offset_el(surf, level, logical_array_layer,
logical_z_offset_px, &x, &y, &z, &a);
t_assert(x == expected_x_offset_el);
t_assert(y == expected_y_offset_el);
}
static void
t_assert_phys_level0_sa(const struct isl_surf *surf, uint32_t width,
uint32_t height, uint32_t depth, uint32_t array_len)
{
t_assert_extent4d(&surf->phys_level0_sa, width, height, depth, array_len);
}
static void
t_assert_gfx4_3d_layer(const struct isl_surf *surf,
uint32_t level,
uint32_t aligned_width,
uint32_t aligned_height,
uint32_t depth,
uint32_t horiz_layers,
uint32_t vert_layers,
uint32_t *base_y)
{
for (uint32_t z = 0; z < depth; ++z) {
t_assert_offset_el(surf, level, 0, z,
aligned_width * (z % horiz_layers),
*base_y + aligned_height * (z / horiz_layers));
}
*base_y += aligned_height * vert_layers;
}
static void
test_bdw_2d_r8g8b8a8_unorm_512x512_array01_samples01_noaux_tiley0(void)
{
bool ok;
struct intel_device_info devinfo;
t_assert(intel_get_device_info_from_pci_id(BDW_GT2_DEVID, &devinfo));
struct isl_device dev;
isl_device_init(&dev, &devinfo);
struct isl_surf surf;
ok = isl_surf_init(&dev, &surf,
.dim = ISL_SURF_DIM_2D,
.format = ISL_FORMAT_R8G8B8A8_UNORM,
.width = 512,
.height = 512,
.depth = 1,
.levels = 10,
.array_len = 1,
.samples = 1,
.usage = ISL_SURF_USAGE_TEXTURE_BIT |
ISL_SURF_USAGE_DISABLE_AUX_BIT,
.tiling_flags = ISL_TILING_Y0_BIT);
t_assert(ok);
t_assert_image_alignment_el(&surf, 4, 4, 1);
t_assert_image_alignment_sa(&surf, 4, 4, 1);
t_assert_phys_level0_sa(&surf, 512, 512, 1, 1);
t_assert(isl_surf_get_array_pitch_el_rows(&surf) >= 772);
t_assert(isl_surf_get_array_pitch_el_rows(&surf) ==
isl_surf_get_array_pitch_sa_rows(&surf));
/* Row pitch should be minimal possible */
t_assert(surf.row_pitch_B == 2048);
t_assert_offset_el(&surf, 0, 0, 0, 0, 0); // +0, +0
t_assert_offset_el(&surf, 1, 0, 0, 0, 512); // +0, +512
t_assert_offset_el(&surf, 2, 0, 0, 256, 512); // +256, +0
t_assert_offset_el(&surf, 3, 0, 0, 256, 640); // +0, +128
t_assert_offset_el(&surf, 4, 0, 0, 256, 704); // +0, +64
t_assert_offset_el(&surf, 5, 0, 0, 256, 736); // +0, +32
t_assert_offset_el(&surf, 6, 0, 0, 256, 752); // +0, +16
t_assert_offset_el(&surf, 7, 0, 0, 256, 760); // +0, +8
t_assert_offset_el(&surf, 8, 0, 0, 256, 764); // +0, +4
t_assert_offset_el(&surf, 9, 0, 0, 256, 768); // +0, +4
}
static void
test_bdw_2d_r8g8b8a8_unorm_1024x1024_array06_samples01_noaux_tiley0(void)
{
bool ok;
struct intel_device_info devinfo;
t_assert(intel_get_device_info_from_pci_id(BDW_GT2_DEVID, &devinfo));
struct isl_device dev;
isl_device_init(&dev, &devinfo);
struct isl_surf surf;
ok = isl_surf_init(&dev, &surf,
.dim = ISL_SURF_DIM_2D,
.format = ISL_FORMAT_R8G8B8A8_UNORM,
.width = 1024,
.height = 1024,
.depth = 1,
.levels = 11,
.array_len = 6,
.samples = 1,
.usage = ISL_SURF_USAGE_TEXTURE_BIT |
ISL_SURF_USAGE_DISABLE_AUX_BIT,
.tiling_flags = ISL_TILING_Y0_BIT);
t_assert(ok);
t_assert_image_alignment_el(&surf, 4, 4, 1);
t_assert_image_alignment_sa(&surf, 4, 4, 1);
t_assert(isl_surf_get_array_pitch_el_rows(&surf) >= 1540);
t_assert(isl_surf_get_array_pitch_el_rows(&surf) ==
isl_surf_get_array_pitch_sa_rows(&surf));
/* Row pitch should be minimal possible */
t_assert(surf.row_pitch_B == 4096);
for (uint32_t a = 0; a < 6; ++a) {
uint32_t b = a * isl_surf_get_array_pitch_sa_rows(&surf);
t_assert_offset_el(&surf, 0, a, 0, 0, b + 0); // +0, +0
t_assert_offset_el(&surf, 1, a, 0, 0, b + 1024); // +0, +1024
t_assert_offset_el(&surf, 2, a, 0, 512, b + 1024); // +512, +0
t_assert_offset_el(&surf, 3, a, 0, 512, b + 1280); // +0, +256
t_assert_offset_el(&surf, 4, a, 0, 512, b + 1408); // +0, +128
t_assert_offset_el(&surf, 5, a, 0, 512, b + 1472); // +0, +64
t_assert_offset_el(&surf, 6, a, 0, 512, b + 1504); // +0, +32
t_assert_offset_el(&surf, 7, a, 0, 512, b + 1520); // +0, +16
t_assert_offset_el(&surf, 8, a, 0, 512, b + 1528); // +0, +8
t_assert_offset_el(&surf, 9, a, 0, 512, b + 1532); // +0, +4
t_assert_offset_el(&surf, 10, a, 0, 512, b + 1536); // +0, +4
}
/* The layout below assumes a specific array pitch. It will need updating
* if isl's array pitch calculations ever change.
*/
t_assert(isl_surf_get_array_pitch_el_rows(&surf) == 1540);
/* skip the remaining array layers */
}
static void
test_bdw_3d_r8g8b8a8_unorm_256x256x256_levels09_tiley0(void)
{
bool ok;
struct intel_device_info devinfo;
t_assert(intel_get_device_info_from_pci_id(BDW_GT2_DEVID, &devinfo));
struct isl_device dev;
isl_device_init(&dev, &devinfo);
struct isl_surf surf;
ok = isl_surf_init(&dev, &surf,
.dim = ISL_SURF_DIM_3D,
.format = ISL_FORMAT_R8G8B8A8_UNORM,
.width = 256,
.height = 256,
.depth = 256,
.levels = 9,
.array_len = 1,
.samples = 1,
.usage = ISL_SURF_USAGE_TEXTURE_BIT |
ISL_SURF_USAGE_DISABLE_AUX_BIT,
.tiling_flags = ISL_TILING_Y0_BIT);
t_assert(ok);
t_assert_image_alignment_el(&surf, 4, 4, 1);
t_assert_image_alignment_sa(&surf, 4, 4, 1);
t_assert(isl_surf_get_array_pitch_sa_rows(&surf) ==
isl_surf_get_array_pitch_el_rows(&surf));
uint32_t base_y = 0;
t_assert_gfx4_3d_layer(&surf, 0, 256, 256, 256, 1, 256, &base_y);
t_assert_gfx4_3d_layer(&surf, 1, 128, 128, 128, 2, 64, &base_y);
t_assert_gfx4_3d_layer(&surf, 2, 64, 64, 64, 4, 16, &base_y);
t_assert_gfx4_3d_layer(&surf, 3, 32, 32, 32, 8, 4, &base_y);
t_assert_gfx4_3d_layer(&surf, 4, 16, 16, 16, 16, 1, &base_y);
t_assert_gfx4_3d_layer(&surf, 5, 8, 8, 8, 32, 1, &base_y);
t_assert_gfx4_3d_layer(&surf, 6, 4, 4, 4, 64, 1, &base_y);
t_assert_gfx4_3d_layer(&surf, 7, 4, 4, 2, 128, 1, &base_y);
t_assert_gfx4_3d_layer(&surf, 8, 4, 4, 1, 256, 1, &base_y);
}
int main(void)
{
/* FINISHME: Add tests for npot sizes */
/* FINISHME: Add tests for 1D surfaces */
test_bdw_2d_r8g8b8a8_unorm_512x512_array01_samples01_noaux_tiley0();
test_bdw_2d_r8g8b8a8_unorm_1024x1024_array06_samples01_noaux_tiley0();
test_bdw_3d_r8g8b8a8_unorm_256x256x256_levels09_tiley0();
}
@@ -0,0 +1,164 @@
/* Copyright © 2024 Intel Corporation
* SPDX-License-Identifier: MIT
*/
#include <assert.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include "dev/intel_device_info.h"
#include "isl/isl.h"
#include "isl/isl_priv.h"
/* An assert that works regardless of NDEBUG. */
#define t_assert(cond) \
do { \
if (!(cond)) { \
fprintf(stderr, "%s:%d: assertion failed\n", __FILE__, __LINE__); \
abort(); \
} \
} while (0)
/* The bare minimum amount of data that should be in the surface */
static uint64_t
surf_data_size(const struct isl_surf *surf, int level)
{
return (isl_format_get_layout(surf->format)->bpb / 8) *
isl_minify(surf->logical_level0_px.w, level) *
isl_minify(surf->logical_level0_px.h, level);
}
static void
test_2d_r8g8b8a8_unorm_16x16x1_levels01_array01_samples01_noaux(const char *platform,
uint32_t tiling_flags)
{
struct intel_device_info devinfo;
t_assert(intel_get_device_info_from_pci_id(
intel_device_name_to_pci_device_id(platform), &devinfo));
struct isl_device dev;
isl_device_init(&dev, &devinfo);
struct isl_surf surf;
bool ok =
isl_surf_init(&dev, &surf,
.dim = ISL_SURF_DIM_2D,
.format = ISL_FORMAT_R8G8B8A8_UNORM,
.width = 16,
.height = 16,
.depth = 1,
.levels = 1,
.array_len = 1,
.samples = 1,
.usage = ISL_SURF_USAGE_TEXTURE_BIT |
ISL_SURF_USAGE_DISABLE_AUX_BIT,
.tiling_flags = tiling_flags);
t_assert(ok);
uint64_t start_tile_B, end_tile_B;
isl_surf_get_image_range_B_tile(&surf, 0, 0, 0, &start_tile_B, &end_tile_B);
t_assert(end_tile_B - start_tile_B <= surf.size_B);
t_assert(end_tile_B - start_tile_B >= surf_data_size(&surf, 0));
}
static void
test_2d_r8g8b8a8_unorm_256x256x1_levels05_array01_samples01_noaux(const char *platform,
uint32_t tiling_flags)
{
struct intel_device_info devinfo;
t_assert(intel_get_device_info_from_pci_id(
intel_device_name_to_pci_device_id(platform), &devinfo));
struct isl_device dev;
isl_device_init(&dev, &devinfo);
struct isl_surf surf;
bool ok =
isl_surf_init(&dev, &surf,
.dim = ISL_SURF_DIM_2D,
.format = ISL_FORMAT_R8G8B8A8_UNORM,
.width = 256,
.height = 256,
.depth = 1,
.levels = 5,
.array_len = 1,
.samples = 1,
.usage = ISL_SURF_USAGE_TEXTURE_BIT |
ISL_SURF_USAGE_DISABLE_AUX_BIT,
.tiling_flags = tiling_flags);
t_assert(ok);
struct isl_surf sub_surf;
uint32_t x_offset_sa, y_offset_sa;
uint64_t offset_B;
isl_surf_get_image_surf(&dev, &surf,
4, 0, 0,
&sub_surf,
&offset_B,
&x_offset_sa,
&y_offset_sa);
uint64_t start_tile_B, end_tile_B;
isl_surf_get_image_range_B_tile(&surf, 4, 0, 0, &start_tile_B, &end_tile_B);
t_assert(end_tile_B - start_tile_B <= surf.size_B);
t_assert(end_tile_B - start_tile_B >= surf_data_size(&surf, 4));
}
static void
test_2d_astc_ldr_4x4_u8srgb_unorm_256x256x1_levels05_array01_samples01_noaux(const char *platform,
uint32_t tiling_flags)
{
struct intel_device_info devinfo;
t_assert(intel_get_device_info_from_pci_id(
intel_device_name_to_pci_device_id(platform), &devinfo));
struct isl_device dev;
isl_device_init(&dev, &devinfo);
struct isl_surf surf;
bool ok =
isl_surf_init(&dev, &surf,
.dim = ISL_SURF_DIM_2D,
.format = ISL_FORMAT_R8G8B8A8_UNORM,
.width = 256,
.height = 256,
.depth = 1,
.levels = 5,
.array_len = 1,
.samples = 1,
.usage = ISL_SURF_USAGE_TEXTURE_BIT |
ISL_SURF_USAGE_DISABLE_AUX_BIT,
.tiling_flags = tiling_flags);
t_assert(ok);
struct isl_surf sub_surf;
uint32_t x_offset_sa, y_offset_sa;
uint64_t offset_B;
isl_surf_get_image_surf(&dev, &surf,
4, 0, 0,
&sub_surf,
&offset_B,
&x_offset_sa,
&y_offset_sa);
uint64_t start_tile_B, end_tile_B;
isl_surf_get_image_range_B_tile(&surf, 4, 0, 0, &start_tile_B, &end_tile_B);
t_assert(end_tile_B - start_tile_B <= surf.size_B);
t_assert(end_tile_B - start_tile_B >= surf_data_size(&surf, 4));
}
int main(void)
{
test_2d_r8g8b8a8_unorm_16x16x1_levels01_array01_samples01_noaux("dg2", ISL_TILING_4_BIT);
test_2d_r8g8b8a8_unorm_256x256x1_levels05_array01_samples01_noaux("dg2", ISL_TILING_4_BIT);
test_2d_r8g8b8a8_unorm_16x16x1_levels01_array01_samples01_noaux("icl", ISL_TILING_Y0_BIT);
test_2d_r8g8b8a8_unorm_256x256x1_levels05_array01_samples01_noaux("icl", ISL_TILING_Y0_BIT);
test_2d_r8g8b8a8_unorm_16x16x1_levels01_array01_samples01_noaux("tgl", ISL_TILING_LINEAR_BIT);
test_2d_r8g8b8a8_unorm_256x256x1_levels05_array01_samples01_noaux("tgl", ISL_TILING_LINEAR_BIT);
test_2d_astc_ldr_4x4_u8srgb_unorm_256x256x1_levels05_array01_samples01_noaux("skl", ISL_TILING_Y0_BIT);
test_2d_astc_ldr_4x4_u8srgb_unorm_256x256x1_levels05_array01_samples01_noaux("skl", ISL_TILING_LINEAR_BIT);
}
+170
View File
@@ -0,0 +1,170 @@
/*
* Copyright 2018 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 <assert.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include "isl/isl.h"
// An asssert that works regardless of NDEBUG.
#define t_assert(cond) \
do { \
if (!(cond)) { \
fprintf(stderr, "%s:%d: assertion failed\n", __FILE__, __LINE__); \
abort(); \
} \
} while (0)
static void
assert_tile_size(enum isl_tiling tiling, enum isl_surf_dim dim,
enum isl_msaa_layout msaa_layout,
uint32_t bpb, uint32_t samples,
uint32_t w, uint32_t h, uint32_t d, uint32_t a)
{
struct isl_tile_info tile_info;
isl_tiling_get_info(tiling, dim, msaa_layout, bpb, samples, &tile_info);
/* Sanity */
t_assert(tile_info.tiling == tiling);
t_assert(tile_info.format_bpb == bpb);
t_assert(tile_info.logical_extent_el.w == w);
t_assert(tile_info.logical_extent_el.h == h);
t_assert(tile_info.logical_extent_el.d == d);
t_assert(tile_info.logical_extent_el.a == a);
bool is_Ys = tiling == ISL_TILING_SKL_Ys ||
tiling == ISL_TILING_ICL_Ys;
uint32_t tile_size = is_Ys ? 64 * 1024 : 4 * 1024;
assert(tile_size == tile_info.phys_extent_B.w *
tile_info.phys_extent_B.h);
assert(tile_size == tile_info.logical_extent_el.w *
tile_info.logical_extent_el.h *
tile_info.logical_extent_el.d *
tile_info.logical_extent_el.a *
bpb / 8);
}
static void
assert_2d_tile_size(enum isl_tiling tiling, uint32_t bpb,
uint32_t halign, uint32_t valign)
{
#define ASSERT_2D(tiling, bpb, samples, w, h, a) \
assert_tile_size(tiling, ISL_SURF_DIM_2D, ISL_MSAA_LAYOUT_ARRAY, \
bpb, samples, w, h, 1, a)
/* Single sampled */
ASSERT_2D(tiling, bpb, 1, halign, valign, 1);
/* Multisampled */
if (tiling == ISL_TILING_SKL_Yf) {
ASSERT_2D(tiling, bpb, 2, halign, valign, 1);
ASSERT_2D(tiling, bpb, 4, halign, valign, 1);
ASSERT_2D(tiling, bpb, 8, halign, valign, 1);
ASSERT_2D(tiling, bpb, 16, halign, valign, 1);
} else {
/* For gfx9 Ys and for both Yf and Ys on gfx11, we have to divide the
* size by the number of samples.
*/
ASSERT_2D(tiling, bpb, 2, halign / 2, valign / 1, 2);
ASSERT_2D(tiling, bpb, 4, halign / 2, valign / 2, 4);
ASSERT_2D(tiling, bpb, 8, halign / 4, valign / 2, 8);
ASSERT_2D(tiling, bpb, 16, halign / 4, valign / 4, 16);
}
#undef ASSERT_2D
}
static void
test_2d_tile_dimensions()
{
assert_2d_tile_size(ISL_TILING_SKL_Ys, 128, 64, 64);
assert_2d_tile_size(ISL_TILING_SKL_Ys, 64, 128, 64);
assert_2d_tile_size(ISL_TILING_SKL_Ys, 32, 128, 128);
assert_2d_tile_size(ISL_TILING_SKL_Ys, 16, 256, 128);
assert_2d_tile_size(ISL_TILING_SKL_Ys, 8, 256, 256);
assert_2d_tile_size(ISL_TILING_SKL_Yf, 128, 16, 16);
assert_2d_tile_size(ISL_TILING_SKL_Yf, 64, 32, 16);
assert_2d_tile_size(ISL_TILING_SKL_Yf, 32, 32, 32);
assert_2d_tile_size(ISL_TILING_SKL_Yf, 16, 64, 32);
assert_2d_tile_size(ISL_TILING_SKL_Yf, 8, 64, 64);
assert_2d_tile_size(ISL_TILING_ICL_Ys, 128, 64, 64);
assert_2d_tile_size(ISL_TILING_ICL_Ys, 64, 128, 64);
assert_2d_tile_size(ISL_TILING_ICL_Ys, 32, 128, 128);
assert_2d_tile_size(ISL_TILING_ICL_Ys, 16, 256, 128);
assert_2d_tile_size(ISL_TILING_ICL_Ys, 8, 256, 256);
assert_2d_tile_size(ISL_TILING_ICL_Yf, 128, 16, 16);
assert_2d_tile_size(ISL_TILING_ICL_Yf, 64, 32, 16);
assert_2d_tile_size(ISL_TILING_ICL_Yf, 32, 32, 32);
assert_2d_tile_size(ISL_TILING_ICL_Yf, 16, 64, 32);
assert_2d_tile_size(ISL_TILING_ICL_Yf, 8, 64, 64);
}
static void
test_3d_tile_dimensions()
{
#define ASSERT_3D(tiling, bpb, halign, valign, dalign) \
assert_tile_size(tiling, ISL_SURF_DIM_3D, ISL_MSAA_LAYOUT_ARRAY, \
bpb, 1, halign, valign, dalign, 1)
ASSERT_3D(ISL_TILING_SKL_Ys, 128, 16, 16, 16);
ASSERT_3D(ISL_TILING_SKL_Ys, 64, 32, 16, 16);
ASSERT_3D(ISL_TILING_SKL_Ys, 32, 32, 32, 16);
ASSERT_3D(ISL_TILING_SKL_Ys, 16, 32, 32, 32);
ASSERT_3D(ISL_TILING_SKL_Ys, 8, 64, 32, 32);
ASSERT_3D(ISL_TILING_SKL_Yf, 128, 4, 8, 8);
ASSERT_3D(ISL_TILING_SKL_Yf, 64, 8, 8, 8);
ASSERT_3D(ISL_TILING_SKL_Yf, 32, 8, 16, 8);
ASSERT_3D(ISL_TILING_SKL_Yf, 16, 8, 16, 16);
ASSERT_3D(ISL_TILING_SKL_Yf, 8, 16, 16, 16);
ASSERT_3D(ISL_TILING_ICL_Ys, 128, 16, 16, 16);
ASSERT_3D(ISL_TILING_ICL_Ys, 64, 32, 16, 16);
ASSERT_3D(ISL_TILING_ICL_Ys, 32, 32, 32, 16);
ASSERT_3D(ISL_TILING_ICL_Ys, 16, 32, 32, 32);
ASSERT_3D(ISL_TILING_ICL_Ys, 8, 64, 32, 32);
ASSERT_3D(ISL_TILING_ICL_Yf, 128, 4, 8, 8);
ASSERT_3D(ISL_TILING_ICL_Yf, 64, 8, 8, 8);
ASSERT_3D(ISL_TILING_ICL_Yf, 32, 8, 16, 8);
ASSERT_3D(ISL_TILING_ICL_Yf, 16, 8, 16, 16);
ASSERT_3D(ISL_TILING_ICL_Yf, 8, 16, 16, 16);
#undef ASSERT_3D
}
int main(void)
{
test_2d_tile_dimensions();
test_3d_tile_dimensions();
return 0;
}
@@ -0,0 +1,472 @@
/*
* Copyright 2021 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 <gtest/gtest.h>
#include <inttypes.h>
#include "util/u_math.h"
#include "isl/isl.h"
#include "isl/isl_priv.h"
#define LIN_OFF(y, tw, x) ((y * tw) + x)
#define IMAGE_FORMAT ISL_FORMAT_R32G32B32_UINT
#define TILEW_IMAGE_FORMAT ISL_FORMAT_R8_UINT
enum TILE_CONV {LIN_TO_TILE, TILE_TO_LIN};
typedef uint8_t *(*swizzle_func_t)(const uint8_t *base_addr, uint32_t pitch, uint32_t x_B, uint32_t y_px);
#define TILE_COORDINATES \
/* x1, x2, y1, y2 */ \
std::make_tuple( 0, 1, 0, 1), \
std::make_tuple( 0, 2, 0, 1), \
std::make_tuple( 0, 4, 0, 1), \
std::make_tuple( 0, 8, 0, 8), \
std::make_tuple( 0, 128, 0, 32), \
std::make_tuple( 19, 20, 25, 32), \
std::make_tuple( 59, 83, 13, 32), \
std::make_tuple( 10, 12, 5, 8), \
std::make_tuple( 64, 65, 16, 17), \
std::make_tuple(128, 129, 0, 32), \
std::make_tuple(245, 521, 5, 8)
#define FULL_TILEX_COORDINATES \
std::make_tuple( 0, 32, 0, 8), \
std::make_tuple( 0, 64, 0, 16), \
std::make_tuple( 0, 64, 0, 32)
#define FULL_TILEY_COORDINATES \
std::make_tuple( 0, 8, 0, 32), \
std::make_tuple( 0, 16, 0, 32), \
std::make_tuple( 0, 16, 0, 64)
#define FULL_TILEW_COORDINATES \
std::make_tuple( 0, 64, 0, 64), \
std::make_tuple( 0, 128, 0, 64), \
std::make_tuple( 0, 128, 0,128)
struct tile_swizzle_ops {
enum isl_tiling tiling;
swizzle_func_t linear_to_tile_swizzle;
};
uint32_t swizzle_bitops(uint32_t num, uint8_t field, uint8_t curr_ind, uint8_t swizzle_ind)
{
uint32_t bitmask = (1 << field) - 1;
uint32_t maskednum = num & (bitmask << curr_ind);
uint32_t bits = maskednum >> curr_ind;
return bits << swizzle_ind;
}
uint8_t *linear_to_tileY_swizzle(const uint8_t *base_addr, uint32_t pitch, uint32_t x_B, uint32_t y_px)
{
const uint32_t cu = 7, cv = 5;
const uint32_t tile_id = (y_px >> cv) * (pitch >> cu) + (x_B >> cu);
/* The table below represents the mapping from coordinate (x_B, y_px) to
* byte offset in a 128x32px 1Bpp image:
*
* Bit ind : 11 10 9 8 7 6 5 4 3 2 1 0
* Tile-Y : u6 u5 u4 v4 v3 v2 v1 v0 u3 u2 u1 u0
*/
uint32_t tiled_off;
tiled_off = tile_id * 4096 |
swizzle_bitops(x_B, 4, 0, 0) |
swizzle_bitops(y_px, 5, 0, 4) |
swizzle_bitops(x_B, 3, 4, 9);
return (uint8_t *)(base_addr + tiled_off);
}
uint8_t *linear_to_tile4_swizzle(const uint8_t * base_addr, uint32_t pitch, uint32_t x_B, uint32_t y_px)
{
const uint32_t cu = 7, cv = 5;
const uint32_t tile_id = (y_px >> cv) * (pitch >> cu) + (x_B >> cu);
/* The table below represents the mapping from coordinate (x_B, y_px) to
* byte offset in a 128x32px 1Bpp image:
*
* Bit ind : 11 10 9 8 7 6 5 4 3 2 1 0
* Tile-Y : v4 v3 u6 v2 u5 u4 v1 v0 u3 u2 u1 u0
*/
uint32_t tiled_off;
tiled_off = tile_id * 4096 |
swizzle_bitops(x_B, 4, 0, 0) |
swizzle_bitops(y_px, 2, 0, 4) |
swizzle_bitops(x_B, 2, 4, 6) |
swizzle_bitops(y_px, 1, 2, 8) |
swizzle_bitops(x_B, 1, 6, 9) |
swizzle_bitops(y_px, 2, 3, 10);
return (uint8_t *) (base_addr + tiled_off);
}
uint8_t *linear_to_tileX_swizzle(const uint8_t * base_addr, uint32_t pitch, uint32_t x_B, uint32_t y_px)
{
const uint32_t cu = 9, cv = 3;
const uint32_t tile_id = (y_px >> cv) * (pitch >> cu) + (x_B >> cu);
/* The table below represents the mapping from coordinate (x_B, y_px) to
* byte offset in a 512x8px 1Bpp image:
*
* Bit ind : 11 10 9 8 7 6 5 4 3 2 1 0
* Tile-X : v2 v1 v0 u8 u7 u6 u5 u4 u3 u2 u1 u0
*/
uint32_t tiled_off;
tiled_off = tile_id * 4096 |
swizzle_bitops(x_B, 9, 0, 0) |
swizzle_bitops(y_px, 3, 0, 9);
return (uint8_t *) (base_addr + tiled_off);
}
uint8_t *linear_to_tileW_swizzle(const uint8_t *base_addr, uint32_t pitch, uint32_t x_B, uint32_t y_px)
{
/* TileW is a special case with doubled physical tile width due to HW
* programming requirements (see isl_tiling_get_info() in
* src/intel/isl/isl.c)
*/
pitch /= 2;
const uint32_t cu = 6, cv = 6;
const uint32_t tile_id = (y_px >> cv) * (pitch >> cu) + (x_B >> cu);
/* The table below represents the mapping from coordinate (x_B, y_px) to
* byte offset in a 64x64px 1Bpp image:
*
* Bit ind : 11 10 9 8 7 6 5 4 3 2 1 0
* Tile-W : u5 u4 u3 v5 v4 v3 v2 u2 v1 u1 v0 u0
*/
uint32_t tiled_off;
tiled_off = tile_id * 4096 |
swizzle_bitops(x_B, 1, 0, 0) |
swizzle_bitops(y_px, 1, 0, 1) |
swizzle_bitops(x_B, 1, 1, 2) |
swizzle_bitops(y_px, 1, 1, 3) |
swizzle_bitops(x_B, 1, 2, 4) |
swizzle_bitops(y_px, 4, 2, 5) |
swizzle_bitops(x_B, 3, 3, 9);
return (uint8_t *) (base_addr + tiled_off);
}
struct tile_swizzle_ops swizzle_opers[] = {
{ISL_TILING_Y0, linear_to_tileY_swizzle},
{ISL_TILING_4, linear_to_tile4_swizzle},
{ISL_TILING_X, linear_to_tileX_swizzle},
{ISL_TILING_W, linear_to_tileW_swizzle},
};
class tileTFixture: public ::testing::Test {
protected:
uint32_t x_max_el;
uint32_t y_max_el;
uint8_t *buf_dst;
uint8_t *buf_src;
uint32_t buf_dst_size_B;
uint32_t buf_src_size_B;
uint32_t tiled_pitch_B, tiled_height;
uint32_t tiled_size_B;
uint32_t linear_pitch_B;
uint32_t linear_sz;
uint32_t fmt_bs; /* format bytes per block */
TILE_CONV conv;
struct tile_swizzle_ops ops;
bool print_results;
struct isl_tile_info tile_info;
public:
void test_setup(TILE_CONV convert, enum isl_tiling tiling_fmt,
enum isl_format format,
uint32_t max_width, uint32_t max_height);
void TearDown();
uint32_t swizzle_bitops(uint32_t num, uint8_t field,
uint8_t curr_ind, uint8_t swizzle_ind);
void bounded_byte_fill(uint32_t x1, uint32_t x2, uint32_t y1, uint32_t y2);
void hex_oword_print(const uint8_t *buf, uint32_t size);
void convert_texture(uint32_t x1, uint32_t x2, uint32_t y1, uint32_t y2);
void compare_conv_result(uint32_t x1, uint32_t x2, uint32_t y1, uint32_t y2);
void run_test(uint32_t x1, uint32_t x2, uint32_t y1, uint32_t y2);
};
class tileYFixture : public tileTFixture,
public ::testing::WithParamInterface<std::tuple<int, int,
int, int>>
{};
class tile4Fixture : public tileTFixture,
public ::testing::WithParamInterface<std::tuple<int, int,
int, int>>
{};
class tileXFixture : public tileTFixture,
public ::testing::WithParamInterface<std::tuple<int, int,
int, int>>
{};
class tileWFixture : public tileTFixture,
public ::testing::WithParamInterface<std::tuple<int, int,
int, int>>
{};
void tileTFixture::test_setup(TILE_CONV convert,
enum isl_tiling tiling_fmt,
enum isl_format format,
uint32_t max_width,
uint32_t max_height)
{
print_results = debug_get_bool_option("ISL_TEST_DEBUG", false);
const struct isl_format_layout *fmtl = isl_format_get_layout(format);
conv = convert;
fmt_bs = fmtl->bpb / 8;
ops.tiling = tiling_fmt;
isl_tiling_get_info(tiling_fmt, ISL_SURF_DIM_2D, ISL_MSAA_LAYOUT_NONE,
fmtl->bpb, 1 , &tile_info);
x_max_el = align(max_width, tile_info.logical_extent_el.w);
y_max_el = align(max_height, tile_info.logical_extent_el.h);
tiled_pitch_B = (x_max_el * (fmt_bs / (tile_info.format_bpb / 8)) /
tile_info.logical_extent_el.w) *
tile_info.phys_extent_B.w;
tiled_height = y_max_el / tile_info.logical_extent_el.h *
tile_info.phys_extent_B.h;
tiled_size_B = tiled_pitch_B * tiled_height;
linear_pitch_B = x_max_el * fmt_bs;
linear_sz = linear_pitch_B * y_max_el;
buf_dst_size_B = convert == LIN_TO_TILE ? tiled_size_B : linear_sz;
buf_src_size_B = convert == LIN_TO_TILE ? linear_sz : tiled_size_B;
buf_src = (uint8_t *) calloc(buf_src_size_B, sizeof(uint8_t));
ASSERT_TRUE(buf_src != nullptr);
buf_dst = (uint8_t *) calloc(buf_dst_size_B, sizeof(uint8_t));
ASSERT_TRUE(buf_src != nullptr);
for (uint8_t i = 0; i < ARRAY_SIZE(swizzle_opers); i++)
if (ops.tiling == swizzle_opers[i].tiling)
ops.linear_to_tile_swizzle = swizzle_opers[i].linear_to_tile_swizzle;
memset(buf_src, 0xcc, buf_src_size_B);
memset(buf_dst, 0xcc, buf_dst_size_B);
}
void tileTFixture::TearDown()
{
free(buf_src);
buf_src = nullptr;
free(buf_dst);
buf_dst = nullptr;
}
void tileTFixture::bounded_byte_fill(uint32_t x1_el, uint32_t x2_el,
uint32_t y1_el, uint32_t y2_el)
{
for(auto y_el = y1_el; y_el < y2_el; y_el++)
for (auto x_b = x1_el * fmt_bs; x_b < x2_el * fmt_bs; x_b++)
if (conv == LIN_TO_TILE) {
*(buf_src + LIN_OFF(y_el, linear_pitch_B, x_b)) = LIN_OFF(y_el, linear_pitch_B, x_b)%16;
} else {
*(ops.linear_to_tile_swizzle(buf_src, tiled_pitch_B, x_b, y_el)) =
LIN_OFF(y_el, linear_pitch_B, x_b)%16;
}
}
void tileTFixture::hex_oword_print(const uint8_t *buf, uint32_t size)
{
uint64_t *itr;
uint32_t i;
for (itr = (uint64_t *)buf, i=0; itr < (uint64_t *)(buf + size); i++) {
fprintf(stdout, "%.16" PRIx64 "%.16" PRIx64, util_bswap64(*(itr)), util_bswap64(*(itr+1)));
itr = itr+2;
if((i+1) % 8 == 0 && i > 0)
printf("\n");
else
printf(" ");
}
}
void tileTFixture::convert_texture(uint32_t x1_el, uint32_t x2_el, uint32_t y1_el, uint32_t y2_el)
{
if (print_results) {
printf("/************** Printing src ***************/\n");
hex_oword_print((const uint8_t *)buf_src, buf_src_size_B);
}
uint32_t linear_offset_B = LIN_OFF(y1_el, linear_pitch_B, x1_el * fmt_bs);
if (conv == LIN_TO_TILE)
isl_memcpy_linear_to_tiled(x1_el * fmt_bs, x2_el * fmt_bs, y1_el, y2_el,
(char *)buf_dst,
(const char *)buf_src + linear_offset_B,
tiled_pitch_B, linear_pitch_B,
0, ops.tiling, ISL_MEMCPY);
else
isl_memcpy_tiled_to_linear(x1_el * fmt_bs, x2_el * fmt_bs, y1_el, y2_el,
(char *)buf_dst + linear_offset_B,
(const char *)buf_src,
linear_pitch_B, tiled_pitch_B,
0, ops.tiling, ISL_MEMCPY);
if (print_results) {
printf("/************** Printing dest **************/\n");
hex_oword_print((const uint8_t *) buf_dst, buf_dst_size_B);
}
}
void tileTFixture::compare_conv_result(uint32_t x1_el, uint32_t x2_el,
uint32_t y1_el, uint32_t y2_el)
{
for (uint32_t y_el = 0; y_el < y_max_el; y_el++) {
for (uint32_t x_el = 0; x_el < x_max_el; x_el++) {
for (uint32_t b = 0; b < fmt_bs; b++) {
uint32_t x_b = x_el * fmt_bs + b;
if (x_el < x1_el || x_el >= x2_el || y_el < y1_el || y_el >= y2_el) {
if (conv == LIN_TO_TILE) {
EXPECT_EQ(*(buf_src + LIN_OFF(y_el, linear_pitch_B, x_b)), 0xcc)
<< "Not matching for x:" << x_el << " and y:" << y_el << std::endl;
} else {
EXPECT_EQ(*(buf_dst + LIN_OFF(y_el, linear_pitch_B, x_b)), 0xcc)
<< "Not matching for x:" << x_el << " and y:" << y_el << std::endl;
}
} else {
if (conv == LIN_TO_TILE) {
EXPECT_EQ(*(buf_src + LIN_OFF(y_el, linear_pitch_B, x_b)),
*(ops.linear_to_tile_swizzle(buf_dst, tiled_pitch_B, x_b, y_el)))
<< "Not matching for x:" << x_el << " and y:" << y_el << std::endl;
} else {
EXPECT_EQ(*(buf_dst + LIN_OFF(y_el, linear_pitch_B, x_b)),
*(ops.linear_to_tile_swizzle(buf_src, tiled_pitch_B, x_b, y_el)))
<< "Not matching for x:" << x_el << " and y:" << y_el << std::endl;
}
}
}
}
}
}
void tileTFixture::run_test(uint32_t x1, uint32_t x2,
uint32_t y1, uint32_t y2)
{
bounded_byte_fill(x1, x2, y1, y2);
convert_texture(x1, x2, y1, y2);
compare_conv_result(x1, x2, y1, y2);
}
TEST_P(tileYFixture, lintotile)
{
auto [x1, x2, y1, y2] = GetParam();
test_setup(LIN_TO_TILE, ISL_TILING_Y0, IMAGE_FORMAT, x2, y2);
if (print_results)
printf("Coordinates: x1=%d x2=%d y1=%d y2=%d \n", x1, x2, y1, y2);
run_test(x1, x2, y1, y2);
}
TEST_P(tileYFixture, tiletolin)
{
auto [x1, x2, y1, y2] = GetParam();
test_setup(TILE_TO_LIN, ISL_TILING_Y0, IMAGE_FORMAT, x2, y2);
if (print_results)
printf("Coordinates: x1=%d x2=%d y1=%d y2=%d \n", x1, x2, y1, y2);
run_test(x1, x2, y1, y2);
}
TEST_P(tile4Fixture, lintotile)
{
auto [x1, x2, y1, y2] = GetParam();
test_setup(LIN_TO_TILE, ISL_TILING_4, IMAGE_FORMAT, x2, y2);
if (print_results)
printf("Coordinates: x1=%d x2=%d y1=%d y2=%d \n", x1, x2, y1, y2);
run_test(x1, x2, y1, y2);
}
TEST_P(tile4Fixture, tiletolin)
{
auto [x1, x2, y1, y2] = GetParam();
test_setup(TILE_TO_LIN, ISL_TILING_4, IMAGE_FORMAT, x2, y2);
if (print_results)
printf("Coordinates: x1=%d x2=%d y1=%d y2=%d \n", x1, x2, y1, y2);
run_test(x1, x2, y1, y2);
}
TEST_P(tileXFixture, lintotile)
{
auto [x1, x2, y1, y2] = GetParam();
test_setup(LIN_TO_TILE, ISL_TILING_X, IMAGE_FORMAT, x2, y2);
if (print_results)
printf("Coordinates: x1=%d x2=%d y1=%d y2=%d \n", x1, x2, y1, y2);
run_test(x1, x2, y1, y2);
}
TEST_P(tileXFixture, tiletolin)
{
auto [x1, x2, y1, y2] = GetParam();
test_setup(TILE_TO_LIN, ISL_TILING_X, IMAGE_FORMAT, x2, y2);
if (print_results)
printf("Coordinates: x1=%d x2=%d y1=%d y2=%d \n", x1, x2, y1, y2);
run_test(x1, x2, y1, y2);
}
TEST_P(tileWFixture, lintotile)
{
auto [x1, x2, y1, y2] = GetParam();
test_setup(LIN_TO_TILE, ISL_TILING_W, TILEW_IMAGE_FORMAT, x2, y2);
if (print_results)
printf("Coordinates: x1=%d x2=%d y1=%d y2=%d \n", x1, x2, y1, y2);
run_test(x1, x2, y1, y2);
}
TEST_P(tileWFixture, tiletolin)
{
auto [x1, x2, y1, y2] = GetParam();
test_setup(TILE_TO_LIN, ISL_TILING_W, TILEW_IMAGE_FORMAT, x2, y2);
if (print_results)
printf("Coordinates: x1=%d x2=%d y1=%d y2=%d \n", x1, x2, y1, y2);
run_test(x1, x2, y1, y2);
}
INSTANTIATE_TEST_SUITE_P(tileY, tileYFixture, testing::Values(TILE_COORDINATES,
FULL_TILEY_COORDINATES));
INSTANTIATE_TEST_SUITE_P(tile4, tile4Fixture, testing::Values(TILE_COORDINATES,
FULL_TILEY_COORDINATES));
INSTANTIATE_TEST_SUITE_P(tileX, tileXFixture, testing::Values(TILE_COORDINATES,
FULL_TILEX_COORDINATES));
INSTANTIATE_TEST_SUITE_P(tileW, tileWFixture, testing::Values(TILE_COORDINATES,
FULL_TILEW_COORDINATES));