[Mesa-dev] [PATCH] gallium/radeon: implement ARB_clear_texture (v2)
Roland Scheidegger
sroland at vmware.com
Sat Aug 6 13:55:12 UTC 2016
Yes, these commands are modelled after d3d10 clears (the only d3d10
clear methods are clear_rt/clear_dsv), so gallium at some point only had
the "ordinary" clear (useful for d3d9 and gl, but doesn't cover
everything neither). It is unfortunate all apis handle clear differently.
Making them honoring render condition optionally would work fine though.
(IIRC the initial reasoning was that a state tracker could just disable
render condition if they shouldn't honor that, whereas it would be
impossible to use them from a state tracker which needs to honor render
condition for them if they wouldn't honor it.)
(FWIW resource_copy_region should actually honor render condition too
for the very same reason but we missed the boat on that...)
Roland
Am 06.08.2016 um 13:26 schrieb Nicolai Hähnle:
> Ah, somehow I missed the earlier email from Ilia, now I see the mention
> of the d3d10 state tracker. I still think this is a surprising hack.
> Maybe render condition can be made optional like for blits?
>
> Nicolai
>
> On 06.08.2016 13:14, Nicolai Hähnle wrote:
>> On 05.08.2016 14:20, Marek Olšák wrote:
>>> On Aug 5, 2016 10:54 AM, "Nicolai Hähnle" <nhaehnle at gmail.com
>>> <mailto:nhaehnle at gmail.com>> wrote:
>>>>
>>>>
>>>>
>>>> On 04.08.2016 21:42, Marek Olšák wrote:
>>>>>
>>>>> From: Marek Olšák <marek.olsak at amd.com <mailto:marek.olsak at amd.com>>
>>>>>
>>>>> Some ideas copied from Jakob Sinclair's implementation, but the color
>>>>> clearing is completely different.
>>>>>
>>>>> v2: remove leftover code, disable conditional rendering
>>>>> ---
>>>>> docs/GL3.txt | 2 +-
>>>>> docs/relnotes/12.1.0.html | 1 +
>>>>> src/gallium/drivers/r600/r600_blit.c | 6 ++-
>>>>> src/gallium/drivers/r600/r600_pipe.c | 2 +-
>>>>> src/gallium/drivers/radeon/r600_texture.c | 66
>>> +++++++++++++++++++++++++++++++
>>>>> src/gallium/drivers/radeonsi/si_blit.c | 6 ++-
>>>>> src/gallium/drivers/radeonsi/si_pipe.c | 2 +-
>>>>> 7 files changed, 80 insertions(+), 5 deletions(-)
>>>>>
>>>>> diff --git a/docs/GL3.txt b/docs/GL3.txt
>>>>> index c185c69..5dcfc31 100644
>>>>> --- a/docs/GL3.txt
>>>>> +++ b/docs/GL3.txt
>>>>> @@ -185,21 +185,21 @@ GL 4.3, GLSL 4.30 -- all DONE: nvc0, radeonsi
>>>>> GL_ARB_texture_query_levels DONE (all
>>> drivers that support GLSL 1.30)
>>>>> GL_ARB_texture_storage_multisample DONE (all
>>> drivers that support GL_ARB_texture_multisample)
>>>>> GL_ARB_texture_view DONE (i965,
>>> nv50, r600, llvmpipe, softpipe, swr)
>>>>> GL_ARB_vertex_attrib_binding DONE (all
>>> drivers)
>>>>>
>>>>>
>>>>> GL 4.4, GLSL 4.40:
>>>>>
>>>>> GL_MAX_VERTEX_ATTRIB_STRIDE DONE (all
>>> drivers)
>>>>> GL_ARB_buffer_storage DONE (i965,
>>> nv50, nvc0, r600, radeonsi)
>>>>> - GL_ARB_clear_texture DONE (i965,
>>> nv50, nvc0)
>>>>> + GL_ARB_clear_texture DONE (i965,
>>> nv50, nvc0, r600, radeonsi)
>>>>> GL_ARB_enhanced_layouts DONE (i965)
>>>>> - compile-time constant expressions DONE
>>>>> - explicit byte offsets for blocks DONE
>>>>> - forced alignment within blocks DONE
>>>>> - specified vec4-slot component numbers DONE (i965)
>>>>> - specified transform/feedback layout DONE
>>>>> - input/output block locations DONE
>>>>> GL_ARB_multi_bind DONE (all
>>> drivers)
>>>>> GL_ARB_query_buffer_object DONE
>>> (i965/hsw+, nvc0)
>>>>> GL_ARB_texture_mirror_clamp_to_edge DONE (i965,
>>> nv50, nvc0, r600, radeonsi, llvmpipe, softpipe, swr)
>>>>> diff --git a/docs/relnotes/12.1.0.html b/docs/relnotes/12.1.0.html
>>>>> index 3935bb0..ed98d13 100644
>>>>> --- a/docs/relnotes/12.1.0.html
>>>>> +++ b/docs/relnotes/12.1.0.html
>>>>> @@ -37,20 +37,21 @@ TBD.
>>>>> </pre>
>>>>>
>>>>>
>>>>> <h2>New features</h2>
>>>>>
>>>>> <p>
>>>>> Note: some of the new features are only available with certain
>>>>> drivers.
>>>>> </p>
>>>>>
>>>>> <ul>
>>>>> +<li>GL_ARB_clear_texture on r600, radeonsi</li>
>>>>> <li>GL_ARB_enhanced_layouts on i965</li>
>>>>> <li>GL_ARB_shader_group_vote on nvc0</li>
>>>>> <li>GL_ARB_ES3_1_compatibility on i965</li>
>>>>> <li>GL_EXT_window_rectangles on nv50, nvc0</li>
>>>>> <li>GL_KHR_texture_compression_astc_sliced_3d on i965</li>
>>>>> </ul>
>>>>>
>>>>> <h2>Bug fixes</h2>
>>>>>
>>>>> TBD.
>>>>> diff --git a/src/gallium/drivers/r600/r600_blit.c
>>> b/src/gallium/drivers/r600/r600_blit.c
>>>>> index a6c5b44..8f2e2a6 100644
>>>>> --- a/src/gallium/drivers/r600/r600_blit.c
>>>>> +++ b/src/gallium/drivers/r600/r600_blit.c
>>>>> @@ -29,21 +29,25 @@
>>>>>
>>>>> enum r600_blitter_op /* bitmask */
>>>>> {
>>>>> R600_SAVE_FRAGMENT_STATE = 1,
>>>>> R600_SAVE_TEXTURES = 2,
>>>>> R600_SAVE_FRAMEBUFFER = 4,
>>>>> R600_DISABLE_RENDER_COND = 8,
>>>>>
>>>>> R600_CLEAR = R600_SAVE_FRAGMENT_STATE,
>>>>>
>>>>> - R600_CLEAR_SURFACE = R600_SAVE_FRAGMENT_STATE |
>>> R600_SAVE_FRAMEBUFFER,
>>>>> + /* GL_ARB_clear_texture should ignore the render condition,
>>>>> but
>>>>> + * Gallium shouldn't. Follow OpenGL.
>>>>> + */
>>>>> + R600_CLEAR_SURFACE = R600_SAVE_FRAGMENT_STATE |
>>> R600_SAVE_FRAMEBUFFER |
>>>>> + R600_DISABLE_RENDER_COND,
>>>>
>>>>
>>>> It's annoying, but doesn't this break conditional rendering of glClear?
>>>
>>> glClear doesn't use these clear functions.
>>
>> I see. It uses clear but not clear_depth_stencil or clear_render_target.
>>
>> Is there anything using clear_depth_stencil / clear_render_target that
>> wants conditional render? Maybe the "definition" of the Gallium
>> interface should be changed here. At least there's a certain logic in
>> that those two functions take a destination surface as parameter while
>> clear doesn't.
>>
>> Nicolai
>>
>>> Marek
>>>
>>>>
>>>> Nicolai
>>>>
>>>>
>>>>>
>>>>> R600_COPY_BUFFER = R600_DISABLE_RENDER_COND,
>>>>>
>>>>> R600_COPY_TEXTURE = R600_SAVE_FRAGMENT_STATE |
>>> R600_SAVE_FRAMEBUFFER | R600_SAVE_TEXTURES |
>>>>> R600_DISABLE_RENDER_COND,
>>>>>
>>>>> R600_BLIT = R600_SAVE_FRAGMENT_STATE |
>>> R600_SAVE_FRAMEBUFFER | R600_SAVE_TEXTURES,
>>>>>
>>>>> R600_DECOMPRESS = R600_SAVE_FRAGMENT_STATE |
>>> R600_SAVE_FRAMEBUFFER | R600_DISABLE_RENDER_COND,
>>>>>
>>>>> diff --git a/src/gallium/drivers/r600/r600_pipe.c
>>> b/src/gallium/drivers/r600/r600_pipe.c
>>>>> index 39a310a..5f69a5d 100644
>>>>> --- a/src/gallium/drivers/r600/r600_pipe.c
>>>>> +++ b/src/gallium/drivers/r600/r600_pipe.c
>>>>> @@ -276,20 +276,21 @@ static int r600_get_param(struct pipe_screen*
>>> pscreen, enum pipe_cap param)
>>>>> case PIPE_CAP_CONDITIONAL_RENDER_INVERTED:
>>>>> case PIPE_CAP_TEXTURE_FLOAT_LINEAR:
>>>>> case PIPE_CAP_TEXTURE_HALF_FLOAT_LINEAR:
>>>>> case PIPE_CAP_TGSI_TXQS:
>>>>> case PIPE_CAP_COPY_BETWEEN_COMPRESSED_AND_PLAIN_FORMATS:
>>>>> case PIPE_CAP_INVALIDATE_BUFFER:
>>>>> case PIPE_CAP_SURFACE_REINTERPRET_BLOCKS:
>>>>> case PIPE_CAP_QUERY_MEMORY_INFO:
>>>>> case PIPE_CAP_FRAMEBUFFER_NO_ATTACHMENT:
>>>>> case PIPE_CAP_POLYGON_OFFSET_UNITS_UNSCALED:
>>>>> + case PIPE_CAP_CLEAR_TEXTURE:
>>>>> return 1;
>>>>>
>>>>> case PIPE_CAP_DEVICE_RESET_STATUS_QUERY:
>>>>> return rscreen->b.info.drm_major == 2 &&
>>> rscreen->b.info.drm_minor >= 43;
>>>>>
>>>>> case PIPE_CAP_RESOURCE_FROM_USER_MEMORY:
>>>>> return !R600_BIG_ENDIAN &&
>>>>> rscreen->b.info.has_userptr;
>>>>>
>>>>> case PIPE_CAP_COMPUTE:
>>>>> return rscreen->b.chip_class > R700;
>>>>> @@ -348,21 +349,20 @@ static int r600_get_param(struct pipe_screen*
>>> pscreen, enum pipe_cap param)
>>>>> case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER:
>>>>> case PIPE_CAP_TGSI_CAN_COMPACT_CONSTANTS:
>>>>> case PIPE_CAP_FRAGMENT_COLOR_CLAMPED:
>>>>> case PIPE_CAP_VERTEX_COLOR_CLAMPED:
>>>>> case PIPE_CAP_USER_VERTEX_BUFFERS:
>>>>> case PIPE_CAP_TEXTURE_GATHER_OFFSETS:
>>>>> case PIPE_CAP_VERTEXID_NOBASE:
>>>>> case PIPE_CAP_DEPTH_BOUNDS_TEST:
>>>>> case PIPE_CAP_FORCE_PERSAMPLE_INTERP:
>>>>> case PIPE_CAP_SHAREABLE_SHADERS:
>>>>> - case PIPE_CAP_CLEAR_TEXTURE:
>>>>> case PIPE_CAP_DRAW_PARAMETERS:
>>>>> case PIPE_CAP_TGSI_PACK_HALF_FLOAT:
>>>>> case PIPE_CAP_MULTI_DRAW_INDIRECT:
>>>>> case PIPE_CAP_MULTI_DRAW_INDIRECT_PARAMS:
>>>>> case PIPE_CAP_TGSI_FS_POSITION_IS_SYSVAL:
>>>>> case PIPE_CAP_TGSI_FS_FACE_IS_INTEGER_SYSVAL:
>>>>> case PIPE_CAP_SHADER_BUFFER_OFFSET_ALIGNMENT:
>>>>> case PIPE_CAP_GENERATE_MIPMAP:
>>>>> case PIPE_CAP_STRING_MARKER:
>>>>> case PIPE_CAP_QUERY_BUFFER_OBJECT:
>>>>> diff --git a/src/gallium/drivers/radeon/r600_texture.c
>>> b/src/gallium/drivers/radeon/r600_texture.c
>>>>> index f7c2f80..0b13f36 100644
>>>>> --- a/src/gallium/drivers/radeon/r600_texture.c
>>>>> +++ b/src/gallium/drivers/radeon/r600_texture.c
>>>>> @@ -23,20 +23,21 @@
>>>>> * Authors:
>>>>> * Jerome Glisse
>>>>> * Corbin Simpson
>>>>> */
>>>>> #include "r600_pipe_common.h"
>>>>> #include "r600_cs.h"
>>>>> #include "r600_query.h"
>>>>> #include "util/u_format.h"
>>>>> #include "util/u_memory.h"
>>>>> #include "util/u_pack_color.h"
>>>>> +#include "util/u_surface.h"
>>>>> #include "os/os_time.h"
>>>>> #include <errno.h>
>>>>> #include <inttypes.h>
>>>>>
>>>>> static void r600_texture_discard_cmask(struct r600_common_screen
>>> *rscreen,
>>>>> struct r600_texture *rtex);
>>>>> static unsigned r600_choose_tiling(struct r600_common_screen
>>>>> *rscreen,
>>>>> const struct pipe_resource *templ);
>>>>>
>>>>>
>>>>> @@ -1689,20 +1690,84 @@ static struct pipe_surface
>>> *r600_create_surface(struct pipe_context *pipe,
>>>>> static void r600_surface_destroy(struct pipe_context *pipe,
>>>>> struct pipe_surface *surface)
>>>>> {
>>>>> struct r600_surface *surf = (struct r600_surface*)surface;
>>>>> r600_resource_reference(&surf->cb_buffer_fmask, NULL);
>>>>> r600_resource_reference(&surf->cb_buffer_cmask, NULL);
>>>>> pipe_resource_reference(&surface->texture, NULL);
>>>>> FREE(surface);
>>>>> }
>>>>>
>>>>> +static void r600_clear_texture(struct pipe_context *pipe,
>>>>> + struct pipe_resource *tex,
>>>>> + unsigned level,
>>>>> + const struct pipe_box *box,
>>>>> + const void *data)
>>>>> +{
>>>>> + struct pipe_screen *screen = pipe->screen;
>>>>> + struct r600_texture *rtex = (struct r600_texture*)tex;
>>>>> + struct pipe_surface tmpl = {{0}}, *sf;
>>>>> + const struct util_format_description *desc =
>>>>> + util_format_description(tex->format);
>>>>> +
>>>>> + tmpl.format = tex->format;
>>>>> + tmpl.u.tex.first_layer = box->z;
>>>>> + tmpl.u.tex.last_layer = box->z + box->depth - 1;
>>>>> + tmpl.u.tex.level = level;
>>>>> + sf = pipe->create_surface(pipe, tex, &tmpl);
>>>>> + if (!sf)
>>>>> + return;
>>>>> +
>>>>> + if (rtex->is_depth) {
>>>>> + unsigned clear;
>>>>> + float depth;
>>>>> + uint8_t stencil = 0;
>>>>> +
>>>>> + /* Depth is always present. */
>>>>> + clear = PIPE_CLEAR_DEPTH;
>>>>> + desc->unpack_z_float(&depth, 0, data, 0, 1, 1);
>>>>> +
>>>>> + if (rtex->surface.flags & RADEON_SURF_SBUFFER) {
>>>>> + clear |= PIPE_CLEAR_STENCIL;
>>>>> + desc->unpack_s_8uint(&stencil, 0, data, 0,
>>>>> 1, 1);
>>>>> + }
>>>>> +
>>>>> + pipe->clear_depth_stencil(pipe, sf, clear, depth,
>>> stencil,
>>>>> + box->x, box->y,
>>>>> + box->width, box->height);
>>>>> + } else {
>>>>> + union pipe_color_union color;
>>>>> +
>>>>> + /* pipe_color_union requires the full vec4
>>> representation. */
>>>>> + if (util_format_is_pure_uint(tex->format))
>>>>> + desc->unpack_rgba_uint(color.ui, 0, data, 0,
>>> 1, 1);
>>>>> + else if (util_format_is_pure_sint(tex->format))
>>>>> + desc->unpack_rgba_sint(color.i, 0, data, 0,
>>> 1, 1);
>>>>> + else
>>>>> + desc->unpack_rgba_float(color.f, 0, data, 0,
>>> 1, 1);
>>>>> +
>>>>> + if (screen->is_format_supported(screen, tex->format,
>>>>> + tex->target, 0,
>>>>> +
>>> PIPE_BIND_RENDER_TARGET)) {
>>>>> + pipe->clear_render_target(pipe, sf, &color,
>>>>> + box->x, box->y,
>>>>> + box->width,
>>> box->height);
>>>>> + } else {
>>>>> + /* Software fallback - just for
>>>>> R9G9B9E5_FLOAT */
>>>>> + util_clear_render_target(pipe, sf, &color,
>>>>> + box->x, box->y,
>>>>> + box->width,
>>> box->height);
>>>>> + }
>>>>> + }
>>>>> + pipe_surface_reference(&sf, NULL);
>>>>> +}
>>>>> +
>>>>> unsigned r600_translate_colorswap(enum pipe_format format, bool
>>> do_endian_swap)
>>>>> {
>>>>> const struct util_format_description *desc =
>>> util_format_description(format);
>>>>>
>>>>> #define HAS_SWIZZLE(chan,swz) (desc->swizzle[chan] ==
>>> PIPE_SWIZZLE_##swz)
>>>>>
>>>>> if (format == PIPE_FORMAT_R11G11B10_FLOAT) /* isn't plain */
>>>>> return V_0280A0_SWAP_STD;
>>>>>
>>>>> if (desc->layout != UTIL_FORMAT_LAYOUT_PLAIN)
>>>>> @@ -2325,11 +2390,12 @@ void evergreen_do_fast_color_clear(struct
>>> r600_common_context *rctx,
>>>>> void r600_init_screen_texture_functions(struct r600_common_screen
>>> *rscreen)
>>>>> {
>>>>> rscreen->b.resource_from_handle = r600_texture_from_handle;
>>>>> rscreen->b.resource_get_handle = r600_texture_get_handle;
>>>>> }
>>>>>
>>>>> void r600_init_context_texture_functions(struct r600_common_context
>>> *rctx)
>>>>> {
>>>>> rctx->b.create_surface = r600_create_surface;
>>>>> rctx->b.surface_destroy = r600_surface_destroy;
>>>>> + rctx->b.clear_texture = r600_clear_texture;
>>>>> }
>>>>> diff --git a/src/gallium/drivers/radeonsi/si_blit.c
>>> b/src/gallium/drivers/radeonsi/si_blit.c
>>>>> index 38a19d5..6fcf0f0 100644
>>>>> --- a/src/gallium/drivers/radeonsi/si_blit.c
>>>>> +++ b/src/gallium/drivers/radeonsi/si_blit.c
>>>>> @@ -28,21 +28,25 @@
>>>>>
>>>>> enum si_blitter_op /* bitmask */
>>>>> {
>>>>> SI_SAVE_TEXTURES = 1,
>>>>> SI_SAVE_FRAMEBUFFER = 2,
>>>>> SI_SAVE_FRAGMENT_STATE = 4,
>>>>> SI_DISABLE_RENDER_COND = 8,
>>>>>
>>>>> SI_CLEAR = SI_SAVE_FRAGMENT_STATE,
>>>>>
>>>>> - SI_CLEAR_SURFACE = SI_SAVE_FRAMEBUFFER |
>>>>> SI_SAVE_FRAGMENT_STATE,
>>>>> + /* GL_ARB_clear_texture should ignore the render condition,
>>>>> but
>>>>> + * Gallium shouldn't. Follow OpenGL.
>>>>> + */
>>>>> + SI_CLEAR_SURFACE = SI_SAVE_FRAMEBUFFER |
>>>>> SI_SAVE_FRAGMENT_STATE |
>>>>> + SI_DISABLE_RENDER_COND,
>>>>>
>>>>> SI_COPY = SI_SAVE_FRAMEBUFFER | SI_SAVE_TEXTURES |
>>>>> SI_SAVE_FRAGMENT_STATE |
>>> SI_DISABLE_RENDER_COND,
>>>>>
>>>>> SI_BLIT = SI_SAVE_FRAMEBUFFER | SI_SAVE_TEXTURES |
>>>>> SI_SAVE_FRAGMENT_STATE,
>>>>>
>>>>> SI_DECOMPRESS = SI_SAVE_FRAMEBUFFER |
>>>>> SI_SAVE_FRAGMENT_STATE |
>>>>> SI_DISABLE_RENDER_COND,
>>>>>
>>>>> diff --git a/src/gallium/drivers/radeonsi/si_pipe.c
>>> b/src/gallium/drivers/radeonsi/si_pipe.c
>>>>> index e33823d..c1c2a9a 100644
>>>>> --- a/src/gallium/drivers/radeonsi/si_pipe.c
>>>>> +++ b/src/gallium/drivers/radeonsi/si_pipe.c
>>>>> @@ -379,20 +379,21 @@ static int si_get_param(struct pipe_screen*
>>> pscreen, enum pipe_cap param)
>>>>> case PIPE_CAP_TGSI_FS_FACE_IS_INTEGER_SYSVAL:
>>>>> case PIPE_CAP_INVALIDATE_BUFFER:
>>>>> case PIPE_CAP_SURFACE_REINTERPRET_BLOCKS:
>>>>> case PIPE_CAP_QUERY_MEMORY_INFO:
>>>>> case PIPE_CAP_TGSI_PACK_HALF_FLOAT:
>>>>> case PIPE_CAP_FRAMEBUFFER_NO_ATTACHMENT:
>>>>> case PIPE_CAP_ROBUST_BUFFER_ACCESS_BEHAVIOR:
>>>>> case PIPE_CAP_GENERATE_MIPMAP:
>>>>> case PIPE_CAP_POLYGON_OFFSET_UNITS_UNSCALED:
>>>>> case PIPE_CAP_STRING_MARKER:
>>>>> + case PIPE_CAP_CLEAR_TEXTURE:
>>>>> return 1;
>>>>>
>>>>> case PIPE_CAP_RESOURCE_FROM_USER_MEMORY:
>>>>> return !SI_BIG_ENDIAN && sscreen->b.info.has_userptr;
>>>>>
>>>>> case PIPE_CAP_DEVICE_RESET_STATUS_QUERY:
>>>>> return (sscreen->b.info.drm_major == 2 &&
>>>>> sscreen->b.info.drm_minor >= 43) ||
>>>>> sscreen->b.info.drm_major == 3;
>>>>>
>>>>> @@ -427,21 +428,20 @@ static int si_get_param(struct pipe_screen*
>>> pscreen, enum pipe_cap param)
>>>>> case PIPE_CAP_BUFFER_SAMPLER_VIEW_RGBA_ONLY:
>>>>> return 0;
>>>>>
>>>>> /* Unsupported features. */
>>>>> case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT:
>>>>> case PIPE_CAP_TGSI_CAN_COMPACT_CONSTANTS:
>>>>> case PIPE_CAP_USER_VERTEX_BUFFERS:
>>>>> case PIPE_CAP_FAKE_SW_MSAA:
>>>>> case PIPE_CAP_TEXTURE_GATHER_OFFSETS:
>>>>> case PIPE_CAP_VERTEXID_NOBASE:
>>>>> - case PIPE_CAP_CLEAR_TEXTURE:
>>>>> case PIPE_CAP_DRAW_PARAMETERS:
>>>>> case PIPE_CAP_MULTI_DRAW_INDIRECT:
>>>>> case PIPE_CAP_MULTI_DRAW_INDIRECT_PARAMS:
>>>>> case PIPE_CAP_QUERY_BUFFER_OBJECT:
>>>>> case PIPE_CAP_CULL_DISTANCE:
>>>>> case PIPE_CAP_PRIMITIVE_RESTART_FOR_PATCHES:
>>>>> case PIPE_CAP_TGSI_VOTE:
>>>>> case PIPE_CAP_MAX_WINDOW_RECTANGLES:
>>>>> return 0;
>>>>>
>>>>>
>>>
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/mesa-dev
More information about the mesa-dev
mailing list