Signed-off-by: Henri Verbeet hverbeet@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;