[PATCH 3/6] wined3d: Implement OpenGL image UAV clears using ARB_clear_texture.
Henri Verbeet
hverbeet at codeweavers.com
Mon Jun 7 09:55:09 CDT 2021
Signed-off-by: Henri Verbeet <hverbeet at codeweavers.com>
---
dlls/d3d11/tests/d3d11.c | 24 ++++-----
dlls/wined3d/utils.c | 12 +++++
dlls/wined3d/view.c | 95 ++++++++++++++++++++++++++++++----
dlls/wined3d/wined3d_private.h | 1 +
4 files changed, 110 insertions(+), 22 deletions(-)
diff --git a/dlls/d3d11/tests/d3d11.c b/dlls/d3d11/tests/d3d11.c
index 217b4870e53..f729a38b4c2 100644
--- a/dlls/d3d11/tests/d3d11.c
+++ b/dlls/d3d11/tests/d3d11.c
@@ -16456,26 +16456,26 @@ static void test_clear_image_unordered_access_view(void)
tests[] =
{
/* Test clearing a specific mip level. */
- {DXGI_FORMAT_R32_FLOAT, 2, 1, 0, 0, 1, {1, 0, 0, 0}, 0x00000001, FALSE, 0, TRUE},
- {DXGI_FORMAT_R32_FLOAT, 2, 1, 1, 0, 1, {1, 0, 0, 0}, 0x00000001, FALSE, 0, TRUE},
+ {DXGI_FORMAT_R32_FLOAT, 2, 1, 0, 0, 1, {1, 0, 0, 0}, 0x00000001},
+ {DXGI_FORMAT_R32_FLOAT, 2, 1, 1, 0, 1, {1, 0, 0, 0}, 0x00000001},
{DXGI_FORMAT_R32_FLOAT, 2, 1, 0, 0, 1, {0x3f000000, 0, 0, 0}, 0x3f000000, TRUE, 0, TRUE},
{DXGI_FORMAT_R32_FLOAT, 2, 1, 1, 0, 1, {0x3f000000, 0, 0, 0}, 0x3f000000, TRUE, 0, TRUE},
/* Test clearing specific array layers. */
- {DXGI_FORMAT_R32_FLOAT, 1, IMAGE_SIZE, 0, 0, IMAGE_SIZE, {1, 0, 0, 0}, 0x00000001, FALSE, 0, TRUE},
- {DXGI_FORMAT_R32_FLOAT, 1, IMAGE_SIZE, 0, 3, 2, {1, 0, 0, 0}, 0x00000001, FALSE, 0, TRUE},
+ {DXGI_FORMAT_R32_FLOAT, 1, IMAGE_SIZE, 0, 0, IMAGE_SIZE, {1, 0, 0, 0}, 0x00000001},
+ {DXGI_FORMAT_R32_FLOAT, 1, IMAGE_SIZE, 0, 3, 2, {1, 0, 0, 0}, 0x00000001},
{DXGI_FORMAT_R32_FLOAT, 1, IMAGE_SIZE, 0, 0, IMAGE_SIZE,
{0x3f000000, 0, 0, 0}, 0x3f000000, TRUE, 0, TRUE},
{DXGI_FORMAT_R32_FLOAT, 1, IMAGE_SIZE, 0, 3, 2,
{0x3f000000, 0, 0, 0}, 0x3f000000, TRUE, 0, TRUE},
/* Test uint clears with formats. */
- {DXGI_FORMAT_R16G16_UINT, 1, 1, 0, 0, 1, {1, 2, 3, 4}, 0x00020001, FALSE, 0, TRUE},
- {DXGI_FORMAT_R16G16_UINT, 1, 1, 0, 0, 1, {0x12345, 0, 0, 0}, 0x00002345, FALSE, 0x0000ffff, TRUE},
- {DXGI_FORMAT_R16G16_UNORM, 1, 1, 0, 0, 1, {1, 2, 3, 4}, 0x00020001, FALSE, 0, TRUE},
- {DXGI_FORMAT_R16G16_FLOAT, 1, 1, 0, 0, 1, {1, 2, 3, 4}, 0x00020001, FALSE, 0, TRUE},
- {DXGI_FORMAT_R8G8B8A8_UINT, 1, 1, 0, 0, 1, {1, 2, 3, 4}, 0x04030201, FALSE, 0, TRUE},
- {DXGI_FORMAT_R8G8B8A8_UINT, 1, 1, 0, 0, 1, {0x123, 0, 0, 0}, 0x00000023, FALSE, 0x000000ff, TRUE},
- {DXGI_FORMAT_R8G8B8A8_UNORM, 1, 1, 0, 0, 1, {1, 2, 3, 4}, 0x04030201, FALSE, 0, TRUE},
- {DXGI_FORMAT_R11G11B10_FLOAT, 1, 1, 0, 0, 1, {1, 2, 3, 4}, 0x00c01001, FALSE, 0, TRUE},
+ {DXGI_FORMAT_R16G16_UINT, 1, 1, 0, 0, 1, {1, 2, 3, 4}, 0x00020001},
+ {DXGI_FORMAT_R16G16_UINT, 1, 1, 0, 0, 1, {0x12345, 0, 0, 0}, 0x00002345, FALSE, 0x0000ffff},
+ {DXGI_FORMAT_R16G16_UNORM, 1, 1, 0, 0, 1, {1, 2, 3, 4}, 0x00020001},
+ {DXGI_FORMAT_R16G16_FLOAT, 1, 1, 0, 0, 1, {1, 2, 3, 4}, 0x00020001},
+ {DXGI_FORMAT_R8G8B8A8_UINT, 1, 1, 0, 0, 1, {1, 2, 3, 4}, 0x04030201},
+ {DXGI_FORMAT_R8G8B8A8_UINT, 1, 1, 0, 0, 1, {0x123, 0, 0, 0}, 0x00000023, FALSE, 0x000000ff},
+ {DXGI_FORMAT_R8G8B8A8_UNORM, 1, 1, 0, 0, 1, {1, 2, 3, 4}, 0x04030201},
+ {DXGI_FORMAT_R11G11B10_FLOAT, 1, 1, 0, 0, 1, {1, 2, 3, 4}, 0x00c01001},
/* Test float clears with formats. */
{DXGI_FORMAT_R16G16_UNORM, 1, 1, 0, 0, 1,
{0x3f000000 /* 0.5f */, 0x3f800000 /* 1.0f */, 0, 0}, 0xffff8000, TRUE, 0, TRUE},
diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c
index 8eacc52ee2c..6e388e66862 100644
--- a/dlls/wined3d/utils.c
+++ b/dlls/wined3d/utils.c
@@ -5803,6 +5803,18 @@ BOOL wined3d_get_primary_adapter_luid(LUID *luid)
return TRUE;
}
+uint32_t wined3d_format_pack(const struct wined3d_format *format, const struct wined3d_uvec4 *value)
+{
+ uint32_t p = 0;
+
+ p |= (value->x & wined3d_mask_from_size(format->red_size)) << format->red_offset;
+ p |= (value->y & wined3d_mask_from_size(format->green_size)) << format->green_offset;
+ p |= (value->z & wined3d_mask_from_size(format->blue_size)) << format->blue_offset;
+ p |= (value->w & wined3d_mask_from_size(format->alpha_size)) << format->alpha_offset;
+
+ return p;
+}
+
/* Note: It's the caller's responsibility to ensure values can be expressed
* in the requested format. UNORM formats for example can only express values
* in the range 0.0f -> 1.0f. */
diff --git a/dlls/wined3d/view.c b/dlls/wined3d/view.c
index 03abaf57102..2d2622e1191 100644
--- a/dlls/wined3d/view.c
+++ b/dlls/wined3d/view.c
@@ -1450,7 +1450,7 @@ void wined3d_unordered_access_view_gl_clear_uint(struct wined3d_unordered_access
const struct wined3d_uvec4 *clear_value, struct wined3d_context_gl *context_gl)
{
const struct wined3d_gl_info *gl_info = context_gl->gl_info;
- const struct wined3d_format_gl *format;
+ const struct wined3d_format_gl *format_gl;
struct wined3d_buffer_gl *buffer_gl;
struct wined3d_resource *resource;
unsigned int offset, size;
@@ -1458,7 +1458,82 @@ void wined3d_unordered_access_view_gl_clear_uint(struct wined3d_unordered_access
resource = view_gl->v.resource;
if (resource->type != WINED3D_RTYPE_BUFFER)
{
- FIXME("Not implemented for %s resources.\n", debug_d3dresourcetype(resource->type));
+ unsigned int layer_count, level_count, base_level, base_layer;
+ unsigned int sub_resource_idx, width, height, depth, i, j;
+ struct wined3d_texture_gl *texture_gl;
+ const void *data = clear_value;
+ GLenum gl_format, gl_type;
+ uint32_t packed;
+
+ if (!gl_info->supported[ARB_CLEAR_TEXTURE])
+ {
+ FIXME("OpenGL implementation does not support ARB_clear_texture.\n");
+ return;
+ }
+
+ format_gl = wined3d_format_gl(resource->format);
+ texture_gl = wined3d_texture_gl(texture_from_resource(resource));
+ layer_count = view_gl->v.desc.u.texture.layer_count;
+ level_count = view_gl->v.desc.u.texture.level_count;
+ base_layer = view_gl->v.desc.u.texture.layer_idx;
+ base_level = view_gl->v.desc.u.texture.level_idx;
+
+ if (format_gl->f.byte_count <= 4)
+ {
+ gl_format = format_gl->format;
+ gl_type = format_gl->type;
+ packed = wined3d_format_pack(&format_gl->f, clear_value);
+ data = &packed;
+ }
+ else if (resource->format_flags & WINED3DFMT_FLAG_INTEGER)
+ {
+ gl_format = GL_RGBA_INTEGER;
+ gl_type = GL_UNSIGNED_INT;
+ }
+ else
+ {
+ gl_format = GL_RGBA;
+ gl_type = GL_FLOAT;
+ }
+
+ for (i = 0; i < layer_count; ++i)
+ {
+ for (j = 0; j < level_count; ++j)
+ {
+ sub_resource_idx = (base_layer + i) * texture_gl->t.level_count + base_level + j;
+ wined3d_texture_prepare_location(&texture_gl->t, sub_resource_idx,
+ &context_gl->c, WINED3D_LOCATION_TEXTURE_RGB);
+
+ width = wined3d_texture_get_level_width(&texture_gl->t, base_level + j);
+ height = wined3d_texture_get_level_height(&texture_gl->t, base_level + j);
+ depth = wined3d_texture_get_level_depth(&texture_gl->t, base_level + j);
+
+ switch (texture_gl->target)
+ {
+ case GL_TEXTURE_1D_ARRAY:
+ GL_EXTCALL(glClearTexSubImage(texture_gl->texture_rgb.name, base_level + j,
+ 0, base_layer + i, 0, width, 1, 1, gl_format, gl_type, data));
+ break;
+
+ case GL_TEXTURE_2D_ARRAY:
+ case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
+ case GL_TEXTURE_CUBE_MAP:
+ case GL_TEXTURE_CUBE_MAP_ARRAY:
+ GL_EXTCALL(glClearTexSubImage(texture_gl->texture_rgb.name, base_level + j,
+ 0, 0, base_layer + i, width, height, 1, gl_format, gl_type, data));
+ break;
+
+ default:
+ GL_EXTCALL(glClearTexSubImage(texture_gl->texture_rgb.name, base_level + j,
+ 0, 0, 0, width, height, depth, gl_format, gl_type, data));
+ break;
+ }
+
+ wined3d_texture_validate_location(&texture_gl->t, sub_resource_idx, WINED3D_LOCATION_TEXTURE_RGB);
+ wined3d_texture_invalidate_location(&texture_gl->t, sub_resource_idx, ~WINED3D_LOCATION_TEXTURE_RGB);
+ }
+ }
+
return;
}
@@ -1468,12 +1543,12 @@ void wined3d_unordered_access_view_gl_clear_uint(struct wined3d_unordered_access
return;
}
- format = wined3d_format_gl(view_gl->v.format);
- if (format->f.id != WINED3DFMT_R32_UINT && format->f.id != WINED3DFMT_R32_SINT
- && format->f.id != WINED3DFMT_R32G32B32A32_UINT
- && format->f.id != WINED3DFMT_R32G32B32A32_SINT)
+ format_gl = wined3d_format_gl(view_gl->v.format);
+ if (format_gl->f.id != WINED3DFMT_R32_UINT && format_gl->f.id != WINED3DFMT_R32_SINT
+ && format_gl->f.id != WINED3DFMT_R32G32B32A32_UINT
+ && format_gl->f.id != WINED3DFMT_R32G32B32A32_SINT)
{
- FIXME("Not implemented for format %s.\n", debug_d3dformat(format->f.id));
+ FIXME("Not implemented for format %s.\n", debug_d3dformat(format_gl->f.id));
return;
}
@@ -1481,10 +1556,10 @@ void wined3d_unordered_access_view_gl_clear_uint(struct wined3d_unordered_access
wined3d_buffer_load_location(&buffer_gl->b, &context_gl->c, WINED3D_LOCATION_BUFFER);
wined3d_unordered_access_view_invalidate_location(&view_gl->v, ~WINED3D_LOCATION_BUFFER);
- get_buffer_view_range(&buffer_gl->b, &view_gl->v.desc, &format->f, &offset, &size);
+ get_buffer_view_range(&buffer_gl->b, &view_gl->v.desc, &format_gl->f, &offset, &size);
wined3d_context_gl_bind_bo(context_gl, buffer_gl->bo.binding, buffer_gl->bo.id);
- GL_EXTCALL(glClearBufferSubData(buffer_gl->bo.binding, format->internal,
- offset, size, format->format, format->type, clear_value));
+ GL_EXTCALL(glClearBufferSubData(buffer_gl->bo.binding, format_gl->internal,
+ offset, size, format_gl->format, format_gl->type, clear_value));
wined3d_context_gl_reference_bo(context_gl, &buffer_gl->bo);
checkGLcall("clear unordered access view");
}
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 6d41f02e842..d08c523bd9f 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -5818,6 +5818,7 @@ BOOL wined3d_format_is_depth_view(enum wined3d_format_id resource_format_id,
enum wined3d_format_id view_format_id) DECLSPEC_HIDDEN;
const struct wined3d_color_key_conversion * wined3d_format_get_color_key_conversion(
const struct wined3d_texture *texture, BOOL need_alpha_ck) DECLSPEC_HIDDEN;
+uint32_t wined3d_format_pack(const struct wined3d_format *format, const struct wined3d_uvec4 *value) DECLSPEC_HIDDEN;
BOOL wined3d_formats_are_srgb_variants(enum wined3d_format_id format1,
enum wined3d_format_id format2) DECLSPEC_HIDDEN;
--
2.20.1
More information about the wine-devel
mailing list