<div dir="ltr"><div>It was marketed that way because D3D didn't have API to do anything else.</div><div><br></div><div>In practice, EQAA can do arbitrary color coverage, color storage, and Z/S sample counts, and each color render target can have different values too. So everything is allowed, but the combinations that don't make sense only waste memory and do useless work that is not stored.<br></div><div><br></div><div>The configs with the best quality/performance tradeoff are "8 >= color coverage samples == Z/S samples >= color storage samples" (the upper limit is for AMD). Having maximum Z/S samples doesn't decrease performance in some cases due to internal GPU optimizations, so it's better to keep them for quality.<br></div><div><br></div><div>The full range of configs that don't waste memory and don't do useless work (i.e. they can be useful) is "16 >= color coverage samples >= Z/S samples >= color storage samples". The color coverage is the only one that can have 16 samples. Z/S has to have 8 or less. Z/S can sometimes have higher quality than allocated due to Z/S compression, but front-to-back rendering quality drops to the allocated Z/S sample count when Z/S doesn't compress well. The Z/S hw can run at color coverage sample rate regardless of allocated Z/S samples.<br></div><div><br></div><div>color storage samples == 1 may also be useful if the resolve shader is implemented well, but it starts to compete with MLAA. I still prefer to have the maximum Z/S sample count here as dictated by the first equation above.<br></div><div><br></div><div>Marek<br></div><div><br></div><div><div class="gmail_extra"><br><div class="gmail_quote">On Mon, May 21, 2018 at 9:14 PM, Roland Scheidegger <span dir="ltr"><<a href="mailto:sroland@vmware.com" target="_blank">sroland@vmware.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">I was under the (apparently wrong) impression EQAA always worked like<br>
that too.<br>
Even AMD's marketing said EQAA has the same number of<br>
stencil/depth/color samples as regular MSAA (when the feature was new,<br>
HD 6900,<br>
<a href="https://developer.amd.com/wordpress/media/2012/10/EQAA%2520Modes%2520for%2520AMD%2520HD%25206900%2520Series%2520Cards.pdf" rel="noreferrer" target="_blank">https://developer.amd.com/<wbr>wordpress/media/2012/10/EQAA%<wbr>2520Modes%2520for%2520AMD%<wbr>2520HD%25206900%2520Series%<wbr>2520Cards.pdf</a>).<br>
As well as every article I've seen on that subject...<br>
So I believe the EQAA options available with windows never use more<br>
depth storage samples than color storage samples.<br>
And both CSAA and EQAA were generally met with lukewarm reception - as<br>
you noted, for front to back rendering it's useless.<br>
I'll agree that in theory having more depth samples sounds quite useful,<br>
but maybe in practice the cost is too high (EQAA as well as CSAA were<br>
marketed as nearly free compared to the MSAA modes with the same number<br>
of depth/stencil/color samples, I could imagine if you use the same<br>
number of depth storage samples as coverage samples the cost could<br>
approach closer to a MSAA mode which just has the higher number of<br>
samples for color too, but I guess it would depend on the number and<br>
type of color buffers).<br>
<br>
Roland<br>
<span class=""><br>
<br>
<br>
Am 22.05.2018 um 02:46 schrieb Marek Olšák:<br>
> Your understanding is correct. I misunderstood CSAA. So it looks like<br>
> that CSAA is more useless than I thought. You get the coverage-samples<br>
> level of quality for back-to-front rendering, but you may get the<br>
> depth-samples level of quality for front-to-back rendering, because<br>
> "edges" generated by depth test failures have the same quality as the<br>
> number of depth samples (if depth values are uncompressed). AMD supports<br>
> that mode too, but I don't recommend using it because of the possible<br>
> decrease in front-to-back rendering quality.<br>
> <br>
> The way the CAP is defined doesn't actually allow NV's implementation of<br>
> CSAA. A new CAP would be needed.<br>
> <br>
> We'll add a new GL extension for advanced MSAA. The NV extension is<br>
> unusable, because it changes GL behavior in a non-backward-compatible<br>
> way by allowing storage_samples = 2 for all renderbuffers (which is<br>
> cheating, but not surprising from NV).<br>
> <br>
> Marek<br>
> <br>
> On Mon, May 21, 2018 at 12:55 PM, Axel Davy <<a href="mailto:davyaxel0@gmail.com">davyaxel0@gmail.com</a><br>
</span><span class="">> <mailto:<a href="mailto:davyaxel0@gmail.com">davyaxel0@gmail.com</a>>> wrote:<br>
> <br>
> Hi,<br>
> <br>
> I get the impression when looking at online documentation about EQAA<br>
> and CSAA, like<br>
> <a href="http://www.nvidia.fr/object/coverage-sampled-aa.html" rel="noreferrer" target="_blank">http://www.nvidia.fr/object/<wbr>coverage-sampled-aa.html</a><br>
</span>> <<a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__www.nvidia.fr_object_coverage-2Dsampled-2Daa.html&d=DwMFaQ&c=uilaK90D4TOVoH58JNXRgQ&r=_QIjpv-UJ77xEQY8fIYoQtr5qv8wKrPJc7v7_-CYAb0&m=mT5z2nGhAlFu_lLjhtTx-Gb1xMAX_goZ2-tp5FknDXU&s=lTxXM-R2kvTIBzi4Wjjl8uT7R88UhQgdvkIHJLVaQsQ&e=" rel="noreferrer" target="_blank">https://urldefense.<wbr>proofpoint.com/v2/url?u=http-<wbr>3A__www.nvidia.fr_object_<wbr>coverage-2Dsampled-2Daa.html&<wbr>d=DwMFaQ&c=<wbr>uilaK90D4TOVoH58JNXRgQ&r=_<wbr>QIjpv-<wbr>UJ77xEQY8fIYoQtr5qv8wKrPJc7v7_<wbr>-CYAb0&m=mT5z2nGhAlFu_lLjhtTx-<wbr>Gb1xMAX_goZ2-tp5FknDXU&s=<wbr>lTxXM-<wbr>R2kvTIBzi4Wjjl8uT7R88UhQgdvkIH<wbr>JLVaQsQ&e=</a>><br>
<span class="">> <br>
> that the number of stored samples is the same for the color and<br>
> depth buffers.<br>
> Only the samples used for coverage is greater.<br>
> <br>
> With your proposal, isn't the number of samples stored in the depth<br>
> buffer always the same than the number of samples used for coverage ?<br>
> That reduces the use-cases. In nine, we have to enforce the number<br>
> of stored samples to be the same for the color and the depth buffer,<br>
> but we could increase the number of samples used for coverage and<br>
> enable EQAA/CSAA (in fact there is a similar way to advertise the<br>
> feature for Nvidia and Amd).<br>
> <br>
> But maybe I misunderstood.<br>
> <br>
> Yours,<br>
> <br>
> Axel Davy<br>
> <br>
> <br>
> On 18/05/2018 06:05, Marek Olšák wrote:<br>
> <br>
</span>> From: Marek Olšák <<a href="mailto:marek.olsak@amd.com">marek.olsak@amd.com</a> <mailto:<a href="mailto:marek.olsak@amd.com">marek.olsak@amd.com</a>>><br>
<div><div class="h5">> <br>
> The interface only uses general MSAA terms, so it's "advanced<br>
> MSAA" and not<br>
> something vendor-specific.<br>
> <br>
> It's a proper subset of EQAA, and a proper superset of CSAA, so<br>
> it's neither.<br>
> <br>
> Changes:<br>
> - pipe_resource is changed<br>
> - is_format_supported is changed<br>
> - a new CAP is added<br>
> ---<br>
> src/gallium/docs/source/<wbr>screen.rst | 31<br>
> ++++++++++++++++++++++++++--<br>
> src/gallium/include/pipe/p_<wbr>defines.h | 1 +<br>
> src/gallium/include/pipe/p_<wbr>screen.h | 1 +<br>
> src/gallium/include/pipe/p_<wbr>state.h | 18 +++++++++++++---<br>
> 4 files changed, 46 insertions(+), 5 deletions(-)<br>
> <br>
> diff --git a/src/gallium/docs/source/<wbr>screen.rst<br>
> b/src/gallium/docs/source/<wbr>screen.rst<br>
> index 5bc6ee99f08..cf4787a1c49 100644<br>
> --- a/src/gallium/docs/source/<wbr>screen.rst<br>
> +++ b/src/gallium/docs/source/<wbr>screen.rst<br>
> @@ -398,20 +398,25 @@ The integer capabilities:<br>
> * ``PIPE_CAP_LOAD_CONSTBUF``: True if the driver supports<br>
> TGSI_OPCODE_LOAD use<br>
> with constant buffers.<br>
> * ``PIPE_CAP_TGSI_ANY_REG_AS_<wbr>ADDRESS``: Any TGSI register can<br>
> be used as<br>
> an address for indirect register indexing.<br>
> * ``PIPE_CAP_TILE_RASTER_ORDER``<wbr>: Whether the driver supports<br>
> GL_MESA_tile_raster_order, using the tile_raster_order_*<br>
> fields in<br>
> pipe_rasterizer_state.<br>
> * ``PIPE_CAP_MAX_COMBINED_<wbr>SHADER_OUTPUT_RESOURCES``: Limit on<br>
> combined shader<br>
> output resources (images + buffers + fragment outputs). If 0<br>
> the state<br>
> tracker works it out.<br>
> +* ``PIPE_CAP_FRAMEBUFFER_MIXED_<wbr>SAMPLES``: Framebuffer<br>
> attachments can have<br>
> + different number of samples each with the following restriction:<br>
> + color.nr_samples >= zs.nr_samples >= color.nr_storage_samples<br>
> + If 0 is returned, the following restriction applies:<br>
> + color.nr_samples == zs.nr_samples >= color.nr_storage_samples<br>
> * ``PIPE_CAP_SIGNED_VERTEX_<wbr>BUFFER_OFFSET``:<br>
> Whether pipe_vertex_buffer::buffer_<wbr>offset is treated as<br>
> signed. The u_vbuf<br>
> module needs this for optimal performance in workstation<br>
> applications.<br>
> * ``PIPE_CAP_CONTEXT_PRIORITY_<wbr>MASK``: For drivers that support<br>
> per-context<br>
> priorities, this returns a bitmask of<br>
> PIPE_CONTEXT_PRIORITY_x for the<br>
> supported priority levels. A driver that does not support<br>
> prioritized<br>
> contexts can return 0.<br>
> * ``PIPE_CAP_FENCE_SIGNAL``: True if the driver supports<br>
> signaling semaphores<br>
> using fence_server_signal().<br>
> * ``PIPE_CAP_CONSTBUF0_FLAGS``: The bits of<br>
> pipe_resource::flags that must be<br>
> @@ -718,20 +723,23 @@ is_format_supported<br>
> Determine if a resource in the given format can be used in a<br>
> specific manner.<br>
> **format** the resource format<br>
> **target** one of the PIPE_TEXTURE_x flags<br>
> **sample_count** the number of samples. 0 and 1 mean no<br>
> multisampling,<br>
> the maximum allowed legal value is 32.<br>
> +**storage_sample_count** the number of storage samples. This<br>
> must be <=<br>
> +sample_count. See the documentation of<br>
> ``pipe_resource::nr_storage_<wbr>samples``.<br>
> +<br>
> **bindings** is a bitmask of :ref:`PIPE_BIND` flags.<br>
> Returns TRUE if all usages can be satisfied.<br>
> can_create_resource<br>
> ^^^^^^^^^^^^^^^^^^^<br>
> Check if a resource can actually be created (but don't<br>
> actually allocate any<br>
> memory). This is used to implement OpenGL's proxy textures. <br>
> Typically, a<br>
> @@ -761,22 +769,41 @@ Modern APIs allow using buffers as shader<br>
> resources.<br>
> (1 for 1D or 1D array textures).<br>
> **depth0** the depth of the base mip level of the texture<br>
> (1 for everything else).<br>
> **array_size** the array size for 1D and 2D array textures.<br>
> For cube maps this must be 6, for other textures 1.<br>
> **last_level** the last mip map level present.<br>
> -**nr_samples** the nr of msaa samples. 0 (or 1) specifies a<br>
> resource<br>
> -which isn't multisampled.<br>
> +**nr_samples**: Number of samples determining quality, driving<br>
> the rasterizer,<br>
> +shading, and framebuffer. It is the number of samples seen by<br>
> the whole<br>
> +graphics pipeline. 0 and 1 specify a resource which isn't<br>
> multisampled.<br>
> +<br>
> +**nr_storage_samples**: Only color buffers can set this lower<br>
> than nr_samples.<br>
> +Multiple samples within a pixel can have the same color.<br>
> ``nr_storage_samples``<br>
> +determines how many slots for different colors there are per pixel.<br>
> +If there are not enough slots to store all sample colors, some<br>
> samples will<br>
> +have an undefined color (called "undefined samples").<br>
> +<br>
> +The resolve blit behavior is driver-specific, but can be one of<br>
> these two:<br>
> +1. Only defined samples will be averaged. Undefined samples<br>
> will be ignored.<br>
> +2. Undefined samples will be approximated by looking at<br>
> surrounding defined<br>
> + samples (even in different pixels).<br>
> +<br>
> +Blits and MSAA texturing: If the sample being fetched is<br>
> undefined, one of<br>
> +the defined samples is returned instead.<br>
> +<br>
> +Sample shading (``set_min_samples``) will operate at a sample<br>
> frequency that<br>
> +is at most ``nr_storage_samples``. Greater ``min_samples``<br>
> values will be<br>
> +replaced by ``nr_storage_samples``.<br>
> **usage** one of the :ref:`PIPE_USAGE` flags.<br>
> **bind** bitmask of the :ref:`PIPE_BIND` flags.<br>
> **flags** bitmask of PIPE_RESOURCE_FLAG flags.<br>
> resource_changed<br>
> diff --git a/src/gallium/include/pipe/p_<wbr>defines.h<br>
> b/src/gallium/include/pipe/p_<wbr>defines.h<br>
> index 6b2f33b9e37..5693396c9e9 100644<br>
> --- a/src/gallium/include/pipe/p_<wbr>defines.h<br>
> +++ b/src/gallium/include/pipe/p_<wbr>defines.h<br>
> @@ -794,20 +794,21 @@ enum pipe_cap<br>
> PIPE_CAP_ALLOW_MAPPED_<wbr>BUFFERS_DURING_EXECUTION,<br>
> PIPE_CAP_POST_DEPTH_COVERAGE,<br>
> PIPE_CAP_BINDLESS_TEXTURE,<br>
> PIPE_CAP_NIR_SAMPLERS_AS_<wbr>DEREF,<br>
> PIPE_CAP_QUERY_SO_OVERFLOW,<br>
> PIPE_CAP_MEMOBJ,<br>
> PIPE_CAP_LOAD_CONSTBUF,<br>
> PIPE_CAP_TGSI_ANY_REG_AS_<wbr>ADDRESS,<br>
> PIPE_CAP_TILE_RASTER_ORDER,<br>
> PIPE_CAP_MAX_COMBINED_SHADER_<wbr>OUTPUT_RESOURCES,<br>
> + PIPE_CAP_FRAMEBUFFER_MIXED_<wbr>SAMPLES,<br>
> PIPE_CAP_SIGNED_VERTEX_<wbr>BUFFER_OFFSET,<br>
> PIPE_CAP_CONTEXT_PRIORITY_<wbr>MASK,<br>
> PIPE_CAP_FENCE_SIGNAL,<br>
> PIPE_CAP_CONSTBUF0_FLAGS,<br>
> PIPE_CAP_PACKED_UNIFORMS,<br>
> PIPE_CAP_CONSERVATIVE_RASTER_<wbr>POST_SNAP_TRIANGLES,<br>
> PIPE_CAP_CONSERVATIVE_RASTER_<wbr>POST_SNAP_POINTS_LINES,<br>
> PIPE_CAP_CONSERVATIVE_RASTER_<wbr>PRE_SNAP_TRIANGLES,<br>
> PIPE_CAP_CONSERVATIVE_RASTER_<wbr>PRE_SNAP_POINTS_LINES,<br>
> PIPE_CAP_MAX_CONSERVATIVE_<wbr>RASTER_SUBPIXEL_PRECISION_<wbr>BIAS,<br>
> diff --git a/src/gallium/include/pipe/p_<wbr>screen.h<br>
> b/src/gallium/include/pipe/p_<wbr>screen.h<br>
> index 101e229088b..94c61dfab2e 100644<br>
> --- a/src/gallium/include/pipe/p_<wbr>screen.h<br>
> +++ b/src/gallium/include/pipe/p_<wbr>screen.h<br>
> @@ -150,20 +150,21 @@ struct pipe_screen {<br>
> /**<br>
> * Check if the given pipe_format is supported as a texture or<br>
> * drawing surface.<br>
> * \param bindings bitmask of PIPE_BIND_*<br>
> */<br>
> boolean (*is_format_supported)( struct pipe_screen *,<br>
> enum pipe_format format,<br>
> enum pipe_texture_target<br>
> target,<br>
> unsigned sample_count,<br>
> + unsigned storage_sample_count,<br>
> unsigned bindings );<br>
> /**<br>
> * Check if the given pipe_format is supported as output<br>
> for this codec/profile.<br>
> * \param profile profile to check, may also be<br>
> PIPE_VIDEO_PROFILE_UNKNOWN<br>
> */<br>
> boolean (*is_video_format_supported)( struct pipe_screen *,<br>
> enum pipe_format format,<br>
> enum<br>
> pipe_video_profile profile,<br>
> enum<br>
> pipe_video_entrypoint entrypoint );<br>
> diff --git a/src/gallium/include/pipe/p_<wbr>state.h<br>
> b/src/gallium/include/pipe/p_<wbr>state.h<br>
> index db9fa1a8e9f..1baa497b227 100644<br>
> --- a/src/gallium/include/pipe/p_<wbr>state.h<br>
> +++ b/src/gallium/include/pipe/p_<wbr>state.h<br>
> @@ -511,41 +511,53 @@ struct pipe_box<br>
> int16_t depth;<br>
> };<br>
> /**<br>
> * A memory object/resource such as a vertex buffer or texture.<br>
> */<br>
> struct pipe_resource<br>
> {<br>
> struct pipe_reference reference;<br>
> - struct pipe_screen *screen; /**< screen that this texture<br>
> belongs to */<br>
> unsigned width0; /**< Used by both buffers and textures. */<br>
> uint16_t height0; /* Textures: The maximum<br>
> height/depth/array_size is 16k. */<br>
> uint16_t depth0;<br>
> uint16_t array_size;<br>
> enum pipe_format format:16; /**< PIPE_FORMAT_x */<br>
> enum pipe_texture_target target:8; /**< PIPE_TEXTURE_x */<br>
> unsigned last_level:8; /**< Index of last mipmap level<br>
> present/defined */<br>
> - unsigned nr_samples:8; /**< for multisampled surfaces, nr<br>
> of samples */<br>
> - unsigned usage:8; /**< PIPE_USAGE_x (not a bitmask) */<br>
> + /** Number of samples determining quality, driving<br>
> rasterizer, shading,<br>
> + * and framebuffer.<br>
> + */<br>
> + unsigned nr_samples:8;<br>
> +<br>
> + /** Multiple samples within a pixel can have the same value.<br>
> + * nr_storage_samples determines how many slots for<br>
> different values<br>
> + * there are per pixel. Only color buffers can set this<br>
> lower than<br>
> + * nr_samples.<br>
> + */<br>
> + unsigned nr_storage_samples:8;<br>
> +<br>
> + unsigned usage:8; /**< PIPE_USAGE_x (not a bitmask) */<br>
> unsigned bind; /**< bitmask of PIPE_BIND_x */<br>
> unsigned flags; /**< bitmask of<br>
> PIPE_RESOURCE_FLAG_x */<br>
> /**<br>
> * For planar images, ie. YUV EGLImage external, etc,<br>
> pointer to the<br>
> * next plane.<br>
> */<br>
> struct pipe_resource *next;<br>
> + /* The screen pointer should be last for optimal structure<br>
> packing. */<br>
> + struct pipe_screen *screen; /**< screen that this texture<br>
> belongs to */<br>
> };<br>
> /**<br>
> * Transfer object. For data transfer to/from a resource.<br>
> */<br>
> struct pipe_transfer<br>
> {<br>
> struct pipe_resource *resource; /**< resource to transfer<br>
> to/from */<br>
> unsigned level; /**< texture mipmap level */<br>
> <br>
> <br>
> <br>
> <br>
> <br>
> <br>
</div></div>> ______________________________<wbr>_________________<br>
> mesa-dev mailing list<br>
> <a href="mailto:mesa-dev@lists.freedesktop.org">mesa-dev@lists.freedesktop.org</a><br>
> <a href="https://urldefense.proofpoint.com/v2/url?u=https-3A__lists.freedesktop.org_mailman_listinfo_mesa-2Ddev&d=DwIGaQ&c=uilaK90D4TOVoH58JNXRgQ&r=_QIjpv-UJ77xEQY8fIYoQtr5qv8wKrPJc7v7_-CYAb0&m=mT5z2nGhAlFu_lLjhtTx-Gb1xMAX_goZ2-tp5FknDXU&s=0NFDqBLa3wIUdtIkZ36Bfu2aZt31YbYQCjMl8BmV2K8&e=" rel="noreferrer" target="_blank">https://urldefense.proofpoint.<wbr>com/v2/url?u=https-3A__lists.<wbr>freedesktop.org_mailman_<wbr>listinfo_mesa-2Ddev&d=DwIGaQ&<wbr>c=uilaK90D4TOVoH58JNXRgQ&r=_<wbr>QIjpv-<wbr>UJ77xEQY8fIYoQtr5qv8wKrPJc7v7_<wbr>-CYAb0&m=mT5z2nGhAlFu_lLjhtTx-<wbr>Gb1xMAX_goZ2-tp5FknDXU&s=<wbr>0NFDqBLa3wIUdtIkZ36Bfu2aZt31Yb<wbr>YQCjMl8BmV2K8&e=</a><br>
> <br>
<br>
</blockquote></div><br></div></div></div>