Repository navigation
Conversation
glClearTexImage and glClearTexSubImage (GL 4.4, GL_ARB_clear_texture): one texel converted as by TexSubImage without the pixel store state, or zeros, repeated over a region of a level, layer by layer; cube maps clear their faces as layers and 1D arrays their rows. Multisample images are not cleared yet. KHR-GL44.clear_tex_image: 75 of 78 pass; the buffer-texture case needs DSA, the STENCIL_INDEX case stencil textures, and the generic-compressed case is a CTS defect (known-failures.json).
glBindBuffersBase/Range, glBindTextures, glBindSamplers, glBindImageTextures and glBindVertexBuffers (GL 4.4, GL_ARB_multi_bind): a range past the last binding changes nothing; an error in one binding leaves it alone and the others are made; the generic buffer binding is not changed. glGetIntegeri_v answers the texture and sampler bindings of a unit. KHR-GL44.multi_bind: 17 of 17.
With a buffer bound to GL_QUERY_BUFFER (GL 4.4, GL_ARB_query_buffer_object), glGetQueryObject* writes the result (32 or 64 bits, or the availability flag) at the given offset through an ordered GPU copy; GL_QUERY_RESULT still waits for the result on the CPU. GL_QUERY_BUFFER_BINDING can be queried. KHR-GL44.map_buffer_alignment passes in 4.4 contexts.
GL 4.4 (GL_ARB_texture_stencil8): STENCIL_INDEX and STENCIL_INDEX8 are texture formats, uploaded with STENCIL_INDEX data and sampled as unsigned integers. Stencil-only multisample blits of one format and sample count copy every sample. GL_MIRROR_CLAMP_TO_EDGE is a wrap mode in 4.4 contexts (GL_ARB_texture_mirror_clamp_to_edge). KHR-GL46.texture_stencil8 passes (development override).
Transform feedback declared in the last vertex processing stage (GL 4.4, GL_ARB_enhanced_layouts: xfb_buffer, xfb_offset, xfb_stride on outputs and block members) replaces glTransformFeedbackVaryings: varyings are captured at their byte offsets with the declared or implicit strides. Block layout(offset/align) comes from glslang's layout like the other block rules. KHR-GL46 transform feedback, geometry and tessellation groups show no regressions.
GL_MAX_UNIFORM_BUFFER_BINDINGS is 84, the GL 4.5 minimum (14 blocks in each of six stages). gl_MaxVertexUniformVectors and gl_MaxFragmentUniformVectors match GL_MAX_*_UNIFORM_VECTORS (KHR-GL46.limits).
GL 4.5 (GL_ARB_direct_state_access): glCreate* for every object type and the named commands for buffers, textures, framebuffers, renderbuffers, vertex arrays, transform feedback objects and queries (97 entry points). Each named command runs the bind-to-edit implementation with the object in a binding for the call, restored before it returns, so both share their validation. Named commands add the GL 4.5 rules the bind-to-edit ones do not have: INVALID_OPERATION for a name that is not an object of the kind or a target the command does not accept, draw/read buffer enums, colour attachments past the limit and sample counts. Also: created queries answer GL_QUERY_TARGET and their defaults before first use; glGetFramebufferParameteriv answers the framebuffer-dependent state (GL 4.5); the default framebuffer reports its right buffers as absent; glFramebufferTextureLayer checks the layer against the target's limit; glVertexAttribFormat requires size 3 for UNSIGNED_INT_10F_11F_11F_REV; glMemoryBarrierByRegion. KHR-GL46.direct_state_access: 371 of 371 (one CompatibilityWarning).
GL 4.5 / ARB_cull_distance on Metal, which has clip distances only. The vertex stage's gl_CullDistance (masked to a local array by SPIRV-Cross) becomes the [[user(cullN)]] varyings plus an indicator per distance (0 where negative, 1e30 elsewhere). Interpolated, the indicator is exactly 0 only inside primitives with the distance negative at every vertex, and a fragment variant discards those fragments. The geometry and tessellation emulations carry gl_CullDistance like gl_ClipDistance (including redeclared output sizes), GL_MAX_CULL_DISTANCES and GL_MAX_COMBINED_CLIP_AND_CULL_ DISTANCES report 8, and #extension GL_ARB_cull_distance compiles as GLSL 4.50 with the macro predefined. KHR-GL46.cull_distance: 202 Pass, 16 NotSupported (by design) native and under Wine; KHR-GL46.limits 140/140.
… strings - glGetTextureSubImage and glGetCompressedTextureSubImage (GL 4.5 / ARB_get_texture_sub_image): regions of every target, cube faces as z, compressed images decoded, whole blocks for the compressed variant. - The *_INVERTED conditional rendering modes (ARB_conditional_render_ inverted). - GL_CONTEXT_RELEASE_BEHAVIOR reports FLUSH (KHR_context_flush_control; releasing a context flushes it). - Buffer sub-data, clears, copies and reads fail only where they overlap a non-persistent mapping (GL 4.5 sections 6.2.2, 6.3, 6.6); a mapped buffer is not renamed by a sub-data update. - glEnable/DisableVertexAttribArray work without a bound VAO in 4.5 core contexts, as the CTS (get_uniform) and drivers expect. - Shadow lookups of incomplete textures return 0. - 4.4 and 4.5 contexts advertise the extensions those versions made core. KHR-GL46 at dev 4.6: get_texture_sub_image 2/2, conditional_render_ inverted 2/2, incomplete_texture_access, get_uniform_tests, buffer_storage 34/34 with the DSA buffer groups.
Metal's samplers give three border colours. Clamp-to-border is now emulated in the shader for the draws that need more: - Every stage is translated by BorderMsl (shader/border.cpp), which wraps each sample and gather of a non-arrayed 1D, 2D, 3D or rectangle texture in a per-texture macro; the default definition is the plain value, so ordinary draws are unchanged. - A draw whose bound texture and sampler wrap CLAMP_TO_BORDER with a border Metal cannot give (other colours, integer and shadow borders, swizzled or non-RGBA formats, rectangle textures) uses a function variant (pipeline key borders) with the border baked in: the hardware value inside the image, the border for nearest samples outside it, hand filtering from texel reads for linear samples across the edge, per-texel substitution for gathers, and the border's depth for comparisons. Vertex (including transform feedback capture) and fragment functions, compute dispatches, and the geometry and tessellation control kernels take variants. Cull distance fixes (from 2bafa02): gl_PerVertex declares gl_CullDistance whether or not a shader writes it, so cull varyings and the fragment cull test now need an actual write (the geometry emulation's unwritten, uninitialised distances culled points in shader_image_load_store.early-fragment-tests), and the fragment cull variant inserts its input struct before an [[early_fragment_tests]] function. KHR-GL46 at dev 4.6: texture_border_clamp 32/32, gpu_shader5 22/22; texture_*, shaders, shader_image_load_store and 19 other shader groups (8,700 cases) with no new failures; GPU test gpu_gl44_border_colors.
glClearTex(Sub)Image of a multisample image, which Metal cannot upload to: a render pass per layer sets every sample of the region, as a load action for whole layers and a scissored draw otherwise. Colour texels are written bit for bit through an unsigned integer view of the storage; depth and stencil through the depth and stencil attachments. GPU test gpu_gl44_clear_texture_multisample; KHR-GL46 clear_tex_image, texture_multisample, sample_variables and copy_image unchanged.
The single-configuration CTS lists (khronos_mustpass_single: KHR-Single- GL4x enhanced_layouts and arrays_of_arrays_gl) were never run; run.py now takes them (gl46-khr-single.txt). enhanced_layouts goes from 3,940 to 4,244 of 4,250: - Interface locations past the stage's GL_MAX_*_COMPONENTS / 4 (and vertex inputs past GL_MAX_VERTEX_ATTRIBS) fail to compile. - GL_LOCATION_COMPONENT, and the GL_TRANSFORM_FEEDBACK_BUFFER interface (BUFFER_BINDING, active variables, TRANSFORM_FEEDBACK_BUFFER_STRIDE; OFFSET and TRANSFORM_FEEDBACK_BUFFER_INDEX of captured varyings). - Transform feedback: only the buffers varyings are captured into must be bound; the interleaved limit applies per buffer; arrays of blocks and struct outputs are captured element by element. - Vertex inputs may alias locations (glslang patch, as OpenGL allows), and attributes packed by component share their locations in the GL_MAX_VERTEX_ATTRIBS count; doubles packed by component read their part of the attribute. - Geometry emulation: arrays of output blocks, and inputs that are arrays per vertex. Tessellation emulation of separable programs strips hashed locations; inputs (and input blocks) the previous stage does not write are allowed while unread (glslang patch extended to blocks). - fp64: arrays of doubles loaded from buffers, and double members of interface blocks, move element by element (MSL native arrays). - Internal emulation programs and the capture relink print their sources under WINEMETALGL_DUMP_SHADERS=1 when they fail. KHR-GL46 transform_feedback, gpu_shader_fp64, vertex_attrib, program_ interface_query, geometry/tessellation_shader, shaders and 8 more groups: no new failures. GPU tests: vertex input aliasing, xfb double matrices.
GL 4.3 arrays of arrays, which the single-configuration CTS list checks
(803 of 806 now):
- Arrays of arrays of samplers and of stage inputs and outputs, which MSL
cannot declare, are flattened in SPIR-V before translation
(flattenArraysOfArrays): access chains through every dimension index
the one-dimensional array at ((i0 * d1 + i1) * d2 + ...).
- A sampler array of arrays is reflected as a uniform per innermost array
("s[i][0]", GL 4.6 section 7.3.1.1) in consecutive slots.
- Every element of an atomic counter array of arrays counts against
GL_MAX_*_ATOMIC_COUNTERS.
- A uniform array of arrays with an initializer takes every unsized
dimension from it (glslang patch extended).
Open: arrays of arrays as varyings through the geometry or tessellation
emulation (InteractionInterfaceArrays2/4). KHR-GL46 shaders, texture_*,
program_interface_query and 7 more groups: no new failures.
Contexts now get version 4.4 (GLSL 4.40) without the development override. GL_AMD_pinned_memory: glBufferData on GL_EXTERNAL_VIRTUAL_MEMORY_BUFFER_ AMD makes page-aligned application memory the buffer's storage (newBufferWithBytesNoCopy), never replaced by orphaning or renaming. Wine's opengl32 limits 32-bit (WoW64) guests to GL 4.3 and hides GL_ARB_buffer_storage unless the host has it; with it, 32-bit guests get 4.4 and persistent mappings in 32-bit memory. Wine fixtures: the version a context reports is in fixture_version.h (raised with each flip); opengl_gl33_resources accepts Wine's mutable pinned-memory storage for 32-bit persistent buffers. Gate: 59 fixtures, x86_64 and i386, all pass. GPU test gpu_gl44_amd_pinned_memory.
Contexts now get version 4.5 (GLSL 4.50, and GLSL ES 3.10 in the shading language list) without the development override. Every GL 4.5 extension is implemented: direct state access, clip control, cull distances, conditional render inverted, derivative control, ES 3.1 compatibility, texture sub-image reads, shader texture image samples, texture barrier, KHR_context_flush_control and KHR_robustness. Wine fixtures: fixture_version.h reports 4.5; opengl_later_entry_points uses glSpecializeShader (GL 4.6) as the later entry point; opengl_gl33_texture's direct state access path (taken now that the entry points exist) gives glTextureStorage2D and glTextureView sized formats, as GL requires. Gate: 59 fixtures, x86_64 and i386, all pass. GPU test gpu_gl45_derivative_control.
…w queries - ARB_shader_draw_parameters: gl_BaseVertex, gl_BaseInstance and gl_DrawID (and the ARB names) become hidden default uniforms the draw fills from the GL command; multi-draws set the draw index around each draw. - ARB_indirect_parameters: PARAMETER_BUFFER and glMultiDraw*IndirectCount. Multi-draw indirect commands are validated against the indirect buffer before anything draws. - ARB_pipeline_statistics_query: the eleven counters, counted on the CPU from the draw paths; fragment shader invocations by a counting fragment function variant (pipeline key countFragments). - ARB_transform_feedback_overflow_query: overflow and per-stream overflow queries, usable for conditional rendering. - ARB_shader_atomic_counter_ops, ARB_shader_group_vote advertised in 4.6 contexts. A vertex function's atomic counter buffers move into its storage block argument buffer: MAX_VERTEX_ATOMIC_COUNTER_BUFFERS is 8. - Atomic counter buffers are referenced only by stages that use them. - Transform feedback: a discarding draw no longer runs the vertex stage after the capture pass, and a rasterizing draw whose vertex stage writes memory captures while drawing, so the stage runs once. - Geometry emulation: stream qualifiers are stripped only inside layout(), not from names such as out_stream0. CTS (KHR-GL46, native cfg1, dev 4.6): the 4.6 groups pass except gl_spirv, spirv_extensions and parallel_shader_compile; a 1385-case sweep of the touched groups passes. GPU tests gpu_gl46_*; gate 59 fixtures x86_64 and i386 pass.
glShaderBinary takes SPIR-V modules (SHADER_BINARY_FORMAT_SPIR_V); glSpecializeShader checks the entry point and specialization constants and translates the module to GLSL 4.60 with SPIRV-Cross, which the existing compiler, emulations and program binaries take as application source (src/core/shader/spirv_input.cpp): - inter-stage variables are named by location and linked to the previous stage's outputs; unnamed resources by location or binding; - program queries report generated names, and every name of a module without debug names, as empty; - GL atomic counters and gl_PatchVerticesIn, which SPIRV-Cross's GLSL lacks; - SPIR_V_BINARY, the SPIR-V/GLSL link check, GL_SPIR_V_EXTENSIONS. Also: GL_MAX_COMBINED_IMAGE_UNIFORMS is checked at link. CTS (KHR-GL46, native, dev 4.6): gl_spirv 8/9, spirv_extensions 1/1; the capabilities case needs more than 8 image uniforms in a stage (next). A 4396-case sweep of program and shader groups shows no other failure.
Contexts report 4.6 and GLSL 4.60, with ARB_parallel_shader_compile and KHR_parallel_shader_compile (compiles and links finish before the call returns: COMPLETION_STATUS is TRUE; the thread limit is kept) and KHR_no_error (the context flag was already honoured). The 10 fixtures that needed GL 4.4 to 4.6 join the gate. Two fixtures followed the version: opengl_wgl_modern now expects 4.6 requests to succeed and 4.7 to fail; opengl_later_entry_points expects glSpecializeShader without the LaterEntryPoints setting, as no core entry point is above a 4.6 context's version. Gate: 69 fixtures, x86_64 and i386, all pass. GPU tests 186, host 46. CTS (native, KHR-GL46): parallel_shader_compile 3/3.
WineMetalGL as its own Wine module, built against any Wine 11.x install: - winemetalgl.dll (builtin, x86_64 and i386): every GL command as a unix call (generated by tools/gen/wine_gen.py), WGL, pixel format selection and font lists adapted from Wine's opengl32 (LGPL-2.1+ notices kept); - opengl32.dll: forwards every export to winemetalgl.dll, installed into a prefix with opengl32=native; - winemetalgl.so: runs the core, owns contexts, pixel formats, window surfaces and pbuffers; window layers come from winemac's metal view when winemac exports macdrv_functions, else from a view of ours in the Cocoa window (stock WineHQ winemac exports nothing); - wow64: 32-bit callers share the unix side; the core allocates buffer storage below 4 GB (new optional wmgl_set_buffer_memory), so mapped pointers reach them as they are; strings, sync objects and pointer arrays are converted by hand; - debug callbacks are queued on the unix side and delivered by the PE side after the GL call that produced them. scripts/build-wine-module.sh and scripts/install-wine-module.sh build and install it; tests/wine/probe-opengl-wow64.sh runs the fixtures through it with WINEMETALGL_MODULE=1 (and keeps a stock Wine's first boot from waiting on the Mono/Gecko dialog). Gate on stock Wine 11.0 (WineHQ tarball, unpatched): 69 fixtures, x86_64 and i386 guests, all pass.
- Remove patches/wine and scripts/stage-wine.sh. The Wine module installs into any x86_64 Wine 11.x without patching or rebuilding Wine; the fixtures pass on stock Wine 11.0 and on MetalSharp's Wine 11.17. - unix_window.m: Wine 11's struct macdrv_win_data is hwnd, cocoa_window, client_view; the module read the window rects as a view. The winemac metal view is used only for a window that already has a client view; WINEMETALGL_WINE_DEBUG logs which way each window takes. - build-wine-module.sh takes a Wine source tree as well as an installation; CI builds the module against the Wine 11.0 release headers with a pinned llvm-mingw and checks the builtin marker and the WoW64 call table. - Releases stage the module (stage-release.sh, verify-release.sh) with install-wine-module.sh, which works from a package too; the arm64 package is the core and the driver ABI header. - Apple's OpenGL for references and benchmarks is Wine's own opengl32 (WINEDLLOVERRIDES=opengl32=b) in replay.py, benchmark.py and run.py. - The fixture probe always uses the module; opengl_later_entry_points no longer sets the patch's LaterEntryPoints key. - Docs: building.md describes the module, release.md the new layout and what MetalSharp changes; README, CONTRIBUTING, DEPENDENCIES, SECURITY and the templates drop the patches.
…te limit - inferStorageImageAccess decorates storage images a stage only reads NonWritable and those it only writes NonReadable, so SPIRV-Cross declares them access::read or access::write; atomics, function arguments and other uses stay read_write. - A stage binds up to 16 images (textures 16..31), at most 8 read_write. GL_MAX_IMAGE_UNITS is 16 (binding points only); the per-stage image uniform limits stay 8, and GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES keeps counting 8 images. - KHR-GL46.gl_spirv.spirv_validation_capabilities_test passes (natively and on stock Wine 11.0 with the module); the image, compute, SPIR-V, multi-bind, view, atomic counter, storage block, layout and DSA groups are unchanged otherwise. - GPU test gpu_gl46_many_images: 13 images in one compute stage.
…ture - GL_ARB_shader_viewport_layer_array (4.1+ contexts): vertex and tessellation evaluation shaders write gl_Layer and gl_ViewportIndex, as the geometry emulation's pass-through vertex function already did. Its 3 CTS cases pass; GPU test gpu_gl46_vertex_layer_viewport. - GL_EXT_texture_shadow_lod (4.0+ contexts): glslang and SPIRV-Cross already translate textureLod and biased texture on array and cube shadow samplers. Its 15 CTS cases pass; GPU test gpu_gl46_texture_shadow_lod. - Wine fixture opengl_buffer_storage (x86_64 and i386): a context above 4.3 with GL_ARB_buffer_storage and GL_AMD_pinned_memory, a persistent coherent mapping that the next draw sees without a flush, and a pinned-memory buffer drawn from the program's pages after they change. 70 fixtures in the gate.
llvm-mingw's plain clang comes first on PATH in CI and has no macOS headers.
… lines - scene4x core44: immutable buffer storage, the pixel count persistently mapped (reset and read through the mapping behind a fence), multi-bind, texture clears in place of glClear, enhanced layouts (normal and height packed by component, an explicit block member offset). - core45: every object created with direct state access, a cull distance beyond the left clip plane, and the stored image's centre read back with glGetTextureSubImage and compared with the displayed pixel. - core46: four indirect draws whose count comes from a parameter buffer, with gl_DrawID and gl_BaseInstance cancelling out in the vertex shader; statistics queries checking the submitted vertices and patches and the compute invocations; a vote in the compute shader; the display pass in SPIR-V. All three render scene4x-core41's frame (Apple's OpenGL reference). - lowerBuiltinUniforms declared the hidden draw-parameter uniforms inside the first #define line when one preceded the code, breaking the shader; declarations now go before the first token outside a directive. Host test shader_builtin_uniforms_after_defines.
wined3d reports feature level 11_1 on WineMetalGL (9_3 on Apple's OpenGL). Its d3d11 and d3d10core conformance tests found: - Geometry shader emulation copied "invariant gl_Position;" (wined3d's geometry shaders) into its compute kernel, so the program failed to link: layered rendering, stream output from geometry shaders and tessellation, viewport arrays. Qualifier-only redeclarations of built-ins are dropped. - GL_EXT_texture_sRGB_decode: TEXTURE_SRGB_DECODE_EXT on textures and samplers, sampled through the format's linear view. wined3d disables its sRGB render target support (ARB_framebuffer_sRGB) without it; sRGB multisample resolves and swapchain views now come out linear. - wined3d writes literal constants as global consts initialized from bit casts; glslang does not fold them and rejected the shader (feature level 9_x draws). The const goes; the bits are kept exactly. - Converted per-instance attributes with divisor UINT_MAX (D3D step rate 0) overflowed 32 bits and converted no elements. - S3TC texture view classes (DXT1 RGB/RGBA, DXT3, DXT5), so sRGB views of typeless BC1-3 textures are allowed; BPTC formats on GL_TEXTURE_3D (GL 4.6 table 8.14). - Occlusion queries over more than 2^32 samples in one pass wrapped: Apple GPUs count a visibility slot in 32 bits, so a pass moves to a new slot before its draws could cover 2^31 samples. - WINEMETALGL_DUMP_SHADERS=1 also prints application shaders that fail to compile. GPU tests for each. d3d11 failures 370 -> 231 and d3d10core 353 -> 210 of 561,394 and 194,651 checks, 205 of each from D24 depth stored as Depth32Float (depth bias units).
…ported reasons for KHR-GL46 - Buffer storage for 32-bit programs is allocated top-down, away from the program's own heap, and a failed allocation is reported with the size and the storage in use (WINEMETALGL_WINE_DEBUG traces each one). - Occlusion queries trace their slot count and any slot that counted nothing (WINEMETALGL_LOG=3). - tests/cts/notsupported.json: reasons for the KHR-GL46 NotSupported groups (sparse texture 2 and clamp, post-depth coverage, 8 samples, image samples, the tessellation in/out limits, ES-only cube map array cases). - gpu_gl46_occlusion_many_draws creates and clears its target inside the query, through a second framebuffer, as wined3d does.
wined3d reports feature level 11_1 on WineMetalGL. docs/testing.md describes how Wine's d3d11 and d3d10core tests are built and run, their results on stock Wine 11.0 with the module, and what the remaining failures are.
Buffers: - Re-specifying a GL_AMD_pinned_memory buffer gives it storage of its own instead of writing into and keeping the application's memory. - Host memory Metal releases (32-bit programs) goes back on an application thread, before the next allocation: Metal may release on its own thread. - glGetBufferSubData and glCopyBufferSubData fail on any non-persistent mapping (GL 4.6 sections 6.6, 6.7), not only an overlapping one. - Range checks compare size with limit - offset, so offset + size cannot wrap past them. Queries: - Visibility results accumulate, and slot 0 is never a query's: a later pass in the command buffer reset what the first query draw had counted there (wined3d's test_occlusion_query lost one of 100 draws). - Framebuffer blits and texture clears drawn in an open pass do not count towards occlusion queries. - Occlusion slots and FRAGMENT_SHADER_INVOCATIONS counters move on before what their draws can count (instances included) passes 2^31. - glQueryCounter refuses a query glCreateQueries made for another target. - TIME_ELAPSED subtracts GPU times as reported; a waited timer result waits for its completion handler instead of ending as 0. - Query-buffer results: a negative offset is INVALID_VALUE; unaligned offsets are written once the buffer is idle. Wine module: - 32-bit glBindBuffersRange, glBindVertexBuffers and glVertexArrayVertexBuffers widen their GLintptr/GLsizeiptr arrays. - A context current on another thread can be neither made current nor deleted (ERROR_BUSY). Contexts are allocated one by one, and the debug callbacks (KHR and AMD, separately) are read through the thread's current context. - Below 4 GB, small buffers and the string copies share 1 MiB chunks in 16 KiB pages instead of a 64 KiB reservation each. - Destroyed windows' drawables go (the PE side notices with IsWindow); the fallback view hides with its window, clips to its ancestors' client areas, and is placed again when its Cocoa window was missing or closed. - A pbuffer keeps one DC until released; wglQueryPbufferARB with an unknown attribute is ERROR_INVALID_DATA; a DC without a pixel format is ERROR_INVALID_PIXEL_FORMAT; 32-bit glGetPointerv narrows checked. - install-wine-module.sh reports a failed codesign. Tests: gpu_gl46_occlusion_many_draws breaks the pass between draws, gpu_gl46_occlusion_ignores_blit, gpu_cr_buffer_range_checks, the pinned memory test re-specifies its buffer, and the opengl_module_edges fixture (multi-bind ranges, ERROR_BUSY, pbuffer DCs, child window lifecycle) joins the gate.
- 3D compressed (BPTC) textures read back each depth: glGetCompressedTexImage copies by depth, not by a slice the texture does not have, and decoded reads (glGetTexImage, glGetTextureSubImage) copy the image into a 2D texture first (Metal makes only 3D views of a 3D texture). - glClearTexImage without data converts zeros like data, so RGB formats stored as RGBA keep alpha 1; a multisample GL_DEPTH_COMPONENT16 clear reads its 16-bit depth; glClearTexSubImage bounds cannot wrap. - Emulated clamp-to-border: projective shadow lookups divide the reference by q; NEAREST_MIPMAP_LINEAR blends two nearest lookups instead of filtering linearly. - Stencil textures (STENCIL_INDEX8, or depth-stencil in STENCIL_INDEX mode) are incomplete with a linear filter (GL 4.6 section 8.17). - Immutable textures can be render targets, for renderable views of a format that is not (GL_RGB9_E5 seen as GL_R32UI). Tests: gpu_gl46_bptc_3d reads back and re-uploads each depth, gpu_gl46_clear_texture_values, gpu_gl46_border_proj_mip_nearest, gpu_gl46_view_render_stencil_complete. KHR-GL46 texture_view, stencil_texturing, clear_texture, get_texture_sub_image, texture_border_clamp, texture_cube_map_array, copy_image, texture_gather, buffer_storage and the DSA texture and buffer groups (dev, native cfg1): 777 Pass, 2 NotSupported, 1 known failure (texture_view.view_sampling).
- glFramebufferTextureLayer and glNamedFramebufferTextureLayer attach a cube map face by layer (GL 4.5). - glGetTexParameter*/glGetTextureParameter* report GL_TEXTURE_TARGET (4.5). - In compatibility contexts the DSA vertex array commands take 0 for the default vertex array. - glGetTextureImage of a cube map packs the six faces as one 3D image (pack parameters, image skipping); bufSize bounds client memory only, and a negative one is INVALID_VALUE. glGetCompressedTextureImage likewise. - glTextureSubImage3D/glCompressedTextureSubImage3D of a cube map: bounds that cannot wrap, UNPACK_SKIP_IMAGES honoured, a compressed depth of 0 writes nothing. - glVertexArrayVertexBuffer takes names from glGenBuffers not yet bound; glTransformFeedbackBuffer* with a buffer that does not exist is INVALID_VALUE (GL 4.6 section 13.2.2). - Pixel buffer ranges (pack, unpack, glReadPixels, glBitmap, glDrawPixels) are checked without offset + size wrapping. Tests: gpu_gl46_dsa_corners, compat_dsa_default_vertex_array. KHR-GL46 direct_state_access, layered framebuffers, packed_pixels, pixelstoragemodes, transform_feedback, texture_cube_map_array and vertex_attrib_binding (dev, native cfg1): 6023 Pass, 82 NotSupported, the known framebuffers_check_status CompatibilityWarning.
- Transform feedback with a vertex stage that writes memory draws its captured list in one pass under both provoking-vertex conventions: the list is drawn through indices that put each primitive's provoking vertex first (a rotation, keeping the winding). The vertex stage no longer runs twice under the default last-vertex convention, and strips and fans flat-shade from GL's provoking vertex under the first. - Geometry and tessellation emulation: an allocation the device cannot make skips the draw (logged) instead of writing through nil buffers; a tessellation control border variant that did not compile is not bound; chunks made for one huge allocation are let go once their work is done. - Indirect draws: command and count offsets near the top of the address space cannot wrap the bounds checks; the indirect and parameter buffers are checked again after the unlocked wait for GPU writes. - glMultiDraw*Indirect*: mode, type, vertex array, indirect buffer and alignment errors are generated once before any command is read, also when no command draws. Tests: gpu_gl46_xfb_memory_flat_provoking. KHR-GL46 draw_indirect, indirect_parameters, shader_draw_parameters, transform_feedback, transform_feedback_overflow_query, tessellation_shader, pipeline_statistics_query, vertex_attrib_64bit and texture_border_clamp (dev, native cfg1): 447 Pass, 1 NotSupported (listed).
MTLRenderPassDescriptor.visibilityResultType is macOS 26 API, which the macOS 15 SDK (CI) does not have. Reserving slot 0 is what fixes the lost draw (gpu_gl46_occlusion_many_draws passes with it alone), on every macOS.
- Arrays of arrays of images are reflected as a uniform per innermost array with consecutive slots, as samplers are; the reflection no longer writes past its image slots (image2D img[2][3]). - Application SPIR-V is checked before SPIRV-Cross parses it: every instruction fits the module, every <id> operand is below the header's bound (at most 2^22), and opcodes are known. Operand kinds come from glslang's SPIR-V tables (spirv_validate.cpp). - SPIR-V atomic counter decrements return the value before the decrement, as OpAtomicIDecrement does (GLSL's function returns the value after). - SPIR-V stages match default-block uniforms by location (ARB_gl_spirv): stages naming a location differently are renamed alike at link; structure types are named by layout whether or not the module names them. - An array of transform feedback output blocks is captured by consecutive buffers, element k into xfb_buffer + k (GLSL 4.60 section 4.4.2.1). - Arrays of arrays of atomic counters are a uniform per innermost array. - A #version or varying index too long for an int no longer throws out of glCompileShader or glLinkProgram. Tests: gpu_gl46_image_arrays_of_arrays, gpu_gl46_spirv_malformed, gpu_gl46_spirv_counter_decrement, gpu_gl46_long_numbers, gpu_gl46_spirv_uniform_locations, gpu_gl46_xfb_block_array_buffers, gpu_gl46_counter_arrays_of_arrays. KHR-GL46 gl_spirv, shader_atomic_counters, transform_feedback*, program_interface_query, shader_image_load_store, shader_draw_parameters and shader_subroutine (dev, native cfg1): 211 Pass, 2 NotSupported (listed). KHR-Single-GL46 enhanced_layouts and arrays_of_arrays_gl: 5048 Pass, the same 8 failures as before (cbf2208).
glslang declared the bias forms (texture of sampler2DArrayShadow and samplerCubeArrayShadow, textureOffset of sampler2DArrayShadow) for every stage, so a vertex shader using one compiled. Since the extension is advertised (f93d243), KHR-GL46.negative_texture_lookup_functions_with_bias runs those cases instead of skipping them, and they failed. KHR-GL46 negative_texture_lookup_functions_with_bias, ext_texture_shadow_lod and texture_lod_bias (dev, native cfg1): 109 Pass, 27 NotSupported (sparse). Full KHR-GL46 at 6211c21 (dev, native cfg1): 15153 Pass; the failures are these three and the known four.
d3d11 230 and d3d10core 209 failures of 561,394 and 194,651 checks, the same as 64-bit and 32-bit programs: test_occlusion_query passes, and 32-bit d3d11 now runs to the end (wined3d's 64 MB persistent chunks find room below 4 GB since small buffers share pages).
DOOM (2016) attaches its render targets on one context and draws with another (its render thread's). GL makes framebuffers per-context container objects, so on the drawing context the names were new, empty framebuffers (binding an unused name creates one in a compatibility context), every scene draw failed with INVALID_FRAMEBUFFER_OPERATION, and the game showed a black screen after loading. Mesa keeps framebuffers in the shared state, and NVIDIA and AMD share them too; framebuffer names now live in the share group. Silent failures are reported (at WINEMETALGL_LOG=1 and above): - a framebuffer that cannot be drawn to, once per framebuffer and attachment point, with what is wrong with the attachment; - each GL error once per command and error, with the command. Tests: gpu_shared_framebuffers (fails without the change). KHR-GL46 DSA framebuffers, framebuffer_blit, draw_buffers, api, CommonBugs, layout_binding, packed_depth_stencil, texture_view, layered FBOs (dev, native cfg1): 94 Pass, the known CompatibilityWarning and view_sampling.
DOOM (2016) ran at 10 fps: its menu video uploads three planes a frame (1920x1088 and 960x544, GL_RED/GL_UNSIGNED_BYTE into R8), and each texel went through the generic converter (four doubles, clamped, re-encoded): about 20 ms a plane under Rosetta, with the share group's lock held, so its other thread waited about 50 ms a frame. Frames now take 12-13 ms (0.2-0.6 ms of it in GL calls). - unpackPixels copies whole rows when the client bytes are the stored bytes: RED/RG/RGBA (and their integer forms) and ALPHA/LUMINANCE/ LUMINANCE_ALPHA of matching 8, 16 and 32-bit components, and the existing raw formats with one-byte types. BGRA bytes into RGBA8 swap two bytes per texel. - Uploads convert straight into the staging memory the GPU copies from, instead of a zero-filled vector copied again. - WINEMETALGL_STATS also profiles every GL command across threads (time, calls and share-group lock waits per frame, the 15 costliest commands and each thread's share), printed every 60 frames. KHR-GL46 packed_pixels, pixelstoragemodes, texture_swizzle, texture_storage, texture_size_promotion, clear_tex_image, texture_stencil8, texture_view, internalformat, get_texture_sub_image (dev, native cfg1): 6192 Pass, the 3 known failures.
- Keep CPU conversions of vertex attributes per buffer until its contents change, and decode runs of elements in typed loops. - Read pixels into a pack buffer with a blit, without waiting. - Cache index-range scans in a hash map and scan without restart in a vectorizable loop. - Reuse the last pipeline, and skip encoder state, textures and samplers the encoder already has; bind the samplers a draw prepared instead of looking them up again. - Upload large default uniforms once for both stages. - Hash pipeline keys a word at a time. - Stats: converted vertices and causes, CPU index rewrites and uniform bytes; WMGL_BENCH draw-overhead benchmark.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
OpenGL 4.4, 4.5 and 4.6 (core and compatibility) on Metal. This is milestone M3 of the GL 4.x roadmap, to be released as
winemetalgl-3.0.0and shipped as a standalone Wine module that needs no Wine patches.This is a draft; the description is the live progress record.
Progress
GL 4.4 (G09):
4.4 flip at
be2d1db.GL 4.5 (G10):
4.5 flip at
7bf4873.GL 4.6 (G11):
4.6 flip at
a451696. The 10 GL 4.4–4.6 fixtures joined the gate.Standalone Wine module (
09e7fcb,a222f63):opengl32.dllforwarder pluswinemetalgl.dll/.so, with WoW64 thunks.--with-opengl --with-vulkan) and on MetalSharp's Wine 11.17.patches/wineis retired. Releases stage the module (install-wine-module.sh).Optional extensions (G12):
ARB_shader_viewport_layer_array,EXT_texture_shadow_lod,EXT_texture_sRGB_decode.ARB_texture_filter_minmaxis not feasible: Metal's reduction mode has no effect on M4 / macOS 27.2.read_writetextures (7b47ed5).wined3d FL 11_1 (G16):
f76fd54; the review found the occlusion-query one (0b8f6ae).docs/testing.md#direct3d-through-wined3d.GL_AMD_pinned_memory(be2d1db) and the 32-bit buffer storage.Corpus: scene4x at 4.4, 4.5 and 4.6 (
fc3fe89), each matching the Apple-recorded 4.1 frame, with readbacks (persistent map, texture sub-image, statistics).Performance (G14): benchmark A/B against 2.4.0, budgets. Development A/B on stock Wine 11.0: no entry more than 4% slower than 2.4.0 once the two flagged ones were rerun alternately; the evidence run follows the code freeze.
Evidence: KHR-GL46 (native cfg1, Wine cfg1 + cfg3 on stock 11.0), the MetalSharp 11.17 cfg1 check, and rechecks of KHR-GL33–43.
Reviews: seven independent reviews by area: shader compiler and SPIR-V, bindings and limits, direct state access, draws (indirect, tessellation, geometry), textures and formats, queries and transform feedback, the Wine module.
0b8f6ae);0ba2044); direct state access (3da4020);eaad155); the shader compiler and SPIR-V (6211c21); a glslang fix the full run caught (7fba80f).ERROR_BUSYfor contexts current elsewhere, unvalidated application SPIR-V, and 3D BPTC readback.DOOM (2016) confirmed by Avery.
Design notes for the 4.x pieces that work around Metal are in
docs/decisions/0002-gl4-architecture.md: DSA, cull distances, border colours, draw parameters, pipeline statistics, SPIR-V and image access.Development runs (not evidence)
KHR-GL46cfg1 on stock Wine 11.0 + module (09e7fcb): 15134 Pass, 4 Fail, 1 CompatibilityWarning, the same as native.opengl_module_edges), all pass on stock Wine 11.0.DOOM[2016] Running Under WineMetalGL with OpenGL 4.5