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:
Erik Faye-Lund
2020-06-30 12:44:19 +02:00
committed by Marge Bot
parent cb11900cb6
commit 2f81398187
32 changed files with 9 additions and 403 deletions
+31
View File
@@ -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
View File
@@ -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']
+1
View File
@@ -68,6 +68,7 @@
release-calendar
sourcedocs
dispatch
gallium/index
.. toctree::
:maxdepth: 1
+912
View File
@@ -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.
+14
View File
@@ -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/*
+128
View File
@@ -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.
+61
View File
@@ -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.
+365
View File
@@ -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.
+116
View File
@@ -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.
+12
View File
@@ -0,0 +1,12 @@
.. _shader:
Shader
======
One of the two types of shaders supported by Gallium.
Members
-------
tokens
A list of tgsi_tokens.
+59
View File
@@ -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.
+105
View File
@@ -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.
+192
View File
@@ -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
^^^^
+9
View File
@@ -0,0 +1,9 @@
Drivers
=======
Driver specific documentation.
.. toctree::
:glob:
drivers/*
+9
View File
@@ -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
+21
View File
@@ -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
+141
View File
@@ -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.
+114
View File
@@ -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
+44
View File
@@ -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
+61
View File
@@ -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
+35
View File
@@ -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.
+32
View File
@@ -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`
+9
View File
@@ -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.
+128
View File
@@ -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.
+207
View File
@@ -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