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;elsesrc_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;elsedst_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.