On Tue, 9 Mar 2021 at 10:26, Jan Sikorski jsikorski@codeweavers.com wrote:
- if (resolve_format_id != WINED3DFMT_UNKNOWN)
- {
I think we only care about the resolve format if we're doing a resolve operation.
switch (resolve_format_id)
{
case WINED3DFMT_R8G8B8A8_UNORM_SRGB:
case WINED3DFMT_B8G8R8A8_UNORM_SRGB:
case WINED3DFMT_B8G8R8X8_UNORM_SRGB:
gl_info->gl_ops.gl.p_glEnable(GL_FRAMEBUFFER_SRGB);
context_invalidate_state(context, STATE_RENDER(WINED3D_RS_SRGBWRITEENABLE));
resolve_internal = resolve_format_gl->srgb_internal;
break;
default:
resolve_internal = resolve_format_gl->internal;
break;
}
Don't hardcode formats like that, it's very fragile. You'll probably want to do something similar to needs_srgb_write(). Should we enable GL_FRAMEBUFFER_SRGB for blits more broadly instead of only for typeless resolves? If yes, this belongs in a separate commit, and something like wined3d_context_gl_apply_fbo_state_blit() may be a more appropriate place.
if (src_location == WINED3D_LOCATION_TEXTURE_SRGB)
src_internal = src_format_gl->srgb_internal;
else if (src_texture->resource.bind_flags & WINED3D_BIND_RENDER_TARGET && wined3d_resource_is_offscreen(&src_texture->resource))
src_internal = src_format_gl->rt_internal;
else
src_internal = src_format_gl->internal;
if (dst_location == WINED3D_LOCATION_TEXTURE_SRGB)
dst_internal = dst_format_gl->srgb_internal;
else if (dst_texture->resource.bind_flags & WINED3D_BIND_RENDER_TARGET && wined3d_resource_is_offscreen(&dst_texture->resource))
dst_internal = dst_format_gl->rt_internal;
else
dst_internal = dst_format_gl->internal;
That could use a helper function.
/* In case of typeless resolve the texture type may not match the resolve type.
* To handle that, allocate intermediate texture(s) to resolve from/to.
* A possible performance improvement would be to resolve using a shader instead. */
if (src_internal != resolve_internal)
{
struct wined3d_resource_desc desc;
unsigned src_level;
HRESULT hr;
src_level = src_sub_resource_idx % src_texture->level_count;
desc.resource_type = WINED3D_RTYPE_TEXTURE_2D;
desc.format = resolve_format_id;
desc.multisample_type = src_texture->resource.multisample_type;
desc.multisample_quality = src_texture->resource.multisample_quality;
desc.usage = WINED3DUSAGE_PRIVATE;
desc.bind_flags = 0;
desc.access = WINED3D_RESOURCE_ACCESS_GPU;
desc.width = wined3d_texture_get_level_width(src_texture, src_level);
desc.height = wined3d_texture_get_level_height(src_texture, src_level);
desc.depth = 1;
desc.size = 0;
hr = wined3d_texture_create(device, &desc, 1, 1, 0, NULL, NULL, &wined3d_null_parent_ops, &src_staging_texture);
if (FAILED(hr))
{
ERR("Failed to create staging texture, hr %#x.\n", hr);
return;
}
device->blitter->ops->blitter_blit(device->blitter, WINED3D_BLIT_OP_RAW_BLIT, context,
src_texture, src_sub_resource_idx, src_location, src_rect,
src_staging_texture, 0, src_location, src_rect,
NULL, WINED3D_TEXF_NONE, WINED3DFMT_UNKNOWN);
src_texture = src_staging_texture;
src_sub_resource_idx = 0;
}
Note that that only works if the source location isn't WINED3D_LOCATION_DRAWABLE. That should always hold in practice, but we may want to be explicit about that.
if (dst_internal != resolve_internal)
{
struct wined3d_resource_desc desc;
unsigned dst_level;
HRESULT hr;
dst_level = dst_sub_resource_idx % dst_texture->level_count;
desc.resource_type = WINED3D_RTYPE_TEXTURE_2D;
desc.format = resolve_format_id;
desc.multisample_type = dst_texture->resource.multisample_type;
desc.multisample_quality = dst_texture->resource.multisample_quality;
desc.usage = WINED3DUSAGE_PRIVATE;
desc.bind_flags = 0;
desc.access = WINED3D_RESOURCE_ACCESS_GPU;
desc.width = wined3d_texture_get_level_width(dst_texture, dst_level);
desc.height = wined3d_texture_get_level_height(dst_texture, dst_level);
desc.depth = 1;
desc.size = 0;
hr = wined3d_texture_create(device, &desc, 1, 1, 0, NULL, NULL, &wined3d_null_parent_ops, &dst_staging_texture);
if (FAILED(hr))
{
ERR("Failed to create staging texture, hr %#x.\n", hr);
if (src_staging_texture)
wined3d_texture_decref(src_staging_texture);
return;
}
wined3d_texture_load_location(dst_staging_texture, 0, context, dst_location);
dst_texture = dst_staging_texture;
dst_sub_resource_idx = 0;
}
- }
Likewise.