Perhaps not unexpectedly, this MR is getting pretty large, as these things tend to. I recommend splitting the test and format support changes into a separate MR.
```diff + hr = ID3D10Device_CheckFormatSupport(device, rtv_desc.Format, &flags); + ok(SUCCEEDED(hr), "Got unexpected hr %#lx.\n", hr); + hr = ID3D10Device_CreateRenderTargetView(device, (ID3D10Resource *)backbuffer_0, &rtv_desc, &backbuffer_0_rtv_srgb); + flags &= D3D10_FORMAT_SUPPORT_BACK_BUFFER_CAST; + flags = (FAILED(hr) && !flags) || (SUCCEEDED(hr) && flags); + todo_wine ok(flags, "Got unexpected for SRGB rtv for UNORM swapchain, hr %#lx.\n", hr); ```
That's a little awkward. I'd suggest something like this: ```c ... expect_hr = flags & D3D10_FORMAT_SUPPORT_BACK_BUFFER_CAST ? S_OK : E_INVALIDARG; hr = ID3D10Device_CreateRenderTargetView(...); ok(hr == expect_hr, "Got hr %#lx, expected %#lx\n", hr, expect_hr); ```
```diff +struct wined3d_swapchain * __cdecl wined3d_swapchain_from_resource(struct wined3d_resource *resource) +{ + return swapchain_from_resource(resource); +} ```
I don't think we need/want wined3d_swapchain_from_resource(). It seems you're using this mainly in d3d11's d3d_rendertarget_view_init() to validate WINED3D_FORMAT_CAP_BACK_BUFFER_CAST support, but if we're going to call into wined3d anyway, we may as well just do that validation inside wined3d. The most convenient place for that is probably validate_resource_view(). There may be a case for swapchain_from_resource() in principle, but in the places where you're using it, it's just a replacement for "texture_vk->t.swapchain" and "texture_gl->t.swapchain".
```diff {WINED3DFMT_R8G8B8A8_UNORM, GL_RGBA8, GL_SRGB8_ALPHA8_EXT, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, 0, WINED3D_FORMAT_CAP_TEXTURE | WINED3D_FORMAT_CAP_POSTPIXELSHADER_BLENDING | WINED3D_FORMAT_CAP_FILTERING | WINED3D_FORMAT_CAP_RENDERTARGET | WINED3D_FORMAT_CAP_SRGB_READ | WINED3D_FORMAT_CAP_SRGB_WRITE - | WINED3D_FORMAT_CAP_VTF, + | WINED3D_FORMAT_CAP_VTF | WINED3D_FORMAT_CAP_BACK_BUFFER_CAST, WINED3D_GL_EXT_NONE, NULL}, ```
I'd add this to format_base_flags[], that would also avoid accessing format_texture_info[] from Vulkan code.
```diff +static void wined3d_swapchain_rendertarget_view_gl_rotate(struct wined3d_swapchain *swapchain) +{ + struct wined3d_swapchain_rendertarget_view_gl *swap_view_gl; + struct wined3d_swapchain_rendertarget_view *swap_view; + struct wined3d_rendertarget_view_gl *view_gl; + GLuint name, name_prev; + + if (!swapchain || swapchain->state.desc.backbuffer_count < 2) + return; ```
I don't think wined3d_swapchain_rendertarget_view_gl_rotate() should ever get called in that case.
```diff +struct wined3d_swapchain_rendertarget_view_gl +{ + struct list entry; + GLuint name; +}; + struct wined3d_rendertarget_view_gl { struct wined3d_rendertarget_view v; struct wined3d_gl_view gl_view; + struct list swapchain_views; }; ```
I think Elizabeth was getting at this, but if we have a struct wined3d_rendertarget_view_gl like this: ```c struct wined3d_rendertarget_view_gl { struct wined3d_rendertarget_view v; struct wined3d_swapchain_view swapchain_view; struct wined3d_gl_view gl_view[1]; }; ``` we can then allocate it like this: ```c count = ...; ... view_gl = calloc(1, offsetof(struct wined3d_rendertarget_view_gl, gl_view[count])); ``` in adapter_gl_create_rendertarget_view(), and get a gl_view[] of the appropriate length.
GL_FRAMEBUFFER_SRGB has been moved back to texture2d_blt_fbo with a condition for resolve_format WINED3D_FORMAT_CAP_SRGB_WRITE. Unclear if this is actually correct but it fixes tests and Frostpunk.
It seems suspicious to me. The way I understand the issue, we should be disabling GL_FRAMEBUFFER_SRGB when copying to/from WINED3D_LOCATION_DRAWABLE, or alternatively simply always when the source and destination formats are the same. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/10567#note_144547