[Mesa-dev] [PATCH] gallium/radeon: implement ARB_clear_texture (v2)
Nicolai Hähnle
nhaehnle at gmail.com
Sat Aug 6 11:26:53 UTC 2016
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;
>>>>
>>>>
>>
More information about the mesa-dev
mailing list