merge gallium docs into main docs
Reviewed-by: Eric Engestrom <eric@engestrom.ch> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/5706>
This commit is contained in:
committed by
Marge Bot
parent
cb11900cb6
commit
2f81398187
@@ -0,0 +1,31 @@
|
||||
# formatting.py
|
||||
# Sphinx extension providing formatting for Gallium-specific data
|
||||
# (c) Corbin Simpson 2010
|
||||
# Public domain to the extent permitted; contact author for special licensing
|
||||
|
||||
import docutils.nodes
|
||||
import sphinx.addnodes
|
||||
|
||||
def parse_envvar(env, sig, signode):
|
||||
envvar, t, default = sig.split(" ", 2)
|
||||
envvar = envvar.strip().upper()
|
||||
t = " Type: %s" % t.strip(" <>").lower()
|
||||
default = " Default: %s" % default.strip(" ()")
|
||||
signode += sphinx.addnodes.desc_name(envvar, envvar)
|
||||
signode += sphinx.addnodes.desc_type(t, t)
|
||||
signode += sphinx.addnodes.desc_annotation(default, default)
|
||||
return envvar
|
||||
|
||||
def parse_opcode(env, sig, signode):
|
||||
opcode, desc = sig.split("-", 1)
|
||||
opcode = opcode.strip().upper()
|
||||
desc = " (%s)" % desc.strip()
|
||||
signode += sphinx.addnodes.desc_name(opcode, opcode)
|
||||
signode += sphinx.addnodes.desc_annotation(desc, desc)
|
||||
return opcode
|
||||
|
||||
def setup(app):
|
||||
app.add_object_type("envvar", "envvar", "%s (environment variable)",
|
||||
parse_envvar)
|
||||
app.add_object_type("opcode", "opcode", "%s (TGSI opcode)",
|
||||
parse_opcode)
|
||||
+8
-4
@@ -20,9 +20,13 @@ import sphinx_rtd_theme
|
||||
# add these directories to sys.path here. If the directory is relative to the
|
||||
# documentation root, use os.path.abspath to make it absolute, like shown here.
|
||||
#
|
||||
# import os
|
||||
# import sys
|
||||
# sys.path.insert(0, os.path.abspath('.'))
|
||||
import os
|
||||
import sys
|
||||
|
||||
# If extensions (or modules to document with autodoc) are in another directory,
|
||||
# add these directories to sys.path here. If the directory is relative to the
|
||||
# documentation root, use os.path.abspath to make it absolute, like shown here.
|
||||
sys.path.append(os.path.abspath('_exts'))
|
||||
|
||||
|
||||
# -- General configuration ------------------------------------------------
|
||||
@@ -34,7 +38,7 @@ import sphinx_rtd_theme
|
||||
# Add any Sphinx extension module names here, as strings. They can be
|
||||
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
|
||||
# ones.
|
||||
extensions = []
|
||||
extensions = ['sphinx.ext.graphviz', 'formatting']
|
||||
|
||||
# Add any paths that contain templates here, relative to this directory.
|
||||
templates_path = ['_templates']
|
||||
|
||||
@@ -68,6 +68,7 @@
|
||||
release-calendar
|
||||
sourcedocs
|
||||
dispatch
|
||||
gallium/index
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
@@ -0,0 +1,912 @@
|
||||
.. _context:
|
||||
|
||||
Context
|
||||
=======
|
||||
|
||||
A Gallium rendering context encapsulates the state which effects 3D
|
||||
rendering such as blend state, depth/stencil state, texture samplers,
|
||||
etc.
|
||||
|
||||
Note that resource/texture allocation is not per-context but per-screen.
|
||||
|
||||
|
||||
Methods
|
||||
-------
|
||||
|
||||
CSO State
|
||||
^^^^^^^^^
|
||||
|
||||
All Constant State Object (CSO) state is created, bound, and destroyed,
|
||||
with triplets of methods that all follow a specific naming scheme.
|
||||
For example, ``create_blend_state``, ``bind_blend_state``, and
|
||||
``destroy_blend_state``.
|
||||
|
||||
CSO objects handled by the context object:
|
||||
|
||||
* :ref:`Blend`: ``*_blend_state``
|
||||
* :ref:`Sampler`: Texture sampler states are bound separately for fragment,
|
||||
vertex, geometry and compute shaders with the ``bind_sampler_states``
|
||||
function. The ``start`` and ``num_samplers`` parameters indicate a range
|
||||
of samplers to change. NOTE: at this time, start is always zero and
|
||||
the CSO module will always replace all samplers at once (no sub-ranges).
|
||||
This may change in the future.
|
||||
* :ref:`Rasterizer`: ``*_rasterizer_state``
|
||||
* :ref:`depth-stencil-alpha`: ``*_depth_stencil_alpha_state``
|
||||
* :ref:`Shader`: These are create, bind and destroy methods for vertex,
|
||||
fragment and geometry shaders.
|
||||
* :ref:`vertexelements`: ``*_vertex_elements_state``
|
||||
|
||||
|
||||
Resource Binding State
|
||||
^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
This state describes how resources in various flavours (textures,
|
||||
buffers, surfaces) are bound to the driver.
|
||||
|
||||
|
||||
* ``set_constant_buffer`` sets a constant buffer to be used for a given shader
|
||||
type. index is used to indicate which buffer to set (some apis may allow
|
||||
multiple ones to be set, and binding a specific one later, though drivers
|
||||
are mostly restricted to the first one right now).
|
||||
|
||||
* ``set_framebuffer_state``
|
||||
|
||||
* ``set_vertex_buffers``
|
||||
|
||||
|
||||
Non-CSO State
|
||||
^^^^^^^^^^^^^
|
||||
|
||||
These pieces of state are too small, variable, and/or trivial to have CSO
|
||||
objects. They all follow simple, one-method binding calls, e.g.
|
||||
``set_blend_color``.
|
||||
|
||||
* ``set_stencil_ref`` sets the stencil front and back reference values
|
||||
which are used as comparison values in stencil test.
|
||||
* ``set_blend_color``
|
||||
* ``set_sample_mask`` sets the per-context multisample sample mask. Note
|
||||
that this takes effect even if multisampling is not explicitly enabled if
|
||||
the frambuffer surface(s) are multisampled. Also, this mask is AND-ed
|
||||
with the optional fragment shader sample mask output (when emitted).
|
||||
* ``set_sample_locations`` sets the sample locations used for rasterization.
|
||||
```get_sample_position``` still returns the default locations. When NULL,
|
||||
the default locations are used.
|
||||
* ``set_min_samples`` sets the minimum number of samples that must be run.
|
||||
* ``set_clip_state``
|
||||
* ``set_polygon_stipple``
|
||||
* ``set_scissor_states`` sets the bounds for the scissor test, which culls
|
||||
pixels before blending to render targets. If the :ref:`Rasterizer` does
|
||||
not have the scissor test enabled, then the scissor bounds never need to
|
||||
be set since they will not be used. Note that scissor xmin and ymin are
|
||||
inclusive, but xmax and ymax are exclusive. The inclusive ranges in x
|
||||
and y would be [xmin..xmax-1] and [ymin..ymax-1]. The number of scissors
|
||||
should be the same as the number of set viewports and can be up to
|
||||
PIPE_MAX_VIEWPORTS.
|
||||
* ``set_viewport_states``
|
||||
* ``set_window_rectangles`` sets the window rectangles to be used for
|
||||
rendering, as defined by GL_EXT_window_rectangles. There are two
|
||||
modes - include and exclude, which define whether the supplied
|
||||
rectangles are to be used for including fragments or excluding
|
||||
them. All of the rectangles are ORed together, so in exclude mode,
|
||||
any fragment inside any rectangle would be culled, while in include
|
||||
mode, any fragment outside all rectangles would be culled. xmin/ymin
|
||||
are inclusive, while xmax/ymax are exclusive (same as scissor states
|
||||
above). Note that this only applies to draws, not clears or
|
||||
blits. (Blits have their own way to pass the requisite rectangles
|
||||
in.)
|
||||
* ``set_tess_state`` configures the default tessellation parameters:
|
||||
|
||||
* ``default_outer_level`` is the default value for the outer tessellation
|
||||
levels. This corresponds to GL's ``PATCH_DEFAULT_OUTER_LEVEL``.
|
||||
* ``default_inner_level`` is the default value for the inner tessellation
|
||||
levels. This corresponds to GL's ``PATCH_DEFAULT_INNER_LEVEL``.
|
||||
|
||||
* ``set_debug_callback`` sets the callback to be used for reporting
|
||||
various debug messages, eventually reported via KHR_debug and
|
||||
similar mechanisms.
|
||||
|
||||
Samplers
|
||||
^^^^^^^^
|
||||
|
||||
pipe_sampler_state objects control how textures are sampled (coordinate
|
||||
wrap modes, interpolation modes, etc). Note that samplers are not used
|
||||
for texture buffer objects. That is, pipe_context::bind_sampler_views()
|
||||
will not bind a sampler if the corresponding sampler view refers to a
|
||||
PIPE_BUFFER resource.
|
||||
|
||||
Sampler Views
|
||||
^^^^^^^^^^^^^
|
||||
|
||||
These are the means to bind textures to shader stages. To create one, specify
|
||||
its format, swizzle and LOD range in sampler view template.
|
||||
|
||||
If texture format is different than template format, it is said the texture
|
||||
is being cast to another format. Casting can be done only between compatible
|
||||
formats, that is formats that have matching component order and sizes.
|
||||
|
||||
Swizzle fields specify the way in which fetched texel components are placed
|
||||
in the result register. For example, ``swizzle_r`` specifies what is going to be
|
||||
placed in first component of result register.
|
||||
|
||||
The ``first_level`` and ``last_level`` fields of sampler view template specify
|
||||
the LOD range the texture is going to be constrained to. Note that these
|
||||
values are in addition to the respective min_lod, max_lod values in the
|
||||
pipe_sampler_state (that is if min_lod is 2.0, and first_level 3, the first mip
|
||||
level used for sampling from the resource is effectively the fifth).
|
||||
|
||||
The ``first_layer`` and ``last_layer`` fields specify the layer range the
|
||||
texture is going to be constrained to. Similar to the LOD range, this is added
|
||||
to the array index which is used for sampling.
|
||||
|
||||
* ``set_sampler_views`` binds an array of sampler views to a shader stage.
|
||||
Every binding point acquires a reference
|
||||
to a respective sampler view and releases a reference to the previous
|
||||
sampler view.
|
||||
|
||||
Sampler views outside of ``[start_slot, start_slot + num_views)`` are
|
||||
unmodified. If ``views`` is NULL, the behavior is the same as if
|
||||
``views[n]`` was NULL for the entire range, ie. releasing the reference
|
||||
for all the sampler views in the specified range.
|
||||
|
||||
* ``create_sampler_view`` creates a new sampler view. ``texture`` is associated
|
||||
with the sampler view which results in sampler view holding a reference
|
||||
to the texture. Format specified in template must be compatible
|
||||
with texture format.
|
||||
|
||||
* ``sampler_view_destroy`` destroys a sampler view and releases its reference
|
||||
to associated texture.
|
||||
|
||||
Hardware Atomic buffers
|
||||
^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Buffers containing hw atomics are required to support the feature
|
||||
on some drivers.
|
||||
|
||||
Drivers that require this need to fill the ``set_hw_atomic_buffers`` method.
|
||||
|
||||
Shader Resources
|
||||
^^^^^^^^^^^^^^^^
|
||||
|
||||
Shader resources are textures or buffers that may be read or written
|
||||
from a shader without an associated sampler. This means that they
|
||||
have no support for floating point coordinates, address wrap modes or
|
||||
filtering.
|
||||
|
||||
There are 2 types of shader resources: buffers and images.
|
||||
|
||||
Buffers are specified using the ``set_shader_buffers`` method.
|
||||
|
||||
Images are specified using the ``set_shader_images`` method. When binding
|
||||
images, the ``level``, ``first_layer`` and ``last_layer`` pipe_image_view
|
||||
fields specify the mipmap level and the range of layers the image will be
|
||||
constrained to.
|
||||
|
||||
Surfaces
|
||||
^^^^^^^^
|
||||
|
||||
These are the means to use resources as color render targets or depthstencil
|
||||
attachments. To create one, specify the mip level, the range of layers, and
|
||||
the bind flags (either PIPE_BIND_DEPTH_STENCIL or PIPE_BIND_RENDER_TARGET).
|
||||
Note that layer values are in addition to what is indicated by the geometry
|
||||
shader output variable XXX_FIXME (that is if first_layer is 3 and geometry
|
||||
shader indicates index 2, the 5th layer of the resource will be used). These
|
||||
first_layer and last_layer parameters will only be used for 1d array, 2d array,
|
||||
cube, and 3d textures otherwise they are 0.
|
||||
|
||||
* ``create_surface`` creates a new surface.
|
||||
|
||||
* ``surface_destroy`` destroys a surface and releases its reference to the
|
||||
associated resource.
|
||||
|
||||
Stream output targets
|
||||
^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Stream output, also known as transform feedback, allows writing the primitives
|
||||
produced by the vertex pipeline to buffers. This is done after the geometry
|
||||
shader or vertex shader if no geometry shader is present.
|
||||
|
||||
The stream output targets are views into buffer resources which can be bound
|
||||
as stream outputs and specify a memory range where it's valid to write
|
||||
primitives. The pipe driver must implement memory protection such that any
|
||||
primitives written outside of the specified memory range are discarded.
|
||||
|
||||
Two stream output targets can use the same resource at the same time, but
|
||||
with a disjoint memory range.
|
||||
|
||||
Additionally, the stream output target internally maintains the offset
|
||||
into the buffer which is incremented everytime something is written to it.
|
||||
The internal offset is equal to how much data has already been written.
|
||||
It can be stored in device memory and the CPU actually doesn't have to query
|
||||
it.
|
||||
|
||||
The stream output target can be used in a draw command to provide
|
||||
the vertex count. The vertex count is derived from the internal offset
|
||||
discussed above.
|
||||
|
||||
* ``create_stream_output_target`` create a new target.
|
||||
|
||||
* ``stream_output_target_destroy`` destroys a target. Users of this should
|
||||
use pipe_so_target_reference instead.
|
||||
|
||||
* ``set_stream_output_targets`` binds stream output targets. The parameter
|
||||
offset is an array which specifies the internal offset of the buffer. The
|
||||
internal offset is, besides writing, used for reading the data during the
|
||||
draw_auto stage, i.e. it specifies how much data there is in the buffer
|
||||
for the purposes of the draw_auto stage. -1 means the buffer should
|
||||
be appended to, and everything else sets the internal offset.
|
||||
|
||||
NOTE: The currently-bound vertex or geometry shader must be compiled with
|
||||
the properly-filled-in structure pipe_stream_output_info describing which
|
||||
outputs should be written to buffers and how. The structure is part of
|
||||
pipe_shader_state.
|
||||
|
||||
Clearing
|
||||
^^^^^^^^
|
||||
|
||||
Clear is one of the most difficult concepts to nail down to a single
|
||||
interface (due to both different requirements from APIs and also driver/hw
|
||||
specific differences).
|
||||
|
||||
``clear`` initializes some or all of the surfaces currently bound to
|
||||
the framebuffer to particular RGBA, depth, or stencil values.
|
||||
Currently, this does not take into account color or stencil write masks (as
|
||||
used by GL), and always clears the whole surfaces (no scissoring as used by
|
||||
GL clear or explicit rectangles like d3d9 uses). It can, however, also clear
|
||||
only depth or stencil in a combined depth/stencil surface.
|
||||
If a surface includes several layers then all layers will be cleared.
|
||||
|
||||
``clear_render_target`` clears a single color rendertarget with the specified
|
||||
color value. While it is only possible to clear one surface at a time (which can
|
||||
include several layers), this surface need not be bound to the framebuffer.
|
||||
If render_condition_enabled is false, any current rendering condition is ignored
|
||||
and the clear will be unconditional.
|
||||
|
||||
``clear_depth_stencil`` clears a single depth, stencil or depth/stencil surface
|
||||
with the specified depth and stencil values (for combined depth/stencil buffers,
|
||||
it is also possible to only clear one or the other part). While it is only
|
||||
possible to clear one surface at a time (which can include several layers),
|
||||
this surface need not be bound to the framebuffer.
|
||||
If render_condition_enabled is false, any current rendering condition is ignored
|
||||
and the clear will be unconditional.
|
||||
|
||||
``clear_texture`` clears a non-PIPE_BUFFER resource's specified level
|
||||
and bounding box with a clear value provided in that resource's native
|
||||
format.
|
||||
|
||||
``clear_buffer`` clears a PIPE_BUFFER resource with the specified clear value
|
||||
(which may be multiple bytes in length). Logically this is a memset with a
|
||||
multi-byte element value starting at offset bytes from resource start, going
|
||||
for size bytes. It is guaranteed that size % clear_value_size == 0.
|
||||
|
||||
Evaluating Depth Buffers
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
``evaluate_depth_buffer`` is a hint to decompress the current depth buffer
|
||||
assuming the current sample locations to avoid problems that could arise when
|
||||
using programmable sample locations.
|
||||
|
||||
If a depth buffer is rendered with different sample location state than
|
||||
what is current at the time of reading the depth buffer, the values may differ
|
||||
because depth buffer compression can depend the sample locations.
|
||||
|
||||
|
||||
Uploading
|
||||
^^^^^^^^^
|
||||
|
||||
For simple single-use uploads, use ``pipe_context::stream_uploader`` or
|
||||
``pipe_context::const_uploader``. The latter should be used for uploading
|
||||
constants, while the former should be used for uploading everything else.
|
||||
PIPE_USAGE_STREAM is implied in both cases, so don't use the uploaders
|
||||
for static allocations.
|
||||
|
||||
Usage:
|
||||
|
||||
Call u_upload_alloc or u_upload_data as many times as you want. After you are
|
||||
done, call u_upload_unmap. If the driver doesn't support persistent mappings,
|
||||
u_upload_unmap makes sure the previously mapped memory is unmapped.
|
||||
|
||||
Gotchas:
|
||||
- Always fill the memory immediately after u_upload_alloc. Any following call
|
||||
to u_upload_alloc and u_upload_data can unmap memory returned by previous
|
||||
u_upload_alloc.
|
||||
- Don't interleave calls using stream_uploader and const_uploader. If you use
|
||||
one of them, do the upload, unmap, and only then can you use the other one.
|
||||
|
||||
|
||||
Drawing
|
||||
^^^^^^^
|
||||
|
||||
``draw_vbo`` draws a specified primitive. The primitive mode and other
|
||||
properties are described by ``pipe_draw_info``.
|
||||
|
||||
The ``mode``, ``start``, and ``count`` fields of ``pipe_draw_info`` specify the
|
||||
the mode of the primitive and the vertices to be fetched, in the range between
|
||||
``start`` to ``start``+``count``-1, inclusive.
|
||||
|
||||
Every instance with instanceID in the range between ``start_instance`` and
|
||||
``start_instance``+``instance_count``-1, inclusive, will be drawn.
|
||||
|
||||
If ``index_size`` != 0, all vertex indices will be looked up from the index
|
||||
buffer.
|
||||
|
||||
In indexed draw, ``min_index`` and ``max_index`` respectively provide a lower
|
||||
and upper bound of the indices contained in the index buffer inside the range
|
||||
between ``start`` to ``start``+``count``-1. This allows the driver to
|
||||
determine which subset of vertices will be referenced during te draw call
|
||||
without having to scan the index buffer. Providing a over-estimation of the
|
||||
the true bounds, for example, a ``min_index`` and ``max_index`` of 0 and
|
||||
0xffffffff respectively, must give exactly the same rendering, albeit with less
|
||||
performance due to unreferenced vertex buffers being unnecessarily DMA'ed or
|
||||
processed. Providing a underestimation of the true bounds will result in
|
||||
undefined behavior, but should not result in program or system failure.
|
||||
|
||||
In case of non-indexed draw, ``min_index`` should be set to
|
||||
``start`` and ``max_index`` should be set to ``start``+``count``-1.
|
||||
|
||||
``index_bias`` is a value added to every vertex index after lookup and before
|
||||
fetching vertex attributes.
|
||||
|
||||
When drawing indexed primitives, the primitive restart index can be
|
||||
used to draw disjoint primitive strips. For example, several separate
|
||||
line strips can be drawn by designating a special index value as the
|
||||
restart index. The ``primitive_restart`` flag enables/disables this
|
||||
feature. The ``restart_index`` field specifies the restart index value.
|
||||
|
||||
When primitive restart is in use, array indexes are compared to the
|
||||
restart index before adding the index_bias offset.
|
||||
|
||||
If a given vertex element has ``instance_divisor`` set to 0, it is said
|
||||
it contains per-vertex data and effective vertex attribute address needs
|
||||
to be recalculated for every index.
|
||||
|
||||
attribAddr = ``stride`` * index + ``src_offset``
|
||||
|
||||
If a given vertex element has ``instance_divisor`` set to non-zero,
|
||||
it is said it contains per-instance data and effective vertex attribute
|
||||
address needs to recalculated for every ``instance_divisor``-th instance.
|
||||
|
||||
attribAddr = ``stride`` * instanceID / ``instance_divisor`` + ``src_offset``
|
||||
|
||||
In the above formulas, ``src_offset`` is taken from the given vertex element
|
||||
and ``stride`` is taken from a vertex buffer associated with the given
|
||||
vertex element.
|
||||
|
||||
The calculated attribAddr is used as an offset into the vertex buffer to
|
||||
fetch the attribute data.
|
||||
|
||||
The value of ``instanceID`` can be read in a vertex shader through a system
|
||||
value register declared with INSTANCEID semantic name.
|
||||
|
||||
|
||||
Queries
|
||||
^^^^^^^
|
||||
|
||||
Queries gather some statistic from the 3D pipeline over one or more
|
||||
draws. Queries may be nested, though not all gallium frontends exercise this.
|
||||
|
||||
Queries can be created with ``create_query`` and deleted with
|
||||
``destroy_query``. To start a query, use ``begin_query``, and when finished,
|
||||
use ``end_query`` to end the query.
|
||||
|
||||
``create_query`` takes a query type (``PIPE_QUERY_*``), as well as an index,
|
||||
which is the vertex stream for ``PIPE_QUERY_PRIMITIVES_GENERATED`` and
|
||||
``PIPE_QUERY_PRIMITIVES_EMITTED``, and allocates a query structure.
|
||||
|
||||
``begin_query`` will clear/reset previous query results.
|
||||
|
||||
``get_query_result`` is used to retrieve the results of a query. If
|
||||
the ``wait`` parameter is TRUE, then the ``get_query_result`` call
|
||||
will block until the results of the query are ready (and TRUE will be
|
||||
returned). Otherwise, if the ``wait`` parameter is FALSE, the call
|
||||
will not block and the return value will be TRUE if the query has
|
||||
completed or FALSE otherwise.
|
||||
|
||||
``get_query_result_resource`` is used to store the result of a query into
|
||||
a resource without synchronizing with the CPU. This write will optionally
|
||||
wait for the query to complete, and will optionally write whether the value
|
||||
is available instead of the value itself.
|
||||
|
||||
``set_active_query_state`` Set whether all current non-driver queries except
|
||||
TIME_ELAPSED are active or paused.
|
||||
|
||||
The interface currently includes the following types of queries:
|
||||
|
||||
``PIPE_QUERY_OCCLUSION_COUNTER`` counts the number of fragments which
|
||||
are written to the framebuffer without being culled by
|
||||
:ref:`depth-stencil-alpha` testing or shader KILL instructions.
|
||||
The result is an unsigned 64-bit integer.
|
||||
This query can be used with ``render_condition``.
|
||||
|
||||
In cases where a boolean result of an occlusion query is enough,
|
||||
``PIPE_QUERY_OCCLUSION_PREDICATE`` should be used. It is just like
|
||||
``PIPE_QUERY_OCCLUSION_COUNTER`` except that the result is a boolean
|
||||
value of FALSE for cases where COUNTER would result in 0 and TRUE
|
||||
for all other cases.
|
||||
This query can be used with ``render_condition``.
|
||||
|
||||
In cases where a conservative approximation of an occlusion query is enough,
|
||||
``PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE`` should be used. It behaves
|
||||
like ``PIPE_QUERY_OCCLUSION_PREDICATE``, except that it may return TRUE in
|
||||
additional, implementation-dependent cases.
|
||||
This query can be used with ``render_condition``.
|
||||
|
||||
``PIPE_QUERY_TIME_ELAPSED`` returns the amount of time, in nanoseconds,
|
||||
the context takes to perform operations.
|
||||
The result is an unsigned 64-bit integer.
|
||||
|
||||
``PIPE_QUERY_TIMESTAMP`` returns a device/driver internal timestamp,
|
||||
scaled to nanoseconds, recorded after all commands issued prior to
|
||||
``end_query`` have been processed.
|
||||
This query does not require a call to ``begin_query``.
|
||||
The result is an unsigned 64-bit integer.
|
||||
|
||||
``PIPE_QUERY_TIMESTAMP_DISJOINT`` can be used to check the
|
||||
internal timer resolution and whether the timestamp counter has become
|
||||
unreliable due to things like throttling etc. - only if this is FALSE
|
||||
a timestamp query (within the timestamp_disjoint query) should be trusted.
|
||||
The result is a 64-bit integer specifying the timer resolution in Hz,
|
||||
followed by a boolean value indicating whether the timestamp counter
|
||||
is discontinuous or disjoint.
|
||||
|
||||
``PIPE_QUERY_PRIMITIVES_GENERATED`` returns a 64-bit integer indicating
|
||||
the number of primitives processed by the pipeline (regardless of whether
|
||||
stream output is active or not).
|
||||
|
||||
``PIPE_QUERY_PRIMITIVES_EMITTED`` returns a 64-bit integer indicating
|
||||
the number of primitives written to stream output buffers.
|
||||
|
||||
``PIPE_QUERY_SO_STATISTICS`` returns 2 64-bit integers corresponding to
|
||||
the result of
|
||||
``PIPE_QUERY_PRIMITIVES_EMITTED`` and
|
||||
the number of primitives that would have been written to stream output buffers
|
||||
if they had infinite space available (primitives_storage_needed), in this order.
|
||||
XXX the 2nd value is equivalent to ``PIPE_QUERY_PRIMITIVES_GENERATED`` but it is
|
||||
unclear if it should be increased if stream output is not active.
|
||||
|
||||
``PIPE_QUERY_SO_OVERFLOW_PREDICATE`` returns a boolean value indicating
|
||||
whether a selected stream output target has overflowed as a result of the
|
||||
commands issued between ``begin_query`` and ``end_query``.
|
||||
This query can be used with ``render_condition``. The output stream is
|
||||
selected by the stream number passed to ``create_query``.
|
||||
|
||||
``PIPE_QUERY_SO_OVERFLOW_ANY_PREDICATE`` returns a boolean value indicating
|
||||
whether any stream output target has overflowed as a result of the commands
|
||||
issued between ``begin_query`` and ``end_query``. This query can be used
|
||||
with ``render_condition``, and its result is the logical OR of multiple
|
||||
``PIPE_QUERY_SO_OVERFLOW_PREDICATE`` queries, one for each stream output
|
||||
target.
|
||||
|
||||
``PIPE_QUERY_GPU_FINISHED`` returns a boolean value indicating whether
|
||||
all commands issued before ``end_query`` have completed. However, this
|
||||
does not imply serialization.
|
||||
This query does not require a call to ``begin_query``.
|
||||
|
||||
``PIPE_QUERY_PIPELINE_STATISTICS`` returns an array of the following
|
||||
64-bit integers:
|
||||
Number of vertices read from vertex buffers.
|
||||
Number of primitives read from vertex buffers.
|
||||
Number of vertex shader threads launched.
|
||||
Number of geometry shader threads launched.
|
||||
Number of primitives generated by geometry shaders.
|
||||
Number of primitives forwarded to the rasterizer.
|
||||
Number of primitives rasterized.
|
||||
Number of fragment shader threads launched.
|
||||
Number of tessellation control shader threads launched.
|
||||
Number of tessellation evaluation shader threads launched.
|
||||
If a shader type is not supported by the device/driver,
|
||||
the corresponding values should be set to 0.
|
||||
|
||||
``PIPE_QUERY_PIPELINE_STATISTICS_SINGLE`` returns a single counter from
|
||||
the ``PIPE_QUERY_PIPELINE_STATISTICS`` group. The specific counter must
|
||||
be selected when calling ``create_query`` by passing one of the
|
||||
``PIPE_STAT_QUERY`` enums as the query's ``index``.
|
||||
|
||||
Gallium does not guarantee the availability of any query types; one must
|
||||
always check the capabilities of the :ref:`Screen` first.
|
||||
|
||||
|
||||
Conditional Rendering
|
||||
^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
A drawing command can be skipped depending on the outcome of a query
|
||||
(typically an occlusion query, or streamout overflow predicate).
|
||||
The ``render_condition`` function specifies the query which should be checked
|
||||
prior to rendering anything. Functions always honoring render_condition include
|
||||
(and are limited to) draw_vbo and clear.
|
||||
The blit, clear_render_target and clear_depth_stencil functions (but
|
||||
not resource_copy_region, which seems inconsistent) can also optionally honor
|
||||
the current render condition.
|
||||
|
||||
If ``render_condition`` is called with ``query`` = NULL, conditional
|
||||
rendering is disabled and drawing takes place normally.
|
||||
|
||||
If ``render_condition`` is called with a non-null ``query`` subsequent
|
||||
drawing commands will be predicated on the outcome of the query.
|
||||
Commands will be skipped if ``condition`` is equal to the predicate result
|
||||
(for non-boolean queries such as OCCLUSION_QUERY, zero counts as FALSE,
|
||||
non-zero as TRUE).
|
||||
|
||||
If ``mode`` is PIPE_RENDER_COND_WAIT the driver will wait for the
|
||||
query to complete before deciding whether to render.
|
||||
|
||||
If ``mode`` is PIPE_RENDER_COND_NO_WAIT and the query has not yet
|
||||
completed, the drawing command will be executed normally. If the query
|
||||
has completed, drawing will be predicated on the outcome of the query.
|
||||
|
||||
If ``mode`` is PIPE_RENDER_COND_BY_REGION_WAIT or
|
||||
PIPE_RENDER_COND_BY_REGION_NO_WAIT rendering will be predicated as above
|
||||
for the non-REGION modes but in the case that an occlusion query returns
|
||||
a non-zero result, regions which were occluded may be ommitted by subsequent
|
||||
drawing commands. This can result in better performance with some GPUs.
|
||||
Normally, if the occlusion query returned a non-zero result subsequent
|
||||
drawing happens normally so fragments may be generated, shaded and
|
||||
processed even where they're known to be obscured.
|
||||
|
||||
|
||||
Flushing
|
||||
^^^^^^^^
|
||||
|
||||
``flush``
|
||||
|
||||
PIPE_FLUSH_END_OF_FRAME: Whether the flush marks the end of frame.
|
||||
|
||||
PIPE_FLUSH_DEFERRED: It is not required to flush right away, but it is required
|
||||
to return a valid fence. If fence_finish is called with the returned fence
|
||||
and the context is still unflushed, and the ctx parameter of fence_finish is
|
||||
equal to the context where the fence was created, fence_finish will flush
|
||||
the context.
|
||||
|
||||
PIPE_FLUSH_ASYNC: The flush is allowed to be asynchronous. Unlike
|
||||
``PIPE_FLUSH_DEFERRED``, the driver must still ensure that the returned fence
|
||||
will finish in finite time. However, subsequent operations in other contexts of
|
||||
the same screen are no longer guaranteed to happen after the flush. Drivers
|
||||
which use this flag must implement pipe_context::fence_server_sync.
|
||||
|
||||
PIPE_FLUSH_HINT_FINISH: Hints to the driver that the caller will immediately
|
||||
wait for the returned fence.
|
||||
|
||||
Additional flags may be set together with ``PIPE_FLUSH_DEFERRED`` for even
|
||||
finer-grained fences. Note that as a general rule, GPU caches may not have been
|
||||
flushed yet when these fences are signaled. Drivers are free to ignore these
|
||||
flags and create normal fences instead. At most one of the following flags can
|
||||
be specified:
|
||||
|
||||
PIPE_FLUSH_TOP_OF_PIPE: The fence should be signaled as soon as the next
|
||||
command is ready to start executing at the top of the pipeline, before any of
|
||||
its data is actually read (including indirect draw parameters).
|
||||
|
||||
PIPE_FLUSH_BOTTOM_OF_PIPE: The fence should be signaled as soon as the previous
|
||||
command has finished executing on the GPU entirely (but data written by the
|
||||
command may still be in caches and inaccessible to the CPU).
|
||||
|
||||
|
||||
``flush_resource``
|
||||
|
||||
Flush the resource cache, so that the resource can be used
|
||||
by an external client. Possible usage:
|
||||
- flushing a resource before presenting it on the screen
|
||||
- flushing a resource if some other process or device wants to use it
|
||||
This shouldn't be used to flush caches if the resource is only managed
|
||||
by a single pipe_screen and is not shared with another process.
|
||||
(i.e. you shouldn't use it to flush caches explicitly if you want to e.g.
|
||||
use the resource for texturing)
|
||||
|
||||
Fences
|
||||
^^^^^^
|
||||
|
||||
``pipe_fence_handle``, and related methods, are used to synchronize
|
||||
execution between multiple parties. Examples include CPU <-> GPU synchronization,
|
||||
renderer <-> windowing system, multiple external APIs, etc.
|
||||
|
||||
A ``pipe_fence_handle`` can either be 'one time use' or 're-usable'. A 'one time use'
|
||||
fence behaves like a traditional GPU fence. Once it reaches the signaled state it
|
||||
is forever considered to be signaled.
|
||||
|
||||
Once a re-usable ``pipe_fence_handle`` becomes signaled, it can be reset
|
||||
back into an unsignaled state. The ``pipe_fence_handle`` will be reset to
|
||||
the unsignaled state by performing a wait operation on said object, i.e.
|
||||
``fence_server_sync``. As a corollary to this behaviour, a re-usable
|
||||
``pipe_fence_handle`` can only have one waiter.
|
||||
|
||||
This behaviour is useful in producer <-> consumer chains. It helps avoid
|
||||
unecessarily sharing a new ``pipe_fence_handle`` each time a new frame is
|
||||
ready. Instead, the fences are exchanged once ahead of time, and access is synchronized
|
||||
through GPU signaling instead of direct producer <-> consumer communication.
|
||||
|
||||
``fence_server_sync`` inserts a wait command into the GPU's command stream.
|
||||
|
||||
``fence_server_signal`` inserts a signal command into the GPU's command stream.
|
||||
|
||||
There are no guarantees that the wait/signal commands will be flushed when
|
||||
calling ``fence_server_sync`` or ``fence_server_signal``. An explicit
|
||||
call to ``flush`` is required to make sure the commands are emitted to the GPU.
|
||||
|
||||
The Gallium implementation may implicitly ``flush`` the command stream during a
|
||||
``fence_server_sync`` or ``fence_server_signal`` call if necessary.
|
||||
|
||||
Resource Busy Queries
|
||||
^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
``is_resource_referenced``
|
||||
|
||||
|
||||
|
||||
Blitting
|
||||
^^^^^^^^
|
||||
|
||||
These methods emulate classic blitter controls.
|
||||
|
||||
These methods operate directly on ``pipe_resource`` objects, and stand
|
||||
apart from any 3D state in the context. Blitting functionality may be
|
||||
moved to a separate abstraction at some point in the future.
|
||||
|
||||
``resource_copy_region`` blits a region of a resource to a region of another
|
||||
resource, provided that both resources have the same format, or compatible
|
||||
formats, i.e., formats for which copying the bytes from the source resource
|
||||
unmodified to the destination resource will achieve the same effect of a
|
||||
textured quad blitter.. The source and destination may be the same resource,
|
||||
but overlapping blits are not permitted.
|
||||
This can be considered the equivalent of a CPU memcpy.
|
||||
|
||||
``blit`` blits a region of a resource to a region of another resource, including
|
||||
scaling, format conversion, and up-/downsampling, as well as a destination clip
|
||||
rectangle (scissors) and window rectangles. It can also optionally honor the
|
||||
current render condition (but either way the blit itself never contributes
|
||||
anything to queries currently gathering data).
|
||||
As opposed to manually drawing a textured quad, this lets the pipe driver choose
|
||||
the optimal method for blitting (like using a special 2D engine), and usually
|
||||
offers, for example, accelerated stencil-only copies even where
|
||||
PIPE_CAP_SHADER_STENCIL_EXPORT is not available.
|
||||
|
||||
|
||||
Transfers
|
||||
^^^^^^^^^
|
||||
|
||||
These methods are used to get data to/from a resource.
|
||||
|
||||
``transfer_map`` creates a memory mapping and the transfer object
|
||||
associated with it.
|
||||
The returned pointer points to the start of the mapped range according to
|
||||
the box region, not the beginning of the resource. If transfer_map fails,
|
||||
the returned pointer to the buffer memory is NULL, and the pointer
|
||||
to the transfer object remains unchanged (i.e. it can be non-NULL).
|
||||
|
||||
``transfer_unmap`` remove the memory mapping for and destroy
|
||||
the transfer object. The pointer into the resource should be considered
|
||||
invalid and discarded.
|
||||
|
||||
``texture_subdata`` and ``buffer_subdata`` perform a simplified
|
||||
transfer for simple writes. Basically transfer_map, data write, and
|
||||
transfer_unmap all in one.
|
||||
|
||||
|
||||
The box parameter to some of these functions defines a 1D, 2D or 3D
|
||||
region of pixels. This is self-explanatory for 1D, 2D and 3D texture
|
||||
targets.
|
||||
|
||||
For PIPE_TEXTURE_1D_ARRAY and PIPE_TEXTURE_2D_ARRAY, the box::z and box::depth
|
||||
fields refer to the array dimension of the texture.
|
||||
|
||||
For PIPE_TEXTURE_CUBE, the box:z and box::depth fields refer to the
|
||||
faces of the cube map (z + depth <= 6).
|
||||
|
||||
For PIPE_TEXTURE_CUBE_ARRAY, the box:z and box::depth fields refer to both
|
||||
the face and array dimension of the texture (face = z % 6, array = z / 6).
|
||||
|
||||
|
||||
.. _transfer_flush_region:
|
||||
|
||||
transfer_flush_region
|
||||
%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
If a transfer was created with ``FLUSH_EXPLICIT``, it will not automatically
|
||||
be flushed on write or unmap. Flushes must be requested with
|
||||
``transfer_flush_region``. Flush ranges are relative to the mapped range, not
|
||||
the beginning of the resource.
|
||||
|
||||
|
||||
|
||||
.. _texture_barrier:
|
||||
|
||||
texture_barrier
|
||||
%%%%%%%%%%%%%%%
|
||||
|
||||
This function flushes all pending writes to the currently-set surfaces and
|
||||
invalidates all read caches of the currently-set samplers. This can be used
|
||||
for both regular textures as well as for framebuffers read via FBFETCH.
|
||||
|
||||
|
||||
|
||||
.. _memory_barrier:
|
||||
|
||||
memory_barrier
|
||||
%%%%%%%%%%%%%%%
|
||||
|
||||
This function flushes caches according to which of the PIPE_BARRIER_* flags
|
||||
are set.
|
||||
|
||||
|
||||
|
||||
.. _resource_commit:
|
||||
|
||||
resource_commit
|
||||
%%%%%%%%%%%%%%%
|
||||
|
||||
This function changes the commit state of a part of a sparse resource. Sparse
|
||||
resources are created by setting the ``PIPE_RESOURCE_FLAG_SPARSE`` flag when
|
||||
calling ``resource_create``. Initially, sparse resources only reserve a virtual
|
||||
memory region that is not backed by memory (i.e., it is uncommitted). The
|
||||
``resource_commit`` function can be called to commit or uncommit parts (or all)
|
||||
of a resource. The driver manages the underlying backing memory.
|
||||
|
||||
The contents of newly committed memory regions are undefined. Calling this
|
||||
function to commit an already committed memory region is allowed and leaves its
|
||||
content unchanged. Similarly, calling this function to uncommit an already
|
||||
uncommitted memory region is allowed.
|
||||
|
||||
For buffers, the given box must be aligned to multiples of
|
||||
``PIPE_CAP_SPARSE_BUFFER_PAGE_SIZE``. As an exception to this rule, if the size
|
||||
of the buffer is not a multiple of the page size, changing the commit state of
|
||||
the last (partial) page requires a box that ends at the end of the buffer
|
||||
(i.e., box->x + box->width == buffer->width0).
|
||||
|
||||
|
||||
|
||||
.. _pipe_transfer:
|
||||
|
||||
PIPE_TRANSFER
|
||||
^^^^^^^^^^^^^
|
||||
|
||||
These flags control the behavior of a transfer object.
|
||||
|
||||
``PIPE_TRANSFER_READ``
|
||||
Resource contents read back (or accessed directly) at transfer create time.
|
||||
|
||||
``PIPE_TRANSFER_WRITE``
|
||||
Resource contents will be written back at transfer_unmap time (or modified
|
||||
as a result of being accessed directly).
|
||||
|
||||
``PIPE_TRANSFER_MAP_DIRECTLY``
|
||||
a transfer should directly map the resource. May return NULL if not supported.
|
||||
|
||||
``PIPE_TRANSFER_DISCARD_RANGE``
|
||||
The memory within the mapped region is discarded. Cannot be used with
|
||||
``PIPE_TRANSFER_READ``.
|
||||
|
||||
``PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE``
|
||||
Discards all memory backing the resource. It should not be used with
|
||||
``PIPE_TRANSFER_READ``.
|
||||
|
||||
``PIPE_TRANSFER_DONTBLOCK``
|
||||
Fail if the resource cannot be mapped immediately.
|
||||
|
||||
``PIPE_TRANSFER_UNSYNCHRONIZED``
|
||||
Do not synchronize pending operations on the resource when mapping. The
|
||||
interaction of any writes to the map and any operations pending on the
|
||||
resource are undefined. Cannot be used with ``PIPE_TRANSFER_READ``.
|
||||
|
||||
``PIPE_TRANSFER_FLUSH_EXPLICIT``
|
||||
Written ranges will be notified later with :ref:`transfer_flush_region`.
|
||||
Cannot be used with ``PIPE_TRANSFER_READ``.
|
||||
|
||||
``PIPE_TRANSFER_PERSISTENT``
|
||||
Allows the resource to be used for rendering while mapped.
|
||||
PIPE_RESOURCE_FLAG_MAP_PERSISTENT must be set when creating
|
||||
the resource.
|
||||
If COHERENT is not set, memory_barrier(PIPE_BARRIER_MAPPED_BUFFER)
|
||||
must be called to ensure the device can see what the CPU has written.
|
||||
|
||||
``PIPE_TRANSFER_COHERENT``
|
||||
If PERSISTENT is set, this ensures any writes done by the device are
|
||||
immediately visible to the CPU and vice versa.
|
||||
PIPE_RESOURCE_FLAG_MAP_COHERENT must be set when creating
|
||||
the resource.
|
||||
|
||||
Compute kernel execution
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
A compute program can be defined, bound or destroyed using
|
||||
``create_compute_state``, ``bind_compute_state`` or
|
||||
``destroy_compute_state`` respectively.
|
||||
|
||||
Any of the subroutines contained within the compute program can be
|
||||
executed on the device using the ``launch_grid`` method. This method
|
||||
will execute as many instances of the program as elements in the
|
||||
specified N-dimensional grid, hopefully in parallel.
|
||||
|
||||
The compute program has access to four special resources:
|
||||
|
||||
* ``GLOBAL`` represents a memory space shared among all the threads
|
||||
running on the device. An arbitrary buffer created with the
|
||||
``PIPE_BIND_GLOBAL`` flag can be mapped into it using the
|
||||
``set_global_binding`` method.
|
||||
|
||||
* ``LOCAL`` represents a memory space shared among all the threads
|
||||
running in the same working group. The initial contents of this
|
||||
resource are undefined.
|
||||
|
||||
* ``PRIVATE`` represents a memory space local to a single thread.
|
||||
The initial contents of this resource are undefined.
|
||||
|
||||
* ``INPUT`` represents a read-only memory space that can be
|
||||
initialized at ``launch_grid`` time.
|
||||
|
||||
These resources use a byte-based addressing scheme, and they can be
|
||||
accessed from the compute program by means of the LOAD/STORE TGSI
|
||||
opcodes. Additional resources to be accessed using the same opcodes
|
||||
may be specified by the user with the ``set_compute_resources``
|
||||
method.
|
||||
|
||||
In addition, normal texture sampling is allowed from the compute
|
||||
program: ``bind_sampler_states`` may be used to set up texture
|
||||
samplers for the compute stage and ``set_sampler_views`` may
|
||||
be used to bind a number of sampler views to it.
|
||||
|
||||
Mipmap generation
|
||||
^^^^^^^^^^^^^^^^^
|
||||
|
||||
If PIPE_CAP_GENERATE_MIPMAP is true, ``generate_mipmap`` can be used
|
||||
to generate mipmaps for the specified texture resource.
|
||||
It replaces texel image levels base_level+1 through
|
||||
last_level for layers range from first_layer through last_layer.
|
||||
It returns TRUE if mipmap generation succeeds, otherwise it
|
||||
returns FALSE. Mipmap generation may fail when it is not supported
|
||||
for particular texture types or formats.
|
||||
|
||||
Device resets
|
||||
^^^^^^^^^^^^^
|
||||
|
||||
Gallium frontends can query or request notifications of when the GPU
|
||||
is reset for whatever reason (application error, driver error). When
|
||||
a GPU reset happens, the context becomes unusable and all related state
|
||||
should be considered lost and undefined. Despite that, context
|
||||
notifications are single-shot, i.e. subsequent calls to
|
||||
``get_device_reset_status`` will return PIPE_NO_RESET.
|
||||
|
||||
* ``get_device_reset_status`` queries whether a device reset has happened
|
||||
since the last call or since the last notification by callback.
|
||||
* ``set_device_reset_callback`` sets a callback which will be called when
|
||||
a device reset is detected. The callback is only called synchronously.
|
||||
|
||||
Bindless
|
||||
^^^^^^^^
|
||||
|
||||
If PIPE_CAP_BINDLESS_TEXTURE is TRUE, the following ``pipe_context`` functions
|
||||
are used to create/delete bindless handles, and to make them resident in the
|
||||
current context when they are going to be used by shaders.
|
||||
|
||||
* ``create_texture_handle`` creates a 64-bit unsigned integer texture handle
|
||||
that is going to be directly used in shaders.
|
||||
* ``delete_texture_handle`` deletes a 64-bit unsigned integer texture handle.
|
||||
* ``make_texture_handle_resident`` makes a 64-bit unsigned texture handle
|
||||
resident in the current context to be accessible by shaders for texture
|
||||
mapping.
|
||||
* ``create_image_handle`` creates a 64-bit unsigned integer image handle that
|
||||
is going to be directly used in shaders.
|
||||
* ``delete_image_handle`` deletes a 64-bit unsigned integer image handle.
|
||||
* ``make_image_handle_resident`` makes a 64-bit unsigned integer image handle
|
||||
resident in the current context to be accessible by shaders for image loads,
|
||||
stores and atomic operations.
|
||||
|
||||
Using several contexts
|
||||
----------------------
|
||||
|
||||
Several contexts from the same screen can be used at the same time. Objects
|
||||
created on one context cannot be used in another context, but the objects
|
||||
created by the screen methods can be used by all contexts.
|
||||
|
||||
Transfers
|
||||
^^^^^^^^^
|
||||
A transfer on one context is not expected to synchronize properly with
|
||||
rendering on other contexts, thus only areas not yet used for rendering should
|
||||
be locked.
|
||||
|
||||
A flush is required after transfer_unmap to expect other contexts to see the
|
||||
uploaded data, unless:
|
||||
|
||||
* Using persistent mapping. Associated with coherent mapping, unmapping the
|
||||
resource is also not required to use it in other contexts. Without coherent
|
||||
mapping, memory_barrier(PIPE_BARRIER_MAPPED_BUFFER) should be called on the
|
||||
context that has mapped the resource. No flush is required.
|
||||
|
||||
* Mapping the resource with PIPE_TRANSFER_MAP_DIRECTLY.
|
||||
@@ -0,0 +1,14 @@
|
||||
CSO
|
||||
===
|
||||
|
||||
CSO, Constant State Objects, are a core part of Gallium's API.
|
||||
|
||||
CSO work on the principle of reusable state; they are created by filling
|
||||
out a state object with the desired properties, then passing that object
|
||||
to a context. The context returns an opaque context-specific handle which
|
||||
can be bound at any time for the desired effect.
|
||||
|
||||
.. toctree::
|
||||
:glob:
|
||||
|
||||
cso/*
|
||||
@@ -0,0 +1,128 @@
|
||||
.. _blend:
|
||||
|
||||
Blend
|
||||
=====
|
||||
|
||||
This state controls blending of the final fragments into the target rendering
|
||||
buffers.
|
||||
|
||||
Blend Factors
|
||||
-------------
|
||||
|
||||
The blend factors largely follow the same pattern as their counterparts
|
||||
in other modern and legacy drawing APIs.
|
||||
|
||||
Dual source blend factors are supported for up to 1 MRT, although
|
||||
you can advertise > 1 MRT, the stack cannot handle them for a few reasons.
|
||||
There is no definition on how the 1D array of shader outputs should be mapped
|
||||
to something that would be a 2D array (location, index). No current hardware
|
||||
exposes > 1 MRT, and we should revisit this issue if anyone ever does.
|
||||
|
||||
Logical Operations
|
||||
------------------
|
||||
|
||||
Logical operations, also known as logicops, lops, or rops, are supported.
|
||||
Only two-operand logicops are available. When logicops are enabled, all other
|
||||
blend state is ignored, including per-render-target state, so logicops are
|
||||
performed on all render targets.
|
||||
|
||||
.. warning::
|
||||
The blend_enable flag is ignored for all render targets when logical
|
||||
operations are enabled.
|
||||
|
||||
For a source component `s` and destination component `d`, the logical
|
||||
operations are defined as taking the bits of each channel of each component,
|
||||
and performing one of the following operations per-channel:
|
||||
|
||||
* ``CLEAR``: 0
|
||||
* ``NOR``: :math:`\lnot(s \lor d)`
|
||||
* ``AND_INVERTED``: :math:`\lnot s \land d`
|
||||
* ``COPY_INVERTED``: :math:`\lnot s`
|
||||
* ``AND_REVERSE``: :math:`s \land \lnot d`
|
||||
* ``INVERT``: :math:`\lnot d`
|
||||
* ``XOR``: :math:`s \oplus d`
|
||||
* ``NAND``: :math:`\lnot(s \land d)`
|
||||
* ``AND``: :math:`s \land d`
|
||||
* ``EQUIV``: :math:`\lnot(s \oplus d)`
|
||||
* ``NOOP``: :math:`d`
|
||||
* ``OR_INVERTED``: :math:`\lnot s \lor d`
|
||||
* ``COPY``: :math:`s`
|
||||
* ``OR_REVERSE``: :math:`s \lor \lnot d`
|
||||
* ``OR``: :math:`s \lor d`
|
||||
* ``SET``: 1
|
||||
|
||||
.. note::
|
||||
The logical operation names and definitions match those of the OpenGL API,
|
||||
and are similar to the ROP2 and ROP3 definitions of GDI. This is
|
||||
intentional, to ease transitions to Gallium.
|
||||
|
||||
Members
|
||||
-------
|
||||
|
||||
These members affect all render targets.
|
||||
|
||||
dither
|
||||
%%%%%%
|
||||
|
||||
Whether dithering is enabled.
|
||||
|
||||
.. note::
|
||||
Dithering is completely implementation-dependent. It may be ignored by
|
||||
drivers for any reason, and some render targets may always or never be
|
||||
dithered depending on their format or usage flags.
|
||||
|
||||
logicop_enable
|
||||
%%%%%%%%%%%%%%
|
||||
|
||||
Whether the blender should perform a logicop instead of blending.
|
||||
|
||||
logicop_func
|
||||
%%%%%%%%%%%%
|
||||
|
||||
The logicop to use. One of ``PIPE_LOGICOP``.
|
||||
|
||||
independent_blend_enable
|
||||
If enabled, blend state is different for each render target, and
|
||||
for each render target set in the respective member of the rt array.
|
||||
If disabled, blend state is the same for all render targets, and only
|
||||
the first member of the rt array contains valid data.
|
||||
rt
|
||||
Contains the per-rendertarget blend state.
|
||||
alpha_to_coverage
|
||||
If enabled, the fragment's alpha value is used to override the fragment's
|
||||
coverage mask. The coverage mask will be all zeros if the alpha value is
|
||||
zero. The coverage mask will be all ones if the alpha value is one.
|
||||
Otherwise, the number of bits set in the coverage mask will be proportional
|
||||
to the alpha value. Note that this step happens regardless of whether
|
||||
multisample is enabled or the destination buffer is multisampled.
|
||||
alpha_to_one
|
||||
If enabled, the fragment's alpha value will be set to one. As with
|
||||
alpha_to_coverage, this step happens regardless of whether multisample
|
||||
is enabled or the destination buffer is multisampled.
|
||||
max_rt
|
||||
The index of the max render target (irrespecitive of whether independent
|
||||
blend is enabled), ie. the number of MRTs minus one. This is provided
|
||||
so that the driver can avoid the overhead of programming unused MRTs.
|
||||
|
||||
|
||||
Per-rendertarget Members
|
||||
------------------------
|
||||
|
||||
blend_enable
|
||||
If blending is enabled, perform a blend calculation according to blend
|
||||
functions and source/destination factors. Otherwise, the incoming fragment
|
||||
color gets passed unmodified (but colormask still applies).
|
||||
rgb_func
|
||||
The blend function to use for rgb channels. One of PIPE_BLEND.
|
||||
rgb_src_factor
|
||||
The blend source factor to use for rgb channels. One of PIPE_BLENDFACTOR.
|
||||
rgb_dst_factor
|
||||
The blend destination factor to use for rgb channels. One of PIPE_BLENDFACTOR.
|
||||
alpha_func
|
||||
The blend function to use for the alpha channel. One of PIPE_BLEND.
|
||||
alpha_src_factor
|
||||
The blend source factor to use for the alpha channel. One of PIPE_BLENDFACTOR.
|
||||
alpha_dst_factor
|
||||
The blend destination factor to use for alpha channel. One of PIPE_BLENDFACTOR.
|
||||
colormask
|
||||
Bitmask of which channels to write. Combination of PIPE_MASK bits.
|
||||
@@ -0,0 +1,61 @@
|
||||
.. _depth-stencil-alpha:
|
||||
|
||||
Depth, Stencil, & Alpha
|
||||
=======================
|
||||
|
||||
These three states control the depth, stencil, and alpha tests, used to
|
||||
discard fragments that have passed through the fragment shader.
|
||||
|
||||
Traditionally, these three tests have been clumped together in hardware, so
|
||||
they are all stored in one structure.
|
||||
|
||||
During actual execution, the order of operations done on fragments is always:
|
||||
|
||||
* Alpha
|
||||
* Stencil
|
||||
* Depth
|
||||
|
||||
Depth Members
|
||||
-------------
|
||||
|
||||
enabled
|
||||
Whether the depth test is enabled.
|
||||
writemask
|
||||
Whether the depth buffer receives depth writes.
|
||||
func
|
||||
The depth test function. One of PIPE_FUNC.
|
||||
|
||||
Stencil Members
|
||||
---------------
|
||||
|
||||
enabled
|
||||
Whether the stencil test is enabled. For the second stencil, whether the
|
||||
two-sided stencil is enabled. If two-sided stencil is disabled, the other
|
||||
fields for the second array member are not valid.
|
||||
func
|
||||
The stencil test function. One of PIPE_FUNC.
|
||||
valuemask
|
||||
Stencil test value mask; this is ANDed with the value in the stencil
|
||||
buffer and the reference value before doing the stencil comparison test.
|
||||
writemask
|
||||
Stencil test writemask; this controls which bits of the stencil buffer
|
||||
are written.
|
||||
fail_op
|
||||
The operation to carry out if the stencil test fails. One of
|
||||
PIPE_STENCIL_OP.
|
||||
zfail_op
|
||||
The operation to carry out if the stencil test passes but the depth test
|
||||
fails. One of PIPE_STENCIL_OP.
|
||||
zpass_op
|
||||
The operation to carry out if the stencil test and depth test both pass.
|
||||
One of PIPE_STENCIL_OP.
|
||||
|
||||
Alpha Members
|
||||
-------------
|
||||
|
||||
enabled
|
||||
Whether the alpha test is enabled.
|
||||
func
|
||||
The alpha test function. One of PIPE_FUNC.
|
||||
ref_value
|
||||
Alpha test reference value; used for certain functions.
|
||||
@@ -0,0 +1,365 @@
|
||||
.. _rasterizer:
|
||||
|
||||
Rasterizer
|
||||
==========
|
||||
|
||||
The rasterizer state controls the rendering of points, lines and triangles.
|
||||
Attributes include polygon culling state, line width, line stipple,
|
||||
multisample state, scissoring and flat/smooth shading.
|
||||
|
||||
Linkage
|
||||
|
||||
clamp_vertex_color
|
||||
^^^^^^^^^^^^^^^^^^
|
||||
|
||||
If set, TGSI_SEMANTIC_COLOR registers are clamped to the [0, 1] range after
|
||||
the execution of the vertex shader, before being passed to the geometry
|
||||
shader or fragment shader.
|
||||
|
||||
OpenGL: glClampColor(GL_CLAMP_VERTEX_COLOR) in GL 3.0 or GL_ARB_color_buffer_float
|
||||
|
||||
D3D11: seems always disabled
|
||||
|
||||
Note the PIPE_CAP_VERTEX_COLOR_CLAMPED query indicates whether or not the
|
||||
driver supports this control. If it's not supported, gallium frontends may
|
||||
have to insert extra clamping code.
|
||||
|
||||
|
||||
clamp_fragment_color
|
||||
^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Controls whether TGSI_SEMANTIC_COLOR outputs of the fragment shader
|
||||
are clamped to [0, 1].
|
||||
|
||||
OpenGL: glClampColor(GL_CLAMP_FRAGMENT_COLOR) in GL 3.0 or ARB_color_buffer_float
|
||||
|
||||
D3D11: seems always disabled
|
||||
|
||||
Note the PIPE_CAP_FRAGMENT_COLOR_CLAMPED query indicates whether or not the
|
||||
driver supports this control. If it's not supported, gallium frontends may
|
||||
have to insert extra clamping code.
|
||||
|
||||
|
||||
Shading
|
||||
-------
|
||||
|
||||
flatshade
|
||||
^^^^^^^^^
|
||||
|
||||
If set, the provoking vertex of each polygon is used to determine the color
|
||||
of the entire polygon. If not set, fragment colors will be interpolated
|
||||
between the vertex colors.
|
||||
|
||||
The actual interpolated shading algorithm is obviously
|
||||
implementation-dependent, but will usually be Gourard for most hardware.
|
||||
|
||||
.. note::
|
||||
|
||||
This is separate from the fragment shader input attributes
|
||||
CONSTANT, LINEAR and PERSPECTIVE. The flatshade state is needed at
|
||||
clipping time to determine how to set the color of new vertices.
|
||||
|
||||
:ref:`Draw` can implement flat shading by copying the provoking vertex
|
||||
color to all the other vertices in the primitive.
|
||||
|
||||
flatshade_first
|
||||
^^^^^^^^^^^^^^^
|
||||
|
||||
Whether the first vertex should be the provoking vertex, for most primitives.
|
||||
If not set, the last vertex is the provoking vertex.
|
||||
|
||||
There are a few important exceptions to the specification of this rule.
|
||||
|
||||
* ``PIPE_PRIMITIVE_POLYGON``: The provoking vertex is always the first
|
||||
vertex. If the caller wishes to change the provoking vertex, they merely
|
||||
need to rotate the vertices themselves.
|
||||
* ``PIPE_PRIMITIVE_QUAD``, ``PIPE_PRIMITIVE_QUAD_STRIP``: The option only has
|
||||
an effect if ``PIPE_CAP_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION`` is true.
|
||||
If it is not, the provoking vertex is always the last vertex.
|
||||
* ``PIPE_PRIMITIVE_TRIANGLE_FAN``: When set, the provoking vertex is the
|
||||
second vertex, not the first. This permits each segment of the fan to have
|
||||
a different color.
|
||||
|
||||
Polygons
|
||||
--------
|
||||
|
||||
light_twoside
|
||||
^^^^^^^^^^^^^
|
||||
|
||||
If set, there are per-vertex back-facing colors. The hardware
|
||||
(perhaps assisted by :ref:`Draw`) should be set up to use this state
|
||||
along with the front/back information to set the final vertex colors
|
||||
prior to rasterization.
|
||||
|
||||
The frontface vertex shader color output is marked with TGSI semantic
|
||||
COLOR[0], and backface COLOR[1].
|
||||
|
||||
front_ccw
|
||||
Indicates whether the window order of front-facing polygons is
|
||||
counter-clockwise (TRUE) or clockwise (FALSE).
|
||||
|
||||
cull_mode
|
||||
Indicates which faces of polygons to cull, either PIPE_FACE_NONE
|
||||
(cull no polygons), PIPE_FACE_FRONT (cull front-facing polygons),
|
||||
PIPE_FACE_BACK (cull back-facing polygons), or
|
||||
PIPE_FACE_FRONT_AND_BACK (cull all polygons).
|
||||
|
||||
fill_front
|
||||
Indicates how to fill front-facing polygons, either
|
||||
PIPE_POLYGON_MODE_FILL, PIPE_POLYGON_MODE_LINE or
|
||||
PIPE_POLYGON_MODE_POINT.
|
||||
fill_back
|
||||
Indicates how to fill back-facing polygons, either
|
||||
PIPE_POLYGON_MODE_FILL, PIPE_POLYGON_MODE_LINE or
|
||||
PIPE_POLYGON_MODE_POINT.
|
||||
|
||||
poly_stipple_enable
|
||||
Whether polygon stippling is enabled.
|
||||
poly_smooth
|
||||
Controls OpenGL-style polygon smoothing/antialiasing
|
||||
|
||||
offset_point
|
||||
If set, point-filled polygons will have polygon offset factors applied
|
||||
offset_line
|
||||
If set, line-filled polygons will have polygon offset factors applied
|
||||
offset_tri
|
||||
If set, filled polygons will have polygon offset factors applied
|
||||
|
||||
offset_units
|
||||
Specifies the polygon offset bias
|
||||
offset_units_unscaled
|
||||
Specifies the unit of the polygon offset bias. If false, use the
|
||||
GL/D3D1X behaviour. If true, offset_units is a floating point offset
|
||||
which isn't scaled (D3D9). Note that GL/D3D1X behaviour has different
|
||||
formula whether the depth buffer is unorm or float, which is not
|
||||
the case for D3D9.
|
||||
offset_scale
|
||||
Specifies the polygon offset scale
|
||||
offset_clamp
|
||||
Upper (if > 0) or lower (if < 0) bound on the polygon offset result
|
||||
|
||||
|
||||
|
||||
Lines
|
||||
-----
|
||||
|
||||
line_width
|
||||
The width of lines.
|
||||
line_smooth
|
||||
Whether lines should be smoothed. Line smoothing is simply anti-aliasing.
|
||||
line_stipple_enable
|
||||
Whether line stippling is enabled.
|
||||
line_stipple_pattern
|
||||
16-bit bitfield of on/off flags, used to pattern the line stipple.
|
||||
line_stipple_factor
|
||||
When drawing a stippled line, each bit in the stipple pattern is
|
||||
repeated N times, where N = line_stipple_factor + 1.
|
||||
line_last_pixel
|
||||
Controls whether the last pixel in a line is drawn or not. OpenGL
|
||||
omits the last pixel to avoid double-drawing pixels at the ends of lines
|
||||
when drawing connected lines.
|
||||
|
||||
|
||||
Points
|
||||
------
|
||||
|
||||
sprite_coord_enable
|
||||
^^^^^^^^^^^^^^^^^^^
|
||||
The effect of this state depends on PIPE_CAP_TGSI_TEXCOORD !
|
||||
|
||||
Controls automatic texture coordinate generation for rendering sprite points.
|
||||
|
||||
If PIPE_CAP_TGSI_TEXCOORD is false:
|
||||
When bit k in the sprite_coord_enable bitfield is set, then generic
|
||||
input k to the fragment shader will get an automatically computed
|
||||
texture coordinate.
|
||||
|
||||
If PIPE_CAP_TGSI_TEXCOORD is true:
|
||||
The bitfield refers to inputs with TEXCOORD semantic instead of generic inputs.
|
||||
|
||||
The texture coordinate will be of the form (s, t, 0, 1) where s varies
|
||||
from 0 to 1 from left to right while t varies from 0 to 1 according to
|
||||
the state of 'sprite_coord_mode' (see below).
|
||||
|
||||
If any bit is set, then point_smooth MUST be disabled (there are no
|
||||
round sprites) and point_quad_rasterization MUST be true (sprites are
|
||||
always rasterized as quads). Any mismatch between these states should
|
||||
be considered a bug in the gallium frontend.
|
||||
|
||||
This feature is implemented in the :ref:`Draw` module but may also be
|
||||
implemented natively by GPUs or implemented with a geometry shader.
|
||||
|
||||
|
||||
sprite_coord_mode
|
||||
^^^^^^^^^^^^^^^^^
|
||||
|
||||
Specifies how the value for each shader output should be computed when drawing
|
||||
point sprites. For PIPE_SPRITE_COORD_LOWER_LEFT, the lower-left vertex will
|
||||
have coordinates (0,0,0,1). For PIPE_SPRITE_COORD_UPPER_LEFT, the upper-left
|
||||
vertex will have coordinates (0,0,0,1).
|
||||
This state is used by :ref:`Draw` to generate texcoords.
|
||||
|
||||
|
||||
point_quad_rasterization
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Determines if points should be rasterized according to quad or point
|
||||
rasterization rules.
|
||||
|
||||
(Legacy-only) OpenGL actually has quite different rasterization rules
|
||||
for points and point sprites - hence this indicates if points should be
|
||||
rasterized as points or according to point sprite (which decomposes them
|
||||
into quads, basically) rules. Newer GL versions no longer support the old
|
||||
point rules at all.
|
||||
|
||||
Additionally Direct3D will always use quad rasterization rules for
|
||||
points, regardless of whether point sprites are enabled or not.
|
||||
|
||||
If this state is enabled, point smoothing and antialiasing are
|
||||
disabled. If it is disabled, point sprite coordinates are not
|
||||
generated.
|
||||
|
||||
.. note::
|
||||
|
||||
Some renderers always internally translate points into quads; this state
|
||||
still affects those renderers by overriding other rasterization state.
|
||||
|
||||
point_tri_clip
|
||||
Determines if clipping of points should happen after they are converted
|
||||
to "rectangles" (required by d3d) or before (required by OpenGL, though
|
||||
this rule is ignored by some IHVs).
|
||||
It is not valid to set this to enabled but have point_quad_rasterization
|
||||
disabled.
|
||||
point_smooth
|
||||
Whether points should be smoothed. Point smoothing turns rectangular
|
||||
points into circles or ovals.
|
||||
point_size_per_vertex
|
||||
Whether the vertex shader is expected to have a point size output.
|
||||
Undefined behaviour is permitted if there is disagreement between
|
||||
this flag and the actual bound shader.
|
||||
point_size
|
||||
The size of points, if not specified per-vertex.
|
||||
|
||||
|
||||
|
||||
Other Members
|
||||
-------------
|
||||
|
||||
scissor
|
||||
Whether the scissor test is enabled.
|
||||
|
||||
multisample
|
||||
Whether :term:`MSAA` is enabled.
|
||||
|
||||
half_pixel_center
|
||||
When true, the rasterizer should use (0.5, 0.5) pixel centers for
|
||||
determining pixel ownership (e.g, OpenGL, D3D10 and higher)::
|
||||
|
||||
0 0.5 1
|
||||
0 +-----+
|
||||
| |
|
||||
0.5 | X |
|
||||
| |
|
||||
1 +-----+
|
||||
|
||||
When false, the rasterizer should use (0, 0) pixel centers for determining
|
||||
pixel ownership (e.g., D3D9 or ealier)::
|
||||
|
||||
-0.5 0 0.5
|
||||
-0.5 +-----+
|
||||
| |
|
||||
0 | X |
|
||||
| |
|
||||
0.5 +-----+
|
||||
|
||||
bottom_edge_rule
|
||||
Determines what happens when a pixel sample lies precisely on a triangle
|
||||
edge.
|
||||
|
||||
When true, a pixel sample is considered to lie inside of a triangle if it
|
||||
lies on the *bottom edge* or *left edge* (e.g., OpenGL drawables)::
|
||||
|
||||
0 x
|
||||
0 +--------------------->
|
||||
|
|
||||
| +-------------+
|
||||
| | |
|
||||
| | |
|
||||
| | |
|
||||
| +=============+
|
||||
|
|
||||
y V
|
||||
|
||||
When false, a pixel sample is considered to lie inside of a triangle if it
|
||||
lies on the *top edge* or *left edge* (e.g., OpenGL FBOs, D3D)::
|
||||
|
||||
0 x
|
||||
0 +--------------------->
|
||||
|
|
||||
| +=============+
|
||||
| | |
|
||||
| | |
|
||||
| | |
|
||||
| +-------------+
|
||||
|
|
||||
y V
|
||||
|
||||
Where:
|
||||
- a *top edge* is an edge that is horizontal and is above the other edges;
|
||||
- a *bottom edge* is an edge that is horizontal and is below the other
|
||||
edges;
|
||||
- a *left edge* is an edge that is not horizontal and is on the left side of
|
||||
the triangle.
|
||||
|
||||
.. note::
|
||||
|
||||
Actually all graphics APIs use a top-left rasterization rule for pixel
|
||||
ownership, but their notion of top varies with the axis origin (which
|
||||
can be either at y = 0 or at y = height). Gallium instead always
|
||||
assumes that top is always at y=0.
|
||||
|
||||
See also:
|
||||
- http://msdn.microsoft.com/en-us/library/windows/desktop/cc627092.aspx
|
||||
- http://msdn.microsoft.com/en-us/library/windows/desktop/bb147314.aspx
|
||||
|
||||
clip_halfz
|
||||
When true clip space in the z axis goes from [0..1] (D3D). When false
|
||||
[-1, 1] (GL)
|
||||
|
||||
depth_clip
|
||||
When false, the near and far depth clipping planes of the view volume are
|
||||
disabled and the depth value will be clamped at the per-pixel level, after
|
||||
polygon offset has been applied and before depth testing.
|
||||
|
||||
clip_plane_enable
|
||||
For each k in [0, PIPE_MAX_CLIP_PLANES), if bit k of this field is set,
|
||||
clipping half-space k is enabled, if it is clear, it is disabled.
|
||||
The clipping half-spaces are defined either by the user clip planes in
|
||||
``pipe_clip_state``, or by the clip distance outputs of the shader stage
|
||||
preceding the fragment shader.
|
||||
If any clip distance output is written, those half-spaces for which no
|
||||
clip distance is written count as disabled; i.e. user clip planes and
|
||||
shader clip distances cannot be mixed, and clip distances take precedence.
|
||||
|
||||
conservative_raster_mode
|
||||
The conservative rasterization mode. For PIPE_CONSERVATIVE_RASTER_OFF,
|
||||
conservative rasterization is disabled. For IPE_CONSERVATIVE_RASTER_POST_SNAP
|
||||
or PIPE_CONSERVATIVE_RASTER_PRE_SNAP, conservative rasterization is nabled.
|
||||
When conservative rasterization is enabled, the polygon smooth, line mooth,
|
||||
point smooth and line stipple settings are ignored.
|
||||
With the post-snap mode, unlike the pre-snap mode, fragments are never
|
||||
generated for degenerate primitives. Degenerate primitives, when rasterized,
|
||||
are considered back-facing and the vertex attributes and depth are that of
|
||||
the provoking vertex.
|
||||
If the post-snap mode is used with an unsupported primitive, the pre-snap
|
||||
mode is used, if supported. Behavior is similar for the pre-snap mode.
|
||||
If the pre-snap mode is used, fragments are generated with respect to the primitive
|
||||
before vertex snapping.
|
||||
|
||||
conservative_raster_dilate
|
||||
The amount of dilation during conservative rasterization.
|
||||
|
||||
subpixel_precision_x
|
||||
A bias added to the horizontal subpixel precision during conservative rasterization.
|
||||
subpixel_precision_y
|
||||
A bias added to the vertical subpixel precision during conservative rasterization.
|
||||
@@ -0,0 +1,116 @@
|
||||
.. _sampler:
|
||||
|
||||
Sampler
|
||||
=======
|
||||
|
||||
Texture units have many options for selecting texels from loaded textures;
|
||||
this state controls an individual texture unit's texel-sampling settings.
|
||||
|
||||
Texture coordinates are always treated as four-dimensional, and referred to
|
||||
with the traditional (S, T, R, Q) notation.
|
||||
|
||||
Members
|
||||
-------
|
||||
|
||||
wrap_s
|
||||
How to wrap the S coordinate. One of PIPE_TEX_WRAP_*.
|
||||
wrap_t
|
||||
How to wrap the T coordinate. One of PIPE_TEX_WRAP_*.
|
||||
wrap_r
|
||||
How to wrap the R coordinate. One of PIPE_TEX_WRAP_*.
|
||||
|
||||
The wrap modes are:
|
||||
|
||||
* ``PIPE_TEX_WRAP_REPEAT``: Standard coord repeat/wrap-around mode.
|
||||
* ``PIPE_TEX_WRAP_CLAMP_TO_EDGE``: Clamp coord to edge of texture, the border
|
||||
color is never sampled.
|
||||
* ``PIPE_TEX_WRAP_CLAMP_TO_BORDER``: Clamp coord to border of texture, the
|
||||
border color is sampled when coords go outside the range [0,1].
|
||||
* ``PIPE_TEX_WRAP_CLAMP``: The coord is clamped to the range [0,1] before
|
||||
scaling to the texture size. This corresponds to the legacy OpenGL GL_CLAMP
|
||||
texture wrap mode. Historically, this mode hasn't acted consistantly across
|
||||
all graphics hardware. It sometimes acts like CLAMP_TO_EDGE or
|
||||
CLAMP_TO_BORDER. The behaviour may also vary depending on linear vs.
|
||||
nearest sampling mode.
|
||||
* ``PIPE_TEX_WRAP_MIRROR_REPEAT``: If the integer part of the coordinate
|
||||
is odd, the coord becomes (1 - coord). Then, normal texture REPEAT is
|
||||
applied to the coord.
|
||||
* ``PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE``: First, the absolute value of the
|
||||
coordinate is computed. Then, regular CLAMP_TO_EDGE is applied to the coord.
|
||||
* ``PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER``: First, the absolute value of the
|
||||
coordinate is computed. Then, regular CLAMP_TO_BORDER is applied to the
|
||||
coord.
|
||||
* ``PIPE_TEX_WRAP_MIRROR_CLAMP``: First, the absolute value of the coord is
|
||||
computed. Then, regular CLAMP is applied to the coord.
|
||||
|
||||
|
||||
min_img_filter
|
||||
The image filter to use when minifying texels. One of PIPE_TEX_FILTER_*.
|
||||
mag_img_filter
|
||||
The image filter to use when magnifying texels. One of PIPE_TEX_FILTER_*.
|
||||
|
||||
The texture image filter modes are:
|
||||
|
||||
* ``PIPE_TEX_FILTER_NEAREST``: One texel is fetched from the texture image
|
||||
at the texture coordinate.
|
||||
* ``PIPE_TEX_FILTER_LINEAR``: Two, four or eight texels (depending on the
|
||||
texture dimensions; 1D/2D/3D) are fetched from the texture image and
|
||||
linearly weighted and blended together.
|
||||
|
||||
min_mip_filter
|
||||
The filter to use when minifying mipmapped textures. One of
|
||||
PIPE_TEX_MIPFILTER_*.
|
||||
|
||||
The texture mip filter modes are:
|
||||
|
||||
* ``PIPE_TEX_MIPFILTER_NEAREST``: A single mipmap level/image is selected
|
||||
according to the texture LOD (lambda) value.
|
||||
* ``PIPE_TEX_MIPFILTER_LINEAR``: The two mipmap levels/images above/below
|
||||
the texture LOD value are sampled from. The results of sampling from
|
||||
those two images are blended together with linear interpolation.
|
||||
* ``PIPE_TEX_MIPFILTER_NONE``: Mipmap filtering is disabled. All texels
|
||||
are taken from the level 0 image.
|
||||
|
||||
|
||||
compare_mode
|
||||
If set to PIPE_TEX_COMPARE_R_TO_TEXTURE, the result of texture sampling
|
||||
is not a color but a true/false value which is the result of comparing the
|
||||
sampled texture value (typically a Z value from a depth texture) to the
|
||||
texture coordinate's R component.
|
||||
If set to PIPE_TEX_COMPARE_NONE, no comparison calculation is performed.
|
||||
compare_func
|
||||
The inequality operator used when compare_mode=1. One of PIPE_FUNC_x.
|
||||
normalized_coords
|
||||
If set, the incoming texture coordinates (nominally in the range [0,1])
|
||||
will be scaled by the texture width, height, depth to compute texel
|
||||
addresses. Otherwise, the texture coords are used as-is (they are not
|
||||
scaled by the texture dimensions).
|
||||
When normalized_coords=0, only a subset of the texture wrap modes are
|
||||
allowed: PIPE_TEX_WRAP_CLAMP, PIPE_TEX_WRAP_CLAMP_TO_EDGE and
|
||||
PIPE_TEX_WRAP_CLAMP_TO_BORDER.
|
||||
lod_bias
|
||||
Bias factor which is added to the computed level of detail.
|
||||
The normal level of detail is computed from the partial derivatives of
|
||||
the texture coordinates and/or the fragment shader TEX/TXB/TXL
|
||||
instruction.
|
||||
min_lod
|
||||
Minimum level of detail, used to clamp LOD after bias. The LOD values
|
||||
correspond to mipmap levels where LOD=0 is the level 0 mipmap image.
|
||||
max_lod
|
||||
Maximum level of detail, used to clamp LOD after bias.
|
||||
border_color
|
||||
Color union used for texel coordinates that are outside the [0,width-1],
|
||||
[0, height-1] or [0, depth-1] ranges. Interpreted according to sampler
|
||||
view format, unless the driver reports
|
||||
PIPE_CAP_TEXTURE_BORDER_COLOR_QUIRK, in which case special care has to be
|
||||
taken (see description of the cap).
|
||||
max_anisotropy
|
||||
Maximum anistropy ratio to use when sampling from textures. For example,
|
||||
if max_anistropy=4, a region of up to 1 by 4 texels will be sampled.
|
||||
Set to zero to disable anisotropic filtering. Any other setting enables
|
||||
anisotropic filtering, however it's not unexpected some drivers only will
|
||||
change their filtering with a setting of 2 and higher.
|
||||
seamless_cube_map
|
||||
If set, the bilinear filter of a cube map may take samples from adjacent
|
||||
cube map faces when sampled near a texture border to produce a seamless
|
||||
look.
|
||||
@@ -0,0 +1,12 @@
|
||||
.. _shader:
|
||||
|
||||
Shader
|
||||
======
|
||||
|
||||
One of the two types of shaders supported by Gallium.
|
||||
|
||||
Members
|
||||
-------
|
||||
|
||||
tokens
|
||||
A list of tgsi_tokens.
|
||||
@@ -0,0 +1,59 @@
|
||||
.. _vertexelements:
|
||||
|
||||
Vertex Elements
|
||||
===============
|
||||
|
||||
This state controls the format of the input attributes contained in
|
||||
pipe_vertex_buffers. There is one pipe_vertex_element array member for each
|
||||
input attribute.
|
||||
|
||||
Input Formats
|
||||
-------------
|
||||
|
||||
Gallium supports a diverse range of formats for vertex data. Drivers are
|
||||
guaranteed to support 32-bit floating-point vectors of one to four components.
|
||||
Additionally, they may support the following formats:
|
||||
|
||||
* Integers, signed or unsigned, normalized or non-normalized, 8, 16, or 32
|
||||
bits wide
|
||||
* Floating-point, 16, 32, or 64 bits wide
|
||||
|
||||
At this time, support for varied vertex data formats is limited by driver
|
||||
deficiencies. It is planned to support a single uniform set of formats for all
|
||||
Gallium drivers at some point.
|
||||
|
||||
Rather than attempt to specify every small nuance of behavior, Gallium uses a
|
||||
very simple set of rules for padding out unspecified components. If an input
|
||||
uses less than four components, it will be padded out with the constant vector
|
||||
``(0, 0, 0, 1)``.
|
||||
|
||||
Fog, point size, the facing bit, and edgeflags, all are in the standard format
|
||||
of ``(x, 0, 0, 1)``, and so only the first component of those inputs is used.
|
||||
|
||||
Position
|
||||
%%%%%%%%
|
||||
|
||||
Vertex position may be specified with two to four components. Using less than
|
||||
two components is not allowed.
|
||||
|
||||
Colors
|
||||
%%%%%%
|
||||
|
||||
Colors, both front- and back-facing, may omit the alpha component, only using
|
||||
three components. Using less than three components is not allowed.
|
||||
|
||||
Members
|
||||
-------
|
||||
|
||||
src_offset
|
||||
The byte offset of the attribute in the buffer given by
|
||||
vertex_buffer_index for the first vertex.
|
||||
instance_divisor
|
||||
The instance data rate divisor, used for instancing.
|
||||
0 means this is per-vertex data, n means per-instance data used for
|
||||
n consecutive instances (n > 0).
|
||||
vertex_buffer_index
|
||||
The vertex buffer this attribute lives in. Several attributes may
|
||||
live in the same vertex buffer.
|
||||
src_format
|
||||
The format of the attribute data. One of the PIPE_FORMAT tokens.
|
||||
@@ -0,0 +1,105 @@
|
||||
Debugging
|
||||
=========
|
||||
|
||||
Debugging utilities in gallium.
|
||||
|
||||
Debug Variables
|
||||
^^^^^^^^^^^^^^^
|
||||
|
||||
All drivers respond to a set of common debug environment variables, as well as
|
||||
some driver-specific variables. Set them as normal environment variables for
|
||||
the platform or operating system you are running. For example, for Linux this
|
||||
can be done by typing "export var=value" into a console and then running the
|
||||
program from that console.
|
||||
|
||||
Common
|
||||
""""""
|
||||
|
||||
.. envvar:: GALLIUM_PRINT_OPTIONS <bool> (false)
|
||||
|
||||
This option controls if the debug variables should be printed to stderr. This
|
||||
is probably the most useful variable, since it allows you to find which
|
||||
variables a driver uses.
|
||||
|
||||
.. envvar:: GALLIUM_RBUG <bool> (false)
|
||||
|
||||
Controls if the :ref:`rbug` should be used.
|
||||
|
||||
.. envvar:: GALLIUM_TRACE <string> ("")
|
||||
|
||||
If set, this variable will cause the :ref:`trace` output to be written to the
|
||||
specified file. Paths may be relative or absolute; relative paths are relative
|
||||
to the working directory. For example, setting it to "trace.xml" will cause
|
||||
the trace to be written to a file of the same name in the working directory.
|
||||
|
||||
.. envvar:: GALLIUM_DUMP_CPU <bool> (false)
|
||||
|
||||
Dump information about the current CPU that the driver is running on.
|
||||
|
||||
.. envvar:: TGSI_PRINT_SANITY <bool> (false)
|
||||
|
||||
Gallium has a built-in shader sanity checker. This option controls whether
|
||||
the shader sanity checker prints its warnings and errors to stderr.
|
||||
|
||||
.. envvar:: DRAW_USE_LLVM <bool> (false)
|
||||
|
||||
Whether the :ref:`Draw` module will attempt to use LLVM for vertex and geometry shaders.
|
||||
|
||||
|
||||
GL State tracker-specific
|
||||
"""""""""""""""""""""""""
|
||||
|
||||
.. envvar:: ST_DEBUG <flags> (0x0)
|
||||
|
||||
Debug :ref:`flags` for the GL state tracker.
|
||||
|
||||
|
||||
Driver-specific
|
||||
"""""""""""""""
|
||||
|
||||
.. envvar:: I915_DEBUG <flags> (0x0)
|
||||
|
||||
Debug :ref:`flags` for the i915 driver.
|
||||
|
||||
.. envvar:: I915_NO_HW <bool> (false)
|
||||
|
||||
Stop the i915 driver from submitting commands to the hardware.
|
||||
|
||||
.. envvar:: I915_DUMP_CMD <bool> (false)
|
||||
|
||||
Dump all commands going to the hardware.
|
||||
|
||||
.. envvar:: LP_DEBUG <flags> (0x0)
|
||||
|
||||
Debug :ref:`flags` for the llvmpipe driver.
|
||||
|
||||
.. envvar:: LP_NUM_THREADS <int> (number of CPUs)
|
||||
|
||||
Number of threads that the llvmpipe driver should use.
|
||||
|
||||
.. envvar:: FD_MESA_DEBUG <flags> (0x0)
|
||||
|
||||
Debug :ref:`flags` for the freedreno driver.
|
||||
|
||||
|
||||
.. _flags:
|
||||
|
||||
Flags
|
||||
"""""
|
||||
|
||||
The variables of type "flags" all take a string with comma-separated flags to
|
||||
enable different debugging for different parts of the drivers or state
|
||||
tracker. If set to "help", the driver will print a list of flags which the
|
||||
variable accepts. Order does not matter.
|
||||
|
||||
|
||||
.. _rbug:
|
||||
|
||||
Remote Debugger
|
||||
^^^^^^^^^^^^^^^
|
||||
|
||||
The remote debugger, commonly known as rbug, allows for runtime inspections of
|
||||
:ref:`Context`, :ref:`Screen`, :ref:`Resource` and :ref:`Shader` objects; and
|
||||
pausing and stepping of :ref:`Draw` calls. Is used with rbug-gui which is
|
||||
hosted outside of the main mesa repository. rbug is can be used over a network
|
||||
connection, so the debugger does not need to be on the same machine.
|
||||
@@ -0,0 +1,192 @@
|
||||
Distribution
|
||||
============
|
||||
|
||||
Along with the interface definitions, the following drivers, gallium frontends,
|
||||
and auxiliary modules are shipped in the standard Gallium distribution.
|
||||
|
||||
Drivers
|
||||
-------
|
||||
|
||||
Intel i915
|
||||
^^^^^^^^^^
|
||||
|
||||
Driver for Intel i915 and i945 chipsets.
|
||||
|
||||
LLVM Softpipe
|
||||
^^^^^^^^^^^^^
|
||||
|
||||
A version of :ref:`softpipe` that uses the Low-Level Virtual Machine to
|
||||
dynamically generate optimized rasterizing pipelines.
|
||||
|
||||
nVidia nv30
|
||||
^^^^^^^^^^^
|
||||
|
||||
Driver for the nVidia nv30 and nv40 families of GPUs.
|
||||
|
||||
nVidia nv50
|
||||
^^^^^^^^^^^
|
||||
|
||||
Driver for the nVidia nv50 family of GPUs.
|
||||
|
||||
nVidia nvc0
|
||||
^^^^^^^^^^^
|
||||
|
||||
Driver for the nVidia nvc0 / fermi family of GPUs.
|
||||
|
||||
VMware SVGA
|
||||
^^^^^^^^^^^
|
||||
|
||||
Driver for VMware virtualized guest operating system graphics processing.
|
||||
|
||||
ATI r300
|
||||
^^^^^^^^
|
||||
|
||||
Driver for the ATI/AMD r300, r400, and r500 families of GPUs.
|
||||
|
||||
ATI/AMD r600
|
||||
^^^^^^^^^^^^
|
||||
|
||||
Driver for the ATI/AMD r600, r700, Evergreen and Northern Islands families of GPUs.
|
||||
|
||||
AMD radeonsi
|
||||
^^^^^^^^^^^^
|
||||
|
||||
Driver for the AMD Southern Islands family of GPUs.
|
||||
|
||||
freedreno
|
||||
^^^^^^^^^
|
||||
|
||||
Driver for Qualcomm Adreno a2xx, a3xx, and a4xx series of GPUs.
|
||||
|
||||
.. _softpipe:
|
||||
|
||||
Softpipe
|
||||
^^^^^^^^
|
||||
|
||||
Reference software rasterizer. Slow but accurate.
|
||||
|
||||
.. _trace:
|
||||
|
||||
Trace
|
||||
^^^^^
|
||||
|
||||
Wrapper driver. Trace dumps an XML record of the calls made to the
|
||||
:ref:`Context` and :ref:`Screen` objects that it wraps.
|
||||
|
||||
Rbug
|
||||
^^^^
|
||||
|
||||
Wrapper driver. :ref:`rbug` driver used with stand alone rbug-gui.
|
||||
|
||||
Gallium frontends
|
||||
-----------------
|
||||
|
||||
Clover
|
||||
^^^^^^
|
||||
|
||||
Tracker that implements the Khronos OpenCL standard.
|
||||
|
||||
.. _dri:
|
||||
|
||||
Direct Rendering Infrastructure
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Tracker that implements the client-side DRI protocol, for providing direct
|
||||
acceleration services to X11 servers with the DRI extension. Supports DRI1
|
||||
and DRI2. Only GL is supported.
|
||||
|
||||
GLX
|
||||
^^^
|
||||
|
||||
MesaGL
|
||||
^^^^^^
|
||||
|
||||
The gallium frontend implementing a GL state machine. Not usable as
|
||||
a standalone frontend; Mesa should be built with another gallium frontend,
|
||||
such as :ref:`DRI` or EGL.
|
||||
|
||||
VDPAU
|
||||
^^^^^
|
||||
|
||||
Tracker for Video Decode and Presentation API for Unix.
|
||||
|
||||
WGL
|
||||
^^^
|
||||
|
||||
Xorg DDX
|
||||
^^^^^^^^
|
||||
|
||||
Tracker for Xorg X11 servers. Provides device-dependent
|
||||
modesetting and acceleration as a DDX driver.
|
||||
|
||||
XvMC
|
||||
^^^^
|
||||
|
||||
Tracker for X-Video Motion Compensation.
|
||||
|
||||
Auxiliary
|
||||
---------
|
||||
|
||||
OS
|
||||
^^
|
||||
|
||||
The OS module contains the abstractions for basic operating system services:
|
||||
|
||||
* memory allocation
|
||||
* simple message logging
|
||||
* obtaining run-time configuration option
|
||||
* threading primitives
|
||||
|
||||
This is the bare minimum required to port Gallium to a new platform.
|
||||
|
||||
The OS module already provides the implementations of these abstractions for
|
||||
the most common platforms. When targeting an embedded platform no
|
||||
implementation will be provided -- these must be provided separately.
|
||||
|
||||
CSO Cache
|
||||
^^^^^^^^^
|
||||
|
||||
The CSO cache is used to accelerate preparation of state by saving
|
||||
driver-specific state structures for later use.
|
||||
|
||||
.. _draw:
|
||||
|
||||
Draw
|
||||
^^^^
|
||||
|
||||
Draw is a software :term:`TCL` pipeline for hardware that lacks vertex shaders
|
||||
or other essential parts of pre-rasterization vertex preparation.
|
||||
|
||||
Gallivm
|
||||
^^^^^^^
|
||||
|
||||
Indices
|
||||
^^^^^^^
|
||||
|
||||
Indices provides tools for translating or generating element indices for
|
||||
use with element-based rendering.
|
||||
|
||||
Pipe Buffer Managers
|
||||
^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Each of these managers provides various services to drivers that are not
|
||||
fully utilizing a memory manager.
|
||||
|
||||
Remote Debugger
|
||||
^^^^^^^^^^^^^^^
|
||||
|
||||
Runtime Assembly Emission
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
TGSI
|
||||
^^^^
|
||||
|
||||
The TGSI auxiliary module provides basic utilities for manipulating TGSI
|
||||
streams.
|
||||
|
||||
Translate
|
||||
^^^^^^^^^
|
||||
|
||||
Util
|
||||
^^^^
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
Drivers
|
||||
=======
|
||||
|
||||
Driver specific documentation.
|
||||
|
||||
.. toctree::
|
||||
:glob:
|
||||
|
||||
drivers/*
|
||||
@@ -0,0 +1,9 @@
|
||||
Freedreno
|
||||
=========
|
||||
|
||||
Freedreno driver specific docs.
|
||||
|
||||
.. toctree::
|
||||
:glob:
|
||||
|
||||
freedreno/*
|
||||
@@ -0,0 +1,432 @@
|
||||
IR3 NOTES
|
||||
=========
|
||||
|
||||
Some notes about ir3, the compiler and machine-specific IR for the shader ISA introduced with adreno a3xx. The same shader ISA is present, with some small differences, in adreno a4xx.
|
||||
|
||||
Compared to the previous generation a2xx ISA (ir2), the a3xx ISA is a "simple" scalar instruction set. However, the compiler is responsible, in most cases, to schedule the instructions. The hardware does not try to hide the shader core pipeline stages. For a common example, a common (cat2) ALU instruction takes four cycles, so a subsequent cat2 instruction which uses the result must have three intervening instructions (or nops). When operating on vec4's, typically the corresponding scalar instructions for operating on the remaining three components could typically fit. Although that results in a lot of edge cases where things fall over, like:
|
||||
|
||||
::
|
||||
|
||||
ADD TEMP[0], TEMP[1], TEMP[2]
|
||||
MUL TEMP[0], TEMP[1], TEMP[0].wzyx
|
||||
|
||||
Here, the second instruction needs the output of the first group of scalar instructions in the wrong order, resulting in not enough instruction spots between the ``add r0.w, r1.w, r2.w`` and ``mul r0.x, r1.x, r0.w``. Which is why the original (old) compiler which merely translated nearly literally from TGSI to ir3, had a strong tendency to fall over.
|
||||
|
||||
So the current compiler instead, in the frontend, generates a directed-acyclic-graph of instructions and basic blocks, which go through various additional passes to eventually schedule and do register assignment.
|
||||
|
||||
For additional documentation about the hardware, see wiki: `a3xx ISA
|
||||
<https://github.com/freedreno/freedreno/wiki/A3xx-shader-instruction-set-architecture>`_.
|
||||
|
||||
External Structure
|
||||
------------------
|
||||
|
||||
``ir3_shader``
|
||||
A single vertex/fragment/etc shader from gallium perspective (ie.
|
||||
maps to a single TGSI shader), and manages a set of shader variants
|
||||
which are generated on demand based on the shader key.
|
||||
|
||||
``ir3_shader_key``
|
||||
The configuration key that identifies a shader variant. Ie. based
|
||||
on other GL state (two-sided-color, render-to-alpha, etc) or render
|
||||
stages (binning-pass vertex shader) different shader variants are
|
||||
generated.
|
||||
|
||||
``ir3_shader_variant``
|
||||
The actual hw shader generated based on input TGSI and shader key.
|
||||
|
||||
``ir3_compiler``
|
||||
Compiler frontend which generates ir3 and runs the various backend
|
||||
stages to schedule and do register assignment.
|
||||
|
||||
The IR
|
||||
------
|
||||
|
||||
The ir3 IR maps quite directly to the hardware, in that instruction opcodes map directly to hardware opcodes, and that dst/src register(s) map directly to the hardware dst/src register(s). But there are a few extensions, in the form of meta_ instructions. And additionally, for normal (non-const, etc) src registers, the ``IR3_REG_SSA`` flag is set and ``reg->instr`` points to the source instruction which produced that value. So, for example, the following TGSI shader:
|
||||
|
||||
::
|
||||
|
||||
VERT
|
||||
DCL IN[0]
|
||||
DCL IN[1]
|
||||
DCL OUT[0], POSITION
|
||||
DCL TEMP[0], LOCAL
|
||||
1: DP3 TEMP[0].x, IN[0].xyzz, IN[1].xyzz
|
||||
2: MOV OUT[0], TEMP[0].xxxx
|
||||
3: END
|
||||
|
||||
eventually generates:
|
||||
|
||||
.. graphviz::
|
||||
|
||||
digraph G {
|
||||
rankdir=RL;
|
||||
nodesep=0.25;
|
||||
ranksep=1.5;
|
||||
subgraph clusterdce198 {
|
||||
label="vert";
|
||||
inputdce198 [shape=record,label="inputs|<in0> i0.x|<in1> i0.y|<in2> i0.z|<in4> i1.x|<in5> i1.y|<in6> i1.z"];
|
||||
instrdcf348 [shape=record,style=filled,fillcolor=lightgrey,label="{mov.f32f32|<dst0>|<src0> }"];
|
||||
instrdcedd0 [shape=record,style=filled,fillcolor=lightgrey,label="{mad.f32|<dst0>|<src0> |<src1> |<src2> }"];
|
||||
inputdce198:<in2>:w -> instrdcedd0:<src0>
|
||||
inputdce198:<in6>:w -> instrdcedd0:<src1>
|
||||
instrdcec30 [shape=record,style=filled,fillcolor=lightgrey,label="{mad.f32|<dst0>|<src0> |<src1> |<src2> }"];
|
||||
inputdce198:<in1>:w -> instrdcec30:<src0>
|
||||
inputdce198:<in5>:w -> instrdcec30:<src1>
|
||||
instrdceb60 [shape=record,style=filled,fillcolor=lightgrey,label="{mul.f|<dst0>|<src0> |<src1> }"];
|
||||
inputdce198:<in0>:w -> instrdceb60:<src0>
|
||||
inputdce198:<in4>:w -> instrdceb60:<src1>
|
||||
instrdceb60:<dst0> -> instrdcec30:<src2>
|
||||
instrdcec30:<dst0> -> instrdcedd0:<src2>
|
||||
instrdcedd0:<dst0> -> instrdcf348:<src0>
|
||||
instrdcf400 [shape=record,style=filled,fillcolor=lightgrey,label="{mov.f32f32|<dst0>|<src0> }"];
|
||||
instrdcedd0:<dst0> -> instrdcf400:<src0>
|
||||
instrdcf4b8 [shape=record,style=filled,fillcolor=lightgrey,label="{mov.f32f32|<dst0>|<src0> }"];
|
||||
instrdcedd0:<dst0> -> instrdcf4b8:<src0>
|
||||
outputdce198 [shape=record,label="outputs|<out0> o0.x|<out1> o0.y|<out2> o0.z|<out3> o0.w"];
|
||||
instrdcf348:<dst0> -> outputdce198:<out0>:e
|
||||
instrdcf400:<dst0> -> outputdce198:<out1>:e
|
||||
instrdcf4b8:<dst0> -> outputdce198:<out2>:e
|
||||
instrdcedd0:<dst0> -> outputdce198:<out3>:e
|
||||
}
|
||||
}
|
||||
|
||||
(after scheduling, etc, but before register assignment).
|
||||
|
||||
Internal Structure
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
|
||||
``ir3_block``
|
||||
Represents a basic block.
|
||||
|
||||
TODO: currently blocks are nested, but I think I need to change that
|
||||
to a more conventional arrangement before implementing proper flow
|
||||
control. Currently the only flow control handles is if/else which
|
||||
gets flattened out and results chosen with ``sel`` instructions.
|
||||
|
||||
``ir3_instruction``
|
||||
Represents a machine instruction or meta_ instruction. Has pointers
|
||||
to dst register (``regs[0]``) and src register(s) (``regs[1..n]``),
|
||||
as needed.
|
||||
|
||||
``ir3_register``
|
||||
Represents a src or dst register, flags indicate const/relative/etc.
|
||||
If ``IR3_REG_SSA`` is set on a src register, the actual register
|
||||
number (name) has not been assigned yet, and instead the ``instr``
|
||||
field points to src instruction.
|
||||
|
||||
In addition there are various util macros/functions to simplify manipulation/traversal of the graph:
|
||||
|
||||
``foreach_src(srcreg, instr)``
|
||||
Iterate each instruction's source ``ir3_register``\s
|
||||
|
||||
``foreach_src_n(srcreg, n, instr)``
|
||||
Like ``foreach_src``, also setting ``n`` to the source number (starting
|
||||
with ``0``).
|
||||
|
||||
``foreach_ssa_src(srcinstr, instr)``
|
||||
Iterate each instruction's SSA source ``ir3_instruction``\s. This skips
|
||||
non-SSA sources (consts, etc), but includes virtual sources (such as the
|
||||
address register if `relative addressing`_ is used).
|
||||
|
||||
``foreach_ssa_src_n(srcinstr, n, instr)``
|
||||
Like ``foreach_ssa_src``, also setting ``n`` to the source number.
|
||||
|
||||
For example:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
foreach_ssa_src_n(src, i, instr) {
|
||||
unsigned d = delay_calc_srcn(ctx, src, instr, i);
|
||||
delay = MAX2(delay, d);
|
||||
}
|
||||
|
||||
|
||||
TODO probably other helper/util stuff worth mentioning here
|
||||
|
||||
.. _meta:
|
||||
|
||||
Meta Instructions
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
||||
**input**
|
||||
Used for shader inputs (registers configured in the command-stream
|
||||
to hold particular input values, written by the shader core before
|
||||
start of execution. Also used for connecting up values within a
|
||||
basic block to an output of a previous block.
|
||||
|
||||
**output**
|
||||
Used to hold outputs of a basic block.
|
||||
|
||||
**flow**
|
||||
TODO
|
||||
|
||||
**phi**
|
||||
TODO
|
||||
|
||||
**fanin**
|
||||
Groups registers which need to be assigned to consecutive scalar
|
||||
registers, for example `sam` (texture fetch) src instructions (see
|
||||
`register groups`_) or array element dereference
|
||||
(see `relative addressing`_).
|
||||
|
||||
**fanout**
|
||||
The counterpart to **fanin**, when an instruction such as `sam`
|
||||
writes multiple components, splits the result into individual
|
||||
scalar components to be consumed by other instructions.
|
||||
|
||||
|
||||
.. _`flow control`:
|
||||
|
||||
Flow Control
|
||||
~~~~~~~~~~~~
|
||||
|
||||
TODO
|
||||
|
||||
|
||||
.. _`register groups`:
|
||||
|
||||
Register Groups
|
||||
~~~~~~~~~~~~~~~
|
||||
|
||||
Certain instructions, such as texture sample instructions, consume multiple consecutive scalar registers via a single src register encoded in the instruction, and/or write multiple consecutive scalar registers. In the simplest example:
|
||||
|
||||
::
|
||||
|
||||
sam (f32)(xyz)r2.x, r0.z, s#0, t#0
|
||||
|
||||
for a 2d texture, would read ``r0.zw`` to get the coordinate, and write ``r2.xyz``.
|
||||
|
||||
Before register assignment, to group the two components of the texture src together:
|
||||
|
||||
.. graphviz::
|
||||
|
||||
digraph G {
|
||||
{ rank=same;
|
||||
fanin;
|
||||
};
|
||||
{ rank=same;
|
||||
coord_x;
|
||||
coord_y;
|
||||
};
|
||||
sam -> fanin [label="regs[1]"];
|
||||
fanin -> coord_x [label="regs[1]"];
|
||||
fanin -> coord_y [label="regs[2]"];
|
||||
coord_x -> coord_y [label="right",style=dotted];
|
||||
coord_y -> coord_x [label="left",style=dotted];
|
||||
coord_x [label="coord.x"];
|
||||
coord_y [label="coord.y"];
|
||||
}
|
||||
|
||||
The frontend sets up the SSA ptrs from ``sam`` source register to the ``fanin`` meta instruction, which in turn points to the instructions producing the ``coord.x`` and ``coord.y`` values. And the grouping_ pass sets up the ``left`` and ``right`` neighbor pointers to the ``fanin``\'s sources, used later by the `register assignment`_ pass to assign blocks of scalar registers.
|
||||
|
||||
And likewise, for the consecutive scalar registers for the destination:
|
||||
|
||||
.. graphviz::
|
||||
|
||||
digraph {
|
||||
{ rank=same;
|
||||
A;
|
||||
B;
|
||||
C;
|
||||
};
|
||||
{ rank=same;
|
||||
fanout_0;
|
||||
fanout_1;
|
||||
fanout_2;
|
||||
};
|
||||
A -> fanout_0;
|
||||
B -> fanout_1;
|
||||
C -> fanout_2;
|
||||
fanout_0 [label="fanout\noff=0"];
|
||||
fanout_0 -> sam;
|
||||
fanout_1 [label="fanout\noff=1"];
|
||||
fanout_1 -> sam;
|
||||
fanout_2 [label="fanout\noff=2"];
|
||||
fanout_2 -> sam;
|
||||
fanout_0 -> fanout_1 [label="right",style=dotted];
|
||||
fanout_1 -> fanout_0 [label="left",style=dotted];
|
||||
fanout_1 -> fanout_2 [label="right",style=dotted];
|
||||
fanout_2 -> fanout_1 [label="left",style=dotted];
|
||||
sam;
|
||||
}
|
||||
|
||||
.. _`relative addressing`:
|
||||
|
||||
Relative Addressing
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Most instructions support addressing indirectly (relative to address register) into const or gpr register file in some or all of their src/dst registers. In this case the register accessed is taken from ``r<a0.x + n>`` or ``c<a0.x + n>``, ie. address register (``a0.x``) value plus ``n``, where ``n`` is encoded in the instruction (rather than the absolute register number).
|
||||
|
||||
Note that cat5 (texture sample) instructions are the notable exception, not
|
||||
supporting relative addressing of src or dst.
|
||||
|
||||
Relative addressing of the const file (for example, a uniform array) is relatively simple. We don't do register assignment of the const file, so all that is required is to schedule things properly. Ie. the instruction that writes the address register must be scheduled first, and we cannot have two different address register values live at one time.
|
||||
|
||||
But relative addressing of gpr file (which can be as src or dst) has additional restrictions on register assignment (ie. the array elements must be assigned to consecutive scalar registers). And in the case of relative dst, subsequent instructions now depend on both the relative write, as well as the previous instruction which wrote that register, since we do not know at compile time which actual register was written.
|
||||
|
||||
Each instruction has an optional ``address`` pointer, to capture the dependency on the address register value when relative addressing is used for any of the src/dst register(s). This behaves as an additional virtual src register, ie. ``foreach_ssa_src()`` will also iterate the address register (last).
|
||||
|
||||
Note that ``nop``\'s for timing constraints, type specifiers (ie.
|
||||
``add.f`` vs ``add.u``), etc, omitted for brevity in examples
|
||||
|
||||
::
|
||||
|
||||
mova a0.x, hr1.y
|
||||
sub r1.y, r2.x, r3.x
|
||||
add r0.x, r1.y, c<a0.x + 2>
|
||||
|
||||
results in:
|
||||
|
||||
.. graphviz::
|
||||
|
||||
digraph {
|
||||
rankdir=LR;
|
||||
sub;
|
||||
const [label="const file"];
|
||||
add;
|
||||
mova;
|
||||
add -> mova;
|
||||
add -> sub;
|
||||
add -> const [label="off=2"];
|
||||
}
|
||||
|
||||
The scheduling pass has some smarts to schedule things such that only a single ``a0.x`` value is used at any one time.
|
||||
|
||||
To implement variable arrays, values are stored in consecutive scalar registers. This has some overlap with `register groups`_, in that ``fanin`` and ``fanout`` are used to help group things for the `register assignment`_ pass.
|
||||
|
||||
To use a variable array as a src register, a slight variation of what is done for const array src. The instruction src is a `fanin` instruction that groups all the array members:
|
||||
|
||||
::
|
||||
|
||||
mova a0.x, hr1.y
|
||||
sub r1.y, r2.x, r3.x
|
||||
add r0.x, r1.y, r<a0.x + 2>
|
||||
|
||||
results in:
|
||||
|
||||
.. graphviz::
|
||||
|
||||
digraph {
|
||||
a0 [label="r0.z"];
|
||||
a1 [label="r0.w"];
|
||||
a2 [label="r1.x"];
|
||||
a3 [label="r1.y"];
|
||||
sub;
|
||||
fanin;
|
||||
mova;
|
||||
add;
|
||||
add -> sub;
|
||||
add -> fanin [label="off=2"];
|
||||
add -> mova;
|
||||
fanin -> a0;
|
||||
fanin -> a1;
|
||||
fanin -> a2;
|
||||
fanin -> a3;
|
||||
}
|
||||
|
||||
TODO better describe how actual deref offset is derived, ie. based on array base register.
|
||||
|
||||
To do an indirect write to a variable array, a ``fanout`` is used. Say the array was assigned to registers ``r0.z`` through ``r1.y`` (hence the constant offset of 2):
|
||||
|
||||
Note that only cat1 (mov) can do indirect write.
|
||||
|
||||
::
|
||||
|
||||
mova a0.x, hr1.y
|
||||
min r2.x, r2.x, c0.x
|
||||
mov r<a0.x + 2>, r2.x
|
||||
mul r0.x, r0.z, c0.z
|
||||
|
||||
|
||||
In this case, the ``mov`` instruction does not write all elements of the array (compared to usage of ``fanout`` for ``sam`` instructions in grouping_). But the ``mov`` instruction does need an additional dependency (via ``fanin``) on instructions that last wrote the array element members, to ensure that they get scheduled before the ``mov`` in scheduling_ stage (which also serves to group the array elements for the `register assignment`_ stage).
|
||||
|
||||
.. graphviz::
|
||||
|
||||
digraph {
|
||||
a0 [label="r0.z"];
|
||||
a1 [label="r0.w"];
|
||||
a2 [label="r1.x"];
|
||||
a3 [label="r1.y"];
|
||||
min;
|
||||
mova;
|
||||
mov;
|
||||
mul;
|
||||
fanout [label="fanout\noff=0"];
|
||||
mul -> fanout;
|
||||
fanout -> mov;
|
||||
fanin;
|
||||
fanin -> a0;
|
||||
fanin -> a1;
|
||||
fanin -> a2;
|
||||
fanin -> a3;
|
||||
mov -> min;
|
||||
mov -> mova;
|
||||
mov -> fanin;
|
||||
}
|
||||
|
||||
Note that there would in fact be ``fanout`` nodes generated for each array element (although only the reachable ones will be scheduled, etc).
|
||||
|
||||
|
||||
|
||||
Shader Passes
|
||||
-------------
|
||||
|
||||
After the frontend has generated the use-def graph of instructions, they are run through various passes which include scheduling_ and `register assignment`_. Because inserting ``mov`` instructions after scheduling would also require inserting additional ``nop`` instructions (since it is too late to reschedule to try and fill the bubbles), the earlier stages try to ensure that (at least given an infinite supply of registers) that `register assignment`_ after scheduling_ cannot fail.
|
||||
|
||||
Note that we essentially have ~256 scalar registers in the
|
||||
architecture (although larger register usage will at some thresholds
|
||||
limit the number of threads which can run in parallel). And at some
|
||||
point we will have to deal with spilling.
|
||||
|
||||
.. _flatten:
|
||||
|
||||
Flatten
|
||||
~~~~~~~
|
||||
|
||||
In this stage, simple if/else blocks are flattened into a single block with ``phi`` nodes converted into ``sel`` instructions. The a3xx ISA has very few predicated instructions, and we would prefer not to use branches for simple if/else.
|
||||
|
||||
|
||||
.. _`copy propagation`:
|
||||
|
||||
Copy Propagation
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
Currently the frontend inserts ``mov``\s in various cases, because certain categories of instructions have limitations about const regs as sources. And the CP pass simply removes all simple ``mov``\s (ie. src-type is same as dst-type, no abs/neg flags, etc).
|
||||
|
||||
The eventual plan is to invert that, with the front-end inserting no ``mov``\s and CP legalize things.
|
||||
|
||||
|
||||
.. _grouping:
|
||||
|
||||
Grouping
|
||||
~~~~~~~~
|
||||
|
||||
In the grouping pass, instructions which need to be grouped (for ``fanin``\s, etc) have their ``left`` / ``right`` neighbor pointers setup. In cases where there is a conflict (ie. one instruction cannot have two unique left or right neighbors), an additional ``mov`` instruction is inserted. This ensures that there is some possible valid `register assignment`_ at the later stages.
|
||||
|
||||
|
||||
.. _depth:
|
||||
|
||||
Depth
|
||||
~~~~~
|
||||
|
||||
In the depth pass, a depth is calculated for each instruction node within it's basic block. The depth is the sum of the required cycles (delay slots needed between two instructions plus one) of each instruction plus the max depth of any of it's source instructions. (meta_ instructions don't add to the depth). As an instruction's depth is calculated, it is inserted into a per block list sorted by deepest instruction. Unreachable instructions and inputs are marked.
|
||||
|
||||
TODO: we should probably calculate both hard and soft depths (?) to
|
||||
try to coax additional instructions to fit in places where we need
|
||||
to use sync bits, such as after a texture fetch or SFU.
|
||||
|
||||
.. _scheduling:
|
||||
|
||||
Scheduling
|
||||
~~~~~~~~~~
|
||||
|
||||
After the grouping_ pass, there are no more instructions to insert or remove. Start scheduling each basic block from the deepest node in the depth sorted list created by the depth_ pass, recursively trying to schedule each instruction after it's source instructions plus delay slots. Insert ``nop``\s as required.
|
||||
|
||||
.. _`register assignment`:
|
||||
|
||||
Register Assignment
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
TODO
|
||||
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
OpenSWR
|
||||
=======
|
||||
|
||||
The Gallium OpenSWR driver is a high performance, highly scalable
|
||||
software renderer targeted towards visualization workloads. For such
|
||||
geometry heavy workloads there is a considerable speedup over llvmpipe,
|
||||
which is to be expected as the geometry frontend of llvmpipe is single
|
||||
threaded.
|
||||
|
||||
This rasterizer is x86 specific and requires AVX or above. The driver
|
||||
fits into the gallium framework, and reuses gallivm for doing the TGSI
|
||||
to vectorized llvm-IR conversion of the shader kernels.
|
||||
|
||||
.. toctree::
|
||||
:glob:
|
||||
|
||||
openswr/usage
|
||||
openswr/faq
|
||||
openswr/profiling
|
||||
openswr/knobs
|
||||
|
||||
@@ -0,0 +1,141 @@
|
||||
FAQ
|
||||
===
|
||||
|
||||
Why another software rasterizer?
|
||||
--------------------------------
|
||||
|
||||
Good question, given there are already three (swrast, softpipe,
|
||||
llvmpipe) in the Mesa tree. Two important reasons for this:
|
||||
|
||||
* Architecture - given our focus on scientific visualization, our
|
||||
workloads are much different than the typical game; we have heavy
|
||||
vertex load and relatively simple shaders. In addition, the core
|
||||
counts of machines we run on are much higher. These parameters led
|
||||
to design decisions much different than llvmpipe.
|
||||
|
||||
* Historical - Intel had developed a high performance software
|
||||
graphics stack for internal purposes. Later we adapted this
|
||||
graphics stack for use in visualization and decided to move forward
|
||||
with Mesa to provide a high quality API layer while at the same
|
||||
time benefiting from the excellent performance the software
|
||||
rasterizerizer gives us.
|
||||
|
||||
What's the architecture?
|
||||
------------------------
|
||||
|
||||
SWR is a tile based immediate mode renderer with a sort-free threading
|
||||
model which is arranged as a ring of queues. Each entry in the ring
|
||||
represents a draw context that contains all of the draw state and work
|
||||
queues. An API thread sets up each draw context and worker threads
|
||||
will execute both the frontend (vertex/geometry processing) and
|
||||
backend (fragment) work as required. The ring allows for backend
|
||||
threads to pull work in order. Large draws are split into chunks to
|
||||
allow vertex processing to happen in parallel, with the backend work
|
||||
pickup preserving draw ordering.
|
||||
|
||||
Our pipeline uses just-in-time compiled code for the fetch shader that
|
||||
does vertex attribute gathering and AOS to SOA conversions, the vertex
|
||||
shader and fragment shaders, streamout, and fragment blending. SWR
|
||||
core also supports geometry and compute shaders but we haven't exposed
|
||||
them through our driver yet. The fetch shader, streamout, and blend is
|
||||
built internally to swr core using LLVM directly, while for the vertex
|
||||
and pixel shaders we reuse bits of llvmpipe from
|
||||
``gallium/auxiliary/gallivm`` to build the kernels, which we wrap
|
||||
differently than llvmpipe's ``auxiliary/draw`` code.
|
||||
|
||||
What's the performance?
|
||||
-----------------------
|
||||
|
||||
For the types of high-geometry workloads we're interested in, we are
|
||||
significantly faster than llvmpipe. This is to be expected, as
|
||||
llvmpipe only threads the fragment processing and not the geometry
|
||||
frontend. The performance advantage over llvmpipe roughly scales
|
||||
linearly with the number of cores available.
|
||||
|
||||
While our current performance is quite good, we know there is more
|
||||
potential in this architecture. When we switched from a prototype
|
||||
OpenGL driver to Mesa we regressed performance severely, some due to
|
||||
interface issues that need tuning, some differences in shader code
|
||||
generation, and some due to conformance and feature additions to the
|
||||
core swr. We are looking to recovering most of this performance back.
|
||||
|
||||
What's the conformance?
|
||||
-----------------------
|
||||
|
||||
The major applications we are targeting are all based on the
|
||||
Visualization Toolkit (VTK), and as such our development efforts have
|
||||
been focused on making sure these work as best as possible. Our
|
||||
current code passes vtk's rendering tests with their new "OpenGL2"
|
||||
(really OpenGL 3.2) backend at 99%.
|
||||
|
||||
piglit testing shows a much lower pass rate, roughly 80% at the time
|
||||
of writing. Core SWR undergoes rigorous unit testing and we are quite
|
||||
confident in the rasterizer, and understand the areas where it
|
||||
currently has issues (example: line rendering is done with triangles,
|
||||
so doesn't match the strict line rendering rules). The majority of
|
||||
the piglit failures are errors in our driver layer interfacing Mesa
|
||||
and SWR. Fixing these issues is one of our major future development
|
||||
goals.
|
||||
|
||||
Why are you open sourcing this?
|
||||
-------------------------------
|
||||
|
||||
* Our customers prefer open source, and allowing them to simply
|
||||
download the Mesa source and enable our driver makes life much
|
||||
easier for them.
|
||||
|
||||
* The internal gallium APIs are not stable, so we'd like our driver
|
||||
to be visible for changes.
|
||||
|
||||
* It's easier to work with the Mesa community when the source we're
|
||||
working with can be used as reference.
|
||||
|
||||
What are your development plans?
|
||||
--------------------------------
|
||||
|
||||
* Performance - see the performance section earlier for details.
|
||||
|
||||
* Conformance - see the conformance section earlier for details.
|
||||
|
||||
* Features - core SWR has a lot of functionality we have yet to
|
||||
expose through our driver, such as MSAA, geometry shaders, compute
|
||||
shaders, and tesselation.
|
||||
|
||||
* AVX512 support
|
||||
|
||||
What is the licensing of the code?
|
||||
----------------------------------
|
||||
|
||||
* All code is under the normal Mesa MIT license.
|
||||
|
||||
Will this work on AMD?
|
||||
----------------------
|
||||
|
||||
* If using an AMD processor with AVX or AVX2, it should work though
|
||||
we don't have that hardware around to test. Patches if needed
|
||||
would be welcome.
|
||||
|
||||
Will this work on ARM, MIPS, POWER, <other non-x86 architecture>?
|
||||
-------------------------------------------------------------------------
|
||||
|
||||
* Not without a lot of work. We make extensive use of AVX and AVX2
|
||||
intrinsics in our code and the in-tree JIT creation. It is not the
|
||||
intention for this codebase to support non-x86 architectures.
|
||||
|
||||
What hardware do I need?
|
||||
------------------------
|
||||
|
||||
* Any x86 processor with at least AVX (introduced in the Intel
|
||||
SandyBridge and AMD Bulldozer microarchitectures in 2011) will
|
||||
work.
|
||||
|
||||
* You don't need a fire-breathing Xeon machine to work on SWR - we do
|
||||
day-to-day development with laptops and desktop CPUs.
|
||||
|
||||
Does one build work on both AVX and AVX2?
|
||||
-----------------------------------------
|
||||
|
||||
Yes. The build system creates two shared libraries, ``libswrAVX.so`` and
|
||||
``libswrAVX2.so``, and ``swr_create_screen()`` loads the appropriate one at
|
||||
runtime.
|
||||
|
||||
@@ -0,0 +1,114 @@
|
||||
Knobs
|
||||
=====
|
||||
|
||||
OpenSWR has a number of environment variables which control its
|
||||
operation, in addition to the normal Mesa and gallium controls.
|
||||
|
||||
.. envvar:: KNOB_ENABLE_ASSERT_DIALOGS <bool> (true)
|
||||
|
||||
Use dialogs when asserts fire. Asserts are only enabled in debug builds
|
||||
|
||||
.. envvar:: KNOB_SINGLE_THREADED <bool> (false)
|
||||
|
||||
If enabled will perform all rendering on the API thread. This is useful mainly for debugging purposes.
|
||||
|
||||
.. envvar:: KNOB_DUMP_SHADER_IR <bool> (false)
|
||||
|
||||
Dumps shader LLVM IR at various stages of jit compilation.
|
||||
|
||||
.. envvar:: KNOB_USE_GENERIC_STORETILE <bool> (false)
|
||||
|
||||
Always use generic function for performing StoreTile. Will be slightly slower than using optimized (jitted) path
|
||||
|
||||
.. envvar:: KNOB_FAST_CLEAR <bool> (true)
|
||||
|
||||
Replace 3D primitive execute with a SWRClearRT operation and defer clear execution to first backend op on hottile, or hottile store
|
||||
|
||||
.. envvar:: KNOB_MAX_NUMA_NODES <uint32_t> (0)
|
||||
|
||||
Maximum # of NUMA-nodes per system used for worker threads 0 == ALL NUMA-nodes in the system N == Use at most N NUMA-nodes for rendering
|
||||
|
||||
.. envvar:: KNOB_MAX_CORES_PER_NUMA_NODE <uint32_t> (0)
|
||||
|
||||
Maximum # of cores per NUMA-node used for worker threads. 0 == ALL non-API thread cores per NUMA-node N == Use at most N cores per NUMA-node
|
||||
|
||||
.. envvar:: KNOB_MAX_THREADS_PER_CORE <uint32_t> (1)
|
||||
|
||||
Maximum # of (hyper)threads per physical core used for worker threads. 0 == ALL hyper-threads per core N == Use at most N hyper-threads per physical core
|
||||
|
||||
.. envvar:: KNOB_MAX_WORKER_THREADS <uint32_t> (0)
|
||||
|
||||
Maximum worker threads to spawn. IMPORTANT: If this is non-zero, no worker threads will be bound to specific HW threads. They will all be "floating" SW threads. In this case, the above 3 KNOBS will be ignored.
|
||||
|
||||
.. envvar:: KNOB_BUCKETS_START_FRAME <uint32_t> (1200)
|
||||
|
||||
Frame from when to start saving buckets data. NOTE: KNOB_ENABLE_RDTSC must be enabled in core/knobs.h for this to have an effect.
|
||||
|
||||
.. envvar:: KNOB_BUCKETS_END_FRAME <uint32_t> (1400)
|
||||
|
||||
Frame at which to stop saving buckets data. NOTE: KNOB_ENABLE_RDTSC must be enabled in core/knobs.h for this to have an effect.
|
||||
|
||||
.. envvar:: KNOB_WORKER_SPIN_LOOP_COUNT <uint32_t> (5000)
|
||||
|
||||
Number of spin-loop iterations worker threads will perform before going to sleep when waiting for work
|
||||
|
||||
.. envvar:: KNOB_MAX_DRAWS_IN_FLIGHT <uint32_t> (160)
|
||||
|
||||
Maximum number of draws outstanding before API thread blocks.
|
||||
|
||||
.. envvar:: KNOB_MAX_PRIMS_PER_DRAW <uint32_t> (2040)
|
||||
|
||||
Maximum primitives in a single Draw(). Larger primitives are split into smaller Draw calls. Should be a multiple of (3 * vectorWidth).
|
||||
|
||||
.. envvar:: KNOB_MAX_TESS_PRIMS_PER_DRAW <uint32_t> (16)
|
||||
|
||||
Maximum primitives in a single Draw() with tessellation enabled. Larger primitives are split into smaller Draw calls. Should be a multiple of (vectorWidth).
|
||||
|
||||
.. envvar:: KNOB_MAX_FRAC_ODD_TESS_FACTOR <float> (63.0f)
|
||||
|
||||
(DEBUG) Maximum tessellation factor for fractional-odd partitioning.
|
||||
|
||||
.. envvar:: KNOB_MAX_FRAC_EVEN_TESS_FACTOR <float> (64.0f)
|
||||
|
||||
(DEBUG) Maximum tessellation factor for fractional-even partitioning.
|
||||
|
||||
.. envvar:: KNOB_MAX_INTEGER_TESS_FACTOR <uint32_t> (64)
|
||||
|
||||
(DEBUG) Maximum tessellation factor for integer partitioning.
|
||||
|
||||
.. envvar:: KNOB_BUCKETS_ENABLE_THREADVIZ <bool> (false)
|
||||
|
||||
Enable threadviz output.
|
||||
|
||||
.. envvar:: KNOB_TOSS_DRAW <bool> (false)
|
||||
|
||||
Disable per-draw/dispatch execution
|
||||
|
||||
.. envvar:: KNOB_TOSS_QUEUE_FE <bool> (false)
|
||||
|
||||
Stop per-draw execution at worker FE NOTE: Requires KNOB_ENABLE_TOSS_POINTS to be enabled in core/knobs.h
|
||||
|
||||
.. envvar:: KNOB_TOSS_FETCH <bool> (false)
|
||||
|
||||
Stop per-draw execution at vertex fetch NOTE: Requires KNOB_ENABLE_TOSS_POINTS to be enabled in core/knobs.h
|
||||
|
||||
.. envvar:: KNOB_TOSS_IA <bool> (false)
|
||||
|
||||
Stop per-draw execution at input assembler NOTE: Requires KNOB_ENABLE_TOSS_POINTS to be enabled in core/knobs.h
|
||||
|
||||
.. envvar:: KNOB_TOSS_VS <bool> (false)
|
||||
|
||||
Stop per-draw execution at vertex shader NOTE: Requires KNOB_ENABLE_TOSS_POINTS to be enabled in core/knobs.h
|
||||
|
||||
.. envvar:: KNOB_TOSS_SETUP_TRIS <bool> (false)
|
||||
|
||||
Stop per-draw execution at primitive setup NOTE: Requires KNOB_ENABLE_TOSS_POINTS to be enabled in core/knobs.h
|
||||
|
||||
.. envvar:: KNOB_TOSS_BIN_TRIS <bool> (false)
|
||||
|
||||
Stop per-draw execution at primitive binning NOTE: Requires KNOB_ENABLE_TOSS_POINTS to be enabled in core/knobs.h
|
||||
|
||||
.. envvar:: KNOB_TOSS_RS <bool> (false)
|
||||
|
||||
Stop per-draw execution at rasterizer NOTE: Requires KNOB_ENABLE_TOSS_POINTS to be enabled in core/knobs.h
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
Profiling
|
||||
=========
|
||||
|
||||
OpenSWR contains built-in profiling which can be enabled
|
||||
at build time to provide insight into performance tuning.
|
||||
|
||||
To enable this, uncomment the following line in ``rasterizer/core/knobs.h`` and rebuild: ::
|
||||
|
||||
//#define KNOB_ENABLE_RDTSC
|
||||
|
||||
Running an application will result in a ``rdtsc.txt`` file being
|
||||
created in current working directory. This file contains profile
|
||||
information captured between the ``KNOB_BUCKETS_START_FRAME`` and
|
||||
``KNOB_BUCKETS_END_FRAME`` (see knobs section).
|
||||
|
||||
The resulting file will contain sections for each thread with a
|
||||
hierarchical breakdown of the time spent in the various operations.
|
||||
For example: ::
|
||||
|
||||
Thread 0 (API)
|
||||
%Tot %Par Cycles CPE NumEvent CPE2 NumEvent2 Bucket
|
||||
0.00 0.00 28370 2837 10 0 0 APIClearRenderTarget
|
||||
0.00 41.23 11698 1169 10 0 0 |-> APIDrawWakeAllThreads
|
||||
0.00 18.34 5202 520 10 0 0 |-> APIGetDrawContext
|
||||
98.72 98.72 12413773688 29957 414380 0 0 APIDraw
|
||||
0.36 0.36 44689364 107 414380 0 0 |-> APIDrawWakeAllThreads
|
||||
96.36 97.62 12117951562 9747 1243140 0 0 |-> APIGetDrawContext
|
||||
0.00 0.00 19904 995 20 0 0 APIStoreTiles
|
||||
0.00 7.88 1568 78 20 0 0 |-> APIDrawWakeAllThreads
|
||||
0.00 25.28 5032 251 20 0 0 |-> APIGetDrawContext
|
||||
1.28 1.28 161344902 64 2486370 0 0 APIGetDrawContext
|
||||
0.00 0.00 50368 2518 20 0 0 APISync
|
||||
0.00 2.70 1360 68 20 0 0 |-> APIDrawWakeAllThreads
|
||||
0.00 65.27 32876 1643 20 0 0 |-> APIGetDrawContext
|
||||
|
||||
|
||||
Thread 1 (WORKER)
|
||||
%Tot %Par Cycles CPE NumEvent CPE2 NumEvent2 Bucket
|
||||
83.92 83.92 13198987522 96411 136902 0 0 FEProcessDraw
|
||||
24.91 29.69 3918184840 167 23410158 0 0 |-> FEFetchShader
|
||||
11.17 13.31 1756972646 75 23410158 0 0 |-> FEVertexShader
|
||||
8.89 10.59 1397902996 59 23410161 0 0 |-> FEPAAssemble
|
||||
19.06 22.71 2997794710 384 7803387 0 0 |-> FEClipTriangles
|
||||
11.67 61.21 1834958176 235 7803387 0 0 |-> FEBinTriangles
|
||||
0.00 0.00 0 0 187258 0 0 |-> FECullZeroAreaAndBackface
|
||||
0.00 0.00 0 0 60051033 0 0 |-> FECullBetweenCenters
|
||||
0.11 0.11 17217556 2869592 6 0 0 FEProcessStoreTiles
|
||||
15.97 15.97 2511392576 73665 34092 0 0 WorkerWorkOnFifoBE
|
||||
14.04 87.95 2208687340 9187 240408 0 0 |-> WorkerFoundWork
|
||||
0.06 0.43 9390536 13263 708 0 0 |-> BELoadTiles
|
||||
0.00 0.01 293020 182 1609 0 0 |-> BEClear
|
||||
12.63 89.94 1986508990 949 2093014 0 0 |-> BERasterizeTriangle
|
||||
2.37 18.75 372374596 177 2093014 0 0 |-> BETriangleSetup
|
||||
0.42 3.35 66539016 31 2093014 0 0 |-> BEStepSetup
|
||||
0.00 0.00 0 0 21766 0 0 |-> BETrivialReject
|
||||
1.05 8.33 165410662 79 2071248 0 0 |-> BERasterizePartial
|
||||
6.06 48.02 953847796 1260 756783 0 0 |-> BEPixelBackend
|
||||
0.20 3.30 31521202 41 756783 0 0 |-> BESetup
|
||||
0.16 2.69 25624304 33 756783 0 0 |-> BEBarycentric
|
||||
0.18 2.92 27884986 36 756783 0 0 |-> BEEarlyDepthTest
|
||||
0.19 3.20 30564174 41 744058 0 0 |-> BEPixelShader
|
||||
0.26 4.30 41058646 55 744058 0 0 |-> BEOutputMerger
|
||||
1.27 20.94 199750822 32 6054264 0 0 |-> BEEndTile
|
||||
0.33 2.34 51758160 23687 2185 0 0 |-> BEStoreTiles
|
||||
0.20 60.22 31169500 28807 1082 0 0 |-> B8G8R8A8_UNORM
|
||||
0.00 0.00 302752 302752 1 0 0 WorkerWaitForThreadEvent
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
Usage
|
||||
=====
|
||||
|
||||
Requirements
|
||||
^^^^^^^^^^^^
|
||||
|
||||
* An x86 processor with AVX or above
|
||||
* LLVM version 3.9 or later
|
||||
* C++14 capable compiler
|
||||
|
||||
Building
|
||||
^^^^^^^^
|
||||
|
||||
To build with GNU automake, select building the swr driver at
|
||||
configure time, for example: ::
|
||||
|
||||
configure --with-gallium-drivers=swrast,swr
|
||||
|
||||
Using
|
||||
^^^^^
|
||||
|
||||
On Linux, building with autotools will create a drop-in alternative
|
||||
for libGL.so into::
|
||||
|
||||
lib/gallium/libGL.so
|
||||
lib/gallium/libswrAVX.so
|
||||
lib/gallium/libswrAVX2.so
|
||||
|
||||
Alternatively, building with SCons will produce::
|
||||
|
||||
build/linux-x86_64/gallium/targets/libgl-xlib/libGL.so
|
||||
build/linux-x86_64/gallium/drivers/swr/libswrAVX.so
|
||||
build/linux-x86_64/gallium/drivers/swr/libswrAVX2.so
|
||||
|
||||
To use it set the LD_LIBRARY_PATH environment variable accordingly.
|
||||
|
||||
**IMPORTANT:** Mesa will default to using llvmpipe or softpipe as the default software renderer. To select the OpenSWR driver, set the GALLIUM_DRIVER environment variable appropriately: ::
|
||||
|
||||
GALLIUM_DRIVER=swr
|
||||
|
||||
To verify OpenSWR is being used, check to see if a message like the following is printed when the application is started: ::
|
||||
|
||||
SWR detected AVX2
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
Formats in gallium
|
||||
==================
|
||||
|
||||
Gallium format names mostly follow D3D10 conventions, with some extensions.
|
||||
|
||||
Format names like XnYnZnWn have the X component in the lowest-address n bits
|
||||
and the W component in the highest-address n bits; for B8G8R8A8, byte 0 is
|
||||
blue and byte 3 is alpha. Note that platform endianness is not considered
|
||||
in this definition. In C::
|
||||
|
||||
struct x8y8z8w8 { uint8_t x, y, z, w; };
|
||||
|
||||
Format aliases like XYZWstrq are (s+t+r+q)-bit integers in host endianness,
|
||||
with the X component in the s least-significant bits of the integer. In C::
|
||||
|
||||
uint32_t xyzw8888 = (x << 0) | (y << 8) | (z << 16) | (w << 24);
|
||||
|
||||
Format suffixes affect the interpretation of the channel:
|
||||
|
||||
- ``SINT``: N bit signed integer [-2^(N-1) ... 2^(N-1) - 1]
|
||||
- ``SNORM``: N bit signed integer normalized to [-1 ... 1]
|
||||
- ``SSCALED``: N bit signed integer [-2^(N-1) ... 2^(N-1) - 1]
|
||||
- ``FIXED``: Signed fixed point integer, (N/2 - 1) bits of mantissa
|
||||
- ``FLOAT``: N bit IEEE754 float
|
||||
- ``NORM``: Normalized integers, signed or unsigned per channel
|
||||
- ``UINT``: N bit unsigned integer [0 ... 2^N - 1]
|
||||
- ``UNORM``: N bit unsigned integer normalized to [0 ... 1]
|
||||
- ``USCALED``: N bit unsigned integer [0 ... 2^N - 1]
|
||||
|
||||
The difference between ``SINT`` and ``SSCALED`` is that the former are pure
|
||||
integers in shaders, while the latter are floats; likewise for ``UINT`` versus
|
||||
``USCALED``.
|
||||
|
||||
There are two exceptions for ``FLOAT``. ``R9G9B9E5_FLOAT`` is nine bits
|
||||
each of red green and blue mantissa, with a shared five bit exponent.
|
||||
``R11G11B10_FLOAT`` is five bits of exponent and five or six bits of mantissa
|
||||
for each color channel.
|
||||
|
||||
For the ``NORM`` suffix, the signedness of each channel is indicated with an
|
||||
S or U after the number of channel bits, as in ``R5SG5SB6U_NORM``.
|
||||
|
||||
The ``SRGB`` suffix is like ``UNORM`` in range, but in the sRGB colorspace.
|
||||
|
||||
Compressed formats are named first by the compression format string (``DXT1``,
|
||||
``ETC1``, etc), followed by a format-specific subtype. Refer to the
|
||||
appropriate compression spec for details.
|
||||
|
||||
Formats used in video playback are named by their FOURCC code.
|
||||
|
||||
Format names with an embedded underscore are subsampled. ``R8G8_B8G8`` is a
|
||||
single 32-bit block of two pixels, where the R and B values are repeated in
|
||||
both pixels.
|
||||
|
||||
References
|
||||
----------
|
||||
|
||||
DirectX Graphics Infrastructure documentation on DXGI_FORMAT enum:
|
||||
http://msdn.microsoft.com/en-us/library/windows/desktop/bb173059%28v=vs.85%29.aspx
|
||||
|
||||
FOURCC codes for YUV formats:
|
||||
http://www.fourcc.org/yuv.php
|
||||
@@ -0,0 +1,35 @@
|
||||
Glossary
|
||||
========
|
||||
|
||||
.. glossary::
|
||||
:sorted:
|
||||
|
||||
MSAA
|
||||
Multi-Sampled Anti-Aliasing. A basic anti-aliasing technique that takes
|
||||
multiple samples of the depth buffer, and uses this information to
|
||||
smooth the edges of polygons.
|
||||
|
||||
TCL
|
||||
Transform, Clipping, & Lighting. The three stages of preparation in a
|
||||
rasterizing pipeline prior to the actual rasterization of vertices into
|
||||
fragments.
|
||||
|
||||
NPOT
|
||||
Non-power-of-two. Usually applied to textures which have at least one
|
||||
dimension which is not a power of two.
|
||||
|
||||
LOD
|
||||
Level of Detail. Also spelled "LoD." The value that determines when the
|
||||
switches between mipmaps occur during texture sampling.
|
||||
|
||||
layer
|
||||
This term is used as the name of the "3rd coordinate" of a resource.
|
||||
3D textures have zslices, cube maps have faces, 1D and 2D array textures
|
||||
have array members (other resources do not have multiple layers).
|
||||
Since the functions only take one parameter no matter what type of
|
||||
resource is used, use the term "layer" instead of a resource type
|
||||
specific one.
|
||||
|
||||
GLSL
|
||||
GL Shading Language. The official, common high-level shader language used
|
||||
in GL 2.0 and above.
|
||||
@@ -0,0 +1,32 @@
|
||||
.. Gallium documentation master file, created by
|
||||
sphinx-quickstart on Sun Dec 20 14:09:05 2009.
|
||||
You can adapt this file completely to your liking, but it should at least
|
||||
contain the root `toctree` directive.
|
||||
|
||||
Welcome to Gallium's documentation!
|
||||
===================================
|
||||
|
||||
Contents:
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
intro
|
||||
debugging
|
||||
tgsi
|
||||
screen
|
||||
resources
|
||||
format
|
||||
context
|
||||
cso
|
||||
distro
|
||||
drivers
|
||||
glossary
|
||||
|
||||
Indices and tables
|
||||
==================
|
||||
|
||||
* :ref:`genindex`
|
||||
* :ref:`modindex`
|
||||
* :ref:`search`
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
Introduction
|
||||
============
|
||||
|
||||
What is Gallium?
|
||||
----------------
|
||||
|
||||
Gallium is essentially an API for writing graphics drivers in a largely
|
||||
device-agnostic fashion. It provides several objects which encapsulate the
|
||||
core services of graphics hardware in a straightforward manner.
|
||||
@@ -0,0 +1,128 @@
|
||||
XXX this could be converted/formatted for Sphinx someday.
|
||||
XXX do not use tabs in this file.
|
||||
|
||||
|
||||
|
||||
position ]
|
||||
primary/secondary colors ]
|
||||
generics (normals, ]
|
||||
texcoords, fog) ] User vertices / arrays
|
||||
point size ]
|
||||
edge flag ]
|
||||
primitive ID } System-generated values
|
||||
vertex ID }
|
||||
| | |
|
||||
V V V
|
||||
+-------------------+
|
||||
| Vertex shader |
|
||||
+-------------------+
|
||||
| | |
|
||||
V V V
|
||||
position
|
||||
clip distance
|
||||
generics
|
||||
front/back & primary/secondary colors
|
||||
point size
|
||||
edge flag
|
||||
primitive ID
|
||||
| | |
|
||||
V V V
|
||||
+------------------------+
|
||||
| Geometry shader |
|
||||
| (consume vertex ID) |
|
||||
| (may change prim type) |
|
||||
+------------------------+
|
||||
| | |
|
||||
V V V
|
||||
[...]
|
||||
fb layer
|
||||
| | |
|
||||
V V V
|
||||
+--------------------------+
|
||||
| Clipper |
|
||||
| (consume clip distances) |
|
||||
+--------------------------+
|
||||
| | |
|
||||
V V V
|
||||
+-------------------+
|
||||
| Polygon Culling |
|
||||
+-------------------+
|
||||
| | |
|
||||
V V V
|
||||
+-----------------------+
|
||||
| Choose front or |
|
||||
| back face color |
|
||||
| (consume other color) |
|
||||
+-----------------------+
|
||||
| | |
|
||||
V V V
|
||||
[...]
|
||||
primary/secondary colors only
|
||||
| | |
|
||||
V V V
|
||||
+-------------------+
|
||||
| Polygon Offset |
|
||||
+-------------------+
|
||||
| | |
|
||||
V V V
|
||||
+----------------------+
|
||||
| Unfilled polygons |
|
||||
| (consume edge flags) |
|
||||
| (change prim type) |
|
||||
+----------------------+
|
||||
| | |
|
||||
V V V
|
||||
position
|
||||
generics
|
||||
primary/secondary colors
|
||||
point size
|
||||
primitive ID
|
||||
fb layer
|
||||
| | |
|
||||
V V V
|
||||
+---------------------------------+
|
||||
| Optional Draw module helpers |
|
||||
| * Polygon Stipple |
|
||||
| * Line Stipple |
|
||||
| * Line AA/smooth (as tris) |
|
||||
| * Wide lines (as tris) |
|
||||
| * Wide points/sprites (as tris) |
|
||||
| * Point AA/smooth (as tris) |
|
||||
| (NOTE: these stages may emit |
|
||||
| new/extra generic attributes |
|
||||
| such as texcoords) |
|
||||
+---------------------------------+
|
||||
| | |
|
||||
V V V
|
||||
position ]
|
||||
generics (+ new/extra ones) ]
|
||||
primary/secondary colors ] Software rast vertices
|
||||
point size ]
|
||||
primitive ID ]
|
||||
fb layer ]
|
||||
| | |
|
||||
V V V
|
||||
+---------------------+
|
||||
| Triangle/Line/Point |
|
||||
| Rasterization |
|
||||
+---------------------+
|
||||
| | |
|
||||
V V V
|
||||
generic attribs
|
||||
primary/secondary colors
|
||||
primitive ID
|
||||
fragment win coord pos } System-generated values
|
||||
front/back face flag }
|
||||
| | |
|
||||
V V V
|
||||
+-------------------+
|
||||
| Fragment shader |
|
||||
+-------------------+
|
||||
| | |
|
||||
V V V
|
||||
zero or more colors
|
||||
zero or one Z value
|
||||
|
||||
|
||||
NOTE: The instance ID is not shown. It can be imagined to be a global variable
|
||||
accessible to all shader stages.
|
||||
@@ -0,0 +1,207 @@
|
||||
.. _resource:
|
||||
|
||||
Resources and derived objects
|
||||
=============================
|
||||
|
||||
Resources represent objects that hold data: textures and buffers.
|
||||
|
||||
They are mostly modelled after the resources in Direct3D 10/11, but with a
|
||||
different transfer/update mechanism, and more features for OpenGL support.
|
||||
|
||||
Resources can be used in several ways, and it is required to specify all planned uses through an appropriate set of bind flags.
|
||||
|
||||
TODO: write much more on resources
|
||||
|
||||
Transfers
|
||||
---------
|
||||
|
||||
Transfers are the mechanism used to access resources with the CPU.
|
||||
|
||||
OpenGL: OpenGL supports mapping buffers and has inline transfer functions for both buffers and textures
|
||||
|
||||
D3D11: D3D11 lacks transfers, but has special resource types that are mappable to the CPU address space
|
||||
|
||||
TODO: write much more on transfers
|
||||
|
||||
Resource targets
|
||||
----------------
|
||||
|
||||
Resource targets determine the type of a resource.
|
||||
|
||||
Note that drivers may not actually have the restrictions listed regarding
|
||||
coordinate normalization and wrap modes, and in fact efficient OpenCL
|
||||
support will probably require drivers that don't have any of them, which
|
||||
will probably be advertised with an appropriate cap.
|
||||
|
||||
TODO: document all targets. Note that both 3D and cube have restrictions
|
||||
that depend on the hardware generation.
|
||||
|
||||
|
||||
PIPE_BUFFER
|
||||
^^^^^^^^^^^
|
||||
|
||||
Buffer resource: can be used as a vertex, index, constant buffer
|
||||
(appropriate bind flags must be requested).
|
||||
|
||||
Buffers do not really have a format, it's just bytes, but they are required
|
||||
to have their type set to a R8 format (without a specific "just byte" format,
|
||||
R8_UINT would probably make the most sense, but for historic reasons R8_UNORM
|
||||
is ok too). (This is just to make some shared buffer/texture code easier so
|
||||
format size can be queried.)
|
||||
width0 serves as size, most other resource properties don't apply but must be
|
||||
set appropriately (depth0/height0/array_size must be 1, last_level 0).
|
||||
|
||||
They can be bound to stream output if supported.
|
||||
TODO: what about the restrictions lifted by the several later GL transform feedback extensions? How does one advertise that in Gallium?
|
||||
|
||||
They can be also be bound to a shader stage (for sampling) as usual by
|
||||
creating an appropriate sampler view, if the driver supports PIPE_CAP_TEXTURE_BUFFER_OBJECTS.
|
||||
This supports larger width than a 1d texture would
|
||||
(TODO limit currently unspecified, minimum must be at least 65536).
|
||||
Only the "direct fetch" sample opcodes are supported (TGSI_OPCODE_TXF,
|
||||
TGSI_OPCODE_SAMPLE_I) so the sampler state (coord wrapping etc.)
|
||||
is mostly ignored (with SAMPLE_I there's no sampler state at all).
|
||||
|
||||
They can be also be bound to the framebuffer (only as color render target, not
|
||||
depth buffer, also there cannot be a depth buffer bound at the same time) as usual
|
||||
by creating an appropriate view (this is not usable in OpenGL).
|
||||
TODO there's no CAP bit currently for this, there's also unspecified size etc. limits
|
||||
TODO: is there any chance of supporting GL pixel buffer object acceleration with this?
|
||||
|
||||
|
||||
OpenGL: vertex buffers in GL 1.5 or GL_ARB_vertex_buffer_object
|
||||
|
||||
- Binding to stream out requires GL 3.0 or GL_NV_transform_feedback
|
||||
- Binding as constant buffers requires GL 3.1 or GL_ARB_uniform_buffer_object
|
||||
- Binding to a sampling stage requires GL 3.1 or GL_ARB_texture_buffer_object
|
||||
|
||||
D3D11: buffer resources
|
||||
- Binding to a render target requires D3D_FEATURE_LEVEL_10_0
|
||||
|
||||
PIPE_TEXTURE_1D / PIPE_TEXTURE_1D_ARRAY
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
1D surface accessed with normalized coordinates.
|
||||
1D array textures are supported depending on PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS.
|
||||
|
||||
- If PIPE_CAP_NPOT_TEXTURES is not supported,
|
||||
width must be a power of two
|
||||
- height0 must be 1
|
||||
- depth0 must be 1
|
||||
- array_size must be 1 for PIPE_TEXTURE_1D
|
||||
- Mipmaps can be used
|
||||
- Must use normalized coordinates
|
||||
|
||||
OpenGL: GL_TEXTURE_1D in GL 1.0
|
||||
|
||||
- PIPE_CAP_NPOT_TEXTURES is equivalent to GL 2.0 or GL_ARB_texture_non_power_of_two
|
||||
|
||||
D3D11: 1D textures in D3D_FEATURE_LEVEL_10_0
|
||||
|
||||
PIPE_TEXTURE_RECT
|
||||
^^^^^^^^^^^^^^^^^
|
||||
2D surface with OpenGL GL_TEXTURE_RECTANGLE semantics.
|
||||
|
||||
- depth0 must be 1
|
||||
- array_size must be 1
|
||||
- last_level must be 0
|
||||
- Must use unnormalized coordinates
|
||||
- Must use a clamp wrap mode
|
||||
|
||||
OpenGL: GL_TEXTURE_RECTANGLE in GL 3.1 or GL_ARB_texture_rectangle or GL_NV_texture_rectangle
|
||||
|
||||
OpenCL: can create OpenCL images based on this, that can then be sampled arbitrarily
|
||||
|
||||
D3D11: not supported (only PIPE_TEXTURE_2D with normalized coordinates is supported)
|
||||
|
||||
PIPE_TEXTURE_2D / PIPE_TEXTURE_2D_ARRAY
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
2D surface accessed with normalized coordinates.
|
||||
2D array textures are supported depending on PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS.
|
||||
|
||||
- If PIPE_CAP_NPOT_TEXTURES is not supported,
|
||||
width and height must be powers of two
|
||||
- depth0 must be 1
|
||||
- array_size must be 1 for PIPE_TEXTURE_2D
|
||||
- Mipmaps can be used
|
||||
- Must use normalized coordinates
|
||||
- No special restrictions on wrap modes
|
||||
|
||||
OpenGL: GL_TEXTURE_2D in GL 1.0
|
||||
|
||||
- PIPE_CAP_NPOT_TEXTURES is equivalent to GL 2.0 or GL_ARB_texture_non_power_of_two
|
||||
|
||||
OpenCL: can create OpenCL images based on this, that can then be sampled arbitrarily
|
||||
|
||||
D3D11: 2D textures
|
||||
|
||||
- PIPE_CAP_NPOT_TEXTURES is equivalent to D3D_FEATURE_LEVEL_9_3
|
||||
|
||||
PIPE_TEXTURE_3D
|
||||
^^^^^^^^^^^^^^^
|
||||
|
||||
3-dimensional array of texels.
|
||||
Mipmap dimensions are reduced in all 3 coordinates.
|
||||
|
||||
- If PIPE_CAP_NPOT_TEXTURES is not supported,
|
||||
width, height and depth must be powers of two
|
||||
- array_size must be 1
|
||||
- Must use normalized coordinates
|
||||
|
||||
OpenGL: GL_TEXTURE_3D in GL 1.2 or GL_EXT_texture3D
|
||||
|
||||
- PIPE_CAP_NPOT_TEXTURES is equivalent to GL 2.0 or GL_ARB_texture_non_power_of_two
|
||||
|
||||
D3D11: 3D textures
|
||||
|
||||
- PIPE_CAP_NPOT_TEXTURES is equivalent to D3D_FEATURE_LEVEL_10_0
|
||||
|
||||
PIPE_TEXTURE_CUBE / PIPE_TEXTURE_CUBE_ARRAY
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Cube maps consist of 6 2D faces.
|
||||
The 6 surfaces form an imaginary cube, and sampling happens by mapping an
|
||||
input 3-vector to the point of the cube surface in that direction.
|
||||
Cube map arrays are supported depending on PIPE_CAP_CUBE_MAP_ARRAY.
|
||||
|
||||
Sampling may be optionally seamless if a driver supports it (PIPE_CAP_SEAMLESS_CUBE_MAP),
|
||||
resulting in filtering taking samples from multiple surfaces near to the edge.
|
||||
|
||||
- Width and height must be equal
|
||||
- depth0 must be 1
|
||||
- array_size must be a multiple of 6
|
||||
- If PIPE_CAP_NPOT_TEXTURES is not supported,
|
||||
width and height must be powers of two
|
||||
- Must use normalized coordinates
|
||||
|
||||
OpenGL: GL_TEXTURE_CUBE_MAP in GL 1.3 or EXT_texture_cube_map
|
||||
|
||||
- PIPE_CAP_NPOT_TEXTURES is equivalent to GL 2.0 or GL_ARB_texture_non_power_of_two
|
||||
- Seamless cube maps require GL 3.2 or GL_ARB_seamless_cube_map or GL_AMD_seamless_cubemap_per_texture
|
||||
- Cube map arrays require GL 4.0 or GL_ARB_texture_cube_map_array
|
||||
|
||||
D3D11: 2D array textures with the D3D11_RESOURCE_MISC_TEXTURECUBE flag
|
||||
|
||||
- PIPE_CAP_NPOT_TEXTURES is equivalent to D3D_FEATURE_LEVEL_10_0
|
||||
- Cube map arrays require D3D_FEATURE_LEVEL_10_1
|
||||
|
||||
Surfaces
|
||||
--------
|
||||
|
||||
Surfaces are views of a resource that can be bound as a framebuffer to serve as the render target or depth buffer.
|
||||
|
||||
TODO: write much more on surfaces
|
||||
|
||||
OpenGL: FBOs are collections of surfaces in GL 3.0 or GL_ARB_framebuffer_object
|
||||
|
||||
D3D11: render target views and depth/stencil views
|
||||
|
||||
Sampler views
|
||||
-------------
|
||||
|
||||
Sampler views are views of a resource that can be bound to a pipeline stage to be sampled from shaders.
|
||||
|
||||
TODO: write much more on sampler views
|
||||
|
||||
OpenGL: texture objects are actually sampler view and resource in a single unit
|
||||
|
||||
D3D11: shader resource views
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user